Well, after a lot of research and working out how to write proper code in bash, I have created a single command that uses the wmctrl commands within a layer of logic to toggle the 'always on top' state effectively on the current GNOME desktop! Behold:
bash -c 'wmctrl -r :ACTIVE: -b $([[ $(xprop -id $(xprop -root -f _NET_ACTIVE_WINDOW 0x " \$0\\n" _NET_ACTIVE_WINDOW | awk "{print \$2}") _NET_WM_STATE) =~ "ABOVE" ]] && echo "remove" || echo "add"),above'
It checks the active window state property "_NET_WM_STATE" using xprops
, and if it contains the text "ABOVE" that means the 'always on top' option is active. Then it just runs the wmctrl
command with the parameter add
or remove
as appropriate.
Command breakdown (each command is inserted into the next, replacing the ■
placeholder):
Get active window id:
xprop -root -f _NET_ACTIVE_WINDOW 0x " \$0\\n" _NET_ACTIVE_WINDOW | awk "{print \$2}"
Get the window state from xprop using the id:
xprop -id $(■) _NET_WM_STATE
Check if the state contains 'ABOVE', indicating that the window is set to 'always on top':
[[ $(■) =~ "ABOVE" ]]
Return "remove" if true, otherwise return "add":
■ && echo "remove" || echo "add"
run wmctrl command using the returned value as a parameter
wmctrl -r :ACTIVE: -b $(■),above
Send the whole thing to bash
so that you can use command substitution ${ ... }
, bash boolean evaluation [[ ... ]]
and the regex match operator =~
bash -c '■'
This last step in particular took me a very long time to figure out. Until I realised that the keyboard shortcuts weren't running in bash by default, I had no idea why the commands were working in the console as I was testing them but silently failing when run directly as a keyboard shortcut. It drove me up the wall for ages!
Note: because you need quotes around the command you're sending to bash, I had to be careful when writing the command that I never went more than one more level deep (using double quotes). Any further nesting of strings in quotes would have required lots of confusing backslashes to escape the quotes.