Hyprland
Hyprland copied to clipboard
Dispatcher for alternating between most recent window in the focus history on the current workspace
This issue technically breaks rule about extending Hyprland with scripts, you can close it without reading further (if you're a monster!).
I'm surprised Hyprland doesn't offer functionality to essentially Alt-Tab between windows as seen in KDE, Gnome, Awesome, etc.
At first it seems that a simple solution would be to alternate between cyclenext
and cyclenext, prev
, like so:
#!/usr/bin/env bash
TOGGLE=/tmp/hypr-alt-tab.toggle
if [ ! -e $TOGGLE ]; then
touch $TOGGLE
hyprctl dispatch cyclenext ""
else
rm $TOGGLE
hyprctl dispatch cyclenext prev
fi
But it has issues:
1. Changing workspaces has a chance to break the behavior
2. Changing window focus in any other way has a chance to break the behavior
4. Cosmic rays screwing with the if statement just like they with this list index ;o so you know it's a real issue!
To make an actual, working version would require a somewhat heavy script:
-
Subscribe to socket, listen for
activewindow>>>
, callhyprctl activewindow
to grab the address (not sure why it's not included in the socket message already) -
Segregate history based on workspaces, requires parsing
hyprctl clients
-
Upkeep saved adresses, another parsing of
hyprctl clients
on many socket updates (window moving, killing, etc.) to discard old addresses or move them around based on new workspace
Why? Because I suck at coding and I want you to do it for me. But seriously... this is a pretty basic feature that would greatly benefit Hyprland users if included :')
Progress:
daemon
#!/usr/bin/env bash
previous_window=""
socat - UNIX-CONNECT:/tmp/hypr/$HYPRLAND_INSTANCE_SIGNATURE/.socket2.sock | while read line; do
if [[ ${line:0:12} == "activewindow" ]]; then
current_window=$(hyprctl activewindow | rg 'Window ([A-Fa-f0-9]+)' -or '$1')
if [[ $current_window != $previous_window ]]; then
echo $previous_window > /tmp/hypr-alt-tab
previous_window=$current_window
fi
fi
done
switcher
#!/usr/bin/env bash
target_window=$(cat /tmp/hypr-alt-tab)
hyprctl dispatch focuswindow address:0x$target_window
Issues:
- Doesn't switch to anything if window stored in history is invalid (would be useful if
hyprctl dispatch focuswindow address:fuckingshit
returnedfail
instead ofok
), but fixing that would just require parsinghyprctl clients
and checking if stored window address is in the list, otherwise docyclenext
. - Works across workspaces, which is not actually intended.
After familiarizing myself more with hyprctl
I think I over-complicated stuff in the original post, however I still expect it to become a built-in feature.
I have no real input to give on the matter, but reading your script - hyprctl
has -j
option for json output, which is easier to parse with gojq, especially in case of something long like clients.
# windows I have open
❯ hyprctl clients -j | gojq -r '.[] | .address'
0x662245b0
0x67f9ace0
0x67f79610
# check if window with this address exists, if it does, returns its parameters, empty otherwise
~
❯ target=awd
~
❯ hyprctl clients -j | gojq -r ".[] | select(.address == \"$target\")"
~
❯ target=0x67f79610
~
❯ hyprctl clients -j | gojq -r ".[] | select(.address == \"$target\")"
{
"address": "0x67f79610",
"at": [
0,
0
],
"class": "foot",
"floating": false,
"fullscreen": true,
"fullscreenMode": 1,
"grouped": [],
"monitor": 0,
"pid": 397793,
"pinned": false,
"size": [
2560,
1396
],
"swallowing": null,
"title": "~ - zsh",
"workspace": {
"id": 2,
"name": "2"
},
"xwayland": false
}
So basically
if [[ "$(hyprctl clients -j | gojq -r ".[] | select(.address == \"$target\")")" != "" ]]; then
# switch
fi
etc
would be useful if hyprctl dispatch focuswindow address:fuckingshit returned fail instead of ok
whoa, watch your language.
it is not a bad fucking idea, but for now all keybind handlers (dispatchers) are void
functions so I'd have to make them into bool
s and think when a fail is reasonable.
could probably done in layers :).
I get a nice stoi
now and again. Some blanket argument parsing, printing the intended usage of the furthest parable sub command (hyprctl = worst case) is a tactic.
But the case that triggered the suggestion requires more custom approach. "no window found with address terrible-invocation"
Implemented in #1545