2
A small wrapper utility to load indicators and put them as menu items
3
into the gnome-panel using its applet interface.
5
Copyright 2009 Canonical Ltd.
8
Ted Gould <ted@canonical.com>
9
Conor Curran <conor.curran@canonical.com>
11
This program is free software: you can redistribute it and/or modify it
12
under the terms of the GNU General Public License version 3, as published
13
by the Free Software Foundation.
15
This program is distributed in the hope that it will be useful, but
16
WITHOUT ANY WARRANTY; without even the implied warranties of
17
MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
18
PURPOSE. See the GNU General Public License for more details.
20
You should have received a copy of the GNU General Public License along
21
with this program. If not, see <http://www.gnu.org/licenses/>.
29
#include <glib-object.h>
30
#include <glib/gi18n-lib.h>
34
#include <libdbusmenu-gtk/menu.h>
36
#include <libindicator/indicator.h>
37
#include <libindicator/indicator-object.h>
38
#include <libindicator/indicator-service-manager.h>
40
#include "shared-names.h"
41
#include "user-widget.h"
43
#define INDICATOR_SESSION_TYPE (indicator_session_get_type ())
44
#define INDICATOR_SESSION(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), INDICATOR_SESSION_TYPE, IndicatorSession))
45
#define INDICATOR_SESSION_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), INDICATOR_SESSION_TYPE, IndicatorSessionClass))
46
#define IS_INDICATOR_SESSION(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), INDICATOR_SESSION_TYPE))
47
#define IS_INDICATOR_SESSION_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), INDICATOR_SESSION_TYPE))
48
#define INDICATOR_SESSION_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), INDICATOR_SESSION_TYPE, IndicatorSessionClass))
50
typedef struct _IndicatorSession IndicatorSession;
51
typedef struct _IndicatorSessionClass IndicatorSessionClass;
53
struct _IndicatorSessionClass
55
IndicatorObjectClass parent_class;
58
struct _IndicatorSession
60
IndicatorObject parent;
61
IndicatorServiceManager * service;
62
IndicatorObjectEntry entry;
63
GCancellable * service_proxy_cancel;
64
GDBusProxy * service_proxy;
68
static gboolean greeter_mode;
70
GType indicator_session_get_type (void);
74
INDICATOR_SET_TYPE(INDICATOR_SESSION_TYPE)
77
static gboolean new_user_item (DbusmenuMenuitem * newitem,
78
DbusmenuMenuitem * parent,
79
DbusmenuClient * client,
81
static gboolean build_restart_item (DbusmenuMenuitem * newitem,
82
DbusmenuMenuitem * parent,
83
DbusmenuClient * client,
85
static void indicator_session_update_users_label (IndicatorSession* self,
87
static void service_connection_cb (IndicatorServiceManager * sm, gboolean connected, gpointer user_data);
88
static void receive_signal (GDBusProxy * proxy, gchar * sender_name, gchar * signal_name, GVariant * parameters, gpointer user_data);
89
static void service_proxy_cb (GObject * object, GAsyncResult * res, gpointer user_data);
90
static void user_real_name_get_cb (GObject * obj, GAsyncResult * res, gpointer user_data);
92
static void indicator_session_class_init (IndicatorSessionClass *klass);
93
static void indicator_session_init (IndicatorSession *self);
94
static void indicator_session_dispose (GObject *object);
95
static void indicator_session_finalize (GObject *object);
96
static GList* indicator_session_get_entries (IndicatorObject* obj);
97
static guint indicator_session_get_location (IndicatorObject * io,
98
IndicatorObjectEntry * entry);
100
G_DEFINE_TYPE (IndicatorSession, indicator_session, INDICATOR_OBJECT_TYPE);
103
indicator_session_class_init (IndicatorSessionClass *klass)
105
GObjectClass *object_class = G_OBJECT_CLASS (klass);
107
object_class->dispose = indicator_session_dispose;
108
object_class->finalize = indicator_session_finalize;
110
IndicatorObjectClass * io_class = INDICATOR_OBJECT_CLASS(klass);
111
io_class->get_entries = indicator_session_get_entries;
112
io_class->get_location = indicator_session_get_location;
117
indicator_session_init (IndicatorSession *self)
119
const gchar * icon_name;
121
self->settings = g_settings_new ("com.canonical.indicator.session");
123
/* Now let's fire these guys up. */
124
self->service = indicator_service_manager_new_version(INDICATOR_SESSION_DBUS_NAME,
125
INDICATOR_SESSION_DBUS_VERSION);
126
g_signal_connect (G_OBJECT(self->service),
127
INDICATOR_SERVICE_MANAGER_SIGNAL_CONNECTION_CHANGE,
128
G_CALLBACK(service_connection_cb), self);
130
greeter_mode = !g_strcmp0(g_getenv("INDICATOR_GREETER_MODE"), "1");
132
self->entry.name_hint = PACKAGE;
133
self->entry.accessible_desc = _("Session Menu");
134
self->entry.label = GTK_LABEL (gtk_label_new ("User Name"));
135
icon_name = greeter_mode ? GREETER_ICON_DEFAULT : ICON_DEFAULT;
136
self->entry.image = GTK_IMAGE (gtk_image_new_from_icon_name (icon_name, GTK_ICON_SIZE_BUTTON));
137
self->entry.menu = GTK_MENU (dbusmenu_gtkmenu_new(INDICATOR_SESSION_DBUS_NAME,
138
INDICATOR_SESSION_DBUS_OBJECT));
139
g_settings_bind (self->settings, "show-real-name-on-panel",
140
self->entry.label, "visible",
141
G_SETTINGS_BIND_GET);
143
gtk_widget_show (GTK_WIDGET(self->entry.menu));
144
gtk_widget_show (GTK_WIDGET(self->entry.image));
145
g_object_ref_sink (self->entry.menu);
146
g_object_ref_sink (self->entry.image);
148
// set up the handlers
149
DbusmenuClient * menu_client = DBUSMENU_CLIENT(dbusmenu_gtkmenu_get_client(DBUSMENU_GTKMENU(self->entry.menu)));
150
dbusmenu_client_add_type_handler (menu_client,
153
dbusmenu_client_add_type_handler (menu_client,
156
dbusmenu_gtkclient_set_accel_group (DBUSMENU_GTKCLIENT(menu_client),
157
gtk_accel_group_new());
161
indicator_session_dispose (GObject *object)
163
IndicatorSession * self = INDICATOR_SESSION(object);
165
g_clear_object (&self->settings);
166
g_clear_object (&self->service);
167
g_clear_object (&self->service_proxy);
169
if (self->service_proxy_cancel != NULL)
171
g_cancellable_cancel(self->service_proxy_cancel);
172
g_clear_object (&self->service_proxy_cancel);
175
g_clear_object (&self->entry.menu);
177
G_OBJECT_CLASS (indicator_session_parent_class)->dispose (object);
181
indicator_session_finalize (GObject *object)
184
G_OBJECT_CLASS (indicator_session_parent_class)->finalize (object);
189
indicator_session_get_entries (IndicatorObject* obj)
191
g_return_val_if_fail(IS_INDICATOR_SESSION(obj), NULL);
193
IndicatorSession* self = INDICATOR_SESSION (obj);
194
return g_list_append (NULL, &self->entry);
198
indicator_session_get_location (IndicatorObject * io,
199
IndicatorObjectEntry * entry)
204
/* callback for the service manager state of being */
206
service_connection_cb (IndicatorServiceManager * sm, gboolean connected, gpointer user_data)
208
IndicatorSession * self = INDICATOR_SESSION (user_data);
211
if (self->service_proxy != NULL){
213
// Fetch synchronisation data and return (proxy is still legit)
214
g_dbus_proxy_call (self->service_proxy,
217
G_DBUS_CALL_FLAGS_NONE,
220
user_real_name_get_cb,
225
self->service_proxy_cancel = g_cancellable_new();
226
g_dbus_proxy_new_for_bus (G_BUS_TYPE_SESSION,
227
G_DBUS_PROXY_FLAGS_NONE,
229
INDICATOR_SESSION_DBUS_NAME,
230
INDICATOR_SESSION_SERVICE_DBUS_OBJECT,
231
INDICATOR_SESSION_SERVICE_DBUS_IFACE,
232
self->service_proxy_cancel,
241
service_proxy_cb (GObject * object, GAsyncResult * res, gpointer user_data)
243
GError * error = NULL;
245
IndicatorSession * self = INDICATOR_SESSION(user_data);
246
g_return_if_fail(self != NULL);
248
GDBusProxy * proxy = g_dbus_proxy_new_for_bus_finish(res, &error);
250
g_clear_object (&self->service_proxy_cancel);
253
g_warning("Could not grab DBus proxy for %s: %s", INDICATOR_SESSION_DBUS_NAME, error->message);
258
/* Okay, we're good to grab the proxy at this point, we're
259
sure that it's ours. */
260
self->service_proxy = proxy;
262
g_signal_connect(proxy, "g-signal", G_CALLBACK(receive_signal), self);
264
// Fetch the user's real name for the user entry label
265
g_dbus_proxy_call (self->service_proxy,
268
G_DBUS_CALL_FLAGS_NONE,
271
user_real_name_get_cb,
278
new_user_item (DbusmenuMenuitem * newitem,
279
DbusmenuMenuitem * parent,
280
DbusmenuClient * client,
283
g_return_val_if_fail (DBUSMENU_IS_MENUITEM(newitem), FALSE);
284
g_return_val_if_fail (DBUSMENU_IS_GTKCLIENT(client), FALSE);
286
GtkWidget * user_item = user_widget_new (newitem);
288
GtkMenuItem *user_widget = GTK_MENU_ITEM(user_item);
290
dbusmenu_gtkclient_newitem_base (DBUSMENU_GTKCLIENT(client),
295
g_debug ("%s (\"%s\")", __func__,
296
dbusmenu_menuitem_property_get (newitem,
297
USER_ITEM_PROP_NAME));
298
gtk_widget_show_all (user_item);
305
user_real_name_get_cb (GObject * obj, GAsyncResult * res, gpointer user_data)
307
IndicatorSession * self = INDICATOR_SESSION(user_data);
309
GError * error = NULL;
310
GVariant * result = g_dbus_proxy_call_finish(self->service_proxy, res, &error);
314
g_warning ("Unable to complete real name dbus query: %s", error->message);
315
g_clear_error (&error);
319
const gchar * username = NULL;
320
g_variant_get (result, "(&s)", &username);
321
indicator_session_update_users_label (self, username);
322
g_variant_unref (result);
326
/* Receives all signals from the service, routed to the appropriate functions */
328
receive_signal (GDBusProxy * proxy,
331
GVariant * parameters,
334
IndicatorSession * self = INDICATOR_SESSION(user_data);
336
if (!g_strcmp0(signal_name, "UserRealNameUpdated"))
338
const gchar * username = NULL;
339
g_variant_get (parameters, "(&s)", &username);
340
indicator_session_update_users_label (self, username);
342
else if (!g_strcmp0(signal_name, "RestartRequired"))
344
const gchar * icon_name = greeter_mode ? GREETER_ICON_RESTART : ICON_RESTART;
345
gtk_image_set_from_icon_name (GTK_IMAGE(self->entry.image), icon_name, GTK_ICON_SIZE_MENU);
346
self->entry.accessible_desc = _("Device Menu (reboot required)");
347
g_signal_emit (G_OBJECT(self), INDICATOR_OBJECT_SIGNAL_ACCESSIBLE_DESC_UPDATE_ID, 0, &self->entry);
355
restart_property_change (DbusmenuMenuitem * item,
356
const gchar * property,
360
DbusmenuGtkClient * client = DBUSMENU_GTKCLIENT(user_data);
361
GtkMenuItem * gmi = dbusmenu_gtkclient_menuitem_get(client, item);
363
if (g_strcmp0(property, RESTART_ITEM_LABEL) == 0) {
364
gtk_menu_item_set_label(gmi, g_variant_get_string(variant, NULL));
365
} else if (g_strcmp0(property, RESTART_ITEM_ICON) == 0) {
366
GtkWidget * image = gtk_image_menu_item_get_image(GTK_IMAGE_MENU_ITEM(gmi));
368
GIcon * gicon = g_themed_icon_new_with_default_fallbacks(g_variant_get_string(variant, NULL));
370
image = gtk_image_new_from_gicon(gicon, GTK_ICON_SIZE_MENU);
371
gtk_image_menu_item_set_image(GTK_IMAGE_MENU_ITEM(gmi), image);
373
gtk_image_set_from_gicon(GTK_IMAGE(image), gicon, GTK_ICON_SIZE_MENU);
375
g_object_unref(G_OBJECT(gicon));
381
build_restart_item (DbusmenuMenuitem * newitem,
382
DbusmenuMenuitem * parent,
383
DbusmenuClient * client,
386
GtkMenuItem * gmi = GTK_MENU_ITEM(gtk_image_menu_item_new());
391
dbusmenu_gtkclient_newitem_base(DBUSMENU_GTKCLIENT(client), newitem, gmi, parent);
393
g_signal_connect(G_OBJECT(newitem), DBUSMENU_MENUITEM_SIGNAL_PROPERTY_CHANGED, G_CALLBACK(restart_property_change), client);
396
variant = dbusmenu_menuitem_property_get_variant(newitem, RESTART_ITEM_LABEL);
397
if (variant != NULL) {
398
restart_property_change(newitem, RESTART_ITEM_LABEL, variant, client);
401
variant = dbusmenu_menuitem_property_get_variant(newitem, RESTART_ITEM_ICON);
402
if (variant != NULL) {
403
restart_property_change(newitem, RESTART_ITEM_ICON, variant, client);
410
indicator_session_update_users_label (IndicatorSession * self,
413
gtk_label_set_text (self->entry.label, name ? name : "");