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 700233 - Gtk+ exits on X11 when querying a slave device
Gtk+ exits on X11 when querying a slave device
Status: RESOLVED FIXED
Product: gtk+
Classification: Platform
Component: Class: GdkDevice
3.8.x
Other Linux
: Normal normal
: ---
Assigned To: gtk-bugs
Carlos Garnacho
Depends on:
Blocks:
 
 
Reported: 2013-05-13 15:50 UTC by Lionel Landwerlin
Modified: 2013-05-20 01:22 UTC
See Also:
GNOME target: ---
GNOME version: ---


Attachments
x11: make _gdk_device_query_state report the master's device state (1.35 KB, patch)
2013-05-13 15:58 UTC, Lionel Landwerlin
none Details | Review
x11: make _gdk_device_query_state report the master's device state (1.35 KB, patch)
2013-05-17 12:34 UTC, Lionel Landwerlin
none Details | Review
x11: make _gdk_device_query_state report the master's device state (1.35 KB, patch)
2013-05-17 20:22 UTC, Lionel Landwerlin
committed Details | Review

Description Lionel Landwerlin 2013-05-13 15:50:53 UTC
I'm having a problem with rhythmbox exiting when clicking on the playlist expander on the left of the main window (that collapse/uncollapse the "My Top Rated", "Recently Added", "Recently Played" items).

It turns out the widget controlling this expander tries to query the position of the device (bit weird to me, it could use the event instead...). Anyway, GTK+ shouldn't exit like this.

Here is the backtrace : 

  • #0 g_logv
    from /usr/lib64/libglib-2.0.so.0
  • #1 g_log
    from /usr/lib64/libglib-2.0.so.0
  • #2 _gdk_x11_display_error_event
    at gdkdisplay-x11.c line 2556
  • #3 gdk_x_error
    at gdkmain-x11.c line 303
  • #4 gdk_x_error
    at gdkmain-x11.c line 266
  • #5 _XError
    at XlibInt.c line 1583
  • #6 handle_error
    at xcb_io.c line 212
  • #7 _XReply
    at xcb_io.c line 698
  • #8 XIQueryPointer
    from /usr/lib64/libXi.so.6
  • #9 gdk_x11_device_xi2_query_state
    at gdkdevice-xi2.c line 333
  • #10 gdk_window_x11_get_device_state
    at gdkwindow-x11.c line 3145
  • #11 gdk_window_x11_get_device_state
    at gdkwindow-x11.c line 3132
  • #12 gdk_window_get_device_position
    at gdkwindow.c line 5172
  • #13 gossip_cell_renderer_expander_activate
  • #14 gtk_cell_area_activate_cell
  • #15 gtk_cell_area_real_event
  • #16 gtk_cell_area_real_event
  • #17 gtk_tree_view_button_press
    at gtktreeview.c line 3059
  • #18 rb_tree_dnd_button_press_event_cb
    at rb-tree-dnd.c line 933
  • #19 _gtk_marshal_BOOLEAN__BOXED
    at gtkmarshalers.c line 85
  • #20 g_closure_invoke
    from /usr/lib64/libgobject-2.0.so.0
  • #21 signal_emit_unlocked_R
    from /usr/lib64/libgobject-2.0.so.0
  • #22 g_signal_emit_valist
    from /usr/lib64/libgobject-2.0.so.0
  • #23 g_signal_emit
    from /usr/lib64/libgobject-2.0.so.0
  • #24 gtk_widget_event_internal
    at gtkwidget.c line 6714
  • #25 gtk_widget_event
    at gtkwidget.c line 6371
  • #26 propagate_event_up
    at gtkmain.c line 2393
  • #27 propagate_event
    at gtkmain.c line 2501
  • #28 gtk_main_do_event
    at gtkmain.c line 1716
  • #29 gdk_event_source_dispatch
    at gdkeventsource.c line 364
  • #30 g_main_context_dispatch
    from /usr/lib64/libglib-2.0.so.0
  • #31 g_main_context_iterate.isra.22
    from /usr/lib64/libglib-2.0.so.0
  • #32 g_main_context_iteration
    from /usr/lib64/libglib-2.0.so.0
  • #33 g_application_run
    from /usr/lib64/libgio-2.0.so.0
  • #34 rb_application_run
    at rb-application.c line 637
  • #35 main
    at main.c line 95

