2
* Copyright (c) 2007-2009 Nick Schermer <nick@xfce.org>
4
* This program is free software; you can redistribute it and/or modify it
5
* under the terms of the GNU General Public License as published by the Free
6
* Software Foundation; either version 2 of the License, or (at your option)
9
* This program is distributed in the hope that it will be useful, but WITHOUT
10
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
14
* You should have received a copy of the GNU General Public License along with
15
* this program; if not, write to the Free Software Foundation, Inc., 59 Temple
16
* Place, Suite 330, Boston, MA 02111-1307 USA
29
#include <libxfce4panel/libxfce4panel.h>
30
#include <common/panel-private.h>
31
#include <common/panel-xfconf.h>
33
#include "systray-box.h"
34
#include "systray-socket.h"
36
#define BUTTON_SIZE (16)
38
#define OFFSCREEN (-9999)
39
#define IS_HORIZONTAL(box) ((box)->arrow_type == GTK_ARROW_LEFT \
40
|| (box)->arrow_type == GTK_ARROW_RIGHT)
44
static void systray_box_get_property (GObject *object,
48
static void systray_box_set_property (GObject *object,
52
static void systray_box_finalize (GObject *object);
53
static void systray_box_size_request (GtkWidget *widget,
54
GtkRequisition *requisition);
55
static void systray_box_size_allocate (GtkWidget *widget,
56
GtkAllocation *allocation);
57
static gboolean systray_box_expose_event (GtkWidget *widget,
58
GdkEventExpose *event);
59
static void systray_box_add (GtkContainer *container,
61
static void systray_box_remove (GtkContainer *container,
63
static void systray_box_forall (GtkContainer *container,
64
gboolean include_internals,
66
gpointer callback_data);
67
static GType systray_box_child_type (GtkContainer *container);
68
static void systray_box_names_collect_visible (gpointer key,
71
static void systray_box_names_collect_hidden (gpointer key,
74
static gboolean systray_box_names_remove (gpointer key,
77
static void systray_box_button_set_arrow (SystrayBox *box);
78
static gboolean systray_box_button_press_event (GtkWidget *widget,
79
GdkEventButton *event,
81
static void systray_box_button_clicked (GtkToggleButton *button,
83
static void systray_box_update_hidden (SystrayBox *box);
87
struct _SystrayBoxClass
89
GtkContainerClass __parent__;
94
GtkContainer __parent__;
96
/* all the icons packed in this box */
99
/* table with names, value contains an uint
100
* that represents the hidden bool */
106
/* position of the arrow button */
107
GtkArrowType arrow_type;
109
/* hidden childeren counter */
110
gint n_hidden_childeren;
112
/* whether hidden icons are visible */
113
guint show_hidden : 1;
118
/* guess size, this is a value used to reduce the tray flickering */
124
/* the child widget */
127
/* whether it could be hidden */
130
/* invisible icon because of invalid requisition */
133
/* the name of the applcation */
147
XFCE_PANEL_DEFINE_TYPE (SystrayBox, systray_box, GTK_TYPE_CONTAINER)
152
systray_box_class_init (SystrayBoxClass *klass)
154
GObjectClass *gobject_class;
155
GtkWidgetClass *gtkwidget_class;
156
GtkContainerClass *gtkcontainer_class;
158
gobject_class = G_OBJECT_CLASS (klass);
159
gobject_class->get_property = systray_box_get_property;
160
gobject_class->set_property = systray_box_set_property;
161
gobject_class->finalize = systray_box_finalize;
163
gtkwidget_class = GTK_WIDGET_CLASS (klass);
164
gtkwidget_class->size_request = systray_box_size_request;
165
gtkwidget_class->size_allocate = systray_box_size_allocate;
166
gtkwidget_class->expose_event = systray_box_expose_event;
168
gtkcontainer_class = GTK_CONTAINER_CLASS (klass);
169
gtkcontainer_class->add = systray_box_add;
170
gtkcontainer_class->remove = systray_box_remove;
171
gtkcontainer_class->forall = systray_box_forall;
172
gtkcontainer_class->child_type = systray_box_child_type;
174
g_object_class_install_property (gobject_class,
176
g_param_spec_boxed ("names-hidden",
178
PANEL_PROPERTIES_TYPE_VALUE_ARRAY,
179
EXO_PARAM_READWRITE));
181
g_object_class_install_property (gobject_class,
183
g_param_spec_boxed ("names-visible",
185
PANEL_PROPERTIES_TYPE_VALUE_ARRAY,
186
EXO_PARAM_READWRITE));
192
systray_box_init (SystrayBox *box)
194
GTK_WIDGET_SET_FLAGS (box, GTK_NO_WINDOW);
196
box->childeren = NULL;
199
box->n_hidden_childeren = 0;
200
box->arrow_type = GTK_ARROW_LEFT;
201
box->show_hidden = FALSE;
202
box->guess_size = 128;
203
box->names = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL);
205
/* create arrow button */
206
box->button = xfce_arrow_button_new (box->arrow_type);
207
GTK_WIDGET_UNSET_FLAGS (box->button, GTK_CAN_DEFAULT | GTK_CAN_FOCUS);
208
gtk_button_set_focus_on_click (GTK_BUTTON (box->button), FALSE);
209
g_signal_connect (G_OBJECT (box->button), "clicked",
210
G_CALLBACK (systray_box_button_clicked), box);
211
g_signal_connect (G_OBJECT (box->button), "button-press-event",
212
G_CALLBACK (systray_box_button_press_event), box);
213
gtk_widget_set_parent (box->button, GTK_WIDGET (box));
219
systray_box_get_property (GObject *object,
224
SystrayBox *box = XFCE_SYSTRAY_BOX (object);
229
case PROP_NAMES_VISIBLE:
230
array = g_ptr_array_new ();
231
g_hash_table_foreach (box->names, systray_box_names_collect_visible, array);
232
g_value_set_boxed (value, array);
233
xfconf_array_free (array);
236
case PROP_NAMES_HIDDEN:
237
array = g_ptr_array_new ();
238
g_hash_table_foreach (box->names, systray_box_names_collect_hidden, array);
239
g_value_set_boxed (value, array);
240
xfconf_array_free (array);
244
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
252
systray_box_set_property (GObject *object,
257
SystrayBox *box = XFCE_SYSTRAY_BOX (object);
262
gboolean hidden = TRUE;
266
case PROP_NAMES_VISIBLE:
270
case PROP_NAMES_HIDDEN:
271
/* remove old names with this state */
272
g_hash_table_foreach_remove (box->names,
273
systray_box_names_remove,
274
GUINT_TO_POINTER (hidden));
277
array = g_value_get_boxed (value);
278
if (G_LIKELY (array != NULL))
280
for (i = 0; i < array->len; i++)
282
tmp = g_ptr_array_index (array, i);
283
panel_assert (G_VALUE_HOLDS_STRING (tmp));
284
name = g_value_dup_string (tmp);
285
g_hash_table_replace (box->names, name, GUINT_TO_POINTER (hidden));
289
/* update icons in the box */
290
systray_box_update_hidden (box);
294
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
302
systray_box_finalize (GObject *object)
304
SystrayBox *box = XFCE_SYSTRAY_BOX (object);
306
/* check if we're leaking */
307
if (G_UNLIKELY (box->childeren != NULL))
309
/* free the child list */
310
g_slist_free (box->childeren);
311
g_debug ("Leaking memory, not all children have been removed");
314
/* destroy the hash table */
315
g_hash_table_destroy (box->names);
317
G_OBJECT_CLASS (systray_box_parent_class)->finalize (object);
323
systray_box_size_request (GtkWidget *widget,
324
GtkRequisition *requisition)
326
SystrayBox *box = XFCE_SYSTRAY_BOX (widget);
328
SystrayBoxChild *child_info;
330
gint child_size = -1;
331
GtkRequisition child_req;
332
gint n_visible_childeren = 0;
334
gint guess_size, icon_size;
336
panel_return_if_fail (XFCE_IS_SYSTRAY_BOX (widget));
337
panel_return_if_fail (requisition != NULL);
339
/* get the guess size */
340
guess_size = box->guess_size - (SPACING * (box->rows - 1));
341
guess_size /= box->rows;
343
/* check if we need to hide or show any childeren */
344
for (li = box->childeren; li != NULL; li = li->next)
346
child_info = li->data;
348
/* get the icons size request */
349
gtk_widget_size_request (child_info->widget, &child_req);
351
if (G_UNLIKELY (child_req.width == 1 || child_req.height == 1))
353
/* icons that return a 1 by 1 requisition supposed to be hidden */
354
if (!child_info->invalid)
356
/* this icon should not be visible */
357
child_info->invalid = TRUE;
359
/* decrease the hidden counter if needed */
360
if (child_info->auto_hide)
361
box->n_hidden_childeren--;
366
/* restore icon if it was previously invisible */
367
if (G_UNLIKELY (child_info->invalid))
370
child_info->invalid = FALSE;
373
if (child_info->auto_hide)
374
box->n_hidden_childeren++;
377
/* count the number of visible childeren */
378
if (!child_info->auto_hide || box->show_hidden)
380
/* get the icon size */
381
icon_size = MIN (guess_size, MAX (child_req.width, child_req.height));
383
/* pick largest icon */
384
if (G_UNLIKELY (child_size == -1))
385
child_size = icon_size;
387
child_size = MAX (child_size, icon_size);
389
/* increase number of visible childeren */
390
n_visible_childeren++;
395
/* number of columns */
396
n_columns = n_visible_childeren / box->rows;
397
if (n_visible_childeren > (n_columns * box->rows))
400
/* set the width and height needed for the icons */
401
if (n_visible_childeren > 0)
403
requisition->width = ((child_size + SPACING) * n_columns) - SPACING;
404
requisition->height = ((child_size + SPACING) * box->rows) - SPACING;
408
requisition->width = requisition->height = 0;
411
/* add the button size if there are hidden icons */
412
if (box->n_hidden_childeren > 0)
414
/* add the button size */
415
requisition->width += BUTTON_SIZE;
418
if (n_visible_childeren > 0)
419
requisition->width += SPACING;
422
/* swap the sizes if the orientation is vertical */
423
if (!IS_HORIZONTAL (box))
425
swap = requisition->width;
426
requisition->width = requisition->height;
427
requisition->height = swap;
430
/* add container border */
431
requisition->width += GTK_CONTAINER (widget)->border_width * 2;
432
requisition->height += GTK_CONTAINER (widget)->border_width * 2;
438
systray_box_size_allocate (GtkWidget *widget,
439
GtkAllocation *allocation)
441
SystrayBox *box = XFCE_SYSTRAY_BOX (widget);
442
SystrayBoxChild *child_info;
449
GtkAllocation child_allocation;
453
panel_return_if_fail (XFCE_IS_SYSTRAY_BOX (widget));
454
panel_return_if_fail (allocation != NULL);
456
/* set widget allocation */
457
widget->allocation = *allocation;
459
n_children = g_slist_length (box->childeren);
463
/* get root coordinates */
464
x = allocation->x + GTK_CONTAINER (widget)->border_width;
465
y = allocation->y + GTK_CONTAINER (widget)->border_width;
468
width = allocation->width - 2 * GTK_CONTAINER (widget)->border_width;
469
height = allocation->height - 2 * GTK_CONTAINER (widget)->border_width;
474
child_size = IS_HORIZONTAL (box) ? width : height;
475
if (box->n_hidden_childeren > 0)
476
child_size -= BUTTON_SIZE + SPACING;
477
n = n_children - (box->show_hidden ? 0 : box->n_hidden_childeren);
478
child_size -= SPACING * MAX (n - 1, 0);
482
if (IS_HORIZONTAL (box))
483
y += MAX (height - child_size, 0) / 2;
485
x += MAX (width - child_size, 0) / 2;
489
child_size = IS_HORIZONTAL (box) ? height : width;
490
child_size -= SPACING * (box->rows - 1);
491
child_size /= box->rows;
494
/* don't allocate zero width icon */
498
/* position arrow button */
499
if (box->n_hidden_childeren > 0)
501
/* initialize allocation */
502
child_allocation.x = allocation->x + GTK_CONTAINER (widget)->border_width;
503
child_allocation.y = allocation->y + GTK_CONTAINER (widget)->border_width;
505
/* set the width and height */
506
if (IS_HORIZONTAL (box))
508
child_allocation.width = BUTTON_SIZE;
509
child_allocation.height = height;
513
child_allocation.width = width;
514
child_allocation.height = BUTTON_SIZE;
517
/* position the button on the other side of the box */
518
if (box->arrow_type == GTK_ARROW_RIGHT)
519
child_allocation.x += width - child_allocation.width;
520
else if (box->arrow_type == GTK_ARROW_DOWN)
521
child_allocation.y += height - child_allocation.height;
523
/* set the offset for the icons */
524
offset = BUTTON_SIZE + SPACING;
526
/* position the arrow button */
527
gtk_widget_size_allocate (box->button, &child_allocation);
529
/* show button if not already visible */
530
if (!GTK_WIDGET_VISIBLE (box->button))
531
gtk_widget_show (box->button);
533
else if (GTK_WIDGET_VISIBLE (box->button))
535
/* hide the button */
536
gtk_widget_hide (box->button);
540
for (li = box->childeren, n = 0; li != NULL; li = li->next)
542
child_info = li->data;
544
if (child_info->invalid || (child_info->auto_hide && !box->show_hidden))
546
/* put icons offscreen */
547
child_allocation.x = child_allocation.y = OFFSCREEN;
551
/* set coordinates */
552
child_allocation.x = (child_size + SPACING) * (n / box->rows) + offset;
553
child_allocation.y = (child_size + SPACING) * (n % box->rows);
555
/* increase item counter */
558
/* swap coordinates on a vertical panel */
559
if (!IS_HORIZONTAL (box))
561
swap = child_allocation.x;
562
child_allocation.x = child_allocation.y;
563
child_allocation.y = swap;
566
/* invert the icon order if the arrow button position is right or down */
567
if (box->arrow_type == GTK_ARROW_RIGHT)
568
child_allocation.x = width - child_allocation.x - child_size;
569
else if (box->arrow_type == GTK_ARROW_DOWN)
570
child_allocation.y = height - child_allocation.y - child_size;
573
child_allocation.x += x;
574
child_allocation.y += y;
577
/* set child width and height */
578
child_allocation.width = child_size;
579
child_allocation.height = child_size;
581
/* allocate widget size */
582
gtk_widget_size_allocate (child_info->widget, &child_allocation);
589
systray_box_expose_event (GtkWidget *widget,
590
GdkEventExpose *event)
592
SystrayBox *box = XFCE_SYSTRAY_BOX (widget);
594
SystrayBoxChild *child_info;
598
result = GTK_WIDGET_CLASS (systray_box_parent_class)->expose_event (widget, event);
600
if (gtk_widget_is_composited (widget))
602
cr = gdk_cairo_create (widget->window);
603
gdk_cairo_region (cr, event->region);
606
for (li = box->childeren; li != NULL; li = li->next)
608
child_info = li->data;
610
/* skip invisible or not composited children */
611
if (child_info->invalid
612
|| (child_info->auto_hide && !box->show_hidden)
613
|| !systray_socket_is_composited (XFCE_SYSTRAY_SOCKET (child_info->widget)))
616
/* paint the child */
617
gdk_cairo_set_source_pixmap (cr, child_info->widget->window,
618
child_info->widget->allocation.x,
619
child_info->widget->allocation.y);
632
systray_box_add (GtkContainer *container,
635
SystrayBox *box = XFCE_SYSTRAY_BOX (container);
637
panel_return_if_fail (XFCE_IS_SYSTRAY_BOX (box));
640
systray_box_add_with_name (box, child, NULL);
646
systray_box_remove (GtkContainer *container,
649
SystrayBox *box = XFCE_SYSTRAY_BOX (container);
650
SystrayBoxChild *child_info;
651
gboolean need_resize;
654
/* search the child */
655
for (li = box->childeren; li != NULL; li = li->next)
657
child_info = li->data;
659
if (child_info->widget == child)
661
/* whether the need to redraw afterwards */
662
need_resize = !child_info->auto_hide;
664
/* update hidden counter */
665
if (child_info->auto_hide && !child_info->invalid)
666
box->n_hidden_childeren--;
668
/* remove from list */
669
box->childeren = g_slist_remove_link (box->childeren, li);
672
g_free (child_info->name);
674
/* free child info */
675
g_slice_free (SystrayBoxChild, child_info);
677
/* unparent the widget */
678
gtk_widget_unparent (child);
680
/* resize when the child was visible */
682
gtk_widget_queue_resize (GTK_WIDGET (container));
692
systray_box_forall (GtkContainer *container,
693
gboolean include_internals,
694
GtkCallback callback,
695
gpointer callback_data)
697
SystrayBox *box = XFCE_SYSTRAY_BOX (container);
698
SystrayBoxChild *child_info;
702
(*callback) (GTK_WIDGET (box->button), callback_data);
704
/* run callback for all childeren */
705
for (li = box->childeren; li != NULL; li = li->next)
707
child_info = li->data;
709
(*callback) (GTK_WIDGET (child_info->widget), callback_data);
716
systray_box_child_type (GtkContainer *container)
719
return GTK_TYPE_WIDGET;
725
systray_box_names_collect (GPtrArray *array,
730
tmp = g_new0 (GValue, 1);
731
g_value_init (tmp, G_TYPE_STRING);
732
g_value_set_string (tmp, name);
733
g_ptr_array_add (array, tmp);
739
systray_box_names_collect_visible (gpointer key,
743
/* add all the visible names */
744
if (!GPOINTER_TO_UINT (value))
745
systray_box_names_collect (user_data, key);
751
systray_box_names_collect_hidden (gpointer key,
755
/* add all the hidden names */
756
if (GPOINTER_TO_UINT (value))
757
systray_box_names_collect (user_data, key);
763
systray_box_names_remove (gpointer key,
767
return GPOINTER_TO_UINT (value) == GPOINTER_TO_UINT (user_data);
773
systray_box_button_set_arrow (SystrayBox *box)
775
GtkArrowType arrow_type;
778
arrow_type = box->arrow_type;
780
/* invert the arrow direction when the button is toggled */
781
if (box->show_hidden)
783
if (IS_HORIZONTAL (box))
784
arrow_type = (arrow_type == GTK_ARROW_LEFT ? GTK_ARROW_RIGHT : GTK_ARROW_LEFT);
786
arrow_type = (arrow_type == GTK_ARROW_UP ? GTK_ARROW_DOWN : GTK_ARROW_UP);
789
/* set the arrow type */
790
xfce_arrow_button_set_arrow_type (XFCE_ARROW_BUTTON (box->button), arrow_type);
796
systray_box_button_press_event (GtkWidget *widget,
797
GdkEventButton *event,
800
/* send the event to the box for the panel menu */
801
gtk_widget_event (box, (GdkEvent *) event);
809
systray_box_button_clicked (GtkToggleButton *button,
812
/* whether to show hidden icons */
813
box->show_hidden = gtk_toggle_button_get_active (button);
815
/* update the arrow */
816
systray_box_button_set_arrow (box);
819
gtk_widget_queue_resize (GTK_WIDGET (box));
825
systray_box_compare_function (gconstpointer a,
828
const SystrayBoxChild *child_a = a;
829
const SystrayBoxChild *child_b = b;
831
/* sort hidden icons before visible ones */
832
if (child_a->auto_hide != child_b->auto_hide)
833
return (child_a->auto_hide ? -1 : 1);
835
/* put icons without name after the hidden icons */
836
if (exo_str_is_empty (child_a->name) || exo_str_is_empty (child_b->name))
838
if (!exo_str_is_empty (child_a->name) == !exo_str_is_empty (child_b->name))
841
return exo_str_is_empty (child_a->name) ? -1 : 1;
845
return strcmp (child_a->name, child_b->name);
851
systray_box_update_hidden (SystrayBox *box)
853
SystrayBoxChild *child_info;
855
gint n_hidden_childeren;
857
panel_return_if_fail (XFCE_IS_SYSTRAY_BOX (box));
860
n_hidden_childeren = 0;
862
/* update the icons */
863
for (li = box->childeren; li != NULL; li = li->next)
865
child_info = li->data;
867
/* update the hidden state */
868
child_info->auto_hide = systray_box_name_get_hidden (box, child_info->name);
870
/* increase counter if needed */
871
if (child_info->auto_hide && !child_info->invalid)
872
n_hidden_childeren++;
875
if (box->n_hidden_childeren != n_hidden_childeren)
878
box->n_hidden_childeren = n_hidden_childeren;
880
/* sort the list again */
881
box->childeren = g_slist_sort (box->childeren,
882
systray_box_compare_function);
885
gtk_widget_queue_resize (GTK_WIDGET (box));
892
systray_box_new (void)
894
return g_object_new (XFCE_TYPE_SYSTRAY_BOX, NULL);
900
systray_box_set_guess_size (SystrayBox *box,
903
panel_return_if_fail (XFCE_IS_SYSTRAY_BOX (box));
905
/* set the systray guess size */
906
box->guess_size = guess_size;
912
systray_box_set_arrow_type (SystrayBox *box,
913
GtkArrowType arrow_type)
915
panel_return_if_fail (XFCE_IS_SYSTRAY_BOX (box));
917
if (G_LIKELY (arrow_type != box->arrow_type))
919
/* set new setting */
920
box->arrow_type = arrow_type;
922
/* update button arrow */
923
systray_box_button_set_arrow (box);
926
if (box->childeren != NULL)
927
gtk_widget_queue_resize (GTK_WIDGET (box));
934
systray_box_set_rows (SystrayBox *box,
937
panel_return_if_fail (XFCE_IS_SYSTRAY_BOX (box));
939
if (G_LIKELY (rows != box->rows))
941
/* set new setting */
942
box->rows = MAX (1, rows);
945
if (box->childeren != NULL)
946
gtk_widget_queue_resize (GTK_WIDGET (box));
953
systray_box_get_rows (SystrayBox *box)
955
panel_return_val_if_fail (XFCE_IS_SYSTRAY_BOX (box), 1);
963
systray_box_add_with_name (SystrayBox *box,
967
SystrayBoxChild *child_info;
969
panel_return_if_fail (XFCE_IS_SYSTRAY_BOX (box));
970
panel_return_if_fail (GTK_IS_WIDGET (child));
971
panel_return_if_fail (child->parent == NULL);
972
panel_return_if_fail (name == NULL || g_utf8_validate (name, -1, NULL));
974
/* create child info */
975
child_info = g_slice_new (SystrayBoxChild);
976
child_info->widget = child;
977
child_info->invalid = FALSE;
978
child_info->name = g_strdup (name);
979
child_info->auto_hide = systray_box_name_get_hidden (box, child_info->name);
981
/* update hidden counter */
982
if (child_info->auto_hide)
983
box->n_hidden_childeren++;
986
box->childeren = g_slist_insert_sorted (box->childeren, child_info,
987
systray_box_compare_function);
989
/* set parent widget */
990
gtk_widget_set_parent (child, GTK_WIDGET (box));
996
systray_box_name_add (SystrayBox *box,
1000
panel_return_if_fail (XFCE_IS_SYSTRAY_BOX (box));
1001
panel_return_if_fail (!exo_str_is_empty (name));
1003
/* insert the application */
1004
g_hash_table_insert (box->names, g_strdup (name),
1005
GUINT_TO_POINTER (hidden ? 1 : 0));
1007
g_object_notify (G_OBJECT (box), hidden ? "names-hidden"
1014
systray_box_name_set_hidden (SystrayBox *box,
1018
panel_return_if_fail (XFCE_IS_SYSTRAY_BOX (box));
1019
panel_return_if_fail (!exo_str_is_empty (name));
1021
/* replace the old name */
1022
g_hash_table_replace (box->names, g_strdup (name),
1023
GUINT_TO_POINTER (hidden ? 1 : 0));
1025
/* save new values */
1026
g_object_notify (G_OBJECT (box), "names-hidden");
1027
g_object_notify (G_OBJECT (box), "names-visible");
1029
/* update the box */
1030
systray_box_update_hidden (box);
1036
systray_box_name_get_hidden (SystrayBox *box,
1041
/* do not hide icons without name */
1042
if (G_UNLIKELY (name == NULL))
1045
/* lookup the name in the table */
1046
p = g_hash_table_lookup (box->names, name);
1047
if (G_UNLIKELY (p == NULL))
1050
systray_box_name_add (box, name, FALSE);
1052
/* do not hide the icon */
1057
return (GPOINTER_TO_UINT (p) == 1 ? TRUE : FALSE);
1064
systray_box_name_list (SystrayBox *box)
1068
/* get the hash table keys */
1069
keys = g_hash_table_get_keys (box->names);
1072
keys = g_list_sort (keys, (GCompareFunc) strcmp);
1080
systray_box_name_clear (SystrayBox *box)
1082
/* remove all the entries from the list */
1083
g_hash_table_remove_all (box->names);
1085
g_object_notify (G_OBJECT (box), "names-hidden");
1086
g_object_notify (G_OBJECT (box), "names-visible");
1088
systray_box_update_hidden (box);