X-Git-Url: http://pileus.org/git/?a=blobdiff_plain;f=gtk%2Fgtkmenushell.c;h=ae36459d43f981feae370333b014a5f46b5df0f8;hb=HEAD;hp=f210cab85ef229213b17a8fa3f9e6f4ec373dd22;hpb=2f0d40335b83d70d04a205dd17e8a5514b79f2d4;p=~andy%2Fgtk diff --git a/gtk/gtkmenushell.c b/gtk/gtkmenushell.c index f210cab85..ae36459d4 100644 --- a/gtk/gtkmenushell.c +++ b/gtk/gtkmenushell.c @@ -12,9 +12,7 @@ * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. + * License along with this library. If not, see . */ /* @@ -42,19 +40,24 @@ #include "gtkbindings.h" #include "gtkkeyhash.h" #include "gtklabel.h" -#include "gtkmainprivate.h" +#include "gtkmain.h" #include "gtkmarshalers.h" #include "gtkmenubar.h" #include "gtkmenuitemprivate.h" #include "gtkmenushellprivate.h" #include "gtkmenuprivate.h" #include "gtkmnemonichash.h" -#include "gtktearoffmenuitem.h" #include "gtkwindow.h" #include "gtkprivate.h" +#include "gtkmain.h" #include "gtkintl.h" #include "gtktypebuiltins.h" +#include "deprecated/gtktearoffmenuitem.h" + +#include "a11y/gtkmenushellaccessible.h" + + #define MENU_SHELL_TIMEOUT 500 #define PACK_DIRECTION(m) \ @@ -70,6 +73,7 @@ enum { CANCEL, CYCLE_FOCUS, MOVE_SELECTED, + INSERT, LAST_SIGNAL }; @@ -367,6 +371,31 @@ gtk_menu_shell_class_init (GtkMenuShellClass *klass) G_TYPE_BOOLEAN, 1, G_TYPE_INT); + /** + * GtkMenuShell::insert: + * @menu_shell: the object on which the signal is emitted + * @child: the #GtkMenuItem that is being inserted + * @position: the position at which the insert occurs + * + * The ::insert signal is emitted when a new #GtkMenuItem is added to + * a #GtkMenuShell. A separate signal is used instead of + * GtkContainer::add because of the need for an additional position + * parameter. + * + * The inverse of this signal is the GtkContainer::removed signal. + * + * Since: 3.2 + **/ + menu_shell_signals[INSERT] = + g_signal_new (I_("insert"), + G_OBJECT_CLASS_TYPE (object_class), + G_SIGNAL_RUN_FIRST, + G_STRUCT_OFFSET (GtkMenuShellClass, insert), + NULL, NULL, + _gtk_marshal_VOID__OBJECT_INT, + G_TYPE_NONE, 2, GTK_TYPE_WIDGET, G_TYPE_INT); + + binding_set = gtk_binding_set_by_class (klass); gtk_binding_entry_add_signal (binding_set, GDK_KEY_Escape, 0, @@ -422,6 +451,8 @@ gtk_menu_shell_class_init (GtkMenuShellClass *klass) TRUE, GTK_PARAM_READWRITE)); + gtk_widget_class_set_accessible_type (widget_class, GTK_TYPE_MENU_SHELL_ACCESSIBLE); + g_type_class_add_private (object_class, sizeof (GtkMenuShellPrivate)); } @@ -549,15 +580,10 @@ gtk_menu_shell_insert (GtkMenuShell *menu_shell, GtkWidget *child, gint position) { - GtkMenuShellClass *class; - g_return_if_fail (GTK_IS_MENU_SHELL (menu_shell)); g_return_if_fail (GTK_IS_MENU_ITEM (child)); - class = GTK_MENU_SHELL_GET_CLASS (menu_shell); - - if (class->insert) - class->insert (menu_shell, child, position); + g_signal_emit (menu_shell, menu_shell_signals[INSERT], 0, child, position); } static void @@ -586,7 +612,8 @@ gtk_menu_shell_deactivate (GtkMenuShell *menu_shell) { g_return_if_fail (GTK_IS_MENU_SHELL (menu_shell)); - g_signal_emit (menu_shell, menu_shell_signals[DEACTIVATE], 0); + if (menu_shell->priv->active) + g_signal_emit (menu_shell, menu_shell_signals[DEACTIVATE], 0); } static void @@ -622,14 +649,14 @@ gtk_menu_shell_realize (GtkWidget *widget) window = gdk_window_new (gtk_widget_get_parent_window (widget), &attributes, attributes_mask); gtk_widget_set_window (widget, window); - gdk_window_set_user_data (window, widget); + gtk_widget_register_window (widget, window); context = gtk_widget_get_style_context (widget); gtk_style_context_set_background (context, window); } -void -_gtk_menu_shell_activate (GtkMenuShell *menu_shell) +static void +gtk_menu_shell_activate (GtkMenuShell *menu_shell) { GtkMenuShellPrivate *priv = menu_shell->priv; @@ -697,7 +724,7 @@ gtk_menu_shell_button_press (GtkWidget *widget, gtk_widget_get_parent (menu_item) == widget && menu_item != priv->active_menu_item) { - _gtk_menu_shell_activate (menu_shell); + gtk_menu_shell_activate (menu_shell); priv->button = event->button; if (GTK_MENU_SHELL_GET_CLASS (menu_shell)->submenu_placement == GTK_TOP_BOTTOM) @@ -1056,13 +1083,11 @@ gtk_menu_shell_enter_notify (GtkWidget *widget, if (!gtk_widget_get_visible (GTK_MENU_ITEM (menu_item)->priv->submenu)) { - gboolean touchscreen_mode; + GdkDevice *source_device; - g_object_get (gtk_widget_get_settings (widget), - "gtk-touchscreen-mode", &touchscreen_mode, - NULL); + source_device = gdk_event_get_source_device ((GdkEvent *) event); - if (touchscreen_mode) + if (gdk_device_get_source (source_device) == GDK_SOURCE_TOUCHSCREEN) _gtk_menu_item_popup_submenu (menu_item, TRUE); } } @@ -1082,7 +1107,7 @@ gtk_menu_shell_leave_notify (GtkWidget *widget, GdkEventCrossing *event) { if (event->mode == GDK_CROSSING_GTK_GRAB || - event->mode == GDK_CROSSING_GTK_GRAB || + event->mode == GDK_CROSSING_GTK_UNGRAB || event->mode == GDK_CROSSING_STATE_CHANGED) return TRUE; @@ -1190,7 +1215,6 @@ gtk_real_menu_shell_deactivate (GtkMenuShell *menu_shell) if (priv->active) { - priv->button = 0; priv->active = FALSE; priv->activate_time = 0; @@ -1313,6 +1337,8 @@ gtk_menu_shell_real_select_item (GtkMenuShell *menu_shell, return; } + gtk_menu_shell_activate (menu_shell); + priv->active_menu_item = menu_item; if (pack_dir == GTK_PACK_DIRECTION_TTB || pack_dir == GTK_PACK_DIRECTION_BTT) _gtk_menu_item_set_placement (GTK_MENU_ITEM (priv->active_menu_item), @@ -1583,45 +1609,19 @@ gtk_real_menu_shell_move_current (GtkMenuShell *menu_shell, GtkMenuShellPrivate *priv = menu_shell->priv; GtkMenuShell *parent_menu_shell = NULL; gboolean had_selection; - gboolean touchscreen_mode; priv->in_unselectable_item = FALSE; had_selection = priv->active_menu_item != NULL; - g_object_get (gtk_widget_get_settings (GTK_WIDGET (menu_shell)), - "gtk-touchscreen-mode", &touchscreen_mode, - NULL); - if (priv->parent_menu_shell) parent_menu_shell = GTK_MENU_SHELL (priv->parent_menu_shell); switch (direction) { case GTK_MENU_DIR_PARENT: - if (touchscreen_mode && - priv->active_menu_item && - GTK_MENU_ITEM (priv->active_menu_item)->priv->submenu && - gtk_widget_get_visible (GTK_MENU_ITEM (priv->active_menu_item)->priv->submenu)) - { - /* if we are on a menu item that has an open submenu but the - * focus is not in that submenu (e.g. because it's empty or - * has only insensitive items), close that submenu instead of - * running into the code below which would close *this* menu. - */ - _gtk_menu_item_popdown_submenu (priv->active_menu_item); - _gtk_menu_shell_update_mnemonics (menu_shell); - } - else if (parent_menu_shell) + if (parent_menu_shell) { - if (touchscreen_mode) - { - /* close menu when returning from submenu. */ - _gtk_menu_item_popdown_submenu (GTK_MENU (menu_shell)->priv->parent_menu_item); - _gtk_menu_shell_update_mnemonics (parent_menu_shell); - break; - } - if (GTK_MENU_SHELL_GET_CLASS (parent_menu_shell)->submenu_placement == GTK_MENU_SHELL_GET_CLASS (menu_shell)->submenu_placement) gtk_menu_shell_deselect (menu_shell); @@ -1723,12 +1723,10 @@ static void gtk_real_menu_shell_cycle_focus (GtkMenuShell *menu_shell, GtkDirectionType dir) { - GtkMenuShellPrivate *priv = menu_shell->priv; - while (menu_shell && !GTK_IS_MENU_BAR (menu_shell)) { - if (priv->parent_menu_shell) - menu_shell = GTK_MENU_SHELL (priv->parent_menu_shell); + if (menu_shell->priv->parent_menu_shell) + menu_shell = GTK_MENU_SHELL (menu_shell->priv->parent_menu_shell); else menu_shell = NULL; } @@ -1859,8 +1857,11 @@ gtk_menu_shell_activate_mnemonic (GtkMenuShell *menu_shell, event->group); if (entries) - result = _gtk_mnemonic_hash_activate (mnemonic_hash, - GPOINTER_TO_UINT (entries->data)); + { + result = _gtk_mnemonic_hash_activate (mnemonic_hash, + GPOINTER_TO_UINT (entries->data)); + g_slist_free (entries); + } return result; }