After an evaluation, GNOME has moved from Bugzilla to GitLab. Learn more about GitLab.
No new issues can be reported in GNOME Bugzilla anymore.
To report an issue in a GNOME project, go to GNOME GitLab.
Do not go to GNOME Gitlab for: Bluefish, Doxygen, GnuCash, GStreamer, java-gnome, LDTP, NetworkManager, Tomboy.
Bug 735749 - gnome-software: Can't switch between screenshots
gnome-software: Can't switch between screenshots
Status: RESOLVED FIXED
Product: gtk+
Classification: Platform
Component: .General
unspecified
Other Linux
: Normal normal
: ---
Assigned To: gtk-bugs
gtk-bugs
: 736167 (view as bug list)
Depends on: 735712
Blocks:
 
 
Reported: 2014-08-31 15:13 UTC by Matthias Clasen
Modified: 2014-09-23 00:50 UTC
See Also:
GNOME target: ---
GNOME version: ---


Attachments
gdkwindow: check grab window and children on get_pointer_window() (1.11 KB, patch)
2014-09-16 15:41 UTC, Carlos Garnacho
committed Details | Review

Description Matthias Clasen 2014-08-31 15:13:19 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!
Comment 1 Matthias Clasen 2014-08-31 15:14:02 UTC
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.
Comment 2 Matthias Clasen 2014-09-06 16:08:37 UTC
*** Bug 736167 has been marked as a duplicate of this bug. ***
Comment 3 Carlos Garnacho 2014-09-16 15:40:49 UTC
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.
Comment 4 Carlos Garnacho 2014-09-16 15:41:31 UTC
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.
Comment 5 Timm Bäder 2014-09-16 17:04:44 UTC
That patch fixes at least all the problems I had, thanks :)
Comment 6 Matthias Clasen 2014-09-17 02:33:40 UTC
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.
Comment 7 Matthias Clasen 2014-09-23 00:50:18 UTC
Attachment 286305 [details] pushed as f964373 - gdkwindow: check grab window and children on get_pointer_window()