aboutsummaryrefslogtreecommitdiff
path: root/src/indicator-application.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/indicator-application.c')
-rw-r--r--src/indicator-application.c1571
1 files changed, 868 insertions, 703 deletions
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;
}