Xpra: Ticket #708: Cannot switch window focus using keyboard on OS X

Cmd-` (backtick) is the default OS X binding for "Move focus to next window." However, this behavior does not work with current (0.14.x) xpra OS X client. Other low-level (lower-level?) keyboard shortcuts work, such as hiding all xpra windows with Cmd-h and quitting xpra with Cmd-q.

In my amateur investigation with -d keyboard and xev, it looks like Cmd-` is being sent to the server and not being processed locally.

So far, I've tried toggling swap keys, as well as binding "Move focus to next window" to other, non-modifier keyboard shortcuts (F19, NumPad?'s *).

Perhaps silly, but I have confirmed that switching windows works with the Windows and Linux clients.

Thank you!



Wed, 08 Oct 2014 02:10:36 GMT - Antoine Martin: owner, status, priority changed; keywords set

I believe that this is a GTK toolkit issue, there is nothing in our code that could intercept keyboard events meant for the host OS.

From what I am reading, it looks like toolkits need to re-inject keyboard events back into the host OS (very strange way of doing things on osx), and for some reason either the other other events don't get passed on, or GTK correctly passes them back to the OS. Just not this one.

Links:

I will try to get a bug report upstream.


Fri, 16 Jan 2015 11:20:39 GMT - Antoine Martin: attachment set

lets keyboard events reach the standard gtk.Window code


Fri, 16 Jan 2015 11:23:18 GMT - Antoine Martin: owner, status changed

@jbylsma: I have OSX 10.5.8 in a VM and command + backtick doesn't do anything here, it could be the odd virtual machine keyboard mapping, or the fact this is an older version of OSX. In any case, I am unable to test the patch above... But maybe you can? I don't see any mention of such a bug against gtk-osx, so this may well be all we need to do. I just can't tell.

@afarr: can you make a build with this patch applied? or even just help me figure out if this key combination is even meant to do anything?


Tue, 10 Feb 2015 02:01:23 GMT - alas:

I'll see about trying to arrange a patch (still having issues with my build vm, which I haven't found enough time to sort out).

I was able to figure out what the command- seems to do. With a 10.6.8 OSX machine the command-tab opens a slide-show for selecting between active applications, with each press of the tab button advancing left to right through the slide-show. With the command button still pressed and the slide-show still displaying, the key allows you to reverse direction and go right to left through the list.

The command-` combination, in itself, doesn't seem to do anything much: with focus on a terminal window it makes the global menu window option flash, and with focus on a finder window it seems to toggle the focus off/on (though not to other finder windows, oddly enough).

I'm guessing he wants the ` key to allow reverse tabbing through xpra session applications?... just a guess though really.


Fri, 13 Feb 2015 04:49:59 GMT - Antoine Martin: owner changed

(re-assigning)


Fri, 20 Feb 2015 22:34:49 GMT - J. Max Mena:

Retested with an OSX 10.10.1 r8647 client against a Fedora 20 r8661 server:

Command + ` functionality does not work in Xpra. I have a feeling it's because the host OS doesn't recognize the command as a valid keyboard shortcut so it doesn't know what to do. For what it's worth the Python keyboard helper produces the following output with the Command and ` keys(no special print with both depressed):

Client:

