aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/app-indicator.c76
-rw-r--r--src/app-indicator.h16
-rw-r--r--src/application-service-marshal.list1
-rw-r--r--src/notification-item.xml6
4 files changed, 92 insertions, 7 deletions
diff --git a/src/app-indicator.c b/src/app-indicator.c
index 40959bf..8f8661b 100644
--- a/src/app-indicator.c
+++ b/src/app-indicator.c
@@ -102,6 +102,7 @@ enum {
NEW_LABEL,
CONNECTION_CHANGED,
NEW_ICON_THEME_PATH,
+ SCROLL_EVENT,
LAST_SIGNAL
};
@@ -169,8 +170,10 @@ static void start_fallback_timer (AppIndicator * self, gboolean disable_timeout)
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 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);
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);
@@ -178,11 +181,12 @@ static void client_menu_changed (GtkWidget *widget, GtkWidget *child, AppIndicat
static void submenu_changed (GtkWidget *widget, GtkWidget *child, gpointer data);
static void theme_changed_cb (GtkIconTheme * theme, 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);
static void bus_watcher_ready (GObject * obj, GAsyncResult * res, gpointer user_data);
static const GDBusInterfaceVTable item_interface_table = {
- method_call: NULL, /* No methods on this object */
+ method_call: bus_method_call,
get_property: bus_get_prop,
set_property: NULL /* No properties that can be set */
};
@@ -469,6 +473,21 @@ app_indicator_class_init (AppIndicatorClass *klass)
g_cclosure_marshal_VOID__STRING,
G_TYPE_NONE, 1, G_TYPE_STRING);
+ /**
+ AppIndicator::scroll-event:
+ @arg0: The #AppIndicator object
+
+ Signaled when there is a new icon set for the
+ object.
+ */
+ signals[SCROLL_EVENT] = g_signal_new (APP_INDICATOR_SIGNAL_SCROLL_EVENT,
+ G_TYPE_FROM_CLASS(klass),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (AppIndicatorClass, scroll_event),
+ NULL, NULL,
+ _application_service_marshal_VOID__INT_UINT,
+ G_TYPE_NONE, 2, G_TYPE_INT, G_TYPE_UINT);
+
/* DBus interfaces */
if (item_node_info == NULL) {
GError * error = NULL;
@@ -899,6 +918,30 @@ bus_creation (GObject * obj, GAsyncResult * res, gpointer user_data)
return;
}
+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)
+{
+ g_return_if_fail(IS_APP_INDICATOR(user_data));
+
+ AppIndicator * app = APP_INDICATOR(user_data);
+ GVariant * retval = NULL;
+
+ if (g_strcmp0(method, "XAyatanaScrollAction") == 0) {
+ gint delta;
+ guint direction;
+
+ g_variant_get(params, "(iu)", &delta, &direction);
+ g_signal_emit(app, signals[SCROLL_EVENT], 0, delta, direction);
+ } else {
+ g_warning("Calling method '%s' on the app-indicator and it's unknown", method);
+ }
+
+ g_dbus_method_invocation_return_value(invocation, retval);
+}
+
/* DBus is asking for a property so we should figure out what it
wants and try and deliver. */
static GVariant *
@@ -1053,7 +1096,8 @@ check_connect (AppIndicator *self)
if (priv->watcher_proxy == NULL) {
/* Build Watcher Proxy */
g_dbus_proxy_new(priv->connection,
- G_DBUS_PROXY_FLAGS_DO_NOT_LOAD_PROPERTIES | G_DBUS_PROXY_FLAGS_DO_NOT_CONNECT_SIGNALS, /* We don't use these, don't bother with them */
+ G_DBUS_PROXY_FLAGS_DO_NOT_LOAD_PROPERTIES|
+ G_DBUS_PROXY_FLAGS_DO_NOT_CONNECT_SIGNALS, /* We don't use these, don't bother with them */
watcher_interface_info,
NOTIFICATION_WATCHER_DBUS_ADDR,
NOTIFICATION_WATCHER_DBUS_OBJ,
@@ -1101,6 +1145,11 @@ bus_watcher_ready (GObject * obj, GAsyncResult * res, gpointer user_data)
/* Setting up a signal to watch when the unique name
changes */
g_signal_connect(G_OBJECT(app->priv->watcher_proxy), "notify::g-name-owner", G_CALLBACK(watcher_owner_changed), user_data);
+
+ char * name = g_dbus_proxy_get_name_owner(app->priv->watcher_proxy);
+ if (name != NULL) {
+ g_free(name);
+ }
}
/* Let's insure that someone is on the other side, else we're
@@ -1315,6 +1364,8 @@ fallback (AppIndicator * self)
status_icon_changes(self, icon);
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);
return icon;
}
@@ -1327,6 +1378,18 @@ status_icon_status_wrapper (AppIndicator * self, const gchar * status, gpointer
return status_icon_changes(self, data);
}
+/* 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)
+{
+ 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 FALSE;
+}
+
/* This tracks changes to either the status or the icons
that are associated with the app indicator */
static void
@@ -1388,6 +1451,14 @@ status_icon_activate (GtkStatusIcon * icon, gpointer data)
return;
}
+/* Handles the right-click action by the status icon by showing
+ the menu in a popup. */
+static void
+status_icon_menu_activate (GtkStatusIcon *status_icon, guint button, guint activate_time, gpointer user_data)
+{
+ status_icon_activate(status_icon, user_data);
+}
+
/* Removes the status icon as the application indicator area
is now up and running again. */
static void
@@ -1395,6 +1466,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);
gtk_status_icon_set_visible(status_icon, FALSE);
g_object_unref(G_OBJECT(status_icon));
return;
diff --git a/src/app-indicator.h b/src/app-indicator.h
index 3e159db..9e0d15f 100644
--- a/src/app-indicator.h
+++ b/src/app-indicator.h
@@ -107,12 +107,18 @@ G_BEGIN_DECLS
String identifier for the #AppIndicator::new-icon-theme-path signal.
*/
+/**
+ APP_INDICATOR_SIGNAL_SCROLL_EVENT:
+
+ String identifier for the #AppIndicator::scroll-event signal.
+*/
#define APP_INDICATOR_SIGNAL_NEW_ICON "new-icon"
#define APP_INDICATOR_SIGNAL_NEW_ATTENTION_ICON "new-attention-icon"
#define APP_INDICATOR_SIGNAL_NEW_STATUS "new-status"
#define APP_INDICATOR_SIGNAL_NEW_LABEL "new-label"
#define APP_INDICATOR_SIGNAL_CONNECTION_CHANGED "connection-changed"
#define APP_INDICATOR_SIGNAL_NEW_ICON_THEME_PATH "new-icon-theme-path"
+#define APP_INDICATOR_SIGNAL_SCROLL_EVENT "scroll-event"
/**
AppIndicatorCategory:
@@ -163,7 +169,7 @@ typedef struct _AppIndicatorPrivate AppIndicatorPrivate;
@new_icon_theme_path: Slot for #AppIndicator::new-icon-theme-path
@new_label: Slot for #AppIndicator::new-label.
@connection_changed: Slot for #AppIndicator::connection-changed.
- @app_indicator_reserved_sw: Reserved for future use.
+ @scroll-event: Slot for #AppIndicator::scroll-event
@app_indicator_reserved_ats: Reserved for future use.
@fallback: Function that gets called to make a #GtkStatusIcon when
there is no Application Indicator area available.
@@ -203,7 +209,12 @@ struct _AppIndicatorClass {
void (* connection_changed) (AppIndicator * indicator,
gboolean connected,
gpointer user_data);
- void (*app_indicator_reserved_sw)(void);
+
+ void (* scroll_event) (AppIndicator * indicator,
+ gint delta,
+ guint direction,
+ gpointer user_data);
+
void (*app_indicator_reserved_ats)(void);
/* Overridable Functions */
@@ -217,7 +228,6 @@ struct _AppIndicatorClass {
void (*app_indicator_reserved_3)(void);
void (*app_indicator_reserved_4)(void);
void (*app_indicator_reserved_5)(void);
- void (*app_indicator_reserved_6)(void);
};
/**
diff --git a/src/application-service-marshal.list b/src/application-service-marshal.list
index 2b2efa5..39a55fe 100644
--- a/src/application-service-marshal.list
+++ b/src/application-service-marshal.list
@@ -21,3 +21,4 @@ VOID: INT, STRING, STRING
VOID: INT, STRING
VOID: STRING, STRING
VOID: BOOL, STRING, OBJECT
+VOID: INT, UINT
diff --git a/src/notification-item.xml b/src/notification-item.xml
index 05afd83..48e9695 100644
--- a/src/notification-item.xml
+++ b/src/notification-item.xml
@@ -17,7 +17,10 @@
<property name="XAyatanaOrderingIndex" type="u" access="read" />
<!-- Methods -->
- <!-- None currently -->
+ <method name="XAyatanaScrollAction">
+ <arg type="i" name="delta" direction="in" />
+ <arg type="u" name="direction" direction="in" />
+ </method>
<!-- Signals -->
<signal name="NewIcon">
@@ -34,6 +37,5 @@
<arg type="s" name="label" direction="out" />
<arg type="s" name="guide" direction="out" />
</signal>
-
</interface>
</node>