Xpra: Ticket #336: floating menu + keyboard focus - input grabs

Many applications exhibit strange menu behaviour in Xpra: when menu is opened it stays on top of every other application when task is switched. For example let's open pretty much any application and maximise it. Then in Xpra session start kcalc then click any menu and switch to another application. Kcalc's menu stays opened on top of another (active) application even though main kcalc window is hidden beneath active application.

Even worse on some occasions like when I press Alt+Tab+Tab to switch to second application from task list, key presses are going not to the active application but to the kcalc's hovering menu. It could be another manifestation of #214 that is easier to reproduce.

kcalc is taken as example of a lightweight application to reproduce the problem which I see in many applications.

Wed, 15 May 2013 05:23:40 GMT - Antoine Martin: status changed; milestone set

Yes, this is a known problem, I will try to take another look at it. You are right, it is related to #214.

The problem here is that we don't get notifications from the client's window manager about those task switching events and so as a window manager ourselves, we can't keep in sync. At least, that's what I think is happening. I believe that we should be able to fix this by sending a focus event when our top level window loses focus. (how to get this event is another issue..)

Sun, 23 Jun 2013 16:48:16 GMT - Antoine Martin:

Ignore comment:1, from what I have read this is because when those menus are shown, the toolkit (qt, gtk, whatever) grabs the pointer and expects events to still be delivered when the mouse leaves the menu and we click outside it. (that's why you have to click twice to click on something else: first to lose the grab, then the actual click)


How do we even know that a window has requested a grab? (will need to be recorded and taken into account when the server takes focus from such a window)

Mon, 24 Jun 2013 04:58:20 GMT - Antoine Martin: summary changed

Here is a good summary of the problem: Pop-up menus and XGrabKeyboard/XGrabPointer

And the X11 docs:

Tue, 25 Jun 2013 04:34:27 GMT - Antoine Martin: owner, status changed

This is fixed in r3713 - but this will need some thorough testing (afarr?) to ensure we haven't made things worse with regards to window focus (ie: #214)

Note: there were other changes related to modal windows and focus recently: r3708 (see #356)

(neither are suitable for backport to v0.9.x)

Wed, 26 Jun 2013 21:44:45 GMT - alas:

With xpra 0.10.0 r3725 windows client side and xpra 0.10.0 r3725 fedora 18 server side... yes, I can still get the floating menus (but it isn't easy). In fact, I can get the entire kcalc app to float atop all other apps on the desktop (including a separately running xpra session).

The kcalc app behaves as expected regarding focus until I place it partially overlapping a local app (such as skype), click one of the menus, change focus to the overlapping app window, then roll the mouse back over the kcalc app to scroll over the top set of menu buttons (kcalc has to be overlapping by little enough for the top menu buttons to be exposed to the roaming mouse). At that point, the menu re-engages & pops up over the top of the overlapping app despite the non-kcalc app supposedly having focus.

At that point I can click on other app windows, use alt-tab, whatever I please ... and the kcalc menu will appear over the top of them (full-sized or not is irrelevant). in fact, at that point if I get curious and decide to bring the kcalc app into focus (clicking on it or using alt-tab) then the entire kcalc app overlays all other apps (with its menus overlapping it, in its turn), again- whether I click or use alt-tab to change focus between apps.

The previously described steps to reproduce, involving the maximization of an app prior to the starting of the kcalc app, no longer produce the issue however (if that's any consolation).

In order to initiate this bug, a user seems to have to click on a menu button and then have to switch focus to another overlapping window while the "menu click" is still active on the kcalc app. Simply starting the kcalc app and clicking on any of the menu buttons seems to be interpreted as a "lasting click" (if that makes any sense)... which allows the mouse to then be dragged from menu button to menu button, causing the drop menus to drop without the requirement of another click.

It seems to be this "lasting click" property which remains active even after the app no longer has focus which creates the focus confusion for the xpra/desktop. (Even after the kcalc app loses focus, the "depressed button graphic" remains visible on the kcalc window and later mouse sweeps are then read by the app as if it still had focus.)

Is there a way to send a "false click" message to the kcalc (or whatever) app when focus changes? (It might be a safe idea to do that with any xpra session app, just in case there is a drop menu potentially waiting to be triggered, as long as a "safe" coordinate for the false-click can be determined.)

Ironically, while the File button will often remain "pressed" if it is last swept over by the mouse, drop menus like Constants will often be interpreted as having been "unclicked" at the first item of the drop menu, displaying the mathematics sub-drop-menu and un-displaying the Constants-main-drop-menu. (If the app has hijacked top-status on the desktop these menus will continue to display with any sweep, despite the app's window not having ever re-gained focus. If the overlap bug hasn't come into play, however, these menus and sub menus disappear as soon as the app window loses focus, exactly as expected.)

I wasn't particularly collecting logs while testing the behavior, but if there's a wid logging patch you'd like me to use to catch some logs, let me know.

(By the way, trying with XPRA_KEYBOARD_DEBUG=1 on server side produced none of the mouse click tracking, but it did result in a GIANT cursor on the xpra session xterms.)

Sun, 30 Jun 2013 06:46:54 GMT - Antoine Martin:

I can still get the floating menus (but it isn't easy)

So I guess this is an improvement worth keeping - at least in part.

r3737 should help us detect when we gain/lose focus more accurately.

And now that we have better focus tracking, maybe we can also re-instate the "override-redirect" flag on client windows:

--- src/xpra/client/gtk_base/gtk_client_window_base.py	(revision 3739)
+++ src/xpra/client/gtk_base/gtk_client_window_base.py	(working copy)
@@ -65,6 +65,9 @@
         if self._override_redirect:
+            if self.gdk_window() is None:
+                self.realize()
+            self.gdk_window().set_override_redirect(True)
             transient_for = self.get_transient_for()
             type_hint = self.get_type_hint()
             if transient_for is not None and transient_for.window is not None and type_hint in self.OR_TYPE_HINTS:

Does that work? Any changes or side-effects?

At that point, the menu re-engages & pops up over the top of the overlapping app despite the non-kcalc app supposedly having focus.

That's because as far as the X11 server is concerned (and kcalc), the application still owns the focus since we have not registered a click outside the window.. The workaround of hiding the menu and sending the focus to the root window may or may not be enough for all/some toolkits (clearly not enough for qt).

the "depressed button graphic" remains visible..

That's because the app still thinks it has focus and that the menu is shown (we hid the menu via an ugly workaround).

Is there a way to send a "false click" message to the kcalc

There is: all the clicks we send are faked, but we're not going to do that:

as long as a "safe" coordinate for the false-click can be determined.

"Safe" coordinates cannot really be determined.
Rather than hacking away, what we should do is honour the keyboard/mouse grab and forward that behaviour to the client... (see comment:3) Unfortunately, this was not easy last time I checked because we were not receiving EnterNotify and LeaveNotify events despite setting the correct event masks for the window - but maybe I did it wrong and will need to try that again.

Ironically, while the File button

I did not understand this whole section.

trying with XPRA_KEYBOARD_DEBUG=1 on server side produced none of the mouse click tracking, but it did result in a GIANT cursor...

Are you certain this is what caused it?

Please also see #214 during testing.

Note: I have also detected a new problem with the kcalc popup menus: with monitor hotplugging, we don't update _NET_WORKAREA as we should, so Qt tries to place the menus in the workarea as much as possible.. which may not be close to the actual window! See #349 for details.

Sun, 30 Jun 2013 20:36:13 GMT - onlyjob:

I just tried it again with 0.9.6 and somehow managed to crash client by opening menu in kcalc and dragging kcalc while its menu is visible. This is not very easy to reproduce but I hope that the crash log may reveal some details:

Traceback (most recent call last):
  File "/usr/lib/python2.7/dist-packages/xpra/client.py", line 1367, in _process_configure_override_redirect
    window.move_resize(x, y, w, h)
  File "/usr/lib/python2.7/dist-packages/xpra/client_window.py", line 583, in move_resize
    self.new_backing(w, h)
  File "/usr/lib/python2.7/dist-packages/xpra/client_window.py", line 308, in new_backing
    self._backing = new_backing(self._id, w, h, self._backing, self._client.supports_mmap, self._client.mmap)
  File "/usr/lib/python2.7/dist-packages/xpra/window_backing.py", line 497, in new_backing
    return make_new_backing(backing_class, wid, w, h, backing, mmap_enabled, mmap)
  File "/usr/lib/python2.7/dist-packages/xpra/window_backing.py", line 510, in make_new_backing
    backing.init(w, h)
  File "/usr/lib/python2.7/dist-packages/xpra/window_backing.py", line 345, in init
    assert w<32768 and h<32768, "dimensions too big: %sx%s" % (w, h)
AssertionError: dimensions too big: 165898320x110598880
Traceback (most recent call last):
  File "/usr/lib/python2.7/dist-packages/xpra/client_window.py", line 464, in do_expose_event
    context = self.window.cairo_create()
cairo.Error: invalid value (typically too big) for the size of the input (surface, pattern, etc.)
The program 'Xpra' received an X Window System error.
This probably reflects a bug in the program.
The error was 'BadAlloc (insufficient resources for operation)'.
  (Details: serial 48161 error_code 11 request_code 12 minor_code 0)
  (Note to programmers: normally, X errors are reported asynchronously;
   that is, you will receive the error a while after causing it.
   To debug your program, run it with the --sync command line
   option to change this behavior. You can then get a meaningful
   backtrace from your debugger if you break on the gdk_x_error() function.)

Mon, 01 Jul 2013 13:43:22 GMT - Antoine Martin:

The bug in comment:7 is likely unrelated and has been moved to #364

Sat, 10 Aug 2013 05:36:47 GMT - Antoine Martin: owner, status, milestone changed

Focus and grabs will be a priority for 0.11

Thu, 17 Oct 2013 07:31:35 GMT - Antoine Martin: milestone changed


Thu, 14 Nov 2013 20:12:07 GMT - alas:

Just a note for future work: There are also sites which now have "secondary pop-ups" which xpra is not handling.

To reproduce: go to zillow.com, pick a city to search for home rentals/purchase, mouse over an arrow (a pop-up appears). - With a local browser, clicking on the arrow brings up a second/larger pop-up... but in an xpra session the "secondary pop-up" doesn't appear.

Mon, 03 Feb 2014 16:04:52 GMT - Antoine Martin: status changed; resolution set

Working patch in #139, please follow up there.

(the "secondary pop-ups" from comment:11 may be a separate issue)

Sat, 23 Jan 2021 04:52:02 GMT - migration script:

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