down/up Meta_L [blank] 65511 55 1 0 ['2'](on up, [] on down)
down/up grave ` 96 50 50 0 0 [](on down and up)

Server(Through Xpra):

down/up Control_L 65507 37 1 0 ['2', 'C'] (down and up)
down/up grave 96 49 0 0 ['2', 'C'] (down and up)

edit: A quick google search produces the following webpage that may be of use:

https://wiki.gnome.org/Projects/GnomeShell/CheatSheet


Tue, 28 Apr 2015 04:31:06 GMT - Antoine Martin: milestone set

I've tried again with virtualbox, no go. I even tried passing through some USB keyboards to the guest, the first one didn't work, with the second one my virtual machine got stuck and had to be rebooted... So I can't do anything about this right now.


Fri, 03 Jul 2015 01:56:00 GMT - Antoine Martin:

See also #906.


Thu, 12 Nov 2015 19:22:30 GMT - J. Max Mena: owner changed

(Ceremonial re-assign; totally not doing this so it looks like I am getting something done. In reality, it was left to afarr by accident; I forgot to re-assign back to you.)

For what it's worth:

You can get identical behavior(what the original ticket is looking for) in XFCE with the meta + tab command. This works as expected in Fedora.


Wed, 02 Nov 2016 14:59:05 GMT - ddally:

I'm able to reproduce this issue with the 0.17.4 Mac client (macOS Sierra) and 0.17.6 server on Ubuntu 16.04. It's not a major problem but it does make dealing with a large amount of remote windows a little more difficult.

Any ideas of what I might try? Happy to gather logs, try test cases, etc.


Wed, 02 Nov 2016 15:00:27 GMT - ddally: cc set


Tue, 15 Nov 2016 03:32:23 GMT - ddally: priority changed

I bumped the priority of this ticket to 'major', as it's somewhat of a headache once a larger number of remote windows are opened. Is anyone else seeing this issue with Mac clients (or NOT seeing the issue with Mac clients)? I'd be happy to help troubleshoot/capture logs.

Thanks, Derek


Tue, 15 Nov 2016 04:22:33 GMT - Antoine Martin: owner changed

@ddally: can you try this patch: attachment/ticket/708/propagate-keyboard-events.patch (just add those two lines) I don't have Mac hardware with me at the moment and the VM I have with me (10.5.8) doesn't do anything when I hit this key combination.. so I cannot test this. FWIW: Command+Tab does work here.

See also #906.


Tue, 15 Nov 2016 06:07:46 GMT - ddally:

Hi -

I applied this patch and reattached the client. Command+` still doesn't have an effect. I tested on an (unpatched) Linux client and see the behavior I'd expect (cycling through Xpra windows).

I tried a couple of other Control and Alt-based key combinations to see if any would provide the same functionality, but none seem to.


Tue, 15 Nov 2016 06:25:19 GMT - Antoine Martin:

OK, just another idea: can you try adding return True or return False at the end of those two key event handling functions? True means we have handled the event so that's unlikely to help, False is the default return value.. so that's also unlikely to help. But worth a try.


Tue, 15 Nov 2016 07:36:14 GMT - ddally:

Hi -

I'm trying to collect some logs on the server side, similar to what @maxmylyn had done earlier with the -d keyboard flag. I'm starting with the working Linux server/Linux client setup, but the lines that are output in the log aren't consistent from one keypress to the next.

Here's a chunk of the logs for the window-switching usecase (Linux client):

2016-11-15 07:23:21,137 handle_key(3,0,Alt_L,65513,64,['mod1']) keyboard_sync=True
2016-11-15 07:23:21,137 handle keycode unpressing 64: key Alt_L
2016-11-15 07:23:21,137 fake_key(64, False)
2016-11-15 07:24:05,424 get_keycode(64, Alt_L, []) native keymap, using unmodified keycode: 64
2016-11-15 07:24:05,424 filtered_modifiers_set([])=
2016-11-15 07:24:05,425 filtered_modifiers_set([])=
2016-11-15 07:24:05,425 handle_key(3,1,Alt_L,65513,64,[]) keyboard_sync=True
2016-11-15 07:24:05,425 handle keycode pressing 64: key Alt_L
2016-11-15 07:24:05,425 fake_key(64, True)
2016-11-15 07:24:05,635 _clear_keys_pressed()
2016-11-15 07:24:06,068 filtered_modifiers_set([])=
2016-11-15 07:24:06,068 filtered_modifiers_set([])=

In the Linux client use case, toggling between windows in the same application works with Alt+Backtick. However, in the logging, I don't see any relevant lines related to the backtick key being depressed. The "_clear_keys_pressed()" and "filtered_modifiers_set([])" are the only lines that appear when backtick is pressed.

