forked from AuroraMiddleware/gtk
Merge branch 'wip/kill-menu' into 'master'
Use menus less See merge request GNOME/gtk!1098
This commit is contained in:
commit
87e7fa9917
@ -30,7 +30,6 @@
|
||||
#endif
|
||||
|
||||
#include <gtk/gtkwidget.h>
|
||||
#include <gtk/gtkmenu.h>
|
||||
#include <gio/gio.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
@ -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"
|
||||
|
@ -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>
|
||||
|
@ -26,8 +26,6 @@
|
||||
#include "gtklabel.h"
|
||||
#include "gtkmain.h"
|
||||
#include "gtkprivate.h"
|
||||
#include "gtkradiomenuitem.h"
|
||||
#include "gtkseparatormenuitem.h"
|
||||
#include "gtksettings.h"
|
||||
|
||||
|
||||
|
@ -23,7 +23,6 @@
|
||||
#endif
|
||||
|
||||
#include <gtk/gtkimcontext.h>
|
||||
#include <gtk/gtkmenushell.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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]);
|
||||
}
|
||||
|
@ -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"
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -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);
|
||||
|
@ -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"
|
||||
|
@ -32,7 +32,6 @@
|
||||
#include <gtk/gtkcontainer.h>
|
||||
#include <gtk/gtkimcontext.h>
|
||||
#include <gtk/gtktextbuffer.h>
|
||||
#include <gtk/gtkmenu.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
|
160
gtk/gtktoolbar.c
160
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,77 +1114,97 @@ 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)
|
||||
{
|
||||
GtkWidget *button, *widget;
|
||||
const char *text;
|
||||
GtkButtonRole role;
|
||||
gboolean active;
|
||||
|
||||
g_assert (GTK_IS_MENU_ITEM (menu_item));
|
||||
gtk_menu_shell_append (GTK_MENU_SHELL (priv->menu), 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* 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);
|
||||
|
||||
/* Regenerate the list of children so we don't try to remove items twice */
|
||||
children = gtk_container_get_children (GTK_CONTAINER (priv->menu));
|
||||
|
||||
list = g_list_last (children);
|
||||
while (list && GTK_IS_SEPARATOR_MENU_ITEM (list->data))
|
||||
{
|
||||
GtkWidget *child = list->data;
|
||||
|
||||
gtk_container_remove (GTK_CONTAINER (priv->menu), child);
|
||||
list = list->prev;
|
||||
}
|
||||
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
|
||||
|
103
gtk/gtkwindow.c
103
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
|
||||
|
Loading…
Reference in New Issue
Block a user