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 340401 - critical warnings when using window groups
critical warnings when using window groups
Status: RESOLVED FIXED
Product: gtk+
Classification: Platform
Component: Printing
unspecified
Other Linux
: Normal critical
: ---
Assigned To: gtk-bugs
: 340789 341112 (view as bug list)
Depends on:
Blocks: 340612
 
 
Reported: 2006-05-02 12:54 UTC by Christian Persch
Modified: 2011-02-04 16:10 UTC
See Also:
GNOME target: ---
GNOME version: ---


Attachments
testcase as patch for print-editor.c (718 bytes, text/plain)
2006-05-02 12:55 UTC, Christian Persch
  Details
Minimal testcase (1.32 KB, text/x-csrc)
2006-05-05 14:14 UTC, Alexander Larsson
  Details
Possible solution (1.10 KB, patch)
2006-05-05 14:57 UTC, Alexander Larsson
none Details | Review
Fix for gtkprintunixdialog.c part of the bug (3.56 KB, patch)
2006-05-05 15:12 UTC, Alexander Larsson
none Details | Review
Possible fix (4.93 KB, patch)
2006-05-12 13:26 UTC, Alexander Larsson
none Details | Review
New approach (6.44 KB, patch)
2006-05-12 15:33 UTC, Alexander Larsson
none Details | Review
Another approach (5.48 KB, application/octet-stream)
2006-05-12 15:45 UTC, Soren Sandmann Pedersen
  Details
The right patch, hopefully (1.42 KB, application/octet-stream)
2006-05-12 15:51 UTC, Soren Sandmann Pedersen
  Details

Description Christian Persch 2006-05-02 12:54:40 UTC
When you use a window which has a window group as parent for a print dialogue, you get loads of critical warnings when the printer list is populated, and when closing the dialogue.

