diff options
| -rw-r--r-- | src/Internal/Marking.hs | 13 | ||||
| -rw-r--r-- | src/Internal/Windows.hs | 47 |
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 |