diff --git a/XMonad/Hooks/EwmhDesktops.hs b/XMonad/Hooks/EwmhDesktops.hs index 29585034..2e77ca36 100644 --- a/XMonad/Hooks/EwmhDesktops.hs +++ b/XMonad/Hooks/EwmhDesktops.hs @@ -4,7 +4,7 @@ ----------------------------------------------------------------------------- -- | -- Module : XMonad.Hooks.EwmhDesktops --- Description : Make xmonad use the extended window manager hints (EWMH). +-- Description : Make xmonad use the extended window manager hints (EWMH). -- Copyright : (c) 2007, 2008 Joachim Breitner -- License : BSD -- @@ -12,25 +12,29 @@ -- Stability : unstable -- Portability : unportable -- --- Makes xmonad use the EWMH hints to tell panel applications about its --- workspaces and the windows therein. It also allows the user to interact --- with xmonad by clicking on panels and window lists. +-- Makes xmonad use the +-- +-- hints to tell panel applications about its workspaces and the windows +-- therein. It also allows the user to interact with xmonad by clicking on +-- panels and window lists. ----------------------------------------------------------------------------- module XMonad.Hooks.EwmhDesktops ( -- * Usage -- $usage ewmh, - ewmhDesktopsStartup, - ewmhDesktopsLogHook, - ewmhDesktopsLogHookCustom, + ewmhFullscreen, NetActivated (..), activated, activateLogHook, + + -- * Standalone hooks (to be deprecated) + ewmhDesktopsStartup, + ewmhDesktopsLogHook, + ewmhDesktopsLogHookCustom, ewmhDesktopsEventHook, ewmhDesktopsEventHookCustom, - ewmhFullscreen, fullscreenEventHook, - fullscreenStartup + fullscreenStartup, ) where import Codec.Binary.UTF8.String (encode) @@ -42,7 +46,6 @@ import XMonad.Prelude import qualified XMonad.StackSet as W import XMonad.Hooks.SetWMName -import qualified XMonad.Util.ExtensibleState as E import XMonad.Util.WorkspaceCompare import XMonad.Util.WindowProperties (getProp32) import qualified XMonad.Util.ExtensibleState as XS @@ -59,7 +62,10 @@ import qualified XMonad.Util.ExtensibleState as XS -- -- > main = xmonad $ … . ewmh . … $ def{…} -- --- You may also be interested in 'docks' from "XMonad.Hooks.ManageDocks". +-- You may also be interested in 'XMonad.Hooks.ManageDocks.docks' and +-- 'XMonad.Hooks.UrgencyHook.withUrgencyHook', which provide support for other +-- parts of the +-- . -- -- __/NOTE:/__ 'ewmh' function will call 'logHook' for handling activated -- window. @@ -89,85 +95,52 @@ import qualified XMonad.Util.ExtensibleState as XS -- > } -- > xmonad xcf --- | Add EWMH functionality to the given config. See above for an example. +-- | Add EWMH support for workspaces (virtual desktops) to the given +-- 'XConfig'. See above for an example. ewmh :: XConfig a -> XConfig a ewmh c = c { startupHook = ewmhDesktopsStartup <+> startupHook c , handleEventHook = ewmhDesktopsEventHook <+> handleEventHook c , logHook = ewmhDesktopsLogHook <+> logHook c } --- | --- Initializes EwmhDesktops and advertises EWMH support to the X --- server +-- | Initializes EwmhDesktops and advertises EWMH support to the X server. ewmhDesktopsStartup :: X () ewmhDesktopsStartup = setSupported --- | --- Notifies pagers and window lists, such as those in the gnome-panel --- of the current state of workspaces and windows. +-- | Notifies pagers and window lists, such as those in the gnome-panel of the +-- current state of workspaces and windows. ewmhDesktopsLogHook :: X () ewmhDesktopsLogHook = ewmhDesktopsLogHookCustom id --- | --- Cached desktop names (e.g. @_NET_NUMBER_OF_DESKTOPS@ and --- @_NET_DESKTOP_NAMES@). -newtype DesktopNames = DesktopNames [String] - deriving Eq +-- | Cached @_NET_DESKTOP_NAMES@, @_NET_NUMBER_OF_DESKTOPS@ +newtype DesktopNames = DesktopNames [String] deriving Eq +instance ExtensionClass DesktopNames where initialValue = DesktopNames [] -instance ExtensionClass DesktopNames where - initialValue = DesktopNames [] +-- | Cached @_NET_CLIENT_LIST@ +newtype ClientList = ClientList [Window] deriving Eq +instance ExtensionClass ClientList where initialValue = ClientList [none] --- | --- Cached client list (e.g. @_NET_CLIENT_LIST@). -newtype ClientList = ClientList [Window] - deriving Eq +-- | Cached @_NET_CLIENT_LIST_STACKING@ +newtype ClientListStacking = ClientListStacking [Window] deriving Eq +instance ExtensionClass ClientListStacking where initialValue = ClientListStacking [none] -instance ExtensionClass ClientList where - initialValue = ClientList [none] +-- | Cached @_NET_CURRENT_DESKTOP@ +newtype CurrentDesktop = CurrentDesktop Int deriving Eq +instance ExtensionClass CurrentDesktop where initialValue = CurrentDesktop (complement 0) --- | --- Cached stacking client list (e.g. @_NET_CLIENT_LIST_STACKING@). -newtype ClientListStacking = ClientListStacking [Window] - deriving Eq +-- | Cached @_NET_WM_DESKTOP@ +newtype WindowDesktops = WindowDesktops (M.Map Window Int) deriving Eq +instance ExtensionClass WindowDesktops where initialValue = WindowDesktops (M.singleton none (complement 0)) -instance ExtensionClass ClientListStacking where - initialValue = ClientListStacking [none] - --- | --- Cached current desktop (e.g. @_NET_CURRENT_DESKTOP@). -newtype CurrentDesktop = CurrentDesktop Int - deriving Eq - -instance ExtensionClass CurrentDesktop where - initialValue = CurrentDesktop (-1) - --- | --- Cached window-desktop assignments (e.g. @_NET_CLIENT_LIST_STACKING@). -newtype WindowDesktops = WindowDesktops (M.Map Window Int) - deriving Eq - -instance ExtensionClass WindowDesktops where - initialValue = WindowDesktops (M.singleton none (-1)) - --- | --- The value of @_NET_ACTIVE_WINDOW@, cached to avoid unnecessary property --- updates. -newtype ActiveWindow = ActiveWindow Window - deriving Eq - -instance ExtensionClass ActiveWindow where - initialValue = ActiveWindow (complement none) +-- | Cached @_NET_ACTIVE_WINDOW@ +newtype ActiveWindow = ActiveWindow Window deriving Eq +instance ExtensionClass ActiveWindow where initialValue = ActiveWindow (complement none) -- | Compare the given value against the value in the extensible state. Run the -- action if it has changed. whenChanged :: (Eq a, ExtensionClass a) => a -> X () -> X () -whenChanged v action = do - v0 <- E.get - unless (v == v0) $ do - action - E.put v +whenChanged = whenX . XS.modified . const --- | --- Generalized version of ewmhDesktopsLogHook that allows an arbitrary +-- | Generalized version of ewmhDesktopsLogHook that allows an arbitrary -- user-specified function to transform the workspace list (post-sorting) ewmhDesktopsLogHookCustom :: ([WindowSpace] -> [WindowSpace]) -> X () ewmhDesktopsLogHookCustom t = withWindowSet $ \s -> do @@ -208,8 +181,8 @@ ewmhDesktopsLogHookCustom t = withWindowSet $ \s -> do let activeWindow' = fromMaybe none (W.peek s) whenChanged (ActiveWindow activeWindow') $ setActiveWindow activeWindow' --- | --- Intercepts messages from pagers and similar applications and reacts on them. +-- | Intercepts messages from pagers and similar applications and reacts on them. +-- -- Currently supports: -- -- * _NET_CURRENT_DESKTOP (switching desktops) @@ -222,8 +195,7 @@ ewmhDesktopsLogHookCustom t = withWindowSet $ \s -> do ewmhDesktopsEventHook :: Event -> X All ewmhDesktopsEventHook = ewmhDesktopsEventHookCustom id --- | --- Generalized version of ewmhDesktopsEventHook that allows an arbitrary +-- | Generalized version of ewmhDesktopsEventHook that allows an arbitrary -- user-specified function to transform the workspace list (post-sorting) ewmhDesktopsEventHookCustom :: ([WindowSpace] -> [WindowSpace]) -> Event -> X All ewmhDesktopsEventHookCustom f e = handle f e >> return (All True) @@ -298,14 +270,6 @@ handle f ClientMessageEvent{ev_window = w, ev_message_type = mt, ev_data = d} = handle _ _ = return () -- | Add EWMH fullscreen functionality to the given config. --- --- This must be applied after 'ewmh', like so: --- --- > main = xmonad $ ewmhFullscreen $ ewmh def --- --- NOT: --- --- > main = xmonad $ ewmh $ ewmhFullscreen def ewmhFullscreen :: XConfig a -> XConfig a ewmhFullscreen c = c { startupHook = startupHook c <+> fullscreenStartup , handleEventHook = handleEventHook c <+> fullscreenEventHook } @@ -314,9 +278,8 @@ ewmhFullscreen c = c { startupHook = startupHook c <+> fullscreenStartup fullscreenStartup :: X () fullscreenStartup = setFullscreenSupported --- | --- An event hook to handle applications that wish to fullscreen using the --- _NET_WM_STATE protocol. This includes users of the gtk_window_fullscreen() +-- | An event hook to handle applications that wish to fullscreen using the +-- @_NET_WM_STATE@ protocol. This includes users of the @gtk_window_fullscreen()@ -- function, such as Totem, Evince and OpenOffice.org. -- -- Note this is not included in 'ewmh'. @@ -385,6 +348,12 @@ setWindowDesktop win i = withDisplay $ \dpy -> do a <- getAtom "_NET_WM_DESKTOP" io $ changeProperty32 dpy win a cARDINAL propModeReplace [fromIntegral i] +setActiveWindow :: Window -> X () +setActiveWindow w = withDisplay $ \dpy -> do + r <- asks theRoot + a <- getAtom "_NET_ACTIVE_WINDOW" + io $ changeProperty32 dpy r a wINDOW propModeReplace [fromIntegral w] + setSupported :: X () setSupported = withDisplay $ \dpy -> do r <- asks theRoot @@ -416,9 +385,3 @@ addSupported props = withDisplay $ \dpy -> do setFullscreenSupported :: X () setFullscreenSupported = addSupported ["_NET_WM_STATE", "_NET_WM_STATE_FULLSCREEN"] - -setActiveWindow :: Window -> X () -setActiveWindow w = withDisplay $ \dpy -> do - r <- asks theRoot - a <- getAtom "_NET_ACTIVE_WINDOW" - io $ changeProperty32 dpy r a wINDOW propModeReplace [fromIntegral w]