Once I understand the logging, I'll hopefully be able to collect/diagnose the Mac use case.


Tue, 15 Nov 2016 07:44:14 GMT - Antoine Martin:

The reason why you're not seeing those keys is that the Linux desktop intercepts them before the client application can see them.

In the macos case, the OS doesn't intercepts them, so either we have to tell it that we didn't handle the keys (return True / False) or we have to re-inject those events into the OS.

For debugging, it's probably best to just log the client side.


Tue, 15 Nov 2016 08:01:39 GMT - ddally:

Hi -

I tried with both return True and return False. Unfortunately no luck there. Will try to capture some Mac client side keyboard logs.


Tue, 15 Nov 2016 16:21:50 GMT - Antoine Martin:

Asked the Command+Backtick shortcut intercepted: Yes, it seems to be generally true.

I don't know offhand how switching windows in response to cmd-backtick is implemented in Cocoa (or ctrl-tab Gnome, for that matter), but I suspect that it's handled by the NSApplication object and that it requires that the Windows menu be managed by that object. There's nothing in GtkosxApplication? to do that. I think that's more likely to be the problem rather than that cmd-backtick is getting eaten by Gtk-2.

As long as your application uses GtkActions? you can configure shortcuts with an accel map. This is demonstrated at line 877 of test-integration.c.

Looks like the fix needs to go in gtk-osx...


Wed, 16 Nov 2016 02:12:47 GMT - ddally:

Hi -

Here are the logs on the Mac client side:

2016-11-15 21:05:03,341 mask_to_names(<flags 0 of type GdkModifierType>)=['mod2']
2016-11-15 21:05:03,341 parse_key_event(<gtk.gdk.Event at 0xdf1acc8: GDK_KEY_PRESS keyval=Meta_L>, True)=<GTKKeyEvent object, contents: {'modifiers': ['mod2'], 'group': 0, 'string': '', 'keyname': 'Meta_L', 'pressed': True, 'keyval': 65511, 'keycode': 55}>
2016-11-15 21:05:03,341 handle_key_action(GLClientWindow(3 : gtk2.GLWindowBacking(3, (660, 488), None)), <GTKKeyEvent object, contents: {'modifiers': ['mod2'], 'group': 0, 'string': '', 'keyname': 'Meta_L', 'pressed': True, 'keyval': 65511, 'keycode': 55}>) wid=3
2016-11-15 21:05:03,342 send_key_action(3, <GTKKeyEvent object, contents: {'modifiers': ['mod2'], 'group': 0, 'string': '', 'keyname': 'Meta_L', 'pressed': True, 'keyval': 65511, 'keycode': 55}>)
2016-11-15 21:05:03,460 mask_to_names(<flags GDK_MOD2_MASK | GDK_META_MASK of type GdkModifierType>)=['mod2']
2016-11-15 21:05:03,461 parse_key_event(<gtk.gdk.Event at 0xdf1acc8: GDK_KEY_PRESS keyval=grave>, True)=<GTKKeyEvent object, contents: {'modifiers': ['mod2'], 'group': 0, 'string': '`', 'keyname': 'grave', 'pressed': True, 'keyval': 96, 'keycode': 50}>
2016-11-15 21:05:03,461 handle_key_action(GLClientWindow(3 : gtk2.GLWindowBacking(3, (660, 488), None)), <GTKKeyEvent object, contents: {'modifiers': ['mod2'], 'group': 0, 'string': '`', 'keyname': 'grave', 'pressed': True, 'keyval': 96, 'keycode': 50}>) wid=3
2016-11-15 21:05:03,461 send_key_action(3, <GTKKeyEvent object, contents: {'modifiers': ['mod2'], 'group': 0, 'string': '`', 'keyname': 'grave', 'pressed': True, 'keyval': 96, 'keycode': 50}>)
2016-11-15 21:05:03,555 mask_to_names(<flags GDK_MOD2_MASK | GDK_META_MASK of type GdkModifierType>)=['mod2']
2016-11-15 21:05:03,555 parse_key_event(<gtk.gdk.Event at 0xdf1acc8: GDK_KEY_RELEASE keyval=grave>, False)=<GTKKeyEvent object, contents: {'modifiers': ['mod2'], 'group': 0, 'string': '`', 'keyname': 'grave', 'pressed': False, 'keyval': 96, 'keycode': 50}>
2016-11-15 21:05:03,555 handle_key_action(GLClientWindow(3 : gtk2.GLWindowBacking(3, (660, 488), None)), <GTKKeyEvent object, contents: {'modifiers': ['mod2'], 'group': 0, 'string': '`', 'keyname': 'grave', 'pressed': False, 'keyval': 96, 'keycode': 50}>) wid=3
2016-11-15 21:05:03,556 send_key_action(3, <GTKKeyEvent object, contents: {'modifiers': ['mod2'], 'group': 0, 'string': '`', 'keyname': 'grave', 'pressed': False, 'keyval': 96, 'keycode': 50}>)
2016-11-15 21:05:03,603 mask_to_names(<flags GDK_MOD2_MASK | GDK_META_MASK of type GdkModifierType>)=['mod2']
2016-11-15 21:05:03,603 parse_key_event(<gtk.gdk.Event at 0xdf1acc8: GDK_KEY_RELEASE keyval=Meta_L>, False)=<GTKKeyEvent object, contents: {'modifiers': ['mod2'], 'group': 0, 'string': '', 'keyname': 'Meta_L', 'pressed': False, 'keyval': 65511, 'keycode': 55}>
2016-11-15 21:05:03,603 handle_key_action(GLClientWindow(3 : gtk2.GLWindowBacking(3, (660, 488), None)), <GTKKeyEvent object, contents: {'modifiers': ['mod2'], 'group': 0, 'string': '', 'keyname': 'Meta_L', 'pressed': False, 'keyval': 65511, 'keycode': 55}>) wid=3
2016-11-15 21:05:03,604 send_key_action(3, <GTKKeyEvent object, contents: {'modifiers': ['mod2'], 'group': 0, 'string': '', 'keyname': 'Meta_L', 'pressed': False, 'keyval': 65511, 'keycode': 55}>)

