-
-
Notifications
You must be signed in to change notification settings - Fork 7
/
DoNotDisturb.hs
83 lines (71 loc) · 2.66 KB
/
DoNotDisturb.hs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
-- |
-- Module : XMonad.Actions.DoNotDisturb
-- Copyright : (c) 2021 Tomáš Janoušek <tomi@nomi.cz>
-- License : BSD3
--
-- Maintainer : Tomáš Janoušek <tomi@nomi.cz>
-- Stability : experimental
-- Portability : unknown
--
-- Helpers and hooks for blocking of distractions and procrastination at the
-- window manager level.
--
module XMonad.Actions.DoNotDisturb (
-- * DoNotDisturb toggle
DoNotDisturb(..),
getDoNotDisturb,
setDoNotDisturb,
toggleDoNotDisturb,
-- * Deferring urgency
deferUrgencyHook,
replayDeferredUrgents,
isDND,
) where
import XMonad
import qualified XMonad.StackSet as W
import XMonad.Hooks.UrgencyHook
import qualified XMonad.Util.ExtensibleState as XS
data DoNotDisturb = Disturb | DoNotDisturb
deriving (Eq, Read, Show)
instance ExtensionClass DoNotDisturb where
initialValue = Disturb
extensionType = PersistentExtension
-- | Get the current state of 'DoNotDisturb'.
--
-- Useful wherever disturbing behaviour needs to be disabled, for example in
-- 'logHook' to disable highlighting urgent workspaces/windows.
getDoNotDisturb :: X DoNotDisturb
getDoNotDisturb = XS.get
-- | Set 'DoNotDisturb' state and refresh if necessary.
setDoNotDisturb :: DoNotDisturb -> X ()
setDoNotDisturb dnd = whenX (XS.modified (const dnd)) refresh
-- | Toggle 'DoNotDisturb' state and refresh.
toggleDoNotDisturb :: X ()
toggleDoNotDisturb = setDoNotDisturb . toggle =<< getDoNotDisturb
where toggle Disturb = DoNotDisturb; toggle DoNotDisturb = Disturb
data DeferredUrgents = DeferredUrgents{ fromDeferredUrgents :: [Window] }
deriving (Read, Show)
instance ExtensionClass DeferredUrgents where
initialValue = DeferredUrgents []
extensionType = PersistentExtension
-- | Mark windows whose urgency was deferred as urgent now.
replayDeferredUrgents :: X ()
replayDeferredUrgents = withWindowSet $ \ws -> do
urgents <- XS.gets fromDeferredUrgents
XS.put $ DeferredUrgents []
mapM_ askUrgent $ filter (`W.member` ws) urgents
-- | 'UrgencyHook' that defers marking the window urgent until
-- 'replayDeferredUrgents' (done in 'setDoNotDisturb' 'Disturb').
-- Use as an argument to 'withUrgencyHook' or 'withUrgencyHookC'.
--
-- Example to defer urgents on workspace 1 when DND:
--
-- > deferUrgencyHook $ isDND <&&> windowTag =? Just "1"
deferUrgencyHook :: Query Bool -> Window -> X ()
deferUrgencyHook q w = whenX (runQuery q w) $ do
let ins ws = if elem w ws then ws else w : ws
XS.modify (DeferredUrgents . ins . fromDeferredUrgents)
clearUrgents' [w]
-- | 'Query' for 'deferUrgencyHook', True if 'DoNotDisturb' is on.
isDND :: Query Bool
isDND = liftX getDoNotDisturb =? DoNotDisturb