feat: implement modal keybindings for layout and master pane control
Add XMonad.Hooks.Modal to separate layout switching and master pane manipulation into distinct modal namespaces. This resolves keybinding conflicts and creates a more organized interaction model. Changes: - Layout mode (M-a l): one-shot layout selection (d/m/f) - Master mode (M-a m): persistent pane adjustments with arrow keys - Restore ppExtras with logMode to display active mode in xmobar - Remove conflicting Home/End/PageUp/PageDown bindings from master pane - Simplify navigation by moving screen focus back to Home/End
This commit is contained in:
parent
9ce0ee6dcc
commit
7568c2aa01
2 changed files with 53 additions and 28 deletions
14
CLAUDE.md
14
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, `<Escape>` 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`)
|
||||
|
||||
|
|
|
@ -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 "launch")
|
||||
|
||||
|
||||
--
|
||||
-- Navigation
|
||||
|
@ -96,12 +94,12 @@ myKeymap =
|
|||
, ("M-<Right>", moveTo Next hiddenWS)
|
||||
|
||||
-- window rotation
|
||||
, ("M-S-<Up>", rotAllUp)
|
||||
, ("M-S-<Down>", rotAllDown)
|
||||
, ("M-<Page_Up>" , rotAllUp)
|
||||
, ("M-<Page_Down>", rotAllDown)
|
||||
|
||||
-- focus screens
|
||||
, ("M-S-<Left>", prevScreen)
|
||||
, ("M-S-<Right>", nextScreen)
|
||||
, ("M-<Home>", prevScreen)
|
||||
, ("M-<End>" , 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-<Home>", sendMessage Shrink) -- shrink master pane width
|
||||
, ("M-<End>", sendMessage Expand) -- expand master pane width
|
||||
, ("M-<Page_Up>", sendMessage (IncMasterN 1)) -- more windows in master
|
||||
, ("M-<Page_Down>", sendMessage (IncMasterN (-1))) -- fewer windows in master
|
||||
|
||||
-- master window operations
|
||||
, ("M-<Delete>", windows W.focusMaster)
|
||||
, ("M-S-<Delete>", windows W.swapMaster )
|
||||
|
@ -141,6 +133,30 @@ myKeymap =
|
|||
]
|
||||
|
||||
|
||||
--
|
||||
-- Modal Modes
|
||||
--
|
||||
|
||||
layoutMode :: Mode
|
||||
layoutMode = mode "layout" $ mkKeysEz
|
||||
-- jump to layout (exits immediately)
|
||||
[ ("t", sendMessage (JumpToLayout "dynamic tiling") >> exitMode)
|
||||
, ("m", sendMessage (JumpToLayout "maximised" ) >> exitMode)
|
||||
, ("f", sendMessage (JumpToLayout "fullscreen" ) >> exitMode)
|
||||
-- adjust master/slave split (stays in mode)
|
||||
, ("<Left>", sendMessage Shrink)
|
||||
, ("<Right>", sendMessage Expand)
|
||||
, ("<Up>", sendMessage (IncMasterN 1))
|
||||
, ("<Down>", sendMessage (IncMasterN (-1)))
|
||||
]
|
||||
|
||||
spawnMode :: Mode
|
||||
spawnMode = mode "launch" $ 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 " <fn=1>[</fn> ") (grey0 " <fn=1>]</fn> ")
|
||||
, 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 "-" 6 $ logMode
|
||||
|
||||
|
||||
--
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue