diff options
author | Matthias Clasen <mclasen@redhat.com> | 2021-05-24 17:27:40 -0400 |
---|---|---|
committer | Matthias Clasen <mclasen@redhat.com> | 2021-05-24 17:27:40 -0400 |
commit | a74420bc1a501f6ee951ed152e8f9a941b0c8438 (patch) | |
tree | db1d1343deb5aa5acf3f1efb6b32d04c93a6f25b | |
parent | b05f3f5614a310de05fb8292e96611aade429a1e (diff) | |
download | gtk+-a74420bc1a501f6ee951ed152e8f9a941b0c8438.tar.gz |
menubutton: Enable F10 for primary menus
Add a ::primary property to GtkMenuButton, which can
be set to make the menu activatable with F10, like
menubars.
-rw-r--r-- | gtk/gtkmenubutton.c | 136 | ||||
-rw-r--r-- | gtk/gtkmenubutton.h | 6 | ||||
-rw-r--r-- | gtk/gtkwindow.c | 6 |
3 files changed, 147 insertions, 1 deletions
diff --git a/gtk/gtkmenubutton.c b/gtk/gtkmenubutton.c index d3b85ea72a..6c9a624831 100644 --- a/gtk/gtkmenubutton.c +++ b/gtk/gtkmenubutton.c @@ -97,6 +97,7 @@ #include "gtkwidgetprivate.h" #include "gtkbuttonprivate.h" #include "gtknative.h" +#include "gtkwindow.h" typedef struct _GtkMenuButtonClass GtkMenuButtonClass; typedef struct _GtkMenuButtonPrivate GtkMenuButtonPrivate; @@ -116,6 +117,8 @@ struct _GtkMenuButton GtkWidget *label_widget; GtkWidget *arrow_widget; GtkArrowType arrow_type; + + gboolean primary; }; struct _GtkMenuButtonClass @@ -133,6 +136,7 @@ enum PROP_LABEL, PROP_USE_UNDERLINE, PROP_HAS_FRAME, + PROP_PRIMARY, LAST_PROP }; @@ -173,6 +177,9 @@ gtk_menu_button_set_property (GObject *object, case PROP_HAS_FRAME: gtk_menu_button_set_has_frame (self, g_value_get_boolean (value)); break; + case PROP_PRIMARY: + gtk_menu_button_set_primary (self, g_value_get_boolean (value)); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); } @@ -209,6 +216,9 @@ gtk_menu_button_get_property (GObject *object, case PROP_HAS_FRAME: g_value_set_boolean (value, gtk_menu_button_get_has_frame (GTK_MENU_BUTTON (object))); break; + case PROP_PRIMARY: + g_value_set_boolean (value, gtk_menu_button_get_primary (GTK_MENU_BUTTON (object))); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); } @@ -326,6 +336,9 @@ gtk_menu_button_grab_focus (GtkWidget *widget) return gtk_widget_grab_focus (self->button); } +static void gtk_menu_button_root (GtkWidget *widget); +static void gtk_menu_button_unroot (GtkWidget *widget); + static void gtk_menu_button_class_init (GtkMenuButtonClass *klass) { @@ -337,6 +350,8 @@ gtk_menu_button_class_init (GtkMenuButtonClass *klass) gobject_class->notify = gtk_menu_button_notify; gobject_class->dispose = gtk_menu_button_dispose; + widget_class->root = gtk_menu_button_root; + widget_class->unroot = gtk_menu_button_unroot; widget_class->measure = gtk_menu_button_measure; widget_class->size_allocate = gtk_menu_button_size_allocate; widget_class->state_flags_changed = gtk_menu_button_state_flags_changed; @@ -432,6 +447,20 @@ gtk_menu_button_class_init (GtkMenuButtonClass *klass) TRUE, GTK_PARAM_READWRITE|G_PARAM_EXPLICIT_NOTIFY); + /** + * GtkMenuButton:primary: (attributes org.gtk.Property.get=gtk_menu_button_get_primary org.gtk.Property.set=gtk_menu_button_set_primary) + * + * Whether the menu button acts as a primary menu. + * + * Primary menus can be opened using the <kbd>F10</kbd> key + */ + menu_button_props[PROP_PRIMARY] = + g_param_spec_boolean ("primary", + P_("Primary"), + P_("Whether the menubutton acts as a primary menu"), + FALSE, + GTK_PARAM_READWRITE|G_PARAM_EXPLICIT_NOTIFY); + g_object_class_install_properties (gobject_class, LAST_PROP, menu_button_props); gtk_widget_class_set_css_name (widget_class, I_("menubutton")); @@ -1039,3 +1068,110 @@ gtk_menu_button_get_use_underline (GtkMenuButton *menu_button) return gtk_button_get_use_underline (GTK_BUTTON (menu_button->button)); } + +static GList * +get_menu_bars (GtkWindow *window) +{ + return g_object_get_data (G_OBJECT (window), "gtk-menu-bar-list"); +} + +static void +set_menu_bars (GtkWindow *window, + GList *menubars) +{ + g_object_set_data (G_OBJECT (window), I_("gtk-menu-bar-list"), menubars); +} + +static void +add_to_window (GtkWindow *window, + GtkMenuButton *button) +{ + GList *menubars = get_menu_bars (window); + + set_menu_bars (window, g_list_prepend (menubars, button)); +} + +static void +remove_from_window (GtkWindow *window, + GtkMenuButton *button) +{ + GList *menubars = get_menu_bars (window); + + menubars = g_list_remove (menubars, button); + set_menu_bars (window, menubars); +} + +static void +gtk_menu_button_root (GtkWidget *widget) +{ + GtkMenuButton *button = GTK_MENU_BUTTON (widget); + + GTK_WIDGET_CLASS (gtk_menu_button_parent_class)->root (widget); + + if (button->primary) + { + GtkWidget *toplevel = GTK_WIDGET (gtk_widget_get_root (widget)); + add_to_window (GTK_WINDOW (toplevel), button); + } +} + +static void +gtk_menu_button_unroot (GtkWidget *widget) +{ + GtkWidget *toplevel; + + toplevel = GTK_WIDGET (gtk_widget_get_root (widget)); + remove_from_window (GTK_WINDOW (toplevel), GTK_MENU_BUTTON (widget)); + + GTK_WIDGET_CLASS (gtk_menu_button_parent_class)->unroot (widget); +} + +/** + * gtk_menu_button_set_primary: (attributes org.gtk.Method.set_property=primary) + * @menu_button: a `GtkMenuButton` + * @primary: whether the menubutton should act as a primary menu + * + * Sets whether menu button acts as a primary menu. + * + * Primary menus can be opened with the <kbd>F10</kbd> key. + */ +void +gtk_menu_button_set_primary (GtkMenuButton *menu_button, + gboolean primary) +{ + GtkRoot *toplevel; + + g_return_if_fail (GTK_IS_MENU_BUTTON (menu_button)); + + if (menu_button->primary == primary) + return; + + menu_button->primary = primary; + toplevel = gtk_widget_get_root (GTK_WIDGET (menu_button)); + + if (toplevel) + { + if (menu_button->primary) + add_to_window (GTK_WINDOW (toplevel), menu_button); + else + remove_from_window (GTK_WINDOW (toplevel), menu_button); + } + + g_object_notify_by_pspec (G_OBJECT (menu_button), menu_button_props[PROP_PRIMARY]); +} + +/** + * gtk_menu_button_get_primary: (attributes org.gtk.Method.get_property=primary) + * @menu_button: a `GtkMenuButton` + * + * Returns whether the menu button acts as a primary menu. + * + * Returns: %TRUE if the button is a primary menu + */ +gboolean +gtk_menu_button_get_primary (GtkMenuButton *menu_button) +{ + g_return_val_if_fail (GTK_IS_MENU_BUTTON (menu_button), FALSE); + + return menu_button->primary; +} diff --git a/gtk/gtkmenubutton.h b/gtk/gtkmenubutton.h index 4ac9da798b..af71beedd6 100644 --- a/gtk/gtkmenubutton.h +++ b/gtk/gtkmenubutton.h @@ -109,6 +109,12 @@ void gtk_menu_button_set_create_popup_func (GtkMenuButton gpointer user_data, GDestroyNotify destroy_notify); +GDK_AVAILABLE_IN_4_4 +void gtk_menu_button_set_primary (GtkMenuButton *menu_button, + gboolean primary); +GDK_AVAILABLE_IN_4_4 +gboolean gtk_menu_button_get_primary (GtkMenuButton *menu_button); + G_END_DECLS #endif /* __GTK_MENU_BUTTON_H__ */ diff --git a/gtk/gtkwindow.c b/gtk/gtkwindow.c index 501341bd22..a826d890f1 100644 --- a/gtk/gtkwindow.c +++ b/gtk/gtkwindow.c @@ -64,6 +64,7 @@ #include "gtkpopovermenubarprivate.h" #include "gtkcssboxesimplprivate.h" #include "gtktooltipprivate.h" +#include "gtkmenubutton.h" #include "inspector/window.h" @@ -5807,7 +5808,10 @@ gtk_window_activate_menubar (GtkWidget *widget, gtk_widget_focus_sort (GTK_WIDGET (window), GTK_DIR_TAB_FORWARD, menubars); first = g_ptr_array_index (menubars, 0); - gtk_popover_menu_bar_select_first (GTK_POPOVER_MENU_BAR (first)); + if (GTK_IS_POPOVER_MENU_BAR (first)) + gtk_popover_menu_bar_select_first (GTK_POPOVER_MENU_BAR (first)); + else if (GTK_IS_MENU_BUTTON (first)) + gtk_menu_button_popup (GTK_MENU_BUTTON (first)); g_ptr_array_free (menubars, TRUE); |