#!/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"