From 0add5af1b92d9a45f312b4b881a3377c984426b3 Mon Sep 17 00:00:00 2001 From: Gabriel Brown Date: Thu, 29 Oct 2026 13:56:53 -0400 Subject: [PATCH] Load the whole config again under Hyprland 0.57 Hyprland 0.57 refuses a bind on a bare modifier and an empty input:scroll_method. The switcher's Super-release commit now binds Super_L and Super_R, which also brings back every bind below it in keybinds.lua. An empty scroll method is left unwritten, so libinput still picks per device. --- config/dot/hypr/input.lua | 20 ++++++++++++-------- config/dot/hypr/keybinds.lua | 15 +++++++++------ config/dot/quickshell/services/Keybinds.qml | 10 +++++----- 3 files changed, 26 insertions(+), 19 deletions(-) diff --git a/config/dot/hypr/input.lua b/config/dot/hypr/input.lua index f4fbbc3..554bc89 100644 --- a/config/dot/hypr/input.lua +++ b/config/dot/hypr/input.lua @@ -8,6 +8,14 @@ local prefs = require("prefs") local actions = require("actions") +-- Empty means "let libinput pick per device". Hyprland 0.57 rejects "" for +-- this option, so empty is expressed by not writing it at all: nil drops the +-- key from the table below and the option stays at its unset default. +local scroll_method = prefs.get("scrollMethod", "") +if scroll_method == "" then + scroll_method = nil +end + hl.config({ input = { kb_layout = prefs.get("keyboardLayout", "us"), @@ -52,16 +60,12 @@ hl.config({ scroll_factor = prefs.get("scrollFactor", 1.0), left_handed = prefs.get("leftHanded", false), - -- Empty is a value, not an omission: it is what `hyprctl getoption` - -- reports as "[[EMPTY]]" before anything writes the option, and it means - -- "let libinput pick per device" -- two fingers on a touchpad, the wheel - -- on a mouse. Writing it back explicitly is the same branch a stock - -- Hyprland takes, and it keeps the setting reversible: without an empty - -- choice in the schema there would be no way back from a scroll method - -- once one was picked. Settings offers 2fg / edge / on_button_down / + -- Empty (omitted, see above) is what `hyprctl getoption` reports as + -- "[[EMPTY]]": libinput picks per device -- two fingers on a touchpad, + -- the wheel on a mouse. Settings offers 2fg / edge / on_button_down / -- no_scroll alongside it, the four words the option's own description -- names (it publishes no map). - scroll_method = prefs.get("scrollMethod", ""), + scroll_method = scroll_method, -- Only consulted while scroll_method is on_button_down. 0 means the -- device's own middle button. diff --git a/config/dot/hypr/keybinds.lua b/config/dot/hypr/keybinds.lua index 33fd3b6..f414968 100644 --- a/config/dot/hypr/keybinds.lua +++ b/config/dot/hypr/keybinds.lua @@ -377,15 +377,18 @@ bind(mod .. " + SHIFT + N", hl.dsp.window.resize({ x = 0, y = step, relative = t -- The gesture needs three binds, not two. Tab steps the selection, and the -- switch is only COMMITTED when the modifier is released -- which is the sole -- way the compositor can tell the gesture is finished. That release bind is on --- the bare modifier, so it fires on EVERY Super release in the session; the --- handler returns immediately when no switch is open, which is why this is --- affordable. +-- the Super keys themselves, so it fires on EVERY Super release in the +-- session; the handler returns immediately when no switch is open, which is +-- why this is affordable. -- --- The release bind carries no description on purpose: it is not a shortcut --- anyone would look up or rebind, and the Shortcuts page lists what it finds. +-- A modifier-only bind has to name the keysym (Super_L / Super_R). Hyprland +-- 0.57 rejects a chord that is a bare modifier ("A bind requires a trigger"), +-- and the error stops this file, costing every bind below it. bind(mod .. " + Tab", hl.dsp.exec_cmd(qs("switcher", "next")), { description = "Next window" }) bind(mod .. " + SHIFT + Tab", hl.dsp.exec_cmd(qs("switcher", "previous")), { description = "Previous window" }) -bind(mod, hl.dsp.exec_cmd(qs("switcher", "commit")), { release = true, description = "Commit window switch" }) +for _, key in ipairs({ "Super_L", "Super_R" }) do + bind(mod .. " + " .. key, hl.dsp.exec_cmd(qs("switcher", "commit")), { release = true, description = "Commit window switch" }) +end -- Jump back to the previously focused window. bind(mod .. " + SHIFT + grave", hl.dsp.focus({ last = true }), { description = "Last window" }) diff --git a/config/dot/quickshell/services/Keybinds.qml b/config/dot/quickshell/services/Keybinds.qml index 9eccfe4..0c0b411 100644 --- a/config/dot/quickshell/services/Keybinds.qml +++ b/config/dot/quickshell/services/Keybinds.qml @@ -487,11 +487,11 @@ Singleton { if ((bind.modmask & modifier.bit) !== 0) parts.push(modifier.name.toUpperCase()); } - // A modifier-only bind has no key at all -- the window switcher commits - // on Super RELEASE. Appending an empty string left a dangling "SUPER + " - // that matched neither the chord hypr/keybinds.lua binds nor the one an - // override would be keyed by, so that bind could never be rebound and - // never found its category. + // Guard against a bind with no key. Hyprland 0.57 refuses to create + // one (the switcher's Super-release commit now names Super_L/Super_R), + // but appending an empty string would leave a dangling "SUPER + " that + // matches neither the chord hypr/keybinds.lua binds nor the one an + // override would be keyed by. const key = String(bind.key ?? ""); if (key !== "") parts.push(key);