aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/application-service-appstore.c2036
-rw-r--r--src/ayatana-application-service-marshal.list26
-rw-r--r--src/ayatana-application-service.xml123
-rw-r--r--src/generate-id.h16
-rw-r--r--src/indicator-application.c1571
5 files changed, 1998 insertions, 1774 deletions
diff --git a/src/application-service-appstore.c b/src/application-service-appstore.c
index 9124fe3..45acbce 100644
--- a/src/application-service-appstore.c
+++ b/src/application-service-appstore.c
@@ -3,20 +3,22 @@ An object that stores the registration of all the application
indicators. It also communicates this to the indicator visualization.
Copyright 2009 Canonical Ltd.
+Copyright 2024-2025 Robert Tari
Authors:
Ted Gould <ted@canonical.com>
+ Robert Tari <robert@tari.in>
-This program is free software: you can redistribute it and/or modify it
-under the terms of the GNU General Public License version 3, as published
+This program is free software: you can redistribute it and/or modify it
+under the terms of the GNU General Public License version 3, as published
by the Free Software Foundation.
-This program is distributed in the hope that it will be useful, but
-WITHOUT ANY WARRANTY; without even the implied warranties of
-MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
+This program is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranties of
+MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
PURPOSE. See the GNU General Public License for more details.
-You should have received a copy of the GNU General Public License along
+You should have received a copy of the GNU General Public License along
with this program. If not, see <http://www.gnu.org/licenses/>.
*/
@@ -25,8 +27,8 @@ with this program. If not, see <http://www.gnu.org/licenses/>.
#endif
#include <libayatana-indicator/indicator-object.h>
-#include <libayatana-appindicator/app-indicator.h>
-#include <libayatana-appindicator/app-indicator-enum-types.h>
+#include <libayatana-appindicator-glib/ayatana-appindicator.h>
+#include <libayatana-appindicator-glib/ayatana-appindicator-enum-types.h>
#include "application-service-appstore.h"
#include "ayatana-application-service-marshal.h"
#include "dbus-shared.h"
@@ -52,6 +54,7 @@ static void props_cb (GObject * object, GAsyncResult * res, gpointer user_data);
#define NOTIFICATION_ITEM_PROP_LABEL_GUIDE "XAyatanaLabelGuide"
#define NOTIFICATION_ITEM_PROP_TITLE "Title"
#define NOTIFICATION_ITEM_PROP_ORDERING_INDEX "XAyatanaOrderingIndex"
+#define NOTIFICATION_ITEM_PROP_TOOLTIP "ToolTip"
#define NOTIFICATION_ITEM_SIG_NEW_ICON "NewIcon"
#define NOTIFICATION_ITEM_SIG_NEW_AICON "NewAttentionIcon"
@@ -59,53 +62,57 @@ static void props_cb (GObject * object, GAsyncResult * res, gpointer user_data);
#define NOTIFICATION_ITEM_SIG_NEW_LABEL "XAyatanaNewLabel"
#define NOTIFICATION_ITEM_SIG_NEW_ICON_THEME_PATH "NewIconThemePath"
#define NOTIFICATION_ITEM_SIG_NEW_TITLE "NewTitle"
+#define NOTIFICATION_ITEM_SIG_NEW_TOOLTIP "NewToolTip"
#define OVERRIDE_GROUP_NAME "Ordering Index Overrides"
#define OVERRIDE_FILE_NAME "ordering-override.keyfile"
/* Private Stuff */
typedef struct {
- GCancellable * bus_cancel;
- GDBusConnection * bus;
- guint dbus_registration;
- GList * applications;
- GHashTable * ordering_overrides;
+ GCancellable * bus_cancel;
+ GDBusConnection * bus;
+ guint dbus_registration;
+ GList * applications;
+ GHashTable * ordering_overrides;
} ApplicationServiceAppstorePrivate;
typedef enum {
- VISIBLE_STATE_HIDDEN,
- VISIBLE_STATE_SHOWN
+ VISIBLE_STATE_HIDDEN,
+ VISIBLE_STATE_SHOWN
} visible_state_t;
#define STATE2STRING(x) ((x) == VISIBLE_STATE_HIDDEN ? "hidden" : "visible")
typedef struct _Application Application;
struct _Application {
- gchar * id;
- gchar * category;
- gchar * dbus_name;
- gchar * dbus_object;
- ApplicationServiceAppstore * appstore; /* not ref'd */
- GCancellable * dbus_proxy_cancel;
- GDBusProxy * dbus_proxy;
- GCancellable * props_cancel;
- gboolean queued_props;
- GDBusProxy * props;
- gboolean validated; /* Whether we've gotten all the parameters and they look good. */
- AppIndicatorStatus status;
- gchar * icon;
- gchar * icon_desc;
- gchar * aicon;
- gchar * aicon_desc;
- gchar * menu;
- gchar * icon_theme_path;
- gchar * label;
- gchar * guide;
- gchar * title;
- gboolean currently_free;
- guint ordering_index;
- visible_state_t visible_state;
- guint name_watcher;
+ gchar * id;
+ gchar * category;
+ gchar * dbus_name;
+ gchar * dbus_object;
+ ApplicationServiceAppstore * appstore; /* not ref'd */
+ GCancellable * dbus_proxy_cancel;
+ GDBusProxy * dbus_proxy;
+ GCancellable * props_cancel;
+ gboolean queued_props;
+ GDBusProxy * props;
+ gboolean validated; /* Whether we've gotten all the parameters and they look good. */
+ AppIndicatorStatus status;
+ gchar * icon;
+ gchar * icon_desc;
+ gchar * aicon;
+ gchar * aicon_desc;
+ gchar * menu;
+ gchar * icon_theme_path;
+ gchar * label;
+ gchar * guide;
+ gchar * title;
+ gboolean currently_free;
+ guint ordering_index;
+ visible_state_t visible_state;
+ guint name_watcher;
+ gchar *sTooltipIcon;
+ gchar *sTooltipTitle;
+ gchar *sTooltipDescription;
};
/* GDBus Stuff */
@@ -140,97 +147,96 @@ G_DEFINE_TYPE_WITH_PRIVATE (ApplicationServiceAppstore, application_service_apps
static void
application_service_appstore_class_init (ApplicationServiceAppstoreClass *klass)
{
- GObjectClass *object_class = G_OBJECT_CLASS (klass);
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
- object_class->dispose = application_service_appstore_dispose;
- object_class->finalize = application_service_appstore_finalize;
+ object_class->dispose = application_service_appstore_dispose;
+ object_class->finalize = application_service_appstore_finalize;
- /* Setting up the DBus interfaces */
- if (node_info == NULL) {
- GError * error = NULL;
+ /* Setting up the DBus interfaces */
+ if (node_info == NULL) {
+ GError * error = NULL;
- node_info = g_dbus_node_info_new_for_xml(_ayatana_application_service, &error);
- if (error != NULL) {
- g_critical("Unable to parse Application Service Interface description: %s", error->message);
- g_error_free(error);
- }
- }
+ node_info = g_dbus_node_info_new_for_xml(_ayatana_application_service, &error);
+ if (error != NULL) {
+ g_critical("Unable to parse Application Service Interface description: %s", error->message);
+ g_error_free(error);
+ }
+ }
- if (interface_info == NULL) {
- interface_info = g_dbus_node_info_lookup_interface(node_info, INDICATOR_APPLICATION_DBUS_IFACE);
+ if (interface_info == NULL) {
+ interface_info = g_dbus_node_info_lookup_interface(node_info, INDICATOR_APPLICATION_DBUS_IFACE);
- if (interface_info == NULL) {
- g_critical("Unable to find interface '" INDICATOR_APPLICATION_DBUS_IFACE "'");
- }
- }
+ if (interface_info == NULL) {
+ g_critical("Unable to find interface '" INDICATOR_APPLICATION_DBUS_IFACE "'");
+ }
+ }
- return;
+ return;
}
static void
application_service_appstore_init (ApplicationServiceAppstore *self)
{
-
- ApplicationServiceAppstorePrivate * priv = application_service_appstore_get_instance_private(self);
+ ApplicationServiceAppstorePrivate * priv = application_service_appstore_get_instance_private(self);
- priv->applications = NULL;
- priv->bus_cancel = NULL;
- priv->dbus_registration = 0;
+ priv->applications = NULL;
+ priv->bus_cancel = NULL;
+ priv->dbus_registration = 0;
- priv->ordering_overrides = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, NULL);
+ priv->ordering_overrides = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, NULL);
- load_override_file(priv->ordering_overrides, DATADIR "/" OVERRIDE_FILE_NAME);
- gchar * userfile = g_build_filename(g_get_user_data_dir(), "indicators", "application", OVERRIDE_FILE_NAME, NULL);
- load_override_file(priv->ordering_overrides, userfile);
- g_free(userfile);
+ load_override_file(priv->ordering_overrides, DATADIR "/" OVERRIDE_FILE_NAME);
+ gchar * userfile = g_build_filename(g_get_user_data_dir(), "indicators", "application", OVERRIDE_FILE_NAME, NULL);
+ load_override_file(priv->ordering_overrides, userfile);
+ g_free(userfile);
- priv->bus_cancel = g_cancellable_new();
- g_bus_get(G_BUS_TYPE_SESSION,
- priv->bus_cancel,
- bus_get_cb,
- self);
+ priv->bus_cancel = g_cancellable_new();
+ g_bus_get(G_BUS_TYPE_SESSION,
+ priv->bus_cancel,
+ bus_get_cb,
+ self);
- return;
+ return;
}
static void
bus_get_cb (GObject * object, GAsyncResult * res, gpointer user_data)
{
- GError * error = NULL;
- GDBusConnection * connection = g_bus_get_finish(res, &error);
-
- if (error != NULL) {
- g_critical("OMG! Unable to get a connection to DBus: %s", error->message);
- g_error_free(error);
- return;
- }
-
- ApplicationServiceAppstorePrivate * priv = application_service_appstore_get_instance_private(APPLICATION_SERVICE_APPSTORE(user_data));
-
- g_warn_if_fail(priv->bus == NULL);
- priv->bus = connection;
-
- if (priv->bus_cancel != NULL) {
- g_object_unref(priv->bus_cancel);
- priv->bus_cancel = NULL;
- }
-
- /* Now register our object on our new connection */
- priv->dbus_registration = g_dbus_connection_register_object(priv->bus,
- INDICATOR_APPLICATION_DBUS_OBJ,
- interface_info,
- &interface_table,
- user_data,
- NULL,
- &error);
-
- if (error != NULL) {
- g_critical("Unable to register the object to DBus: %s", error->message);
- g_error_free(error);
- return;
- }
-
- return;
+ GError * error = NULL;
+ GDBusConnection * connection = g_bus_get_finish(res, &error);
+
+ if (error != NULL) {
+ g_critical("OMG! Unable to get a connection to DBus: %s", error->message);
+ g_error_free(error);
+ return;
+ }
+
+ ApplicationServiceAppstorePrivate * priv = application_service_appstore_get_instance_private(APPLICATION_SERVICE_APPSTORE(user_data));
+
+ g_warn_if_fail(priv->bus == NULL);
+ priv->bus = connection;
+
+ if (priv->bus_cancel != NULL) {
+ g_object_unref(priv->bus_cancel);
+ priv->bus_cancel = NULL;
+ }
+
+ /* Now register our object on our new connection */
+ priv->dbus_registration = g_dbus_connection_register_object(priv->bus,
+ INDICATOR_APPLICATION_DBUS_OBJ,
+ interface_info,
+ &interface_table,
+ user_data,
+ NULL,
+ &error);
+
+ if (error != NULL) {
+ g_critical("Unable to register the object to DBus: %s", error->message);
+ g_error_free(error);
+ return;
+ }
+
+ return;
}
/* A method has been called from our dbus inteface. Figure out what it
@@ -241,117 +247,117 @@ bus_method_call (GDBusConnection * connection, const gchar * sender,
const gchar * method, GVariant * params,
GDBusMethodInvocation * invocation, gpointer user_data)
{
- ApplicationServiceAppstore * service = APPLICATION_SERVICE_APPSTORE(user_data);
- GVariant * retval = NULL;
- Application *app = NULL;
- gchar *dbusaddress = NULL;
- gchar *dbusmenuobject = NULL;
-
- if (g_strcmp0(method, "GetApplications") == 0) {
- retval = get_applications(service);
- } else if (g_strcmp0(method, "ApplicationScrollEvent") == 0) {
- gchar *orientation = NULL;
- gint delta;
- guint direction;
-
- g_variant_get (params, "(ssiu)", &dbusaddress, &dbusmenuobject,
- &delta, &direction);
-
- switch (direction) {
- case INDICATOR_OBJECT_SCROLL_UP:
- delta = -delta;
- orientation = "vertical";
- break;
- case INDICATOR_OBJECT_SCROLL_DOWN:
- /* delta unchanged */
- orientation = "vertical";
- break;
- case INDICATOR_OBJECT_SCROLL_LEFT:
- delta = -delta;
- orientation = "horizontal";
- break;
- case INDICATOR_OBJECT_SCROLL_RIGHT:
- /* delta unchanged */
- orientation = "horizontal";
- break;
- default:
- g_assert_not_reached();
- break;
- }
-
- app = find_application_by_menu(service, dbusaddress, dbusmenuobject);
-
- if (app != NULL && app->dbus_proxy != NULL && orientation != NULL) {
- g_dbus_proxy_call(app->dbus_proxy, "Scroll",
- g_variant_new("(is)", delta, orientation),
- G_DBUS_CALL_FLAGS_NONE, -1, NULL, NULL, NULL);
- }
- } else if (g_strcmp0(method, "ApplicationSecondaryActivateEvent") == 0) {
- guint time;
-
- g_variant_get (params, "(ssu)", &dbusaddress, &dbusmenuobject, &time);
- app = find_application_by_menu(service, dbusaddress, dbusmenuobject);
-
- if (app != NULL && app->dbus_proxy != NULL) {
- g_dbus_proxy_call(app->dbus_proxy, "XAyatanaSecondaryActivate",
- g_variant_new("(u)", time),
- G_DBUS_CALL_FLAGS_NONE, -1, NULL, NULL, NULL);
- }
- } else {
- g_warning("Calling method '%s' on the indicator service and it's unknown", method);
- }
-
- g_free(dbusaddress);
- g_free(dbusmenuobject);
-
- g_dbus_method_invocation_return_value(invocation, retval);
- return;
+ ApplicationServiceAppstore * service = APPLICATION_SERVICE_APPSTORE(user_data);
+ GVariant * retval = NULL;
+ Application *app = NULL;
+ gchar *dbusaddress = NULL;
+ gchar *dbusmenuobject = NULL;
+
+ if (g_strcmp0(method, "GetApplications") == 0) {
+ retval = get_applications(service);
+ } else if (g_strcmp0(method, "ApplicationScrollEvent") == 0) {
+ gchar *orientation = NULL;
+ gint delta;
+ guint direction;
+
+ g_variant_get (params, "(ssiu)", &dbusaddress, &dbusmenuobject,
+ &delta, &direction);
+
+ switch (direction) {
+ case INDICATOR_OBJECT_SCROLL_UP:
+ delta = -delta;
+ orientation = "vertical";
+ break;
+ case INDICATOR_OBJECT_SCROLL_DOWN:
+ /* delta unchanged */
+ orientation = "vertical";
+ break;
+ case INDICATOR_OBJECT_SCROLL_LEFT:
+ delta = -delta;
+ orientation = "horizontal";
+ break;
+ case INDICATOR_OBJECT_SCROLL_RIGHT:
+ /* delta unchanged */
+ orientation = "horizontal";
+ break;
+ default:
+ g_assert_not_reached();
+ break;
+ }
+
+ app = find_application_by_menu(service, dbusaddress, dbusmenuobject);
+
+ if (app != NULL && app->dbus_proxy != NULL && orientation != NULL) {
+ g_dbus_proxy_call(app->dbus_proxy, "Scroll",
+ g_variant_new("(is)", delta, orientation),
+ G_DBUS_CALL_FLAGS_NONE, -1, NULL, NULL, NULL);
+ }
+ } else if (g_strcmp0(method, "ApplicationSecondaryActivateEvent") == 0) {
+ guint time;
+
+ g_variant_get (params, "(ssu)", &dbusaddress, &dbusmenuobject, &time);
+ app = find_application_by_menu(service, dbusaddress, dbusmenuobject);
+
+ if (app != NULL && app->dbus_proxy != NULL) {
+ g_dbus_proxy_call(app->dbus_proxy, "XAyatanaSecondaryActivate",
+ g_variant_new("(u)", time),
+ G_DBUS_CALL_FLAGS_NONE, -1, NULL, NULL, NULL);
+ }
+ } else {
+ g_warning("Calling method '%s' on the indicator service and it's unknown", method);
+ }
+
+ g_free(dbusaddress);
+ g_free(dbusmenuobject);
+
+ g_dbus_method_invocation_return_value(invocation, retval);
+ return;
}
static void
application_service_appstore_dispose (GObject *object)
{
- ApplicationServiceAppstorePrivate * priv = application_service_appstore_get_instance_private(APPLICATION_SERVICE_APPSTORE(object));
-
- while (priv->applications != NULL) {
- application_service_appstore_application_remove(APPLICATION_SERVICE_APPSTORE(object),
- ((Application *)priv->applications->data)->dbus_name,
- ((Application *)priv->applications->data)->dbus_object);
- }
-
- if (priv->dbus_registration != 0) {
- g_dbus_connection_unregister_object(priv->bus, priv->dbus_registration);
- /* Don't care if it fails, there's nothing we can do */
- priv->dbus_registration = 0;
- }
-
- if (priv->bus != NULL) {
- g_object_unref(priv->bus);
- priv->bus = NULL;
- }
-
- if (priv->bus_cancel != NULL) {
- g_cancellable_cancel(priv->bus_cancel);
- g_object_unref(priv->bus_cancel);
- priv->bus_cancel = NULL;
- }
-
- G_OBJECT_CLASS (application_service_appstore_parent_class)->dispose (object);
- return;
+ ApplicationServiceAppstorePrivate * priv = application_service_appstore_get_instance_private(APPLICATION_SERVICE_APPSTORE(object));
+
+ while (priv->applications != NULL) {
+ application_service_appstore_application_remove(APPLICATION_SERVICE_APPSTORE(object),
+ ((Application *)priv->applications->data)->dbus_name,
+ ((Application *)priv->applications->data)->dbus_object);
+ }
+
+ if (priv->dbus_registration != 0) {
+ g_dbus_connection_unregister_object(priv->bus, priv->dbus_registration);
+ /* Don't care if it fails, there's nothing we can do */
+ priv->dbus_registration = 0;
+ }
+
+ if (priv->bus != NULL) {
+ g_object_unref(priv->bus);
+ priv->bus = NULL;
+ }
+
+ if (priv->bus_cancel != NULL) {
+ g_cancellable_cancel(priv->bus_cancel);
+ g_object_unref(priv->bus_cancel);
+ priv->bus_cancel = NULL;
+ }
+
+ G_OBJECT_CLASS (application_service_appstore_parent_class)->dispose (object);
+ return;
}
static void
application_service_appstore_finalize (GObject *object)
{
- ApplicationServiceAppstorePrivate * priv = application_service_appstore_get_instance_private(APPLICATION_SERVICE_APPSTORE(object));
+ ApplicationServiceAppstorePrivate * priv = application_service_appstore_get_instance_private(APPLICATION_SERVICE_APPSTORE(object));
- if (priv->ordering_overrides != NULL) {
- g_hash_table_destroy(priv->ordering_overrides);
- priv->ordering_overrides = NULL;
- }
+ if (priv->ordering_overrides != NULL) {
+ g_hash_table_destroy(priv->ordering_overrides);
+ priv->ordering_overrides = NULL;
+ }
- G_OBJECT_CLASS (application_service_appstore_parent_class)->finalize (object);
- return;
+ G_OBJECT_CLASS (application_service_appstore_parent_class)->finalize (object);
+ return;
}
/* Loads the file and adds the override entries to the table
@@ -359,55 +365,55 @@ application_service_appstore_finalize (GObject *object)
static void
load_override_file (GHashTable * hash, const gchar * filename)
{
- g_return_if_fail(hash != NULL);
- g_return_if_fail(filename != NULL);
-
- if (!g_file_test(filename, G_FILE_TEST_EXISTS)) {
- g_debug("Override file '%s' doesn't exist", filename);
- return;
- }
-
- g_debug("Loading overrides from: '%s'", filename);
-
- GError * error = NULL;
- GKeyFile * keyfile = g_key_file_new();
- g_key_file_load_from_file(keyfile, filename, G_KEY_FILE_NONE, &error);
-
- if (error != NULL) {
- g_warning("Unable to load keyfile '%s' because: %s", filename, error->message);
- g_error_free(error);
- g_key_file_free(keyfile);
- return;
- }
-
- gchar ** keys = g_key_file_get_keys(keyfile, OVERRIDE_GROUP_NAME, NULL, &error);
- if (error != NULL) {
- g_warning("Unable to get keys from keyfile '%s' because: %s", filename, error->message);
- g_error_free(error);
- g_key_file_free(keyfile);
- return;
- }
-
- gchar * key;
- gint i;
-
- for (i = 0; (key = keys[i]) != NULL; i++) {
- GError * valerror = NULL;
- gint val = g_key_file_get_integer(keyfile, OVERRIDE_GROUP_NAME, key, &valerror);
-
- if (valerror != NULL) {
- g_warning("Unable to get key '%s' out of file '%s' because: %s", key, filename, valerror->message);
- g_error_free(valerror);
- continue;
- }
- g_debug("%s: override '%s' with value '%d'", filename, key, val);
-
- g_hash_table_insert(hash, g_strdup(key), GINT_TO_POINTER(val));
- }
- g_strfreev(keys);
- g_key_file_free(keyfile);
-
- return;
+ g_return_if_fail(hash != NULL);
+ g_return_if_fail(filename != NULL);
+
+ if (!g_file_test(filename, G_FILE_TEST_EXISTS)) {
+ g_debug("Override file '%s' doesn't exist", filename);
+ return;
+ }
+
+ g_debug("Loading overrides from: '%s'", filename);
+
+ GError * error = NULL;
+ GKeyFile * keyfile = g_key_file_new();
+ g_key_file_load_from_file(keyfile, filename, G_KEY_FILE_NONE, &error);
+
+ if (error != NULL) {
+ g_warning("Unable to load keyfile '%s' because: %s", filename, error->message);
+ g_error_free(error);
+ g_key_file_free(keyfile);
+ return;
+ }
+
+ gchar ** keys = g_key_file_get_keys(keyfile, OVERRIDE_GROUP_NAME, NULL, &error);
+ if (error != NULL) {
+ g_warning("Unable to get keys from keyfile '%s' because: %s", filename, error->message);
+ g_error_free(error);
+ g_key_file_free(keyfile);
+ return;
+ }
+
+ gchar * key;
+ gint i;
+
+ for (i = 0; (key = keys[i]) != NULL; i++) {
+ GError * valerror = NULL;
+ gint val = g_key_file_get_integer(keyfile, OVERRIDE_GROUP_NAME, key, &valerror);
+
+ if (valerror != NULL) {
+ g_warning("Unable to get key '%s' out of file '%s' because: %s", key, filename, valerror->message);
+ g_error_free(valerror);
+ continue;
+ }
+ g_debug("%s: override '%s' with value '%d'", filename, key, val);
+
+ g_hash_table_insert(hash, g_strdup(key), GINT_TO_POINTER(val));
+ }
+ g_strfreev(keys);
+ g_key_file_free(keyfile);
+
+ return;
}
/* Return from getting the properties from the item. We're looking at those
@@ -417,277 +423,303 @@ static void
got_all_properties (GObject * source_object, GAsyncResult * res,
gpointer user_data)
{
- Application * app = (Application *)user_data;
- g_return_if_fail(app != NULL);
-
- GError * error = NULL;
- GVariant * menu = NULL, * id = NULL, * category = NULL,
- * status = NULL, * icon_name = NULL, * aicon_name = NULL,
- * icon_desc = NULL, * aicon_desc = NULL,
- * icon_theme_path = NULL, * index = NULL, * label = NULL,
- * guide = NULL, * title = NULL;
-
- GVariant * properties = g_dbus_proxy_call_finish(G_DBUS_PROXY(source_object), res, &error);
-
- if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) {
- g_error_free (error);
- return; // Must exit before accessing freed memory
- }
-
- if (app->props_cancel != NULL) {
- g_object_unref(app->props_cancel);
- app->props_cancel = NULL;
- }
-
- if (error != NULL) {
- g_critical("Could not grab DBus properties for %s: %s", app->dbus_name, error->message);
- g_error_free(error);
- if (!app->validated)
- application_free(app);
- return;
- }
-
- ApplicationServiceAppstorePrivate * priv = application_service_appstore_get_instance_private(app->appstore);
-
- /* Grab all properties from variant */
- GVariantIter * iter = NULL;
- const gchar * name = NULL;
- GVariant * value = NULL;
- g_variant_get(properties, "(a{sv})", &iter);
- while (g_variant_iter_loop (iter, "{&sv}", &name, &value)) {
- if (g_strcmp0(name, NOTIFICATION_ITEM_PROP_MENU) == 0) {
- menu = g_variant_ref(value);
- } else if (g_strcmp0(name, NOTIFICATION_ITEM_PROP_ID) == 0) {
- id = g_variant_ref(value);
- } else if (g_strcmp0(name, NOTIFICATION_ITEM_PROP_CATEGORY) == 0) {
- category = g_variant_ref(value);
- } else if (g_strcmp0(name, NOTIFICATION_ITEM_PROP_STATUS) == 0) {
- status = g_variant_ref(value);
- } else if (g_strcmp0(name, NOTIFICATION_ITEM_PROP_ICON_NAME) == 0) {
- icon_name = g_variant_ref(value);
- } else if (g_strcmp0(name, NOTIFICATION_ITEM_PROP_ICON_DESC) == 0) {
- icon_desc = g_variant_ref(value);
- } else if (g_strcmp0(name, NOTIFICATION_ITEM_PROP_AICON_NAME) == 0) {
- aicon_name = g_variant_ref(value);
- } else if (g_strcmp0(name, NOTIFICATION_ITEM_PROP_AICON_DESC) == 0) {
- aicon_desc = g_variant_ref(value);
- } else if (g_strcmp0(name, NOTIFICATION_ITEM_PROP_ICON_THEME_PATH) == 0) {
- icon_theme_path = g_variant_ref(value);
- } else if (g_strcmp0(name, NOTIFICATION_ITEM_PROP_ORDERING_INDEX) == 0) {
- index = g_variant_ref(value);
- } else if (g_strcmp0(name, NOTIFICATION_ITEM_PROP_LABEL) == 0) {
- label = g_variant_ref(value);
- } else if (g_strcmp0(name, NOTIFICATION_ITEM_PROP_LABEL_GUIDE) == 0) {
- guide = g_variant_ref(value);
- } else if (g_strcmp0(name, NOTIFICATION_ITEM_PROP_TITLE) == 0) {
- title = g_variant_ref(value);
- } /* else ignore */
- }
- g_variant_iter_free (iter);
- g_variant_unref(properties);
-
- if (menu == NULL || id == NULL || category == NULL || status == NULL ||
- icon_name == NULL) {
- g_warning("Notification Item on object %s of %s doesn't have enough properties.", app->dbus_object, app->dbus_name);
- if (!app->validated)
- application_free(app);
- }
- else {
- app->validated = TRUE;
-
- /* It is possible we're coming through a second time and
- getting the properties. So we need to ensure we don't
- already have them stored */
- g_free(app->id);
- g_free(app->category);
- g_free(app->icon);
- g_free(app->menu);
-
- app->id = g_variant_dup_string(id, NULL);
- app->category = g_variant_dup_string(category, NULL);
- app->status = string_to_status(g_variant_get_string(status, NULL));
- app->icon = g_variant_dup_string(icon_name, NULL);
- app->menu = g_variant_dup_string(menu, NULL);
-
- /* Now the optional properties */
-
- g_free(app->icon_desc);
- if (icon_desc != NULL) {
- app->icon_desc = g_variant_dup_string(icon_desc, NULL);
- }
- else {
- app->icon_desc = g_strdup("");
- }
-
- g_free(app->aicon);
- if (aicon_name != NULL) {
- app->aicon = g_variant_dup_string(aicon_name, NULL);
- } else {
- app->aicon = g_strdup("");
- }
-
- g_free(app->aicon_desc);
- if (aicon_desc != NULL) {
- app->aicon_desc = g_variant_dup_string(aicon_desc, NULL);
- }
- else {
- app->aicon_desc = g_strdup("");
- }
-
- g_free(app->icon_theme_path);
- if (icon_theme_path != NULL) {
- app->icon_theme_path = g_variant_dup_string(icon_theme_path, NULL);
- } else {
- app->icon_theme_path = g_strdup("");
- }
-
- gpointer ordering_index_over = g_hash_table_lookup(priv->ordering_overrides, app->id);
- if (ordering_index_over == NULL) {
- if (index == NULL || g_variant_get_uint32(index) == 0) {
- app->ordering_index = generate_id(string_to_cat(app->category), app->id);
- } else {
- app->ordering_index = g_variant_get_uint32(index);
- }
- } else {
- app->ordering_index = GPOINTER_TO_UINT(ordering_index_over);
- }
- g_debug("'%s' ordering index is '%X'", app->id, app->ordering_index);
- priv->applications = g_list_sort_with_data(priv->applications, app_sort_func, NULL);
-
- g_free(app->label);
- if (label != NULL) {
- app->label = g_variant_dup_string(label, NULL);
- } else {
- app->label = g_strdup("");
- }
-
- g_free(app->guide);
- if (guide != NULL) {
- app->guide = g_variant_dup_string(guide, NULL);
- } else {
- app->guide = g_strdup("");
- }
-
- g_free(app->title);
- if (title != NULL) {
- app->title = g_variant_dup_string(title, NULL);
- } else {
- app->title = g_strdup("");
- }
-
- apply_status(app);
-
- if (app->queued_props) {
- get_all_properties(app);
- app->queued_props = FALSE;
- }
- }
-
- if (menu) g_variant_unref (menu);
- if (id) g_variant_unref (id);
- if (category) g_variant_unref (category);
- if (status) g_variant_unref (status);
- if (icon_name) g_variant_unref (icon_name);
- if (icon_desc) g_variant_unref (icon_desc);
- if (aicon_name) g_variant_unref (aicon_name);
- if (aicon_desc) g_variant_unref (aicon_desc);
- if (icon_theme_path) g_variant_unref (icon_theme_path);
- if (index) g_variant_unref (index);
- if (label) g_variant_unref (label);
- if (guide) g_variant_unref (guide);
- if (title) g_variant_unref (title);
-
- return;
+ Application * app = (Application *)user_data;
+ g_return_if_fail(app != NULL);
+
+ GError * error = NULL;
+ GVariant * menu = NULL, * id = NULL, * category = NULL,
+ * status = NULL, * icon_name = NULL, * aicon_name = NULL,
+ * icon_desc = NULL, * aicon_desc = NULL,
+ * icon_theme_path = NULL, * index = NULL, * label = NULL,
+ * guide = NULL, * title = NULL;
+ GVariant *pTooltip = NULL;
+
+ GVariant * properties = g_dbus_proxy_call_finish(G_DBUS_PROXY(source_object), res, &error);
+
+ if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) {
+ g_error_free (error);
+ return; // Must exit before accessing freed memory
+ }
+
+ if (app->props_cancel != NULL) {
+ g_object_unref(app->props_cancel);
+ app->props_cancel = NULL;
+ }
+
+ if (error != NULL) {
+ g_critical("Could not grab DBus properties for %s: %s", app->dbus_name, error->message);
+ g_error_free(error);
+ if (!app->validated)
+ application_free(app);
+ return;
+ }
+
+ ApplicationServiceAppstorePrivate * priv = application_service_appstore_get_instance_private(app->appstore);
+
+ /* Grab all properties from variant */
+ GVariantIter * iter = NULL;
+ const gchar * name = NULL;
+ GVariant * value = NULL;
+ g_variant_get(properties, "(a{sv})", &iter);
+ while (g_variant_iter_loop (iter, "{&sv}", &name, &value)) {
+ if (g_strcmp0(name, NOTIFICATION_ITEM_PROP_MENU) == 0) {
+ menu = g_variant_ref(value);
+ } else if (g_strcmp0(name, NOTIFICATION_ITEM_PROP_ID) == 0) {
+ id = g_variant_ref(value);
+ } else if (g_strcmp0(name, NOTIFICATION_ITEM_PROP_CATEGORY) == 0) {
+ category = g_variant_ref(value);
+ } else if (g_strcmp0(name, NOTIFICATION_ITEM_PROP_STATUS) == 0) {
+ status = g_variant_ref(value);
+ } else if (g_strcmp0(name, NOTIFICATION_ITEM_PROP_ICON_NAME) == 0) {
+ icon_name = g_variant_ref(value);
+ } else if (g_strcmp0(name, NOTIFICATION_ITEM_PROP_ICON_DESC) == 0) {
+ icon_desc = g_variant_ref(value);
+ } else if (g_strcmp0(name, NOTIFICATION_ITEM_PROP_AICON_NAME) == 0) {
+ aicon_name = g_variant_ref(value);
+ } else if (g_strcmp0(name, NOTIFICATION_ITEM_PROP_AICON_DESC) == 0) {
+ aicon_desc = g_variant_ref(value);
+ } else if (g_strcmp0(name, NOTIFICATION_ITEM_PROP_ICON_THEME_PATH) == 0) {
+ icon_theme_path = g_variant_ref(value);
+ } else if (g_strcmp0(name, NOTIFICATION_ITEM_PROP_ORDERING_INDEX) == 0) {
+ index = g_variant_ref(value);
+ } else if (g_strcmp0(name, NOTIFICATION_ITEM_PROP_LABEL) == 0) {
+ label = g_variant_ref(value);
+ } else if (g_strcmp0(name, NOTIFICATION_ITEM_PROP_LABEL_GUIDE) == 0) {
+ guide = g_variant_ref(value);
+ } else if (g_strcmp0(name, NOTIFICATION_ITEM_PROP_TITLE) == 0) {
+ title = g_variant_ref(value);
+ }
+ else if (g_strcmp0 (name, NOTIFICATION_ITEM_PROP_TOOLTIP) == 0)
+ {
+ pTooltip = g_variant_ref (value);
+ }
+ /* else ignore */
+ }
+ g_variant_iter_free (iter);
+ g_variant_unref(properties);
+
+ if (menu == NULL || id == NULL || category == NULL || status == NULL ||
+ icon_name == NULL) {
+ g_warning("Notification Item on object %s of %s doesn't have enough properties.", app->dbus_object, app->dbus_name);
+ if (!app->validated)
+ application_free(app);
+ }
+ else {
+ app->validated = TRUE;
+
+ /* It is possible we're coming through a second time and
+ getting the properties. So we need to ensure we don't
+ already have them stored */
+ g_free(app->id);
+ g_free(app->category);
+ g_free(app->icon);
+ g_free(app->menu);
+
+ app->id = g_variant_dup_string(id, NULL);
+ app->category = g_variant_dup_string(category, NULL);
+ app->status = string_to_status(g_variant_get_string(status, NULL));
+ app->icon = g_variant_dup_string(icon_name, NULL);
+ app->menu = g_variant_dup_string(menu, NULL);
+
+ /* Now the optional properties */
+
+ g_free(app->icon_desc);
+ if (icon_desc != NULL) {
+ app->icon_desc = g_variant_dup_string(icon_desc, NULL);
+ }
+ else {
+ app->icon_desc = g_strdup("");
+ }
+
+ g_free(app->aicon);
+ if (aicon_name != NULL) {
+ app->aicon = g_variant_dup_string(aicon_name, NULL);
+ } else {
+ app->aicon = g_strdup("");
+ }
+
+ g_free(app->aicon_desc);
+ if (aicon_desc != NULL) {
+ app->aicon_desc = g_variant_dup_string(aicon_desc, NULL);
+ }
+ else {
+ app->aicon_desc = g_strdup("");
+ }
+
+ g_free(app->icon_theme_path);
+ if (icon_theme_path != NULL) {
+ app->icon_theme_path = g_variant_dup_string(icon_theme_path, NULL);
+ } else {
+ app->icon_theme_path = g_strdup("");
+ }
+
+ gpointer ordering_index_over = g_hash_table_lookup(priv->ordering_overrides, app->id);
+ if (ordering_index_over == NULL) {
+ if (index == NULL || g_variant_get_uint32(index) == 0) {
+ app->ordering_index = generate_id(string_to_cat(app->category), app->id);
+ } else {
+ app->ordering_index = g_variant_get_uint32(index);
+ }
+ } else {
+ app->ordering_index = GPOINTER_TO_UINT(ordering_index_over);
+ }
+ g_debug("'%s' ordering index is '%X'", app->id, app->ordering_index);
+ priv->applications = g_list_sort_with_data(priv->applications, app_sort_func, NULL);
+
+ g_free(app->label);
+ if (label != NULL) {
+ app->label = g_variant_dup_string(label, NULL);
+ } else {
+ app->label = g_strdup("");
+ }
+
+ g_free(app->guide);
+ if (guide != NULL) {
+ app->guide = g_variant_dup_string(guide, NULL);
+ } else {
+ app->guide = g_strdup("");
+ }
+
+ g_free(app->title);
+ if (title != NULL) {
+ app->title = g_variant_dup_string(title, NULL);
+ } else {
+ app->title = g_strdup("");
+ }
+
+ g_free (app->sTooltipIcon);
+ g_free (app->sTooltipTitle);
+ g_free (app->sTooltipDescription);
+
+ if (pTooltip != NULL)
+ {
+ g_variant_get (pTooltip, "(sa(iiay)ss)", &app->sTooltipIcon, NULL, &app->sTooltipTitle, &app->sTooltipDescription);
+ }
+ else
+ {
+ app->sTooltipIcon = g_strdup ("");
+ app->sTooltipTitle = g_strdup ("");
+ app->sTooltipDescription = g_strdup ("");
+ }
+
+ apply_status(app);
+
+ if (app->queued_props) {
+ get_all_properties(app);
+ app->queued_props = FALSE;
+ }
+ }
+
+ if (menu) g_variant_unref (menu);
+ if (id) g_variant_unref (id);
+ if (category) g_variant_unref (category);
+ if (status) g_variant_unref (status);
+ if (icon_name) g_variant_unref (icon_name);
+ if (icon_desc) g_variant_unref (icon_desc);
+ if (aicon_name) g_variant_unref (aicon_name);
+ if (aicon_desc) g_variant_unref (aicon_desc);
+ if (icon_theme_path) g_variant_unref (icon_theme_path);
+ if (index) g_variant_unref (index);
+ if (label) g_variant_unref (label);
+ if (guide) g_variant_unref (guide);
+ if (title) g_variant_unref (title);
+
+ if (pTooltip)
+ {
+ g_variant_unref (pTooltip);
+ }
+
+ return;
}
static void
get_all_properties (Application * app)
{
- if (app->props != NULL && app->props_cancel == NULL) {
- app->props_cancel = g_cancellable_new();
- g_dbus_proxy_call(app->props, "GetAll",
- g_variant_new("(s)", NOTIFICATION_ITEM_DBUS_IFACE),
- G_DBUS_CALL_FLAGS_NONE, -1, app->props_cancel,
- got_all_properties, app);
- }
- else {
- g_debug("Queuing a properties check");
- app->queued_props = TRUE;
- }
+ if (app->props != NULL && app->props_cancel == NULL) {
+ app->props_cancel = g_cancellable_new();
+ g_dbus_proxy_call(app->props, "GetAll",
+ g_variant_new("(s)", NOTIFICATION_ITEM_DBUS_IFACE),
+ G_DBUS_CALL_FLAGS_NONE, -1, app->props_cancel,
+ got_all_properties, app);
+ }
+ else {
+ g_debug("Queuing a properties check");
+ app->queued_props = TRUE;
+ }
}
/* Simple translation function -- could be optimized */
static AppIndicatorStatus
string_to_status(const gchar * status_string)
{
- GEnumClass * klass = G_ENUM_CLASS(g_type_class_ref(APP_INDICATOR_TYPE_INDICATOR_STATUS));
- g_return_val_if_fail(klass != NULL, APP_INDICATOR_STATUS_PASSIVE);
+ GEnumClass * klass = G_ENUM_CLASS(g_type_class_ref(APP_INDICATOR_TYPE_INDICATOR_STATUS));
+ g_return_val_if_fail(klass != NULL, APP_INDICATOR_STATUS_PASSIVE);
- AppIndicatorStatus retval = APP_INDICATOR_STATUS_PASSIVE;
+ AppIndicatorStatus retval = APP_INDICATOR_STATUS_PASSIVE;
- GEnumValue * val = g_enum_get_value_by_nick(klass, status_string);
- if (val == NULL) {
- g_warning("Unrecognized status '%s' assuming passive.", status_string);
- } else {
- retval = (AppIndicatorStatus)val->value;
- }
+ GEnumValue * val = g_enum_get_value_by_nick(klass, status_string);
+ if (val == NULL) {
+ g_warning("Unrecognized status '%s' assuming passive.", status_string);
+ } else {
+ retval = (AppIndicatorStatus)val->value;
+ }
- g_type_class_unref(klass);
+ g_type_class_unref(klass);
- return retval;
+ return retval;
}
/* Simple translation function -- could be optimized */
static AppIndicatorCategory
string_to_cat(const gchar * cat_string)
{
- GEnumClass * klass = G_ENUM_CLASS(g_type_class_ref(APP_INDICATOR_TYPE_INDICATOR_CATEGORY));
- g_return_val_if_fail(klass != NULL, APP_INDICATOR_CATEGORY_OTHER);
+ GEnumClass * klass = G_ENUM_CLASS(g_type_class_ref(APP_INDICATOR_TYPE_INDICATOR_CATEGORY));
+ g_return_val_if_fail(klass != NULL, APP_INDICATOR_CATEGORY_OTHER);
- AppIndicatorCategory retval = APP_INDICATOR_CATEGORY_OTHER;
+ AppIndicatorCategory retval = APP_INDICATOR_CATEGORY_OTHER;
- GEnumValue * val = g_enum_get_value_by_nick(klass, cat_string);
- if (val == NULL) {
- g_warning("Unrecognized status '%s' assuming other.", cat_string);
- } else {
- retval = (AppIndicatorCategory)val->value;
- }
+ GEnumValue * val = g_enum_get_value_by_nick(klass, cat_string);
+ if (val == NULL) {
+ g_warning("Unrecognized status '%s' assuming other.", cat_string);
+ } else {
+ retval = (AppIndicatorCategory)val->value;
+ }
- g_type_class_unref(klass);
+ g_type_class_unref(klass);
- return retval;
+ return retval;
}
/* A small helper function to get the position of an application
in the app list of the applications that are visible. */
-static gint
+static gint
get_position (Application * app) {
- ApplicationServiceAppstorePrivate * priv = application_service_appstore_get_instance_private(app->appstore);
-
- GList * lapp;
- gint count;
-
- /* Go through the list and try to find ours */
- for (lapp = priv->applications, count = 0; lapp != NULL; lapp = g_list_next(lapp), count++) {
- if (lapp->data == app) {
- break;
- }
-
- /* If the selected app isn't visible let's not
- count it's position */
- Application * thisapp = (Application *)(lapp->data);
- if (thisapp->visible_state == VISIBLE_STATE_HIDDEN) {
- count--;
- }
- }
-
- if (lapp == NULL) {
- g_warning("Unable to find position for app '%s'", app->id);
- return -1;
- }
-
- return count;
+ ApplicationServiceAppstorePrivate * priv = application_service_appstore_get_instance_private(app->appstore);
+
+ GList * lapp;
+ gint count;
+
+ /* Go through the list and try to find ours */
+ for (lapp = priv->applications, count = 0; lapp != NULL; lapp = g_list_next(lapp), count++) {
+ if (lapp->data == app) {
+ break;
+ }
+
+ /* If the selected app isn't visible let's not
+ count it's position */
+ Application * thisapp = (Application *)(lapp->data);
+ if (thisapp->visible_state == VISIBLE_STATE_HIDDEN) {
+ count--;
+ }
+ }
+
+ if (lapp == NULL) {
+ g_warning("Unable to find position for app '%s'", app->id);
+ return -1;
+ }
+
+ return count;
}
/* A simple global function for dealing with freeing the information
@@ -695,86 +727,89 @@ get_position (Application * app) {
static void
application_free (Application * app)
{
- if (app == NULL) return;
- g_debug("Application free '%s'", app->id);
-
- /* Handle the case where this could be called by unref'ing one of
- the proxy objects. */
- if (app->currently_free) return;
- app->currently_free = TRUE;
-
- ApplicationServiceAppstorePrivate * priv = application_service_appstore_get_instance_private(app->appstore);
-
- /* Remove from the application list */
- priv->applications = g_list_remove(priv->applications, app);
-
- if (app->name_watcher != 0) {
- g_dbus_connection_signal_unsubscribe(g_dbus_proxy_get_connection(app->dbus_proxy), app->name_watcher);
- app->name_watcher = 0;
- }
-
- if (app->props) {
- g_object_unref(app->props);
- }
-
- if (app->props_cancel != NULL) {
- g_cancellable_cancel(app->props_cancel);
- g_object_unref(app->props_cancel);
- app->props_cancel = NULL;
- }
-
- if (app->dbus_proxy) {
- g_object_unref(app->dbus_proxy);
- }
-
- if (app->dbus_proxy_cancel != NULL) {
- g_cancellable_cancel(app->dbus_proxy_cancel);
- g_object_unref(app->dbus_proxy_cancel);
- app->dbus_proxy_cancel = NULL;
- }
-
- if (app->id != NULL) {
- g_free(app->id);
- }
- if (app->category != NULL) {
- g_free(app->category);
- }
- if (app->dbus_name != NULL) {
- g_free(app->dbus_name);
- }
- if (app->dbus_object != NULL) {
- g_free(app->dbus_object);
- }
- if (app->icon != NULL) {
- g_free(app->icon);
- }
- if (app->icon_desc != NULL) {
- g_free(app->icon_desc);
- }
- if (app->aicon != NULL) {
- g_free(app->aicon);
- }
- if (app->aicon_desc != NULL) {
- g_free(app->aicon_desc);
- }
- if (app->menu != NULL) {
- g_free(app->menu);
- }
- if (app->icon_theme_path != NULL) {
- g_free(app->icon_theme_path);
- }
- if (app->label != NULL) {
- g_free(app->label);
- }
- if (app->guide != NULL) {
- g_free(app->guide);
- }
- if (app->title != NULL) {
- g_free(app->title);
- }
-
- g_free(app);
- return;
+ if (app == NULL) return;
+ g_debug("Application free '%s'", app->id);
+
+ /* Handle the case where this could be called by unref'ing one of
+ the proxy objects. */
+ if (app->currently_free) return;
+ app->currently_free = TRUE;
+
+ ApplicationServiceAppstorePrivate * priv = application_service_appstore_get_instance_private(app->appstore);
+
+ /* Remove from the application list */
+ priv->applications = g_list_remove(priv->applications, app);
+
+ if (app->name_watcher != 0) {
+ g_dbus_connection_signal_unsubscribe(g_dbus_proxy_get_connection(app->dbus_proxy), app->name_watcher);
+ app->name_watcher = 0;
+ }
+
+ if (app->props) {
+ g_object_unref(app->props);
+ }
+
+ if (app->props_cancel != NULL) {
+ g_cancellable_cancel(app->props_cancel);
+ g_object_unref(app->props_cancel);
+ app->props_cancel = NULL;
+ }
+
+ if (app->dbus_proxy) {
+ g_object_unref(app->dbus_proxy);
+ }
+
+ if (app->dbus_proxy_cancel != NULL) {
+ g_cancellable_cancel(app->dbus_proxy_cancel);
+ g_object_unref(app->dbus_proxy_cancel);
+ app->dbus_proxy_cancel = NULL;
+ }
+
+ if (app->id != NULL) {
+ g_free(app->id);
+ }
+ if (app->category != NULL) {
+ g_free(app->category);
+ }
+ if (app->dbus_name != NULL) {
+ g_free(app->dbus_name);
+ }
+ if (app->dbus_object != NULL) {
+ g_free(app->dbus_object);
+ }
+ if (app->icon != NULL) {
+ g_free(app->icon);
+ }
+ if (app->icon_desc != NULL) {
+ g_free(app->icon_desc);
+ }
+ if (app->aicon != NULL) {
+ g_free(app->aicon);
+ }
+ if (app->aicon_desc != NULL) {
+ g_free(app->aicon_desc);
+ }
+ if (app->menu != NULL) {
+ g_free(app->menu);
+ }
+ if (app->icon_theme_path != NULL) {
+ g_free(app->icon_theme_path);
+ }
+ if (app->label != NULL) {
+ g_free(app->label);
+ }
+ if (app->guide != NULL) {
+ g_free(app->guide);
+ }
+ if (app->title != NULL) {
+ g_free(app->title);
+ }
+
+ g_free (app->sTooltipIcon);
+ g_free (app->sTooltipTitle);
+ g_free (app->sTooltipDescription);
+ g_free(app);
+ return;
}
/* Gets called when the proxy changes owners, which is usually when it
@@ -782,16 +817,16 @@ application_free (Application * app)
static void
application_died (Application * app)
{
- /* Application died */
- g_debug("Application proxy destroyed '%s'", app->id);
+ /* Application died */
+ g_debug("Application proxy destroyed '%s'", app->id);
- /* Remove from the panel */
- app->status = APP_INDICATOR_STATUS_PASSIVE;
- apply_status(app);
+ /* Remove from the panel */
+ app->status = APP_INDICATOR_STATUS_PASSIVE;
+ apply_status(app);
- /* Destroy the data */
- application_free(app);
- return;
+ /* Destroy the data */
+ application_free(app);
+ return;
}
/* This function takes two Application structure
@@ -799,34 +834,34 @@ application_died (Application * app)
static gint
app_sort_func (gconstpointer a, gconstpointer b, gpointer userdata)
{
- Application * appa = (Application *)a;
- Application * appb = (Application *)b;
- return (appb->ordering_index/2) - (appa->ordering_index/2);
+ Application * appa = (Application *)a;
+ Application * appb = (Application *)b;
+ return (appb->ordering_index/2) - (appa->ordering_index/2);
}
static void
emit_signal (ApplicationServiceAppstore * appstore, const gchar * name,
GVariant * variant)
{
- ApplicationServiceAppstorePrivate * priv = application_service_appstore_get_instance_private(appstore);
+ ApplicationServiceAppstorePrivate * priv = application_service_appstore_get_instance_private(appstore);
- GError * error = NULL;
+ GError * error = NULL;
- g_dbus_connection_emit_signal (priv->bus,
- NULL,
- INDICATOR_APPLICATION_DBUS_OBJ,
- INDICATOR_APPLICATION_DBUS_IFACE,
- name,
- variant,
- &error);
+ g_dbus_connection_emit_signal (priv->bus,
+ NULL,
+ INDICATOR_APPLICATION_DBUS_OBJ,
+ INDICATOR_APPLICATION_DBUS_IFACE,
+ name,
+ variant,
+ &error);
- if (error != NULL) {
- g_critical("Unable to send %s signal: %s", name, error->message);
- g_error_free(error);
- return;
- }
+ if (error != NULL) {
+ g_critical("Unable to send %s signal: %s", name, error->message);
+ g_error_free(error);
+ return;
+ }
- return;
+ return;
}
/* Change the status of the application. If we're going passive
@@ -835,82 +870,85 @@ emit_signal (ApplicationServiceAppstore * appstore, const gchar * name,
static void
apply_status (Application * app)
{
- ApplicationServiceAppstore * appstore = app->appstore;
-
- /* g_debug("Applying status. Status: %d Visible: %d", app->status, app->visible_state); */
-
- visible_state_t goal_state = VISIBLE_STATE_HIDDEN;
-
- if (app->status != APP_INDICATOR_STATUS_PASSIVE) {
- goal_state = VISIBLE_STATE_SHOWN;
- }
-
- /* Nothing needs to change, we're good */
- if (app->visible_state == goal_state /* ) { */
- && goal_state == VISIBLE_STATE_HIDDEN) {
- /* TODO: Uhg, this is a little wrong in that we're going to
- send an icon every time the status changes and the indicator
- is visible even though it might not be updating. But, at
- this point we need a small patch that is harmless. In the
- future we need to track which icon is shown and remove the
- duplicate message. */
- return;
- }
-
- if (app->visible_state != goal_state) {
- g_debug("Changing app '%s' state from %s to %s", app->id, STATE2STRING(app->visible_state), STATE2STRING(goal_state));
- }
-
- /* This means we're going off line */
- if (goal_state == VISIBLE_STATE_HIDDEN) {
- gint position = get_position(app);
- if (position == -1) return;
-
- emit_signal (appstore, "ApplicationRemoved",
- g_variant_new ("(i)", position));
- } else {
- /* Figure out which icon we should be using */
- gchar * newicon = app->icon;
- gchar * newdesc = app->icon_desc;
- if (app->status == APP_INDICATOR_STATUS_ATTENTION && app->aicon != NULL && app->aicon[0] != '\0') {
- newicon = app->aicon;
- newdesc = app->aicon_desc;
- }
-
- if (newdesc == NULL) {
- newdesc = "";
- }
-
- /* Determine whether we're already shown or not */
- if (app->visible_state == VISIBLE_STATE_HIDDEN) {
- /* Put on panel */
- emit_signal (appstore, "ApplicationAdded",
- g_variant_new ("(sisossssss)", newicon,
- get_position(app),
- app->dbus_name, app->menu,
- app->icon_theme_path,
- app->label, app->guide,
- newdesc, app->id, app->title));
- } else {
- /* Icon update */
- gint position = get_position(app);
- if (position == -1) return;
-
- emit_signal (appstore, "ApplicationIconChanged",
- g_variant_new ("(iss)", position, newicon, newdesc));
- emit_signal (appstore, "ApplicationLabelChanged",
- g_variant_new ("(iss)", position,
- app->label != NULL ? app->label : "",
- app->guide != NULL ? app->guide : ""));
- emit_signal (appstore, "ApplicationTitleChanged",
- g_variant_new ("(is)", position,
- app->title != NULL ? app->title : ""));
- }
- }
-
- app->visible_state = goal_state;
-
- return;
+ ApplicationServiceAppstore * appstore = app->appstore;
+
+ /* g_debug("Applying status. Status: %d Visible: %d", app->status, app->visible_state); */
+
+ visible_state_t goal_state = VISIBLE_STATE_HIDDEN;
+
+ if (app->status != APP_INDICATOR_STATUS_PASSIVE) {
+ goal_state = VISIBLE_STATE_SHOWN;
+ }
+
+ /* Nothing needs to change, we're good */
+ if (app->visible_state == goal_state /* ) { */
+ && goal_state == VISIBLE_STATE_HIDDEN) {
+ /* TODO: Uhg, this is a little wrong in that we're going to
+ send an icon every time the status changes and the indicator
+ is visible even though it might not be updating. But, at
+ this point we need a small patch that is harmless. In the
+ future we need to track which icon is shown and remove the
+ duplicate message. */
+ return;
+ }
+
+ if (app->visible_state != goal_state) {
+ g_debug("Changing app '%s' state from %s to %s", app->id, STATE2STRING(app->visible_state), STATE2STRING(goal_state));
+ }
+
+ /* This means we're going off line */
+ if (goal_state == VISIBLE_STATE_HIDDEN) {
+ gint position = get_position(app);
+ if (position == -1) return;
+
+ emit_signal (appstore, "ApplicationRemoved",
+ g_variant_new ("(i)", position));
+ } else {
+ /* Figure out which icon we should be using */
+ gchar * newicon = app->icon;
+ gchar * newdesc = app->icon_desc;
+ if (app->status == APP_INDICATOR_STATUS_ATTENTION && app->aicon != NULL && app->aicon[0] != '\0') {
+ newicon = app->aicon;
+ newdesc = app->aicon_desc;
+ }
+
+ if (newdesc == NULL) {
+ newdesc = "";
+ }
+
+ /* Determine whether we're already shown or not */
+ if (app->visible_state == VISIBLE_STATE_HIDDEN) {
+ /* Put on panel */
+ emit_signal (appstore, "ApplicationAdded",
+ g_variant_new ("(sisosssssssss)", newicon,
+ get_position(app),
+ app->dbus_name, app->menu,
+ app->icon_theme_path,
+ app->label, app->guide,
+ newdesc, app->id, app->title, app->sTooltipIcon != NULL ? app->sTooltipIcon : "", app->sTooltipTitle != NULL ? app->sTooltipTitle : "", app->sTooltipDescription != NULL ? app->sTooltipDescription : ""));
+ } else {
+ /* Icon update */
+ gint position = get_position(app);
+ if (position == -1) return;
+
+ emit_signal (appstore, "ApplicationIconChanged",
+ g_variant_new ("(iss)", position, newicon, newdesc));
+ emit_signal (appstore, "ApplicationLabelChanged",
+ g_variant_new ("(iss)", position,
+ app->label != NULL ? app->label : "",
+ app->guide != NULL ? app->guide : ""));
+ emit_signal (appstore, "ApplicationTitleChanged",
+ g_variant_new ("(is)", position,
+ app->title != NULL ? app->title : ""));
+
+ GVariant *pParams = g_variant_new ("(isss)", position, app->sTooltipIcon != NULL ? app->sTooltipIcon : "", app->sTooltipTitle != NULL ? app->sTooltipTitle : "", app->sTooltipDescription != NULL ? app->sTooltipDescription : "");
+ emit_signal (appstore, "ApplicationTooltipChanged", pParams);
+ }
+ }
+
+ app->visible_state = goal_state;
+
+ return;
}
/* Called when the Notification Item signals that it
@@ -918,10 +956,10 @@ apply_status (Application * app)
static void
new_status (Application * app, const gchar * status)
{
- app->status = string_to_status(status);
- apply_status(app);
+ app->status = string_to_status(status);
+ apply_status(app);
- return;
+ return;
}
/* Called when the Notification Item signals that it
@@ -929,23 +967,23 @@ new_status (Application * app, const gchar * status)
static void
new_icon_theme_path (Application * app, const gchar * icon_theme_path)
{
- if (g_strcmp0(icon_theme_path, app->icon_theme_path)) {
- /* If the new icon theme path is actually a new icon theme path */
- if (app->icon_theme_path != NULL) g_free(app->icon_theme_path);
- app->icon_theme_path = g_strdup(icon_theme_path);
-
- if (app->visible_state != VISIBLE_STATE_HIDDEN) {
- gint position = get_position(app);
- if (position == -1) return;
-
- emit_signal (app->appstore,
- "ApplicationIconThemePathChanged",
- g_variant_new ("(is)", position,
- app->icon_theme_path));
- }
- }
-
- return;
+ if (g_strcmp0(icon_theme_path, app->icon_theme_path)) {
+ /* If the new icon theme path is actually a new icon theme path */
+ if (app->icon_theme_path != NULL) g_free(app->icon_theme_path);
+ app->icon_theme_path = g_strdup(icon_theme_path);
+
+ if (app->visible_state != VISIBLE_STATE_HIDDEN) {
+ gint position = get_position(app);
+ if (position == -1) return;
+
+ emit_signal (app->appstore,
+ "ApplicationIconThemePathChanged",
+ g_variant_new ("(is)", position,
+ app->icon_theme_path));
+ }
+ }
+
+ return;
}
/* Called when the Notification Item signals that it
@@ -953,37 +991,37 @@ new_icon_theme_path (Application * app, const gchar * icon_theme_path)
static void
new_label (Application * app, const gchar * label, const gchar * guide)
{
- gboolean changed = FALSE;
-
- if (g_strcmp0(app->label, label) != 0) {
- changed = TRUE;
- if (app->label != NULL) {
- g_free(app->label);
- app->label = NULL;
- }
- app->label = g_strdup(label);
- }
-
- if (g_strcmp0(app->guide, guide) != 0) {
- changed = TRUE;
- if (app->guide != NULL) {
- g_free(app->guide);
- app->guide = NULL;
- }
- app->guide = g_strdup(guide);
- }
-
- if (changed) {
- gint position = get_position(app);
- if (position == -1) return;
-
- emit_signal (app->appstore, "ApplicationLabelChanged",
- g_variant_new ("(iss)", position,
- app->label != NULL ? app->label : "",
- app->guide != NULL ? app->guide : ""));
- }
-
- return;
+ gboolean changed = FALSE;
+
+ if (g_strcmp0(app->label, label) != 0) {
+ changed = TRUE;
+ if (app->label != NULL) {
+ g_free(app->label);
+ app->label = NULL;
+ }
+ app->label = g_strdup(label);
+ }
+
+ if (g_strcmp0(app->guide, guide) != 0) {
+ changed = TRUE;
+ if (app->guide != NULL) {
+ g_free(app->guide);
+ app->guide = NULL;
+ }
+ app->guide = g_strdup(guide);
+ }
+
+ if (changed) {
+ gint position = get_position(app);
+ if (position == -1) return;
+
+ emit_signal (app->appstore, "ApplicationLabelChanged",
+ g_variant_new ("(iss)", position,
+ app->label != NULL ? app->label : "",
+ app->guide != NULL ? app->guide : ""));
+ }
+
+ return;
}
/* Adding a new NotificationItem object from DBus in to the
@@ -992,62 +1030,65 @@ new_label (Application * app, const gchar * label, const gchar * guide)
void
application_service_appstore_application_add (ApplicationServiceAppstore * appstore, const gchar * dbus_name, const gchar * dbus_object)
{
- g_debug("Adding new application: %s:%s", dbus_name, dbus_object);
-
- /* Make sure we got a sensible request */
- g_return_if_fail(IS_APPLICATION_SERVICE_APPSTORE(appstore));
- g_return_if_fail(dbus_name != NULL && dbus_name[0] != '\0');
- g_return_if_fail(dbus_object != NULL && dbus_object[0] != '\0');
- Application * app = find_application(appstore, dbus_name, dbus_object);
-
- if (app != NULL) {
- g_debug("Application already exists, re-requesting properties.");
- get_all_properties(app);
- return;
- }
-
- /* Build the application entry. This will be carried
- along until we're sure we've got everything. */
- app = g_new0(Application, 1);
-
- app->validated = FALSE;
- app->dbus_name = g_strdup(dbus_name);
- app->dbus_object = g_strdup(dbus_object);
- app->appstore = appstore;
- app->status = APP_INDICATOR_STATUS_PASSIVE;
- app->icon = NULL;
- app->aicon = NULL;
- app->menu = NULL;
- app->icon_theme_path = NULL;
- app->label = NULL;
- app->guide = NULL;
- app->title = NULL;
- app->currently_free = FALSE;
- app->ordering_index = 0;
- app->visible_state = VISIBLE_STATE_HIDDEN;
- app->name_watcher = 0;
- app->props_cancel = NULL;
- app->props = NULL;
- app->queued_props = FALSE;
-
- /* Get the DBus proxy for the NotificationItem interface */
- app->dbus_proxy_cancel = g_cancellable_new();
- g_dbus_proxy_new_for_bus(G_BUS_TYPE_SESSION,
- G_DBUS_PROXY_FLAGS_NONE,
- NULL,
- app->dbus_name,
- app->dbus_object,
- NOTIFICATION_ITEM_DBUS_IFACE,
- app->dbus_proxy_cancel,
- dbus_proxy_cb,
- app);
-
- ApplicationServiceAppstorePrivate * priv = application_service_appstore_get_instance_private(app->appstore);
- priv->applications = g_list_insert_sorted_with_data (priv->applications, app, app_sort_func, NULL);
-
- /* We're returning, nothing is yet added until the properties
- come back and give us more info. */
- return;
+ g_debug("Adding new application: %s:%s", dbus_name, dbus_object);
+
+ /* Make sure we got a sensible request */
+ g_return_if_fail(IS_APPLICATION_SERVICE_APPSTORE(appstore));
+ g_return_if_fail(dbus_name != NULL && dbus_name[0] != '\0');
+ g_return_if_fail(dbus_object != NULL && dbus_object[0] != '\0');
+ Application * app = find_application(appstore, dbus_name, dbus_object);
+
+ if (app != NULL) {
+ g_debug("Application already exists, re-requesting properties.");
+ get_all_properties(app);
+ return;
+ }
+
+ /* Build the application entry. This will be carried
+ along until we're sure we've got everything. */
+ app = g_new0(Application, 1);
+
+ app->validated = FALSE;
+ app->dbus_name = g_strdup(dbus_name);
+ app->dbus_object = g_strdup(dbus_object);
+ app->appstore = appstore;
+ app->status = APP_INDICATOR_STATUS_PASSIVE;
+ app->icon = NULL;
+ app->aicon = NULL;
+ app->menu = NULL;
+ app->icon_theme_path = NULL;
+ app->label = NULL;
+ app->guide = NULL;
+ app->title = NULL;
+ app->currently_free = FALSE;
+ app->ordering_index = 0;
+ app->visible_state = VISIBLE_STATE_HIDDEN;
+ app->name_watcher = 0;
+ app->props_cancel = NULL;
+ app->props = NULL;
+ app->queued_props = FALSE;
+ app->sTooltipIcon = NULL;
+ app->sTooltipTitle = NULL;
+ app->sTooltipDescription = NULL;
+
+ /* Get the DBus proxy for the NotificationItem interface */
+ app->dbus_proxy_cancel = g_cancellable_new();
+ g_dbus_proxy_new_for_bus(G_BUS_TYPE_SESSION,
+ G_DBUS_PROXY_FLAGS_NONE,
+ NULL,
+ app->dbus_name,
+ app->dbus_object,
+ NOTIFICATION_ITEM_DBUS_IFACE,
+ app->dbus_proxy_cancel,
+ dbus_proxy_cb,
+ app);
+
+ ApplicationServiceAppstorePrivate * priv = application_service_appstore_get_instance_private(app->appstore);
+ priv->applications = g_list_insert_sorted_with_data (priv->applications, app, app_sort_func, NULL);
+
+ /* We're returning, nothing is yet added until the properties
+ come back and give us more info. */
+ return;
}
static void
@@ -1056,113 +1097,113 @@ name_changed (GDBusConnection * connection, const gchar * sender_name,
const gchar * signal_name, GVariant * parameters,
gpointer user_data)
{
- Application * app = (Application *)user_data;
+ Application * app = (Application *)user_data;
- gchar * new_name = NULL;
- g_variant_get(parameters, "(sss)", NULL, NULL, &new_name);
+ gchar * new_name = NULL;
+ g_variant_get(parameters, "(sss)", NULL, NULL, &new_name);
- if (new_name == NULL || new_name[0] == 0)
- application_died(app);
+ if (new_name == NULL || new_name[0] == 0)
+ application_died(app);
- g_free(new_name);
+ g_free(new_name);
}
/* Callback from trying to create the proxy for the app. */
static void
dbus_proxy_cb (GObject * object, GAsyncResult * res, gpointer user_data)
{
- GError * error = NULL;
-
- Application * app = (Application *)user_data;
- g_return_if_fail(app != NULL);
-
- GDBusProxy * proxy = g_dbus_proxy_new_for_bus_finish(res, &error);
-
- if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) {
- g_error_free (error);
- return; // Must exit before accessing freed memory
- }
-
- if (app->dbus_proxy_cancel != NULL) {
- g_object_unref(app->dbus_proxy_cancel);
- app->dbus_proxy_cancel = NULL;
- }
-
- if (error != NULL) {
- g_critical("Could not grab DBus proxy for %s: %s", app->dbus_name, error->message);
- g_error_free(error);
- application_free(app);
- return;
- }
-
- /* Okay, we're good to grab the proxy at this point, we're
- sure that it's ours. */
- app->dbus_proxy = proxy;
-
- /* We've got it, let's watch it for destruction */
- app->name_watcher = g_dbus_connection_signal_subscribe(
- g_dbus_proxy_get_connection(proxy),
- "org.freedesktop.DBus",
- "org.freedesktop.DBus",
- "NameOwnerChanged",
- "/org/freedesktop/DBus",
- g_dbus_proxy_get_name(proxy),
- G_DBUS_SIGNAL_FLAGS_NONE,
- name_changed,
- app,
- NULL);
-
- g_signal_connect(proxy, "g-signal", G_CALLBACK(app_receive_signal), app);
-
- app->props_cancel = g_cancellable_new();
- g_dbus_proxy_new(g_dbus_proxy_get_connection(proxy),
- G_DBUS_PROXY_FLAGS_NONE,
- NULL,
- app->dbus_name,
- app->dbus_object,
- "org.freedesktop.DBus.Properties",
- app->props_cancel,
- props_cb,
- app);
-
- return;
+ GError * error = NULL;
+
+ Application * app = (Application *)user_data;
+ g_return_if_fail(app != NULL);
+
+ GDBusProxy * proxy = g_dbus_proxy_new_for_bus_finish(res, &error);
+
+ if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) {
+ g_error_free (error);
+ return; // Must exit before accessing freed memory
+ }
+
+ if (app->dbus_proxy_cancel != NULL) {
+ g_object_unref(app->dbus_proxy_cancel);
+ app->dbus_proxy_cancel = NULL;
+ }
+
+ if (error != NULL) {
+ g_critical("Could not grab DBus proxy for %s: %s", app->dbus_name, error->message);
+ g_error_free(error);
+ application_free(app);
+ return;
+ }
+
+ /* Okay, we're good to grab the proxy at this point, we're
+ sure that it's ours. */
+ app->dbus_proxy = proxy;
+
+ /* We've got it, let's watch it for destruction */
+ app->name_watcher = g_dbus_connection_signal_subscribe(
+ g_dbus_proxy_get_connection(proxy),
+ "org.freedesktop.DBus",
+ "org.freedesktop.DBus",
+ "NameOwnerChanged",
+ "/org/freedesktop/DBus",
+ g_dbus_proxy_get_name(proxy),
+ G_DBUS_SIGNAL_FLAGS_NONE,
+ name_changed,
+ app,
+ NULL);
+
+ g_signal_connect(proxy, "g-signal", G_CALLBACK(app_receive_signal), app);
+
+ app->props_cancel = g_cancellable_new();
+ g_dbus_proxy_new(g_dbus_proxy_get_connection(proxy),
+ G_DBUS_PROXY_FLAGS_NONE,
+ NULL,
+ app->dbus_name,
+ app->dbus_object,
+ "org.freedesktop.DBus.Properties",
+ app->props_cancel,
+ props_cb,
+ app);
+
+ return;
}
/* Callback from trying to create the proxy for the app. */
static void
props_cb (GObject * object, GAsyncResult * res, gpointer user_data)
{
- GError * error = NULL;
+ GError * error = NULL;
- Application * app = (Application *)user_data;
- g_return_if_fail(app != NULL);
+ Application * app = (Application *)user_data;
+ g_return_if_fail(app != NULL);
- GDBusProxy * proxy = g_dbus_proxy_new_for_bus_finish(res, &error);
+ GDBusProxy * proxy = g_dbus_proxy_new_for_bus_finish(res, &error);
- if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) {
- g_error_free (error);
- return; // Must exit before accessing freed memory
- }
+ if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) {
+ g_error_free (error);
+ return; // Must exit before accessing freed memory
+ }
- if (app->props_cancel != NULL) {
- g_object_unref(app->props_cancel);
- app->props_cancel = NULL;
- }
+ if (app->props_cancel != NULL) {
+ g_object_unref(app->props_cancel);
+ app->props_cancel = NULL;
+ }
- if (error != NULL) {
- g_critical("Could not grab Properties DBus proxy for %s: %s", app->dbus_name, error->message);
- g_error_free(error);
- application_free(app);
- return;
- }
+ if (error != NULL) {
+ g_critical("Could not grab Properties DBus proxy for %s: %s", app->dbus_name, error->message);
+ g_error_free(error);
+ application_free(app);
+ return;
+ }
- /* Okay, we're good to grab the proxy at this point, we're
- sure that it's ours. */
- app->props = proxy;
+ /* Okay, we're good to grab the proxy at this point, we're
+ sure that it's ours. */
+ app->props = proxy;
- get_all_properties(app);
+ get_all_properties(app);
- return;
+ return;
}
/* Receives all signals from the service, routed to the appropriate functions */
@@ -1170,85 +1211,88 @@ static void
app_receive_signal (GDBusProxy * proxy, gchar * sender_name, gchar * signal_name,
GVariant * parameters, gpointer user_data)
{
- Application * app = (Application *)user_data;
-
- if (!app->validated) return;
-
- if (g_strcmp0(signal_name, NOTIFICATION_ITEM_SIG_NEW_ICON) == 0) {
- /* icon name isn't provided by signal, so look it up */
- get_all_properties(app);
- }
- else if (g_strcmp0(signal_name, NOTIFICATION_ITEM_SIG_NEW_AICON) == 0) {
- /* aicon name isn't provided by signal, so look it up */
- get_all_properties(app);
- }
- else if (g_strcmp0(signal_name, NOTIFICATION_ITEM_SIG_NEW_TITLE) == 0) {
- /* title name isn't provided by signal, so look it up */
- get_all_properties(app);
- }
- else if (g_strcmp0(signal_name, NOTIFICATION_ITEM_SIG_NEW_STATUS) == 0) {
- gchar * status = NULL;
- g_variant_get(parameters, "(s)", &status);
- new_status(app, status);
- g_free(status);
- }
- else if (g_strcmp0(signal_name, NOTIFICATION_ITEM_SIG_NEW_ICON_THEME_PATH) == 0) {
- gchar * icon_theme_path = NULL;
- g_variant_get(parameters, "(s)", &icon_theme_path);
- new_icon_theme_path(app, icon_theme_path);
- g_free(icon_theme_path);
- }
- else if (g_strcmp0(signal_name, NOTIFICATION_ITEM_SIG_NEW_LABEL) == 0) {
- gchar * label = NULL, * guide = NULL;
- g_variant_get(parameters, "(ss)", &label, &guide);
- new_label(app, label, guide);
- g_free(label);
- g_free(guide);
- }
-
- return;
+ Application * app = (Application *)user_data;
+
+ if (!app->validated) return;
+
+ if (g_strcmp0(signal_name, NOTIFICATION_ITEM_SIG_NEW_ICON) == 0) {
+ /* icon name isn't provided by signal, so look it up */
+ get_all_properties(app);
+ }
+ else if (g_strcmp0(signal_name, NOTIFICATION_ITEM_SIG_NEW_AICON) == 0) {
+ /* aicon name isn't provided by signal, so look it up */
+ get_all_properties(app);
+ }
+ else if (g_strcmp0(signal_name, NOTIFICATION_ITEM_SIG_NEW_TITLE) == 0) {
+ /* title name isn't provided by signal, so look it up */
+ get_all_properties(app);
+ }
+ else if (g_strcmp0(signal_name, NOTIFICATION_ITEM_SIG_NEW_STATUS) == 0) {
+ gchar * status = NULL;
+ g_variant_get(parameters, "(s)", &status);
+ new_status(app, status);
+ g_free(status);
+ }
+ else if (g_strcmp0(signal_name, NOTIFICATION_ITEM_SIG_NEW_ICON_THEME_PATH) == 0) {
+ gchar * icon_theme_path = NULL;
+ g_variant_get(parameters, "(s)", &icon_theme_path);
+ new_icon_theme_path(app, icon_theme_path);
+ g_free(icon_theme_path);
+ }
+ else if (g_strcmp0(signal_name, NOTIFICATION_ITEM_SIG_NEW_LABEL) == 0) {
+ gchar * label = NULL, * guide = NULL;
+ g_variant_get(parameters, "(ss)", &label, &guide);
+ new_label(app, label, guide);
+ g_free(label);
+ g_free(guide);
+ }
+ else if (g_strcmp0 (signal_name, NOTIFICATION_ITEM_SIG_NEW_TOOLTIP) == 0)
+ {
+ // The tooltip data isn't provided by the signal, so look it up
+ get_all_properties (app);
+ }
}
/* Looks for an application in the list of applications */
static Application *
find_application (ApplicationServiceAppstore * appstore, const gchar * address, const gchar * object)
{
- ApplicationServiceAppstorePrivate * priv = application_service_appstore_get_instance_private(appstore);
+ ApplicationServiceAppstorePrivate * priv = application_service_appstore_get_instance_private(appstore);
- GList * listpntr;
+ GList * listpntr;
- for (listpntr = priv->applications; listpntr != NULL; listpntr = g_list_next(listpntr)) {
- Application * app = (Application *)listpntr->data;
+ for (listpntr = priv->applications; listpntr != NULL; listpntr = g_list_next(listpntr)) {
+ Application * app = (Application *)listpntr->data;
- if (!g_strcmp0(app->dbus_name, address) && !g_strcmp0(app->dbus_object, object)) {
- return app;
- }
- }
+ if (!g_strcmp0(app->dbus_name, address) && !g_strcmp0(app->dbus_object, object)) {
+ return app;
+ }
+ }
- return NULL;
+ return NULL;
}
/* Looks for an application in the list of applications with the matching menu */
static Application *
find_application_by_menu (ApplicationServiceAppstore * appstore, const gchar * address, const gchar * menuobject)
{
- g_return_val_if_fail(appstore, NULL);
- g_return_val_if_fail(address, NULL);
- g_return_val_if_fail(menuobject, NULL);
+ g_return_val_if_fail(appstore, NULL);
+ g_return_val_if_fail(address, NULL);
+ g_return_val_if_fail(menuobject, NULL);
- ApplicationServiceAppstorePrivate * priv = application_service_appstore_get_instance_private(appstore);
+ ApplicationServiceAppstorePrivate * priv = application_service_appstore_get_instance_private(appstore);
- GList *l;
+ GList *l;
- for (l = priv->applications; l != NULL; l = l->next) {
- Application *a = l->data;
- if (g_strcmp0(a->dbus_name, address) == 0 &&
- g_strcmp0(a->menu, menuobject) == 0) {
- return a;
- }
- }
+ for (l = priv->applications; l != NULL; l = l->next) {
+ Application *a = l->data;
+ if (g_strcmp0(a->dbus_name, address) == 0 &&
+ g_strcmp0(a->menu, menuobject) == 0) {
+ return a;
+ }
+ }
- return NULL;
+ return NULL;
}
/* Removes an application. Currently only works for the apps
@@ -1256,37 +1300,37 @@ find_application_by_menu (ApplicationServiceAppstore * appstore, const gchar * a
void
application_service_appstore_application_remove (ApplicationServiceAppstore * appstore, const gchar * dbus_name, const gchar * dbus_object)
{
- g_return_if_fail(IS_APPLICATION_SERVICE_APPSTORE(appstore));
- g_return_if_fail(dbus_name != NULL && dbus_name[0] != '\0');
- g_return_if_fail(dbus_object != NULL && dbus_object[0] != '\0');
-
- Application * app = find_application(appstore, dbus_name, dbus_object);
- if (app != NULL) {
- application_died(app);
- } else {
- g_warning("Unable to find application %s:%s", dbus_name, dbus_object);
- }
-
- return;
+ g_return_if_fail(IS_APPLICATION_SERVICE_APPSTORE(appstore));
+ g_return_if_fail(dbus_name != NULL && dbus_name[0] != '\0');
+ g_return_if_fail(dbus_object != NULL && dbus_object[0] != '\0');
+
+ Application * app = find_application(appstore, dbus_name, dbus_object);
+ if (app != NULL) {
+ application_died(app);
+ } else {
+ g_warning("Unable to find application %s:%s", dbus_name, dbus_object);
+ }
+
+ return;
}
gchar**
application_service_appstore_application_get_list (ApplicationServiceAppstore * appstore)
{
- ApplicationServiceAppstorePrivate * priv = application_service_appstore_get_instance_private(appstore);
+ ApplicationServiceAppstorePrivate * priv = application_service_appstore_get_instance_private(appstore);
- gchar ** out;
- gchar ** outpntr;
- GList * listpntr;
+ gchar ** out;
+ gchar ** outpntr;
+ GList * listpntr;
- out = g_new(gchar*, g_list_length(priv->applications) + 1);
+ out = g_new(gchar*, g_list_length(priv->applications) + 1);
- for (listpntr = priv->applications, outpntr = out; listpntr != NULL; listpntr = g_list_next(listpntr), ++outpntr) {
- Application * app = (Application *)listpntr->data;
- *outpntr = g_strdup_printf("%s%s", app->dbus_name, app->dbus_object);
- }
- *outpntr = 0;
- return out;
+ for (listpntr = priv->applications, outpntr = out; listpntr != NULL; listpntr = g_list_next(listpntr), ++outpntr) {
+ Application * app = (Application *)listpntr->data;
+ *outpntr = g_strdup_printf("%s%s", app->dbus_name, app->dbus_object);
+ }
+ *outpntr = 0;
+ return out;
}
/* Creates a basic appstore object and attaches the
@@ -1294,53 +1338,53 @@ application_service_appstore_application_get_list (ApplicationServiceAppstore *
ApplicationServiceAppstore *
application_service_appstore_new (void)
{
- ApplicationServiceAppstore * appstore = APPLICATION_SERVICE_APPSTORE(g_object_new(APPLICATION_SERVICE_APPSTORE_TYPE, NULL));
- return appstore;
+ ApplicationServiceAppstore * appstore = APPLICATION_SERVICE_APPSTORE(g_object_new(APPLICATION_SERVICE_APPSTORE_TYPE, NULL));
+ return appstore;
}
/* DBus Interface */
static GVariant *
get_applications (ApplicationServiceAppstore * appstore)
{
- ApplicationServiceAppstorePrivate * priv = application_service_appstore_get_instance_private(appstore);
-
- GVariant * out = NULL;
-
- if (g_list_length(priv->applications) > 0) {
- GVariantBuilder builder;
- GList * listpntr;
- gint position = 0;
-
- g_variant_builder_init(&builder, G_VARIANT_TYPE ("a(sisossssss)"));
-
- for (listpntr = priv->applications; listpntr != NULL; listpntr = g_list_next(listpntr)) {
- Application * app = (Application *)listpntr->data;
- if (app->visible_state == VISIBLE_STATE_HIDDEN) {
- continue;
- }
-
- g_variant_builder_add (&builder, "(sisossssss)", app->icon,
- position++, app->dbus_name, app->menu,
- app->icon_theme_path, app->label,
- app->guide,
- (app->icon_desc != NULL) ? app->icon_desc : "",
- app->id, app->title);
- }
-
- out = g_variant_builder_end(&builder);
- } else {
- GError * error = NULL;
- out = g_variant_parse(g_variant_type_new("a(sisossssss)"), "[]", NULL, NULL, &error);
- if (error != NULL) {
- g_warning("Unable to parse '[]' as a 'a(sisossssss)': %s", error->message);
- out = NULL;
- g_error_free(error);
- }
- }
-
- if (out != NULL) {
- return g_variant_new_tuple(&out, 1);
- } else {
- return NULL;
- }
+ ApplicationServiceAppstorePrivate * priv = application_service_appstore_get_instance_private(appstore);
+
+ GVariant * out = NULL;
+
+ if (g_list_length(priv->applications) > 0) {
+ GVariantBuilder builder;
+ GList * listpntr;
+ gint position = 0;
+
+ g_variant_builder_init(&builder, G_VARIANT_TYPE ("a(sisosssssssss)"));
+
+ for (listpntr = priv->applications; listpntr != NULL; listpntr = g_list_next(listpntr)) {
+ Application * app = (Application *)listpntr->data;
+ if (app->visible_state == VISIBLE_STATE_HIDDEN) {
+ continue;
+ }
+
+ g_variant_builder_add (&builder, "(sisosssssssss)", app->icon,
+ position++, app->dbus_name, app->menu,
+ app->icon_theme_path, app->label,
+ app->guide,
+ (app->icon_desc != NULL) ? app->icon_desc : "",
+ app->id, app->title, app->sTooltipIcon != NULL ? app->sTooltipIcon : "", app->sTooltipTitle != NULL ? app->sTooltipTitle : "", app->sTooltipDescription != NULL ? app->sTooltipDescription : "");
+ }
+
+ out = g_variant_builder_end(&builder);
+ } else {
+ GError * error = NULL;
+ out = g_variant_parse(g_variant_type_new("a(sisosssssssss)"), "[]", NULL, NULL, &error);
+ if (error != NULL) {
+ g_warning("Unable to parse '[]' as a 'a(sisosssssssss)': %s", error->message);
+ out = NULL;
+ g_error_free(error);
+ }
+ }
+
+ if (out != NULL) {
+ return g_variant_new_tuple(&out, 1);
+ } else {
+ return NULL;
+ }
}
diff --git a/src/ayatana-application-service-marshal.list b/src/ayatana-application-service-marshal.list
index 2b2efa5..d89209d 100644
--- a/src/ayatana-application-service-marshal.list
+++ b/src/ayatana-application-service-marshal.list
@@ -1,23 +1,25 @@
# Marshaller definitions to be generated.
-#
+#
# Copyright 2009 Canonical Ltd.
-#
+# Copyright 2025 Robert Tari
+#
# Authors:
# Ted Gould <ted@canonical.com>
-#
-# This program is free software: you can redistribute it and/or modify it
-# under the terms of the GNU General Public License version 3, as published
+# Robert Tari <robert@tari.in>
+#
+# This program is free software: you can redistribute it and/or modify it
+# under the terms of the GNU General Public License version 3, as published
# by the Free Software Foundation.
-#
-# This program is distributed in the hope that it will be useful, but
-# WITHOUT ANY WARRANTY; without even the implied warranties of
-# MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
+#
+# This program is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranties of
+# MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
# PURPOSE. See the GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License along
+#
+# You should have received a copy of the GNU General Public License along
# with this program. If not, see <http://www.gnu.org/licenses/>.
VOID: STRING, INT, STRING, STRING, STRING, STRING, STRING
VOID: INT, STRING, STRING
VOID: INT, STRING
VOID: STRING, STRING
-VOID: BOOL, STRING, OBJECT
+VOID: BOOLEAN, STRING, OBJECT
diff --git a/src/ayatana-application-service.xml b/src/ayatana-application-service.xml
index 93a3ec6..867b17b 100644
--- a/src/ayatana-application-service.xml
+++ b/src/ayatana-application-service.xml
@@ -4,77 +4,88 @@ An interface for communication between the service and indicator.
Copyright 2009 Canonical Ltd.
Copyright 2015 Arctica Project
+Copyright 2024 Robert Tari
Authors:
Ted Gould <ted@canonical.com>
Mike Gabriel <mike.gabriel@das-netzwerkteam.de>
+ Robert Tari <robert@tari.in>
-This program is free software: you can redistribute it and/or modify it
-under the terms of the GNU General Public License version 3, as published
+This program is free software: you can redistribute it and/or modify it
+under the terms of the GNU General Public License version 3, as published
by the Free Software Foundation.
-This program is distributed in the hope that it will be useful, but
-WITHOUT ANY WARRANTY; without even the implied warranties of
-MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
+This program is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranties of
+MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
PURPOSE. See the GNU General Public License for more details.
-You should have received a copy of the GNU General Public License along
+You should have received a copy of the GNU General Public License along
with this program. If not, see <http://www.gnu.org/licenses/>.
-->
<node name="/">
- <interface name="org.ayatana.indicator.application.service">
+ <interface name="org.ayatana.indicator.application.service">
<!-- Properties -->
- <!-- None currently -->
+ <!-- None currently -->
<!-- Methods -->
- <method name="GetApplications">
- <arg type="a(sisossssss)" name="applications" direction="out" />
- </method>
- <method name="ApplicationScrollEvent">
- <arg type="s" name="dbusaddress" direction="in" />
- <arg type="s" name="dbusobject" direction="in" />
- <arg type="i" name="delta" direction="in" />
- <arg type="u" name="direction" direction="in" />
- </method>
- <method name="ApplicationSecondaryActivateEvent">
- <arg type="s" name="dbusaddress" direction="in" />
- <arg type="s" name="dbusobject" direction="in" />
- <arg type="u" name="time" direction="in" />
- </method>
+ <method name="GetApplications">
+ <arg type="a(sisosssssssss)" name="applications" direction="out" />
+ </method>
+ <method name="ApplicationScrollEvent">
+ <arg type="s" name="dbusaddress" direction="in" />
+ <arg type="s" name="dbusobject" direction="in" />
+ <arg type="i" name="delta" direction="in" />
+ <arg type="u" name="direction" direction="in" />
+ </method>
+ <method name="ApplicationSecondaryActivateEvent">
+ <arg type="s" name="dbusaddress" direction="in" />
+ <arg type="s" name="dbusobject" direction="in" />
+ <arg type="u" name="time" direction="in" />
+ </method>
<!-- Signals -->
- <signal name="ApplicationAdded">
- <arg type="s" name="iconname" direction="out" />
- <arg type="i" name="position" direction="out" />
- <arg type="s" name="dbusaddress" direction="out" />
- <arg type="o" name="dbusobject" direction="out" />
- <arg type="s" name="iconpath" direction="out" />
- <arg type="s" name="label" direction="out" />
- <arg type="s" name="labelguide" direction="out" />
- <arg type="s" name="accessibledesc" direction="out" />
- <arg type="s" name="hint" direction="out" />
- <arg type="s" name="title" direction="out" />
- </signal>
- <signal name="ApplicationRemoved">
- <arg type="i" name="position" direction="out" />
- </signal>
- <signal name="ApplicationIconChanged">
- <arg type="i" name="position" direction="out" />
- <arg type="s" name="icon_name" direction="out" />
- <arg type="s" name="icon_desc" direction="out" />
- </signal>
- <signal name="ApplicationIconThemePathChanged">
- <arg type="i" name="position" direction="out" />
- <arg type="s" name="icon_theme_path" direction="out" />
- </signal>
- <signal name="ApplicationLabelChanged">
- <arg type="i" name="position" direction="out" />
- <arg type="s" name="label" direction="out" />
- <arg type="s" name="guide" direction="out" />
- </signal>
- <signal name="ApplicationTitleChanged">
- <arg type="i" name="position" direction="out" />
- <arg type="s" name="title" direction="out" />
- </signal>
- </interface>
+ <signal name="ApplicationAdded">
+ <arg type="s" name="iconname" direction="out" />
+ <arg type="i" name="position" direction="out" />
+ <arg type="s" name="dbusaddress" direction="out" />
+ <arg type="o" name="dbusobject" direction="out" />
+ <arg type="s" name="iconpath" direction="out" />
+ <arg type="s" name="label" direction="out" />
+ <arg type="s" name="labelguide" direction="out" />
+ <arg type="s" name="accessibledesc" direction="out" />
+ <arg type="s" name="hint" direction="out" />
+ <arg type="s" name="title" direction="out" />
+ <arg type="s" name="tooltipicon" direction="out" />
+ <arg type="s" name="tooltiptitle" direction="out" />
+ <arg type="s" name="tooltipdescription" direction="out" />
+ </signal>
+ <signal name="ApplicationRemoved">
+ <arg type="i" name="position" direction="out" />
+ </signal>
+ <signal name="ApplicationIconChanged">
+ <arg type="i" name="position" direction="out" />
+ <arg type="s" name="icon_name" direction="out" />
+ <arg type="s" name="icon_desc" direction="out" />
+ </signal>
+ <signal name="ApplicationIconThemePathChanged">
+ <arg type="i" name="position" direction="out" />
+ <arg type="s" name="icon_theme_path" direction="out" />
+ </signal>
+ <signal name="ApplicationLabelChanged">
+ <arg type="i" name="position" direction="out" />
+ <arg type="s" name="label" direction="out" />
+ <arg type="s" name="guide" direction="out" />
+ </signal>
+ <signal name="ApplicationTitleChanged">
+ <arg type="i" name="position" direction="out" />
+ <arg type="s" name="title" direction="out" />
+ </signal>
+ <signal name="ApplicationTooltipChanged">
+ <arg type="i" name="position" direction="out" />
+ <arg type="s" name="icon" direction="out" />
+ <arg type="s" name="title" direction="out" />
+ <arg type="s" name="description" direction="out" />
+ </signal>
+ </interface>
</node>
diff --git a/src/generate-id.h b/src/generate-id.h
index 1d2da21..48343ee 100644
--- a/src/generate-id.h
+++ b/src/generate-id.h
@@ -2,20 +2,22 @@
Quick litte lack to generate the ordering ID.
Copyright 2010 Canonical Ltd.
+Copyright 2025 Robert Tari
Authors:
Ted Gould <ted@canonical.com>
+ Robert Tari <robert@tari.in>
-This program is free software: you can redistribute it and/or modify it
-under the terms of the GNU General Public License version 3, as published
+This program is free software: you can redistribute it and/or modify it
+under the terms of the GNU General Public License version 3, as published
by the Free Software Foundation.
-This program is distributed in the hope that it will be useful, but
-WITHOUT ANY WARRANTY; without even the implied warranties of
-MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
+This program is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranties of
+MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
PURPOSE. See the GNU General Public License for more details.
-You should have received a copy of the GNU General Public License along
+You should have received a copy of the GNU General Public License along
with this program. If not, see <http://www.gnu.org/licenses/>.
*/
@@ -23,7 +25,7 @@ with this program. If not, see <http://www.gnu.org/licenses/>.
#define __GENERATE_ID_H__
#include <glib.h>
-#include "libayatana-appindicator/app-indicator.h"
+#include "libayatana-appindicator-glib/ayatana-appindicator.h"
guint32 generate_id (const AppIndicatorCategory category, const gchar * id);
diff --git a/src/indicator-application.c b/src/indicator-application.c
index 24bdb92..556d264 100644
--- a/src/indicator-application.c
+++ b/src/indicator-application.c
@@ -4,20 +4,22 @@ given by the service and turns it into real-world pixels that users can
actually use. Well, GTK does that, but this asks nicely.
Copyright 2009 Canonical Ltd.
+Copyright 2024-2025 Robert Tari
Authors:
Ted Gould <ted@canonical.com>
+ Robert Tari <robert@tari.in>
-This program is free software: you can redistribute it and/or modify it
-under the terms of the GNU General Public License version 3, as published
+This program is free software: you can redistribute it and/or modify it
+under the terms of the GNU General Public License version 3, as published
by the Free Software Foundation.
-This program is distributed in the hope that it will be useful, but
-WITHOUT ANY WARRANTY; without even the implied warranties of
-MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
+This program is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranties of
+MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
PURPOSE. See the GNU General Public License for more details.
-You should have received a copy of the GNU General Public License along
+You should have received a copy of the GNU General Public License along
with this program. If not, see <http://www.gnu.org/licenses/>.
*/
@@ -57,11 +59,11 @@ typedef struct _IndicatorApplication IndicatorApplication;
typedef struct _IndicatorApplicationClass IndicatorApplicationClass;
struct _IndicatorApplicationClass {
- IndicatorObjectClass parent_class;
+ IndicatorObjectClass parent_class;
};
struct _IndicatorApplication {
- IndicatorObject parent;
+ IndicatorObject parent;
};
GType indicator_application_get_type (void);
@@ -74,24 +76,31 @@ INDICATOR_SET_TYPE(INDICATOR_APPLICATION_TYPE)
#endif
typedef struct {
- GCancellable * service_proxy_cancel;
- GDBusProxy * service_proxy;
- GList * applications;
- GHashTable * theme_dirs;
- guint disconnect_kill;
- GCancellable * get_apps_cancel;
- guint watch;
+ GCancellable * service_proxy_cancel;
+ GDBusProxy * service_proxy;
+ GList * applications;
+ GHashTable * theme_dirs;
+ guint disconnect_kill;
+ GCancellable * get_apps_cancel;
+ guint watch;
+ GDBusConnection *pConnection;
} IndicatorApplicationPrivate;
typedef struct _ApplicationEntry ApplicationEntry;
struct _ApplicationEntry {
- IndicatorObjectEntry entry;
- gchar * icon_theme_path;
- gboolean old_service;
- gchar * dbusobject;
- gchar * dbusaddress;
- gchar * guide;
- gchar * longname;
+ IndicatorObjectEntry entry;
+ gchar * icon_theme_path;
+ gboolean old_service;
+ gchar * dbusobject;
+ gchar * dbusaddress;
+ gchar * guide;
+ gchar * longname;
+ gint nPosition;
+ GMenuModel *pModel;
+ GActionGroup *pActions;
+ gboolean bMenuShown;
+ gchar *sTooltipIcon;
+ gchar *sTooltipMarkup;
};
static void indicator_application_class_init (IndicatorApplicationClass *klass);
@@ -107,7 +116,7 @@ static void disconnected (GDBusConnection * con, const gchar * name, gpointer us
static void disconnected_helper (gpointer data, gpointer user_data);
static gboolean disconnected_kill (gpointer user_data);
static void disconnected_kill_helper (gpointer data, gpointer user_data);
-static void application_added (IndicatorApplication * application, const gchar * iconname, gint position, const gchar * dbusaddress, const gchar * dbusobject, const gchar * icon_theme_path, const gchar * label, const gchar * guide, const gchar * accessible_desc, const gchar * hint);
+static void application_added (IndicatorApplication * application, const gchar * iconname, gint position, const gchar * dbusaddress, const gchar * dbusobject, const gchar * icon_theme_path, const gchar * label, const gchar * guide, const gchar * accessible_desc, const gchar * hint, const gchar *sTooltipIcon, const gchar *sTooltipTitle, const gchar *sTooltipDescription);
static void application_removed (IndicatorApplication * application, gint position);
static void application_label_changed (IndicatorApplication * application, gint position, const gchar * label, const gchar * guide);
static void application_icon_changed (IndicatorApplication * application, gint position, const gchar * iconname, const gchar * icondesc);
@@ -125,106 +134,108 @@ G_DEFINE_TYPE_WITH_PRIVATE (IndicatorApplication, indicator_application, INDICAT
static void
indicator_application_class_init (IndicatorApplicationClass *klass)
{
- GObjectClass *object_class = G_OBJECT_CLASS (klass);
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
- object_class->dispose = indicator_application_dispose;
- object_class->finalize = indicator_application_finalize;
+ object_class->dispose = indicator_application_dispose;
+ object_class->finalize = indicator_application_finalize;
- IndicatorObjectClass * io_class = INDICATOR_OBJECT_CLASS(klass);
+ IndicatorObjectClass * io_class = INDICATOR_OBJECT_CLASS(klass);
- io_class->get_entries = get_entries;
- io_class->get_location = get_location;
- io_class->secondary_activate = entry_secondary_activate;
- io_class->entry_scrolled = entry_scrolled;
+ io_class->get_entries = get_entries;
+ io_class->get_location = get_location;
+ io_class->secondary_activate = entry_secondary_activate;
+ io_class->entry_scrolled = entry_scrolled;
- return;
+ return;
}
static void
indicator_application_init (IndicatorApplication *self)
{
- IndicatorApplicationPrivate * priv = indicator_application_get_instance_private(self);
+ IndicatorApplicationPrivate * priv = indicator_application_get_instance_private(self);
- /* These are built in the connection phase */
- priv->service_proxy_cancel = NULL;
- priv->service_proxy = NULL;
- priv->theme_dirs = NULL;
- priv->disconnect_kill = 0;
+ /* These are built in the connection phase */
+ priv->service_proxy_cancel = NULL;
+ priv->service_proxy = NULL;
+ priv->theme_dirs = NULL;
+ priv->disconnect_kill = 0;
- priv->watch = g_bus_watch_name(G_BUS_TYPE_SESSION,
- INDICATOR_APPLICATION_DBUS_ADDR,
- G_BUS_NAME_WATCHER_FLAGS_NONE,
- connected,
- disconnected,
- self,
- NULL);
+ priv->watch = g_bus_watch_name(G_BUS_TYPE_SESSION,
+ INDICATOR_APPLICATION_DBUS_ADDR,
+ G_BUS_NAME_WATCHER_FLAGS_NONE,
+ connected,
+ disconnected,
+ self,
+ NULL);
- priv->applications = NULL;
+ priv->applications = NULL;
+ priv->pConnection = g_bus_get_sync (G_BUS_TYPE_SESSION, NULL, NULL);
+ priv->theme_dirs = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, NULL);
- priv->theme_dirs = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, NULL);
+ priv->get_apps_cancel = NULL;
- priv->get_apps_cancel = NULL;
-
- return;
+ return;
}
static void
indicator_application_dispose (GObject *object)
{
- IndicatorApplicationPrivate * priv = indicator_application_get_instance_private(INDICATOR_APPLICATION(object));
-
- if (priv->disconnect_kill != 0) {
- g_source_remove(priv->disconnect_kill);
- }
-
- if (priv->get_apps_cancel != NULL) {
- g_cancellable_cancel(priv->get_apps_cancel);
- g_object_unref(priv->get_apps_cancel);
- priv->get_apps_cancel = NULL;
- }
-
- while (priv->applications != NULL) {
- application_removed(INDICATOR_APPLICATION(object),
- 0);
- }
-
- if (priv->service_proxy != NULL) {
- g_object_unref(G_OBJECT(priv->service_proxy));
- priv->service_proxy = NULL;
- }
-
- if (priv->service_proxy_cancel != NULL) {
- g_cancellable_cancel(priv->service_proxy_cancel);
- g_object_unref(priv->service_proxy_cancel);
- priv->service_proxy_cancel = NULL;
- }
-
- if (priv->theme_dirs != NULL) {
- gpointer directory;
- GHashTableIter iter;
- g_hash_table_iter_init (&iter, priv->theme_dirs);
- while (g_hash_table_iter_next (&iter, &directory, NULL)) {
- icon_theme_remove_dir_from_search_path (directory);
- }
- g_hash_table_destroy(priv->theme_dirs);
- priv->theme_dirs = NULL;
- }
-
- if (priv->watch != 0) {
- g_bus_unwatch_name(priv->watch);
- priv->watch = 0;
- }
-
- G_OBJECT_CLASS (indicator_application_parent_class)->dispose (object);
- return;
+ IndicatorApplicationPrivate * priv = indicator_application_get_instance_private(INDICATOR_APPLICATION(object));
+
+ if (priv->disconnect_kill != 0) {
+ g_source_remove(priv->disconnect_kill);
+ }
+
+ if (priv->get_apps_cancel != NULL) {
+ g_cancellable_cancel(priv->get_apps_cancel);
+ g_object_unref(priv->get_apps_cancel);
+ priv->get_apps_cancel = NULL;
+ }
+
+ while (priv->applications != NULL) {
+ application_removed(INDICATOR_APPLICATION(object),
+ 0);
+ }
+
+ if (priv->service_proxy != NULL) {
+ g_object_unref(G_OBJECT(priv->service_proxy));
+ priv->service_proxy = NULL;
+ }
+
+ if (priv->service_proxy_cancel != NULL) {
+ g_cancellable_cancel(priv->service_proxy_cancel);
+ g_object_unref(priv->service_proxy_cancel);
+ priv->service_proxy_cancel = NULL;
+ }
+
+ if (priv->theme_dirs != NULL) {
+ gpointer directory;
+ GHashTableIter iter;
+ g_hash_table_iter_init (&iter, priv->theme_dirs);
+ while (g_hash_table_iter_next (&iter, &directory, NULL)) {
+ icon_theme_remove_dir_from_search_path (directory);
+ }
+ g_hash_table_destroy(priv->theme_dirs);
+ priv->theme_dirs = NULL;
+ }
+
+ if (priv->watch != 0) {
+ g_bus_unwatch_name(priv->watch);
+ priv->watch = 0;
+ }
+
+ g_clear_object (&priv->pConnection);
+
+ G_OBJECT_CLASS (indicator_application_parent_class)->dispose (object);
+ return;
}
static void
indicator_application_finalize (GObject *object)
{
- G_OBJECT_CLASS (indicator_application_parent_class)->finalize (object);
- return;
+ G_OBJECT_CLASS (indicator_application_parent_class)->finalize (object);
+ return;
}
/* Brings up the connection to a service that has just come onto the
@@ -232,29 +243,29 @@ indicator_application_finalize (GObject *object)
static void
connected (GDBusConnection * con, const gchar * name, const gchar * owner, gpointer user_data)
{
- IndicatorApplication * application = INDICATOR_APPLICATION(user_data);
- g_return_if_fail(application != NULL);
+ IndicatorApplication * application = INDICATOR_APPLICATION(user_data);
+ g_return_if_fail(application != NULL);
- IndicatorApplicationPrivate * priv = indicator_application_get_instance_private(application);
+ IndicatorApplicationPrivate * priv = indicator_application_get_instance_private(application);
- g_debug("Connected to Application Indicator Service.");
+ g_debug("Connected to Application Indicator Service.");
- if (priv->service_proxy_cancel == NULL && priv->service_proxy == NULL) {
- /* Build the service proxy */
- priv->service_proxy_cancel = g_cancellable_new();
+ if (priv->service_proxy_cancel == NULL && priv->service_proxy == NULL) {
+ /* Build the service proxy */
+ priv->service_proxy_cancel = g_cancellable_new();
- g_dbus_proxy_new_for_bus(G_BUS_TYPE_SESSION,
- G_DBUS_PROXY_FLAGS_NONE,
- NULL,
- INDICATOR_APPLICATION_DBUS_ADDR,
- INDICATOR_APPLICATION_DBUS_OBJ,
- INDICATOR_APPLICATION_DBUS_IFACE,
- priv->service_proxy_cancel,
- service_proxy_cb,
- application);
- }
+ g_dbus_proxy_new_for_bus(G_BUS_TYPE_SESSION,
+ G_DBUS_PROXY_FLAGS_NONE,
+ NULL,
+ INDICATOR_APPLICATION_DBUS_ADDR,
+ INDICATOR_APPLICATION_DBUS_OBJ,
+ INDICATOR_APPLICATION_DBUS_IFACE,
+ priv->service_proxy_cancel,
+ service_proxy_cb,
+ application);
+ }
- return;
+ return;
}
/* Callback from trying to create the proxy for the service, this
@@ -262,49 +273,49 @@ connected (GDBusConnection * con, const gchar * name, const gchar * owner, gpoin
static void
service_proxy_cb (GObject * object, GAsyncResult * res, gpointer user_data)
{
- GError * error = NULL;
+ GError * error = NULL;
- IndicatorApplication * self = INDICATOR_APPLICATION(user_data);
- g_return_if_fail(self != NULL);
+ IndicatorApplication * self = INDICATOR_APPLICATION(user_data);
+ g_return_if_fail(self != NULL);
- IndicatorApplicationPrivate * priv = indicator_application_get_instance_private(self);
+ IndicatorApplicationPrivate * priv = indicator_application_get_instance_private(self);
- GDBusProxy * proxy = g_dbus_proxy_new_for_bus_finish(res, &error);
+ GDBusProxy * proxy = g_dbus_proxy_new_for_bus_finish(res, &error);
- if (priv->service_proxy_cancel != NULL) {
- g_object_unref(priv->service_proxy_cancel);
- priv->service_proxy_cancel = NULL;
- }
+ if (priv->service_proxy_cancel != NULL) {
+ g_object_unref(priv->service_proxy_cancel);
+ priv->service_proxy_cancel = NULL;
+ }
- if (error != NULL) {
- g_critical("Could not grab DBus proxy for %s: %s", INDICATOR_APPLICATION_DBUS_ADDR, error->message);
- g_error_free(error);
- return;
- }
+ if (error != NULL) {
+ g_critical("Could not grab DBus proxy for %s: %s", INDICATOR_APPLICATION_DBUS_ADDR, error->message);
+ g_error_free(error);
+ return;
+ }
- /* Okay, we're good to grab the proxy at this point, we're
- sure that it's ours. */
- priv->service_proxy = proxy;
+ /* Okay, we're good to grab the proxy at this point, we're
+ sure that it's ours. */
+ priv->service_proxy = proxy;
- g_signal_connect(proxy, "g-signal", G_CALLBACK(receive_signal), self);
+ g_signal_connect(proxy, "g-signal", G_CALLBACK(receive_signal), self);
- /* We shouldn't be in a situation where we've already
- called this function. It doesn't *hurt* anything, but
- man we should look into it more. */
- if (priv->get_apps_cancel != NULL) {
- g_warning("Already getting applications? Odd.");
- return;
- }
+ /* We shouldn't be in a situation where we've already
+ called this function. It doesn't *hurt* anything, but
+ man we should look into it more. */
+ if (priv->get_apps_cancel != NULL) {
+ g_warning("Already getting applications? Odd.");
+ return;
+ }
- priv->get_apps_cancel = g_cancellable_new();
+ priv->get_apps_cancel = g_cancellable_new();
- /* Query it for existing applications */
- g_debug("Request current apps");
- g_dbus_proxy_call(priv->service_proxy, "GetApplications", NULL,
- G_DBUS_CALL_FLAGS_NONE, -1, priv->get_apps_cancel,
- get_applications, self);
+ /* Query it for existing applications */
+ g_debug("Request current apps");
+ g_dbus_proxy_call(priv->service_proxy, "GetApplications", NULL,
+ G_DBUS_CALL_FLAGS_NONE, -1, priv->get_apps_cancel,
+ get_applications, self);
- return;
+ return;
}
/* Marks every current application as belonging to the old
@@ -313,26 +324,26 @@ service_proxy_cb (GObject * object, GAsyncResult * res, gpointer user_data)
static void
disconnected (GDBusConnection * con, const gchar * name, gpointer user_data)
{
- IndicatorApplication * application = INDICATOR_APPLICATION(user_data);
- g_return_if_fail(application != NULL);
-
- IndicatorApplicationPrivate * priv = indicator_application_get_instance_private(application);
- g_list_foreach(priv->applications, disconnected_helper, application);
- /* I'll like this to be a little shorter, but it's a bit
- inpractical to make it so. This means that the user will
- probably notice a visible glitch. Though, if applications
- are disappearing there isn't much we can do. */
- priv->disconnect_kill = g_timeout_add(250, disconnected_kill, application);
- return;
+ IndicatorApplication * application = INDICATOR_APPLICATION(user_data);
+ g_return_if_fail(application != NULL);
+
+ IndicatorApplicationPrivate * priv = indicator_application_get_instance_private(application);
+ g_list_foreach(priv->applications, disconnected_helper, application);
+ /* I'll like this to be a little shorter, but it's a bit
+ inpractical to make it so. This means that the user will
+ probably notice a visible glitch. Though, if applications
+ are disappearing there isn't much we can do. */
+ priv->disconnect_kill = g_timeout_add(250, disconnected_kill, application);
+ return;
}
/* Marks an entry as being from the old service */
static void
disconnected_helper (gpointer data, gpointer user_data)
{
- ApplicationEntry * entry = (ApplicationEntry *)data;
- entry->old_service = TRUE;
- return;
+ ApplicationEntry * entry = (ApplicationEntry *)data;
+ entry->old_service = TRUE;
+ return;
}
/* Makes sure the old applications that don't come back
@@ -340,26 +351,26 @@ disconnected_helper (gpointer data, gpointer user_data)
static gboolean
disconnected_kill (gpointer user_data)
{
- g_return_val_if_fail(IS_INDICATOR_APPLICATION(user_data), FALSE);
- IndicatorApplicationPrivate * priv = indicator_application_get_instance_private(INDICATOR_APPLICATION(user_data));
+ g_return_val_if_fail(IS_INDICATOR_APPLICATION(user_data), FALSE);
+ IndicatorApplicationPrivate * priv = indicator_application_get_instance_private(INDICATOR_APPLICATION(user_data));
- priv->disconnect_kill = 0;
- g_list_foreach(priv->applications, disconnected_kill_helper, user_data);
- return FALSE;
+ priv->disconnect_kill = 0;
+ g_list_foreach(priv->applications, disconnected_kill_helper, user_data);
+ return FALSE;
}
-/* Looks for entries that are still associated with the
+/* Looks for entries that are still associated with the
old service and removes them. */
static void
disconnected_kill_helper (gpointer data, gpointer user_data)
{
- g_return_if_fail(IS_INDICATOR_APPLICATION(user_data));
- IndicatorApplicationPrivate * priv = indicator_application_get_instance_private(INDICATOR_APPLICATION(user_data));
- ApplicationEntry * entry = (ApplicationEntry *)data;
- if (entry->old_service) {
- application_removed(INDICATOR_APPLICATION(user_data), g_list_index(priv->applications, data));
- }
- return;
+ g_return_if_fail(IS_INDICATOR_APPLICATION(user_data));
+ IndicatorApplicationPrivate * priv = indicator_application_get_instance_private(INDICATOR_APPLICATION(user_data));
+ ApplicationEntry * entry = (ApplicationEntry *)data;
+ if (entry->old_service) {
+ application_removed(INDICATOR_APPLICATION(user_data), g_list_index(priv->applications, data));
+ }
+ return;
}
/* Goes through the list of applications that we're maintaining and
@@ -368,32 +379,32 @@ disconnected_kill_helper (gpointer data, gpointer user_data)
static GList *
get_entries (IndicatorObject * io)
{
- g_return_val_if_fail(IS_INDICATOR_APPLICATION(io), NULL);
+ g_return_val_if_fail(IS_INDICATOR_APPLICATION(io), NULL);
- IndicatorApplicationPrivate * priv = indicator_application_get_instance_private(INDICATOR_APPLICATION(io));
+ IndicatorApplicationPrivate * priv = indicator_application_get_instance_private(INDICATOR_APPLICATION(io));
- GList * retval = NULL;
- GList * apppointer = NULL;
+ GList * retval = NULL;
+ GList * apppointer = NULL;
- for (apppointer = priv->applications; apppointer != NULL; apppointer = g_list_next(apppointer)) {
- IndicatorObjectEntry * entry = &(((ApplicationEntry *)apppointer->data)->entry);
- retval = g_list_prepend(retval, entry);
- }
+ for (apppointer = priv->applications; apppointer != NULL; apppointer = g_list_next(apppointer)) {
+ IndicatorObjectEntry * entry = &(((ApplicationEntry *)apppointer->data)->entry);
+ retval = g_list_prepend(retval, entry);
+ }
- if (retval != NULL) {
- retval = g_list_reverse(retval);
- }
+ if (retval != NULL) {
+ retval = g_list_reverse(retval);
+ }
- return retval;
+ return retval;
}
/* Finds the location of a specific entry */
-static guint
+static guint
get_location (IndicatorObject * io, IndicatorObjectEntry * entry)
{
- g_return_val_if_fail(IS_INDICATOR_APPLICATION(io), 0);
- IndicatorApplicationPrivate * priv = indicator_application_get_instance_private(INDICATOR_APPLICATION(io));
- return g_list_index(priv->applications, entry);
+ g_return_val_if_fail(IS_INDICATOR_APPLICATION(io), 0);
+ IndicatorApplicationPrivate * priv = indicator_application_get_instance_private(INDICATOR_APPLICATION(io));
+ return g_list_index(priv->applications, entry);
}
/* Redirect the secondary activate to the Application Item */
@@ -401,62 +412,70 @@ static void
entry_secondary_activate (IndicatorObject * io, IndicatorObjectEntry * entry,
guint time, gpointer data)
{
- g_return_if_fail(IS_INDICATOR_APPLICATION(io));
+ g_return_if_fail(IS_INDICATOR_APPLICATION(io));
- IndicatorApplicationPrivate * priv = indicator_application_get_instance_private(INDICATOR_APPLICATION(io));
- g_return_if_fail(priv->service_proxy);
+ IndicatorApplicationPrivate * priv = indicator_application_get_instance_private(INDICATOR_APPLICATION(io));
+ g_return_if_fail(priv->service_proxy);
- GList *l = g_list_find(priv->applications, entry);
- if (l == NULL)
- return;
+ GList *l = g_list_find(priv->applications, entry);
+ if (l == NULL)
+ return;
- ApplicationEntry *app = l->data;
+ ApplicationEntry *app = l->data;
- if (app && app->dbusaddress && app->dbusobject && priv->service_proxy) {
- g_dbus_proxy_call(priv->service_proxy, "ApplicationSecondaryActivateEvent",
- g_variant_new("(ssu)", app->dbusaddress,
- app->dbusobject,
- time),
- G_DBUS_CALL_FLAGS_NONE, -1, NULL, NULL, NULL);
- }
+ if (app && app->dbusaddress && app->dbusobject && priv->service_proxy) {
+ g_dbus_proxy_call(priv->service_proxy, "ApplicationSecondaryActivateEvent",
+ g_variant_new("(ssu)", app->dbusaddress,
+ app->dbusobject,
+ time),
+ G_DBUS_CALL_FLAGS_NONE, -1, NULL, NULL, NULL);
+ }
}
/* Redirect the scroll event to the Application Item */
static void entry_scrolled (IndicatorObject * io, IndicatorObjectEntry * entry, gint delta, IndicatorScrollDirection direction)
{
- g_return_if_fail(IS_INDICATOR_APPLICATION(io));
+ g_return_if_fail(IS_INDICATOR_APPLICATION(io));
- IndicatorApplicationPrivate * priv = indicator_application_get_instance_private(INDICATOR_APPLICATION(io));
- g_return_if_fail(priv->service_proxy);
+ IndicatorApplicationPrivate * priv = indicator_application_get_instance_private(INDICATOR_APPLICATION(io));
+ g_return_if_fail(priv->service_proxy);
- GList *l = g_list_find(priv->applications, entry);
- if (l == NULL)
- return;
+ GList *l = g_list_find(priv->applications, entry);
+ if (l == NULL)
+ return;
- ApplicationEntry *app = l->data;
+ ApplicationEntry *app = l->data;
- if (app && app->dbusaddress && app->dbusobject && priv->service_proxy) {
- g_dbus_proxy_call(priv->service_proxy, "ApplicationScrollEvent",
- g_variant_new("(ssiu)", app->dbusaddress,
- app->dbusobject,
- delta, direction),
- G_DBUS_CALL_FLAGS_NONE, -1, NULL, NULL, NULL);
- }
+ if (app && app->dbusaddress && app->dbusobject && priv->service_proxy) {
+ g_dbus_proxy_call(priv->service_proxy, "ApplicationScrollEvent",
+ g_variant_new("(ssiu)", app->dbusaddress,
+ app->dbusobject,
+ delta, direction),
+ G_DBUS_CALL_FLAGS_NONE, -1, NULL, NULL, NULL);
+ }
}
/* Does a quick meausre of how big the string is in
pixels with a Pango layout */
static gint
-measure_string (GtkStyle * style, PangoContext * context, const gchar * string)
+measure_string (GtkStyleContext *pContext, PangoContext * context, const gchar * string)
{
- PangoLayout * layout = pango_layout_new(context);
- pango_layout_set_text(layout, string, -1);
- pango_layout_set_font_description(layout, style->font_desc);
-
- gint width;
- pango_layout_get_pixel_size(layout, &width, NULL);
- g_object_unref(layout);
- return width;
+ PangoLayout * layout = pango_layout_new(context);
+ pango_layout_set_text(layout, string, -1);
+ PangoFontDescription *pDescription = NULL;
+ GtkStateFlags nFlags = gtk_style_context_get_state (pContext);
+ gtk_style_context_get (pContext, nFlags, GTK_STYLE_PROPERTY_FONT, &pDescription, NULL);
+
+ if (pDescription)
+ {
+ pango_layout_set_font_description(layout, pDescription);
+ pango_font_description_free (pDescription);
+ }
+
+ gint width;
+ pango_layout_get_pixel_size(layout, &width, NULL);
+ g_object_unref(layout);
+ return width;
}
/* Try to get a good guess at what a maximum width of the entire
@@ -464,104 +483,217 @@ measure_string (GtkStyle * style, PangoContext * context, const gchar * string)
static void
guess_label_size (ApplicationEntry * app)
{
- /* This is during startup. */
- if (app->entry.label == NULL) return;
+ /* This is during startup. */
+ if (app->entry.label == NULL) return;
- GtkStyle * style = gtk_widget_get_style(GTK_WIDGET(app->entry.label));
- PangoContext * context = gtk_widget_get_pango_context(GTK_WIDGET(app->entry.label));
+ GtkStyleContext *pContext = gtk_widget_get_style_context (GTK_WIDGET (app->entry.label));
+ PangoContext * context = gtk_widget_get_pango_context(GTK_WIDGET(app->entry.label));
- gint length = measure_string(style, context, gtk_label_get_text(app->entry.label));
+ gint length = measure_string(pContext, context, gtk_label_get_text(app->entry.label));
- if (app->guide != NULL) {
- gint guidelen = measure_string(style, context, app->guide);
- if (guidelen > length) {
- length = guidelen;
- }
- }
+ if (app->guide != NULL) {
+ gint guidelen = measure_string(pContext, context, app->guide);
+ if (guidelen > length) {
+ length = guidelen;
+ }
+ }
+
+ gtk_widget_set_size_request(GTK_WIDGET(app->entry.label), length, -1);
+
+ return;
+}
+
+static void onMenuPoppedUp (GtkWidget *pWidget, gpointer pFlippedRect, gpointer pFinalRect, gboolean bFlippedX, gboolean bFlippedY, gpointer pData)
+{
+ ApplicationEntry *pEntry = (ApplicationEntry*) pData;
+ pEntry->bMenuShown = TRUE;
+}
+
+static void onMenuHide (GtkWidget *pWidget, gpointer pData)
+{
+ ApplicationEntry *pEntry = (ApplicationEntry*) pData;
+ pEntry->bMenuShown = FALSE;
+}
+
+static gboolean onQueryTooltip (GtkWidget *pWidget, gint nX, gint nY, gboolean bKeyboardMode, GtkTooltip *pTooltip, gpointer pData)
+{
+ ApplicationEntry *pEntry = (ApplicationEntry*) pData;
- gtk_widget_set_size_request(GTK_WIDGET(app->entry.label), length, -1);
+ if (!pEntry->bMenuShown && pEntry->sTooltipMarkup)
+ {
+ gtk_tooltip_set_markup (pTooltip, pEntry->sTooltipMarkup);
+
+ if (pEntry->sTooltipIcon)
+ {
+ gtk_tooltip_set_icon_from_icon_name (pTooltip, pEntry->sTooltipIcon, GTK_ICON_SIZE_LARGE_TOOLBAR);
+ }
+
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+static gboolean onTooltipConnect (gpointer pData)
+{
+ ApplicationEntry *pEntry = (ApplicationEntry*) pData;
+
+ if (pEntry->entry.label)
+ {
+ gtk_widget_set_has_tooltip (GTK_WIDGET (pEntry->entry.label), TRUE);
+ g_signal_connect (pEntry->entry.label, "query-tooltip", G_CALLBACK (onQueryTooltip), pEntry);
+ }
+
+ if (pEntry->entry.image)
+ {
+ gtk_widget_set_has_tooltip (GTK_WIDGET (pEntry->entry.image), TRUE);
+ g_signal_connect (pEntry->entry.image, "query-tooltip", G_CALLBACK (onQueryTooltip), pEntry);
+ }
+
+ return G_SOURCE_REMOVE;
+}
+
+static void applicationAddedFinish (ApplicationEntry *pEntry)
+{
+ /* Keep copies of these for ourself, just in case. */
+ g_object_ref (pEntry->entry.image);
+ g_object_ref (pEntry->entry.menu);
+
+ gtk_widget_show (GTK_WIDGET (pEntry->entry.image));
+ gtk_widget_hide (GTK_WIDGET (pEntry->entry.menu));
+ IndicatorApplicationPrivate * pPrivate = indicator_application_get_instance_private (INDICATOR_APPLICATION (pEntry->entry.parent_object));
+ pPrivate->applications = g_list_insert (pPrivate->applications, pEntry, pEntry->nPosition);
+ g_signal_emit (G_OBJECT (pEntry->entry.parent_object), INDICATOR_OBJECT_SIGNAL_ENTRY_ADDED_ID, 0, &(pEntry->entry), TRUE);
+ g_signal_connect (pEntry->entry.menu, "popped-up", G_CALLBACK (onMenuPoppedUp), pEntry);
+ g_signal_connect (pEntry->entry.menu, "hide", G_CALLBACK (onMenuHide), pEntry);
+
+ // Make sure our widgets are constructed and displayed
+ g_timeout_add_seconds (2, onTooltipConnect, pEntry);
+}
+
+static void onMenuModelChanged (GMenuModel *pModel, gint nPosition, gint nRemoved, gint nAdded, gpointer pData)
+{
+ ApplicationEntry *pEntry = (ApplicationEntry*) pData;
+ g_signal_handlers_disconnect_by_data (pEntry->pModel, pEntry);
+ pEntry->entry.menu = GTK_MENU (gtk_menu_new_from_model (G_MENU_MODEL (pModel)));
+ gtk_menu_shell_bind_model (GTK_MENU_SHELL (pEntry->entry.menu), pModel, NULL, TRUE);
+ IndicatorApplicationPrivate *pPrivate = indicator_application_get_instance_private (INDICATOR_APPLICATION (pEntry->entry.parent_object));
+ pEntry->pActions = G_ACTION_GROUP (g_dbus_action_group_get (pPrivate->pConnection, pEntry->dbusaddress, pEntry->dbusobject));
+ gtk_widget_insert_action_group (GTK_WIDGET (pEntry->entry.menu), "indicator", pEntry->pActions);
+ applicationAddedFinish (pEntry);
+}
- return;
+static void setTooltip (ApplicationEntry *pEntry, const gchar *sTooltipIcon, const gchar *sTooltipTitle, const gchar *sTooltipDescription)
+{
+ g_free (pEntry->sTooltipIcon);
+ pEntry->sTooltipIcon = NULL;
+ g_free (pEntry->sTooltipMarkup);
+ pEntry->sTooltipMarkup = NULL;
+
+ if (sTooltipTitle && sTooltipTitle[0] != '\0' && sTooltipDescription && sTooltipDescription[0] != '\0')
+ {
+ pEntry->sTooltipMarkup = g_strdup_printf ("<b>%s</b>\n\n%s", sTooltipTitle, sTooltipDescription);
+ }
+ else if (sTooltipTitle && sTooltipTitle[0] != '\0')
+ {
+ pEntry->sTooltipMarkup = g_strdup (sTooltipTitle);
+ }
+ else if (sTooltipDescription && sTooltipDescription[0] != '\0')
+ {
+ pEntry->sTooltipMarkup = g_strdup (sTooltipDescription);
+ }
+
+ if (sTooltipIcon && sTooltipIcon[0] != '\0')
+ {
+ pEntry->sTooltipIcon = g_strdup (sTooltipIcon);
+ }
}
/* Here we respond to new applications by building up the
ApplicationEntry and signaling the indicator host that
we've got a new indicator. */
static void
-application_added (IndicatorApplication * application, const gchar * iconname, gint position, const gchar * dbusaddress, const gchar * dbusobject, const gchar * icon_theme_path, const gchar * label, const gchar * guide, const gchar * accessible_desc, const gchar * hint)
+application_added (IndicatorApplication * application, const gchar * iconname, gint position, const gchar * dbusaddress, const gchar * dbusobject, const gchar * icon_theme_path, const gchar * label, const gchar * guide, const gchar * accessible_desc, const gchar * hint, const gchar *sTooltipIcon, const gchar *sTooltipTitle, const gchar *sTooltipDescription)
{
- g_return_if_fail(IS_INDICATOR_APPLICATION(application));
- g_debug("Building new application entry: %s with icon: %s at position %i", dbusaddress, iconname, position);
- IndicatorApplicationPrivate * priv = indicator_application_get_instance_private(application);
-
- ApplicationEntry * app = g_new0(ApplicationEntry, 1);
-
- app->entry.parent_object = INDICATOR_OBJECT(application);
- app->old_service = FALSE;
- app->icon_theme_path = NULL;
- if (icon_theme_path != NULL && icon_theme_path[0] != '\0') {
- app->icon_theme_path = g_strdup(icon_theme_path);
- theme_dir_ref(application, icon_theme_path);
- }
-
- app->dbusaddress = g_strdup(dbusaddress);
- app->dbusobject = g_strdup(dbusobject);
- app->guide = NULL;
-
- /* We make a long name using the suffix, and if that
- icon is available we want to use it. Otherwise we'll
- just use the name we were given. */
- app->longname = NULL;
- if (!g_str_has_suffix(iconname, PANEL_ICON_SUFFIX)) {
- app->longname = g_strdup_printf("%s-%s", iconname, PANEL_ICON_SUFFIX);
- } else {
- app->longname = g_strdup(iconname);
- }
- app->entry.image = indicator_image_helper(app->longname);
-
- if (label == NULL || label[0] == '\0') {
- app->entry.label = NULL;
- } else {
- app->entry.label = GTK_LABEL(gtk_label_new(label));
- g_object_ref(G_OBJECT(app->entry.label));
- gtk_widget_show(GTK_WIDGET(app->entry.label));
-
- if (app->guide != NULL) {
- g_free(app->guide);
- app->guide = NULL;
- }
-
- if (guide != NULL) {
- app->guide = g_strdup(guide);
- }
-
- guess_label_size(app);
- }
-
- if (accessible_desc == NULL || accessible_desc[0] == '\0') {
- app->entry.accessible_desc = NULL;
- } else {
- app->entry.accessible_desc = g_strdup(accessible_desc);
- }
-
- if (hint == NULL || hint[0] == '\0') {
- app->entry.name_hint = NULL;
- } else {
- app->entry.name_hint = g_strdup(hint);
- }
-
- app->entry.menu = GTK_MENU(dbusmenu_gtkmenu_new((gchar *)dbusaddress, (gchar *)dbusobject));
-
- /* Keep copies of these for ourself, just in case. */
- g_object_ref(app->entry.image);
- g_object_ref(app->entry.menu);
-
- gtk_widget_show(GTK_WIDGET(app->entry.image));
-
- priv->applications = g_list_insert(priv->applications, app, position);
-
- g_signal_emit(G_OBJECT(application), INDICATOR_OBJECT_SIGNAL_ENTRY_ADDED_ID, 0, &(app->entry), TRUE);
- return;
+ g_return_if_fail(IS_INDICATOR_APPLICATION(application));
+ g_debug("Building new application entry: %s with icon: %s at position %i", dbusaddress, iconname, position);
+ ApplicationEntry * app = g_new0(ApplicationEntry, 1);
+
+ app->bMenuShown = FALSE;
+ app->entry.parent_object = INDICATOR_OBJECT(application);
+ app->nPosition = position;
+ app->old_service = FALSE;
+ app->icon_theme_path = NULL;
+ if (icon_theme_path != NULL && icon_theme_path[0] != '\0') {
+ app->icon_theme_path = g_strdup(icon_theme_path);
+ theme_dir_ref(application, icon_theme_path);
+ }
+
+ app->dbusaddress = g_strdup(dbusaddress);
+ app->dbusobject = g_strdup(dbusobject);
+ app->guide = NULL;
+
+ /* We make a long name using the suffix, and if that
+ icon is available we want to use it. Otherwise we'll
+ just use the name we were given. */
+ app->longname = NULL;
+ if (!g_str_has_suffix(iconname, PANEL_ICON_SUFFIX)) {
+ app->longname = g_strdup_printf("%s-%s", iconname, PANEL_ICON_SUFFIX);
+ } else {
+ app->longname = g_strdup(iconname);
+ }
+ app->entry.image = indicator_image_helper(app->longname);
+
+ if (label == NULL || label[0] == '\0') {
+ app->entry.label = NULL;
+ } else {
+ app->entry.label = GTK_LABEL(gtk_label_new(label));
+ g_object_ref(G_OBJECT(app->entry.label));
+ gtk_widget_show(GTK_WIDGET(app->entry.label));
+
+ if (app->guide != NULL) {
+ g_free(app->guide);
+ app->guide = NULL;
+ }
+
+ if (guide != NULL) {
+ app->guide = g_strdup(guide);
+ }
+
+ guess_label_size(app);
+ }
+
+ if (accessible_desc == NULL || accessible_desc[0] == '\0') {
+ app->entry.accessible_desc = NULL;
+ } else {
+ app->entry.accessible_desc = g_strdup(accessible_desc);
+ }
+
+ if (hint == NULL || hint[0] == '\0') {
+ app->entry.name_hint = NULL;
+ } else {
+ app->entry.name_hint = g_strdup(hint);
+ }
+
+ setTooltip (app, sTooltipIcon, sTooltipTitle, sTooltipDescription);
+ gboolean bGLibMenu = g_str_has_prefix (dbusobject, "/org/ayatana/appindicator/");
+
+ if (bGLibMenu)
+ {
+ IndicatorApplicationPrivate * pPrivate = indicator_application_get_instance_private (application);
+ app->pModel = G_MENU_MODEL (g_dbus_menu_model_get (pPrivate->pConnection, dbusaddress, dbusobject));
+ g_signal_connect (app->pModel, "items-changed", G_CALLBACK (onMenuModelChanged), app);
+
+ if (g_menu_model_get_n_items (app->pModel))
+ {
+ onMenuModelChanged (app->pModel, 0, 0, 1, app);
+ }
+ }
+ else
+ {
+ app->entry.menu = GTK_MENU (dbusmenu_gtkmenu_new ((gchar*) dbusaddress, (gchar*) dbusobject));
+ applicationAddedFinish (app);
+ }
}
/* This removes the application from the list and free's all
@@ -569,52 +701,57 @@ application_added (IndicatorApplication * application, const gchar * iconname, g
static void
application_removed (IndicatorApplication * application, gint position)
{
- g_return_if_fail(IS_INDICATOR_APPLICATION(application));
- IndicatorApplicationPrivate * priv = indicator_application_get_instance_private(application);
- ApplicationEntry * app = (ApplicationEntry *)g_list_nth_data(priv->applications, position);
-
- if (app == NULL) {
- g_warning("Unable to find application at position: %d", position);
- return;
- }
-
- priv->applications = g_list_remove(priv->applications, app);
- g_signal_emit(G_OBJECT(application), INDICATOR_OBJECT_SIGNAL_ENTRY_REMOVED_ID, 0, &(app->entry), TRUE);
-
- if (app->icon_theme_path != NULL) {
- theme_dir_unref(application, app->icon_theme_path);
- g_free(app->icon_theme_path);
- }
- if (app->dbusaddress != NULL) {
- g_free(app->dbusaddress);
- }
- if (app->dbusobject != NULL) {
- g_free(app->dbusobject);
- }
- if (app->guide != NULL) {
- g_free(app->guide);
- }
- if (app->longname != NULL) {
- g_free(app->longname);
- }
- if (app->entry.image != NULL) {
- g_object_unref(G_OBJECT(app->entry.image));
- }
- if (app->entry.label != NULL) {
- g_object_unref(G_OBJECT(app->entry.label));
- }
- if (app->entry.menu != NULL) {
- g_object_unref(G_OBJECT(app->entry.menu));
- }
- if (app->entry.accessible_desc != NULL) {
- g_free((gchar *)app->entry.accessible_desc);
- }
- if (app->entry.name_hint != NULL) {
- g_free((gchar *)app->entry.name_hint);
- }
- g_free(app);
-
- return;
+ g_return_if_fail(IS_INDICATOR_APPLICATION(application));
+ IndicatorApplicationPrivate * priv = indicator_application_get_instance_private(application);
+ ApplicationEntry * app = (ApplicationEntry *)g_list_nth_data(priv->applications, position);
+
+ if (app == NULL) {
+ g_warning("Unable to find application at position: %d", position);
+ return;
+ }
+
+ priv->applications = g_list_remove(priv->applications, app);
+ g_signal_emit(G_OBJECT(application), INDICATOR_OBJECT_SIGNAL_ENTRY_REMOVED_ID, 0, &(app->entry), TRUE);
+
+ if (app->icon_theme_path != NULL) {
+ theme_dir_unref(application, app->icon_theme_path);
+ g_free(app->icon_theme_path);
+ }
+ if (app->dbusaddress != NULL) {
+ g_free(app->dbusaddress);
+ }
+ if (app->dbusobject != NULL) {
+ g_free(app->dbusobject);
+ }
+ if (app->guide != NULL) {
+ g_free(app->guide);
+ }
+ if (app->longname != NULL) {
+ g_free(app->longname);
+ }
+ if (app->entry.image != NULL) {
+ g_object_unref(G_OBJECT(app->entry.image));
+ }
+ if (app->entry.label != NULL) {
+ g_object_unref(G_OBJECT(app->entry.label));
+ }
+ if (app->entry.menu != NULL) {
+ g_object_unref(G_OBJECT(app->entry.menu));
+ }
+ if (app->entry.accessible_desc != NULL) {
+ g_free((gchar *)app->entry.accessible_desc);
+ }
+ if (app->entry.name_hint != NULL) {
+ g_free((gchar *)app->entry.name_hint);
+ }
+
+ g_free (app->sTooltipIcon);
+ g_free (app->sTooltipMarkup);
+ g_clear_object (&app->pModel);
+ g_clear_object (&app->pActions);
+ g_free(app);
+
+ return;
}
/* The callback for the signal that the label for an application
@@ -622,80 +759,82 @@ application_removed (IndicatorApplication * application, gint position)
static void
application_label_changed (IndicatorApplication * application, gint position, const gchar * label, const gchar * guide)
{
- IndicatorApplicationPrivate * priv = indicator_application_get_instance_private(application);
- ApplicationEntry * app = (ApplicationEntry *)g_list_nth_data(priv->applications, position);
- gboolean signal_reload = FALSE;
-
- if (app == NULL) {
- g_warning("Unable to find application at position: %d", position);
- return;
- }
-
- if (label == NULL || label[0] == '\0') {
- /* No label, let's see if we need to delete the old one */
- if (app->entry.label != NULL) {
- g_object_unref(G_OBJECT(app->entry.label));
- app->entry.label = NULL;
-
- signal_reload = TRUE;
- }
- } else {
- /* We've got a label, is this just an update or is
- it a new thing. */
- if (app->entry.label != NULL) {
- gtk_label_set_text(app->entry.label, label);
- } else {
- app->entry.label = GTK_LABEL(gtk_label_new(label));
- g_object_ref(G_OBJECT(app->entry.label));
- gtk_widget_show(GTK_WIDGET(app->entry.label));
-
- signal_reload = TRUE;
- }
- }
-
- /* Copy the guide if we have one */
- if (app->guide != NULL) {
- g_free(app->guide);
- app->guide = NULL;
- }
-
- if (guide != NULL && guide[0] != '\0') {
- app->guide = g_strdup(guide);
- }
-
- /* Protected against not having a label */
- guess_label_size(app);
-
- if (signal_reload) {
- /* Telling the listener that this has been removed, and then
- readded to make it reparse the entry. */
- if (app->entry.label != NULL) {
- gtk_widget_hide(GTK_WIDGET(app->entry.label));
- }
-
- if (app->entry.image != NULL) {
- gtk_widget_hide(GTK_WIDGET(app->entry.image));
- }
-
- if (app->entry.menu != NULL) {
- gtk_menu_detach(app->entry.menu);
- }
-
- g_signal_emit(G_OBJECT(application), INDICATOR_OBJECT_SIGNAL_ENTRY_REMOVED_ID, 0, &(app->entry), TRUE);
-
- if (app->entry.label != NULL) {
- gtk_widget_show(GTK_WIDGET(app->entry.label));
- }
-
- if (app->entry.image != NULL) {
- indicator_image_helper_update(app->entry.image, app->longname);
- gtk_widget_show(GTK_WIDGET(app->entry.image));
- }
-
- g_signal_emit(G_OBJECT(application), INDICATOR_OBJECT_SIGNAL_ENTRY_ADDED_ID, 0, &(app->entry), TRUE);
- }
-
- return;
+ IndicatorApplicationPrivate * priv = indicator_application_get_instance_private(application);
+ ApplicationEntry * app = (ApplicationEntry *)g_list_nth_data(priv->applications, position);
+ gboolean signal_reload = FALSE;
+
+ if (app == NULL) {
+ g_warning("Unable to find application at position: %d", position);
+ return;
+ }
+
+ if (label == NULL || label[0] == '\0') {
+ /* No label, let's see if we need to delete the old one */
+ if (app->entry.label != NULL) {
+ g_object_unref(G_OBJECT(app->entry.label));
+ app->entry.label = NULL;
+
+ signal_reload = TRUE;
+ }
+ } else {
+ /* We've got a label, is this just an update or is
+ it a new thing. */
+ if (app->entry.label != NULL) {
+ gtk_label_set_text(app->entry.label, label);
+ } else {
+ app->entry.label = GTK_LABEL(gtk_label_new(label));
+ gtk_widget_set_has_tooltip (GTK_WIDGET (app->entry.label), TRUE);
+ g_signal_connect (app->entry.label, "query-tooltip", G_CALLBACK (onQueryTooltip), app);
+ g_object_ref(G_OBJECT(app->entry.label));
+ gtk_widget_show(GTK_WIDGET(app->entry.label));
+
+ signal_reload = TRUE;
+ }
+ }
+
+ /* Copy the guide if we have one */
+ if (app->guide != NULL) {
+ g_free(app->guide);
+ app->guide = NULL;
+ }
+
+ if (guide != NULL && guide[0] != '\0') {
+ app->guide = g_strdup(guide);
+ }
+
+ /* Protected against not having a label */
+ guess_label_size(app);
+
+ if (signal_reload) {
+ /* Telling the listener that this has been removed, and then
+ readded to make it reparse the entry. */
+ if (app->entry.label != NULL) {
+ gtk_widget_hide(GTK_WIDGET(app->entry.label));
+ }
+
+ if (app->entry.image != NULL) {
+ gtk_widget_hide(GTK_WIDGET(app->entry.image));
+ }
+
+ if (app->entry.menu != NULL) {
+ gtk_menu_detach(app->entry.menu);
+ }
+
+ g_signal_emit(G_OBJECT(application), INDICATOR_OBJECT_SIGNAL_ENTRY_REMOVED_ID, 0, &(app->entry), TRUE);
+
+ if (app->entry.label != NULL) {
+ gtk_widget_show(GTK_WIDGET(app->entry.label));
+ }
+
+ if (app->entry.image != NULL) {
+ indicator_image_helper_update(app->entry.image, app->longname);
+ gtk_widget_show(GTK_WIDGET(app->entry.image));
+ }
+
+ g_signal_emit(G_OBJECT(application), INDICATOR_OBJECT_SIGNAL_ENTRY_ADDED_ID, 0, &(app->entry), TRUE);
+ }
+
+ return;
}
/* The callback for the signal that the icon for an application
@@ -703,47 +842,47 @@ application_label_changed (IndicatorApplication * application, gint position, co
static void
application_icon_changed (IndicatorApplication * application, gint position, const gchar * iconname, const gchar * icondesc)
{
- IndicatorApplicationPrivate * priv = indicator_application_get_instance_private(application);
- ApplicationEntry * app = (ApplicationEntry *)g_list_nth_data(priv->applications, position);
-
- if (app == NULL) {
- g_warning("Unable to find application at position: %d", position);
- return;
- }
-
- if (iconname == NULL) {
- g_warning("We can't have a NULL icon name on %d", position);
- return;
- }
-
- /* We make a long name using the suffix, and if that
- icon is available we want to use it. Otherwise we'll
- just use the name we were given. */
- if (app->longname != NULL) {
- g_free(app->longname);
- app->longname = NULL;
- }
- if (!g_str_has_suffix(iconname, PANEL_ICON_SUFFIX)) {
- app->longname = g_strdup_printf("%s-%s", iconname, PANEL_ICON_SUFFIX);
- } else {
- app->longname = g_strdup(iconname);
- }
- indicator_image_helper_update(app->entry.image, app->longname);
-
- if (g_strcmp0(app->entry.accessible_desc, icondesc) != 0) {
- if (app->entry.accessible_desc != NULL) {
- g_free((gchar *)app->entry.accessible_desc);
- app->entry.accessible_desc = NULL;
- }
-
- if (icondesc != NULL && icondesc[0] != '\0') {
- app->entry.accessible_desc = g_strdup(icondesc);
- }
-
- g_signal_emit(G_OBJECT(application), INDICATOR_OBJECT_SIGNAL_ACCESSIBLE_DESC_UPDATE_ID, 0, &(app->entry), TRUE);
- }
-
- return;
+ IndicatorApplicationPrivate * priv = indicator_application_get_instance_private(application);
+ ApplicationEntry * app = (ApplicationEntry *)g_list_nth_data(priv->applications, position);
+
+ if (app == NULL) {
+ g_warning("Unable to find application at position: %d", position);
+ return;
+ }
+
+ if (iconname == NULL) {
+ g_warning("We can't have a NULL icon name on %d", position);
+ return;
+ }
+
+ /* We make a long name using the suffix, and if that
+ icon is available we want to use it. Otherwise we'll
+ just use the name we were given. */
+ if (app->longname != NULL) {
+ g_free(app->longname);
+ app->longname = NULL;
+ }
+ if (!g_str_has_suffix(iconname, PANEL_ICON_SUFFIX)) {
+ app->longname = g_strdup_printf("%s-%s", iconname, PANEL_ICON_SUFFIX);
+ } else {
+ app->longname = g_strdup(iconname);
+ }
+ indicator_image_helper_update(app->entry.image, app->longname);
+
+ if (g_strcmp0(app->entry.accessible_desc, icondesc) != 0) {
+ if (app->entry.accessible_desc != NULL) {
+ g_free((gchar *)app->entry.accessible_desc);
+ app->entry.accessible_desc = NULL;
+ }
+
+ if (icondesc != NULL && icondesc[0] != '\0') {
+ app->entry.accessible_desc = g_strdup(icondesc);
+ }
+
+ g_signal_emit(G_OBJECT(application), INDICATOR_OBJECT_SIGNAL_ACCESSIBLE_DESC_UPDATE_ID, 0, &(app->entry), TRUE);
+ }
+
+ return;
}
/* The callback for the signal that the icon theme path for an application
@@ -751,28 +890,28 @@ application_icon_changed (IndicatorApplication * application, gint position, con
static void
application_icon_theme_path_changed (IndicatorApplication * application, gint position, const gchar * icon_theme_path)
{
- IndicatorApplicationPrivate * priv = indicator_application_get_instance_private(application);
- ApplicationEntry * app = (ApplicationEntry *)g_list_nth_data(priv->applications, position);
-
- if (app == NULL) {
- g_warning("Unable to find application at position: %d", position);
- return;
- }
-
- if (g_strcmp0(icon_theme_path, app->icon_theme_path) != 0) {
- if(app->icon_theme_path != NULL) {
- theme_dir_unref(application, app->icon_theme_path);
- g_free(app->icon_theme_path);
+ IndicatorApplicationPrivate * priv = indicator_application_get_instance_private(application);
+ ApplicationEntry * app = (ApplicationEntry *)g_list_nth_data(priv->applications, position);
+
+ if (app == NULL) {
+ g_warning("Unable to find application at position: %d", position);
+ return;
+ }
+
+ if (g_strcmp0(icon_theme_path, app->icon_theme_path) != 0) {
+ if(app->icon_theme_path != NULL) {
+ theme_dir_unref(application, app->icon_theme_path);
+ g_free(app->icon_theme_path);
app->icon_theme_path = NULL;
}
if (icon_theme_path != NULL && icon_theme_path[0] != '\0') {
- app->icon_theme_path = g_strdup(icon_theme_path);
- theme_dir_ref(application, app->icon_theme_path);
- }
- indicator_image_helper_update(app->entry.image, app->longname);
- }
+ app->icon_theme_path = g_strdup(icon_theme_path);
+ theme_dir_ref(application, app->icon_theme_path);
+ }
+ indicator_image_helper_update(app->entry.image, app->longname);
+ }
- return;
+ return;
}
/* Receives all signals from the service, routed to the appropriate functions */
@@ -780,84 +919,104 @@ static void
receive_signal (GDBusProxy * proxy, gchar * sender_name, gchar * signal_name,
GVariant * parameters, gpointer user_data)
{
- IndicatorApplication * self = INDICATOR_APPLICATION(user_data);
- IndicatorApplicationPrivate * priv = indicator_application_get_instance_private(self);
-
- /* If we're in the middle of a GetApplications call and we get
- any of these our state is probably going to just be confused. Let's
- cancel the call we had and try again to try and get a clear answer */
- if (priv->get_apps_cancel != NULL) {
- g_cancellable_cancel(priv->get_apps_cancel);
- g_object_unref(priv->get_apps_cancel);
-
- priv->get_apps_cancel = g_cancellable_new();
-
- g_dbus_proxy_call(priv->service_proxy, "GetApplications", NULL,
- G_DBUS_CALL_FLAGS_NONE, -1, priv->get_apps_cancel,
- get_applications, self);
- return;
- }
-
- if (g_strcmp0(signal_name, "ApplicationAdded") == 0) {
- gchar * iconname = NULL;
- gint position;
- gchar * dbusaddress = NULL;
- gchar * dbusobject = NULL;
- gchar * icon_theme_path = NULL;
- gchar * label = NULL;
- gchar * guide = NULL;
- gchar * accessible_desc = NULL;
- gchar * hint = NULL;
- gchar * title = NULL;
- g_variant_get (parameters, "(sisossssss)", &iconname,
- &position, &dbusaddress, &dbusobject,
- &icon_theme_path, &label, &guide,
- &accessible_desc, &hint, &title);
- application_added(self, iconname, position, dbusaddress,
- dbusobject, icon_theme_path, label, guide,
- accessible_desc, hint);
- g_free(iconname);
- g_free(dbusaddress);
- g_free(dbusobject);
- g_free(icon_theme_path);
- g_free(label);
- g_free(guide);
- g_free(accessible_desc);
- g_free(hint);
- g_free(title);
- }
- else if (g_strcmp0(signal_name, "ApplicationRemoved") == 0) {
- gint position;
- g_variant_get (parameters, "(i)", &position);
- application_removed(self, position);
- }
- else if (g_strcmp0(signal_name, "ApplicationIconChanged") == 0) {
- gint position;
- gchar * iconname = NULL;
- gchar * icondesc = NULL;
- g_variant_get (parameters, "(iss)", &position, &iconname, &icondesc);
- application_icon_changed(self, position, iconname, icondesc);
- g_free(iconname);
- g_free(icondesc);
- }
- else if (g_strcmp0(signal_name, "ApplicationIconThemePathChanged") == 0) {
- gint position;
- gchar * icon_theme_path = NULL;
- g_variant_get (parameters, "(is)", &position, &icon_theme_path);
- application_icon_theme_path_changed(self, position, icon_theme_path);
- g_free(icon_theme_path);
- }
- else if (g_strcmp0(signal_name, "ApplicationLabelChanged") == 0) {
- gint position;
- gchar * label = NULL;
- gchar * guide = NULL;
- g_variant_get (parameters, "(iss)", &position, &label, &guide);
- application_label_changed(self, position, label, guide);
- g_free(label);
- g_free(guide);
- }
-
- return;
+ IndicatorApplication * self = INDICATOR_APPLICATION(user_data);
+ IndicatorApplicationPrivate * priv = indicator_application_get_instance_private(self);
+
+ /* If we're in the middle of a GetApplications call and we get
+ any of these our state is probably going to just be confused. Let's
+ cancel the call we had and try again to try and get a clear answer */
+ if (priv->get_apps_cancel != NULL) {
+ g_cancellable_cancel(priv->get_apps_cancel);
+ g_object_unref(priv->get_apps_cancel);
+
+ priv->get_apps_cancel = g_cancellable_new();
+
+ g_dbus_proxy_call(priv->service_proxy, "GetApplications", NULL,
+ G_DBUS_CALL_FLAGS_NONE, -1, priv->get_apps_cancel,
+ get_applications, self);
+ return;
+ }
+
+ if (g_strcmp0(signal_name, "ApplicationAdded") == 0) {
+ gchar * iconname = NULL;
+ gint position;
+ gchar * dbusaddress = NULL;
+ gchar * dbusobject = NULL;
+ gchar * icon_theme_path = NULL;
+ gchar * label = NULL;
+ gchar * guide = NULL;
+ gchar * accessible_desc = NULL;
+ gchar * hint = NULL;
+ gchar * title = NULL;
+ gchar *sTooltipIcon = NULL;
+ gchar *sTooltipTitle = NULL;
+ gchar *sTooltipDescription = NULL;
+ g_variant_get (parameters, "(sisosssssssss)", &iconname,
+ &position, &dbusaddress, &dbusobject,
+ &icon_theme_path, &label, &guide,
+ &accessible_desc, &hint, &title, &sTooltipIcon, &sTooltipTitle, &sTooltipDescription);
+
+ application_added(self, iconname, position, dbusaddress,
+ dbusobject, icon_theme_path, label, guide,
+ accessible_desc, hint, sTooltipIcon, sTooltipTitle, sTooltipDescription);
+ g_free(iconname);
+ g_free(dbusaddress);
+ g_free(dbusobject);
+ g_free(icon_theme_path);
+ g_free(label);
+ g_free(guide);
+ g_free(accessible_desc);
+ g_free(hint);
+ g_free(title);
+ g_free (sTooltipIcon);
+ g_free (sTooltipTitle);
+ g_free (sTooltipDescription);
+ }
+ else if (g_strcmp0(signal_name, "ApplicationRemoved") == 0) {
+ gint position;
+ g_variant_get (parameters, "(i)", &position);
+ application_removed(self, position);
+ }
+ else if (g_strcmp0(signal_name, "ApplicationIconChanged") == 0) {
+ gint position;
+ gchar * iconname = NULL;
+ gchar * icondesc = NULL;
+ g_variant_get (parameters, "(iss)", &position, &iconname, &icondesc);
+ application_icon_changed(self, position, iconname, icondesc);
+ g_free(iconname);
+ g_free(icondesc);
+ }
+ else if (g_strcmp0(signal_name, "ApplicationIconThemePathChanged") == 0) {
+ gint position;
+ gchar * icon_theme_path = NULL;
+ g_variant_get (parameters, "(is)", &position, &icon_theme_path);
+ application_icon_theme_path_changed(self, position, icon_theme_path);
+ g_free(icon_theme_path);
+ }
+ else if (g_strcmp0(signal_name, "ApplicationLabelChanged") == 0) {
+ gint position;
+ gchar * label = NULL;
+ gchar * guide = NULL;
+ g_variant_get (parameters, "(iss)", &position, &label, &guide);
+ application_label_changed(self, position, label, guide);
+ g_free(label);
+ g_free(guide);
+ }
+ else if (g_strcmp0 (signal_name, "ApplicationTooltipChanged") == 0)
+ {
+ gint nPosition = 0;
+ gchar *sIcon = NULL;
+ gchar *sTitle = NULL;
+ gchar *sDescription = NULL;
+ g_variant_get (parameters, "(isss)", &nPosition, &sIcon, &sTitle, &sDescription);
+ ApplicationEntry *pEntry = (ApplicationEntry*) g_list_nth_data (priv->applications, nPosition);
+ setTooltip (pEntry, sIcon, sTitle, sDescription);
+ g_free (sIcon);
+ g_free (sTitle);
+ g_free (sDescription);
+ }
+
+ return;
}
/* This responds to the list of applications that the service
@@ -865,46 +1024,46 @@ receive_signal (GDBusProxy * proxy, gchar * sender_name, gchar * signal_name,
static void
get_applications (GObject * obj, GAsyncResult * res, gpointer user_data)
{
- IndicatorApplication * self = INDICATOR_APPLICATION(user_data);
- IndicatorApplicationPrivate * priv = indicator_application_get_instance_private(self);
- GError * error = NULL;
- GVariant * result;
- GVariant * child;
- GVariantIter * iter;
-
- result = g_dbus_proxy_call_finish(priv->service_proxy, res, &error);
-
- /* No one can cancel us anymore, we've completed! */
- if (priv->get_apps_cancel != NULL) {
- if (error == NULL || error->domain != G_IO_ERROR || error->code != G_IO_ERROR_CANCELLED) {
- g_object_unref(priv->get_apps_cancel);
- priv->get_apps_cancel = NULL;
- }
- }
-
- /* If we got an error, print it and exit out */
- if (error != NULL) {
- g_warning("Unable to get application list: %s", error->message);
- g_error_free(error);
- return;
- }
-
- /* Remove all applications that we previously had
- as we're going to repopulate the list. */
- while (priv->applications != NULL) {
- application_removed(self, 0);
- }
-
- /* Get our new applications that we got in the request */
- g_variant_get(result, "(a(sisossssss))", &iter);
- while ((child = g_variant_iter_next_value (iter))) {
- get_applications_helper(self, child);
- g_variant_unref(child);
- }
- g_variant_iter_free (iter);
- g_variant_unref(result);
-
- return;
+ IndicatorApplication * self = INDICATOR_APPLICATION(user_data);
+ IndicatorApplicationPrivate * priv = indicator_application_get_instance_private(self);
+ GError * error = NULL;
+ GVariant * result;
+ GVariant * child;
+ GVariantIter * iter;
+
+ result = g_dbus_proxy_call_finish(priv->service_proxy, res, &error);
+
+ /* No one can cancel us anymore, we've completed! */
+ if (priv->get_apps_cancel != NULL) {
+ if (error == NULL || error->domain != G_IO_ERROR || error->code != G_IO_ERROR_CANCELLED) {
+ g_object_unref(priv->get_apps_cancel);
+ priv->get_apps_cancel = NULL;
+ }
+ }
+
+ /* If we got an error, print it and exit out */
+ if (error != NULL) {
+ g_warning("Unable to get application list: %s", error->message);
+ g_error_free(error);
+ return;
+ }
+
+ /* Remove all applications that we previously had
+ as we're going to repopulate the list. */
+ while (priv->applications != NULL) {
+ application_removed(self, 0);
+ }
+
+ /* Get our new applications that we got in the request */
+ g_variant_get(result, "(a(sisosssssssss))", &iter);
+ while ((child = g_variant_iter_next_value (iter))) {
+ get_applications_helper(self, child);
+ g_variant_unref(child);
+ }
+ g_variant_iter_free (iter);
+ g_variant_unref(result);
+
+ return;
}
/* A little helper that takes apart the DBus structure and calls
@@ -912,33 +1071,39 @@ get_applications (GObject * obj, GAsyncResult * res, gpointer user_data)
static void
get_applications_helper (IndicatorApplication * self, GVariant * variant)
{
- gchar * icon_name = NULL;
- gint position;
- gchar * dbus_address = NULL;
- gchar * dbus_object = NULL;
- gchar * icon_theme_path = NULL;
- gchar * label = NULL;
- gchar * guide = NULL;
- gchar * accessible_desc = NULL;
- gchar * hint = NULL;
- gchar * title = NULL;
- g_variant_get(variant, "(sisossssss)", &icon_name, &position,
- &dbus_address, &dbus_object, &icon_theme_path, &label,
- &guide, &accessible_desc, &hint, &title);
-
- application_added(self, icon_name, position, dbus_address, dbus_object, icon_theme_path, label, guide, accessible_desc, hint);
-
- g_free(icon_name);
- g_free(dbus_address);
- g_free(dbus_object);
- g_free(icon_theme_path);
- g_free(label);
- g_free(guide);
- g_free(accessible_desc);
- g_free(hint);
- g_free(title);
-
- return;
+ gchar * icon_name = NULL;
+ gint position;
+ gchar * dbus_address = NULL;
+ gchar * dbus_object = NULL;
+ gchar * icon_theme_path = NULL;
+ gchar * label = NULL;
+ gchar * guide = NULL;
+ gchar * accessible_desc = NULL;
+ gchar * hint = NULL;
+ gchar * title = NULL;
+ gchar *sTooltipIcon = NULL;
+ gchar *sTooltipTitle = NULL;
+ gchar *sTooltipDescription = NULL;
+ g_variant_get(variant, "(sisosssssssss)", &icon_name, &position,
+ &dbus_address, &dbus_object, &icon_theme_path, &label,
+ &guide, &accessible_desc, &hint, &title, &sTooltipIcon, &sTooltipTitle, &sTooltipDescription);
+
+ application_added(self, icon_name, position, dbus_address, dbus_object, icon_theme_path, label, guide, accessible_desc, hint, sTooltipIcon, sTooltipTitle, sTooltipDescription);
+
+ g_free(icon_name);
+ g_free(dbus_address);
+ g_free(dbus_object);
+ g_free(icon_theme_path);
+ g_free(label);
+ g_free(guide);
+ g_free(accessible_desc);
+ g_free(hint);
+ g_free(title);
+ g_free (sTooltipIcon);
+ g_free (sTooltipTitle);
+ g_free (sTooltipDescription);
+
+ return;
}
/* Unrefs a theme directory. This may involve removing it from
@@ -946,58 +1111,58 @@ get_applications_helper (IndicatorApplication * self, GVariant * variant)
static void
theme_dir_unref(IndicatorApplication * ia, const gchar * dir)
{
- IndicatorApplicationPrivate * priv = indicator_application_get_instance_private(ia);
-
- if (!g_hash_table_contains (priv->theme_dirs, dir)) {
- g_warning("Unref'd a directory '%s' that wasn't in the theme dir hash table.", dir);
- } else {
- int count = GPOINTER_TO_INT(g_hash_table_lookup(priv->theme_dirs, dir));
- if (count > 1) {
- count--;
- g_hash_table_insert(priv->theme_dirs, g_strdup(dir), GINT_TO_POINTER(count));
- } else {
- icon_theme_remove_dir_from_search_path (dir);
- g_hash_table_remove (priv->theme_dirs, dir);
- }
- }
+ IndicatorApplicationPrivate * priv = indicator_application_get_instance_private(ia);
+
+ if (!g_hash_table_contains (priv->theme_dirs, dir)) {
+ g_warning("Unref'd a directory '%s' that wasn't in the theme dir hash table.", dir);
+ } else {
+ int count = GPOINTER_TO_INT(g_hash_table_lookup(priv->theme_dirs, dir));
+ if (count > 1) {
+ count--;
+ g_hash_table_insert(priv->theme_dirs, g_strdup(dir), GINT_TO_POINTER(count));
+ } else {
+ icon_theme_remove_dir_from_search_path (dir);
+ g_hash_table_remove (priv->theme_dirs, dir);
+ }
+ }
}
static void
icon_theme_remove_dir_from_search_path (const char * dir)
{
- GtkIconTheme * icon_theme = gtk_icon_theme_get_default();
- gchar ** paths;
- gint path_count;
-
- gtk_icon_theme_get_search_path(icon_theme, &paths, &path_count);
-
- gint i;
- gboolean found = FALSE;
- for (i = 0; i < path_count; i++) {
- if (found) {
- /* If we've already found the right entry */
- paths[i - 1] = paths[i];
- } else {
- /* We're still looking, is this the one? */
- if (!g_strcmp0(paths[i], dir)) {
- found = TRUE;
- /* We're freeing this here as it won't be captured by the
- g_strfreev() below as it's out of the array. */
- g_free(paths[i]);
- }
- }
- }
-
- /* If we found one we need to reset the path to
- accomidate the changes */
- if (found) {
- paths[path_count - 1] = NULL; /* Clear the last one */
- gtk_icon_theme_set_search_path(icon_theme, (const gchar **)paths, path_count - 1);
- }
-
- g_strfreev(paths);
-
- return;
+ GtkIconTheme * icon_theme = gtk_icon_theme_get_default();
+ gchar ** paths;
+ gint path_count;
+
+ gtk_icon_theme_get_search_path(icon_theme, &paths, &path_count);
+
+ gint i;
+ gboolean found = FALSE;
+ for (i = 0; i < path_count; i++) {
+ if (found) {
+ /* If we've already found the right entry */
+ paths[i - 1] = paths[i];
+ } else {
+ /* We're still looking, is this the one? */
+ if (!g_strcmp0(paths[i], dir)) {
+ found = TRUE;
+ /* We're freeing this here as it won't be captured by the
+ g_strfreev() below as it's out of the array. */
+ g_free(paths[i]);
+ }
+ }
+ }
+
+ /* If we found one we need to reset the path to
+ accomidate the changes */
+ if (found) {
+ paths[path_count - 1] = NULL; /* Clear the last one */
+ gtk_icon_theme_set_search_path(icon_theme, (const gchar **)paths, path_count - 1);
+ }
+
+ g_strfreev(paths);
+
+ return;
}
/* Refs a theme directory, and it may add it to the search
@@ -1005,23 +1170,23 @@ icon_theme_remove_dir_from_search_path (const char * dir)
static void
theme_dir_ref(IndicatorApplication * ia, const gchar * dir)
{
- IndicatorApplicationPrivate * priv = indicator_application_get_instance_private(ia);
-
- int count = 0;
- if ((count = GPOINTER_TO_INT(g_hash_table_lookup(priv->theme_dirs, dir))) != 0) {
- /* It exists so what we need to do is increase the ref
- count of this dir. */
- count++;
- } else {
- /* It doesn't exist, so we need to add it to the table
- and to the search path. */
- gtk_icon_theme_append_search_path(gtk_icon_theme_get_default(), dir);
- g_debug("\tAppending search path: %s", dir);
- count = 1;
- }
-
- g_hash_table_insert(priv->theme_dirs, g_strdup(dir), GINT_TO_POINTER(count));
-
- return;
+ IndicatorApplicationPrivate * priv = indicator_application_get_instance_private(ia);
+
+ int count = 0;
+ if ((count = GPOINTER_TO_INT(g_hash_table_lookup(priv->theme_dirs, dir))) != 0) {
+ /* It exists so what we need to do is increase the ref
+ count of this dir. */
+ count++;
+ } else {
+ /* It doesn't exist, so we need to add it to the table
+ and to the search path. */
+ gtk_icon_theme_append_search_path(gtk_icon_theme_get_default(), dir);
+ g_debug("\tAppending search path: %s", dir);
+ count = 1;
+ }
+
+ g_hash_table_insert(priv->theme_dirs, g_strdup(dir), GINT_TO_POINTER(count));
+
+ return;
}