diff options
Diffstat (limited to 'bin')
| -rwxr-xr-x | bin/gnome-window-switcher | 72 |
1 files changed, 72 insertions, 0 deletions
diff --git a/bin/gnome-window-switcher b/bin/gnome-window-switcher new file mode 100755 index 0000000..87cbcdc --- /dev/null +++ b/bin/gnome-window-switcher @@ -0,0 +1,72 @@ +#!/bin/sh + +workspace_router_call() { + method="$1" + shift + + command -v gdbus >/dev/null 2>&1 || return 1 + + gdbus call \ + --session \ + --dest name.rbenencia.WorkspaceRouter \ + --object-path /name/rbenencia/WorkspaceRouter \ + --method "name.rbenencia.WorkspaceRouter.$method" \ + "$@" +} + +list_windows_json() { + workspace_router_call ListWindows | + sed -n "s/^('\\(.*\\)',)\$/\\1/p" +} + +activate_window() { + window_id="$1" + workspace_router_call ActivateWindow "uint32:$window_id" >/dev/null +} + +command -v jq >/dev/null 2>&1 || { + echo "gnome-window-switcher: jq is required" >&2 + exit 1 +} + +command -v rofi >/dev/null 2>&1 || { + echo "gnome-window-switcher: rofi is required" >&2 + exit 1 +} + +windows_json=$(list_windows_json) || { + echo "gnome-window-switcher: Workspace Router is unavailable" >&2 + exit 1 +} + +choices=$( + printf '%s\n' "$windows_json" | + jq -r ' + sort_by(.workspace, .appName, .title) + | .[] + | [.id, ("[" + ((.workspace + 1) | tostring) + "]"), (.appName // .wmClass // "Unknown"), (.title // "")] + | @tsv + ' +) + +[ -n "$choices" ] || exit 0 + +# GNOME invokes custom keybindings before the shortcut is fully released. +# Give rofi a moment, then force the keyboard grab and focus takeover. +sleep 0.1 + +selection=$( + printf '%s\n' "$choices" | + cut -f2- | + rofi -dmenu -i -p "window" -format i -no-lazy-grab -steal-focus +) || exit 0 + +window_id=$( + printf '%s\n' "$choices" | + sed -n "$((selection + 1))p" | + cut -f1 +) + +[ -n "$window_id" ] || exit 1 + +activate_window "$window_id" |
