let clients track their urgency, per ICCCM

This removes the dependency on redoLayout -- now WithUrgencyHook defines handleMess only.
This commit is contained in:
Devin Mullins 2007-11-11 02:12:41 +00:00
parent 92490057b4
commit 4835a3be3f

View File

@ -38,9 +38,9 @@ import XMonad.Util.NamedWindows (getName)
import Control.Monad (when) import Control.Monad (when)
import Control.Monad.Reader (asks) import Control.Monad.Reader (asks)
import Control.Monad.State (gets) import Control.Monad.State (gets)
import Data.Bits (testBit, clearBit) import Data.Bits (testBit)
import Data.IORef import Data.IORef
import Data.List ((\\), delete) import Data.List (delete)
import Data.Maybe (listToMaybe) import Data.Maybe (listToMaybe)
import qualified Data.Set as S import qualified Data.Set as S
import Graphics.X11.Xlib import Graphics.X11.Xlib
@ -96,22 +96,20 @@ instance UrgencyHook h Window => LayoutModifier (WithUrgencyHook h) Window where
handleMess (WithUrgencyHook theHook) mess handleMess (WithUrgencyHook theHook) mess
| Just PropertyEvent { ev_event_type = t, ev_atom = a, ev_window = w } <- fromMessage mess = do | Just PropertyEvent { ev_event_type = t, ev_atom = a, ev_window = w } <- fromMessage mess = do
when (t == propertyNotify && a == wM_HINTS) $ withDisplay $ \dpy -> do when (t == propertyNotify && a == wM_HINTS) $ withDisplay $ \dpy -> do
wmh@WMHints { wmh_flags = flags } <- io $ getWMHints dpy w WMHints { wmh_flags = flags } <- io $ getWMHints dpy w
when (testBit flags urgencyHintBit) $ do if (testBit flags urgencyHintBit)
then do
-- Note: Broken clients, such as Xchat2, will set the urgency flag multiple
-- times (perhaps in an effort to get the task bar to "flash"). If this
-- bothers you, please submit a bug report.
userCode $ urgencyHook theHook w userCode $ urgencyHook theHook w
-- Clear the urgency bit in the WMHints flags field. According to the
-- Xlib manual, the *client* is supposed to clear this flag when the urgency
-- has been resolved, but, Xchat2, for example, sets the WMHints several
-- times (e.g. causing the dzen to blink) unless it's cleared. XMonad is
-- not a typical WM, so we're just breaking one more rule, here.
io $ setWMHints dpy w wmh { wmh_flags = clearBit flags urgencyHintBit }
adjustUrgents (\ws -> if elem w ws then ws else w : ws) adjustUrgents (\ws -> if elem w ws then ws else w : ws)
-- Call logHook after IORef has been modified. else
userCode =<< asks (logHook . config) -- Remove window from urgents list when client removes urgency status.
-- Doing the setWMHints triggers another propertyNotify with the bit -- The client should do this, e.g., when it receives focus.
-- cleared, so we ignore that message. This has the potentially wrong adjustUrgents (delete w)
-- effect of ignoring *all* urgency-clearing messages, some of which might -- Call logHook after IORef has been modified.
-- be legitimate. Let's wait for bug reports on that, though. userCode =<< asks (logHook . config)
return Nothing return Nothing
| Just DestroyWindowEvent {ev_window = w} <- fromMessage mess = do | Just DestroyWindowEvent {ev_window = w} <- fromMessage mess = do
adjustUrgents (delete w) adjustUrgents (delete w)
@ -119,12 +117,6 @@ instance UrgencyHook h Window => LayoutModifier (WithUrgencyHook h) Window where
| otherwise = | otherwise =
return Nothing return Nothing
-- Clear the urgency bit and remove from the urgent list when the window becomes visible.
redoLayout _ _ _ windowRects = do
visibles <- gets mapped
adjustUrgents (\\ (S.toList visibles))
return (windowRects, Nothing)
adjustUrgents :: ([Window] -> [Window]) -> X () adjustUrgents :: ([Window] -> [Window]) -> X ()
adjustUrgents f = io $ modifyIORef urgents f adjustUrgents f = io $ modifyIORef urgents f