diff --git a/README.md b/README.md
index 153dc6d..9a99de8 100644
--- a/README.md
+++ b/README.md
@@ -3,10 +3,17 @@
janishutz Hyprland
-Collection of dotfiles for my personal Hyprland setup, running on Arch Linux. Includes a setup and install script (that one is not complete yet though). For my neovim config, see [here](https://git.janishutz.com/janishutz/nvim)
+Collection of dotfiles for my personal Hyprland setup, running on Arch Linux.
+Includes a setup and install script (that one is not complete yet though).
+For my neovim config, see [here](https://git.janishutz.com/janishutz/nvim)

+I am currently working on redoing my keybinds for Hyprland, in what I call `hyprmode`:
+They are going to use submaps and will be significantly different, yet still familiar.
+This will enable me to have many more keybinds with reasonable starter bindings.
+I will also update Astal to have a mode indicator if `hyprmode` is enabled.
+
## Features
- Astal4 based Status Bar and Quick Actions menu
- System info
diff --git a/config/hypr/hyprland/modal-binds/README.md b/config/hypr/hyprland/modal-binds/README.md
new file mode 100644
index 0000000..9e443c9
--- /dev/null
+++ b/config/hypr/hyprland/modal-binds/README.md
@@ -0,0 +1,14 @@
+# Hyprmode
+Using Vim Motions and in general vim-style commands is really neat - so why not apply to the Window Manager as well?
+
+## Mapping
+- `Super + W`: Manage windows (close windows, resize them, change split)
+- `Super + Y`: Workspace management (change workspace, move windows to workspaces)
+- `Super + C`: Notification management (dismiss notifications)
+- `Super + X`: Launch commands (for software)
+- `Super + D`: Device management (brightness, volume, media, etc)
+- `Super + S`: Screenshot
+
+There are several quick binds available, such as `Super + [0-9]` to switch workspaces, `Super + Shift + [0-9]` to move windows as well as `Super + [hjkl]` to move focus.
+
+Additionally, there are shortcuts to commonly used apps, such as `Super + Enter` for `kitty`, `Super + Shift + L` for `librewolf` and `Super + Space` for `rofi`
diff --git a/config/hypr/hyprland/modal-binds/device.conf b/config/hypr/hyprland/modal-binds/device.conf
new file mode 100644
index 0000000..2084e15
--- /dev/null
+++ b/config/hypr/hyprland/modal-binds/device.conf
@@ -0,0 +1,45 @@
+# ────────────────────────────────────────────────────────────────────
+# ╭────────────────────────────────────────────────╮
+# │ device config │
+# ╰────────────────────────────────────────────────╯
+
+# ── Brightness-Control ──────────────────────────────────────────────
+bind = ,code:232, exec, light -U 5 && notify-send 'Display brightness decreased by 5%'
+bind = ,code:233, exec, light -A 5 && notify-send 'Display brightness increased by 5%'
+
+
+# ── Volume control ──────────────────────────────────────────────────
+bind = ,code:123, exec, pamixer -i 5
+bind = ,code:122, exec, pamixer -d 5
+bind = ,code:121, exec, pamixer -t
+
+
+# ── Submap ──────────────────────────────────────────────────────────
+bind = $mainMod, W, submap, device
+submap = device
+
+
+# ── FPV goggles binds ───────────────────────────────────────────────
+bind = CTRL, D, exec, hyprctl keyword monitor HDMI-A-1, 1280x720@60, 1920x0, 1, mirror, DP-1 && notify-send 'Set FPV goggles to mirror main screen' --app-name="Hyprctl"
+bind = CTRL, E, exec, hyprctl keyword monitor HDMI-A-1, 1280x720@60, 3840x0, 1 && notify-send 'Set to expand FPV goggles' --app-name="Hyprctl"
+
+
+# ── Monitor config binds ────────────────────────────────────────────
+bind = SHIFT, D, exec, hyprctl keyword monitor HDMI-A-1, 1920x1080@60, 1920x0, 1, mirror, eDP-1 && notify-send 'Set to mirror internal display'
+bind = SHIFT, E, exec, hyprctl keyword monitor HDMI-A-1, 1920x1080@60, 1920x0, 1 && notify-send 'Set to expand external display'
+
+
+# ── Internal display controls ───────────────────────────────────────
+bind = , E, exec, hyprctl keyword monitor eDP-1, 2880x1800@60, 0x0, 1.5 && cpupower-gui -b && notify-send 'Set to battery optimized settings'
+bind = , B, exec, hyprctl keyword monitor eDP-1, 2880x1800@120, 0x0, 1.5 && cpupower-gui -b && notify-send 'Set to balanced performance settings'
+bind = , P, exec, hyprctl keyword monitor eDP-1, 2880x1800@120, 0x0, 1.5 && cpupower-gui -p && notify-send 'Set to performance optimized settings'
+
+
+# ── Using docked ────────────────────────────────────────────────────
+bind = , D, exec, hyprctl keyword monitor eDP-1, disable
+
+
+# ── Exit submap ─────────────────────────────────────────────────────
+bind = , escape, submap, reset
+submap = reset
+# ────────────────────────────────────────────────────────────────────
diff --git a/config/hypr/hyprland/modal-binds/launch.conf b/config/hypr/hyprland/modal-binds/launch.conf
new file mode 100644
index 0000000..dfd6e87
--- /dev/null
+++ b/config/hypr/hyprland/modal-binds/launch.conf
@@ -0,0 +1,51 @@
+# ────────────────────────────────────────────────────────────────────
+# ╭────────────────────────────────────────────────╮
+# │ App launching │
+# ╰────────────────────────────────────────────────╯
+bind = $mainMod SHIFT, L, exec, librewolf
+bind = $mainMod SHIFT, D, exec, vesktop
+bind = $mainMod SHIFT, Z, exec, zathura
+bind = $mainMod, Return, exec, kitty
+
+
+# ── Rofi ────────────────────────────────────────────────────────────
+bind = $mainMod, Space, exec, killall rofi || rofi -show combi -modes combi -combi-modes "window,drun,run"
+bind = $mainMod SHIFT, H, exec, cliphist list | rofi -dmenu | cliphist decode | wl-copy
+
+
+# ── Power / logout ──────────────────────────────────────────────────
+bind = $mainMod, escape, exec, wlogout
+
+
+
+# ────────────────────────────────────────────────────────────────────
+# ╭────────────────────────────────────────────────╮
+# │ Launch submap │
+# ╰────────────────────────────────────────────────╯
+bind = $mainMod, X, submap, launch
+submap = launch
+
+
+# ── Kitty ───────────────────────────────────────────────────────────
+bind = , K, exec, kitty
+bind = , Return, exec, kitty
+
+
+# ── Others ──────────────────────────────────────────────────────────
+bind = , L, exec, librewolf
+bind = , E, exec, thunar
+bind = , D, exec, vesktop
+bind = , V, exec, vscodium
+bind = , T, exec, thunderbird
+bind = , H, exec, heroic
+bind = , Z, exec, zathura
+bind = , A, exec, notify-send 'AirPlay server starting...' --app-name="AirPlay Audio" && terminator -T "hidden-terminator" -e "systemctl start avahi-daemon && shairport-sync -a LinuxPlay"
+bind = SHIFT, A, exec, notify-send 'AirPlay video server starting...' --app-name="AirPlay Video" && terminator -T "hidden-terminator" -e "systemctl start avahi-daemon && sleep 5 && uxplay -n LinuxVideoPlay -nh"
+bind = , S, exec, notify-send 'Steam is launching...' --app-name="Steam" && steam
+bind = , O, exec, terminator -e "~/projects/dotfiles/ai.sh"
+
+
+# ── Exit submap ─────────────────────────────────────────────────────
+bind = , escape, submap, reset
+submap = reset
+# ────────────────────────────────────────────────────────────────────
diff --git a/config/hypr/hyprland/modal-binds/screenshot.conf b/config/hypr/hyprland/modal-binds/screenshot.conf
new file mode 100644
index 0000000..44841e8
--- /dev/null
+++ b/config/hypr/hyprland/modal-binds/screenshot.conf
@@ -0,0 +1,19 @@
+# ────────────────────────────────────────────────────────────────────
+# ╭────────────────────────────────────────────────╮
+# │ Screenshotting binds │
+# ╰────────────────────────────────────────────────╯
+bind = $mainMod, S, submap, screenshotting
+submap = screenshotting
+
+bind = , Y, exec, grimblast --notify copy area
+bind = , C, exec, grimblast --notify copysave area
+bind = , S, exec, grimblast --notify save area
+bind = SHIFT, Y, exec, grimblast --notify copy screen
+bind = SHIFT, C, exec, grimblast --notify copysave screen
+bind = SHIFT, S, exec, grimblast --notify save screen
+
+
+# ── Exit submap ─────────────────────────────────────────────────────
+bind = , escape, submap, reset
+submap = reset
+# ────────────────────────────────────────────────────────────────────
diff --git a/config/hypr/hyprland/modal-binds/window-management.conf b/config/hypr/hyprland/modal-binds/window-management.conf
new file mode 100644
index 0000000..8b90e2b
--- /dev/null
+++ b/config/hypr/hyprland/modal-binds/window-management.conf
@@ -0,0 +1,40 @@
+# ────────────────────────────────────────────────────────────────────
+# ╭────────────────────────────────────────────────╮
+# │ Window management submap │
+# ╰────────────────────────────────────────────────╯
+bind = $mainMod, Q, killactive
+
+# ── Resize, move using mouse plus mainMod ───────────────────────────
+bindm = $mainMod, mouse:272, movewindow
+bindm = $mainMod, mouse:273, resizewindow
+
+
+# ── Submap ──────────────────────────────────────────────────────────
+bind = $mainMod, W, submap, windowing
+submap = windowing
+
+# ── Resize windows ──────────────────────────────────────────────────
+binde = , L, resizeactive, 10 0
+binde = , H, resizeactive, -10 0
+binde = , K, resizeactive, 0 -10
+binde = , J, resizeactive, 0 10
+
+
+# ── Change splitratio ───────────────────────────────────────────────
+binde = SHIFT, H, splitratio, -0.01
+binde = SHIFT, L, splitratio, +0.01
+
+
+# ── Kill, freeze, etc ───────────────────────────────────────────────
+bind = SHIFT, f, exec, hyprfreeze -a
+bind = , x, killactive
+bind = , q, killactive
+bind = , f, fullscreen
+bind = , v, togglefloating
+bind = SHIFT, k, exec, notify-send 'Insta-Kill activated' --app-name="Hyprctl" && hyprctl kill
+
+
+# ── Exit submap ─────────────────────────────────────────────────────
+bind = , escape, submap, reset
+submap = reset
+# ────────────────────────────────────────────────────────────────────
diff --git a/config/hypr/hyprland/modal-binds/workspace.conf b/config/hypr/hyprland/modal-binds/workspace.conf
new file mode 100644
index 0000000..be2cdf1
--- /dev/null
+++ b/config/hypr/hyprland/modal-binds/workspace.conf
@@ -0,0 +1,118 @@
+# ┌ ┐
+# │ Switch workspaces with mainMod + [0-9] │
+# └ ┘
+bind = $mainMod, 1, workspace, 1
+bind = $mainMod, 2, workspace, 2
+bind = $mainMod, 3, workspace, 3
+bind = $mainMod, 4, workspace, 4
+bind = $mainMod, 5, workspace, 5
+bind = $mainMod, 6, workspace, 6
+bind = $mainMod, 7, workspace, 7
+bind = $mainMod, 8, workspace, 8
+bind = $mainMod, 9, workspace, 9
+bind = $mainMod, 0, workspace, 10
+
+# ┌ ┐
+# │ Move active window to a workspace with │
+# │ mainMod + SHIFT + [0-9] │
+# └ ┘
+bind = $mainMod SHIFT, 1, movetoworkspace, 1
+bind = $mainMod SHIFT, 2, movetoworkspace, 2
+bind = $mainMod SHIFT, 3, movetoworkspace, 3
+bind = $mainMod SHIFT, 4, movetoworkspace, 4
+bind = $mainMod SHIFT, 5, movetoworkspace, 5
+bind = $mainMod SHIFT, 6, movetoworkspace, 6
+bind = $mainMod SHIFT, 7, movetoworkspace, 7
+bind = $mainMod SHIFT, 8, movetoworkspace, 8
+bind = $mainMod SHIFT, 9, movetoworkspace, 9
+bind = $mainMod SHIFT, 0, movetoworkspace, 10
+
+# ┌ ┐
+# │ Move focus with vim motions │
+# └ ┘
+bind = $mainMod, h, movefocus, l
+bind = $mainMod, l, movefocus, r
+bind = $mainMod, j, movefocus, d
+bind = $mainMod, k, movefocus, u
+
+
+# ┌ ┐
+# │ Special workspace │
+# └ ┘
+bind = $mainMod SHIFT, M, movetoworkspace, special
+bind = $mainMod, M, togglespecialworkspace
+
+# ┌ ┐
+# │ Scroll through existing workspaces with │
+# │ mainMod + scroll │
+# └ ┘
+bind = $mainMod, mouse_down, workspace, e+1
+bind = $mainMod, mouse_up, workspace, e-1
+
+# ┌ ┐
+# │ move to next window / previous window with │
+# │ ALT + Tab / SHIFT + ALT + Tab │
+# └ ┘
+bind = ALT SHIFT, tab, cyclenext, prev
+bind = ALT, tab, focusurgentorlast
+
+
+
+# ────────────────────────────────────────────────────────────────────
+# ╭────────────────────────────────────────────────╮
+# │ Submap for workspace management │
+# ╰────────────────────────────────────────────────╯
+bind = $mainMod, Y, submap, workspace
+submap = workspace
+
+# ── Move to workspace ───────────────────────────────────────────────
+bind = , 1, workspace, 1
+bind = , 2, workspace, 2
+bind = , 3, workspace, 3
+bind = , 4, workspace, 4
+bind = , 5, workspace, 5
+bind = , 6, workspace, 6
+bind = , 7, workspace, 7
+bind = , 8, workspace, 8
+bind = , 9, workspace, 9
+bind = , 0, workspace, 10
+
+
+# ── Move active window to workspace ─────────────────────────────────
+bind = SHIFT, 1, movetoworkspace, 1
+bind = SHIFT, 2, movetoworkspace, 2
+bind = SHIFT, 3, movetoworkspace, 3
+bind = SHIFT, 4, movetoworkspace, 4
+bind = SHIFT, 5, movetoworkspace, 5
+bind = SHIFT, 6, movetoworkspace, 6
+bind = SHIFT, 7, movetoworkspace, 7
+bind = SHIFT, 8, movetoworkspace, 8
+bind = SHIFT, 9, movetoworkspace, 9
+bind = SHIFT, 0, movetoworkspace, 10
+
+
+# ── Move workspace with vim motions or mouse scroll ─────────────────
+bind = , h, workspace, e-1
+bind = , l, workspace, e+1
+bind = , mouse_down, workspace, e+1
+bind = , mouse_up, workspace, e-1
+
+
+# ── Move window to workspace with vim motions ───────────────────────
+bind = SHIFT, h, movetoworkspace, e-1
+bind = SHIFT, l, movetoworkspace, e+1
+
+
+# ── Special workspace ───────────────────────────────────────────────
+bind = , s, togglespecialworkspace
+bind = SHIFT, s, movetoworkspace, special
+
+
+# ── dwindle ─────────────────────────────────────────────────────────
+bind = , M, layoutmsg, swapsplit
+
+
+# ── Exit submap ─────────────────────────────────────────────────────
+bind = , escape, submap, reset
+submap = reset
+# ────────────────────────────────────────────────────────────────────
diff --git a/config/hypr/hyprland/mode-binds.conf b/config/hypr/hyprland/mode-binds.conf
new file mode 100644
index 0000000..3b549a7
--- /dev/null
+++ b/config/hypr/hyprland/mode-binds.conf
@@ -0,0 +1,14 @@
+$mainMod = SUPER
+source=./modal-binds/workspace.conf
+source=./modal-binds/launch.conf
+source=./modal-binds/window-management.conf
+source=./modal-binds/screenshot.conf
+source=./modal-binds/device.conf
+
+
+bind = CTRL ALT, Delete, exec, notify-send 'I am not Windows' 'Did ya really think that was gonna do anything? Only an eternally broken OS could need such a stupid keybind'
+bind = ALT, F4, exec, notify-send 'I am not Windows' 'That just feels like a way too unergonomic keybind to be used for such a common action'
+bind = $mainMod, left, exec, notify-send 'I am not Windows' 'This is no inefficient stacking manager. Tiling happens automatically'
+bind = $mainMod, right, exec, notify-send 'I am not Windows' 'This is no inefficient stacking manager. Tiling happens automatically'
+bind = $mainMod, up, exec, notify-send 'I am not Windows' 'This is no inefficient stacking manager. Tiling happens automatically'
+bind = $mainMod, down, exec, notify-send 'I am not Windows' 'This is no inefficient stacking manager. Tiling happens automatically'
diff --git a/config/hypr/hyprland_desktop.conf b/config/hypr/hyprland_desktop.conf
index b5b4114..beace04 100644
--- a/config/hypr/hyprland_desktop.conf
+++ b/config/hypr/hyprland_desktop.conf
@@ -17,14 +17,8 @@
# ╰────────────────────────────────────────────────╯
# ────────────────────────────────────────────────────────────────────
-# monitor=DP-1, preferred, 0x0, 1, vrr, 2
monitor=DP-1, 1920x1080@144, 0x0, 1, vrr, 2
monitor=DP-2, 1920x1080@75, 1920x0, 1
-# monitor=,highres highrr, auto, 1
-
-
-# exec = swaybg -m fill -i /mnt/storage/SORTED/Pictures/Wallpapers/wallpaper/arch-bg-matterhorn.jpg
-# exec = swaybg -m fill -i /mnt/storage/SORTED/Pictures/Wallpapers/McLaren/main_livery_upscaled.jpg
source=./hyprland/binds.conf
diff --git a/config/hypr/hyprland_docked.conf b/config/hypr/hyprland_docked.conf
index 4a2436b..9cf3049 100644
--- a/config/hypr/hyprland_docked.conf
+++ b/config/hypr/hyprland_docked.conf
@@ -42,16 +42,6 @@ xwayland {
force_zero_scaling = true
}
-# ── Volume control ──────────────────────────────────────────────────
-bind = ,code:123, exec, pamixer -i 5
-bind = ,code:122, exec, pamixer -d 5
-bind = ,code:121, exec, pamixer -t
-
-
-# ── Brightness-Control ──────────────────────────────────────────────
-bind = ,code:232, exec, light -U 5 && notify-send 'Display brightness decreased by 5%'
-bind = ,code:233, exec, light -A 5 && notify-send 'Display brightness increased by 5%'
-
# ── Vivado inversion ────────────────────────────────────────────────
windowrule = plugin:invertwindow, class:Vivado
diff --git a/config/hypr/hyprland_laptop.conf b/config/hypr/hyprland_laptop.conf
index 4506061..240cf44 100644
--- a/config/hypr/hyprland_laptop.conf
+++ b/config/hypr/hyprland_laptop.conf
@@ -44,30 +44,8 @@ xwayland {
force_zero_scaling = true
}
-# ── Volume control ──────────────────────────────────────────────────
-bind = ,code:123, exec, pamixer -i 5
-bind = ,code:122, exec, pamixer -d 5
-bind = ,code:121, exec, pamixer -t
-# ── Brightness-Control ──────────────────────────────────────────────
-bind = ,code:232, exec, light -U 5 && notify-send 'Display brightness decreased by 5%'
-bind = ,code:233, exec, light -A 5 && notify-send 'Display brightness increased by 5%'
-
-
-# ── Monitor config binds ────────────────────────────────────────────
-bind = $mainMod CTRL, D, exec, hyprctl keyword monitor HDMI-A-1, 1920x1080@60, 1920x0, 1, mirror, eDP-1 && notify-send 'Set to mirror internal display'
-bind = $mainMod CTRL, E, exec, hyprctl keyword monitor HDMI-A-1, 1920x1080@60, 1920x0, 1 && notify-send 'Set to expand external display'
-
-
-# ── Internal display controls ───────────────────────────────────────
-bind = $mainMod ALT, E, exec, hyprctl keyword monitor eDP-1, 2880x1800@60, 0x0, 1.5 && cpupower-gui -b && notify-send 'Set to battery optimized settings'
-bind = $mainMod ALT, B, exec, hyprctl keyword monitor eDP-1, 2880x1800@120, 0x0, 1.5 && cpupower-gui -b && notify-send 'Set to balanced performance settings'
-bind = $mainMod ALT, P, exec, hyprctl keyword monitor eDP-1, 2880x1800@120, 0x0, 1.5 && cpupower-gui -p && notify-send 'Set to performance optimized settings'
-
-# ── Using docked ────────────────────────────────────────────────────
-bind = $mainMod ALT, D, exec, hyprctl keyword monitor eDP-1, disable
-
# ── Vivado inversion ────────────────────────────────────────────────
windowrule = plugin:invertwindow, class:Vivado
windowrule = tile, title:(.*)Vivado(.*)
diff --git a/setup b/setup
index 4dc7806..a2e9eb7 100755
--- a/setup
+++ b/setup
@@ -36,6 +36,8 @@ else
fi
platform=$(echo "$platform" | tr '[:upper:]' '[:lower:]')
+
+# ────────────────────────────────────────────────────────────────────
# Get user preference for regenerating the styling
regen=""
read -p "Would you like to regenerate styling? (y/N) " regen
@@ -53,6 +55,19 @@ else
read -p "Apply full config? (y/N) " restart
fi
+# ────────────────────────────────────────────────────────────────────
+# Hyprmode config
+hyprmode=""
+if [[ -f ~/.config/hyprmode ]]; then
+ echo "Hyprmode config already specified, skipping"
+ platform=$(cat ~/.config/hyprmode)
+else
+ read -p "Would you like to use Hyprmode? (Y/n) " hyprmode
+fi
+hyprmode=$(echo "$hyprmode" | tr '[:upper:]' '[:lower:]')
+
+
+# ────────────────────────────────────────────────────────────────────
echo "=> Moving configs to correct destinations"
killall swaybg
cp -r ./config/fish ~/.config/
@@ -71,6 +86,16 @@ else
cp -f ~/.config/hypr/hyprland_laptop.conf ~/.config/hypr/hyprland.conf
fi
+# Enable or disable "Hyprmode" (using hyprland with vim-inspired modes)
+if [[ "$hyprmode" == "y" ]]; then
+ echo "Enabling hyprmode"
+ mv -f ~/.config/hypr/hyprland/mode-binds.conf ~/.config/hypr/hyprland/binds.conf
+else
+ echo "Disabling hyprmode"
+ rm -rf ~/.config/hypr/hyprland/modal-binds
+ rm ~/.config/hypr/hyprland/mode-binds.conf
+fi
+
# Done this way intentionally to control what is copied
cp -r ./config/kitty ~/.config/
cp -r ./config/fastfetch ~/.config/
@@ -82,6 +107,8 @@ cp -r ./config/yazi ~/.config/
cp -r ./config/zathura ~/.config/
cp ./config/lint/indentconfig.yaml ~/.indentconfig.yaml
+# ────────────────────────────────────────────────────────────────────
+
echo "
=> Installing yazi plugins
"
@@ -111,6 +138,8 @@ if [[ "$restart" == "y" ]]; then
./scripts/restart-bar
fi
+# ────────────────────────────────────────────────────────────────────
+
hyprctl reload
echo "