Add multimonitor support in a good way

This commit is contained in:
Leon Kowarschick 2020-05-09 15:24:23 +02:00
parent f92fc0173c
commit 3b03a5c324
8 changed files with 128 additions and 92 deletions

View file

@ -1,5 +1,8 @@
*.background: #282828 *.background: #282828
Xcursor.size: 16
Xcursor.theme: capitaine-cursors-light
rofi.lines: 5 rofi.lines: 5
rofi.eh: 2 rofi.eh: 2
rofi.padding: 200 rofi.padding: 200

View file

@ -1,4 +1,4 @@
{ {
"optOut": false, "optOut": false,
"lastUpdateCheck": 1588770448547 "lastUpdateCheck": 1588866305414
} }

View file

@ -65,7 +65,7 @@ inactive-opacity-override = false;
# Blur background of transparent windows. Bad performance with X Render backend. GLX backend is preferred. # Blur background of transparent windows. Bad performance with X Render backend. GLX backend is preferred.
blur-background = false; blur-background = false;
blur-method = "dual_kawase"; #blur-method = "dual_kawase";
#blur-method = "kernel"; #blur-method = "kernel";
blur-strength = 10; # max 20 blur-strength = 10; # max 20
blur-size = 20; blur-size = 20;

View file

@ -170,8 +170,10 @@ label = "%{F#444} %{F-}%{B#444} %time% | %date% %{B-}%{F#444} %{
[module/xmonad] [module/xmonad]
type = custom/script type = custom/script
exec = xmonad-log ;exec = "xmonad-log"
exec = '/home/leon/.config/polybar/polybar-scripts/xmonad-status.sh'
tail = true tail = true
;interval = 1
[module/timerDisplay] [module/timerDisplay]

View file

@ -0,0 +1,17 @@
#!/bin/bash
if [ "$MONITOR" = "HDMI-A-0" ]; then
while true; do
tail -F /tmp/xmonad-state-bar0
done
else
while true; do
tail -F /tmp/xmonad-state-bar1
done
fi
#while true; do
#if read -r line </tmp/.xmonad-state-bar0; then
#echo "$line"
#fi
#done

View file

