[maemo-commits] [maemo-commits] r11364 - in projects/haf/trunk/gtk+: . gtk
From: subversion at stage.maemo.org subversion at stage.maemo.orgDate: Fri Apr 27 19:11:03 EEST 2007
- Previous message: [maemo-commits] r11363 - in projects/haf/trunk/libhildonmime: . debian libhildonmime tests
- Next message: [maemo-commits] r11365 - in projects/haf/trunk/libhildonmime: libhildonmime tests
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]
Author: mitch Date: 2007-04-27 19:11:00 +0300 (Fri, 27 Apr 2007) New Revision: 11364 Modified: projects/haf/trunk/gtk+/ChangeLog projects/haf/trunk/gtk+/gtk/gtkmenu.c projects/haf/trunk/gtk+/gtk/gtkmenuitem.c projects/haf/trunk/gtk+/gtk/gtkmenuitem.h projects/haf/trunk/gtk+/gtk/gtkmenushell.c Log: 2007-04-27 Michael Natterer <mitch at imendio.com> Merge from upstream trunk, getting rid of tons and tons of MAEMO_CHANGES: Merged heavily modified patch from maemo-gtk which enables opening and closing submenus on click, and introduces some usability changes when gtk-touchscreen-mode is enabled (bug #128968): * gtk/gtkmenushell.c (struct GtkMenuShellPrivate): added boolean "activated_submenu" to indicate that the current mouse operation (click or drag) has opened a submenu. (gtk_menu_shell_button_press): pop up submenus without delay and record the fact in "activated_submenu". (gtk_menu_shell_button_release): if a submenu was explicitely opened, or not opened by this release's button_press, or enough time has passed since timeout-opening it, close the submenu here. (gtk_menu_shell_enter_notify): when entering a menu item with any mouse button pressed, open its submenu. (gtk_real_menu_shell_move_current): in touchsreen mode, close the submenu when moving the focus away from it via keyboard-navigation. * gtk/gtkmenuitem.[ch] (_gtk_menu_item_popup_submenu): added parameter "gboolean with_delay" so GtkMenuShell can control this for the different scenarios of submenu showing. (_gtk_menu_item_popdown_submenu): new function. also needed by GtkMenuShell for closing submenus on click. Renamed internal function gtk_menu_item_select_timeout() to gtk_menu_item_popup_timeout(). (gtk_menu_item_real_popup_submenu): new utility function which does the actual popup and records the exact time of the popup when the menu was timeout-opened (using g_get_current_time()). (gtk_real_menu_item_select): don't add the popup timeout when in touchscreen mode. * gtk/gtkmenu.c (gtk_menu_popup): in touchscreen mode, select the first item of every opened menu. Modified: projects/haf/trunk/gtk+/ChangeLog =================================================================== --- projects/haf/trunk/gtk+/ChangeLog 2007-04-27 16:02:53 UTC (rev 11363) +++ projects/haf/trunk/gtk+/ChangeLog 2007-04-27 16:11:00 UTC (rev 11364) @@ -1,3 +1,49 @@ +2007-04-27 Michael Natterer <mitch at imendio.com> + + Merge from upstream trunk, getting rid of tons and tons + of MAEMO_CHANGES: + + Merged heavily modified patch from maemo-gtk which enables opening + and closing submenus on click, and introduces some usability + changes when gtk-touchscreen-mode is enabled (bug #128968): + + * gtk/gtkmenushell.c (struct GtkMenuShellPrivate): added boolean + "activated_submenu" to indicate that the current mouse operation + (click or drag) has opened a submenu. + + (gtk_menu_shell_button_press): pop up submenus without delay + and record the fact in "activated_submenu". + + (gtk_menu_shell_button_release): if a submenu was explicitely + opened, or not opened by this release's button_press, or enough + time has passed since timeout-opening it, close the submenu here. + + (gtk_menu_shell_enter_notify): when entering a menu item with + any mouse button pressed, open its submenu. + + (gtk_real_menu_shell_move_current): in touchsreen mode, close the + submenu when moving the focus away from it via keyboard-navigation. + + * gtk/gtkmenuitem.[ch] (_gtk_menu_item_popup_submenu): added + parameter "gboolean with_delay" so GtkMenuShell can control this + for the different scenarios of submenu showing. + + (_gtk_menu_item_popdown_submenu): new function. also needed by + GtkMenuShell for closing submenus on click. + + Renamed internal function gtk_menu_item_select_timeout() to + gtk_menu_item_popup_timeout(). + + (gtk_menu_item_real_popup_submenu): new utility function which + does the actual popup and records the exact time of the popup when + the menu was timeout-opened (using g_get_current_time()). + + (gtk_real_menu_item_select): don't add the popup timeout when in + touchscreen mode. + + * gtk/gtkmenu.c (gtk_menu_popup): in touchscreen mode, select the + first item of every opened menu. + 2007-04-25 Michael Natterer <mitch at imendio.com> Merge from upstream trunk: Modified: projects/haf/trunk/gtk+/gtk/gtkmenu.c =================================================================== --- projects/haf/trunk/gtk+/gtk/gtkmenu.c 2007-04-27 16:02:53 UTC (rev 11363) +++ projects/haf/trunk/gtk+/gtk/gtkmenu.c 2007-04-27 16:11:00 UTC (rev 11364) @@ -1538,12 +1538,21 @@ NULL); _gtk_menu_shell_set_first_click (menu_shell); +#endif /* MAEMO_CHANGES */ /* if no item is selected, select the first one */ if (!menu_shell->active_menu_item) - gtk_menu_shell_select_first (menu_shell, TRUE); -#endif /* MAEMO_CHANGES */ + { + gboolean touchscreen_mode; + g_object_get (gtk_widget_get_settings (GTK_WIDGET (menu)), + "gtk-touchscreen-mode", &touchscreen_mode, + NULL); + + if (touchscreen_mode) + gtk_menu_shell_select_first (menu_shell, TRUE); + } + /* Once everything is set up correctly, map the toplevel window on the screen. */ Modified: projects/haf/trunk/gtk+/gtk/gtkmenuitem.c =================================================================== --- projects/haf/trunk/gtk+/gtk/gtkmenuitem.c 2007-04-27 16:02:53 UTC (rev 11363) +++ projects/haf/trunk/gtk+/gtk/gtkmenuitem.c 2007-04-27 16:11:00 UTC (rev 11364) @@ -71,9 +71,6 @@ static void gtk_real_menu_item_select (GtkItem *item); static void gtk_real_menu_item_deselect (GtkItem *item); -#ifdef MAEMO_CHANGES -static void gtk_real_menu_item_activate (GtkMenuItem *item); -#endif /* MAEMO_CHANGES */ static void gtk_real_menu_item_activate_item (GtkMenuItem *item); static void gtk_real_menu_item_toggle_size_request (GtkMenuItem *menu_item, gint *requisition); @@ -82,7 +79,7 @@ static gboolean gtk_menu_item_mnemonic_activate (GtkWidget *widget, gboolean group_cycling); -static gint gtk_menu_item_select_timeout (gpointer data); +static gint gtk_menu_item_popup_timeout (gpointer data); static void gtk_menu_item_position_menu (GtkMenu *menu, gint *x, gint *y, @@ -133,11 +130,7 @@ item_class->select = gtk_real_menu_item_select; item_class->deselect = gtk_real_menu_item_deselect; -#ifdef MAEMO_CHANGES - klass->activate = gtk_real_menu_item_activate; -#else klass->activate = NULL; -#endif /* MAEMO_CHANGES */ klass->activate_item = gtk_real_menu_item_activate_item; klass->toggle_size_request = gtk_real_menu_item_toggle_size_request; klass->toggle_size_allocate = gtk_real_menu_item_toggle_size_allocate; @@ -896,75 +889,28 @@ return FALSE; } -static gint -get_popup_delay (GtkMenuItem *menu_item) -{ - GtkWidget *parent = GTK_WIDGET (menu_item)->parent; - - if (GTK_IS_MENU_SHELL (parent)) - { - return _gtk_menu_shell_get_popup_delay (GTK_MENU_SHELL (parent)); - } - else - { - gint popup_delay; - - g_object_get (gtk_widget_get_settings (GTK_WIDGET (menu_item)), - "gtk-menu-popup-delay", &popup_delay, - NULL); - - return popup_delay; - } -} - static void gtk_real_menu_item_select (GtkItem *item) { GtkMenuItem *menu_item; + gboolean touchscreen_mode; g_return_if_fail (GTK_IS_MENU_ITEM (item)); menu_item = GTK_MENU_ITEM (item); - if (menu_item->submenu && + g_object_get (gtk_widget_get_settings (GTK_WIDGET (item)), + "gtk-touchscreen-mode", &touchscreen_mode, + NULL); + + if (!touchscreen_mode && + menu_item->submenu && (!GTK_WIDGET_MAPPED (menu_item->submenu) || GTK_MENU (menu_item->submenu)->tearoff_active)) { - gint popup_delay; - - if (menu_item->timer) - { - g_source_remove (menu_item->timer); - menu_item->timer = 0; - popup_delay = 0; - } - else - popup_delay = get_popup_delay (menu_item); - - if (popup_delay > 0) - { - GdkEvent *event = gtk_get_current_event (); - -#ifndef MAEMO_CHANGES - menu_item->timer = g_timeout_add (popup_delay, - gtk_menu_item_select_timeout, - menu_item); -#endif /* !MAEMO_CHANGES */ - - if (event && - event->type != GDK_BUTTON_PRESS && - event->type != GDK_ENTER_NOTIFY) - menu_item->timer_from_keypress = TRUE; - else - menu_item->timer_from_keypress = FALSE; - - if (event) - gdk_event_free (event); - } - else - _gtk_menu_item_popup_submenu (GTK_WIDGET (menu_item)); + _gtk_menu_item_popup_submenu (GTK_WIDGET (menu_item), TRUE); } - + gtk_widget_set_state (GTK_WIDGET (menu_item), GTK_STATE_PRELIGHT); gtk_widget_queue_draw (GTK_WIDGET (menu_item)); } @@ -972,18 +918,6 @@ static void gtk_real_menu_item_deselect (GtkItem *item) { -#ifdef MAEMO_CHANGES - GtkWidget *menu_item; - - g_return_if_fail (GTK_IS_MENU_ITEM (item)); - - menu_item = GTK_WIDGET (item); - - _gtk_menu_item_popdown_submenu (menu_item); - - gtk_widget_set_state (menu_item, GTK_STATE_NORMAL); - gtk_widget_queue_draw (menu_item); -#else GtkMenuItem *menu_item; g_return_if_fail (GTK_IS_MENU_ITEM (item)); @@ -991,19 +925,10 @@ menu_item = GTK_MENU_ITEM (item); if (menu_item->submenu) - { - if (menu_item->timer) - { - g_source_remove (menu_item->timer); - menu_item->timer = 0; - } - else - gtk_menu_popdown (GTK_MENU (menu_item->submenu)); - } + _gtk_menu_item_popdown_submenu (GTK_WIDGET (menu_item)); gtk_widget_set_state (GTK_WIDGET (menu_item), GTK_STATE_NORMAL); gtk_widget_queue_draw (GTK_WIDGET (menu_item)); -#endif /* MAEMO_CHANGES */ } static gboolean @@ -1024,51 +949,7 @@ return TRUE; } -#ifdef MAEMO_CHANGES -/* This function exists only for opening submenus on - * activation. - */ static void -gtk_real_menu_item_activate (GtkMenuItem *item) -{ - GdkEvent *event; - gint popup_delay; - - g_return_if_fail (GTK_IS_MENU_ITEM (item)); - - if (!GTK_IS_MENU (item->submenu) || - GTK_WIDGET_VISIBLE (item->submenu)) - return; - - event = gtk_get_current_event (); - - /* Add a delay before opening a new menu */ - if (item->timer) - { - g_source_remove (item->timer); - item->timer = 0; - popup_delay = 0; - } - else - popup_delay = get_popup_delay (item); - - item->timer = g_timeout_add (popup_delay, - gtk_menu_item_select_timeout, - item); - - /* We don't want to select first item if the submenu - * is opened with mouse release because the selection - * would move straigh back under the cursor. - */ - if ((event == NULL) || (event->type != GDK_BUTTON_RELEASE)) - gtk_menu_shell_select_first (GTK_MENU_SHELL (item->submenu), TRUE); - - if (event) - gdk_event_free (event); -} -#endif /* MAEMO_CHANGES */ - -static void gtk_real_menu_item_activate_item (GtkMenuItem *menu_item) { GtkWidget *widget; @@ -1089,14 +970,14 @@ _gtk_menu_shell_activate (menu_shell); - gtk_menu_shell_select_item (GTK_MENU_SHELL (widget->parent), widget); + gtk_menu_shell_select_item (GTK_MENU_SHELL (widget->parent), widget); + _gtk_menu_item_popup_submenu (widget, FALSE); - _gtk_menu_item_popup_submenu (widget); - gtk_menu_shell_select_first (GTK_MENU_SHELL (menu_item->submenu), TRUE); } } } + static void gtk_real_menu_item_toggle_size_request (GtkMenuItem *menu_item, gint *requisition) @@ -1115,8 +996,53 @@ menu_item->toggle_size = allocation; } +static void +gtk_menu_item_real_popup_submenu (GtkWidget *widget, + gboolean remember_exact_time) +{ + GtkMenuItem *menu_item = GTK_MENU_ITEM (widget); + + if (GTK_WIDGET_IS_SENSITIVE (menu_item->submenu)) + { + gboolean take_focus; + + take_focus = gtk_menu_shell_get_take_focus (GTK_MENU_SHELL (widget->parent)); + gtk_menu_shell_set_take_focus (GTK_MENU_SHELL (menu_item->submenu), + take_focus); + + if (remember_exact_time) + { + GTimeVal *popup_time = g_new0 (GTimeVal, 1); + + g_get_current_time (popup_time); + + g_object_set_data_full (G_OBJECT (menu_item->submenu), + "gtk-menu-exact-popup-time", popup_time, + (GDestroyNotify) g_free); + } + else + { + g_object_set_data (G_OBJECT (menu_item->submenu), + "gtk-menu-exact-popup-time", NULL); + } + + gtk_menu_popup (GTK_MENU (menu_item->submenu), + widget->parent, + widget, + gtk_menu_item_position_menu, + menu_item, + GTK_MENU_SHELL (widget->parent)->button, + 0); + } + + /* Enable themeing of the parent menu item depending on whether + * its submenu is shown or not. + */ + gtk_widget_queue_draw (widget); +} + static gint -gtk_menu_item_select_timeout (gpointer data) +gtk_menu_item_popup_timeout (gpointer data) { GtkMenuItem *menu_item; GtkWidget *parent; @@ -1130,53 +1056,79 @@ if ((GTK_IS_MENU_SHELL (parent) && GTK_MENU_SHELL (parent)->active) || (GTK_IS_MENU (parent) && GTK_MENU (parent)->torn_off)) { - _gtk_menu_item_popup_submenu (GTK_WIDGET (menu_item)); + gtk_menu_item_real_popup_submenu (GTK_WIDGET (menu_item), TRUE); if (menu_item->timer_from_keypress && menu_item->submenu) GTK_MENU_SHELL (menu_item->submenu)->ignore_enter = TRUE; } + menu_item->timer = 0; + GDK_THREADS_LEAVE (); return FALSE; } -void -_gtk_menu_item_popup_submenu (GtkWidget *widget) +static gint +get_popup_delay (GtkWidget *widget) { - GtkMenuItem *menu_item; + if (GTK_IS_MENU_SHELL (widget->parent)) + { + return _gtk_menu_shell_get_popup_delay (GTK_MENU_SHELL (widget->parent)); + } + else + { + gint popup_delay; - menu_item = GTK_MENU_ITEM (widget); + g_object_get (gtk_widget_get_settings (widget), + "gtk-menu-popup-delay", &popup_delay, + NULL); + return popup_delay; + } +} + +void +_gtk_menu_item_popup_submenu (GtkWidget *widget, + gboolean with_delay) +{ + GtkMenuItem *menu_item = GTK_MENU_ITEM (widget); + if (menu_item->timer) - g_source_remove (menu_item->timer); - menu_item->timer = 0; + { + g_source_remove (menu_item->timer); + menu_item->timer = 0; + with_delay = FALSE; + } - if (GTK_WIDGET_IS_SENSITIVE (menu_item->submenu)) + if (with_delay) { - gboolean take_focus; + gint popup_delay = get_popup_delay (widget); - take_focus = gtk_menu_shell_get_take_focus (GTK_MENU_SHELL (widget->parent)); - gtk_menu_shell_set_take_focus (GTK_MENU_SHELL (menu_item->submenu), - take_focus); + if (popup_delay > 0) + { + GdkEvent *event = gtk_get_current_event (); - gtk_menu_popup (GTK_MENU (menu_item->submenu), - widget->parent, - widget, - gtk_menu_item_position_menu, - menu_item, - GTK_MENU_SHELL (widget->parent)->button, - 0); + menu_item->timer = g_timeout_add (popup_delay, + gtk_menu_item_popup_timeout, + menu_item); + + if (event && + event->type != GDK_BUTTON_PRESS && + event->type != GDK_ENTER_NOTIFY) + menu_item->timer_from_keypress = TRUE; + else + menu_item->timer_from_keypress = FALSE; + + if (event) + gdk_event_free (event); + + return; + } } -#ifdef MAEMO_CHANGES - /* This is required as changed submenu arrow isn't drawn automatically - * and drawing it must be requested. - */ - gtk_widget_queue_draw (widget); -#endif /* MAEMO_CHANGES */ + gtk_menu_item_real_popup_submenu (widget, FALSE); } -#ifdef MAEMO_CHANGES void _gtk_menu_item_popdown_submenu (GtkWidget *widget) { @@ -1186,6 +1138,9 @@ if (menu_item->submenu) { + g_object_set_data (G_OBJECT (menu_item->submenu), + "gtk-menu-exact-popup-time", NULL); + if (menu_item->timer) { g_source_remove (menu_item->timer); @@ -1193,11 +1148,10 @@ } else gtk_menu_popdown (GTK_MENU (menu_item->submenu)); - } - gtk_widget_queue_draw (widget); + gtk_widget_queue_draw (widget); + } } -#endif /* MAEMO_CHANGES */ static void get_offsets (GtkMenu *menu, @@ -1417,7 +1371,6 @@ return menu_item->right_justify; } - static void gtk_menu_item_show_all (GtkWidget *widget) { Modified: projects/haf/trunk/gtk+/gtk/gtkmenuitem.h =================================================================== --- projects/haf/trunk/gtk+/gtk/gtkmenuitem.h 2007-04-27 16:02:53 UTC (rev 11363) +++ projects/haf/trunk/gtk+/gtk/gtkmenuitem.h 2007-04-27 16:11:00 UTC (rev 11364) @@ -119,10 +119,9 @@ GtkAccelGroup *accel_group, gboolean group_changed); gboolean _gtk_menu_item_is_selectable (GtkWidget *menu_item); -void _gtk_menu_item_popup_submenu (GtkWidget *menu_item); -#ifdef MAEMO_CHANGES +void _gtk_menu_item_popup_submenu (GtkWidget *menu_item, + gboolean with_delay); void _gtk_menu_item_popdown_submenu (GtkWidget *menu_item); -#endif /* MAEMO_CHANGES */ #ifndef GTK_DISABLE_DEPRECATED #define gtk_menu_item_right_justify(menu_item) gtk_menu_item_set_right_justified ((menu_item), TRUE) Modified: projects/haf/trunk/gtk+/gtk/gtkmenushell.c =================================================================== --- projects/haf/trunk/gtk+/gtk/gtkmenushell.c 2007-04-27 16:02:53 UTC (rev 11363) +++ projects/haf/trunk/gtk+/gtk/gtkmenushell.c 2007-04-27 16:11:00 UTC (rev 11364) @@ -32,9 +32,7 @@ #include "gtkkeyhash.h" #include "gtkmain.h" #include "gtkmarshalers.h" -#ifdef MAEMO_CHANGES #include "gtkmenu.h" -#endif /* MAEMO_CHANGES */ #include "gtkmenubar.h" #include "gtkmenuitem.h" #include "gtkmenushell.h" @@ -135,10 +133,10 @@ GtkMnemonicHash *mnemonic_hash; GtkKeyHash *key_hash; - gboolean take_focus; + guint take_focus : 1; + guint activated_submenu : 1; #ifdef MAEMO_CHANGES - gboolean activated_submenu; - gboolean first_click; + guint first_click : 1; #endif /* MAEMO_CHANGES */ }; @@ -388,8 +386,8 @@ priv->mnemonic_hash = NULL; priv->key_hash = NULL; priv->take_focus = TRUE; -#ifdef MAEMO_CHANGES priv->activated_submenu = FALSE; +#ifdef MAEMO_CHANGES priv->first_click = FALSE; #endif /* MAEMO_CHANGES */ } @@ -544,80 +542,58 @@ gtk_menu_shell_button_press (GtkWidget *widget, GdkEventButton *event) { -#ifdef MAEMO_CHANGES - GtkMenuShellPrivate *priv; -#endif /* MAEMO_CHANGES */ GtkMenuShell *menu_shell; GtkWidget *menu_item; - g_return_val_if_fail (GTK_IS_MENU_SHELL (widget), FALSE); - g_return_val_if_fail (event != NULL, FALSE); - if (event->type != GDK_BUTTON_PRESS) return FALSE; menu_shell = GTK_MENU_SHELL (widget); -#ifdef MAEMO_CHANGES - priv = GTK_MENU_SHELL_GET_PRIVATE (widget); + if (menu_shell->parent_menu_shell) + return gtk_widget_event (menu_shell->parent_menu_shell, (GdkEvent*) event); + menu_item = gtk_menu_shell_get_item (menu_shell, (GdkEvent *)event); -#endif /* MAEMO_CHANGES */ -#ifdef MAEMO_CHANGES - if (!menu_shell->active) -#else - if (menu_shell->parent_menu_shell) + if (menu_item && _gtk_menu_item_is_selectable (menu_item) && + menu_item != GTK_MENU_SHELL (menu_item->parent)->active_menu_item) { - return gtk_widget_event (menu_shell->parent_menu_shell, (GdkEvent*) event); + /* select the menu item *before* activating the shell, so submenus + * which might be open are closed the friendly way. If we activate + * (and thus grab) this menu shell first, we might get grab_broken + * events which will close the entire menu hierarchy. Selecting the + * menu item also fixes up the state as if enter_notify() would + * have run before (which normally selects the item). + */ + if (GTK_MENU_SHELL_GET_CLASS (menu_item->parent)->submenu_placement != GTK_TOP_BOTTOM) + { + gtk_menu_shell_select_item (GTK_MENU_SHELL (menu_item->parent), menu_item); + } } - else if (!menu_shell->active || !menu_shell->button) -#endif /* MAEMO_CHANGES */ + + if (!menu_shell->active || !menu_shell->button) { _gtk_menu_shell_activate (menu_shell); - + menu_shell->button = event->button; -#ifndef MAEMO_CHANGES - menu_item = gtk_menu_shell_get_item (menu_shell, (GdkEvent *)event); -#endif /* MAEMO_CHANGES */ - - if (menu_item && _gtk_menu_item_is_selectable (menu_item)) - { - if ((menu_item->parent == widget) && - (menu_item != menu_shell->active_menu_item)) - { - if (GTK_MENU_SHELL_GET_CLASS (menu_shell)->submenu_placement == GTK_TOP_BOTTOM) - { - menu_shell->activate_time = event->time; - } - - gtk_menu_shell_select_item (menu_shell, menu_item); - } - } + if (menu_item && _gtk_menu_item_is_selectable (menu_item) && + menu_item->parent == widget && + menu_item != menu_shell->active_menu_item) + { + if (GTK_MENU_SHELL_GET_CLASS (menu_shell)->submenu_placement == GTK_TOP_BOTTOM) + { + menu_shell->activate_time = event->time; + gtk_menu_shell_select_item (menu_shell, menu_item); + } + } } else { #ifdef MAEMO_CHANGES - priv->first_click = FALSE; + GtkMenuShellPrivate *priv = GTK_MENU_SHELL_GET_PRIVATE (widget); - /* Activate submenu on button press, so that we can drag-move into it if - * necessary. - */ - if (menu_item && _gtk_menu_item_is_selectable (menu_item) && - GTK_MENU_ITEM (menu_item)->submenu != NULL && - !GTK_WIDGET_VISIBLE (GTK_MENU_ITEM (menu_item)->submenu)) - { - /* Hildon-crack: The item could be unselected when the tap - * occurs, make sure it gets selected. The real fix is bug#11670, - * remove this crack when it is done. - * NB#9417 - */ - gtk_menu_shell_select_item (menu_shell, menu_item); - - gtk_menu_shell_activate_item (menu_shell, menu_item, FALSE); - - priv->activated_submenu = TRUE; - } + priv->first_click = FALSE; #endif /* MAEMO_CHANGES */ widget = gtk_get_event_widget ((GdkEvent*) event); @@ -628,6 +604,18 @@ } } + if (menu_item && _gtk_menu_item_is_selectable (menu_item) && + GTK_MENU_ITEM (menu_item)->submenu != NULL && + !GTK_WIDGET_VISIBLE (GTK_MENU_ITEM (menu_item)->submenu)) + { + GtkMenuShellPrivate *priv; + + _gtk_menu_item_popup_submenu (menu_item, FALSE); + + priv = GTK_MENU_SHELL_GET_PRIVATE (menu_item->parent); + priv->activated_submenu = TRUE; + } + return TRUE; } @@ -655,162 +643,141 @@ gtk_menu_shell_button_release (GtkWidget *widget, GdkEventButton *event) { -#ifdef MAEMO_CHANGES - GtkMenuShellPrivate *priv; -#endif /* MAEMO_CHANGES */ - GtkMenuShell *menu_shell; - GtkWidget *menu_item; - gint deactivate; + GtkMenuShell *menu_shell = GTK_MENU_SHELL (widget); + GtkMenuShellPrivate *priv = GTK_MENU_SHELL_GET_PRIVATE (widget); - g_return_val_if_fail (GTK_IS_MENU_SHELL (widget), FALSE); - g_return_val_if_fail (event != NULL, FALSE); - - menu_shell = GTK_MENU_SHELL (widget); - -#ifdef MAEMO_CHANGES - - priv = GTK_MENU_SHELL_GET_PRIVATE (widget); - - menu_item = gtk_menu_shell_get_item (menu_shell, (GdkEvent*) event); - - if (menu_item && _gtk_menu_item_is_selectable (menu_item)) + if (menu_shell->active) { - if (GTK_MENU_ITEM (menu_item)->submenu == NULL) - { - GtkSettings *settings = gtk_widget_get_settings (widget); - int timeout; + GtkWidget *menu_item; + gboolean deactivate = TRUE; - g_object_get (settings, "gtk-timeout-initial", &timeout, NULL); + 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); + } - /* Prevent immediate activation on first click, this is mainly - * for combo popups and the like. */ - if (!priv->first_click || - (menu_shell->activate_time == 0) || - ((event->time - menu_shell->activate_time) > timeout)) - gtk_menu_shell_activate_item (menu_shell, menu_item, TRUE); + menu_shell->button = 0; + menu_item = gtk_menu_shell_get_item (menu_shell, (GdkEvent*) event); - /* activate_item will take care of deactivation if needed */ - deactivate = FALSE; - } - else + if ((event->time - menu_shell->activate_time) > MENU_SHELL_TIMEOUT) { - /* If we ended up on an item with a submenu, leave the menu up. */ - deactivate = FALSE; + if (menu_item && (menu_shell->active_menu_item == menu_item) && + _gtk_menu_item_is_selectable (menu_item)) + { + GtkWidget *submenu = GTK_MENU_ITEM (menu_item)->submenu; - /* popdown the submenu if we didn't pop it up in this click */ - if (!priv->activated_submenu && - GTK_MENU_SHELL_GET_CLASS (menu_shell)->submenu_placement != GTK_TOP_BOTTOM) - _gtk_menu_item_popdown_submenu (menu_item); - } - } - else if (menu_item && - !_gtk_menu_item_is_selectable (menu_item) && - GTK_MENU_SHELL_GET_CLASS (menu_shell)->submenu_placement != GTK_TOP_BOTTOM) - { - deactivate = FALSE; - } - else if (menu_shell->parent_menu_shell) - { - /* Forward to parent (deactivate, mostly) if we have one */ - gtk_widget_event (menu_shell->parent_menu_shell, (GdkEvent*) event); + if (submenu == NULL) + { +#ifdef MAEMO_CHANGES + if (!priv->first_click) +#endif /* MAEMO_CHANGES */ + gtk_menu_shell_activate_item (menu_shell, menu_item, TRUE); - deactivate = FALSE; - } - else - { - /* Not over a menuitem of any kind, no parent shell, so deactivate. */ - deactivate = TRUE; - } + deactivate = FALSE; + } + else if (GTK_MENU_SHELL_GET_CLASS (menu_shell)->submenu_placement != GTK_TOP_BOTTOM || + priv->activated_submenu) + { + gint popdown_delay; + GTimeVal *popup_time; + gint64 usec_since_popup = 0; - if (priv->first_click) - { - /* We only ever want to prevent deactivation on the first - * press/release. */ - priv->first_click = FALSE; + g_object_get (gtk_widget_get_settings (widget), + "gtk-menu-popdown-delay", &popdown_delay, + NULL); - deactivate = FALSE; - } + popup_time = g_object_get_data (G_OBJECT (submenu), + "gtk-menu-exact-popup-time"); - if (deactivate) - { - gtk_menu_shell_deactivate (menu_shell); - g_signal_emit (menu_shell, menu_shell_signals[SELECTION_DONE], 0); - } + if (popup_time) + { + GTimeVal current_time; - priv->activated_submenu = FALSE; + g_get_current_time (¤t_time); -#else /* !MAEMO_CHANGES */ - if (menu_shell->active) - { - 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); - } + usec_since_popup = ((gint64) current_time.tv_sec * 1000 * 1000 + + (gint64) current_time.tv_usec - + (gint64) popup_time->tv_sec * 1000 * 1000 - + (gint64) popup_time->tv_usec); - menu_shell->button = 0; - menu_item = gtk_menu_shell_get_item (menu_shell, (GdkEvent*) event); + g_object_set_data (G_OBJECT (submenu), + "gtk-menu-exact-popup-time", NULL); + } - deactivate = TRUE; + /* only close the submenu on click if we opened the + * menu explicitely (usec_since_popup == 0) or + * enough time has passed since it was opened by + * GtkMenuItem's timeout (usec_since_popup > delay). + */ + if (!priv->activated_submenu && + (usec_since_popup == 0 || + usec_since_popup > popdown_delay * 1000)) + { + _gtk_menu_item_popdown_submenu (menu_item); + } + else + { + gtk_menu_item_select (GTK_MENU_ITEM (menu_item)); + } - if ((event->time - menu_shell->activate_time) > MENU_SHELL_TIMEOUT) - { - if (menu_item && (menu_shell->active_menu_item == menu_item) && - _gtk_menu_item_is_selectable (menu_item)) - { - if (GTK_MENU_ITEM (menu_item)->submenu == NULL) - { - gtk_menu_shell_activate_item (menu_shell, menu_item, TRUE); - return TRUE; - } - else if (GTK_MENU_SHELL_GET_CLASS (menu_shell)->submenu_placement != GTK_TOP_BOTTOM) - { - gtk_menu_item_select (GTK_MENU_ITEM (menu_item)); - return TRUE; - } - } - else if (menu_item && - !_gtk_menu_item_is_selectable (menu_item) && - GTK_MENU_SHELL_GET_CLASS (menu_shell)->submenu_placement != GTK_TOP_BOTTOM) - { - deactivate = FALSE; - } - else if (menu_shell->parent_menu_shell) - { - menu_shell->active = TRUE; - gtk_widget_event (menu_shell->parent_menu_shell, (GdkEvent*) event); - return TRUE; - } + deactivate = FALSE; + } + } + else if (menu_item && + !_gtk_menu_item_is_selectable (menu_item) && + GTK_MENU_SHELL_GET_CLASS (menu_shell)->submenu_placement != GTK_TOP_BOTTOM) + { + deactivate = FALSE; + } + else if (menu_shell->parent_menu_shell) + { + menu_shell->active = TRUE; + gtk_widget_event (menu_shell->parent_menu_shell, (GdkEvent*) event); + deactivate = FALSE; + } - /* If we ended up on an item with a submenu, leave the menu up. - */ - if (menu_item && (menu_shell->active_menu_item == menu_item) && - GTK_MENU_SHELL_GET_CLASS (menu_shell)->submenu_placement != GTK_TOP_BOTTOM) - { - deactivate = FALSE; - } - } + /* If we ended up on an item with a submenu, leave the menu up. + */ + if (menu_item && (menu_shell->active_menu_item == menu_item) && + GTK_MENU_SHELL_GET_CLASS (menu_shell)->submenu_placement != GTK_TOP_BOTTOM) + { + deactivate = FALSE; + } + } else /* a very fast press-release */ - { - /* We only ever want to prevent deactivation on the first + { + /* We only ever want to prevent deactivation on the first * press/release. Setting the time to zero is a bit of a - * hack, since we could be being triggered in the first - * few fractions of a second after a server time wraparound. - * the chances of that happening are ~1/10^6, without - * serious harm if we lose. - */ - menu_shell->activate_time = 0; - deactivate = FALSE; - } - + * hack, since we could be being triggered in the first + * few fractions of a second after a server time wraparound. + * the chances of that happening are ~1/10^6, without + * serious harm if we lose. + */ + menu_shell->activate_time = 0; + deactivate = FALSE; + } + +#ifdef MAEMO_CHANGES + if (priv->first_click) + { + /* We only ever want to prevent deactivation on the first + * press/release. */ + priv->first_click = FALSE; + + deactivate = FALSE; + } +#endif /* MAEMO_CHANGES */ + if (deactivate) - { - gtk_menu_shell_deactivate (menu_shell); - g_signal_emit (menu_shell, menu_shell_signals[SELECTION_DONE], 0); - } + { + gtk_menu_shell_deactivate (menu_shell); + g_signal_emit (menu_shell, menu_shell_signals[SELECTION_DONE], 0); + } + + priv->activated_submenu = FALSE; } -#endif /* MAEMO_CHANGES */ return TRUE; } @@ -847,23 +814,17 @@ gtk_menu_shell_enter_notify (GtkWidget *widget, GdkEventCrossing *event) { -#ifdef MAEMO_CHANGES - GtkMenuShellPrivate *priv; -#endif /* MAEMO_CHANGES */ GtkMenuShell *menu_shell; - GtkWidget *menu_item; g_return_val_if_fail (GTK_IS_MENU_SHELL (widget), FALSE); g_return_val_if_fail (event != NULL, FALSE); menu_shell = GTK_MENU_SHELL (widget); -#ifdef MAEMO_CHANGES - priv = GTK_MENU_SHELL_GET_PRIVATE (widget); -#endif /* MAEMO_CHANGES */ - if (menu_shell->active) { + GtkWidget *menu_item; + menu_item = gtk_get_event_widget ((GdkEvent*) event); if (!menu_item || @@ -883,19 +844,26 @@ { gtk_menu_shell_select_item (menu_shell, menu_item); -#ifdef MAEMO_CHANGES - /* If the pen is down, and there is a submenu that is not - * yet visible, activate it + /* If any mouse button is down, and there is a submenu + * that is not yet visible, activate it. It's sufficient + * to check for any button's mask (not only the one + * matching menu_shell->button), because there is no + * situation a mouse button could be pressed while + * entering a menu item where we wouldn't want to show + * its submenu. */ - if ((event->state & GDK_BUTTON1_MASK) && + if ((event->state & (GDK_BUTTON1_MASK | GDK_BUTTON2_MASK | GDK_BUTTON2_MASK)) && GTK_MENU_ITEM (menu_item)->submenu != NULL && !GTK_WIDGET_VISIBLE (GTK_MENU_ITEM (menu_item)->submenu)) { - gtk_menu_shell_activate_item (menu_shell, menu_item, FALSE); + GtkMenuShellPrivate *priv; + priv = GTK_MENU_SHELL_GET_PRIVATE (menu_item->parent); + + _gtk_menu_item_popup_submenu (menu_item, TRUE); + priv->activated_submenu = TRUE; } -#endif /* MAEMO_CHANGES */ } } else if (menu_shell->parent_menu_shell) @@ -931,14 +899,8 @@ if (!_gtk_menu_item_is_selectable (event_widget)) return TRUE; -#ifdef MAEMO_CHANGES if ((menu_shell->active_menu_item == event_widget) && - ((menu_item->submenu == NULL) || - (!GTK_WIDGET_VISIBLE (menu_item->submenu)))) -#else - if ((menu_shell->active_menu_item == event_widget) && (menu_item->submenu == NULL)) -#endif /* MAEMO_CHANGES */ { if ((event->detail != GDK_NOTIFY_INFERIOR) && (GTK_WIDGET_STATE (menu_item) != GTK_STATE_NORMAL)) @@ -1140,13 +1102,11 @@ GTK_MENU_SHELL_GET_CLASS (menu_shell)->submenu_placement); gtk_menu_item_select (GTK_MENU_ITEM (menu_shell->active_menu_item)); -#ifndef MAEMO_CHANGES /* This allows the bizarre radio buttons-with-submenus-display-history * behavior */ if (GTK_MENU_ITEM (menu_shell->active_menu_item)->submenu) gtk_widget_activate (menu_shell->active_menu_item); -#endif /* !MAEMO_CHANGES */ } void @@ -1168,9 +1128,6 @@ { GSList *slist, *shells = NULL; gboolean deactivate = force_deactivate; -#ifdef MAEMO_CHANGES - gboolean submenu = FALSE; -#endif /* MAEMO_CHANGES */ g_return_if_fail (GTK_IS_MENU_SHELL (menu_shell)); g_return_if_fail (GTK_IS_MENU_ITEM (menu_item)); @@ -1181,16 +1138,7 @@ g_object_ref (menu_shell); g_object_ref (menu_item); -#ifdef MAEMO_CHANGES - if (GTK_MENU_ITEM (menu_item)->submenu != NULL) - submenu = TRUE; -#endif /* MAEMO_CHANGES */ - -#ifdef MAEMO_CHANGES - if (deactivate && !submenu) -#else if (deactivate) -#endif /* MAEMO_CHANGES */ { GtkMenuShell *parent_menu_shell = menu_shell; @@ -1210,29 +1158,15 @@ */ gdk_display_sync (gtk_widget_get_display (menu_item)); } -#ifdef MAEMO_CHANGES - else if (submenu) - { - _gtk_menu_item_set_placement (GTK_MENU_ITEM (menu_item), - GTK_MENU_SHELL_GET_CLASS (menu_shell)->submenu_placement); - } -#endif /* MAEMO_CHANGES */ gtk_widget_activate (menu_item); -#ifdef MAEMO_CHANGES - if (!submenu) - { -#endif /* MAEMO_CHANGES */ for (slist = shells; slist; slist = slist->next) { g_signal_emit (slist->data, menu_shell_signals[SELECTION_DONE], 0); g_object_unref (slist->data); } g_slist_free (shells); -#ifdef MAEMO_CHANGES - } -#endif /* MAEMO_CHANGES */ g_object_unref (menu_shell); g_object_unref (menu_item); @@ -1372,11 +1306,7 @@ if (menu_item->submenu) { -#ifdef MAEMO_CHANGES - gtk_menu_shell_activate_item (menu_shell, GTK_WIDGET (menu_item), FALSE); -#else - _gtk_menu_item_popup_submenu (GTK_WIDGET (menu_item)); -#endif /* MAEMO_CHANGES */ + _gtk_menu_item_popup_submenu (GTK_WIDGET (menu_item), FALSE); gtk_menu_shell_select_first (GTK_MENU_SHELL (menu_item->submenu), TRUE); if (GTK_MENU_SHELL (menu_item->submenu)->active_menu_item) return TRUE; @@ -1386,8 +1316,8 @@ } static void -gtk_real_menu_shell_move_current (GtkMenuShell *menu_shell, - GtkMenuDirectionType direction) +gtk_real_menu_shell_move_current (GtkMenuShell *menu_shell, + GtkMenuDirectionType direction) { GtkMenuShell *parent_menu_shell = NULL; gboolean had_selection; @@ -1400,21 +1330,21 @@ switch (direction) { case GTK_MENU_DIR_PARENT: + if (parent_menu_shell) + { + gboolean touchscreen_mode; -#ifdef MAEMO_CHANGES - if(!parent_menu_shell || GTK_IS_MENU_BAR (parent_menu_shell)) - break; + g_object_get (gtk_widget_get_settings (GTK_WIDGET (menu_shell)), + "gtk-touchscreen-mode", &touchscreen_mode, + NULL); - /* menu should be closed when returning from submenu. - * WARNING: This function is from GtkMenu, which normally - * shouldn't be called from GtkMenuShell, but currently - * there are no better alternatives. - */ - gtk_menu_popdown (GTK_MENU (menu_shell)); -#endif /* MAEMO_CHANGES */ + if (touchscreen_mode) + { + /* close menu when returning from submenu. */ + _gtk_menu_item_popdown_submenu (GTK_MENU (menu_shell)->parent_menu_item); + break; + } - if (parent_menu_shell) - { 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); @@ -1496,16 +1426,12 @@ if (menu_shell->active_menu_item && _gtk_menu_item_is_selectable (menu_shell->active_menu_item)) { -#ifndef MAEMO_CHANGES if (GTK_MENU_ITEM (menu_shell->active_menu_item)->submenu == NULL) -#endif /* !MAEMO_CHANGES */ gtk_menu_shell_activate_item (menu_shell, menu_shell->active_menu_item, force_hide); -#ifndef MAEMO_CHANGES else - _gtk_menu_item_popup_submenu (menu_shell->active_menu_item); -#endif /* !MAEMO_CHANGES */ + _gtk_menu_item_popup_submenu (menu_shell->active_menu_item, FALSE); } }
- Previous message: [maemo-commits] r11363 - in projects/haf/trunk/libhildonmime: . debian libhildonmime tests
- Next message: [maemo-commits] r11365 - in projects/haf/trunk/libhildonmime: libhildonmime tests
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]