hyprland: add SUPER+arrow workspace cycling and overview binds
SUPER+Left/Right cycle existing workspaces on the active monitor (m+1/m-1 with cycling enabled), SUPER+Up opens the hyprshell overview scoped to the current monitor (create/manage workspaces there), and SUPER+Down closes the overview again. Adds binds-help.sh cheat sheet (SHIFT+SUPER+H) and overview-close.sh helper.
This commit is contained in:
@@ -1,72 +1,86 @@
|
|||||||
-- See https://wiki.hypr.land/Configuring/Basics/Binds/ for more
|
-- See https://wiki.hypr.land/Configuring/Basics/Binds/ for more
|
||||||
|
|
||||||
-- Sound through pactl
|
-- Sound through pactl
|
||||||
hl.bind("XF86AudioRaiseVolume", hl.dsp.exec_cmd("pactl set-sink-volume @DEFAULT_SINK@ +10%"))
|
hl.bind("XF86AudioRaiseVolume", hl.dsp.exec_cmd("pactl set-sink-volume @DEFAULT_SINK@ +10%"), { desc = "Raise volume" })
|
||||||
hl.bind("XF86AudioLowerVolume", hl.dsp.exec_cmd("pactl set-sink-volume @DEFAULT_SINK@ -10%"))
|
hl.bind("XF86AudioLowerVolume", hl.dsp.exec_cmd("pactl set-sink-volume @DEFAULT_SINK@ -10%"), { desc = "Lower volume" })
|
||||||
hl.bind("XF86AudioMute", hl.dsp.exec_cmd("pactl set-sink-mute @DEFAULT_SINK@ toggle"))
|
hl.bind("XF86AudioMute", hl.dsp.exec_cmd("pactl set-sink-mute @DEFAULT_SINK@ toggle"), { desc = "Mute audio" })
|
||||||
hl.bind("XF86AudioPlay", hl.dsp.exec_cmd("playerctl play-pause"))
|
hl.bind("XF86AudioPlay", hl.dsp.exec_cmd("playerctl play-pause"), { desc = "Play/pause media" })
|
||||||
hl.bind("XF86AudioPrev", hl.dsp.exec_cmd("playerctl previous"))
|
hl.bind("XF86AudioPrev", hl.dsp.exec_cmd("playerctl previous"), { desc = "Previous track" })
|
||||||
hl.bind("XF86AudioNext", hl.dsp.exec_cmd("playerctl next"))
|
hl.bind("XF86AudioNext", hl.dsp.exec_cmd("playerctl next"), { desc = "Next track" })
|
||||||
|
|
||||||
-- Brightness through brightnessctl
|
-- Brightness through brightnessctl
|
||||||
hl.bind("XF86MonBrightnessUp", hl.dsp.exec_cmd("brightnessctl set +5%"))
|
hl.bind("XF86MonBrightnessUp", hl.dsp.exec_cmd("brightnessctl set +5%"), { desc = "Increase brightness" })
|
||||||
hl.bind("XF86MonBrightnessDown", hl.dsp.exec_cmd("brightnessctl set 5%-"))
|
hl.bind("XF86MonBrightnessDown", hl.dsp.exec_cmd("brightnessctl set 5%-"), { desc = "Decrease brightness" })
|
||||||
|
|
||||||
-- Main modifier binds
|
-- Main modifier binds
|
||||||
hl.bind(mainMod .. " + T", hl.dsp.exec_cmd(terminal))
|
hl.bind(mainMod .. " + T", hl.dsp.exec_cmd(terminal), { desc = "Open terminal" })
|
||||||
hl.bind(mainMod .. " + B", hl.dsp.exec_cmd(browser))
|
hl.bind(mainMod .. " + B", hl.dsp.exec_cmd(browser), { desc = "Open browser" })
|
||||||
hl.bind(mainMod .. " + F", hl.dsp.exec_cmd(fileManager))
|
hl.bind(mainMod .. " + F", hl.dsp.exec_cmd(fileManager), { desc = "Open file manager" })
|
||||||
hl.bind(mainMod .. " + C", hl.dsp.window.close())
|
hl.bind(mainMod .. " + C", hl.dsp.window.close(), { desc = "Close active window" })
|
||||||
hl.bind(mainMod .. " + Q", hl.dsp.exec_cmd("hyprctl dispatch closewindow \"class:$(hyprctl activewindow -j | jq -r .class)\""))
|
hl.bind(mainMod .. " + Q", hl.dsp.exec_cmd("hyprctl dispatch closewindow \"class:$(hyprctl activewindow -j | jq -r .class)\""), { desc = "Close active window (by class)" })
|
||||||
hl.bind(mainMod .. " + M", hl.dsp.exit())
|
hl.bind(mainMod .. " + M", hl.dsp.exit(), { desc = "Exit Hyprland" })
|
||||||
hl.bind(mainMod .. " + V", hl.dsp.window.float({ action = "toggle" }))
|
hl.bind(mainMod .. " + V", hl.dsp.window.float({ action = "toggle" }), { desc = "Toggle floating" })
|
||||||
hl.bind(mainMod .. " + space", hl.dsp.exec_cmd(menu))
|
hl.bind(mainMod .. " + space", hl.dsp.exec_cmd(menu), { desc = "Open app menu" })
|
||||||
hl.bind(SUPER_SHIFT .. " + L", hl.dsp.exec_cmd("hyprlock"))
|
hl.bind(SUPER_SHIFT .. " + L", hl.dsp.exec_cmd("hyprlock"), { desc = "Lock screen" })
|
||||||
hl.bind(SUPER_SHIFT .. " + R", hl.dsp.exec_cmd("hyprctl reload"))
|
hl.bind(SUPER_SHIFT .. " + R", hl.dsp.exec_cmd("hyprctl reload"), { desc = "Reload config" })
|
||||||
-- Monique: GUI monitor arrangement/display settings
|
-- Monique: GUI monitor arrangement/display settings
|
||||||
hl.bind(SUPER_SHIFT .. " + M", hl.dsp.exec_cmd("monique"))
|
hl.bind(SUPER_SHIFT .. " + M", hl.dsp.exec_cmd("monique"), { desc = "Open monique (monitor settings)" })
|
||||||
hl.bind(SUPER_SHIFT .. " + D", hl.dsp.exec_cmd("hyprctl keyword monitor eDP-1, disable"))
|
hl.bind(SUPER_SHIFT .. " + D", hl.dsp.exec_cmd("hyprctl keyword monitor eDP-1, disable"), { desc = "Disable eDP-1 (clamshell)" })
|
||||||
hl.bind(SUPER_SHIFT .. " + F", hl.dsp.exec_cmd("hyprctl keyword monitor eDP-1, enable"))
|
hl.bind(SUPER_SHIFT .. " + F", hl.dsp.exec_cmd("hyprctl keyword monitor eDP-1, enable"), { desc = "Enable eDP-1" })
|
||||||
|
|
||||||
-- Screenshots
|
-- Screenshots
|
||||||
hl.bind("Print", hl.dsp.exec_cmd("grim -c -o \"$(hyprctl activeworkspace -j | jq -r '.monitor')\" $(xdg-user-dir PICTURES)/Screenshots/$(date +'%s_grim.png')"))
|
hl.bind("Print", hl.dsp.exec_cmd("grim -c -o \"$(hyprctl activeworkspace -j | jq -r '.monitor')\" $(xdg-user-dir PICTURES)/Screenshots/$(date +'%s_grim.png')"), { desc = "Screenshot active monitor" })
|
||||||
hl.bind("SHIFT + Print", hl.dsp.exec_cmd("grim -g \"$(slurp)\" $(xdg-user-dir PICTURES)/Screenshots/$(date +'%s_grim.png')"))
|
hl.bind("SHIFT + Print", hl.dsp.exec_cmd("grim -g \"$(slurp)\" $(xdg-user-dir PICTURES)/Screenshots/$(date +'%s_grim.png')"), { desc = "Screenshot region" })
|
||||||
|
|
||||||
-- Dwindle layout
|
-- Dwindle layout
|
||||||
hl.bind(mainMod .. " + P", hl.dsp.window.pseudo()) -- dwindle
|
hl.bind(mainMod .. " + P", hl.dsp.window.pseudo(), { desc = "Toggle pseudo tiling" }) -- dwindle
|
||||||
hl.bind(mainMod .. " + E", hl.dsp.layout("togglesplit")) -- dwindle
|
hl.bind(mainMod .. " + E", hl.dsp.layout("togglesplit"), { desc = "Toggle split" }) -- dwindle
|
||||||
hl.bind(mainMod .. " + CTRL + F", hl.dsp.window.fullscreen({ action = "toggle" })) -- dwindle
|
hl.bind(mainMod .. " + CTRL + F", hl.dsp.window.fullscreen({ action = "toggle" }), { desc = "Toggle fullscreen" }) -- dwindle
|
||||||
hl.bind(mainMod .. " + W", hl.dsp.group.toggle()) -- dwindle
|
hl.bind(mainMod .. " + W", hl.dsp.group.toggle(), { desc = "Toggle window group" }) -- dwindle
|
||||||
|
|
||||||
-- Move focus with mainMod + vim keys
|
-- Move focus with mainMod + vim keys
|
||||||
hl.bind(mainMod .. " + H", hl.dsp.focus({ direction = "l" }))
|
hl.bind(mainMod .. " + H", hl.dsp.focus({ direction = "l" }), { desc = "Focus left" })
|
||||||
hl.bind(mainMod .. " + L", hl.dsp.focus({ direction = "r" }))
|
hl.bind(mainMod .. " + L", hl.dsp.focus({ direction = "r" }), { desc = "Focus right" })
|
||||||
hl.bind(mainMod .. " + K", hl.dsp.focus({ direction = "u" }))
|
hl.bind(mainMod .. " + K", hl.dsp.focus({ direction = "u" }), { desc = "Focus up" })
|
||||||
hl.bind(mainMod .. " + J", hl.dsp.focus({ direction = "d" }))
|
hl.bind(mainMod .. " + J", hl.dsp.focus({ direction = "d" }), { desc = "Focus down" })
|
||||||
|
|
||||||
|
-- Cycle workspaces on the active monitor with mainMod + arrows (m+1/m-1 stay
|
||||||
|
-- on the current monitor; plain +1/-1 would follow the workspace if it moves
|
||||||
|
-- to another monitor). These only visit non-empty workspaces.
|
||||||
|
hl.bind(mainMod .. " + Left", hl.dsp.focus({ workspace = "m-1" }), { desc = "Previous workspace (active monitor)" })
|
||||||
|
hl.bind(mainMod .. " + Right", hl.dsp.focus({ workspace = "m+1" }), { desc = "Next workspace (active monitor)" })
|
||||||
|
|
||||||
-- Switch workspaces with mainMod + [0-9]
|
-- Switch workspaces with mainMod + [0-9]
|
||||||
for i = 1, 10 do
|
for i = 1, 10 do
|
||||||
local key = i % 10 -- 10 maps to key 0
|
local key = i % 10 -- 10 maps to key 0
|
||||||
hl.bind(mainMod .. " + " .. key, hl.dsp.focus({ workspace = i }))
|
hl.bind(mainMod .. " + " .. key, hl.dsp.focus({ workspace = i }), { desc = "Go to workspace " .. i })
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Move active window to a workspace with mainMod + SHIFT + [0-9]
|
-- Move active window to a workspace with mainMod + SHIFT + [0-9]
|
||||||
for i = 1, 10 do
|
for i = 1, 10 do
|
||||||
local key = i % 10 -- 10 maps to key 0
|
local key = i % 10 -- 10 maps to key 0
|
||||||
hl.bind(mainMod .. " + SHIFT + " .. key, hl.dsp.window.move({ workspace = i }))
|
hl.bind(mainMod .. " + SHIFT + " .. key, hl.dsp.window.move({ workspace = i }), { desc = "Move window to workspace " .. i })
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Example special workspace (scratchpad)
|
-- Example special workspace (scratchpad)
|
||||||
hl.bind(mainMod .. " + S", hl.dsp.workspace.toggle_special("magic"))
|
hl.bind(mainMod .. " + S", hl.dsp.workspace.toggle_special("magic"), { desc = "Toggle scratchpad" })
|
||||||
hl.bind(mainMod .. " + SHIFT + S", hl.dsp.window.move({ workspace = "special:magic" }))
|
hl.bind(mainMod .. " + SHIFT + S", hl.dsp.window.move({ workspace = "special:magic" }), { desc = "Move window to scratchpad" })
|
||||||
|
|
||||||
-- Scroll through existing workspaces with mainMod + scroll
|
-- Scroll through existing workspaces with mainMod + scroll
|
||||||
hl.bind(mainMod .. " + mouse_down", hl.dsp.focus({ workspace = "e+1" }))
|
hl.bind(mainMod .. " + mouse_down", hl.dsp.focus({ workspace = "e+1" }), { desc = "Next workspace (scroll)" })
|
||||||
hl.bind(mainMod .. " + mouse_up", hl.dsp.focus({ workspace = "e-1" }))
|
hl.bind(mainMod .. " + mouse_up", hl.dsp.focus({ workspace = "e-1" }), { desc = "Previous workspace (scroll)" })
|
||||||
|
|
||||||
|
-- Keybind cheat sheet
|
||||||
|
hl.bind(SUPER_SHIFT .. " + H", hl.dsp.exec_cmd("binds-help.sh"), { desc = "Keybind cheat sheet" })
|
||||||
|
|
||||||
|
-- Workspace overview (macOS Mission Control style). SUPER + Up is registered by
|
||||||
|
-- the hyprshell daemon itself ("Open Overview with Super + Up"); SUPER + Down
|
||||||
|
-- closes the overview again without switching.
|
||||||
|
hl.bind(mainMod .. " + Down", hl.dsp.exec_cmd("overview-close.sh"), { desc = "Close workspace overview" })
|
||||||
|
|
||||||
-- Move/resize windows with mainMod + LMB/RMB and dragging
|
-- Move/resize windows with mainMod + LMB/RMB and dragging
|
||||||
hl.bind(mainMod .. " + mouse:272", hl.dsp.window.drag(), { mouse = true })
|
hl.bind(mainMod .. " + mouse:272", hl.dsp.window.drag(), { mouse = true, desc = "Drag window" })
|
||||||
hl.bind(mainMod .. " + mouse:273", hl.dsp.window.resize(), { mouse = true })
|
hl.bind(mainMod .. " + mouse:273", hl.dsp.window.resize(), { mouse = true, desc = "Resize window" })
|
||||||
|
|
||||||
-- Laptop lid is handled by hypr-lid-power.service (delayed lock/suspend when
|
-- Laptop lid is handled by hypr-lid-power.service (delayed lock/suspend when
|
||||||
-- closed undocked; display/clamshell handling is done by moniqued) instead of
|
-- closed undocked; display/clamshell handling is done by moniqued) instead of
|
||||||
|
|||||||
@@ -39,6 +39,14 @@ hl.config({
|
|||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
|
||||||
|
hl.config({
|
||||||
|
binds = {
|
||||||
|
-- Let SUPER+Left/Right (and scroll) wrap around instead of stopping at the
|
||||||
|
-- edge when cycling workspaces on the active monitor.
|
||||||
|
allow_workspace_cycles = true,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
hl.config({
|
hl.config({
|
||||||
decoration = {
|
decoration = {
|
||||||
rounding = 4,
|
rounding = 4,
|
||||||
|
|||||||
Executable
+31
@@ -0,0 +1,31 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
# Searchable cheat sheet of Hyprland keybindings, shown in wofi.
|
||||||
|
#
|
||||||
|
# The descriptions shown here come from the `desc` option passed to hl.bind()
|
||||||
|
# in ~/.config/hypr/binds.lua, read back at runtime via `hyprctl binds -j`,
|
||||||
|
# so the cheat sheet always matches the live config.
|
||||||
|
set -u
|
||||||
|
|
||||||
|
mods_from_mask() {
|
||||||
|
local mask="$1" out=""
|
||||||
|
(( mask & 1 )) && out="${out:+$out + }SHIFT"
|
||||||
|
(( mask & 4 )) && out="${out:+$out + }CTRL"
|
||||||
|
(( mask & 8 )) && out="${out:+$out + }ALT"
|
||||||
|
(( mask & 64 )) && out="${out:+$out + }SUPER"
|
||||||
|
(( mask & 128 )) && out="${out:+$out + }MOD5"
|
||||||
|
printf "%s" "$out"
|
||||||
|
}
|
||||||
|
|
||||||
|
hyprctl binds -j |
|
||||||
|
jq -rc '.[] | select(.has_description) | select(.description != "") | [.modmask, .key, .description] | @tsv' |
|
||||||
|
while IFS=$'\t' read -r mask key desc; do
|
||||||
|
if (( mask )); then
|
||||||
|
mods="$(mods_from_mask "$mask")"
|
||||||
|
printf '%s + %s\t%s\n' "$mods" "$key" "$desc"
|
||||||
|
else
|
||||||
|
printf '%s\t%s\n' "$key" "$desc"
|
||||||
|
fi
|
||||||
|
done |
|
||||||
|
sort -k1,1 |
|
||||||
|
column -t -s $'\t' |
|
||||||
|
wofi --dmenu --prompt "Hyprland keybinds" >/dev/null
|
||||||
Executable
+16
@@ -0,0 +1,16 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
# macOS-style SUPER+Down: close the hyprshell workspace overview if it is open,
|
||||||
|
# returning to the current workspace without switching.
|
||||||
|
#
|
||||||
|
# hyprshell's overview is a gtk4-layer-shell surface whose namespace is
|
||||||
|
# "hyprshell_overview", and the OpenOverview IPC message toggles the overview
|
||||||
|
# closed when it is already open (see OverviewRootInput::OpenOverview).
|
||||||
|
set -u
|
||||||
|
|
||||||
|
if ! hyprctl layers -j | jq -e '
|
||||||
|
.. | objects | .namespace? // empty | select(. == "hyprshell_overview")
|
||||||
|
' >/dev/null; then
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
hyprshell socat '"OpenOverview"'
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
// Edit with `hyprshell config edit`
|
// Edit with `hyprshell config edit`
|
||||||
(
|
(
|
||||||
version: 3,
|
version: 4,
|
||||||
windows: (
|
windows: (
|
||||||
scale: 8.5,
|
scale: 8.5,
|
||||||
items_per_row: 5,
|
items_per_row: 5,
|
||||||
@@ -69,11 +69,13 @@
|
|||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
key: "Tab",
|
key: "Up",
|
||||||
modifier: "alt",
|
top_offset: 430,
|
||||||
filter_by: [],
|
modifier: "super",
|
||||||
hide_filtered: false,
|
filter_by: [
|
||||||
exclude_special_workspaces: "",
|
current_monitor,
|
||||||
|
],
|
||||||
|
exclude_workspaces: "special:.*",
|
||||||
),
|
),
|
||||||
switch: (
|
switch: (
|
||||||
modifier: "alt",
|
modifier: "alt",
|
||||||
@@ -82,7 +84,8 @@
|
|||||||
current_monitor,
|
current_monitor,
|
||||||
],
|
],
|
||||||
switch_workspaces: false,
|
switch_workspaces: false,
|
||||||
exclude_special_workspaces: "",
|
exclude_workspaces: "",
|
||||||
|
kill_key: 'q',
|
||||||
),
|
),
|
||||||
switch_2: None,
|
switch_2: None,
|
||||||
),
|
),
|
||||||
|
|||||||
Reference in New Issue
Block a user