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 |
}
|
|
174 | 250 |
}
|
175 | 251 |
|
176 | 252 |
return FALLBACK_ICON_SIZE;
|
177 | |
}
|
178 | |
|
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 | 253 |
}
|
248 | 254 |
|
249 | 255 |
static cairo_surface_t *
|
|
289 | 295 |
}
|
290 | 296 |
}
|
291 | 297 |
|
292 | |
static gboolean
|
293 | |
process_pixmaps (SnItem *item,
|
294 | |
GVariant *pixmaps,
|
295 | |
gchar **image_path)
|
|
298 |
static cairo_surface_t *
|
|
299 |
get_icon_surface (SnItem *item,
|
|
300 |
GVariant *pixmaps,
|
|
301 |
gchar **md5)
|
296 | 302 |
{
|
297 | 303 |
GVariantIter *iter;
|
298 | 304 |
cairo_surface_t *surface;
|
299 | 305 |
gint width, height;
|
300 | 306 |
gint largest_width, largest_height;
|
|
307 |
gsize largest_data_size;
|
301 | 308 |
GVariant *byte_array_var;
|
302 | 309 |
gconstpointer data;
|
303 | 310 |
guchar *best_image_array = NULL;
|
304 | 311 |
|
305 | 312 |
largest_width = largest_height = 0;
|
306 | 313 |
|
|
314 |
*md5 = NULL;
|
|
315 |
|
307 | 316 |
g_variant_get (pixmaps, "a(iiay)", &iter);
|
308 | 317 |
|
309 | 318 |
if (iter == NULL)
|
310 | 319 |
{
|
311 | |
return FALSE;
|
|
320 |
return NULL;
|
312 | 321 |
}
|
313 | 322 |
|
314 | 323 |
while (g_variant_iter_loop (iter, "(ii@ay)", &width, &height, &byte_array_var))
|
|
331 | 340 |
|
332 | 341 |
best_image_array = g_memdup (data, data_size);
|
333 | 342 |
|
|
343 |
largest_data_size = data_size;
|
334 | 344 |
largest_width = width;
|
335 | 345 |
largest_height = height;
|
336 | 346 |
}
|
|
338 | 348 |
}
|
339 | 349 |
}
|
340 | 350 |
|
|
351 |
g_variant_iter_free (iter);
|
|
352 |
|
341 | 353 |
if (best_image_array == NULL)
|
342 | 354 |
{
|
343 | |
g_warning ("No valid pixmaps found.");
|
344 | |
return FALSE;
|
|
355 |
return NULL;
|
345 | 356 |
}
|
346 | 357 |
|
347 | 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);
|
348 | 360 |
|
349 | 361 |
if (cairo_surface_status (surface) != CAIRO_STATUS_SUCCESS)
|
350 | 362 |
{
|
351 | 363 |
cairo_surface_destroy (surface);
|
352 | |
return FALSE;
|
353 | |
}
|
354 | |
|
355 | |
item->last_png_path = item->png_path;
|
356 | |
|
357 | |
gchar *filename = g_strdup_printf ("xapp-tmp-%p-%d.png", item, get_icon_id (item));
|
358 | |
gchar *save_filename = g_build_path ("/", g_get_tmp_dir (), filename, NULL);
|
359 | |
g_free (filename);
|
360 | |
|
361 | |
cairo_status_t status = CAIRO_STATUS_SUCCESS;
|
362 | |
status = cairo_surface_write_to_png (surface, save_filename);
|
363 | |
|
364 | |
if (status != CAIRO_STATUS_SUCCESS)
|
365 | |
{
|
366 | |
g_warning ("Failed to save png of status icon");
|
367 | |
g_free (image_path);
|
368 | |
cairo_surface_destroy (surface);
|
369 | |
return FALSE;
|
370 | |
}
|
371 | |
|
372 | |
*image_path = save_filename;
|
373 | |
cairo_surface_destroy (surface);
|
374 | |
|
375 | |
return TRUE;
|
376 | |
}
|
377 | |
|
378 | |
static void
|
379 | |
set_icon_from_pixmap (SnItem *item)
|
380 | |
{
|
381 | |
GVariant *pixmaps = NULL;
|
382 | |
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;
|
383 | 380 |
|
384 | 381 |
if (item->status == STATUS_ACTIVE)
|
385 | 382 |
{
|
386 | |
pixmaps = get_pixmap_property (item, "IconPixmap");
|
|
383 |
if (new_props->icon_surface)
|
|
384 |
{
|
|
385 |
surface = new_props->icon_surface;
|
|
386 |
}
|
387 | 387 |
}
|
388 | 388 |
else
|
389 | 389 |
if (item->status == STATUS_NEEDS_ATTENTION)
|
390 | 390 |
{
|
391 | |
pixmaps = get_pixmap_property (item, "AttentionIconPixmap");
|
392 | |
|
393 | |
if (!pixmaps)
|
394 | |
{
|
395 | |
pixmaps = get_pixmap_property (item, "IconPixmap");
|
396 | |
}
|
397 | |
}
|
398 | |
|
399 | |
if (!pixmaps)
|
400 | |
{
|
401 | |
xapp_status_icon_set_icon_name (item->status_icon, "image-missing");
|
402 | |
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 |
if (status != CAIRO_STATUS_SUCCESS)
|
|
409 |
{
|
|
410 |
g_warning ("Failed to save png of status icon");
|
|
411 |
}
|
|
412 |
|
|
413 |
xapp_status_icon_set_icon_name (item->status_icon, save_filename);
|
|
414 |
g_free (save_filename);
|
403 | 415 |
return;
|
404 | 416 |
}
|
405 | 417 |
|
406 | |
if (process_pixmaps (item, pixmaps, &image_path))
|
407 | |
{
|
408 | |
xapp_status_icon_set_icon_name (item->status_icon, image_path);
|
409 | |
g_free (image_path);
|
410 | |
}
|
411 | |
|
412 | |
g_variant_unref (pixmaps);
|
|
418 |
g_debug ("No pixmaps to use");
|
|
419 |
xapp_status_icon_set_icon_name (item->status_icon, "image-missing");
|
413 | 420 |
}
|
414 | 421 |
|
415 | 422 |
static gchar *
|
416 | |
get_icon_filename_from_theme (SnItem *item,
|
|
423 |
get_icon_filename_from_theme (SnItem *item,
|
417 | 424 |
const gchar *theme_path,
|
418 | 425 |
const gchar *icon_name)
|
419 | 426 |
{
|
420 | 427 |
GtkIconInfo *info;
|
421 | 428 |
gchar *filename;
|
422 | 429 |
const gchar *array[2];
|
|
430 |
gint host_icon_size;
|
423 | 431 |
|
424 | 432 |
array[0] = icon_name;
|
425 | 433 |
array[1] = NULL;
|
426 | 434 |
|
427 | 435 |
// We have a theme path, but try the system theme first
|
428 | 436 |
GtkIconTheme *theme = gtk_icon_theme_get_default ();
|
|
437 |
host_icon_size = get_icon_size (item);
|
429 | 438 |
|
430 | 439 |
info = gtk_icon_theme_choose_icon_for_scale (theme,
|
431 | 440 |
array,
|
432 | |
get_icon_size (item),
|
|
441 |
host_icon_size,
|
433 | 442 |
lookup_ui_scale (),
|
434 | 443 |
GTK_ICON_LOOKUP_FORCE_SVG | GTK_ICON_LOOKUP_FORCE_SYMBOLIC);
|
435 | 444 |
|
|
442 | 451 |
|
443 | 452 |
info = gtk_icon_theme_choose_icon_for_scale (theme,
|
444 | 453 |
array,
|
445 | |
get_icon_size (item),
|
|
454 |
host_icon_size,
|
446 | 455 |
lookup_ui_scale (),
|
447 | 456 |
GTK_ICON_LOOKUP_FORCE_SVG | GTK_ICON_LOOKUP_FORCE_SYMBOLIC);
|
448 | 457 |
|
|
460 | 469 |
return filename;
|
461 | 470 |
}
|
462 | 471 |
|
463 | |
static void
|
464 | |
process_icon_name (SnItem *item,
|
465 | |
const gchar *icon_theme_path,
|
466 | |
const gchar *icon_name)
|
467 | |
{
|
468 | |
if (g_path_is_absolute (icon_name) || !icon_theme_path)
|
|
472 |
static gboolean
|
|
473 |
set_icon_name (SnItem *item,
|
|
474 |
const gchar *icon_theme_path,
|
|
475 |
const gchar *icon_name)
|
|
476 |
{
|
|
477 |
g_debug ("Checking for icon name for %s",
|
|
478 |
item->sortable_name);
|
|
479 |
|
|
480 |
if (icon_name == NULL)
|
|
481 |
{
|
|
482 |
return FALSE;
|
|
483 |
}
|
|
484 |
|
|
485 |
if (g_path_is_absolute (icon_name))
|
469 | 486 |
{
|
470 | 487 |
xapp_status_icon_set_icon_name (item->status_icon, icon_name);
|
|
488 |
|
|
489 |
return TRUE;
|
471 | 490 |
}
|
472 | 491 |
else
|
473 | 492 |
{
|
|
477 | 496 |
{
|
478 | 497 |
xapp_status_icon_set_icon_name (item->status_icon, filename);
|
479 | 498 |
g_free (filename);
|
480 | |
}
|
481 | |
else
|
482 | |
{
|
483 | |
xapp_status_icon_set_icon_name (item->status_icon, "image-missing");
|
484 | |
}
|
485 | |
}
|
486 | |
}
|
487 | |
|
488 | |
static void
|
489 | |
set_icon_name_or_path (SnItem *item,
|
490 | |
const gchar *icon_theme_path,
|
491 | |
const gchar *icon_name,
|
492 | |
const gchar *att_icon_name,
|
493 | |
const gchar *olay_icon_name)
|
|
499 |
return TRUE;
|
|
500 |
}
|
|
501 |
}
|
|
502 |
|
|
503 |
return FALSE;
|
|
504 |
}
|
|
505 |
|
|
506 |
static gboolean
|
|
507 |
set_icon_name_or_path (SnItem *item,
|
|
508 |
SnItemPropertiesResult *new_props)
|
494 | 509 |
{
|
495 | 510 |
const gchar *name_to_use = NULL;
|
496 | 511 |
|
497 | 512 |
if (item->status == STATUS_ACTIVE)
|
498 | 513 |
{
|
499 | |
if (icon_name)
|
500 | |
{
|
501 | |
name_to_use = icon_name;
|
|
514 |
if (new_props->icon_name)
|
|
515 |
{
|
|
516 |
name_to_use = new_props->icon_name;
|
502 | 517 |
}
|
503 | 518 |
}
|
504 | 519 |
else
|
505 | 520 |
if (item->status == STATUS_NEEDS_ATTENTION)
|
506 | 521 |
{
|
507 | |
if (att_icon_name)
|
508 | |
{
|
509 | |
name_to_use = att_icon_name;
|
|
522 |
if (new_props->attention_icon_name)
|
|
523 |
{
|
|
524 |
name_to_use = new_props->attention_icon_name;
|
510 | 525 |
}
|
511 | 526 |
else
|
512 | |
if (icon_name)
|
513 | |
{
|
514 | |
name_to_use = icon_name;
|
515 | |
}
|
516 | |
}
|
517 | |
|
518 | |
if (name_to_use == NULL)
|
519 | |
{
|
520 | |
name_to_use = "image-missing";
|
521 | |
}
|
522 | |
|
523 | |
process_icon_name (item, icon_theme_path, name_to_use);
|
524 | |
}
|
525 | |
|
526 | |
static void
|
527 | |
update_icon (SnItem *item)
|
528 | |
{
|
529 | |
gchar *icon_theme_path;
|
530 | |
gchar *icon_name, *att_icon_name, *olay_icon_name;
|
531 | |
|
532 | |
icon_theme_path = get_string_property (item, "IconThemePath");
|
533 | |
icon_name = get_string_property (item, "IconName");
|
534 | |
att_icon_name = get_string_property (item, "AttentionIconName");
|
535 | |
olay_icon_name = get_string_property (item, "OverlayIconName");
|
536 | |
|
537 | |
if (icon_name || att_icon_name || olay_icon_name)
|
538 | |
{
|
539 | |
// g_printerr ("icon name '%s' '%s' '%s'\n", icon_name, att_icon_name, olay_icon_name);
|
540 | |
set_icon_name_or_path (item,
|
541 | |
icon_theme_path,
|
542 | |
icon_name,
|
543 | |
att_icon_name,
|
544 | |
olay_icon_name);
|
545 | |
}
|
546 | |
else
|
547 | |
{
|
548 | |
set_icon_from_pixmap (item);
|
549 | |
}
|
550 | |
|
551 | |
g_free (icon_theme_path);
|
552 | |
g_free (icon_name);
|
553 | |
g_free (att_icon_name);
|
554 | |
g_free (olay_icon_name);
|
555 | |
}
|
556 | |
|
557 | |
static void
|
558 | |
update_menu (SnItem *item)
|
559 | |
{
|
560 | |
gchar *menu_path;
|
561 | |
|
|
527 |
if (new_props->icon_name)
|
|
528 |
{
|
|
529 |
name_to_use = new_props->icon_name;
|
|
530 |
}
|
|
531 |
}
|
|
532 |
|
|
533 |
return set_icon_name (item, new_props->icon_theme_path, name_to_use);
|
|
534 |
}
|
|
535 |
|
|
536 |
static void
|
|
537 |
update_icon (SnItem *item, SnItemPropertiesResult *new_props)
|
|
538 |
{
|
|
539 |
if (!set_icon_name_or_path (item, new_props))
|
|
540 |
{
|
|
541 |
set_icon_from_pixmap (item, new_props);
|
|
542 |
}
|
|
543 |
}
|
|
544 |
|
|
545 |
static void
|
|
546 |
update_menu (SnItem *item, SnItemPropertiesResult *new_props)
|
|
547 |
{
|
562 | 548 |
g_clear_object (&item->menu);
|
563 | 549 |
|
564 | 550 |
xapp_status_icon_set_primary_menu (item->status_icon, NULL);
|
565 | 551 |
xapp_status_icon_set_secondary_menu (item->status_icon, NULL);
|
566 | 552 |
|
567 | |
menu_path = get_string_property (item, "Menu");
|
568 | |
|
569 | |
if (menu_path == NULL)
|
|
553 |
if (new_props->menu_path == NULL)
|
570 | 554 |
{
|
571 | 555 |
return;
|
572 | 556 |
}
|
573 | 557 |
|
574 | |
item->menu = GTK_WIDGET (dbusmenu_gtkmenu_new ((gchar *) g_dbus_proxy_get_name (item->sn_item_proxy), menu_path));
|
|
558 |
item->menu = GTK_WIDGET (dbusmenu_gtkmenu_new ((gchar *) g_dbus_proxy_get_name (item->sn_item_proxy),
|
|
559 |
new_props->menu_path));
|
575 | 560 |
g_object_ref_sink (item->menu);
|
576 | 561 |
|
|
562 |
g_debug ("New menu for '%s'", item->sortable_name);
|
|
563 |
|
577 | 564 |
if (item->is_ai && !item->should_activate)
|
578 | 565 |
{
|
579 | 566 |
xapp_status_icon_set_primary_menu (item->status_icon, GTK_MENU (item->menu));
|
580 | 567 |
}
|
581 | 568 |
|
582 | 569 |
xapp_status_icon_set_secondary_menu (item->status_icon, GTK_MENU (item->menu));
|
583 | |
|
584 | |
g_free (menu_path);
|
585 | 570 |
}
|
586 | 571 |
|
587 | 572 |
static gchar *
|
|
608 | 593 |
}
|
609 | 594 |
|
610 | 595 |
static void
|
611 | |
update_tooltip (SnItem *item)
|
612 | |
{
|
613 | |
g_autoptr(GVariant) tt_var = NULL;
|
|
596 |
update_tooltip (SnItem *item, SnItemPropertiesResult *new_props)
|
|
597 |
{
|
|
598 |
if (new_props->title)
|
|
599 |
{
|
|
600 |
assign_sortable_name (item, new_props->title);
|
|
601 |
}
|
614 | 602 |
|
615 | 603 |
if (!item->should_replace_tooltip)
|
616 | 604 |
{
|
617 | |
tt_var = get_property (item, "ToolTip");
|
618 | |
}
|
619 | |
|
620 | |
if (tt_var)
|
621 | |
{
|
622 | |
const gchar *type_str;
|
623 | |
type_str = g_variant_get_type_string (tt_var);
|
624 | |
|
625 | |
if (g_strcmp0 (type_str, "(sa(iiay)ss)") == 0)
|
626 | |
{
|
627 | |
const gchar *tooltip_title, *tooltip_body;
|
628 | |
|
629 | |
g_variant_get (tt_var, "(sa(iiay)&s&s)", NULL, NULL, &tooltip_title, &tooltip_body);
|
630 | |
|
631 | |
if (g_strcmp0 (tooltip_title, "") != 0)
|
632 | |
{
|
633 | |
|
634 | |
if (g_strcmp0 (tooltip_body, "") != 0)
|
635 | |
{
|
636 | |
gchar *text;
|
637 | |
text = g_strdup_printf ("%s\n%s", tooltip_title, tooltip_body);
|
638 | |
|
639 | |
xapp_status_icon_set_tooltip_text (item->status_icon, text);
|
640 | |
g_debug ("Tooltip text from ToolTip: %s", text);
|
641 | |
|
642 | |
g_free (text);
|
643 | |
}
|
644 | |
else
|
645 | |
{
|
646 | |
g_debug ("Tooltip text from ToolTip: %s", tooltip_title);
|
647 | |
xapp_status_icon_set_tooltip_text (item->status_icon, tooltip_title);
|
648 | |
}
|
649 | |
|
650 | |
return;
|
651 | |
}
|
652 | |
}
|
653 | |
}
|
654 | |
|
655 | |
gchar *title_string;
|
656 | |
title_string = get_string_property (item, "Title");
|
657 | |
|
658 | |
if (title_string != NULL)
|
|
605 |
if (new_props->tooltip_heading != NULL)
|
|
606 |
{
|
|
607 |
if (new_props->tooltip_body != NULL)
|
|
608 |
{
|
|
609 |
gchar *text;
|
|
610 |
text = g_strdup_printf ("%s\n%s",
|
|
611 |
new_props->tooltip_heading,
|
|
612 |
new_props->tooltip_body);
|
|
613 |
|
|
614 |
xapp_status_icon_set_tooltip_text (item->status_icon, text);
|
|
615 |
g_debug ("Tooltip text for '%s' from ToolTip: %s",
|
|
616 |
item->sortable_name,
|
|
617 |
text);
|
|
618 |
|
|
619 |
g_free (text);
|
|
620 |
}
|
|
621 |
else
|
|
622 |
{
|
|
623 |
g_debug ("Tooltip text for '%s' from ToolTip: %s",
|
|
624 |
item->sortable_name,
|
|
625 |
new_props->tooltip_heading);
|
|
626 |
|
|
627 |
xapp_status_icon_set_tooltip_text (item->status_icon, new_props->tooltip_heading);
|
|
628 |
}
|
|
629 |
|
|
630 |
return;
|
|
631 |
}
|
|
632 |
}
|
|
633 |
|
|
634 |
if (new_props->title != NULL)
|
659 | 635 |
{
|
660 | 636 |
gchar *capped_string;
|
661 | 637 |
|
662 | |
capped_string = capitalize (title_string);
|
|
638 |
capped_string = capitalize (new_props->title);
|
663 | 639 |
xapp_status_icon_set_tooltip_text (item->status_icon, capped_string);
|
664 | |
g_debug ("Tooltip text from Title: %s", capped_string);
|
665 | |
|
666 | |
g_free (title_string);
|
|
640 |
|
|
641 |
g_debug ("Tooltip text for '%s' from Title: %s",
|
|
642 |
item->sortable_name,
|
|
643 |
capped_string);
|
|
644 |
|
667 | 645 |
g_free (capped_string);
|
668 | 646 |
return;
|
669 | 647 |
}
|
|
672 | 650 |
}
|
673 | 651 |
|
674 | 652 |
static void
|
675 | |
update_status (SnItem *item)
|
676 | |
{
|
677 | |
Status old_status;
|
678 | |
gchar *status;
|
679 | |
|
680 | |
old_status = item->status;
|
681 | |
|
682 | |
status = get_string_property (item, "Status");
|
683 | |
|
684 | |
if (g_strcmp0 (status, "Passive") == 0)
|
|
653 |
update_status (SnItem *item, SnItemPropertiesResult *new_props)
|
|
654 |
{
|
|
655 |
if (g_strcmp0 (new_props->status, "Passive") == 0)
|
685 | 656 |
{
|
686 | 657 |
item->status = STATUS_PASSIVE;
|
687 | 658 |
xapp_status_icon_set_visible (item->status_icon, FALSE);
|
688 | 659 |
}
|
689 | |
else if (g_strcmp0 (status, "NeedsAttention") == 0)
|
|
660 |
else
|
|
661 |
if (g_strcmp0 (new_props->status, "NeedsAttention") == 0)
|
690 | 662 |
{
|
691 | 663 |
item->status = STATUS_NEEDS_ATTENTION;
|
692 | 664 |
xapp_status_icon_set_visible (item->status_icon, TRUE);
|
|
697 | 669 |
xapp_status_icon_set_visible (item->status_icon, TRUE);
|
698 | 670 |
}
|
699 | 671 |
|
700 | |
g_free (status);
|
701 | |
|
702 | |
if (old_status != item->status)
|
703 | |
{
|
704 | |
update_icon (item);
|
705 | |
}
|
|
672 |
g_debug ("Status for '%s' is now '%s'", item->sortable_name, new_props->status);
|
|
673 |
}
|
|
674 |
|
|
675 |
static gchar *
|
|
676 |
null_or_string_from_string (const gchar *str)
|
|
677 |
{
|
|
678 |
if (str != NULL && strlen(str) > 0)
|
|
679 |
{
|
|
680 |
return g_strdup (str);
|
|
681 |
}
|
|
682 |
else
|
|
683 |
{
|
|
684 |
return NULL;
|
|
685 |
}
|
|
686 |
}
|
|
687 |
|
|
688 |
static gchar *
|
|
689 |
null_or_string_from_variant (GVariant *variant)
|
|
690 |
{
|
|
691 |
const gchar *str;
|
|
692 |
|
|
693 |
str = g_variant_get_string (variant, NULL);
|
|
694 |
|
|
695 |
return null_or_string_from_string (str);
|
|
696 |
}
|
|
697 |
|
|
698 |
static void
|
|
699 |
get_all_properties_callback (GObject *source_object,
|
|
700 |
GAsyncResult *res,
|
|
701 |
gpointer user_data)
|
|
702 |
{
|
|
703 |
SnItem *item = SN_ITEM (user_data);
|
|
704 |
SnItemPropertiesResult *new_props;
|
|
705 |
GError *error = NULL;
|
|
706 |
GVariant *properties;
|
|
707 |
GVariantIter *iter = NULL;
|
|
708 |
const gchar *name;
|
|
709 |
GVariant *value;
|
|
710 |
|
|
711 |
properties = g_dbus_proxy_call_finish (G_DBUS_PROXY (source_object), res, &error);
|
|
712 |
|
|
713 |
if (error != NULL)
|
|
714 |
{
|
|
715 |
if (!g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED))
|
|
716 |
{
|
|
717 |
g_critical ("Could get propertyies for %s: %s\n",
|
|
718 |
g_dbus_proxy_get_name (item->sn_item_proxy),
|
|
719 |
error->message);
|
|
720 |
}
|
|
721 |
|
|
722 |
g_error_free (error);
|
|
723 |
return;
|
|
724 |
}
|
|
725 |
|
|
726 |
if (properties == NULL)
|
|
727 |
{
|
|
728 |
return;
|
|
729 |
}
|
|
730 |
|
|
731 |
new_props = g_slice_new0 (SnItemPropertiesResult);
|
|
732 |
|
|
733 |
g_variant_get (properties, "(a{sv})", &iter);
|
|
734 |
|
|
735 |
while (g_variant_iter_loop (iter, "{&sv}", &name, &value))
|
|
736 |
{
|
|
737 |
if (g_strcmp0 (name, "Title") == 0)
|
|
738 |
{
|
|
739 |
new_props->title = null_or_string_from_variant (value);
|
|
740 |
|
|
741 |
if (g_strcmp0 (new_props->title, item->current_props->title) != 0)
|
|
742 |
{
|
|
743 |
new_props->update_tooltip = TRUE;
|
|
744 |
}
|
|
745 |
}
|
|
746 |
else
|
|
747 |
if (g_strcmp0 (name, "Status") == 0)
|
|
748 |
{
|
|
749 |
new_props->status = null_or_string_from_variant (value);
|
|
750 |
|
|
751 |
if (g_strcmp0 (new_props->status, item->current_props->status) != 0)
|
|
752 |
{
|
|
753 |
new_props->update_status = TRUE;
|
|
754 |
}
|
|
755 |
}
|
|
756 |
else
|
|
757 |
if (g_strcmp0 (name, "ToolTip") == 0)
|
|
758 |
{
|
|
759 |
const gchar *ts;
|
|
760 |
|
|
761 |
ts = g_variant_get_type_string (value);
|
|
762 |
|
|
763 |
if (g_strcmp0 (ts, "(sa(iiay)ss)") == 0)
|
|
764 |
{
|
|
765 |
gchar *heading, *body;
|
|
766 |
|
|
767 |
g_variant_get (value, "(sa(iiay)ss)", NULL, NULL,
|
|
768 |
&heading,
|
|
769 |
&body);
|
|
770 |
|
|
771 |
new_props->tooltip_heading = null_or_string_from_string (heading);
|
|
772 |
new_props->tooltip_body = null_or_string_from_string (body);
|
|
773 |
|
|
774 |
g_free (heading);
|
|
775 |
g_free (body);
|
|
776 |
}
|
|
777 |
else
|
|
778 |
if (g_strcmp0 (ts, "s") == 0)
|
|
779 |
{
|
|
780 |
new_props->tooltip_body = null_or_string_from_variant (value);
|
|
781 |
}
|
|
782 |
|
|
783 |
if (g_strcmp0 (new_props->tooltip_heading, item->current_props->tooltip_heading) != 0 ||
|
|
784 |
g_strcmp0 (new_props->tooltip_body, item->current_props->tooltip_body) != 0)
|
|
785 |
{
|
|
786 |
new_props->update_tooltip = TRUE;
|
|
787 |
}
|
|
788 |
}
|
|
789 |
else
|
|
790 |
if (g_strcmp0 (name, "Menu") == 0)
|
|
791 |
{
|
|
792 |
new_props->menu_path = null_or_string_from_variant (value);
|
|
793 |
|
|
794 |
if (g_strcmp0 (new_props->menu_path, item->current_props->menu_path) != 0)
|
|
795 |
{
|
|
796 |
new_props->update_menu = TRUE;
|
|
797 |
}
|
|
798 |
}
|
|
799 |
else
|
|
800 |
if (g_strcmp0 (name, "IconThemePath") == 0)
|
|
801 |
{
|
|
802 |
new_props->icon_theme_path = null_or_string_from_variant (value);
|
|
803 |
|
|
804 |
if (g_strcmp0 (new_props->icon_theme_path, item->current_props->icon_theme_path) != 0)
|
|
805 |
{
|
|
806 |
new_props->update_icon = TRUE;
|
|
807 |
}
|
|
808 |
}
|
|
809 |
else
|
|
810 |
if (g_strcmp0 (name, "IconName") == 0)
|
|
811 |
{
|
|
812 |
new_props->icon_name = null_or_string_from_variant (value);
|
|
813 |
if (g_strcmp0 (new_props->icon_name, item->current_props->icon_name) != 0)
|
|
814 |
{
|
|
815 |
new_props->update_icon = TRUE;
|
|
816 |
}
|
|
817 |
}
|
|
818 |
else
|
|
819 |
if (g_strcmp0 (name, "IconPixmap") == 0)
|
|
820 |
{
|
|
821 |
new_props->icon_surface = get_icon_surface (item, value, &new_props->icon_md5);
|
|
822 |
|
|
823 |
if (g_strcmp0 (new_props->icon_md5, item->current_props->icon_md5) != 0)
|
|
824 |
{
|
|
825 |
new_props->update_icon = TRUE;
|
|
826 |
}
|
|
827 |
}
|
|
828 |
else
|
|
829 |
if (g_strcmp0 (name, "AttentionIconName") == 0)
|
|
830 |
{
|
|
831 |
new_props->attention_icon_name = null_or_string_from_variant (value);
|
|
832 |
|
|
833 |
if (g_strcmp0 (new_props->attention_icon_name, item->current_props->attention_icon_name) != 0)
|
|
834 |
{
|
|
835 |
new_props->update_icon = TRUE;
|
|
836 |
}
|
|
837 |
}
|
|
838 |
else
|
|
839 |
if (g_strcmp0 (name, "AttentionIconPixmap") == 0)
|
|
840 |
{
|
|
841 |
new_props->attention_icon_surface = get_icon_surface (item, value, &new_props->attention_icon_md5);
|
|
842 |
|
|
843 |
if (g_strcmp0 (new_props->attention_icon_md5, item->current_props->attention_icon_md5) != 0)
|
|
844 |
{
|
|
845 |
new_props->update_icon = TRUE;
|
|
846 |
}
|
|
847 |
}
|
|
848 |
else
|
|
849 |
if (g_strcmp0 (name, "OverlayIconName") == 0)
|
|
850 |
{
|
|
851 |
new_props->overlay_icon_name = null_or_string_from_variant (value);
|
|
852 |
|
|
853 |
if (g_strcmp0 (new_props->overlay_icon_name, item->current_props->overlay_icon_name) != 0)
|
|
854 |
{
|
|
855 |
new_props->update_icon = TRUE;
|
|
856 |
}
|
|
857 |
}
|
|
858 |
else
|
|
859 |
if (g_strcmp0 (name, "OverlayIconPixmap") == 0)
|
|
860 |
{
|
|
861 |
new_props->overlay_icon_surface = get_icon_surface (item, value, &new_props->overlay_icon_md5);
|
|
862 |
|
|
863 |
if (g_strcmp0 (new_props->overlay_icon_md5, item->current_props->overlay_icon_md5) != 0)
|
|
864 |
{
|
|
865 |
new_props->update_icon = TRUE;
|
|
866 |
}
|
|
867 |
}
|
|
868 |
}
|
|
869 |
|
|
870 |
g_variant_iter_free (iter);
|
|
871 |
g_variant_unref (properties);
|
|
872 |
|
|
873 |
if (new_props->update_status)
|
|
874 |
{
|
|
875 |
update_status (item, new_props);
|
|
876 |
}
|
|
877 |
|
|
878 |
if (new_props->update_tooltip)
|
|
879 |
{
|
|
880 |
update_tooltip (item, new_props);
|
|
881 |
}
|
|
882 |
|
|
883 |
if (new_props->update_menu)
|
|
884 |
{
|
|
885 |
update_menu (item, new_props);
|
|
886 |
}
|
|
887 |
|
|
888 |
if (new_props->update_icon)
|
|
889 |
{
|
|
890 |
update_icon (item, new_props);
|
|
891 |
}
|
|
892 |
|
|
893 |
props_free (item->current_props);
|
|
894 |
item->current_props = new_props;
|
|
895 |
}
|
|
896 |
|
|
897 |
static gboolean
|
|
898 |
update_all_properties (gpointer data)
|
|
899 |
{
|
|
900 |
SnItem *item = SN_ITEM (data);
|
|
901 |
|
|
902 |
g_dbus_proxy_call (item->prop_proxy,
|
|
903 |
"GetAll",
|
|
904 |
g_variant_new ("(s)",
|
|
905 |
g_dbus_proxy_get_interface_name (item->sn_item_proxy)),
|
|
906 |
G_DBUS_CALL_FLAGS_NONE,
|
|
907 |
5 * 1000,
|
|
908 |
item->cancellable,
|
|
909 |
get_all_properties_callback,
|
|
910 |
item);
|
|
911 |
|
|
912 |
item->update_properties_timeout = 0;
|
|
913 |
|
|
914 |
return G_SOURCE_REMOVE;
|
|
915 |
}
|
|
916 |
|
|
917 |
static void
|
|
918 |
queue_update_properties (SnItem *item, gboolean force)
|
|
919 |
{
|
|
920 |
if (item->update_properties_timeout > 0)
|
|
921 |
{
|
|
922 |
g_source_remove (item->update_properties_timeout);
|
|
923 |
}
|
|
924 |
|
|
925 |
if (force)
|
|
926 |
{
|
|
927 |
props_free (item->current_props);
|
|
928 |
item->current_props = g_slice_new0 (SnItemPropertiesResult);
|
|
929 |
}
|
|
930 |
|
|
931 |
item->update_properties_timeout = g_timeout_add (10, G_SOURCE_FUNC (update_all_properties), item);
|
706 | 932 |
}
|
707 | 933 |
|
708 | 934 |
static void
|
|
721 | 947 |
|
722 | 948 |
if (g_strcmp0 (signal_name, "NewIcon") == 0 ||
|
723 | 949 |
g_strcmp0 (signal_name, "NewAttentionIcon") == 0 ||
|
724 | |
g_strcmp0 (signal_name, "NewOverlayIcon") == 0)
|
725 | |
{
|
726 | |
update_icon (item);
|
727 | |
}
|
728 | |
else
|
729 | |
if (g_strcmp0 (signal_name, "NewStatus") == 0)
|
730 | |
{
|
731 | |
update_status (item); // This will update_icon(item) also.
|
732 | |
}
|
733 | |
else
|
734 | |
if (g_strcmp0 (signal_name, "NewMenu") == 0)
|
735 | |
{
|
736 | |
update_menu (item);
|
737 | |
}
|
738 | |
else
|
739 | |
if (g_strcmp0 (signal_name, "NewToolTip") ||
|
740 | |
g_strcmp0 (signal_name, "NewTitle"))
|
741 | |
{
|
742 | |
update_tooltip (item);
|
|
950 |
g_strcmp0 (signal_name, "NewOverlayIcon") == 0 ||
|
|
951 |
g_strcmp0 (signal_name, "NewToolTip") == 0 ||
|
|
952 |
g_strcmp0 (signal_name, "NewTitle") == 0 ||
|
|
953 |
g_strcmp0 (signal_name, "NewStatus") == 0 ||
|
|
954 |
g_strcmp0 (signal_name, "NewMenu") == 0)
|
|
955 |
{
|
|
956 |
queue_update_properties (item, FALSE);
|
743 | 957 |
}
|
744 | 958 |
}
|
745 | 959 |
|
|
834 | 1048 |
return;
|
835 | 1049 |
}
|
836 | 1050 |
|
837 | |
update_icon (item);
|
838 | |
update_status (item);
|
839 | |
update_icon (item);
|
840 | |
update_tooltip (item);
|
|
1051 |
queue_update_properties (item, TRUE);
|
841 | 1052 |
}
|
842 | 1053 |
|
843 | 1054 |
static void
|
844 | 1055 |
assign_sortable_name (SnItem *item,
|
845 | |
XAppStatusIcon *status_icon)
|
846 | |
{
|
847 | |
gchar *init_name, *normalized, *sortable_name;
|
|
1056 |
const gchar *title)
|
|
1057 |
{
|
|
1058 |
gchar *init_name, *normalized;
|
|
1059 |
gchar *sortable_name, *old_sortable_name;
|
848 | 1060 |
|
849 | 1061 |
init_name = sn_item_interface_dup_id (SN_ITEM_INTERFACE (item->sn_item_proxy));
|
850 | 1062 |
|
851 | |
if (init_name == NULL)
|
852 | |
{
|
853 | |
init_name = get_string_property (item, "Title");
|
|
1063 |
if (init_name == NULL && title != NULL)
|
|
1064 |
{
|
|
1065 |
init_name = g_strdup (title);
|
|
1066 |
}
|
|
1067 |
else
|
|
1068 |
{
|
|
1069 |
init_name = g_strdup (g_dbus_proxy_get_name (G_DBUS_PROXY (item->sn_item_proxy)));
|
854 | 1070 |
}
|
855 | 1071 |
|
856 | 1072 |
normalized = g_utf8_normalize (init_name,
|
|
859 | 1075 |
|
860 | 1076 |
sortable_name = g_utf8_strdown (normalized, -1);
|
861 | 1077 |
|
862 | |
g_debug ("Sort name for %s is '%s'", g_dbus_proxy_get_name (G_DBUS_PROXY (item->sn_item_proxy)), sortable_name);
|
863 | |
xapp_status_icon_set_name (status_icon, sortable_name);
|
864 | |
|
865 | |
item->sortable_name = sortable_name;
|
866 | |
|
867 | 1078 |
g_free (init_name);
|
868 | 1079 |
g_free (normalized);
|
|
1080 |
|
|
1081 |
if (g_strcmp0 (sortable_name, item->sortable_name) == 0)
|
|
1082 |
{
|
|
1083 |
g_free (sortable_name);
|
|
1084 |
return;
|
|
1085 |
}
|
|
1086 |
|
|
1087 |
g_debug ("Sort name for '%s' is '%s'",
|
|
1088 |
g_dbus_proxy_get_name (G_DBUS_PROXY (item->sn_item_proxy)),
|
|
1089 |
sortable_name);
|
|
1090 |
|
|
1091 |
xapp_status_icon_set_name (item->status_icon, sortable_name);
|
|
1092 |
|
|
1093 |
old_sortable_name = item->sortable_name;
|
|
1094 |
item->sortable_name = sortable_name;
|
|
1095 |
g_free (old_sortable_name);
|
|
1096 |
|
|
1097 |
update_conditionals (item);
|
869 | 1098 |
}
|
870 | 1099 |
|
871 | 1100 |
static void
|
|
881 | 1110 |
|
882 | 1111 |
if (error != NULL)
|
883 | 1112 |
{
|
884 | |
g_printerr ("Could not get prop proxy: %s\n", error->message);
|
885 | |
g_error_free (error);
|
886 | |
return;
|
|
1113 |
if (!g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED))
|
|
1114 |
{
|
|
1115 |
g_critical ("Could not get property proxy for %s: %s\n",
|
|
1116 |
g_dbus_proxy_get_name (item->sn_item_proxy),
|
|
1117 |
error->message);
|
|
1118 |
g_error_free (error);
|
|
1119 |
return;
|
|
1120 |
}
|
887 | 1121 |
}
|
888 | 1122 |
|
889 | 1123 |
g_signal_connect (item->sn_item_proxy,
|
|
893 | 1127 |
|
894 | 1128 |
item->status_icon = xapp_status_icon_new ();
|
895 | 1129 |
|
896 | |
json = g_strdup_printf ("{ 'highlight-both-menus': %s }", item->is_ai ? "true" : "false");
|
|
1130 |
json = g_strdup_printf ("{ \"highlight-both-menus\": %s }", item->is_ai ? "true" : "false");
|
897 | 1131 |
xapp_status_icon_set_metadata (item->status_icon, json);
|
898 | 1132 |
g_free (json);
|
899 | 1133 |
|
|
903 | 1137 |
g_signal_connect (item->status_icon, "scroll-event", G_CALLBACK (xapp_icon_scroll), item);
|
904 | 1138 |
g_signal_connect (item->status_icon, "state-changed", G_CALLBACK (xapp_icon_state_changed), item);
|
905 | 1139 |
|
906 | |
assign_sortable_name (item, item->status_icon);
|
907 | |
|
908 | |
item->should_activate = should_activate (item);
|
909 | |
item->should_replace_tooltip = should_replace_tooltip (item);
|
910 | |
|
911 | |
update_status (item);
|
912 | |
update_menu (item);
|
913 | |
update_tooltip (item);
|
914 | |
update_icon (item);
|
|
1140 |
assign_sortable_name (item, NULL);
|
|
1141 |
update_conditionals (item);
|
|
1142 |
|
|
1143 |
queue_update_properties (item, TRUE);
|
915 | 1144 |
}
|
916 | 1145 |
|
917 | 1146 |
static void
|
|
923 | 1152 |
g_dbus_proxy_get_name (item->sn_item_proxy),
|
924 | 1153 |
g_dbus_proxy_get_object_path (item->sn_item_proxy),
|
925 | 1154 |
"org.freedesktop.DBus.Properties",
|
926 | |
NULL,
|
|
1155 |
item->cancellable,
|
927 | 1156 |
property_proxy_acquired,
|
928 | 1157 |
item);
|
929 | 1158 |
}
|
|
936 | 1165 |
|
937 | 1166 |
item->sn_item_proxy = sn_item_proxy;
|
938 | 1167 |
item->is_ai = is_ai;
|
|
1168 |
item->cancellable = g_cancellable_new ();
|
939 | 1169 |
|
940 | 1170 |
initialize_item (item);
|
941 | 1171 |
return item;
|
942 | 1172 |
}
|
943 | 1173 |
|
944 | |
void
|
945 | |
sn_item_update_menus (SnItem *item)
|
946 | |
{
|
947 | |
update_menu (item);
|
948 | |
}⏎
|