It looks like John's suggestion would be to add an accel map for MacOS builds. The toggling of windows within an application seems like a general-enough use case that it'd be something that GTK should abstract away, no?

What would be a good example of another GTK-based MacOS app to test? I had thought that Pidgin would be a good option but it looks like it's not supported (or at least not recommended) for MacOS.


Wed, 16 Nov 2016 05:05:47 GMT - Antoine Martin:

Other apps that use gtk-osx with pygtk2 - AFAIK:

etc..


Fri, 09 Dec 2016 15:08:41 GMT - ddally:

Hi -

Here's a minimal program to demonstrate the behavior:

#include <gtk/gtk.h>
int main(int argc, char* argv[]) {
  gtk_init(&argc, &argv);
  gtk_widget_show(gtk_window_new(GTK_WINDOW_TOPLEVEL));
  gtk_widget_show(gtk_window_new(GTK_WINDOW_TOPLEVEL));
  gtk_main();
  return 0;
}

Toggling windows works with a Linux-based Xpra client, but not a Mac-based one. Another possibly interesting note is that window cycling does work correctly with XQuartz (vanilla X forwarding as opposed to Xpra) from a Linux machine.

It does seem that if GtkosxApplication provides the translation from GTK to NSApplication that that would be the logical place for the window toggling functionality to exist.

Is toggling windows within an application a seldom-used use case? I would have thought that it would be core functionality for gtk-osx.

Thanks, Derek


Wed, 28 Mar 2018 05:50:03 GMT - Antoine Martin:

Is toggling windows within an application a seldom-used use case? I would have thought that it would be core functionality for gtk-osx.

