aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJosh Rahm <rahm@google.com>2021-11-15 16:48:28 -0700
committerJosh Rahm <joshuarahm@gmail.com>2022-10-09 12:19:45 -0600
commit7852e8c0adccc301e4927b7d72f1df86cb71a278 (patch)
tree152dec8460e6d06f54958b4f522713e8432f94bc
parent349be728078137e48731a4a0a33ef8459040fc2f (diff)
downloadrde-7852e8c0adccc301e4927b7d72f1df86cb71a278.tar.gz
rde-7852e8c0adccc301e4927b7d72f1df86cb71a278.tar.bz2
rde-7852e8c0adccc301e4927b7d72f1df86cb71a278.zip
Change marking to use greedy viewing.
-rw-r--r--src/Internal/Marking.hs13
-rw-r--r--src/Internal/Windows.hs47
2 files changed, 55 insertions, 5 deletions
diff --git a/src/Internal/Marking.hs b/src/Internal/Marking.hs
index fc1c082..c1234ec 100644
--- a/src/Internal/Marking.hs
+++ b/src/Internal/Marking.hs
@@ -1,7 +1,7 @@
{-# LANGUAGE ScopedTypeVariables #-}
module Internal.Marking where
-import Internal.Windows (mapWindows)
+import Internal.Windows (mapWindows, findWindow, getLocationWorkspace)
import XMonad
import XMonad.StackSet hiding (focus)
import Data.IORef
@@ -30,6 +30,13 @@ data MarkState =
instance ExtensionClass MarkState where
initialValue = MarkState Map.empty Nothing
+greedyFocus :: Window -> X ()
+greedyFocus win = do
+ ws <- withWindowSet $ \ss ->
+ return $ getLocationWorkspace =<< findWindow ss win
+ mapM_ (windows . greedyView . tag) ws
+ focus win
+
markCurrentWindow :: Mark -> X ()
markCurrentWindow mark = do
withFocused $ \win ->
@@ -47,7 +54,7 @@ jumpToLast :: X ()
jumpToLast = do
m <- markLast <$> XS.get
saveLastMark
- mapM_ focus m
+ mapM_ greedyFocus m
jumpToMark :: Mark -> X ()
jumpToMark mark = do
@@ -56,7 +63,7 @@ jumpToMark mark = do
Nothing -> return ()
Just w -> do
saveLastMark
- focus w
+ greedyFocus w
setFocusedWindow :: a -> StackSet i l a s sd -> StackSet i l a s sd
setFocusedWindow
diff --git a/src/Internal/Windows.hs b/src/Internal/Windows.hs
index 0f109b7..b6f5335 100644
--- a/src/Internal/Windows.hs
+++ b/src/Internal/Windows.hs
@@ -1,7 +1,8 @@
module Internal.Windows where
-import XMonad.StackSet (Stack(..), StackSet(..), Screen(..), Workspace(..), integrate)
-import Data.Maybe (listToMaybe)
+import Control.Applicative ((<|>))
+import XMonad.StackSet (Stack(..), StackSet(..), Screen(..), Workspace(..), integrate, integrate')
+import Data.Maybe (listToMaybe, catMaybes)
import qualified Data.Map as Map
mapWindows :: (Ord a, Ord b) => (a -> b) -> StackSet i l a s sd -> StackSet i l b s sd
@@ -30,3 +31,45 @@ swapWindows wa wb = mapWindows $ \w ->
_ | w == wa -> wb
_ | w == wb -> wa
_ -> w
+
+data WindowLocation i l a s sd =
+ OnScreen (Screen i l a s sd) |
+ OnHiddenWorkspace (Workspace i l a) |
+ Floating
+
+getLocationWorkspace :: WindowLocation i l a s sd -> Maybe (Workspace i l a)
+getLocationWorkspace (OnScreen (Screen w _ _)) = Just w
+getLocationWorkspace (OnHiddenWorkspace w) = Just w
+getLocationWorkspace _ = Nothing
+
+workspaceMember :: (Eq a) => Workspace i l a -> a -> Bool
+workspaceMember (Workspace _ _ s) w = w `elem` integrate' s
+
+{- Finds a Window and returns the screen its on and the workspace its on.
+ - Returns nothing if the window doesn't exist.
+ -
+ - If the window is not a screen Just (Nothing, workspace) is returned.
+ - If the window is a floating window Just (Nothing, Nothing) is returned. -}
+findWindow ::
+ (Eq a) => StackSet i l a s sd -> a -> Maybe (WindowLocation i l a s sd)
+findWindow (StackSet cur vis hid float) win =
+ listToMaybe . catMaybes $
+ map findWindowScreen (cur : vis) ++
+ map findWindowWorkspace hid ++
+ [findWindowFloat]
+
+ where
+ findWindowScreen s@(Screen ws _ _) =
+ if workspaceMember ws win
+ then Just (OnScreen s)
+ else Nothing
+
+ findWindowWorkspace w =
+ if workspaceMember w win
+ then Just (OnHiddenWorkspace w)
+ else Nothing
+
+ findWindowFloat =
+ if win `elem` Map.keys float
+ then Just Floating
+ else Nothing