Open shell menus and panels through Hyprland global shortcuts (#13418)

Every binding that opened a menu or panel ran omarchy-menu or
omarchy-shell, which starts a qs client just to deliver one IPC call:
~60ms before the shell heard about the keypress.

The shell now registers a Hyprland global shortcut for each menu route
and panel in default/omarchy/shortcuts, and o.bind turns { menu = ... }
and { panel = ... } into hl.dsp.global for those, so a keypress spawns
nothing. A route or panel missing from the list binds through the
command as before. The default menu and panel bindings use the new form.

SUPER+SPACE opens the menu in ~31ms instead of ~94ms, measured from a
simulated keypress until the menu layer maps.

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
David Heinemeier HanssonandClaude Opus 5.5 authored and GitHub committed 2026-09-27 18:02:01 +02:00
1 parent fd961e5300
commit 6762769bbf
9 files changed
+251 -22

No files matched your search

+46
View File
@@ -1,6 +1,7 @@
import QtQuick
import QtQml.Models
import Quickshell
import Quickshell.Hyprland
import Quickshell.Io
import qs.Commons
@@ -1513,6 +1514,51 @@ ShellRoot {
}
}
// ------------------------------------------------------ global shortcuts
//
// Bindings that open a menu route or panel dispatch these through Hyprland,
// so a keypress reaches the shell without spawning an omarchy-shell IPC
// client. The list is shared with default/hypr/helpers.lua, which binds a
// route or panel missing from it through the command instead.
function parseShortcuts(raw) {
var entries = []
var lines = String(raw || "").split("\n")
for (var i = 0; i < lines.length; i++) {
var match = /^([A-Za-z]+)\s+(\S+)\s*$/.exec(lines[i])
if (match && (match[1] === "menu" || match[1] === "panel"))
entries.push({ kind: match[1], target: match[2], name: match[1] + "." + match[2] })
}
return entries
}
function runShortcut(entry) {
if (entry.kind === "menu")
shell.toggle("omarchy.menu", JSON.stringify({ menu: entry.target }))
else
shell.toggle(entry.target, "{}")
}
FileView {
id: shortcutsFile
path: shell.omarchyPath + "/default/omarchy/shortcuts"
watchChanges: true
onFileChanged: reload()
}
Variants {
model: shell.parseShortcuts(shortcutsFile.text())
GlobalShortcut {
required property var modelData
appid: "omarchy"
name: modelData.name
description: modelData.kind === "menu" ? "Toggle the " + modelData.target + " menu" : "Toggle the " + modelData.target + " panel"
onPressed: shell.runShortcut(modelData)
}
}
// --------------------------------------------------- image selector IPC
function imagePickerItem() {