[gnome-panel] panel: Make edit actions of panel objects a second different popup menu
- From: Vincent Untz <vuntz src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-panel] panel: Make edit actions of panel objects a second different popup menu
- Date: Tue, 22 Feb 2011 22:20:27 +0000 (UTC)
commit 4b30e4e8376a2fa0a194c3694fdde87b039a6f03
Author: Vincent Untz <vuntz gnome org>
Date: Tue Feb 22 19:38:38 2011 +0100
panel: Make edit actions of panel objects a second different popup menu
In the same way we only allow moving the panel when a mouse button
modifier is used (like in metacity), we only display "edit" actions of
panel objects when the modifier is pressed too.
This means a menu with "Remove"/"Move"/"Lock" options is displayed only
when Alt (default setting) is pressed. When this is not the case, the
action menu from the object is displayed instead.
gnome-panel/applet.c | 348 +++++++++++++++++++++++++-------------
gnome-panel/applet.h | 4 +-
gnome-panel/panel-context-menu.c | 6 +-
3 files changed, 236 insertions(+), 122 deletions(-)
---
diff --git a/gnome-panel/applet.c b/gnome-panel/applet.c
index 7db4dae..62a2d6a 100644
--- a/gnome-panel/applet.c
+++ b/gnome-panel/applet.c
@@ -20,6 +20,7 @@
#include "drawer.h"
#include "launcher.h"
#include "panel-addto.h"
+#include "panel-bindings.h"
#include "panel-gconf.h"
#include "panel-config-global.h"
#include "panel-applet-frame.h"
@@ -154,25 +155,50 @@ panel_applet_clean (AppletInfo *info)
}
static void
-panel_applet_recreate_menu (AppletInfo *info)
+panel_applet_recreate_menu (AppletInfo *info)
{
- GList *l;
+ if (info->menu) {
+ GList *l;
- if (!info->menu)
- return;
+ for (l = info->user_menu; l; l = l->next) {
+ AppletUserMenu *menu = l->data;
- for (l = info->user_menu; l; l = l->next) {
- AppletUserMenu *menu = l->data;
+ menu->menuitem = NULL;
+ menu->submenu = NULL;
+ }
+
+ g_signal_handlers_disconnect_by_func (info->menu,
+ G_CALLBACK (applet_menu_show), info);
+ g_signal_handlers_disconnect_by_func (info->menu,
+ G_CALLBACK (applet_menu_deactivate), info);
- menu->menuitem =NULL;
- menu->submenu =NULL;
+ g_object_unref (info->menu);
+ info->menu = NULL;
+ }
+
+ panel_applet_get_menu (info);
+}
+
+static void
+panel_applet_recreate_edit_menu (AppletInfo *info)
+{
+ if (info->edit_menu) {
+ g_signal_handlers_disconnect_by_func (info->edit_menu,
+ G_CALLBACK (applet_menu_show), info);
+ g_signal_handlers_disconnect_by_func (info->edit_menu,
+ G_CALLBACK (applet_menu_deactivate), info);
+ g_object_unref (info->edit_menu);
+ info->edit_menu = NULL;
}
- g_signal_handlers_disconnect_by_func (info->menu, G_CALLBACK (applet_menu_show), info);
- g_signal_handlers_disconnect_by_func (info->menu, G_CALLBACK (applet_menu_deactivate), info);
+ panel_applet_get_edit_menu (info);
+}
- g_object_unref (info->menu);
- info->menu = panel_applet_create_menu (info);
+static void
+panel_applet_recreate_menus (AppletInfo *info)
+{
+ panel_applet_recreate_menu (info);
+ panel_applet_recreate_edit_menu (info);
}
static void
@@ -212,7 +238,7 @@ panel_applet_locked_change_notify (GConfClient *client,
if (info->type == PANEL_OBJECT_APPLET)
panel_applet_frame_sync_menu_state (PANEL_APPLET_FRAME (info->widget));
else
- panel_applet_recreate_menu (info);
+ panel_applet_recreate_edit_menu (info);
}
static void
@@ -476,16 +502,10 @@ add_to_submenus (AppletInfo *info,
g_free(n);
}
-GtkWidget *
-panel_applet_create_menu (AppletInfo *info)
+static GtkWidget *
+panel_applet_create_bare_menu (AppletInfo *info)
{
- GtkWidget *menu;
- GtkWidget *menuitem;
- GList *l;
- PanelWidget *panel_widget;
- gboolean added_anything = FALSE;
-
- panel_widget = panel_applet_get_panel_widget (info);
+ GtkWidget *menu;
menu = g_object_ref_sink (gtk_menu_new ());
@@ -497,6 +517,21 @@ panel_applet_create_menu (AppletInfo *info)
g_signal_connect (menu, "deactivate",
G_CALLBACK (applet_menu_deactivate), info);
+ return menu;
+}
+
+GtkWidget *
+panel_applet_get_menu (AppletInfo *info)
+{
+ GtkWidget *menu;
+ GList *l;
+ gboolean added_anything = FALSE;
+
+ if (info->menu)
+ return info->menu;
+
+ menu = panel_applet_create_bare_menu (info);
+
for (l = info->user_menu; l; l = l->next) {
AppletUserMenu *user_menu = l->data;
@@ -509,73 +544,91 @@ panel_applet_create_menu (AppletInfo *info)
added_anything = TRUE;
}
- if (!panel_lockdown_get_locked_down ()) {
- GtkWidget *image;
- gboolean locked;
- gboolean lockable;
- gboolean movable;
- gboolean removable;
+ if ( ! added_anything) {
+ g_signal_handlers_disconnect_by_func (menu,
+ G_CALLBACK (applet_menu_show), info);
+ g_signal_handlers_disconnect_by_func (menu,
+ G_CALLBACK (applet_menu_deactivate), info);
- lockable = panel_applet_lockable (info);
- movable = panel_applet_can_freely_move (info);
- removable = panel_profile_id_lists_are_writable ();
+ g_object_unref (menu);
+ return NULL;
+ }
- locked = panel_widget_get_applet_locked (panel_widget, info->widget);
+ info->menu = menu;
- if (added_anything) {
- menuitem = gtk_separator_menu_item_new ();
- gtk_menu_shell_append (GTK_MENU_SHELL (menu), menuitem);
- gtk_widget_show (menuitem);
- }
+ return info->menu;
+}
- menuitem = gtk_image_menu_item_new_with_mnemonic (_("_Remove From Panel"));
- image = gtk_image_new_from_stock (GTK_STOCK_REMOVE,
- GTK_ICON_SIZE_MENU);
- gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (menuitem),
- image);
- g_signal_connect (menuitem, "activate",
- G_CALLBACK (applet_remove_callback), info);
- gtk_widget_show (menuitem);
- gtk_menu_shell_append (GTK_MENU_SHELL (menu), menuitem);
- gtk_widget_set_sensitive (menuitem, (!locked || lockable) && removable);
-
- menuitem = gtk_menu_item_new_with_mnemonic (_("_Move"));
- g_signal_connect (menuitem, "activate",
- G_CALLBACK (move_applet_callback), info);
- gtk_widget_show (menuitem);
- gtk_menu_shell_append (GTK_MENU_SHELL (menu), menuitem);
- gtk_widget_set_sensitive (menuitem, !locked && movable);
-
- g_assert (info->move_item == NULL);
-
- info->move_item = menuitem;
- g_object_add_weak_pointer (G_OBJECT (menuitem),
- (gpointer *) &info->move_item);
-
- menuitem = gtk_separator_menu_item_new ();
- gtk_menu_shell_append (GTK_MENU_SHELL (menu), menuitem);
- gtk_widget_show (menuitem);
-
- menuitem = gtk_check_menu_item_new_with_mnemonic (_("Loc_k To Panel"));
- gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (menuitem),
- locked);
- g_signal_connect (menuitem, "toggled",
- G_CALLBACK (panel_applet_lock), info);
- gtk_widget_show (menuitem);
- gtk_menu_shell_append (GTK_MENU_SHELL (menu), menuitem);
- gtk_widget_set_sensitive (menuitem, lockable);
+GtkWidget *
+panel_applet_get_edit_menu (AppletInfo *info)
+{
+ GtkWidget *menu;
+ GtkWidget *menuitem;
+ PanelWidget *panel_widget;
+ GtkWidget *image;
+ gboolean locked;
+ gboolean lockable;
+ gboolean movable;
+ gboolean removable;
- added_anything = TRUE;
- }
+ if (info->edit_menu)
+ return info->edit_menu;
- if ( ! added_anything) {
- g_object_unref (menu);
+ if (panel_lockdown_get_locked_down ())
return NULL;
- }
- return menu;
+ menu = panel_applet_create_bare_menu (info);
+ panel_widget = panel_applet_get_panel_widget (info);
+
+ lockable = panel_applet_lockable (info);
+ movable = panel_applet_can_freely_move (info);
+ removable = panel_profile_id_lists_are_writable ();
+
+ locked = panel_widget_get_applet_locked (panel_widget, info->widget);
+
+ menuitem = gtk_image_menu_item_new_with_mnemonic (_("_Remove From Panel"));
+ image = gtk_image_new_from_stock (GTK_STOCK_REMOVE,
+ GTK_ICON_SIZE_MENU);
+ gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (menuitem),
+ image);
+ g_signal_connect (menuitem, "activate",
+ G_CALLBACK (applet_remove_callback), info);
+ gtk_widget_show (menuitem);
+ gtk_menu_shell_append (GTK_MENU_SHELL (menu), menuitem);
+ gtk_widget_set_sensitive (menuitem, (!locked || lockable) && removable);
+
+ menuitem = gtk_menu_item_new_with_mnemonic (_("_Move"));
+ g_signal_connect (menuitem, "activate",
+ G_CALLBACK (move_applet_callback), info);
+ gtk_widget_show (menuitem);
+ gtk_menu_shell_append (GTK_MENU_SHELL (menu), menuitem);
+ gtk_widget_set_sensitive (menuitem, !locked && movable);
+
+ g_assert (info->move_item == NULL);
+
+ info->move_item = menuitem;
+ g_object_add_weak_pointer (G_OBJECT (menuitem),
+ (gpointer *) &info->move_item);
+
+ menuitem = gtk_separator_menu_item_new ();
+ gtk_menu_shell_append (GTK_MENU_SHELL (menu), menuitem);
+ gtk_widget_show (menuitem);
+
+ menuitem = gtk_check_menu_item_new_with_mnemonic (_("Loc_k To Panel"));
+ gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (menuitem),
+ locked);
+ g_signal_connect (menuitem, "toggled",
+ G_CALLBACK (panel_applet_lock), info);
+ gtk_widget_show (menuitem);
+ gtk_menu_shell_append (GTK_MENU_SHELL (menu), menuitem);
+ gtk_widget_set_sensitive (menuitem, lockable);
+
+ info->edit_menu = menu;
+
+ return info->edit_menu;
}
+
void
panel_applet_menu_set_recurse (GtkMenu *menu,
const gchar *key,
@@ -672,31 +725,29 @@ panel_applet_position_menu (GtkMenu *menu,
static void
applet_show_menu (AppletInfo *info,
+ GtkWidget *menu,
GdkEventButton *event)
{
PanelWidget *panel_widget;
g_return_if_fail (info != NULL);
- panel_widget = panel_applet_get_panel_widget (info);
-
- if (info->menu == NULL)
- info->menu = panel_applet_create_menu (info);
-
- if (info->menu == NULL)
+ if (menu == NULL)
return;
- panel_applet_menu_set_recurse (GTK_MENU (info->menu),
+ panel_widget = panel_applet_get_panel_widget (info);
+
+ panel_applet_menu_set_recurse (GTK_MENU (menu),
"menu_panel",
panel_widget);
- gtk_menu_set_screen (GTK_MENU (info->menu),
+ gtk_menu_set_screen (GTK_MENU (menu),
gtk_window_get_screen (GTK_WINDOW (panel_widget->toplevel)));
- if (!gtk_widget_get_realized (info->menu))
- gtk_widget_show (info->menu);
+ if (!gtk_widget_get_realized (menu))
+ gtk_widget_show (menu);
- gtk_menu_popup (GTK_MENU (info->menu),
+ gtk_menu_popup (GTK_MENU (menu),
NULL,
NULL,
(GtkMenuPositionFunc) panel_applet_position_menu,
@@ -706,42 +757,95 @@ applet_show_menu (AppletInfo *info,
}
static gboolean
-applet_do_popup_menu (GtkWidget *widget,
- GdkEventButton *event,
- AppletInfo *info)
+applet_must_skip_menu (AppletInfo *info)
{
if (panel_applet_is_in_drag ())
- return FALSE;
+ return TRUE;
if (info->type == PANEL_OBJECT_APPLET)
- return FALSE;
-
- applet_show_menu (info, event);
+ return TRUE;
- return TRUE;
+ return FALSE;
}
static gboolean
-applet_popup_menu (GtkWidget *widget,
- AppletInfo *info)
+applet_button_press (GtkWidget *widget,
+ GdkEventButton *event,
+ AppletInfo *info)
{
- GdkEventButton event;
+ guint modifiers;
+
+ if (event->button != 3)
+ return FALSE;
- event.button = 3;
- event.time = GDK_CURRENT_TIME;
+ if (applet_must_skip_menu (info))
+ return FALSE;
+
+ modifiers = event->state & GDK_MODIFIER_MASK;
+
+ if (modifiers == panel_bindings_get_mouse_button_modifier_keymask ())
+ applet_show_menu (info, panel_applet_get_edit_menu (info), event);
+ else
+ applet_show_menu (info, panel_applet_get_menu (info), event);
- return applet_do_popup_menu (widget, &event, info);
+ return TRUE;
}
static gboolean
-applet_button_press (GtkWidget *widget,
- GdkEventButton *event,
- AppletInfo *info)
+applet_key_press (GtkWidget *widget,
+ GdkEventKey *event,
+ AppletInfo *info)
{
- if (event->button == 3)
- return applet_do_popup_menu (widget, event, info);
+ GdkEventButton eventbutton;
+ GtkBindingSet *binding_set;
+ GtkBindingEntry *binding_entry;
+ gboolean is_popup = FALSE;
+ gboolean is_edit_popup = FALSE;
- return FALSE;
+ if (applet_must_skip_menu (info))
+ return FALSE;
+
+ eventbutton.button = 3;
+ eventbutton.time = event->time;
+
+ /* We're not connecting to the popup-menu signal since we want to be
+ * able to deal with two cases:
+ * - exact keybinding of popup-menu => we open the context menu
+ * - keybinding of popup-menu + modifier from metacity => we open menu
+ * to "edit"
+ */
+ binding_set = gtk_binding_set_by_class (g_type_class_peek (GTK_TYPE_WIDGET));
+
+ 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, "popup-menu") == 0 ||
+ g_strcmp0 (binding_signal->signal_name, "popup_menu") == 0) {
+ if (binding_entry->keyval != event->keyval)
+ break;
+
+ is_popup = (event->state & GDK_MODIFIER_MASK) == binding_entry->modifiers;
+ is_edit_popup = (event->state & GDK_MODIFIER_MASK) == (panel_bindings_get_mouse_button_modifier_keymask ()|binding_entry->modifiers);
+ break;
+ }
+ }
+
+ if (is_popup || is_edit_popup)
+ break;
+ }
+
+ if (is_popup)
+ applet_show_menu (info, panel_applet_get_menu (info), &eventbutton);
+
+ if (is_edit_popup)
+ applet_show_menu (info, panel_applet_get_edit_menu (info), &eventbutton);
+
+ return (is_popup || is_edit_popup);
}
static void
@@ -775,16 +879,27 @@ panel_applet_destroy (GtkWidget *widget,
}
if (info->type != PANEL_OBJECT_APPLET)
- panel_lockdown_notify_remove (G_CALLBACK (panel_applet_recreate_menu),
+ panel_lockdown_notify_remove (G_CALLBACK (panel_applet_recreate_menus),
info);
if (info->menu) {
- g_signal_handlers_disconnect_by_func (info->menu, G_CALLBACK (applet_menu_show), info);
- g_signal_handlers_disconnect_by_func (info->menu, G_CALLBACK (applet_menu_deactivate), info);
+ g_signal_handlers_disconnect_by_func (info->menu,
+ G_CALLBACK (applet_menu_show), info);
+ g_signal_handlers_disconnect_by_func (info->menu,
+ G_CALLBACK (applet_menu_deactivate), info);
g_object_unref (info->menu);
}
info->menu = NULL;
+ if (info->edit_menu) {
+ g_signal_handlers_disconnect_by_func (info->edit_menu,
+ G_CALLBACK (applet_menu_show), info);
+ g_signal_handlers_disconnect_by_func (info->edit_menu,
+ G_CALLBACK (applet_menu_deactivate), info);
+ g_object_unref (info->menu);
+ }
+ info->edit_menu = NULL;
+
if (info->data_destroy)
info->data_destroy (info->data);
info->data = NULL;
@@ -1307,6 +1422,7 @@ panel_applet_register (GtkWidget *applet,
info->type = type;
info->widget = applet;
info->menu = NULL;
+ info->edit_menu = NULL;
info->data = data;
info->data_destroy = data_destroy;
info->user_menu = NULL;
@@ -1316,7 +1432,7 @@ panel_applet_register (GtkWidget *applet,
g_object_set_data (G_OBJECT (applet), "applet_info", info);
if (type != PANEL_OBJECT_APPLET)
- panel_lockdown_notify_add (G_CALLBACK (panel_applet_recreate_menu),
+ panel_lockdown_notify_add (G_CALLBACK (panel_applet_recreate_menus),
info);
key = panel_gconf_full_key ((type == PANEL_OBJECT_APPLET) ?
@@ -1368,8 +1484,8 @@ panel_applet_register (GtkWidget *applet,
G_CALLBACK (applet_button_press),
info);
- g_signal_connect (applet, "popup_menu",
- G_CALLBACK (applet_popup_menu),
+ g_signal_connect (applet, "key_press_event",
+ G_CALLBACK (applet_key_press),
info);
}
diff --git a/gnome-panel/applet.h b/gnome-panel/applet.h
index f60d9a9..5edd598 100644
--- a/gnome-panel/applet.h
+++ b/gnome-panel/applet.h
@@ -19,6 +19,7 @@ typedef struct {
GtkWidget *widget;
GtkWidget *menu;
+ GtkWidget *edit_menu;
GtkWidget *move_item;
GList *user_menu;
@@ -97,7 +98,8 @@ gboolean panel_applet_can_freely_move (AppletInfo *applet);
/* True if the locked flag is writable */
gboolean panel_applet_lockable (AppletInfo *applet);
-GtkWidget *panel_applet_create_menu (AppletInfo *info);
+GtkWidget *panel_applet_get_menu (AppletInfo *info);
+GtkWidget *panel_applet_get_edit_menu (AppletInfo *info);
void panel_applet_menu_set_recurse (GtkMenu *menu,
const gchar *key,
diff --git a/gnome-panel/panel-context-menu.c b/gnome-panel/panel-context-menu.c
index f25bba8..b9f8f5f 100644
--- a/gnome-panel/panel-context-menu.c
+++ b/gnome-panel/panel-context-menu.c
@@ -184,11 +184,7 @@ panel_context_menu_create (PanelWidget *panel)
g_assert (pointer != NULL);
info = (AppletInfo *) pointer;
- if (info->menu == NULL) {
- info->menu = panel_applet_create_menu (info);
- }
-
- return info->menu;
+ return panel_applet_get_menu (info);
}
if (panel_lockdown_get_locked_down ())
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]