diff options
| author | Marco Trevisan (Treviño) <mail@3v1n0.net> | 2014-01-24 20:00:03 +0100 |
|---|---|---|
| committer | Marco Trevisan (Treviño) <mail@3v1n0.net> | 2014-01-24 20:00:03 +0100 |
| commit | a736595e4c8e7adbf655c3096ab1a1ec9a48fb60 (patch) | |
| tree | 483fc3334dc7cf06238b2812679182be9549007a /services | |
| parent | 59e2f35230a9ad06116741a56978ac5bbc43e5fb (diff) | |
PanelService: add ShowEntries method to show a list of entries in a drop-down menu
(bzr r3566.5.262)
Diffstat (limited to 'services')
| -rw-r--r-- | services/panel-main.c | 20 | ||||
| -rw-r--r-- | services/panel-service.c | 130 | ||||
| -rw-r--r-- | services/panel-service.h | 6 |
3 files changed, 147 insertions, 9 deletions
diff --git a/services/panel-main.c b/services/panel-main.c index a43304e66..590055dab 100644 --- a/services/panel-main.c +++ b/services/panel-main.c @@ -55,6 +55,13 @@ static const gchar introspection_xml[] = " <arg type='u' name='button' direction='in'/>" " </method>" "" + " <method name='ShowEntries'>" + " <arg type='as' name='entries_ids' direction='in'/>" + " <arg type='u' name='xid' direction='in'/>" + " <arg type='i' name='x' direction='in'/>" + " <arg type='i' name='y' direction='in'/>" + " </method>" + "" " <method name='ShowAppMenu'>" " <arg type='u' name='xid' direction='in'/>" " <arg type='i' name='x' direction='in'/>" @@ -183,6 +190,19 @@ handle_method_call (GDBusConnection *connection, g_dbus_method_invocation_return_value (invocation, NULL); g_free (entry_id); } + else if (g_strcmp0 (method_name, "ShowEntries") == 0) + { + guint32 xid; + gchar **entries; + gint32 x; + gint32 y; + g_variant_get (parameters, "(^asuii)", &entries, &xid, &x, &y); + + panel_service_show_entries (service, (const gchar**) entries, xid, x, y); + + g_dbus_method_invocation_return_value (invocation, NULL); + g_strfreev (entries); + } else if (g_strcmp0 (method_name, "ShowAppMenu") == 0) { guint32 xid; diff --git a/services/panel-service.c b/services/panel-service.c index 22bc2a311..3a01f3d75 100644 --- a/services/panel-service.c +++ b/services/panel-service.c @@ -62,6 +62,7 @@ struct _PanelServicePrivate gint32 timeouts[N_TIMEOUT_SLOTS]; + IndicatorObjectEntry *first_entry; IndicatorObjectEntry *last_entry; GtkWidget *menubar; GtkWidget *offscreen_window; @@ -1781,7 +1782,6 @@ indicator_entry_compare_func (gpointer* v1, gpointer* v2) static void activate_next_prev_menu (PanelService *self, - IndicatorObject *object, IndicatorObjectEntry *entry, GtkMenuDirectionType direction) { @@ -1869,7 +1869,7 @@ on_active_menu_move_current (GtkMenu *menu, PanelService *self) { PanelServicePrivate *priv; - IndicatorObject *object; + IndicatorObjectEntry *entry; g_return_if_fail (PANEL_IS_SERVICE (self)); priv = self->priv; @@ -1893,21 +1893,21 @@ on_active_menu_move_current (GtkMenu *menu, { /* Skip direction due to there being a submenu, * and we don't want to inhibit going into that */ + g_list_free (children); return; } } g_list_free (children); - } - /* Find the next/prev indicator */ - object = get_entry_parent_indicator(priv->last_entry); - if (object == NULL) + entry = priv->last_entry; + } + else { - g_warning ("Unable to find IndicatorObject for entry"); - return; + entry = (priv->first_entry) ? priv->first_entry : priv->last_entry; } - activate_next_prev_menu (self, object, priv->last_entry, direction); + /* Find the next/prev indicator */ + activate_next_prev_menu (self, entry, direction); } static void @@ -2062,6 +2062,118 @@ panel_service_show_entry (PanelService *self, panel_service_show_entry_common (self, object, entry, xid, x, y, button); } +static void +fake_entry_destroy (GtkWidget *menu, IndicatorObjectEntry *fake_entry) +{ + PanelService *self = panel_service_get_default(); + + self->priv->first_entry = NULL; + g_free (fake_entry); +} + +void +panel_service_show_entries (PanelService *self, + const gchar **entries, + guint32 xid, + gint32 x, + gint32 y) +{ + gint i; + IndicatorObject *object; + IndicatorObjectEntry *entry, *fake_entry, *first_entry, *last_entry; + GtkWidget *menu; + + g_return_if_fail (PANEL_IS_SERVICE (self)); + g_return_if_fail (entries && entries[0]); + + object = NULL; + first_entry = NULL; + last_entry = NULL; + menu = gtk_menu_new (); + + for (i = 0; entries[i]; ++i) + { + entry = get_indicator_entry_by_id (self, entries[i]); + + if (!entry) + continue; + + if (!object) + { + object = get_entry_parent_indicator (entry); + + if (!object) + continue; + } + else if (object != get_entry_parent_indicator (entry)) + { + g_error ("Impossible build a menu with entries from different indicators!"); + continue; + } + + GtkWidget *menu_item; + const char *label = NULL; + + if (GTK_IS_LABEL (entry->label)) + label = gtk_label_get_label (entry->label); + + if (GTK_IS_IMAGE (entry->image)) + { + G_GNUC_BEGIN_IGNORE_DEPRECATIONS + if (label) + { + menu_item = gtk_image_menu_item_new_with_mnemonic (label); + } + else + { + menu_item = gtk_image_menu_item_new (); + } + + gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (menu_item), GTK_WIDGET (entry->image)); + gtk_image_menu_item_set_always_show_image (GTK_IMAGE_MENU_ITEM (menu_item), TRUE); + G_GNUC_END_IGNORE_DEPRECATIONS + } + else if (label) + { + menu_item = gtk_menu_item_new_with_mnemonic (label); + } + else + { + continue; + } + + gtk_menu_shell_append (GTK_MENU_SHELL (menu), menu_item); + gtk_menu_item_set_submenu (GTK_MENU_ITEM (menu_item), GTK_WIDGET (entry->menu)); + g_signal_connect (menu_item, "activate", G_CALLBACK (menuitem_activated), entry); + gtk_widget_show (menu_item); + + if (!first_entry) + first_entry = entry; + + last_entry = entry; + } + + if (!last_entry) + { + g_warning ("No valid entries to show"); + gtk_widget_destroy (menu); + return; + } + + fake_entry = g_new0 (IndicatorObjectEntry, 1); + fake_entry->parent_object = object; + fake_entry->menu = GTK_MENU (menu); + + g_signal_connect (menu, "deactivate", G_CALLBACK (menu_deactivated), NULL); + g_signal_connect (menu, "destroy", G_CALLBACK (fake_entry_destroy), fake_entry); + g_signal_connect (menu, "destroy", G_CALLBACK (gtk_widget_destroyed), &self->priv->last_menu); + + panel_service_show_entry_common (self, object, fake_entry, xid, x, y, 1); + self->priv->first_entry = first_entry; + self->priv->last_entry = last_entry; +} + + void panel_service_show_app_menu (PanelService *self, guint32 xid, gint32 x, gint32 y) { diff --git a/services/panel-service.h b/services/panel-service.h index 06d5c35f0..ad8f63383 100644 --- a/services/panel-service.h +++ b/services/panel-service.h @@ -101,6 +101,12 @@ void panel_service_show_entry (PanelService *self, gint32 y, guint32 button); +void panel_service_show_entries (PanelService *self, + const gchar **entries, + guint32 xid, + gint32 x, + gint32 y); + void panel_service_show_app_menu (PanelService *self, guint32 xid, gint32 x, |
