From 209d0867e6369e75aa6b96ed229a0aaa6df91b64 Mon Sep 17 00:00:00 2001 From: Kristian Rietveld Date: Thu, 29 Nov 2001 20:36:12 +0000 Subject: [PATCH] add checks for empty menu items to behave like insensitive items (#59456) Thu Nov 29 21:35:56 2001 Kristian Rietveld * gtk/gtkmenu.c (gtk_menu_motion_notify): add checks for empty menu items to behave like insensitive items (#59456) * gtk/gtkmenuitem.c (gtk_real_menu_item_activate_item): select next item if the first item in the menu is a tear off item (#59456-2, suggestion by Matthias Clasen) * gtk/gtkmenushell.c (gtk_menu_shell_button_press), (gtk_menu_shell_button_release), (gtk_menu_shell_entry_notify), (gtk_menu_shell_leave_notify), (gtk_real_menu_shell_move_current), (gtk_real_menu_shell_activate_current): add check, so empty menu items behave like insensitive items (#59456) * gtk/gtkmenuitem.[ch]: add _gtk_menu_item_is_selectable to make the checks more readable ... * gtk/gtkmenushell.c (gtk_menu_shell_button_press), (gtk_menu_shell_button_release): causes the menu to dropdown if the caption is clicked again (#64977) --- ChangeLog | 22 ++++++++++++++++++ ChangeLog.pre-2-0 | 22 ++++++++++++++++++ ChangeLog.pre-2-10 | 22 ++++++++++++++++++ ChangeLog.pre-2-2 | 22 ++++++++++++++++++ ChangeLog.pre-2-4 | 22 ++++++++++++++++++ ChangeLog.pre-2-6 | 22 ++++++++++++++++++ ChangeLog.pre-2-8 | 22 ++++++++++++++++++ gtk/gtkmenu.c | 3 ++- gtk/gtkmenuitem.c | 23 ++++++++++++++++++- gtk/gtkmenuitem.h | 2 ++ gtk/gtkmenushell.c | 56 ++++++++++++++++++++++++++++++---------------- 11 files changed, 217 insertions(+), 21 deletions(-) diff --git a/ChangeLog b/ChangeLog index a13891feb9..9372aca56d 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,25 @@ +Thu Nov 29 21:35:56 2001 Kristian Rietveld + + * gtk/gtkmenu.c (gtk_menu_motion_notify): add checks for + empty menu items to behave like insensitive items (#59456) + + * gtk/gtkmenuitem.c (gtk_real_menu_item_activate_item): select + next item if the first item in the menu is a tear off item + (#59456-2, suggestion by Matthias Clasen) + + * gtk/gtkmenushell.c (gtk_menu_shell_button_press), + (gtk_menu_shell_button_release), (gtk_menu_shell_entry_notify), + (gtk_menu_shell_leave_notify), (gtk_real_menu_shell_move_current), + (gtk_real_menu_shell_activate_current): add check, so empty + menu items behave like insensitive items (#59456) + + * gtk/gtkmenuitem.[ch]: add _gtk_menu_item_is_selectable to make + the checks more readable ... + + * gtk/gtkmenushell.c (gtk_menu_shell_button_press), + (gtk_menu_shell_button_release): causes the menu to dropdown if the + caption is clicked again (#64977) + 2001-11-29 Havoc Pennington * gtk/gtktextiter.c (_gtk_text_iter_forward_indexable_segment): diff --git a/ChangeLog.pre-2-0 b/ChangeLog.pre-2-0 index a13891feb9..9372aca56d 100644 --- a/ChangeLog.pre-2-0 +++ b/ChangeLog.pre-2-0 @@ -1,3 +1,25 @@ +Thu Nov 29 21:35:56 2001 Kristian Rietveld + + * gtk/gtkmenu.c (gtk_menu_motion_notify): add checks for + empty menu items to behave like insensitive items (#59456) + + * gtk/gtkmenuitem.c (gtk_real_menu_item_activate_item): select + next item if the first item in the menu is a tear off item + (#59456-2, suggestion by Matthias Clasen) + + * gtk/gtkmenushell.c (gtk_menu_shell_button_press), + (gtk_menu_shell_button_release), (gtk_menu_shell_entry_notify), + (gtk_menu_shell_leave_notify), (gtk_real_menu_shell_move_current), + (gtk_real_menu_shell_activate_current): add check, so empty + menu items behave like insensitive items (#59456) + + * gtk/gtkmenuitem.[ch]: add _gtk_menu_item_is_selectable to make + the checks more readable ... + + * gtk/gtkmenushell.c (gtk_menu_shell_button_press), + (gtk_menu_shell_button_release): causes the menu to dropdown if the + caption is clicked again (#64977) + 2001-11-29 Havoc Pennington * gtk/gtktextiter.c (_gtk_text_iter_forward_indexable_segment): diff --git a/ChangeLog.pre-2-10 b/ChangeLog.pre-2-10 index a13891feb9..9372aca56d 100644 --- a/ChangeLog.pre-2-10 +++ b/ChangeLog.pre-2-10 @@ -1,3 +1,25 @@ +Thu Nov 29 21:35:56 2001 Kristian Rietveld + + * gtk/gtkmenu.c (gtk_menu_motion_notify): add checks for + empty menu items to behave like insensitive items (#59456) + + * gtk/gtkmenuitem.c (gtk_real_menu_item_activate_item): select + next item if the first item in the menu is a tear off item + (#59456-2, suggestion by Matthias Clasen) + + * gtk/gtkmenushell.c (gtk_menu_shell_button_press), + (gtk_menu_shell_button_release), (gtk_menu_shell_entry_notify), + (gtk_menu_shell_leave_notify), (gtk_real_menu_shell_move_current), + (gtk_real_menu_shell_activate_current): add check, so empty + menu items behave like insensitive items (#59456) + + * gtk/gtkmenuitem.[ch]: add _gtk_menu_item_is_selectable to make + the checks more readable ... + + * gtk/gtkmenushell.c (gtk_menu_shell_button_press), + (gtk_menu_shell_button_release): causes the menu to dropdown if the + caption is clicked again (#64977) + 2001-11-29 Havoc Pennington * gtk/gtktextiter.c (_gtk_text_iter_forward_indexable_segment): diff --git a/ChangeLog.pre-2-2 b/ChangeLog.pre-2-2 index a13891feb9..9372aca56d 100644 --- a/ChangeLog.pre-2-2 +++ b/ChangeLog.pre-2-2 @@ -1,3 +1,25 @@ +Thu Nov 29 21:35:56 2001 Kristian Rietveld + + * gtk/gtkmenu.c (gtk_menu_motion_notify): add checks for + empty menu items to behave like insensitive items (#59456) + + * gtk/gtkmenuitem.c (gtk_real_menu_item_activate_item): select + next item if the first item in the menu is a tear off item + (#59456-2, suggestion by Matthias Clasen) + + * gtk/gtkmenushell.c (gtk_menu_shell_button_press), + (gtk_menu_shell_button_release), (gtk_menu_shell_entry_notify), + (gtk_menu_shell_leave_notify), (gtk_real_menu_shell_move_current), + (gtk_real_menu_shell_activate_current): add check, so empty + menu items behave like insensitive items (#59456) + + * gtk/gtkmenuitem.[ch]: add _gtk_menu_item_is_selectable to make + the checks more readable ... + + * gtk/gtkmenushell.c (gtk_menu_shell_button_press), + (gtk_menu_shell_button_release): causes the menu to dropdown if the + caption is clicked again (#64977) + 2001-11-29 Havoc Pennington * gtk/gtktextiter.c (_gtk_text_iter_forward_indexable_segment): diff --git a/ChangeLog.pre-2-4 b/ChangeLog.pre-2-4 index a13891feb9..9372aca56d 100644 --- a/ChangeLog.pre-2-4 +++ b/ChangeLog.pre-2-4 @@ -1,3 +1,25 @@ +Thu Nov 29 21:35:56 2001 Kristian Rietveld + + * gtk/gtkmenu.c (gtk_menu_motion_notify): add checks for + empty menu items to behave like insensitive items (#59456) + + * gtk/gtkmenuitem.c (gtk_real_menu_item_activate_item): select + next item if the first item in the menu is a tear off item + (#59456-2, suggestion by Matthias Clasen) + + * gtk/gtkmenushell.c (gtk_menu_shell_button_press), + (gtk_menu_shell_button_release), (gtk_menu_shell_entry_notify), + (gtk_menu_shell_leave_notify), (gtk_real_menu_shell_move_current), + (gtk_real_menu_shell_activate_current): add check, so empty + menu items behave like insensitive items (#59456) + + * gtk/gtkmenuitem.[ch]: add _gtk_menu_item_is_selectable to make + the checks more readable ... + + * gtk/gtkmenushell.c (gtk_menu_shell_button_press), + (gtk_menu_shell_button_release): causes the menu to dropdown if the + caption is clicked again (#64977) + 2001-11-29 Havoc Pennington * gtk/gtktextiter.c (_gtk_text_iter_forward_indexable_segment): diff --git a/ChangeLog.pre-2-6 b/ChangeLog.pre-2-6 index a13891feb9..9372aca56d 100644 --- a/ChangeLog.pre-2-6 +++ b/ChangeLog.pre-2-6 @@ -1,3 +1,25 @@ +Thu Nov 29 21:35:56 2001 Kristian Rietveld + + * gtk/gtkmenu.c (gtk_menu_motion_notify): add checks for + empty menu items to behave like insensitive items (#59456) + + * gtk/gtkmenuitem.c (gtk_real_menu_item_activate_item): select + next item if the first item in the menu is a tear off item + (#59456-2, suggestion by Matthias Clasen) + + * gtk/gtkmenushell.c (gtk_menu_shell_button_press), + (gtk_menu_shell_button_release), (gtk_menu_shell_entry_notify), + (gtk_menu_shell_leave_notify), (gtk_real_menu_shell_move_current), + (gtk_real_menu_shell_activate_current): add check, so empty + menu items behave like insensitive items (#59456) + + * gtk/gtkmenuitem.[ch]: add _gtk_menu_item_is_selectable to make + the checks more readable ... + + * gtk/gtkmenushell.c (gtk_menu_shell_button_press), + (gtk_menu_shell_button_release): causes the menu to dropdown if the + caption is clicked again (#64977) + 2001-11-29 Havoc Pennington * gtk/gtktextiter.c (_gtk_text_iter_forward_indexable_segment): diff --git a/ChangeLog.pre-2-8 b/ChangeLog.pre-2-8 index a13891feb9..9372aca56d 100644 --- a/ChangeLog.pre-2-8 +++ b/ChangeLog.pre-2-8 @@ -1,3 +1,25 @@ +Thu Nov 29 21:35:56 2001 Kristian Rietveld + + * gtk/gtkmenu.c (gtk_menu_motion_notify): add checks for + empty menu items to behave like insensitive items (#59456) + + * gtk/gtkmenuitem.c (gtk_real_menu_item_activate_item): select + next item if the first item in the menu is a tear off item + (#59456-2, suggestion by Matthias Clasen) + + * gtk/gtkmenushell.c (gtk_menu_shell_button_press), + (gtk_menu_shell_button_release), (gtk_menu_shell_entry_notify), + (gtk_menu_shell_leave_notify), (gtk_real_menu_shell_move_current), + (gtk_real_menu_shell_activate_current): add check, so empty + menu items behave like insensitive items (#59456) + + * gtk/gtkmenuitem.[ch]: add _gtk_menu_item_is_selectable to make + the checks more readable ... + + * gtk/gtkmenushell.c (gtk_menu_shell_button_press), + (gtk_menu_shell_button_release): causes the menu to dropdown if the + caption is clicked again (#64977) + 2001-11-29 Havoc Pennington * gtk/gtktextiter.c (_gtk_text_iter_forward_indexable_segment): diff --git a/gtk/gtkmenu.c b/gtk/gtkmenu.c index 8e5751c6a4..940433f4b5 100644 --- a/gtk/gtkmenu.c +++ b/gtk/gtkmenu.c @@ -1717,7 +1717,8 @@ gtk_menu_motion_notify (GtkWidget *widget, * which may be different from 'widget'. */ menu_item = gtk_get_event_widget ((GdkEvent*) event); - if (!menu_item || !GTK_IS_MENU_ITEM (menu_item) || !GTK_WIDGET_IS_SENSITIVE (menu_item) || + if (!menu_item || !GTK_IS_MENU_ITEM (menu_item) || + !_gtk_menu_item_is_selectable (menu_item) || !GTK_IS_MENU (menu_item->parent)) return FALSE; diff --git a/gtk/gtkmenuitem.c b/gtk/gtkmenuitem.c index d965f9b160..a656f8edac 100644 --- a/gtk/gtkmenuitem.c +++ b/gtk/gtkmenuitem.c @@ -31,6 +31,8 @@ #include "gtkmenu.h" #include "gtkmenubar.h" #include "gtkmenuitem.h" +#include "gtktearoffmenuitem.h" +#include "gtkseparatormenuitem.h" #include "gtksignal.h" @@ -757,7 +759,13 @@ gtk_real_menu_item_activate_item (GtkMenuItem *menu_item) submenu = GTK_MENU_SHELL (menu_item->submenu); if (submenu->children) - gtk_menu_shell_select_item (submenu, submenu->children->data); + { + if (submenu->children->next && + GTK_IS_TEAROFF_MENU_ITEM (submenu->children->data)) + gtk_menu_shell_select_item (submenu, submenu->children->next->data); + else + gtk_menu_shell_select_item (submenu, submenu->children->data); + } } } } @@ -1103,3 +1111,16 @@ gtk_menu_item_forall (GtkContainer *container, if (bin->child) callback (bin->child, callback_data); } + +gboolean +_gtk_menu_item_is_selectable (GtkWidget *menu_item) +{ + if ((!GTK_BIN (menu_item)->child && + G_OBJECT_TYPE (menu_item) == GTK_TYPE_MENU_ITEM) || + GTK_IS_SEPARATOR_MENU_ITEM (menu_item) || + !GTK_WIDGET_IS_SENSITIVE (menu_item) || + !GTK_WIDGET_VISIBLE (menu_item)) + return FALSE; + + return TRUE; +} diff --git a/gtk/gtkmenuitem.h b/gtk/gtkmenuitem.h index c29d2bf8d9..cf254b8428 100644 --- a/gtk/gtkmenuitem.h +++ b/gtk/gtkmenuitem.h @@ -110,10 +110,12 @@ gboolean gtk_menu_item_get_right_justified (GtkMenuItem *menu_item); void gtk_menu_item_set_accel_path (GtkMenuItem *menu_item, const gchar *accel_path); +/* private */ void _gtk_menu_item_refresh_accel_path (GtkMenuItem *menu_item, const gchar *prefix, GtkAccelGroup *accel_group, gboolean group_changed); +gboolean _gtk_menu_item_is_selectable (GtkWidget *menu_item); #ifndef GTK_DISABLE_DEPRECATED #define gtk_menu_item_right_justify(menu_item) gtk_menu_item_set_right_justified ((menu_item), TRUE) diff --git a/gtk/gtkmenushell.c b/gtk/gtkmenushell.c index 7f3deea037..ccd200b909 100644 --- a/gtk/gtkmenushell.c +++ b/gtk/gtkmenushell.c @@ -29,7 +29,6 @@ #include "gtkmain.h" #include "gtkmarshalers.h" #include "gtkmenuitem.h" -#include "gtktearoffmenuitem.h" /* FIXME */ #include "gtkmenushell.h" #include "gtksignal.h" #include "gtkwindow.h" @@ -411,12 +410,17 @@ gtk_menu_shell_button_press (GtkWidget *widget, menu_item = gtk_menu_shell_get_item (menu_shell, (GdkEvent *)event); - if (menu_item && - GTK_WIDGET_IS_SENSITIVE (menu_item)) + if (menu_item && _gtk_menu_item_is_selectable (menu_item)) { if ((menu_item->parent == widget) && (menu_item != menu_shell->active_menu_item)) - gtk_menu_shell_select_item (menu_shell, menu_item); + { + if (GTK_MENU_SHELL_GET_CLASS (menu_shell)->submenu_placement == GTK_TOP_BOTTOM) + g_object_set_data (G_OBJECT (menu_shell), + "gtk-menushell-just-activated", + GUINT_TO_POINTER (1)); + gtk_menu_shell_select_item (menu_shell, menu_item); + } } } else @@ -446,22 +450,39 @@ gtk_menu_shell_button_release (GtkWidget *widget, menu_shell = GTK_MENU_SHELL (widget); if (menu_shell->active) { + gboolean deactivate_immediately = FALSE; + if (menu_shell->button && (event->button != menu_shell->button)) { menu_shell->button = 0; if (menu_shell->parent_menu_shell) return gtk_widget_event (menu_shell->parent_menu_shell, (GdkEvent*) event); } - + menu_shell->button = 0; menu_item = gtk_menu_shell_get_item (menu_shell, (GdkEvent*) event); deactivate = TRUE; + if (menu_item + && GTK_MENU_SHELL_GET_CLASS (menu_shell)->submenu_placement == GTK_TOP_BOTTOM) + { + if (g_object_get_data (G_OBJECT (menu_shell), "gtk-menushell-just-activated")) + g_object_set_data (G_OBJECT (menu_shell), "gtk-menushell-just-activated", NULL); + else + deactivate_immediately = TRUE; + } + if ((event->time - menu_shell->activate_time) > MENU_SHELL_TIMEOUT) { + if (deactivate_immediately) + { + gtk_menu_shell_deactivate (menu_shell); + return TRUE; + } + if (menu_item && (menu_shell->active_menu_item == menu_item) && - GTK_WIDGET_IS_SENSITIVE (menu_item)) + _gtk_menu_item_is_selectable (menu_item)) { if (GTK_MENU_ITEM (menu_item)->submenu == NULL) { @@ -469,7 +490,7 @@ gtk_menu_shell_button_release (GtkWidget *widget, return TRUE; } } - else if (menu_item && !GTK_WIDGET_IS_SENSITIVE (menu_item)) + else if (menu_item && !_gtk_menu_item_is_selectable (menu_item)) deactivate = FALSE; else if (menu_shell->parent_menu_shell) { @@ -562,7 +583,9 @@ gtk_menu_shell_enter_notify (GtkWidget *widget, { menu_item = gtk_get_event_widget ((GdkEvent*) event); - if (!menu_item || !GTK_WIDGET_IS_SENSITIVE (menu_item)) + if (!menu_item || + (GTK_IS_MENU_ITEM (menu_item) && + !_gtk_menu_item_is_selectable (menu_item))) return TRUE; if ((menu_item->parent == widget) && @@ -614,7 +637,7 @@ gtk_menu_shell_leave_notify (GtkWidget *widget, return TRUE; } - if (!GTK_WIDGET_IS_SENSITIVE (menu_item)) + if (!_gtk_menu_item_is_selectable (event_widget)) return TRUE; if ((menu_shell->active_menu_item == event_widget) && @@ -785,7 +808,7 @@ gtk_menu_shell_real_select_item (GtkMenuShell *menu_shell, GtkWidget *menu_item) { gtk_menu_shell_deselect (menu_shell); - + menu_shell->active_menu_item = menu_item; _gtk_menu_item_set_placement (GTK_MENU_ITEM (menu_shell->active_menu_item), GTK_MENU_SHELL_GET_CLASS (menu_shell)->submenu_placement); @@ -874,9 +897,7 @@ gtk_menu_shell_move_selected (GtkMenuShell *menu_shell, { node = node->next; while (node != start_node && - (!node || - !GTK_WIDGET_IS_SENSITIVE (node->data) || - !GTK_WIDGET_VISIBLE (node->data) )) + (!node || !_gtk_menu_item_is_selectable (node->data))) { if (!node) node = menu_shell->children; @@ -888,9 +909,7 @@ gtk_menu_shell_move_selected (GtkMenuShell *menu_shell, { node = node->prev; while (node != start_node && - (!node || - !GTK_WIDGET_IS_SENSITIVE (node->data) || - !GTK_WIDGET_VISIBLE (node->data) )) + (!node || !_gtk_menu_item_is_selectable (node->data))) { if (!node) node = g_list_last (menu_shell->children); @@ -949,7 +968,7 @@ gtk_real_menu_shell_move_current (GtkMenuShell *menu_shell, case GTK_MENU_DIR_CHILD: if (menu_shell->active_menu_item && - GTK_BIN (menu_shell->active_menu_item)->child && + _gtk_menu_item_is_selectable (menu_shell->active_menu_item) && GTK_MENU_ITEM (menu_shell->active_menu_item)->submenu) { menu_shell = GTK_MENU_SHELL (GTK_MENU_ITEM (menu_shell->active_menu_item)->submenu); @@ -995,7 +1014,7 @@ gtk_real_menu_shell_activate_current (GtkMenuShell *menu_shell, gboolean force_hide) { if (menu_shell->active_menu_item && - GTK_WIDGET_IS_SENSITIVE (menu_shell->active_menu_item) && + _gtk_menu_item_is_selectable (menu_shell->active_menu_item) && GTK_MENU_ITEM (menu_shell->active_menu_item)->submenu == NULL) { gtk_menu_shell_activate_item (menu_shell, @@ -1014,4 +1033,3 @@ gtk_real_menu_shell_cancel (GtkMenuShell *menu_shell) gtk_menu_shell_deactivate (menu_shell); gtk_signal_emit (GTK_OBJECT (menu_shell), menu_shell_signals[SELECTION_DONE]); } -