I don't use macos often enough to know. To get this issue resolved, I think the best way is to follow up here: gtk-osx-users list


Tue, 07 Jul 2020 18:15:21 GMT - Mateusz Szygenda:

Hello guys,

I decided to give this issue a try and did some digging. I was able to verify that the issue indeed lies within GTK and that Xpra does not take any part in it.

I prepared a fix in GTK codebase that resolves the issue, yet I am waiting for some approval from GTK maintainers (not sure if it'll go through). If you'd like to follow that please have a look here:

https://gitlab.gnome.org/GNOME/gtk/-/issues/2914


Wed, 08 Jul 2020 09:48:52 GMT - Antoine Martin: owner changed

I prepared a fix in GTK codebase that resolves the issue ...

Great stuff! Thanks for doing this.

Will I need to change the return value for the keyboard handler in xpra?

I could apply your patch to our build of GTK, but I can't seem to find a way to download the changes in patch format easily in gitlab. Can you attach the patch here?


Wed, 08 Jul 2020 10:40:34 GMT - Mateusz Szygenda: attachment set

GTK patchfor event propagation for GTK3.24


Wed, 08 Jul 2020 10:41:56 GMT - Mateusz Szygenda:

I attached the patch to this issue.

I didn't have to make any changes to Xpra to get this working locally.


Thu, 09 Jul 2020 07:34:50 GMT - Antoine Martin:

I attached the patch to this issue.

Thanks!

Merged into our GTK moduleset in r26930. We can remove once it is merged upstream.

There's a build with this change in the beta area: https://xpra.org/beta/osx

Please close the ticket if it works for you.


Thu, 09 Jul 2020 11:06:26 GMT - Mateusz Szygenda:

I don't see a dmg with "r26930" in it's name in that folder. Sure that version was built? I downloaded some dmg with today's date but it doesn't seem to include the fix.


Thu, 09 Jul 2020 16:06:14 GMT - Antoine Martin:

I don't see a dmg with "r26930" in its name in that folder.

The r26929 builds were meant to have this change included: I built them manually just before I committed the patch.

I downloaded some dmg with today's date but it doesn't seem to include the fix.

Weird. It should be included in the first of today's build (r26929).

I've just re-built everything and posted r26933 builds. Does that work any better for you?


Thu, 09 Jul 2020 17:52:47 GMT - jbylsma:

I can confirm that Cmd-` switches between Windows with r26933 builds (timestamped 2020-07-09 17:04). However, it looks like the ` is subsequently being passed through on the window it was switched from; opening two xterm windows and switching between them enters a à character to the terminal. xev in the xterm registers a ` (grave). Enabling "Control/Command Key Swap" triggers a bell and appears to be returning ^@ but I'm less confident there. I'm not up on my terminal escape codes but they seem like the modifier keys + ` are just being passed through.

I'm also running an older Xpra server (v4.0.1-r26379, Ubuntu 20.04 LTS), which could be impacting behavior. I should be able to test an upgraded server later.

(sorry for the radio silence, Trac emails went to spam during the first year of the issue).


Sat, 11 Jul 2020 19:36:08 GMT - Mateusz Szygenda:

Yup, new build r26933 seem to include the fix and works fine.

Regarding xterm issue mentioned. I think this will depend on the app (whether it handles the CMD+, CTRL+ somehow (like xterm which puts à in the terminal)). It seems however most of the apps just ignore it and work just fine.

Question whether xpra should not forward certain key-events to the application should be I guess well-discussed. Maybe solution to that would be introducing similar mode to the Cmd/Ctrl? key swap. But instead swapping it could ignore key-events that include Cmd key? So that all mac key-shortcuts are left to the OS? I think this should definitely be left to the user's decision (some could see that as a bug).


Sun, 12 Jul 2020 10:22:57 GMT - Mateusz Szygenda:

Actually it looks that such functionality could be achieved already with key-shortcuts that xpra let you define.

@jbylsma just add these two parameters to xpra as you run it:

--key-shortcut=meta+grave:void --key-shortcut=ctrl+grave:void

Mon, 13 Jul 2020 01:41:03 GMT - jbylsma:

Confirmed that modifier+grave keyboard shortcuts prevent keyboard input from being passed to the Xpra applications and successfully alternate between windows.

Thank you!!


Mon, 13 Jul 2020 07:10:15 GMT - Antoine Martin: owner, status changed

Confirmed that modifier+grave keyboard shortcuts prevent keyboard input from being passed to the Xpra applications and successfully alternate between windows.

Shouldn't we be making this the default on MacOS then? Any reason not to?


Mon, 13 Jul 2020 11:48:35 GMT - Mateusz Szygenda:

IMO Sounds like a reasonable default for OSX clients.

I would extend the list by meta+shift+grave, ctrl+shift+grave. Which does the same thing but in the other direction.


Mon, 13 Jul 2020 14:49:47 GMT - jbylsma:

The shift equivalents may not be required; Meta+Shift+Grave and Ctrl+Shift+Grave appear to function properly (reverse order switch windows) and do not passthrough input when using --key-shortcut=meta+grave:void --key-shortcut=ctrl+grave:void.

(tested with applications that didn't reveal input, see following comment)


Mon, 13 Jul 2020 15:02:14 GMT - jbylsma:

Previous comment is incorrect, I tested with application that didn't reveal input.

Using --key-shortcut=shift+meta+grave:void --key-shortcut=shift+ctrl+grave:void functions correctly (reverse order switch windows) but appears to pass input through.


Thu, 16 Jul 2020 12:16:22 GMT - Antoine Martin:

but appears to pass input through.

That's odd, it shouldn't: handle_key_action does not call process_key_event if key_handled_as_shortcut returns True.

I've added those 4 shortcuts to the default macos config: r26983. (new beta builds posted here: https://xpra.org/beta/osx/)

If that doesn't help then maybe the key event is different from what you expect? (perhaps shift is modifying grave into something else?) Try running with -d keyboard. I can't really do this myself because I only run macos in virtualbox, and the key events often get messed up by the virtualization layer.


Thu, 16 Jul 2020 16:40:18 GMT - jbylsma:

Yes, of course it gets modified to something else, a tilde. I feel very silly.

I verified that windows are switched without passthrough on the previous beta (without default shortcuts) and the current beta (with default shortcuts) using the following:

I thinking through the bindings, I don't believe we need the ctrl equivalents. If the ctrl/cmd swap is enabled, core OSX bindings (Cmd-Q, Cmd-H) still function as expected, setting up the expectation that cmd-grave would function similarly. I would not expect ctrl+grave to cycle through windows (nor would it without additional configuration). Additionally, if a user wanted to pass through cmd+grave through Xpra, they could do so by enabling the swap and pressing ctrl+grave.

Mateusz Szygenda mentioned some cmd behavior modifications in comment:30. The idea of having OSX be able to capture all cmd input, overriding system bindings, could be beneficial when xpra has a full desktop environment with many modifier bindings. That is well above and beyond the scope of this ticket and probably not easily feasible.


Thu, 16 Jul 2020 17:00:55 GMT - Antoine Martin: owner, status changed

So, are we all happy with the GTK patch + r26987? (new beta build posted)

Can we finally close this ticket? It only took 6 years! Thanks everyone for sticking by, and Mateusz Szygenda for the GTK patch.


Thu, 16 Jul 2020 17:22:32 GMT - jbylsma: status changed; resolution set

I'm happy: confirmed that new beta build of https://github.com/Xpra-org/xpra/commit/64619d33a3d21d5edab2bff0e1af01077cccd149"fixed," please change if I've overstepped my bounds.

Thank you!


Sat, 23 Jan 2021 05:03:37 GMT - migration script:

this ticket has been moved to: https://github.com/Xpra-org/xpra/issues/708