mirror of
https://github.com/xmonad/xmonad-contrib.git
synced 2025-05-19 03:20:21 -07:00
Merge pull request #886 from liskin/steam-fixes
Fixes/workarounds for Steam client menus/flickering
This commit is contained in:
commit
700507fcd0
18
CHANGES.md
18
CHANGES.md
@ -22,11 +22,18 @@
|
|||||||
|
|
||||||
### New Modules
|
### New Modules
|
||||||
|
|
||||||
* `XMonad.Actions.Profiles`.
|
* `XMonad.Actions.Profiles`
|
||||||
|
|
||||||
- Group workspaces by similarity. Useful when one has lots
|
- Group workspaces by similarity. Useful when one has lots
|
||||||
of workspaces and uses only a couple per unit of work.
|
of workspaces and uses only a couple per unit of work.
|
||||||
|
|
||||||
|
* `XMonad.Hooks.FloatConfigureReq`
|
||||||
|
|
||||||
|
- Customize handling of floating windows' move/resize/restack requests
|
||||||
|
(ConfigureRequest). Useful as a workaround for some misbehaving client
|
||||||
|
applications (Steam, rxvt-unicode, anything that tries to restore
|
||||||
|
absolute position of floats).
|
||||||
|
|
||||||
### Bug Fixes and Minor Changes
|
### Bug Fixes and Minor Changes
|
||||||
|
|
||||||
* Fix build-with-cabal.sh when XDG_CONFIG_HOME is defined.
|
* Fix build-with-cabal.sh when XDG_CONFIG_HOME is defined.
|
||||||
@ -49,6 +56,15 @@
|
|||||||
- The history file is not extraneously read and written anymore if
|
- The history file is not extraneously read and written anymore if
|
||||||
the `historySize` is set to 0.
|
the `historySize` is set to 0.
|
||||||
|
|
||||||
|
* `XMonad.Hooks.EwmhDesktops`
|
||||||
|
|
||||||
|
- Requests for unmanaged windows no longer cause a refresh. This avoids
|
||||||
|
flicker and also fixes disappearing menus in the Steam client and
|
||||||
|
possibly a few other client applications.
|
||||||
|
|
||||||
|
(See also `XMonad.Hooks.FloatConfigureReq` and/or `XMonad.Util.Hacks`
|
||||||
|
for additional Steam client workarounds.)
|
||||||
|
|
||||||
### Other changes
|
### Other changes
|
||||||
|
|
||||||
## 0.18.0 (February 3, 2024)
|
## 0.18.0 (February 3, 2024)
|
||||||
|
@ -459,7 +459,14 @@ ewmhDesktopsEventHook'
|
|||||||
a_aw <- getAtom "_NET_ACTIVE_WINDOW"
|
a_aw <- getAtom "_NET_ACTIVE_WINDOW"
|
||||||
a_cw <- getAtom "_NET_CLOSE_WINDOW"
|
a_cw <- getAtom "_NET_CLOSE_WINDOW"
|
||||||
|
|
||||||
if | mt == a_cd, n : _ <- d, Just ww <- ws !? fi n ->
|
if | mt == a_cw ->
|
||||||
|
killWindow w
|
||||||
|
| not (w `W.member` s) ->
|
||||||
|
-- do nothing for unmanaged windows; it'd be just a useless
|
||||||
|
-- refresh which breaks menus/popups of misbehaving apps that
|
||||||
|
-- send _NET_ACTIVE_WINDOW requests for override-redirect wins
|
||||||
|
mempty
|
||||||
|
| mt == a_cd, n : _ <- d, Just ww <- ws !? fi n ->
|
||||||
if W.currentTag s == W.tag ww then mempty else windows $ W.view (W.tag ww)
|
if W.currentTag s == W.tag ww then mempty else windows $ W.view (W.tag ww)
|
||||||
| mt == a_cd ->
|
| mt == a_cd ->
|
||||||
trace $ "Bad _NET_CURRENT_DESKTOP with data=" ++ show d
|
trace $ "Bad _NET_CURRENT_DESKTOP with data=" ++ show d
|
||||||
@ -473,8 +480,6 @@ ewmhDesktopsEventHook'
|
|||||||
if W.peek s == Just w then mempty else windows $ W.focusWindow w
|
if W.peek s == Just w then mempty else windows $ W.focusWindow w
|
||||||
| mt == a_aw -> do
|
| mt == a_aw -> do
|
||||||
if W.peek s == Just w then mempty else windows . appEndo =<< runQuery activateHook w
|
if W.peek s == Just w then mempty else windows . appEndo =<< runQuery activateHook w
|
||||||
| mt == a_cw ->
|
|
||||||
killWindow w
|
|
||||||
| otherwise ->
|
| otherwise ->
|
||||||
-- The Message is unknown to us, but that is ok, not all are meant
|
-- The Message is unknown to us, but that is ok, not all are meant
|
||||||
-- to be handled by the window manager
|
-- to be handled by the window manager
|
||||||
|
126
XMonad/Hooks/FloatConfigureReq.hs
Normal file
126
XMonad/Hooks/FloatConfigureReq.hs
Normal file
@ -0,0 +1,126 @@
|
|||||||
|
{-# LANGUAGE LambdaCase #-}
|
||||||
|
-- |
|
||||||
|
-- Module : XMonad.Hooks.FloatConfigureReq
|
||||||
|
-- Description : Customize handling of floating windows' move\/resize\/restack requests (ConfigureRequest).
|
||||||
|
-- Copyright : (c) 2024 Tomáš Janoušek <tomi@nomi.cz>
|
||||||
|
-- License : BSD3
|
||||||
|
-- Maintainer : Tomáš Janoušek <tomi@nomi.cz>
|
||||||
|
--
|
||||||
|
-- xmonad normally honours those requests by doing exactly what the client
|
||||||
|
-- application asked, and refreshing. There are some misbehaving clients,
|
||||||
|
-- however, that:
|
||||||
|
--
|
||||||
|
-- * try to move their window to the last known absolute position regardless
|
||||||
|
-- of the current xrandr/xinerama layout
|
||||||
|
--
|
||||||
|
-- * move their window to 0, 0 for no particular reason (e.g. rxvt-unicode)
|
||||||
|
--
|
||||||
|
-- * issue lots of no-op requests causing flickering (e.g. Steam)
|
||||||
|
--
|
||||||
|
-- This module provides a replacement handler for 'ConfigureRequestEvent' to
|
||||||
|
-- work around such misbehaviours.
|
||||||
|
--
|
||||||
|
module XMonad.Hooks.FloatConfigureReq (
|
||||||
|
-- * Usage
|
||||||
|
-- $usage
|
||||||
|
MaybeMaybeManageHook,
|
||||||
|
floatConfReqHook,
|
||||||
|
|
||||||
|
-- * Known workarounds
|
||||||
|
fixSteamFlicker,
|
||||||
|
fixSteamFlickerMMMH,
|
||||||
|
) where
|
||||||
|
|
||||||
|
import qualified Data.Map.Strict as M
|
||||||
|
import XMonad
|
||||||
|
import XMonad.Hooks.ManageHelpers
|
||||||
|
import XMonad.Prelude
|
||||||
|
import qualified XMonad.StackSet as W
|
||||||
|
|
||||||
|
-- $usage
|
||||||
|
-- To use this, include the following in your @xmonad.hs@:
|
||||||
|
--
|
||||||
|
-- > import XMonad.Hooks.FloatConfigureReq
|
||||||
|
-- > import XMonad.Hooks.ManageHelpers
|
||||||
|
--
|
||||||
|
-- > myFloatConfReqHook :: MaybeMaybeManageHook
|
||||||
|
-- > myFloatConfReqHook = composeAll
|
||||||
|
-- > [ … ]
|
||||||
|
--
|
||||||
|
-- > myEventHook :: Event -> X All
|
||||||
|
-- > myEventHook = mconcat
|
||||||
|
-- > [ …
|
||||||
|
-- > , floatConfReqHook myFloatConfReqHook
|
||||||
|
-- > , … ]
|
||||||
|
--
|
||||||
|
-- > main = xmonad $ …
|
||||||
|
-- > $ def{ handleEventHook = myEventHook
|
||||||
|
-- > , … }
|
||||||
|
--
|
||||||
|
-- Then fill the @myFloatConfReqHook@ with whatever custom rules you need.
|
||||||
|
--
|
||||||
|
-- As an example, the following will prevent rxvt-unicode from moving its
|
||||||
|
-- (floating) window to 0, 0 after a font change but still ensure its size
|
||||||
|
-- increment hints are respected:
|
||||||
|
--
|
||||||
|
-- > className =? "URxvt" -?> pure <$> doFloat
|
||||||
|
--
|
||||||
|
-- Another example that avoids flickering and xmonad slowdowns caused by the
|
||||||
|
-- Steam client (completely ignore all its requests, none of which are
|
||||||
|
-- meaningful in the context of a tiling WM):
|
||||||
|
--
|
||||||
|
-- > map toLower `fmap` className =? "steam" -?> mempty
|
||||||
|
--
|
||||||
|
-- (this example is also available as 'fixSteamFlickerMMMH' to be added to
|
||||||
|
-- one's @myFloatConfReqHook@ and also 'fixSteamFlicker' to be added directly
|
||||||
|
-- to one's 'handleEventHook')
|
||||||
|
|
||||||
|
-- | A variant of 'MaybeManageHook' that additionally may or may not make
|
||||||
|
-- changes to the 'WindowSet'.
|
||||||
|
type MaybeMaybeManageHook = Query (Maybe (Maybe (Endo WindowSet)))
|
||||||
|
|
||||||
|
-- | Customizable handler for a 'ConfigureRequestEvent'. If the event's
|
||||||
|
-- 'ev_window' is a managed floating window, the provided
|
||||||
|
-- 'MaybeMaybeManageHook' is consulted and its result interpreted as follows:
|
||||||
|
--
|
||||||
|
-- * @Nothing@ - no match, fall back to the default handler
|
||||||
|
--
|
||||||
|
-- * @Just Nothing@ - match but ignore, no refresh, just send ConfigureNotify
|
||||||
|
--
|
||||||
|
-- * @Just (Just a)@ - match, modify 'WindowSet', refresh, send ConfigureNotify
|
||||||
|
floatConfReqHook :: MaybeMaybeManageHook -> Event -> X All
|
||||||
|
floatConfReqHook mh ConfigureRequestEvent{ev_window = w} =
|
||||||
|
runQuery (join <$> (isFloatQ -?> mh)) w >>= \case
|
||||||
|
Nothing -> mempty
|
||||||
|
Just e -> do
|
||||||
|
whenJust e (windows . appEndo)
|
||||||
|
sendConfEvent
|
||||||
|
pure (All False)
|
||||||
|
where
|
||||||
|
sendConfEvent = withDisplay $ \dpy ->
|
||||||
|
withWindowAttributes dpy w $ \wa -> do
|
||||||
|
io . allocaXEvent $ \ev -> do
|
||||||
|
-- We may have made no changes to the window size/position
|
||||||
|
-- and thus the X server didn't emit any ConfigureNotify,
|
||||||
|
-- so we need to send the ConfigureNotify ourselves to make
|
||||||
|
-- sure there is a reply to this ConfigureRequestEvent and the
|
||||||
|
-- window knows we (possibly) ignored its request.
|
||||||
|
setEventType ev configureNotify
|
||||||
|
setConfigureEvent ev w w
|
||||||
|
(wa_x wa) (wa_y wa) (wa_width wa)
|
||||||
|
(wa_height wa) (wa_border_width wa) none (wa_override_redirect wa)
|
||||||
|
sendEvent dpy w False 0 ev
|
||||||
|
floatConfReqHook _ _ = mempty
|
||||||
|
|
||||||
|
-- | A 'Query' to determine if a window is floating.
|
||||||
|
isFloatQ :: Query Bool
|
||||||
|
isFloatQ = ask >>= \w -> liftX . gets $ M.member w . W.floating . windowset
|
||||||
|
|
||||||
|
-- | A pre-packaged 'floatConfReqHook' that fixes flickering of the Steam client by ignoring 'ConfigureRequestEvent's on any of its floating windows.
|
||||||
|
--
|
||||||
|
-- To use this, add 'fixSteamFlicker' to your 'handleEventHook'.
|
||||||
|
fixSteamFlicker :: Event -> X All
|
||||||
|
fixSteamFlicker = floatConfReqHook fixSteamFlickerMMMH
|
||||||
|
|
||||||
|
fixSteamFlickerMMMH :: MaybeMaybeManageHook
|
||||||
|
fixSteamFlickerMMMH = map toLower `fmap` className =? "steam" -?> mempty
|
@ -40,10 +40,14 @@ module XMonad.Util.Hacks (
|
|||||||
trayerPaddingXmobarEventHook,
|
trayerPaddingXmobarEventHook,
|
||||||
trayPaddingXmobarEventHook,
|
trayPaddingXmobarEventHook,
|
||||||
trayPaddingEventHook,
|
trayPaddingEventHook,
|
||||||
|
|
||||||
|
-- * Steam flickering fix
|
||||||
|
fixSteamFlicker,
|
||||||
) where
|
) where
|
||||||
|
|
||||||
|
|
||||||
import XMonad
|
import XMonad
|
||||||
|
import XMonad.Hooks.FloatConfigureReq (fixSteamFlicker)
|
||||||
import XMonad.Hooks.StatusBar (xmonadPropLog')
|
import XMonad.Hooks.StatusBar (xmonadPropLog')
|
||||||
import XMonad.Prelude (All (All), fi, filterM, when)
|
import XMonad.Prelude (All (All), fi, filterM, when)
|
||||||
import System.Posix.Env (putEnv)
|
import System.Posix.Env (putEnv)
|
||||||
|
@ -192,6 +192,7 @@ library
|
|||||||
XMonad.Hooks.EwmhDesktops
|
XMonad.Hooks.EwmhDesktops
|
||||||
XMonad.Hooks.FadeInactive
|
XMonad.Hooks.FadeInactive
|
||||||
XMonad.Hooks.FadeWindows
|
XMonad.Hooks.FadeWindows
|
||||||
|
XMonad.Hooks.FloatConfigureReq
|
||||||
XMonad.Hooks.FloatNext
|
XMonad.Hooks.FloatNext
|
||||||
XMonad.Hooks.Focus
|
XMonad.Hooks.Focus
|
||||||
XMonad.Hooks.InsertPosition
|
XMonad.Hooks.InsertPosition
|
||||||
|
Loading…
x
Reference in New Issue
Block a user