GNOME Bugzilla – Bug 141543
GtkWidget set "realized" before gtk_widget_realize() has finished
Last modified: 2004-12-22 21:47:04 UTC
The GIMP (2.0.1 here) segfaults when i create a new image using an XInput device. The callback gimp_display_shell_canvas_tool_events() (in app/display/gimpdisplayshell-callbacks.c), triggered early by a "configure" event, asks for pointer coordinates. But, despite the canvas' window is created, it isn't appended to the input_windows GList yet. It's only done at the end of gtk_widget_realize() (in gtk/gtkwidget.c), but events are already sent and the widget is marked as REALIZED. The segfault occurs in gdk_input_translate_coordinates(), called by gdk_device_get_state() (both in gdk/x11/gdkinput-x11.c). In gdk_device_get_state(), when the pointer isn't the core pointer, Gdk needs the input window. To achieve this, it uses _gdk_input_window_find(), which returns NULL (because the window isn't in the input_windows list, as said above). When Gtk is compiled in debug mode, the statement "g_return_if_fail (input_window != NULL);" stops the execution with a warning (and the GIMP doesn't complain), but when in non-debug mode, the execution go on and reach gdk_input_translate_coordinates(), which dereferences the NULL pointer. The problem doesn't occur when using the core pointer, because de input_windows list isn't used. In the GIMP, the callback just checks if the canvas' window is ready (which is true) and continues. Maybe it should check the REALIZED flag, considering it's set only when the widget is _really_ ready. As i'm not familiar with Gtk+, the GIMP or XFree/XInput internals, i tried to give as many details as i can. System: XFree 4.3.99.901 Gtk+ 2.4.0 The GIMP 2.0.1 XInput device: Wacom Intuos Graphics Tablet, using wacom(4) XFree driver
Mass changing gtk+ bugs with target milestone of 2.4.2 to target 2.4.4, as Matthias said he was trying to do himself on IRC and was asking for help with. If you see this message, it means I was successful at fixing the borken-ness in bugzilla :) Sorry for the spam; just query on this message and delete all emails you get with this message, since there will probably be a lot.
If this is what causes the diagnostic messages: (gimp-2.0.exe:444): Gdk-CRITICAL **: file gdkinput-win32.c: line 1242 (gdk_devic e_get_state): assertion `input_window != NULL' failed We can reduce the chances of GIMP freezing up in with --use-wintab by eliminating this diagnostic message when it happens. (see Bug #151175)
Processing events in a realize function is in no way valid.
We don't process events in a "realize" callback. We have a "configure_event" callback, and in this callback we check if widget->window is non-NULL before proceeding. IMHO the reporter is right and GTK+ should emit "realize" at the end of gtk_widget_realize(). Owen, what do you think?
In the end, the user is claiming that you are calling gdk_device_get_state() out of this callback. That still doesn't make sense to me. And I'd really suggest not using configure_event callbacks for GtkDrawingArea. It's just a bad attempt on my part years ago to make things more convenient. Connect to realize and/or size_allocate as desired. widget_class->realize is the default handler for the "realize" signal, it isn't a two pass thing. That can't be changed compatibly...
Since this report has been reassigned to GIMP we should probably figure out if we need to do any changes.
We need to do changes to avoid this crash. Setting milestone to 2.2.
Fixed in CVS: 2004-11-09 Michael Natterer <mitch@gimp.org> * app/display/gimpdisplayshell.c (gimp_display_shell_new): don't connect to "event" and don't connect any canvas event to gimp_display_shell_events(). Connect all tool events separately (doesn't include "configure-event" and thus fixes bug #141543). * app/display/gimpdisplayshell-callbacks.c (gimp_display_shell_canvas_tool_events): call gimp_display_shell_events() manually before doing tool event processing. * app/display/gimpdisplayshell.c * app/display/gimpdisplayshell-callbacks.[ch]: connect to "size_allocate" of the canvas, not to "configure_event" (suggested by Owen in bug #141543). * app/display/gimpdisplayshell-callbacks.[ch]: removed gimp_display_shell_popup_menu(). (gimp_display_shell_origin_button_press): emit "popup-menu" on the shell manually instead of calling above function. * app/display/gimpdisplayshell.c: added the whole menu popup code here.