I've found out that it is not possible to run glade in my KDE desktop with widget style oxygen-gtk. If I click on the new window icon from toolbar glage immeadiately crashes with SIGSEGV. glade creates a GDK_WINDOW_OFFSCREEN window and oxygen-gtk wants to get frame extents for this window. The problem is that it is not possible to get frame extents of an offscreen window. I guess, this problem is related to those lines from oxygen-gtk "TODO" 44: Gtk3-Demo -> offscreen pixmap -> effects 45: crash. However, my gtk3-demo doesn't have 'offscreen pixmap' menu. My version of gtk3-demo have 'Offscreen windows' -> Effects and it works. (glade doesn't work) The foloowing lines are copied from glade, gtk and oxygen-gtk sources. The lines show steps to crash. 1. glade creates an attributes for offscreen window glade_design_layout_realize() : gladeui/glade-design-layout.c : 1630 attributes.window_type = GDK_WINDOW_OFFSCREEN; 2. glade_design_layout_realize() : gladeui/glade-design-layout.c : 1644 ipriv->offscreen_window = gdk_window_new (gtk_widget_get_root_window (widget), &attributes, attributes_mask); 3. gdk_window_new () : gdk/gdkwindow.c 11375 if (gdk_window_is_offscreen (window)) { _gdk_offscreen_window_new (window, attributes, attributes_mask); 4. Private helper function gdk_window_is_offscreen() : gdk/gdkwindow.c : 11375 static gboolean gdk_window_is_offscreen (GdkWindow *window) { return window->window_type == GDK_WINDOW_OFFSCREEN; } 5. _gdk_offscreen_window_new() : gdk/gdkoffscreenwindow.c : 803 window->impl = g_object_new (GDK_TYPE_OFFSCREEN_WINDOW, NULL); 6. gdk_offscreen_window_class_init() : gdk/gdkoffscreenwindow.c : 766 impl_class->get_frame_extents = NULL; -- Set implementation function to NULL. (IMHO it is not a good idea.) -- And finally. 7. Gtk::gdk_toplevel_get_frame_size() : src/oxygengtkutils.cpp : 882 gdk_window_get_frame_extents( topLevel, &rect ); 8. gdk_window_get_frame_extents() : gdk/gdkwindow.c : 10443 GDK_WINDOW_IMPL_GET_CLASS (window->impl)->get_frame_extents (window, rect); -- Ooops, get_frame_extents is NULL here Reproducible: Always Steps to Reproduce: 1. run glade 2. click on the Window icon from Toplevels toolbar Actual Results: glade crashes Expected Results: a new window item appears in glade work area I found this bug on Fedora 16 x86_64 with following configuration: oxygen-gtk3-1.0.4-1.fc16.x86_64 gtk3-3.2.4-1.fc16.x86_64 glade3-3.10.0-6.fc16.x86_64 backtrace: #0 0x0000000000000000 in ?? () #1 0x00007fa524b0f9c6 in gdk_toplevel_get_frame_size (h=0x7fff8f06a904, w=0x7fff8f06a900, window=<optimized out>) at /usr/src/debug/oxygen-gtk3-1.0.4/src/oxygengtkutils.cpp:882 #2 Oxygen::Gtk::gdk_toplevel_get_frame_size (window=<optimized out>, w=0x7fff8f06a900, h=0x7fff8f06a904) at /usr/src/debug/oxygen-gtk3-1.0.4/src/oxygengtkutils.cpp:868 #3 0x00007fa524b0fd25 in Oxygen::Gtk::gdk_window_map_to_toplevel (window=0x18cbd80 [GdkX11Window], x=0x7fff8f06a908, y=0x7fff8f06a90c, w=0x7fff8f06a900, h= 0x7fff8f06a904, frame=true) at /usr/src/debug/oxygen-gtk3-1.0.4/src/oxygengtkutils.cpp:747 #4 0x00007fa524b2ba4e in gdk_map_to_toplevel (frame=<optimized out>, h=<optimized out>, w=<optimized out>, y=<optimized out>, x=<optimized out>, widget=<optimized out>, window=<optimized out>) at /usr/src/debug/oxygen-gtk3-1.0.4/src/oxygengtkutils.h:117 #5 Oxygen::Style::renderWindowBackground (this=0xde2000, context=0x3e7b8a7860, window=0x18cbd80 [GdkX11Window], widget=0x0, x=0, y=0, w=440, h=250, options= ..., tiles=...) at /usr/src/debug/oxygen-gtk3-1.0.4/src/oxygenstyle.cpp:264 #6 0x00007fa524b77af5 in renderWindowBackground (tiles=<optimized out>, o=..., h=0, w=0, y=0, x=0, window=0x18cbd80 [GdkX11Window], context=0x3e7b8a7860, this=<optimized out>) at /usr/src/debug/oxygen-gtk3-1.0.4/src/oxygenstyle.h:141 #7 Oxygen::render_background (engine=<optimized out>, context=0x3e7b8a7860, x=0, y=0, w=440, h=250) at /usr/src/debug/oxygen-gtk3-1.0.4/src/oxygenthemingengine.cpp:311 #8 0x0000003e733d080e in gtk_render_background (context=0x1a8b030 [GtkStyleContext], cr=0x3e7b8a7860, x=0, y=0, width=440, height=250) at gtkstylecontext.c:3740 #9 0x0000003e7349ade8 in gtk_window_draw (widget=0xf04470 [GtkWindow], cr=0x3e7b8a7860) at gtkwindow.c:7449 #10 0x0000003e733529d8 in _gtk_marshal_BOOLEAN__BOXED (closure=0xd68d30, return_value=0x7fff8f06b0e0, n_param_values=<optimized out>, param_values=0x1efacd0, invocation_hint=<optimized out>, marshal_data=<optimized out>) at gtkmarshalers.c:85 #11 0x0000003e7347ccf0 in gtk_widget_draw_marshaller (closure=0xd68d30, return_value=0x7fff8f06b0e0, n_param_values=2, param_values=0x1efacd0, invocation_hint=<optimized out>, marshal_data=<optimized out>) at gtkwidget.c:819 #12 0x0000003e6be0ea44 in g_closure_invoke (closure=0xd68d30, return_value=0x7fff8f06b0e0, n_param_values=2, param_values=0x1efacd0, invocation_hint=<optimized out>) at gclosure.c:774 #13 0x0000003e6be20b7c in signal_emit_unlocked_R (node=<optimized out>, detail=0, instance=0xf04470, emission_return=0x7fff8f06b240, instance_and_params= 0x1efacd0) at gsignal.c:3310 #14 0x0000003e6be29f33 in g_signal_emit_valist (instance=<optimized out>, signal_id=<optimized out>, detail=<optimized out>, var_args=<optimized out>) at gsignal.c:3013 #15 0x0000003e6be2a302 in g_signal_emit (instance=<optimized out>, signal_id=<optimized out>, detail=<optimized out>) at gsignal.c:3060 #16 0x0000003e7348e46a in _gtk_widget_draw_internal (clip_to_size=1, cr=0x3e7b8a7860, widget=0xf04470 [GtkWindow]) at gtkwidget.c:5722 #17 _gtk_widget_draw_internal (widget=0xf04470 [GtkWindow], cr=0x3e7b8a7860, clip_to_size=<optimized out>) at gtkwidget.c:5698 #18 0x0000003e7348e5b1 in gtk_widget_send_expose (widget=0xf04470 [GtkWindow], event=<optimized out>) at gtkwidget.c:5969 #19 0x0000003e73352879 in gtk_main_do_event (event=0x7fff8f06b450) at gtkmain.c:1801 #20 0x0000003e72634c0f in _gdk_window_process_updates_recurse (window=0x18cbd80 [GdkX11Window], expose_region=0xf57740) at gdkwindow.c:3857 #21 0x0000003e72634baf in _gdk_window_process_updates_recurse (window=0x18cbc60 [GdkX11Window], expose_region=0x18e9130) at gdkwindow.c:3830 #22 0x0000003e726341df in gdk_window_process_updates_internal (window=0x18cbc60 [GdkX11Window]) at gdkwindow.c:4013 #23 0x0000003e72634650 in gdk_window_process_all_updates () at gdkwindow.c:4144 #24 0x0000003e732ccc56 in gtk_container_idle_sizer (data=<optimized out>) at gtkcontainer.c:1664 #25 0x0000003e7261a38f in gdk_threads_dispatch (data=0x1ad4900) at gdk.c:754 #26 0x0000003e69e44f3d in g_main_dispatch (context=0xd9ca20) at gmain.c:2441 #27 g_main_context_dispatch (context=0xd9ca20) at gmain.c:3011 #28 0x0000003e69e45738 in g_main_context_iterate (context=0xd9ca20, block=<optimized out>, dispatch=1, self=<optimized out>) at gmain.c:3089 #29 0x0000003e69e45c85 in g_main_loop_run (loop=0x1052e80) at gmain.c:3297 #30 0x0000003e7335198d in gtk_main () at gtkmain.c:1362 #31 0x00000000004087cc in main (argc=1, argv=0x7fff8f06b948) at main.c:187
Created attachment 71684 [details] proposed patch I'm not sure where fix this bug. I usually choose the way of minimal changes therefore I added a special casing for offscreen windows to oxygen-gtk code.
> gdk_offscreen_window_class_init() : gdk/gdkoffscreenwindow.c : 766 > impl_class->get_frame_extents = NULL; Great... so they think we should know that for some windows the methods aren't implemented... especially if this is undocumented. Your patch looks good, but... doesn't this look like a GTK bug? Have you asked GTK devs what they think of this?
You are right, it looks like a GTK bug. But, according to the following comment from gtk/gtkoffscreenwindow.c file: * GtkOffscreenWindow derives from #GtkWindow only as an implementation * detail. Applications should not use any API specific to #GtkWindow * to operate on this object. It should be treated as a #GtkBin that * has no parent widget. it is an intention to not treat an offscreen window as "general window". (now I doubt about correctness of my patch, but I saw similar lines in gtk code) I haven't asked GTK devs ... I'm going to talk to someone from GTK on monday. As I wrote in details, I do think that implementation should always implement all of the inherited methods (if they want to simulate OOP in C they should simulate everything and only subset of features) ... I saw about a dozen of unimplemented methods in offscreen window impl and I bet they won't be willing to implement all of them. (IMHO it doesn't make sense to implement only get_frames_extent() function )
Ruslan ? So what's the plan ? Push the patch ? Resolve as Upstream ? (that is not a fix) ? I think pushing the patch is good. Alternatively, we can actually check if the underlying function is actually implemented or not (similar to what's done in oxygenanimations, l245 or so, in current gtk3 branch, namely: ) GtkWidgetClass* widgetClass = GTK_WIDGET_GET_CLASS( widget ); if( widgetClass && widgetClass->style_updated ) {...}
Well, if you are good with more and more hacks here, push it :) More seriously, I think we'll not get gtk devs to fix this on their side so I guess we'll have to do this. So, I'm ok with pushing this patch.
I send an email to gtk-devel-list 14 days ago but the email wasn't approved after a week of waiting :( therefore I've created a bug for gtk 3 and I proposed a patch for this bug ... https://bugzilla.gnome.org/show_bug.cgi?id=678369
@Ruslan ... I guess Jakub's patch (to oxygen-gtk3) is actually less hacky than mine so I'd rather push his. (to minimize hacks) @Jakub, The patch you submitted to gtk3 is impressive and cool. Keep us posted if it ever gets pushed.
I spent about 4 hours with coding and testing but I have never believed that the patch can be accepted :D
... mmm unless I misunderstood, I cannot reproduce with glade3 version 3.8.2 and gtk3 version 3.5.2 See: http://wstaw.org/m/2012/06/21/plasma-desktoppF2751.png (after clicking from new project on the leftmost button (first row) below TopLevel). What do I miss ?
From glade git: commit ebd9b9a5c28b5ec50c29c19f3b7f8f6d83ed93ac Author: Juan Pablo Ugarte <jp@synctv.com> Date: Wed Jan 12 16:20:13 2011 -0300 Experimental offscreen GladeDesignLayout commit 121840b6082224fd5444af1eca61f9234b726eba Author: Tristan Van Berkom <tristan.van.berkom@gmail.com> Date: Tue Feb 1 19:56:07 2011 +0900 ... NEWS +Glade 3.9.2 ... + - Added support for editing a GtkOffscreenWindow ... So I guess, you have to use at least glade 3.9.2. I wrote glade3-3.10.0-6.fc16.x86_64 to bug description.
And as you may see here https://bugs.launchpad.net/ubuntu/+source/anjuta/+bug/982645 glade is not the only app which uses offscreen windows.
Git commit 99da2cf5a71b99d268ddee12c4b1c8ad678172ca by Hugo Pereira Da Costa. Committed on 21/06/2012 at 17:50. Pushed by hpereiradacosta into branch 'gtk3'. do not call gdk_window_get_frame_extents on OFFSCREEN_WINDOWS, because underlying function is not implemented, which results in crash. M +15 -4 src/oxygengtkutils.cpp http://commits.kde.org/oxygen-gtk/99da2cf5a71b99d268ddee12c4b1c8ad678172ca
Git commit 9ae5ad4fe0f393b8ebcda1050ee0a19e3da18650 by Hugo Pereira Da Costa. Committed on 21/06/2012 at 17:50. Pushed by hpereiradacosta into branch 'gtk3-1.0'. do not call gdk_window_get_frame_extents on OFFSCREEN_WINDOWS, because underlying function is not implemented, which results in crash. M +15 -4 src/oxygengtkutils.cpp http://commits.kde.org/oxygen-gtk/9ae5ad4fe0f393b8ebcda1050ee0a19e3da18650
So ... fixed. As for the actual gtk3 bug, a 'simpler' patch, that might get accepted would be to just check for the validity of the get_frame_extents function pointer in the wrapper function gdk_window_get_frame_extents, dump an error string and leave the rect unchanged. At least this would result in no crash. Closing. Thanks for tracking this down, reporting, and providing the patch (that's ideal bug report I'd say. Wish we had more like these :))