X.H.EwmhDesktops: Ignore _NET_WM_STATE_FULLSCREEN from unmanaged windows

This prevents an unnecessary refresh.

That refresh would normally be harmless but it does reset the input
focus, which happens to upset some non-conforming clients such as
https://github.com/flameshot-org/flameshot. Flameshot is an interactive
screenshot tool that creates an override-redirect fullscreen window to
let the user select a rectangle to capture and then allows drawing and
adding text and so on, but it unfortunately doesn't follow ICCCM
recommendations:

> If it is necessary for a client to receive keystrokes on an
> override-redirect window, either the client must grab the keyboard, or
> the client must have another top-level window that is not
> override-redirect and that has selected the Locally Active or Globally
> Active focus model.

Instead, it just takes input focus and hopes for the best. And it also
sends an entirely useless _NET_WM_STATE_FULLSCREEN request, which would
trigger a refresh and take that focus away.

This commit works around that by not handling that useless
_NET_WM_STATE_FULLSCREEN for unmanaged windows and thus preventing that
refresh. It's just a workaround, however: if a legitimate refresh is
necessary at any point, the focus _will_ be taken away.

Fixes: https://github.com/xmonad/xmonad-contrib/issues/550
Fixes: https://github.com/flameshot-org/flameshot/issues/773
This commit is contained in:
Tomas Janousek 2021-05-28 15:13:09 +01:00
parent 37fc86c5c4
commit fde7f4f8b0

View File

@ -307,6 +307,7 @@ fullscreenStartup = setFullscreenSupported
-- Note this is not included in 'ewmh'. -- Note this is not included in 'ewmh'.
fullscreenEventHook :: Event -> X All fullscreenEventHook :: Event -> X All
fullscreenEventHook (ClientMessageEvent _ _ _ dpy win typ (action:dats)) = do fullscreenEventHook (ClientMessageEvent _ _ _ dpy win typ (action:dats)) = do
managed <- isClient win
wmstate <- getAtom "_NET_WM_STATE" wmstate <- getAtom "_NET_WM_STATE"
fullsc <- getAtom "_NET_WM_STATE_FULLSCREEN" fullsc <- getAtom "_NET_WM_STATE_FULLSCREEN"
wstate <- fromMaybe [] <$> getProp32 wmstate win wstate <- fromMaybe [] <$> getProp32 wmstate win
@ -319,7 +320,7 @@ fullscreenEventHook (ClientMessageEvent _ _ _ dpy win typ (action:dats)) = do
toggle = 2 toggle = 2
chWstate f = io $ changeProperty32 dpy win wmstate aTOM propModeReplace (f wstate) chWstate f = io $ changeProperty32 dpy win wmstate aTOM propModeReplace (f wstate)
when (typ == wmstate && fi fullsc `elem` dats) $ do when (managed && typ == wmstate && fi fullsc `elem` dats) $ do
when (action == add || (action == toggle && not isFull)) $ do when (action == add || (action == toggle && not isFull)) $ do
chWstate (fi fullsc:) chWstate (fi fullsc:)
windows $ W.float win $ W.RationalRect 0 0 1 1 windows $ W.float win $ W.RationalRect 0 0 1 1