From 52b2a291e980e75e3fc45aa3d0ae2f8f40566c2a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marco=20Trevisan=20=28Trevi=C3=B1o=29?= Date: Thu, 27 Jan 2011 00:29:57 +0100 Subject: app-indicator: listen for XAyatanaScrollAction and emit "scroll-event" signal libappindicator now when it gets a dbus call from indicator-application (via the method XAyatanaScrollAction) about the incoming scroll event, sends a "scroll-event" signal to the appindicator application using this library. This works both in indicator and fallback (systray mode). This commit includes a fix for bug #707591 --- src/app-indicator.c | 76 +++++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 74 insertions(+), 2 deletions(-) (limited to 'src/app-indicator.c') 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; -- cgit v1.2.3 From e18d298c9366e46a66948cd06165aadf01824da1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marco=20Trevisan=20=28Trevi=C3=B1o=29?= Date: Thu, 27 Jan 2011 12:40:33 +0100 Subject: app-indicator: remove old debug code. --- src/app-indicator.c | 5 ----- 1 file changed, 5 deletions(-) (limited to 'src/app-indicator.c') diff --git a/src/app-indicator.c b/src/app-indicator.c index 8f8661b..4bef6de 100644 --- a/src/app-indicator.c +++ b/src/app-indicator.c @@ -1145,11 +1145,6 @@ 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 -- cgit v1.2.3 From 0d97a5e6201be283ba2dd017297b71122c7f19e2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marco=20Trevisan=20=28Trevi=C3=B1o=29?= Date: Sat, 29 Jan 2011 03:27:29 +0100 Subject: Using the SNI method "Scroll" instead of XAyatanaScrollAction The indicator signal will use anyway the same syntax. --- src/app-indicator.c | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) (limited to 'src/app-indicator.c') diff --git a/src/app-indicator.c b/src/app-indicator.c index 4bef6de..26d8c73 100644 --- a/src/app-indicator.c +++ b/src/app-indicator.c @@ -929,12 +929,25 @@ bus_method_call (GDBusConnection * connection, const gchar * sender, AppIndicator * app = APP_INDICATOR(user_data); GVariant * retval = NULL; - if (g_strcmp0(method, "XAyatanaScrollAction") == 0) { - gint delta; + if (g_strcmp0(method, "Scroll") == 0) { guint direction; + gint delta; + const gchar *orientation; + + g_variant_get(params, "(i&s)", &delta, &orientation); + + if (g_strcmp0(orientation, "horizontal") == 0) { + direction = (delta >= 0) ? GDK_SCROLL_RIGHT : GDK_SCROLL_LEFT; + } else if (g_strcmp0(orientation, "vertical") == 0) { + direction = (delta >= 0) ? GDK_SCROLL_DOWN : GDK_SCROLL_UP; + } else { + g_dbus_method_invocation_return_value(invocation, retval); + return; + } - g_variant_get(params, "(iu)", &delta, &direction); + delta = ABS(delta); 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); } -- cgit v1.2.3