25 | 25 |
STATUS_NEEDS_ATTENTION
|
26 | 26 |
} Status;
|
27 | 27 |
|
|
28 |
typedef struct
|
|
29 |
{
|
|
30 |
gchar *id;
|
|
31 |
gchar *title;
|
|
32 |
gchar *status;
|
|
33 |
gchar *tooltip_heading;
|
|
34 |
gchar *tooltip_body;
|
|
35 |
gchar *menu_path;
|
|
36 |
|
|
37 |
gchar *icon_theme_path;
|
|
38 |
gchar *icon_name;
|
|
39 |
gchar *attention_icon_name;
|
|
40 |
gchar *overlay_icon_name;
|
|
41 |
|
|
42 |
gchar *icon_md5;
|
|
43 |
gchar *attention_icon_md5;
|
|
44 |
gchar *overlay_icon_md5;
|
|
45 |
cairo_surface_t *icon_surface;
|
|
46 |
cairo_surface_t *attention_icon_surface;
|
|
47 |
cairo_surface_t *overlay_icon_surface;
|
|
48 |
|
|
49 |
gboolean update_status;
|
|
50 |
gboolean update_tooltip;
|
|
51 |
gboolean update_menu;
|
|
52 |
gboolean update_icon;
|
|
53 |
} SnItemPropertiesResult;
|
|
54 |
|
28 | 55 |
struct _SnItem
|
29 | 56 |
{
|
30 | 57 |
GObject parent_instance;
|
|
32 | 59 |
GDBusProxy *sn_item_proxy; // SnItemProxy
|
33 | 60 |
GDBusProxy *prop_proxy; // dbus properties (we can't trust SnItemProxy)
|
34 | 61 |
|
35 | |
GtkWidget *menu;
|
36 | 62 |
XAppStatusIcon *status_icon;
|
|
63 |
|
|
64 |
SnItemPropertiesResult *current_props;
|
|
65 |
GCancellable *cancellable;
|
37 | 66 |
|
38 | 67 |
Status status;
|
39 | 68 |
gchar *last_png_path;
|
40 | 69 |
gchar *png_path;
|
41 | 70 |
|
42 | 71 |
gint current_icon_id;
|
|
72 |
|
|
73 |
guint update_properties_timeout;
|
43 | 74 |
gchar *sortable_name;
|
44 | 75 |
|
45 | 76 |
gboolean should_activate;
|
46 | 77 |
gboolean should_replace_tooltip;
|
47 | 78 |
gboolean is_ai;
|
|
79 |
|
|
80 |
GtkWidget *menu;
|
48 | 81 |
};
|
49 | 82 |
|
50 | 83 |
G_DEFINE_TYPE (SnItem, sn_item, G_TYPE_OBJECT)
|
51 | 84 |
|
52 | |
static void update_menu (SnItem *item);
|
53 | |
static void update_status (SnItem *item);
|
54 | |
static void update_tooltip (SnItem *item);
|
55 | |
static void update_icon (SnItem *item);
|
|
85 |
static void update_menu (SnItem *item, SnItemPropertiesResult *new_props);
|
|
86 |
static void update_status (SnItem *item, SnItemPropertiesResult *new_props);
|
|
87 |
static void update_tooltip (SnItem *item, SnItemPropertiesResult *new_props);
|
|
88 |
static void update_icon (SnItem *item, SnItemPropertiesResult *new_props);
|
|
89 |
static void assign_sortable_name (SnItem *item, const gchar *title);
|
|
90 |
|
|
91 |
static void
|
|
92 |
props_free (SnItemPropertiesResult *props)
|
|
93 |
{
|
|
94 |
if (props == NULL)
|
|
95 |
{
|
|
96 |
return;
|
|
97 |
}
|
|
98 |
|
|
99 |
g_free (props->id);
|
|
100 |
g_free (props->title);
|
|
101 |
g_free (props->status);
|
|
102 |
g_free (props->tooltip_heading);
|
|
103 |
g_free (props->tooltip_body);
|
|
104 |
g_free (props->menu_path);
|
|
105 |
g_free (props->icon_theme_path);
|
|
106 |
g_free (props->icon_name);
|
|
107 |
g_free (props->attention_icon_name);
|
|
108 |
g_free (props->overlay_icon_name);
|
|
109 |
|
|
110 |
g_free (props->icon_md5);
|
|
111 |
g_free (props->attention_icon_md5);
|
|
112 |
g_free (props->overlay_icon_md5);
|
|
113 |
|
|
114 |
cairo_surface_destroy (props->icon_surface);
|
|
115 |
cairo_surface_destroy (props->attention_icon_surface);
|
|
116 |
cairo_surface_destroy (props->overlay_icon_surface);
|
|
117 |
|
|
118 |
g_slice_free (SnItemPropertiesResult, props);
|
|
119 |
}
|
56 | 120 |
|
57 | 121 |
static gboolean
|
58 | 122 |
should_activate (SnItem *item)
|
|
80 | 144 |
g_strfreev (ids);
|
81 | 145 |
|
82 | 146 |
return should;
|
|
147 |
}
|
|
148 |
|
|
149 |
static void
|
|
150 |
update_conditionals (SnItem *item)
|
|
151 |
{
|
|
152 |
item->should_replace_tooltip = should_replace_tooltip (item);
|
|
153 |
item->should_activate = should_activate (item);
|
83 | 154 |
}
|
84 | 155 |
|
85 | 156 |
static void
|
|
106 | 177 |
g_free (item->last_png_path);
|
107 | 178 |
item->last_png_path = NULL;
|
108 | 179 |
}
|
|
180 |
|
|
181 |
g_clear_handle_id (&item->update_properties_timeout, g_source_remove);
|
109 | 182 |
|
110 | 183 |
g_clear_pointer (&item->sortable_name, g_free);
|
111 | 184 |
g_clear_object (&item->status_icon);
|
112 | 185 |
g_clear_object (&item->menu);
|
113 | 186 |
g_clear_object (&item->prop_proxy);
|
114 | 187 |
g_clear_object (&item->sn_item_proxy);
|
|
188 |
g_clear_object (&item->cancellable);
|
|
189 |
|
|
190 |
props_free (item->current_props);
|
115 | 191 |
|
116 | 192 |
G_OBJECT_CLASS (sn_item_parent_class)->dispose (object);
|
117 | 193 |
}
|
|
176 | 252 |
return FALLBACK_ICON_SIZE;
|
177 | 253 |
}
|
178 | 254 |
|
179 | |
static GVariant *
|
180 | |
get_property (SnItem *item,
|
181 | |
const gchar *prop_name)
|
182 | |
{
|
183 | |
GVariant *res, *var;
|
184 | |
GError *error = NULL;
|
185 | |
|
186 | |
res = g_dbus_proxy_call_sync (item->prop_proxy,
|
187 | |
"Get",
|
188 | |
g_variant_new ("(ss)",
|
189 | |
g_dbus_proxy_get_interface_name (item->sn_item_proxy),
|
190 | |
prop_name),
|
191 | |
G_DBUS_CALL_FLAGS_NONE,
|
192 | |
5 * 1000,
|
193 | |
NULL,
|
194 | |
&error);
|
195 | |
|
196 | |
if (error != NULL)
|
197 | |
{
|
198 | |
g_error_free (error);
|
199 | |
return NULL;
|
200 | |
}
|
201 | |
|
202 | |
g_variant_get (res, "(v)", &var);
|
203 | |
g_variant_unref (res);
|
204 | |
|
205 | |
return var;
|
206 | |
}
|
207 | |
|
208 | |
static GVariant *
|
209 | |
get_pixmap_property (SnItem *item,
|
210 | |
const gchar *name)
|
211 | |
{
|
212 | |
GVariant *var = NULL;
|
213 | |
|
214 | |
var = get_property (item, name);
|
215 | |
|
216 | |
if (var == NULL)
|
217 | |
{
|
218 | |
return NULL;
|
219 | |
}
|
220 | |
|
221 | |
return var;
|
222 | |
}
|
223 | |
|
224 | |
static gchar *
|
225 | |
get_string_property (SnItem *item,
|
226 | |
const gchar *name)
|
227 | |
{
|
228 | |
GVariant *var = NULL;
|
229 | |
gchar *result = NULL;
|
230 | |
|
231 | |
var = get_property (item, name);
|
232 | |
|
233 | |
if (var == NULL)
|
234 | |
{
|
235 | |
return NULL;
|
236 | |
}
|
237 | |
|
238 | |
result = g_variant_dup_string (var, NULL);
|
239 | |
g_variant_unref (var);
|
240 | |
|
241 | |
if (g_strcmp0 (result, "") == 0)
|
242 | |
{
|
243 | |
g_clear_pointer (&result, g_free);
|
244 | |
}
|
245 | |
|
246 | |
return result;
|
247 | |
}
|
248 | |
|
249 | 255 |
static cairo_surface_t *
|
250 | 256 |
surface_from_pixmap_data (gint width,
|
251 | 257 |
gint height,
|
252 | |
GBytes *bytes)
|
|
258 |
guchar *data)
|
253 | 259 |
{
|
254 | 260 |
cairo_surface_t *surface;
|
255 | 261 |
GdkPixbuf *pixbuf;
|
256 | 262 |
gint rowstride, i;
|
257 | |
gsize size;
|
258 | |
gconstpointer data;
|
259 | |
guchar *copy;
|
260 | 263 |
guchar alpha;
|
261 | |
|
262 | |
data = g_bytes_get_data (bytes, &size);
|
263 | |
copy = g_memdup ((guchar *) data, size);
|
264 | 264 |
|
265 | 265 |
surface = NULL;
|
266 | 266 |
rowstride = width * 4;
|
|
268 | 268 |
|
269 | 269 |
while (i < 4 * width * height)
|
270 | 270 |
{
|
271 | |
alpha = copy[i ];
|
272 | |
copy[i ] = copy[i + 1];
|
273 | |
copy[i + 1] = copy[i + 2];
|
274 | |
copy[i + 2] = copy[i + 3];
|
275 | |
copy[i + 3] = alpha;
|
|
271 |
alpha = data[i ];
|
|
272 |
data[i ] = data[i + 1];
|
|
273 |
data[i + 1] = data[i + 2];
|
|
274 |
data[i + 2] = data[i + 3];
|
|
275 |
data[i + 3] = alpha;
|
276 | 276 |
i += 4;
|
277 | 277 |
}
|
278 | 278 |
|
279 | |
pixbuf = gdk_pixbuf_new_from_data (copy,
|
|
279 |
pixbuf = gdk_pixbuf_new_from_data (data,
|
280 | 280 |
GDK_COLORSPACE_RGB,
|
281 | 281 |
TRUE, 8,
|
282 | 282 |
width, height,
|
|
295 | 295 |
}
|
296 | 296 |
}
|
297 | 297 |
|
298 | |
static gboolean
|
299 | |
process_pixmaps (SnItem *item,
|
300 | |
GVariant *pixmaps,
|
301 | |
gchar **image_path)
|
302 | |
{
|
303 | |
GVariantIter iter;
|
|
298 |
static cairo_surface_t *
|
|
299 |
get_icon_surface (SnItem *item,
|
|
300 |
GVariant *pixmaps,
|
|
301 |
gchar **md5)
|
|
302 |
{
|
|
303 |
GVariantIter *iter;
|
304 | 304 |
cairo_surface_t *surface;
|
305 | 305 |
gint width, height;
|
306 | 306 |
gint largest_width, largest_height;
|
|
307 |
gsize largest_data_size;
|
307 | 308 |
GVariant *byte_array_var;
|
308 | |
GBytes *best_image_bytes = NULL;
|
|
309 |
gconstpointer data;
|
|
310 |
guchar *best_image_array = NULL;
|
309 | 311 |
|
310 | 312 |
largest_width = largest_height = 0;
|
311 | 313 |
|
312 | |
g_variant_iter_init (&iter, pixmaps);
|
313 | |
|
314 | |
while (g_variant_iter_loop (&iter, "(ii@ay)", &width, &height, &byte_array_var))
|
315 | |
{
|
316 | |
if (width > 0 & height > 0 &&
|
|
314 |
*md5 = NULL;
|
|
315 |
|
|
316 |
g_variant_get (pixmaps, "a(iiay)", &iter);
|
|
317 |
|
|
318 |
if (iter == NULL)
|
|
319 |
{
|
|
320 |
return NULL;
|
|
321 |
}
|
|
322 |
|
|
323 |
while (g_variant_iter_loop (iter, "(ii@ay)", &width, &height, &byte_array_var))
|
|
324 |
{
|
|
325 |
if (width > 0 & height > 0 && byte_array_var != NULL &&
|
317 | 326 |
((width * height) > (largest_width * largest_height)))
|
318 | 327 |
{
|
319 | 328 |
gsize data_size = g_variant_get_size (byte_array_var);
|
320 | 329 |
|
321 | 330 |
if (data_size == width * height * 4)
|
322 | 331 |
{
|
323 | |
g_clear_pointer (&best_image_bytes, g_bytes_unref);
|
324 | |
|
325 | |
largest_width = width;
|
326 | |
largest_height = height;
|
327 | |
best_image_bytes = g_variant_get_data_as_bytes (byte_array_var);
|
328 | |
}
|
329 | |
}
|
330 | |
}
|
331 | |
|
332 | |
if (best_image_bytes == NULL)
|
333 | |
{
|
334 | |
g_warning ("No valid pixmaps found.");
|
335 | |
return FALSE;
|
336 | |
}
|
337 | |
|
338 | |
surface = surface_from_pixmap_data (largest_width, largest_height, best_image_bytes);
|
|
332 |
data = g_variant_get_data (byte_array_var);
|
|
333 |
|
|
334 |
if (data != NULL)
|
|
335 |
{
|
|
336 |
if (best_image_array != NULL)
|
|
337 |
{
|
|
338 |
g_free (best_image_array);
|
|
339 |
}
|
|
340 |
|
|
341 |
best_image_array = g_memdup (data, data_size);
|
|
342 |
|
|
343 |
largest_data_size = data_size;
|
|
344 |
largest_width = width;
|
|
345 |
largest_height = height;
|
|
346 |
}
|
|
347 |
}
|
|
348 |
}
|
|
349 |
}
|
|
350 |
|
|
351 |
g_variant_iter_free (iter);
|
|
352 |
|
|
353 |
if (best_image_array == NULL)
|
|
354 |
{
|
|
355 |
return NULL;
|
|
356 |
}
|
|
357 |
|
|
358 |
surface = surface_from_pixmap_data (largest_width, largest_height, best_image_array);
|
|
359 |
*md5 = g_compute_checksum_for_data (G_CHECKSUM_MD5, best_image_array, largest_data_size);
|
339 | 360 |
|
340 | 361 |
if (cairo_surface_status (surface) != CAIRO_STATUS_SUCCESS)
|
341 | 362 |
{
|
342 | 363 |
cairo_surface_destroy (surface);
|
343 | |
return FALSE;
|
344 | |
}
|
345 | |
|
346 | |
item->last_png_path = item->png_path;
|
347 | |
|
348 | |
gchar *filename = g_strdup_printf ("xapp-tmp-%p-%d.png", item, get_icon_id (item));
|
349 | |
gchar *save_filename = g_build_path ("/", g_get_tmp_dir (), filename, NULL);
|
350 | |
g_free (filename);
|
351 | |
|
352 | |
cairo_status_t status = CAIRO_STATUS_SUCCESS;
|
353 | |
status = cairo_surface_write_to_png (surface, save_filename);
|
354 | |
|
355 | |
if (status != CAIRO_STATUS_SUCCESS)
|
356 | |
{
|
357 | |
g_warning ("Failed to save png of status icon");
|
358 | |
g_free (image_path);
|
359 | |
cairo_surface_destroy (surface);
|
360 | |
return FALSE;
|
361 | |
}
|
362 | |
|
363 | |
*image_path = save_filename;
|
364 | |
cairo_surface_destroy (surface);
|
365 | |
|
366 | |
return TRUE;
|
367 | |
}
|
368 | |
|
369 | |
static void
|
370 | |
set_icon_from_pixmap (SnItem *item)
|
371 | |
{
|
372 | |
GVariant *pixmaps;
|
373 | |
gchar *image_path;
|
|
364 |
return NULL;
|
|
365 |
}
|
|
366 |
|
|
367 |
return surface;
|
|
368 |
}
|
|
369 |
|
|
370 |
static void
|
|
371 |
set_icon_from_pixmap (SnItem *item, SnItemPropertiesResult *new_props)
|
|
372 |
{
|
|
373 |
cairo_surface_t *surface;
|
|
374 |
gchar *filename, *save_filename;
|
|
375 |
|
|
376 |
g_debug ("Trying to use icon pixmap for %s",
|
|
377 |
item->sortable_name);
|
|
378 |
|
|
379 |
surface = NULL;
|
374 | 380 |
|
375 | 381 |
if (item->status == STATUS_ACTIVE)
|
376 | 382 |
{
|
377 | |
pixmaps = get_pixmap_property (item, "IconPixmap");
|
|
383 |
if (new_props->icon_surface)
|
|
384 |
{
|
|
385 |
surface = new_props->icon_surface;
|
|
386 |
}
|
378 | 387 |
}
|
379 | 388 |
else
|
380 | 389 |
if (item->status == STATUS_NEEDS_ATTENTION)
|
381 | 390 |
{
|
382 | |
pixmaps = get_pixmap_property (item, "AttentionIconPixmap");
|
383 | |
|
384 | |
if (!pixmaps)
|
385 | |
{
|
386 | |
pixmaps = get_pixmap_property (item, "IconPixmap");
|
387 | |
}
|
388 | |
}
|
389 | |
|
390 | |
if (!pixmaps)
|
391 | |
{
|
392 | |
xapp_status_icon_set_icon_name (item->status_icon, "image-missing");
|
393 | |
g_warning ("No pixmaps to use");
|
|
391 |
if (new_props->attention_icon_surface)
|
|
392 |
{
|
|
393 |
surface = new_props->attention_icon_surface;
|
|
394 |
}
|
|
395 |
}
|
|
396 |
|
|
397 |
if (surface != NULL)
|
|
398 |
{
|
|
399 |
item->last_png_path = item->png_path;
|
|
400 |
|
|
401 |
filename = g_strdup_printf ("xapp-tmp-%p-%d.png", item, get_icon_id (item));
|
|
402 |
save_filename = g_build_path ("/", g_get_tmp_dir (), filename, NULL);
|
|
403 |
g_free (filename);
|
|
404 |
|
|
405 |
cairo_status_t status = CAIRO_STATUS_SUCCESS;
|
|
406 |
status = cairo_surface_write_to_png (surface, save_filename);
|
|
407 |
|
|
408 |
g_debug ("Saving tmp image file for '%s' to '%s'", item->sortable_name, save_filename);
|
|
409 |
|
|
410 |
if (status != CAIRO_STATUS_SUCCESS)
|
|
411 |
{
|
|
412 |
g_warning ("Failed to save png of status icon");
|
|
413 |
}
|
|
414 |
|
|
415 |
xapp_status_icon_set_icon_name (item->status_icon, save_filename);
|
|
416 |
g_free (save_filename);
|
394 | 417 |
return;
|
395 | 418 |
}
|
396 | 419 |
|
397 | |
if (process_pixmaps (item, pixmaps, &image_path))
|
398 | |
{
|
399 | |
xapp_status_icon_set_icon_name (item->status_icon, image_path);
|
400 | |
g_free (image_path);
|
401 | |
}
|
402 | |
|
403 | |
g_variant_unref (pixmaps);
|
|
420 |
g_debug ("No pixmaps to use");
|
|
421 |
xapp_status_icon_set_icon_name (item->status_icon, "image-missing");
|
404 | 422 |
}
|
405 | 423 |
|
406 | 424 |
static gchar *
|
407 | |
get_icon_filename_from_theme (SnItem *item,
|
|
425 |
get_icon_filename_from_theme (SnItem *item,
|
408 | 426 |
const gchar *theme_path,
|
409 | 427 |
const gchar *icon_name)
|
410 | 428 |
{
|
411 | 429 |
GtkIconInfo *info;
|
412 | 430 |
gchar *filename;
|
413 | 431 |
const gchar *array[2];
|
|
432 |
gint host_icon_size;
|
414 | 433 |
|
415 | 434 |
array[0] = icon_name;
|
416 | 435 |
array[1] = NULL;
|
417 | 436 |
|
418 | 437 |
// We have a theme path, but try the system theme first
|
419 | 438 |
GtkIconTheme *theme = gtk_icon_theme_get_default ();
|
|
439 |
host_icon_size = get_icon_size (item);
|
420 | 440 |
|
421 | 441 |
info = gtk_icon_theme_choose_icon_for_scale (theme,
|
422 | 442 |
array,
|
423 | |
get_icon_size (item),
|
|
443 |
host_icon_size,
|
424 | 444 |
lookup_ui_scale (),
|
425 | 445 |
GTK_ICON_LOOKUP_FORCE_SVG | GTK_ICON_LOOKUP_FORCE_SYMBOLIC);
|
426 | 446 |
|
|
433 | 453 |
|
434 | 454 |
info = gtk_icon_theme_choose_icon_for_scale (theme,
|
435 | 455 |
array,
|
436 | |
get_icon_size (item),
|
|
456 |
host_icon_size,
|
437 | 457 |
lookup_ui_scale (),
|
438 | 458 |
GTK_ICON_LOOKUP_FORCE_SVG | GTK_ICON_LOOKUP_FORCE_SYMBOLIC);
|
439 | 459 |
|
|
451 | 471 |
return filename;
|
452 | 472 |
}
|
453 | 473 |
|
454 | |
static void
|
455 | |
process_icon_name (SnItem *item,
|
456 | |
const gchar *icon_theme_path,
|
457 | |
const gchar *icon_name)
|
458 | |
{
|
459 | |
if (g_path_is_absolute (icon_name) || !icon_theme_path)
|
|
474 |
static gboolean
|
|
475 |
set_icon_name (SnItem *item,
|
|
476 |
const gchar *icon_theme_path,
|
|
477 |
const gchar *icon_name)
|
|
478 |
{
|
|
479 |
g_debug ("Checking for icon name for %s",
|
|
480 |
item->sortable_name);
|
|
481 |
|
|
482 |
if (icon_name == NULL)
|
|
483 |
{
|
|
484 |
return FALSE;
|
|
485 |
}
|
|
486 |
|
|
487 |
if (g_path_is_absolute (icon_name))
|
460 | 488 |
{
|
461 | 489 |
xapp_status_icon_set_icon_name (item->status_icon, icon_name);
|
|
490 |
|
|
491 |
return TRUE;
|
462 | 492 |
}
|
463 | 493 |
else
|
464 | 494 |
{
|
|
468 | 498 |
{
|
469 | 499 |
xapp_status_icon_set_icon_name (item->status_icon, filename);
|
470 | 500 |
g_free (filename);
|
471 | |
}
|
472 | |
else
|
473 | |
{
|
474 | |
xapp_status_icon_set_icon_name (item->status_icon, "image-missing");
|
475 | |
}
|
476 | |
}
|
477 | |
}
|
478 | |
|
479 | |
static void
|
480 | |
set_icon_name_or_path (SnItem *item,
|
481 | |
const gchar *icon_theme_path,
|
482 | |
const gchar *icon_name,
|
483 | |
const gchar *att_icon_name,
|
484 | |
const gchar *olay_icon_name)
|
|
501 |
return TRUE;
|
|
502 |
}
|
|
503 |
}
|
|
504 |
|
|
505 |
return FALSE;
|
|
506 |
}
|
|
507 |
|
|
508 |
static gboolean
|
|
509 |
set_icon_name_or_path (SnItem *item,
|
|
510 |
SnItemPropertiesResult *new_props)
|
485 | 511 |
{
|
486 | 512 |
const gchar *name_to_use = NULL;
|
487 | 513 |
|
488 | 514 |
if (item->status == STATUS_ACTIVE)
|
489 | 515 |
{
|
490 | |
if (icon_name)
|
491 | |
{
|
492 | |
name_to_use = icon_name;
|
|
516 |
if (new_props->icon_name)
|
|
517 |
{
|
|
518 |
name_to_use = new_props->icon_name;
|
493 | 519 |
}
|
494 | 520 |
}
|
495 | 521 |
else
|
496 | 522 |
if (item->status == STATUS_NEEDS_ATTENTION)
|
497 | 523 |
{
|
498 | |
if (att_icon_name)
|
499 | |
{
|
500 | |
name_to_use = att_icon_name;
|
|
524 |
if (new_props->attention_icon_name)
|
|
525 |
{
|
|
526 |
name_to_use = new_props->attention_icon_name;
|
501 | 527 |
}
|
502 | 528 |
else
|
503 | |
if (icon_name)
|
504 | |
{
|
505 | |
name_to_use = icon_name;
|
506 | |
}
|
507 | |
}
|
508 | |
|
509 | |
if (name_to_use == NULL)
|
510 | |
{
|
511 | |
name_to_use = "image-missing";
|
512 | |
}
|
513 | |
|
514 | |
process_icon_name (item, icon_theme_path, name_to_use);
|
515 | |
}
|
516 | |
|
517 | |
static void
|
518 | |
update_icon (SnItem *item)
|
519 | |
{
|
520 | |
gchar *icon_theme_path;
|
521 | |
gchar *icon_name, *att_icon_name, *olay_icon_name;
|
522 | |
|
523 | |
icon_theme_path = get_string_property (item, "IconThemePath");
|
524 | |
icon_name = get_string_property (item, "IconName");
|
525 | |
att_icon_name = get_string_property (item, "AttentionIconName");
|
526 | |
olay_icon_name = get_string_property (item, "OverlayIconName");
|
527 | |
|
528 | |
if (icon_name || att_icon_name || olay_icon_name)
|
529 | |
{
|
530 | |
// g_printerr ("icon name '%s' '%s' '%s'\n", icon_name, att_icon_name, olay_icon_name);
|
531 | |
set_icon_name_or_path (item,
|
532 | |
icon_theme_path,
|
533 | |
icon_name,
|
534 | |
att_icon_name,
|
535 | |
olay_icon_name);
|
536 | |
}
|
537 | |
else
|
538 | |
{
|
539 | |
set_icon_from_pixmap (item);
|
540 | |
}
|
541 | |
|
542 | |
g_free (icon_theme_path);
|
543 | |
g_free (icon_name);
|
544 | |
g_free (att_icon_name);
|
545 | |
g_free (olay_icon_name);
|
546 | |
}
|
547 | |
|
548 | |
static void
|
549 | |
update_menu (SnItem *item)
|
550 | |
{
|
551 | |
gchar *menu_path;
|
552 | |
|
|
529 |
if (new_props->icon_name)
|
|
530 |
{
|
|
531 |
name_to_use = new_props->icon_name;
|
|
532 |
}
|
|
533 |
}
|
|
534 |
|
|
535 |
return set_icon_name (item, new_props->icon_theme_path, name_to_use);
|
|
536 |
}
|
|
537 |
|
|
538 |
static void
|
|
539 |
update_icon (SnItem *item, SnItemPropertiesResult *new_props)
|
|
540 |
{
|
|
541 |
if (!set_icon_name_or_path (item, new_props))
|
|
542 |
{
|
|
543 |
set_icon_from_pixmap (item, new_props);
|
|
544 |
}
|
|
545 |
}
|
|
546 |
|
|
547 |
static void
|
|
548 |
update_menu (SnItem *item, SnItemPropertiesResult *new_props)
|
|
549 |
{
|
553 | 550 |
g_clear_object (&item->menu);
|
554 | 551 |
|
555 | 552 |
xapp_status_icon_set_primary_menu (item->status_icon, NULL);
|
556 | 553 |
xapp_status_icon_set_secondary_menu (item->status_icon, NULL);
|
557 | 554 |
|
558 | |
menu_path = get_string_property (item, "Menu");
|
559 | |
|
560 | |
if (menu_path == NULL)
|
|
555 |
if (new_props->menu_path == NULL)
|
561 | 556 |
{
|
562 | 557 |
return;
|
563 | 558 |
}
|
564 | 559 |
|
565 | |
item->menu = GTK_WIDGET (dbusmenu_gtkmenu_new ((gchar *) g_dbus_proxy_get_name (item->sn_item_proxy), menu_path));
|
|
560 |
item->menu = GTK_WIDGET (dbusmenu_gtkmenu_new ((gchar *) g_dbus_proxy_get_name (item->sn_item_proxy),
|
|
561 |
new_props->menu_path));
|
566 | 562 |
g_object_ref_sink (item->menu);
|
567 | 563 |
|
|
564 |
g_debug ("New menu for '%s'", item->sortable_name);
|
|
565 |
|
568 | 566 |
if (item->is_ai && !item->should_activate)
|
569 | 567 |
{
|
570 | 568 |
xapp_status_icon_set_primary_menu (item->status_icon, GTK_MENU (item->menu));
|
571 | 569 |
}
|
572 | 570 |
|
573 | 571 |
xapp_status_icon_set_secondary_menu (item->status_icon, GTK_MENU (item->menu));
|
574 | |
|
575 | |
g_free (menu_path);
|
576 | 572 |
}
|
577 | 573 |
|
578 | 574 |
static gchar *
|
|
599 | 595 |
}
|
600 | 596 |
|
601 | 597 |
static void
|
602 | |
update_tooltip (SnItem *item)
|
603 | |
{
|
604 | |
g_autoptr(GVariant) tt_var = NULL;
|
|
598 |
update_tooltip (SnItem *item, SnItemPropertiesResult *new_props)
|
|
599 |
{
|
|
600 |
if (new_props->title)
|
|
601 |
{
|
|
602 |
assign_sortable_name (item, new_props->title);
|
|
603 |
}
|
605 | 604 |
|
606 | 605 |
if (!item->should_replace_tooltip)
|
607 | 606 |
{
|
608 | |
tt_var = get_property (item, "ToolTip");
|
609 | |
}
|
610 | |
|
611 | |
if (tt_var)
|
612 | |
{
|
613 | |
const gchar *type_str;
|
614 | |
type_str = g_variant_get_type_string (tt_var);
|
615 | |
|
616 | |
if (g_strcmp0 (type_str, "(sa(iiay)ss)") == 0)
|
617 | |
{
|
618 | |
const gchar *tooltip_title, *tooltip_body;
|
619 | |
|
620 | |
g_variant_get (tt_var, "(sa(iiay)&s&s)", NULL, NULL, &tooltip_title, &tooltip_body);
|
621 | |
|
622 | |
if (g_strcmp0 (tooltip_title, "") != 0)
|
623 | |
{
|
624 | |
|
625 | |
if (g_strcmp0 (tooltip_body, "") != 0)
|
626 | |
{
|
627 | |
gchar *text;
|
628 | |
text = g_strdup_printf ("%s\n%s", tooltip_title, tooltip_body);
|
629 | |
|
630 | |
xapp_status_icon_set_tooltip_text (item->status_icon, text);
|
631 | |
g_debug ("Tooltip text from ToolTip: %s", text);
|
632 | |
|
633 | |
g_free (text);
|
634 | |
}
|
635 | |
else
|
636 | |
{
|
637 | |
g_debug ("Tooltip text from ToolTip: %s", tooltip_title);
|
638 | |
xapp_status_icon_set_tooltip_text (item->status_icon, tooltip_title);
|
639 | |
}
|
640 | |
|
641 | |
return;
|
642 | |
}
|
643 | |
}
|
644 | |
}
|
645 | |
|
646 | |
gchar *title_string;
|
647 | |
title_string = get_string_property (item, "Title");
|
648 | |
|
649 | |
if (title_string != NULL)
|
|
607 |
if (new_props->tooltip_heading != NULL)
|
|
608 |
{
|
|
609 |
if (new_props->tooltip_body != NULL)
|
|
610 |
{
|
|
611 |
gchar *text;
|
|
612 |
text = g_strdup_printf ("%s\n%s",
|
|
613 |
new_props->tooltip_heading,
|
|
614 |
new_props->tooltip_body);
|
|
615 |
|
|
616 |
xapp_status_icon_set_tooltip_text (item->status_icon, text);
|
|
617 |
g_debug ("Tooltip text for '%s' from ToolTip: %s",
|
|
618 |
item->sortable_name,
|
|
619 |
text);
|
|
620 |
|
|
621 |
g_free (text);
|
|
622 |
}
|
|
623 |
else
|
|
624 |
{
|
|
625 |
g_debug ("Tooltip text for '%s' from ToolTip: %s",
|
|
626 |
item->sortable_name,
|
|
627 |
new_props->tooltip_heading);
|
|
628 |
|
|
629 |
xapp_status_icon_set_tooltip_text (item->status_icon, new_props->tooltip_heading);
|
|
630 |
}
|
|
631 |
|
|
632 |
return;
|
|
633 |
}
|
|
634 |
}
|
|
635 |
|
|
636 |
if (new_props->title != NULL)
|
650 | 637 |
{
|
651 | 638 |
gchar *capped_string;
|
652 | 639 |
|
653 | |
capped_string = capitalize (title_string);
|
|
640 |
capped_string = capitalize (new_props->title);
|
654 | 641 |
xapp_status_icon_set_tooltip_text (item->status_icon, capped_string);
|
655 | |
g_debug ("Tooltip text from Title: %s", capped_string);
|
656 | |
|
657 | |
g_free (title_string);
|
|
642 |
|
|
643 |
g_debug ("Tooltip text for '%s' from Title: %s",
|
|
644 |
item->sortable_name,
|
|
645 |
capped_string);
|
|
646 |
|
658 | 647 |
g_free (capped_string);
|
659 | 648 |
return;
|
660 | 649 |
}
|
|
663 | 652 |
}
|
664 | 653 |
|
665 | 654 |
static void
|
666 | |
update_status (SnItem *item)
|
667 | |
{
|
668 | |
Status old_status;
|
669 | |
gchar *status;
|
670 | |
|
671 | |
old_status = item->status;
|
672 | |
|
673 | |
status = get_string_property (item, "Status");
|
674 | |
|
675 | |
if (g_strcmp0 (status, "Passive") == 0)
|
|
655 |
update_status (SnItem *item, SnItemPropertiesResult *new_props)
|
|
656 |
{
|
|
657 |
if (g_strcmp0 (new_props->status, "Passive") == 0)
|
676 | 658 |
{
|
677 | 659 |
item->status = STATUS_PASSIVE;
|
678 | 660 |
xapp_status_icon_set_visible (item->status_icon, FALSE);
|
679 | 661 |
}
|
680 | |
else if (g_strcmp0 (status, "NeedsAttention") == 0)
|
|
662 |
else
|
|
663 |
if (g_strcmp0 (new_props->status, "NeedsAttention") == 0)
|
681 | 664 |
{
|
682 | 665 |
item->status = STATUS_NEEDS_ATTENTION;
|
683 | 666 |
xapp_status_icon_set_visible (item->status_icon, TRUE);
|
|
688 | 671 |
xapp_status_icon_set_visible (item->status_icon, TRUE);
|
689 | 672 |
}
|
690 | 673 |
|
691 | |
g_free (status);
|
692 | |
|
693 | |
if (old_status != item->status)
|
694 | |
{
|
695 | |
update_icon (item);
|
696 | |
}
|
|
674 |
g_debug ("Status for '%s' is now '%s'", item->sortable_name, new_props->status);
|
|
675 |
}
|
|
676 |
|
|
677 |
static gchar *
|
|
678 |
null_or_string_from_string (const gchar *str)
|
|
679 |
{
|
|
680 |
if (str != NULL && strlen(str) > 0)
|
|
681 |
{
|
|
682 |
return g_strdup (str);
|
|
683 |
}
|
|
684 |
else
|
|
685 |
{
|
|
686 |
return NULL;
|
|
687 |
}
|
|
688 |
}
|
|
689 |
|
|
690 |
static gchar *
|
|
691 |
null_or_string_from_variant (GVariant *variant)
|
|
692 |
{
|
|
693 |
const gchar *str;
|
|
694 |
|
|
695 |
str = g_variant_get_string (variant, NULL);
|
|
696 |
|
|
697 |
return null_or_string_from_string (str);
|
|
698 |
}
|
|
699 |
|
|
700 |
static void
|
|
701 |
get_all_properties_callback (GObject *source_object,
|
|
702 |
GAsyncResult *res,
|
|
703 |
gpointer user_data)
|
|
704 |
{
|
|
705 |
SnItem *item = SN_ITEM (user_data);
|
|
706 |
SnItemPropertiesResult *new_props;
|
|
707 |
GError *error = NULL;
|
|
708 |
GVariant *properties;
|
|
709 |
GVariantIter *iter = NULL;
|
|
710 |
const gchar *name;
|
|
711 |
GVariant *value;
|
|
712 |
|
|
713 |
properties = g_dbus_proxy_call_finish (G_DBUS_PROXY (source_object), res, &error);
|
|
714 |
|
|
715 |
if (error != NULL)
|
|
716 |
{
|
|
717 |
if (!g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED))
|
|
718 |
{
|
|
719 |
g_critical ("Could get propertyies for %s: %s\n",
|
|
720 |
g_dbus_proxy_get_name (item->sn_item_proxy),
|
|
721 |
error->message);
|
|
722 |
}
|
|
723 |
|
|
724 |
g_error_free (error);
|
|
725 |
return;
|
|
726 |
}
|
|
727 |
|
|
728 |
if (properties == NULL)
|
|
729 |
{
|
|
730 |
return;
|
|
731 |
}
|
|
732 |
|
|
733 |
new_props = g_slice_new0 (SnItemPropertiesResult);
|
|
734 |
|
|
735 |
g_variant_get (properties, "(a{sv})", &iter);
|
|
736 |
|
|
737 |
while (g_variant_iter_loop (iter, "{&sv}", &name, &value))
|
|
738 |
{
|
|
739 |
if (g_strcmp0 (name, "Title") == 0)
|
|
740 |
{
|
|
741 |
new_props->title = null_or_string_from_variant (value);
|
|
742 |
|
|
743 |
if (g_strcmp0 (new_props->title, item->current_props->title) != 0)
|
|
744 |
{
|
|
745 |
new_props->update_tooltip = TRUE;
|
|
746 |
}
|
|
747 |
}
|
|
748 |
else
|
|
749 |
if (g_strcmp0 (name, "Status") == 0)
|
|
750 |
{
|
|
751 |
new_props->status = null_or_string_from_variant (value);
|
|
752 |
|
|
753 |
if (g_strcmp0 (new_props->status, item->current_props->status) != 0)
|
|
754 |
{
|
|
755 |
new_props->update_status = TRUE;
|
|
756 |
}
|
|
757 |
}
|
|
758 |
else
|
|
759 |
if (g_strcmp0 (name, "ToolTip") == 0)
|
|
760 |
{
|
|
761 |
const gchar *ts;
|
|
762 |
|
|
763 |
ts = g_variant_get_type_string (value);
|
|
764 |
|
|
765 |
if (g_strcmp0 (ts, "(sa(iiay)ss)") == 0)
|
|
766 |
{
|
|
767 |
gchar *heading, *body;
|
|
768 |
|
|
769 |
g_variant_get (value, "(sa(iiay)ss)", NULL, NULL,
|
|
770 |
&heading,
|
|
771 |
&body);
|
|
772 |
|
|
773 |
new_props->tooltip_heading = null_or_string_from_string (heading);
|
|
774 |
new_props->tooltip_body = null_or_string_from_string (body);
|
|
775 |
|
|
776 |
g_free (heading);
|
|
777 |
g_free (body);
|
|
778 |
}
|
|
779 |
else
|
|
780 |
if (g_strcmp0 (ts, "s") == 0)
|
|
781 |
{
|
|
782 |
new_props->tooltip_body = null_or_string_from_variant (value);
|
|
783 |
}
|
|
784 |
|
|
785 |
if (g_strcmp0 (new_props->tooltip_heading, item->current_props->tooltip_heading) != 0 ||
|
|
786 |
g_strcmp0 (new_props->tooltip_body, item->current_props->tooltip_body) != 0)
|
|
787 |
{
|
|
788 |
new_props->update_tooltip = TRUE;
|
|
789 |
}
|
|
790 |
}
|
|
791 |
else
|
|
792 |
if (g_strcmp0 (name, "Menu") == 0)
|
|
793 |
{
|
|
794 |
new_props->menu_path = null_or_string_from_variant (value);
|
|
795 |
|
|
796 |
if (g_strcmp0 (new_props->menu_path, item->current_props->menu_path) != 0)
|
|
797 |
{
|
|
798 |
new_props->update_menu = TRUE;
|
|
799 |
}
|
|
800 |
}
|
|
801 |
else
|
|
802 |
if (g_strcmp0 (name, "IconThemePath") == 0)
|
|
803 |
{
|
|
804 |
new_props->icon_theme_path = null_or_string_from_variant (value);
|
|
805 |
|
|
806 |
if (g_strcmp0 (new_props->icon_theme_path, item->current_props->icon_theme_path) != 0)
|
|
807 |
{
|
|
808 |
new_props->update_icon = TRUE;
|
|
809 |
}
|
|
810 |
}
|
|
811 |
else
|
|
812 |
if (g_strcmp0 (name, "IconName") == 0)
|
|
813 |
{
|
|
814 |
new_props->icon_name = null_or_string_from_variant (value);
|
|
815 |
if (g_strcmp0 (new_props->icon_name, item->current_props->icon_name) != 0)
|
|
816 |
{
|
|
817 |
new_props->update_icon = TRUE;
|
|
818 |
}
|
|
819 |
}
|
|
820 |
else
|
|
821 |
if (g_strcmp0 (name, "IconPixmap") == 0)
|
|
822 |
{
|
|
823 |
new_props->icon_surface = get_icon_surface (item, value, &new_props->icon_md5);
|
|
824 |
|
|
825 |
if (g_strcmp0 (new_props->icon_md5, item->current_props->icon_md5) != 0)
|
|
826 |
{
|
|
827 |
new_props->update_icon = TRUE;
|
|
828 |
}
|
|
829 |
}
|
|
830 |
else
|
|
831 |
if (g_strcmp0 (name, "AttentionIconName") == 0)
|
|
832 |
{
|
|
833 |
new_props->attention_icon_name = null_or_string_from_variant (value);
|
|
834 |
|
|
835 |
if (g_strcmp0 (new_props->attention_icon_name, item->current_props->attention_icon_name) != 0)
|
|
836 |
{
|
|
837 |
new_props->update_icon = TRUE;
|
|
838 |
}
|
|
839 |
}
|
|
840 |
else
|
|
841 |
if (g_strcmp0 (name, "AttentionIconPixmap") == 0)
|
|
842 |
{
|
|
843 |
new_props->attention_icon_surface = get_icon_surface (item, value, &new_props->attention_icon_md5);
|
|
844 |
|
|
845 |
if (g_strcmp0 (new_props->attention_icon_md5, item->current_props->attention_icon_md5) != 0)
|
|
846 |
{
|
|
847 |
new_props->update_icon = TRUE;
|
|
848 |
}
|
|
849 |
}
|
|
850 |
else
|
|
851 |
if (g_strcmp0 (name, "OverlayIconName") == 0)
|
|
852 |
{
|
|
853 |
new_props->overlay_icon_name = null_or_string_from_variant (value);
|
|
854 |
|
|
855 |
if (g_strcmp0 (new_props->overlay_icon_name, item->current_props->overlay_icon_name) != 0)
|
|
856 |
{
|
|
857 |
new_props->update_icon = TRUE;
|
|
858 |
}
|
|
859 |
}
|
|
860 |
else
|
|
861 |
if (g_strcmp0 (name, "OverlayIconPixmap") == 0)
|
|
862 |
{
|
|
863 |
new_props->overlay_icon_surface = get_icon_surface (item, value, &new_props->overlay_icon_md5);
|
|
864 |
|
|
865 |
if (g_strcmp0 (new_props->overlay_icon_md5, item->current_props->overlay_icon_md5) != 0)
|
|
866 |
{
|
|
867 |
new_props->update_icon = TRUE;
|
|
868 |
}
|
|
869 |
}
|
|
870 |
}
|
|
871 |
|
|
872 |
g_variant_iter_free (iter);
|
|
873 |
g_variant_unref (properties);
|
|
874 |
|
|
875 |
if (new_props->update_status)
|
|
876 |
{
|
|
877 |
update_status (item, new_props);
|
|
878 |
}
|
|
879 |
|
|
880 |
if (new_props->update_tooltip)
|
|
881 |
{
|
|
882 |
update_tooltip (item, new_props);
|
|
883 |
}
|
|
884 |
|
|
885 |
if (new_props->update_menu)
|
|
886 |
{
|
|
887 |
update_menu (item, new_props);
|
|
888 |
}
|
|
889 |
|
|
890 |
if (new_props->update_icon)
|
|
891 |
{
|
|
892 |
update_icon (item, new_props);
|
|
893 |
}
|
|
894 |
|
|
895 |
props_free (item->current_props);
|
|
896 |
item->current_props = new_props;
|
|
897 |
}
|
|
898 |
|
|
899 |
static gboolean
|
|
900 |
update_all_properties (gpointer data)
|
|
901 |
{
|
|
902 |
SnItem *item = SN_ITEM (data);
|
|
903 |
|
|
904 |
g_dbus_proxy_call (item->prop_proxy,
|
|
905 |
"GetAll",
|
|
906 |
g_variant_new ("(s)",
|
|
907 |
g_dbus_proxy_get_interface_name (item->sn_item_proxy)),
|
|
908 |
G_DBUS_CALL_FLAGS_NONE,
|
|
909 |
5 * 1000,
|
|
910 |
item->cancellable,
|
|
911 |
get_all_properties_callback,
|
|
912 |
item);
|
|
913 |
|
|
914 |
item->update_properties_timeout = 0;
|
|
915 |
|
|
916 |
return G_SOURCE_REMOVE;
|
|
917 |
}
|
|
918 |
|
|
919 |
static void
|
|
920 |
queue_update_properties (SnItem *item, gboolean force)
|
|
921 |
{
|
|
922 |
if (item->update_properties_timeout > 0)
|
|
923 |
{
|
|
924 |
g_source_remove (item->update_properties_timeout);
|
|
925 |
}
|
|
926 |
|
|
927 |
if (force)
|
|
928 |
{
|
|
929 |
props_free (item->current_props);
|
|
930 |
item->current_props = g_slice_new0 (SnItemPropertiesResult);
|
|
931 |
}
|
|
932 |
|
|
933 |
item->update_properties_timeout = g_timeout_add (10, G_SOURCE_FUNC (update_all_properties), item);
|
697 | 934 |
}
|
698 | 935 |
|
699 | 936 |
static void
|
|
712 | 949 |
|
713 | 950 |
if (g_strcmp0 (signal_name, "NewIcon") == 0 ||
|
714 | 951 |
g_strcmp0 (signal_name, "NewAttentionIcon") == 0 ||
|
715 | |
g_strcmp0 (signal_name, "NewOverlayIcon") == 0)
|
716 | |
{
|
717 | |
update_icon (item);
|
718 | |
}
|
719 | |
else
|
720 | |
if (g_strcmp0 (signal_name, "NewStatus") == 0)
|
721 | |
{
|
722 | |
update_status (item); // This will update_icon(item) also.
|
723 | |
}
|
724 | |
else
|
725 | |
if (g_strcmp0 (signal_name, "NewMenu") == 0)
|
726 | |
{
|
727 | |
update_menu (item);
|
728 | |
}
|
729 | |
else
|
730 | |
if (g_strcmp0 (signal_name, "NewToolTip") ||
|
731 | |
g_strcmp0 (signal_name, "NewTitle"))
|
732 | |
{
|
733 | |
update_tooltip (item);
|
|
952 |
g_strcmp0 (signal_name, "NewOverlayIcon") == 0 ||
|
|
953 |
g_strcmp0 (signal_name, "NewToolTip") == 0 ||
|
|
954 |
g_strcmp0 (signal_name, "NewTitle") == 0 ||
|
|
955 |
g_strcmp0 (signal_name, "NewStatus") == 0 ||
|
|
956 |
g_strcmp0 (signal_name, "NewMenu") == 0)
|
|
957 |
{
|
|
958 |
queue_update_properties (item, FALSE);
|
734 | 959 |
}
|
735 | 960 |
}
|
736 | 961 |
|
|
825 | 1050 |
return;
|
826 | 1051 |
}
|
827 | 1052 |
|
828 | |
update_icon (item);
|
829 | |
update_status (item);
|
830 | |
update_icon (item);
|
831 | |
update_tooltip (item);
|
|
1053 |
queue_update_properties (item, TRUE);
|
832 | 1054 |
}
|
833 | 1055 |
|
834 | 1056 |
static void
|
835 | 1057 |
assign_sortable_name (SnItem *item,
|
836 | |
XAppStatusIcon *status_icon)
|
837 | |
{
|
838 | |
gchar *init_name, *normalized, *sortable_name;
|
|
1058 |
const gchar *title)
|
|
1059 |
{
|
|
1060 |
gchar *init_name, *normalized;
|
|
1061 |
gchar *sortable_name, *old_sortable_name;
|
839 | 1062 |
|
840 | 1063 |
init_name = sn_item_interface_dup_id (SN_ITEM_INTERFACE (item->sn_item_proxy));
|
841 | 1064 |
|
842 | |
if (init_name == NULL)
|
843 | |
{
|
844 | |
init_name = get_string_property (item, "Title");
|
|
1065 |
if (init_name == NULL && title != NULL)
|
|
1066 |
{
|
|
1067 |
init_name = g_strdup (title);
|
|
1068 |
}
|
|
1069 |
else
|
|
1070 |
{
|
|
1071 |
init_name = g_strdup (g_dbus_proxy_get_name (G_DBUS_PROXY (item->sn_item_proxy)));
|
845 | 1072 |
}
|
846 | 1073 |
|
847 | 1074 |
normalized = g_utf8_normalize (init_name,
|
|
850 | 1077 |
|
851 | 1078 |
sortable_name = g_utf8_strdown (normalized, -1);
|
852 | 1079 |
|
853 | |
g_debug ("Sort name for %s is '%s'", g_dbus_proxy_get_name (G_DBUS_PROXY (item->sn_item_proxy)), sortable_name);
|
854 | |
xapp_status_icon_set_name (status_icon, sortable_name);
|
855 | |
|
856 | |
item->sortable_name = sortable_name;
|
857 | |
|
858 | 1080 |
g_free (init_name);
|
859 | 1081 |
g_free (normalized);
|
|
1082 |
|
|
1083 |
if (g_strcmp0 (sortable_name, item->sortable_name) == 0)
|
|
1084 |
{
|
|
1085 |
g_free (sortable_name);
|
|
1086 |
return;
|
|
1087 |
}
|
|
1088 |
|
|
1089 |
g_debug ("Sort name for '%s' is '%s'",
|
|
1090 |
g_dbus_proxy_get_name (G_DBUS_PROXY (item->sn_item_proxy)),
|
|
1091 |
sortable_name);
|
|
1092 |
|
|
1093 |
xapp_status_icon_set_name (item->status_icon, sortable_name);
|
|
1094 |
|
|
1095 |
old_sortable_name = item->sortable_name;
|
|
1096 |
item->sortable_name = sortable_name;
|
|
1097 |
g_free (old_sortable_name);
|
|
1098 |
|
|
1099 |
update_conditionals (item);
|
860 | 1100 |
}
|
861 | 1101 |
|
862 | 1102 |
static void
|
|
872 | 1112 |
|
873 | 1113 |
if (error != NULL)
|
874 | 1114 |
{
|
875 | |
g_printerr ("Could not get prop proxy: %s\n", error->message);
|
876 | |
g_error_free (error);
|
877 | |
return;
|
|
1115 |
if (!g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED))
|
|
1116 |
{
|
|
1117 |
g_critical ("Could not get property proxy for %s: %s\n",
|
|
1118 |
g_dbus_proxy_get_name (item->sn_item_proxy),
|
|
1119 |
error->message);
|
|
1120 |
g_error_free (error);
|
|
1121 |
return;
|
|
1122 |
}
|
878 | 1123 |
}
|
879 | 1124 |
|
880 | 1125 |
g_signal_connect (item->sn_item_proxy,
|
|
884 | 1129 |
|
885 | 1130 |
item->status_icon = xapp_status_icon_new ();
|
886 | 1131 |
|
887 | |
json = g_strdup_printf ("{ 'highlight-both-menus': %s }", item->is_ai ? "true" : "false");
|
|
1132 |
json = g_strdup_printf ("{ \"highlight-both-menus\": %s }", item->is_ai ? "true" : "false");
|
888 | 1133 |
xapp_status_icon_set_metadata (item->status_icon, json);
|
889 | 1134 |
g_free (json);
|
890 | 1135 |
|
|
894 | 1139 |
g_signal_connect (item->status_icon, "scroll-event", G_CALLBACK (xapp_icon_scroll), item);
|
895 | 1140 |
g_signal_connect (item->status_icon, "state-changed", G_CALLBACK (xapp_icon_state_changed), item);
|
896 | 1141 |
|
897 | |
assign_sortable_name (item, item->status_icon);
|
898 | |
|
899 | |
item->should_activate = should_activate (item);
|
900 | |
item->should_replace_tooltip = should_replace_tooltip (item);
|
901 | |
|
902 | |
update_status (item);
|
903 | |
update_menu (item);
|
904 | |
update_tooltip (item);
|
905 | |
update_icon (item);
|
|
1142 |
assign_sortable_name (item, NULL);
|
|
1143 |
update_conditionals (item);
|
|
1144 |
|
|
1145 |
queue_update_properties (item, TRUE);
|
906 | 1146 |
}
|
907 | 1147 |
|
908 | 1148 |
static void
|
|
914 | 1154 |
g_dbus_proxy_get_name (item->sn_item_proxy),
|
915 | 1155 |
g_dbus_proxy_get_object_path (item->sn_item_proxy),
|
916 | 1156 |
"org.freedesktop.DBus.Properties",
|
917 | |
NULL,
|
|
1157 |
item->cancellable,
|
918 | 1158 |
property_proxy_acquired,
|
919 | 1159 |
item);
|
920 | 1160 |
}
|
|
927 | 1167 |
|
928 | 1168 |
item->sn_item_proxy = sn_item_proxy;
|
929 | 1169 |
item->is_ai = is_ai;
|
|
1170 |
item->cancellable = g_cancellable_new ();
|
930 | 1171 |
|
931 | 1172 |
initialize_item (item);
|
932 | 1173 |
return item;
|
933 | 1174 |
}
|
934 | 1175 |
|
935 | |
void
|
936 | |
sn_item_update_menus (SnItem *item)
|
937 | |
{
|
938 | |
update_menu (item);
|
939 | |
}⏎
|