dots/.xmonad/xmonad.hs

310 lines
9.5 KiB
Haskell
Raw Normal View History

2024-03-30 16:15:35 +01:00
-- {{{ Imports
2023-06-04 15:20:52 +02:00
2024-03-30 16:15:35 +01:00
import Control.Monad (liftM2)
2024-12-22 23:58:23 +01:00
import Data.Map qualified as M
2022-12-01 16:21:19 +01:00
import XMonad
import XMonad.Actions.CopyWindow (copyToAll, killAllOtherCopies)
2023-12-30 12:40:00 +01:00
import XMonad.Actions.FloatSnap
2024-12-22 23:58:23 +01:00
import XMonad.Actions.Submap
2022-12-01 16:21:19 +01:00
import XMonad.Hooks.EwmhDesktops
import XMonad.Hooks.ManageDocks
import XMonad.Hooks.ManageHelpers
2024-03-30 16:15:35 +01:00
import XMonad.Hooks.OnPropertyChange (onXPropertyChange)
2022-12-01 16:21:19 +01:00
import XMonad.Hooks.StatusBar
import XMonad.Hooks.StatusBar.PP
2024-03-30 16:50:15 +01:00
import XMonad.Hooks.WindowSwallowing (swallowEventHook)
2023-06-04 15:20:52 +02:00
import XMonad.Layout.CenteredIfSingle
import XMonad.Layout.IndependentScreens
2024-12-22 23:58:23 +01:00
import XMonad.Layout.LayoutHints (hintsEventHook, layoutHints)
2022-12-01 16:21:19 +01:00
import XMonad.Layout.PerScreen
2024-03-30 16:58:57 +01:00
import XMonad.Layout.PerWorkspace
2023-06-04 15:20:52 +02:00
import XMonad.Layout.Renamed
2024-03-30 16:58:57 +01:00
import XMonad.Layout.Spacing
2024-12-22 23:58:23 +01:00
import XMonad.Layout.Tabbed
2022-12-01 16:21:19 +01:00
import XMonad.Layout.ThreeColumns
2024-12-22 23:58:23 +01:00
import XMonad.StackSet qualified as W
2022-12-01 16:21:19 +01:00
import XMonad.Util.EZConfig
2024-12-22 23:58:23 +01:00
import XMonad.Util.Hacks qualified as Hacks
2022-12-01 16:21:19 +01:00
import XMonad.Util.Loggers
import XMonad.Util.Paste
2023-06-04 15:20:52 +02:00
2023-06-02 22:12:39 +02:00
-- }}}
-- Statusbar {{{
2022-09-23 00:46:34 +02:00
2023-06-02 22:21:03 +02:00
pp :: PP
pp =
2022-12-01 16:18:44 +01:00
def
2023-05-04 23:57:30 +02:00
{ ppSep = tertiaryColor " ",
2022-12-01 16:18:44 +01:00
ppCurrent = brackitify,
ppHidden = secondaryColor,
ppHiddenNoWindows = tertiaryColor,
ppUrgent = red . wrap (yellow "!") (yellow "!"),
2023-06-02 22:22:42 +02:00
ppLayout = id,
2022-12-01 16:18:44 +01:00
ppTitle = shorten 80,
ppTitleSanitize = xmobarStrip,
2024-12-23 00:02:20 +01:00
ppOrder = \[workspaces, layout, windows, _] -> [layout],
2022-12-01 16:18:44 +01:00
ppExtras = [logTitles formatFocused formatUnfocused]
2022-10-25 21:11:18 +02:00
}
where
2023-05-04 23:57:30 +02:00
brackitify = wrap "" ""
formatFocused = secondaryColor . ppWindow
2022-10-25 21:11:18 +02:00
formatUnfocused = tertiaryColor . ppWindow
2022-09-24 01:07:06 +02:00
2022-10-25 21:11:18 +02:00
ppWindow = xmobarRaw . (\w -> if null w then "Untitled" else w) . shorten 16
2022-09-24 01:07:06 +02:00
2022-12-01 16:18:44 +01:00
primaryColor = xmobarColor "#000000" ""
secondaryColor = xmobarColor "#333333" ""
tertiaryColor = xmobarColor "#555555" ""
yellow = xmobarColor "#ff0" ""
red = xmobarColor "#ff5555" ""
2022-09-24 01:07:06 +02:00
2023-06-02 22:12:39 +02:00
-- }}}
-- Workspaces & screens {{{
2022-10-25 21:15:15 +02:00
-- Shift to workspace and view workspace
2024-01-03 19:39:15 +01:00
shiftAndView = doF . liftM2 (.) W.greedyView W.shift
2022-09-23 00:46:34 +02:00
2023-06-04 15:00:30 +02:00
-- }}}
-- Hooks {{{
2024-03-30 16:26:32 +01:00
-- startupHook {{{
2023-05-21 18:27:55 +02:00
myStartupHook =
do
2024-12-23 00:02:20 +01:00
spawn "killall -q polybar; parallel ::: 'polybar -r top' 'polybar -r bottom'"
2024-03-30 16:26:32 +01:00
-- }}}
2023-05-21 18:27:55 +02:00
2024-03-30 16:26:32 +01:00
-- manageHook {{{
2023-06-04 14:48:23 +02:00
myManageHook :: ManageHook
2022-12-01 16:21:19 +01:00
myManageHook =
composeAll
2023-06-04 14:48:23 +02:00
[ isDialog --> doCenterFloat,
className =? "Zathura" --> doShift "1_info",
className =? "firefox" --> shiftAndView "1_www",
className =? "firefoxdeveloperedition" --> shiftAndView "1_www",
className =? "Anki" --> shiftAndView "1_etc",
className =? "Obsidian" --> shiftAndView "1_etc",
2022-12-01 16:21:19 +01:00
className =? "Launcher" --> doRectFloat (W.RationalRect 0.05 0.4 0.9 0.5),
2023-06-04 14:48:23 +02:00
className =? "Zettelkasten" --> doRectFloat (W.RationalRect 0.05 0.4 0.9 0.5),
2022-12-01 16:21:19 +01:00
className =? "Calculator" --> doCenterFloat,
className =? "feh" --> doCenterFloat,
2023-06-04 14:48:23 +02:00
-- Center matplotlib and prevent focus stealing
-- className =? "matplotlib" --> doRectFloat (W.RationalRect 0.5 0.5 0.5 0.5),
className =? "matplotlib" --> doCenterFloat,
2023-05-21 18:23:55 +02:00
className =? "Matplotlib" --> doCenterFloat,
className =? "Xournalpp" --> doRectFloat (W.RationalRect 0.5 0.5 0.5 0.5),
2023-06-04 14:48:23 +02:00
className =? "KeePassXC" --> doRectFloat (W.RationalRect 0.1 0.1 0.8 0.8),
className =? "flameshot" --> doRectFloat (W.RationalRect 0.1 0.1 0.8 0.8)
2022-12-01 16:21:19 +01:00
]
2024-03-30 16:26:32 +01:00
-- }}}
2022-09-23 00:46:34 +02:00
2024-03-30 16:26:32 +01:00
-- dynamicManageHook {{{
myDynamicManageHook :: ManageHook
myDynamicManageHook =
composeAll
[
title =? "Zettelkasten — Firefox Developer Edition" --> doShift "1_sh"
]
2024-03-30 16:26:32 +01:00
-- }}}
2024-03-30 16:26:32 +01:00
-- layoutHook {{{
2022-12-01 16:21:19 +01:00
myLayoutHook =
2024-03-30 16:58:57 +01:00
avoidStruts $
smartSpacingWithEdge 4 $
layoutHints $
onWorkspace "1_sh" (Tall nmaster delta 0.8) $
ifWider smallWidth (tWide ||| c3mWide ||| f) t
2022-09-24 01:07:06 +02:00
where
2023-06-04 14:49:51 +02:00
smallWidth = 1920
2024-03-30 16:58:57 +01:00
-- Tall layouts
tWide =
centeredIfSingle 0.62 1 t
t =
named "[]+" $
Tall nmaster delta ratio
-- Column layouts
c3mWide =
centeredIfSingle 0.62 1 c3m
c3m =
named "[|]" $
ThreeColMid nmaster delta ratio
-- Fullscreen layouts
f = named "[+]" Full
-- Modifiers
named n = renamed [Replace n]
2022-09-24 01:07:06 +02:00
nmaster = 1
2024-03-30 16:58:57 +01:00
ratio = 0.62
2022-12-01 16:21:19 +01:00
delta = 4 / 100
2024-03-30 16:26:32 +01:00
-- }}}
2022-09-24 01:07:06 +02:00
2024-03-30 16:26:32 +01:00
-- handleEventHook {{{
2024-03-30 16:21:22 +01:00
myHandleEventHook =
2024-03-30 16:50:15 +01:00
handleEventHook def
-- See window swallowing (https://hackage.haskell.org/package/xmonad-contrib-0.18.0/docs/XMonad-Hooks-WindowSwallowing.html)
<> swallowEventHook (className =? "Alacritty") (return True)
<> onXPropertyChange "WM_NAME" myDynamicManageHook
<> Hacks.windowedFullscreenFixEventHook
<> hintsEventHook
2024-03-30 16:26:32 +01:00
-- }}}
2024-03-30 16:21:22 +01:00
2023-06-04 15:00:30 +02:00
-- }}}
-- Main config {{{
myWorkspaces = [ "sh", "www", "dev", "info", "etc" ]
myWorkspaceKeys = [ "a", "s", "d", "f", "g" ]
mySharedWorkspaces = [ "shared" ]
mySharedWorkspaceKeys = [ "1" ]
2024-03-30 16:17:43 +01:00
-- Use Win key instead of Alt
myModMask = mod4Mask
2023-05-15 14:36:12 +02:00
2022-12-01 16:21:19 +01:00
myConfig =
def
{ terminal = "alacritty",
2024-03-30 16:17:43 +01:00
modMask = myModMask,
2023-06-04 15:20:52 +02:00
workspaces = withScreen 1 myWorkspaces ++ withScreen 2 mySharedWorkspaces,
2022-12-01 16:21:19 +01:00
-- Styling
2023-05-04 23:57:30 +02:00
focusedBorderColor = "#000",
normalBorderColor = "#0000",
2023-05-21 18:25:51 +02:00
borderWidth = 4,
2022-12-01 16:21:19 +01:00
-- Hooks
2023-05-21 18:27:55 +02:00
startupHook = myStartupHook,
2022-12-01 16:21:19 +01:00
manageHook = myManageHook <+> manageHook def,
2024-03-30 16:58:57 +01:00
layoutHook = myLayoutHook,
2024-03-30 16:21:22 +01:00
handleEventHook = myHandleEventHook
2022-12-01 16:21:19 +01:00
}
2023-06-04 15:20:14 +02:00
`removeKeysP` myRemoveKeys
`additionalKeysP` myKeys
`additionalMouseBindings` myMouseBindings
2022-09-24 01:07:06 +02:00
2023-06-04 15:00:30 +02:00
-- }}}
-- Keybindings {{{
2022-09-24 01:07:06 +02:00
-- Keybindings to be added/overridden
2023-06-04 15:20:14 +02:00
myKeys :: [(String, X ())]
myKeys =
[ ("M-<Space> s", unfloatFocusedW),
("M-<Space> <Space>", nextLayout), -- Cycle through layouts
("M-<Space> S-<Space>", defaultLayout), --
("M-<Space> M-<Space>", nextLayout), -- ..fat finger
("M-<Space> M-S-<Space>", defaultLayout), --
("<F8>", spawnKeepassXC),
("M-z", spawnZettelkasten),
("M-p", spawnLauncher),
2024-06-04 13:25:46 +02:00
("M-w", spawnWindowSwitcher),
("M-S-w", spawnWifiMenu),
2022-12-01 16:21:19 +01:00
("<Insert>", pasteSelection),
2023-06-04 15:20:14 +02:00
("<Print>", printScreen),
("<XF86AudioRaiseVolume>", raiseVol), -- Audio volume & playback
("<XF86AudioLowerVolume>", lowerVol), --
("<XF86AudioMute>", mute), --
("M-<Right>", nextTrack), --
("M-<Left>", prevTrack), --
("M-<Up>", play), --
("M-<Down>", pause), --
("<XF86MonBrightnessUp>", brighten), -- Brightness & hue controls
("<XF86MonBrightnessDown>", dim), --
("S-<XF86MonBrightnessUp>", warm), --
("S-<XF86MonBrightnessDown>", cool), --
("M-S-<XF86MonBrightnessUp>", resetTemp), --
("M-S-<XF86MonBrightnessDown>", resetTemp), --
("M-S-b", fullscreenBrowser),
("<XF86Calculator>", spawnCalculator),
2024-01-28 20:26:46 +01:00
("<XF86PowerOff>", spawn "systemctl suspend"), --TODO: Only enable this on laptop
("M-c", windows copyToAll),
("M-S-c", killAllOtherCopies),
("M-S-<Delete>", kill)
2023-06-04 15:20:14 +02:00
] ++
[ (m ++ k, windows $ f w) |
(m, f) <- zip ["M-", "M-S-"]
[W.greedyView, W.shift],
(k, w) <- zip myWorkspaceKeys
(withScreen 1 myWorkspaces)
2023-06-04 15:20:14 +02:00
++ zip mySharedWorkspaceKeys
(withScreen 2 mySharedWorkspaces)
2022-09-24 01:07:06 +02:00
]
2023-06-02 22:22:42 +02:00
zipKeyPrefixes :: [String] -> [String] -> [String]
zipKeyPrefixes prefixes keys = [prefix ++ key | prefix <- prefixes, key <- keys]
2022-09-24 01:07:06 +02:00
-- Keybindings to be removed
2023-06-04 15:20:14 +02:00
myRemoveKeys :: [String]
myRemoveKeys = "M-S-q" : zipKeyPrefixes ["M-", "M-S-"] (map show [ 1..5 ])
2023-12-30 12:40:00 +01:00
myMouseBindings =
[
((mod4Mask, button1), (\w -> focus w >> mouseMoveWindow w >> afterDrag (snapMagicMove (Just 50) (Just 50) w)))
, ((mod4Mask .|. shiftMask, button1), (\w -> focus w >> mouseMoveWindow w >> afterDrag (snapMagicResize [L,R,U,D] (Just 50) (Just 50) w)))
, ((mod4Mask, button3), (\w -> focus w >> mouseResizeWindow w >> afterDrag (snapMagicResize [R,D] (Just 50) (Just 50) w)))
]
2023-06-04 15:20:14 +02:00
unfloatFocusedW :: X ()
unfloatFocusedW = withFocused $ windows . W.sink
myStartupHook :: X ()
nextLayout = sendMessage NextLayout
defaultLayout :: X ()
defaultLayout = setLayout $ Layout myLayoutHook
spawnZettelkasten :: X ()
spawnZettelkasten = spawn "alacritty --class Zettelkasten,Zettelkasten -e nvim $(cat ~/.zk/current-zettel.txt)"
spawnKeepassXC :: X ()
spawnKeepassXC = spawn "keepassxc"
fullscreenBrowser :: X ()
fullscreenBrowser = spawn "firefox --fullscreen"
2024-06-04 13:25:46 +02:00
spawnWindowSwitcher = spawn "rofi -show window -show-icons"
spawnWifiMenu = spawn "rofi -show wifi -modi \"wifi:iwdrofimenu\""
2024-01-28 20:27:45 +01:00
spawnLauncher, spawnClipManager, spawnCalculator :: X ()
spawnLauncher = spawn "rofi -show drun -show-icons"
spawnClipManager = spawn "rofi -modi 'clipboard:greenclip print' -show clipboard -run-command '{cmd}'"
2023-06-04 15:20:14 +02:00
spawnCalculator = spawn "alacritty --class 'Calculator' -e ipython -i /home/h/.bin/calc.py"
printScreen :: X ()
printScreen = spawn "flameshot gui"
raiseVol, lowerVol, mute :: X ()
raiseVol = spawn "pactl set-sink-volume @DEFAULT_SINK@ +5%"
lowerVol = spawn "pactl set-sink-volume @DEFAULT_SINK@ -5%"
mute = spawn "pactl set-sink-mute @DEFAULT_SINK@ toggle"
nextTrack, prevTrack, play, pause :: X ()
nextTrack = spawn "playerctl next"
prevTrack = spawn "playerctl previous"
play = spawn "playerctl play"
pause = spawn "playerctl pause"
brighten, dim, warm, cool, resetTemp :: X ()
brighten = spawn "brightnessctl set 20+"
dim = spawn "brightnessctl set 20-"
2023-11-21 13:57:28 +01:00
warm = spawn "screen-temperature +50"
cool = spawn "screen-temperature -50"
2023-09-12 12:45:01 +02:00
resetTemp = spawn "screen-temperature 3000"
2022-09-24 01:07:06 +02:00
2023-06-04 15:00:30 +02:00
-- }}}
-- Main {{{
2023-06-04 15:20:52 +02:00
main :: IO ()
2023-11-18 17:35:16 +01:00
main =
2024-12-23 00:02:20 +01:00
do xmonad
$ ewmh
$ withEasySB
(statusBarProp "polybar" $ pure pp)
defToggleStrutsKey
myConfig
2023-06-04 15:00:30 +02:00
-- }}}