4

This is not a big issue, but, a little annoying, and, above all intriguing. I run a Debian 9 stable machine with Xfce 4.12 for a while, and I am setting up a GNOME desktop in parallel to try it out.

On Xfce I have a custom keyboard shortcut wmctrl -r :ACTIVE: -b toggle,above that has been working for ever toggling focused windows on top and on same level as others.

I tried the same one on GNOME 3.22 in System settings / Keyboard , I can only toggle the focused window on top of others, it does not toggle it back to same level as other windows. I have to right click the window's frame, and uncheck the "Always on top" option.

Does anyone have any idea why this could happen?

2
  • It was not a big issue ,so thanks for letting me know this does not affect only my system, and in that case, the workaround offered by 林果皞 seems like a good solution.
    – lyndhurst
    Nov 26, 2017 at 15:16
  • 2
    Please don't add [solved] to the title, instead "accept" the answer you have found most useful (by clicking on the tick mark (✓) next to the answer) so others may more easily find it in the future.
    – pomsky
    Nov 27, 2017 at 7:20

2 Answers 2

4

I noticed this too at April 2016, my workaround is use 2 keys to toggle, e.g.:

wmctrl  -r :ACTIVE: -b add,above
wmctrl  -r :ACTIVE: -b remove,above
2

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.

1
  • 1
    You solved it ! Thanks.
    – lleaff
    Nov 28, 2019 at 4:05

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.