summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMatthias Clasen <mclasen@redhat.com>2019-09-16 22:10:02 +0000
committerMatthias Clasen <mclasen@redhat.com>2019-09-16 22:10:02 +0000
commit87e7fa9917d89f1ad74a744995ea6c0e81281659 (patch)
treeaabdefadac66ccf8a6d319f860774548c8379516
parent97231ca231f4fcd84a5dd61f1eec1d7e2c5b703d (diff)
parentb14b0efefe840b8ca1ce3077e1170e757bc12340 (diff)
downloadgtk+-87e7fa9917d89f1ad74a744995ea6c0e81281659.tar.gz
Merge branch 'wip/kill-menu' into 'master'
Use menus less See merge request GNOME/gtk!1098
-rw-r--r--gtk/gtkappchooserwidget.h1
-rw-r--r--gtk/gtkentry.c2
-rw-r--r--gtk/gtkentry.h1
-rw-r--r--gtk/gtkimmulticontext.c2
-rw-r--r--gtk/gtkimmulticontext.h1
-rw-r--r--gtk/gtkmenutoolbutton.c54
-rw-r--r--gtk/gtkmenutoolbutton.h6
-rw-r--r--gtk/gtknotebook.c61
-rw-r--r--gtk/gtktext.c2
-rw-r--r--gtk/gtktextutil.c105
-rw-r--r--gtk/gtktextutil.h7
-rw-r--r--gtk/gtktextview.c2
-rw-r--r--gtk/gtktextview.h1
-rw-r--r--gtk/gtktoolbar.c160
-rw-r--r--gtk/gtkwindow.c103
15 files changed, 214 insertions, 294 deletions
diff --git a/gtk/gtkappchooserwidget.h b/gtk/gtkappchooserwidget.h
index defef6ef7e..c71919e494 100644
--- a/gtk/gtkappchooserwidget.h
+++ b/gtk/gtkappchooserwidget.h
@@ -30,7 +30,6 @@
#endif
#include <gtk/gtkwidget.h>
-#include <gtk/gtkmenu.h>
#include <gio/gio.h>
G_BEGIN_DECLS
diff --git a/gtk/gtkentry.c b/gtk/gtkentry.c
index 1c1fbee79c..a2ebe7110b 100644
--- a/gtk/gtkentry.c
+++ b/gtk/gtkentry.c
@@ -51,8 +51,6 @@
#include "gtklabel.h"
#include "gtkmain.h"
#include "gtkmarshalers.h"
-#include "gtkmenu.h"
-#include "gtkmenuitem.h"
#include "gtkpango.h"
#include "gtkpopover.h"
#include "gtkprivate.h"
diff --git a/gtk/gtkentry.h b/gtk/gtkentry.h
index b71c4d3ac6..80ebd94bfa 100644
--- a/gtk/gtkentry.h
+++ b/gtk/gtkentry.h
@@ -36,7 +36,6 @@
#include <gtk/gtkeditable.h>
#include <gtk/gtkimcontext.h>
-#include <gtk/gtkmenu.h>
#include <gtk/gtkentrybuffer.h>
#include <gtk/gtkentrycompletion.h>
#include <gtk/gtkimage.h>
diff --git a/gtk/gtkimmulticontext.c b/gtk/gtkimmulticontext.c
index 7412bba956..0ab67eddf2 100644
--- a/gtk/gtkimmulticontext.c
+++ b/gtk/gtkimmulticontext.c
@@ -26,8 +26,6 @@
#include "gtklabel.h"
#include "gtkmain.h"
#include "gtkprivate.h"
-#include "gtkradiomenuitem.h"
-#include "gtkseparatormenuitem.h"
#include "gtksettings.h"
diff --git a/gtk/gtkimmulticontext.h b/gtk/gtkimmulticontext.h
index bee93f9aae..53e72d5aeb 100644
--- a/gtk/gtkimmulticontext.h
+++ b/gtk/gtkimmulticontext.h
@@ -23,7 +23,6 @@
#endif
#include <gtk/gtkimcontext.h>
-#include <gtk/gtkmenushell.h>
G_BEGIN_DECLS
diff --git a/gtk/gtkmenutoolbutton.c b/gtk/gtkmenutoolbutton.c
index cfcb1127cf..19aba366ce 100644
--- a/gtk/gtkmenutoolbutton.c
+++ b/gtk/gtkmenutoolbutton.c
@@ -26,6 +26,7 @@
#include "gtkmenubuttonprivate.h"
#include "gtkbox.h"
#include "gtkmenu.h"
+#include "gtkpopover.h"
#include "gtkmain.h"
#include "gtksizerequest.h"
#include "gtkbuildable.h"
@@ -103,7 +104,8 @@ enum
enum
{
PROP_0,
- PROP_MENU
+ PROP_MENU,
+ PROP_POPOVER
};
static gint signals[LAST_SIGNAL];
@@ -210,6 +212,10 @@ gtk_menu_tool_button_set_property (GObject *object,
gtk_menu_tool_button_set_menu (button, g_value_get_object (value));
break;
+ case PROP_POPOVER:
+ gtk_menu_tool_button_set_popover (button, g_value_get_object (value));
+ break;
+
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
@@ -230,6 +236,10 @@ gtk_menu_tool_button_get_property (GObject *object,
g_value_set_object (value, gtk_menu_button_get_popup (GTK_MENU_BUTTON (button->priv->arrow_button)));
break;
+ case PROP_POPOVER:
+ g_value_set_object (value, gtk_menu_button_get_popover (GTK_MENU_BUTTON (button->priv->arrow_button)));
+ break;
+
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
@@ -279,6 +289,13 @@ gtk_menu_tool_button_class_init (GtkMenuToolButtonClass *klass)
P_("The dropdown menu"),
GTK_TYPE_MENU,
GTK_PARAM_READWRITE));
+ g_object_class_install_property (object_class,
+ PROP_POPOVER,
+ g_param_spec_object ("popover",
+ P_("Popover"),
+ P_("The dropdown popover"),
+ GTK_TYPE_POPOVER,
+ GTK_PARAM_READWRITE));
}
static void
@@ -324,6 +341,9 @@ gtk_menu_tool_button_buildable_add_child (GtkBuildable *buildable,
if (type && strcmp (type, "menu") == 0)
gtk_menu_tool_button_set_menu (GTK_MENU_TOOL_BUTTON (buildable),
GTK_WIDGET (child));
+ else if (type && strcmp (type, "popover") == 0)
+ gtk_menu_tool_button_set_popover (GTK_MENU_TOOL_BUTTON (buildable),
+ GTK_WIDGET (child));
else
parent_buildable_iface->add_child (buildable, builder, child, type);
}
@@ -419,6 +439,38 @@ gtk_menu_tool_button_get_menu (GtkMenuToolButton *button)
return GTK_WIDGET (ret);
}
+void
+gtk_menu_tool_button_set_popover (GtkMenuToolButton *button,
+ GtkWidget *popover)
+{
+ GtkMenuToolButtonPrivate *priv;
+
+ g_return_if_fail (GTK_IS_MENU_TOOL_BUTTON (button));
+ g_return_if_fail (GTK_IS_POPOVER (popover) || popover == NULL);
+
+ priv = button->priv;
+
+ gtk_menu_button_set_popover (GTK_MENU_BUTTON (priv->arrow_button), popover);
+ gtk_menu_button_set_create_popup_func (GTK_MENU_BUTTON (priv->arrow_button),
+ _show_menu_emit, NULL, NULL);
+
+ g_object_notify (G_OBJECT (button), "popover");
+}
+
+GtkWidget *
+gtk_menu_tool_button_get_popover (GtkMenuToolButton *button)
+{
+ GtkPopover *ret;
+
+ g_return_val_if_fail (GTK_IS_MENU_TOOL_BUTTON (button), NULL);
+
+ ret = gtk_menu_button_get_popover (GTK_MENU_BUTTON (button->priv->arrow_button));
+ if (!ret)
+ return NULL;
+
+ return GTK_WIDGET (ret);
+}
+
/**
* gtk_menu_tool_button_set_arrow_tooltip_text:
* @button: a #GtkMenuToolButton
diff --git a/gtk/gtkmenutoolbutton.h b/gtk/gtkmenutoolbutton.h
index 03304dbbe1..3bfdc0ada1 100644
--- a/gtk/gtkmenutoolbutton.h
+++ b/gtk/gtkmenutoolbutton.h
@@ -24,7 +24,6 @@
#error "Only <gtk/gtk.h> can be included directly."
#endif
-#include <gtk/gtkmenu.h>
#include <gtk/gtktoolbutton.h>
G_BEGIN_DECLS
@@ -47,6 +46,11 @@ void gtk_menu_tool_button_set_menu (GtkMenuToolButton *button,
GDK_AVAILABLE_IN_ALL
GtkWidget *gtk_menu_tool_button_get_menu (GtkMenuToolButton *button);
GDK_AVAILABLE_IN_ALL
+void gtk_menu_tool_button_set_popover (GtkMenuToolButton *button,
+ GtkWidget *popover);
+GDK_AVAILABLE_IN_ALL
+GtkWidget *gtk_menu_tool_button_get_popover (GtkMenuToolButton *button);
+GDK_AVAILABLE_IN_ALL
void gtk_menu_tool_button_set_arrow_tooltip_text (GtkMenuToolButton *button,
const gchar *text);
GDK_AVAILABLE_IN_ALL
diff --git a/gtk/gtknotebook.c b/gtk/gtknotebook.c
index fab59e7ab9..2082a1038a 100644
--- a/gtk/gtknotebook.c
+++ b/gtk/gtknotebook.c
@@ -43,8 +43,7 @@
#include "gtklabel.h"
#include "gtkmain.h"
#include "gtkmarshalers.h"
-#include "gtkmenu.h"
-#include "gtkmenuitem.h"
+#include "gtkpopovermenu.h"
#include "gtkorientable.h"
#include "gtksizerequest.h"
#include "gtkstylecontextprivate.h"
@@ -237,6 +236,7 @@ struct _GtkNotebookPrivate
GtkWidget *action_widget[N_ACTION_WIDGETS];
GtkWidget *dnd_child;
GtkWidget *menu;
+ GtkWidget *menu_box;
GtkWidget *stack_widget;
GtkWidget *header_widget;
@@ -807,8 +807,6 @@ static void gtk_notebook_menu_item_recreate (GtkNotebook *notebook,
GList *list);
static void gtk_notebook_menu_label_unparent (GtkWidget *widget,
gpointer data);
-static void gtk_notebook_menu_detacher (GtkWidget *widget,
- GtkMenu *menu);
static void gtk_notebook_update_tab_pos (GtkNotebook *notebook);
@@ -2501,7 +2499,14 @@ gtk_notebook_gesture_pressed (GtkGestureClick *gesture,
if (in_tabs (notebook, x, y) && priv->menu && gdk_event_triggers_context_menu (event))
{
- gtk_menu_popup_at_pointer (GTK_MENU (priv->menu), event);
+ GdkRectangle rect;
+
+ rect.x = x;
+ rect.y = y;
+ rect.width = 1;
+ rect.height = 1;
+ gtk_popover_set_pointing_to (GTK_POPOVER (priv->menu), &rect);
+ gtk_popover_popup (GTK_POPOVER (priv->menu));
return;
}
@@ -5592,14 +5597,14 @@ gtk_notebook_menu_switch_page (GtkWidget *widget,
{
GtkNotebookPrivate *priv;
GtkNotebook *notebook;
- GtkWidget *parent;
GList *children;
guint page_num;
- parent = gtk_widget_get_parent (widget);
- notebook = GTK_NOTEBOOK (gtk_menu_get_attach_widget (GTK_MENU (parent)));
+ notebook = GTK_NOTEBOOK (gtk_widget_get_ancestor (widget, GTK_TYPE_NOTEBOOK));
priv = notebook->priv;
+ gtk_popover_popdown (GTK_POPOVER (priv->menu));
+
if (priv->cur_page == page)
return;
@@ -5623,7 +5628,6 @@ gtk_notebook_menu_switch_page (GtkWidget *widget,
* gtk_notebook_menu_item_create
* gtk_notebook_menu_item_recreate
* gtk_notebook_menu_label_unparent
- * gtk_notebook_menu_detacher
*/
static void
gtk_notebook_menu_item_create (GtkNotebook *notebook,
@@ -5643,15 +5647,14 @@ gtk_notebook_menu_item_create (GtkNotebook *notebook,
gtk_widget_set_valign (page->menu_label, GTK_ALIGN_CENTER);
}
- gtk_widget_show (page->menu_label);
- menu_item = gtk_menu_item_new ();
+ menu_item = gtk_button_new ();
+ gtk_button_set_relief (GTK_BUTTON (menu_item), GTK_RELIEF_NONE);
gtk_container_add (GTK_CONTAINER (menu_item), page->menu_label);
- gtk_menu_shell_insert (GTK_MENU_SHELL (priv->menu), menu_item,
- g_list_index (priv->children, page));
- g_signal_connect (menu_item, "activate",
+ gtk_container_add (GTK_CONTAINER (priv->menu_box), menu_item);
+ g_signal_connect (menu_item, "clicked",
G_CALLBACK (gtk_notebook_menu_switch_page), page);
- if (gtk_widget_get_visible (page->child))
- gtk_widget_show (menu_item);
+ if (!gtk_widget_get_visible (page->child))
+ gtk_widget_hide (menu_item);
}
static void
@@ -5675,18 +5678,6 @@ gtk_notebook_menu_label_unparent (GtkWidget *widget,
_gtk_bin_set_child (GTK_BIN (widget), NULL);
}
-static void
-gtk_notebook_menu_detacher (GtkWidget *widget,
- GtkMenu *menu)
-{
- GtkNotebook *notebook = GTK_NOTEBOOK (widget);
- GtkNotebookPrivate *priv = notebook->priv;
-
- g_return_if_fail (priv->menu == (GtkWidget*) menu);
-
- priv->menu = NULL;
-}
-
/* Public GtkNotebook Page Insert/Remove Methods :
*
* gtk_notebook_append_page
@@ -6531,9 +6522,10 @@ gtk_notebook_popup_enable (GtkNotebook *notebook)
if (priv->menu)
return;
- priv->menu = gtk_menu_new ();
- gtk_style_context_add_class (gtk_widget_get_style_context (priv->menu),
- GTK_STYLE_CLASS_CONTEXT_MENU);
+ priv->menu = gtk_popover_menu_new (priv->tabs_widget);
+
+ priv->menu_box = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
+ gtk_popover_menu_add_submenu (GTK_POPOVER_MENU (priv->menu), priv->menu_box, "main");
for (list = gtk_notebook_search_page (notebook, NULL, STEP_NEXT, FALSE);
list;
@@ -6541,9 +6533,6 @@ gtk_notebook_popup_enable (GtkNotebook *notebook)
gtk_notebook_menu_item_create (notebook, list->data);
gtk_notebook_update_labels (notebook);
- gtk_menu_attach_to_widget (GTK_MENU (priv->menu),
- GTK_WIDGET (notebook),
- gtk_notebook_menu_detacher);
g_object_notify_by_pspec (G_OBJECT (notebook), properties[PROP_ENABLE_POPUP]);
}
@@ -6566,9 +6555,11 @@ gtk_notebook_popup_disable (GtkNotebook *notebook)
if (!priv->menu)
return;
- gtk_container_foreach (GTK_CONTAINER (priv->menu),
+ gtk_container_foreach (GTK_CONTAINER (priv->menu_box),
(GtkCallback) gtk_notebook_menu_label_unparent, NULL);
gtk_widget_destroy (priv->menu);
+ priv->menu = NULL;
+ priv->menu_box = NULL;
g_object_notify_by_pspec (G_OBJECT (notebook), properties[PROP_ENABLE_POPUP]);
}
diff --git a/gtk/gtktext.c b/gtk/gtktext.c
index 5ac7637a98..ffe683fed7 100644
--- a/gtk/gtktext.c
+++ b/gtk/gtktext.c
@@ -49,8 +49,6 @@
#include "gtkmagnifierprivate.h"
#include "gtkmain.h"
#include "gtkmarshalers.h"
-#include "gtkmenu.h"
-#include "gtkmenuitem.h"
#include "gtkpango.h"
#include "gtkpopovermenu.h"
#include "gtkprivate.h"
diff --git a/gtk/gtktextutil.c b/gtk/gtktextutil.c
index 2c3c43d8bc..200f87285c 100644
--- a/gtk/gtktextutil.c
+++ b/gtk/gtktextutil.c
@@ -29,7 +29,6 @@
#include "gtktextbuffer.h"
#include "gtktextlayoutprivate.h"
-#include "gtkmenuitem.h"
#include "gtkintl.h"
#define DRAG_ICON_MAX_WIDTH 250
@@ -37,110 +36,6 @@
#define DRAG_ICON_MAX_LINES 7
#define ELLIPSIS_CHARACTER "\xe2\x80\xa6"
-typedef struct _GtkUnicodeMenuEntry GtkUnicodeMenuEntry;
-typedef struct _GtkTextUtilCallbackInfo GtkTextUtilCallbackInfo;
-
-struct _GtkUnicodeMenuEntry {
- const char *label;
- gunichar ch;
-};
-
-struct _GtkTextUtilCallbackInfo
-{
- GtkTextUtilCharChosenFunc func;
- gpointer data;
-};
-
-static const GtkUnicodeMenuEntry bidi_menu_entries[] = {
- { N_("LRM _Left-to-right mark"), 0x200E },
- { N_("RLM _Right-to-left mark"), 0x200F },
- { N_("LRE Left-to-right _embedding"), 0x202A },
- { N_("RLE Right-to-left e_mbedding"), 0x202B },
- { N_("LRO Left-to-right _override"), 0x202D },
- { N_("RLO Right-to-left o_verride"), 0x202E },
- { N_("PDF _Pop directional formatting"), 0x202C },
- { N_("ZWS _Zero width space"), 0x200B },
- { N_("ZWJ Zero width _joiner"), 0x200D },
- { N_("ZWNJ Zero width _non-joiner"), 0x200C }
-};
-
-static GtkTextUtilCallbackInfo *
-callback_info_new (GtkTextUtilCharChosenFunc func,
- gpointer data)
-{
- GtkTextUtilCallbackInfo *info;
-
- info = g_slice_new (GtkTextUtilCallbackInfo);
-
- info->func = func;
- info->data = data;
-
- return info;
-}
-
-static void
-callback_info_free (GtkTextUtilCallbackInfo *info)
-{
- g_slice_free (GtkTextUtilCallbackInfo, info);
-}
-
-static void
-activate_cb (GtkWidget *menu_item,
- gpointer data)
-{
- GtkUnicodeMenuEntry *entry;
- GtkTextUtilCallbackInfo *info = data;
- char buf[7];
-
- entry = g_object_get_data (G_OBJECT (menu_item), "gtk-unicode-menu-entry");
-
- buf[g_unichar_to_utf8 (entry->ch, buf)] = '\0';
-
- (* info->func) (buf, info->data);
-}
-
-/*
- * _gtk_text_util_append_special_char_menuitems
- * @menushell: a #GtkMenuShell
- * @callback: call this when an item is chosen
- * @data: data for callback
- *
- * Add menuitems for various bidi control characters to a menu;
- * the menuitems, when selected, will call the given function
- * with the chosen character.
- *
- * This function is private/internal in GTK 2.0, the functionality may
- * become public sometime, but it probably needs more thought first.
- * e.g. maybe there should be a way to just get the list of items,
- * instead of requiring the menu items to be created.
- */
-void
-_gtk_text_util_append_special_char_menuitems (GtkMenuShell *menushell,
- GtkTextUtilCharChosenFunc func,
- gpointer data)
-{
- int i;
-
- for (i = 0; i < G_N_ELEMENTS (bidi_menu_entries); i++)
- {
- GtkWidget *menuitem;
- GtkTextUtilCallbackInfo *info;
-
- info = callback_info_new (func, data);
-
- menuitem = gtk_menu_item_new_with_mnemonic (_(bidi_menu_entries[i].label));
- g_object_set_data (G_OBJECT (menuitem), I_("gtk-unicode-menu-entry"),
- (gpointer)&bidi_menu_entries[i]);
-
- g_signal_connect_data (menuitem, "activate",
- G_CALLBACK (activate_cb),
- info, (GClosureNotify) callback_info_free, 0);
-
- gtk_widget_show (menuitem);
- gtk_menu_shell_append (menushell, menuitem);
- }
-}
-
static void
append_n_lines (GString *str, const gchar *text, GSList *lines, gint n_lines)
{
diff --git a/gtk/gtktextutil.h b/gtk/gtktextutil.h
index 450ed464a1..4ad534ce7b 100644
--- a/gtk/gtktextutil.h
+++ b/gtk/gtktextutil.h
@@ -31,13 +31,6 @@ G_BEGIN_DECLS
* GtkTextView and GtkEntry
*/
-typedef void (* GtkTextUtilCharChosenFunc) (const char *text,
- gpointer data);
-
-void _gtk_text_util_append_special_char_menuitems (GtkMenuShell *menushell,
- GtkTextUtilCharChosenFunc func,
- gpointer data);
-
GdkPaintable * gtk_text_util_create_drag_icon (GtkWidget *widget,
gchar *text,
gssize len);
diff --git a/gtk/gtktextview.c b/gtk/gtktextview.c
index dbf89dfa84..7811fd79af 100644
--- a/gtk/gtktextview.c
+++ b/gtk/gtktextview.c
@@ -36,8 +36,6 @@
#include "gtkintl.h"
#include "gtkmain.h"
#include "gtkmarshalers.h"
-#include "gtkmenu.h"
-#include "gtkmenuitem.h"
#include "gtkrenderbackgroundprivate.h"
#include "gtkseparatormenuitem.h"
#include "gtksettings.h"
diff --git a/gtk/gtktextview.h b/gtk/gtktextview.h
index 9bb9b89eb3..bf666f7b81 100644
--- a/gtk/gtktextview.h
+++ b/gtk/gtktextview.h
@@ -32,7 +32,6 @@
#include <gtk/gtkcontainer.h>
#include <gtk/gtkimcontext.h>
#include <gtk/gtktextbuffer.h>
-#include <gtk/gtkmenu.h>
G_BEGIN_DECLS
diff --git a/gtk/gtktoolbar.c b/gtk/gtktoolbar.c
index 667d80961c..6d6d88e1ed 100644
--- a/gtk/gtktoolbar.c
+++ b/gtk/gtktoolbar.c
@@ -45,10 +45,14 @@
#include "gtklabel.h"
#include "gtkmain.h"
#include "gtkmarshalers.h"
-#include "gtkmenu.h"
#include "gtkorientable.h"
#include "gtkorientableprivate.h"
#include "gtkprivate.h"
+#include "gtkpopovermenu.h"
+#include "gtkmodelbutton.h"
+#include "gtkseparator.h"
+#include "gtkradiomenuitem.h"
+#include "gtkcheckmenuitem.h"
#include "gtkradiobutton.h"
#include "gtkradiotoolbutton.h"
#include "gtkseparatormenuitem.h"
@@ -132,7 +136,8 @@ struct _GtkToolbarClass
struct _GtkToolbarPrivate
{
- GtkMenu *menu;
+ GtkWidget *menu;
+ GtkWidget *menu_box;
GtkSettings *settings;
GtkToolbarStyle style;
@@ -429,6 +434,7 @@ gtk_toolbar_class_init (GtkToolbarClass *klass)
NULL,
G_TYPE_NONE, 1,
GTK_TYPE_TOOLBAR_STYLE);
+
/**
* GtkToolbar::popup-context-menu:
* @toolbar: the #GtkToolbar which emitted the signal
@@ -1108,76 +1114,96 @@ menu_deactivated (GtkWidget *menu,
}
static void
-menu_detached (GtkWidget *widget,
- GtkMenu *menu)
+button_clicked (GtkWidget *button,
+ GtkWidget *item)
{
- GtkToolbar *toolbar = GTK_TOOLBAR (widget);
- GtkToolbarPrivate *priv = toolbar->priv;
-
- priv->menu = NULL;
+ gtk_popover_popdown (GTK_POPOVER (gtk_widget_get_ancestor (button, GTK_TYPE_POPOVER)));
+ if (GTK_IS_TOOL_BUTTON (item))
+ g_signal_emit_by_name (_gtk_tool_button_get_button (GTK_TOOL_BUTTON (item)), "clicked");
}
static void
rebuild_menu (GtkToolbar *toolbar)
{
GtkToolbarPrivate *priv = toolbar->priv;
- GList *list, *children;
+ GList *list;
if (!priv->menu)
{
- priv->menu = GTK_MENU (gtk_menu_new ());
- gtk_menu_attach_to_widget (priv->menu,
- GTK_WIDGET (toolbar),
- menu_detached);
+ priv->menu = gtk_popover_menu_new (priv->arrow_button);
+ priv->menu_box = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
+ gtk_popover_menu_add_submenu (GTK_POPOVER_MENU (priv->menu), priv->menu_box, "main");
- g_signal_connect (priv->menu, "deactivate",
+ g_signal_connect (priv->menu, "closed",
G_CALLBACK (menu_deactivated), toolbar);
}
- gtk_container_foreach (GTK_CONTAINER (priv->menu), remove_item, NULL);
-
+ gtk_container_foreach (GTK_CONTAINER (priv->menu_box), remove_item, NULL);
+
for (list = priv->content; list != NULL; list = list->next)
{
ToolbarContent *content = list->data;
-
+
if (toolbar_content_get_state (content) == OVERFLOWN &&
!toolbar_content_is_placeholder (content))
{
GtkWidget *menu_item = toolbar_content_retrieve_menu_item (content);
-
+
if (menu_item)
{
- g_assert (GTK_IS_MENU_ITEM (menu_item));
- gtk_menu_shell_append (GTK_MENU_SHELL (priv->menu), menu_item);
- }
- }
- }
-
- /* Remove leading and trailing separator items */
- children = gtk_container_get_children (GTK_CONTAINER (priv->menu));
-
- list = children;
- while (list && GTK_IS_SEPARATOR_MENU_ITEM (list->data))
- {
- GtkWidget *child = list->data;
-
- gtk_container_remove (GTK_CONTAINER (priv->menu), child);
- list = list->next;
- }
- g_list_free (children);
+ GtkWidget *button, *widget;
+ const char *text;
+ GtkButtonRole role;
+ gboolean active;
- /* Regenerate the list of children so we don't try to remove items twice */
- children = gtk_container_get_children (GTK_CONTAINER (priv->menu));
+ g_assert (GTK_IS_MENU_ITEM (menu_item));
+ text = gtk_menu_item_get_label (GTK_MENU_ITEM (menu_item));
+ if (text == NULL)
+ {
+ GtkWidget *box, *child;
+ box = gtk_bin_get_child (GTK_BIN (menu_item));
+ for (child = gtk_widget_get_first_child (box);
+ child;
+ child = gtk_widget_get_next_sibling (child))
+ {
+ if (GTK_IS_LABEL (child))
+ {
+ text = gtk_label_get_label (GTK_LABEL (child));
+ break;
+ }
+ }
+ }
- list = g_list_last (children);
- while (list && GTK_IS_SEPARATOR_MENU_ITEM (list->data))
- {
- GtkWidget *child = list->data;
+ if (GTK_IS_SEPARATOR_MENU_ITEM (menu_item))
+ {
+ gtk_container_add (GTK_CONTAINER (priv->menu_box), gtk_separator_new (GTK_ORIENTATION_HORIZONTAL));
+ continue;
+ }
+ else if (GTK_IS_RADIO_MENU_ITEM (menu_item))
+ role = GTK_BUTTON_ROLE_RADIO;
+ else if (GTK_IS_CHECK_MENU_ITEM (menu_item))
+ role = GTK_BUTTON_ROLE_CHECK;
+ else
+ role = GTK_BUTTON_ROLE_NORMAL;
- gtk_container_remove (GTK_CONTAINER (priv->menu), child);
- list = list->prev;
+ if (GTK_IS_CHECK_MENU_ITEM (menu_item))
+ active = gtk_check_menu_item_get_active (GTK_CHECK_MENU_ITEM (menu_item));
+ else
+ active = FALSE;
+
+ button = gtk_model_button_new ();
+ g_object_set (button,
+ "text", text,
+ "role", role,
+ "active", active,
+ NULL);
+ widget = toolbar_content_get_widget (content);
+ g_signal_connect (button, "clicked",
+ G_CALLBACK (button_clicked), widget);
+ gtk_container_add (GTK_CONTAINER (priv->menu_box), button);
+ }
+ }
}
- g_list_free (children);
priv->need_rebuild = FALSE;
}
@@ -2124,52 +2150,10 @@ show_menu (GtkToolbar *toolbar,
GdkEventButton *event)
{
GtkToolbarPrivate *priv = toolbar->priv;
- GtkRequisition minimum_size;
rebuild_menu (toolbar);
- gtk_widget_show (GTK_WIDGET (priv->menu));
-
- switch (priv->orientation)
- {
- case GTK_ORIENTATION_HORIZONTAL:
- gtk_widget_get_preferred_size (priv->arrow_button, &minimum_size, NULL);
-
- g_object_set (priv->menu,
- "anchor-hints", (GDK_ANCHOR_FLIP_Y |
- GDK_ANCHOR_SLIDE |
- GDK_ANCHOR_RESIZE),
- "menu-type-hint", GDK_SURFACE_TYPE_HINT_DROPDOWN_MENU,
- "rect-anchor-dx", -minimum_size.width,
- NULL);
-
- gtk_menu_popup_at_widget (priv->menu,
- priv->arrow_button,
- GDK_GRAVITY_SOUTH_EAST,
- GDK_GRAVITY_NORTH_WEST,
- (GdkEvent *) event);
-
- break;
-
- case GTK_ORIENTATION_VERTICAL:
- g_object_set (priv->menu,
- "anchor-hints", (GDK_ANCHOR_FLIP_X |
- GDK_ANCHOR_SLIDE |
- GDK_ANCHOR_RESIZE),
- NULL);
-
- gtk_menu_popup_at_widget (priv->menu,
- priv->arrow_button,
- GDK_GRAVITY_NORTH_EAST,
- GDK_GRAVITY_NORTH_WEST,
- (GdkEvent *) event);
-
- break;
-
- default:
- g_assert_not_reached ();
- break;
- }
+ gtk_popover_popup (GTK_POPOVER (priv->menu));
}
static void
diff --git a/gtk/gtkwindow.c b/gtk/gtkwindow.c
index a907d8e3b3..c93b733f61 100644
--- a/gtk/gtkwindow.c
+++ b/gtk/gtkwindow.c
@@ -60,6 +60,9 @@
#include "gtkmenushellprivate.h"
#include "gtkpointerfocusprivate.h"
#include "gtkpopoverprivate.h"
+#include "gtkpopovermenu.h"
+#include "gtkmodelbutton.h"
+#include "gtkseparator.h"
#include "gtkprivate.h"
#include "gtkroot.h"
#include "gtknative.h"
@@ -6569,12 +6572,12 @@ _gtk_window_unset_focus_and_default (GtkWindow *window,
}
static void
-popup_menu_detach (GtkWidget *widget,
- GtkMenu *menu)
+popup_menu_closed (GtkPopover *popover,
+ GtkWindow *widget)
{
GtkWindowPrivate *priv = gtk_window_get_instance_private (GTK_WINDOW (widget));
- priv->popup_menu = NULL;
+ g_clear_pointer (&priv->popup_menu, gtk_widget_unparent);
}
static GdkSurfaceState
@@ -6670,6 +6673,7 @@ ontop_window_clicked (GtkMenuItem *menuitem,
GtkWindow *window = (GtkWindow *)user_data;
GtkWindowPrivate *priv = gtk_window_get_instance_private (window);
+ gtk_popover_popdown (GTK_POPOVER (priv->popup_menu));
gtk_window_set_keep_above (window, !priv->above_initially);
}
@@ -6690,6 +6694,7 @@ gtk_window_do_popup_fallback (GtkWindow *window,
GtkWidget *menuitem;
GdkSurfaceState state;
gboolean maximized, iconified;
+ GtkWidget *box;
if (priv->popup_menu)
gtk_widget_destroy (priv->popup_menu);
@@ -6699,16 +6704,14 @@ gtk_window_do_popup_fallback (GtkWindow *window,
iconified = (state & GDK_SURFACE_STATE_ICONIFIED) == GDK_SURFACE_STATE_ICONIFIED;
maximized = priv->maximized && !iconified;
- priv->popup_menu = gtk_menu_new ();
- gtk_style_context_add_class (gtk_widget_get_style_context (priv->popup_menu),
- GTK_STYLE_CLASS_CONTEXT_MENU);
+ priv->popup_menu = gtk_popover_menu_new (priv->title_box);
- gtk_menu_attach_to_widget (GTK_MENU (priv->popup_menu),
- GTK_WIDGET (window),
- popup_menu_detach);
+ box = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
+ gtk_popover_menu_add_submenu (GTK_POPOVER_MENU (priv->popup_menu), box, "main");
+
+ menuitem = gtk_model_button_new ();
+ g_object_set (menuitem, "text", _("Restore"), NULL);
- menuitem = gtk_menu_item_new_with_label (_("Restore"));
- gtk_widget_show (menuitem);
/* "Restore" means "Unmaximize" or "Unminimize"
* (yes, some WMs allow window menu to be shown for minimized windows).
* Not restorable:
@@ -6721,70 +6724,80 @@ gtk_window_do_popup_fallback (GtkWindow *window,
(!iconified && !priv->resizable) ||
priv->type_hint != GDK_SURFACE_TYPE_HINT_NORMAL)
gtk_widget_set_sensitive (menuitem, FALSE);
- g_signal_connect (G_OBJECT (menuitem), "activate",
+ g_signal_connect (G_OBJECT (menuitem), "clicked",
G_CALLBACK (restore_window_clicked), window);
- gtk_menu_shell_append (GTK_MENU_SHELL (priv->popup_menu), menuitem);
+ gtk_container_add (GTK_CONTAINER (box), menuitem);
+
+ menuitem = gtk_model_button_new ();
+ g_object_set (menuitem, "text", _("Move"), NULL);
- menuitem = gtk_menu_item_new_with_label (_("Move"));
- gtk_widget_show (menuitem);
if (maximized || iconified)
gtk_widget_set_sensitive (menuitem, FALSE);
- g_signal_connect (G_OBJECT (menuitem), "activate",
+ g_signal_connect (G_OBJECT (menuitem), "clicked",
G_CALLBACK (move_window_clicked), window);
- gtk_menu_shell_append (GTK_MENU_SHELL (priv->popup_menu), menuitem);
+ gtk_container_add (GTK_CONTAINER (box), menuitem);
+
+ menuitem = gtk_model_button_new ();
+ g_object_set (menuitem, "text", _("Resize"), NULL);
- menuitem = gtk_menu_item_new_with_label (_("Resize"));
- gtk_widget_show (menuitem);
if (!priv->resizable || maximized || iconified)
gtk_widget_set_sensitive (menuitem, FALSE);
- g_signal_connect (G_OBJECT (menuitem), "activate",
+ g_signal_connect (G_OBJECT (menuitem), "clicked",
G_CALLBACK (resize_window_clicked), window);
- gtk_menu_shell_append (GTK_MENU_SHELL (priv->popup_menu), menuitem);
+ gtk_container_add (GTK_CONTAINER (box), menuitem);
+
+ menuitem = gtk_model_button_new ();
+ g_object_set (menuitem, "text", _("Minimize"), NULL);
- menuitem = gtk_menu_item_new_with_label (_("Minimize"));
- gtk_widget_show (menuitem);
if (iconified ||
priv->type_hint != GDK_SURFACE_TYPE_HINT_NORMAL)
gtk_widget_set_sensitive (menuitem, FALSE);
- g_signal_connect (G_OBJECT (menuitem), "activate",
+ g_signal_connect (G_OBJECT (menuitem), "clicked",
G_CALLBACK (minimize_window_clicked), window);
- gtk_menu_shell_append (GTK_MENU_SHELL (priv->popup_menu), menuitem);
+ gtk_container_add (GTK_CONTAINER (box), menuitem);
+
+ menuitem = gtk_model_button_new ();
+ g_object_set (menuitem, "text", _("Maximize"), NULL);
- menuitem = gtk_menu_item_new_with_label (_("Maximize"));
- gtk_widget_show (menuitem);
if (maximized ||
!priv->resizable ||
priv->type_hint != GDK_SURFACE_TYPE_HINT_NORMAL)
gtk_widget_set_sensitive (menuitem, FALSE);
- g_signal_connect (G_OBJECT (menuitem), "activate",
+ g_signal_connect (G_OBJECT (menuitem), "clicked",
G_CALLBACK (maximize_window_clicked), window);
- gtk_menu_shell_append (GTK_MENU_SHELL (priv->popup_menu), menuitem);
+ gtk_container_add (GTK_CONTAINER (box), menuitem);
- menuitem = gtk_separator_menu_item_new ();
- gtk_widget_show (menuitem);
- gtk_menu_shell_append (GTK_MENU_SHELL (priv->popup_menu), menuitem);
+ menuitem = gtk_separator_new (GTK_ORIENTATION_HORIZONTAL);
+ gtk_container_add (GTK_CONTAINER (box), menuitem);
+
+ menuitem = gtk_model_button_new ();
+ g_object_set (menuitem,
+ "text", _("Always on Top"),
+ "role", GTK_BUTTON_ROLE_CHECK,
+ "active", priv->above_initially,
+ NULL);
- menuitem = gtk_check_menu_item_new_with_label (_("Always on Top"));
- gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (menuitem), priv->above_initially);
if (maximized)
gtk_widget_set_sensitive (menuitem, FALSE);
- gtk_widget_show (menuitem);
- g_signal_connect (G_OBJECT (menuitem), "activate",
+ g_signal_connect (G_OBJECT (menuitem), "clicked",
G_CALLBACK (ontop_window_clicked), window);
- gtk_menu_shell_append (GTK_MENU_SHELL (priv->popup_menu), menuitem);
+ gtk_container_add (GTK_CONTAINER (box), menuitem);
- menuitem = gtk_separator_menu_item_new ();
- gtk_widget_show (menuitem);
- gtk_menu_shell_append (GTK_MENU_SHELL (priv->popup_menu), menuitem);
+ menuitem = gtk_separator_new (GTK_ORIENTATION_HORIZONTAL);
+ gtk_container_add (GTK_CONTAINER (box), menuitem);
+
+ menuitem = gtk_model_button_new ();
+ g_object_set (menuitem, "text", _("Close"), NULL);
- menuitem = gtk_menu_item_new_with_label (_("Close"));
- gtk_widget_show (menuitem);
if (!priv->deletable)
gtk_widget_set_sensitive (menuitem, FALSE);
- g_signal_connect (G_OBJECT (menuitem), "activate",
+ g_signal_connect (G_OBJECT (menuitem), "clicked",
G_CALLBACK (close_window_clicked), window);
- gtk_menu_shell_append (GTK_MENU_SHELL (priv->popup_menu), menuitem);
- gtk_menu_popup_at_pointer (GTK_MENU (priv->popup_menu), (GdkEvent *) event);
+ gtk_container_add (GTK_CONTAINER (box), menuitem);
+
+ g_signal_connect (priv->popup_menu, "closed",
+ G_CALLBACK (popup_menu_closed), window);
+ gtk_popover_popup (GTK_POPOVER (priv->popup_menu));
}
static void