diff --git a/CLAUDE.md b/CLAUDE.md index 3c0876a..e93c218 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -90,12 +90,18 @@ main = xmonad **Key architectural components:** -- **Navigation2D**: Directional window and screen navigation using arrow keys and Navigation2D module -- **Custom keybindings**: Leader-key approach (`M-a` prefix) for spawning applications and layout switching +- **Modal keybindings**: Uses `XMonad.Hooks.Modal` for organizing keybindings into modes (inspired by i3wm) + - Layout mode (`M-a l`): Unified mode for both layout operations + - `d/m/f` - Jump to layout (exits immediately) + - Arrow keys - Adjust master/slave split (stays in mode, `` to exit) + - Spawn mode (`M-a s`): Launch infrequent applications (exits immediately) + - `t` - Thunar file manager + - `s` - Screenshot tool +- **Leader-key approach**: `M-a` prefix for spawning applications and entering modes - **Window manipulation**: Uses `XMonad.Actions.RotSlaves` for window rotation (mimics wezterm behavior) - **Layout system**: Three layouts - dynamic tiling, maximised, and fullscreen -- **StatusBar integration**: Communicates with xmobar via `_XMONAD_LOG_1` X property -- **Mnemonic bindings**: Control (M-C) for layout manipulation, Shift (M-S) for window operations +- **StatusBar integration**: Communicates with xmobar via `_XMONAD_LOG_1` X property, displays active mode via `logMode` +- **Multimedia keys**: Uses `Graphics.X11.ExtraTypes.XF86` for XF86 multimedia key support (audio controls) ### XMobar Configuration (`src/xmobar.hs`) diff --git a/src/xmonad.hs b/src/xmonad.hs index 03864d7..fa52ec8 100644 --- a/src/xmonad.hs +++ b/src/xmonad.hs @@ -6,12 +6,14 @@ import XMonad.Actions.RotSlaves import XMonad.Hooks.DynamicLog import XMonad.Hooks.EwmhDesktops import XMonad.Hooks.ManageDocks +import XMonad.Hooks.Modal import XMonad.Hooks.StatusBar import XMonad.Layout.NoBorders import XMonad.Layout.Renamed import XMonad.Layout.Spacing import XMonad.StackSet qualified as W import XMonad.Util.EZConfig +import XMonad.Util.Font import XMonad.Util.Loggers import Graphics.X11.ExtraTypes.XF86 @@ -30,6 +32,7 @@ main = xmonad . ewmhFullscreen . ewmh . withSB myXmobar + . modal [layoutMode, spawnMode] $ myConfig myConfig = def @@ -65,23 +68,18 @@ myScrot = "scrot -s '%Y%m%d_%H%M%S.png' -e 'mv $f ~/Pictures/scrots myKeymap = -- - -- LeaderKey + -- Core operations -- - -- spawning programs - [ ("M-a n", spawn myTerminal ) - , ("M-a e", spawn myLauncher ) - , ("M-a t", spawn myFileManager) - , ("M-a s", spawn myScrot ) - - -- toggling layouts - , ("M-a d", sendMessage $ JumpToLayout "dynamic tiling") - , ("M-a m", sendMessage $ JumpToLayout "maximised" ) - , ("M-a f", sendMessage $ JumpToLayout "fullscreen" ) - - -- quit window + -- spawn/kill programs + [ ("M-a n", spawn myTerminal) + , ("M-a e", spawn myLauncher) , ("M-a q", kill) + -- modal modes + , ("M-a l", setMode "layout") + , ("M-a s", setMode "spawn" ) + -- -- Navigation @@ -96,12 +94,12 @@ myKeymap = , ("M-", moveTo Next hiddenWS) -- window rotation - , ("M-S-", rotAllUp) - , ("M-S-", rotAllDown) + , ("M-" , rotAllUp) + , ("M-", rotAllDown) -- focus screens - , ("M-S-", prevScreen) - , ("M-S-", nextScreen) + , ("M-", prevScreen) + , ("M-" , nextScreen) -- switch workspaces , ("M-1", windows $ W.greedyView "code" ) @@ -117,12 +115,6 @@ myKeymap = , ("M-S-4", windows $ W.shift "games") , ("M-S-5", windows $ W.shift "misc" ) - -- master pane manipulation - , ("M-", sendMessage Shrink) -- shrink master pane width - , ("M-", sendMessage Expand) -- expand master pane width - , ("M-", sendMessage (IncMasterN 1)) -- more windows in master - , ("M-", sendMessage (IncMasterN (-1))) -- fewer windows in master - -- master window operations , ("M-", windows W.focusMaster) , ("M-S-", windows W.swapMaster ) @@ -141,6 +133,30 @@ myKeymap = ] +-- +-- Modal Modes +-- + +layoutMode :: Mode +layoutMode = mode "layout" $ mkKeysEz + -- jump to layout (exits immediately) + [ ("d", sendMessage (JumpToLayout "dynamic tiling") >> exitMode) + , ("m", sendMessage (JumpToLayout "maximised" ) >> exitMode) + , ("f", sendMessage (JumpToLayout "fullscreen" ) >> exitMode) + -- adjust master/slave split (stays in mode) + , ("", sendMessage Shrink) + , ("", sendMessage Expand) + , ("", sendMessage (IncMasterN 1)) + , ("", sendMessage (IncMasterN (-1))) + ] + +spawnMode :: Mode +spawnMode = mode "spawn" $ mkKeysEz + [ ("t", spawn myFileManager >> exitMode) + , ("s", spawn myScrot >> exitMode) + ] + + -- -- Layouts -- @@ -175,8 +191,11 @@ myXmobarPP = def , ppHiddenNoWindows = grey0 . wrap " " "" , ppUrgent = red . wrap " " "" , ppLayout = aqua . wrap (grey0 " [ ") (grey0 " ] ") - , ppOrder = \[ws, l, _] -> [ws, l] + , ppOrder = \case { [ws, l, title, mode] -> [ws, l, mode, title]; xs -> xs } + , ppExtras = [lMode] } + where + lMode = xmobarColorL "#d8a657" "#282828" . fixedWidthL AlignCenter "-" 4 $ logMode --