comparison pkui-icon.c @ 46:aa5d3752091d

Make the update viewer command configurable Make the update viewer command configurable at copile time through the UPDATE_VIEWER_COMMAND macro. Make the update viewer command configurable at run time through the -c/--command command line option. Treat the update viewer command as a shell command and parse it via g_shell_parse_argv(), this allows for running the update viewer via xdg-su, gnomesu, pkexec etc. Disable install action in the notification and on the status icon in case no update viewer command has been provided.
author Guido Berhoerster <gber@opensuse.org>
date Thu, 18 Jun 2015 14:10:57 +0200
parents f6edbee6441f
children 1eb92ab03287
comparison
equal deleted inserted replaced
45:a29fbf0a7f6c 46:aa5d3752091d
23 #include "pkui-backend.h" 23 #include "pkui-backend.h"
24 #include "pkui-icon.h" 24 #include "pkui-icon.h"
25 25
26 G_DEFINE_TYPE(PkuiIcon, pkui_icon, G_TYPE_OBJECT) 26 G_DEFINE_TYPE(PkuiIcon, pkui_icon, G_TYPE_OBJECT)
27 27
28 #define UPDATE_VIEWER_COMMAND "/usr/bin/gpk-update-viewer" 28 #ifndef UPDATE_VIEWER_COMMAND
29 #define UPDATE_VIEWER_COMMAND ""
30 #endif /* UPDATE_VIEWER_COMMAND */
29 31
30 #define PKUI_ICON_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE((obj), \ 32 #define PKUI_ICON_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE((obj), \
31 PKUI_TYPE_ICON, PkuiIconPrivate)) 33 PKUI_TYPE_ICON, PkuiIconPrivate))
32 34
33 struct _PkuiIconPrivate 35 struct _PkuiIconPrivate
35 PkuiBackend *backend; 37 PkuiBackend *backend;
36 38
37 GtkStatusIcon *status_icon; 39 GtkStatusIcon *status_icon;
38 GtkWidget *status_icon_popup_menu; 40 GtkWidget *status_icon_popup_menu;
39 NotifyNotification *notification; 41 NotifyNotification *notification;
42 gchar *update_viewer_command;
40 }; 43 };
41 44
42 static GtkWidget* icon_popup_menu_create(PkuiIcon *self); 45 static GtkWidget* icon_popup_menu_create(PkuiIcon *self);
43 static void icon_popup_menu_popup(GtkStatusIcon *status_icon, guint button, 46 static void icon_popup_menu_popup(GtkStatusIcon *status_icon, guint button,
44 guint activate_time, gpointer user_data); 47 guint activate_time, gpointer user_data);
58 if (self->priv->notification != NULL) { 61 if (self->priv->notification != NULL) {
59 notify_notification_close(self->priv->notification, NULL); 62 notify_notification_close(self->priv->notification, NULL);
60 g_object_unref(self->priv->notification); 63 g_object_unref(self->priv->notification);
61 } 64 }
62 g_object_unref(self->priv->backend); 65 g_object_unref(self->priv->backend);
66 g_free(self->priv->update_viewer_command);
63 67
64 G_OBJECT_CLASS(pkui_icon_parent_class)->finalize(gobject); 68 G_OBJECT_CLASS(pkui_icon_parent_class)->finalize(gobject);
65 } 69 }
66 70
67 static void 71 static void
95 G_CALLBACK(icon_popup_menu_popup), self); 99 G_CALLBACK(icon_popup_menu_popup), self);
96 100
97 self->priv->notification = NULL; 101 self->priv->notification = NULL;
98 102
99 self->priv->backend = NULL; 103 self->priv->backend = NULL;
104
105 self->priv->update_viewer_command = NULL;
100 } 106 }
101 107
102 static void 108 static void
103 exec_update_viewer(PkuiIcon *self) 109 exec_update_viewer(PkuiIcon *self)
104 { 110 {
105 static const gchar *argv[] = { UPDATE_VIEWER_COMMAND, NULL }; 111 gchar **argv = NULL;
112 GError *error = NULL;
106 GPid pid; 113 GPid pid;
107 gboolean retval;
108 114
109 g_return_if_fail(PKUI_IS_BACKEND(self->priv->backend)); 115 g_return_if_fail(PKUI_IS_BACKEND(self->priv->backend));
110 116 g_return_if_fail(self->priv->update_viewer_command != NULL);
111 g_debug("executing " UPDATE_VIEWER_COMMAND); 117
112 118 g_debug("executing command %s", self->priv->update_viewer_command);
113 retval = g_spawn_async(NULL, (gchar **)argv, NULL, 119
114 G_SPAWN_DO_NOT_REAP_CHILD, NULL, NULL, &pid, NULL); 120 if (!g_shell_parse_argv(self->priv->update_viewer_command, NULL,
115 if (!retval) { 121 &argv, &error)) {
116 g_warning("Could not execute" UPDATE_VIEWER_COMMAND); 122 g_warning("Could not parse command: %s", error->message);
123 g_error_free(error);
124 return;
125 }
126
127 if (!g_spawn_async(NULL, argv, NULL,
128 G_SPAWN_DO_NOT_REAP_CHILD | G_SPAWN_SEARCH_PATH, NULL, NULL, &pid,
129 &error)) {
130 g_warning("Could not execute command: %s", error->message);
131 g_error_free(error);
117 return; 132 return;
118 } 133 }
119 g_child_watch_add(pid, (GChildWatchFunc)update_viewer_exited, self); 134 g_child_watch_add(pid, (GChildWatchFunc)update_viewer_exited, self);
120 135
121 pkui_backend_set_inhibit_check(self->priv->backend, TRUE); 136 pkui_backend_set_inhibit_check(self->priv->backend, TRUE);
213 notification_handle_action(NotifyNotification *notification, gchar *action, 228 notification_handle_action(NotifyNotification *notification, gchar *action,
214 gpointer user_data) 229 gpointer user_data)
215 { 230 {
216 PkuiIcon *self = PKUI_ICON(user_data); 231 PkuiIcon *self = PKUI_ICON(user_data);
217 232
218 if (strcmp(action, "install-updates") == 0) 233 if (strcmp(action, "install-updates") == 0) {
219 exec_update_viewer(self); 234 exec_update_viewer(self);
235 }
220 } 236 }
221 237
222 static void 238 static void
223 update_notification(PkuiIcon *self, guint updates_normal, 239 update_notification(PkuiIcon *self, guint updates_normal,
224 guint updates_important) 240 guint updates_important)
260 message, icon 276 message, icon
261 #if (NOTIFY_VERSION_MAJOR == 0 && NOTIFY_VERSION_MINOR < 7) 277 #if (NOTIFY_VERSION_MAJOR == 0 && NOTIFY_VERSION_MINOR < 7)
262 , NULL 278 , NULL
263 #endif 279 #endif
264 ); 280 );
265 notify_notification_add_action(self->priv->notification, 281 if (self->priv->update_viewer_command != NULL) {
266 "install-updates", ngettext("Install Update", 282 notify_notification_add_action(self->priv->notification,
267 "Install Updates", updates_normal + updates_important), 283 "install-updates", ngettext("Install Update",
268 notification_handle_action, self, NULL); 284 "Install Updates",
285 updates_normal + updates_important),
286 notification_handle_action, self, NULL);
287 }
269 } else 288 } else
270 notify_notification_update(self->priv->notification, title, 289 notify_notification_update(self->priv->notification, title,
271 message, icon); 290 message, icon);
272 291
273 notify_notification_set_timeout(self->priv->notification, 292 notify_notification_set_timeout(self->priv->notification,
321 static void 340 static void
322 icon_activated(GtkStatusIcon *status_icon, gpointer user_data) 341 icon_activated(GtkStatusIcon *status_icon, gpointer user_data)
323 { 342 {
324 PkuiIcon *self = PKUI_ICON(user_data); 343 PkuiIcon *self = PKUI_ICON(user_data);
325 344
326 exec_update_viewer(self); 345 if (self->priv->update_viewer_command != NULL) {
346 exec_update_viewer(self);
347 }
327 } 348 }
328 349
329 PkuiIcon * 350 PkuiIcon *
330 pkui_icon_new(guint startup_delay, guint check_interval) 351 pkui_icon_new(guint startup_delay, guint check_interval,
352 const gchar *update_viewer_command)
331 { 353 {
332 PkuiIcon *icon = g_object_new(PKUI_TYPE_ICON, NULL); 354 PkuiIcon *icon = g_object_new(PKUI_TYPE_ICON, NULL);
333 355
356 icon->priv->update_viewer_command = g_strdup((update_viewer_command !=
357 NULL) ? update_viewer_command : UPDATE_VIEWER_COMMAND);
334 icon->priv->backend = pkui_backend_new(startup_delay, check_interval); 358 icon->priv->backend = pkui_backend_new(startup_delay, check_interval);
335 g_signal_connect(icon->priv->backend, "state-changed", 359 g_signal_connect(icon->priv->backend, "state-changed",
336 G_CALLBACK(backend_state_changed), icon); 360 G_CALLBACK(backend_state_changed), icon);
337 361
338 return (icon); 362 return (icon);