Press the browser key twice, get one browser
The application keys ran their command unconditionally, so pressing the browser key twice gave you two browsers. That is the single most common "Linux feels wrong" moment and it is a twenty-line fix: match the window class, focus it if it is there, launch if it is not. Two details the obvious version gets wrong. Patterns are anchored, because an unanchored "mail" matches gmail-notifier and the mail key would raise somebody's notifier. And class alone is not enough here: the terminal and the editor are both kitty, so the editor bind narrows by title or it raises whatever terminal happened to be open. The contract's fixture contains both traps. Found and fixed a bug this shipped with earlier today. Hyprland 0.56 dispatches through Lua, so `hyprctl dispatch focuswindow address:0x...` is parsed as Lua source and fails with a syntax error -- which is what the launcher's Switch Window command had been doing since it landed. Its own contract stubbed hyprctl and recorded the arguments, so the call looked correct and never ran. Both now use the selector form hl.focus actually accepts, and the contract asserts the shape rather than only that something was dispatched.
This commit is contained in:
@@ -136,13 +136,40 @@ local function write_categories()
|
||||
file:close()
|
||||
end
|
||||
|
||||
-- Focus it if it is already open, start it if it is not -- which is what the
|
||||
-- application keys do on macOS and Windows, and what pressing the browser key
|
||||
-- twice ought to do. bin/panama-launch matches on window class, narrowed by
|
||||
-- title where the class alone cannot tell two things apart: the terminal and
|
||||
-- the editor are both kitty here, so only the title distinguishes them.
|
||||
--
|
||||
-- Patterns are regular expressions and are anchored. An unanchored "mail"
|
||||
-- would match gmail-notifier, and the mail key would raise somebody's notifier
|
||||
-- instead. Single-quoted for the shell so a backslash reaches the matcher
|
||||
-- rather than being eaten on the way.
|
||||
local function shell_quote(value)
|
||||
return "'" .. value:gsub("'", "'\\''") .. "'"
|
||||
end
|
||||
|
||||
local launcher_bin = "$HOME/.local/share/Panama/bin/panama-launch"
|
||||
|
||||
local function launch_or_focus(class, command, title)
|
||||
local parts = { launcher_bin, "--class", shell_quote(class) }
|
||||
if title then
|
||||
parts[#parts + 1] = "--title"
|
||||
parts[#parts + 1] = shell_quote(title)
|
||||
end
|
||||
parts[#parts + 1] = "--"
|
||||
parts[#parts + 1] = command
|
||||
return table.concat(parts, " ")
|
||||
end
|
||||
|
||||
category("Applications")
|
||||
bind(mod .. " + T", hl.dsp.exec_cmd(terminal), { description = "Terminal" })
|
||||
bind(mod .. " + N", hl.dsp.exec_cmd(editor), { description = "Neovim" })
|
||||
bind(mod .. " + W", hl.dsp.exec_cmd(browser), { description = "Browser" })
|
||||
bind(mod .. " + F", hl.dsp.exec_cmd(files), { description = "Files" })
|
||||
bind(mod .. " + C", hl.dsp.exec_cmd(calculator), { description = "Calculator" })
|
||||
bind(mod .. " + E", hl.dsp.exec_cmd(mail), { description = "Mail" })
|
||||
bind(mod .. " + T", hl.dsp.exec_cmd(launch_or_focus("^kitty$", terminal)), { description = "Terminal" })
|
||||
bind(mod .. " + N", hl.dsp.exec_cmd(launch_or_focus("^kitty$", editor, "nvim")), { description = "Neovim" })
|
||||
bind(mod .. " + W", hl.dsp.exec_cmd(launch_or_focus("^helium", browser)), { description = "Browser" })
|
||||
bind(mod .. " + F", hl.dsp.exec_cmd(launch_or_focus("^org\\.gnome\\.Nautilus$", files)), { description = "Files" })
|
||||
bind(mod .. " + C", hl.dsp.exec_cmd(launch_or_focus("^org\\.gnome\\.Calculator$", calculator)), { description = "Calculator" })
|
||||
bind(mod .. " + E", hl.dsp.exec_cmd(launch_or_focus("^org\\.mozilla\\.thunderbird", mail)), { description = "Mail" })
|
||||
bind(mod .. " + I", hl.dsp.exec_cmd(settings), { description = "Settings" })
|
||||
bind("CTRL + SHIFT + Escape", hl.dsp.exec_cmd(sysmonitor), { description = "System monitor" })
|
||||
|
||||
|
||||
@@ -41,7 +41,9 @@ case "${1:-}" in
|
||||
address="$(cut -f1 <<<"$picked")"
|
||||
pid="$(cut -f2 <<<"$picked")"
|
||||
if [[ "$1" == window ]]; then
|
||||
exec hyprctl dispatch focuswindow "address:$address"
|
||||
# The Lua dispatch form. `hyprctl dispatch focuswindow address:0x...`
|
||||
# is read as Lua source on 0.56 and fails with a parse error.
|
||||
exec hyprctl dispatch "hl.dsp.focus({ window = \"address:$address\" })"
|
||||
fi
|
||||
# TERM first; the window still being mapped a moment later means the app
|
||||
# ignored it, which is what force quit exists for.
|
||||
|
||||
Reference in New Issue
Block a user