X.H.Rescreen: Port to ExtensibleConf

This commit is contained in:
Tomas Janousek
2021-05-17 16:51:09 +01:00
parent 280964b9f5
commit 4a6f21604f

View File

@@ -13,9 +13,9 @@ module XMonad.Hooks.Rescreen (
-- * Usage -- * Usage
-- $usage -- $usage
RescreenConfig(..), RescreenConfig(..),
addAfterRescreenHook,
addRandrChangeHook,
rescreenHook, rescreenHook,
rescreenStartupHook,
rescreenEventHook,
) where ) where
import Control.Monad (void) import Control.Monad (void)
@@ -23,6 +23,7 @@ import Data.Monoid (All(..))
import Graphics.X11.Xrandr import Graphics.X11.Xrandr
import XMonad import XMonad
import qualified XMonad.Util.ExtensibleConf as XC
-- $usage -- $usage
-- This module provides a replacement for the screen configuration change -- This module provides a replacement for the screen configuration change
@@ -64,6 +65,12 @@ instance Default RescreenConfig where
, randrChangeHook = mempty , randrChangeHook = mempty
} }
instance Semigroup RescreenConfig where
RescreenConfig arh rch <> RescreenConfig arh' rch' = RescreenConfig (arh <> arh') (rch <> rch')
instance Monoid RescreenConfig where
mempty = def
-- | Attach custom hooks to screen (xrandr) configuration change events. -- | Attach custom hooks to screen (xrandr) configuration change events.
-- Replaces the built-in rescreen handling of xmonad core with: -- Replaces the built-in rescreen handling of xmonad core with:
-- --
@@ -79,11 +86,23 @@ instance Default RescreenConfig where
-- --
-- 'randrChangeHook' may be used to automatically trigger xrandr (or perhaps -- 'randrChangeHook' may be used to automatically trigger xrandr (or perhaps
-- autorandr) when outputs are (dis)connected. -- autorandr) when outputs are (dis)connected.
--
-- Note that 'rescreenHook' is safe to use several times, 'rescreen' is still
-- done just once and hooks are invoked in sequence, also just once.
rescreenHook :: RescreenConfig -> XConfig a -> XConfig a rescreenHook :: RescreenConfig -> XConfig a -> XConfig a
rescreenHook cfg xConfig = rescreenHook = flip XC.once rescreenHook'
xConfig{ startupHook = startupHook xConfig <> rescreenStartupHook
, handleEventHook = handleEventHook xConfig <> rescreenEventHook cfg -- | Shortcut for 'rescreenHook'.
} addAfterRescreenHook :: X () -> XConfig a -> XConfig a
addAfterRescreenHook h = rescreenHook def{ afterRescreenHook = h }
-- | Shortcut for 'rescreenHook'.
addRandrChangeHook :: X () -> XConfig a -> XConfig a
addRandrChangeHook h = rescreenHook def{ randrChangeHook = h }
rescreenHook' :: XConfig a -> XConfig a
rescreenHook' c = c{ startupHook = startupHook c <> rescreenStartupHook
, handleEventHook = handleEventHook c <> rescreenEventHook }
-- | Startup hook to listen for @RRScreenChangeNotify@ events. -- | Startup hook to listen for @RRScreenChangeNotify@ events.
rescreenStartupHook :: X () rescreenStartupHook :: X ()
@@ -93,18 +112,18 @@ rescreenStartupHook = do
io $ xrrSelectInput dpy root rrScreenChangeNotifyMask io $ xrrSelectInput dpy root rrScreenChangeNotifyMask
-- | Event hook with custom rescreen/randr hooks. See 'rescreenHook' for more. -- | Event hook with custom rescreen/randr hooks. See 'rescreenHook' for more.
rescreenEventHook :: RescreenConfig -> Event -> X All rescreenEventHook :: Event -> X All
rescreenEventHook cfg e = do rescreenEventHook e = do
shouldHandle <- case e of shouldHandle <- case e of
ConfigureEvent{ ev_window = w } -> isRoot w ConfigureEvent{ ev_window = w } -> isRoot w
RRScreenChangeNotifyEvent{ ev_window = w } -> isRoot w RRScreenChangeNotifyEvent{ ev_window = w } -> isRoot w
_ -> pure False _ -> pure False
if shouldHandle if shouldHandle
then All False <$ handleEvent cfg e then All False <$ handleEvent e
else mempty else mempty
handleEvent :: RescreenConfig -> Event -> X () handleEvent :: Event -> X ()
handleEvent RescreenConfig{..} e = do handleEvent e = XC.with $ \RescreenConfig{..} -> do
-- Xorg emits several events after every change, clear them to prevent -- Xorg emits several events after every change, clear them to prevent
-- triggering the hook multiple times. -- triggering the hook multiple times.
moreConfigureEvents <- clearTypedWindowEvents (ev_window e) configureNotify moreConfigureEvents <- clearTypedWindowEvents (ev_window e) configureNotify