forked from AuroraMiddleware/gtk
don't add the same menu to different menuitems/ optionmenus.
Tue Feb 3 15:09:55 1998 Tim Janik <timj@gimp.org> * gtk/testgtk.c: don't add the same menu to different menuitems/ optionmenus. * gtk/gtkmenuitem.h: * gtk/gtkmenuitem.c: new function gtk_menu_item_remove_submenu ro be consistent with optionmenu. use gtk_menu_attach_to_widget/ gtk_menu_detach for setting/removing the submenu. invoke gtk_widget_destroy(submenu) in destructor to be consistent with other destructors. * gtk/gtkoptionmenu.h: * gtk/gtkoptionmenu.c: attach/detach to menu widget via gtk_menu_attach_to_widget/gtk_menu_detach. invoke gtk_widget_destroy(menu) in destructor to be consistent with other destructors.
This commit is contained in:
parent
b45cd0430c
commit
5842311062
49
BUGS
49
BUGS
@ -1,49 +0,0 @@
|
||||
From timj@gimp.org Sat Jan 24 19:15:22 1998
|
||||
Date: Sat, 24 Jan 1998 18:25:10 +0100 (CET)
|
||||
From: Tim Janik <timj@gimp.org>
|
||||
To: Peter Mattis <petm@xcf.berkeley.edu>
|
||||
Cc: Gtk+ Devils <gtkdev@gimp.org>
|
||||
Subject: widget destruction while in call
|
||||
|
||||
hi peter and gtk+ devils ;)
|
||||
|
||||
|
||||
i've got the following problem, when double clicking on a list item
|
||||
it's window should be destroyed, because the selection is made.
|
||||
now this doesn't work 'cause the program is aborted with a
|
||||
BadWindow error (from X).
|
||||
|
||||
this happens because the function that is connected to the lists
|
||||
button_press_event calls gtk_widget_destroy () on the main window.
|
||||
then the widget destruction is propagated through the tree until
|
||||
the list widget should be destroyed. but since the list widget is
|
||||
still GTK_IN_CALL (from the button_press_event) it isn't destroyed
|
||||
but only flagged as GTK_NEED_DESTROY. at this point the propagation
|
||||
stops, and nothing happends to the list widgets children.
|
||||
after the return of the button_press_event handler, the clicked
|
||||
list item is now selected/unselected (depends on the previous state).
|
||||
it therefore updates its GdkWindow (XWindow) by setting the new
|
||||
backgroundcolor (selected->blue/unselected->white). since it's
|
||||
parent XWindows are destroyed already the window which the list item
|
||||
wants to draw on is also destroyed. at this point the BadWindow error
|
||||
occours cause the XWindow handle has become invalid (the application
|
||||
already received a destroy notify).
|
||||
|
||||
now, solutions might be:
|
||||
1) check for private->destroyed on *all* gdk call as it's done
|
||||
it a lot of places already, or
|
||||
2) propagate a widget unrealize signal through the tree before
|
||||
destroying a widget, or
|
||||
3) propagate GTK_NEED_DESTROY down the tree (not only flag the
|
||||
list container), this would require gtk_object_destroy() to
|
||||
return wether the object got actually destroyed or flagged
|
||||
only. then prohibit gdk operations on widgets flagged as
|
||||
GTK_NEED_DESTROY.
|
||||
|
||||
i'm not sure what the best solution might be, but i tend to favour
|
||||
1) or 3).
|
||||
|
||||
|
||||
---
|
||||
ciaoTJ
|
||||
|
13
ChangeLog
13
ChangeLog
@ -1,7 +1,20 @@
|
||||
Tue Feb 3 15:09:55 1998 Tim Janik <timj@gimp.org>
|
||||
|
||||
* gtk/testgtk.c: don't add the same menu to different menuitems/
|
||||
optionmenus.
|
||||
|
||||
* gtk/gtkmenuitem.h:
|
||||
* gtk/gtkmenuitem.c: new function gtk_menu_item_remove_submenu ro
|
||||
be consistent with optionmenu. use gtk_menu_attach_to_widget/
|
||||
gtk_menu_detach for setting/removing the submenu.
|
||||
invoke gtk_widget_destroy(submenu) in destructor to be consistent
|
||||
with other destructors.
|
||||
|
||||
* gtk/gtkoptionmenu.h:
|
||||
* gtk/gtkoptionmenu.c: attach/detach to menu widget via
|
||||
gtk_menu_attach_to_widget/gtk_menu_detach.
|
||||
invoke gtk_widget_destroy(menu) in destructor to be consistent
|
||||
with other destructors.
|
||||
|
||||
* gtk/gtkmenu.h:
|
||||
* gtk/gtkmenu.c: new functions gtk_menu_attach_to_widget
|
||||
|
@ -1,7 +1,20 @@
|
||||
Tue Feb 3 15:09:55 1998 Tim Janik <timj@gimp.org>
|
||||
|
||||
* gtk/testgtk.c: don't add the same menu to different menuitems/
|
||||
optionmenus.
|
||||
|
||||
* gtk/gtkmenuitem.h:
|
||||
* gtk/gtkmenuitem.c: new function gtk_menu_item_remove_submenu ro
|
||||
be consistent with optionmenu. use gtk_menu_attach_to_widget/
|
||||
gtk_menu_detach for setting/removing the submenu.
|
||||
invoke gtk_widget_destroy(submenu) in destructor to be consistent
|
||||
with other destructors.
|
||||
|
||||
* gtk/gtkoptionmenu.h:
|
||||
* gtk/gtkoptionmenu.c: attach/detach to menu widget via
|
||||
gtk_menu_attach_to_widget/gtk_menu_detach.
|
||||
invoke gtk_widget_destroy(menu) in destructor to be consistent
|
||||
with other destructors.
|
||||
|
||||
* gtk/gtkmenu.h:
|
||||
* gtk/gtkmenu.c: new functions gtk_menu_attach_to_widget
|
||||
|
@ -1,7 +1,20 @@
|
||||
Tue Feb 3 15:09:55 1998 Tim Janik <timj@gimp.org>
|
||||
|
||||
* gtk/testgtk.c: don't add the same menu to different menuitems/
|
||||
optionmenus.
|
||||
|
||||
* gtk/gtkmenuitem.h:
|
||||
* gtk/gtkmenuitem.c: new function gtk_menu_item_remove_submenu ro
|
||||
be consistent with optionmenu. use gtk_menu_attach_to_widget/
|
||||
gtk_menu_detach for setting/removing the submenu.
|
||||
invoke gtk_widget_destroy(submenu) in destructor to be consistent
|
||||
with other destructors.
|
||||
|
||||
* gtk/gtkoptionmenu.h:
|
||||
* gtk/gtkoptionmenu.c: attach/detach to menu widget via
|
||||
gtk_menu_attach_to_widget/gtk_menu_detach.
|
||||
invoke gtk_widget_destroy(menu) in destructor to be consistent
|
||||
with other destructors.
|
||||
|
||||
* gtk/gtkmenu.h:
|
||||
* gtk/gtkmenu.c: new functions gtk_menu_attach_to_widget
|
||||
|
@ -1,7 +1,20 @@
|
||||
Tue Feb 3 15:09:55 1998 Tim Janik <timj@gimp.org>
|
||||
|
||||
* gtk/testgtk.c: don't add the same menu to different menuitems/
|
||||
optionmenus.
|
||||
|
||||
* gtk/gtkmenuitem.h:
|
||||
* gtk/gtkmenuitem.c: new function gtk_menu_item_remove_submenu ro
|
||||
be consistent with optionmenu. use gtk_menu_attach_to_widget/
|
||||
gtk_menu_detach for setting/removing the submenu.
|
||||
invoke gtk_widget_destroy(submenu) in destructor to be consistent
|
||||
with other destructors.
|
||||
|
||||
* gtk/gtkoptionmenu.h:
|
||||
* gtk/gtkoptionmenu.c: attach/detach to menu widget via
|
||||
gtk_menu_attach_to_widget/gtk_menu_detach.
|
||||
invoke gtk_widget_destroy(menu) in destructor to be consistent
|
||||
with other destructors.
|
||||
|
||||
* gtk/gtkmenu.h:
|
||||
* gtk/gtkmenu.c: new functions gtk_menu_attach_to_widget
|
||||
|
@ -1,7 +1,20 @@
|
||||
Tue Feb 3 15:09:55 1998 Tim Janik <timj@gimp.org>
|
||||
|
||||
* gtk/testgtk.c: don't add the same menu to different menuitems/
|
||||
optionmenus.
|
||||
|
||||
* gtk/gtkmenuitem.h:
|
||||
* gtk/gtkmenuitem.c: new function gtk_menu_item_remove_submenu ro
|
||||
be consistent with optionmenu. use gtk_menu_attach_to_widget/
|
||||
gtk_menu_detach for setting/removing the submenu.
|
||||
invoke gtk_widget_destroy(submenu) in destructor to be consistent
|
||||
with other destructors.
|
||||
|
||||
* gtk/gtkoptionmenu.h:
|
||||
* gtk/gtkoptionmenu.c: attach/detach to menu widget via
|
||||
gtk_menu_attach_to_widget/gtk_menu_detach.
|
||||
invoke gtk_widget_destroy(menu) in destructor to be consistent
|
||||
with other destructors.
|
||||
|
||||
* gtk/gtkmenu.h:
|
||||
* gtk/gtkmenu.c: new functions gtk_menu_attach_to_widget
|
||||
|
@ -1,7 +1,20 @@
|
||||
Tue Feb 3 15:09:55 1998 Tim Janik <timj@gimp.org>
|
||||
|
||||
* gtk/testgtk.c: don't add the same menu to different menuitems/
|
||||
optionmenus.
|
||||
|
||||
* gtk/gtkmenuitem.h:
|
||||
* gtk/gtkmenuitem.c: new function gtk_menu_item_remove_submenu ro
|
||||
be consistent with optionmenu. use gtk_menu_attach_to_widget/
|
||||
gtk_menu_detach for setting/removing the submenu.
|
||||
invoke gtk_widget_destroy(submenu) in destructor to be consistent
|
||||
with other destructors.
|
||||
|
||||
* gtk/gtkoptionmenu.h:
|
||||
* gtk/gtkoptionmenu.c: attach/detach to menu widget via
|
||||
gtk_menu_attach_to_widget/gtk_menu_detach.
|
||||
invoke gtk_widget_destroy(menu) in destructor to be consistent
|
||||
with other destructors.
|
||||
|
||||
* gtk/gtkmenu.h:
|
||||
* gtk/gtkmenu.c: new functions gtk_menu_attach_to_widget
|
||||
|
@ -1,7 +1,20 @@
|
||||
Tue Feb 3 15:09:55 1998 Tim Janik <timj@gimp.org>
|
||||
|
||||
* gtk/testgtk.c: don't add the same menu to different menuitems/
|
||||
optionmenus.
|
||||
|
||||
* gtk/gtkmenuitem.h:
|
||||
* gtk/gtkmenuitem.c: new function gtk_menu_item_remove_submenu ro
|
||||
be consistent with optionmenu. use gtk_menu_attach_to_widget/
|
||||
gtk_menu_detach for setting/removing the submenu.
|
||||
invoke gtk_widget_destroy(submenu) in destructor to be consistent
|
||||
with other destructors.
|
||||
|
||||
* gtk/gtkoptionmenu.h:
|
||||
* gtk/gtkoptionmenu.c: attach/detach to menu widget via
|
||||
gtk_menu_attach_to_widget/gtk_menu_detach.
|
||||
invoke gtk_widget_destroy(menu) in destructor to be consistent
|
||||
with other destructors.
|
||||
|
||||
* gtk/gtkmenu.h:
|
||||
* gtk/gtkmenu.c: new functions gtk_menu_attach_to_widget
|
||||
|
3
TODO
3
TODO
@ -42,9 +42,6 @@ BUGS
|
||||
the deactivation, but not the destruction of it's submenu.
|
||||
this is not a bug in the fileselection code but in the optionmenu
|
||||
code.
|
||||
|
||||
* Look also at ./BUGS (i added it, because it describes some bugs in
|
||||
a more specific way -timj).
|
||||
|
||||
|
||||
NEW FEATURES
|
||||
|
@ -196,39 +196,58 @@ gtk_menu_item_destroy (GtkObject *object)
|
||||
menu_item = GTK_MENU_ITEM (object);
|
||||
|
||||
if (menu_item->submenu)
|
||||
{
|
||||
gtk_widget_destroy (menu_item->submenu);
|
||||
gtk_widget_unref (menu_item->submenu);
|
||||
menu_item->submenu = NULL;
|
||||
}
|
||||
gtk_widget_destroy (menu_item->submenu);
|
||||
|
||||
if (GTK_OBJECT_CLASS (parent_class)->destroy)
|
||||
(* GTK_OBJECT_CLASS (parent_class)->destroy) (object);
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_menu_item_detacher (GtkWidget *widget,
|
||||
GtkMenu *menu)
|
||||
{
|
||||
GtkMenuItem *menu_item;
|
||||
|
||||
g_return_if_fail (widget != NULL);
|
||||
g_return_if_fail (GTK_IS_MENU_ITEM (widget));
|
||||
|
||||
menu_item = GTK_MENU_ITEM (widget);
|
||||
g_return_if_fail (menu_item->submenu == (GtkWidget*) menu);
|
||||
|
||||
menu_item->submenu = NULL;
|
||||
}
|
||||
|
||||
void
|
||||
gtk_menu_item_set_submenu (GtkMenuItem *menu_item,
|
||||
GtkWidget *submenu)
|
||||
{
|
||||
g_return_if_fail (menu_item != NULL);
|
||||
g_return_if_fail (GTK_IS_MENU_ITEM (menu_item));
|
||||
|
||||
|
||||
if (menu_item->submenu != submenu)
|
||||
{
|
||||
if (menu_item->submenu)
|
||||
{
|
||||
g_return_if_fail (!GTK_WIDGET_VISIBLE (menu_item->submenu));
|
||||
gtk_widget_unref (menu_item->submenu);
|
||||
}
|
||||
gtk_menu_item_remove_submenu (menu_item);
|
||||
|
||||
menu_item->submenu = submenu;
|
||||
if (menu_item->submenu)
|
||||
gtk_widget_ref (menu_item->submenu);
|
||||
|
||||
gtk_menu_attach_to_widget (GTK_MENU (submenu),
|
||||
GTK_WIDGET (menu_item),
|
||||
gtk_menu_item_detacher);
|
||||
|
||||
if (GTK_WIDGET (menu_item)->parent)
|
||||
gtk_widget_queue_resize (GTK_WIDGET (menu_item));
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
gtk_menu_item_remove_submenu (GtkMenuItem *menu_item)
|
||||
{
|
||||
g_return_if_fail (menu_item != NULL);
|
||||
g_return_if_fail (GTK_IS_MENU_ITEM (menu_item));
|
||||
|
||||
if (menu_item->submenu)
|
||||
gtk_menu_detach (GTK_MENU (menu_item->submenu));
|
||||
}
|
||||
|
||||
void
|
||||
gtk_menu_item_set_placement (GtkMenuItem *menu_item,
|
||||
GtkSubmenuPlacement placement)
|
||||
|
@ -76,6 +76,7 @@ GtkWidget* gtk_menu_item_new (void);
|
||||
GtkWidget* gtk_menu_item_new_with_label (const gchar *label);
|
||||
void gtk_menu_item_set_submenu (GtkMenuItem *menu_item,
|
||||
GtkWidget *submenu);
|
||||
void gtk_menu_item_remove_submenu (GtkMenuItem *menu_item);
|
||||
void gtk_menu_item_set_placement (GtkMenuItem *menu_item,
|
||||
GtkSubmenuPlacement placement);
|
||||
void gtk_menu_item_accelerator_size (GtkMenuItem *menu_item);
|
||||
|
@ -230,7 +230,7 @@ gtk_option_menu_destroy (GtkObject *object)
|
||||
option_menu = GTK_OPTION_MENU (object);
|
||||
|
||||
if (option_menu->menu)
|
||||
gtk_menu_detach (GTK_MENU (option_menu->menu));
|
||||
gtk_widget_destroy (option_menu->menu);
|
||||
|
||||
if (GTK_OBJECT_CLASS (parent_class)->destroy)
|
||||
(* GTK_OBJECT_CLASS (parent_class)->destroy) (object);
|
||||
@ -487,7 +487,6 @@ gtk_option_menu_remove_contents (GtkOptionMenu *option_menu)
|
||||
if (GTK_WIDGET (option_menu->menu_item)->state != GTK_BUTTON (option_menu)->child->state)
|
||||
gtk_widget_set_state (GTK_BUTTON (option_menu)->child,
|
||||
GTK_WIDGET (option_menu->menu_item)->state);
|
||||
/* GTK_WIDGET_UNSET_FLAGS (GTK_BUTTON (option_menu)->child, GTK_MAPPED | GTK_REALIZED); */
|
||||
gtk_widget_unrealize (GTK_BUTTON (option_menu)->child);
|
||||
gtk_widget_reparent (GTK_BUTTON (option_menu)->child, option_menu->menu_item);
|
||||
gtk_widget_unref (option_menu->menu_item);
|
||||
|
@ -1111,7 +1111,6 @@ GtkWidget*
|
||||
create_menu (int depth)
|
||||
{
|
||||
GtkWidget *menu;
|
||||
GtkWidget *submenu;
|
||||
GtkWidget *menuitem;
|
||||
GSList *group;
|
||||
char buf[32];
|
||||
@ -1121,7 +1120,6 @@ create_menu (int depth)
|
||||
return NULL;
|
||||
|
||||
menu = gtk_menu_new ();
|
||||
submenu = NULL;
|
||||
group = NULL;
|
||||
|
||||
for (i = 0, j = 1; i < 5; i++, j++)
|
||||
@ -1134,12 +1132,7 @@ create_menu (int depth)
|
||||
gtk_menu_append (GTK_MENU (menu), menuitem);
|
||||
gtk_widget_show (menuitem);
|
||||
|
||||
if (depth > 0)
|
||||
{
|
||||
if (!submenu)
|
||||
submenu = create_menu (depth - 1);
|
||||
gtk_menu_item_set_submenu (GTK_MENU_ITEM (menuitem), submenu);
|
||||
}
|
||||
gtk_menu_item_set_submenu (GTK_MENU_ITEM (menuitem), create_menu (depth - 1));
|
||||
}
|
||||
|
||||
return menu;
|
||||
@ -1190,12 +1183,12 @@ create_menus ()
|
||||
gtk_widget_show (menuitem);
|
||||
|
||||
menuitem = gtk_menu_item_new_with_label ("foo");
|
||||
gtk_menu_item_set_submenu (GTK_MENU_ITEM (menuitem), menu);
|
||||
gtk_menu_item_set_submenu (GTK_MENU_ITEM (menuitem), create_menu (3));
|
||||
gtk_menu_bar_append (GTK_MENU_BAR (menubar), menuitem);
|
||||
gtk_widget_show (menuitem);
|
||||
|
||||
menuitem = gtk_menu_item_new_with_label ("bar");
|
||||
gtk_menu_item_set_submenu (GTK_MENU_ITEM (menuitem), menu);
|
||||
gtk_menu_item_set_submenu (GTK_MENU_ITEM (menuitem), create_menu (4));
|
||||
gtk_menu_item_right_justify (GTK_MENU_ITEM (menuitem));
|
||||
gtk_menu_bar_append (GTK_MENU_BAR (menubar), menuitem);
|
||||
gtk_widget_show (menuitem);
|
||||
|
@ -1111,7 +1111,6 @@ GtkWidget*
|
||||
create_menu (int depth)
|
||||
{
|
||||
GtkWidget *menu;
|
||||
GtkWidget *submenu;
|
||||
GtkWidget *menuitem;
|
||||
GSList *group;
|
||||
char buf[32];
|
||||
@ -1121,7 +1120,6 @@ create_menu (int depth)
|
||||
return NULL;
|
||||
|
||||
menu = gtk_menu_new ();
|
||||
submenu = NULL;
|
||||
group = NULL;
|
||||
|
||||
for (i = 0, j = 1; i < 5; i++, j++)
|
||||
@ -1134,12 +1132,7 @@ create_menu (int depth)
|
||||
gtk_menu_append (GTK_MENU (menu), menuitem);
|
||||
gtk_widget_show (menuitem);
|
||||
|
||||
if (depth > 0)
|
||||
{
|
||||
if (!submenu)
|
||||
submenu = create_menu (depth - 1);
|
||||
gtk_menu_item_set_submenu (GTK_MENU_ITEM (menuitem), submenu);
|
||||
}
|
||||
gtk_menu_item_set_submenu (GTK_MENU_ITEM (menuitem), create_menu (depth - 1));
|
||||
}
|
||||
|
||||
return menu;
|
||||
@ -1190,12 +1183,12 @@ create_menus ()
|
||||
gtk_widget_show (menuitem);
|
||||
|
||||
menuitem = gtk_menu_item_new_with_label ("foo");
|
||||
gtk_menu_item_set_submenu (GTK_MENU_ITEM (menuitem), menu);
|
||||
gtk_menu_item_set_submenu (GTK_MENU_ITEM (menuitem), create_menu (3));
|
||||
gtk_menu_bar_append (GTK_MENU_BAR (menubar), menuitem);
|
||||
gtk_widget_show (menuitem);
|
||||
|
||||
menuitem = gtk_menu_item_new_with_label ("bar");
|
||||
gtk_menu_item_set_submenu (GTK_MENU_ITEM (menuitem), menu);
|
||||
gtk_menu_item_set_submenu (GTK_MENU_ITEM (menuitem), create_menu (4));
|
||||
gtk_menu_item_right_justify (GTK_MENU_ITEM (menuitem));
|
||||
gtk_menu_bar_append (GTK_MENU_BAR (menubar), menuitem);
|
||||
gtk_widget_show (menuitem);
|
||||
|
Loading…
Reference in New Issue
Block a user