mirror of
https://github.com/xmonad/xmonad-contrib.git
synced 2025-08-04 06:01:52 -07:00
EwmhWindows wrap up for inclusion
Now with haddock documentation, a proper header and nicer, warningfree code, ready for a first release and inclusion in XMonadConrib. It works for me, but needs more testing. If you run xmonad with gnome-panel or something similar, please try it. Thanks, Joachim
This commit is contained in:
120
EwmhDesktops.hs
120
EwmhDesktops.hs
@@ -1,42 +1,114 @@
|
|||||||
module XMonadContrib.EwmhDesktops (ewmhDesktopsLogHook) where
|
-----------------------------------------------------------------------------
|
||||||
|
-- |
|
||||||
|
-- Module : XMonadContrib.EwmhDesktops
|
||||||
|
-- Copyright : (c) Joachim Breitner <mail@joachim-breitner.de>
|
||||||
|
-- License : BSD
|
||||||
|
--
|
||||||
|
-- Maintainer : Joachim Breitner <mail@joachim-breitner.de>
|
||||||
|
-- Stability : unstable
|
||||||
|
-- Portability : unportable
|
||||||
|
--
|
||||||
|
-- Makes xmonad use the EWMH hints to tell panel applications about its
|
||||||
|
-- workspaces and the windows therein.
|
||||||
|
-----------------------------------------------------------------------------
|
||||||
|
module XMonadContrib.EwmhDesktops (
|
||||||
|
-- * Usage
|
||||||
|
-- $usage
|
||||||
|
ewmhDesktopsLogHook
|
||||||
|
) where
|
||||||
|
|
||||||
import Data.Maybe (listToMaybe,fromJust)
|
|
||||||
import Data.List (elemIndex, sortBy)
|
import Data.List (elemIndex, sortBy)
|
||||||
import Data.Ord ( comparing)
|
import Data.Ord (comparing)
|
||||||
|
import Data.Maybe (fromMaybe)
|
||||||
|
|
||||||
import Control.Monad.Reader
|
import Control.Monad.Reader
|
||||||
import XMonad
|
import XMonad
|
||||||
import qualified StackSet as W
|
import qualified StackSet as W
|
||||||
import System.IO
|
|
||||||
import Graphics.X11.Xlib
|
import Graphics.X11.Xlib
|
||||||
import Graphics.X11.Xlib.Extras
|
import Graphics.X11.Xlib.Extras
|
||||||
|
|
||||||
ewmhDesktopsLogHook :: X ()
|
-- $usage
|
||||||
ewmhDesktopsLogHook = withDisplay $ \dpy -> withWindowSet $ \s -> do
|
-- Add the imports to your configuration file and add the logHook:
|
||||||
-- Number of Workspaces
|
--
|
||||||
-- Bad hack because xmonad forgets the original order of things, it seems
|
-- > import XMonadContrib.EwmhDesktops
|
||||||
let ws = sortBy (comparing W.tag) $ W.workspaces s
|
--
|
||||||
|
-- > logHook :: X()
|
||||||
|
-- > logHook = do ewmhDesktopsLogHook
|
||||||
|
-- > return ()
|
||||||
|
|
||||||
let n = fromIntegral (length ws)
|
-- %import XMonadContrib.EwmhDesktops
|
||||||
a <- getAtom "_NET_NUMBER_OF_DESKTOPS"
|
-- %def -- comment out default logHook definition above if you uncomment this:
|
||||||
c <- getAtom "CARDINAL"
|
-- %def logHook = ewmhDesktopsLogHook
|
||||||
r <- asks theRoot
|
|
||||||
io $ changeProperty32 dpy r a c propModeReplace [n]
|
|
||||||
|
-- |
|
||||||
|
-- Notifies pagers and window lists, such as those in the gnome-panel
|
||||||
|
-- of the current state of workspaces and windows.
|
||||||
|
ewmhDesktopsLogHook :: X ()
|
||||||
|
ewmhDesktopsLogHook = withWindowSet $ \s -> do
|
||||||
|
-- Bad hack because xmonad forgets the original order of things, it seems
|
||||||
|
-- see http://code.google.com/p/xmonad/issues/detail?id=53
|
||||||
|
let ws = sortBy (comparing W.tag) $ W.workspaces s
|
||||||
|
let wins = W.allWindows s
|
||||||
|
|
||||||
|
-- Number of Workspaces
|
||||||
|
setNumberOfDesktops (length ws)
|
||||||
|
|
||||||
-- Names thereof
|
-- Names thereof
|
||||||
a <- getAtom "_NET_DESKTOP_NAMES"
|
setDesktopNames (map W.tag ws)
|
||||||
c <- getAtom "UTF8_STRING"
|
|
||||||
let names = map (fromIntegral.fromEnum) $
|
|
||||||
concatMap (("Workspace "++) . (++['\0']). W.tag) ws
|
|
||||||
io $ changeProperty8 dpy r a c propModeReplace names
|
|
||||||
|
|
||||||
-- Current desktop
|
-- Current desktop
|
||||||
a <- getAtom "_NET_CURRENT_DESKTOP"
|
fromMaybe (return ()) $ do
|
||||||
c <- getAtom "CARDINAL"
|
n <- W.lookupWorkspace 0 s
|
||||||
let Just n = W.lookupWorkspace 0 s
|
i <- elemIndex n $ map W.tag ws
|
||||||
let Just i = elemIndex n $ map W.tag ws
|
return $ setCurrentDesktop i
|
||||||
io $ changeProperty32 dpy r a c propModeReplace [fromIntegral i]
|
|
||||||
|
setClientList wins
|
||||||
|
|
||||||
|
-- Per window Desktop
|
||||||
|
forM (zip ws [(0::Int)..]) $ \(w, wn) ->
|
||||||
|
forM (W.integrate' (W.stack w)) $ \win -> do
|
||||||
|
setWindowDesktop win wn
|
||||||
|
|
||||||
return ()
|
return ()
|
||||||
|
|
||||||
|
|
||||||
|
setNumberOfDesktops :: (Integral a) => a -> X ()
|
||||||
|
setNumberOfDesktops n = withDisplay $ \dpy -> do
|
||||||
|
a <- getAtom "_NET_NUMBER_OF_DESKTOPS"
|
||||||
|
c <- getAtom "CARDINAL"
|
||||||
|
r <- asks theRoot
|
||||||
|
io $ changeProperty32 dpy r a c propModeReplace [fromIntegral n]
|
||||||
|
|
||||||
|
setCurrentDesktop :: (Integral a) => a -> X ()
|
||||||
|
setCurrentDesktop i = withDisplay $ \dpy -> do
|
||||||
|
a <- getAtom "_NET_CURRENT_DESKTOP"
|
||||||
|
c <- getAtom "CARDINAL"
|
||||||
|
r <- asks theRoot
|
||||||
|
io $ changeProperty32 dpy r a c propModeReplace [fromIntegral i]
|
||||||
|
|
||||||
|
setDesktopNames :: [String] -> X ()
|
||||||
|
setDesktopNames names = withDisplay $ \dpy -> do
|
||||||
|
-- Names thereof
|
||||||
|
r <- asks theRoot
|
||||||
|
a <- getAtom "_NET_DESKTOP_NAMES"
|
||||||
|
c <- getAtom "UTF8_STRING"
|
||||||
|
let names' = map (fromIntegral.fromEnum) $
|
||||||
|
concatMap (("Workspace "++) . (++['\0'])) names
|
||||||
|
io $ changeProperty8 dpy r a c propModeReplace names'
|
||||||
|
|
||||||
|
setClientList :: [Window] -> X ()
|
||||||
|
setClientList wins = withDisplay $ \dpy -> do
|
||||||
|
-- (What order do we really need? Something about age and stacking)
|
||||||
|
r <- asks theRoot
|
||||||
|
c <- getAtom "WINDOW"
|
||||||
|
a <- getAtom "_NET_CLIENT_LIST"
|
||||||
|
io $ changeProperty32 dpy r a c propModeReplace wins
|
||||||
|
a' <- getAtom "_NET_CLIENT_LIST_STACKING"
|
||||||
|
io $ changeProperty32 dpy r a' c propModeReplace wins
|
||||||
|
|
||||||
|
setWindowDesktop :: (Integral a) => Window -> a -> X ()
|
||||||
|
setWindowDesktop win i = withDisplay $ \dpy -> do
|
||||||
|
a <- getAtom "_NET_WM_DESKTOP"
|
||||||
|
c <- getAtom "CARDINAL"
|
||||||
|
io $ changeProperty32 dpy win a c propModeReplace [fromIntegral i]
|
||||||
|
@@ -34,6 +34,7 @@ import XMonadContrib.DwmPromote ()
|
|||||||
import XMonadContrib.DynamicLog ()
|
import XMonadContrib.DynamicLog ()
|
||||||
import XMonadContrib.DynamicWorkspaces ()
|
import XMonadContrib.DynamicWorkspaces ()
|
||||||
import XMonadContrib.Dzen ()
|
import XMonadContrib.Dzen ()
|
||||||
|
import XMonadContrib.EwmhDesktop ()
|
||||||
import XMonadContrib.FindEmptyWorkspace ()
|
import XMonadContrib.FindEmptyWorkspace ()
|
||||||
import XMonadContrib.FlexibleResize ()
|
import XMonadContrib.FlexibleResize ()
|
||||||
import XMonadContrib.FlexibleManipulate ()
|
import XMonadContrib.FlexibleManipulate ()
|
||||||
@@ -75,3 +76,4 @@ import XMonadContrib.XPropManage ()
|
|||||||
import XMonadContrib.Warp ()
|
import XMonadContrib.Warp ()
|
||||||
import XMonadContrib.WindowNavigation ()
|
import XMonadContrib.WindowNavigation ()
|
||||||
import XMonadContrib.WorkspaceDir ()
|
import XMonadContrib.WorkspaceDir ()
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user