GNOME Bugzilla – Bug 723085
Clutter's event handling can get "stuck" under ClutterGTK+
Last modified: 2021-06-10 11:31:22 UTC
Created attachment 267287 [details] Gtk app showing the problem. Run it in i3wm, click the red area, notice the fourth event is triggered only when the mouse is moved afterwards! The effect of this bug is that under i3wm the mouse button released event is sent late to Clutter.Actors in a GtkClutter.Embed (as soon as the mouse is moved after the click). I'm not an expert in this matter, I just want the app to work. Your help is appreciated. It can be argued whether this is an i3wm bug or a Gtk bug, especially considering that this problem shows up only under i3wm, but please continue reading. i3wm's Michael sais it's a problem with Gtk because "Java’s toolkit needs WM_TAKE_FOCUS" and Gtk should not be confused by the extra WM_TAKE_FOCUS messages i3wm sends. I checked whether sending WM_TAKE_FOCUS messages is legal according to the spec. The relevant paragraph about when the WM_TAKE_FOCUS should be sent is in the "Input Focus" section in http://www.x.org/releases/X11R7.7/doc/xorg-docs/icccm/icccm.html#Input_Focus: """A client could receive WM_TAKE_FOCUS when opening from an icon or when the user has clicked outside the top-level window in an area that indicates to the window manager that it should assign the focus (for example, clicking in the headline bar can be used to assign the focus).""" As I understand, it does not specify any limit on when or how many WM_TAKE_FOCUS can be sent. Reading about how the app should respond to the WM_TAKE_FOCUS messages, I imagine making a change to Gtk's WM_TAKE_FOCUS handling should not be very difficult: """Windows with the atom WM_TAKE_FOCUS in their WM_PROTOCOLS property may receive a ClientMessage event from the window manager (as described in ClientMessage Events. ) with WM_TAKE_FOCUS in its data[0] field and a valid timestamp (i.e., not CurrentTime) in its data[1] field. If they want the focus, they should respond with a SetInputFocus request with its window field set to the window of theirs that last had the input focus or to their default input window, and the time field set to the timestamp in the message. For further information, see Input Focus""" Also, I noticed this problem happens only with a Clutter.Actor in a GtkClutter.Embed, see the attached script. Maybe it's a problem with Clutter that the button-release message is sent late? See below the description of what i3wm does with WM_TAKE_FOCUS, copy/pasted from: http://bugs.i3wm.org/report/ticket/1167#comment:7 * When managing a new window, i3 checks whether the program lists WM_TAKE_FOCUS in its WM_PROTOCOLS atom. * For windows where that is true, whenever focus is changed to that window, i3 will send a WM_TAKE_FOCUS ClientMessage. Depending on the WM_HINTS atom, it will either set focus, too (hints.input=1) or not set focus at all and rely on the client responding to the WM_TAKE_FOCUS ClientMessage (hints.input=0) * When the user clicks on a window, focus is explicitly set to that window again, i.e. a WM_TAKE_FOCUS ClientMessage is sent. Since X11 clients can arbitrarily change focus, this is the simplest solution to make sure that click to focus works properly. I’m not sure if other window managers rather track focus accurately, but it seems to me that this behavior should not disturb the toolkit, no matter whether i3 is the only WM which does it…
So this is a fun bug. Normally, Clutter dispatches events like GDK does: it receives a new event from Xlib's queue, translates it to a Clutter event, and then acts on it. This is through an GSource, which constantly queries for events: https://git.gnome.org/browse/clutter/tree/clutter/x11/clutter-event-x11.c#n239 However, not all Clutter events are translated directly from X11 events. Clients can synthesize fake Clutter events and put them on the queue with _clutter_event_push(). Normally, this case is taken care of because the GSource check also includes clutter_events_pending(). However, ClutterGTK+ does not use this GSource. It disables X11 event retrieval, and instead, it uses a GDK event filter function with clutter_x11_handle_event(): https://git.gnome.org/browse/clutter/tree/clutter/x11/clutter-event-x11.c#n141 Looking at it, I can spot an already see an obvious bug: if the event queue isn't empty when clutter_x11_handle_event is called, then it will process a few events, and then lag behind the latest events that were generated. Why is the event queue not empty? Because FocusIn, as generated by your WM_TAKE_FOCUS, generates a synthesized CLUTTER_EVENT_STAGE_STATE event. It isn't directly translated, so the fallback "goto out;" path is taken and the event queue isn't pumped. I can think of a few fixes: 1. The quick fix would be to have clutter_x11_handle_event() just always pump the event queue until it's out of events. 2. Insert a GSource into ClutterGTK+ to make sure it's always pumping events, so that any external user who synthesizes additional events with e.g. clutter_event_put() will have their events dispatched as well. This would be the cleaner fix, and at the same time we should probably remove the pumping from clutter_x11_handle_event() anyway.
(In reply to comment #1) > I can think of a few fixes: > 1. The quick fix would be to have clutter_x11_handle_event() just always pump > the event queue until it's out of events. > 2. Insert a GSource into ClutterGTK+ to make sure it's always pumping events, Any Clutter developer having this on the to-do list?
(In reply to comment #2) > (In reply to comment #1) > > I can think of a few fixes: > > 1. The quick fix would be to have clutter_x11_handle_event() just always pump > > the event queue until it's out of events. > > 2. Insert a GSource into ClutterGTK+ to make sure it's always pumping events, > > Any Clutter developer having this on the to-do list? no, not that I know of.
[Removing outdated "GNOME target" value.]
GNOME is going to shut down bugzilla.gnome.org in favor of gitlab.gnome.org. As part of that, we are mass-closing older open tickets in bugzilla.gnome.org which have not seen updates for a longer time (resources are unfortunately quite limited so not every ticket can get handled). If you can still reproduce the situation described in this ticket in a recent and supported software version of clutter, then please follow https://wiki.gnome.org/GettingInTouch/BugReportingGuidelines and create a ticket at https://gitlab.gnome.org/GNOME/clutter/-/issues/ Thank you for your understanding and your help.