module Internal.Windows where 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 mapWindows fn (StackSet cur vis hid float) = StackSet (mapWindowsScreen cur) (map mapWindowsScreen vis) (map mapWindowsWorkspace hid) (Map.mapKeys fn float) where mapWindowsScreen (Screen work a b) = Screen (mapWindowsWorkspace work) a b mapWindowsWorkspace (Workspace t l stack) = Workspace t l (fmap (mapStack fn) stack) -- | What genius decided to hide the instances for the Stack type!!??? mapStack :: (a -> b) -> Stack a -> Stack b mapStack fn (Stack focus up down) = Stack (fn focus) (map fn up) (map fn down) getMaster :: StackSet i l a s sd -> Maybe a getMaster (StackSet (Screen (Workspace _ _ ss) _ _) _ _ _) = head . integrate <$> ss swapWindows :: (Ord a) => a -> a -> StackSet i l a s d -> StackSet i l a s d swapWindows wa wb = mapWindows $ \w -> case w of _ | 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