(lt-print-editor:16209): Gtk-CRITICAL **: gtk_window_group_remove_window: assertion `window->group == window_group' failed

Trace from the 1st one:
  • #0 g_log
    at gmessages.c line 516
  • #1 g_return_if_fail_warning
    at gmessages.c line 532
  • #2 gtk_window_group_remove_window
    at gtkwindow.c line 7120
  • #3 gtk_window_set_transient_for
    at gtkwindow.c line 1862
  • #4 gtk_window_destroy
    at gtkwindow.c line 3934
  • #5 g_cclosure_marshal_VOID__VOID
    at gmarshal.c line 77
  • #6 g_type_class_meta_marshal
    at gclosure.c line 567
  • #7 g_closure_invoke
    at gclosure.c line 490
  • #8 signal_emit_unlocked_R
    at gsignal.c line 2554
  • #9 g_signal_emit_valist
    at gsignal.c line 2197
  • #10 g_signal_emit
    at gsignal.c line 2241
  • #11 gtk_object_dispose
    at gtkobject.c line 418
  • #12 gtk_widget_dispose
    at gtkwidget.c line 6779
  • #13 gtk_window_dispose
    at gtkwindow.c line 1799
  • #14 g_object_run_dispose
    at gobject.c line 571
  • #15 gtk_object_destroy
    at gtkobject.c line 403
  • #16 gtk_widget_destroy
    at gtkwidget.c line 2064
  • #17 gtk_menu_destroy
    at gtkmenu.c line 973
  • #18 g_cclosure_marshal_VOID__VOID
    at gmarshal.c line 77
  • #19 g_type_class_meta_marshal
    at gclosure.c line 567
  • #20 g_closure_invoke
    at gclosure.c line 490
  • #21 signal_emit_unlocked_R
    at gsignal.c line 2554
  • #22 g_signal_emit_valist
    at gsignal.c line 2197
  • #23 g_signal_emit
    at gsignal.c line 2241
  • #24 gtk_object_dispose
    at gtkobject.c line 418
  • #25 gtk_widget_dispose
    at gtkwidget.c line 6779
  • #26 g_object_unref
    at gobject.c line 1734
  • #27 g_value_object_free_value
    at gobject.c line 1882
  • #28 g_value_unset
    at gvalue.c line 155
  • #29 g_signal_emit_valist
    at gsignal.c line 2226
  • #30 g_signal_emit
    at gsignal.c line 2241
  • #31 gtk_container_remove
    at gtkcontainer.c line 991
  • #32 gtk_widget_dispose
    at gtkwidget.c line 6771
  • #33 g_object_unref
    at gobject.c line 1734
  • #34 gtk_menu_detach
    at gtkmenu.c line 1177
  • #35 gtk_combo_box_finalize
    at gtkcombobox.c line 4978
  • #36 g_object_unref
    at gobject.c line 1762
  • #37 g_object_run_dispose
    at gobject.c line 572
  • #38 gtk_object_destroy
    at gtkobject.c line 403
  • #39 gtk_widget_destroy
    at gtkwidget.c line 2064
  • #40 gtk_printer_option_widget_set_source
    at gtkprinteroptionwidget.c line 363
  • #41 setup_option
    at gtkprintunixdialog.c line 857
  • #42 selected_printer_changed
    at gtkprintunixdialog.c line 1065
  • #43 g_cclosure_marshal_VOID__BOOLEAN
    at gmarshal.c line 111
  • #44 g_closure_invoke
    at gclosure.c line 490
  • #45 signal_emit_unlocked_R
    at gsignal.c line 2438
  • #46 g_signal_emit_valist
    at gsignal.c line 2197
  • #47 g_signal_emit_by_name
    at gsignal.c line 2265
  • #48 cups_request_ppd_cb
    at gtkprintbackendcups.c line 1201
  • #49 cups_dispatch_watch_dispatch
    at gtkprintbackendcups.c line 549
  • #50 g_main_context_dispatch
    at gmain.c line 1916
  • #51 g_main_context_iterate
    at gmain.c line 2547
  • #52 g_main_loop_run
    at gmain.c line 2751
  • #53 gtk_dialog_run
    at gtkdialog.c line 1027
  • #54 _gtk_print_operation_platform_backend_run_dialog
    at gtkprintoperation-unix.c line 298
  • #55 gtk_print_operation_run
    at gtkprintoperation.c line 1341
  • #56 do_print
    at print-editor.c line 418
  • #57 g_cclosure_marshal_VOID__VOID
    at gmarshal.c line 77
  • #58 g_closure_invoke
    at gclosure.c line 490
  • #59 signal_emit_unlocked_R
    at gsignal.c line 2438
  • #60 g_signal_emit_valist
    at gsignal.c line 2197
  • #61 g_signal_emit
    at gsignal.c line 2241
  • #62 _gtk_action_emit_activate
    at gtkaction.c line 862
  • #63 gtk_action_activate
    at gtkaction.c line 889
  • #64 g_cclosure_marshal_VOID__VOID
    at gmarshal.c line 77
  • #65 g_closure_invoke
    at gclosure.c line 490
  • #66 signal_emit_unlocked_R
    at gsignal.c line 2438
  • #67 g_signal_emit_valist
    at gsignal.c line 2197
  • #68 g_signal_emit
    at gsignal.c line 2241
  • #69 gtk_widget_activate
    at gtkwidget.c line 3838
  • #70 gtk_menu_shell_activate_item
    at gtkmenushell.c line 1057
  • #71 gtk_real_menu_shell_activate_current
    at gtkmenushell.c line 1302
  • #72 g_cclosure_marshal_VOID__BOOLEAN
    at gmarshal.c line 111
  • #73 g_type_class_meta_marshal
    at gclosure.c line 567
  • #74 g_closure_invoke
    at gclosure.c line 490
  • #75 signal_emit_unlocked_R
    at gsignal.c line 2476
  • #76 g_signal_emitv
    at gsignal.c line 2109
  • #77 gtk_binding_entry_activate
    at gtkbindings.c line 535
  • #78 binding_match_activate
    at gtkbindings.c line 955
  • #79 gtk_bindings_activate_list
    at gtkbindings.c line 1089
  • #80 gtk_bindings_activate_event
    at gtkbindings.c line 1166
  • #81 gtk_menu_shell_key_press
    at gtkmenushell.c line 730
  • #82 gtk_menu_key_press
    at gtkmenu.c line 2736
  • #83 _gtk_marshal_BOOLEAN__BOXED
    at gtkmarshalers.c line 83
  • #84 g_type_class_meta_marshal
    at gclosure.c line 567
  • #85 g_closure_invoke
    at gclosure.c line 490
  • #86 signal_emit_unlocked_R
    at gsignal.c line 2476
  • #87 g_signal_emit_valist
    at gsignal.c line 2207
  • #88 g_signal_emit
    at gsignal.c line 2241
  • #89 gtk_widget_event_internal
    at gtkwidget.c line 3807
  • #90 gtk_propagate_event
    at gtkmain.c line 2153
  • #91 gtk_main_do_event
    at gtkmain.c line 1420
  • #92 gdk_event_dispatch
    at gdkevents-x11.c line 2314
  • #93 g_main_context_dispatch
    at gmain.c line 1916
  • #94 g_main_context_iterate
    at gmain.c line 2547
  • #95 g_main_loop_run
    at gmain.c line 2751
  • #96 gtk_main
    at gtkmain.c line 999
  • #97 main
    at print-editor.c line 685

Comment 1 Christian Persch 2006-05-02 12:55:23 UTC
Created attachment 64660 [details]
testcase as patch for print-editor.c
Comment 2 Alexander Larsson 2006-05-05 12:37:11 UTC
I think the problem is that we set transient_for after we create a GtkComboBox and put it in the dialog. We then destroy the combobox, causing it to destroy its popup window. At that time we've set the right transient_for for the dialog, but the popup window has the old wrong transient_for.
Comment 3 Alexander Larsson 2006-05-05 14:13:50 UTC
No, I changed the order and this is still happening. I think the problem is this in gtk_menu_popdown():

  /* The X Grab, if present, will automatically be removed when we hide
   * the window */
  gtk_widget_hide (menu->toplevel);
  gtk_window_group_add_window (gtk_window_get_group (NULL), GTK_WINDOW (menu->toplevel));

This always sets the window group of the toplevel to the default group when its destroyed. However, we earlier set transient_for on the toplevel, so when that gets destroyed we do:

static void
gtk_window_destroy (GtkObject *object)
{
  GtkWindow *window = GTK_WINDOW (object);
  
  toplevel_list = g_slist_remove (toplevel_list, window);

  if (window->transient_parent)
    gtk_window_set_transient_for (window, NULL);

... leading to: 

gtk_window_unset_transient_for  (GtkWindow *window)
{
  if (window->transient_parent)
    {
      if (window->transient_parent->group)
	gtk_window_group_remove_window (window->transient_parent->group,
					window);


But the transient parent is still in the custom window group, while the menu toplevel is in the default group, which crashes on the assert in gtk_window_group_remove_window().

I'm attaching a small testcase for this.

Comment 4 Alexander Larsson 2006-05-05 14:14:44 UTC
Created attachment 64861 [details]
Minimal testcase
Comment 5 Alexander Larsson 2006-05-05 14:26:06 UTC
I think this is a menu issue. In gtk_menu_popup() we set the menu window group to the same as the parent menushells window group, and on gtk_menu_popdown we set it to the default group. But at the same time we also set transient_fo for on the menu toplevel which also sets the window group. This then causes a conflict.
Comment 6 Alexander Larsson 2006-05-05 14:57:22 UTC
Created attachment 64865 [details] [review]
Possible solution

It seems gtk_menu_popup only sets the window group if the menu is popped up from a parent menuitem (i.e. parent_menu_shell != NULL), but it always sets it back to the default group. This patch makes it only switch back if we had a parent menushell.

I don't know if this is right, but it seems to make things work at least.
Comment 7 Alexander Larsson 2006-05-05 15:12:42 UTC
Created attachment 64866 [details] [review]
Fix for gtkprintunixdialog.c part of the bug

My initial analysis is also right. The previous patch fixes the testcase, but the print dialog still crashes. This patch fixes that by making the transient-for window a construct property and creating the comboboxes (and other widgets) after the transient-for is set.

Maybe the transient-for construct property should be on GtkWindow or GtkDialog though. I'm not sure why e.g. gtk_file_chooser_dialog_new_valist don't pass the parent as a construct property like the other args.
Comment 8 Matthias Clasen 2006-05-05 15:41:29 UTC
The menu changes look good.

The gtkprintunixdialog changes look fine to me, 
modulo moving the property up the chain.

We discussed moving the transient parent property up to GtkDialog,
but it should probably be a GtkWindow property, even. 
Comment 9 Matthias Clasen 2006-05-06 12:46:13 UTC
*** Bug 340789 has been marked as a duplicate of this bug. ***
Comment 10 Alexander Larsson 2006-05-12 09:49:53 UTC
I commited this, moving the transient-for property to GtkWindow.
Comment 11 Kjartan Maraas 2006-05-12 10:07:19 UTC
*** Bug 341112 has been marked as a duplicate of this bug. ***
Comment 12 Alexander Larsson 2006-05-12 13:15:55 UTC
It seems this isn't really fixed yet. This is causing a crash in evolution when closing the composer window.
Comment 13 Alexander Larsson 2006-05-12 13:21:14 UTC
So, what happens in evolution is that the window gets destroyed, and then a plug inside the window gets unparented, causing it to change its window group. Then a menu inside the plug gets the hierarchy-changed signal on its attached window ( gtkmenu.c:attach_widget_hierarchy_changed) and re-sets the transient parent, but when unsetting the transient parent we look at the window->transient_parent->group which is not the same as it was when we added the group, causing an assert.

Also, i think the handling of window groups in gtk_menu_popup/popdown isn't necessary anymore, given the new handling of transient_for in attach_widget_hierarchy_changed. We now always set the menu transient to its attached widget (i.e. combobox or parent menuitem), which handles the window group stuff.
Comment 14 Alexander Larsson 2006-05-12 13:26:39 UTC
Created attachment 65313 [details] [review]
Possible fix
Comment 15 Alexander Larsson 2006-05-12 15:33:10 UTC
Created attachment 65321 [details] [review]
New approach

This is a new approach that removes all setting of transient-for on hierarchy changes. Instead we just set it on popup, first to the parent menushell, and if that is not availbile (i.e. if the parent is a combobox) then to the attached widget (unless the screen was explicitly set, then we don't want to move it to the attached widgets screen).
Comment 16 Soren Sandmann Pedersen 2006-05-12 15:45:08 UTC
Created attachment 65324 [details]
Another approach

This patch takes the approach of just using gdk_window_set_transient_for(). That should keep window groups intact. The advantage of this is that menus will then have correct transient parents if they change attach widget when they are open.

But both approaches are fine with me.
Comment 17 Soren Sandmann Pedersen 2006-05-12 15:51:55 UTC
Created attachment 65326 [details]
The right patch, hopefully
Comment 18 Alexander Larsson 2006-05-12 16:08:07 UTC
Commited the approach from comment #15. The two approaches are both basically sound, but that one gets the window group from the attach widget into the menu toplevel window, which seems better.
Comment 19 Yevgen Muntyan 2006-05-12 17:28:46 UTC
Please take a look at #340898.