[gnome-panel] libpanel-applet, panel: Make edit actions of applets a second menu



commit a7c9ed7e9732263e11d0c069d0363aa8e29bcad9
Author: Vincent Untz <vuntz gnome org>
Date:   Tue Feb 22 21:55:19 2011 +0100

    libpanel-applet, panel: Make edit actions of applets a second menu
    
    This is really the same as previous commits :-)

 .../panel-applet-container.c                       |   44 +++
 .../panel-applet-container.h                       |    9 +
 .../panel-applet-frame-dbus.c                      |   13 +
 gnome-panel/panel-applet-frame.c                   |   16 +-
 gnome-panel/panel-applet-frame.h                   |    4 +
 libpanel-applet/Makefile.am                        |    2 +
 libpanel-applet/panel-applet-bindings.c            |  310 ++++++++++++++++++++
 libpanel-applet/panel-applet-bindings.h            |   45 +++
 libpanel-applet/panel-applet.c                     |   88 +++++-
 9 files changed, 522 insertions(+), 9 deletions(-)
---
diff --git a/gnome-panel/libpanel-applet-private/panel-applet-container.c b/gnome-panel/libpanel-applet-private/panel-applet-container.c
index fd51208..f8cc985 100644
--- a/gnome-panel/libpanel-applet-private/panel-applet-container.c
+++ b/gnome-panel/libpanel-applet-private/panel-applet-container.c
@@ -798,3 +798,47 @@ panel_applet_container_child_popup_menu_finish (PanelAppletContainer *container,
 
 	return !g_simple_async_result_propagate_error (simple, error);
 }