Comment 1 Lionel Landwerlin 2013-05-13 15:58:57 UTC
Created attachment 244062 [details] [review]
x11: make _gdk_device_query_state report the master's device state

I've seen other part of the API that just prevent querying anything on slave device like gdk_device_get_position/gdk_device_get_window_at_position but the query state is still accessible through the GdkWindow API.

Maybe with this new approach we could relax the checks in GdkDevice.
Comment 2 Matthias Clasen 2013-05-17 02:43:10 UTC
whats the X error ?

I don't think XIQueryPointer is supposed to give an error for slave devices.
Comment 3 Lionel Landwerlin 2013-05-17 07:32:42 UTC
We get an "X Error: BadDevice, invalid or uninitialized input device".
There is a similar check in gdk_x11_device_xi2_set_window_cursor for example.
Comment 4 Carlos Garnacho 2013-05-17 10:32:11 UTC
Xserver does return BadDevice for that call on slave devices that are attached to a master, as the position is then dependent on the master pointer one, and the button/modifier state can be just a subset of that one too, so that call is only meant to work on master and floating devices.

http://cgit.freedesktop.org/xorg/xserver/tree/Xi/xiquerypointer.c#n104

Although from a look at the rhythmbox code, I see it's not using the source device from the event to query the position, but the device that ought typically to be a master device:

https://git.gnome.org/browse/rhythmbox/tree/widgets/gossip-cell-renderer-expander.c#n326

So are events from slave devices somehow being enabled in rhythmbox? what for? I think the real error is behind that.

As for the patch, I see it worthwhile to have GTK+ fall in less X errors, the right condition though is == GDK_DEVICE_TYPE_SLAVE , the patch as is turns this gdk call into a no-op for floating devices (these never have an associated device)
Comment 5 Lionel Landwerlin 2013-05-17 10:48:41 UTC
How can you enable slave devices?
Comment 6 Carlos Garnacho 2013-05-17 10:54:48 UTC
either calling gdk_window_set_device_events() for a slave device, or more indirectly by doing gdk_device_grab() on a slave device, so it gets temporarily detached from the master and sends events on its own.
Comment 7 Lionel Landwerlin 2013-05-17 11:19:05 UTC
I reproduced that crash without the application ever calling either of these 2 functions...
Comment 8 Carlos Garnacho 2013-05-17 11:21:36 UTC
Ok... after peeking a bit on annotate:

commit 7293b612f96d03f8cc08741bd669ccf21c19b214
Author: Jonathan Matthew <jonathan@d14n.org>
Date:   Sat Apr 13 14:59:34 2013 +1000

    use gdk_event_get_device instead of gdk_event_get_source_device
    
    We don't actually care about physical devices vs virtual devices,
    we just want to know where the pointer was.  Now that we're using
    XI2 (see commit f84a33d), requesting the physical device position
    causes XI_BadDevice errors.
    
    https://bugzilla.gnome.org/show_bug.cgi?id=697915

So fixed in rhythmbox master, the GTK+ patch could still be fine with the change I proposed on comment #4
Comment 9 Lionel Landwerlin 2013-05-17 12:33:45 UTC
Thank you Carlos.

Attaching the new patch. I'm also wondering about a couple of things.

Currently the problem we encounter happens on a gdk_window_get_device_position() call. What about the gdk_device_get_position()/gdk_device_get_state() that ultimately end up calling query_state() on the xi2 backend too? Right now the generic code in gdkdevice.c prints warnings if you call these functions on a slave device. Should it be changed?

GtkTreeView also calls gdk_window_get_device_position() using gdk_event_get_device(). Should that be changed in the same way rhythmbox changed its internal widgets?
Comment 10 Lionel Landwerlin 2013-05-17 12:34:09 UTC
Created attachment 244519 [details] [review]
x11: make _gdk_device_query_state report the master's device state
Comment 11 Lionel Landwerlin 2013-05-17 20:22:33 UTC
Created attachment 244580 [details] [review]
x11: make _gdk_device_query_state report the master's device state

My mistake, wrong condition...
Comment 12 Matthias Clasen 2013-05-18 22:58:59 UTC
Review of attachment 244580 [details] [review]:

ok
Comment 13 Matthias Clasen 2013-05-20 01:22:33 UTC
Attachment 244580 [details] pushed as ea6ac66 - x11: make _gdk_device_query_state report the master's device state