Merge lp:~3v1n0/libappindicator/incons-paths-on-snap-xenial into lp:libappindicator/16.04

Proposed by Marco Trevisan (Treviño)
Status: Merged
Approved by: Andrea Azzarone
Approved revision: 275
Merged at revision: 274
Proposed branch: lp:~3v1n0/libappindicator/incons-paths-on-snap-xenial
Merge into: lp:libappindicator/16.04
Diff against target: 339 lines (+139/-11)
2 files modified
example/simple-client-vala.vala (+1/-1)
src/app-indicator.c (+138/-10)
To merge this branch: bzr merge lp:~3v1n0/libappindicator/incons-paths-on-snap-xenial
Reviewer Review Type Date Requested Status
Andrea Azzarone (community) Approve
Review via email: mp+316972@code.launchpad.net

Commit message

AppIndicator: fix icon and theme paths when running in $SNAP environment

Prepend $SNAP path to icons and theme paths when running in a sandboxed
environment, this allows to run app indicators without caring about the fact
they've been designed or compiled to run in a snap world or not.

Description of the change

Backported commit from upstream

To post a comment you must log in.
274. By Marco Trevisan (Treviño) on 2017-02-13

AppIndicator: fix icon and theme paths when running in environment

Prepend path to icons and theme paths when running in a sandboxed
environment, this allows to run app indicators without caring about the fact
they've been designed or compiled to run in a snap world or not.

275. By Marco Trevisan (Treviño) on 2017-02-13

AppIndicator: don't emit label changes when guide is empty (and not null)

Andrea Azzarone (azzar1) wrote :

LGTM

review: Approve
276. By Marco Trevisan (Treviño) on 2017-02-15