+
+void
+panel_applet_container_child_popup_edit_menu (PanelAppletContainer *container,
+					      guint                 button,
+					      guint32               timestamp,
+					      GCancellable         *cancellable,
+					      GAsyncReadyCallback   callback,
+					      gpointer              user_data)
+{
+	GSimpleAsyncResult *result;
+	GDBusProxy         *proxy = container->priv->applet_proxy;
+
+	if (!proxy)
+		return;
+
+	result = g_simple_async_result_new (G_OBJECT (container),
+					    callback,
+					    user_data,
+					    panel_applet_container_child_popup_edit_menu);
+
+	g_dbus_connection_call (g_dbus_proxy_get_connection (proxy),
+				g_dbus_proxy_get_name (proxy),
+				g_dbus_proxy_get_object_path (proxy),
+				PANEL_APPLET_INTERFACE,
+				"PopupEditMenu",
+				g_variant_new ("(uu)", button, timestamp),
+				NULL,
+				G_DBUS_CALL_FLAGS_NO_AUTO_START,
+				-1, cancellable,
+				child_popup_menu_cb,
+				result);
+}
+
+gboolean
+panel_applet_container_child_popup_edit_menu_finish (PanelAppletContainer *container,
+						     GAsyncResult         *result,
+						     GError              **error)
+{
+	GSimpleAsyncResult *simple = G_SIMPLE_ASYNC_RESULT (result);
+
+	g_warn_if_fail (g_simple_async_result_get_source_tag (simple) == panel_applet_container_child_popup_edit_menu);
+
+	return !g_simple_async_result_propagate_error (simple, error);
+}
diff --git a/gnome-panel/libpanel-applet-private/panel-applet-container.h b/gnome-panel/libpanel-applet-private/panel-applet-container.h
index e4de97a..912193e 100644
--- a/gnome-panel/libpanel-applet-private/panel-applet-container.h
+++ b/gnome-panel/libpanel-applet-private/panel-applet-container.h
@@ -91,6 +91,15 @@ void       panel_applet_container_child_popup_menu        (PanelAppletContainer
 gboolean   panel_applet_container_child_popup_menu_finish (PanelAppletContainer *container,
 							   GAsyncResult         *result,
 							   GError              **error);
+void       panel_applet_container_child_popup_edit_menu   (PanelAppletContainer *container,
+							   guint                 button,
+							   guint32               timestamp,
+							   GCancellable         *cancellable,
+							   GAsyncReadyCallback   callback,
+							   gpointer              user_data);
+gboolean   panel_applet_container_child_popup_edit_menu_finish (PanelAppletContainer *container,
+								GAsyncResult         *result,
+								GError              **error);
 
 void       panel_applet_container_child_set               (PanelAppletContainer *container,
 							   const gchar          *property_name,
diff --git a/gnome-panel/libpanel-applet-private/panel-applet-frame-dbus.c b/gnome-panel/libpanel-applet-private/panel-applet-frame-dbus.c
index dd3aecb..7f365ab 100644
--- a/gnome-panel/libpanel-applet-private/panel-applet-frame-dbus.c
+++ b/gnome-panel/libpanel-applet-private/panel-applet-frame-dbus.c
@@ -185,6 +185,18 @@ panel_applet_frame_dbus_popup_menu (PanelAppletFrame *frame,
 }
 
 static void
+panel_applet_frame_dbus_popup_edit_menu (PanelAppletFrame *frame,
+					 guint             button,
+					 guint32           timestamp)
+{
+	PanelAppletFrameDBus *dbus_frame = PANEL_APPLET_FRAME_DBUS (frame);
+
+	panel_applet_container_child_popup_edit_menu (dbus_frame->priv->container,
+						      button, timestamp,
+						      NULL, NULL, NULL);
+}
+
+static void
 change_orientation_cb (PanelAppletContainer *container,
 		       GAsyncResult         *res,
 		       PanelAppletFrame     *frame)
@@ -380,6 +392,7 @@ panel_applet_frame_dbus_class_init (PanelAppletFrameDBusClass *class)
 	frame_class->init_properties = panel_applet_frame_dbus_init_properties;
 	frame_class->sync_menu_state = panel_applet_frame_dbus_sync_menu_state;
 	frame_class->popup_menu = panel_applet_frame_dbus_popup_menu;
+	frame_class->popup_edit_menu = panel_applet_frame_dbus_popup_edit_menu;
 	frame_class->change_orientation = panel_applet_frame_dbus_change_orientation;
 	frame_class->change_size = panel_applet_frame_dbus_change_size;
 	frame_class->change_background = panel_applet_frame_dbus_change_background;
diff --git a/gnome-panel/panel-applet-frame.c b/gnome-panel/panel-applet-frame.c
index 7452542..acbdc43 100644
--- a/gnome-panel/panel-applet-frame.c
+++ b/gnome-panel/panel-applet-frame.c
@@ -34,6 +34,7 @@
 #include <gdk/gdkx.h>
 
 #include "panel-applets-manager.h"
+#include "panel-bindings.h"
 #include "panel-profile.h"
 #include "panel.h"
 #include "applet.h"
@@ -376,14 +377,23 @@ panel_applet_frame_button_changed (GtkWidget      *widget,
 	case 3:
 		if (event->type == GDK_BUTTON_PRESS ||
 		    event->type == GDK_2BUTTON_PRESS) {
+			guint modifiers;
+
+			modifiers = event->state & GDK_MODIFIER_MASK;
+
 			display = gtk_widget_get_display (widget);
 			device_manager = gdk_display_get_device_manager (display);
 			pointer = gdk_device_manager_get_client_pointer (device_manager);
 			gdk_device_ungrab (pointer, GDK_CURRENT_TIME);
 
-			PANEL_APPLET_FRAME_GET_CLASS (frame)->popup_menu (frame,
-									  event->button,
-									  event->time);
+			if (modifiers == panel_bindings_get_mouse_button_modifier_keymask ())
+				PANEL_APPLET_FRAME_GET_CLASS (frame)->popup_edit_menu (frame,
+										       event->button,
+										       event->time);
+			else
+				PANEL_APPLET_FRAME_GET_CLASS (frame)->popup_menu (frame,
+										  event->button,
+										  event->time);
 
 			handled = TRUE;
 		} else if (event->type == GDK_BUTTON_RELEASE)
diff --git a/gnome-panel/panel-applet-frame.h b/gnome-panel/panel-applet-frame.h
index a551c4c..2d0723e 100644
--- a/gnome-panel/panel-applet-frame.h
+++ b/gnome-panel/panel-applet-frame.h
@@ -59,6 +59,10 @@ struct _PanelAppletFrameClass {
 					   guint                button,
 					   guint32              timestamp);
 
+	void     (*popup_edit_menu)       (PanelAppletFrame    *frame,
+					   guint                button,
+					   guint32              timestamp);
+
 	void     (*change_orientation)    (PanelAppletFrame    *frame,
 					   PanelOrientation     orientation);
 
diff --git a/libpanel-applet/Makefile.am b/libpanel-applet/Makefile.am
index 8a34fdc..cb607a2 100644
--- a/libpanel-applet/Makefile.am
+++ b/libpanel-applet/Makefile.am
@@ -21,6 +21,8 @@ libpanel_applet_4_la_SOURCES =		\
 	panel-applet.c			\
 	panel-applet-factory.h		\
 	panel-applet-factory.c		\
+	panel-applet-bindings.h		\
+	panel-applet-bindings.c		\
 	panel-applet-gconf.c		\
 	panel-applet-gconf.h
 
diff --git a/libpanel-applet/panel-applet-bindings.c b/libpanel-applet/panel-applet-bindings.c
new file mode 100644
index 0000000..8562fba
--- /dev/null
+++ b/libpanel-applet/panel-applet-bindings.c
@@ -0,0 +1,310 @@
+/*
+ * panel-applet-bindings.c: utility for key bindings.
+ *
+ * Copyright (c) 2011 Novell, 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, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ * Authors:
+ *     Vincent Untz <vuntz gnome org>
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <gtk/gtk.h>
+#include <gdk/gdkx.h>
+#include <X11/Xlib.h>
+
+#include "panel-applet-bindings.h"
+
+/******************************\
+ * copied from panel-xutils.c *
+\******************************/
+
+static guint
+panel_applet_bindings_get_real_modifier_mask (guint mask)
+{
+	guint real_mask;
+	Display *display;
+	int i, min_keycode, max_keycode, keysyms_per_keycode;
+	int max_keycodes_per_modifier;
+	KeySym *keysyms_for_keycodes;
+	XModifierKeymap *modifier_keymap;
+
+	real_mask = mask & ((Mod5Mask << 1) - 1);
+
+	/* Already real */
+	if (mask == real_mask) {
+		return mask;
+	}
+
+	display = GDK_DISPLAY_XDISPLAY (gdk_display_get_default ());
+
+	XDisplayKeycodes (display, &min_keycode, &max_keycode);
+	keysyms_for_keycodes = XGetKeyboardMapping (display,
+						    min_keycode,
+						    max_keycode - min_keycode + 1,
+						    &keysyms_per_keycode);
+
+	modifier_keymap = XGetModifierMapping (display);
+	max_keycodes_per_modifier = modifier_keymap->max_keypermod;
+
+	/* Loop through all the modifiers and find out which "real"
+	 * (Mod2..Mod5) modifiers Super, Hyper, and Meta are mapped to.
+	 * Note, Mod1 is used by the Alt modifier */
+	for (i = Mod2MapIndex * max_keycodes_per_modifier;
+	     i < (Mod5MapIndex + 1) * max_keycodes_per_modifier;
+	     i++) {
+		int keycode;
+		int j;
+		KeySym *keysyms_for_keycode;
+		int map_index;
+		int map_mask;
+
+		keycode = modifier_keymap->modifiermap[i];
+
+		/* The array is sparse, there may be some
+		 * empty entries.  Filter those out
+		 * (along with any invalid entries) */
+		if (keycode < min_keycode || keycode > max_keycode)
+			continue;
+
+		keysyms_for_keycode = keysyms_for_keycodes +
+		                      (keycode - min_keycode) * keysyms_per_keycode;
+
+		map_index = i / max_keycodes_per_modifier;
+
+		g_assert (map_index <= Mod5MapIndex);
+
+		map_mask = 1 << map_index;
+
+		for (j = 0; j < keysyms_per_keycode; j++) {
+			switch (keysyms_for_keycode[j]) {
+				case XK_Super_L:
+				case XK_Super_R:
+					if (mask & GDK_SUPER_MASK)
+						real_mask |= map_mask;
+					break;
+				case XK_Hyper_L:
+				case XK_Hyper_R:
+					if (mask & GDK_HYPER_MASK)
+						real_mask |= map_mask;
+					break;
+				case XK_Meta_L:
+				case XK_Meta_R:
+					if (mask & GDK_META_MASK)
+						real_mask |= map_mask;
+					break;
+				default:
+					break;
+			}
+		}
+	}
+
+	XFreeModifiermap (modifier_keymap);
+	XFree (keysyms_for_keycodes);
+
+	return real_mask;
+}
+
+/*********************************\
+ * adapted from panel-bindings.c *
+\*********************************/
+
+#define MOUSE_MODIFIER_DIR "/apps/metacity/general"
+#define MOUSE_MODIFIER_KEY "/apps/metacity/general/mouse_button_modifier"
+#define DEFAULT_MOUSE_MODIFIER GDK_MOD1_MASK
+
+static guint initialised = 0;
+static guint notify_id = 0;
+
+static guint mouse_button_modifier_keymask = DEFAULT_MOUSE_MODIFIER;
+
+static void
+panel_bindings_mouse_modifier_set_from_string (const char *str)
+{
+	guint modifier_keysym;
+	guint modifier_keymask;
+
+	gtk_accelerator_parse (str, &modifier_keysym, &modifier_keymask);
+
+	if (modifier_keysym == 0 && modifier_keymask == 0) {
+		g_warning ("Unable to parse mouse modifier '%s'\n", str);
+		return;
+	}
+
+	if (modifier_keymask)
+		mouse_button_modifier_keymask = modifier_keymask;
+	else
+		mouse_button_modifier_keymask = DEFAULT_MOUSE_MODIFIER;
+}
+
+static void
+panel_bindings_mouse_modifier_changed (GConfClient  *client,
+				       guint         cnxn_id,
+				       GConfEntry   *entry,
+				       gpointer      user_data)
+{
+	GConfValue *value;
+	const char *str;
+
+	value = gconf_entry_get_value (entry);
+
+	if (!value || value->type != GCONF_VALUE_STRING)
+		return;
+
+	str = gconf_value_get_string (value);
+	panel_bindings_mouse_modifier_set_from_string (str);
+}
+
+void
+panel_applet_bindings_clean (GConfClient *client)
+{
+	if (initialised == 0)
+		return;
+
+	initialised--;
+
+	if (initialised > 0)
+		return;
+
+	gconf_client_remove_dir (client, MOUSE_MODIFIER_DIR, NULL);
+	if (notify_id > 0)
+		gconf_client_notify_remove (client, notify_id);
+	notify_id = 0;
+}
+
+void
+panel_applet_bindings_init (GConfClient *client)
+{
+	GError *error;
+	char   *str;
+
+	if (initialised > 0) {
+		initialised++;
+		return;
+	}
+
+	/* mouse button modifier */
+	error = NULL;
+	gconf_client_add_dir (client, MOUSE_MODIFIER_DIR,
+			      GCONF_CLIENT_PRELOAD_NONE, &error);
+	if (error) {
+		g_warning ("Error loading gconf directory '%s': %s",
+			   MOUSE_MODIFIER_DIR, error->message),
+		g_error_free (error);
+	}
+
+	error = NULL;
+	notify_id = gconf_client_notify_add (client, MOUSE_MODIFIER_KEY,
+				 panel_bindings_mouse_modifier_changed,
+				 NULL, NULL, &error);
+	if (error) {
+		g_warning ("Error watching gconf key '%s': %s",
+			   MOUSE_MODIFIER_KEY, error->message);
+		g_error_free (error);
+	}
+
+	error = NULL;
+	str = gconf_client_get_string (client, MOUSE_MODIFIER_KEY, &error);
+	if (error) {
+		g_warning ("Error getting value for '%s': %s",
+			   MOUSE_MODIFIER_KEY, error->message);
+		g_error_free (error);
+	} else {
+		panel_bindings_mouse_modifier_set_from_string (str);
+		g_free (str);
+	}
+
+	initialised = 1;
+}
+
+guint
+panel_applet_bindings_get_mouse_button_modifier_keymask (void)
+{
+	g_assert (initialised != 0);
+	g_assert (mouse_button_modifier_keymask != 0);
+
+	return panel_applet_bindings_get_real_modifier_mask (mouse_button_modifier_keymask);
+}
+
+/****************************\
+ * copied from panel-util.c *
+\****************************/
+
+static void
+panel_applet_bindings_key_event_is_binding (GdkEventKey *event,
+					    GType        type,
+					    const char  *signal_name,
+					    gboolean    *is_popup,
+					    gboolean    *is_popup_modifier)
+{
+	GtkBindingSet   *binding_set;
+	GtkBindingEntry *binding_entry;
+	gboolean         popup = FALSE;
+	gboolean         popup_modifier = FALSE;
+	char            *signal_dash;
+	char            *signal_underscore;
+
+	signal_dash = g_strdup (signal_name);
+	g_strdelimit (signal_dash, "_", '-');
+	signal_underscore = g_strdup (signal_name);
+	g_strdelimit (signal_underscore, "-", '_');
+
+	binding_set = gtk_binding_set_by_class (g_type_class_peek (type));
+
+	for (binding_entry = binding_set->entries;
+	     binding_entry != NULL;
+	     binding_entry = binding_entry->set_next) {
+		GtkBindingSignal *binding_signal;
+
+		for (binding_signal = binding_entry->signals;
+		     binding_signal != NULL;
+		     binding_signal = binding_signal->next) {
+			if (g_strcmp0 (binding_signal->signal_name, signal_dash) == 0 ||
+			    g_strcmp0 (binding_signal->signal_name, signal_underscore) == 0) {
+				if (binding_entry->keyval != event->keyval)
+					break;
+
+				popup = (event->state & GDK_MODIFIER_MASK) == binding_entry->modifiers;
+				popup_modifier = (event->state & GDK_MODIFIER_MASK) == (panel_applet_bindings_get_mouse_button_modifier_keymask ()|binding_entry->modifiers);
+				break;
+			}
+		}
+
+		if (popup || popup_modifier)
+			break;
+	}
+
+	if (is_popup)
+		*is_popup = popup;
+	if (is_popup_modifier)
+		*is_popup_modifier = popup_modifier;
+
+	g_free (signal_dash);
+	g_free (signal_underscore);
+}
+
+void
+panel_applet_bindings_key_event_is_popup (GdkEventKey *event,
+					  gboolean    *is_popup,
+					  gboolean    *is_popup_modifier)
+{
+	panel_applet_bindings_key_event_is_binding (event, GTK_TYPE_WIDGET, "popup-menu",
+						    is_popup, is_popup_modifier);
+}
diff --git a/libpanel-applet/panel-applet-bindings.h b/libpanel-applet/panel-applet-bindings.h
new file mode 100644
index 0000000..79127e6
--- /dev/null
+++ b/libpanel-applet/panel-applet-bindings.h
@@ -0,0 +1,45 @@
+/*
+ * panel-applet-bindings.h: utility for key bindings.
+ *
+ * Copyright (c) 2011 Novell, 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, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ * Authors:
+ *     Vincent Untz <vuntz gnome org>
+ */
+
+#ifndef __PANEL_APPLET_BINDINGS_H__
+#define __PANEL_APPLET_BINDINGS_H__
+
+#include <glib.h>
+#include <gdk/gdk.h>
+#include <gconf/gconf-client.h>
+
+G_BEGIN_DECLS
+
+void  panel_applet_bindings_init  (GConfClient *client);
+void  panel_applet_bindings_clean (GConfClient *client);
+
+guint panel_applet_bindings_get_mouse_button_modifier_keymask (void);
+
+void panel_applet_bindings_key_event_is_popup (GdkEventKey *event,
+					       gboolean    *is_popup,
+					       gboolean    *is_popup_modifier);
+
+G_END_DECLS
+
+#endif /* __PANEL_APPLET_BINDINGS_H__ */
diff --git a/libpanel-applet/panel-applet.c b/libpanel-applet/panel-applet.c
index ccf79cd..f12e1ac 100644
--- a/libpanel-applet/panel-applet.c
+++ b/libpanel-applet/panel-applet.c
@@ -44,12 +44,20 @@
 #include <cairo-xlib.h>
 
 #include "panel-applet.h"
+#include "panel-applet-bindings.h"
 #include "panel-applet-factory.h"
 #include "panel-applet-marshal.h"
 #include "panel-applet-enums.h"
 
 #define PANEL_APPLET_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), PANEL_TYPE_APPLET, PanelAppletPrivate))
 
+
+/* FIXME
+    PopupEditMenu dbus method
+ */
+
+
+
 struct _PanelAppletPrivate {
 	GtkWidget         *plug;
 	GtkWidget         *applet;
@@ -126,7 +134,8 @@ static const gchar panel_menu_ui[] =
 	"<ui>\n"
 	"  <popup name=\"PanelAppletPopup\" action=\"PopupAction\">\n"
 	"    <placeholder name=\"AppletItems\"/>\n"
-	"    <separator/>\n"
+	"  </popup>\n"
+	"  <popup name=\"PanelAppletEditPopup\" action=\"PopupEditAction\">\n"
 	"    <menuitem name=\"RemoveItem\" action=\"Remove\"/>\n"
 	"    <menuitem name=\"MoveItem\" action=\"Move\"/>\n"
 	"    <separator/>\n"
@@ -135,6 +144,9 @@ static const gchar panel_menu_ui[] =
 	"</ui>\n";
 
 static const GtkActionEntry menu_entries[] = {
+	{ "PopupAction", NULL, "Popup Action",
+	  NULL, NULL,
+	  NULL },
 	{ "Remove", GTK_STOCK_REMOVE, N_("_Remove From Panel"),
 	  NULL, NULL,
 	  G_CALLBACK (panel_applet_menu_cmd_remove) },
@@ -882,6 +894,8 @@ panel_applet_finalize (GObject *object)
 
 	panel_applet_set_preferences_key (applet, NULL);
 
+	panel_applet_bindings_clean (applet->priv->client);
+
 	if (applet->priv->client)
 		g_object_unref (applet->priv->client);
 	applet->priv->client = NULL;
@@ -1014,9 +1028,23 @@ panel_applet_menu_popup (PanelApplet *applet,
 			 guint32      time)
 {
 	GtkWidget *menu;
+	GList     *children, *l;
+	gboolean   visible = FALSE;
 
 	menu = gtk_ui_manager_get_widget (applet->priv->ui_manager,
 					  "/PanelAppletPopup");
+
+	children = gtk_container_get_children (GTK_CONTAINER (menu));
+	for (l = children; l != NULL; l = l->next) {
+		visible = gtk_widget_get_visible (GTK_WIDGET (l->data));
+		if (visible)
+			break;
+	}
+	g_list_free (children);
+
+	if (!visible)
+		return;
+
 	gtk_menu_popup (GTK_MENU (menu),
 			NULL, NULL,
 			(GtkMenuPositionFunc) panel_applet_position_menu,
@@ -1024,6 +1052,25 @@ panel_applet_menu_popup (PanelApplet *applet,
 			button, time);
 }
 
+static void
+panel_applet_edit_menu_popup (PanelApplet *applet,
+			      guint        button,
+			      guint32      time)
+{
+	GtkWidget *menu;
+
+	if (applet->priv->locked_down)
+		return;
+
+	menu = gtk_ui_manager_get_widget (applet->priv->ui_manager,
+					  "/PanelAppletEditPopup");
+	gtk_menu_popup (GTK_MENU (menu),
+			NULL, NULL,
+			NULL,
+			applet,
+			button, time);
+}
+
 static gboolean
 panel_applet_can_focus (GtkWidget *widget)
 {
@@ -1109,7 +1156,14 @@ panel_applet_button_press (GtkWidget      *widget,
 	}
 
 	if (event->button == 3) {
-		panel_applet_menu_popup (applet, event->button, event->time);
+		guint modifiers;
+
+		modifiers = event->state & GDK_MODIFIER_MASK;
+
+		if (modifiers == panel_applet_bindings_get_mouse_button_modifier_keymask ())
+			panel_applet_edit_menu_popup (applet, event->button, event->time);
+		else
+			panel_applet_menu_popup (applet, event->button, event->time);
 
 		return TRUE;
 	}
@@ -1127,11 +1181,20 @@ panel_applet_button_release (GtkWidget      *widget,
 }
 
 static gboolean
-panel_applet_popup_menu (GtkWidget *widget)
+panel_applet_key_press_event (GtkWidget   *widget,
+			      GdkEventKey *event)
 {
-	panel_applet_menu_popup (PANEL_APPLET (widget), 3, GDK_CURRENT_TIME);
+	gboolean is_popup = FALSE;
+	gboolean is_edit_popup = FALSE;
 
-	return TRUE;
+	panel_applet_bindings_key_event_is_popup (event, &is_popup, &is_edit_popup);
+
+	if (is_edit_popup)
+		panel_applet_edit_menu_popup (PANEL_APPLET (widget), 3, event->time);
+	else if (is_popup)
+		panel_applet_menu_popup (PANEL_APPLET (widget), 3, event->time);
+
+	return (is_popup || is_edit_popup);
 }
 
 static GtkSizeRequestMode
@@ -1824,6 +1887,7 @@ panel_applet_init (PanelApplet *applet)
 					   panel_menu_ui, -1, NULL);
 
 
+	panel_applet_bindings_init (applet->priv->client);
 
 
 	applet->priv->plug = gtk_plug_new (0);
@@ -1862,6 +1926,7 @@ panel_applet_class_init (PanelAppletClass *klass)
 
 	widget_class->button_press_event = panel_applet_button_press;
 	widget_class->button_release_event = panel_applet_button_release;
+	widget_class->key_press_event = panel_applet_key_press_event;
 	widget_class->get_request_mode = panel_applet_get_request_mode;
         widget_class->get_preferred_width = panel_applet_get_preferred_width;
         widget_class->get_preferred_height = panel_applet_get_preferred_height;
@@ -1869,7 +1934,6 @@ panel_applet_class_init (PanelAppletClass *klass)
 	widget_class->draw = panel_applet_draw;
 	widget_class->focus = panel_applet_focus;
 	widget_class->realize = panel_applet_realize;
-	widget_class->popup_menu = panel_applet_popup_menu;
 
 	g_type_class_add_private (klass, sizeof (PanelAppletPrivate));
 
@@ -2039,6 +2103,14 @@ method_call_cb (GDBusConnection       *connection,
 		panel_applet_menu_popup (applet, button, time);
 
 		g_dbus_method_invocation_return_value (invocation, NULL);
+	} else if (g_strcmp0 (method_name, "PopupEditMenu") == 0) {
+		guint button;
+		guint time;
+
+		g_variant_get (parameters, "(uu)", &button, &time);
+		panel_applet_edit_menu_popup (applet, button, time);
+
+		g_dbus_method_invocation_return_value (invocation, NULL);
 	}
 }
 
@@ -2129,6 +2201,10 @@ static const gchar introspection_xml[] =
 	      "<arg name='button' type='u' direction='in'/>"
 	      "<arg name='time' type='u' direction='in'/>"
 	    "</method>"
+	    "<method name='PopupEditMenu'>"
+	      "<arg name='button' type='u' direction='in'/>"
+	      "<arg name='time' type='u' direction='in'/>"
+	    "</method>"
 	    "<property name='PrefsKey' type='s' access='readwrite'/>"
 	    "<property name='Orient' type='u' access='readwrite' />"
 	    "<property name='Size' type='u' access='readwrite'/>"



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]