[gnome-panel] status-notifier: add items to panel
- From: Alberts Muktupāvels <muktupavels src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-panel] status-notifier: add items to panel
- Date: Thu, 3 Nov 2016 00:33:25 +0000 (UTC)
commit 9d265f9d69d2b4bfc8bd9bbab9d491515212a7d1
Author: Alberts Muktupāvels <alberts muktupavels gmail com>
Date: Thu Nov 3 02:30:09 2016 +0200
status-notifier: add items to panel
applets/status-notifier/sn-applet.c | 40 +++++++++-
applets/status-notifier/sn-host-v0.c | 103 ++++++++++++++++++++------
applets/status-notifier/sn-host.c | 33 ++++++++
applets/status-notifier/sn-host.h | 8 ++-
applets/status-notifier/sn-item-v0.c | 85 +++++++++++++++++++++-
applets/status-notifier/sn-item-v0.h | 3 +
applets/status-notifier/sn-item.c | 136 +++++++++++++++++++++++++++++++++-
applets/status-notifier/sn-item.h | 3 +
8 files changed, 382 insertions(+), 29 deletions(-)
---
diff --git a/applets/status-notifier/sn-applet.c b/applets/status-notifier/sn-applet.c
index f6bfa60..65bd141 100644
--- a/applets/status-notifier/sn-applet.c
+++ b/applets/status-notifier/sn-applet.c
@@ -19,27 +19,53 @@
#include "sn-applet.h"
#include "sn-host-v0.h"
+#include "sn-item.h"
struct _SnApplet
{
GpApplet parent;
- SnHost *host_v0;
-
GtkWidget *box;
+
+ GSList *hosts;
+ GSList *items;
};
G_DEFINE_TYPE (SnApplet, sn_applet, GP_TYPE_APPLET)
static void
+item_added_cb (SnHost *host,
+ SnItem *item,
+ SnApplet *sn)
+{
+ sn->items = g_slist_prepend (sn->items, item);
+ gtk_box_pack_start (GTK_BOX (sn->box), GTK_WIDGET (item), FALSE, FALSE, 0);
+ gtk_widget_show (GTK_WIDGET (item));
+}
+
+static void
+item_removed_cb (SnHost *host,
+ SnItem *item,
+ SnApplet *sn)
+{
+ gtk_container_remove (GTK_CONTAINER (sn->box), GTK_WIDGET (item));
+ sn->items = g_slist_remove (sn->items, item);
+}
+
+static void
sn_applet_constructed (GObject *object)
{
SnApplet *sn;
+ SnHost *host;
G_OBJECT_CLASS (sn_applet_parent_class)->constructed (object);
sn = SN_APPLET (object);
- sn->host_v0 = sn_host_v0_new ();
+ host = sn_host_v0_new ();
+ sn->hosts = g_slist_prepend (sn->hosts, host);
+
+ g_signal_connect (host, "item-added", G_CALLBACK (item_added_cb), sn);
+ g_signal_connect (host, "item-removed", G_CALLBACK (item_removed_cb), sn);
gtk_widget_show (GTK_WIDGET (object));
}
@@ -51,7 +77,13 @@ sn_applet_dispose (GObject *object)
sn = SN_APPLET (object);
- g_clear_object (&sn->host_v0);
+ if (sn->hosts != NULL)
+ {
+ g_slist_free_full (sn->hosts, g_object_unref);
+ sn->hosts = NULL;
+ }
+
+ g_clear_pointer (&sn->items, g_slist_free);
G_OBJECT_CLASS (sn_applet_parent_class)->dispose (object);
}
diff --git a/applets/status-notifier/sn-host-v0.c b/applets/status-notifier/sn-host-v0.c
index c43ab1b..3cd6af9 100644
--- a/applets/status-notifier/sn-host-v0.c
+++ b/applets/status-notifier/sn-host-v0.c
@@ -18,6 +18,7 @@
#include "config.h"
#include "sn-host-v0.h"
+#include "sn-item-v0.h"
#include "sn-watcher-v0-gen.h"
#define SN_HOST_BUS_NAME "org.kde.StatusNotifierHost"
@@ -36,8 +37,17 @@ struct _SnHostV0
guint watcher_id;
SnWatcherV0Gen *watcher;
+
+ GSList *items;
};
+static void sn_host_v0_gen_init (SnHostV0GenIface *iface);
+static void sn_host_init (SnHostInterface *iface);
+
+G_DEFINE_TYPE_WITH_CODE (SnHostV0, sn_host_v0, SN_TYPE_HOST_V0_GEN_SKELETON,
+ G_IMPLEMENT_INTERFACE (SN_TYPE_HOST_V0_GEN, sn_host_v0_gen_init)
+ G_IMPLEMENT_INTERFACE (SN_TYPE_HOST, sn_host_init))
+
static void
sn_host_v0_gen_init (SnHostV0GenIface *iface)
{
@@ -48,10 +58,6 @@ sn_host_init (SnHostInterface *iface)
{
}
-G_DEFINE_TYPE_WITH_CODE (SnHostV0, sn_host_v0, SN_TYPE_HOST_V0_GEN_SKELETON,
- G_IMPLEMENT_INTERFACE (SN_TYPE_HOST_V0_GEN, sn_host_v0_gen_init)
- G_IMPLEMENT_INTERFACE (SN_TYPE_HOST, sn_host_init))
-
static void
get_bus_name_and_object_path (const gchar *service,
gchar **bus_name,
@@ -82,29 +88,74 @@ get_bus_name_and_object_path (const gchar *service,
}
static void
-item_registered_cb (SnWatcherV0Gen *watcher,
- const gchar *service,
- SnHostV0 *v0)
+add_registered_item (SnHostV0 *v0,
+ const gchar *service)
{
gchar *bus_name;
gchar *object_path;
+ SnItem *item;
bus_name = NULL;
object_path = NULL;
get_bus_name_and_object_path (service, &bus_name, &object_path);
- g_debug ("item: bus name - %s, object path - %s", bus_name, object_path);
+ item = sn_item_v0_new (bus_name, object_path);
+ g_object_ref_sink (item);
+
+ v0->items = g_slist_prepend (v0->items, item);
+ sn_host_emit_item_added (SN_HOST (v0), item);
g_free (bus_name);
g_free (object_path);
}
static void
+item_registered_cb (SnWatcherV0Gen *watcher,
+ const gchar *service,
+ SnHostV0 *v0)
+{
+ add_registered_item (v0, service);
+}
+
+static void
item_unregistered_cb (SnWatcherV0Gen *watcher,
const gchar *service,
SnHostV0 *v0)
{
+ GSList *l;
+
+ for (l = v0->items; l != NULL; l = g_slist_next (l))
+ {
+ SnItem *item;
+ gboolean found;
+ gchar *bus_name;
+ gchar *object_path;
+
+ item = SN_ITEM (l->data);
+
+ found = FALSE;
+ bus_name = NULL;
+ object_path = NULL;
+
+ get_bus_name_and_object_path (service, &bus_name, &object_path);
+
+ if (g_strcmp0 (sn_item_get_bus_name (item), bus_name) == 0 &&
+ g_strcmp0 (sn_item_get_object_path (item), object_path) == 0)
+ {
+ v0->items = g_slist_remove (v0->items, item);
+ sn_host_emit_item_removed (SN_HOST (v0), item);
+ g_object_unref (item);
+
+ found = TRUE;
+ }
+
+ g_free (bus_name);
+ g_free (object_path);
+
+ if (found)
+ break;
+ }
}
static void
@@ -139,20 +190,7 @@ register_host_cb (GObject *source_object,
items = sn_watcher_v0_gen_dup_registered_items (v0->watcher);
for (i = 0; items[i] != NULL; i++)
- {
- gchar *bus_name;
- gchar *object_path;
-
- bus_name = NULL;
- object_path = NULL;
-
- get_bus_name_and_object_path (items[i], &bus_name, &object_path);
-
- g_debug ("item: bus name - %s, object path - %s", bus_name, object_path);
-
- g_free (bus_name);
- g_free (object_path);
- }
+ add_registered_item (v0, items[i]);
g_strfreev (items);
}
@@ -194,6 +232,13 @@ name_appeared_cb (GDBusConnection *connection,
}
static void
+emit_item_removed_signal (gpointer data,
+ gpointer user_data)
+{
+ sn_host_emit_item_removed (SN_HOST (user_data), SN_ITEM (data));
+}
+
+static void
name_vanished_cb (GDBusConnection *connection,
const gchar *name,
gpointer user_data)
@@ -203,6 +248,13 @@ name_vanished_cb (GDBusConnection *connection,
v0 = SN_HOST_V0 (user_data);
g_clear_object (&v0->watcher);
+
+ if (v0->items)
+ {
+ g_slist_foreach (v0->items, emit_item_removed_signal, v0);
+ g_slist_free_full (v0->items, g_object_unref);
+ v0->items = NULL;
+ }
}
static void
@@ -256,6 +308,13 @@ sn_host_v0_dispose (GObject *object)
g_clear_object (&v0->watcher);
+ if (v0->items)
+ {
+ g_slist_foreach (v0->items, emit_item_removed_signal, v0);
+ g_slist_free_full (v0->items, g_object_unref);
+ v0->items = NULL;
+ }
+
G_OBJECT_CLASS (sn_host_v0_parent_class)->dispose (object);
}
diff --git a/applets/status-notifier/sn-host.c b/applets/status-notifier/sn-host.c
index 97b8b66..c8fe48c 100644
--- a/applets/status-notifier/sn-host.c
+++ b/applets/status-notifier/sn-host.c
@@ -18,10 +18,43 @@
#include "config.h"
#include "sn-host.h"
+#include "sn-item.h"
+
+enum
+{
+ SIGNAL_ITEM_ADDED,
+ SIGNAL_ITEM_REMOVED,
+
+ LAST_SIGNAL
+};
+
+static guint signals[LAST_SIGNAL] = { 0 };
G_DEFINE_INTERFACE (SnHost, sn_host, G_TYPE_OBJECT)
static void
sn_host_default_init (SnHostInterface *iface)
{
+ signals[SIGNAL_ITEM_ADDED] =
+ g_signal_new ("item-added", G_TYPE_FROM_INTERFACE (iface),
+ G_SIGNAL_RUN_LAST, 0, NULL, NULL, NULL,
+ G_TYPE_NONE, 1, SN_TYPE_ITEM);
+
+ signals[SIGNAL_ITEM_REMOVED] =
+ g_signal_new ("item-removed", G_TYPE_FROM_INTERFACE (iface),
+ G_SIGNAL_RUN_LAST, 0, NULL, NULL, NULL,
+ G_TYPE_NONE, 1, SN_TYPE_ITEM);
+}
+
+void
+sn_host_emit_item_added (SnHost *host,
+ SnItem *item)
+{
+ g_signal_emit (host, signals[SIGNAL_ITEM_ADDED], 0, item);
+}
+
+void sn_host_emit_item_removed (SnHost *host,
+ SnItem *item)
+{
+ g_signal_emit (host, signals[SIGNAL_ITEM_REMOVED], 0, item);
}
diff --git a/applets/status-notifier/sn-host.h b/applets/status-notifier/sn-host.h
index 4084363..d21f04e 100644
--- a/applets/status-notifier/sn-host.h
+++ b/applets/status-notifier/sn-host.h
@@ -18,7 +18,7 @@
#ifndef SN_HOST_H
#define SN_HOST_H
-#include <glib-object.h>
+#include "sn-item.h"
G_BEGIN_DECLS
@@ -30,6 +30,12 @@ struct _SnHostInterface
GTypeInterface parent;
};
+void sn_host_emit_item_added (SnHost *host,
+ SnItem *item);
+
+void sn_host_emit_item_removed (SnHost *host,
+ SnItem *item);
+
G_END_DECLS
#endif
diff --git a/applets/status-notifier/sn-item-v0.c b/applets/status-notifier/sn-item-v0.c
index 37cdccb..e88df0c 100644
--- a/applets/status-notifier/sn-item-v0.c
+++ b/applets/status-notifier/sn-item-v0.c
@@ -18,20 +18,103 @@
#include "config.h"
#include "sn-item-v0.h"
+#include "sn-item-v0-gen.h"
struct _SnItemV0
{
- SnItem parent;
+ SnItem parent;
+
+ GCancellable *cancellable;
+ SnItemV0Gen *proxy;
};
G_DEFINE_TYPE (SnItemV0, sn_item_v0, SN_TYPE_ITEM)
static void
+proxy_ready_cb (GObject *source_object,
+ GAsyncResult *res,
+ gpointer user_data)
+{
+ SnItemV0 *v0;
+ SnItemV0Gen *proxy;
+ GError *error;
+
+ error = NULL;
+ proxy = sn_item_v0_gen_proxy_new_for_bus_finish (res, &error);
+
+ if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED))
+ {
+ g_error_free (error);
+ return;
+ }
+
+ v0 = SN_ITEM_V0 (user_data);
+ v0->proxy = proxy;
+
+ if (error)
+ {
+ g_warning ("%s", error->message);
+ g_error_free (error);
+ return;
+ }
+}
+
+static void
+sn_item_v0_constructed (GObject *object)
+{
+ SnItemV0 *v0;
+ SnItem *item;
+
+ v0 = SN_ITEM_V0 (object);
+ item = SN_ITEM (v0);
+
+ G_OBJECT_CLASS (sn_item_v0_parent_class)->constructed (object);
+
+ v0->cancellable = g_cancellable_new ();
+ sn_item_v0_gen_proxy_new_for_bus (G_BUS_TYPE_SESSION,
+ G_DBUS_PROXY_FLAGS_NONE,
+ sn_item_get_bus_name (item),
+ sn_item_get_object_path (item),
+ v0->cancellable,
+ proxy_ready_cb, v0);
+}
+
+static void
+sn_item_v0_dispose (GObject *object)
+{
+ SnItemV0 *v0;
+
+ v0 = SN_ITEM_V0 (object);
+
+ g_cancellable_cancel (v0->cancellable);
+ g_clear_object (&v0->cancellable);
+ g_clear_object (&v0->proxy);
+
+ G_OBJECT_CLASS (sn_item_v0_parent_class)->dispose (object);
+}
+
+static void
sn_item_v0_class_init (SnItemV0Class *v0_class)
{
+ GObjectClass *object_class;
+
+ object_class = G_OBJECT_CLASS (v0_class);
+
+ object_class->constructed = sn_item_v0_constructed;
+ object_class->dispose = sn_item_v0_dispose;
}
static void
sn_item_v0_init (SnItemV0 *v0)
{
}
+
+SnItem *
+sn_item_v0_new (const gchar *bus_name,
+ const gchar *object_path)
+{
+ return g_object_new (SN_TYPE_ITEM_V0,
+ "bus-name", bus_name,
+ "object-path", object_path,
+ NULL);
+}
diff --git a/applets/status-notifier/sn-item-v0.h b/applets/status-notifier/sn-item-v0.h
index 7da2033..87672ad 100644
--- a/applets/status-notifier/sn-item-v0.h
+++ b/applets/status-notifier/sn-item-v0.h
@@ -25,6 +25,9 @@ G_BEGIN_DECLS
#define SN_TYPE_ITEM_V0 sn_item_v0_get_type ()
G_DECLARE_FINAL_TYPE (SnItemV0, sn_item_v0, SN, ITEM_V0, SnItem)
+SnItem *sn_item_v0_new (const gchar *bus_name,
+ const gchar *object_path);
+
G_END_DECLS
#endif
diff --git a/applets/status-notifier/sn-item.c b/applets/status-notifier/sn-item.c
index 10d1bff..0512793 100644
--- a/applets/status-notifier/sn-item.c
+++ b/applets/status-notifier/sn-item.c
@@ -19,14 +19,148 @@
#include "sn-item.h"
-G_DEFINE_ABSTRACT_TYPE (SnItem, sn_item, GTK_TYPE_BUTTON)
+typedef struct
+{
+ gchar *bus_name;
+ gchar *object_path;
+} SnItemPrivate;
+
+enum
+{
+ PROP_0,
+
+ PROP_BUS_NAME,
+ PROP_OBJECT_PATH,
+
+ LAST_PROP
+};
+
+static GParamSpec *properties[LAST_PROP] = { NULL };
+
+G_DEFINE_ABSTRACT_TYPE_WITH_PRIVATE (SnItem, sn_item, GTK_TYPE_BUTTON)
+
+static void
+sn_item_finalize (GObject *object)
+{
+ SnItem *item;
+ SnItemPrivate *priv;
+
+ item = SN_ITEM (object);
+ priv = sn_item_get_instance_private (item);
+
+ g_clear_pointer (&priv->bus_name, g_free);
+ g_clear_pointer (&priv->object_path, g_free);
+
+ G_OBJECT_CLASS (sn_item_parent_class)->finalize (object);
+}
+
+static void
+sn_item_get_property (GObject *object,
+ guint property_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ SnItem *item;
+ SnItemPrivate *priv;
+
+ item = SN_ITEM (object);
+ priv = sn_item_get_instance_private (item);
+
+ switch (property_id)
+ {
+ case PROP_BUS_NAME:
+ g_value_set_string (value, priv->bus_name);
+ break;
+
+ case PROP_OBJECT_PATH:
+ g_value_set_string (value, priv->object_path);
+ break;
+
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+ break;
+ }
+}
+
+static void
+sn_item_set_property (GObject *object,
+ guint property_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ SnItem *item;
+ SnItemPrivate *priv;
+
+ item = SN_ITEM (object);
+ priv = sn_item_get_instance_private (item);
+
+ switch (property_id)
+ {
+ case PROP_BUS_NAME:
+ priv->bus_name = g_value_dup_string (value);
+ break;
+
+ case PROP_OBJECT_PATH:
+ priv->object_path = g_value_dup_string (value);
+ break;
+
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+ break;
+ }
+}
+
+static void
+install_properties (GObjectClass *object_class)
+{
+ properties[PROP_BUS_NAME] =
+ g_param_spec_string ("bus-name", "bus-name", "bus-name", NULL,
+ G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE |
+ G_PARAM_STATIC_STRINGS);
+
+ properties[PROP_OBJECT_PATH] =
+ g_param_spec_string ("object-path", "object-path", "object-path", NULL,
+ G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE |
+ G_PARAM_STATIC_STRINGS);
+
+ g_object_class_install_properties (object_class, LAST_PROP, properties);
+}
static void
sn_item_class_init (SnItemClass *item_class)
{
+ GObjectClass *object_class;
+
+ object_class = G_OBJECT_CLASS (item_class);
+
+ object_class->finalize = sn_item_finalize;
+ object_class->get_property = sn_item_get_property;
+ object_class->set_property = sn_item_set_property;
+
+ install_properties (object_class);
}
static void
sn_item_init (SnItem *item)
{
}
+
+const gchar *
+sn_item_get_bus_name (SnItem *item)
+{
+ SnItemPrivate *priv;
+
+ priv = sn_item_get_instance_private (item);
+
+ return priv->bus_name;
+}
+
+const gchar *
+sn_item_get_object_path (SnItem *item)
+{
+ SnItemPrivate *priv;
+
+ priv = sn_item_get_instance_private (item);
+
+ return priv->object_path;
+}
diff --git a/applets/status-notifier/sn-item.h b/applets/status-notifier/sn-item.h
index c3612ca..5985bec 100644
--- a/applets/status-notifier/sn-item.h
+++ b/applets/status-notifier/sn-item.h
@@ -30,6 +30,9 @@ struct _SnItemClass
GtkButtonClass parent_class;
};
+const gchar *sn_item_get_bus_name (SnItem *item);
+const gchar *sn_item_get_object_path (SnItem *item);
+
G_END_DECLS
#endif
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]