app-indicator: don't append the snap prefix if the icon is saved in a well known readable path

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'example/simple-client-vala.vala'
2--- example/simple-client-vala.vala 2012-03-21 18:02:41 +0000
3+++ example/simple-client-vala.vala 2017-02-15 14:12:42 +0000
4@@ -104,7 +104,7 @@
5 print(@"Got scroll event! delta: $delta, direction: $direction\n");
6 });
7
8- Timeout.add_seconds(1, () => {
9+ GLib.Timeout.add_seconds(1, () => {
10 percentage = (percentage + 1) % 100;
11 if (can_haz_label) {
12 ci.set_label(@"$(percentage+1)%", "");
13
14=== modified file 'src/app-indicator.c'
15--- src/app-indicator.c 2014-11-10 09:14:07 +0000
16+++ src/app-indicator.c 2017-02-15 14:12:42 +0000
17@@ -38,6 +38,8 @@
18
19 #include <libindicator/indicator-desktop-shortcuts.h>
20
21+#include <stdlib.h>
22+
23 #include "app-indicator.h"
24 #include "app-indicator-enum-types.h"
25 #include "application-service-marshal.h"
26@@ -71,8 +73,11 @@
27 AppIndicatorCategory category;
28 AppIndicatorStatus status;
29 gchar *icon_name;
30+ gchar *absolute_icon_name;
31 gchar *attention_icon_name;
32+ gchar *absolute_attention_icon_name;
33 gchar *icon_theme_path;
34+ gchar *absolute_icon_theme_path;
35 DbusmenuServer *menuservice;
36 GtkWidget *menu;
37 GtkWidget *sec_activate_target;
38@@ -188,6 +193,8 @@
39 static void unfallback (AppIndicator * self, GtkStatusIcon * status_icon);
40 static gchar * append_panel_icon_suffix (const gchar * icon_name);
41 static void watcher_owner_changed (GObject * obj, GParamSpec * pspec, gpointer user_data);
42+static gchar * get_real_theme_path (AppIndicator * self);
43+static gchar * append_snap_prefix (const gchar * path);
44 static void theme_changed_cb (GtkIconTheme * theme, gpointer user_data);
45 static void sec_activate_target_parent_changed(GtkWidget *menuitem, GtkWidget *old_parent, gpointer user_data);
46 static GVariant * bus_get_prop (GDBusConnection * connection, const gchar * sender, const gchar * path, const gchar * interface, const gchar * property, GError ** error, gpointer user_data);
47@@ -331,7 +338,7 @@
48 "An additional place to look for icon names that may be installed by the application.",
49 NULL,
50 G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT));
51-
52+
53 /**
54 * AppIndicator:connected:
55 *
56@@ -582,6 +589,7 @@
57 app_indicator_init (AppIndicator *self)
58 {
59 AppIndicatorPrivate * priv = APP_INDICATOR_GET_PRIVATE(self);
60+ self->priv = priv;
61
62 priv->id = NULL;
63 priv->clean_id = NULL;
64@@ -590,6 +598,7 @@
65 priv->icon_name = NULL;
66 priv->attention_icon_name = NULL;
67 priv->icon_theme_path = NULL;
68+ priv->absolute_icon_theme_path = get_real_theme_path (self);
69 priv->menu = NULL;
70 priv->menuservice = NULL;
71 priv->ordering_index = 0;
72@@ -611,8 +620,6 @@
73 priv->sec_activate_target = NULL;
74 priv->sec_activate_enabled = FALSE;
75
76- self->priv = priv;
77-
78 /* Start getting the session bus */
79 g_object_ref(self); /* ref for the bus creation callback */
80 g_bus_get(G_BUS_TYPE_SESSION, NULL, bus_creation, self);
81@@ -725,16 +732,31 @@
82 priv->icon_name = NULL;
83 }
84
85+ if (priv->absolute_icon_name != NULL) {
86+ g_free(priv->absolute_icon_name);
87+ priv->absolute_icon_name = NULL;
88+ }
89+
90 if (priv->attention_icon_name != NULL) {
91 g_free(priv->attention_icon_name);
92 priv->attention_icon_name = NULL;
93 }
94
95+ if (priv->absolute_attention_icon_name != NULL) {
96+ g_free(priv->absolute_attention_icon_name);
97+ priv->absolute_attention_icon_name = NULL;
98+ }
99+
100 if (priv->icon_theme_path != NULL) {
101 g_free(priv->icon_theme_path);
102 priv->icon_theme_path = NULL;
103 }
104-
105+
106+ if (priv->absolute_icon_theme_path != NULL) {
107+ g_free(priv->absolute_icon_theme_path);
108+ priv->absolute_icon_theme_path = NULL;
109+ }
110+
111 if (priv->title != NULL) {
112 g_free(priv->title);
113 priv->title = NULL;
114@@ -907,6 +929,11 @@
115 gchar * oldguide = priv->label_guide;
116 priv->label_guide = g_value_dup_string(value);
117
118+ if (priv->label_guide != NULL && priv->label_guide[0] == '\0') {
119+ g_free(priv->label_guide);
120+ priv->label_guide = NULL;
121+ }
122+
123 if (g_strcmp0(oldguide, priv->label_guide) != 0) {
124 signal_label_change(APP_INDICATOR(object));
125 }
126@@ -1119,8 +1146,14 @@
127 enum_value = g_enum_get_value ((GEnumClass *) g_type_class_ref (APP_INDICATOR_TYPE_INDICATOR_STATUS), priv->status);
128 return g_variant_new_string(enum_value->value_nick ? enum_value->value_nick : "");
129 } else if (g_strcmp0(property, "IconName") == 0) {
130+ if (priv->absolute_icon_name) {
131+ return g_variant_new_string(priv->absolute_icon_name);
132+ }
133 return g_variant_new_string(priv->icon_name ? priv->icon_name : "");
134 } else if (g_strcmp0(property, "AttentionIconName") == 0) {
135+ if (priv->absolute_attention_icon_name) {
136+ return g_variant_new_string(priv->absolute_attention_icon_name);
137+ }
138 return g_variant_new_string(priv->attention_icon_name ? priv->attention_icon_name : "");
139 } else if (g_strcmp0(property, "Title") == 0) {
140 const gchar * output = NULL;
141@@ -1136,6 +1169,9 @@
142 }
143 return g_variant_new_string(output);
144 } else if (g_strcmp0(property, "IconThemePath") == 0) {
145+ if (priv->absolute_icon_theme_path) {
146+ return g_variant_new_string(priv->absolute_icon_theme_path);
147+ }
148 return g_variant_new_string(priv->icon_theme_path ? priv->icon_theme_path : "");
149 } else if (g_strcmp0(property, "Menu") == 0) {
150 if (priv->menuservice != NULL) {
151@@ -1601,19 +1637,23 @@
152
153 /* add the icon_theme_path once if needed */
154 GtkIconTheme *icon_theme = gtk_icon_theme_get_default();
155- if (self->priv->icon_theme_path != NULL) {
156+ const gchar *theme_path = self->priv->absolute_icon_theme_path ?
157+ self->priv->absolute_icon_theme_path :
158+ self->priv->icon_theme_path;
159+
160+ if (theme_path != NULL) {
161 gchar **path;
162 gint n_elements, i;
163 gboolean found=FALSE;
164 gtk_icon_theme_get_search_path(icon_theme, &path, &n_elements);
165 for (i=0; i< n_elements || path[i] == NULL; i++) {
166- if(g_strcmp0(path[i], self->priv->icon_theme_path) == 0) {
167+ if(g_strcmp0(path[i], theme_path) == 0) {
168 found=TRUE;
169 break;
170 }
171 }
172 if(!found) {
173- gtk_icon_theme_append_search_path(icon_theme, self->priv->icon_theme_path);
174+ gtk_icon_theme_append_search_path(icon_theme, theme_path);
175 }
176 g_strfreev (path);
177 }
178@@ -1637,8 +1677,12 @@
179 };
180
181 if (icon_name != NULL) {
182+ gchar *snapped_icon = append_snap_prefix(icon_name);
183+
184 if (g_file_test(icon_name, G_FILE_TEST_EXISTS)) {
185 gtk_status_icon_set_from_file(icon, icon_name);
186+ } else if (snapped_icon && g_file_test(snapped_icon, G_FILE_TEST_EXISTS)) {
187+ gtk_status_icon_set_from_file(icon, snapped_icon);
188 } else {
189 gchar *longname = append_panel_icon_suffix(icon_name);
190
191@@ -1650,6 +1694,8 @@
192
193 g_free(longname);
194 }
195+
196+ g_free(snapped_icon);
197 }
198
199 return;
200@@ -1663,7 +1709,7 @@
201 GtkMenu * menu = app_indicator_get_menu(APP_INDICATOR(data));
202 if (menu == NULL)
203 return;
204-
205+
206 gtk_menu_popup(menu,
207 NULL, /* Parent Menu */
208 NULL, /* Parent item */
209@@ -1711,7 +1757,7 @@
210 long_name = g_strdup (icon_name);
211 }
212
213- return long_name;
214+ return long_name;
215 }
216
217 static gboolean
218@@ -1888,6 +1934,14 @@
219 if (g_strcmp0 (self->priv->attention_icon_name, icon_name) != 0) {
220 g_free (self->priv->attention_icon_name);
221 self->priv->attention_icon_name = g_strdup (icon_name);
222+
223+ g_free(self->priv->absolute_attention_icon_name);
224+ self->priv->absolute_attention_icon_name = NULL;
225+
226+ if (icon_name && icon_name[0] == '/') {
227+ self->priv->absolute_attention_icon_name = append_snap_prefix (icon_name);
228+ }
229+
230 changed = TRUE;
231 }
232
233@@ -1963,6 +2017,14 @@
234 }
235
236 self->priv->icon_name = g_strdup(icon_name);
237+
238+ g_free(self->priv->absolute_icon_name);
239+ self->priv->absolute_icon_name = NULL;
240+
241+ if (icon_name && icon_name[0] == '/') {
242+ self->priv->absolute_icon_name = append_snap_prefix (icon_name);
243+ }
244+
245 changed = TRUE;
246 }
247
248@@ -2024,6 +2086,66 @@
249 return;
250 }
251
252+static const gchar *
253+get_snap_prefix ()
254+{
255+ const gchar *snap = g_getenv ("SNAP");
256+ return (snap && *snap != '\0') ? snap : NULL;
257+}
258+
259+static gchar *
260+append_snap_prefix (const gchar *path)
261+{
262+ gint i;
263+ gchar real_path[PATH_MAX];
264+ const gchar *snap = get_snap_prefix ();
265+
266+ if (snap != NULL && path != NULL) {
267+ if (realpath (path, real_path) != NULL) {
268+ path = real_path;
269+ }
270+
271+ if (g_str_has_prefix (path, "/tmp/")) {
272+ g_warning ("Using '/tmp' paths in SNAP environment will lead to unreadable resources");
273+ return NULL;
274+ }
275+
276+ if (g_str_has_prefix (path, snap) ||
277+ g_str_has_prefix (path, g_get_home_dir ()) ||
278+ g_str_has_prefix (path, g_get_user_cache_dir ()) ||
279+ g_str_has_prefix (path, g_get_user_config_dir ()) ||
280+ g_str_has_prefix (path, g_get_user_data_dir ()) ||
281+ g_str_has_prefix (path, g_get_user_runtime_dir ())) {
282+ return g_strdup (path);
283+ }
284+
285+ for (i = 0; i < G_USER_N_DIRECTORIES; ++ i) {
286+ if (g_str_has_prefix (path, g_get_user_special_dir (i))) {
287+ return g_strdup (path);
288+ }
289+ }
290+
291+ return g_build_path (G_DIR_SEPARATOR_S, snap, path, NULL);
292+ }
293+
294+ return NULL;
295+}
296+
297+static gchar *
298+get_real_theme_path (AppIndicator * self)
299+{
300+ const gchar *theme_path = self->priv->icon_theme_path;
301+ gchar *snapped_path = append_snap_prefix (theme_path);
302+
303+ if (snapped_path != NULL) {
304+ return snapped_path;
305+ } else if (get_snap_prefix ()) {
306+ return g_build_path (G_DIR_SEPARATOR_S, g_get_user_data_dir (), "icons", NULL);
307+ }
308+
309+ return NULL;
310+}
311+
312 /**
313 * app_indicator_set_icon_theme_path:
314 * @self: The #AppIndicator object to use
315@@ -2042,9 +2164,15 @@
316
317 self->priv->icon_theme_path = g_strdup(icon_theme_path);
318
319+ g_free (self->priv->absolute_icon_theme_path);
320+ self->priv->absolute_icon_theme_path = get_real_theme_path (self);
321+
322 g_signal_emit (self, signals[NEW_ICON_THEME_PATH], 0, self->priv->icon_theme_path, TRUE);
323
324 if (self->priv->dbus_registration != 0 && self->priv->connection != NULL) {
325+ const gchar *theme_path = self->priv->absolute_icon_theme_path ?
326+ self->priv->absolute_icon_theme_path :
327+ self->priv->icon_theme_path;
328 GError * error = NULL;
329
330 g_dbus_connection_emit_signal(self->priv->connection,
331@@ -2052,7 +2180,7 @@
332 self->priv->path,
333 NOTIFICATION_ITEM_DBUS_IFACE,
334 "NewIconThemePath",
335- g_variant_new("(s)", self->priv->icon_theme_path),
336+ g_variant_new("(s)", theme_path ? theme_path : ""),
337 &error);
338
339 if (error != NULL) {

Subscribers

People subscribed via source and target branches