@ -4,21 +4,23 @@
module Config (main) where module Config (main) where
import Control.Concurrent
import Control.Exception ( catch
, SomeException
)
import Data.Char (isDigit) import Data.Char (isDigit)
import Data.List (isSuffixOf, isPrefixOf) import Data.List ( isSuffixOf , isPrefixOf)
import System.Exit (exitSuccess) import System.Exit (exitSuccess)
import qualified Rofi import qualified Rofi
import qualified Codec.Binary.UTF8.String as UTF8
import qualified DBus as D
import qualified DBus.Client as D
import qualified Data.Map as M import qualified Data.Map as M
import qualified Data.Monoid import qualified Data.Monoid
import Data.Foldable ( for_ )
import qualified System.IO as SysIO import qualified System.IO as SysIO
import XMonad.Layout.HintedGrid import XMonad.Layout.HintedGrid
import XMonad.Layout.TwoPanePersistent
import XMonad hiding ((|||)) import XMonad hiding ((|||))
import XMonad.Actions.Commands import XMonad.Actions.Commands
@ -26,7 +28,6 @@ import XMonad.Actions.CopyWindow
import XMonad.Actions.Submap import XMonad.Actions.Submap
import XMonad.Config.Desktop import XMonad.Config.Desktop
import XMonad.Hooks.DynamicLog import XMonad.Hooks.DynamicLog
import XMonad.Hooks.FadeInactive
import XMonad.Hooks.ManageDocks import XMonad.Hooks.ManageDocks
import XMonad.Hooks.SetWMName (setWMName) import XMonad.Hooks.SetWMName (setWMName)
import XMonad.Layout.BinarySpacePartition import XMonad.Layout.BinarySpacePartition
@ -39,10 +40,9 @@ import XMonad.Layout.NoBorders
import XMonad.Layout.Renamed (renamed, Rename(Replace)) import XMonad.Layout.Renamed (renamed, Rename(Replace))
import XMonad.Layout.ResizableTile import XMonad.Layout.ResizableTile
import XMonad.Layout.Spacing (spacingRaw, Border(..), toggleWindowSpacingEnabled) import XMonad.Layout.Spacing (spacingRaw, Border(..), toggleWindowSpacingEnabled)
import XMonad.Layout.Spiral (spiral)
import XMonad.Layout.ToggleLayouts import XMonad.Layout.ToggleLayouts
import XMonad.Layout.ZoomRow import XMonad.Layout.ZoomRow
import XMonad.Util.EZConfig (additionalKeysP, removeKeysP, checkKeymap) import XMonad.Util.EZConfig (additionalKeysP, removeKeysP)
import XMonad.Util.NamedScratchpad import XMonad.Util.NamedScratchpad
import XMonad.Util.Run import XMonad.Util.Run
import XMonad.Util.SpawnOnce (spawnOnce) import XMonad.Util.SpawnOnce (spawnOnce)
@ -50,6 +50,7 @@ import qualified XMonad.Actions.Navigation2D as Nav2d
import qualified XMonad.Hooks.EwmhDesktops as Ewmh import qualified XMonad.Hooks.EwmhDesktops as Ewmh
import qualified XMonad.Hooks.ManageHelpers as ManageHelpers import qualified XMonad.Hooks.ManageHelpers as ManageHelpers
import qualified XMonad.Layout.BoringWindows as BoringWindows import qualified XMonad.Layout.BoringWindows as BoringWindows
import XMonad.Layout.IndependentScreens
import qualified XMonad.StackSet as W import qualified XMonad.StackSet as W
import qualified XMonad.Util.XSelection as XSel import qualified XMonad.Util.XSelection as XSel
@ -133,13 +134,6 @@ myLayout = avoidStruts . BoringWindows.boringWindows . smartBorders . toggleLayo
in spacingRaw True spacingBorder True gapBorder True in spacingRaw True spacingBorder True gapBorder True
-- }}}
-- Loghook -------------------------------------- {{{
myLogHook :: X ()
myLogHook = return () -- fadeInactiveLogHook 0.95 -- opacity of unfocused windows
-- }}} -- }}}
-- Startuphook ----------------------------- {{{ -- Startuphook ----------------------------- {{{
@ -153,8 +147,9 @@ myStartupHook = do
spawnOnce "mailspring --background" spawnOnce "mailspring --background"
spawnOnce "redshift -P -O 5000" spawnOnce "redshift -P -O 5000"
spawn "xset r rate 300 50" -- make key repeat quicker spawn "xset r rate 300 50" -- make key repeat quicker
spawn "/home/leon/.screenlayout/dualscreen-landscape.sh"
_ <- liftIO $ Control.Concurrent.threadDelay (1000 * 10)
spawn "/home/leon/.config/polybar/launch.sh" spawn "/home/leon/.config/polybar/launch.sh"
spawn "/home/leon/.screenlayout/dualscreen.sh"
spawn "feh --bg-fill /home/leon/Bilder/wallpapers/mountains_with_clounds.jpg" spawn "feh --bg-fill /home/leon/Bilder/wallpapers/mountains_with_clounds.jpg"
setWMName "LG3D" -- Java stuff hack setWMName "LG3D" -- Java stuff hack
@ -164,7 +159,7 @@ myStartupHook = do
-- Default mappings that need to be removed -- Default mappings that need to be removed
removedKeys :: [String] removedKeys :: [String]
removedKeys = ["M-S-c", "M-S-q", "M-h", "M-l"] removedKeys = ["M-S-c", "M-S-q", "M-h", "M-l"] ++ ["M-" ++ show n | n <- [1..9 :: Int]]
multiMonitorOperation :: (WorkspaceId -> WindowSet -> WindowSet) -> ScreenId -> X () multiMonitorOperation :: (WorkspaceId -> WindowSet -> WindowSet) -> ScreenId -> X ()
multiMonitorOperation operation n = do multiMonitorOperation operation n = do
@ -174,8 +169,9 @@ multiMonitorOperation operation n = do
Nothing -> return () Nothing -> return ()
myKeys :: [(String, X ())] myKeys :: XConfig a -> XConfig a
myKeys = [ ("M-+", sendMessage zoomIn) myKeys c = additionalKeysP c $
[ ("M-+", sendMessage zoomIn)
, ("M--", sendMessage zoomOut) , ("M--", sendMessage zoomOut)
, ("M-#", sendMessage zoomReset) , ("M-#", sendMessage zoomReset)
@ -193,10 +189,10 @@ myKeys = [ ("M-+", sendMessage zoomIn)
, ("<XF86AudioLowerVolume>", spawn "amixer sset Master 5%-") , ("<XF86AudioLowerVolume>", spawn "amixer sset Master 5%-")
-- Multi monitor -- Multi monitor
, ("M-s", multiMonitorOperation W.view 0) , ("M-s", multiMonitorOperation W.view 1)
, ("M-d", multiMonitorOperation W.view 1) , ("M-d", multiMonitorOperation W.view 0)
, ("M-S-s", (multiMonitorOperation W.shift 0) >> multiMonitorOperation W.view 0) , ("M-S-s", (multiMonitorOperation W.shift 1) >> multiMonitorOperation W.view 1)
, ("M-S-d", (multiMonitorOperation W.shift 1) >> multiMonitorOperation W.view 1) , ("M-S-d", (multiMonitorOperation W.shift 0) >> multiMonitorOperation W.view 0)
-- programs -- programs
, ("M-p", spawn myLauncher) , ("M-p", spawn myLauncher)
@ -215,9 +211,13 @@ myKeys = [ ("M-+", sendMessage zoomIn)
] ++ generatedMappings ] ++ generatedMappings
where where
generatedMappings :: [(String, X ())] generatedMappings :: [(String, X ())]
generatedMappings = copyToWorkspaceMappings ++ windowGoMappings ++ windowSwapMappings ++ resizeMappings generatedMappings = windowGoMappings ++ windowSwapMappings ++ resizeMappings ++ workspaceMappings
where where
copyToWorkspaceMappings = [ ("M-C-" ++ wsp, windows $ copy wsp) | wsp <- map show [1..9 :: Int] ] workspaceMappings =
[ (mappingPrefix ++ show wspNum, windows $ onCurrentScreen action wsp)
| (wsp, wspNum) <- zip (workspaces' c) [1..9 :: Int]
, (mappingPrefix, action) <- [("M-", W.greedyView), ("M-S-", W.shift), ("M-C-", copy)]
]
keyDirPairs = [("h", L), ("j", D), ("k", U), ("l", R)] keyDirPairs = [("h", L), ("j", D), ("k", U), ("l", R)]
@ -230,6 +230,9 @@ myKeys = [ ("M-+", sendMessage zoomIn)
, ("M-C-l", ifLayoutIs "BSP" (sendMessage $ ExpandTowards R) (ifLayoutIs "Horizon" (sendMessage ExpandSlave) (sendMessage Expand))) , ("M-C-l", ifLayoutIs "BSP" (sendMessage $ ExpandTowards R) (ifLayoutIs "Horizon" (sendMessage ExpandSlave) (sendMessage Expand)))
] ]
toggleFullscreen :: X () toggleFullscreen :: X ()
toggleFullscreen = do toggleFullscreen = do
sendMessage ToggleLayout -- toggle fullscreen layout sendMessage ToggleLayout -- toggle fullscreen layout
@ -307,29 +310,35 @@ myManageHook = composeAll
-- Main ------------------------------------ {{{ -- Main ------------------------------------ {{{
main :: IO () main :: IO ()
main = do main = do
dbus <- D.connectSession currentScreenCount :: Int <- countScreens
-- Request access to the DBus name let monitorIndices = [0..currentScreenCount - 1]
_ <- D.requestName dbus (D.busName_ "org.xmonad.Log")
[D.nameAllowReplacement, D.nameReplaceExisting, D.nameDoNotQueue]
-- $ ewmh (kills IntelliJ) -- create a fifo named pipe for every monitor (called /tmp/xmonad-state-bar0, etc)
xmonad for_ monitorIndices (\idx -> safeSpawn "mkfifo" ["/tmp/xmonad-state-bar" ++ show idx])
$ Ewmh.ewmh
$ Nav2d.withNavigation2DConfig def { Nav2d.defaultTiledNavigation = Nav2d.sideNavigation }
$ myConfig dbus
myConfig dbus = desktopConfig -- create polybarLogHooks for every monitor and combine them using the <+> monoid instance
let polybarLogHooks = foldMap (polybarLogHook . fromIntegral) monitorIndices
let myConfig = myKeys (desktopConfig
{ terminal = myTerminal { terminal = myTerminal
, workspaces = withScreens (fromIntegral currentScreenCount) (map show [1..9 :: Int])
, modMask = myModMask , modMask = myModMask
, borderWidth = 2 , borderWidth = 2
, layoutHook = myLayout , layoutHook = myLayout
, logHook = myLogHook <+> dynamicLogWithPP (polybarPP dbus) <+> logHook def , logHook = polybarLogHook 0 <+> polybarLogHook 1 <+> logHook def
, startupHook = myStartupHook <+> startupHook def <+> return () >> checkKeymap (myConfig dbus ) myKeys , startupHook = myStartupHook <+> startupHook def -- <+> return () >> checkKeymap myConfig (myKeys myConfig)
, manageHook = myManageHook <+> manageHook def , manageHook = myManageHook <+> manageHook def
, focusedBorderColor = aqua , focusedBorderColor = aqua
, normalBorderColor = "#282828" , normalBorderColor = "#282828"
--, handleEventHook = minimizeEventHook <+> handleEventHook def <+> hintsEventHook -- <+> Ewmh.fullscreenEventHook --, handleEventHook = minimizeEventHook <+> handleEventHook def <+> hintsEventHook -- <+> Ewmh.fullscreenEventHook
} `removeKeysP` removedKeys `additionalKeysP` myKeys } `removeKeysP` removedKeys)
xmonad
$ Ewmh.ewmh
$ Nav2d.withNavigation2DConfig def { Nav2d.defaultTiledNavigation = Nav2d.sideNavigation }
$ myConfig
@ -337,11 +346,19 @@ myConfig dbus = desktopConfig
-- POLYBAR Kram -------------------------------------- {{{ -- POLYBAR Kram -------------------------------------- {{{
-- | Loghook for polybar on a given monitor.
-- Will write the polybar formatted string to /tmp/xmonad-state-bar${monitor}
polybarLogHook :: Int -> X ()
polybarLogHook monitor = do
barOut <- dynamicLogString $ polybarPP monitor
io $ SysIO.appendFile ("/tmp/xmonad-state-bar" ++ show monitor) (barOut ++ "\n")
polybarPP :: D.Client -> PP
polybarPP dbus = namedScratchpadFilterOutWorkspacePP $ def -- swapping namedScratchpadFilterOutWorkspacePP and marshallPP will throw "Prelude.read no Parse" errors..... wtf
{ ppOutput = dbusOutput dbus -- | create a polybar Pretty printer, marshalled for given monitor.
, ppCurrent = withBG bg2 polybarPP :: Int -> PP
polybarPP monitor = namedScratchpadFilterOutWorkspacePP $ marshallPP (fromIntegral monitor) $ def
{ ppCurrent = withBG bg2
, ppVisible = withBG bg2 , ppVisible = withBG bg2
, ppUrgent = withFG red , ppUrgent = withFG red
, ppLayout = removeWord "Minimize" . removeWord "Hinted" . removeWord "Spacing" . withFG purple , ppLayout = removeWord "Minimize" . removeWord "Hinted" . removeWord "Spacing" . withFG purple
@ -349,7 +366,7 @@ polybarPP dbus = namedScratchpadFilterOutWorkspacePP $ def
, ppWsSep = "" , ppWsSep = ""
, ppSep = " | " , ppSep = " | "
, ppExtras = [] , ppExtras = []
, ppTitle = const "" -- withFG aqua . (shorten 40) , ppTitle = withFG aqua . (shorten 40)
} }
where where
removeWord substr = unwords . filter (/= substr) . words removeWord substr = unwords . filter (/= substr) . words
@ -360,21 +377,16 @@ polybarPP dbus = namedScratchpadFilterOutWorkspacePP $ def
| otherwise = wsp | otherwise = wsp
wrapOnClickCmd command = wrap ("%{A1:" ++ command ++ ":}") "%{A}" wrapOnClickCmd command = wrap ("%{A1:" ++ command ++ ":}") "%{A}"
-- Emit a DBus signal on log updates
dbusOutput :: D.Client -> String -> IO ()
dbusOutput dbus str = do
let signal = (D.signal objectPath interfaceName memberName) {
D.signalBody = [D.toVariant $ UTF8.decodeString str]
}
D.emit dbus signal
where
objectPath = D.objectPath_ "/org/xmonad/Log"
interfaceName = D.interfaceName_ "org.xmonad.Log"
memberName = D.memberName_ "Update"
-- }}} -- }}}
-- Utilities --------------------------------------------------- {{{ -- Utilities --------------------------------------------------- {{{
catchAndNotifyAny :: IO () -> IO ()
catchAndNotifyAny ioAction = catch ioAction (\(e :: SomeException) -> safeSpawn "notify-send" ["Xmonad exception", show e])
promptDzenWhileRunning :: String -> [String] -> X () -> X () promptDzenWhileRunning :: String -> [String] -> X () -> X ()
promptDzenWhileRunning promptTitle options action = do promptDzenWhileRunning promptTitle options action = do
handle <- spawnPipe $ "sleep 1 && dzen2 -e onstart=uncollapse -l " ++ lineCount ++ " -fn '" ++ font ++ "'" handle <- spawnPipe $ "sleep 1 && dzen2 -e onstart=uncollapse -l " ++ lineCount ++ " -fn '" ++ font ++ "'"

2
files/scripts/gpuinfo.sh Executable file
View file

@ -0,0 +1,2 @@
#!/bin/dash
sudo cat /sys/kernel/debug/dri/0/amdgpu_pm_info