GNOME Bugzilla – Bug 735749
gnome-software: Can't switch between screenshots
Last modified: 2014-09-23 00:50:23 UTC
+++ This bug was initially created as a clone of Bug #735712 +++ Clicking on the small thumbnails does nothing, the big screenshot stays the same. I know you know about this issue, but I'm filing it here anyway - we should really fix this before 3.14!
The cloned bug has a patch that shows this has something to do with event masks on the window-widget we stuff in the listbox rows. Setting the mask explicitly fixes things.
*** Bug 736167 has been marked as a duplicate of this bug. ***
This has turned out to be a lot more interesting than I initially expected, it actually turns out to be a quite old bug in GDK, uncovered by a combination of factors. - Since recently, it seems that the toplevel window input shape is updated quite more frequently, after any style/state change, each time the input shape is updated, _gdk_synthesize_crossing_events_for_geometry_change() is triggered - In the specific situation of the gnome-software screenshots, there is a parent window with button/motion/crossing masks set, and a child window per-row with just the exposure mask set. When clicking, the former window gets an implicit grab (with !owner_events), the latter is kept as window_under_pointer within GDK. - When clicking the button, the input shape also changes, triggering crossing events checks for the window, when the implicit grab is already set up. - get_pointer_window() from gdkwindow.c is ultimately called, but due to the existing !owner_events grab, and the grab/under_pointer windows being different, NULL is returned. The windows differ and GDK_LEAVE_EVENT is synthesized on button_press. - gtk_list_box_leave_notify_event() is triggered with a GDK_CROSSING_NORMAL event, and unsets the active row, so button_release() is ineffective. I think the gist of the bug is get_pointer_window() not checking that pointer_under_window can be actually a child of the grab window, in which case, it should be still returned. I'm attaching a patch that does that, it makes gnome-software 3.12.2 run fine with both gtk+ 3.12 and master.
Created attachment 286305 [details] [review] gdkwindow: check grab window and children on get_pointer_window() If !owner_events, the pointer window has been usually set to NULL if the pointer fell outside the grabbing widget, but it was not being checked that the pointer_window is actually a child of the grab window, in which case it should be obtained as if ungrabbed.
That patch fixes at least all the problems I had, thanks :)
Thanks for the analysis, Carlos. I think we should probably hold this patch for .1, since this is tricky material, and we've already worked around the problem in gnome-software.
Attachment 286305 [details] pushed as f964373 - gdkwindow: check grab window and children on get_pointer_window()