aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTed Gould <ted@gould.cx>2011-07-22 13:58:39 -0500
committerTed Gould <ted@gould.cx>2011-07-22 13:58:39 -0500
commit5c4ee09c774dccfb8af7bf89b1709c93d3db2769 (patch)
treed5915ea399ae5d7731b07e23725c8fe6cba070a4
parentbf95161bb260f193fbb8508f5f25c56080498a31 (diff)
parentf551fdbd371ee30b8be507f9471b252ab84504c9 (diff)
downloadlibayatana-appindicator-5c4ee09c774dccfb8af7bf89b1709c93d3db2769.tar.gz
libayatana-appindicator-5c4ee09c774dccfb8af7bf89b1709c93d3db2769.tar.bz2
libayatana-appindicator-5c4ee09c774dccfb8af7bf89b1709c93d3db2769.zip
Adding in support for the secondary activate (middle click)
-rw-r--r--bindings/mono/examples/IndicatorExample.cs9
-rw-r--r--bindings/vala/examples/indicator-example.vala5
-rw-r--r--docs/reference/libappindicator-sections.txt2
-rw-r--r--example/simple-client-vala.vala13
-rw-r--r--example/simple-client.c103
-rw-r--r--src/app-indicator.c153
-rw-r--r--src/app-indicator.h3
-rw-r--r--src/application-service-marshal.list1
-rw-r--r--src/notification-item.xml7
9 files changed, 235 insertions, 61 deletions
diff --git a/bindings/mono/examples/IndicatorExample.cs b/bindings/mono/examples/IndicatorExample.cs
index c18a665..7413c54 100644
--- a/bindings/mono/examples/IndicatorExample.cs
+++ b/bindings/mono/examples/IndicatorExample.cs
@@ -41,12 +41,19 @@ public class IndicatorExample
indicator.Status = Status.Attention;
Menu menu = new Menu ();
- menu.Append (new MenuItem ("Foo"));
+ var foo = new MenuItem ("Foo");
+ menu.Append (foo);
+ foo.Activated += delegate {
+ System.Console.WriteLine ("Foo item has been activated");
+ };
+
menu.Append (new MenuItem ("Bar"));
indicator.Menu = menu;
indicator.Menu.ShowAll ();
+ indicator.SecondaryActivateTarget = foo;
+
win.ShowAll ();
Application.Run ();
diff --git a/bindings/vala/examples/indicator-example.vala b/bindings/vala/examples/indicator-example.vala
index 621c962..7bb1d7d 100644
--- a/bindings/vala/examples/indicator-example.vala
+++ b/bindings/vala/examples/indicator-example.vala
@@ -47,14 +47,15 @@ public class IndicatorExample {
item.show();
menu.append(item);
- item = new MenuItem.with_label("Bar");
+ var bar = item = new MenuItem.with_label("Bar");
item.show();
item.activate.connect(() => {
- indicator.set_status(IndicatorStatus.ATTENTION);
+ indicator.set_status(IndicatorStatus.ACTIVE);
});
menu.append(item);
indicator.set_menu(menu);
+ indicator.set_secondary_activate_target(bar);
win.show_all();
diff --git a/docs/reference/libappindicator-sections.txt b/docs/reference/libappindicator-sections.txt
index da05f40..6f09364 100644
--- a/docs/reference/libappindicator-sections.txt
+++ b/docs/reference/libappindicator-sections.txt
@@ -31,6 +31,7 @@ app_indicator_set_icon_full
app_indicator_set_icon_theme_path
app_indicator_set_label
app_indicator_set_ordering_index
+app_indicator_set_secondary_activate_target
app_indicator_get_id
app_indicator_get_category
app_indicator_get_status
@@ -43,6 +44,7 @@ app_indicator_get_menu
app_indicator_get_label
app_indicator_get_label_guide
app_indicator_get_ordering_index
+app_indicator_get_secondary_activate_target
app_indicator_build_menu_from_desktop
</SECTION>
diff --git a/example/simple-client-vala.vala b/example/simple-client-vala.vala
index 61e0c2f..8d661ce 100644
--- a/example/simple-client-vala.vala
+++ b/example/simple-client-vala.vala
@@ -72,6 +72,17 @@ class SimpleClient {
menu.append(mi);
mi.activate.connect(() => { print("Sub3\n"); });
+ mi = new MenuItem.with_label("Toggle Attention");
+ menu.append(mi);
+ mi.activate.connect(() => {
+ if (ci.get_status() == IndicatorStatus.ATTENTION)
+ ci.set_status(IndicatorStatus.ACTIVE);
+ else
+ ci.set_status(IndicatorStatus.ATTENTION);
+ });
+
+ ci.set_secondary_activate_target(mi);
+
menu.show_all();
item.set_submenu(menu);
}
@@ -109,7 +120,7 @@ class SimpleClient {
chk.show();
var radio = new RadioMenuItem.with_label(new SList<RadioMenuItem>(), "2");
- radio.activate.connect(() => { print("2\n"); });
+ radio.activate.connect(() => { print("2\n"); });
menu.append(radio);
radio.show();
diff --git a/example/simple-client.c b/example/simple-client.c
index 9e63e14..dcee81b 100644
--- a/example/simple-client.c
+++ b/example/simple-client.c
@@ -31,46 +31,46 @@ static gboolean can_haz_label = TRUE;
static void
label_toggle_cb (GtkWidget * widget, gpointer data)
{
- can_haz_label = !can_haz_label;
+ can_haz_label = !can_haz_label;
- if (can_haz_label) {
- gtk_menu_item_set_label(GTK_MENU_ITEM(widget), "Hide label");
- } else {
- gtk_menu_item_set_label(GTK_MENU_ITEM(widget), "Show label");
- }
+ if (can_haz_label) {
+ gtk_menu_item_set_label(GTK_MENU_ITEM(widget), "Hide label");
+ } else {
+ gtk_menu_item_set_label(GTK_MENU_ITEM(widget), "Show label");
+ }
- return;
+ return;
}
static void
activate_clicked_cb (GtkWidget *widget, gpointer data)
{
- AppIndicator * ci = APP_INDICATOR(data);
-
- if (active) {
- app_indicator_set_status (ci, APP_INDICATOR_STATUS_ATTENTION);
- gtk_menu_item_set_label(GTK_MENU_ITEM(widget), "I'm okay now");
- active = FALSE;
- } else {
- app_indicator_set_status (ci, APP_INDICATOR_STATUS_ACTIVE);
- gtk_menu_item_set_label(GTK_MENU_ITEM(widget), "Get Attention");
- active = TRUE;
- }
+ AppIndicator * ci = APP_INDICATOR(data);
+
+ if (active) {
+ app_indicator_set_status (ci, APP_INDICATOR_STATUS_ATTENTION);
+ gtk_menu_item_set_label(GTK_MENU_ITEM(widget), "I'm okay now");
+ active = FALSE;
+ } else {
+ app_indicator_set_status (ci, APP_INDICATOR_STATUS_ACTIVE);
+ gtk_menu_item_set_label(GTK_MENU_ITEM(widget), "Get Attention");
+ active = TRUE;
+ }
}
static void
local_icon_toggle_cb (GtkWidget *widget, gpointer data)
{
- AppIndicator * ci = APP_INDICATOR(data);
+ AppIndicator * ci = APP_INDICATOR(data);
- if (gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(widget))) {
- app_indicator_set_icon_full(ci, LOCAL_ICON, "Local Icon");
- } else {
- app_indicator_set_icon_full(ci, "indicator-messages", "System Icon");
- }
+ if (gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(widget))) {
+ app_indicator_set_icon_full(ci, LOCAL_ICON, "Local Icon");
+ } else {
+ app_indicator_set_icon_full(ci, "indicator-messages", "System Icon");
+ }
- return;
+ return;
}
static void
@@ -98,9 +98,9 @@ image_clicked_cb (GtkWidget *widget, gpointer data)
}
static void
-scroll_event_cb (AppIndicator * ci, gint delta, guint direction)
+scroll_event_cb (AppIndicator * ci, gint delta, guint direction, gpointer data)
{
- g_print("Got scroll event! delta: %d, direction: %d\n", delta, direction);
+ g_print("Got scroll event! delta: %d, direction: %d\n", delta, direction);
}
static void
@@ -138,15 +138,15 @@ guint percentage = 0;
static gboolean
percent_change (gpointer user_data)
{
- percentage = (percentage + 1) % 100;
- if (can_haz_label) {
- gchar * percentstr = g_strdup_printf("%d%%", percentage + 1);
- app_indicator_set_label (APP_INDICATOR(user_data), percentstr, "100%");
- g_free(percentstr);
- } else {
- app_indicator_set_label (APP_INDICATOR(user_data), NULL, NULL);
- }
- return TRUE;
+ percentage = (percentage + 1) % 100;
+ if (can_haz_label) {
+ gchar * percentstr = g_strdup_printf("%d%%", percentage + 1);
+ app_indicator_set_label (APP_INDICATOR(user_data), percentstr, "100%");
+ g_free(percentstr);
+ } else {
+ app_indicator_set_label (APP_INDICATOR(user_data), NULL, NULL);
+ }
+ return TRUE;
}
int
@@ -161,17 +161,17 @@ main (int argc, char ** argv)
"indicator-messages",
APP_INDICATOR_CATEGORY_APPLICATION_STATUS);
- g_assert (IS_APP_INDICATOR (ci));
+ g_assert (IS_APP_INDICATOR (ci));
g_assert (G_IS_OBJECT (ci));
- app_indicator_set_status (ci, APP_INDICATOR_STATUS_ACTIVE);
- app_indicator_set_attention_icon_full(ci, "indicator-messages-new", "System Messages Icon Highlighted");
- app_indicator_set_label (ci, "1%", "100%");
+ app_indicator_set_status (ci, APP_INDICATOR_STATUS_ACTIVE);
+ app_indicator_set_attention_icon_full(ci, "indicator-messages-new", "System Messages Icon Highlighted");
+ app_indicator_set_label (ci, "1%", "100%");
- g_signal_connect (ci, "scroll-event",
+ g_signal_connect (ci, "scroll-event",
G_CALLBACK (scroll_event_cb), NULL);
- g_timeout_add_seconds(1, percent_change, ci);
+ g_timeout_add_seconds(1, percent_change, ci);
menu = gtk_menu_new ();
GtkWidget *item = gtk_check_menu_item_new_with_label ("1");
@@ -195,37 +195,38 @@ main (int argc, char ** argv)
g_signal_connect (toggle_item, "activate",
G_CALLBACK (toggle_sensitivity_cb), item);
gtk_menu_shell_append (GTK_MENU_SHELL (menu), toggle_item);
- gtk_widget_show(toggle_item);
+ gtk_widget_show(toggle_item);
item = gtk_image_menu_item_new_from_stock (GTK_STOCK_NEW, NULL);
g_signal_connect (item, "activate",
G_CALLBACK (image_clicked_cb), NULL);
gtk_menu_shell_append (GTK_MENU_SHELL (menu), item);
- gtk_widget_show(item);
+ gtk_widget_show(item);
item = gtk_menu_item_new_with_label ("Get Attention");
g_signal_connect (item, "activate",
G_CALLBACK (activate_clicked_cb), ci);
gtk_menu_shell_append (GTK_MENU_SHELL (menu), item);
- gtk_widget_show(item);
+ gtk_widget_show(item);
+ app_indicator_set_secondary_activate_target(ci, item);
item = gtk_menu_item_new_with_label ("Show label");
- label_toggle_cb(item, ci);
+ label_toggle_cb(item, ci);
g_signal_connect (item, "activate",
G_CALLBACK (label_toggle_cb), ci);
gtk_menu_shell_append (GTK_MENU_SHELL (menu), item);
- gtk_widget_show(item);
+ gtk_widget_show(item);
item = gtk_check_menu_item_new_with_label ("Set Local Icon");
g_signal_connect (item, "activate",
G_CALLBACK (local_icon_toggle_cb), ci);
gtk_menu_shell_append (GTK_MENU_SHELL (menu), item);
- gtk_widget_show(item);
+ gtk_widget_show(item);
app_indicator_set_menu (ci, GTK_MENU (menu));
- mainloop = g_main_loop_new(NULL, FALSE);
- g_main_loop_run(mainloop);
+ mainloop = g_main_loop_new(NULL, FALSE);
+ g_main_loop_run(mainloop);
- return 0;
+ return 0;
}
diff --git a/src/app-indicator.c b/src/app-indicator.c
index bc08eea..bdc4ea9 100644
--- a/src/app-indicator.c
+++ b/src/app-indicator.c
@@ -77,6 +77,8 @@ struct _AppIndicatorPrivate {
gchar *icon_theme_path;
DbusmenuServer *menuservice;
GtkWidget *menu;
+ GtkWidget *sec_activate_target;
+ gboolean sec_activate_enabled;
guint32 ordering_index;
gchar * label;
gchar * label_guide;
@@ -104,8 +106,8 @@ enum {
NEW_STATUS,
NEW_LABEL,
CONNECTION_CHANGED,
- NEW_ICON_THEME_PATH,
- SCROLL_EVENT,
+ NEW_ICON_THEME_PATH,
+ SCROLL_EVENT,
LAST_SIGNAL
};
@@ -178,6 +180,7 @@ static gboolean fallback_timer_expire (gpointer data);
static GtkStatusIcon * fallback (AppIndicator * self);
static void status_icon_status_wrapper (AppIndicator * self, const gchar * status, gpointer data);
static gboolean scroll_event_wrapper(GtkWidget *status_icon, GdkEventScroll *event, gpointer user_data);
+static gboolean middle_click_wrapper(GtkWidget *status_icon, GdkEventButton *event, gpointer user_data);
static void status_icon_changes (AppIndicator * self, gpointer data);
static void status_icon_activate (GtkStatusIcon * icon, gpointer data);
static void status_icon_menu_activate (GtkStatusIcon *status_icon, guint button, guint activate_time, gpointer user_data);
@@ -185,6 +188,7 @@ static void unfallback (AppIndicator * self, GtkStatusIcon * status_icon);
static gchar * append_panel_icon_suffix (const gchar * icon_name);
static void watcher_owner_changed (GObject * obj, GParamSpec * pspec, gpointer user_data);
static void theme_changed_cb (GtkIconTheme * theme, gpointer user_data);
+static void sec_activate_target_parent_changed(GtkWidget *menuitem, GtkWidget *old_parent, gpointer user_data);
static GVariant * bus_get_prop (GDBusConnection * connection, const gchar * sender, const gchar * path, const gchar * interface, const gchar * property, GError ** error, gpointer user_data);
static void bus_method_call (GDBusConnection * connection, const gchar * sender, const gchar * path, const gchar * interface, const gchar * method, GVariant * params, GDBusMethodInvocation * invocation, gpointer user_data);
static void bus_creation (GObject * obj, GAsyncResult * res, gpointer user_data);
@@ -508,8 +512,7 @@ app_indicator_class_init (AppIndicatorClass *klass)
@arg1: How many steps the scroll wheel has taken
@arg2: (type Gdk.ScrollDirection) Which direction the wheel went in
- Signaled when there is a new icon set for the
- object.
+ Signaled when the #AppIndicator receives a scroll event.
*/
signals[SCROLL_EVENT] = g_signal_new (APP_INDICATOR_SIGNAL_SCROLL_EVENT,
G_TYPE_FROM_CLASS(klass),
@@ -588,6 +591,9 @@ app_indicator_init (AppIndicator *self)
priv->shorties = NULL;
+ priv->sec_activate_target = NULL;
+ priv->sec_activate_enabled = FALSE;
+
/* Start getting the session bus */
g_object_ref(self); /* ref for the bus creation callback */
g_bus_get(G_BUS_TYPE_SESSION, NULL, bus_creation, self);
@@ -663,6 +669,12 @@ app_indicator_dispose (GObject *object)
priv->connection = NULL;
}
+ if (priv->sec_activate_target != NULL) {
+ g_signal_handlers_disconnect_by_func (priv->sec_activate_target, sec_activate_target_parent_changed, self);
+ g_object_unref(G_OBJECT(priv->sec_activate_target));
+ priv->sec_activate_target = NULL;
+ }
+
g_signal_handlers_disconnect_by_func(gtk_icon_theme_get_default(), G_CALLBACK(theme_changed_cb), self);
G_OBJECT_CLASS (app_indicator_parent_class)->dispose (object);
@@ -990,6 +1002,7 @@ bus_method_call (GDBusConnection * connection, const gchar * sender,
g_return_if_fail(IS_APP_INDICATOR(user_data));
AppIndicator * app = APP_INDICATOR(user_data);
+ AppIndicatorPrivate * priv = app->priv;
GVariant * retval = NULL;
if (g_strcmp0(method, "Scroll") == 0) {
@@ -1011,6 +1024,16 @@ bus_method_call (GDBusConnection * connection, const gchar * sender,
delta = ABS(delta);
g_signal_emit(app, signals[SCROLL_EVENT], 0, delta, direction);
+ } else if (g_strcmp0(method, "SecondaryActivate") == 0 ||
+ g_strcmp0(method, "XAyatanaSecondaryActivate") == 0) {
+ GtkWidget *menuitem = priv->sec_activate_target;
+
+ if (priv->sec_activate_enabled && menuitem &&
+ gtk_widget_get_visible (menuitem) &&
+ gtk_widget_get_sensitive (menuitem))
+ {
+ gtk_widget_activate (menuitem);
+ }
} else {
g_warning("Calling method '%s' on the app-indicator and it's unknown", method);
}
@@ -1442,6 +1465,7 @@ fallback (AppIndicator * self)
g_signal_connect(G_OBJECT(icon), "activate", G_CALLBACK(status_icon_activate), self);
g_signal_connect(G_OBJECT(icon), "popup-menu", G_CALLBACK(status_icon_menu_activate), self);
g_signal_connect(G_OBJECT(icon), "scroll-event", G_CALLBACK(scroll_event_wrapper), self);
+ g_signal_connect(G_OBJECT(icon), "button-release-event", G_CALLBACK(middle_click_wrapper), self);
return icon;
}
@@ -1457,12 +1481,39 @@ status_icon_status_wrapper (AppIndicator * self, const gchar * status, gpointer
/* A wrapper for redirecting the scroll events to the app-indicator from status
icon widget. */
static gboolean
-scroll_event_wrapper(GtkWidget *status_icon, GdkEventScroll *event, gpointer data)
+scroll_event_wrapper (GtkWidget *status_icon, GdkEventScroll *event, gpointer data)
{
g_return_val_if_fail(IS_APP_INDICATOR(data), FALSE);
AppIndicator * app = APP_INDICATOR(data);
g_signal_emit(app, signals[SCROLL_EVENT], 0, 1, event->direction);
+ return TRUE;
+}
+
+static gboolean
+middle_click_wrapper (GtkWidget *status_icon, GdkEventButton *event, gpointer data)
+{
+ g_return_val_if_fail(IS_APP_INDICATOR(data), FALSE);
+ AppIndicator * app = APP_INDICATOR(data);
+ AppIndicatorPrivate *priv = app->priv;
+
+ if (event->button == 2 && event->type == GDK_BUTTON_RELEASE) {
+ GtkAllocation alloc;
+ gint px = event->x;
+ gint py = event->y;
+ gtk_widget_get_allocation (status_icon, &alloc);
+ GtkWidget *menuitem = priv->sec_activate_target;
+
+ if (px >= 0 && px < alloc.width && py >= 0 && py < alloc.height &&
+ priv->sec_activate_enabled && menuitem &&
+ gtk_widget_get_visible (menuitem) &&
+ gtk_widget_get_sensitive (menuitem))
+ {
+ gtk_widget_activate (menuitem);
+ return TRUE;
+ }
+ }
+
return FALSE;
}
@@ -1535,6 +1586,7 @@ unfallback (AppIndicator * self, GtkStatusIcon * status_icon)
g_signal_handlers_disconnect_by_func(G_OBJECT(self), status_icon_status_wrapper, status_icon);
g_signal_handlers_disconnect_by_func(G_OBJECT(self), status_icon_changes, status_icon);
g_signal_handlers_disconnect_by_func(G_OBJECT(self), scroll_event_wrapper, status_icon);
+ g_signal_handlers_disconnect_by_func(G_OBJECT(self), middle_click_wrapper, status_icon);
gtk_status_icon_set_visible(status_icon, FALSE);
g_object_unref(G_OBJECT(status_icon));
return;
@@ -1557,6 +1609,38 @@ append_panel_icon_suffix (const gchar *icon_name)
return long_name;
}
+static gboolean
+widget_is_menu_child(AppIndicator * self, GtkWidget *child)
+{
+ g_return_val_if_fail(IS_APP_INDICATOR(self), FALSE);
+
+ if (!self->priv->menu) return FALSE;
+ if (!child) return FALSE;
+
+ GtkWidget *parent;
+
+ while ((parent = gtk_widget_get_parent(child))) {
+ if (parent == self->priv->menu)
+ return TRUE;
+
+ if (GTK_IS_MENU(parent))
+ child = gtk_menu_get_attach_widget(GTK_MENU(parent));
+ else
+ child = parent;
+ }
+
+ return FALSE;
+}
+
+static void
+sec_activate_target_parent_changed(GtkWidget *menuitem, GtkWidget *old_parent,
+ gpointer data)
+{
+ g_return_if_fail(IS_APP_INDICATOR(data));
+ AppIndicator *self = data;
+ self->priv->sec_activate_enabled = widget_is_menu_child(self, menuitem);
+}
+
/* ************************* */
/* Public Functions */
@@ -1946,6 +2030,8 @@ app_indicator_set_menu (AppIndicator *self, GtkMenu *menu)
setup_dbusmenu (self);
+ priv->sec_activate_enabled = widget_is_menu_child (self, priv->sec_activate_target);
+
check_connect (self);
return;
@@ -1973,6 +2059,45 @@ app_indicator_set_ordering_index (AppIndicator *self, guint32 ordering_index)
}
/**
+ app_indicator_set_secondary_activate_target:
+ @self: The #AppIndicator
+ @menuitem: A #GtkWidget to be activated on secondary activation
+
+ Set the @menuitem to be activated when a secondary activation event (i.e. a
+ middle-click) is emitted over the #AppIndicator icon/label.
+
+ The @menuitem can be also a complex #GtkWidget, but to get activated when
+ a secondary activation occurs in the #Appindicator, it must be a visible and
+ active child (or inner-child) of the #AppIndicator:menu.
+
+ Setting @menuitem to %NULL causes to disable this feature.
+**/
+void
+app_indicator_set_secondary_activate_target (AppIndicator *self, GtkWidget *menuitem)
+{
+ g_return_if_fail (IS_APP_INDICATOR (self));
+ AppIndicatorPrivate *priv = self->priv;
+
+ if (priv->sec_activate_target) {
+ g_signal_handlers_disconnect_by_func (priv->sec_activate_target,
+ sec_activate_target_parent_changed,
+ self);
+ g_object_unref(G_OBJECT(priv->sec_activate_target));
+ priv->sec_activate_target = NULL;
+ }
+
+ if (menuitem == NULL) {
+ return;
+ }
+
+ g_return_if_fail (GTK_IS_WIDGET (menuitem));
+
+ priv->sec_activate_target = g_object_ref(G_OBJECT(menuitem));
+ priv->sec_activate_enabled = widget_is_menu_child(self, menuitem);
+ g_signal_connect(menuitem, "parent-set", G_CALLBACK(sec_activate_target_parent_changed), self);
+}
+
+/**
app_indicator_get_id:
@self: The #AppIndicator object to use
@@ -2107,7 +2232,7 @@ app_indicator_get_attention_icon_desc (AppIndicator *self)
Gets the menu being used for this application indicator.
Wrapper function for property #AppIndicator:menu.
- Return value: (transfer none): A #GtkMenu object or %NULL if one hasn't been set.
+ Return value: (transfer full): A #GtkMenu object or %NULL if one hasn't been set.
*/
GtkMenu *
app_indicator_get_menu (AppIndicator *self)
@@ -2173,6 +2298,22 @@ app_indicator_get_ordering_index (AppIndicator *self)
}
}
+/**
+ app_indicator_get_secondary_activate_target:
+ @self: The #AppIndicator object to use
+
+ Gets the menuitem being called on secondary-activate event.
+
+ Return value: (transfer full): A #GtkWidget object or %NULL if none has been set.
+*/
+GtkWidget *
+app_indicator_get_secondary_activate_target (AppIndicator *self)
+{
+ g_return_val_if_fail (IS_APP_INDICATOR (self), NULL);
+
+ return GTK_WIDGET(self->priv->sec_activate_target);
+}
+
#define APP_INDICATOR_SHORTY_NICK "app-indicator-shorty-nick"
/* Callback when an item from the desktop shortcuts gets
diff --git a/src/app-indicator.h b/src/app-indicator.h
index f96212d..09b7520 100644
--- a/src/app-indicator.h
+++ b/src/app-indicator.h
@@ -284,6 +284,8 @@ void app_indicator_set_icon_theme_path(AppIndicator
const gchar *icon_theme_path);
void app_indicator_set_ordering_index (AppIndicator *self,
guint32 ordering_index);
+void app_indicator_set_secondary_activate_target (AppIndicator *self,
+ GtkWidget *menuitem);
/* Get properties */
const gchar * app_indicator_get_id (AppIndicator *self);
@@ -298,6 +300,7 @@ GtkMenu * app_indicator_get_menu (AppIndic
const gchar * app_indicator_get_label (AppIndicator *self);
const gchar * app_indicator_get_label_guide (AppIndicator *self);
guint32 app_indicator_get_ordering_index (AppIndicator *self);
+GtkWidget * app_indicator_get_secondary_activate_target (AppIndicator *self);
/* Helpers */
void app_indicator_build_menu_from_desktop (AppIndicator * self,
diff --git a/src/application-service-marshal.list b/src/application-service-marshal.list
index 39a55fe..ae3aa6f 100644
--- a/src/application-service-marshal.list
+++ b/src/application-service-marshal.list
@@ -22,3 +22,4 @@ VOID: INT, STRING
VOID: STRING, STRING
VOID: BOOL, STRING, OBJECT
VOID: INT, UINT
+VOID: INT, INT
diff --git a/src/notification-item.xml b/src/notification-item.xml
index bbf77c5..589a438 100644
--- a/src/notification-item.xml
+++ b/src/notification-item.xml
@@ -23,6 +23,13 @@
<arg type="i" name="delta" direction="in" />
<arg type="s" name="orientation" direction="in" />
</method>
+ <method name="SecondaryActivate">
+ <arg type="i" name="x" direction="in" />
+ <arg type="i" name="y" direction="in" />
+ </method>
+ <method name="XAyatanaSecondaryActivate">
+ <arg type="u" name="timestamp" direction="in" />
+ </method>
<!-- Signals -->
<signal name="NewIcon">