diff --git a/docs/reference/gtk/gtk4-docs.xml b/docs/reference/gtk/gtk4-docs.xml index 13bbfe4228..577f229ca9 100644 --- a/docs/reference/gtk/gtk4-docs.xml +++ b/docs/reference/gtk/gtk4-docs.xml @@ -217,12 +217,6 @@ Menus, Combo Box, Toolbar - - - - - - @@ -311,7 +305,6 @@ - diff --git a/docs/reference/gtk/gtk4-sections.txt b/docs/reference/gtk/gtk4-sections.txt index fc58477346..d011835273 100644 --- a/docs/reference/gtk/gtk4-sections.txt +++ b/docs/reference/gtk/gtk4-sections.txt @@ -674,34 +674,6 @@ GTK_CHECK_BUTTON_GET_CLASS gtk_check_button_get_type -
-gtkcheckmenuitem -GtkCheckMenuItem -GtkCheckMenuItemClass -GtkCheckMenuItem -gtk_check_menu_item_new -gtk_check_menu_item_new_with_label -gtk_check_menu_item_new_with_mnemonic -gtk_check_menu_item_get_active -gtk_check_menu_item_set_active -gtk_check_menu_item_toggled -gtk_check_menu_item_get_inconsistent -gtk_check_menu_item_set_inconsistent -gtk_check_menu_item_set_draw_as_radio -gtk_check_menu_item_get_draw_as_radio - - -GTK_CHECK_MENU_ITEM -GTK_IS_CHECK_MENU_ITEM -GTK_TYPE_CHECK_MENU_ITEM -GTK_CHECK_MENU_ITEM_CLASS -GTK_IS_CHECK_MENU_ITEM_CLASS -GTK_CHECK_MENU_ITEM_GET_CLASS - -GtkCheckMenuItemPrivate -gtk_check_menu_item_get_type -
-
gtkcolorbutton GtkColorButton @@ -1830,66 +1802,6 @@ GTK_MAP_LIST_MODEL_GET_CLASS gtk_map_list_model_get_type
-
-gtkmenu -GtkMenu -GtkMenu -gtk_menu_new -gtk_menu_new_from_model -GtkPopoverMenuFlags -gtk_menu_reorder_child -gtk_menu_popup_at_rect -gtk_menu_popup_at_widget -gtk_menu_popup_at_pointer -gtk_menu_set_accel_group -gtk_menu_get_accel_group -gtk_menu_set_accel_path -gtk_menu_get_accel_path -gtk_menu_set_monitor -gtk_menu_get_monitor -gtk_menu_place_on_monitor -gtk_menu_set_reserve_toggle_size -gtk_menu_get_reserve_toggle_size - -gtk_menu_popdown -gtk_menu_reposition -gtk_menu_get_active -gtk_menu_set_active -gtk_menu_attach_to_widget -gtk_menu_detach -gtk_menu_get_attach_widget -gtk_menu_get_for_attach_widget -GtkMenuDetachFunc - -GTK_MENU -GTK_IS_MENU -GTK_TYPE_MENU -GTK_MENU_CLASS -GTK_IS_MENU_CLASS -GTK_MENU_GET_CLASS - -GtkMenuPrivate -gtk_menu_get_type -
- -
-gtkmenubar -GtkMenuBar -GtkMenuBar -gtk_menu_bar_new -gtk_menu_bar_new_from_model - -GTK_MENU_BAR -GTK_IS_MENU_BAR -GTK_TYPE_MENU_BAR -GTK_MENU_BAR_CLASS -GTK_IS_MENU_BAR_CLASS -GTK_MENU_BAR_GET_CLASS - -GtkMenuBarPrivate -gtk_menu_bar_get_type -
-
gtkmenubutton GtkMenuButton @@ -1925,72 +1837,6 @@ GtkMenuButtonPrivate gtk_menu_button_get_type
-
-gtkmenuitem -GtkMenuItem -GtkMenuItem -GtkMenuItemClass -gtk_menu_item_new -gtk_menu_item_new_with_label -gtk_menu_item_new_with_mnemonic -gtk_menu_item_get_label -gtk_menu_item_set_label -gtk_menu_item_get_use_underline -gtk_menu_item_set_use_underline -gtk_menu_item_set_submenu -gtk_menu_item_get_submenu -gtk_menu_item_set_accel_path -gtk_menu_item_get_accel_path -gtk_menu_item_select -gtk_menu_item_deselect -gtk_menu_item_activate -gtk_menu_item_toggle_size_request -gtk_menu_item_toggle_size_allocate -gtk_menu_item_get_reserve_indicator -gtk_menu_item_set_reserve_indicator - -GTK_MENU_ITEM -GTK_IS_MENU_ITEM -GTK_TYPE_MENU_ITEM -GTK_MENU_ITEM_CLASS -GTK_IS_MENU_ITEM_CLASS -GTK_MENU_ITEM_GET_CLASS - -GtkMenuItemPrivate -gtk_menu_item_get_type -
- -
-gtkmenushell -GtkMenuShell -GtkMenuShell -gtk_menu_shell_append -gtk_menu_shell_prepend -gtk_menu_shell_insert -gtk_menu_shell_deactivate -gtk_menu_shell_select_item -gtk_menu_shell_select_first -gtk_menu_shell_deselect -gtk_menu_shell_activate_item -gtk_menu_shell_cancel -gtk_menu_shell_set_take_focus -gtk_menu_shell_get_take_focus -gtk_menu_shell_get_selected_item -gtk_menu_shell_get_parent_shell -gtk_menu_shell_bind_model -GtkMenuDirectionType - -GTK_MENU_SHELL -GTK_IS_MENU_SHELL -GTK_TYPE_MENU_SHELL -GTK_MENU_SHELL_CLASS -GTK_IS_MENU_SHELL_CLASS -GTK_MENU_SHELL_GET_CLASS - -GtkMenuShellPrivate -gtk_menu_shell_get_type -
-
gtkmessagedialog GtkMessageDialog @@ -2253,31 +2099,6 @@ GtkRadioButtonPrivate gtk_radio_button_get_type
-
-gtkradiomenuitem -GtkRadioMenuItem -GtkRadioMenuItem -gtk_radio_menu_item_new -gtk_radio_menu_item_new_with_label -gtk_radio_menu_item_new_with_mnemonic -gtk_radio_menu_item_new_from_widget -gtk_radio_menu_item_new_with_label_from_widget -gtk_radio_menu_item_new_with_mnemonic_from_widget -gtk_radio_menu_item_set_group -gtk_radio_menu_item_get_group -gtk_radio_menu_item_join_group - -GTK_RADIO_MENU_ITEM -GTK_IS_RADIO_MENU_ITEM -GTK_TYPE_RADIO_MENU_ITEM -GTK_RADIO_MENU_ITEM_CLASS -GTK_IS_RADIO_MENU_ITEM_CLASS -GTK_RADIO_MENU_ITEM_GET_CLASS - -GtkRadioMenuItemPrivate -gtk_radio_menu_item_get_type -
-
gtkrange GtkRange @@ -2584,22 +2405,6 @@ gtk_separator_get_type GtkSeparatorPrivate
-
-gtkseparatormenuitem -GtkSeparatorMenuItem -GtkSeparatorMenuItem -gtk_separator_menu_item_new - -GTK_SEPARATOR_MENU_ITEM -GTK_SEPARATOR_MENU_ITEM_CLASS -GTK_SEPARATOR_MENU_ITEM_GET_CLASS -GTK_IS_SEPARATOR_MENU_ITEM -GTK_IS_SEPARATOR_MENU_ITEM_CLASS -GTK_TYPE_SEPARATOR_MENU_ITEM - -gtk_separator_menu_item_get_type -
-
gtksettings GtkSettings diff --git a/docs/reference/gtk/gtk4.types.in b/docs/reference/gtk/gtk4.types.in index 2db6ce2348..f758c3eee7 100644 --- a/docs/reference/gtk/gtk4.types.in +++ b/docs/reference/gtk/gtk4.types.in @@ -44,7 +44,6 @@ gtk_cell_renderer_text_get_type gtk_cell_renderer_toggle_get_type gtk_cell_view_get_type gtk_check_button_get_type -gtk_check_menu_item_get_type gtk_color_button_get_type gtk_color_chooser_get_type gtk_color_chooser_dialog_get_type @@ -119,11 +118,7 @@ gtk_map_list_model_get_type gtk_media_controls_get_type gtk_media_file_get_type gtk_media_stream_get_type -gtk_menu_bar_get_type gtk_menu_button_get_type -gtk_menu_get_type -gtk_menu_item_get_type -gtk_menu_shell_get_type gtk_menu_tool_button_get_type gtk_message_dialog_get_type gtk_mount_operation_get_type @@ -152,7 +147,6 @@ gtk_print_settings_get_type @DISABLE_ON_W32@gtk_print_unix_dialog_get_type gtk_progress_bar_get_type gtk_radio_button_get_type -gtk_radio_menu_item_get_type gtk_radio_tool_button_get_type gtk_range_get_type gtk_recent_manager_get_type @@ -167,7 +161,6 @@ gtk_search_bar_get_type gtk_search_entry_get_type gtk_selection_model_get_type gtk_separator_get_type -gtk_separator_menu_item_get_type gtk_separator_tool_item_get_type gtk_settings_get_type gtk_shortcut_label_get_type diff --git a/docs/reference/gtk/meson.build b/docs/reference/gtk/meson.build index ea469faf16..0ee718a1c5 100644 --- a/docs/reference/gtk/meson.build +++ b/docs/reference/gtk/meson.build @@ -17,7 +17,6 @@ private_headers = [ 'gtkbuttonprivate.h', 'gtkcellareaboxcontextprivate.h', 'gtkcheckbuttonprivate.h', - 'gtkcheckmenuitemprivate.h', 'gtkcolorchooserprivate.h', 'gtkcoloreditorprivate.h', 'gtkcolorplaneprivate.h', @@ -138,9 +137,6 @@ private_headers = [ 'gtkmagnifierprivate.h', 'gtkmediafileprivate.h', 'gtkmenubuttonprivate.h', - 'gtkmenuitemprivate.h', - 'gtkmenuprivate.h', - 'gtkmenushellprivate.h', 'gtkmodulesprivate.h', 'gtkmountoperationprivate.h', 'gtknativedialogprivate.h', diff --git a/gtk/a11y/gtk-a11y-autocleanups.h b/gtk/a11y/gtk-a11y-autocleanups.h index 7bc1a3bae5..ad64194238 100644 --- a/gtk/a11y/gtk-a11y-autocleanups.h +++ b/gtk/a11y/gtk-a11y-autocleanups.h @@ -25,7 +25,6 @@ G_DEFINE_AUTOPTR_CLEANUP_FUNC(GtkBooleanCellAccessible, g_object_unref) G_DEFINE_AUTOPTR_CLEANUP_FUNC(GtkButtonAccessible, g_object_unref) G_DEFINE_AUTOPTR_CLEANUP_FUNC(GtkCellAccessible, g_object_unref) G_DEFINE_AUTOPTR_CLEANUP_FUNC(GtkCellAccessibleParent, g_object_unref) -G_DEFINE_AUTOPTR_CLEANUP_FUNC(GtkCheckMenuItemAccessible, g_object_unref) G_DEFINE_AUTOPTR_CLEANUP_FUNC(GtkComboBoxAccessible, g_object_unref) G_DEFINE_AUTOPTR_CLEANUP_FUNC(GtkContainerAccessible, g_object_unref) G_DEFINE_AUTOPTR_CLEANUP_FUNC(GtkContainerCellAccessible, g_object_unref) @@ -43,17 +42,13 @@ G_DEFINE_AUTOPTR_CLEANUP_FUNC(GtkLinkButtonAccessible, g_object_unref) G_DEFINE_AUTOPTR_CLEANUP_FUNC(GtkListBoxAccessible, g_object_unref) G_DEFINE_AUTOPTR_CLEANUP_FUNC(GtkListBoxRowAccessible, g_object_unref) G_DEFINE_AUTOPTR_CLEANUP_FUNC(GtkLockButtonAccessible, g_object_unref) -G_DEFINE_AUTOPTR_CLEANUP_FUNC(GtkMenuAccessible, g_object_unref) G_DEFINE_AUTOPTR_CLEANUP_FUNC(GtkMenuButtonAccessible, g_object_unref) -G_DEFINE_AUTOPTR_CLEANUP_FUNC(GtkMenuItemAccessible, g_object_unref) -G_DEFINE_AUTOPTR_CLEANUP_FUNC(GtkMenuShellAccessible, g_object_unref) G_DEFINE_AUTOPTR_CLEANUP_FUNC(GtkNotebookAccessible, g_object_unref) G_DEFINE_AUTOPTR_CLEANUP_FUNC(GtkNotebookPageAccessible, g_object_unref) G_DEFINE_AUTOPTR_CLEANUP_FUNC(GtkPanedAccessible, g_object_unref) G_DEFINE_AUTOPTR_CLEANUP_FUNC(GtkPopoverAccessible, g_object_unref) G_DEFINE_AUTOPTR_CLEANUP_FUNC(GtkProgressBarAccessible, g_object_unref) G_DEFINE_AUTOPTR_CLEANUP_FUNC(GtkRadioButtonAccessible, g_object_unref) -G_DEFINE_AUTOPTR_CLEANUP_FUNC(GtkRadioMenuItemAccessible, g_object_unref) G_DEFINE_AUTOPTR_CLEANUP_FUNC(GtkRangeAccessible, g_object_unref) G_DEFINE_AUTOPTR_CLEANUP_FUNC(GtkRendererCellAccessible, g_object_unref) G_DEFINE_AUTOPTR_CLEANUP_FUNC(GtkScaleAccessible, g_object_unref) diff --git a/gtk/a11y/gtkcheckmenuitemaccessible.c b/gtk/a11y/gtkcheckmenuitemaccessible.c deleted file mode 100644 index e0011f5a3a..0000000000 --- a/gtk/a11y/gtkcheckmenuitemaccessible.c +++ /dev/null @@ -1,128 +0,0 @@ -/* GTK+ - accessibility implementations - * Copyright 2002 Sun Microsystems Inc. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * 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, see . - */ - -#include "config.h" - -#include -#include -#include "gtkcheckmenuitemaccessible.h" - - -G_DEFINE_TYPE (GtkCheckMenuItemAccessible, gtk_check_menu_item_accessible, GTK_TYPE_MENU_ITEM_ACCESSIBLE) - -static void -toggled_cb (GtkWidget *widget) -{ - AtkObject *accessible; - GtkCheckMenuItem *check_menu_item; - gboolean active; - - check_menu_item = GTK_CHECK_MENU_ITEM (widget); - active = gtk_check_menu_item_get_active (check_menu_item); - - accessible = gtk_widget_get_accessible (widget); - atk_object_notify_state_change (accessible, ATK_STATE_CHECKED, active); -} - -static void -gtk_check_menu_item_accessible_initialize (AtkObject *obj, - gpointer data) -{ - ATK_OBJECT_CLASS (gtk_check_menu_item_accessible_parent_class)->initialize (obj, data); - - g_signal_connect (data, "toggled", G_CALLBACK (toggled_cb), NULL); - - obj->role = ATK_ROLE_CHECK_MENU_ITEM; -} - -static AtkStateSet * -gtk_check_menu_item_accessible_ref_state_set (AtkObject *accessible) -{ - AtkStateSet *state_set; - GtkCheckMenuItem *check_menu_item; - GtkWidget *widget; - - widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (accessible)); - if (widget == NULL) - return NULL; - - state_set = ATK_OBJECT_CLASS (gtk_check_menu_item_accessible_parent_class)->ref_state_set (accessible); - - check_menu_item = GTK_CHECK_MENU_ITEM (widget); - - if (gtk_check_menu_item_get_active (check_menu_item)) - atk_state_set_add_state (state_set, ATK_STATE_CHECKED); - - if (gtk_check_menu_item_get_inconsistent (check_menu_item)) - { - atk_state_set_remove_state (state_set, ATK_STATE_ENABLED); - atk_state_set_add_state (state_set, ATK_STATE_INDETERMINATE); - } - - return state_set; -} - -static void -gtk_check_menu_item_accessible_notify_gtk (GObject *obj, - GParamSpec *pspec) -{ - GtkCheckMenuItem *check_menu_item = GTK_CHECK_MENU_ITEM (obj); - AtkObject *atk_obj; - gboolean sensitive; - gboolean inconsistent; - gboolean active; - - atk_obj = gtk_widget_get_accessible (GTK_WIDGET (check_menu_item)); - sensitive = gtk_widget_get_sensitive (GTK_WIDGET (check_menu_item)); - inconsistent = gtk_check_menu_item_get_inconsistent (check_menu_item); - active = gtk_check_menu_item_get_active (check_menu_item); - - if (strcmp (pspec->name, "inconsistent") == 0) - { - atk_object_notify_state_change (atk_obj, ATK_STATE_INDETERMINATE, inconsistent); - atk_object_notify_state_change (atk_obj, ATK_STATE_ENABLED, (sensitive && !inconsistent)); - } - else if (strcmp (pspec->name, "sensitive") == 0) - { - /* Need to override gailwidget behavior of notifying for ENABLED */ - atk_object_notify_state_change (atk_obj, ATK_STATE_SENSITIVE, sensitive); - atk_object_notify_state_change (atk_obj, ATK_STATE_ENABLED, (sensitive && !inconsistent)); - } - else if (strcmp (pspec->name, "active") == 0) - { - atk_object_notify_state_change (atk_obj, ATK_STATE_CHECKED, active); - } - else - GTK_WIDGET_ACCESSIBLE_CLASS (gtk_check_menu_item_accessible_parent_class)->notify_gtk (obj, pspec); -} - -static void -gtk_check_menu_item_accessible_class_init (GtkCheckMenuItemAccessibleClass *klass) -{ - AtkObjectClass *class = ATK_OBJECT_CLASS (klass); - GtkWidgetAccessibleClass *widget_class = (GtkWidgetAccessibleClass*)klass; - - widget_class->notify_gtk = gtk_check_menu_item_accessible_notify_gtk; - - class->ref_state_set = gtk_check_menu_item_accessible_ref_state_set; - class->initialize = gtk_check_menu_item_accessible_initialize; -} - -static void -gtk_check_menu_item_accessible_init (GtkCheckMenuItemAccessible *item) -{ -} diff --git a/gtk/a11y/gtkcheckmenuitemaccessible.h b/gtk/a11y/gtkcheckmenuitemaccessible.h deleted file mode 100644 index 08a4b55b64..0000000000 --- a/gtk/a11y/gtkcheckmenuitemaccessible.h +++ /dev/null @@ -1,57 +0,0 @@ -/* GTK+ - accessibility implementations - * Copyright 2002 Sun Microsystems Inc. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library. If not, see . - */ - -#ifndef __GTK_CHECK_MENU_ITEM_ACCESSIBLE_H__ -#define __GTK_CHECK_MENU_ITEM_ACCESSIBLE_H__ - -#if !defined (__GTK_A11Y_H_INSIDE__) && !defined (GTK_COMPILATION) -#error "Only can be included directly." -#endif - -#include - -G_BEGIN_DECLS - -#define GTK_TYPE_CHECK_MENU_ITEM_ACCESSIBLE (gtk_check_menu_item_accessible_get_type ()) -#define GTK_CHECK_MENU_ITEM_ACCESSIBLE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GTK_TYPE_CHECK_MENU_ITEM_ACCESSIBLE, GtkCheckMenuItemAccessible)) -#define GTK_CHECK_MENU_ITEM_ACCESSIBLE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GTK_TYPE_CHECK_MENU_ITEM_ACCESSIBLE, GtkCheckMenuItemAccessibleClass)) -#define GTK_IS_CHECK_MENU_ITEM_ACCESSIBLE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GTK_TYPE_CHECK_MENU_ITEM_ACCESSIBLE)) -#define GTK_IS_CHECK_MENU_ITEM_ACCESSIBLE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GTK_TYPE_CHECK_MENU_ITEM_ACCESSIBLE)) -#define GTK_CHECK_MENU_ITEM_ACCESSIBLE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GTK_TYPE_CHECK_MENU_ITEM_ACCESSIBLE, GtkCheckMenuItemAccessibleClass)) - -typedef struct _GtkCheckMenuItemAccessible GtkCheckMenuItemAccessible; -typedef struct _GtkCheckMenuItemAccessibleClass GtkCheckMenuItemAccessibleClass; -typedef struct _GtkCheckMenuItemAccessiblePrivate GtkCheckMenuItemAccessiblePrivate; - -struct _GtkCheckMenuItemAccessible -{ - GtkMenuItemAccessible parent; - - GtkCheckMenuItemAccessiblePrivate *priv; -}; - -struct _GtkCheckMenuItemAccessibleClass -{ - GtkMenuItemAccessibleClass parent_class; -}; - -GDK_AVAILABLE_IN_ALL -GType gtk_check_menu_item_accessible_get_type (void); - -G_END_DECLS - -#endif /* __GTK_CHECK_MENU_ITEM_ACCESSIBLE_H__ */ diff --git a/gtk/a11y/gtkmenuaccessible.c b/gtk/a11y/gtkmenuaccessible.c deleted file mode 100644 index 4d2967db26..0000000000 --- a/gtk/a11y/gtkmenuaccessible.c +++ /dev/null @@ -1,99 +0,0 @@ -/* GTK+ - accessibility implementations - * Copyright 2001, 2002, 2003 Sun Microsystems Inc. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * 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, see . - */ - -#include "config.h" - -#include "gtkmenuaccessible.h" -#include "gtkwidgetaccessibleprivate.h" - -#include - -G_DEFINE_TYPE (GtkMenuAccessible, gtk_menu_accessible, GTK_TYPE_MENU_SHELL_ACCESSIBLE) - -static void -gtk_menu_accessible_initialize (AtkObject *obj, - gpointer data) -{ - ATK_OBJECT_CLASS (gtk_menu_accessible_parent_class)->initialize (obj, data); - - obj->role = ATK_ROLE_MENU; - - _gtk_widget_accessible_set_layer (GTK_WIDGET_ACCESSIBLE (obj), ATK_LAYER_POPUP); -} - -static AtkObject * -gtk_menu_accessible_get_parent (AtkObject *accessible) -{ - AtkObject *parent; - GtkWidget *widget, *parent_widget; - - widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (accessible)); - if (widget == NULL) - return NULL; - - parent = accessible->accessible_parent; - if (parent != NULL) - return parent; - - /* If the menu is attached to a menu item or a button (Gnome Menu) - * report the menu item as parent. - */ - parent_widget = gtk_menu_get_attach_widget (GTK_MENU (widget)); - - if (!GTK_IS_MENU_ITEM (parent_widget) && - !GTK_IS_BUTTON (parent_widget) && - !GTK_IS_COMBO_BOX (parent_widget)) - parent_widget = gtk_widget_get_parent (widget); - - if (parent_widget == NULL) - return NULL; - - parent = gtk_widget_get_accessible (parent_widget); - atk_object_set_parent (accessible, parent); - - return parent; -} - -static gint -gtk_menu_accessible_get_index_in_parent (AtkObject *accessible) -{ - GtkWidget *widget; - - widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (accessible)); - if (widget == NULL) - return -1; - - if (gtk_menu_get_attach_widget (GTK_MENU (widget))) - return 0; - - return ATK_OBJECT_CLASS (gtk_menu_accessible_parent_class)->get_index_in_parent (accessible); -} - -static void -gtk_menu_accessible_class_init (GtkMenuAccessibleClass *klass) -{ - AtkObjectClass *class = ATK_OBJECT_CLASS (klass); - - class->get_parent = gtk_menu_accessible_get_parent; - class->get_index_in_parent = gtk_menu_accessible_get_index_in_parent; - class->initialize = gtk_menu_accessible_initialize; -} - -static void -gtk_menu_accessible_init (GtkMenuAccessible *accessible) -{ -} diff --git a/gtk/a11y/gtkmenuaccessible.h b/gtk/a11y/gtkmenuaccessible.h deleted file mode 100644 index 6a890fe270..0000000000 --- a/gtk/a11y/gtkmenuaccessible.h +++ /dev/null @@ -1,57 +0,0 @@ -/* GTK+ - accessibility implementations - * Copyright 2001 Sun Microsystems Inc. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library. If not, see . - */ - -#ifndef __GTK_MENU_ACCESSIBLE_H__ -#define __GTK_MENU_ACCESSIBLE_H__ - -#if !defined (__GTK_A11Y_H_INSIDE__) && !defined (GTK_COMPILATION) -#error "Only can be included directly." -#endif - -#include - -G_BEGIN_DECLS - -#define GTK_TYPE_MENU_ACCESSIBLE (gtk_menu_accessible_get_type ()) -#define GTK_MENU_ACCESSIBLE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GTK_TYPE_MENU_ACCESSIBLE, GtkMenuAccessible)) -#define GTK_MENU_ACCESSIBLE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GTK_TYPE_MENU_ACCESSIBLE, GtkMenuAccessibleClass)) -#define GTK_IS_MENU_ACCESSIBLE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GTK_TYPE_MENU_ACCESSIBLE)) -#define GTK_IS_MENU_ACCESSIBLE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GTK_TYPE_MENU_ACCESSIBLE)) -#define GTK_MENU_ACCESSIBLE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GTK_TYPE_MENU_ACCESSIBLE, GtkMenuAccessibleClass)) - -typedef struct _GtkMenuAccessible GtkMenuAccessible; -typedef struct _GtkMenuAccessibleClass GtkMenuAccessibleClass; -typedef struct _GtkMenuAccessiblePrivate GtkMenuAccessiblePrivate; - -struct _GtkMenuAccessible -{ - GtkMenuShellAccessible parent; - - GtkMenuAccessiblePrivate *priv; -}; - -struct _GtkMenuAccessibleClass -{ - GtkMenuShellAccessibleClass parent_class; -}; - -GDK_AVAILABLE_IN_ALL -GType gtk_menu_accessible_get_type (void); - -G_END_DECLS - -#endif /* __GTK_MENU_ACCESSIBLE_H__ */ diff --git a/gtk/a11y/gtkmenuitemaccessible.c b/gtk/a11y/gtkmenuitemaccessible.c deleted file mode 100644 index fe5dbff2cc..0000000000 --- a/gtk/a11y/gtkmenuitemaccessible.c +++ /dev/null @@ -1,926 +0,0 @@ -/* GTK+ - accessibility implementations - * Copyright 2001, 2002, 2003 Sun Microsystems Inc. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * 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, see . - */ - -#include "config.h" - -#include -#include -#include -#include "gtkmenuitemaccessible.h" -#include "gtkwidgetaccessibleprivate.h" -#include "gtk/gtkmenuitemprivate.h" - -struct _GtkMenuItemAccessiblePrivate -{ - gchar *text; - gboolean selected; -}; - -#define KEYBINDING_SEPARATOR ";" - -static void menu_item_select (GtkMenuItem *item); -static void menu_item_deselect (GtkMenuItem *item); - -static GtkWidget *get_label_from_container (GtkWidget *container); -static gchar *get_text_from_label_widget (GtkWidget *widget); - -static gint menu_item_insert_gtk (GtkMenuShell *shell, - GtkWidget *widget, - gint position); -static gint menu_item_remove_gtk (GtkContainer *container, - GtkWidget *widget); - -static void atk_action_interface_init (AtkActionIface *iface); -static void atk_selection_interface_init (AtkSelectionIface *iface); - -G_DEFINE_TYPE_WITH_CODE (GtkMenuItemAccessible, gtk_menu_item_accessible, GTK_TYPE_CONTAINER_ACCESSIBLE, - G_ADD_PRIVATE (GtkMenuItemAccessible) - G_IMPLEMENT_INTERFACE (ATK_TYPE_ACTION, atk_action_interface_init); - G_IMPLEMENT_INTERFACE (ATK_TYPE_SELECTION, atk_selection_interface_init)) - -static void -gtk_menu_item_accessible_initialize (AtkObject *obj, - gpointer data) -{ - GtkWidget *widget; - GtkWidget *parent; - GtkWidget *menu; - - ATK_OBJECT_CLASS (gtk_menu_item_accessible_parent_class)->initialize (obj, data); - g_signal_connect (data, "select", G_CALLBACK (menu_item_select), NULL); - g_signal_connect (data, "deselect", G_CALLBACK (menu_item_deselect), NULL); - - widget = GTK_WIDGET (data); - if ((gtk_widget_get_state_flags (widget) & GTK_STATE_FLAG_PRELIGHT) != 0) - GTK_MENU_ITEM_ACCESSIBLE (obj)->priv->selected = TRUE; - - parent = gtk_widget_get_parent (widget); - if (GTK_IS_MENU (parent)) - { - GtkWidget *parent_widget; - - parent_widget = gtk_menu_get_attach_widget (GTK_MENU (parent)); - - if (!GTK_IS_MENU_ITEM (parent_widget)) - parent_widget = gtk_widget_get_parent (widget); - if (parent_widget) - atk_object_set_parent (obj, gtk_widget_get_accessible (parent_widget)); - } - - _gtk_widget_accessible_set_layer (GTK_WIDGET_ACCESSIBLE (obj), ATK_LAYER_POPUP); - - obj->role = ATK_ROLE_MENU_ITEM; - - menu = gtk_menu_item_get_submenu (GTK_MENU_ITEM (data)); - if (menu) - { - g_signal_connect (menu, "insert", G_CALLBACK (menu_item_insert_gtk), NULL); - g_signal_connect (menu, "remove", G_CALLBACK (menu_item_remove_gtk), NULL); - } -} - -static gint -gtk_menu_item_accessible_get_n_children (AtkObject *obj) -{ - GtkWidget *widget; - GtkWidget *submenu; - gint count = 0; - - widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (obj)); - if (widget == NULL) - return count; - - submenu = gtk_menu_item_get_submenu (GTK_MENU_ITEM (widget)); - if (submenu) - { - GList *children; - - children = gtk_container_get_children (GTK_CONTAINER (submenu)); - count = g_list_length (children); - g_list_free (children); - } - return count; -} - -static AtkObject * -gtk_menu_item_accessible_ref_child (AtkObject *obj, - gint i) -{ - AtkObject *accessible; - GtkWidget *widget; - GtkWidget *submenu; - - widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (obj)); - if (widget == NULL) - return NULL; - - accessible = NULL; - submenu = gtk_menu_item_get_submenu (GTK_MENU_ITEM (widget)); - if (submenu) - { - GList *children; - GList *tmp_list; - - children = gtk_container_get_children (GTK_CONTAINER (submenu)); - tmp_list = g_list_nth (children, i); - if (tmp_list) - { - accessible = gtk_widget_get_accessible (GTK_WIDGET (tmp_list->data)); - g_object_ref (accessible); - } - g_list_free (children); - } - - return accessible; -} - -static AtkStateSet * -gtk_menu_item_accessible_ref_state_set (AtkObject *obj) -{ - AtkObject *menu_item; - AtkStateSet *state_set, *parent_state_set; - - state_set = ATK_OBJECT_CLASS (gtk_menu_item_accessible_parent_class)->ref_state_set (obj); - - atk_state_set_add_state (state_set, ATK_STATE_SELECTABLE); - if (GTK_MENU_ITEM_ACCESSIBLE (obj)->priv->selected) - atk_state_set_add_state (state_set, ATK_STATE_SELECTED); - - menu_item = atk_object_get_parent (obj); - - if (menu_item) - { - if (!GTK_IS_MENU_ITEM (gtk_accessible_get_widget (GTK_ACCESSIBLE (menu_item)))) - return state_set; - - parent_state_set = atk_object_ref_state_set (menu_item); - if (!atk_state_set_contains_state (parent_state_set, ATK_STATE_SELECTED)) - { - atk_state_set_remove_state (state_set, ATK_STATE_FOCUSED); - atk_state_set_remove_state (state_set, ATK_STATE_SHOWING); - } - g_object_unref (parent_state_set); - } - - return state_set; -} - -static AtkRole -gtk_menu_item_accessible_get_role (AtkObject *obj) -{ - GtkWidget *widget; - - widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (obj)); - if (widget != NULL && - gtk_menu_item_get_submenu (GTK_MENU_ITEM (widget))) - return ATK_ROLE_MENU; - - return ATK_OBJECT_CLASS (gtk_menu_item_accessible_parent_class)->get_role (obj); -} - -static const gchar * -gtk_menu_item_accessible_get_name (AtkObject *obj) -{ - const gchar *name; - GtkWidget *widget; - GtkWidget *label; - GtkMenuItemAccessible *accessible; - - widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (obj)); - if (widget == NULL) - return NULL; - - name = ATK_OBJECT_CLASS (gtk_menu_item_accessible_parent_class)->get_name (obj); - if (name) - return name; - - accessible = GTK_MENU_ITEM_ACCESSIBLE (obj); - label = get_label_from_container (widget); - - g_free (accessible->priv->text); - accessible->priv->text = get_text_from_label_widget (label); - - return accessible->priv->text; -} - -static void -gtk_menu_item_accessible_finalize (GObject *object) -{ - GtkMenuItemAccessible *accessible = GTK_MENU_ITEM_ACCESSIBLE (object); - - g_free (accessible->priv->text); - - G_OBJECT_CLASS (gtk_menu_item_accessible_parent_class)->finalize (object); -} - -static void -gtk_menu_item_accessible_notify_gtk (GObject *obj, - GParamSpec *pspec) -{ - AtkObject* atk_obj; - - atk_obj = gtk_widget_get_accessible (GTK_WIDGET (obj)); - - if (strcmp (pspec->name, "label") == 0) - { - if (atk_obj->name == NULL) - g_object_notify (G_OBJECT (atk_obj), "accessible-name"); - g_signal_emit_by_name (atk_obj, "visible-data-changed"); - } - else - GTK_WIDGET_ACCESSIBLE_CLASS (gtk_menu_item_accessible_parent_class)->notify_gtk (obj, pspec); -} - -static void -gtk_menu_item_accessible_class_init (GtkMenuItemAccessibleClass *klass) -{ - GObjectClass *gobject_class = G_OBJECT_CLASS (klass); - AtkObjectClass *class = ATK_OBJECT_CLASS (klass); - GtkWidgetAccessibleClass *widget_class = (GtkWidgetAccessibleClass*)klass; - - widget_class->notify_gtk = gtk_menu_item_accessible_notify_gtk; - - gobject_class->finalize = gtk_menu_item_accessible_finalize; - - class->get_n_children = gtk_menu_item_accessible_get_n_children; - class->ref_child = gtk_menu_item_accessible_ref_child; - class->ref_state_set = gtk_menu_item_accessible_ref_state_set; - class->initialize = gtk_menu_item_accessible_initialize; - class->get_name = gtk_menu_item_accessible_get_name; - class->get_role = gtk_menu_item_accessible_get_role; -} - -static void -gtk_menu_item_accessible_init (GtkMenuItemAccessible *menu_item) -{ - menu_item->priv = gtk_menu_item_accessible_get_instance_private (menu_item); -} - -static GtkWidget * -get_label_from_container (GtkWidget *container) -{ - GtkWidget *label; - GList *children, *tmp_list; - - if (!GTK_IS_CONTAINER (container)) - return NULL; - - children = gtk_container_get_children (GTK_CONTAINER (container)); - label = NULL; - - for (tmp_list = children; tmp_list != NULL; tmp_list = tmp_list->next) - { - if (GTK_IS_LABEL (tmp_list->data)) - { - label = tmp_list->data; - break; - } - else if (GTK_IS_CELL_VIEW (tmp_list->data)) - { - label = tmp_list->data; - break; - } - else if (GTK_IS_BOX (tmp_list->data)) - { - label = get_label_from_container (GTK_WIDGET (tmp_list->data)); - if (label) - break; - } - } - g_list_free (children); - - return label; -} - -static gchar * -get_text_from_label_widget (GtkWidget *label) -{ - if (GTK_IS_LABEL (label)) - return g_strdup (gtk_label_get_text (GTK_LABEL (label))); - else if (GTK_IS_CELL_VIEW (label)) - { - GList *cells, *l; - GtkTreeModel *model; - GtkTreeIter iter; - GtkTreePath *path; - GtkCellArea *area; - gchar *text; - - model = gtk_cell_view_get_model (GTK_CELL_VIEW (label)); - path = gtk_cell_view_get_displayed_row (GTK_CELL_VIEW (label)); - gtk_tree_model_get_iter (model, &iter, path); - gtk_tree_path_free (path); - - area = gtk_cell_layout_get_area (GTK_CELL_LAYOUT (label)); - gtk_cell_area_apply_attributes (area, model, &iter, FALSE, FALSE); - cells = gtk_cell_layout_get_cells (GTK_CELL_LAYOUT (label)); - - text = NULL; - for (l = cells; l; l = l->next) - { - GtkCellRenderer *cell = l->data; - - if (GTK_IS_CELL_RENDERER_TEXT (cell)) - { - g_object_get (cell, "text", &text, NULL); - break; - } - } - - g_list_free (cells); - - return text; - } - - return NULL; -} - -static void -ensure_menus_unposted (GtkMenuItemAccessible *menu_item) -{ - AtkObject *parent; - GtkWidget *widget; - - parent = atk_object_get_parent (ATK_OBJECT (menu_item)); - while (parent) - { - widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (parent)); - if (GTK_IS_MENU (widget)) - { - if (gtk_widget_get_mapped (widget)) - gtk_menu_shell_cancel (GTK_MENU_SHELL (widget)); - - return; - } - parent = atk_object_get_parent (parent); - } -} - -static gboolean -gtk_menu_item_accessible_do_action (AtkAction *action, - gint i) -{ - GtkWidget *item, *item_parent; - gboolean item_mapped; - - item = gtk_accessible_get_widget (GTK_ACCESSIBLE (action)); - if (item == NULL) - return FALSE; - - if (i != 0) - return FALSE; - - if (!gtk_widget_get_sensitive (item) || !gtk_widget_get_visible (item)) - return FALSE; - - item_parent = gtk_widget_get_parent (item); - if (!GTK_IS_MENU_SHELL (item_parent)) - return FALSE; - - gtk_menu_shell_select_item (GTK_MENU_SHELL (item_parent), item); - item_mapped = gtk_widget_get_mapped (item); - - /* This is what is called when is pressed for a menu item. - * The last argument means 'force hide'. - */ - g_signal_emit_by_name (item_parent, "activate-current", 1); - if (!item_mapped) - ensure_menus_unposted (GTK_MENU_ITEM_ACCESSIBLE (action)); - - return TRUE; -} - -static gint -gtk_menu_item_accessible_get_n_actions (AtkAction *action) -{ - GtkWidget *item; - - item = gtk_accessible_get_widget (GTK_ACCESSIBLE (action)); - if (item == NULL) - return 0; - - if (!_gtk_menu_item_is_selectable (item)) - return 0; - - return 1; -} - -static const gchar * -gtk_menu_item_accessible_action_get_name (AtkAction *action, - gint i) -{ - if (i == 0 && gtk_menu_item_accessible_get_n_actions (action) > 0) - return "click"; - return NULL; -} - -static const gchar * -gtk_menu_item_accessible_action_get_localized_name (AtkAction *action, - gint i) -{ - if (i == 0 && gtk_menu_item_accessible_get_n_actions (action) > 0) - return C_("Action name", "Click"); - return NULL; -} - -static const gchar * -gtk_menu_item_accessible_action_get_description (AtkAction *action, - gint i) -{ - if (i == 0 && gtk_menu_item_accessible_get_n_actions (action) > 0) - return C_("Action description", "Clicks the menuitem"); - return NULL; -} - -static gboolean -find_accel_by_widget (GtkAccelKey *key, - GClosure *closure, - gpointer data) -{ - /* We assume that closure->data points to the widget - * pending gtk_widget_get_accel_closures being made public - */ - return data == (gpointer) closure->data; -} - -static gboolean -find_accel_by_closure (GtkAccelKey *key, - GClosure *closure, - gpointer data) -{ - return data == (gpointer) closure; -} - -static GtkWidget * -find_item_label (GtkWidget *item) -{ - GtkWidget *child; - - child = gtk_bin_get_child (GTK_BIN (item)); - if (GTK_IS_CONTAINER (child)) - { - GList *children, *l; - children = gtk_container_get_children (GTK_CONTAINER (child)); - for (l = children; l; l = l->next) - { - if (GTK_IS_LABEL (l->data)) - { - child = l->data; - break; - } - } - g_list_free (children); - } - - if (GTK_IS_LABEL (child)) - return child; - - return NULL; -} - -/* This function returns a string of the form A;B;C where A is - * the keybinding for the widget; B is the keybinding to traverse - * from the menubar and C is the accelerator. The items in the - * keybinding to traverse from the menubar are separated by “:”. - */ -static const gchar * -gtk_menu_item_accessible_get_keybinding (AtkAction *action, - gint i) -{ - gchar *keybinding = NULL; - gchar *item_keybinding = NULL; - gchar *full_keybinding = NULL; - gchar *accelerator = NULL; - GtkWidget *item; - GtkWidget *temp_item; - GtkWidget *child; - GtkWidget *parent; - - item = gtk_accessible_get_widget (GTK_ACCESSIBLE (action)); - if (item == NULL) - return NULL; - - if (i != 0) - return NULL; - - temp_item = item; - while (TRUE) - { - GdkModifierType mnemonic_modifier = 0; - guint key_val; - gchar *key, *temp_keybinding; - - if (gtk_bin_get_child (GTK_BIN (temp_item)) == NULL) - return NULL; - - parent = gtk_widget_get_ancestor (temp_item, GTK_TYPE_MENU_SHELL); - if (!parent) - /* parent can be NULL when activating a window from the panel */ - return NULL; - - if (GTK_IS_MENU_BAR (parent)) - { - GtkRoot *root; - - root = gtk_widget_get_root (parent); - if (root && GTK_IS_WINDOW (root)) - mnemonic_modifier = gtk_window_get_mnemonic_modifier (GTK_WINDOW (root)); - } - - child = find_item_label (temp_item); - if (GTK_IS_LABEL (child)) - { - key_val = gtk_label_get_mnemonic_keyval (GTK_LABEL (child)); - if (key_val != GDK_KEY_VoidSymbol) - { - key = gtk_accelerator_name (key_val, mnemonic_modifier); - if (full_keybinding) - temp_keybinding = g_strconcat (key, ":", full_keybinding, NULL); - else - temp_keybinding = g_strdup (key); - - if (temp_item == item) - item_keybinding = g_strdup (key); - - g_free (key); - g_free (full_keybinding); - full_keybinding = temp_keybinding; - } - else - { - /* No keybinding */ - g_free (full_keybinding); - full_keybinding = NULL; - break; - } - } - - /* We have reached the menu bar so we are finished */ - if (GTK_IS_MENU_BAR (parent)) - break; - - g_return_val_if_fail (GTK_IS_MENU (parent), NULL); - temp_item = gtk_menu_get_attach_widget (GTK_MENU (parent)); - if (!GTK_IS_MENU_ITEM (temp_item)) - { - /* Menu is attached to something other than a menu item; - * probably an option menu - */ - g_free (full_keybinding); - full_keybinding = NULL; - break; - } - } - - parent = gtk_widget_get_ancestor (item, GTK_TYPE_MENU_SHELL); - if (GTK_IS_MENU (parent)) - { - child = find_item_label (item); - if (GTK_IS_ACCEL_LABEL (child)) - { - guint accel_key; - GdkModifierType accel_mods; - - gtk_accel_label_get_accel (GTK_ACCEL_LABEL (child), &accel_key, &accel_mods); - - if (accel_key) - accelerator = gtk_accelerator_name (accel_key, accel_mods); - } - - if (!accelerator) - { - GtkAccelGroup *group; - GtkAccelKey *key = NULL; - - group = gtk_menu_get_accel_group (GTK_MENU (parent)); - if (group) - key = gtk_accel_group_find (group, find_accel_by_widget, item); - else if (GTK_IS_ACCEL_LABEL (child)) - { - GtkAccelLabel *accel_label; - GClosure *accel_closure; - - accel_label = GTK_ACCEL_LABEL (child); - g_object_get (accel_label, "accel-closure", &accel_closure, NULL); - if (accel_closure) - { - key = gtk_accel_group_find (gtk_accel_group_from_accel_closure (accel_closure), - find_accel_by_closure, - accel_closure); - g_closure_unref (accel_closure); - } - } - - if (key) - accelerator = gtk_accelerator_name (key->accel_key, key->accel_mods); - } - } - - /* Concatenate the bindings */ - if (item_keybinding || full_keybinding || accelerator) - { - gchar *temp; - if (item_keybinding) - { - keybinding = g_strconcat (item_keybinding, KEYBINDING_SEPARATOR, NULL); - g_free (item_keybinding); - } - else - keybinding = g_strdup (KEYBINDING_SEPARATOR); - - if (full_keybinding) - { - temp = g_strconcat (keybinding, full_keybinding, - KEYBINDING_SEPARATOR, NULL); - g_free (full_keybinding); - } - else - temp = g_strconcat (keybinding, KEYBINDING_SEPARATOR, NULL); - - g_free (keybinding); - keybinding = temp; - if (accelerator) - { - temp = g_strconcat (keybinding, accelerator, NULL); - g_free (accelerator); - g_free (keybinding); - keybinding = temp; - } - } - - return keybinding; -} - -static void -atk_action_interface_init (AtkActionIface *iface) -{ - iface->do_action = gtk_menu_item_accessible_do_action; - iface->get_n_actions = gtk_menu_item_accessible_get_n_actions; - iface->get_name = gtk_menu_item_accessible_action_get_name; - iface->get_localized_name = gtk_menu_item_accessible_action_get_localized_name; - iface->get_description = gtk_menu_item_accessible_action_get_description; - iface->get_keybinding = gtk_menu_item_accessible_get_keybinding; -} - -static void -menu_item_selection (GtkMenuItem *item, - gboolean selected) -{ - AtkObject *obj, *parent; - gint i; - - obj = gtk_widget_get_accessible (GTK_WIDGET (item)); - GTK_MENU_ITEM_ACCESSIBLE (obj)->priv->selected = selected; - atk_object_notify_state_change (obj, ATK_STATE_SELECTED, selected); - - for (i = 0; i < atk_object_get_n_accessible_children (obj); i++) - { - AtkObject *child; - child = atk_object_ref_accessible_child (obj, i); - atk_object_notify_state_change (child, ATK_STATE_SHOWING, selected); - g_object_unref (child); - } - parent = atk_object_get_parent (obj); - g_signal_emit_by_name (parent, "selection-changed"); -} - -static gboolean -gtk_menu_item_accessible_add_selection (AtkSelection *selection, - gint i) -{ - GtkMenuShell *shell; - GList *kids; - guint length; - GtkWidget *widget; - GtkWidget *menu; - GtkWidget *child; - - widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (selection)); - if (widget == NULL) - return FALSE; - - menu = gtk_menu_item_get_submenu (GTK_MENU_ITEM (widget)); - if (menu == NULL) - return FALSE; - - shell = GTK_MENU_SHELL (menu); - kids = gtk_container_get_children (GTK_CONTAINER (shell)); - length = g_list_length (kids); - if (i < 0 || i > length) - { - g_list_free (kids); - return FALSE; - } - - child = g_list_nth_data (kids, i); - g_list_free (kids); - g_return_val_if_fail (GTK_IS_MENU_ITEM (child), FALSE); - gtk_menu_shell_select_item (shell, GTK_WIDGET (child)); - return TRUE; -} - -static gboolean -gtk_menu_item_accessible_clear_selection (AtkSelection *selection) -{ - GtkWidget *widget; - GtkWidget *menu; - - widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (selection)); - if (widget == NULL) - return FALSE; - - menu = gtk_menu_item_get_submenu (GTK_MENU_ITEM (widget)); - if (menu == NULL) - return FALSE; - - gtk_menu_shell_deselect (GTK_MENU_SHELL (menu)); - - return TRUE; -} - -static AtkObject * -gtk_menu_item_accessible_ref_selection (AtkSelection *selection, - gint i) -{ - GtkMenuShell *shell; - AtkObject *obj; - GtkWidget *widget; - GtkWidget *menu; - GtkWidget *item; - - if (i != 0) - return NULL; - - widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (selection)); - if (widget == NULL) - return NULL; - - menu = gtk_menu_item_get_submenu (GTK_MENU_ITEM (widget)); - if (menu == NULL) - return NULL; - - shell = GTK_MENU_SHELL (menu); - - item = gtk_menu_shell_get_selected_item (shell); - if (item != NULL) - { - obj = gtk_widget_get_accessible (item); - g_object_ref (obj); - return obj; - } - - return NULL; -} - -static gint -gtk_menu_item_accessible_get_selection_count (AtkSelection *selection) -{ - GtkMenuShell *shell; - GtkWidget *widget; - GtkWidget *menu; - - widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (selection)); - if (widget == NULL) - return 0; - - menu = gtk_menu_item_get_submenu (GTK_MENU_ITEM (widget)); - if (menu == NULL) - return 0; - - shell = GTK_MENU_SHELL (menu); - - if (gtk_menu_shell_get_selected_item (shell) != NULL) - return 1; - - return 0; -} - -static gboolean -gtk_menu_item_accessible_is_child_selected (AtkSelection *selection, - gint i) -{ - GtkMenuShell *shell; - gint j; - GtkWidget *widget; - GtkWidget *menu; - GtkWidget *item; - GList *kids; - - widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (selection)); - if (widget == NULL) - return FALSE; - - menu = gtk_menu_item_get_submenu (GTK_MENU_ITEM (widget)); - if (menu == NULL) - return FALSE; - - shell = GTK_MENU_SHELL (menu); - - item = gtk_menu_shell_get_selected_item (shell); - if (item == NULL) - return FALSE; - - kids = gtk_container_get_children (GTK_CONTAINER (shell)); - j = g_list_index (kids, item); - g_list_free (kids); - - return j==i; -} - -static gboolean -gtk_menu_item_accessible_remove_selection (AtkSelection *selection, - gint i) -{ - GtkMenuShell *shell; - GtkWidget *widget; - GtkWidget *menu; - GtkWidget *item; - - if (i != 0) - return FALSE; - - widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (selection)); - if (widget == NULL) - return FALSE; - - menu = gtk_menu_item_get_submenu (GTK_MENU_ITEM (widget)); - if (menu == NULL) - return FALSE; - - shell = GTK_MENU_SHELL (menu); - - item = gtk_menu_shell_get_selected_item (shell); - if (item && gtk_menu_item_get_submenu (GTK_MENU_ITEM (item))) - gtk_menu_shell_deselect (shell); - - return TRUE; -} - -static void -atk_selection_interface_init (AtkSelectionIface *iface) -{ - iface->add_selection = gtk_menu_item_accessible_add_selection; - iface->clear_selection = gtk_menu_item_accessible_clear_selection; - iface->ref_selection = gtk_menu_item_accessible_ref_selection; - iface->get_selection_count = gtk_menu_item_accessible_get_selection_count; - iface->is_child_selected = gtk_menu_item_accessible_is_child_selected; - iface->remove_selection = gtk_menu_item_accessible_remove_selection; -} - -static gint -menu_item_insert_gtk (GtkMenuShell *shell, - GtkWidget *widget, - gint position) -{ - GtkWidget *parent_widget; - - g_return_val_if_fail (GTK_IS_MENU (shell), 1); - - parent_widget = gtk_menu_get_attach_widget (GTK_MENU (shell)); - if (GTK_IS_MENU_ITEM (parent_widget)) - GTK_CONTAINER_ACCESSIBLE_CLASS (gtk_menu_item_accessible_parent_class)->add_gtk (GTK_CONTAINER (shell), widget, gtk_widget_get_accessible (parent_widget)); - - return 1; -} - -static gint -menu_item_remove_gtk (GtkContainer *container, - GtkWidget *widget) -{ - GtkWidget *parent_widget; - - g_return_val_if_fail (GTK_IS_MENU (container), 1); - - parent_widget = gtk_menu_get_attach_widget (GTK_MENU (container)); - if (GTK_IS_MENU_ITEM (parent_widget)) - { - GTK_CONTAINER_ACCESSIBLE_CLASS (gtk_menu_item_accessible_parent_class)->remove_gtk (container, widget, gtk_widget_get_accessible (parent_widget)); - } - return 1; -} - -static void -menu_item_select (GtkMenuItem *item) -{ - menu_item_selection (item, TRUE); -} - -static void -menu_item_deselect (GtkMenuItem *item) -{ - menu_item_selection (item, FALSE); -} diff --git a/gtk/a11y/gtkmenuitemaccessible.h b/gtk/a11y/gtkmenuitemaccessible.h deleted file mode 100644 index a810de0767..0000000000 --- a/gtk/a11y/gtkmenuitemaccessible.h +++ /dev/null @@ -1,57 +0,0 @@ -/* GTK+ - accessibility implementations - * Copyright 2001 Sun Microsystems Inc. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library. If not, see . - */ - -#ifndef __GTK_MENU_ITEM_ACCESSIBLE_H__ -#define __GTK_MENU_ITEM_ACCESSIBLE_H__ - -#if !defined (__GTK_A11Y_H_INSIDE__) && !defined (GTK_COMPILATION) -#error "Only can be included directly." -#endif - -#include - -G_BEGIN_DECLS - -#define GTK_TYPE_MENU_ITEM_ACCESSIBLE (gtk_menu_item_accessible_get_type ()) -#define GTK_MENU_ITEM_ACCESSIBLE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GTK_TYPE_MENU_ITEM_ACCESSIBLE, GtkMenuItemAccessible)) -#define GTK_MENU_ITEM_ACCESSIBLE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GTK_TYPE_MENU_ITEM_ACCESSIBLE, GtkMenuItemAccessibleClass)) -#define GTK_IS_MENU_ITEM_ACCESSIBLE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GTK_TYPE_MENU_ITEM_ACCESSIBLE)) -#define GTK_IS_MENU_ITEM_ACCESSIBLE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GTK_TYPE_MENU_ITEM_ACCESSIBLE)) -#define GTK_MENU_ITEM_ACCESSIBLE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GTK_TYPE_MENU_ITEM_ACCESSIBLE, GtkMenuItemAccessibleClass)) - -typedef struct _GtkMenuItemAccessible GtkMenuItemAccessible; -typedef struct _GtkMenuItemAccessibleClass GtkMenuItemAccessibleClass; -typedef struct _GtkMenuItemAccessiblePrivate GtkMenuItemAccessiblePrivate; - -struct _GtkMenuItemAccessible -{ - GtkContainerAccessible parent; - - GtkMenuItemAccessiblePrivate *priv; -}; - -struct _GtkMenuItemAccessibleClass -{ - GtkContainerAccessibleClass parent_class; -}; - -GDK_AVAILABLE_IN_ALL -GType gtk_menu_item_accessible_get_type (void); - -G_END_DECLS - -#endif /* __GTK_MENU_ITEM_ACCESSIBLE_H__ */ diff --git a/gtk/a11y/gtkmenushellaccessible.c b/gtk/a11y/gtkmenushellaccessible.c deleted file mode 100644 index a01441d633..0000000000 --- a/gtk/a11y/gtkmenushellaccessible.c +++ /dev/null @@ -1,199 +0,0 @@ -/* GTK+ - accessibility implementations - * Copyright 2001 Sun Microsystems Inc. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * 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, see . - */ - -#include "config.h" - -#include -#include "gtkmenushellaccessible.h" - - -static void atk_selection_interface_init (AtkSelectionIface *iface); - -G_DEFINE_TYPE_WITH_CODE (GtkMenuShellAccessible, gtk_menu_shell_accessible, GTK_TYPE_CONTAINER_ACCESSIBLE, - G_IMPLEMENT_INTERFACE (ATK_TYPE_SELECTION, atk_selection_interface_init)) - -static void -gtk_menu_shell_accessible_initialize (AtkObject *accessible, - gpointer data) -{ - ATK_OBJECT_CLASS (gtk_menu_shell_accessible_parent_class)->initialize (accessible, data); - - accessible->role = ATK_ROLE_UNKNOWN; -} - -static void -gtk_menu_shell_accessible_class_init (GtkMenuShellAccessibleClass *klass) -{ - AtkObjectClass *atk_object_class = ATK_OBJECT_CLASS (klass); - - atk_object_class->initialize = gtk_menu_shell_accessible_initialize; -} - -static void -gtk_menu_shell_accessible_init (GtkMenuShellAccessible *menu_shell) -{ -} - -static gboolean -gtk_menu_shell_accessible_add_selection (AtkSelection *selection, - gint i) -{ - GList *kids; - GtkWidget *item; - guint length; - GtkWidget *widget; - - widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (selection)); - if (widget == NULL) - return FALSE; - - kids = gtk_container_get_children (GTK_CONTAINER (widget)); - length = g_list_length (kids); - if (i < 0 || i > length) - { - g_list_free (kids); - return FALSE; - } - - item = g_list_nth_data (kids, i); - g_list_free (kids); - g_return_val_if_fail (GTK_IS_MENU_ITEM (item), FALSE); - gtk_menu_shell_select_item (GTK_MENU_SHELL (widget), item); - return TRUE; -} - -static gboolean -gtk_menu_shell_accessible_clear_selection (AtkSelection *selection) -{ - GtkMenuShell *shell; - GtkWidget *widget; - - widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (selection)); - if (widget == NULL) - return FALSE; - - shell = GTK_MENU_SHELL (widget); - - gtk_menu_shell_deselect (shell); - return TRUE; -} - -static AtkObject * -gtk_menu_shell_accessible_ref_selection (AtkSelection *selection, - gint i) -{ - GtkMenuShell *shell; - AtkObject *obj; - GtkWidget *widget; - GtkWidget *item; - - widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (selection)); - if (widget == NULL) - return NULL; - - if (i != 0) - return NULL; - - shell = GTK_MENU_SHELL (widget); - - item = gtk_menu_shell_get_selected_item (shell); - if (item != NULL) - { - obj = gtk_widget_get_accessible (item); - g_object_ref (obj); - return obj; - } - return NULL; -} - -static gint -gtk_menu_shell_accessible_get_selection_count (AtkSelection *selection) -{ - GtkMenuShell *shell; - GtkWidget *widget; - - widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (selection)); - if (widget == NULL) - return 0; - - shell = GTK_MENU_SHELL (widget); - - if (gtk_menu_shell_get_selected_item (shell) != NULL) - return 1; - - return 0; -} - -static gboolean -gtk_menu_shell_accessible_is_child_selected (AtkSelection *selection, - gint i) -{ - GtkMenuShell *shell; - GList *kids; - gint j; - GtkWidget *widget; - GtkWidget *item; - - widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (selection)); - if (widget == NULL) - return FALSE; - - shell = GTK_MENU_SHELL (widget); - item = gtk_menu_shell_get_selected_item (shell); - if (item == NULL) - return FALSE; - - kids = gtk_container_get_children (GTK_CONTAINER (shell)); - j = g_list_index (kids, item); - g_list_free (kids); - - return j==i; -} - -static gboolean -gtk_menu_shell_accessible_remove_selection (AtkSelection *selection, - gint i) -{ - GtkMenuShell *shell; - GtkWidget *widget; - GtkWidget *item; - - widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (selection)); - if (widget == NULL) - return FALSE; - - if (i != 0) - return FALSE; - - shell = GTK_MENU_SHELL (widget); - - item = gtk_menu_shell_get_selected_item (shell); - if (item && gtk_menu_item_get_submenu (GTK_MENU_ITEM (item))) - gtk_menu_shell_deselect (shell); - return TRUE; -} - -static void -atk_selection_interface_init (AtkSelectionIface *iface) -{ - iface->add_selection = gtk_menu_shell_accessible_add_selection; - iface->clear_selection = gtk_menu_shell_accessible_clear_selection; - iface->ref_selection = gtk_menu_shell_accessible_ref_selection; - iface->get_selection_count = gtk_menu_shell_accessible_get_selection_count; - iface->is_child_selected = gtk_menu_shell_accessible_is_child_selected; - iface->remove_selection = gtk_menu_shell_accessible_remove_selection; -} diff --git a/gtk/a11y/gtkmenushellaccessible.h b/gtk/a11y/gtkmenushellaccessible.h deleted file mode 100644 index 5782a3537f..0000000000 --- a/gtk/a11y/gtkmenushellaccessible.h +++ /dev/null @@ -1,57 +0,0 @@ -/* GTK+ - accessibility implementations - * Copyright 2001 Sun Microsystems Inc. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library. If not, see . - */ - -#ifndef __GTK_MENU_SHELL_ACCESSIBLE_H__ -#define __GTK_MENU_SHELL_ACCESSIBLE_H__ - -#if !defined (__GTK_A11Y_H_INSIDE__) && !defined (GTK_COMPILATION) -#error "Only can be included directly." -#endif - -#include - -G_BEGIN_DECLS - -#define GTK_TYPE_MENU_SHELL_ACCESSIBLE (gtk_menu_shell_accessible_get_type ()) -#define GTK_MENU_SHELL_ACCESSIBLE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GTK_TYPE_MENU_SHELL_ACCESSIBLE, GtkMenuShellAccessible)) -#define GTK_MENU_SHELL_ACCESSIBLE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GTK_TYPE_MENU_SHELL_ACCESSIBLE, GtkMenuShellAccessibleClass)) -#define GTK_IS_MENU_SHELL_ACCESSIBLE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GTK_TYPE_MENU_SHELL_ACCESSIBLE)) -#define GTK_IS_MENU_SHELL_ACCESSIBLE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GTK_TYPE_MENU_SHELL_ACCESSIBLE)) -#define GTK_MENU_SHELL_ACCESSIBLE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GTK_TYPE_MENU_SHELL_ACCESSIBLE, GtkMenuShellAccessibleClass)) - -typedef struct _GtkMenuShellAccessible GtkMenuShellAccessible; -typedef struct _GtkMenuShellAccessibleClass GtkMenuShellAccessibleClass; -typedef struct _GtkMenuShellAccessiblePrivate GtkMenuShellAccessiblePrivate; - -struct _GtkMenuShellAccessible -{ - GtkContainerAccessible parent; - - GtkMenuShellAccessiblePrivate *priv; -}; - -struct _GtkMenuShellAccessibleClass -{ - GtkContainerAccessibleClass parent_class; -}; - -GDK_AVAILABLE_IN_ALL -GType gtk_menu_shell_accessible_get_type (void); - -G_END_DECLS - -#endif /* __GTK_MENU_SHELL_ACCESSIBLE_H__ */ diff --git a/gtk/a11y/gtkradiomenuitemaccessible.c b/gtk/a11y/gtkradiomenuitemaccessible.c deleted file mode 100644 index d7205657b1..0000000000 --- a/gtk/a11y/gtkradiomenuitemaccessible.c +++ /dev/null @@ -1,117 +0,0 @@ -/* GTK+ - accessibility implementations - * Copyright 2002 Sun Microsystems Inc. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * 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, see . - */ - -#include "config.h" - -#include -#include "gtkradiomenuitemaccessible.h" - -struct _GtkRadioMenuItemAccessiblePrivate -{ - GSList *old_group; -}; - -G_DEFINE_TYPE_WITH_PRIVATE (GtkRadioMenuItemAccessible, - gtk_radio_menu_item_accessible, - GTK_TYPE_CHECK_MENU_ITEM_ACCESSIBLE) - - -static AtkRelationSet * -gtk_radio_menu_item_accessible_ref_relation_set (AtkObject *obj) -{ - GtkWidget *widget; - AtkRelationSet *relation_set; - GSList *list; - GtkRadioMenuItemAccessible *radio_menu_item; - - widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (obj)); - if (widget == NULL) - return NULL; - - radio_menu_item = GTK_RADIO_MENU_ITEM_ACCESSIBLE (obj); - - relation_set = ATK_OBJECT_CLASS (gtk_radio_menu_item_accessible_parent_class)->ref_relation_set (obj); - - /* If the radio menu_item's group has changed remove the relation */ - list = gtk_radio_menu_item_get_group (GTK_RADIO_MENU_ITEM (widget)); - - if (radio_menu_item->priv->old_group != list) - { - AtkRelation *relation; - - relation = atk_relation_set_get_relation_by_type (relation_set, ATK_RELATION_MEMBER_OF); - atk_relation_set_remove (relation_set, relation); - } - - if (!atk_relation_set_contains (relation_set, ATK_RELATION_MEMBER_OF)) - { - /* Get the members of the menu_item group */ - radio_menu_item->priv->old_group = list; - if (list) - { - AtkObject **accessible_array; - guint list_length; - AtkRelation* relation; - gint i = 0; - - list_length = g_slist_length (list); - accessible_array = g_new (AtkObject *, list_length); - while (list != NULL) - { - GtkWidget* list_item = list->data; - - accessible_array[i++] = gtk_widget_get_accessible (list_item); - - list = list->next; - } - relation = atk_relation_new (accessible_array, list_length, - ATK_RELATION_MEMBER_OF); - g_free (accessible_array); - - atk_relation_set_add (relation_set, relation); - - /* Unref the relation so that it is not leaked */ - g_object_unref (relation); - } - } - - return relation_set; -} - -static void -gtk_radio_menu_item_accessible_initialize (AtkObject *obj, - gpointer data) -{ - ATK_OBJECT_CLASS (gtk_radio_menu_item_accessible_parent_class)->initialize (obj, data); - - obj->role = ATK_ROLE_RADIO_MENU_ITEM; -} - -static void -gtk_radio_menu_item_accessible_class_init (GtkRadioMenuItemAccessibleClass *klass) -{ - AtkObjectClass *class = ATK_OBJECT_CLASS (klass); - - class->ref_relation_set = gtk_radio_menu_item_accessible_ref_relation_set; - class->initialize = gtk_radio_menu_item_accessible_initialize; -} - -static void -gtk_radio_menu_item_accessible_init (GtkRadioMenuItemAccessible *radio_menu_item) -{ - radio_menu_item->priv = gtk_radio_menu_item_accessible_get_instance_private (radio_menu_item); -} diff --git a/gtk/a11y/gtkradiomenuitemaccessible.h b/gtk/a11y/gtkradiomenuitemaccessible.h deleted file mode 100644 index 2cd32e0494..0000000000 --- a/gtk/a11y/gtkradiomenuitemaccessible.h +++ /dev/null @@ -1,57 +0,0 @@ -/* GTK+ - accessibility implementations - * Copyright 2002 Sun Microsystems Inc. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library. If not, see . - */ - -#ifndef __GTK_RADIO_MENU_ITEM_ACCESSIBLE_H__ -#define __GTK_RADIO_MENU_ITEM_ACCESSIBLE_H__ - -#if !defined (__GTK_A11Y_H_INSIDE__) && !defined (GTK_COMPILATION) -#error "Only can be included directly." -#endif - -#include - -G_BEGIN_DECLS - -#define GTK_TYPE_RADIO_MENU_ITEM_ACCESSIBLE (gtk_radio_menu_item_accessible_get_type ()) -#define GTK_RADIO_MENU_ITEM_ACCESSIBLE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GTK_TYPE_RADIO_MENU_ITEM_ACCESSIBLE, GtkRadioMenuItemAccessible)) -#define GTK_RADIO_MENU_ITEM_ACCESSIBLE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GTK_TYPE_RADIO_MENU_ITEM_ACCESSIBLE, GtkRadioMenuItemAccessibleClass)) -#define GTK_IS_RADIO_MENU_ITEM_ACCESSIBLE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GTK_TYPE_RADIO_MENU_ITEM_ACCESSIBLE)) -#define GTK_IS_RADIO_MENU_ITEM_ACCESSIBLE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GTK_TYPE_RADIO_MENU_ITEM_ACCESSIBLE)) -#define GTK_RADIO_MENU_ITEM_ACCESSIBLE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GTK_TYPE_RADIO_MENU_ITEM_ACCESSIBLE, GtkRadioMenuItemAccessibleClass)) - -typedef struct _GtkRadioMenuItemAccessible GtkRadioMenuItemAccessible; -typedef struct _GtkRadioMenuItemAccessibleClass GtkRadioMenuItemAccessibleClass; -typedef struct _GtkRadioMenuItemAccessiblePrivate GtkRadioMenuItemAccessiblePrivate; - -struct _GtkRadioMenuItemAccessible -{ - GtkCheckMenuItemAccessible parent; - - GtkRadioMenuItemAccessiblePrivate *priv; -}; - -struct _GtkRadioMenuItemAccessibleClass -{ - GtkCheckMenuItemAccessibleClass parent_class; -}; - -GDK_AVAILABLE_IN_ALL -GType gtk_radio_menu_item_accessible_get_type (void); - -G_END_DECLS - -#endif /* __GTK_RADIO_MENU_ITEM_ACCESSIBLE_H__ */ diff --git a/gtk/a11y/gtktoplevelaccessible.c b/gtk/a11y/gtktoplevelaccessible.c index 1512d6fe75..a7d07fec2f 100644 --- a/gtk/a11y/gtktoplevelaccessible.c +++ b/gtk/a11y/gtktoplevelaccessible.c @@ -22,8 +22,6 @@ #include #include -#include -#include #include #include @@ -91,25 +89,6 @@ gtk_toplevel_accessible_get_name (AtkObject *obj) return g_get_prgname (); } -static gboolean -is_attached_menu_window (GtkWidget *widget) -{ - GtkWidget *child; - - child = gtk_bin_get_child (GTK_BIN (widget)); - if (GTK_IS_MENU (child)) - { - GtkWidget *attach; - - attach = gtk_menu_get_attach_widget (GTK_MENU (child)); - /* Allow for menu belonging to the Panel Menu, which is a GtkButton */ - if (GTK_IS_MENU_ITEM (attach) || GTK_IS_BUTTON (attach)) - return TRUE; - } - - return FALSE; -} - static void gtk_toplevel_accessible_class_init (GtkToplevelAccessibleClass *klass) { @@ -177,8 +156,7 @@ show_event_watcher (GSignalInvocationHint *ihint, return TRUE; widget = GTK_WIDGET (object); - if (gtk_widget_get_parent (widget) || - is_attached_menu_window (widget)) + if (gtk_widget_get_parent (widget)) return TRUE; child = gtk_widget_get_accessible (widget); @@ -236,7 +214,6 @@ gtk_toplevel_accessible_init (GtkToplevelAccessible *toplevel) widget = GTK_WIDGET (window); if (!window || !gtk_widget_get_visible (widget) || - is_attached_menu_window (widget) || gtk_widget_get_parent (GTK_WIDGET (window))) { GList *temp_l = l->next; diff --git a/gtk/a11y/meson.build b/gtk/a11y/meson.build index 4ea944d0fd..550e4e7173 100644 --- a/gtk/a11y/meson.build +++ b/gtk/a11y/meson.build @@ -5,7 +5,6 @@ a11y_sources = files([ 'gtkbuttonaccessible.c', 'gtkcellaccessible.c', 'gtkcellaccessibleparent.c', - 'gtkcheckmenuitemaccessible.c', 'gtkcolorswatchaccessible.c', 'gtkcomboboxaccessible.c', 'gtkcontaineraccessible.c', @@ -24,10 +23,7 @@ a11y_sources = files([ 'gtklistboxaccessible.c', 'gtklistboxrowaccessible.c', 'gtklockbuttonaccessible.c', - 'gtkmenuaccessible.c', 'gtkmenubuttonaccessible.c', - 'gtkmenuitemaccessible.c', - 'gtkmenushellaccessible.c', 'gtknotebookaccessible.c', 'gtknotebookpageaccessible.c', 'gtkpanedaccessible.c', @@ -35,7 +31,6 @@ a11y_sources = files([ 'gtkpopoveraccessible.c', 'gtkprogressbaraccessible.c', 'gtkradiobuttonaccessible.c', - 'gtkradiomenuitemaccessible.c', 'gtkrangeaccessible.c', 'gtkrenderercellaccessible.c', 'gtkscaleaccessible.c', @@ -62,7 +57,6 @@ a11y_headers = files([ 'gtkbuttonaccessible.h', 'gtkcellaccessible.h', 'gtkcellaccessibleparent.h', - 'gtkcheckmenuitemaccessible.h', 'gtkcomboboxaccessible.h', 'gtkcontaineraccessible.h', 'gtkcontainercellaccessible.h', @@ -80,17 +74,13 @@ a11y_headers = files([ 'gtklistboxaccessible.h', 'gtklistboxrowaccessible.h', 'gtklockbuttonaccessible.h', - 'gtkmenuaccessible.h', 'gtkmenubuttonaccessible.h', - 'gtkmenuitemaccessible.h', - 'gtkmenushellaccessible.h', 'gtknotebookaccessible.h', 'gtknotebookpageaccessible.h', 'gtkpanedaccessible.h', 'gtkpopoveraccessible.h', 'gtkprogressbaraccessible.h', 'gtkradiobuttonaccessible.h', - 'gtkradiomenuitemaccessible.h', 'gtkrangeaccessible.h', 'gtkrenderercellaccessible.h', 'gtkscaleaccessible.h', diff --git a/gtk/gtk-a11y.h b/gtk/gtk-a11y.h index 8013c3a9df..7afaf753de 100644 --- a/gtk/gtk-a11y.h +++ b/gtk/gtk-a11y.h @@ -32,7 +32,6 @@ #include #include #include -#include #include #include #include @@ -50,17 +49,13 @@ #include #include #include -#include #include -#include -#include #include #include #include #include #include #include -#include #include #include #include diff --git a/gtk/gtk-autocleanups.h b/gtk/gtk-autocleanups.h index 2e11f477d4..91889b0bdb 100644 --- a/gtk/gtk-autocleanups.h +++ b/gtk/gtk-autocleanups.h @@ -53,7 +53,6 @@ G_DEFINE_AUTOPTR_CLEANUP_FUNC(GtkCellRendererText, g_object_unref) G_DEFINE_AUTOPTR_CLEANUP_FUNC(GtkCellRendererToggle, g_object_unref) G_DEFINE_AUTOPTR_CLEANUP_FUNC(GtkCellView, g_object_unref) G_DEFINE_AUTOPTR_CLEANUP_FUNC(GtkCheckButton, g_object_unref) -G_DEFINE_AUTOPTR_CLEANUP_FUNC(GtkCheckMenuItem, g_object_unref) G_DEFINE_AUTOPTR_CLEANUP_FUNC(GtkClipboard, g_object_unref) G_DEFINE_AUTOPTR_CLEANUP_FUNC(GtkColorButton, g_object_unref) G_DEFINE_AUTOPTR_CLEANUP_FUNC(GtkColorChooser, g_object_unref) @@ -105,9 +104,7 @@ G_DEFINE_AUTOPTR_CLEANUP_FUNC(GtkLevelBar, g_object_unref) G_DEFINE_AUTOPTR_CLEANUP_FUNC(GtkLinkButton, g_object_unref) G_DEFINE_AUTOPTR_CLEANUP_FUNC(GtkListStore, g_object_unref) G_DEFINE_AUTOPTR_CLEANUP_FUNC(GtkLockButton, g_object_unref) -G_DEFINE_AUTOPTR_CLEANUP_FUNC(GtkMenuBar, g_object_unref) G_DEFINE_AUTOPTR_CLEANUP_FUNC(GtkMenuButton, g_object_unref) -G_DEFINE_AUTOPTR_CLEANUP_FUNC(GtkMenuItem, g_object_unref) G_DEFINE_AUTOPTR_CLEANUP_FUNC(GtkMenuToolButton, g_object_unref) G_DEFINE_AUTOPTR_CLEANUP_FUNC(GtkMessageDialog, g_object_unref) G_DEFINE_AUTOPTR_CLEANUP_FUNC(GtkMountOperation, g_object_unref) @@ -124,7 +121,6 @@ G_DEFINE_AUTOPTR_CLEANUP_FUNC(GtkPrintOperationPreview, g_object_unref) G_DEFINE_AUTOPTR_CLEANUP_FUNC(GtkPrintSettings, g_object_unref) G_DEFINE_AUTOPTR_CLEANUP_FUNC(GtkProgressBar, g_object_unref) G_DEFINE_AUTOPTR_CLEANUP_FUNC(GtkRadioButton, g_object_unref) -G_DEFINE_AUTOPTR_CLEANUP_FUNC(GtkRadioMenuItem, g_object_unref) G_DEFINE_AUTOPTR_CLEANUP_FUNC(GtkRadioToolButton, g_object_unref) G_DEFINE_AUTOPTR_CLEANUP_FUNC(GtkRange, g_object_unref) G_DEFINE_AUTOPTR_CLEANUP_FUNC(GtkRecentManager, g_object_unref) @@ -137,7 +133,6 @@ G_DEFINE_AUTOPTR_CLEANUP_FUNC(GtkScrolledWindow, g_object_unref) G_DEFINE_AUTOPTR_CLEANUP_FUNC(GtkSearchBar, g_object_unref) G_DEFINE_AUTOPTR_CLEANUP_FUNC(GtkSearchEntry, g_object_unref) G_DEFINE_AUTOPTR_CLEANUP_FUNC(GtkSeparator, g_object_unref) -G_DEFINE_AUTOPTR_CLEANUP_FUNC(GtkSeparatorMenuItem, g_object_unref) G_DEFINE_AUTOPTR_CLEANUP_FUNC(GtkSeparatorToolItem, g_object_unref) G_DEFINE_AUTOPTR_CLEANUP_FUNC(GtkSettings, g_object_unref) G_DEFINE_AUTOPTR_CLEANUP_FUNC(GtkStackSidebar, g_object_unref) diff --git a/gtk/gtk.h b/gtk/gtk.h index 1fd949bd5f..a64a2a826a 100644 --- a/gtk/gtk.h +++ b/gtk/gtk.h @@ -76,7 +76,6 @@ #include #include #include -#include #include #include #include @@ -156,11 +155,7 @@ #include #include #include -#include -#include #include -#include -#include #include #include #include @@ -185,7 +180,6 @@ #include #include #include -#include #include #include #include @@ -202,7 +196,6 @@ #include #include #include -#include #include #include #include diff --git a/gtk/gtkcheckmenuitem.c b/gtk/gtkcheckmenuitem.c deleted file mode 100644 index c7c4532d5d..0000000000 --- a/gtk/gtkcheckmenuitem.c +++ /dev/null @@ -1,623 +0,0 @@ -/* GTK - The GIMP Toolkit - * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * 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, see . - */ - -/* - * Modified by the GTK+ Team and others 1997-2001. See the AUTHORS - * file for a list of people on the GTK+ Team. See the ChangeLog - * files for a list of changes. These files are distributed with - * GTK+ at ftp://ftp.gtk.org/pub/gtk/. - */ - -#include "config.h" -#include "gtkcheckmenuitemprivate.h" -#include "gtkmenuitemprivate.h" -#include "gtkaccellabel.h" -#include "gtkmarshalers.h" -#include "gtkprivate.h" -#include "gtkintl.h" -#include "a11y/gtkcheckmenuitemaccessible.h" -#include "gtkcssnodeprivate.h" -#include "gtkcssstylepropertyprivate.h" -#include "gtkwidgetprivate.h" -#include "gtkiconprivate.h" - -/** - * SECTION:gtkcheckmenuitem - * @Short_description: A menu item with a check box - * @Title: GtkCheckMenuItem - * - * A #GtkCheckMenuItem is a menu item that maintains the state of a boolean - * value in addition to a #GtkMenuItem usual role in activating application - * code. - * - * A check box indicating the state of the boolean value is displayed - * at the left side of the #GtkMenuItem. Activating the #GtkMenuItem - * toggles the value. - * - * # CSS nodes - * - * |[ - * menuitem - * ├── check.left - * ╰── - * ]| - * - * GtkCheckMenuItem has a main CSS node with name menuitem, and a subnode - * with name check, which gets the .left or .right style class. - */ - -typedef struct _GtkCheckMenuItemPrivate GtkCheckMenuItemPrivate; - -struct _GtkCheckMenuItemPrivate -{ - GtkWidget *indicator_widget; - - guint active : 1; - guint draw_as_radio : 1; - guint inconsistent : 1; -}; - -enum { - TOGGLED, - LAST_SIGNAL -}; - -enum { - PROP_0, - PROP_ACTIVE, - PROP_INCONSISTENT, - PROP_DRAW_AS_RADIO -}; - -static void gtk_check_menu_item_activate (GtkMenuItem *menu_item); -static void gtk_check_menu_item_toggle_size_request (GtkMenuItem *menu_item, - gint *requisition); -static void gtk_check_menu_item_set_property (GObject *object, - guint prop_id, - const GValue *value, - GParamSpec *pspec); -static void gtk_check_menu_item_get_property (GObject *object, - guint prop_id, - GValue *value, - GParamSpec *pspec); - -static void gtk_check_menu_item_state_flags_changed (GtkWidget *widget, - GtkStateFlags previous_state); -static void gtk_check_menu_item_direction_changed (GtkWidget *widget, - GtkTextDirection previous_dir); - -static guint check_menu_item_signals[LAST_SIGNAL] = { 0 }; - -G_DEFINE_TYPE_WITH_CODE (GtkCheckMenuItem, gtk_check_menu_item, GTK_TYPE_MENU_ITEM, - G_ADD_PRIVATE (GtkCheckMenuItem)) - -static void -gtk_check_menu_item_size_allocate (GtkWidget *widget, - int width, - int height, - int baseline) -{ - GtkAllocation indicator_alloc; - GtkCheckMenuItem *check_menu_item = GTK_CHECK_MENU_ITEM (widget); - GtkCheckMenuItemPrivate *priv = gtk_check_menu_item_get_instance_private (check_menu_item); - gint toggle_size; - - GTK_WIDGET_CLASS (gtk_check_menu_item_parent_class)->size_allocate (widget, - width, - height, - baseline); - - gtk_widget_measure (priv->indicator_widget, - GTK_ORIENTATION_HORIZONTAL, - -1, - &indicator_alloc.width, NULL, - NULL, NULL); - gtk_widget_measure (priv->indicator_widget, - GTK_ORIENTATION_VERTICAL, - -1, - &indicator_alloc.height, NULL, - NULL, NULL); - toggle_size = GTK_MENU_ITEM (check_menu_item)->priv->toggle_size; - - if (gtk_widget_get_direction (widget) == GTK_TEXT_DIR_LTR) - indicator_alloc.x = (toggle_size - indicator_alloc.width) / 2; - else - indicator_alloc.x = width - toggle_size + - (toggle_size - indicator_alloc.width) / 2; - - indicator_alloc.y = (height - indicator_alloc.height) / 2; - - gtk_widget_size_allocate (priv->indicator_widget, - &indicator_alloc, - baseline); -} - -static void -gtk_check_menu_item_finalize (GObject *object) -{ - GtkCheckMenuItem *item = GTK_CHECK_MENU_ITEM (object); - GtkCheckMenuItemPrivate *priv = gtk_check_menu_item_get_instance_private (item); - - gtk_widget_unparent (priv->indicator_widget); - - G_OBJECT_CLASS (gtk_check_menu_item_parent_class)->finalize (object); -} - -static void -gtk_check_menu_item_class_init (GtkCheckMenuItemClass *klass) -{ - GObjectClass *gobject_class; - GtkWidgetClass *widget_class; - GtkMenuItemClass *menu_item_class; - - gobject_class = G_OBJECT_CLASS (klass); - widget_class = (GtkWidgetClass*) klass; - menu_item_class = (GtkMenuItemClass*) klass; - - gobject_class->set_property = gtk_check_menu_item_set_property; - gobject_class->get_property = gtk_check_menu_item_get_property; - gobject_class->finalize = gtk_check_menu_item_finalize; - - widget_class->size_allocate = gtk_check_menu_item_size_allocate; - widget_class->state_flags_changed = gtk_check_menu_item_state_flags_changed; - widget_class->direction_changed = gtk_check_menu_item_direction_changed; - - g_object_class_install_property (gobject_class, - PROP_ACTIVE, - g_param_spec_boolean ("active", - P_("Active"), - P_("Whether the menu item is checked"), - FALSE, - GTK_PARAM_READWRITE|G_PARAM_EXPLICIT_NOTIFY)); - - g_object_class_install_property (gobject_class, - PROP_INCONSISTENT, - g_param_spec_boolean ("inconsistent", - P_("Inconsistent"), - P_("Whether to display an “inconsistent” state"), - FALSE, - GTK_PARAM_READWRITE|G_PARAM_EXPLICIT_NOTIFY)); - - g_object_class_install_property (gobject_class, - PROP_DRAW_AS_RADIO, - g_param_spec_boolean ("draw-as-radio", - P_("Draw as radio menu item"), - P_("Whether the menu item looks like a radio menu item"), - FALSE, - GTK_PARAM_READWRITE|G_PARAM_EXPLICIT_NOTIFY)); - - menu_item_class->activate = gtk_check_menu_item_activate; - menu_item_class->hide_on_activate = FALSE; - menu_item_class->toggle_size_request = gtk_check_menu_item_toggle_size_request; - - klass->toggled = NULL; - - /** - * GtkCheckMenuItem::toggled: - * @checkmenuitem: the object which received the signal. - * - * This signal is emitted when the state of the check box is changed. - * - * A signal handler can use gtk_check_menu_item_get_active() - * to discover the new state. - */ - check_menu_item_signals[TOGGLED] = - g_signal_new (I_("toggled"), - G_OBJECT_CLASS_TYPE (gobject_class), - G_SIGNAL_RUN_FIRST, - G_STRUCT_OFFSET (GtkCheckMenuItemClass, toggled), - NULL, NULL, - NULL, - G_TYPE_NONE, 0); - - gtk_widget_class_set_accessible_type (widget_class, GTK_TYPE_CHECK_MENU_ITEM_ACCESSIBLE); - gtk_widget_class_set_css_name (widget_class, I_("menuitem")); -} - -/** - * gtk_check_menu_item_new: - * - * Creates a new #GtkCheckMenuItem. - * - * Returns: a new #GtkCheckMenuItem. - */ -GtkWidget* -gtk_check_menu_item_new (void) -{ - return g_object_new (GTK_TYPE_CHECK_MENU_ITEM, NULL); -} - -/** - * gtk_check_menu_item_new_with_label: - * @label: the string to use for the label. - * - * Creates a new #GtkCheckMenuItem with a label. - * - * Returns: a new #GtkCheckMenuItem. - */ -GtkWidget* -gtk_check_menu_item_new_with_label (const gchar *label) -{ - return g_object_new (GTK_TYPE_CHECK_MENU_ITEM, - "label", label, - NULL); -} - - -/** - * gtk_check_menu_item_new_with_mnemonic: - * @label: The text of the button, with an underscore in front of the - * character - * - * Creates a new #GtkCheckMenuItem containing a label. The label - * will be created using gtk_label_new_with_mnemonic(), so underscores - * in @label indicate the mnemonic for the menu item. - * - * Returns: a new #GtkCheckMenuItem - */ -GtkWidget* -gtk_check_menu_item_new_with_mnemonic (const gchar *label) -{ - return g_object_new (GTK_TYPE_CHECK_MENU_ITEM, - "label", label, - "use-underline", TRUE, - NULL); -} - -/** - * gtk_check_menu_item_set_active: - * @check_menu_item: a #GtkCheckMenuItem. - * @is_active: boolean value indicating whether the check box is active. - * - * Sets the active state of the menu item’s check box. - */ -void -gtk_check_menu_item_set_active (GtkCheckMenuItem *check_menu_item, - gboolean is_active) -{ - GtkCheckMenuItemPrivate *priv = gtk_check_menu_item_get_instance_private (check_menu_item); - - g_return_if_fail (GTK_IS_CHECK_MENU_ITEM (check_menu_item)); - - is_active = is_active != 0; - - if (priv->active != is_active) - gtk_menu_item_activate (GTK_MENU_ITEM (check_menu_item)); -} - -/** - * gtk_check_menu_item_get_active: - * @check_menu_item: a #GtkCheckMenuItem - * - * Returns whether the check menu item is active. See - * gtk_check_menu_item_set_active (). - * - * Returns: %TRUE if the menu item is checked. - */ -gboolean -gtk_check_menu_item_get_active (GtkCheckMenuItem *check_menu_item) -{ - GtkCheckMenuItemPrivate *priv = gtk_check_menu_item_get_instance_private (check_menu_item); - - g_return_val_if_fail (GTK_IS_CHECK_MENU_ITEM (check_menu_item), FALSE); - - return priv->active; -} - -static void -gtk_check_menu_item_toggle_size_request (GtkMenuItem *menu_item, - gint *requisition) -{ - GtkCheckMenuItem *check_menu_item = GTK_CHECK_MENU_ITEM (menu_item); - GtkCheckMenuItemPrivate *priv = gtk_check_menu_item_get_instance_private (check_menu_item); - - g_return_if_fail (GTK_IS_CHECK_MENU_ITEM (menu_item)); - - gtk_widget_measure (priv->indicator_widget, - GTK_ORIENTATION_HORIZONTAL, - -1, - requisition, NULL, - NULL, NULL); -} - -/** - * gtk_check_menu_item_toggled: - * @check_menu_item: a #GtkCheckMenuItem. - * - * Emits the #GtkCheckMenuItem::toggled signal. - */ -void -gtk_check_menu_item_toggled (GtkCheckMenuItem *check_menu_item) -{ - g_signal_emit (check_menu_item, check_menu_item_signals[TOGGLED], 0); -} - -static void -update_node_state (GtkCheckMenuItem *check_menu_item) -{ - GtkCheckMenuItemPrivate *priv = gtk_check_menu_item_get_instance_private (check_menu_item); - GtkStateFlags state; - - state = gtk_widget_get_state_flags (GTK_WIDGET (check_menu_item)); - state &= ~(GTK_STATE_FLAG_CHECKED | GTK_STATE_FLAG_INCONSISTENT); - - if (priv->inconsistent) - state |= GTK_STATE_FLAG_INCONSISTENT; - if (priv->active) - state |= GTK_STATE_FLAG_CHECKED; - - gtk_widget_set_state_flags (priv->indicator_widget, state, TRUE); -} - -/** - * gtk_check_menu_item_set_inconsistent: - * @check_menu_item: a #GtkCheckMenuItem - * @setting: %TRUE to display an “inconsistent” third state check - * - * If the user has selected a range of elements (such as some text or - * spreadsheet cells) that are affected by a boolean setting, and the - * current values in that range are inconsistent, you may want to - * display the check in an “in between” state. This function turns on - * “in between” display. Normally you would turn off the inconsistent - * state again if the user explicitly selects a setting. This has to be - * done manually, gtk_check_menu_item_set_inconsistent() only affects - * visual appearance, it doesn’t affect the semantics of the widget. - * - **/ -void -gtk_check_menu_item_set_inconsistent (GtkCheckMenuItem *check_menu_item, - gboolean setting) -{ - GtkCheckMenuItemPrivate *priv = gtk_check_menu_item_get_instance_private (check_menu_item); - - g_return_if_fail (GTK_IS_CHECK_MENU_ITEM (check_menu_item)); - - setting = setting != FALSE; - - if (setting != priv->inconsistent) - { - priv->inconsistent = setting; - update_node_state (check_menu_item); - gtk_widget_queue_draw (GTK_WIDGET (check_menu_item)); - g_object_notify (G_OBJECT (check_menu_item), "inconsistent"); - } -} - -/** - * gtk_check_menu_item_get_inconsistent: - * @check_menu_item: a #GtkCheckMenuItem - * - * Retrieves the value set by gtk_check_menu_item_set_inconsistent(). - * - * Returns: %TRUE if inconsistent - **/ -gboolean -gtk_check_menu_item_get_inconsistent (GtkCheckMenuItem *check_menu_item) -{ - GtkCheckMenuItemPrivate *priv = gtk_check_menu_item_get_instance_private (check_menu_item); - - g_return_val_if_fail (GTK_IS_CHECK_MENU_ITEM (check_menu_item), FALSE); - - return priv->inconsistent; -} - -/** - * gtk_check_menu_item_set_draw_as_radio: - * @check_menu_item: a #GtkCheckMenuItem - * @draw_as_radio: whether @check_menu_item is drawn like a #GtkRadioMenuItem - * - * Sets whether @check_menu_item is drawn like a #GtkRadioMenuItem - **/ -void -gtk_check_menu_item_set_draw_as_radio (GtkCheckMenuItem *check_menu_item, - gboolean draw_as_radio) -{ - GtkCheckMenuItemPrivate *priv = gtk_check_menu_item_get_instance_private (check_menu_item); - GtkCssNode *indicator_node; - - g_return_if_fail (GTK_IS_CHECK_MENU_ITEM (check_menu_item)); - - draw_as_radio = draw_as_radio != FALSE; - - if (draw_as_radio != priv->draw_as_radio) - { - priv->draw_as_radio = draw_as_radio; - indicator_node = gtk_widget_get_css_node (priv->indicator_widget); - if (draw_as_radio) - gtk_css_node_set_name (indicator_node, I_("radio")); - else - gtk_css_node_set_name (indicator_node, I_("check")); - - gtk_widget_queue_draw (GTK_WIDGET (check_menu_item)); - - g_object_notify (G_OBJECT (check_menu_item), "draw-as-radio"); - } -} - -/** - * gtk_check_menu_item_get_draw_as_radio: - * @check_menu_item: a #GtkCheckMenuItem - * - * Returns whether @check_menu_item looks like a #GtkRadioMenuItem - * - * Returns: Whether @check_menu_item looks like a #GtkRadioMenuItem - **/ -gboolean -gtk_check_menu_item_get_draw_as_radio (GtkCheckMenuItem *check_menu_item) -{ - GtkCheckMenuItemPrivate *priv = gtk_check_menu_item_get_instance_private (check_menu_item); - - g_return_val_if_fail (GTK_IS_CHECK_MENU_ITEM (check_menu_item), FALSE); - - return priv->draw_as_radio; -} - -static void -gtk_check_menu_item_init (GtkCheckMenuItem *check_menu_item) -{ - GtkCheckMenuItemPrivate *priv = gtk_check_menu_item_get_instance_private (check_menu_item); - - priv->active = FALSE; - - priv->indicator_widget = gtk_icon_new ("check"); - gtk_widget_set_parent (priv->indicator_widget, GTK_WIDGET (check_menu_item)); - update_node_state (check_menu_item); -} - -static void -gtk_check_menu_item_activate (GtkMenuItem *menu_item) -{ - GtkCheckMenuItem *check_menu_item = GTK_CHECK_MENU_ITEM (menu_item); - GtkCheckMenuItemPrivate *priv = gtk_check_menu_item_get_instance_private (check_menu_item); - - priv->active = !priv->active; - - gtk_check_menu_item_toggled (check_menu_item); - update_node_state (check_menu_item); - gtk_widget_queue_draw (GTK_WIDGET (check_menu_item)); - - GTK_MENU_ITEM_CLASS (gtk_check_menu_item_parent_class)->activate (menu_item); - - g_object_notify (G_OBJECT (check_menu_item), "active"); -} - -static void -gtk_check_menu_item_state_flags_changed (GtkWidget *widget, - GtkStateFlags previous_state) - -{ - GtkCheckMenuItem *check_menu_item = GTK_CHECK_MENU_ITEM (widget); - - update_node_state (check_menu_item); - - GTK_WIDGET_CLASS (gtk_check_menu_item_parent_class)->state_flags_changed (widget, previous_state); -} - -static void -gtk_check_menu_item_direction_changed (GtkWidget *widget, - GtkTextDirection previous_dir) -{ - GtkCheckMenuItem *check_menu_item = GTK_CHECK_MENU_ITEM (widget); - GtkCheckMenuItemPrivate *priv = gtk_check_menu_item_get_instance_private (check_menu_item); - GtkStyleContext *context; - GtkWidget *child; - - context = gtk_widget_get_style_context (priv->indicator_widget); - - if (gtk_widget_get_direction (widget) == GTK_TEXT_DIR_RTL) - { - gtk_style_context_add_class (context, GTK_STYLE_CLASS_LEFT); - gtk_style_context_remove_class (context, GTK_STYLE_CLASS_RIGHT); - - child = gtk_widget_get_last_child (widget); - - if (child != priv->indicator_widget) - gtk_widget_insert_before (priv->indicator_widget, widget, NULL); - } - else - { - gtk_style_context_add_class (context, GTK_STYLE_CLASS_RIGHT); - gtk_style_context_remove_class (context, GTK_STYLE_CLASS_LEFT); - - child = gtk_widget_get_first_child (widget); - - if (child != priv->indicator_widget) - gtk_widget_insert_after (priv->indicator_widget, widget, NULL); - } - - GTK_WIDGET_CLASS (gtk_check_menu_item_parent_class)->direction_changed (widget, previous_dir); -} - -static void -gtk_check_menu_item_get_property (GObject *object, - guint prop_id, - GValue *value, - GParamSpec *pspec) -{ - GtkCheckMenuItem *check_menu_item = GTK_CHECK_MENU_ITEM (object); - GtkCheckMenuItemPrivate *priv = gtk_check_menu_item_get_instance_private (check_menu_item); - - switch (prop_id) - { - case PROP_ACTIVE: - g_value_set_boolean (value, priv->active); - break; - case PROP_INCONSISTENT: - g_value_set_boolean (value, priv->inconsistent); - break; - case PROP_DRAW_AS_RADIO: - g_value_set_boolean (value, priv->draw_as_radio); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; - } -} - - -static void -gtk_check_menu_item_set_property (GObject *object, - guint prop_id, - const GValue *value, - GParamSpec *pspec) -{ - GtkCheckMenuItem *checkitem = GTK_CHECK_MENU_ITEM (object); - - switch (prop_id) - { - case PROP_ACTIVE: - gtk_check_menu_item_set_active (checkitem, g_value_get_boolean (value)); - break; - case PROP_INCONSISTENT: - gtk_check_menu_item_set_inconsistent (checkitem, g_value_get_boolean (value)); - break; - case PROP_DRAW_AS_RADIO: - gtk_check_menu_item_set_draw_as_radio (checkitem, g_value_get_boolean (value)); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; - } -} - -/* Private */ - -/* - * _gtk_check_menu_item_set_active: - * @check_menu_item: a #GtkCheckMenuItem - * @is_active: whether the action is active or not - * - * Sets the #GtkCheckMenuItem:active property directly. This function does - * not emit signals or notifications: it is left to the caller to do so. - */ -void -_gtk_check_menu_item_set_active (GtkCheckMenuItem *check_menu_item, - gboolean is_active) -{ - GtkCheckMenuItemPrivate *priv = gtk_check_menu_item_get_instance_private (check_menu_item); - - priv->active = is_active; - update_node_state (check_menu_item); -} - -GtkWidget * -_gtk_check_menu_item_get_indicator_widget (GtkCheckMenuItem *check_menu_item) -{ - GtkCheckMenuItemPrivate *priv = gtk_check_menu_item_get_instance_private (check_menu_item); - - return priv->indicator_widget; -} diff --git a/gtk/gtkcheckmenuitem.h b/gtk/gtkcheckmenuitem.h deleted file mode 100644 index ba8cfaf041..0000000000 --- a/gtk/gtkcheckmenuitem.h +++ /dev/null @@ -1,102 +0,0 @@ -/* GTK - The GIMP Toolkit - * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * 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, see . - */ - -/* - * Modified by the GTK+ Team and others 1997-2001. See the AUTHORS - * file for a list of people on the GTK+ Team. See the ChangeLog - * files for a list of changes. These files are distributed with - * GTK+ at ftp://ftp.gtk.org/pub/gtk/. - */ - -#ifndef __GTK_CHECK_MENU_ITEM_H__ -#define __GTK_CHECK_MENU_ITEM_H__ - - -#if !defined (__GTK_H_INSIDE__) && !defined (GTK_COMPILATION) -#error "Only can be included directly." -#endif - -#include - - -G_BEGIN_DECLS - -#define GTK_TYPE_CHECK_MENU_ITEM (gtk_check_menu_item_get_type ()) -#define GTK_CHECK_MENU_ITEM(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GTK_TYPE_CHECK_MENU_ITEM, GtkCheckMenuItem)) -#define GTK_CHECK_MENU_ITEM_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GTK_TYPE_CHECK_MENU_ITEM, GtkCheckMenuItemClass)) -#define GTK_IS_CHECK_MENU_ITEM(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GTK_TYPE_CHECK_MENU_ITEM)) -#define GTK_IS_CHECK_MENU_ITEM_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GTK_TYPE_CHECK_MENU_ITEM)) -#define GTK_CHECK_MENU_ITEM_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GTK_TYPE_CHECK_MENU_ITEM, GtkCheckMenuItemClass)) - - -typedef struct _GtkCheckMenuItem GtkCheckMenuItem; -typedef struct _GtkCheckMenuItemClass GtkCheckMenuItemClass; - -struct _GtkCheckMenuItem -{ - GtkMenuItem menu_item; -}; - -/** - * GtkCheckMenuItemClass: - * @parent_class: The parent class. - * @toggled: Signal emitted when the state of the check box is changed. - */ -struct _GtkCheckMenuItemClass -{ - GtkMenuItemClass parent_class; - - /*< public >*/ - - void (* toggled) (GtkCheckMenuItem *check_menu_item); - - /*< private >*/ - - gpointer padding[8]; -}; - - -GDK_AVAILABLE_IN_ALL -GType gtk_check_menu_item_get_type (void) G_GNUC_CONST; - -GDK_AVAILABLE_IN_ALL -GtkWidget* gtk_check_menu_item_new (void); -GDK_AVAILABLE_IN_ALL -GtkWidget* gtk_check_menu_item_new_with_label (const gchar *label); -GDK_AVAILABLE_IN_ALL -GtkWidget* gtk_check_menu_item_new_with_mnemonic (const gchar *label); -GDK_AVAILABLE_IN_ALL -void gtk_check_menu_item_set_active (GtkCheckMenuItem *check_menu_item, - gboolean is_active); -GDK_AVAILABLE_IN_ALL -gboolean gtk_check_menu_item_get_active (GtkCheckMenuItem *check_menu_item); -GDK_AVAILABLE_IN_ALL -void gtk_check_menu_item_toggled (GtkCheckMenuItem *check_menu_item); -GDK_AVAILABLE_IN_ALL -void gtk_check_menu_item_set_inconsistent (GtkCheckMenuItem *check_menu_item, - gboolean setting); -GDK_AVAILABLE_IN_ALL -gboolean gtk_check_menu_item_get_inconsistent (GtkCheckMenuItem *check_menu_item); -GDK_AVAILABLE_IN_ALL -void gtk_check_menu_item_set_draw_as_radio (GtkCheckMenuItem *check_menu_item, - gboolean draw_as_radio); -GDK_AVAILABLE_IN_ALL -gboolean gtk_check_menu_item_get_draw_as_radio (GtkCheckMenuItem *check_menu_item); - -G_END_DECLS - -#endif /* __GTK_CHECK_MENU_ITEM_H__ */ diff --git a/gtk/gtkcheckmenuitemprivate.h b/gtk/gtkcheckmenuitemprivate.h deleted file mode 100644 index 1728249ae2..0000000000 --- a/gtk/gtkcheckmenuitemprivate.h +++ /dev/null @@ -1,31 +0,0 @@ -/* GTK - The GIMP Toolkit - * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * 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, see . - */ - -#ifndef __GTK_CHECK_MENU_ITEM_PRIVATE_H__ -#define __GTK_CHECK_MENU_ITEM_PRIVATE_H__ - -#include - -G_BEGIN_DECLS - -void _gtk_check_menu_item_set_active (GtkCheckMenuItem *check_menu_item, - gboolean is_active); -GtkWidget * _gtk_check_menu_item_get_indicator_widget (GtkCheckMenuItem *check_menu_item); - -G_END_DECLS - -#endif /* __GTK_CHECK_MENU_ITEM_PRIVATE_H__ */ diff --git a/gtk/gtkcombobox.c b/gtk/gtkcombobox.c index caf9a04f3e..bbb7dba9b1 100644 --- a/gtk/gtkcombobox.c +++ b/gtk/gtkcombobox.c @@ -32,9 +32,6 @@ #include "gtkliststore.h" #include "gtkmain.h" #include "gtkmarshalers.h" -#include "gtkmenuitem.h" -#include "gtkmenuprivate.h" -#include "gtkmenushellprivate.h" #include "gtkprivate.h" #include "gtktogglebutton.h" #include "gtktreepopoverprivate.h" diff --git a/gtk/gtkentry.c b/gtk/gtkentry.c index ff6074a7df..e4e41bf535 100644 --- a/gtk/gtkentry.c +++ b/gtk/gtkentry.c @@ -55,7 +55,6 @@ #include "gtkpopover.h" #include "gtkprivate.h" #include "gtkprogressbar.h" -#include "gtkseparatormenuitem.h" #include "gtkselection.h" #include "gtksettings.h" #include "gtksnapshot.h" diff --git a/gtk/gtkfilechooserwidget.c b/gtk/gtkfilechooserwidget.c index 7ac3e20889..9e29889813 100644 --- a/gtk/gtkfilechooserwidget.c +++ b/gtk/gtkfilechooserwidget.c @@ -28,7 +28,6 @@ #include "gtkcelllayout.h" #include "gtkcellrendererpixbuf.h" #include "gtkcellrenderertext.h" -#include "gtkcheckmenuitem.h" #include "gtkcomboboxtext.h" #include "gtkcssnumbervalueprivate.h" #include "gtkdragsource.h" @@ -55,7 +54,6 @@ #include "gtkprivate.h" #include "gtkrecentmanager.h" #include "gtksearchentryprivate.h" -#include "gtkseparatormenuitem.h" #include "gtksettings.h" #include "gtksizegroup.h" #include "gtksizerequest.h" diff --git a/gtk/gtklabel.c b/gtk/gtklabel.c index 9d8c0c49d9..671f73d155 100644 --- a/gtk/gtklabel.c +++ b/gtk/gtklabel.c @@ -41,12 +41,9 @@ #include "gtkintl.h" #include "gtkmain.h" #include "gtkmarshalers.h" -#include "gtkmenuitem.h" -#include "gtkmenushellprivate.h" #include "gtknotebook.h" #include "gtkpango.h" #include "gtkprivate.h" -#include "gtkseparatormenuitem.h" #include "gtkshow.h" #include "gtksnapshot.h" #include "gtkstylecontextprivate.h" diff --git a/gtk/gtklabel.h b/gtk/gtklabel.h index 2116d79b0e..b00e8cc0ad 100644 --- a/gtk/gtklabel.h +++ b/gtk/gtklabel.h @@ -30,7 +30,6 @@ #endif #include -#include #include G_BEGIN_DECLS diff --git a/gtk/gtkmain.c b/gtk/gtkmain.c index 7d3f43bc9b..fe5868a95d 100644 --- a/gtk/gtkmain.c +++ b/gtk/gtkmain.c @@ -119,7 +119,6 @@ #include "gtkdndprivate.h" #include "gtkmain.h" #include "gtkmediafileprivate.h" -#include "gtkmenu.h" #include "gtkmodulesprivate.h" #include "gtkprivate.h" #include "gtkrecentmanager.h" diff --git a/gtk/gtkmenu.c b/gtk/gtkmenu.c deleted file mode 100644 index c95036fdd1..0000000000 --- a/gtk/gtkmenu.c +++ /dev/null @@ -1,2792 +0,0 @@ -/* GTK - The GIMP Toolkit - * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * 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, see . - */ - -/* - * Modified by the GTK+ Team and others 1997-2000. See the AUTHORS - * file for a list of people on the GTK+ Team. See the ChangeLog - * files for a list of changes. These files are distributed with - * GTK+ at ftp://ftp.gtk.org/pub/gtk/. - */ - -/** - * SECTION:gtkmenu - * @Short_description: A menu widget - * @Title: GtkMenu - * - * A #GtkMenu is a #GtkMenuShell that implements a drop down menu - * consisting of a list of #GtkMenuItem objects which can be navigated - * and activated by the user to perform application functions. - * - * A #GtkMenu is most commonly dropped down by activating a - * #GtkMenuItem in a #GtkMenuBar or popped up by activating a - * #GtkMenuItem in another #GtkMenu. - * - * A #GtkMenu can also be popped up by activating a #GtkComboBox. - * Other composite widgets such as the #GtkNotebook can pop up a - * #GtkMenu as well. - * - * Applications can display a #GtkMenu as a popup menu by calling one of the - * gtk_menu_popup_*() function. The example below shows how an application can - * pop up a menu when the 3rd mouse button is pressed. - * - * ## Connecting the popup signal handler. - * - * |[ - * // connect our handler which will popup the menu - * gesture = gtk_gesture_click_new (window); - * gtk_gesture_single_set_button (GTK_GESTURE_SINGLE (gesture), - * GDK_BUTTON_SECONDARY); - * g_signal_connect (gesture, "begin", G_CALLBACK (my_popup_handler), menu); - * ]| - * - * ## Signal handler which displays a popup menu. - * - * |[ - * static void - * my_popup_handler (GtkGesture *gesture, - * GdkEventSequence *sequence - * gpointer data) - * { - * GtkMenu *menu = data; - * const GdkEvent *event; - * - * event = gtk_gesture_get_last_event (gesture, sequence); - * gtk_menu_popup_at_pointer (menu, event); - * } - * ]| - * - * # CSS nodes - * - * |[ - * menu - * ├── - * ┊ - * ╰── - * ]| - * - * The main CSS node of GtkMenu has name menu. - */ - -#include "config.h" - -#include "gtkmenuprivate.h" - -#include "gtkaccellabel.h" -#include "gtkaccelmap.h" -#include "gtkadjustment.h" -#include "gtkbindings.h" -#include "gtkbox.h" -#include "gtkscrolledwindow.h" -#include "gtkcheckmenuitemprivate.h" -#include "gtkcssnodeprivate.h" -#include "gtkcssstylepropertyprivate.h" -#include "gtkdnd.h" -#include "gtkeventcontrollerscroll.h" -#include "gtkiconprivate.h" -#include "gtkintl.h" -#include "gtkmain.h" -#include "gtkmarshalers.h" -#include "gtkmenuitemprivate.h" -#include "gtkmenushellprivate.h" -#include "gtkprivate.h" -#include "gtkscrollbar.h" -#include "gtksettings.h" -#include "gtksnapshot.h" -#include "gtkstylecontextprivate.h" -#include "gtktypebuiltins.h" -#include "gtkwidgetpath.h" -#include "gtkwidgetprivate.h" -#include "gtkwindowgroup.h" -#include "gtkwindowprivate.h" -#include "gtkeventcontrollerkey.h" -#include "gtknative.h" - -#include "a11y/gtkmenuaccessible.h" - -#include "gdk/gdk-private.h" - -#include -#include - -#define MENU_POPUP_DELAY 225 - -#define ATTACHED_MENUS "gtk-attached-menus" - -typedef struct _GtkMenuAttachData GtkMenuAttachData; -typedef struct _GtkMenuPopdownData GtkMenuPopdownData; - -struct _GtkMenuAttachData -{ - GtkWidget *attach_widget; - GtkMenuDetachFunc detacher; -}; - -struct _GtkMenuPopdownData -{ - GtkMenu *menu; - GdkDevice *device; -}; - -enum { - MOVE_SCROLL, - POPPED_UP, - LAST_SIGNAL -}; - -enum { - PROP_0, - PROP_ACTIVE, - PROP_ACCEL_GROUP, - PROP_ACCEL_PATH, - PROP_ATTACH_WIDGET, - PROP_TEAROFF_STATE, - PROP_TEAROFF_TITLE, - PROP_MONITOR, - PROP_RESERVE_TOGGLE_SIZE, - PROP_ANCHOR_HINTS, - PROP_RECT_ANCHOR_DX, - PROP_RECT_ANCHOR_DY, - PROP_MENU_TYPE_HINT -}; - -static void gtk_menu_set_property (GObject *object, - guint prop_id, - const GValue *value, - GParamSpec *pspec); -static void gtk_menu_get_property (GObject *object, - guint prop_id, - GValue *value, - GParamSpec *pspec); -static void gtk_menu_finalize (GObject *object); -static void gtk_menu_dispose (GObject *object); -static void gtk_menu_destroy (GtkWidget *widget); -static void gtk_menu_realize (GtkWidget *widget); -static void gtk_menu_unrealize (GtkWidget *widget); -static void gtk_menu_size_allocate (GtkWidget *widget, - int widget_width, - int widget_height, - int baseline); -static void gtk_menu_show (GtkWidget *widget); -static void gtk_menu_motion (GtkEventController *controller, - double x, - double y, - gpointer user_data); -static void gtk_menu_grab_notify (GtkWidget *widget, - gboolean was_grabbed); -static void gtk_menu_scroll_item_visible (GtkMenuShell *menu_shell, - GtkWidget *menu_item); -static void gtk_menu_select_item (GtkMenuShell *menu_shell, - GtkWidget *menu_item); -static void gtk_menu_real_insert (GtkMenuShell *menu_shell, - GtkWidget *child, - gint position); -static gboolean gtk_menu_focus (GtkWidget *widget, - GtkDirectionType direction); -static gint gtk_menu_get_popup_delay (GtkMenuShell *menu_shell); -static void gtk_menu_move_current (GtkMenuShell *menu_shell, - GtkMenuDirectionType direction); -static void gtk_menu_real_move_scroll (GtkMenu *menu, - GtkScrollType type); - -static void gtk_menu_deactivate (GtkMenuShell *menu_shell); -static void gtk_menu_position (GtkMenu *menu); -static void gtk_menu_add (GtkContainer *menu, - GtkWidget *widget); -static void gtk_menu_remove (GtkContainer *menu, - GtkWidget *widget); - -static void menu_grab_transfer_surface_destroy (GtkMenu *menu); -static GdkSurface *menu_grab_transfer_surface_get (GtkMenu *menu); - -static gboolean gtk_menu_real_can_activate_accel (GtkWidget *widget, - guint signal_id); -static void _gtk_menu_refresh_accel_paths (GtkMenu *menu, - gboolean group_changed); -static void gtk_menu_measure (GtkWidget *widget, - GtkOrientation orientation, - int for_size, - int *minimum, - int *natural, - int *minimum_baseline, - int *natural_baseline); -static void gtk_menu_pressed_cb (GtkGestureClick *gesture, - int n_press, - double x, - double y, - gpointer user_data); -static void gtk_menu_released_cb (GtkGestureClick *gesture, - int n_press, - double x, - double y, - gpointer user_data); - - -static const gchar attach_data_key[] = "gtk-menu-attach-data"; - -static guint menu_signals[LAST_SIGNAL] = { 0 }; - -G_DEFINE_TYPE_WITH_PRIVATE (GtkMenu, gtk_menu, GTK_TYPE_MENU_SHELL) - -static void -update_scrollbars (GtkMenu *menu) -{ - GtkMenuPrivate *priv = menu->priv; - GtkWidget *child; - int n = 0; - GtkPolicyType policy = GTK_POLICY_NEVER; - - for (child = gtk_widget_get_first_child (priv->box); - child; - child = gtk_widget_get_next_sibling (child)) - { - n++; - if (n == 10) - { - policy = GTK_POLICY_AUTOMATIC; - break; - } - } - - gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (priv->swin), - GTK_POLICY_NEVER, - policy); -} - -static GList * -gtk_menu_get_items (GtkMenuShell *menu_shell) -{ - GtkMenuPrivate *priv = GTK_MENU (menu_shell)->priv; - - return gtk_container_get_children (GTK_CONTAINER (priv->box)); -} - -static void -gtk_menu_forall (GtkContainer *container, - GtkCallback callback, - gpointer data) -{ - GtkMenuPrivate *priv = GTK_MENU (container)->priv; - - if (priv->box) - gtk_container_forall (GTK_CONTAINER (priv->box), callback, data); -} - -static void -gtk_menu_class_init (GtkMenuClass *class) -{ - GObjectClass *gobject_class = G_OBJECT_CLASS (class); - GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (class); - GtkContainerClass *container_class = GTK_CONTAINER_CLASS (class); - GtkMenuShellClass *menu_shell_class = GTK_MENU_SHELL_CLASS (class); - GtkBindingSet *binding_set; - - gobject_class->set_property = gtk_menu_set_property; - gobject_class->get_property = gtk_menu_get_property; - gobject_class->finalize = gtk_menu_finalize; - gobject_class->dispose = gtk_menu_dispose; - - widget_class->destroy = gtk_menu_destroy; - widget_class->realize = gtk_menu_realize; - widget_class->unrealize = gtk_menu_unrealize; - widget_class->size_allocate = gtk_menu_size_allocate; - widget_class->show = gtk_menu_show; - widget_class->focus = gtk_menu_focus; - widget_class->can_activate_accel = gtk_menu_real_can_activate_accel; - widget_class->grab_notify = gtk_menu_grab_notify; - widget_class->measure = gtk_menu_measure; - - container_class->add = gtk_menu_add; - container_class->remove = gtk_menu_remove; - container_class->forall = gtk_menu_forall; - - menu_shell_class->submenu_placement = GTK_LEFT_RIGHT; - menu_shell_class->deactivate = gtk_menu_deactivate; - menu_shell_class->select_item = gtk_menu_select_item; - menu_shell_class->insert = gtk_menu_real_insert; - menu_shell_class->get_popup_delay = gtk_menu_get_popup_delay; - menu_shell_class->move_current = gtk_menu_move_current; - menu_shell_class->get_items = gtk_menu_get_items; - - /** - * GtkMenu::move-scroll: - * @menu: a #GtkMenu - * @scroll_type: a #GtkScrollType - */ - menu_signals[MOVE_SCROLL] = - g_signal_new_class_handler (I_("move-scroll"), - G_OBJECT_CLASS_TYPE (gobject_class), - G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION, - G_CALLBACK (gtk_menu_real_move_scroll), - NULL, NULL, - NULL, - G_TYPE_NONE, 1, - GTK_TYPE_SCROLL_TYPE); - - /** - * GtkMenu::popped-up: - * @menu: the #GtkMenu that popped up - * @flipped_rect: (nullable): the position of @menu after any possible - * flipping or %NULL if the backend can't obtain it - * @final_rect: (nullable): the final position of @menu or %NULL if the - * backend can't obtain it - * @flipped_x: %TRUE if the anchors were flipped horizontally - * @flipped_y: %TRUE if the anchors were flipped vertically - * - * Emitted when the position of @menu is finalized after being popped up - * using gtk_menu_popup_at_rect (), gtk_menu_popup_at_widget (), or - * gtk_menu_popup_at_pointer (). - * - * @menu might be flipped over the anchor rectangle in order to keep it - * on-screen, in which case @flipped_x and @flipped_y will be set to %TRUE - * accordingly. - * - * @flipped_rect is the ideal position of @menu after any possible flipping, - * but before any possible sliding. @final_rect is @flipped_rect, but possibly - * translated in the case that flipping is still ineffective in keeping @menu - * on-screen. - * - * ![](popup-slide.png) - * - * The blue menu is @menu's ideal position, the green menu is @flipped_rect, - * and the red menu is @final_rect. - * - * See gtk_menu_popup_at_rect (), gtk_menu_popup_at_widget (), - * gtk_menu_popup_at_pointer (), #GtkMenu:anchor-hints, - * #GtkMenu:rect-anchor-dx, #GtkMenu:rect-anchor-dy, and - * #GtkMenu:menu-type-hint. - */ - menu_signals[POPPED_UP] = - g_signal_new_class_handler (I_("popped-up"), - G_OBJECT_CLASS_TYPE (gobject_class), - G_SIGNAL_RUN_FIRST, - NULL, - NULL, - NULL, - _gtk_marshal_VOID__POINTER_POINTER_BOOLEAN_BOOLEAN, - G_TYPE_NONE, - 4, - G_TYPE_POINTER, - G_TYPE_POINTER, - G_TYPE_BOOLEAN, - G_TYPE_BOOLEAN); - - /** - * GtkMenu:active: - * - * The index of the currently selected menu item, or -1 if no - * menu item is selected. - **/ - g_object_class_install_property (gobject_class, - PROP_ACTIVE, - g_param_spec_int ("active", - P_("Active"), - P_("The currently selected menu item"), - -1, G_MAXINT, -1, - GTK_PARAM_READWRITE)); - - /** - * GtkMenu:accel-group: - * - * The accel group holding accelerators for the menu. - **/ - g_object_class_install_property (gobject_class, - PROP_ACCEL_GROUP, - g_param_spec_object ("accel-group", - P_("Accel Group"), - P_("The accel group holding accelerators for the menu"), - GTK_TYPE_ACCEL_GROUP, - GTK_PARAM_READWRITE)); - - /** - * GtkMenu:accel-path: - * - * An accel path used to conveniently construct accel paths of child items. - **/ - g_object_class_install_property (gobject_class, - PROP_ACCEL_PATH, - g_param_spec_string ("accel-path", - P_("Accel Path"), - P_("An accel path used to conveniently construct accel paths of child items"), - NULL, - GTK_PARAM_READWRITE)); - - /** - * GtkMenu:attach-widget: - * - * The widget the menu is attached to. Setting this property attaches - * the menu without a #GtkMenuDetachFunc. If you need to use a detacher, - * use gtk_menu_attach_to_widget() directly. - **/ - g_object_class_install_property (gobject_class, - PROP_ATTACH_WIDGET, - g_param_spec_object ("attach-widget", - P_("Attach Widget"), - P_("The widget the menu is attached to"), - GTK_TYPE_WIDGET, - GTK_PARAM_READWRITE)); - - /** - * GtkMenu:monitor: - * - * The monitor the menu will be popped up on. - **/ - g_object_class_install_property (gobject_class, - PROP_MONITOR, - g_param_spec_int ("monitor", - P_("Monitor"), - P_("The monitor the menu will be popped up on"), - -1, G_MAXINT, -1, - GTK_PARAM_READWRITE|G_PARAM_EXPLICIT_NOTIFY)); - - /** - * GtkMenu:reserve-toggle-size: - * - * A boolean that indicates whether the menu reserves space for - * toggles and icons, regardless of their actual presence. - * - * This property should only be changed from its default value - * for special-purposes such as tabular menus. Regular menus that - * are connected to a menu bar or context menus should reserve - * toggle space for consistency. - */ - g_object_class_install_property (gobject_class, - PROP_RESERVE_TOGGLE_SIZE, - g_param_spec_boolean ("reserve-toggle-size", - P_("Reserve Toggle Size"), - P_("A boolean that indicates whether the menu reserves space for toggles and icons"), - TRUE, - GTK_PARAM_READWRITE|G_PARAM_EXPLICIT_NOTIFY)); - - /** - * GtkMenu:anchor-hints: - * - * Positioning hints for aligning the menu relative to a rectangle. - * - * These hints determine how the menu should be positioned in the case that - * the menu would fall off-screen if placed in its ideal position. - * - * ![](popup-flip.png) - * - * For example, %GDK_ANCHOR_FLIP_Y will replace %GDK_GRAVITY_NORTH_WEST with - * %GDK_GRAVITY_SOUTH_WEST and vice versa if the menu extends beyond the - * bottom edge of the monitor. - * - * See gtk_menu_popup_at_rect (), gtk_menu_popup_at_widget (), - * gtk_menu_popup_at_pointer (), #GtkMenu:rect-anchor-dx, - * #GtkMenu:rect-anchor-dy, #GtkMenu:menu-type-hint, and #GtkMenu::popped-up. - */ - g_object_class_install_property (gobject_class, - PROP_ANCHOR_HINTS, - g_param_spec_flags ("anchor-hints", - P_("Anchor hints"), - P_("Positioning hints for when the menu might fall off-screen"), - GDK_TYPE_ANCHOR_HINTS, - GDK_ANCHOR_FLIP | - GDK_ANCHOR_SLIDE | - GDK_ANCHOR_RESIZE, - G_PARAM_READWRITE | - G_PARAM_CONSTRUCT | - G_PARAM_STATIC_NAME | - G_PARAM_STATIC_NICK | - G_PARAM_STATIC_BLURB | - G_PARAM_EXPLICIT_NOTIFY)); - - /** - * GtkMenu:rect-anchor-dx: - * - * Horizontal offset to apply to the menu, i.e. the rectangle or widget - * anchor. - * - * See gtk_menu_popup_at_rect (), gtk_menu_popup_at_widget (), - * gtk_menu_popup_at_pointer (), #GtkMenu:anchor-hints, - * #GtkMenu:rect-anchor-dy, #GtkMenu:menu-type-hint, and #GtkMenu::popped-up. - */ - g_object_class_install_property (gobject_class, - PROP_RECT_ANCHOR_DX, - g_param_spec_int ("rect-anchor-dx", - P_("Rect anchor dx"), - P_("Rect anchor horizontal offset"), - G_MININT, - G_MAXINT, - 0, - G_PARAM_READWRITE | - G_PARAM_CONSTRUCT | - G_PARAM_STATIC_NAME | - G_PARAM_STATIC_NICK | - G_PARAM_STATIC_BLURB | - G_PARAM_EXPLICIT_NOTIFY)); - - /** - * GtkMenu:rect-anchor-dy: - * - * Vertical offset to apply to the menu, i.e. the rectangle or widget anchor. - * - * See gtk_menu_popup_at_rect (), gtk_menu_popup_at_widget (), - * gtk_menu_popup_at_pointer (), #GtkMenu:anchor-hints, - * #GtkMenu:rect-anchor-dx, #GtkMenu:menu-type-hint, and #GtkMenu::popped-up. - */ - g_object_class_install_property (gobject_class, - PROP_RECT_ANCHOR_DY, - g_param_spec_int ("rect-anchor-dy", - P_("Rect anchor dy"), - P_("Rect anchor vertical offset"), - G_MININT, - G_MAXINT, - 0, - G_PARAM_READWRITE | - G_PARAM_CONSTRUCT | - G_PARAM_STATIC_NAME | - G_PARAM_STATIC_NICK | - G_PARAM_STATIC_BLURB | - G_PARAM_EXPLICIT_NOTIFY)); - - /** - * GtkMenu:menu-type-hint: - * - * The #GdkSurfaceTypeHint to use for the menu's #GdkSurface. - * - * See gtk_menu_popup_at_rect (), gtk_menu_popup_at_widget (), - * gtk_menu_popup_at_pointer (), #GtkMenu:anchor-hints, - * #GtkMenu:rect-anchor-dx, #GtkMenu:rect-anchor-dy, and #GtkMenu::popped-up. - */ - g_object_class_install_property (gobject_class, - PROP_MENU_TYPE_HINT, - g_param_spec_enum ("menu-type-hint", - P_("Menu type hint"), - P_("Menu window type hint"), - GDK_TYPE_SURFACE_TYPE_HINT, - GDK_SURFACE_TYPE_HINT_POPUP_MENU, - G_PARAM_READWRITE | - G_PARAM_CONSTRUCT | - G_PARAM_STATIC_NAME | - G_PARAM_STATIC_NICK | - G_PARAM_STATIC_BLURB | - G_PARAM_EXPLICIT_NOTIFY)); - - binding_set = gtk_binding_set_by_class (class); - gtk_binding_entry_add_signal (binding_set, - GDK_KEY_Up, 0, - I_("move-current"), 1, - GTK_TYPE_MENU_DIRECTION_TYPE, - GTK_MENU_DIR_PREV); - gtk_binding_entry_add_signal (binding_set, - GDK_KEY_KP_Up, 0, - "move-current", 1, - GTK_TYPE_MENU_DIRECTION_TYPE, - GTK_MENU_DIR_PREV); - gtk_binding_entry_add_signal (binding_set, - GDK_KEY_Down, 0, - "move-current", 1, - GTK_TYPE_MENU_DIRECTION_TYPE, - GTK_MENU_DIR_NEXT); - gtk_binding_entry_add_signal (binding_set, - GDK_KEY_KP_Down, 0, - "move-current", 1, - GTK_TYPE_MENU_DIRECTION_TYPE, - GTK_MENU_DIR_NEXT); - gtk_binding_entry_add_signal (binding_set, - GDK_KEY_Left, 0, - "move-current", 1, - GTK_TYPE_MENU_DIRECTION_TYPE, - GTK_MENU_DIR_PARENT); - gtk_binding_entry_add_signal (binding_set, - GDK_KEY_KP_Left, 0, - "move-current", 1, - GTK_TYPE_MENU_DIRECTION_TYPE, - GTK_MENU_DIR_PARENT); - gtk_binding_entry_add_signal (binding_set, - GDK_KEY_Right, 0, - "move-current", 1, - GTK_TYPE_MENU_DIRECTION_TYPE, - GTK_MENU_DIR_CHILD); - gtk_binding_entry_add_signal (binding_set, - GDK_KEY_KP_Right, 0, - "move-current", 1, - GTK_TYPE_MENU_DIRECTION_TYPE, - GTK_MENU_DIR_CHILD); - gtk_binding_entry_add_signal (binding_set, - GDK_KEY_Home, 0, - "move-scroll", 1, - GTK_TYPE_SCROLL_TYPE, - GTK_SCROLL_START); - gtk_binding_entry_add_signal (binding_set, - GDK_KEY_KP_Home, 0, - "move-scroll", 1, - GTK_TYPE_SCROLL_TYPE, - GTK_SCROLL_START); - gtk_binding_entry_add_signal (binding_set, - GDK_KEY_End, 0, - "move-scroll", 1, - GTK_TYPE_SCROLL_TYPE, - GTK_SCROLL_END); - gtk_binding_entry_add_signal (binding_set, - GDK_KEY_KP_End, 0, - "move-scroll", 1, - GTK_TYPE_SCROLL_TYPE, - GTK_SCROLL_END); - gtk_binding_entry_add_signal (binding_set, - GDK_KEY_Page_Up, 0, - "move-scroll", 1, - GTK_TYPE_SCROLL_TYPE, - GTK_SCROLL_PAGE_UP); - gtk_binding_entry_add_signal (binding_set, - GDK_KEY_KP_Page_Up, 0, - "move-scroll", 1, - GTK_TYPE_SCROLL_TYPE, - GTK_SCROLL_PAGE_UP); - gtk_binding_entry_add_signal (binding_set, - GDK_KEY_Page_Down, 0, - "move-scroll", 1, - GTK_TYPE_SCROLL_TYPE, - GTK_SCROLL_PAGE_DOWN); - gtk_binding_entry_add_signal (binding_set, - GDK_KEY_KP_Page_Down, 0, - "move-scroll", 1, - GTK_TYPE_SCROLL_TYPE, - GTK_SCROLL_PAGE_DOWN); - - gtk_widget_class_set_accessible_type (widget_class, GTK_TYPE_MENU_ACCESSIBLE); - gtk_widget_class_set_css_name (widget_class, I_("menu")); -} - - -static void -gtk_menu_set_property (GObject *object, - guint prop_id, - const GValue *value, - GParamSpec *pspec) -{ - GtkMenu *menu = GTK_MENU (object); - - switch (prop_id) - { - case PROP_ACTIVE: - gtk_menu_set_active (menu, g_value_get_int (value)); - break; - case PROP_ACCEL_GROUP: - gtk_menu_set_accel_group (menu, g_value_get_object (value)); - break; - case PROP_ACCEL_PATH: - gtk_menu_set_accel_path (menu, g_value_get_string (value)); - break; - case PROP_ATTACH_WIDGET: - { - GtkWidget *widget; - - widget = gtk_menu_get_attach_widget (menu); - if (widget) - gtk_menu_detach (menu); - - widget = (GtkWidget*) g_value_get_object (value); - if (widget) - gtk_menu_attach_to_widget (menu, widget, NULL); - } - break; - case PROP_MONITOR: - gtk_menu_set_monitor (menu, g_value_get_int (value)); - break; - case PROP_RESERVE_TOGGLE_SIZE: - gtk_menu_set_reserve_toggle_size (menu, g_value_get_boolean (value)); - break; - case PROP_ANCHOR_HINTS: - if (menu->priv->anchor_hints != g_value_get_flags (value)) - { - menu->priv->anchor_hints = g_value_get_flags (value); - g_object_notify_by_pspec (object, pspec); - } - break; - case PROP_RECT_ANCHOR_DX: - if (menu->priv->rect_anchor_dx != g_value_get_int (value)) - { - menu->priv->rect_anchor_dx = g_value_get_int (value); - g_object_notify_by_pspec (object, pspec); - } - break; - case PROP_RECT_ANCHOR_DY: - if (menu->priv->rect_anchor_dy != g_value_get_int (value)) - { - menu->priv->rect_anchor_dy = g_value_get_int (value); - g_object_notify_by_pspec (object, pspec); - } - break; - case PROP_MENU_TYPE_HINT: - if (menu->priv->menu_type_hint != g_value_get_enum (value)) - { - menu->priv->menu_type_hint = g_value_get_enum (value); - g_object_notify_by_pspec (object, pspec); - } - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; - } -} - -static void -gtk_menu_get_property (GObject *object, - guint prop_id, - GValue *value, - GParamSpec *pspec) -{ - GtkMenu *menu = GTK_MENU (object); - - switch (prop_id) - { - case PROP_ACTIVE: - { - GList *children = gtk_menu_shell_get_items (GTK_MENU_SHELL (menu)); - g_value_set_int (value, g_list_index (children, gtk_menu_get_active (menu))); - g_list_free (children); - } - break; - case PROP_ACCEL_GROUP: - g_value_set_object (value, gtk_menu_get_accel_group (menu)); - break; - case PROP_ACCEL_PATH: - g_value_set_string (value, gtk_menu_get_accel_path (menu)); - break; - case PROP_ATTACH_WIDGET: - g_value_set_object (value, gtk_menu_get_attach_widget (menu)); - break; - case PROP_MONITOR: - g_value_set_int (value, gtk_menu_get_monitor (menu)); - break; - case PROP_RESERVE_TOGGLE_SIZE: - g_value_set_boolean (value, gtk_menu_get_reserve_toggle_size (menu)); - break; - case PROP_ANCHOR_HINTS: - g_value_set_flags (value, menu->priv->anchor_hints); - break; - case PROP_RECT_ANCHOR_DX: - g_value_set_int (value, menu->priv->rect_anchor_dx); - break; - case PROP_RECT_ANCHOR_DY: - g_value_set_int (value, menu->priv->rect_anchor_dy); - break; - case PROP_MENU_TYPE_HINT: - g_value_set_enum (value, menu->priv->menu_type_hint); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; - } -} - -static void -gtk_menu_init (GtkMenu *menu) -{ - GtkMenuPrivate *priv; - GtkGesture *gesture; - GtkEventController *controller; - - priv = gtk_menu_get_instance_private (menu); - - menu->priv = priv; - - priv->toplevel = gtk_window_new (GTK_WINDOW_POPUP); - gtk_container_add (GTK_CONTAINER (priv->toplevel), GTK_WIDGET (menu)); - g_signal_connect (priv->toplevel, "destroy", G_CALLBACK (gtk_widget_destroyed), &priv->toplevel); - - gtk_window_set_resizable (GTK_WINDOW (priv->toplevel), FALSE); - gtk_window_set_mnemonic_modifier (GTK_WINDOW (priv->toplevel), 0); - - _gtk_window_request_csd (GTK_WINDOW (priv->toplevel)); - gtk_style_context_add_class (gtk_widget_get_style_context (priv->toplevel), - GTK_STYLE_CLASS_POPUP); - - /* Refloat the menu, so that reference counting for the menu isn't - * affected by it being a child of the toplevel - */ - g_object_force_floating (G_OBJECT (menu)); - priv->needs_destruction_ref = TRUE; - - priv->swin = gtk_scrolled_window_new (NULL, NULL); - gtk_widget_set_parent (priv->swin, GTK_WIDGET (menu)); - gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (priv->swin), - GTK_POLICY_NEVER, - GTK_POLICY_NEVER); - gtk_scrolled_window_set_propagate_natural_width (GTK_SCROLLED_WINDOW (priv->swin), - TRUE); - gtk_scrolled_window_set_propagate_natural_height (GTK_SCROLLED_WINDOW (priv->swin), - TRUE); - - priv->box = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0); - gtk_container_add (GTK_CONTAINER (priv->swin), priv->box); - - priv->monitor_num = -1; - - priv->anchor_hints = GDK_ANCHOR_FLIP | GDK_ANCHOR_SLIDE | GDK_ANCHOR_RESIZE; - priv->rect_anchor_dx = 0; - priv->rect_anchor_dy = 0; - priv->menu_type_hint = GDK_SURFACE_TYPE_HINT_POPUP_MENU; - - gesture = gtk_gesture_click_new (); - gtk_gesture_single_set_touch_only (GTK_GESTURE_SINGLE (gesture), FALSE); - gtk_gesture_single_set_button (GTK_GESTURE_SINGLE (gesture), 0); - gtk_event_controller_set_propagation_phase (GTK_EVENT_CONTROLLER (gesture), GTK_PHASE_BUBBLE); - g_signal_connect (gesture, "pressed", G_CALLBACK (gtk_menu_pressed_cb), menu); - g_signal_connect (gesture, "released", G_CALLBACK (gtk_menu_released_cb), menu); - gtk_widget_add_controller (GTK_WIDGET (menu), GTK_EVENT_CONTROLLER (gesture)); - - controller = gtk_event_controller_motion_new (); - g_signal_connect (controller, "motion", G_CALLBACK (gtk_menu_motion), menu); - gtk_widget_add_controller (GTK_WIDGET (menu), controller); -} - -static void -moved_to_rect_cb (GdkSurface *surface, - const GdkRectangle *flipped_rect, - const GdkRectangle *final_rect, - gboolean flipped_x, - gboolean flipped_y, - GtkMenu *menu) -{ - g_signal_emit (menu, - menu_signals[POPPED_UP], - 0, - flipped_rect, - final_rect, - flipped_x, - flipped_y); -} - -static void -gtk_menu_destroy (GtkWidget *widget) -{ - GtkMenu *menu = GTK_MENU (widget); - GtkMenuPrivate *priv = menu->priv; - GtkMenuAttachData *data; - - data = g_object_get_data (G_OBJECT (widget), attach_data_key); - if (data) - gtk_menu_detach (menu); - - g_clear_object (&priv->old_active_menu_item); - - /* Add back the reference count for being a child */ - if (priv->needs_destruction_ref) - { - priv->needs_destruction_ref = FALSE; - g_object_ref (widget); - } - - g_clear_object (&priv->accel_group); - - if (priv->toplevel) - { - g_signal_handlers_disconnect_by_func (priv->toplevel, moved_to_rect_cb, menu); - gtk_widget_destroy (priv->toplevel); - } - - GTK_WIDGET_CLASS (gtk_menu_parent_class)->destroy (widget); -} - -static void -gtk_menu_finalize (GObject *object) -{ - G_OBJECT_CLASS (gtk_menu_parent_class)->finalize (object); -} - -static void -gtk_menu_dispose (GObject *object) -{ - GtkMenu *menu = GTK_MENU (object); - GtkMenuPrivate *priv = menu->priv; - - g_clear_pointer (&priv->swin, gtk_widget_unparent); - priv->box = NULL; - - G_OBJECT_CLASS (gtk_menu_parent_class)->dispose (object); -} - -static void -menu_change_display (GtkMenu *menu, - GdkDisplay *new_display) -{ - GtkMenuPrivate *priv = menu->priv; - - if (new_display == gtk_widget_get_display (GTK_WIDGET (menu))) - return; - - gtk_window_set_display (GTK_WINDOW (priv->toplevel), new_display); - priv->monitor_num = -1; -} - -static void -attach_widget_root_changed (GObject *attach_widget, - GParamSpec *pspec, - gpointer menu) -{ - if (!g_object_get_data (G_OBJECT (menu), "gtk-menu-explicit-display")) - menu_change_display (menu, gtk_widget_get_display (GTK_WIDGET (attach_widget))); -} - -static void -menu_toplevel_attached_to (GtkWindow *toplevel, GParamSpec *pspec, GtkMenu *menu) -{ - GtkMenuAttachData *data; - - data = g_object_get_data (G_OBJECT (menu), attach_data_key); - - g_return_if_fail (data); - - gtk_menu_detach (menu); -} - -/** - * gtk_menu_attach_to_widget: - * @menu: a #GtkMenu - * @attach_widget: the #GtkWidget that the menu will be attached to - * @detacher: (scope async)(allow-none): the user supplied callback function - * that will be called when the menu calls gtk_menu_detach() - * - * Attaches the menu to the widget and provides a callback function - * that will be invoked when the menu calls gtk_menu_detach() during - * its destruction. - * - * If the menu is attached to the widget then it will be destroyed - * when the widget is destroyed, as if it was a child widget. - * An attached menu will also move between screens correctly if the - * widgets moves between screens. - */ -void -gtk_menu_attach_to_widget (GtkMenu *menu, - GtkWidget *attach_widget, - GtkMenuDetachFunc detacher) -{ - GtkMenuAttachData *data; - GList *list; - - g_return_if_fail (GTK_IS_MENU (menu)); - g_return_if_fail (GTK_IS_WIDGET (attach_widget)); - - /* keep this function in sync with gtk_widget_set_parent() */ - data = g_object_get_data (G_OBJECT (menu), attach_data_key); - if (data) - { - g_warning ("gtk_menu_attach_to_widget(): menu already attached to %s", - g_type_name (G_TYPE_FROM_INSTANCE (data->attach_widget))); - return; - } - - g_object_ref_sink (menu); - - data = g_slice_new (GtkMenuAttachData); - data->attach_widget = attach_widget; - - g_signal_connect (attach_widget, "notify::root", - G_CALLBACK (attach_widget_root_changed), menu); - attach_widget_root_changed (G_OBJECT (attach_widget), NULL, menu); - - data->detacher = detacher; - g_object_set_data (G_OBJECT (menu), I_(attach_data_key), data); - list = g_object_steal_data (G_OBJECT (attach_widget), ATTACHED_MENUS); - if (!g_list_find (list, menu)) - list = g_list_prepend (list, menu); - - g_object_set_data_full (G_OBJECT (attach_widget), I_(ATTACHED_MENUS), list, - (GDestroyNotify) g_list_free); - - /* Attach the widget to the toplevel window. */ - gtk_window_set_attached_to (GTK_WINDOW (menu->priv->toplevel), attach_widget); - g_signal_connect (GTK_WINDOW (menu->priv->toplevel), "notify::attached-to", - G_CALLBACK (menu_toplevel_attached_to), menu); - - _gtk_widget_update_parent_muxer (GTK_WIDGET (menu)); - - g_object_notify (G_OBJECT (menu), "attach-widget"); -} - -/** - * gtk_menu_get_attach_widget: - * @menu: a #GtkMenu - * - * Returns the #GtkWidget that the menu is attached to. - * - * Returns: (transfer none): the #GtkWidget that the menu is attached to - */ -GtkWidget* -gtk_menu_get_attach_widget (GtkMenu *menu) -{ - GtkMenuAttachData *data; - - g_return_val_if_fail (GTK_IS_MENU (menu), NULL); - - data = g_object_get_data (G_OBJECT (menu), attach_data_key); - if (data) - return data->attach_widget; - return NULL; -} - -/** - * gtk_menu_detach: - * @menu: a #GtkMenu - * - * Detaches the menu from the widget to which it had been attached. - * This function will call the callback function, @detacher, provided - * when the gtk_menu_attach_to_widget() function was called. - */ -void -gtk_menu_detach (GtkMenu *menu) -{ - GtkWindow *toplevel; - GtkMenuAttachData *data; - GList *list; - - g_return_if_fail (GTK_IS_MENU (menu)); - toplevel = GTK_WINDOW (menu->priv->toplevel); - - /* keep this function in sync with gtk_widget_unparent() */ - data = g_object_get_data (G_OBJECT (menu), attach_data_key); - if (!data) - { - g_warning ("gtk_menu_detach(): menu is not attached"); - return; - } - g_object_set_data (G_OBJECT (menu), I_(attach_data_key), NULL); - - /* Detach the toplevel window. */ - if (toplevel) - { - g_signal_handlers_disconnect_by_func (toplevel, - (gpointer) menu_toplevel_attached_to, - menu); - if (gtk_window_get_attached_to (toplevel) == data->attach_widget) - gtk_window_set_attached_to (toplevel, NULL); - } - - g_signal_handlers_disconnect_by_func (data->attach_widget, - (gpointer) attach_widget_root_changed, - menu); - - if (data->detacher) - data->detacher (data->attach_widget, menu); - list = g_object_steal_data (G_OBJECT (data->attach_widget), ATTACHED_MENUS); - list = g_list_remove (list, menu); - if (list) - g_object_set_data_full (G_OBJECT (data->attach_widget), I_(ATTACHED_MENUS), list, - (GDestroyNotify) g_list_free); - else - g_object_set_data (G_OBJECT (data->attach_widget), I_(ATTACHED_MENUS), NULL); - - if (gtk_widget_get_realized (GTK_WIDGET (menu))) - gtk_widget_unrealize (GTK_WIDGET (menu)); - - g_slice_free (GtkMenuAttachData, data); - - _gtk_widget_update_parent_muxer (GTK_WIDGET (menu)); - - g_object_notify (G_OBJECT (menu), "attach-widget"); - g_object_unref (menu); -} - -static void -gtk_menu_add (GtkContainer *container, - GtkWidget *widget) -{ - GtkMenu *menu = GTK_MENU (container); - GtkMenuPrivate *priv = menu->priv; - - gtk_container_add (GTK_CONTAINER (priv->box), widget); - - update_scrollbars (menu); -} - -static void -gtk_menu_remove (GtkContainer *container, - GtkWidget *widget) -{ - GtkMenu *menu = GTK_MENU (container); - GtkMenuPrivate *priv = menu->priv; - - /* Clear out old_active_menu_item if it matches the item we are removing */ - if (priv->old_active_menu_item == widget) - g_clear_object (&priv->old_active_menu_item); - - gtk_container_remove (GTK_CONTAINER (priv->box), widget); - - GTK_CONTAINER_CLASS (gtk_menu_parent_class)->remove (container, widget); - - update_scrollbars (menu); -} - -/** - * gtk_menu_new: - * - * Creates a new #GtkMenu - * - * Returns: a new #GtkMenu - */ -GtkWidget* -gtk_menu_new (void) -{ - return g_object_new (GTK_TYPE_MENU, NULL); -} - -static void -gtk_menu_real_insert (GtkMenuShell *menu_shell, - GtkWidget *child, - gint position) -{ - GtkMenu *menu = GTK_MENU (menu_shell); - GtkMenuPrivate *priv = menu->priv; - - gtk_container_add (GTK_CONTAINER (priv->box), child); - gtk_menu_reorder_child (menu, child, position); - - update_scrollbars (menu); -} - -static gboolean -popup_grab_on_surface (GdkSurface *surface, - GdkDevice *pointer) -{ - GdkGrabStatus status; - GdkSeat *seat; - - g_return_val_if_fail (gdk_surface_get_display (surface) == gdk_device_get_display (pointer), FALSE); - - seat = gdk_device_get_seat (pointer); - status = gdk_seat_grab (seat, surface, - GDK_SEAT_CAPABILITY_ALL, TRUE, - NULL, NULL, NULL, NULL); - - return status == GDK_GRAB_SUCCESS; -} - -static void -associate_menu_grab_transfer_surface (GtkMenu *menu) -{ - GtkMenuPrivate *priv = menu->priv; - GdkSurface *toplevel_surface; - GdkSurface *transfer_surface; - - toplevel_surface = gtk_native_get_surface (GTK_NATIVE (priv->toplevel)); - transfer_surface = g_object_get_data (G_OBJECT (menu), "gtk-menu-transfer-surface"); - - if (toplevel_surface == NULL || transfer_surface == NULL) - return; - - g_object_set_data (G_OBJECT (toplevel_surface), I_("gdk-attached-grab-surface"), transfer_surface); -} - -static void -gtk_menu_popup_internal (GtkMenu *menu, - GdkDevice *device, - GtkWidget *parent_menu_shell, - GtkWidget *parent_menu_item, - guint button, - guint32 activate_time) -{ - GtkMenuPrivate *priv = menu->priv; - GtkWidget *widget; - GtkWidget *xgrab_shell; - GtkWidget *parent; - GdkEvent *current_event; - GtkMenuShell *menu_shell; - gboolean grab_keyboard; - GtkWidget *parent_toplevel; - GdkDevice *pointer, *source_device = NULL; - GdkDisplay *display; - - g_return_if_fail (GTK_IS_MENU (menu)); - g_return_if_fail (device == NULL || GDK_IS_DEVICE (device)); - - display = gtk_widget_get_display (GTK_WIDGET (menu)); - - if (device == NULL) - device = gtk_get_current_event_device (); - - if (device && gdk_device_get_display (device) != display) - device = NULL; - - if (device == NULL) - { - device = gdk_seat_get_pointer (gdk_display_get_default_seat (display)); - g_return_if_fail (gdk_device_get_display (device) == display); - } - - - widget = GTK_WIDGET (menu); - menu_shell = GTK_MENU_SHELL (menu); - - if (gdk_device_get_source (device) == GDK_SOURCE_KEYBOARD) - pointer = gdk_device_get_associated_device (device); - else - pointer = device; - - g_return_if_fail (gdk_device_get_display (pointer) == display); - - menu_shell->priv->parent_menu_shell = parent_menu_shell; - - /* Find the last viewable ancestor, and make an X grab on it - */ - parent = GTK_WIDGET (menu); - xgrab_shell = NULL; - while (parent) - { - gboolean viewable = TRUE; - GtkWidget *tmp = parent; - - while (tmp) - { - if (!gtk_widget_get_mapped (tmp)) - { - viewable = FALSE; - break; - } - tmp = gtk_widget_get_parent (tmp); - } - - if (viewable) - xgrab_shell = parent; - - parent = GTK_MENU_SHELL (parent)->priv->parent_menu_shell; - } - - /* We want to receive events generated when we map the menu; - * unfortunately, since there is probably already an implicit - * grab in place from the button that the user used to pop up - * the menu, we won't receive then -- in particular, the EnterNotify - * when the menu pops up under the pointer. - * - * If we are grabbing on a parent menu shell, no problem; just grab - * on that menu shell first before popping up the window with - * owner_events = TRUE. - * - * When grabbing on the menu itself, things get more convoluted -- - * we do an explicit grab on a specially created window with - * owner_events = TRUE, which we override further down with a - * grab on the menu. (We can't grab on the menu until it is mapped; - * we probably could just leave the grab on the other window, - * with a little reorganization of the code in gtkmenu*). - */ - grab_keyboard = gtk_menu_shell_get_take_focus (menu_shell); - gtk_window_set_accept_focus (GTK_WINDOW (priv->toplevel), grab_keyboard); - - if (xgrab_shell && xgrab_shell != widget) - { - if (popup_grab_on_surface (gtk_native_get_surface (gtk_widget_get_native (xgrab_shell)), pointer)) - { - _gtk_menu_shell_set_grab_device (GTK_MENU_SHELL (xgrab_shell), pointer); - GTK_MENU_SHELL (xgrab_shell)->priv->have_xgrab = TRUE; - } - } - else - { - GdkSurface *transfer_surface; - - xgrab_shell = widget; - transfer_surface = menu_grab_transfer_surface_get (menu); - if (popup_grab_on_surface (transfer_surface, pointer)) - { - _gtk_menu_shell_set_grab_device (GTK_MENU_SHELL (xgrab_shell), pointer); - GTK_MENU_SHELL (xgrab_shell)->priv->have_xgrab = TRUE; - } - } - - if (!GTK_MENU_SHELL (xgrab_shell)->priv->have_xgrab) - { - /* We failed to make our pointer/keyboard grab. - * Rather than leaving the user with a stuck up window, - * we just abort here. Presumably the user will try again. - */ - menu_shell->priv->parent_menu_shell = NULL; - menu_grab_transfer_surface_destroy (menu); - return; - } - - _gtk_menu_shell_set_grab_device (GTK_MENU_SHELL (menu), pointer); - menu_shell->priv->active = TRUE; - menu_shell->priv->button = button; - - /* If we are popping up the menu from something other than, a button - * press then, as a heuristic, we ignore enter events for the menu - * until we get a MOTION_NOTIFY. - */ - - current_event = gtk_get_current_event (); - if (current_event) - { - GdkEventType event_type = gdk_event_get_event_type (current_event); - - if ((event_type != GDK_BUTTON_PRESS) && - (event_type != GDK_ENTER_NOTIFY)) - menu_shell->priv->ignore_enter = TRUE; - - source_device = gdk_event_get_source_device (current_event); - g_object_unref (current_event); - } - else - menu_shell->priv->ignore_enter = TRUE; - - parent_toplevel = NULL; - if (parent_menu_shell) - parent_toplevel = GTK_WIDGET (gtk_widget_get_root (parent_menu_shell)); - else - { - GtkWidget *attach_widget = gtk_menu_get_attach_widget (menu); - if (attach_widget) - parent_toplevel = GTK_WIDGET (gtk_widget_get_root (attach_widget)); - } - - /* Set transient for to get the right window group and parent */ - if (GTK_IS_WINDOW (parent_toplevel)) - gtk_window_set_transient_for (GTK_WINDOW (priv->toplevel), - GTK_WINDOW (parent_toplevel)); - - priv->parent_menu_item = parent_menu_item; - menu_shell->priv->activate_time = activate_time; - - /* We need to show the menu here rather in the init function - * because code expects to be able to tell if the menu is onscreen - * by looking at gtk_widget_get_visible (menu) - */ - gtk_widget_show (GTK_WIDGET (menu)); - - gtk_menu_position (menu); - - associate_menu_grab_transfer_surface (menu); - - /* if no item is selected, select the first one */ - if (!menu_shell->priv->active_menu_item && - source_device && gdk_device_get_source (source_device) == GDK_SOURCE_TOUCHSCREEN) - gtk_menu_shell_select_first (menu_shell, TRUE); - - /* Once everything is set up correctly, map the toplevel */ - gtk_widget_show (priv->toplevel); - - if (xgrab_shell == widget) - popup_grab_on_surface (gtk_native_get_surface (gtk_widget_get_native (widget)), pointer); /* Should always succeed */ - - gtk_grab_add (GTK_WIDGET (menu)); - - if (parent_menu_shell) - { - gboolean keyboard_mode; - - keyboard_mode = _gtk_menu_shell_get_keyboard_mode (GTK_MENU_SHELL (parent_menu_shell)); - _gtk_menu_shell_set_keyboard_mode (menu_shell, keyboard_mode); - } - else if (menu_shell->priv->button == 0) /* a keynav-activated context menu */ - _gtk_menu_shell_set_keyboard_mode (menu_shell, TRUE); - - _gtk_menu_shell_update_mnemonics (menu_shell); -} - -static GdkDevice * -get_device_for_event (const GdkEvent *event) -{ - GdkDevice *device = NULL; - GdkSeat *seat = NULL; - GdkDisplay *display = NULL; - - device = gdk_event_get_device (event); - - if (device) - return device; - - seat = gdk_event_get_seat (event); - - if (!seat) - { - display = gdk_event_get_display (event); - - if (!display) - { - g_warning ("no display for event, using default"); - display = gdk_display_get_default (); - } - - if (display) - seat = gdk_display_get_default_seat (display); - } - - return seat ? gdk_seat_get_pointer (seat) : NULL; -} - -/** - * gtk_menu_popup_at_rect: - * @menu: the #GtkMenu to pop up - * @rect_surface: (not nullable): the #GdkSurface @rect is relative to - * @rect: (not nullable): the #GdkRectangle to align @menu with - * @rect_anchor: the point on @rect to align with @menu's anchor point - * @menu_anchor: the point on @menu to align with @rect's anchor point - * @trigger_event: (nullable): the #GdkEvent that initiated this request or - * %NULL if it's the current event - * - * Displays @menu and makes it available for selection. - * - * See gtk_menu_popup_at_widget () and gtk_menu_popup_at_pointer (), which - * handle more common cases for popping up menus. - * - * @menu will be positioned at @rect, aligning their anchor points. @rect is - * relative to the top-left corner of @rect_surface. @rect_anchor and - * @menu_anchor determine anchor points on @rect and @menu to pin together. - * @menu can optionally be offset by #GtkMenu:rect-anchor-dx and - * #GtkMenu:rect-anchor-dy. - * - * Anchors should be specified under the assumption that the text direction is - * left-to-right; they will be flipped horizontally automatically if the text - * direction is right-to-left. - * - * Other properties that influence the behaviour of this function are - * #GtkMenu:anchor-hints and #GtkMenu:menu-type-hint. Connect to the - * #GtkMenu::popped-up signal to find out how it was actually positioned. - */ -void -gtk_menu_popup_at_rect (GtkMenu *menu, - GdkSurface *rect_surface, - const GdkRectangle *rect, - GdkGravity rect_anchor, - GdkGravity menu_anchor, - const GdkEvent *trigger_event) -{ - GtkMenuPrivate *priv; - GdkEvent *current_event = NULL; - GdkDevice *device = NULL; - guint button = 0; - guint32 activate_time = GDK_CURRENT_TIME; - - g_return_if_fail (GTK_IS_MENU (menu)); - g_return_if_fail (GDK_IS_SURFACE (rect_surface)); - g_return_if_fail (rect); - - priv = menu->priv; - priv->rect_surface = rect_surface; - priv->rect = *rect; - priv->widget = NULL; - priv->rect_anchor = rect_anchor; - priv->menu_anchor = menu_anchor; - - if (!trigger_event) - { - current_event = gtk_get_current_event (); - trigger_event = current_event; - } - - if (trigger_event) - { - device = get_device_for_event (trigger_event); - gdk_event_get_button (trigger_event, &button); - activate_time = gdk_event_get_time (trigger_event); - } - else - g_warning ("no trigger event for menu popup"); - - gtk_menu_popup_internal (menu, - device, - NULL, - NULL, - button, - activate_time); - - g_clear_object (¤t_event); -} - -/** - * gtk_menu_popup_at_widget: - * @menu: the #GtkMenu to pop up - * @widget: (not nullable): the #GtkWidget to align @menu with - * @widget_anchor: the point on @widget to align with @menu's anchor point - * @menu_anchor: the point on @menu to align with @widget's anchor point - * @trigger_event: (nullable): the #GdkEvent that initiated this request or - * %NULL if it's the current event - * - * Displays @menu and makes it available for selection. - * - * See gtk_menu_popup_at_pointer () to pop up a menu at the master pointer. - * gtk_menu_popup_at_rect () also allows you to position a menu at an arbitrary - * rectangle. - * - * ![](popup-anchors.png) - * - * @menu will be positioned at @widget, aligning their anchor points. - * @widget_anchor and @menu_anchor determine anchor points on @widget and @menu - * to pin together. @menu can optionally be offset by #GtkMenu:rect-anchor-dx - * and #GtkMenu:rect-anchor-dy. - * - * Anchors should be specified under the assumption that the text direction is - * left-to-right; they will be flipped horizontally automatically if the text - * direction is right-to-left. - * - * Other properties that influence the behaviour of this function are - * #GtkMenu:anchor-hints and #GtkMenu:menu-type-hint. Connect to the - * #GtkMenu::popped-up signal to find out how it was actually positioned. - */ -void -gtk_menu_popup_at_widget (GtkMenu *menu, - GtkWidget *widget, - GdkGravity widget_anchor, - GdkGravity menu_anchor, - const GdkEvent *trigger_event) -{ - GtkMenuPrivate *priv; - GdkEvent *current_event = NULL; - GdkDevice *device = NULL; - guint button = 0; - guint32 activate_time = GDK_CURRENT_TIME; - GtkWidget *parent_menu_shell = NULL; - GtkWidget *parent_menu_item = NULL; - - g_return_if_fail (GTK_IS_MENU (menu)); - g_return_if_fail (GTK_IS_WIDGET (widget)); - - priv = menu->priv; - priv->rect_surface = NULL; - priv->widget = widget; - priv->rect_anchor = widget_anchor; - priv->menu_anchor = menu_anchor; - - if (!trigger_event) - { - current_event = gtk_get_current_event (); - trigger_event = current_event; - } - - if (trigger_event) - { - device = get_device_for_event (trigger_event); - gdk_event_get_button (trigger_event, &button); - activate_time = gdk_event_get_time (trigger_event); - } - else - g_warning ("no trigger event for menu popup"); - - if (GTK_IS_MENU_ITEM (priv->widget)) - { - parent_menu_item = priv->widget; - parent_menu_shell = GTK_WIDGET (gtk_menu_item_get_menu_shell (GTK_MENU_ITEM (parent_menu_item))); - } - - gtk_menu_popup_internal (menu, - device, - parent_menu_shell, - parent_menu_item, - button, - activate_time); - - g_clear_object (¤t_event); -} - -/** - * gtk_menu_popup_at_pointer: - * @menu: the #GtkMenu to pop up - * @trigger_event: (nullable): the #GdkEvent that initiated this request or - * %NULL if it's the current event - * - * Displays @menu and makes it available for selection. - * - * See gtk_menu_popup_at_widget () to pop up a menu at a widget. - * gtk_menu_popup_at_rect () also allows you to position a menu at an arbitrary - * rectangle. - * - * @menu will be positioned at the pointer associated with @trigger_event. - * - * Properties that influence the behaviour of this function are - * #GtkMenu:anchor-hints, #GtkMenu:rect-anchor-dx, #GtkMenu:rect-anchor-dy, and - * #GtkMenu:menu-type-hint. Connect to the #GtkMenu::popped-up signal to find - * out how it was actually positioned. - */ -void -gtk_menu_popup_at_pointer (GtkMenu *menu, - const GdkEvent *trigger_event) -{ - GdkEvent *current_event = NULL; - GdkSurface *rect_surface = NULL; - GdkDevice *device = NULL; - GdkRectangle rect = { 0, 0, 1, 1 }; - - g_return_if_fail (GTK_IS_MENU (menu)); - - if (!trigger_event) - { - current_event = gtk_get_current_event (); - trigger_event = current_event; - } - - if (trigger_event) - { - rect_surface = gdk_event_get_surface (trigger_event); - - if (rect_surface) - { - device = get_device_for_event (trigger_event); - - if (device && gdk_device_get_source (device) == GDK_SOURCE_KEYBOARD) - device = gdk_device_get_associated_device (device); - - if (device) - { - double px, py; - gdk_surface_get_device_position (rect_surface, device, &px, &py, NULL); - rect.x = round (px); - rect.y = round (py); - } - } - } - else - g_warning ("no trigger event for menu popup"); - - gtk_menu_popup_at_rect (menu, - rect_surface, - &rect, - GDK_GRAVITY_SOUTH_EAST, - GDK_GRAVITY_NORTH_WEST, - trigger_event); - - g_clear_object (¤t_event); -} - -/** - * gtk_menu_update_scroll_offset: - * @menu: the #GtkMenu that popped up - * @flipped_rect: (nullable): the position of @menu after any possible flipping - * or %NULL if unknown - * @final_rect: (nullable): the final position of @menu or %NULL if unknown - * @flipped_x: %TRUE if the anchors were flipped horizontally - * @flipped_y: %TRUE if the anchors were flipped vertically - * @user_data: user data - * - * Updates the scroll offset of @menu based on the amount of sliding done while - * positioning @menu. Connect this to the #GtkMenu::popped-up signal to keep the - * contents of the menu vertically aligned with their ideal position, for combo - * boxes for example. - */ -void -gtk_menu_update_scroll_offset (GtkMenu *menu, - const GdkRectangle *flipped_rect, - const GdkRectangle *final_rect, - gboolean flipped_x, - gboolean flipped_y, - gpointer user_data) -{ -} - -/** - * gtk_menu_popdown: - * @menu: a #GtkMenu - * - * Removes the menu from the screen. - */ -void -gtk_menu_popdown (GtkMenu *menu) -{ - GtkMenuPrivate *priv; - GtkMenuShell *menu_shell; - - g_return_if_fail (GTK_IS_MENU (menu)); - - menu_shell = GTK_MENU_SHELL (menu); - priv = menu->priv; - - menu_shell->priv->parent_menu_shell = NULL; - menu_shell->priv->active = FALSE; - menu_shell->priv->ignore_enter = FALSE; - - if (menu_shell->priv->active_menu_item) - { - if (priv->old_active_menu_item) - g_object_unref (priv->old_active_menu_item); - priv->old_active_menu_item = menu_shell->priv->active_menu_item; - g_object_ref (priv->old_active_menu_item); - } - - gtk_menu_shell_deselect (menu_shell); - - /* The X Grab, if present, will automatically be removed - * when we hide the window - */ - if (priv->toplevel) - { - gtk_widget_hide (priv->toplevel); - gtk_window_set_transient_for (GTK_WINDOW (priv->toplevel), NULL); - } - - gtk_widget_hide (GTK_WIDGET (menu)); - - menu_shell->priv->have_xgrab = FALSE; - - gtk_grab_remove (GTK_WIDGET (menu)); - - _gtk_menu_shell_set_grab_device (menu_shell, NULL); - - menu_grab_transfer_surface_destroy (menu); -} - -/** - * gtk_menu_get_active: - * @menu: a #GtkMenu - * - * Returns the selected menu item from the menu. This is used by the - * #GtkComboBox. - * - * Returns: (transfer none): the #GtkMenuItem that was last selected - * in the menu. If a selection has not yet been made, the - * first menu item is selected. - */ -GtkWidget* -gtk_menu_get_active (GtkMenu *menu) -{ - GtkMenuPrivate *priv; - GtkWidget *child = NULL; - GList *children, *l; - - g_return_val_if_fail (GTK_IS_MENU (menu), NULL); - - priv = menu->priv; - - if (!priv->old_active_menu_item) - { - children = gtk_menu_shell_get_items (GTK_MENU_SHELL (menu)); - for (l = children; l; l = l->next) - { - child = l->data; - - if (gtk_bin_get_child (GTK_BIN (child))) - break; - child = NULL; - } - g_list_free (children); - - priv->old_active_menu_item = child; - if (priv->old_active_menu_item) - g_object_ref (priv->old_active_menu_item); - } - - return priv->old_active_menu_item; -} - -/** - * gtk_menu_set_active: - * @menu: a #GtkMenu - * @index: the index of the menu item to select. Index values are - * from 0 to n-1 - * - * Selects the specified menu item within the menu. This is used by - * the #GtkComboBox and should not be used by anyone else. - */ -void -gtk_menu_set_active (GtkMenu *menu, - guint index) -{ - GtkMenuPrivate *priv; - GtkWidget *child; - GList *children; - GList *tmp_list; - - g_return_if_fail (GTK_IS_MENU (menu)); - - priv = menu->priv; - - children = gtk_menu_shell_get_items (GTK_MENU_SHELL (menu)); - tmp_list = g_list_nth (children, index); - if (tmp_list) - { - child = tmp_list->data; - if (gtk_bin_get_child (GTK_BIN (child))) - { - if (priv->old_active_menu_item) - g_object_unref (priv->old_active_menu_item); - priv->old_active_menu_item = child; - g_object_ref (priv->old_active_menu_item); - } - } - g_object_notify (G_OBJECT (menu), "active"); - g_list_free (children); -} - -/** - * gtk_menu_set_accel_group: - * @menu: a #GtkMenu - * @accel_group: (allow-none): the #GtkAccelGroup to be associated - * with the menu. - * - * Set the #GtkAccelGroup which holds global accelerators for the - * menu. This accelerator group needs to also be added to all windows - * that this menu is being used in with gtk_window_add_accel_group(), - * in order for those windows to support all the accelerators - * contained in this group. - */ -void -gtk_menu_set_accel_group (GtkMenu *menu, - GtkAccelGroup *accel_group) -{ - GtkMenuPrivate *priv; - - g_return_if_fail (GTK_IS_MENU (menu)); - g_return_if_fail (GTK_IS_ACCEL_GROUP (accel_group)); - - priv = menu->priv; - - if (priv->accel_group != accel_group) - { - if (priv->accel_group) - g_object_unref (priv->accel_group); - priv->accel_group = accel_group; - if (priv->accel_group) - g_object_ref (priv->accel_group); - _gtk_menu_refresh_accel_paths (menu, TRUE); - } -} - -/** - * gtk_menu_get_accel_group: - * @menu: a #GtkMenu - * - * Gets the #GtkAccelGroup which holds global accelerators for the - * menu. See gtk_menu_set_accel_group(). - * - * Returns: (transfer none): the #GtkAccelGroup associated with the menu - */ -GtkAccelGroup* -gtk_menu_get_accel_group (GtkMenu *menu) -{ - g_return_val_if_fail (GTK_IS_MENU (menu), NULL); - - return menu->priv->accel_group; -} - -static gboolean -gtk_menu_real_can_activate_accel (GtkWidget *widget, - guint signal_id) -{ - /* Menu items chain here to figure whether they can activate their - * accelerators. Unlike ordinary widgets, menus allow accel - * activation even if invisible since that's the usual case for - * submenus/popup-menus. however, the state of the attach widget - * affects the "activeness" of the menu. - */ - GtkWidget *awidget = gtk_menu_get_attach_widget (GTK_MENU (widget)); - - if (awidget) - return gtk_widget_can_activate_accel (awidget, signal_id); - else - return gtk_widget_is_sensitive (widget); -} - -/** - * gtk_menu_set_accel_path: - * @menu: a valid #GtkMenu - * @accel_path: (nullable): a valid accelerator path, or %NULL to unset the path - * - * Sets an accelerator path for this menu from which accelerator paths - * for its immediate children, its menu items, can be constructed. - * The main purpose of this function is to spare the programmer the - * inconvenience of having to call gtk_menu_item_set_accel_path() on - * each menu item that should support runtime user changable accelerators. - * Instead, by just calling gtk_menu_set_accel_path() on their parent, - * each menu item of this menu, that contains a label describing its - * purpose, automatically gets an accel path assigned. - * - * For example, a menu containing menu items “New” and “Exit”, will, after - * `gtk_menu_set_accel_path (menu, "/File");` has been - * called, assign its items the accel paths: `"/File/New"` - * and `"/File/Exit"`. - * - * Assigning accel paths to menu items then enables the user to change - * their accelerators at runtime. More details about accelerator paths - * and their default setups can be found at gtk_accel_map_add_entry(). - * - * Note that @accel_path string will be stored in a #GQuark. Therefore, - * if you pass a static string, you can save some memory by interning - * it first with g_intern_static_string(). - */ -void -gtk_menu_set_accel_path (GtkMenu *menu, - const gchar *accel_path) -{ - GtkMenuPrivate *priv; - - g_return_if_fail (GTK_IS_MENU (menu)); - - priv = menu->priv; - - if (accel_path) - g_return_if_fail (accel_path[0] == '<' && strchr (accel_path, '/')); /* simplistic check */ - - priv->accel_path = g_intern_string (accel_path); - if (priv->accel_path) - _gtk_menu_refresh_accel_paths (menu, FALSE); -} - -/** - * gtk_menu_get_accel_path: - * @menu: a valid #GtkMenu - * - * Retrieves the accelerator path set on the menu. - * - * Returns: the accelerator path set on the menu. - */ -const gchar* -gtk_menu_get_accel_path (GtkMenu *menu) -{ - g_return_val_if_fail (GTK_IS_MENU (menu), NULL); - - return menu->priv->accel_path; -} - -typedef struct { - GtkMenu *menu; - gboolean group_changed; -} AccelPropagation; - -static void -refresh_accel_paths_foreach (GtkWidget *widget, - gpointer data) -{ - GtkMenuPrivate *priv; - AccelPropagation *prop = data; - - if (GTK_IS_MENU_ITEM (widget)) /* should always be true */ - { - priv = prop->menu->priv; - _gtk_menu_item_refresh_accel_path (GTK_MENU_ITEM (widget), - priv->accel_path, - priv->accel_group, - prop->group_changed); - } -} - -static void -_gtk_menu_refresh_accel_paths (GtkMenu *menu, - gboolean group_changed) -{ - GtkMenuPrivate *priv = menu->priv; - - if (priv->accel_path && priv->accel_group) - { - AccelPropagation prop; - - prop.menu = menu; - prop.group_changed = group_changed; - gtk_container_foreach (GTK_CONTAINER (menu), - refresh_accel_paths_foreach, - &prop); - } -} - -/** - * gtk_menu_reposition: - * @menu: a #GtkMenu - * - * Repositions the menu according to its position function. - */ -void -gtk_menu_reposition (GtkMenu *menu) -{ - g_return_if_fail (GTK_IS_MENU (menu)); - - if (gtk_widget_is_drawable (GTK_WIDGET (menu))) - gtk_menu_position (menu); -} - -/** - * gtk_menu_reorder_child: - * @menu: a #GtkMenu - * @child: the #GtkMenuItem to move - * @position: the new position to place @child. - * Positions are numbered from 0 to n - 1 - * - * Moves @child to a new @position in the list of @menu - * children. - */ -void -gtk_menu_reorder_child (GtkMenu *menu, - GtkWidget *child, - gint position) -{ - GtkWidget *sibling = NULL; - int i; - - g_return_if_fail (GTK_IS_MENU (menu)); - g_return_if_fail (GTK_IS_MENU_ITEM (child)); - - if (position < 0) - sibling = gtk_widget_get_last_child (menu->priv->box); - - for (i = 0; i < position; i++) - { - if (sibling == NULL) - sibling = gtk_widget_get_first_child (menu->priv->box); - else - sibling = gtk_widget_get_next_sibling (sibling); - } - - gtk_box_reorder_child_after (GTK_BOX (menu->priv->box), child, sibling); -} - -static void -gtk_menu_realize (GtkWidget *widget) -{ - GTK_WIDGET_CLASS (gtk_menu_parent_class)->realize (widget); - - if (GTK_MENU_SHELL (widget)->priv->active_menu_item) - gtk_menu_scroll_item_visible (GTK_MENU_SHELL (widget), - GTK_MENU_SHELL (widget)->priv->active_menu_item); -} - -static gboolean -gtk_menu_focus (GtkWidget *widget, - GtkDirectionType direction) -{ - /* A menu or its menu items cannot have focus */ - return FALSE; -} - -static GdkSurface * -menu_grab_transfer_surface_get (GtkMenu *menu) -{ - GdkSurface *surface = g_object_get_data (G_OBJECT (menu), "gtk-menu-transfer-surface"); - if (!surface) - { - GdkRectangle rect = { -100, -100, 1, 1 }; - surface = gdk_surface_new_temp (gtk_widget_get_display (GTK_WIDGET (menu)), &rect); - - gdk_surface_show (surface); - - g_object_set_data (G_OBJECT (menu), I_("gtk-menu-transfer-surface"), surface); - } - - return surface; -} - -static void -menu_grab_transfer_surface_destroy (GtkMenu *menu) -{ - GdkSurface *surface = g_object_get_data (G_OBJECT (menu), "gtk-menu-transfer-surface"); - if (surface) - { - GdkSurface *widget_surface; - - gdk_surface_destroy (surface); - g_object_set_data (G_OBJECT (menu), I_("gtk-menu-transfer-surface"), NULL); - - widget_surface = gtk_native_get_surface (gtk_widget_get_native (GTK_WIDGET (menu))); - g_object_set_data (G_OBJECT (widget_surface), I_("gdk-attached-grab-surface"), surface); - } -} - -static void -gtk_menu_unrealize (GtkWidget *widget) -{ - GtkMenu *menu = GTK_MENU (widget); - - menu_grab_transfer_surface_destroy (menu); - - GTK_WIDGET_CLASS (gtk_menu_parent_class)->unrealize (widget); -} - -static void -gtk_menu_size_allocate (GtkWidget *widget, - int width, - int height, - int baseline) -{ - GtkMenu *menu = GTK_MENU (widget); - GtkMenuPrivate *priv = menu->priv; - GList *children, *l; - - children = gtk_container_get_children (GTK_CONTAINER (priv->box)); - for (l = children; l; l = l->next) - { - GtkWidget *child = l->data; - - gtk_menu_item_toggle_size_allocate (GTK_MENU_ITEM (child), - priv->toggle_size); - } - g_list_free (children); - - gtk_widget_size_allocate (priv->swin, - &(GtkAllocation) { 0, 0, width, height }, - baseline); -} - -static void -gtk_menu_show (GtkWidget *widget) -{ - GtkMenu *menu = GTK_MENU (widget); - - _gtk_menu_refresh_accel_paths (menu, FALSE); - - GTK_WIDGET_CLASS (gtk_menu_parent_class)->show (widget); -} - -static void -gtk_menu_measure (GtkWidget *widget, - GtkOrientation orientation, - int for_size, - int *minimum, - int *natural, - int *minimum_baseline, - int *natural_baseline) -{ - GtkMenu *menu = GTK_MENU (widget); - GtkMenuPrivate *priv = gtk_menu_get_instance_private (menu); - - gtk_widget_measure (priv->swin, - orientation, - for_size, - minimum, natural, - minimum_baseline, natural_baseline); - - if (orientation == GTK_ORIENTATION_HORIZONTAL) - { - GList *children, *l; - guint max_toggle_size; - guint max_accel_width; - - max_toggle_size = 0; - max_accel_width = 0; - - children = gtk_container_get_children (GTK_CONTAINER (priv->box)); - for (l = children; l; l = l->next) - { - GtkWidget *child = l->data; - gint toggle_size; - - if (!gtk_widget_get_visible (child)) - continue; - - gtk_menu_item_toggle_size_request (GTK_MENU_ITEM (child), &toggle_size); - max_toggle_size = MAX (max_toggle_size, toggle_size); - max_accel_width = MAX (max_accel_width, - GTK_MENU_ITEM (child)->priv->accelerator_width); - } - g_list_free (children); - - /* If the menu doesn't include any images or check items - * reserve the space so that all menus are consistent. - * We only do this for 'ordinary' menus, not for combobox - * menus or multi-column menus - */ - if (max_toggle_size == 0 && - !priv->no_toggle_size) - { - GtkWidget *menu_item; - GtkWidget *indicator_widget; - gint indicator_width; - - /* Create a GtkCheckMenuItem, to query indicator size */ - menu_item = gtk_check_menu_item_new (); - indicator_widget = _gtk_check_menu_item_get_indicator_widget (GTK_CHECK_MENU_ITEM (menu_item)); - - gtk_widget_measure (indicator_widget, - GTK_ORIENTATION_HORIZONTAL, - -1, - &indicator_width, NULL, - NULL, NULL); - max_toggle_size = indicator_width; - - g_object_ref_sink (menu_item); - g_object_unref (menu_item); - } - - priv->toggle_size = max_toggle_size; - priv->accel_size = max_accel_width; - - *minimum += 2 * max_toggle_size + max_accel_width; - *natural += 2 * max_toggle_size + max_accel_width; - } -} - -static void -gtk_menu_pressed_cb (GtkGestureClick *gesture, - int n_press, - double x, - double y, - gpointer user_data) -{ - GtkMenu *menu = user_data; - GdkEventSequence *sequence = gtk_gesture_single_get_current_sequence (GTK_GESTURE_SINGLE (gesture)); - const GdkEvent *event = gtk_gesture_get_last_event (GTK_GESTURE (gesture), sequence); - GdkDevice *source_device; - GtkWidget *event_widget; - - source_device = gdk_event_get_source_device (event); - event_widget = gtk_get_event_widget ((GdkEvent *)event); - - if (GTK_IS_MENU_ITEM (event_widget) && - gdk_device_get_source (source_device) == GDK_SOURCE_TOUCHSCREEN && - GTK_MENU_ITEM (event_widget)->priv->submenu != NULL && - !gtk_widget_is_drawable (GTK_MENU_ITEM (event_widget)->priv->submenu)) - menu->priv->ignore_button_release = TRUE; - - gtk_gesture_set_state (GTK_GESTURE (gesture), GTK_EVENT_SEQUENCE_DENIED); -} - -static void -gtk_menu_released_cb (GtkGestureClick *gesture, - int n_press, - double x, - double y, - gpointer user_data) -{ - GtkMenu *menu = user_data; - GtkMenuPrivate *priv = menu->priv; - - if (priv->ignore_button_release) - { - priv->ignore_button_release = FALSE; - gtk_gesture_set_state (GTK_GESTURE (gesture), GTK_EVENT_SEQUENCE_DENIED); - return; - } -} - -static gboolean -check_threshold (GtkWidget *widget, - gint start_x, - gint start_y, - gint x, - gint y) -{ -#define THRESHOLD 8 - - return - ABS (start_x - x) > THRESHOLD || - ABS (start_y - y) > THRESHOLD; -} - -static gboolean -definitely_within_item (GtkMenu *menu, - GtkWidget *widget, - gint x, - gint y) -{ - int w, h; - graphene_rect_t bounds; - - if (!gtk_widget_compute_bounds (widget, GTK_WIDGET (menu), &bounds)) - return FALSE; - - w = bounds.size.width; - h = bounds.size.height; - - return - check_threshold (widget, 0, 0, x, y) && - check_threshold (widget, w - 1, 0, x, y) && - check_threshold (widget, w - 1, h - 1, x, y) && - check_threshold (widget, 0, h - 1, x, y); -} - -static void -gtk_menu_motion (GtkEventController *controller, - double x, - double y, - gpointer user_data) -{ - GtkWidget *menu_item; - GtkMenu *menu; - GtkMenuShell *menu_shell; - GtkWidget *parent; - GdkDevice *source_device; - GdkEventMotion *event; - - menu_item = GTK_WIDGET (user_data); - - event = (GdkEventMotion *)gtk_get_current_event (); /* FIXME: controller event */ - - source_device = gdk_event_get_source_device ((GdkEvent *)event); - - if (GTK_IS_MENU (menu_item) && - gdk_device_get_source (source_device) != GDK_SOURCE_TOUCHSCREEN) - { - GtkMenuPrivate *priv = GTK_MENU(menu_item)->priv; - - if (priv->ignore_button_release) - priv->ignore_button_release = FALSE; - } - - /*We received the event for one of two reasons: - * - * a) We are the active menu, and did gtk_grab_add() - * b) The widget is a child of ours, and the event was propagated - * - * Since for computation of navigation regions, we want the menu which - * is the parent of the menu item, for a), we need to find that menu, - * which may be different from 'widget'. - */ - parent = gtk_widget_get_parent (menu_item); - if (!GTK_IS_MENU_ITEM (menu_item) || - !GTK_IS_MENU (parent)) - return; - menu_shell = GTK_MENU_SHELL (parent); - menu = GTK_MENU (menu_shell); - - if (definitely_within_item (menu, menu_item, event->x, event->y)) - menu_shell->priv->activate_time = 0; - - /* Make sure we pop down if we enter a non-selectable menu item, so we - * don't show a submenu when the cursor is outside the stay-up triangle. - */ - if (!_gtk_menu_item_is_selectable (menu_item)) - { - /* We really want to deselect, but this gives the menushell code - * a chance to do some bookkeeping about the menuitem. - */ - gtk_menu_shell_select_item (menu_shell, menu_item); - } -} - -static void -gtk_menu_deactivate (GtkMenuShell *menu_shell) -{ - GtkWidget *parent; - - g_return_if_fail (GTK_IS_MENU (menu_shell)); - - parent = menu_shell->priv->parent_menu_shell; - - menu_shell->priv->activate_time = 0; - gtk_menu_popdown (GTK_MENU (menu_shell)); - - if (parent) - gtk_menu_shell_deactivate (GTK_MENU_SHELL (parent)); -} - -static GdkGravity -get_horizontally_flipped_anchor (GdkGravity anchor) -{ - switch (anchor) - { - case GDK_GRAVITY_STATIC: - case GDK_GRAVITY_NORTH_WEST: - return GDK_GRAVITY_NORTH_EAST; - case GDK_GRAVITY_NORTH: - return GDK_GRAVITY_NORTH; - case GDK_GRAVITY_NORTH_EAST: - return GDK_GRAVITY_NORTH_WEST; - case GDK_GRAVITY_WEST: - return GDK_GRAVITY_EAST; - case GDK_GRAVITY_CENTER: - return GDK_GRAVITY_CENTER; - case GDK_GRAVITY_EAST: - return GDK_GRAVITY_WEST; - case GDK_GRAVITY_SOUTH_WEST: - return GDK_GRAVITY_SOUTH_EAST; - case GDK_GRAVITY_SOUTH: - return GDK_GRAVITY_SOUTH; - case GDK_GRAVITY_SOUTH_EAST: - return GDK_GRAVITY_SOUTH_WEST; - default: - g_warning ("unknown GdkGravity: %d", anchor); - return anchor; - } -} - -static void -gtk_menu_position (GtkMenu *menu) -{ - GtkMenuPrivate *priv = menu->priv; - GdkSurface *rect_surface = NULL; - GdkRectangle rect; - GtkTextDirection text_direction = GTK_TEXT_DIR_NONE; - GdkGravity rect_anchor; - GdkGravity menu_anchor; - GdkAnchorHints anchor_hints; - gint rect_anchor_dx, rect_anchor_dy; - GdkSurface *toplevel; - - rect_anchor = priv->rect_anchor; - menu_anchor = priv->menu_anchor; - anchor_hints = priv->anchor_hints; - rect_anchor_dx = priv->rect_anchor_dx; - rect_anchor_dy = priv->rect_anchor_dy; - - if (priv->rect_surface) - { - rect_surface = priv->rect_surface; - rect = priv->rect; - } - else if (priv->widget) - { - rect_surface = gtk_native_get_surface (gtk_widget_get_native (priv->widget)); - gtk_widget_get_surface_allocation (priv->widget, &rect); - text_direction = gtk_widget_get_direction (priv->widget); - } - else - { - g_assert_not_reached (); - } - - /* Realize so we have the proper width and height to figure out - * the right place to popup the menu. - */ - gtk_widget_realize (priv->toplevel); - - if (!gtk_widget_get_visible (priv->toplevel)) - gtk_window_set_type_hint (GTK_WINDOW (priv->toplevel), priv->menu_type_hint); - - if (text_direction == GTK_TEXT_DIR_NONE) - text_direction = gtk_widget_get_direction (GTK_WIDGET (menu)); - - if (text_direction == GTK_TEXT_DIR_RTL) - { - rect_anchor = get_horizontally_flipped_anchor (rect_anchor); - menu_anchor = get_horizontally_flipped_anchor (menu_anchor); - } - - toplevel = gtk_native_get_surface (GTK_NATIVE (priv->toplevel)); - - gdk_surface_set_transient_for (toplevel, rect_surface); - - g_signal_handlers_disconnect_by_func (toplevel, moved_to_rect_cb, menu); - - g_signal_connect (toplevel, "moved-to-rect", G_CALLBACK (moved_to_rect_cb), - menu); - - gdk_surface_move_to_rect (toplevel, - &rect, - rect_anchor, - menu_anchor, - anchor_hints, - rect_anchor_dx, - rect_anchor_dy); -} - -static void -gtk_menu_scroll_item_visible (GtkMenuShell *menu_shell, - GtkWidget *menu_item) -{ - GtkMenu *menu = GTK_MENU (menu_shell); - GtkMenuPrivate *priv = menu->priv; - graphene_rect_t rect; - GtkAdjustment *adj; - double value, page; - - if (!gtk_widget_compute_bounds (menu_item, priv->box, &rect)) - return; - - adj = gtk_scrolled_window_get_vadjustment (GTK_SCROLLED_WINDOW (priv->swin)); - - page = gtk_adjustment_get_page_size (adj); - value = gtk_adjustment_get_value (adj); - - if (rect.origin.y + rect.size.height > value + page) - gtk_adjustment_set_value (adj, rect.origin.y + rect.size.height - page); - else if (rect.origin.y < value) - gtk_adjustment_set_value (adj, rect.origin.y); -} - -static void -gtk_menu_select_item (GtkMenuShell *menu_shell, - GtkWidget *menu_item) -{ - GtkMenu *menu = GTK_MENU (menu_shell); - - if (gtk_widget_get_realized (GTK_WIDGET (menu))) - gtk_menu_scroll_item_visible (menu_shell, menu_item); - - GTK_MENU_SHELL_CLASS (gtk_menu_parent_class)->select_item (menu_shell, menu_item); -} - -static gint -gtk_menu_get_popup_delay (GtkMenuShell *menu_shell) -{ - return MENU_POPUP_DELAY; -} - -static void -gtk_menu_move_current (GtkMenuShell *menu_shell, - GtkMenuDirectionType direction) -{ - if (gtk_widget_get_direction (GTK_WIDGET (menu_shell)) == GTK_TEXT_DIR_RTL) - { - switch (direction) - { - case GTK_MENU_DIR_CHILD: - direction = GTK_MENU_DIR_PARENT; - break; - case GTK_MENU_DIR_PARENT: - direction = GTK_MENU_DIR_CHILD; - break; - case GTK_MENU_DIR_NEXT: - case GTK_MENU_DIR_PREV: - default: - break; - } - } - - GTK_MENU_SHELL_CLASS (gtk_menu_parent_class)->move_current (menu_shell, direction); -} - -static void -gtk_menu_real_move_scroll (GtkMenu *menu, - GtkScrollType type) -{ - GtkMenuPrivate *priv = menu->priv; - GtkMenuShell *menu_shell = GTK_MENU_SHELL (menu); - int menu_size, item_size; - int dist; - int i; - GtkWidget *item, *next; - - if (menu_shell->priv->active_menu_item) - item = menu_shell->priv->active_menu_item; - else - item = gtk_widget_get_first_child (priv->box); - - menu_size = gtk_widget_get_allocated_height (GTK_WIDGET (menu)); - item_size = gtk_widget_get_allocated_height (GTK_WIDGET (item)); - - dist = menu_size / item_size; - - switch ((guint) type) - { - case GTK_SCROLL_PAGE_UP: - i = 0; - while (i < dist) - { - next = gtk_widget_get_prev_sibling (item); - if (next == NULL) - break; - i++; - item = next; - } - break; - case GTK_SCROLL_PAGE_DOWN: - i = 0; - while (i < dist) - { - next = gtk_widget_get_next_sibling (item); - if (next == NULL) - break; - i++; - item = next; - } - break; - case GTK_SCROLL_START: - item = gtk_widget_get_first_child (priv->box); - break; - case GTK_SCROLL_END: - item = gtk_widget_get_last_child (priv->box); - break; - default: - return; - } - - gtk_menu_shell_select_item (menu_shell, item); -} - -/** - * gtk_menu_set_monitor: - * @menu: a #GtkMenu - * @monitor_num: the number of the monitor on which the menu should - * be popped up - * - * Informs GTK+ on which monitor a menu should be popped up. - * See gdk_monitor_get_geometry(). - * - * This function should be called from a #GtkMenuPositionFunc - * if the menu should not appear on the same monitor as the pointer. - * This information can’t be reliably inferred from the coordinates - * returned by a #GtkMenuPositionFunc, since, for very long menus, - * these coordinates may extend beyond the monitor boundaries or even - * the screen boundaries. - */ -void -gtk_menu_set_monitor (GtkMenu *menu, - gint monitor_num) -{ - GtkMenuPrivate *priv; - - g_return_if_fail (GTK_IS_MENU (menu)); - - priv = menu->priv; - - if (priv->monitor_num != monitor_num) - { - priv->monitor_num = monitor_num; - g_object_notify (G_OBJECT (menu), "monitor"); - } -} - -/** - * gtk_menu_get_monitor: - * @menu: a #GtkMenu - * - * Retrieves the number of the monitor on which to show the menu. - * - * Returns: the number of the monitor on which the menu should - * be popped up or -1, if no monitor has been set - */ -gint -gtk_menu_get_monitor (GtkMenu *menu) -{ - g_return_val_if_fail (GTK_IS_MENU (menu), -1); - - return menu->priv->monitor_num; -} - -/** - * gtk_menu_place_on_monitor: - * @menu: a #GtkMenu - * @monitor: the monitor to place the menu on - * - * Places @menu on the given monitor. - */ -void -gtk_menu_place_on_monitor (GtkMenu *menu, - GdkMonitor *monitor) -{ - GdkDisplay *display; - gint i, monitor_num; - - g_return_if_fail (GTK_IS_MENU (menu)); - - display = gtk_widget_get_display (GTK_WIDGET (menu)); - monitor_num = 0; - for (i = 0; ; i++) - { - GdkMonitor *m = gdk_display_get_monitor (display, i); - if (m == monitor) - { - monitor_num = i; - break; - } - if (m == NULL) - break; - } - - gtk_menu_set_monitor (menu, monitor_num); -} - -/** - * gtk_menu_get_for_attach_widget: - * @widget: a #GtkWidget - * - * Returns a list of the menus which are attached to this widget. - * This list is owned by GTK+ and must not be modified. - * - * Returns: (element-type GtkWidget) (transfer none): the list - * of menus attached to his widget. - */ -GList* -gtk_menu_get_for_attach_widget (GtkWidget *widget) -{ - GList *list; - - g_return_val_if_fail (GTK_IS_WIDGET (widget), NULL); - - list = g_object_get_data (G_OBJECT (widget), ATTACHED_MENUS); - - return list; -} - -static void -gtk_menu_grab_notify (GtkWidget *widget, - gboolean was_grabbed) -{ - GtkWidget *toplevel; - GtkWindowGroup *group; - GtkWidget *grab; - GdkDevice *pointer; - - GTK_WIDGET_CLASS (gtk_menu_parent_class)->grab_notify (widget, was_grabbed); - - pointer = _gtk_menu_shell_get_grab_device (GTK_MENU_SHELL (widget)); - - if (!pointer || - !gtk_widget_device_is_shadowed (widget, pointer)) - return; - - toplevel = GTK_WIDGET (gtk_widget_get_root (widget)); - - if (!GTK_IS_WINDOW (toplevel)) - return; - - group = gtk_window_get_group (GTK_WINDOW (toplevel)); - grab = gtk_window_group_get_current_grab (group); - - if (GTK_MENU_SHELL (widget)->priv->active && !GTK_IS_MENU_SHELL (grab)) - gtk_menu_shell_cancel (GTK_MENU_SHELL (widget)); -} - -/** - * gtk_menu_set_reserve_toggle_size: - * @menu: a #GtkMenu - * @reserve_toggle_size: whether to reserve size for toggles - * - * Sets whether the menu should reserve space for drawing toggles - * or icons, regardless of their actual presence. - */ -void -gtk_menu_set_reserve_toggle_size (GtkMenu *menu, - gboolean reserve_toggle_size) -{ - GtkMenuPrivate *priv; - gboolean no_toggle_size; - - g_return_if_fail (GTK_IS_MENU (menu)); - - priv = menu->priv; - - no_toggle_size = !reserve_toggle_size; - if (priv->no_toggle_size != no_toggle_size) - { - priv->no_toggle_size = no_toggle_size; - - g_object_notify (G_OBJECT (menu), "reserve-toggle-size"); - } -} - -/** - * gtk_menu_get_reserve_toggle_size: - * @menu: a #GtkMenu - * - * Returns whether the menu reserves space for toggles and - * icons, regardless of their actual presence. - * - * Returns: Whether the menu reserves toggle space - */ -gboolean -gtk_menu_get_reserve_toggle_size (GtkMenu *menu) -{ - g_return_val_if_fail (GTK_IS_MENU (menu), FALSE); - - return !menu->priv->no_toggle_size; -} - -/** - * gtk_menu_new_from_model: - * @model: a #GMenuModel - * - * Creates a #GtkMenu and populates it with menu items and - * submenus according to @model. - * - * The created menu items are connected to actions found in the - * #GtkApplicationWindow to which the menu belongs - typically - * by means of being attached to a widget (see gtk_menu_attach_to_widget()) - * that is contained within the #GtkApplicationWindows widget hierarchy. - * - * Actions can also be added using gtk_widget_insert_action_group() on the menu's - * attach widget or on any of its parent widgets. - * - * Returns: a new #GtkMenu - */ -GtkWidget * -gtk_menu_new_from_model (GMenuModel *model) -{ - GtkWidget *menu; - - g_return_val_if_fail (G_IS_MENU_MODEL (model), NULL); - - menu = gtk_menu_new (); - gtk_menu_shell_bind_model (GTK_MENU_SHELL (menu), model, NULL, TRUE); - - return menu; -} diff --git a/gtk/gtkmenu.h b/gtk/gtkmenu.h deleted file mode 100644 index c4217516db..0000000000 --- a/gtk/gtkmenu.h +++ /dev/null @@ -1,140 +0,0 @@ -/* GTK - The GIMP Toolkit - * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * 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, see . - */ - -/* - * Modified by the GTK+ Team and others 1997-2000. See the AUTHORS - * file for a list of people on the GTK+ Team. See the ChangeLog - * files for a list of changes. These files are distributed with - * GTK+ at ftp://ftp.gtk.org/pub/gtk/. - */ - -#ifndef __GTK_MENU_H__ -#define __GTK_MENU_H__ - -#if !defined (__GTK_H_INSIDE__) && !defined (GTK_COMPILATION) -#error "Only can be included directly." -#endif - -#include -#include - -G_BEGIN_DECLS - -#define GTK_TYPE_MENU (gtk_menu_get_type ()) -#define GTK_MENU(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GTK_TYPE_MENU, GtkMenu)) -#define GTK_IS_MENU(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GTK_TYPE_MENU)) - - -typedef struct _GtkMenu GtkMenu; - -/** - * GtkMenuDetachFunc: - * @attach_widget: the #GtkWidget that the menu is being detached from. - * @menu: the #GtkMenu being detached. - * - * A user function supplied when calling gtk_menu_attach_to_widget() which - * will be called when the menu is later detached from the widget. - */ -typedef void (*GtkMenuDetachFunc) (GtkWidget *attach_widget, - GtkMenu *menu); - -GDK_AVAILABLE_IN_ALL -GType gtk_menu_get_type (void) G_GNUC_CONST; -GDK_AVAILABLE_IN_ALL -GtkWidget* gtk_menu_new (void); -GDK_AVAILABLE_IN_ALL -GtkWidget* gtk_menu_new_from_model (GMenuModel *model); - -GDK_AVAILABLE_IN_ALL -void gtk_menu_popup_at_rect (GtkMenu *menu, - GdkSurface *rect_surface, - const GdkRectangle *rect, - GdkGravity rect_anchor, - GdkGravity menu_anchor, - const GdkEvent *trigger_event); -GDK_AVAILABLE_IN_ALL -void gtk_menu_popup_at_widget (GtkMenu *menu, - GtkWidget *widget, - GdkGravity widget_anchor, - GdkGravity menu_anchor, - const GdkEvent *trigger_event); -GDK_AVAILABLE_IN_ALL -void gtk_menu_popup_at_pointer (GtkMenu *menu, - const GdkEvent *trigger_event); - -GDK_AVAILABLE_IN_ALL -void gtk_menu_reposition (GtkMenu *menu); - -GDK_AVAILABLE_IN_ALL -void gtk_menu_popdown (GtkMenu *menu); - -GDK_AVAILABLE_IN_ALL -GtkWidget* gtk_menu_get_active (GtkMenu *menu); -GDK_AVAILABLE_IN_ALL -void gtk_menu_set_active (GtkMenu *menu, - guint index); - -GDK_AVAILABLE_IN_ALL -void gtk_menu_set_accel_group (GtkMenu *menu, - GtkAccelGroup *accel_group); -GDK_AVAILABLE_IN_ALL -GtkAccelGroup* gtk_menu_get_accel_group (GtkMenu *menu); -GDK_AVAILABLE_IN_ALL -void gtk_menu_set_accel_path (GtkMenu *menu, - const gchar *accel_path); -GDK_AVAILABLE_IN_ALL -const gchar* gtk_menu_get_accel_path (GtkMenu *menu); - -GDK_AVAILABLE_IN_ALL -void gtk_menu_attach_to_widget (GtkMenu *menu, - GtkWidget *attach_widget, - GtkMenuDetachFunc detacher); -GDK_AVAILABLE_IN_ALL -void gtk_menu_detach (GtkMenu *menu); - -GDK_AVAILABLE_IN_ALL -GtkWidget* gtk_menu_get_attach_widget (GtkMenu *menu); - -GDK_AVAILABLE_IN_ALL -void gtk_menu_reorder_child (GtkMenu *menu, - GtkWidget *child, - gint position); - -GDK_AVAILABLE_IN_ALL -void gtk_menu_set_monitor (GtkMenu *menu, - gint monitor_num); -GDK_AVAILABLE_IN_ALL -gint gtk_menu_get_monitor (GtkMenu *menu); - -GDK_AVAILABLE_IN_ALL -void gtk_menu_place_on_monitor (GtkMenu *menu, - GdkMonitor *monitor); - -GDK_AVAILABLE_IN_ALL -GList* gtk_menu_get_for_attach_widget (GtkWidget *widget); - -GDK_AVAILABLE_IN_ALL -void gtk_menu_set_reserve_toggle_size (GtkMenu *menu, - gboolean reserve_toggle_size); -GDK_AVAILABLE_IN_ALL -gboolean gtk_menu_get_reserve_toggle_size (GtkMenu *menu); - -G_DEFINE_AUTOPTR_CLEANUP_FUNC(GtkMenu, g_object_unref) - -G_END_DECLS - -#endif /* __GTK_MENU_H__ */ diff --git a/gtk/gtkmenubar.c b/gtk/gtkmenubar.c deleted file mode 100644 index 324c1d9381..0000000000 --- a/gtk/gtkmenubar.c +++ /dev/null @@ -1,489 +0,0 @@ -/* GTK - The GIMP Toolkit - * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * 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, see . - */ - -/* - * Modified by the GTK+ Team and others 1997-2000. See the AUTHORS - * file for a list of people on the GTK+ Team. See the ChangeLog - * files for a list of changes. These files are distributed with - * GTK+ at ftp://ftp.gtk.org/pub/gtk/. - */ - -/** - * SECTION:gtkmenubar - * @Title: GtkMenuBar - * @Short_description: A subclass of GtkMenuShell which holds GtkMenuItem widgets - * @See_also: #GtkMenuShell, #GtkMenu, #GtkMenuItem - * - * The #GtkMenuBar is a subclass of #GtkMenuShell which contains one or - * more #GtkMenuItems. The result is a standard menu bar which can hold - * many menu items. - * - * # CSS nodes - * - * GtkMenuBar has a single CSS node with name menubar. - */ - -#include "config.h" - -#include "gtkmenubar.h" -#include "gtkmenubarprivate.h" - -#include "gtkboxlayout.h" -#include "gtkbindings.h" -#include "gtkmain.h" -#include "gtkmarshalers.h" -#include "gtkmenuitemprivate.h" -#include "gtkmenuprivate.h" -#include "gtkmenushellprivate.h" -#include "gtksettings.h" -#include "gtksizerequest.h" -#include "gtkwindow.h" -#include "gtkcontainerprivate.h" -#include "gtkcheckmenuitem.h" -#include "gtkintl.h" -#include "gtkprivate.h" -#include "gtktypebuiltins.h" -#include "gtkwidgetprivate.h" - -#define MENU_BAR_POPUP_DELAY 0 - - -typedef struct _GtkMenuBarPrivate GtkMenuBarPrivate; -typedef struct _GtkMenuBarClass GtkMenuBarClass; - -struct _GtkMenuBar -{ - GtkMenuShell menu_shell; - - int toggle_size; -}; - -struct _GtkMenuBarClass -{ - GtkMenuShellClass parent_class; -}; - -static void gtk_menu_bar_add (GtkContainer *container, - GtkWidget *widget); -static void gtk_menu_bar_remove (GtkContainer *container, - GtkWidget *widget); - -static void gtk_menu_bar_root (GtkWidget *widget); -static void gtk_menu_bar_unroot (GtkWidget *widget); -static gint gtk_menu_bar_get_popup_delay (GtkMenuShell *menu_shell); -static void gtk_menu_bar_move_current (GtkMenuShell *menu_shell, - GtkMenuDirectionType direction); -static void gtk_menu_bar_insert (GtkMenuShell *menu_shell, - GtkWidget *child, - gint position); - -G_DEFINE_TYPE (GtkMenuBar, gtk_menu_bar, GTK_TYPE_MENU_SHELL) - -static GList * -gtk_menu_bar_get_items (GtkMenuShell *menu_shell) -{ - GtkMenuBar *menu_bar = GTK_MENU_BAR (menu_shell); - GList *list = NULL; - GtkWidget *child; - - for (child = gtk_widget_get_last_child (GTK_WIDGET (menu_bar)); - child != NULL; - child = gtk_widget_get_prev_sibling (child)) - { - list = g_list_prepend (list, child); - } - - return list; -} - -static void -gtk_menu_bar_finalize (GObject *object) -{ - G_OBJECT_CLASS (gtk_menu_bar_parent_class)->finalize (object); -} - -static void -gtk_menu_bar_dispose (GObject *object) -{ - GtkMenuBar *menu_bar = GTK_MENU_BAR (object); - GtkWidget *child; - - child = gtk_widget_get_first_child (GTK_WIDGET (menu_bar)); - while (child) - { - GtkWidget *next = gtk_widget_get_next_sibling (child); - - gtk_widget_unparent (child); - - child = next; - } - - G_OBJECT_CLASS (gtk_menu_bar_parent_class)->dispose (object); -} - -static void -gtk_menu_bar_forall (GtkContainer *container, - GtkCallback callback, - gpointer data) -{ - GtkMenuBar *menu_bar = GTK_MENU_BAR (container); - GtkWidget *child; - - child = gtk_widget_get_first_child (GTK_WIDGET (menu_bar)); - while (child) - { - GtkWidget *next = gtk_widget_get_next_sibling (child); - - (*callback) (child, data); - - child = next; - } -} - -static void -gtk_menu_bar_class_init (GtkMenuBarClass *class) -{ - GObjectClass *object_class = G_OBJECT_CLASS (class); - GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (class); - GtkContainerClass *container_class = GTK_CONTAINER_CLASS (class); - GtkMenuShellClass *menu_shell_class = GTK_MENU_SHELL_CLASS (class); - - GtkBindingSet *binding_set; - - object_class->finalize = gtk_menu_bar_finalize; - object_class->dispose = gtk_menu_bar_dispose; - - widget_class->root = gtk_menu_bar_root; - widget_class->unroot = gtk_menu_bar_unroot; - - container_class->add = gtk_menu_bar_add; - container_class->remove = gtk_menu_bar_remove; - container_class->forall = gtk_menu_bar_forall; - - menu_shell_class->insert = gtk_menu_bar_insert; - menu_shell_class->submenu_placement = GTK_TOP_BOTTOM; - menu_shell_class->get_popup_delay = gtk_menu_bar_get_popup_delay; - menu_shell_class->move_current = gtk_menu_bar_move_current; - menu_shell_class->get_items = gtk_menu_bar_get_items; - - binding_set = gtk_binding_set_by_class (class); - gtk_binding_entry_add_signal (binding_set, - GDK_KEY_Left, 0, - "move-current", 1, - GTK_TYPE_MENU_DIRECTION_TYPE, - GTK_MENU_DIR_PREV); - gtk_binding_entry_add_signal (binding_set, - GDK_KEY_KP_Left, 0, - "move-current", 1, - GTK_TYPE_MENU_DIRECTION_TYPE, - GTK_MENU_DIR_PREV); - gtk_binding_entry_add_signal (binding_set, - GDK_KEY_Right, 0, - "move-current", 1, - GTK_TYPE_MENU_DIRECTION_TYPE, - GTK_MENU_DIR_NEXT); - gtk_binding_entry_add_signal (binding_set, - GDK_KEY_KP_Right, 0, - "move-current", 1, - GTK_TYPE_MENU_DIRECTION_TYPE, - GTK_MENU_DIR_NEXT); - gtk_binding_entry_add_signal (binding_set, - GDK_KEY_Up, 0, - "move-current", 1, - GTK_TYPE_MENU_DIRECTION_TYPE, - GTK_MENU_DIR_PARENT); - gtk_binding_entry_add_signal (binding_set, - GDK_KEY_KP_Up, 0, - "move-current", 1, - GTK_TYPE_MENU_DIRECTION_TYPE, - GTK_MENU_DIR_PARENT); - gtk_binding_entry_add_signal (binding_set, - GDK_KEY_Down, 0, - "move-current", 1, - GTK_TYPE_MENU_DIRECTION_TYPE, - GTK_MENU_DIR_CHILD); - gtk_binding_entry_add_signal (binding_set, - GDK_KEY_KP_Down, 0, - "move-current", 1, - GTK_TYPE_MENU_DIRECTION_TYPE, - GTK_MENU_DIR_CHILD); - - gtk_widget_class_set_accessible_role (widget_class, ATK_ROLE_MENU_BAR); - gtk_widget_class_set_layout_manager_type (widget_class, GTK_TYPE_BOX_LAYOUT); - gtk_widget_class_set_css_name (widget_class, I_("menubar")); -} - -static void -gtk_menu_bar_init (GtkMenuBar *menu_bar) -{ -} - -/** - * gtk_menu_bar_new: - * - * Creates a new #GtkMenuBar - * - * Returns: the new menu bar, as a #GtkWidget - */ -GtkWidget* -gtk_menu_bar_new (void) -{ - return g_object_new (GTK_TYPE_MENU_BAR, NULL); -} - -static GList * -get_menu_bars (GtkWindow *window) -{ - return g_object_get_data (G_OBJECT (window), "gtk-menu-bar-list"); -} - -GList * -_gtk_menu_bar_get_viewable_menu_bars (GtkWindow *window) -{ - GList *menu_bars; - GList *viewable_menu_bars = NULL; - - for (menu_bars = get_menu_bars (window); - menu_bars; - menu_bars = menu_bars->next) - { - GtkWidget *widget = menu_bars->data; - gboolean viewable = TRUE; - - while (widget) - { - if (!gtk_widget_get_mapped (widget)) - viewable = FALSE; - - widget = gtk_widget_get_parent (widget); - } - - if (viewable) - viewable_menu_bars = g_list_prepend (viewable_menu_bars, menu_bars->data); - } - - return g_list_reverse (viewable_menu_bars); -} - -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, - GtkMenuBar *menubar) -{ - GList *menubars = get_menu_bars (window); - - set_menu_bars (window, g_list_prepend (menubars, menubar)); -} - -static void -remove_from_window (GtkWindow *window, - GtkMenuBar *menubar) -{ - GList *menubars = get_menu_bars (window); - - menubars = g_list_remove (menubars, menubar); - set_menu_bars (window, menubars); -} - -static void -gtk_menu_bar_root (GtkWidget *widget) -{ - GtkMenuBar *menubar = GTK_MENU_BAR (widget); - GtkWidget *toplevel; - - GTK_WIDGET_CLASS (gtk_menu_bar_parent_class)->root (widget); - - toplevel = GTK_WIDGET (gtk_widget_get_root (widget)); - add_to_window (GTK_WINDOW (toplevel), menubar); -} - -static void -gtk_menu_bar_unroot (GtkWidget *widget) -{ - GtkMenuBar *menubar = GTK_MENU_BAR (widget); - GtkWidget *toplevel; - - toplevel = GTK_WIDGET (gtk_widget_get_root (widget)); - remove_from_window (GTK_WINDOW (toplevel), menubar); - - GTK_WIDGET_CLASS (gtk_menu_bar_parent_class)->unroot (widget); -} - -/** - * _gtk_menu_bar_cycle_focus: - * @menubar: a #GtkMenuBar - * @dir: direction in which to cycle the focus - * - * Move the focus between menubars in the toplevel. - **/ -void -_gtk_menu_bar_cycle_focus (GtkMenuBar *menubar, - GtkDirectionType dir) -{ - GtkWidget *toplevel = GTK_WIDGET (gtk_widget_get_root (GTK_WIDGET (menubar))); - GtkMenuItem *to_activate = NULL; - - if (GTK_IS_WINDOW (toplevel)) - { - GList *tmp_menubars = _gtk_menu_bar_get_viewable_menu_bars (GTK_WINDOW (toplevel)); - GList *l; - GPtrArray *menubars; - gboolean found; - guint index; - - menubars = g_ptr_array_sized_new (g_list_length (tmp_menubars)); - - for (l = tmp_menubars; l; l = l->next) - g_ptr_array_add (menubars, l->data); - - gtk_widget_focus_sort (toplevel, dir, menubars); - - found = g_ptr_array_find (menubars, menubar, &index); - - if (found && index < menubars->len - 1) - { - GtkWidget *next = g_ptr_array_index (menubars, index + 1); - GtkMenuShell *new_menushell = GTK_MENU_SHELL (next); - GList *children = gtk_menu_shell_get_items (new_menushell); - - if (children) - to_activate = children->data; - g_list_free (children); - } - - g_ptr_array_free (menubars, TRUE); - } - - gtk_menu_shell_cancel (GTK_MENU_SHELL (menubar)); - - if (to_activate) - g_signal_emit_by_name (to_activate, "activate_item"); -} - -static gint -gtk_menu_bar_get_popup_delay (GtkMenuShell *menu_shell) -{ - return MENU_BAR_POPUP_DELAY; -} - -static void -gtk_menu_bar_move_current (GtkMenuShell *menu_shell, - GtkMenuDirectionType direction) -{ - GtkMenuBar *menubar = GTK_MENU_BAR (menu_shell); - - if (gtk_widget_get_direction (GTK_WIDGET (menubar)) == GTK_TEXT_DIR_RTL) - { - switch (direction) - { - case GTK_MENU_DIR_PREV: - direction = GTK_MENU_DIR_NEXT; - break; - case GTK_MENU_DIR_NEXT: - direction = GTK_MENU_DIR_PREV; - break; - case GTK_MENU_DIR_PARENT: - case GTK_MENU_DIR_CHILD: - default: - break; - } - } - - GTK_MENU_SHELL_CLASS (gtk_menu_bar_parent_class)->move_current (menu_shell, direction); -} - -/** - * gtk_menu_bar_new_from_model: - * @model: a #GMenuModel - * - * Creates a new #GtkMenuBar and populates it with menu items - * and submenus according to @model. - * - * The created menu items are connected to actions found in the - * #GtkApplicationWindow to which the menu bar belongs - typically - * by means of being contained within the #GtkApplicationWindows - * widget hierarchy. - * - * Returns: a new #GtkMenuBar - */ -GtkWidget * -gtk_menu_bar_new_from_model (GMenuModel *model) -{ - GtkWidget *menubar; - - g_return_val_if_fail (G_IS_MENU_MODEL (model), NULL); - - menubar = gtk_menu_bar_new (); - gtk_menu_shell_bind_model (GTK_MENU_SHELL (menubar), model, NULL, FALSE); - - return menubar; -} - -static void -gtk_menu_bar_add (GtkContainer *container, - GtkWidget *widget) -{ - gtk_widget_set_parent (widget, GTK_WIDGET (container)); -} - -static void -gtk_menu_bar_remove (GtkContainer *container, - GtkWidget *widget) -{ - gtk_widget_unparent (widget); - - GTK_CONTAINER_CLASS (gtk_menu_bar_parent_class)->remove (container, widget); -} - -static void -gtk_menu_bar_reorder_child (GtkMenuBar *menu_bar, - GtkWidget *child, - gint position) -{ - GtkWidget *sibling = NULL; - int i; - - if (position < 0) - sibling = gtk_widget_get_last_child (GTK_WIDGET (menu_bar)); - - for (i = 0; i < position; i++) - { - if (sibling == NULL) - sibling = gtk_widget_get_first_child (GTK_WIDGET (menu_bar)); - else - sibling = gtk_widget_get_next_sibling (sibling); - } - - gtk_widget_insert_after (child, GTK_WIDGET (menu_bar), sibling); -} - -static void -gtk_menu_bar_insert (GtkMenuShell *menu_shell, - GtkWidget *child, - gint position) -{ - GtkMenuBar *menu_bar = GTK_MENU_BAR (menu_shell); - - gtk_widget_set_parent (child, GTK_WIDGET (menu_bar)); - gtk_menu_bar_reorder_child (menu_bar, child, position); -} diff --git a/gtk/gtkmenubar.h b/gtk/gtkmenubar.h deleted file mode 100644 index ee1d8a654a..0000000000 --- a/gtk/gtkmenubar.h +++ /dev/null @@ -1,56 +0,0 @@ -/* GTK - The GIMP Toolkit - * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * 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, see . - */ - -/* - * Modified by the GTK+ Team and others 1997-2000. See the AUTHORS - * file for a list of people on the GTK+ Team. See the ChangeLog - * files for a list of changes. These files are distributed with - * GTK+ at ftp://ftp.gtk.org/pub/gtk/. - */ - -#ifndef __GTK_MENU_BAR_H__ -#define __GTK_MENU_BAR_H__ - - -#if !defined (__GTK_H_INSIDE__) && !defined (GTK_COMPILATION) -#error "Only can be included directly." -#endif - -#include - - -G_BEGIN_DECLS - - -#define GTK_TYPE_MENU_BAR (gtk_menu_bar_get_type ()) -#define GTK_MENU_BAR(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GTK_TYPE_MENU_BAR, GtkMenuBar)) -#define GTK_IS_MENU_BAR(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GTK_TYPE_MENU_BAR)) - -typedef struct _GtkMenuBar GtkMenuBar; - -GDK_AVAILABLE_IN_ALL -GType gtk_menu_bar_get_type (void) G_GNUC_CONST; -GDK_AVAILABLE_IN_ALL -GtkWidget* gtk_menu_bar_new (void); -GDK_AVAILABLE_IN_ALL -GtkWidget* gtk_menu_bar_new_from_model (GMenuModel *model); - - -G_END_DECLS - - -#endif /* __GTK_MENU_BAR_H__ */ diff --git a/gtk/gtkmenubarprivate.h b/gtk/gtkmenubarprivate.h deleted file mode 100644 index 5c910dfa6b..0000000000 --- a/gtk/gtkmenubarprivate.h +++ /dev/null @@ -1,43 +0,0 @@ -/* GTK - The GIMP Toolkit - * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * 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, see . - */ - -/* - * Modified by the GTK+ Team and others 1997-2000. See the AUTHORS - * file for a list of people on the GTK+ Team. See the ChangeLog - * files for a list of changes. These files are distributed with - * GTK+ at ftp://ftp.gtk.org/pub/gtk/. - */ - -#ifndef __GTK_MENU_BAR_PRIVATE_H__ -#define __GTK_MENU_BAR_PRIVATE_H__ - - -#include - - -G_BEGIN_DECLS - - -void _gtk_menu_bar_cycle_focus (GtkMenuBar *menubar, - GtkDirectionType dir); -GList* _gtk_menu_bar_get_viewable_menu_bars (GtkWindow *window); - - -G_END_DECLS - - -#endif /* __GTK_MENU_BAR_PRIVATE_H__ */ diff --git a/gtk/gtkmenuitem.c b/gtk/gtkmenuitem.c deleted file mode 100644 index 1cd529babf..0000000000 --- a/gtk/gtkmenuitem.c +++ /dev/null @@ -1,1951 +0,0 @@ -/* GTK - The GIMP Toolkit - * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * 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, see . - */ - -/* - * Modified by the GTK+ Team and others 1997-2000. See the AUTHORS - * file for a list of people on the GTK+ Team. See the ChangeLog - * files for a list of changes. These files are distributed with - * GTK+ at ftp://ftp.gtk.org/pub/gtk/. - */ - -#include "config.h" - -#include - -#include "gtkaccellabel.h" -#include "gtklabel.h" -#include "gtkcontainerprivate.h" -#include "gtkmain.h" -#include "gtkmarshalers.h" -#include "gtkmenushellprivate.h" -#include "gtkmenuitemprivate.h" -#include "gtkmenubar.h" -#include "gtkmenuprivate.h" -#include "gtkseparatormenuitem.h" -#include "gtkprivate.h" -#include "gtkbuildable.h" -#include "gtkwidgetprivate.h" -#include "gtkintl.h" -#include "gtksettings.h" -#include "gtktypebuiltins.h" -#include "a11y/gtkmenuitemaccessible.h" -#include "gtkstylecontextprivate.h" -#include "gtkcssstylepropertyprivate.h" -#include "gtkiconprivate.h" -#include "gtknative.h" - -#define MENU_POPUP_DELAY 225 - -/** - * SECTION:gtkmenuitem - * @Short_description: The widget used for item in menus - * @Title: GtkMenuItem - * @See_also: #GtkBin, #GtkMenuShell - * - * The #GtkMenuItem widget and the derived widgets are the only valid - * children for menus. Their function is to correctly handle highlighting, - * alignment, events and submenus. - * - * As a GtkMenuItem derives from #GtkBin it can hold any valid child widget, - * although only a few are really useful. - * - * By default, a GtkMenuItem sets a #GtkAccelLabel as its child. - * GtkMenuItem has direct functions to set the label and its mnemonic. - * For more advanced label settings, you can fetch the child widget from the GtkBin. - * - * An example for setting markup and accelerator on a MenuItem: - * |[ - * GtkWidget *menu_item = gtk_menu_item_new_with_label ("Example Menu Item"); - * - * GtkWidget *child = gtk_bin_get_child (GTK_BIN (menu_item)); - * gtk_label_set_markup (GTK_LABEL (child), "new label with markup"); - * gtk_accel_label_set_accel (GTK_ACCEL_LABEL (child), GDK_KEY_1, 0); - * ]| - * - * # GtkMenuItem as GtkBuildable - * - * The GtkMenuItem implementation of the #GtkBuildable interface supports - * adding a submenu by specifying “submenu” as the “type” attribute of - * a element. - * - * An example of UI definition fragment with submenus: - * |[ - * - * - * - * - * - * ]| - * - * # CSS nodes - * - * |[ - * menuitem - * ├── - * ╰── [arrow.right] - * ]| - * - * GtkMenuItem has a single CSS node with name menuitem. If the menuitem - * has a submenu, it gets another CSS node with name arrow, which has - * the .left or .right style class. - */ - -/* Directions for submenus */ -typedef enum -{ - GTK_DIRECTION_LEFT, - GTK_DIRECTION_RIGHT -} GtkSubmenuDirection; - - -enum { - ACTIVATE, - ACTIVATE_ITEM, - TOGGLE_SIZE_REQUEST, - TOGGLE_SIZE_ALLOCATE, - SELECT, - DESELECT, - LAST_SIGNAL -}; - -enum { - PROP_0, - PROP_SUBMENU, - PROP_ACCEL_PATH, - PROP_LABEL, - PROP_USE_UNDERLINE, - - LAST_PROP, - - PROP_ACTION_NAME, - PROP_ACTION_TARGET -}; - - -static void gtk_menu_item_dispose (GObject *object); -static void gtk_menu_item_set_property (GObject *object, - guint prop_id, - const GValue *value, - GParamSpec *pspec); -static void gtk_menu_item_get_property (GObject *object, - guint prop_id, - GValue *value, - GParamSpec *pspec); -static void gtk_menu_item_destroy (GtkWidget *widget); -static void gtk_menu_item_enter (GtkEventController *controller, - double x, - double y, - GdkCrossingMode mode, - GdkNotifyType detail, - gpointer user_data); -static void gtk_menu_item_leave (GtkEventController *controller, - GdkCrossingMode mode, - GdkNotifyType detail, - gpointer user_data); -static void gtk_menu_item_parent_cb (GObject *object, - GParamSpec *pspec, - gpointer user_data); -static void gtk_menu_item_direction_changed (GtkWidget *widget, - GtkTextDirection previous_dir); - - -static void gtk_real_menu_item_select (GtkMenuItem *item); -static void gtk_real_menu_item_deselect (GtkMenuItem *item); -static void gtk_real_menu_item_activate (GtkMenuItem *item); -static void gtk_real_menu_item_activate_item (GtkMenuItem *item); -static void gtk_real_menu_item_toggle_size_request (GtkMenuItem *menu_item, - gint *requisition); -static void gtk_real_menu_item_toggle_size_allocate (GtkMenuItem *menu_item, - gint allocation); -static gboolean gtk_menu_item_mnemonic_activate (GtkWidget *widget, - gboolean group_cycling); - -static void gtk_menu_item_ensure_label (GtkMenuItem *menu_item); -static gint gtk_menu_item_popup_timeout (gpointer data); - -static void gtk_menu_item_forall (GtkContainer *container, - GtkCallback callback, - gpointer callback_data); - -static gboolean gtk_menu_item_can_activate_accel (GtkWidget *widget, - guint signal_id); - -static void gtk_real_menu_item_set_label (GtkMenuItem *menu_item, - const gchar *label); -static const gchar * gtk_real_menu_item_get_label (GtkMenuItem *menu_item); - -static void gtk_menu_item_buildable_interface_init (GtkBuildableIface *iface); -static void gtk_menu_item_buildable_add_child (GtkBuildable *buildable, - GtkBuilder *builder, - GObject *child, - const gchar *type); -static void gtk_menu_item_buildable_custom_finished(GtkBuildable *buildable, - GtkBuilder *builder, - GObject *child, - const gchar *tagname, - gpointer user_data); - -static void gtk_menu_item_actionable_interface_init (GtkActionableInterface *iface); - -static guint menu_item_signals[LAST_SIGNAL] = { 0 }; -static GParamSpec *menu_item_props[LAST_PROP]; - -static GtkBuildableIface *parent_buildable_iface; - -G_DEFINE_TYPE_WITH_CODE (GtkMenuItem, gtk_menu_item, GTK_TYPE_BIN, - G_ADD_PRIVATE (GtkMenuItem) - G_IMPLEMENT_INTERFACE (GTK_TYPE_BUILDABLE, - gtk_menu_item_buildable_interface_init) - G_IMPLEMENT_INTERFACE (GTK_TYPE_ACTIONABLE, - gtk_menu_item_actionable_interface_init)) - -static void -gtk_menu_item_set_action_name (GtkActionable *actionable, - const gchar *action_name) -{ - GtkMenuItem *menu_item = GTK_MENU_ITEM (actionable); - - if (!menu_item->priv->action_helper) - menu_item->priv->action_helper = gtk_action_helper_new (actionable); - - gtk_action_helper_set_action_name (menu_item->priv->action_helper, action_name); -} - -static void -gtk_menu_item_set_action_target_value (GtkActionable *actionable, - GVariant *action_target) -{ - GtkMenuItem *menu_item = GTK_MENU_ITEM (actionable); - - if (!menu_item->priv->action_helper) - menu_item->priv->action_helper = gtk_action_helper_new (actionable); - - gtk_action_helper_set_action_target_value (menu_item->priv->action_helper, action_target); -} - -static const gchar * -gtk_menu_item_get_action_name (GtkActionable *actionable) -{ - GtkMenuItem *menu_item = GTK_MENU_ITEM (actionable); - - return gtk_action_helper_get_action_name (menu_item->priv->action_helper); -} - -static GVariant * -gtk_menu_item_get_action_target_value (GtkActionable *actionable) -{ - GtkMenuItem *menu_item = GTK_MENU_ITEM (actionable); - - return gtk_action_helper_get_action_target_value (menu_item->priv->action_helper); -} - -static void -gtk_menu_item_actionable_interface_init (GtkActionableInterface *iface) -{ - iface->set_action_name = gtk_menu_item_set_action_name; - iface->get_action_name = gtk_menu_item_get_action_name; - iface->set_action_target_value = gtk_menu_item_set_action_target_value; - iface->get_action_target_value = gtk_menu_item_get_action_target_value; -} - -GtkMenuShell * -gtk_menu_item_get_menu_shell (GtkMenuItem *item) -{ - return GTK_MENU_SHELL (gtk_widget_get_ancestor (GTK_WIDGET (item), GTK_TYPE_MENU_SHELL)); -} - -static void -gtk_menu_item_size_allocate (GtkWidget *widget, - int width, - int height, - int baseline) -{ - GtkMenuItem *menu_item = GTK_MENU_ITEM (widget); - GtkMenuItemPrivate *priv = menu_item->priv; - GtkAllocation child_allocation; - GtkTextDirection direction; - GtkWidget *child; - GtkMenuShell *shell; - - g_return_if_fail (GTK_IS_MENU_ITEM (widget)); - - direction = gtk_widget_get_direction (widget); - - shell = gtk_menu_item_get_menu_shell (menu_item); - - child = gtk_bin_get_child (GTK_BIN (widget)); - if (child) - { - child_allocation = (GtkAllocation) {0, 0, width, height}; - - if (direction == GTK_TEXT_DIR_LTR) - child_allocation.x += priv->toggle_size; - child_allocation.width -= priv->toggle_size; - - if ((priv->submenu && !GTK_IS_MENU_BAR (shell)) || priv->reserve_indicator) - { - GtkAllocation arrow_alloc; - - gtk_widget_measure (priv->arrow_widget, - GTK_ORIENTATION_HORIZONTAL, - -1, - &arrow_alloc.width, NULL, - NULL, NULL); - gtk_widget_measure (priv->arrow_widget, - GTK_ORIENTATION_VERTICAL, - -1, - &arrow_alloc.height, NULL, - NULL, NULL); - - if (direction == GTK_TEXT_DIR_LTR) - { - arrow_alloc.x = child_allocation.x + - child_allocation.width - arrow_alloc.width; - } - else - { - arrow_alloc.x = 0; - child_allocation.x += arrow_alloc.width; - } - - child_allocation.width -= arrow_alloc.width; - arrow_alloc.y = child_allocation.y + - (child_allocation.height - arrow_alloc.height) / 2; - - gtk_widget_size_allocate(priv->arrow_widget, &arrow_alloc, baseline); - } - - child_allocation.width = MAX (1, child_allocation.width); - - gtk_widget_size_allocate (child, &child_allocation, baseline); - } - - if (priv->submenu) - gtk_menu_reposition (GTK_MENU (priv->submenu)); -} - -static void -gtk_menu_item_accel_width_foreach (GtkWidget *widget, - gpointer data) -{ - guint *width = data; - - if (GTK_IS_ACCEL_LABEL (widget)) - { - guint w; - - w = gtk_accel_label_get_accel_width (GTK_ACCEL_LABEL (widget)); - *width = MAX (*width, w); - } - else if (GTK_IS_CONTAINER (widget)) - gtk_container_foreach (GTK_CONTAINER (widget), - gtk_menu_item_accel_width_foreach, - data); -} - -static void -gtk_menu_item_real_get_width (GtkWidget *widget, - gint *minimum_size, - gint *natural_size) -{ - GtkMenuItem *menu_item = GTK_MENU_ITEM (widget); - GtkMenuItemPrivate *priv = menu_item->priv; - GtkWidget *child; - GtkMenuShell *shell; - guint accel_width; - gint min_width, nat_width; - - min_width = nat_width = 0; - - shell = gtk_menu_item_get_menu_shell (menu_item); - child = gtk_bin_get_child (GTK_BIN (widget)); - - if (child != NULL && gtk_widget_get_visible (child)) - { - gint child_min, child_nat; - - gtk_widget_measure (child, GTK_ORIENTATION_HORIZONTAL, -1, - &child_min, &child_nat, NULL, NULL); - - if ((priv->submenu && !GTK_IS_MENU_BAR (shell)) || priv->reserve_indicator) - { - gint arrow_size; - - gtk_widget_measure (priv->arrow_widget, - GTK_ORIENTATION_HORIZONTAL, - -1, - &arrow_size, NULL, - NULL, NULL); - - min_width += arrow_size; - nat_width = min_width; - } - - min_width += child_min; - nat_width += child_nat; - } - - accel_width = 0; - gtk_container_foreach (GTK_CONTAINER (menu_item), - gtk_menu_item_accel_width_foreach, - &accel_width); - priv->accelerator_width = accel_width; - - *minimum_size = min_width; - *natural_size = nat_width; -} - -static void -gtk_menu_item_real_get_height (GtkWidget *widget, - gint for_size, - gint *minimum_size, - gint *natural_size) -{ - GtkMenuItem *menu_item = GTK_MENU_ITEM (widget); - GtkMenuItemPrivate *priv = menu_item->priv; - GtkWidget *child; - GtkMenuShell *shell; - guint accel_width; - gint min_height, nat_height; - gint avail_size = 0; - - min_height = nat_height = 0; - - if (for_size != -1) - avail_size = for_size; - - shell = gtk_menu_item_get_menu_shell (menu_item); - child = gtk_bin_get_child (GTK_BIN (widget)); - - if (child != NULL && gtk_widget_get_visible (child)) - { - gint child_min, child_nat; - gint arrow_size = 0; - - if ((priv->submenu && !GTK_IS_MENU_BAR (shell)) || priv->reserve_indicator) - gtk_widget_measure (priv->arrow_widget, - GTK_ORIENTATION_VERTICAL, - -1, - &arrow_size, NULL, - NULL, NULL); - - if (for_size != -1) - { - avail_size -= arrow_size; - gtk_widget_measure (child, GTK_ORIENTATION_VERTICAL, - avail_size, - &child_min, &child_nat, - NULL, NULL); - } - else - { - gtk_widget_measure (child, GTK_ORIENTATION_VERTICAL, -1, - &child_min, &child_nat, - NULL, NULL); - - } - - min_height += child_min; - nat_height += child_nat; - - min_height = MAX (min_height, arrow_size); - nat_height = MAX (nat_height, arrow_size); - } - - accel_width = 0; - gtk_container_foreach (GTK_CONTAINER (menu_item), - gtk_menu_item_accel_width_foreach, - &accel_width); - priv->accelerator_width = accel_width; - - *minimum_size = min_height; - *natural_size = nat_height; -} - -static void -gtk_menu_item_measure (GtkWidget *widget, - GtkOrientation orientation, - int for_size, - int *minimum, - int *natural, - int *minimum_baseline, - int *natural_baseline) -{ - if (orientation == GTK_ORIENTATION_HORIZONTAL) - gtk_menu_item_real_get_width (widget, minimum, natural); - else - gtk_menu_item_real_get_height (widget, for_size, minimum, natural); -} - - - -static void -gtk_menu_item_class_init (GtkMenuItemClass *klass) -{ - GObjectClass *gobject_class = G_OBJECT_CLASS (klass); - GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass); - GtkContainerClass *container_class = GTK_CONTAINER_CLASS (klass); - - gobject_class->dispose = gtk_menu_item_dispose; - gobject_class->set_property = gtk_menu_item_set_property; - gobject_class->get_property = gtk_menu_item_get_property; - - widget_class->destroy = gtk_menu_item_destroy; - widget_class->size_allocate = gtk_menu_item_size_allocate; - widget_class->mnemonic_activate = gtk_menu_item_mnemonic_activate; - widget_class->can_activate_accel = gtk_menu_item_can_activate_accel; - widget_class->measure = gtk_menu_item_measure; - widget_class->direction_changed = gtk_menu_item_direction_changed; - - container_class->forall = gtk_menu_item_forall; - - klass->activate = gtk_real_menu_item_activate; - 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; - klass->set_label = gtk_real_menu_item_set_label; - klass->get_label = gtk_real_menu_item_get_label; - klass->select = gtk_real_menu_item_select; - klass->deselect = gtk_real_menu_item_deselect; - - klass->hide_on_activate = TRUE; - - /** - * GtkMenuItem::activate: - * @menuitem: the object which received the signal. - * - * Emitted when the item is activated. - */ - menu_item_signals[ACTIVATE] = - g_signal_new (I_("activate"), - G_OBJECT_CLASS_TYPE (gobject_class), - G_SIGNAL_RUN_FIRST | G_SIGNAL_ACTION, - G_STRUCT_OFFSET (GtkMenuItemClass, activate), - NULL, NULL, - NULL, - G_TYPE_NONE, 0); - widget_class->activate_signal = menu_item_signals[ACTIVATE]; - - /** - * GtkMenuItem::activate-item: - * @menuitem: the object which received the signal. - * - * Emitted when the item is activated, but also if the menu item has a - * submenu. For normal applications, the relevant signal is - * #GtkMenuItem::activate. - */ - menu_item_signals[ACTIVATE_ITEM] = - g_signal_new (I_("activate-item"), - G_OBJECT_CLASS_TYPE (gobject_class), - G_SIGNAL_RUN_FIRST, - G_STRUCT_OFFSET (GtkMenuItemClass, activate_item), - NULL, NULL, - NULL, - G_TYPE_NONE, 0); - - menu_item_signals[TOGGLE_SIZE_REQUEST] = - g_signal_new (I_("toggle-size-request"), - G_OBJECT_CLASS_TYPE (gobject_class), - G_SIGNAL_RUN_FIRST, - G_STRUCT_OFFSET (GtkMenuItemClass, toggle_size_request), - NULL, NULL, - NULL, - G_TYPE_NONE, 1, - G_TYPE_POINTER); - - menu_item_signals[TOGGLE_SIZE_ALLOCATE] = - g_signal_new (I_("toggle-size-allocate"), - G_OBJECT_CLASS_TYPE (gobject_class), - G_SIGNAL_RUN_FIRST, - G_STRUCT_OFFSET (GtkMenuItemClass, toggle_size_allocate), - NULL, NULL, - NULL, - G_TYPE_NONE, 1, - G_TYPE_INT); - - menu_item_signals[SELECT] = - g_signal_new (I_("select"), - G_OBJECT_CLASS_TYPE (gobject_class), - G_SIGNAL_RUN_FIRST, - G_STRUCT_OFFSET (GtkMenuItemClass, select), - NULL, NULL, - NULL, - G_TYPE_NONE, 0); - - menu_item_signals[DESELECT] = - g_signal_new (I_("deselect"), - G_OBJECT_CLASS_TYPE (gobject_class), - G_SIGNAL_RUN_FIRST, - G_STRUCT_OFFSET (GtkMenuItemClass, deselect), - NULL, NULL, - NULL, - G_TYPE_NONE, 0); - - /** - * GtkMenuItem:submenu: - * - * The submenu attached to the menu item, or %NULL if it has none. - */ - menu_item_props[PROP_SUBMENU] = - g_param_spec_object ("submenu", - P_("Submenu"), - P_("The submenu attached to the menu item, or NULL if it has none"), - GTK_TYPE_MENU, - GTK_PARAM_READWRITE); - - /** - * GtkMenuItem:accel-path: - * - * Sets the accelerator path of the menu item, through which runtime - * changes of the menu item's accelerator caused by the user can be - * identified and saved to persistant storage. - */ - menu_item_props[PROP_ACCEL_PATH] = - g_param_spec_string ("accel-path", - P_("Accel Path"), - P_("Sets the accelerator path of the menu item"), - NULL, - GTK_PARAM_READWRITE); - - /** - * GtkMenuItem:label: - * - * The text for the child label. - */ - menu_item_props[PROP_LABEL] = - g_param_spec_string ("label", - P_("Label"), - P_("The text for the child label"), - "", - GTK_PARAM_READWRITE); - - /** - * GtkMenuItem:use-underline: - * - * %TRUE if underlines in the text indicate mnemonics. - */ - menu_item_props[PROP_USE_UNDERLINE] = - g_param_spec_boolean ("use-underline", - P_("Use underline"), - P_("If set, an underline in the text indicates " - "the next character should be used for the " - "mnemonic accelerator key"), - FALSE, - GTK_PARAM_READWRITE|G_PARAM_EXPLICIT_NOTIFY); - - g_object_class_install_properties (gobject_class, LAST_PROP, menu_item_props); - - g_object_class_override_property (gobject_class, PROP_ACTION_NAME, "action-name"); - g_object_class_override_property (gobject_class, PROP_ACTION_TARGET, "action-target"); - - gtk_widget_class_set_accessible_type (widget_class, GTK_TYPE_MENU_ITEM_ACCESSIBLE); - gtk_widget_class_set_css_name (widget_class, I_("menuitem")); -} - -static void -gtk_menu_item_init (GtkMenuItem *menu_item) -{ - GtkEventController *controller; - GtkMenuItemPrivate *priv; - - priv = gtk_menu_item_get_instance_private (menu_item); - menu_item->priv = priv; - - g_signal_connect (menu_item, "notify::parent", G_CALLBACK (gtk_menu_item_parent_cb), NULL); - - priv->submenu = NULL; - priv->toggle_size = 0; - priv->accelerator_width = 0; - if (gtk_widget_get_direction (GTK_WIDGET (menu_item)) == GTK_TEXT_DIR_RTL) - priv->submenu_direction = GTK_DIRECTION_LEFT; - else - priv->submenu_direction = GTK_DIRECTION_RIGHT; - priv->submenu_placement = GTK_TOP_BOTTOM; - priv->timer = 0; - - controller = gtk_event_controller_motion_new (); - g_signal_connect (controller, "enter", G_CALLBACK (gtk_menu_item_enter), menu_item); - g_signal_connect (controller, "leave", G_CALLBACK (gtk_menu_item_leave), menu_item); - gtk_widget_add_controller (GTK_WIDGET (menu_item), controller); -} - -/** - * gtk_menu_item_new: - * - * Creates a new #GtkMenuItem. - * - * Returns: the newly created #GtkMenuItem - */ -GtkWidget* -gtk_menu_item_new (void) -{ - return g_object_new (GTK_TYPE_MENU_ITEM, NULL); -} - -/** - * gtk_menu_item_new_with_label: - * @label: the text for the label - * - * Creates a new #GtkMenuItem whose child is a #GtkLabel. - * - * Returns: the newly created #GtkMenuItem - */ -GtkWidget* -gtk_menu_item_new_with_label (const gchar *label) -{ - return g_object_new (GTK_TYPE_MENU_ITEM, - "label", label, - NULL); -} - - -/** - * gtk_menu_item_new_with_mnemonic: - * @label: The text of the button, with an underscore in front of the - * mnemonic character - * - * Creates a new #GtkMenuItem containing a label. - * - * The label will be created using gtk_label_new_with_mnemonic(), - * so underscores in @label indicate the mnemonic for the menu item. - * - * Returns: a new #GtkMenuItem - */ -GtkWidget* -gtk_menu_item_new_with_mnemonic (const gchar *label) -{ - return g_object_new (GTK_TYPE_MENU_ITEM, - "use-underline", TRUE, - "label", label, - NULL); -} - -static void -gtk_menu_item_dispose (GObject *object) -{ - GtkMenuItem *menu_item = GTK_MENU_ITEM (object); - GtkMenuItemPrivate *priv = menu_item->priv; - - g_clear_object (&priv->action_helper); - g_clear_pointer (&priv->arrow_widget, gtk_widget_unparent); - - G_OBJECT_CLASS (gtk_menu_item_parent_class)->dispose (object); -} - -static void -gtk_menu_item_set_property (GObject *object, - guint prop_id, - const GValue *value, - GParamSpec *pspec) -{ - GtkMenuItem *menu_item = GTK_MENU_ITEM (object); - - switch (prop_id) - { - case PROP_SUBMENU: - gtk_menu_item_set_submenu (menu_item, g_value_get_object (value)); - break; - case PROP_ACCEL_PATH: - gtk_menu_item_set_accel_path (menu_item, g_value_get_string (value)); - break; - case PROP_LABEL: - gtk_menu_item_set_label (menu_item, g_value_get_string (value)); - break; - case PROP_USE_UNDERLINE: - gtk_menu_item_set_use_underline (menu_item, g_value_get_boolean (value)); - break; - case PROP_ACTION_NAME: - gtk_menu_item_set_action_name (GTK_ACTIONABLE (menu_item), g_value_get_string (value)); - break; - case PROP_ACTION_TARGET: - gtk_menu_item_set_action_target_value (GTK_ACTIONABLE (menu_item), g_value_get_variant (value)); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; - } -} - -static void -gtk_menu_item_get_property (GObject *object, - guint prop_id, - GValue *value, - GParamSpec *pspec) -{ - GtkMenuItem *menu_item = GTK_MENU_ITEM (object); - GtkMenuItemPrivate *priv = menu_item->priv; - - switch (prop_id) - { - case PROP_SUBMENU: - g_value_set_object (value, gtk_menu_item_get_submenu (menu_item)); - break; - case PROP_ACCEL_PATH: - g_value_set_string (value, gtk_menu_item_get_accel_path (menu_item)); - break; - case PROP_LABEL: - g_value_set_string (value, gtk_menu_item_get_label (menu_item)); - break; - case PROP_USE_UNDERLINE: - g_value_set_boolean (value, gtk_menu_item_get_use_underline (menu_item)); - break; - case PROP_ACTION_NAME: - g_value_set_string (value, gtk_action_helper_get_action_name (priv->action_helper)); - break; - case PROP_ACTION_TARGET: - g_value_set_variant (value, gtk_action_helper_get_action_target_value (priv->action_helper)); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; - } -} - -static void -gtk_menu_item_destroy (GtkWidget *widget) -{ - GtkMenuItem *menu_item = GTK_MENU_ITEM (widget); - GtkMenuItemPrivate *priv = menu_item->priv; - - if (priv->submenu) - gtk_widget_destroy (priv->submenu); - - GTK_WIDGET_CLASS (gtk_menu_item_parent_class)->destroy (widget); -} - -static void -gtk_menu_item_detacher (GtkWidget *widget, - GtkMenu *menu) -{ - GtkMenuItem *menu_item = GTK_MENU_ITEM (widget); - GtkMenuItemPrivate *priv = menu_item->priv; - - g_return_if_fail (priv->submenu == (GtkWidget*) menu); - - priv->submenu = NULL; - g_clear_pointer (&priv->arrow_widget, gtk_widget_unparent); -} - -static void -gtk_menu_item_buildable_interface_init (GtkBuildableIface *iface) -{ - parent_buildable_iface = g_type_interface_peek_parent (iface); - iface->add_child = gtk_menu_item_buildable_add_child; - iface->custom_finished = gtk_menu_item_buildable_custom_finished; -} - -static void -gtk_menu_item_buildable_add_child (GtkBuildable *buildable, - GtkBuilder *builder, - GObject *child, - const gchar *type) -{ - if (type && strcmp (type, "submenu") == 0) - gtk_menu_item_set_submenu (GTK_MENU_ITEM (buildable), - GTK_WIDGET (child)); - else - parent_buildable_iface->add_child (buildable, builder, child, type); -} - - -static void -gtk_menu_item_buildable_custom_finished (GtkBuildable *buildable, - GtkBuilder *builder, - GObject *child, - const gchar *tagname, - gpointer user_data) -{ - GtkWidget *toplevel; - - if (strcmp (tagname, "accelerator") == 0) - { - GtkMenuShell *menu_shell; - GtkWidget *attach; - - menu_shell = gtk_menu_item_get_menu_shell (GTK_MENU_ITEM (buildable)); - if (menu_shell) - { - while (GTK_IS_MENU (menu_shell) && - (attach = gtk_menu_get_attach_widget (GTK_MENU (menu_shell))) != NULL) - menu_shell = GTK_MENU_SHELL (gtk_widget_get_parent (attach)); - - toplevel = GTK_WIDGET (gtk_widget_get_root (GTK_WIDGET (menu_shell))); - } - else - { - /* Fall back to something ... */ - toplevel = GTK_WIDGET (gtk_widget_get_root (GTK_WIDGET (buildable))); - - g_warning ("found a GtkMenuItem '%s' without a parent GtkMenuShell, assigned accelerators wont work.", - gtk_buildable_get_name (buildable)); - } - - /* Feed the correct toplevel to the GtkWidget accelerator parsing code */ - _gtk_widget_buildable_finish_accelerator (GTK_WIDGET (buildable), toplevel, user_data); - } - else - parent_buildable_iface->custom_finished (buildable, builder, child, tagname, user_data); -} - -static void -update_arrow_classes (GtkMenuItem *menu_item) -{ - GtkMenuItemPrivate *priv = menu_item->priv; - GtkStyleContext *context; - GtkWidget *child; - - if (!priv->arrow_widget) - return; - - context = gtk_widget_get_style_context (priv->arrow_widget); - - if (gtk_widget_get_direction (GTK_WIDGET (menu_item)) == GTK_TEXT_DIR_RTL) - { - gtk_style_context_add_class (context, GTK_STYLE_CLASS_LEFT); - gtk_style_context_remove_class (context, GTK_STYLE_CLASS_RIGHT); - - child = gtk_widget_get_first_child (GTK_WIDGET (menu_item)); - - if (child != priv->arrow_widget) - gtk_widget_insert_after (priv->arrow_widget, GTK_WIDGET (menu_item), NULL); - } - else - { - gtk_style_context_add_class (context, GTK_STYLE_CLASS_RIGHT); - gtk_style_context_remove_class (context, GTK_STYLE_CLASS_LEFT); - - child = gtk_widget_get_last_child (GTK_WIDGET (menu_item)); - - if (child != priv->arrow_widget) - gtk_widget_insert_before (priv->arrow_widget, GTK_WIDGET (menu_item), NULL); - } -} - -static void -update_arrow_widget (GtkMenuItem *menu_item) -{ - GtkMenuItemPrivate *priv = menu_item->priv; - GtkWidget *widget = GTK_WIDGET (menu_item); - gboolean should_have_arrow; - - should_have_arrow = priv->reserve_indicator || - (priv->submenu && !GTK_IS_MENU_BAR (gtk_menu_item_get_menu_shell (menu_item))); - - if (should_have_arrow) - { - if (!priv->arrow_widget) - { - priv->arrow_widget = gtk_icon_new ("arrow"); - gtk_widget_set_parent (priv->arrow_widget, widget); - } - } - else if (priv->arrow_widget) - { - gtk_widget_unparent (priv->arrow_widget); - priv->arrow_widget = NULL; - } -} - -/** - * gtk_menu_item_set_submenu: - * @menu_item: a #GtkMenuItem - * @submenu: (allow-none) (type Gtk.Menu): the submenu, or %NULL - * - * Sets or replaces the menu item’s submenu, or removes it when a %NULL - * submenu is passed. - */ -void -gtk_menu_item_set_submenu (GtkMenuItem *menu_item, - GtkWidget *submenu) -{ - GtkWidget *widget; - GtkMenuItemPrivate *priv; - - g_return_if_fail (GTK_IS_MENU_ITEM (menu_item)); - g_return_if_fail (submenu == NULL || GTK_IS_MENU (submenu)); - - widget = GTK_WIDGET (menu_item); - priv = menu_item->priv; - - if (priv->submenu != submenu) - { - if (priv->submenu) - { - gtk_menu_detach (GTK_MENU (priv->submenu)); - priv->submenu = NULL; - } - - if (submenu) - { - priv->submenu = submenu; - gtk_menu_attach_to_widget (GTK_MENU (submenu), - widget, - gtk_menu_item_detacher); - } - - update_arrow_widget (menu_item); - gtk_widget_queue_resize (widget); - - g_object_notify_by_pspec (G_OBJECT (menu_item), menu_item_props[PROP_SUBMENU]); - } -} - -/** - * gtk_menu_item_get_submenu: - * @menu_item: a #GtkMenuItem - * - * Gets the submenu underneath this menu item, if any. - * See gtk_menu_item_set_submenu(). - * - * Returns: (nullable) (transfer none): submenu for this menu item, or %NULL if none - */ -GtkWidget * -gtk_menu_item_get_submenu (GtkMenuItem *menu_item) -{ - g_return_val_if_fail (GTK_IS_MENU_ITEM (menu_item), NULL); - - return menu_item->priv->submenu; -} - -void _gtk_menu_item_set_placement (GtkMenuItem *menu_item, - GtkSubmenuPlacement placement); - -void -_gtk_menu_item_set_placement (GtkMenuItem *menu_item, - GtkSubmenuPlacement placement) -{ - g_return_if_fail (GTK_IS_MENU_ITEM (menu_item)); - - menu_item->priv->submenu_placement = placement; -} - -/** - * gtk_menu_item_select: - * @menu_item: the menu item - * - * Emits the #GtkMenuItem::select signal on the given item. - */ -void -gtk_menu_item_select (GtkMenuItem *menu_item) -{ - g_return_if_fail (GTK_IS_MENU_ITEM (menu_item)); - - g_signal_emit (menu_item, menu_item_signals[SELECT], 0); -} - -/** - * gtk_menu_item_deselect: - * @menu_item: the menu item - * - * Emits the #GtkMenuItem::deselect signal on the given item. - */ -void -gtk_menu_item_deselect (GtkMenuItem *menu_item) -{ - g_return_if_fail (GTK_IS_MENU_ITEM (menu_item)); - - g_signal_emit (menu_item, menu_item_signals[DESELECT], 0); -} - -/** - * gtk_menu_item_activate: - * @menu_item: the menu item - * - * Emits the #GtkMenuItem::activate signal on the given item - */ -void -gtk_menu_item_activate (GtkMenuItem *menu_item) -{ - g_return_if_fail (GTK_IS_MENU_ITEM (menu_item)); - - g_signal_emit (menu_item, menu_item_signals[ACTIVATE], 0); -} - -/** - * gtk_menu_item_toggle_size_request: - * @menu_item: the menu item - * @requisition: (inout): the requisition to use as signal data. - * - * Emits the #GtkMenuItem::toggle-size-request signal on the given item. - */ -void -gtk_menu_item_toggle_size_request (GtkMenuItem *menu_item, - gint *requisition) -{ - g_return_if_fail (GTK_IS_MENU_ITEM (menu_item)); - - g_signal_emit (menu_item, menu_item_signals[TOGGLE_SIZE_REQUEST], 0, requisition); -} - -/** - * gtk_menu_item_toggle_size_allocate: - * @menu_item: the menu item. - * @allocation: the allocation to use as signal data. - * - * Emits the #GtkMenuItem::toggle-size-allocate signal on the given item. - */ -void -gtk_menu_item_toggle_size_allocate (GtkMenuItem *menu_item, - gint allocation) -{ - g_return_if_fail (GTK_IS_MENU_ITEM (menu_item)); - - g_signal_emit (menu_item, menu_item_signals[TOGGLE_SIZE_ALLOCATE], 0, allocation); -} - -static void -gtk_menu_item_enter (GtkEventController *controller, - double x, - double y, - GdkCrossingMode mode, - GdkNotifyType detail, - gpointer user_data) -{ - GtkMenuItem *menu_item = GTK_MENU_ITEM (user_data); - GtkMenuShell *menu_shell; - GdkEvent *event; - - event = gtk_get_current_event (); /* FIXME controller event */ - - if (mode == GDK_CROSSING_GTK_GRAB || - mode == GDK_CROSSING_GTK_UNGRAB || - mode == GDK_CROSSING_STATE_CHANGED) - return; - - if (gdk_event_get_device ((GdkEvent*) event) == - gdk_event_get_source_device ((GdkEvent*) event)) - return; - - menu_shell = gtk_menu_item_get_menu_shell (menu_item); - - if (menu_shell != NULL && - menu_shell->priv->active && - gtk_event_controller_motion_contains_pointer (GTK_EVENT_CONTROLLER_MOTION (controller))) - gtk_menu_shell_select_item (menu_shell, GTK_WIDGET (menu_item)); -} - -static void -gtk_menu_item_leave (GtkEventController *controller, - GdkCrossingMode mode, - GdkNotifyType detail, - gpointer user_data) -{ - GtkMenuItem *menu_item = GTK_MENU_ITEM (user_data); - GtkMenuShell *menu_shell = gtk_menu_item_get_menu_shell (menu_item); - - if (menu_shell && - !menu_item->priv->submenu && - !gtk_event_controller_motion_contains_pointer (GTK_EVENT_CONTROLLER_MOTION (controller))) - gtk_menu_shell_deselect (menu_shell); -} - -static void -gtk_real_menu_item_select (GtkMenuItem *menu_item) -{ - GtkMenuItemPrivate *priv = menu_item->priv; - GdkDevice *source_device = NULL; - GdkEvent *current_event; - - current_event = gtk_get_current_event (); - - if (current_event) - { - source_device = gdk_event_get_source_device (current_event); - g_object_unref (current_event); - } - - if ((!source_device || - gdk_device_get_source (source_device) != GDK_SOURCE_TOUCHSCREEN) && - priv->submenu && - !gtk_widget_get_mapped (priv->submenu)) - { - _gtk_menu_item_popup_submenu (GTK_WIDGET (menu_item), TRUE); - } - - gtk_widget_set_state_flags (GTK_WIDGET (menu_item), - GTK_STATE_FLAG_PRELIGHT, FALSE); -} - -static void -gtk_real_menu_item_deselect (GtkMenuItem *menu_item) -{ - GtkMenuItemPrivate *priv = menu_item->priv; - - if (priv->submenu) - _gtk_menu_item_popdown_submenu (GTK_WIDGET (menu_item)); - - gtk_widget_unset_state_flags (GTK_WIDGET (menu_item), - GTK_STATE_FLAG_PRELIGHT); -} - -static gboolean -gtk_menu_item_mnemonic_activate (GtkWidget *widget, - gboolean group_cycling) -{ - GtkMenuShell *menu_shell; - - menu_shell = gtk_menu_item_get_menu_shell (GTK_MENU_ITEM (widget)); - - if (menu_shell) - _gtk_menu_shell_set_keyboard_mode (menu_shell, TRUE); - - if (group_cycling && - menu_shell && - menu_shell->priv->active) - { - gtk_menu_shell_select_item (menu_shell, widget); - } - else - g_signal_emit (widget, menu_item_signals[ACTIVATE_ITEM], 0); - - return TRUE; -} - -static void -gtk_real_menu_item_activate (GtkMenuItem *menu_item) -{ - GtkMenuItemPrivate *priv = menu_item->priv; - - if (priv->action_helper) - gtk_action_helper_activate (priv->action_helper); -} - - -static void -gtk_real_menu_item_activate_item (GtkMenuItem *menu_item) -{ - GtkMenuItemPrivate *priv = menu_item->priv; - GtkMenuShell *menu_shell; - GtkWidget *widget; - - widget = GTK_WIDGET (menu_item); - menu_shell = gtk_menu_item_get_menu_shell (menu_item); - - if (menu_shell) - { - if (priv->submenu == NULL) - gtk_menu_shell_activate_item (menu_shell, widget, TRUE); - else - { - gtk_menu_shell_select_item (menu_shell, widget); - _gtk_menu_item_popup_submenu (widget, FALSE); - - gtk_menu_shell_select_first (GTK_MENU_SHELL (priv->submenu), TRUE); - } - } -} - -static void -gtk_real_menu_item_toggle_size_request (GtkMenuItem *menu_item, - gint *requisition) -{ - g_return_if_fail (GTK_IS_MENU_ITEM (menu_item)); - - *requisition = 0; -} - -static void -gtk_real_menu_item_toggle_size_allocate (GtkMenuItem *menu_item, - gint allocation) -{ - g_return_if_fail (GTK_IS_MENU_ITEM (menu_item)); - - menu_item->priv->toggle_size = allocation; -} - -static void -gtk_real_menu_item_set_label (GtkMenuItem *menu_item, - const gchar *label) -{ - GtkWidget *child; - - gtk_menu_item_ensure_label (menu_item); - - child = gtk_bin_get_child (GTK_BIN (menu_item)); - if (GTK_IS_LABEL (child) || - GTK_IS_ACCEL_LABEL (child)) - { - g_object_set (child, "label", label ? label : "", NULL); - - g_object_notify_by_pspec (G_OBJECT (menu_item), menu_item_props[PROP_LABEL]); - } -} - -static const gchar * -gtk_real_menu_item_get_label (GtkMenuItem *menu_item) -{ - GtkWidget *child; - - gtk_menu_item_ensure_label (menu_item); - - child = gtk_bin_get_child (GTK_BIN (menu_item)); - if (GTK_IS_LABEL (child)) - return gtk_label_get_label (GTK_LABEL (child)); - else if (GTK_IS_ACCEL_LABEL (child)) - return gtk_accel_label_get_label (GTK_ACCEL_LABEL (child)); - - return NULL; -} - -static void -free_timeval (GTimeVal *val) -{ - g_slice_free (GTimeVal, val); -} - -static void -popped_up_cb (GtkMenu *menu, - const GdkRectangle *flipped_rect, - const GdkRectangle *final_rect, - gboolean flipped_x, - gboolean flipped_y, - GtkMenuItem *menu_item) -{ - GtkMenuShell *menu_shell = gtk_menu_item_get_menu_shell (menu_item); - GtkMenu *parent_menu = GTK_IS_MENU (menu_shell) ? GTK_MENU (menu_shell) : NULL; - - if (parent_menu && GTK_IS_MENU_ITEM (parent_menu->priv->parent_menu_item)) - menu_item->priv->submenu_direction = GTK_MENU_ITEM (parent_menu->priv->parent_menu_item)->priv->submenu_direction; - else - { - /* this case is stateful, do it at most once */ - g_signal_handlers_disconnect_by_func (menu, popped_up_cb, menu_item); - } - - if (flipped_x) - { - switch (menu_item->priv->submenu_direction) - { - case GTK_DIRECTION_LEFT: - menu_item->priv->submenu_direction = GTK_DIRECTION_RIGHT; - break; - - case GTK_DIRECTION_RIGHT: - default: - menu_item->priv->submenu_direction = GTK_DIRECTION_LEFT; - break; - } - } -} - -static void -gtk_menu_item_real_popup_submenu (GtkWidget *widget, - const GdkEvent *trigger_event, - gboolean remember_exact_time) -{ - GtkMenuItem *menu_item = GTK_MENU_ITEM (widget); - GtkMenuItemPrivate *priv = menu_item->priv; - GtkSubmenuDirection submenu_direction; - GtkStyleContext *context; - GtkBorder parent_padding; - GtkBorder menu_padding; - gint horizontal_offset; - gint vertical_offset; - GtkMenuShell *menu_shell; - GtkMenu *parent_menu; - - menu_shell = gtk_menu_item_get_menu_shell (menu_item); - parent_menu = GTK_IS_MENU (menu_shell) ? GTK_MENU (menu_shell) : NULL; - - if (gtk_widget_is_sensitive (priv->submenu) && menu_shell) - { - gboolean take_focus; - - take_focus = gtk_menu_shell_get_take_focus (menu_shell); - gtk_menu_shell_set_take_focus (GTK_MENU_SHELL (priv->submenu), take_focus); - - if (remember_exact_time) - { - GTimeVal *popup_time = g_slice_new0 (GTimeVal); - - g_get_current_time (popup_time); - - g_object_set_data_full (G_OBJECT (priv->submenu), - "gtk-menu-exact-popup-time", popup_time, - (GDestroyNotify) free_timeval); - } - else - { - g_object_set_data (G_OBJECT (priv->submenu), - "gtk-menu-exact-popup-time", NULL); - } - - /* Position the submenu at the menu item if it is mapped. - * Otherwise, position the submenu at the pointer device. - */ - if (gtk_native_get_surface (gtk_widget_get_native (widget))) - { - switch (priv->submenu_placement) - { - case GTK_TOP_BOTTOM: - g_object_set (priv->submenu, - "anchor-hints", (GDK_ANCHOR_FLIP_Y | - GDK_ANCHOR_SLIDE | - GDK_ANCHOR_RESIZE), - "menu-type-hint", (priv->from_menubar ? - GDK_SURFACE_TYPE_HINT_DROPDOWN_MENU : - GDK_SURFACE_TYPE_HINT_POPUP_MENU), - NULL); - - gtk_menu_popup_at_widget (GTK_MENU (priv->submenu), - widget, - GDK_GRAVITY_SOUTH_WEST, - GDK_GRAVITY_NORTH_WEST, - trigger_event); - - break; - - case GTK_LEFT_RIGHT: - default: - if (parent_menu && GTK_IS_MENU_ITEM (parent_menu->priv->parent_menu_item)) - submenu_direction = GTK_MENU_ITEM (parent_menu->priv->parent_menu_item)->priv->submenu_direction; - else - submenu_direction = priv->submenu_direction; - - g_signal_handlers_disconnect_by_func (priv->submenu, popped_up_cb, menu_item); - g_signal_connect (priv->submenu, "popped-up", G_CALLBACK (popped_up_cb), menu_item); - - horizontal_offset = 0; - vertical_offset = 0; - - context = gtk_widget_get_style_context (GTK_WIDGET (menu_shell)); - gtk_style_context_get_padding (context, &parent_padding); - context = gtk_widget_get_style_context (priv->submenu); - gtk_style_context_get_padding (context, &menu_padding); - - g_object_set (priv->submenu, - "anchor-hints", (GDK_ANCHOR_FLIP_X | - GDK_ANCHOR_SLIDE | - GDK_ANCHOR_RESIZE), - "rect-anchor-dy", vertical_offset - menu_padding.top, - NULL); - - switch (submenu_direction) - { - case GTK_DIRECTION_RIGHT: - default: - g_object_set (priv->submenu, - "rect-anchor-dx", horizontal_offset + parent_padding.right + menu_padding.left, - NULL); - - gtk_menu_popup_at_widget (GTK_MENU (priv->submenu), - widget, - GDK_GRAVITY_NORTH_EAST, - GDK_GRAVITY_NORTH_WEST, - trigger_event); - - break; - - case GTK_DIRECTION_LEFT: - g_object_set (priv->submenu, - "rect-anchor-dx", -(horizontal_offset + parent_padding.left + menu_padding.right), - NULL); - - gtk_menu_popup_at_widget (GTK_MENU (priv->submenu), - widget, - GDK_GRAVITY_NORTH_WEST, - GDK_GRAVITY_NORTH_EAST, - trigger_event); - - break; - } - - break; - } - } - else - gtk_menu_popup_at_pointer (GTK_MENU (priv->submenu), trigger_event); - } - - /* Enable themeing of the parent menu item depending on whether - * its submenu is shown or not. - */ - gtk_widget_queue_draw (widget); -} - -typedef struct -{ - GtkMenuItem *menu_item; - GdkEvent *trigger_event; -} PopupInfo; - -static gint -gtk_menu_item_popup_timeout (gpointer data) -{ - PopupInfo *info = data; - GtkMenuItem *menu_item = info->menu_item; - GtkMenuItemPrivate *priv = menu_item->priv; - GtkMenuShell *menu_shell; - - menu_shell = gtk_menu_item_get_menu_shell (menu_item); - - if (menu_shell && menu_shell->priv->active) - gtk_menu_item_real_popup_submenu (GTK_WIDGET (menu_item), info->trigger_event, TRUE); - - priv->timer = 0; - - g_clear_object (&info->trigger_event); - g_slice_free (PopupInfo, info); - - return FALSE; -} - -static gint -get_popup_delay (GtkWidget *widget) -{ - GtkMenuShell *menu_shell; - - menu_shell = gtk_menu_item_get_menu_shell (GTK_MENU_ITEM (widget)); - if (menu_shell) - return _gtk_menu_shell_get_popup_delay (menu_shell); - else - return MENU_POPUP_DELAY; -} - -void -_gtk_menu_item_popup_submenu (GtkWidget *widget, - gboolean with_delay) -{ - GtkMenuItem *menu_item = GTK_MENU_ITEM (widget); - GtkMenuItemPrivate *priv = menu_item->priv; - - if (priv->timer) - { - g_source_remove (priv->timer); - priv->timer = 0; - with_delay = FALSE; - } - - if (with_delay) - { - gint popup_delay = get_popup_delay (widget); - - if (popup_delay > 0) - { - PopupInfo *info = g_slice_new (PopupInfo); - - info->menu_item = menu_item; - info->trigger_event = gtk_get_current_event (); - - priv->timer = g_timeout_add (popup_delay, gtk_menu_item_popup_timeout, info); - g_source_set_name_by_id (priv->timer, "[gtk] gtk_menu_item_popup_timeout"); - - return; - } - } - - gtk_menu_item_real_popup_submenu (widget, NULL, FALSE); -} - -void -_gtk_menu_item_popdown_submenu (GtkWidget *widget) -{ - GtkMenuItem *menu_item = GTK_MENU_ITEM (widget); - GtkMenuItemPrivate *priv = menu_item->priv; - - if (priv->submenu) - { - g_object_set_data (G_OBJECT (priv->submenu), - "gtk-menu-exact-popup-time", NULL); - - if (priv->timer) - { - g_source_remove (priv->timer); - priv->timer = 0; - } - else - gtk_menu_popdown (GTK_MENU (priv->submenu)); - - gtk_widget_queue_draw (widget); - } -} - -static gboolean -gtk_menu_item_can_activate_accel (GtkWidget *widget, - guint signal_id) -{ - GtkMenuShell *menu_shell; - - menu_shell = gtk_menu_item_get_menu_shell (GTK_MENU_ITEM (widget)); - - /* Chain to the parent GtkMenu for further checks */ - return (gtk_widget_is_sensitive (widget) && gtk_widget_get_visible (widget) && - menu_shell && gtk_widget_can_activate_accel (GTK_WIDGET (menu_shell), signal_id)); -} - -static void -gtk_menu_item_accel_name_foreach (GtkWidget *widget, - gpointer data) -{ - const gchar **path_p = data; - - if (!*path_p) - { - if (GTK_IS_LABEL (widget)) - { - *path_p = gtk_label_get_text (GTK_LABEL (widget)); - if (*path_p && (*path_p)[0] == 0) - *path_p = NULL; - } - else if (GTK_IS_CONTAINER (widget)) - gtk_container_foreach (GTK_CONTAINER (widget), - gtk_menu_item_accel_name_foreach, - data); - } -} - -static void -gtk_menu_item_parent_cb (GObject *object, - GParamSpec *pspec, - gpointer user_data) -{ - GtkMenuItem *menu_item = GTK_MENU_ITEM (object); - GtkMenu *menu; - GtkMenuShell *menu_shell; - - menu_shell = gtk_menu_item_get_menu_shell (menu_item); - menu = GTK_IS_MENU (menu_shell) ? GTK_MENU (menu_shell) : NULL; - - if (menu) - _gtk_menu_item_refresh_accel_path (menu_item, - menu->priv->accel_path, - menu->priv->accel_group, - TRUE); - - update_arrow_widget (menu_item); -} - -static void -gtk_menu_item_direction_changed (GtkWidget *widget, - GtkTextDirection previous_dir) -{ - GtkMenuItem *menu_item = GTK_MENU_ITEM (widget); - - update_arrow_classes (menu_item); - - GTK_WIDGET_CLASS (gtk_menu_item_parent_class)->direction_changed (widget, previous_dir); -} - -void -_gtk_menu_item_refresh_accel_path (GtkMenuItem *menu_item, - const gchar *prefix, - GtkAccelGroup *accel_group, - gboolean group_changed) -{ - GtkMenuItemPrivate *priv = menu_item->priv; - const gchar *path; - GtkWidget *widget; - - g_return_if_fail (GTK_IS_MENU_ITEM (menu_item)); - g_return_if_fail (!accel_group || GTK_IS_ACCEL_GROUP (accel_group)); - - widget = GTK_WIDGET (menu_item); - - if (!accel_group) - { - gtk_widget_set_accel_path (widget, NULL, NULL); - return; - } - - path = _gtk_widget_get_accel_path (widget, NULL); - if (!path) /* no active accel_path yet */ - { - path = priv->accel_path; - if (!path && prefix) - { - const gchar *postfix = NULL; - gchar *new_path; - - /* try to construct one from label text */ - gtk_container_foreach (GTK_CONTAINER (menu_item), - gtk_menu_item_accel_name_foreach, - &postfix); - if (postfix) - { - new_path = g_strconcat (prefix, "/", postfix, NULL); - path = priv->accel_path = g_intern_string (new_path); - g_free (new_path); - } - } - if (path) - gtk_widget_set_accel_path (widget, path, accel_group); - } - else if (group_changed) /* reinstall accelerators */ - gtk_widget_set_accel_path (widget, path, accel_group); -} - -/** - * gtk_menu_item_set_accel_path: - * @menu_item: a valid #GtkMenuItem - * @accel_path: (allow-none): accelerator path, corresponding to this menu - * item’s functionality, or %NULL to unset the current path. - * - * Set the accelerator path on @menu_item, through which runtime - * changes of the menu item’s accelerator caused by the user can be - * identified and saved to persistent storage (see gtk_accel_map_save() - * on this). To set up a default accelerator for this menu item, call - * gtk_accel_map_add_entry() with the same @accel_path. See also - * gtk_accel_map_add_entry() on the specifics of accelerator paths, - * and gtk_menu_set_accel_path() for a more convenient variant of - * this function. - * - * This function is basically a convenience wrapper that handles - * calling gtk_widget_set_accel_path() with the appropriate accelerator - * group for the menu item. - * - * Note that you do need to set an accelerator on the parent menu with - * gtk_menu_set_accel_group() for this to work. - * - * Note that @accel_path string will be stored in a #GQuark. - * Therefore, if you pass a static string, you can save some memory - * by interning it first with g_intern_static_string(). - */ -void -gtk_menu_item_set_accel_path (GtkMenuItem *menu_item, - const gchar *accel_path) -{ - GtkMenuItemPrivate *priv = menu_item->priv; - GtkWidget *widget; - GtkMenuShell *menu_shell; - - g_return_if_fail (GTK_IS_MENU_ITEM (menu_item)); - g_return_if_fail (accel_path == NULL || - (accel_path[0] == '<' && strchr (accel_path, '/'))); - - widget = GTK_WIDGET (menu_item); - - /* store new path */ - priv->accel_path = g_intern_string (accel_path); - - /* forget accelerators associated with old path */ - gtk_widget_set_accel_path (widget, NULL, NULL); - - /* install accelerators associated with new path */ - menu_shell = gtk_menu_item_get_menu_shell (menu_item); - if (GTK_IS_MENU (menu_shell)) - { - GtkMenu *menu = GTK_MENU (menu_shell); - - if (menu->priv->accel_group) - _gtk_menu_item_refresh_accel_path (GTK_MENU_ITEM (widget), - NULL, - menu->priv->accel_group, - FALSE); - } -} - -/** - * gtk_menu_item_get_accel_path: - * @menu_item: a valid #GtkMenuItem - * - * Retrieve the accelerator path that was previously set on @menu_item. - * - * See gtk_menu_item_set_accel_path() for details. - * - * Returns: (nullable) (transfer none): the accelerator path corresponding to - * this menu item’s functionality, or %NULL if not set - */ -const gchar * -gtk_menu_item_get_accel_path (GtkMenuItem *menu_item) -{ - g_return_val_if_fail (GTK_IS_MENU_ITEM (menu_item), NULL); - - return menu_item->priv->accel_path; -} - -static void -gtk_menu_item_forall (GtkContainer *container, - GtkCallback callback, - gpointer callback_data) -{ - GtkWidget *child; - - g_return_if_fail (GTK_IS_MENU_ITEM (container)); - g_return_if_fail (callback != NULL); - - child = gtk_bin_get_child (GTK_BIN (container)); - if (child) - callback (child, callback_data); -} - -gboolean -_gtk_menu_item_is_selectable (GtkWidget *menu_item) -{ - if ((!gtk_bin_get_child (GTK_BIN (menu_item)) && - G_OBJECT_TYPE (menu_item) == GTK_TYPE_MENU_ITEM) || - GTK_IS_SEPARATOR_MENU_ITEM (menu_item) || - !gtk_widget_is_sensitive (menu_item) || - !gtk_widget_get_visible (menu_item)) - return FALSE; - - return TRUE; -} - -static void -gtk_menu_item_ensure_label (GtkMenuItem *menu_item) -{ - GtkWidget *accel_label; - - if (!gtk_bin_get_child (GTK_BIN (menu_item))) - { - accel_label = g_object_new (GTK_TYPE_ACCEL_LABEL, NULL); - gtk_widget_set_halign (accel_label, GTK_ALIGN_FILL); - gtk_widget_set_valign (accel_label, GTK_ALIGN_CENTER); - - gtk_container_add (GTK_CONTAINER (menu_item), accel_label); - gtk_accel_label_set_accel_widget (GTK_ACCEL_LABEL (accel_label), - GTK_WIDGET (menu_item)); - } -} - -/** - * gtk_menu_item_set_label: - * @menu_item: a #GtkMenuItem - * @label: the text you want to set - * - * Sets @text on the @menu_item label - */ -void -gtk_menu_item_set_label (GtkMenuItem *menu_item, - const gchar *label) -{ - g_return_if_fail (GTK_IS_MENU_ITEM (menu_item)); - - GTK_MENU_ITEM_GET_CLASS (menu_item)->set_label (menu_item, label); -} - -/** - * gtk_menu_item_get_label: - * @menu_item: a #GtkMenuItem - * - * Sets @text on the @menu_item label - * - * Returns: The text in the @menu_item label. This is the internal - * string used by the label, and must not be modified. - */ -const gchar * -gtk_menu_item_get_label (GtkMenuItem *menu_item) -{ - g_return_val_if_fail (GTK_IS_MENU_ITEM (menu_item), NULL); - - return GTK_MENU_ITEM_GET_CLASS (menu_item)->get_label (menu_item); -} - -/** - * gtk_menu_item_set_use_underline: - * @menu_item: a #GtkMenuItem - * @setting: %TRUE if underlines in the text indicate mnemonics - * - * If true, an underline in the text indicates the next character - * should be used for the mnemonic accelerator key. - */ -void -gtk_menu_item_set_use_underline (GtkMenuItem *menu_item, - gboolean setting) -{ - GtkWidget *child; - - g_return_if_fail (GTK_IS_MENU_ITEM (menu_item)); - - gtk_menu_item_ensure_label (menu_item); - - child = gtk_bin_get_child (GTK_BIN (menu_item)); - if (GTK_IS_ACCEL_LABEL (child) && - gtk_accel_label_get_use_underline (GTK_ACCEL_LABEL (child)) != setting) - { - gtk_accel_label_set_use_underline (GTK_ACCEL_LABEL (child), setting); - g_object_notify_by_pspec (G_OBJECT (menu_item), menu_item_props[PROP_USE_UNDERLINE]); - } -} - -/** - * gtk_menu_item_get_use_underline: - * @menu_item: a #GtkMenuItem - * - * Checks if an underline in the text indicates the next character - * should be used for the mnemonic accelerator key. - * - * Returns: %TRUE if an embedded underline in the label - * indicates the mnemonic accelerator key. - */ -gboolean -gtk_menu_item_get_use_underline (GtkMenuItem *menu_item) -{ - GtkWidget *child; - - g_return_val_if_fail (GTK_IS_MENU_ITEM (menu_item), FALSE); - - gtk_menu_item_ensure_label (menu_item); - - child = gtk_bin_get_child (GTK_BIN (menu_item)); - if (GTK_IS_LABEL (child)) - return gtk_label_get_use_underline (GTK_LABEL (child)); - else if (GTK_IS_ACCEL_LABEL (child)) - return gtk_accel_label_get_use_underline (GTK_ACCEL_LABEL (child)); - - - return FALSE; -} - -/** - * gtk_menu_item_set_reserve_indicator: - * @menu_item: a #GtkMenuItem - * @reserve: the new value - * - * Sets whether the @menu_item should reserve space for - * the submenu indicator, regardless if it actually has - * a submenu or not. - * - * There should be little need for applications to call - * this functions. - */ -void -gtk_menu_item_set_reserve_indicator (GtkMenuItem *menu_item, - gboolean reserve) -{ - GtkMenuItemPrivate *priv; - - g_return_if_fail (GTK_IS_MENU_ITEM (menu_item)); - - priv = menu_item->priv; - - if (priv->reserve_indicator != reserve) - { - priv->reserve_indicator = reserve; - update_arrow_widget (menu_item); - gtk_widget_queue_resize (GTK_WIDGET (menu_item)); - } -} - -/** - * gtk_menu_item_get_reserve_indicator: - * @menu_item: a #GtkMenuItem - * - * Returns whether the @menu_item reserves space for - * the submenu indicator, regardless if it has a submenu - * or not. - * - * Returns: %TRUE if @menu_item always reserves space for the - * submenu indicator - */ -gboolean -gtk_menu_item_get_reserve_indicator (GtkMenuItem *menu_item) -{ - g_return_val_if_fail (GTK_IS_MENU_ITEM (menu_item), FALSE); - - return menu_item->priv->reserve_indicator; -} diff --git a/gtk/gtkmenuitem.h b/gtk/gtkmenuitem.h deleted file mode 100644 index 422706a2af..0000000000 --- a/gtk/gtkmenuitem.h +++ /dev/null @@ -1,158 +0,0 @@ -/* GTK - The GIMP Toolkit - * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * 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, see . - */ - -/* - * Modified by the GTK+ Team and others 1997-2000. See the AUTHORS - * file for a list of people on the GTK+ Team. See the ChangeLog - * files for a list of changes. These files are distributed with - * GTK+ at ftp://ftp.gtk.org/pub/gtk/. - */ - -#ifndef __GTK_MENU_ITEM_H__ -#define __GTK_MENU_ITEM_H__ - -#if !defined (__GTK_H_INSIDE__) && !defined (GTK_COMPILATION) -#error "Only can be included directly." -#endif - -#include - - -G_BEGIN_DECLS - -#define GTK_TYPE_MENU_ITEM (gtk_menu_item_get_type ()) -#define GTK_MENU_ITEM(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GTK_TYPE_MENU_ITEM, GtkMenuItem)) -#define GTK_MENU_ITEM_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GTK_TYPE_MENU_ITEM, GtkMenuItemClass)) -#define GTK_IS_MENU_ITEM(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GTK_TYPE_MENU_ITEM)) -#define GTK_IS_MENU_ITEM_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GTK_TYPE_MENU_ITEM)) -#define GTK_MENU_ITEM_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GTK_TYPE_MENU_ITEM, GtkMenuItemClass)) - - -typedef struct _GtkMenuItem GtkMenuItem; -typedef struct _GtkMenuItemClass GtkMenuItemClass; -typedef struct _GtkMenuItemPrivate GtkMenuItemPrivate; - -struct _GtkMenuItem -{ - GtkBin bin; - - /*< private >*/ - GtkMenuItemPrivate *priv; -}; - -/** - * GtkMenuItemClass: - * @parent_class: The parent class. - * @hide_on_activate: If %TRUE, then we should always - * hide the menu when the %GtkMenuItem is activated. Otherwise, - * it is up to the caller. - * @activate: Signal emitted when the item is activated. - * @activate_item: Signal emitted when the item is activated, but also - * if the menu item has a submenu. - * @toggle_size_request: - * @toggle_size_allocate: - * @set_label: Sets @text on the #GtkMenuItem label - * @get_label: Gets @text from the #GtkMenuItem label - * @select: Signal emitted when the item is selected. - * @deselect: Signal emitted when the item is deselected. - */ -struct _GtkMenuItemClass -{ - GtkBinClass parent_class; - - /*< public >*/ - - /* If the following flag is true, then we should always - * hide the menu when the MenuItem is activated. Otherwise, - * it is up to the caller. For instance, when navigating - * a menu with the keyboard, doesn't hide, but - * does. - */ - guint hide_on_activate : 1; - - void (* activate) (GtkMenuItem *menu_item); - void (* activate_item) (GtkMenuItem *menu_item); - void (* toggle_size_request) (GtkMenuItem *menu_item, - gint *requisition); - void (* toggle_size_allocate) (GtkMenuItem *menu_item, - gint allocation); - void (* set_label) (GtkMenuItem *menu_item, - const gchar *label); - const gchar * (* get_label) (GtkMenuItem *menu_item); - - void (* select) (GtkMenuItem *menu_item); - void (* deselect) (GtkMenuItem *menu_item); - - /*< private >*/ - - gpointer padding[8]; -}; - - -GDK_AVAILABLE_IN_ALL -GType gtk_menu_item_get_type (void) G_GNUC_CONST; - -GDK_AVAILABLE_IN_ALL -GtkWidget* gtk_menu_item_new (void); -GDK_AVAILABLE_IN_ALL -GtkWidget* gtk_menu_item_new_with_label (const gchar *label); -GDK_AVAILABLE_IN_ALL -GtkWidget* gtk_menu_item_new_with_mnemonic (const gchar *label); -GDK_AVAILABLE_IN_ALL -void gtk_menu_item_set_submenu (GtkMenuItem *menu_item, - GtkWidget *submenu); -GDK_AVAILABLE_IN_ALL -GtkWidget* gtk_menu_item_get_submenu (GtkMenuItem *menu_item); -GDK_AVAILABLE_IN_ALL -void gtk_menu_item_select (GtkMenuItem *menu_item); -GDK_AVAILABLE_IN_ALL -void gtk_menu_item_deselect (GtkMenuItem *menu_item); -GDK_AVAILABLE_IN_ALL -void gtk_menu_item_activate (GtkMenuItem *menu_item); -GDK_AVAILABLE_IN_ALL -void gtk_menu_item_toggle_size_request (GtkMenuItem *menu_item, - gint *requisition); -GDK_AVAILABLE_IN_ALL -void gtk_menu_item_toggle_size_allocate (GtkMenuItem *menu_item, - gint allocation); -GDK_AVAILABLE_IN_ALL -void gtk_menu_item_set_accel_path (GtkMenuItem *menu_item, - const gchar *accel_path); -GDK_AVAILABLE_IN_ALL -const gchar * gtk_menu_item_get_accel_path (GtkMenuItem *menu_item); - -GDK_AVAILABLE_IN_ALL -void gtk_menu_item_set_label (GtkMenuItem *menu_item, - const gchar *label); -GDK_AVAILABLE_IN_ALL -const gchar * gtk_menu_item_get_label (GtkMenuItem *menu_item); - -GDK_AVAILABLE_IN_ALL -void gtk_menu_item_set_use_underline (GtkMenuItem *menu_item, - gboolean setting); -GDK_AVAILABLE_IN_ALL -gboolean gtk_menu_item_get_use_underline (GtkMenuItem *menu_item); - -GDK_AVAILABLE_IN_ALL -void gtk_menu_item_set_reserve_indicator (GtkMenuItem *menu_item, - gboolean reserve); -GDK_AVAILABLE_IN_ALL -gboolean gtk_menu_item_get_reserve_indicator (GtkMenuItem *menu_item); - -G_END_DECLS - -#endif /* __GTK_MENU_ITEM_H__ */ diff --git a/gtk/gtkmenuitemprivate.h b/gtk/gtkmenuitemprivate.h deleted file mode 100644 index 0482471e70..0000000000 --- a/gtk/gtkmenuitemprivate.h +++ /dev/null @@ -1,63 +0,0 @@ -/* GTK - The GIMP Toolkit - * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * 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, see . - */ - -#ifndef __GTK_MENU_ITEM_PRIVATE_H__ -#define __GTK_MENU_ITEM_PRIVATE_H__ - -#include -#include -#include -#include -#include - -G_BEGIN_DECLS - -struct _GtkMenuItemPrivate -{ - GtkWidget *submenu; - - guint16 toggle_size; - guint16 accelerator_width; - - guint timer; - - const char *accel_path; - - GtkActionHelper *action_helper; - - GtkWidget *arrow_widget; - - guint submenu_placement : 1; - guint submenu_direction : 1; - guint from_menubar : 1; - guint reserve_indicator : 1; -}; - -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); -void _gtk_menu_item_popup_submenu (GtkWidget *menu_item, - gboolean with_delay); -void _gtk_menu_item_popdown_submenu (GtkWidget *menu_item); -GtkMenuShell * - gtk_menu_item_get_menu_shell (GtkMenuItem *menu_item); - -G_END_DECLS - -#endif /* __GTK_MENU_ITEM_PRIVATE_H__ */ diff --git a/gtk/gtkmenuprivate.h b/gtk/gtkmenuprivate.h deleted file mode 100644 index 4c6d630321..0000000000 --- a/gtk/gtkmenuprivate.h +++ /dev/null @@ -1,96 +0,0 @@ -/* GTK - The GIMP Toolkit - * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * 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, see . - */ - -/* - * Modified by the GTK+ Team and others 1997-2000. See the AUTHORS - * file for a list of people on the GTK+ Team. See the ChangeLog - * files for a list of changes. These files are distributed with - * GTK+ at ftp://ftp.gtk.org/pub/gtk/. - */ - -#ifndef __GTK_MENU_PRIVATE_H__ -#define __GTK_MENU_PRIVATE_H__ - -#include -#include -#include - -G_BEGIN_DECLS - -typedef struct _GtkMenuClass GtkMenuClass; -typedef struct _GtkMenuPrivate GtkMenuPrivate; - -struct _GtkMenu -{ - GtkMenuShell menu_shell; - - GtkMenuPrivate *priv; -}; - -struct _GtkMenuClass -{ - GtkMenuShellClass parent_class; -}; - -struct _GtkMenuPrivate -{ - GtkWidget *parent_menu_item; - GtkWidget *old_active_menu_item; - - GtkAccelGroup *accel_group; - const char *accel_path; - - GdkSurface *rect_surface; - GdkRectangle rect; - GtkWidget *widget; - GdkGravity rect_anchor; - GdkGravity menu_anchor; - GdkAnchorHints anchor_hints; - gint rect_anchor_dx; - gint rect_anchor_dy; - GdkSurfaceTypeHint menu_type_hint; - - guint toggle_size; - guint accel_size; - - /* Do _not_ touch these widgets directly. We hide the reference - * count from the toplevel to the menu, so it must be restored - * before operating on these widgets - */ - GtkWidget *toplevel; - GtkWidget *swin; - GtkWidget *box; - - guint needs_destruction_ref : 1; - - guint ignore_button_release : 1; - guint no_toggle_size : 1; - - gint monitor_num; -}; - -G_GNUC_INTERNAL -void gtk_menu_update_scroll_offset (GtkMenu *menu, - const GdkRectangle *flipped_rect, - const GdkRectangle *final_rect, - gboolean flipped_x, - gboolean flipped_y, - gpointer user_data); - -G_END_DECLS - -#endif /* __GTK_MENU_PRIVATE_H__ */ diff --git a/gtk/gtkmenushell.c b/gtk/gtkmenushell.c deleted file mode 100644 index 55bea7ddb4..0000000000 --- a/gtk/gtkmenushell.c +++ /dev/null @@ -1,1947 +0,0 @@ -/* GTK - The GIMP Toolkit - * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * 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, see . - */ - -/* - * Modified by the GTK+ Team and others 1997-2000. See the AUTHORS - * file for a list of people on the GTK+ Team. See the ChangeLog - * files for a list of changes. These files are distributed with - * GTK+ at ftp://ftp.gtk.org/pub/gtk/. - */ - -/** - * SECTION:gtkmenushell - * @Title: GtkMenuShell - * @Short_description: A base class for menu objects - * - * A #GtkMenuShell is the abstract base class used to derive the - * #GtkMenu and #GtkMenuBar subclasses. - * - * A #GtkMenuShell is a container of #GtkMenuItem objects arranged - * in a list which can be navigated, selected, and activated by the - * user to perform application functions. A #GtkMenuItem can have a - * submenu associated with it, allowing for nested hierarchical menus. - * - * # Terminology - * - * A menu item can be “selected”, this means that it is displayed - * in the prelight state, and if it has a submenu, that submenu - * will be popped up. - * - * A menu is “active” when it is visible onscreen and the user - * is selecting from it. A menubar is not active until the user - * clicks on one of its menuitems. When a menu is active, - * passing the mouse over a submenu will pop it up. - * - * There is also a concept of the current menu and a current - * menu item. The current menu item is the selected menu item - * that is furthest down in the hierarchy. (Every active menu shell - * does not necessarily contain a selected menu item, but if - * it does, then the parent menu shell must also contain - * a selected menu item.) The current menu is the menu that - * contains the current menu item. It will always have a GTK - * grab and receive all key presses. - */ -#include "config.h" - -#include "gtkmenushellprivate.h" - -#include "gtkbindings.h" -#include "gtkintl.h" -#include "gtkkeyhash.h" -#include "gtklabelprivate.h" -#include "gtkmain.h" -#include "gtkmarshalers.h" -#include "gtkmenubarprivate.h" -#include "gtkmenuitemprivate.h" -#include "gtkmnemonichash.h" -#include "gtkmodelmenuitemprivate.h" -#include "gtkprivate.h" -#include "gtkseparatormenuitem.h" -#include "gtktypebuiltins.h" -#include "gtkwidgetprivate.h" -#include "gtkwindow.h" -#include "gtkwindowprivate.h" -#include "gtkeventcontrollerkey.h" -#include "gtkgestureclick.h" - -#include "a11y/gtkmenushellaccessible.h" - - -#define MENU_SHELL_TIMEOUT 500 -#define MENU_POPUP_DELAY 225 -#define MENU_POPDOWN_DELAY 1000 - -enum { - DEACTIVATE, - SELECTION_DONE, - MOVE_CURRENT, - ACTIVATE_CURRENT, - CANCEL, - CYCLE_FOCUS, - MOVE_SELECTED, - INSERT, - LAST_SIGNAL -}; - -enum { - PROP_0, - PROP_TAKE_FOCUS -}; - - -static void gtk_menu_shell_set_property (GObject *object, - guint prop_id, - const GValue *value, - GParamSpec *pspec); -static void gtk_menu_shell_get_property (GObject *object, - guint prop_id, - GValue *value, - GParamSpec *pspec); -static void gtk_menu_shell_finalize (GObject *object); -static void gtk_menu_shell_dispose (GObject *object); -static gboolean gtk_menu_shell_key_press (GtkEventControllerKey *key, - guint keyval, - guint keycode, - GdkModifierType modifiers, - GtkWidget *widget); -static void gtk_menu_shell_root (GtkWidget *widget); -static void click_pressed (GtkGestureClick *gesture, - gint n_press, - gdouble x, - gdouble y, - GtkMenuShell *menu_shell); -static void click_released (GtkGestureClick *gesture, - gint n_press, - gdouble x, - gdouble y, - GtkMenuShell *menu_shell); -static void click_stopped (GtkGestureClick *gesture, - GtkMenuShell *menu_shell); - - -static void gtk_menu_shell_add (GtkContainer *container, - GtkWidget *widget); -static void gtk_menu_shell_remove (GtkContainer *container, - GtkWidget *widget); -static void gtk_real_menu_shell_deactivate (GtkMenuShell *menu_shell); -static GType gtk_menu_shell_child_type (GtkContainer *container); -static void gtk_menu_shell_real_select_item (GtkMenuShell *menu_shell, - GtkWidget *menu_item); -static gboolean gtk_menu_shell_select_submenu_first (GtkMenuShell *menu_shell); - -static void gtk_real_menu_shell_move_current (GtkMenuShell *menu_shell, - GtkMenuDirectionType direction); -static void gtk_real_menu_shell_activate_current (GtkMenuShell *menu_shell, - gboolean force_hide); -static void gtk_real_menu_shell_cancel (GtkMenuShell *menu_shell); -static void gtk_real_menu_shell_cycle_focus (GtkMenuShell *menu_shell, - GtkDirectionType dir); - -static void gtk_menu_shell_reset_key_hash (GtkMenuShell *menu_shell); -static gboolean gtk_menu_shell_activate_mnemonic (GtkMenuShell *menu_shell, - guint keycode, - GdkModifierType state, - guint group); -static gboolean gtk_menu_shell_real_move_selected (GtkMenuShell *menu_shell, - gint distance); - -static guint menu_shell_signals[LAST_SIGNAL] = { 0 }; - -G_DEFINE_ABSTRACT_TYPE_WITH_PRIVATE (GtkMenuShell, gtk_menu_shell, GTK_TYPE_CONTAINER) - -static void -gtk_menu_shell_class_init (GtkMenuShellClass *klass) -{ - GObjectClass *object_class; - GtkWidgetClass *widget_class; - GtkContainerClass *container_class; - - GtkBindingSet *binding_set; - - object_class = (GObjectClass*) klass; - widget_class = (GtkWidgetClass*) klass; - container_class = (GtkContainerClass*) klass; - - object_class->set_property = gtk_menu_shell_set_property; - object_class->get_property = gtk_menu_shell_get_property; - object_class->finalize = gtk_menu_shell_finalize; - object_class->dispose = gtk_menu_shell_dispose; - - widget_class->root = gtk_menu_shell_root; - - container_class->add = gtk_menu_shell_add; - container_class->remove = gtk_menu_shell_remove; - container_class->child_type = gtk_menu_shell_child_type; - - klass->submenu_placement = GTK_TOP_BOTTOM; - klass->deactivate = gtk_real_menu_shell_deactivate; - klass->selection_done = NULL; - klass->move_current = gtk_real_menu_shell_move_current; - klass->activate_current = gtk_real_menu_shell_activate_current; - klass->cancel = gtk_real_menu_shell_cancel; - klass->select_item = gtk_menu_shell_real_select_item; - klass->move_selected = gtk_menu_shell_real_move_selected; - - /** - * GtkMenuShell::deactivate: - * @menushell: the object which received the signal - * - * This signal is emitted when a menu shell is deactivated. - */ - menu_shell_signals[DEACTIVATE] = - g_signal_new (I_("deactivate"), - G_OBJECT_CLASS_TYPE (object_class), - G_SIGNAL_RUN_FIRST, - G_STRUCT_OFFSET (GtkMenuShellClass, deactivate), - NULL, NULL, - NULL, - G_TYPE_NONE, 0); - - /** - * GtkMenuShell::selection-done: - * @menushell: the object which received the signal - * - * This signal is emitted when a selection has been - * completed within a menu shell. - */ - menu_shell_signals[SELECTION_DONE] = - g_signal_new (I_("selection-done"), - G_OBJECT_CLASS_TYPE (object_class), - G_SIGNAL_RUN_FIRST, - G_STRUCT_OFFSET (GtkMenuShellClass, selection_done), - NULL, NULL, - NULL, - G_TYPE_NONE, 0); - - /** - * GtkMenuShell::move-current: - * @menushell: the object which received the signal - * @direction: the direction to move - * - * A keybinding signal which moves the current menu item - * in the direction specified by @direction. - */ - menu_shell_signals[MOVE_CURRENT] = - g_signal_new (I_("move-current"), - G_OBJECT_CLASS_TYPE (object_class), - G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION, - G_STRUCT_OFFSET (GtkMenuShellClass, move_current), - NULL, NULL, - NULL, - G_TYPE_NONE, 1, - GTK_TYPE_MENU_DIRECTION_TYPE); - - /** - * GtkMenuShell::activate-current: - * @menushell: the object which received the signal - * @force_hide: if %TRUE, hide the menu after activating the menu item - * - * An action signal that activates the current menu item within - * the menu shell. - */ - menu_shell_signals[ACTIVATE_CURRENT] = - g_signal_new (I_("activate-current"), - G_OBJECT_CLASS_TYPE (object_class), - G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION, - G_STRUCT_OFFSET (GtkMenuShellClass, activate_current), - NULL, NULL, - NULL, - G_TYPE_NONE, 1, - G_TYPE_BOOLEAN); - - /** - * GtkMenuShell::cancel: - * @menushell: the object which received the signal - * - * An action signal which cancels the selection within the menu shell. - * Causes the #GtkMenuShell::selection-done signal to be emitted. - */ - menu_shell_signals[CANCEL] = - g_signal_new (I_("cancel"), - G_OBJECT_CLASS_TYPE (object_class), - G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION, - G_STRUCT_OFFSET (GtkMenuShellClass, cancel), - NULL, NULL, - NULL, - G_TYPE_NONE, 0); - - /** - * GtkMenuShell::cycle-focus: - * @menushell: the object which received the signal - * @direction: the direction to cycle in - * - * A keybinding signal which moves the focus in the - * given @direction. - */ - menu_shell_signals[CYCLE_FOCUS] = - g_signal_new_class_handler (I_("cycle-focus"), - G_OBJECT_CLASS_TYPE (object_class), - G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION, - G_CALLBACK (gtk_real_menu_shell_cycle_focus), - NULL, NULL, - NULL, - G_TYPE_NONE, 1, - GTK_TYPE_DIRECTION_TYPE); - - /** - * GtkMenuShell::move-selected: - * @menu_shell: the object on which the signal is emitted - * @distance: +1 to move to the next item, -1 to move to the previous - * - * The ::move-selected signal is emitted to move the selection to - * another item. - * - * Returns: %TRUE to stop the signal emission, %FALSE to continue - */ - menu_shell_signals[MOVE_SELECTED] = - g_signal_new (I_("move-selected"), - G_OBJECT_CLASS_TYPE (object_class), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (GtkMenuShellClass, move_selected), - _gtk_boolean_handled_accumulator, NULL, - _gtk_marshal_BOOLEAN__INT, - 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. - **/ - 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); - g_signal_set_va_marshaller (menu_shell_signals[INSERT], - G_OBJECT_CLASS_TYPE (object_class), - _gtk_marshal_VOID__OBJECT_INTv); - - - binding_set = gtk_binding_set_by_class (klass); - gtk_binding_entry_add_signal (binding_set, - GDK_KEY_Escape, 0, - "cancel", 0); - gtk_binding_entry_add_signal (binding_set, - GDK_KEY_Return, 0, - "activate-current", 1, - G_TYPE_BOOLEAN, - TRUE); - gtk_binding_entry_add_signal (binding_set, - GDK_KEY_ISO_Enter, 0, - "activate-current", 1, - G_TYPE_BOOLEAN, - TRUE); - gtk_binding_entry_add_signal (binding_set, - GDK_KEY_KP_Enter, 0, - "activate-current", 1, - G_TYPE_BOOLEAN, - TRUE); - gtk_binding_entry_add_signal (binding_set, - GDK_KEY_space, 0, - "activate-current", 1, - G_TYPE_BOOLEAN, - FALSE); - gtk_binding_entry_add_signal (binding_set, - GDK_KEY_KP_Space, 0, - "activate-current", 1, - G_TYPE_BOOLEAN, - FALSE); - gtk_binding_entry_add_signal (binding_set, - GDK_KEY_F10, 0, - "cycle-focus", 1, - GTK_TYPE_DIRECTION_TYPE, GTK_DIR_TAB_FORWARD); - gtk_binding_entry_add_signal (binding_set, - GDK_KEY_F10, GDK_SHIFT_MASK, - "cycle-focus", 1, - GTK_TYPE_DIRECTION_TYPE, GTK_DIR_TAB_BACKWARD); - - /** - * GtkMenuShell:take-focus: - * - * A boolean that determines whether the menu and its submenus grab the - * keyboard focus. See gtk_menu_shell_set_take_focus() and - * gtk_menu_shell_get_take_focus(). - **/ - g_object_class_install_property (object_class, - PROP_TAKE_FOCUS, - g_param_spec_boolean ("take-focus", - P_("Take Focus"), - P_("A boolean that determines whether the menu grabs the keyboard focus"), - TRUE, - GTK_PARAM_READWRITE|G_PARAM_EXPLICIT_NOTIFY)); - - gtk_widget_class_set_accessible_type (widget_class, GTK_TYPE_MENU_SHELL_ACCESSIBLE); -} - -static GType -gtk_menu_shell_child_type (GtkContainer *container) -{ - return GTK_TYPE_MENU_ITEM; -} - -static void -gtk_menu_shell_init (GtkMenuShell *menu_shell) -{ - GtkWidget *widget = GTK_WIDGET (menu_shell); - GtkEventController *controller; - - menu_shell->priv = gtk_menu_shell_get_instance_private (menu_shell); - menu_shell->priv->take_focus = TRUE; - - controller = gtk_event_controller_key_new (); - gtk_event_controller_set_propagation_limit (controller, GTK_LIMIT_NONE); - g_signal_connect (controller, "key-pressed", - G_CALLBACK (gtk_menu_shell_key_press), widget); - gtk_widget_add_controller (widget, controller); - - controller = GTK_EVENT_CONTROLLER (gtk_gesture_click_new ()); - gtk_event_controller_set_propagation_limit (controller, GTK_LIMIT_NONE); - gtk_gesture_single_set_button (GTK_GESTURE_SINGLE (controller), 0); - g_signal_connect (controller, "pressed", - G_CALLBACK (click_pressed), menu_shell); - g_signal_connect (controller, "released", - G_CALLBACK (click_released), menu_shell); - g_signal_connect (controller, "stopped", - G_CALLBACK (click_stopped), menu_shell); - gtk_widget_add_controller (widget, controller); -} - -static void -gtk_menu_shell_set_property (GObject *object, - guint prop_id, - const GValue *value, - GParamSpec *pspec) -{ - GtkMenuShell *menu_shell = GTK_MENU_SHELL (object); - - switch (prop_id) - { - case PROP_TAKE_FOCUS: - gtk_menu_shell_set_take_focus (menu_shell, g_value_get_boolean (value)); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; - } -} - -static void -gtk_menu_shell_get_property (GObject *object, - guint prop_id, - GValue *value, - GParamSpec *pspec) -{ - GtkMenuShell *menu_shell = GTK_MENU_SHELL (object); - - switch (prop_id) - { - case PROP_TAKE_FOCUS: - g_value_set_boolean (value, gtk_menu_shell_get_take_focus (menu_shell)); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; - } -} - -static void -gtk_menu_shell_finalize (GObject *object) -{ - GtkMenuShell *menu_shell = GTK_MENU_SHELL (object); - GtkMenuShellPrivate *priv = menu_shell->priv; - - if (priv->mnemonic_hash) - _gtk_mnemonic_hash_free (priv->mnemonic_hash); - if (priv->key_hash) - _gtk_key_hash_free (priv->key_hash); - - G_OBJECT_CLASS (gtk_menu_shell_parent_class)->finalize (object); -} - - -static void -gtk_menu_shell_dispose (GObject *object) -{ - GtkMenuShell *menu_shell = GTK_MENU_SHELL (object); - - g_clear_pointer (&menu_shell->priv->tracker, gtk_menu_tracker_free); - gtk_menu_shell_deactivate (menu_shell); - - G_OBJECT_CLASS (gtk_menu_shell_parent_class)->dispose (object); -} - -/** - * gtk_menu_shell_append: - * @menu_shell: a #GtkMenuShell - * @child: (type Gtk.MenuItem): The #GtkMenuItem to add - * - * Adds a new #GtkMenuItem to the end of the menu shell's - * item list. - */ -void -gtk_menu_shell_append (GtkMenuShell *menu_shell, - GtkWidget *child) -{ - gtk_menu_shell_insert (menu_shell, child, -1); -} - -/** - * gtk_menu_shell_prepend: - * @menu_shell: a #GtkMenuShell - * @child: The #GtkMenuItem to add - * - * Adds a new #GtkMenuItem to the beginning of the menu shell's - * item list. - */ -void -gtk_menu_shell_prepend (GtkMenuShell *menu_shell, - GtkWidget *child) -{ - gtk_menu_shell_insert (menu_shell, child, 0); -} - -/** - * gtk_menu_shell_insert: - * @menu_shell: a #GtkMenuShell - * @child: The #GtkMenuItem to add - * @position: The position in the item list where @child - * is added. Positions are numbered from 0 to n-1 - * - * Adds a new #GtkMenuItem to the menu shell’s item list - * at the position indicated by @position. - */ -void -gtk_menu_shell_insert (GtkMenuShell *menu_shell, - GtkWidget *child, - gint position) -{ - g_return_if_fail (GTK_IS_MENU_SHELL (menu_shell)); - g_return_if_fail (GTK_IS_MENU_ITEM (child)); - - g_signal_emit (menu_shell, menu_shell_signals[INSERT], 0, child, position); -} - -/** - * gtk_menu_shell_deactivate: - * @menu_shell: a #GtkMenuShell - * - * Deactivates the menu shell. - * - * Typically this results in the menu shell being erased - * from the screen. - */ -void -gtk_menu_shell_deactivate (GtkMenuShell *menu_shell) -{ - g_return_if_fail (GTK_IS_MENU_SHELL (menu_shell)); - - if (menu_shell->priv->active) - g_signal_emit (menu_shell, menu_shell_signals[DEACTIVATE], 0); -} - -static void -gtk_menu_shell_activate (GtkMenuShell *menu_shell) -{ - GtkMenuShellPrivate *priv = menu_shell->priv; - - if (!priv->active) - { - GdkDevice *device; - - device = gtk_get_current_event_device (); - - _gtk_menu_shell_set_grab_device (menu_shell, device); - gtk_grab_add (GTK_WIDGET (menu_shell)); - - priv->have_grab = TRUE; - priv->active = TRUE; - } -} - -static void -gtk_menu_shell_deactivate_and_emit_done (GtkMenuShell *menu_shell) -{ - gtk_menu_shell_deactivate (menu_shell); - g_signal_emit (menu_shell, menu_shell_signals[SELECTION_DONE], 0); -} - -static GtkMenuShell * -gtk_menu_shell_get_toplevel_shell (GtkMenuShell *menu_shell) -{ - while (menu_shell->priv->parent_menu_shell) - menu_shell = GTK_MENU_SHELL (menu_shell->priv->parent_menu_shell); - - return menu_shell; -} - -static void -click_stopped (GtkGestureClick *gesture, - GtkMenuShell *menu_shell) -{ - GtkMenuShellPrivate *priv = menu_shell->priv; - GdkSurface *surface; - GdkEvent *event; - - event = gtk_get_current_event (); - if (!event) - return; - - if (gdk_event_get_grab_surface (event, &surface)) - { - if (priv->have_xgrab && surface == NULL) - { - /* Unset the active menu item so gtk_menu_popdown() doesn't see it. */ - gtk_menu_shell_deselect (menu_shell); - gtk_menu_shell_deactivate_and_emit_done (menu_shell); - } - } - - g_object_unref (event); -} - -static void -click_pressed (GtkGestureClick *gesture, - gint n_press, - gdouble x, - gdouble y, - GtkMenuShell *menu_shell) -{ - GtkMenuShellPrivate *priv = menu_shell->priv; - GtkWidget *menu_item; - GdkEvent *event; - GtkMenuShell *item_shell; - - event = gtk_get_current_event (); - menu_item = gtk_get_event_target_with_type (event, GTK_TYPE_MENU_ITEM); - if (menu_item) - item_shell = gtk_menu_item_get_menu_shell (GTK_MENU_ITEM (menu_item)); - - if (menu_item && - _gtk_menu_item_is_selectable (menu_item) && - item_shell == menu_shell) - { - if (menu_item != menu_shell->priv->active_menu_item) - { - /* 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_shell)->submenu_placement != GTK_TOP_BOTTOM) - gtk_menu_shell_select_item (menu_shell, menu_item); - } - - if (GTK_MENU_ITEM (menu_item)->priv->submenu != NULL && - !gtk_widget_get_visible (GTK_MENU_ITEM (menu_item)->priv->submenu)) - { - _gtk_menu_item_popup_submenu (menu_item, FALSE); - priv->activated_submenu = TRUE; - } - } - - if (!priv->active || !priv->button) - { - gboolean initially_active = priv->active; - guint button; - guint32 time; - - button = gtk_gesture_single_get_current_button (GTK_GESTURE_SINGLE (gesture)); - time = gdk_event_get_time (event); - - priv->button = button; - - if (menu_item) - { - if (_gtk_menu_item_is_selectable (menu_item) && - item_shell == menu_shell && - menu_item != priv->active_menu_item) - { - priv->active = TRUE; - - if (GTK_MENU_SHELL_GET_CLASS (menu_shell)->submenu_placement == GTK_TOP_BOTTOM) - { - priv->activate_time = time; - gtk_menu_shell_select_item (menu_shell, menu_item); - } - } - } - else if (!initially_active) - { - gtk_menu_shell_deactivate (menu_shell); - gtk_gesture_set_state (GTK_GESTURE (gesture), - GTK_EVENT_SEQUENCE_CLAIMED); - } - } - - g_object_unref (event); -} - -static void -click_released (GtkGestureClick *gesture, - gint n_press, - gdouble x, - gdouble y, - GtkMenuShell *menu_shell) -{ - GtkMenuShellPrivate *priv = menu_shell->priv; - GtkMenuShell *parent_shell = GTK_MENU_SHELL (priv->parent_menu_shell); - gboolean activated_submenu = FALSE; - guint new_button; - guint32 time; - GdkEvent *event; - - event = gtk_get_current_event (); - new_button = gtk_gesture_single_get_current_button (GTK_GESTURE_SINGLE (gesture)); - time = gdk_event_get_time (event); - - gtk_gesture_set_state (GTK_GESTURE (gesture), GTK_EVENT_SEQUENCE_CLAIMED); - - if (parent_shell) - { - /* If a submenu was just activated, it is its shell which is receiving - * the button release event. In this case, we must check the parent - * shell to know about the submenu state. - */ - activated_submenu = parent_shell->priv->activated_submenu; - parent_shell->priv->activated_submenu = FALSE; - } - - if (priv->parent_menu_shell && - (time - GTK_MENU_SHELL (priv->parent_menu_shell)->priv->activate_time) < MENU_SHELL_TIMEOUT) - { - /* The button-press originated in the parent menu bar and we are - * a pop-up menu. It was a quick press-and-release so we don't want - * to activate an item but we leave the popup in place instead. - * https://bugzilla.gnome.org/show_bug.cgi?id=703069 - */ - GTK_MENU_SHELL (priv->parent_menu_shell)->priv->activate_time = 0; - return; - } - - if (priv->active) - { - GtkWidget *menu_item; - guint button = priv->button; - - priv->button = 0; - - if (button && (new_button != button) && priv->parent_menu_shell) - { - gtk_menu_shell_deactivate_and_emit_done (gtk_menu_shell_get_toplevel_shell (menu_shell)); - return; - } - - if ((time - priv->activate_time) <= MENU_SHELL_TIMEOUT) - { - /* 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. - */ - priv->activate_time = 0; - return; - } - - menu_item = gtk_get_event_target_with_type (event, GTK_TYPE_MENU_ITEM); - - if (menu_item) - { - GtkWidget *submenu = GTK_MENU_ITEM (menu_item)->priv->submenu; - GtkMenuShell *parent_menu_item_shell = gtk_menu_item_get_menu_shell (GTK_MENU_ITEM (menu_item)); - - if (!_gtk_menu_item_is_selectable (GTK_WIDGET (menu_item))) - return; - - if (submenu == NULL) - { - gtk_menu_shell_activate_item (menu_shell, GTK_WIDGET (menu_item), TRUE); - return; - } - else if (GTK_MENU_SHELL (parent_menu_item_shell)->priv->parent_menu_shell && - (activated_submenu || - GTK_MENU_SHELL_GET_CLASS (menu_shell)->submenu_placement != GTK_TOP_BOTTOM)) - { - GTimeVal *popup_time; - gint64 usec_since_popup = 0; - - popup_time = g_object_get_data (G_OBJECT (menu_shell), - "gtk-menu-exact-popup-time"); - if (popup_time) - { - GTimeVal current_time; - - g_get_current_time (¤t_time); - - 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); - - g_object_set_data (G_OBJECT (menu_shell), - "gtk-menu-exact-popup-time", NULL); - } - - /* Only close the submenu on click if we opened the - * menu explicitly (usec_since_popup == 0) or - * enough time has passed since it was opened by - * GtkMenuItem's timeout (usec_since_popup > delay). - */ - if (!activated_submenu && - (usec_since_popup == 0 || - usec_since_popup > MENU_POPDOWN_DELAY * 1000)) - { - _gtk_menu_item_popdown_submenu (menu_item); - } - else - { - gtk_menu_item_select (GTK_MENU_ITEM (menu_item)); - } - - return; - } - } - - gtk_menu_shell_deactivate_and_emit_done (gtk_menu_shell_get_toplevel_shell (menu_shell)); - } - - g_object_unref (event); -} - -void -_gtk_menu_shell_set_keyboard_mode (GtkMenuShell *menu_shell, - gboolean keyboard_mode) -{ - menu_shell->priv->keyboard_mode = keyboard_mode; -} - -gboolean -_gtk_menu_shell_get_keyboard_mode (GtkMenuShell *menu_shell) -{ - return menu_shell->priv->keyboard_mode; -} - -void -_gtk_menu_shell_update_mnemonics (GtkMenuShell *menu_shell) -{ - GtkMenuShell *target; - gboolean found; - gboolean mnemonics_visible; - - target = menu_shell; - found = FALSE; - while (target) - { - GtkMenuShellPrivate *priv = target->priv; - GtkWidget *toplevel = GTK_WIDGET (gtk_widget_get_root (GTK_WIDGET (target))); - - /* The idea with keyboard mode is that once you start using - * the keyboard to navigate the menus, we show mnemonics - * until the menu navigation is over. To that end, we spread - * the keyboard mode upwards in the menu hierarchy here. - * Also see gtk_menu_popup, where we inherit it downwards. - */ - if (menu_shell->priv->keyboard_mode) - target->priv->keyboard_mode = TRUE; - - /* While navigating menus, the first parent menu with an active - * item is the one where mnemonics are effective, as can be seen - * in gtk_menu_shell_key_press below. - * We also show mnemonics in context menus. The grab condition is - * necessary to ensure we remove underlines from menu bars when - * dismissing menus. - */ - mnemonics_visible = target->priv->keyboard_mode && - (((target->priv->active_menu_item || priv->in_unselectable_item) && !found) || - (target == menu_shell && - !target->priv->parent_menu_shell && - gtk_widget_has_grab (GTK_WIDGET (target)))); - - /* While menus are up, only show underlines inside the menubar, - * not in the entire window. - */ - if (GTK_IS_MENU_BAR (target)) - { - gtk_window_set_mnemonics_visible (GTK_WINDOW (toplevel), FALSE); - _gtk_label_mnemonics_visible_apply_recursively (GTK_WIDGET (target), - mnemonics_visible); - } - else - gtk_window_set_mnemonics_visible (GTK_WINDOW (toplevel), mnemonics_visible); - - if (target->priv->active_menu_item || priv->in_unselectable_item) - found = TRUE; - - target = GTK_MENU_SHELL (target->priv->parent_menu_shell); - } -} - -static gboolean -gtk_menu_shell_key_press (GtkEventControllerKey *key, - guint keyval, - guint keycode, - GdkModifierType modifiers, - GtkWidget *widget) -{ - GtkMenuShell *menu_shell = GTK_MENU_SHELL (widget); - GtkMenuShellPrivate *priv = menu_shell->priv; - - priv->keyboard_mode = TRUE; - - if (!(priv->active_menu_item || priv->in_unselectable_item) && - priv->parent_menu_shell) - return gtk_event_controller_key_forward (key, priv->parent_menu_shell); - - return gtk_menu_shell_activate_mnemonic (menu_shell, keycode, modifiers, - gtk_event_controller_key_get_group (key)); -} - -static void -gtk_menu_shell_root (GtkWidget *widget) -{ - GTK_WIDGET_CLASS (gtk_menu_shell_parent_class)->root (widget); - - gtk_menu_shell_reset_key_hash (GTK_MENU_SHELL (widget)); -} - -static void -gtk_menu_shell_add (GtkContainer *container, - GtkWidget *widget) -{ - gtk_menu_shell_append (GTK_MENU_SHELL (container), widget); -} - -static void -gtk_menu_shell_remove (GtkContainer *container, - GtkWidget *widget) -{ - GtkMenuShell *menu_shell = GTK_MENU_SHELL (container); - GtkMenuShellPrivate *priv = menu_shell->priv; - - if (widget == priv->active_menu_item) - { - g_signal_emit_by_name (priv->active_menu_item, "deselect"); - priv->active_menu_item = NULL; - } -} - -static void -gtk_real_menu_shell_deactivate (GtkMenuShell *menu_shell) -{ - GtkMenuShellPrivate *priv = menu_shell->priv; - - if (priv->active) - { - priv->button = 0; - priv->active = FALSE; - priv->activate_time = 0; - - if (priv->active_menu_item) - { - gtk_menu_item_deselect (GTK_MENU_ITEM (priv->active_menu_item)); - priv->active_menu_item = NULL; - } - - if (priv->have_grab) - { - priv->have_grab = FALSE; - gtk_grab_remove (GTK_WIDGET (menu_shell)); - } - if (priv->have_xgrab) - { - gdk_seat_ungrab (gdk_device_get_seat (priv->grab_pointer)); - priv->have_xgrab = FALSE; - } - - priv->keyboard_mode = FALSE; - _gtk_menu_shell_set_grab_device (menu_shell, NULL); - - _gtk_menu_shell_update_mnemonics (menu_shell); - } -} - -/* Handlers for action signals */ - -/** - * gtk_menu_shell_select_item: - * @menu_shell: a #GtkMenuShell - * @menu_item: The #GtkMenuItem to select - * - * Selects the menu item from the menu shell. - */ -void -gtk_menu_shell_select_item (GtkMenuShell *menu_shell, - GtkWidget *menu_item) -{ - GtkMenuShellPrivate *priv; - GtkMenuShellClass *class; - - g_return_if_fail (GTK_IS_MENU_SHELL (menu_shell)); - g_return_if_fail (GTK_IS_MENU_ITEM (menu_item)); - - priv = menu_shell->priv; - class = GTK_MENU_SHELL_GET_CLASS (menu_shell); - - if (class->select_item && - !(priv->active && - priv->active_menu_item == menu_item)) - class->select_item (menu_shell, menu_item); -} - -void _gtk_menu_item_set_placement (GtkMenuItem *menu_item, - GtkSubmenuPlacement placement); - -static void -gtk_menu_shell_real_select_item (GtkMenuShell *menu_shell, - GtkWidget *menu_item) -{ - GtkMenuShellPrivate *priv = menu_shell->priv; - - if (priv->active_menu_item) - { - gtk_menu_item_deselect (GTK_MENU_ITEM (priv->active_menu_item)); - priv->active_menu_item = NULL; - } - - if (!_gtk_menu_item_is_selectable (menu_item)) - { - priv->in_unselectable_item = TRUE; - _gtk_menu_shell_update_mnemonics (menu_shell); - return; - } - - gtk_menu_shell_activate (menu_shell); - - priv->active_menu_item = menu_item; - _gtk_menu_item_set_placement (GTK_MENU_ITEM (priv->active_menu_item), - GTK_MENU_SHELL_GET_CLASS (menu_shell)->submenu_placement); - gtk_menu_item_select (GTK_MENU_ITEM (priv->active_menu_item)); - - _gtk_menu_shell_update_mnemonics (menu_shell); - - /* This allows the bizarre radio buttons-with-submenus-display-history - * behavior - */ - if (GTK_MENU_ITEM (priv->active_menu_item)->priv->submenu) - gtk_widget_activate (priv->active_menu_item); -} - -/** - * gtk_menu_shell_deselect: - * @menu_shell: a #GtkMenuShell - * - * Deselects the currently selected item from the menu shell, - * if any. - */ -void -gtk_menu_shell_deselect (GtkMenuShell *menu_shell) -{ - GtkMenuShellPrivate *priv; - - g_return_if_fail (GTK_IS_MENU_SHELL (menu_shell)); - - priv = menu_shell->priv; - - if (priv->active_menu_item) - { - gtk_menu_item_deselect (GTK_MENU_ITEM (priv->active_menu_item)); - priv->active_menu_item = NULL; - _gtk_menu_shell_update_mnemonics (menu_shell); - } -} - -/** - * gtk_menu_shell_activate_item: - * @menu_shell: a #GtkMenuShell - * @menu_item: the #GtkMenuItem to activate - * @force_deactivate: if %TRUE, force the deactivation of the - * menu shell after the menu item is activated - * - * Activates the menu item within the menu shell. - */ -void -gtk_menu_shell_activate_item (GtkMenuShell *menu_shell, - GtkWidget *menu_item, - gboolean force_deactivate) -{ - GSList *slist, *shells = NULL; - gboolean deactivate = force_deactivate; - - g_return_if_fail (GTK_IS_MENU_SHELL (menu_shell)); - g_return_if_fail (GTK_IS_MENU_ITEM (menu_item)); - - if (!deactivate) - deactivate = GTK_MENU_ITEM_GET_CLASS (menu_item)->hide_on_activate; - - g_object_ref (menu_shell); - g_object_ref (menu_item); - - if (deactivate) - { - GtkMenuShell *parent_menu_shell = menu_shell; - - do - { - parent_menu_shell->priv->selection_done_coming_soon = TRUE; - - g_object_ref (parent_menu_shell); - shells = g_slist_prepend (shells, parent_menu_shell); - parent_menu_shell = (GtkMenuShell*) parent_menu_shell->priv->parent_menu_shell; - } - while (parent_menu_shell); - shells = g_slist_reverse (shells); - - gtk_menu_shell_deactivate (menu_shell); - - /* Flush the x-queue, so any grabs are removed and - * the menu is actually taken down - */ - gdk_display_sync (gtk_widget_get_display (menu_item)); - } - - gtk_widget_activate (menu_item); - - for (slist = shells; slist; slist = slist->next) - { - GtkMenuShell *parent_menu_shell = slist->data; - - g_signal_emit (parent_menu_shell, menu_shell_signals[SELECTION_DONE], 0); - parent_menu_shell->priv->selection_done_coming_soon = FALSE; - g_object_unref (slist->data); - } - g_slist_free (shells); - - g_object_unref (menu_shell); - g_object_unref (menu_item); -} - -GList * -gtk_menu_shell_get_items (GtkMenuShell *menu_shell) -{ - return GTK_MENU_SHELL_GET_CLASS (menu_shell)->get_items (menu_shell); -} - -/* Distance should be +/- 1 */ -static gboolean -gtk_menu_shell_real_move_selected (GtkMenuShell *menu_shell, - gint distance) -{ - GtkMenuShellPrivate *priv = menu_shell->priv; - - if (priv->active_menu_item) - { - GList *children = gtk_menu_shell_get_items (menu_shell); - GList *node = g_list_find (children, priv->active_menu_item); - GList *start_node = node; - - if (distance > 0) - { - node = node->next; - while (node != start_node && - (!node || !_gtk_menu_item_is_selectable (node->data))) - { - if (node) - node = node->next; - else - node = children; - } - } - else - { - node = node->prev; - while (node != start_node && - (!node || !_gtk_menu_item_is_selectable (node->data))) - { - if (node) - node = node->prev; - else - node = g_list_last (children); - } - } - - if (node) - gtk_menu_shell_select_item (menu_shell, node->data); - - g_list_free (children); - } - - return TRUE; -} - -/* Distance should be +/- 1 */ -static void -gtk_menu_shell_move_selected (GtkMenuShell *menu_shell, - gint distance) -{ - gboolean handled = FALSE; - - g_signal_emit (menu_shell, menu_shell_signals[MOVE_SELECTED], 0, - distance, &handled); -} - -/** - * gtk_menu_shell_select_first: - * @menu_shell: a #GtkMenuShell - * @search_sensitive: if %TRUE, search for the first selectable - * menu item, otherwise select nothing if - * the first item isn’t sensitive. This - * should be %FALSE if the menu is being - * popped up initially. - * - * Select the first visible or selectable child of the menu shell. - */ -void -gtk_menu_shell_select_first (GtkMenuShell *menu_shell, - gboolean search_sensitive) -{ - GList *children; - GList *tmp_list; - - g_return_if_fail (GTK_IS_MENU_SHELL (menu_shell)); - - children = gtk_menu_shell_get_items (menu_shell); - tmp_list = children; - while (tmp_list) - { - GtkWidget *child = tmp_list->data; - - if ((!search_sensitive && gtk_widget_get_visible (child)) || - _gtk_menu_item_is_selectable (child)) - { - gtk_menu_shell_select_item (menu_shell, child); - break; - } - - tmp_list = tmp_list->next; - } - - g_list_free (children); -} - -void -_gtk_menu_shell_select_last (GtkMenuShell *menu_shell, - gboolean search_sensitive) -{ - GList *tmp_list; - GList *children; - - children = gtk_menu_shell_get_items (menu_shell); - tmp_list = g_list_last (children); - while (tmp_list) - { - GtkWidget *child = tmp_list->data; - - if ((!search_sensitive && gtk_widget_get_visible (child)) || - _gtk_menu_item_is_selectable (child)) - { - gtk_menu_shell_select_item (menu_shell, child); - break; - } - - tmp_list = tmp_list->prev; - } - - g_list_free (children); -} - -static gboolean -gtk_menu_shell_select_submenu_first (GtkMenuShell *menu_shell) -{ - GtkMenuShellPrivate *priv = menu_shell->priv; - GtkMenuItem *menu_item; - - if (priv->active_menu_item == NULL) - return FALSE; - - menu_item = GTK_MENU_ITEM (priv->active_menu_item); - - if (menu_item->priv->submenu) - { - _gtk_menu_item_popup_submenu (GTK_WIDGET (menu_item), FALSE); - gtk_menu_shell_select_first (GTK_MENU_SHELL (menu_item->priv->submenu), TRUE); - if (GTK_MENU_SHELL (menu_item->priv->submenu)->priv->active_menu_item) - return TRUE; - } - - return FALSE; -} - -/* Moves the current menu item in direction 'direction': - * - * - GTK_MENU_DIR_PARENT: To the parent menu shell - * - GTK_MENU_DIR_CHILD: To the child menu shell (if this item has a submenu). - * - GTK_MENU_DIR_NEXT/PREV: To the next or previous item in this menu. - * - * As a bit of a hack to get movement between menus and - * menubars working, if submenu_placement is different for - * the menu and its MenuShell then the following apply: - * - * - For “parent” the current menu is not just moved to - * the parent, but moved to the previous entry in the parent - * - For 'child', if there is no child, then current is - * moved to the next item in the parent. - * - * Note that the above explanation of ::move_current was written - * before menus and menubars had support for RTL flipping and - * different packing directions, and therefore only applies for - * when text direction and packing direction are both left-to-right. - */ -static void -gtk_real_menu_shell_move_current (GtkMenuShell *menu_shell, - GtkMenuDirectionType direction) -{ - GtkMenuShellPrivate *priv = menu_shell->priv; - GtkMenuShell *parent_menu_shell = NULL; - gboolean had_selection; - - priv->in_unselectable_item = FALSE; - - had_selection = priv->active_menu_item != NULL; - - if (priv->parent_menu_shell) - parent_menu_shell = GTK_MENU_SHELL (priv->parent_menu_shell); - - switch (direction) - { - case GTK_MENU_DIR_PARENT: - 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); - else - { - gtk_menu_shell_move_selected (parent_menu_shell, -1); - gtk_menu_shell_select_submenu_first (parent_menu_shell); - } - } - /* If there is no parent and the submenu is in the opposite direction - * to the menu, then make the PARENT direction wrap around to - * the bottom of the submenu. - */ - else if (priv->active_menu_item && - _gtk_menu_item_is_selectable (priv->active_menu_item) && - GTK_MENU_ITEM (priv->active_menu_item)->priv->submenu) - { - GtkMenuShell *submenu = GTK_MENU_SHELL (GTK_MENU_ITEM (priv->active_menu_item)->priv->submenu); - - if (GTK_MENU_SHELL_GET_CLASS (menu_shell)->submenu_placement != - GTK_MENU_SHELL_GET_CLASS (submenu)->submenu_placement) - _gtk_menu_shell_select_last (submenu, TRUE); - } - break; - - case GTK_MENU_DIR_CHILD: - if (priv->active_menu_item && - _gtk_menu_item_is_selectable (priv->active_menu_item) && - GTK_MENU_ITEM (priv->active_menu_item)->priv->submenu) - { - if (gtk_menu_shell_select_submenu_first (menu_shell)) - break; - } - - /* Try to find a menu running the opposite direction */ - while (parent_menu_shell && - (GTK_MENU_SHELL_GET_CLASS (parent_menu_shell)->submenu_placement == - GTK_MENU_SHELL_GET_CLASS (menu_shell)->submenu_placement)) - { - parent_menu_shell = GTK_MENU_SHELL (parent_menu_shell->priv->parent_menu_shell); - } - - if (parent_menu_shell) - { - gtk_menu_shell_move_selected (parent_menu_shell, 1); - - gtk_menu_shell_select_submenu_first (parent_menu_shell); - } - break; - - case GTK_MENU_DIR_PREV: - gtk_menu_shell_move_selected (menu_shell, -1); - if (!had_selection && !priv->active_menu_item) - _gtk_menu_shell_select_last (menu_shell, TRUE); - break; - - case GTK_MENU_DIR_NEXT: - gtk_menu_shell_move_selected (menu_shell, 1); - if (!had_selection && !priv->active_menu_item) - gtk_menu_shell_select_first (menu_shell, TRUE); - break; - - default: - break; - } -} - -/* Activate the current item. If 'force_hide' is true, hide - * the current menu item always. Otherwise, only hide - * it if menu_item->klass->hide_on_activate is true. - */ -static void -gtk_real_menu_shell_activate_current (GtkMenuShell *menu_shell, - gboolean force_hide) -{ - GtkMenuShellPrivate *priv = menu_shell->priv; - - if (priv->active_menu_item && - _gtk_menu_item_is_selectable (priv->active_menu_item)) - { - if (GTK_MENU_ITEM (priv->active_menu_item)->priv->submenu == NULL) - gtk_menu_shell_activate_item (menu_shell, - priv->active_menu_item, - force_hide); - else - gtk_menu_shell_select_submenu_first (menu_shell); - } -} - -static void -gtk_real_menu_shell_cancel (GtkMenuShell *menu_shell) -{ - /* Unset the active menu item so gtk_menu_popdown() doesn't see it. */ - gtk_menu_shell_deselect (menu_shell); - gtk_menu_shell_deactivate (menu_shell); - g_signal_emit (menu_shell, menu_shell_signals[SELECTION_DONE], 0); -} - -static void -gtk_real_menu_shell_cycle_focus (GtkMenuShell *menu_shell, - GtkDirectionType dir) -{ - while (menu_shell && !GTK_IS_MENU_BAR (menu_shell)) - { - if (menu_shell->priv->parent_menu_shell) - menu_shell = GTK_MENU_SHELL (menu_shell->priv->parent_menu_shell); - else - menu_shell = NULL; - } - - if (menu_shell) - _gtk_menu_bar_cycle_focus (GTK_MENU_BAR (menu_shell), dir); -} - -gint -_gtk_menu_shell_get_popup_delay (GtkMenuShell *menu_shell) -{ - GtkMenuShellClass *klass = GTK_MENU_SHELL_GET_CLASS (menu_shell); - - if (klass->get_popup_delay) - { - return klass->get_popup_delay (menu_shell); - } - else - { - return MENU_POPUP_DELAY; - } -} - -/** - * gtk_menu_shell_cancel: - * @menu_shell: a #GtkMenuShell - * - * Cancels the selection within the menu shell. - */ -void -gtk_menu_shell_cancel (GtkMenuShell *menu_shell) -{ - g_return_if_fail (GTK_IS_MENU_SHELL (menu_shell)); - - g_signal_emit (menu_shell, menu_shell_signals[CANCEL], 0); -} - -static GtkMnemonicHash * -gtk_menu_shell_get_mnemonic_hash (GtkMenuShell *menu_shell, - gboolean create) -{ - GtkMenuShellPrivate *priv = menu_shell->priv; - - if (!priv->mnemonic_hash && create) - priv->mnemonic_hash = _gtk_mnemonic_hash_new (); - - return priv->mnemonic_hash; -} - -static void -menu_shell_add_mnemonic_foreach (guint keyval, - GSList *targets, - gpointer data) -{ - GtkKeyHash *key_hash = data; - - _gtk_key_hash_add_entry (key_hash, keyval, 0, GUINT_TO_POINTER (keyval)); -} - -static GtkKeyHash * -gtk_menu_shell_get_key_hash (GtkMenuShell *menu_shell, - gboolean create) -{ - GtkMenuShellPrivate *priv = menu_shell->priv; - GtkWidget *widget = GTK_WIDGET (menu_shell); - - if (!priv->key_hash && create) - { - GtkMnemonicHash *mnemonic_hash = gtk_menu_shell_get_mnemonic_hash (menu_shell, FALSE); - GdkKeymap *keymap = gdk_display_get_keymap (gtk_widget_get_display (widget)); - - if (!mnemonic_hash) - return NULL; - - priv->key_hash = _gtk_key_hash_new (keymap, NULL); - - _gtk_mnemonic_hash_foreach (mnemonic_hash, - menu_shell_add_mnemonic_foreach, - priv->key_hash); - } - - return priv->key_hash; -} - -static void -gtk_menu_shell_reset_key_hash (GtkMenuShell *menu_shell) -{ - GtkMenuShellPrivate *priv = menu_shell->priv; - - if (priv->key_hash) - { - _gtk_key_hash_free (priv->key_hash); - priv->key_hash = NULL; - } -} - -static gboolean -gtk_menu_shell_activate_mnemonic (GtkMenuShell *menu_shell, - guint keycode, - GdkModifierType state, - guint group) -{ - GtkMnemonicHash *mnemonic_hash; - GtkKeyHash *key_hash; - GSList *entries; - gboolean result = FALSE; - - mnemonic_hash = gtk_menu_shell_get_mnemonic_hash (menu_shell, FALSE); - if (!mnemonic_hash) - return FALSE; - - key_hash = gtk_menu_shell_get_key_hash (menu_shell, TRUE); - if (!key_hash) - return FALSE; - - entries = _gtk_key_hash_lookup (key_hash, - keycode, - state, - gtk_accelerator_get_default_mod_mask (), - group); - - if (entries) - { - result = _gtk_mnemonic_hash_activate (mnemonic_hash, - GPOINTER_TO_UINT (entries->data)); - g_slist_free (entries); - } - - return result; -} - -void -_gtk_menu_shell_add_mnemonic (GtkMenuShell *menu_shell, - guint keyval, - GtkWidget *target) -{ - g_return_if_fail (GTK_IS_MENU_SHELL (menu_shell)); - g_return_if_fail (GTK_IS_WIDGET (target)); - - _gtk_mnemonic_hash_add (gtk_menu_shell_get_mnemonic_hash (menu_shell, TRUE), - keyval, target); - gtk_menu_shell_reset_key_hash (menu_shell); -} - -void -_gtk_menu_shell_remove_mnemonic (GtkMenuShell *menu_shell, - guint keyval, - GtkWidget *target) -{ - g_return_if_fail (GTK_IS_MENU_SHELL (menu_shell)); - g_return_if_fail (GTK_IS_WIDGET (target)); - - _gtk_mnemonic_hash_remove (gtk_menu_shell_get_mnemonic_hash (menu_shell, TRUE), - keyval, target); - gtk_menu_shell_reset_key_hash (menu_shell); -} - -void -_gtk_menu_shell_set_grab_device (GtkMenuShell *menu_shell, - GdkDevice *device) -{ - GtkMenuShellPrivate *priv; - - g_return_if_fail (GTK_IS_MENU_SHELL (menu_shell)); - g_return_if_fail (device == NULL || GDK_IS_DEVICE (device)); - - priv = menu_shell->priv; - - if (!device) - priv->grab_pointer = NULL; - else if (gdk_device_get_source (device) == GDK_SOURCE_KEYBOARD) - priv->grab_pointer = gdk_device_get_associated_device (device); - else - priv->grab_pointer = device; -} - -GdkDevice * -_gtk_menu_shell_get_grab_device (GtkMenuShell *menu_shell) -{ - g_return_val_if_fail (GTK_IS_MENU_SHELL (menu_shell), NULL); - - return menu_shell->priv->grab_pointer; -} - -/** - * gtk_menu_shell_get_take_focus: - * @menu_shell: a #GtkMenuShell - * - * Returns %TRUE if the menu shell will take the keyboard focus on popup. - * - * Returns: %TRUE if the menu shell will take the keyboard focus on popup. - */ -gboolean -gtk_menu_shell_get_take_focus (GtkMenuShell *menu_shell) -{ - g_return_val_if_fail (GTK_IS_MENU_SHELL (menu_shell), FALSE); - - return menu_shell->priv->take_focus; -} - -/** - * gtk_menu_shell_set_take_focus: - * @menu_shell: a #GtkMenuShell - * @take_focus: %TRUE if the menu shell should take the keyboard - * focus on popup - * - * If @take_focus is %TRUE (the default) the menu shell will take - * the keyboard focus so that it will receive all keyboard events - * which is needed to enable keyboard navigation in menus. - * - * Setting @take_focus to %FALSE is useful only for special applications - * like virtual keyboard implementations which should not take keyboard - * focus. - * - * The @take_focus state of a menu or menu bar is automatically - * propagated to submenus whenever a submenu is popped up, so you - * don’t have to worry about recursively setting it for your entire - * menu hierarchy. Only when programmatically picking a submenu and - * popping it up manually, the @take_focus property of the submenu - * needs to be set explicitly. - * - * Note that setting it to %FALSE has side-effects: - * - * If the focus is in some other app, it keeps the focus and keynav in - * the menu doesn’t work. Consequently, keynav on the menu will only - * work if the focus is on some toplevel owned by the onscreen keyboard. - * - * To avoid confusing the user, menus with @take_focus set to %FALSE - * should not display mnemonics or accelerators, since it cannot be - * guaranteed that they will work. - */ -void -gtk_menu_shell_set_take_focus (GtkMenuShell *menu_shell, - gboolean take_focus) -{ - GtkMenuShellPrivate *priv; - - g_return_if_fail (GTK_IS_MENU_SHELL (menu_shell)); - - priv = menu_shell->priv; - - take_focus = !!take_focus; - if (priv->take_focus != take_focus) - { - priv->take_focus = take_focus; - g_object_notify (G_OBJECT (menu_shell), "take-focus"); - } -} - -/** - * gtk_menu_shell_get_selected_item: - * @menu_shell: a #GtkMenuShell - * - * Gets the currently selected item. - * - * Returns: (transfer none): the currently selected item - */ -GtkWidget * -gtk_menu_shell_get_selected_item (GtkMenuShell *menu_shell) -{ - g_return_val_if_fail (GTK_IS_MENU_SHELL (menu_shell), NULL); - - return menu_shell->priv->active_menu_item; -} - -/** - * gtk_menu_shell_get_parent_shell: - * @menu_shell: a #GtkMenuShell - * - * Gets the parent menu shell. - * - * The parent menu shell of a submenu is the #GtkMenu or #GtkMenuBar - * from which it was opened up. - * - * Returns: (transfer none): the parent #GtkMenuShell - */ -GtkWidget * -gtk_menu_shell_get_parent_shell (GtkMenuShell *menu_shell) -{ - g_return_val_if_fail (GTK_IS_MENU_SHELL (menu_shell), NULL); - - return menu_shell->priv->parent_menu_shell; -} - -static void -gtk_menu_shell_item_activate (GtkMenuItem *menuitem, - gpointer user_data) -{ - GtkMenuTrackerItem *item = user_data; - - gtk_menu_tracker_item_activated (item); -} - -static void -gtk_menu_shell_submenu_shown (GtkWidget *submenu, - gpointer user_data) -{ - GtkMenuTrackerItem *item = user_data; - - gtk_menu_tracker_item_request_submenu_shown (item, TRUE); -} - -static void -gtk_menu_shell_submenu_hidden (GtkWidget *submenu, - gpointer user_data) -{ - GtkMenuTrackerItem *item = user_data; - - if (!GTK_MENU_SHELL (submenu)->priv->selection_done_coming_soon) - gtk_menu_tracker_item_request_submenu_shown (item, FALSE); -} - -static void -gtk_menu_shell_submenu_selection_done (GtkWidget *submenu, - gpointer user_data) -{ - GtkMenuTrackerItem *item = user_data; - - if (GTK_MENU_SHELL (submenu)->priv->selection_done_coming_soon) - gtk_menu_tracker_item_request_submenu_shown (item, FALSE); -} - -static void -gtk_menu_shell_tracker_remove_func (gint position, - gpointer user_data) -{ - GtkMenuShell *menu_shell = user_data; - GList *children; - GtkWidget *child; - - children = gtk_menu_shell_get_items (menu_shell); - - child = g_list_nth_data (children, position); - /* We use destroy here because in the case of an item with a submenu, - * the attached-to from the submenu holds a ref on the item and a - * simple gtk_container_remove() isn't good enough to break that. - */ - gtk_widget_destroy (child); - - g_list_free (children); -} - -static void -gtk_menu_shell_tracker_insert_func (GtkMenuTrackerItem *item, - gint position, - gpointer user_data) -{ - GtkMenuShell *menu_shell = user_data; - GtkWidget *widget; - - if (gtk_menu_tracker_item_get_is_separator (item)) - { - const gchar *label; - - widget = gtk_separator_menu_item_new (); - - /* For separators, we may have a section heading, so check the - * "label" property. - * - * Note: we only do this once, and we only do it if the label is - * non-NULL because even setting a NULL label on the separator - * will be enough to create a GtkLabel and add it, changing the - * appearance in the process. - */ - - label = gtk_menu_tracker_item_get_label (item); - if (label) - gtk_menu_item_set_label (GTK_MENU_ITEM (widget), label); - } - else if (gtk_menu_tracker_item_get_has_link (item, G_MENU_LINK_SUBMENU)) - { - GtkMenuShell *submenu; - - widget = gtk_model_menu_item_new (); - g_object_bind_property (item, "label", widget, "text", G_BINDING_SYNC_CREATE); - - submenu = GTK_MENU_SHELL (gtk_menu_new ()); - gtk_widget_hide (GTK_WIDGET (submenu)); - - /* We recurse directly here: we could use an idle instead to - * prevent arbitrary recursion depth. We could also do it - * lazy... - */ - submenu->priv->tracker = gtk_menu_tracker_new_for_item_link (item, - G_MENU_LINK_SUBMENU, TRUE, FALSE, - gtk_menu_shell_tracker_insert_func, - gtk_menu_shell_tracker_remove_func, - submenu); - gtk_menu_item_set_submenu (GTK_MENU_ITEM (widget), GTK_WIDGET (submenu)); - - if (gtk_menu_tracker_item_get_should_request_show (item)) - { - /* We don't request show in the strictest sense of the - * word: we just notify when we are showing and don't - * bother waiting for the reply. - * - * This could be fixed one day, but it would be slightly - * complicated and would have a strange interaction with - * the submenu pop-up delay. - * - * Note: 'item' is already kept alive from above. - */ - g_signal_connect (submenu, "show", G_CALLBACK (gtk_menu_shell_submenu_shown), item); - g_signal_connect (submenu, "hide", G_CALLBACK (gtk_menu_shell_submenu_hidden), item); - g_signal_connect (submenu, "selection-done", G_CALLBACK (gtk_menu_shell_submenu_selection_done), item); - } - } - else - { - widget = gtk_model_menu_item_new (); - - /* We bind to "text" instead of "label" because GtkModelMenuItem - * uses this property (along with "icon") to control its child - * widget. Once this is merged into GtkMenuItem we can go back to - * using "label". - */ - g_object_bind_property (item, "label", widget, "text", G_BINDING_SYNC_CREATE); - g_object_bind_property (item, "icon", widget, "icon", G_BINDING_SYNC_CREATE); - g_object_bind_property (item, "sensitive", widget, "sensitive", G_BINDING_SYNC_CREATE); - g_object_bind_property (item, "role", widget, "action-role", G_BINDING_SYNC_CREATE); - g_object_bind_property (item, "toggled", widget, "toggled", G_BINDING_SYNC_CREATE); - g_object_bind_property (item, "accel", widget, "accel", G_BINDING_SYNC_CREATE); - - g_signal_connect (widget, "activate", G_CALLBACK (gtk_menu_shell_item_activate), item); - gtk_widget_show (widget); - } - - /* TODO: drop this when we have bindings that ref the source */ - g_object_set_data_full (G_OBJECT (widget), "GtkMenuTrackerItem", g_object_ref (item), g_object_unref); - - gtk_menu_shell_insert (menu_shell, widget, position); -} - -/** - * gtk_menu_shell_bind_model: - * @menu_shell: a #GtkMenuShell - * @model: (allow-none): the #GMenuModel to bind to or %NULL to remove - * binding - * @action_namespace: (allow-none): the namespace for actions in @model - * @with_separators: %TRUE if toplevel items in @shell should have - * separators between them - * - * Establishes a binding between a #GtkMenuShell and a #GMenuModel. - * - * The contents of @shell are removed and then refilled with menu items - * according to @model. When @model changes, @shell is updated. - * Calling this function twice on @shell with different @model will - * cause the first binding to be replaced with a binding to the new - * model. If @model is %NULL then any previous binding is undone and - * all children are removed. - * - * @with_separators determines if toplevel items (eg: sections) have - * separators inserted between them. This is typically desired for - * menus but doesn’t make sense for menubars. - * - * If @action_namespace is non-%NULL then the effect is as if all - * actions mentioned in the @model have their names prefixed with the - * namespace, plus a dot. For example, if the action “quit” is - * mentioned and @action_namespace is “app” then the effective action - * name is “app.quit”. - * - * This function uses #GtkActionable to define the action name and - * target values on the created menu items. If you want to use an - * action group other than “app” and “win”, or if you want to use a - * #GtkMenuShell outside of a #GtkApplicationWindow, then you will need - * to attach your own action group to the widget hierarchy using - * gtk_widget_insert_action_group(). As an example, if you created a - * group with a “quit” action and inserted it with the name “mygroup” - * then you would use the action name “mygroup.quit” in your - * #GMenuModel. - * - * For most cases you are probably better off using - * gtk_menu_new_from_model() or gtk_menu_bar_new_from_model() or just - * directly passing the #GMenuModel to gtk_application_set_app_menu() or - * gtk_application_set_menubar(). - */ -void -gtk_menu_shell_bind_model (GtkMenuShell *menu_shell, - GMenuModel *model, - const gchar *action_namespace, - gboolean with_separators) -{ - GtkActionMuxer *muxer; - GList *children, *l; - - g_return_if_fail (GTK_IS_MENU_SHELL (menu_shell)); - g_return_if_fail (model == NULL || G_IS_MENU_MODEL (model)); - - muxer = _gtk_widget_get_action_muxer (GTK_WIDGET (menu_shell), TRUE); - - g_clear_pointer (&menu_shell->priv->tracker, gtk_menu_tracker_free); - - children = gtk_menu_shell_get_items (menu_shell); - for (l = children; l; l = l->next) - gtk_widget_destroy (GTK_WIDGET (l->data)); - g_list_free (children); - - if (model) - menu_shell->priv->tracker = gtk_menu_tracker_new (GTK_ACTION_OBSERVABLE (muxer), model, - with_separators, TRUE, FALSE, action_namespace, - gtk_menu_shell_tracker_insert_func, - gtk_menu_shell_tracker_remove_func, - menu_shell); -} diff --git a/gtk/gtkmenushell.h b/gtk/gtkmenushell.h deleted file mode 100644 index 10274da35f..0000000000 --- a/gtk/gtkmenushell.h +++ /dev/null @@ -1,135 +0,0 @@ -/* GTK - The GIMP Toolkit - * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * 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, see . - */ - -/* - * Modified by the GTK+ Team and others 1997-2000. See the AUTHORS - * file for a list of people on the GTK+ Team. See the ChangeLog - * files for a list of changes. These files are distributed with - * GTK+ at ftp://ftp.gtk.org/pub/gtk/. - */ - -#ifndef __GTK_MENU_SHELL_H__ -#define __GTK_MENU_SHELL_H__ - -#if !defined (__GTK_H_INSIDE__) && !defined (GTK_COMPILATION) -#error "Only can be included directly." -#endif - -#include - -G_BEGIN_DECLS - -#define GTK_TYPE_MENU_SHELL (gtk_menu_shell_get_type ()) -#define GTK_MENU_SHELL(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GTK_TYPE_MENU_SHELL, GtkMenuShell)) -#define GTK_MENU_SHELL_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GTK_TYPE_MENU_SHELL, GtkMenuShellClass)) -#define GTK_IS_MENU_SHELL(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GTK_TYPE_MENU_SHELL)) -#define GTK_IS_MENU_SHELL_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GTK_TYPE_MENU_SHELL)) -#define GTK_MENU_SHELL_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GTK_TYPE_MENU_SHELL, GtkMenuShellClass)) - - -typedef struct _GtkMenuShell GtkMenuShell; -typedef struct _GtkMenuShellClass GtkMenuShellClass; -typedef struct _GtkMenuShellPrivate GtkMenuShellPrivate; - -struct _GtkMenuShell -{ - GtkContainer container; - - /*< private >*/ - GtkMenuShellPrivate *priv; -}; - -struct _GtkMenuShellClass -{ - GtkContainerClass parent_class; - - guint submenu_placement : 1; - - void (*deactivate) (GtkMenuShell *menu_shell); - void (*selection_done) (GtkMenuShell *menu_shell); - - void (*move_current) (GtkMenuShell *menu_shell, - GtkMenuDirectionType direction); - void (*activate_current) (GtkMenuShell *menu_shell, - gboolean force_hide); - void (*cancel) (GtkMenuShell *menu_shell); - void (*select_item) (GtkMenuShell *menu_shell, - GtkWidget *menu_item); - void (*insert) (GtkMenuShell *menu_shell, - GtkWidget *child, - gint position); - gint (*get_popup_delay) (GtkMenuShell *menu_shell); - gboolean (*move_selected) (GtkMenuShell *menu_shell, - gint distance); - GList * (*get_items) (GtkMenuShell *menu_shell); - - /*< private >*/ - gpointer padding[8]; -}; - - -GDK_AVAILABLE_IN_ALL -GType gtk_menu_shell_get_type (void) G_GNUC_CONST; - -GDK_AVAILABLE_IN_ALL -void gtk_menu_shell_append (GtkMenuShell *menu_shell, - GtkWidget *child); -GDK_AVAILABLE_IN_ALL -void gtk_menu_shell_prepend (GtkMenuShell *menu_shell, - GtkWidget *child); -GDK_AVAILABLE_IN_ALL -void gtk_menu_shell_insert (GtkMenuShell *menu_shell, - GtkWidget *child, - gint position); -GDK_AVAILABLE_IN_ALL -void gtk_menu_shell_deactivate (GtkMenuShell *menu_shell); -GDK_AVAILABLE_IN_ALL -void gtk_menu_shell_select_item (GtkMenuShell *menu_shell, - GtkWidget *menu_item); -GDK_AVAILABLE_IN_ALL -void gtk_menu_shell_deselect (GtkMenuShell *menu_shell); -GDK_AVAILABLE_IN_ALL -void gtk_menu_shell_activate_item (GtkMenuShell *menu_shell, - GtkWidget *menu_item, - gboolean force_deactivate); -GDK_AVAILABLE_IN_ALL -void gtk_menu_shell_select_first (GtkMenuShell *menu_shell, - gboolean search_sensitive); -GDK_AVAILABLE_IN_ALL -void gtk_menu_shell_cancel (GtkMenuShell *menu_shell); -GDK_AVAILABLE_IN_ALL -gboolean gtk_menu_shell_get_take_focus (GtkMenuShell *menu_shell); -GDK_AVAILABLE_IN_ALL -void gtk_menu_shell_set_take_focus (GtkMenuShell *menu_shell, - gboolean take_focus); - -GDK_AVAILABLE_IN_ALL -GtkWidget *gtk_menu_shell_get_selected_item (GtkMenuShell *menu_shell); -GDK_AVAILABLE_IN_ALL -GtkWidget *gtk_menu_shell_get_parent_shell (GtkMenuShell *menu_shell); - -GDK_AVAILABLE_IN_ALL -void gtk_menu_shell_bind_model (GtkMenuShell *menu_shell, - GMenuModel *model, - const gchar *action_namespace, - gboolean with_separators); - -G_DEFINE_AUTOPTR_CLEANUP_FUNC(GtkMenuShell, g_object_unref) - -G_END_DECLS - -#endif /* __GTK_MENU_SHELL_H__ */ diff --git a/gtk/gtkmenushellprivate.h b/gtk/gtkmenushellprivate.h deleted file mode 100644 index b966e686c3..0000000000 --- a/gtk/gtkmenushellprivate.h +++ /dev/null @@ -1,98 +0,0 @@ -/* GTK - The GIMP Toolkit - * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * 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, see . - */ - -#ifndef __GTK_MENU_SHELL_PRIVATE_H__ -#define __GTK_MENU_SHELL_PRIVATE_H__ - - -#include -#include -#include -#include -#include - -G_BEGIN_DECLS - -/* Placement of submenus */ -typedef enum -{ - GTK_TOP_BOTTOM, - GTK_LEFT_RIGHT -} GtkSubmenuPlacement; - -struct _GtkMenuShellPrivate -{ - GtkWidget *active_menu_item; /* This is not an "active" menu item - * (there is no such thing) but rather, - * the selected menu item in that MenuShell, - * if there is one. - */ - GtkWidget *parent_menu_shell; - GtkMenuTracker *tracker; // if bound to a GMenuModel - - guint button; - guint32 activate_time; - - guint active : 1; - guint have_grab : 1; - guint have_xgrab : 1; - guint ignore_enter : 1; - guint keyboard_mode : 1; - - guint take_focus : 1; - guint activated_submenu : 1; - guint in_unselectable_item : 1; /* This flag is a crutch to keep - * mnemonics in the same menu if - * the user moves the mouse over - * an unselectable menuitem. - */ - - guint selection_done_coming_soon : 1; /* Set TRUE when a selection-done - * signal is coming soon (when checked - * from inside of a "hide" handler). - */ - GtkMnemonicHash *mnemonic_hash; - GtkKeyHash *key_hash; - - GdkDevice *grab_pointer; - GtkEventController *key_controller; -}; - -void _gtk_menu_shell_select_last (GtkMenuShell *menu_shell, - gboolean search_sensitive); -gint _gtk_menu_shell_get_popup_delay (GtkMenuShell *menu_shell); -void _gtk_menu_shell_set_grab_device (GtkMenuShell *menu_shell, - GdkDevice *device); -GdkDevice *_gtk_menu_shell_get_grab_device (GtkMenuShell *menu_shell); - -void _gtk_menu_shell_add_mnemonic (GtkMenuShell *menu_shell, - guint keyval, - GtkWidget *target); -void _gtk_menu_shell_remove_mnemonic (GtkMenuShell *menu_shell, - guint keyval, - GtkWidget *target); - -void _gtk_menu_shell_update_mnemonics (GtkMenuShell *menu_shell); -void _gtk_menu_shell_set_keyboard_mode (GtkMenuShell *menu_shell, - gboolean keyboard_mode); -gboolean _gtk_menu_shell_get_keyboard_mode (GtkMenuShell *menu_shell); -GList *gtk_menu_shell_get_items (GtkMenuShell *menu_shell); - - -G_END_DECLS - -#endif /* __GTK_MENU_SHELL_PRIVATE_H__ */ diff --git a/gtk/gtkmenutoolbutton.c b/gtk/gtkmenutoolbutton.c index 0f7cd35cb9..d49e036734 100644 --- a/gtk/gtkmenutoolbutton.c +++ b/gtk/gtkmenutoolbutton.c @@ -25,7 +25,6 @@ #include "gtkmenubutton.h" #include "gtkmenubuttonprivate.h" #include "gtkbox.h" -#include "gtkmenu.h" #include "gtkpopover.h" #include "gtkmain.h" #include "gtksizerequest.h" diff --git a/gtk/gtkmodelmenuitem.c b/gtk/gtkmodelmenuitem.c deleted file mode 100644 index b52e126053..0000000000 --- a/gtk/gtkmodelmenuitem.c +++ /dev/null @@ -1,505 +0,0 @@ -/* - * Copyright © 2011, 2013 Canonical Limited - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the licence, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * 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, see . - * - * Author: Ryan Lortie - */ - -#include "config.h" - -#include "gtkmodelmenuitemprivate.h" - -#include "gtkaccellabel.h" -#include "gtklabel.h" -#include "gtkcheckmenuitemprivate.h" -#include "gtkimage.h" -#include "gtkbox.h" - -struct _GtkModelMenuItem -{ - GtkCheckMenuItem parent_instance; - GtkMenuTrackerItemRole role; - gboolean has_indicator; -}; - -typedef GtkCheckMenuItemClass GtkModelMenuItemClass; - -G_DEFINE_TYPE (GtkModelMenuItem, gtk_model_menu_item, GTK_TYPE_CHECK_MENU_ITEM) - -enum -{ - PROP_0, - PROP_ACTION_ROLE, - PROP_ICON, - PROP_TEXT, - PROP_TOGGLED, - PROP_ACCEL -}; - -static void -gtk_model_menu_item_toggle_size_request (GtkMenuItem *menu_item, - gint *requisition) -{ - GtkModelMenuItem *item = GTK_MODEL_MENU_ITEM (menu_item); - - if (item->has_indicator) - GTK_MENU_ITEM_CLASS (gtk_model_menu_item_parent_class) - ->toggle_size_request (menu_item, requisition); - - else - *requisition = 0; -} - -static void -gtk_model_menu_item_activate (GtkMenuItem *item) -{ - /* block the automatic toggle behaviour -- just do nothing */ -} - -static void -gtk_model_menu_item_set_has_indicator (GtkModelMenuItem *item, - gboolean has_indicator) -{ - if (has_indicator == item->has_indicator) - return; - - item->has_indicator = has_indicator; - - gtk_widget_set_visible (_gtk_check_menu_item_get_indicator_widget (GTK_CHECK_MENU_ITEM (item)), - item->has_indicator); -} - -static void -gtk_model_menu_item_set_action_role (GtkModelMenuItem *item, - GtkMenuTrackerItemRole role) -{ - AtkObject *accessible; - AtkRole a11y_role; - - if (role == item->role) - return; - - gtk_check_menu_item_set_draw_as_radio (GTK_CHECK_MENU_ITEM (item), role == GTK_MENU_TRACKER_ITEM_ROLE_RADIO); - gtk_model_menu_item_set_has_indicator (item, role != GTK_MENU_TRACKER_ITEM_ROLE_NORMAL); - - accessible = gtk_widget_get_accessible (GTK_WIDGET (item)); - switch (role) - { - case GTK_MENU_TRACKER_ITEM_ROLE_NORMAL: - a11y_role = ATK_ROLE_MENU_ITEM; - break; - - case GTK_MENU_TRACKER_ITEM_ROLE_CHECK: - a11y_role = ATK_ROLE_CHECK_MENU_ITEM; - break; - - case GTK_MENU_TRACKER_ITEM_ROLE_RADIO: - a11y_role = ATK_ROLE_RADIO_MENU_ITEM; - break; - - default: - g_assert_not_reached (); - } - - atk_object_set_role (accessible, a11y_role); - g_object_notify (G_OBJECT (item), "action-role"); -} - -static void -gtk_model_menu_item_set_icon (GtkModelMenuItem *item, - GIcon *icon) -{ - GtkWidget *child; - - g_return_if_fail (GTK_IS_MODEL_MENU_ITEM (item)); - g_return_if_fail (icon == NULL || G_IS_ICON (icon)); - - child = gtk_bin_get_child (GTK_BIN (item)); - - /* There are only three possibilities here: - * - * - no child - * - accel label child - * - already a box - * - * Handle the no-child case by having GtkMenuItem create the accel - * label, then we will only have two possible cases. - */ - if (child == NULL) - { - gtk_menu_item_get_label (GTK_MENU_ITEM (item)); - child = gtk_bin_get_child (GTK_BIN (item)); - g_assert (GTK_IS_ACCEL_LABEL (child)); - } - - /* If it is a box, make sure there are no images inside of it already. - */ - if (GTK_IS_BOX (child)) - { - GList *children; - - children = gtk_container_get_children (GTK_CONTAINER (child)); - while (children) - { - if (GTK_IS_IMAGE (children->data)) - gtk_widget_destroy (children->data); - - children = g_list_delete_link (children, children); - } - } - else - { - GtkWidget *box; - - if (icon == NULL) - return; - - box = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0); - - /* Reparent the child without destroying it */ - g_object_ref (child); - gtk_container_remove (GTK_CONTAINER (item), child); - gtk_container_add (GTK_CONTAINER (box), child); - g_object_unref (child); - - gtk_container_add (GTK_CONTAINER (item), box); - - /* Now we have a box */ - child = box; - } - - g_assert (GTK_IS_BOX (child)); - - /* child is now a box containing a label and no image. Add the icon, - * if appropriate. - */ - if (icon != NULL) - { - GtkWidget *image; - - image = gtk_image_new_from_gicon (icon); - gtk_image_set_pixel_size (GTK_IMAGE (image), 16); - gtk_box_insert_child_after (GTK_BOX (child), image, NULL); - } - - g_object_notify (G_OBJECT (item), "icon"); -} - -static GIcon * -gtk_model_menu_item_get_icon (GtkModelMenuItem *item) -{ - GtkWidget *child; - GIcon *icon = NULL; - - child = gtk_bin_get_child (GTK_BIN (item)); - if (GTK_IS_BOX (child)) - { - GList *children, *l; - - children = gtk_container_get_children (GTK_CONTAINER (child)); - for (l = children; l; l = l->next) - { - if (GTK_IS_IMAGE (l->data)) - { - icon = gtk_image_get_gicon (GTK_IMAGE (l->data)); - break; - } - } - g_list_free (children); - } - - return icon; -} - -static void -gtk_model_menu_item_set_text (GtkModelMenuItem *item, - const gchar *text) -{ - GtkWidget *child; - GList *children; - - child = gtk_bin_get_child (GTK_BIN (item)); - if (child == NULL) - { - gtk_menu_item_get_label (GTK_MENU_ITEM (item)); - child = gtk_bin_get_child (GTK_BIN (item)); - g_assert (GTK_IS_ACCEL_LABEL (child)); - } - - if (GTK_IS_LABEL (child)) - { - gtk_label_set_text_with_mnemonic (GTK_LABEL (child), text); - return; - } - else if (GTK_IS_ACCEL_LABEL (child)) - { - gtk_accel_label_set_label (GTK_ACCEL_LABEL (child), text); - return; - } - - if (!GTK_IS_CONTAINER (child)) - return; - - children = gtk_container_get_children (GTK_CONTAINER (child)); - - while (children) - { - if (GTK_IS_LABEL (children->data)) - gtk_label_set_label (GTK_LABEL (children->data), text); - - children = g_list_delete_link (children, children); - } - - g_object_notify (G_OBJECT (item), "text"); -} - -static const gchar * -gtk_model_menu_item_get_text (GtkModelMenuItem *item) -{ - GtkWidget *child; - - child = gtk_bin_get_child (GTK_BIN (item)); - - if (GTK_IS_LABEL (child)) - return gtk_label_get_text (GTK_LABEL (child)); - else if (GTK_IS_ACCEL_LABEL (child)) - return gtk_accel_label_get_label (GTK_ACCEL_LABEL (child)); - - if (GTK_IS_CONTAINER (child)) - { - GList *children, *l; - const gchar *text = NULL; - - children = gtk_container_get_children (GTK_CONTAINER (child)); - for (l = children; l; l = l->next) - { - if (GTK_IS_LABEL (l->data)) - { - text = gtk_label_get_text (GTK_LABEL (l->data)); - break; - } - } - g_list_free (children); - - return text; - } - - return NULL; -} - -static void -gtk_model_menu_item_set_accel (GtkModelMenuItem *item, - const gchar *accel) -{ - GtkWidget *child; - GList *children; - GdkModifierType modifiers; - guint key; - - if (accel) - { - gtk_accelerator_parse (accel, &key, &modifiers); - if (!key) - modifiers = 0; - } - else - { - key = 0; - modifiers = 0; - } - - child = gtk_bin_get_child (GTK_BIN (item)); - if (child == NULL) - { - gtk_menu_item_get_label (GTK_MENU_ITEM (item)); - child = gtk_bin_get_child (GTK_BIN (item)); - g_assert (GTK_IS_LABEL (child)); - } - - if (GTK_IS_ACCEL_LABEL (child)) - { - gtk_accel_label_set_accel (GTK_ACCEL_LABEL (child), key, modifiers); - return; - } - - if (!GTK_IS_CONTAINER (child)) - return; - - children = gtk_container_get_children (GTK_CONTAINER (child)); - - while (children) - { - if (GTK_IS_ACCEL_LABEL (children->data)) - gtk_accel_label_set_accel (children->data, key, modifiers); - - children = g_list_delete_link (children, children); - } -} - -static gchar * -gtk_model_menu_item_get_accel (GtkModelMenuItem *item) -{ - GtkWidget *child; - GtkWidget *accel_label = NULL; - - child = gtk_bin_get_child (GTK_BIN (item)); - - if (GTK_IS_ACCEL_LABEL (child)) - accel_label = child; - else if (GTK_IS_CONTAINER (child)) - { - GList *children, *l; - - children = gtk_container_get_children (GTK_CONTAINER (child)); - for (l = children; l; l = l->next) - { - if (GTK_IS_ACCEL_LABEL (l->data)) - { - accel_label = GTK_WIDGET (l->data); - break; - } - } - g_list_free (children); - } - - if (accel_label) - { - guint key; - GdkModifierType mods; - - gtk_accel_label_get_accel (GTK_ACCEL_LABEL (accel_label), &key, &mods); - - return gtk_accelerator_name (key, mods); - } - - return NULL; -} - -static void -gtk_model_menu_item_get_property (GObject *object, - guint prop_id, - GValue *value, - GParamSpec *pspec) -{ - GtkModelMenuItem *item = GTK_MODEL_MENU_ITEM (object); - - switch (prop_id) - { - case PROP_ACTION_ROLE: - g_value_set_enum (value, item->role); - break; - - case PROP_ICON: - g_value_set_object (value, gtk_model_menu_item_get_icon (item)); - break; - - case PROP_TEXT: - g_value_set_string (value, gtk_model_menu_item_get_text (item)); - break; - - case PROP_TOGGLED: - g_value_set_boolean (value, gtk_check_menu_item_get_active (GTK_CHECK_MENU_ITEM (item))); - break; - - case PROP_ACCEL: - g_value_take_string (value, gtk_model_menu_item_get_accel (item)); - break; - - default: - g_assert_not_reached (); - } -} - -static void -gtk_model_menu_item_set_property (GObject *object, - guint prop_id, - const GValue *value, - GParamSpec *pspec) -{ - GtkModelMenuItem *item = GTK_MODEL_MENU_ITEM (object); - - switch (prop_id) - { - case PROP_ACTION_ROLE: - gtk_model_menu_item_set_action_role (item, g_value_get_enum (value)); - break; - - case PROP_ICON: - gtk_model_menu_item_set_icon (item, g_value_get_object (value)); - break; - - case PROP_TEXT: - gtk_model_menu_item_set_text (item, g_value_get_string (value)); - break; - - case PROP_TOGGLED: - _gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (item), g_value_get_boolean (value)); - g_object_notify (object, "active"); - break; - - case PROP_ACCEL: - gtk_model_menu_item_set_accel (item, g_value_get_string (value)); - break; - - default: - g_assert_not_reached (); - } -} - -static void -gtk_model_menu_item_init (GtkModelMenuItem *item) -{ - item->has_indicator = FALSE; - gtk_widget_hide (_gtk_check_menu_item_get_indicator_widget (GTK_CHECK_MENU_ITEM (item))); -} - -static void -gtk_model_menu_item_class_init (GtkModelMenuItemClass *class) -{ - GtkMenuItemClass *item_class = GTK_MENU_ITEM_CLASS (class); - GObjectClass *object_class = G_OBJECT_CLASS (class); - - item_class->toggle_size_request = gtk_model_menu_item_toggle_size_request; - item_class->activate = gtk_model_menu_item_activate; - - object_class->get_property = gtk_model_menu_item_get_property; - object_class->set_property = gtk_model_menu_item_set_property; - - g_object_class_install_property (object_class, PROP_ACTION_ROLE, - g_param_spec_enum ("action-role", "action role", "action role", - GTK_TYPE_MENU_TRACKER_ITEM_ROLE, - GTK_MENU_TRACKER_ITEM_ROLE_NORMAL, - G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_EXPLICIT_NOTIFY)); - g_object_class_install_property (object_class, PROP_ICON, - g_param_spec_object ("icon", "icon", "icon", G_TYPE_ICON, - G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_EXPLICIT_NOTIFY)); - g_object_class_install_property (object_class, PROP_TEXT, - g_param_spec_string ("text", "text", "text", NULL, - G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_EXPLICIT_NOTIFY)); - g_object_class_install_property (object_class, PROP_TOGGLED, - g_param_spec_boolean ("toggled", "toggled", "toggled", FALSE, - G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_EXPLICIT_NOTIFY)); - g_object_class_install_property (object_class, PROP_ACCEL, - g_param_spec_string ("accel", "accel", "accel", NULL, - G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_EXPLICIT_NOTIFY)); - - gtk_widget_class_set_accessible_role (GTK_WIDGET_CLASS (class), ATK_ROLE_MENU_ITEM); -} - -GtkWidget * -gtk_model_menu_item_new (void) -{ - return g_object_new (GTK_TYPE_MODEL_MENU_ITEM, NULL); -} diff --git a/gtk/gtkmodelmenuitemprivate.h b/gtk/gtkmodelmenuitemprivate.h deleted file mode 100644 index 92be6a3f5b..0000000000 --- a/gtk/gtkmodelmenuitemprivate.h +++ /dev/null @@ -1,40 +0,0 @@ -/* - * Copyright © 2011 Canonical Limited - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the licence, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * 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, see . - * - * Author: Ryan Lortie - */ - -#ifndef __GTK_MODEL_MENU_ITEM_PRIVATE_H__ -#define __GTK_MODEL_MENU_ITEM_PRIVATE_H__ - -#include -#include - -#define GTK_TYPE_MODEL_MENU_ITEM (gtk_model_menu_item_get_type ()) -#define GTK_MODEL_MENU_ITEM(inst) (G_TYPE_CHECK_INSTANCE_CAST ((inst), \ - GTK_TYPE_MODEL_MENU_ITEM, GtkModelMenuItem)) -#define GTK_IS_MODEL_MENU_ITEM(inst) (G_TYPE_CHECK_INSTANCE_TYPE ((inst), \ - GTK_TYPE_MODEL_MENU_ITEM)) - -typedef struct _GtkModelMenuItem GtkModelMenuItem; - -G_GNUC_INTERNAL -GType gtk_model_menu_item_get_type (void) G_GNUC_CONST; - -G_GNUC_INTERNAL -GtkWidget * gtk_model_menu_item_new (void); - -#endif /* __GTK_MODEL_MENU_ITEM_PRIVATE_H__ */ diff --git a/gtk/gtkmountoperation.c b/gtk/gtkmountoperation.c index 3d292e1378..b94d124818 100644 --- a/gtk/gtkmountoperation.c +++ b/gtk/gtkmountoperation.c @@ -48,7 +48,6 @@ #include "gtkcellrendererpixbuf.h" #include "gtkscrolledwindow.h" #include "gtkicontheme.h" -#include "gtkmenuitem.h" #include "gtkmain.h" #include "gtksettings.h" #include "gtkstylecontextprivate.h" diff --git a/gtk/gtkpasswordentry.c b/gtk/gtkpasswordentry.c index 99717faf37..a2eeda7900 100644 --- a/gtk/gtkpasswordentry.c +++ b/gtk/gtkpasswordentry.c @@ -29,7 +29,6 @@ #include "gtkgestureclick.h" #include "gtkbox.h" #include "gtkimage.h" -#include "gtkcheckmenuitem.h" #include "gtkintl.h" #include "gtkprivate.h" #include "gtkmarshalers.h" diff --git a/gtk/gtkplacessidebar.c b/gtk/gtkplacessidebar.c index 6b2ec5596e..6af770161b 100644 --- a/gtk/gtkplacessidebar.c +++ b/gtk/gtkplacessidebar.c @@ -40,10 +40,8 @@ #include "gtkintl.h" #include "gtkmain.h" #include "gtkmarshalers.h" -#include "gtkmenuitem.h" #include "gtkmountoperation.h" #include "gtkscrolledwindow.h" -#include "gtkseparatormenuitem.h" #include "gtksettings.h" #include "gtktrashmonitor.h" #include "gtktypebuiltins.h" @@ -195,10 +193,6 @@ struct _GtkPlacesSidebarClass { void (* open_location) (GtkPlacesSidebar *sidebar, GFile *location, GtkPlacesOpenFlags open_flags); - void (* populate_popup) (GtkPlacesSidebar *sidebar, - GtkMenu *menu, - GFile *selected_item, - GVolume *selected_volume); void (* show_error_message) (GtkPlacesSidebar *sidebar, const gchar *primary, const gchar *secondary); diff --git a/gtk/gtkradiomenuitem.c b/gtk/gtkradiomenuitem.c deleted file mode 100644 index 261f0f44b5..0000000000 --- a/gtk/gtkradiomenuitem.c +++ /dev/null @@ -1,616 +0,0 @@ -/* GTK - The GIMP Toolkit - * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * 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, see . - */ - -/* - * Modified by the GTK+ Team and others 1997-2000. See the AUTHORS - * file for a list of people on the GTK+ Team. See the ChangeLog - * files for a list of changes. These files are distributed with - * GTK+ at ftp://ftp.gtk.org/pub/gtk/. - */ - -#include "config.h" -#include "gtkaccellabel.h" -#include "gtkcheckmenuitemprivate.h" -#include "gtkmarshalers.h" -#include "gtkradiomenuitem.h" -#include "gtkprivate.h" -#include "gtkintl.h" -#include "a11y/gtkradiomenuitemaccessible.h" - -/** - * SECTION:gtkradiomenuitem - * @Short_description: A choice from multiple check menu items - * @Title: GtkRadioMenuItem - * @See_also: #GtkMenuItem, #GtkCheckMenuItem - * - * A radio menu item is a check menu item that belongs to a group. At each - * instant exactly one of the radio menu items from a group is selected. - * - * The group list does not need to be freed, as each #GtkRadioMenuItem will - * remove itself and its list item when it is destroyed. - * - * The correct way to create a group of radio menu items is approximatively - * this: - * - * ## How to create a group of radio menu items. - * - * |[ - * GSList *group = NULL; - * GtkWidget *item; - * gint i; - * - * for (i = 0; i < 5; i++) - * { - * item = gtk_radio_menu_item_new_with_label (group, "This is an example"); - * group = gtk_radio_menu_item_get_group (GTK_RADIO_MENU_ITEM (item)); - * if (i == 1) - * gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (item), TRUE); - * } - * ]| - * - * # CSS nodes - * - * |[ - * menuitem - * ├── radio.left - * ╰── - * ]| - * - * GtkRadioMenuItem has a main CSS node with name menuitem, and a subnode - * with name radio, which gets the .left or .right style class. - */ - -typedef struct _GtkRadioMenuItemPrivate GtkRadioMenuItemPrivate; -typedef struct _GtkRadioMenuItemClass GtkRadioMenuItemClass; - -struct _GtkRadioMenuItem -{ - GtkCheckMenuItem check_menu_item; -}; - -struct _GtkRadioMenuItemClass -{ - GtkCheckMenuItemClass parent_class; - - void (*group_changed) (GtkRadioMenuItem *radio_menu_item); -}; - -struct _GtkRadioMenuItemPrivate -{ - GSList *group; -}; - -enum { - PROP_0, - PROP_GROUP -}; - - -static void gtk_radio_menu_item_destroy (GtkWidget *widget); -static void gtk_radio_menu_item_activate (GtkMenuItem *menu_item); -static void gtk_radio_menu_item_set_property (GObject *object, - guint prop_id, - const GValue *value, - GParamSpec *pspec); -static void gtk_radio_menu_item_get_property (GObject *object, - guint prop_id, - GValue *value, - GParamSpec *pspec); - -static guint group_changed_signal = 0; - -G_DEFINE_TYPE_WITH_PRIVATE (GtkRadioMenuItem, gtk_radio_menu_item, GTK_TYPE_CHECK_MENU_ITEM) - -/** - * gtk_radio_menu_item_new: - * @group: (element-type GtkRadioMenuItem) (allow-none): the group to which the - * radio menu item is to be attached, or %NULL - * - * Creates a new #GtkRadioMenuItem. - * - * Returns: a new #GtkRadioMenuItem - */ -GtkWidget* -gtk_radio_menu_item_new (GSList *group) -{ - GtkRadioMenuItem *radio_menu_item; - - radio_menu_item = g_object_new (GTK_TYPE_RADIO_MENU_ITEM, NULL); - - gtk_radio_menu_item_set_group (radio_menu_item, group); - - return GTK_WIDGET (radio_menu_item); -} - -static void -gtk_radio_menu_item_set_property (GObject *object, - guint prop_id, - const GValue *value, - GParamSpec *pspec) -{ - GtkRadioMenuItem *radio_menu_item; - - radio_menu_item = GTK_RADIO_MENU_ITEM (object); - - switch (prop_id) - { - GSList *slist; - - case PROP_GROUP: - slist = g_value_get_object (value); - if (slist) - slist = gtk_radio_menu_item_get_group ((GtkRadioMenuItem*) g_value_get_object (value)); - gtk_radio_menu_item_set_group (radio_menu_item, slist); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; - } -} - -static void -gtk_radio_menu_item_get_property (GObject *object, - guint prop_id, - GValue *value, - GParamSpec *pspec) -{ - switch (prop_id) - { - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; - } -} - -/** - * gtk_radio_menu_item_set_group: - * @radio_menu_item: a #GtkRadioMenuItem. - * @group: (element-type GtkRadioMenuItem) (allow-none): the new group, or %NULL. - * - * Sets the group of a radio menu item, or changes it. - */ -void -gtk_radio_menu_item_set_group (GtkRadioMenuItem *radio_menu_item, - GSList *group) -{ - GtkRadioMenuItemPrivate *priv = gtk_radio_menu_item_get_instance_private (radio_menu_item); - GtkWidget *old_group_singleton = NULL; - GtkWidget *new_group_singleton = NULL; - - g_return_if_fail (GTK_IS_RADIO_MENU_ITEM (radio_menu_item)); - - if (priv->group == group) - return; - - if (priv->group) - { - GSList *slist; - - priv->group = g_slist_remove (priv->group, radio_menu_item); - - if (priv->group && !priv->group->next) - old_group_singleton = g_object_ref (priv->group->data); - - for (slist = priv->group; slist; slist = slist->next) - { - GtkRadioMenuItem *tmp_item = slist->data; - GtkRadioMenuItemPrivate *tmp_priv = gtk_radio_menu_item_get_instance_private (tmp_item); - - tmp_priv->group = priv->group; - } - } - - if (group && !group->next) - new_group_singleton = g_object_ref (group->data); - - priv->group = g_slist_prepend (group, radio_menu_item); - - if (group) - { - GSList *slist; - - for (slist = group; slist; slist = slist->next) - { - GtkRadioMenuItem *tmp_item = slist->data; - GtkRadioMenuItemPrivate *tmp_priv = gtk_radio_menu_item_get_instance_private (tmp_item); - - tmp_priv->group = priv->group; - } - - _gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (radio_menu_item), FALSE); - } - else - { - _gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (radio_menu_item), TRUE); - /* gtk_widget_set_state (GTK_WIDGET (radio_menu_item), GTK_STATE_ACTIVE); - */ - } - - g_object_ref (radio_menu_item); - - g_object_notify (G_OBJECT (radio_menu_item), "group"); - g_signal_emit (radio_menu_item, group_changed_signal, 0); - if (old_group_singleton) - { - g_signal_emit (old_group_singleton, group_changed_signal, 0); - g_object_unref (old_group_singleton); - } - if (new_group_singleton) - { - g_signal_emit (new_group_singleton, group_changed_signal, 0); - g_object_unref (new_group_singleton); - } - - g_object_unref (radio_menu_item); -} - - -/** - * gtk_radio_menu_item_new_with_label: - * @group: (element-type GtkRadioMenuItem) (allow-none): - * group the radio menu item is inside, or %NULL - * @label: the text for the label - * - * Creates a new #GtkRadioMenuItem whose child is a simple #GtkLabel. - * - * Returns: (transfer none): A new #GtkRadioMenuItem - */ -GtkWidget* -gtk_radio_menu_item_new_with_label (GSList *group, - const gchar *label) -{ - return g_object_new (GTK_TYPE_RADIO_MENU_ITEM, - "group", (group) ? group->data : NULL, - "label", label, - NULL); -} - - -/** - * gtk_radio_menu_item_new_with_mnemonic: - * @group: (element-type GtkRadioMenuItem) (allow-none): - * group the radio menu item is inside, or %NULL - * @label: the text of the button, with an underscore in front of the - * mnemonic character - * - * Creates a new #GtkRadioMenuItem containing a label. The label - * will be created using gtk_label_new_with_mnemonic(), so underscores - * in @label indicate the mnemonic for the menu item. - * - * Returns: a new #GtkRadioMenuItem - */ -GtkWidget* -gtk_radio_menu_item_new_with_mnemonic (GSList *group, - const gchar *label) -{ - return g_object_new (GTK_TYPE_RADIO_MENU_ITEM, - "group", (group) ? group->data : NULL, - "label", label, - "use-underline", TRUE, - NULL); -} - -/** - * gtk_radio_menu_item_new_from_widget: (constructor) - * @group: (allow-none): An existing #GtkRadioMenuItem - * - * Creates a new #GtkRadioMenuItem adding it to the same group as @group. - * - * Returns: (transfer none): The new #GtkRadioMenuItem - **/ -GtkWidget * -gtk_radio_menu_item_new_from_widget (GtkRadioMenuItem *group) -{ - GSList *list = NULL; - - g_return_val_if_fail (group == NULL || GTK_IS_RADIO_MENU_ITEM (group), NULL); - - if (group) - list = gtk_radio_menu_item_get_group (group); - - return gtk_radio_menu_item_new (list); -} - -/** - * gtk_radio_menu_item_new_with_mnemonic_from_widget: (constructor) - * @group: (allow-none): An existing #GtkRadioMenuItem - * @label: (allow-none): the text of the button, with an underscore in front of the - * mnemonic character - * - * Creates a new GtkRadioMenuItem containing a label. The label will be - * created using gtk_label_new_with_mnemonic(), so underscores in label - * indicate the mnemonic for the menu item. - * - * The new #GtkRadioMenuItem is added to the same group as @group. - * - * Returns: (transfer none): The new #GtkRadioMenuItem - **/ -GtkWidget * -gtk_radio_menu_item_new_with_mnemonic_from_widget (GtkRadioMenuItem *group, - const gchar *label) -{ - GSList *list = NULL; - - g_return_val_if_fail (group == NULL || GTK_IS_RADIO_MENU_ITEM (group), NULL); - - if (group) - list = gtk_radio_menu_item_get_group (group); - - return gtk_radio_menu_item_new_with_mnemonic (list, label); -} - -/** - * gtk_radio_menu_item_new_with_label_from_widget: (constructor) - * @group: (allow-none): an existing #GtkRadioMenuItem - * @label: (allow-none): the text for the label - * - * Creates a new GtkRadioMenuItem whose child is a simple GtkLabel. - * The new #GtkRadioMenuItem is added to the same group as @group. - * - * Returns: (transfer none): The new #GtkRadioMenuItem - **/ -GtkWidget * -gtk_radio_menu_item_new_with_label_from_widget (GtkRadioMenuItem *group, - const gchar *label) -{ - GSList *list = NULL; - - g_return_val_if_fail (group == NULL || GTK_IS_RADIO_MENU_ITEM (group), NULL); - - if (group) - list = gtk_radio_menu_item_get_group (group); - - return gtk_radio_menu_item_new_with_label (list, label); -} - -/** - * gtk_radio_menu_item_get_group: - * @radio_menu_item: a #GtkRadioMenuItem - * - * Returns the group to which the radio menu item belongs, as a #GList of - * #GtkRadioMenuItem. The list belongs to GTK+ and should not be freed. - * - * Returns: (element-type GtkRadioMenuItem) (transfer none): the group - * of @radio_menu_item - */ -GSList* -gtk_radio_menu_item_get_group (GtkRadioMenuItem *radio_menu_item) -{ - GtkRadioMenuItemPrivate *priv = gtk_radio_menu_item_get_instance_private (radio_menu_item); - - g_return_val_if_fail (GTK_IS_RADIO_MENU_ITEM (radio_menu_item), NULL); - - return priv->group; -} - -static void -gtk_radio_menu_item_class_init (GtkRadioMenuItemClass *klass) -{ - GObjectClass *gobject_class; - GtkWidgetClass *widget_class; - GtkMenuItemClass *menu_item_class; - - gobject_class = G_OBJECT_CLASS (klass); - widget_class = GTK_WIDGET_CLASS (klass); - menu_item_class = GTK_MENU_ITEM_CLASS (klass); - - gobject_class->set_property = gtk_radio_menu_item_set_property; - gobject_class->get_property = gtk_radio_menu_item_get_property; - - widget_class->destroy = gtk_radio_menu_item_destroy; - - gtk_widget_class_set_accessible_type (widget_class, GTK_TYPE_RADIO_MENU_ITEM_ACCESSIBLE); - - menu_item_class->activate = gtk_radio_menu_item_activate; - - /** - * GtkRadioMenuItem:group: - * - * The radio menu item whose group this widget belongs to. - */ - g_object_class_install_property (gobject_class, - PROP_GROUP, - g_param_spec_object ("group", - P_("Group"), - P_("The radio menu item whose group this widget belongs to."), - GTK_TYPE_RADIO_MENU_ITEM, - GTK_PARAM_WRITABLE)); - - /** - * GtkStyle::group-changed: - * @style: the object which received the signal - * - * Emitted when the group of radio menu items that a radio menu item belongs - * to changes. This is emitted when a radio menu item switches from - * being alone to being part of a group of 2 or more menu items, or - * vice-versa, and when a button is moved from one group of 2 or - * more menu items ton a different one, but not when the composition - * of the group that a menu item belongs to changes. - */ - group_changed_signal = g_signal_new (I_("group-changed"), - G_OBJECT_CLASS_TYPE (gobject_class), - G_SIGNAL_RUN_FIRST, - G_STRUCT_OFFSET (GtkRadioMenuItemClass, group_changed), - NULL, NULL, - NULL, - G_TYPE_NONE, 0); -} - -static void -gtk_radio_menu_item_init (GtkRadioMenuItem *radio_menu_item) -{ - GtkRadioMenuItemPrivate *priv = gtk_radio_menu_item_get_instance_private (radio_menu_item); - - priv->group = g_slist_prepend (NULL, radio_menu_item); - gtk_check_menu_item_set_draw_as_radio (GTK_CHECK_MENU_ITEM (radio_menu_item), TRUE); -} - -static void -gtk_radio_menu_item_destroy (GtkWidget *widget) -{ - GtkRadioMenuItem *radio_menu_item = GTK_RADIO_MENU_ITEM (widget); - GtkRadioMenuItemPrivate *priv = gtk_radio_menu_item_get_instance_private (radio_menu_item); - GtkWidget *old_group_singleton = NULL; - GSList *tmp_list; - gboolean was_in_group; - - was_in_group = priv->group && priv->group->next; - - priv->group = g_slist_remove (priv->group, radio_menu_item); - if (priv->group && !priv->group->next) - old_group_singleton = priv->group->data; - - tmp_list = priv->group; - - while (tmp_list) - { - GtkRadioMenuItem *tmp_item = tmp_list->data; - GtkRadioMenuItemPrivate *tmp_priv = gtk_radio_menu_item_get_instance_private (tmp_item); - tmp_list = tmp_list->next; - - tmp_priv->group = priv->group; - } - - /* this radio menu item is no longer in the group */ - priv->group = NULL; - - if (old_group_singleton) - g_signal_emit (old_group_singleton, group_changed_signal, 0); - if (was_in_group) - g_signal_emit (radio_menu_item, group_changed_signal, 0); - - GTK_WIDGET_CLASS (gtk_radio_menu_item_parent_class)->destroy (widget); -} - -static void -gtk_radio_menu_item_activate (GtkMenuItem *menu_item) -{ - GtkRadioMenuItem *radio_menu_item = GTK_RADIO_MENU_ITEM (menu_item); - GtkRadioMenuItemPrivate *priv = gtk_radio_menu_item_get_instance_private (radio_menu_item); - GtkCheckMenuItem *check_menu_item = GTK_CHECK_MENU_ITEM (menu_item); - GtkCheckMenuItem *tmp_menu_item; - GSList *tmp_list; - gboolean active; - gint toggled; - - toggled = FALSE; - - active = gtk_check_menu_item_get_active (check_menu_item); - if (active) - { - tmp_menu_item = NULL; - tmp_list = priv->group; - - while (tmp_list) - { - tmp_menu_item = tmp_list->data; - tmp_list = tmp_list->next; - - if (gtk_check_menu_item_get_active (tmp_menu_item) && - tmp_menu_item != check_menu_item) - break; - - tmp_menu_item = NULL; - } - - if (tmp_menu_item) - { - toggled = TRUE; - _gtk_check_menu_item_set_active (check_menu_item, !active); - } - } - else - { - toggled = TRUE; - _gtk_check_menu_item_set_active (check_menu_item, !active); - - tmp_list = priv->group; - while (tmp_list) - { - tmp_menu_item = tmp_list->data; - tmp_list = tmp_list->next; - - if (gtk_check_menu_item_get_active (tmp_menu_item) && - tmp_menu_item != check_menu_item) - { - gtk_menu_item_activate (GTK_MENU_ITEM (tmp_menu_item)); - break; - } - } - } - - if (toggled) - { - gtk_check_menu_item_toggled (check_menu_item); - } - - gtk_widget_queue_draw (GTK_WIDGET (radio_menu_item)); -} - -/** - * gtk_radio_menu_item_join_group: - * @radio_menu_item: a #GtkRadioMenuItem - * @group_source: (allow-none): a #GtkRadioMenuItem whose group we are - * joining, or %NULL to remove the @radio_menu_item from its current - * group - * - * Joins a #GtkRadioMenuItem object to the group of another #GtkRadioMenuItem - * object. - * - * This function should be used by language bindings to avoid the memory - * manangement of the opaque #GSList of gtk_radio_menu_item_get_group() - * and gtk_radio_menu_item_set_group(). - * - * A common way to set up a group of #GtkRadioMenuItem instances is: - * - * |[ - * GtkRadioMenuItem *last_item = NULL; - * - * while ( ...more items to add... ) - * { - * GtkRadioMenuItem *radio_item; - * - * radio_item = gtk_radio_menu_item_new (...); - * - * gtk_radio_menu_item_join_group (radio_item, last_item); - * last_item = radio_item; - * } - * ]| - */ -void -gtk_radio_menu_item_join_group (GtkRadioMenuItem *radio_menu_item, - GtkRadioMenuItem *group_source) -{ - g_return_if_fail (GTK_IS_RADIO_MENU_ITEM (radio_menu_item)); - g_return_if_fail (group_source == NULL || GTK_IS_RADIO_MENU_ITEM (group_source)); - - if (group_source != NULL) - { - GSList *group = gtk_radio_menu_item_get_group (group_source); - - if (group == NULL) - { - /* if the group source does not have a group, we force one */ - gtk_radio_menu_item_set_group (group_source, NULL); - group = gtk_radio_menu_item_get_group (group_source); - } - - gtk_radio_menu_item_set_group (radio_menu_item, group); - } - else - gtk_radio_menu_item_set_group (radio_menu_item, NULL); -} diff --git a/gtk/gtkradiomenuitem.h b/gtk/gtkradiomenuitem.h deleted file mode 100644 index 49a89d71ad..0000000000 --- a/gtk/gtkradiomenuitem.h +++ /dev/null @@ -1,75 +0,0 @@ -/* GTK - The GIMP Toolkit - * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * 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, see . - */ - -/* - * Modified by the GTK+ Team and others 1997-2000. See the AUTHORS - * file for a list of people on the GTK+ Team. See the ChangeLog - * files for a list of changes. These files are distributed with - * GTK+ at ftp://ftp.gtk.org/pub/gtk/. - */ - -#ifndef __GTK_RADIO_MENU_ITEM_H__ -#define __GTK_RADIO_MENU_ITEM_H__ - - -#if !defined (__GTK_H_INSIDE__) && !defined (GTK_COMPILATION) -#error "Only can be included directly." -#endif - -#include - - -G_BEGIN_DECLS - -#define GTK_TYPE_RADIO_MENU_ITEM (gtk_radio_menu_item_get_type ()) -#define GTK_RADIO_MENU_ITEM(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GTK_TYPE_RADIO_MENU_ITEM, GtkRadioMenuItem)) -#define GTK_IS_RADIO_MENU_ITEM(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GTK_TYPE_RADIO_MENU_ITEM)) - -typedef struct _GtkRadioMenuItem GtkRadioMenuItem; - -GDK_AVAILABLE_IN_ALL -GType gtk_radio_menu_item_get_type (void) G_GNUC_CONST; - -GDK_AVAILABLE_IN_ALL -GtkWidget* gtk_radio_menu_item_new (GSList *group); -GDK_AVAILABLE_IN_ALL -GtkWidget* gtk_radio_menu_item_new_with_label (GSList *group, - const gchar *label); -GDK_AVAILABLE_IN_ALL -GtkWidget* gtk_radio_menu_item_new_with_mnemonic (GSList *group, - const gchar *label); -GDK_AVAILABLE_IN_ALL -GtkWidget* gtk_radio_menu_item_new_from_widget (GtkRadioMenuItem *group); -GDK_AVAILABLE_IN_ALL -GtkWidget *gtk_radio_menu_item_new_with_mnemonic_from_widget (GtkRadioMenuItem *group, - const gchar *label); -GDK_AVAILABLE_IN_ALL -GtkWidget *gtk_radio_menu_item_new_with_label_from_widget (GtkRadioMenuItem *group, - const gchar *label); -GDK_AVAILABLE_IN_ALL -GSList* gtk_radio_menu_item_get_group (GtkRadioMenuItem *radio_menu_item); -GDK_AVAILABLE_IN_ALL -void gtk_radio_menu_item_set_group (GtkRadioMenuItem *radio_menu_item, - GSList *group); - -GDK_AVAILABLE_IN_ALL -void gtk_radio_menu_item_join_group (GtkRadioMenuItem *radio_menu_item, - GtkRadioMenuItem *group_source); - -G_END_DECLS - -#endif /* __GTK_RADIO_MENU_ITEM_H__ */ diff --git a/gtk/gtkseparatormenuitem.c b/gtk/gtkseparatormenuitem.c deleted file mode 100644 index f15105370c..0000000000 --- a/gtk/gtkseparatormenuitem.c +++ /dev/null @@ -1,94 +0,0 @@ -/* GTK - The GIMP Toolkit - * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * 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, see . - */ - -/* - * Modified by the GTK+ Team and others 1997-2000. See the AUTHORS - * file for a list of people on the GTK+ Team. See the ChangeLog - * files for a list of changes. These files are distributed with - * GTK+ at ftp://ftp.gtk.org/pub/gtk/. - */ - -#include "config.h" - -#include "gtkseparatormenuitem.h" -#include "gtkintl.h" - -#include "gtkstylecontext.h" - -/** - * SECTION:gtkseparatormenuitem - * @Short_description: A separator used in menus - * @Title: GtkSeparatorMenuItem - * - * The #GtkSeparatorMenuItem is a separator used to group - * items within a menu. It displays a horizontal line with a shadow to - * make it appear sunken into the interface. - * - * # CSS nodes - * - * GtkSeparatorMenuItem has a single CSS node with name separator. - */ - -typedef struct _GtkSeparatorMenuItemClass GtkSeparatorMenuItemClass; - -struct _GtkSeparatorMenuItem -{ - GtkMenuItem menu_item; -}; - -struct _GtkSeparatorMenuItemClass -{ - GtkMenuItemClass parent_class; -}; - -G_DEFINE_TYPE (GtkSeparatorMenuItem, gtk_separator_menu_item, GTK_TYPE_MENU_ITEM) - - -static const char * -gtk_separator_menu_item_get_label (GtkMenuItem *item) -{ - return ""; -} - -static void -gtk_separator_menu_item_class_init (GtkSeparatorMenuItemClass *class) -{ - GTK_CONTAINER_CLASS (class)->child_type = NULL; - - GTK_MENU_ITEM_CLASS (class)->get_label = gtk_separator_menu_item_get_label; - - gtk_widget_class_set_accessible_role (GTK_WIDGET_CLASS (class), ATK_ROLE_SEPARATOR); - gtk_widget_class_set_css_name (GTK_WIDGET_CLASS (class), I_("separator")); -} - -static void -gtk_separator_menu_item_init (GtkSeparatorMenuItem *item) -{ -} - -/** - * gtk_separator_menu_item_new: - * - * Creates a new #GtkSeparatorMenuItem. - * - * Returns: a new #GtkSeparatorMenuItem. - */ -GtkWidget * -gtk_separator_menu_item_new (void) -{ - return g_object_new (GTK_TYPE_SEPARATOR_MENU_ITEM, NULL); -} diff --git a/gtk/gtkseparatormenuitem.h b/gtk/gtkseparatormenuitem.h deleted file mode 100644 index 7d18b9eaf4..0000000000 --- a/gtk/gtkseparatormenuitem.h +++ /dev/null @@ -1,53 +0,0 @@ -/* GTK - The GIMP Toolkit - * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * 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, see . - */ - -/* - * Modified by the GTK+ Team and others 1997-2000. See the AUTHORS - * file for a list of people on the GTK+ Team. See the ChangeLog - * files for a list of changes. These files are distributed with - * GTK+ at ftp://ftp.gtk.org/pub/gtk/. - */ - -#ifndef __GTK_SEPARATOR_MENU_ITEM_H__ -#define __GTK_SEPARATOR_MENU_ITEM_H__ - - -#if !defined (__GTK_H_INSIDE__) && !defined (GTK_COMPILATION) -#error "Only can be included directly." -#endif - -#include - - -G_BEGIN_DECLS - -#define GTK_TYPE_SEPARATOR_MENU_ITEM (gtk_separator_menu_item_get_type ()) -#define GTK_SEPARATOR_MENU_ITEM(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GTK_TYPE_SEPARATOR_MENU_ITEM, GtkSeparatorMenuItem)) -#define GTK_IS_SEPARATOR_MENU_ITEM(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GTK_TYPE_SEPARATOR_MENU_ITEM)) - - -typedef struct _GtkSeparatorMenuItem GtkSeparatorMenuItem; - -GDK_AVAILABLE_IN_ALL -GType gtk_separator_menu_item_get_type (void) G_GNUC_CONST; -GDK_AVAILABLE_IN_ALL -GtkWidget* gtk_separator_menu_item_new (void); - - -G_END_DECLS - -#endif /* __GTK_SEPARATOR_MENU_ITEM_H__ */ diff --git a/gtk/gtkseparatortoolitem.c b/gtk/gtkseparatortoolitem.c index d85ab09891..2bd71cfd90 100644 --- a/gtk/gtkseparatortoolitem.c +++ b/gtk/gtkseparatortoolitem.c @@ -23,7 +23,6 @@ #include "gtkintl.h" #include "gtkprivate.h" -#include "gtkseparatormenuitem.h" #include "gtkstylecontext.h" #include "gtktoolbarprivate.h" #include "gtkwidgetprivate.h" diff --git a/gtk/gtktext.c b/gtk/gtktext.c index 736b2bc83e..3b49ef71ba 100644 --- a/gtk/gtktext.c +++ b/gtk/gtktext.c @@ -52,7 +52,6 @@ #include "gtkpango.h" #include "gtkpopovermenu.h" #include "gtkprivate.h" -#include "gtkseparatormenuitem.h" #include "gtkselection.h" #include "gtksettings.h" #include "gtksnapshot.h" diff --git a/gtk/gtktextview.c b/gtk/gtktextview.c index 0c1282c011..ab55d08057 100644 --- a/gtk/gtktextview.c +++ b/gtk/gtktextview.c @@ -37,7 +37,6 @@ #include "gtkmain.h" #include "gtkmarshalers.h" #include "gtkrenderbackgroundprivate.h" -#include "gtkseparatormenuitem.h" #include "gtksettings.h" #include "gtktextiterprivate.h" #include "gtkimmulticontext.h" diff --git a/gtk/gtktoggletoolbutton.c b/gtk/gtktoggletoolbutton.c index 36241a764f..a91642a9b2 100644 --- a/gtk/gtktoggletoolbutton.c +++ b/gtk/gtktoggletoolbutton.c @@ -19,7 +19,6 @@ #include "config.h" #include "gtktoggletoolbutton.h" -#include "gtkcheckmenuitem.h" #include "gtklabel.h" #include "gtktogglebutton.h" #include "gtkintl.h" diff --git a/gtk/gtktoolbar.c b/gtk/gtktoolbar.c index fc232996f2..fd733ea2d7 100644 --- a/gtk/gtktoolbar.c +++ b/gtk/gtktoolbar.c @@ -51,11 +51,8 @@ #include "gtkpopovermenuprivate.h" #include "gtkmodelbuttonprivate.h" #include "gtkseparator.h" -#include "gtkradiomenuitem.h" -#include "gtkcheckmenuitem.h" #include "gtkradiobutton.h" #include "gtkradiotoolbutton.h" -#include "gtkseparatormenuitem.h" #include "gtkseparatortoolitem.h" #include "gtktoolshell.h" #include "gtktypebuiltins.h" diff --git a/gtk/gtktoolitem.c b/gtk/gtktoolitem.c index 0de206aaea..dcd0dec924 100644 --- a/gtk/gtktoolitem.c +++ b/gtk/gtktoolitem.c @@ -26,7 +26,6 @@ #include "gtkmarshalers.h" #include "gtktoolshell.h" -#include "gtkseparatormenuitem.h" #include "gtksizerequest.h" #include "gtkintl.h" #include "gtkprivate.h" diff --git a/gtk/gtktoolitem.h b/gtk/gtktoolitem.h index 5dcdc80315..103cdf523d 100644 --- a/gtk/gtktoolitem.h +++ b/gtk/gtktoolitem.h @@ -26,7 +26,6 @@ #endif #include -#include #include G_BEGIN_DECLS diff --git a/gtk/gtkwidget.c b/gtk/gtkwidget.c index b939567dbc..0c42bc1534 100644 --- a/gtk/gtkwidget.c +++ b/gtk/gtkwidget.c @@ -51,7 +51,6 @@ #include "gtklayoutmanagerprivate.h" #include "gtkmain.h" #include "gtkmarshalers.h" -#include "gtkmenu.h" #include "gtkpopover.h" #include "gtkprivate.h" #include "gtkrenderbackgroundprivate.h" diff --git a/gtk/inspector/object-tree.c b/gtk/inspector/object-tree.c index cfc41987f5..c6f4665d8e 100644 --- a/gtk/inspector/object-tree.c +++ b/gtk/inspector/object-tree.c @@ -41,7 +41,6 @@ #include "gtkiconview.h" #include "gtklabel.h" #include "gtklistbox.h" -#include "gtkmenuitem.h" #include "gtkpopover.h" #include "gtksettings.h" #include "gtksizegroup.h" diff --git a/gtk/meson.build b/gtk/meson.build index 00a3068864..85a25212a6 100644 --- a/gtk/meson.build +++ b/gtk/meson.build @@ -199,7 +199,6 @@ gtk_public_sources = files([ 'gtkcenterbox.c', 'gtkcenterlayout.c', 'gtkcheckbutton.c', - 'gtkcheckmenuitem.c', 'gtkcolorbutton.c', 'gtkcolorchooser.c', 'gtkcolorchooserdialog.c', @@ -284,15 +283,10 @@ gtk_public_sources = files([ 'gtkmediacontrols.c', 'gtkmediafile.c', 'gtkmediastream.c', - 'gtkmenu.c', - 'gtkmenubar.c', 'gtkmenubutton.c', - 'gtkmenuitem.c', - 'gtkmenushell.c', 'gtkmenutoolbutton.c', 'gtkmessagedialog.c', 'gtkmodelbutton.c', - 'gtkmodelmenuitem.c', 'gtkmodules.c', 'gtkmountoperation.c', 'gtknativedialog.c', @@ -318,7 +312,6 @@ gtk_public_sources = files([ 'gtkprogressbar.c', 'gtkpropertylookuplistmodel.c', 'gtkradiobutton.c', - 'gtkradiomenuitem.c', 'gtkradiotoolbutton.c', 'gtkrange.c', 'gtktreerbtree.c', @@ -342,7 +335,6 @@ gtk_public_sources = files([ 'gtkselection.c', 'gtkselectionmodel.c', 'gtkseparator.c', - 'gtkseparatormenuitem.c', 'gtkseparatortoolitem.c', 'gtksettings.c', 'gtkshortcutlabel.c', @@ -465,7 +457,6 @@ gtk_public_headers = files([ 'gtkcellrenderertoggle.h', 'gtkcellview.h', 'gtkcheckbutton.h', - 'gtkcheckmenuitem.h', 'gtkcolorbutton.h', 'gtkcolorchooser.h', 'gtkcolorchooserdialog.h', @@ -547,11 +538,7 @@ gtk_public_headers = files([ 'gtkmediacontrols.h', 'gtkmediafile.h', 'gtkmediastream.h', - 'gtkmenu.h', - 'gtkmenubar.h', 'gtkmenubutton.h', - 'gtkmenuitem.h', - 'gtkmenushell.h', 'gtkmenutoolbutton.h', 'gtkmessagedialog.h', 'gtkmountoperation.h', @@ -576,7 +563,6 @@ gtk_public_headers = files([ 'gtkprintsettings.h', 'gtkprogressbar.h', 'gtkradiobutton.h', - 'gtkradiomenuitem.h', 'gtkradiotoolbutton.h', 'gtkrange.h', 'gtkrecentmanager.h', @@ -593,7 +579,6 @@ gtk_public_headers = files([ 'gtkselection.h', 'gtkselectionmodel.h', 'gtkseparator.h', - 'gtkseparatormenuitem.h', 'gtkseparatortoolitem.h', 'gtksettings.h', 'gtkshortcutlabel.h', diff --git a/po-properties/POTFILES.in b/po-properties/POTFILES.in index 7e742f8661..921f38d504 100644 --- a/po-properties/POTFILES.in +++ b/po-properties/POTFILES.in @@ -50,7 +50,6 @@ gtk/a11y/gtkentryaccessible.c gtk/a11y/gtkexpanderaccessible.c gtk/a11y/gtkimageaccessible.c gtk/a11y/gtkmenubuttonaccessible.c -gtk/a11y/gtkmenuitemaccessible.c gtk/a11y/gtkrenderercellaccessible.c gtk/a11y/gtkscalebuttonaccessible.c gtk/a11y/gtkspinneraccessible.c @@ -194,11 +193,7 @@ gtk/gtkmaplistmodel.c gtk/gtkmediacontrols.c gtk/gtkmediafile.c gtk/gtkmediastream.c -gtk/gtkmenubar.c gtk/gtkmenubutton.c -gtk/gtkmenu.c -gtk/gtkmenuitem.c -gtk/gtkmenushell.c gtk/gtkmenutoolbutton.c gtk/gtkmenutrackeritem.c gtk/gtkmessagedialog.c