X.H.ManageDocks: React to strut updates of override_redirect docks

We only requested PropertyChange events from docks in the `manageDocks`
manageHook, but that only gets called for normal windows, not
override_redirect ones. Therefore, xmobar in its default configuration
wouldn't get its struts refreshed on changes. This resulted in gaps not
updating after xmobar repositions itself on xrandr changes.

If one wanted to handle that repositioning in xmonad, it was possible to
configure xmobar with `overrideRedirect = False`, which is meant for
window managers with proper EWMH stacking order support [1], so in
xmonad it resulted in xmobar covering fullscreen windows. That can be
worked around by adding `checkDock --> doLower` to manageHook, but it
starts to smell of too many workarounds.

[1]: https://specifications.freedesktop.org/wm-spec/wm-spec-1.5.html#STACKINGORDER

The fix is to request PropertyChange events for all windows that we
treat as docks.

Related: https://github.com/xmonad/xmonad-contrib/pull/490
This commit is contained in:
Tomas Janousek
2021-03-23 01:39:34 +00:00
parent 88b9c80618
commit ec14617123
2 changed files with 20 additions and 6 deletions

View File

@@ -343,7 +343,16 @@
- Export `AvoidStruts` constructor
- Restored compatibility with pre-0.13 configs by making the startup hook
unnecessary for correct functioning.
unnecessary for correct functioning (strut cache is initialized on-demand).
- Fixed ignoring of strut updates from override-redirect windows, which is
default for xmobar.
Previously, if one wanted xmobar to reposition itself after xrandr
changes and have xmonad handle that repositioning, one would need to
configure xmobar with `overrideRedirect = False`, which would disable
lowering on start and thus cause other problems. This is no longer
necessary.
* `XMonad.Hooks.ManageHelpers`

View File

@@ -130,17 +130,22 @@ maybeInitStrutCache = maybe (queryDocks >>= foldlM (flip updateStrut) M.empty) p
updateStrut :: Window -> WindowStruts -> X WindowStruts
updateStrut w cache = do
when (w `M.notMember` cache) $ requestDockEvents w
strut <- getStrut w
pure $ M.insert w strut cache
-- | Detects if the given window is of type DOCK and if so, reveals
-- it, but does not manage it.
manageDocks :: ManageHook
manageDocks = checkDock --> (doIgnore <+> setDocksMask)
where setDocksMask = do
ask >>= \win -> liftX $ withDisplay $ \dpy ->
io $ selectInput dpy win (propertyChangeMask .|. structureNotifyMask)
mempty
manageDocks = checkDock --> (doIgnore <+> doRequestDockEvents)
where
doRequestDockEvents = ask >>= liftX . requestDockEvents >> mempty
-- | Request events for a dock window.
-- (Only if not already a client to avoid overriding 'clientMask')
requestDockEvents :: Window -> X ()
requestDockEvents w = whenX (not <$> isClient w) $ withDisplay $ \dpy ->
io $ selectInput dpy w (propertyChangeMask .|. structureNotifyMask)
-- | Checks if a window is a DOCK or DESKTOP window
checkDock :: Query Bool