Keep the games workspace on the HDMI screen
Wine games lose the mouse when their window moves between screens. safeView replaces greedyView for mod-N, xmobar clicks and mpv so workspace 3 always opens on screen 0 and is never swapped away; safeRescreen keeps a hidden workspace 3 off the laptop screen when screens change.
This commit is contained in:
@@ -4,6 +4,7 @@ import Data.Monoid
|
|||||||
import Graphics.X11.ExtraTypes.XF86
|
import Graphics.X11.ExtraTypes.XF86
|
||||||
import Control.Monad (forM_, liftM2, when)
|
import Control.Monad (forM_, liftM2, when)
|
||||||
import XMonad
|
import XMonad
|
||||||
|
import XMonad.Actions.OnScreen (greedyViewOnScreen)
|
||||||
import XMonad.Actions.PhysicalScreens
|
import XMonad.Actions.PhysicalScreens
|
||||||
import XMonad.Hooks.EwmhDesktops
|
import XMonad.Hooks.EwmhDesktops
|
||||||
import XMonad.Hooks.ManageDocks
|
import XMonad.Hooks.ManageDocks
|
||||||
@@ -34,10 +35,10 @@ main :: IO ()
|
|||||||
main =
|
main =
|
||||||
xmonad
|
xmonad
|
||||||
. ewmhFullscreen
|
. ewmhFullscreen
|
||||||
. setEwmhSwitchDesktopHook W.greedyView
|
. setEwmhSwitchDesktopHook safeView
|
||||||
. ewmh
|
. ewmh
|
||||||
. docks
|
. docks
|
||||||
. addAfterRescreenHook restartStatusBars
|
. rescreenHook def {afterRescreenHook = restartStatusBars, rescreenWorkspacesHook = Last (Just safeRescreen)}
|
||||||
. addRandrChangeHook (spawn myScreenHotplug)
|
. addRandrChangeHook (spawn myScreenHotplug)
|
||||||
$ myConfig
|
$ myConfig
|
||||||
|
|
||||||
@@ -145,6 +146,32 @@ myConfig =
|
|||||||
| (key, sc) <- zip [xK_w, xK_e] [0 ..],
|
| (key, sc) <- zip [xK_w, xK_e] [0 ..],
|
||||||
(f, mask) <- [(viewScreen def, 0), (sendToScreen def, shiftMask)]
|
(f, mask) <- [(viewScreen def, 0), (sendToScreen def, shiftMask)]
|
||||||
]
|
]
|
||||||
|
++ [((myModMask, key), windows $ safeView ws) | (ws, key) <- zip myWorkspaces [xK_1 .. xK_9]]
|
||||||
|
|
||||||
|
-- greedyView that keeps wsGames on screen 0 (HDMI): Wine games lose the mouse when moved between screens
|
||||||
|
safeView :: WorkspaceId -> WindowSet -> WindowSet
|
||||||
|
safeView i ws
|
||||||
|
| i == wsGames = greedyViewOnScreen 0 i ws
|
||||||
|
| W.currentTag ws == wsGames && i `elem` map (W.tag . W.workspace) (W.visible ws) = W.view i ws
|
||||||
|
| otherwise = W.greedyView i ws
|
||||||
|
|
||||||
|
-- xmonad's rescreen, except that a hidden wsGames is never put on a secondary screen
|
||||||
|
safeRescreen :: X ()
|
||||||
|
safeRescreen = do
|
||||||
|
screens <- withDisplay getCleanedScreenInfo
|
||||||
|
case screens of
|
||||||
|
[] -> return ()
|
||||||
|
xinesc : xinescs ->
|
||||||
|
windows $ \ws ->
|
||||||
|
let notGames = (/= wsGames) . W.tag
|
||||||
|
pool = map W.workspace (W.visible ws) ++ filter notGames (W.hidden ws)
|
||||||
|
(xs, _) = splitAt (length xinescs) pool
|
||||||
|
shown = map W.tag (W.workspace (W.current ws) : xs)
|
||||||
|
in ws
|
||||||
|
{ W.current = W.Screen (W.workspace (W.current ws)) 0 (SD xinesc),
|
||||||
|
W.visible = zipWith3 W.Screen xs [1 ..] (map SD xinescs),
|
||||||
|
W.hidden = filter ((`notElem` shown) . W.tag) (map W.workspace (W.visible ws) ++ W.hidden ws)
|
||||||
|
}
|
||||||
|
|
||||||
-- Workspaces
|
-- Workspaces
|
||||||
myWorkspaces :: [String]
|
myWorkspaces :: [String]
|
||||||
@@ -291,7 +318,7 @@ myManageHook =
|
|||||||
isFullscreen --> doFullFloat
|
isFullscreen --> doFullFloat
|
||||||
]
|
]
|
||||||
<+> namedScratchpadManageHook myScratchpads
|
<+> namedScratchpadManageHook myScratchpads
|
||||||
where viewShift = doF . liftM2 (.) W.greedyView W.shift
|
where viewShift = doF . liftM2 (.) safeView W.shift
|
||||||
|
|
||||||
-- Handle event hook
|
-- Handle event hook
|
||||||
myHandleEventHook :: Event -> X All
|
myHandleEventHook :: Event -> X All
|
||||||
|
|||||||
Reference in New Issue
Block a user