Extract notification window focus helper

This commit is contained in:
David Heinemeier Hansson
2026-05-21 11:44:11 +02:00
parent d132e0ec61
commit e5b585d6b3
2 changed files with 29 additions and 10 deletions
+23
View File
@@ -0,0 +1,23 @@
#!/bin/bash
# omarchy:summary=Focus a Hyprland window by application class
# omarchy:args=<app-name>
# omarchy:examples=omarchy hyprland focus app Slack
usage() {
echo "Usage: omarchy-hyprland-focus-app <app-name>" >&2
exit 1
}
app=${1:-}
[[ -n $app ]] || usage
address=$(
hyprctl clients -j 2>/dev/null |
jq -r --arg name "${app,,}" \
'[.[] | select((.class // "") | ascii_downcase | startswith($name))] | first.address // empty'
)
[[ -n $address ]] || exit 1
hyprctl dispatch focuswindow "address:$address" >/dev/null
+6 -10
View File
@@ -16,6 +16,7 @@ Item {
// Injected by omarchy-shell (the first-party service loader).
property var shell: null
property string omarchyPath: Quickshell.env("OMARCHY_PATH")
readonly property string home: Quickshell.env("HOME")
// History + DND live under XDG_STATE_HOME: they're persistent user state
// (history of received notifications, last-set DND preference), not
@@ -361,18 +362,13 @@ Item {
}
// Try to focus an existing Hyprland window matching the notification's
// sender. We shell out to a small bash one-liner because Hyprland's class
// matcher is regex-based but its case-sensitivity is implementation-
// defined (std::regex doesn't reliably honor `(?i)`). Easier to query the
// client list ourselves and pick the first match.
// sender. The helper handles case-insensitive class matching.
function focusApp(entry) {
if (!entry || !entry.app) return
var lower = String(entry.app).toLowerCase()
focusAppProc.command = ["bash", "-lc",
"hyprctl clients -j 2>/dev/null | " +
"jq -r --arg name " + Util.shellQuote(lower) + " " +
"'[.[] | select((.class // \"\") | ascii_downcase | startswith($name))] | first.address // empty' | " +
"xargs -r -I{} hyprctl dispatch focuswindow address:{}"]
focusAppProc.command = [
service.omarchyPath + "/bin/omarchy-hyprland-focus-app",
String(entry.app)
]
focusAppProc.running = true
}