Re: Destroying a menu
- From: Jerome Blondel <jeromeblondel yahoo fr>
- To: Iago Rubio <iago iagorubio com>, gtk-app-devel-list gnome org
- Subject: Re: Destroying a menu
- Date: Wed, 23 Jan 2008 12:47:18 +0100
Iago Rubio
On Mon, 2008-01-21 at 10:47 +0100, Jerome Blondel wrote:
Hi
If I set a menu as a submenu for a menu item, is it destroyed when I
destroy the toplevel menu?
IFAIK yes.
When you attach a menu to a widget it's referenced with
g_object_ref_sink, so if it only has a floating reference, its ref count
is not increased but converted to a normal reference, so the container
will own the only reference to the menu.
If you want to maintain the menu, you must increase its ref count.
Even when the ref count of the submenu is increased, the program still
crashes on the second time the submenu is popped up. It seems the
destruction of the container has other side-effects.
This is the code:
Part 1 (in the setup code):
// setup of the stars context submenu
this->popup_actions = gtk_menu_new();
this->popup_action_center = gtk_menu_item_new_with_label("Center");
this->popup_action_focus = gtk_menu_item_new_with_label("Focus");
this->popup_action_info = gtk_menu_item_new_with_label("Info");
gtk_menu_shell_append(GTK_MENU_SHELL(this->popup_actions),
this->popup_action_center);
gtk_menu_shell_append(GTK_MENU_SHELL(this->popup_actions),
this->popup_action_focus);
gtk_menu_shell_append(GTK_MENU_SHELL(this->popup_actions),
this->popup_action_info);
g_object_set_data(G_OBJECT(this->popup_actions), "body", NULL);
g_signal_connect(G_OBJECT(this->popup_action_center), "activate",
G_CALLBACK(on_star_center), this);
g_signal_connect(G_OBJECT(this->popup_action_focus), "activate",
G_CALLBACK(on_star_focus), this);
g_signal_connect(G_OBJECT(this->popup_action_info), "activate",
G_CALLBACK(on_star_info), this);
// don't let them be destroyed... but it doesn't work
g_object_ref(this->popup_actions);
Part 2 (in the right-click handler)
else if (ev->button == 3)
{
selected_stars = s->find_stars(p, 2.0);
// popup a menu
if (selected_stars)
{
GtkWidget *stars;
if (s->popup_stars)
gtk_widget_destroy(GTK_WIDGET(s->popup_stars));
// setup of the submenu on the fly, fallback solution
/*
s->popup_actions = gtk_menu_new();
s->popup_action_center = gtk_menu_item_new_with_label("Center");
s->popup_action_focus = gtk_menu_item_new_with_label("Focus");
s->popup_action_info = gtk_menu_item_new_with_label("Info");
gtk_menu_shell_append(GTK_MENU_SHELL(s->popup_actions),
s->popup_action_center);
gtk_menu_shell_append(GTK_MENU_SHELL(s->popup_actions),
s->popup_action_focus);
gtk_menu_shell_append(GTK_MENU_SHELL(s->popup_actions),
s->popup_action_info);
g_object_set_data(G_OBJECT(s->popup_actions), "body", NULL);
g_signal_connect(G_OBJECT(s->popup_action_center), "activate",
G_CALLBACK(on_star_center), s);
g_signal_connect(G_OBJECT(s->popup_action_focus), "activate",
G_CALLBACK(on_star_focus), s);
g_signal_connect(G_OBJECT(s->popup_action_info), "activate",
G_CALLBACK(on_star_info), s);
*/
// setup of the menu
s->popup_stars = gtk_menu_new();
for (k = selected_stars; k != NULL; k = k->next)
{
Body *b = static_cast<Body *>(k->data);
gchar *str = b->pretty_name();
stars = gtk_menu_item_new_with_label(str);
g_free(str);
g_object_set_data(G_OBJECT(stars), "body", b);
gtk_menu_shell_append(GTK_MENU_SHELL(s->popup_stars),
stars);
gtk_menu_item_set_submenu(GTK_MENU_ITEM(stars),
s->popup_actions);
g_signal_connect(G_OBJECT(stars), "activate",
G_CALLBACK(on_star_item_activate), s);
}
gtk_widget_show_all(s->popup_stars);
gtk_menu_popup(GTK_MENU(s->popup_stars), NULL, NULL, NULL,
NULL,
ev->button, ev->time);
g_slist_free(selected_stars);
}
Here are the error messages.
// first popup of the context menu with two items in it
(coords:3110): Gtk-WARNING **: gtk_menu_attach_to_widget(): menu already
attached to GtkMenuItem
// second popup of the context menu with two items in it
(coords:3110): Gtk-CRITICAL **: gtk_window_set_screen: assertion
`GTK_IS_WINDOW (window)' failed
(coords:3110): Gtk-WARNING **: gtk_menu_attach_to_widget(): menu already
attached to GtkMenuItem
// trying to popup a submenu now
(coords:3110): Gtk-CRITICAL **: gtk_window_set_accept_focus: assertion
`GTK_IS_WINDOW (window)' failed
(coords:3110): GLib-GObject-CRITICAL **: g_type_instance_get_private:
assertion `instance != NULL && instance->g_class != NULL' failed
(coords:3110): Gtk-CRITICAL **: gtk_window_set_transient_for: assertion
`GTK_IS_WINDOW (window)' failed
Program received signal SIGSEGV, Segmentation fault.
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]