From 471fd54c34c152909a13c2ac093d7205da0d1935 Mon Sep 17 00:00:00 2001 From: Viktor Odintsev Date: Fri, 23 Jun 2017 09:01:00 +0300 Subject: [PATCH] Allow to order icons in systray --- plugins/systray/systray-box.c | 51 +++++- plugins/systray/systray-box.h | 3 +- plugins/systray/systray-dialog.glade | 139 +++++++++++---- plugins/systray/systray.c | 319 ++++++++++++++++++++++++++--------- 4 files changed, 387 insertions(+), 125 deletions(-) diff --git a/plugins/systray/systray-box.c b/plugins/systray/systray-box.c index 88c4a141..45d28241 100644 --- a/plugins/systray/systray-box.c +++ b/plugins/systray/systray-box.c @@ -69,7 +69,8 @@ static void systray_box_forall (GtkContainer *container, gpointer callback_data); static GType systray_box_child_type (GtkContainer *container); static gint systray_box_compare_function (gconstpointer a, - gconstpointer b); + gconstpointer b, + gpointer user_data); @@ -91,6 +92,9 @@ struct _SystrayBox /* all the icons packed in this box */ GSList *childeren; + /* table of item indexes */ + GHashTable *names_ordered; + /* orientation of the box */ guint horizontal : 1; @@ -152,6 +156,7 @@ systray_box_init (SystrayBox *box) gtk_widget_set_has_window (GTK_WIDGET (box), FALSE); box->childeren = NULL; + box->names_ordered = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL); box->size_max = SIZE_MAX_DEFAULT; box->size_alloc = SIZE_MAX_DEFAULT; box->n_hidden_childeren = 0; @@ -189,6 +194,8 @@ systray_box_finalize (GObject *object) { SystrayBox *box = XFCE_SYSTRAY_BOX (object); + g_hash_table_destroy (box->names_ordered); + /* check if we're leaking */ if (G_UNLIKELY (box->childeren != NULL)) { @@ -625,8 +632,9 @@ systray_box_add (GtkContainer *container, panel_return_if_fail (GTK_IS_WIDGET (child)); panel_return_if_fail (gtk_widget_get_parent (child) == NULL); - box->childeren = g_slist_insert_sorted (box->childeren, child, - systray_box_compare_function); + box->childeren = g_slist_insert_sorted_with_data (box->childeren, child, + systray_box_compare_function, + box); gtk_widget_set_parent (child, GTK_WIDGET (box)); @@ -689,10 +697,14 @@ systray_box_child_type (GtkContainer *container) static gint systray_box_compare_function (gconstpointer a, - gconstpointer b) + gconstpointer b, + gpointer user_data) { + SystrayBox *box = user_data; const gchar *name_a, *name_b; + gint index_a = -1, index_b = -1; gboolean hidden_a, hidden_b; + gpointer value; /* sort hidden icons before visible ones */ hidden_a = systray_socket_get_hidden (XFCE_SYSTRAY_SOCKET (a)); @@ -700,10 +712,23 @@ systray_box_compare_function (gconstpointer a, if (hidden_a != hidden_b) return hidden_a ? 1 : -1; - /* sort icons by name */ name_a = systray_socket_get_name (XFCE_SYSTRAY_SOCKET (a)); name_b = systray_socket_get_name (XFCE_SYSTRAY_SOCKET (b)); + if (g_hash_table_lookup_extended (box->names_ordered, name_a, NULL, &value)) + index_a = GPOINTER_TO_INT (value); + if (g_hash_table_lookup_extended (box->names_ordered, name_b, NULL, &value)) + index_b = GPOINTER_TO_INT (value); + + /* sort ordered icons before unordered ones */ + if ((index_a >= 0) != (index_b >= 0)) + return index_a >= 0 ? 1 : -1; + + /* sort ordered icons by index */ + if (index_a >= 0 && index_b >= 0) + return index_a - index_b; + + /* sort unordered icons by name */ #if GLIB_CHECK_VERSION (2, 16, 0) return g_strcmp0 (name_a, name_b); #else @@ -820,12 +845,22 @@ systray_box_get_show_hidden (SystrayBox *box) void -systray_box_update (SystrayBox *box) +systray_box_update (SystrayBox *box, + GSList *names_ordered) { + GSList *li; + gint i; + panel_return_if_fail (XFCE_IS_SYSTRAY_BOX (box)); - box->childeren = g_slist_sort (box->childeren, - systray_box_compare_function); + g_hash_table_remove_all (box->names_ordered); + + for (li = names_ordered, i = 0; li != NULL; li = li->next, i++) + g_hash_table_replace (box->names_ordered, g_strdup (li->data), GINT_TO_POINTER (i)); + + box->childeren = g_slist_sort_with_data (box->childeren, + systray_box_compare_function, + box); /* update the box, so we update the has-hidden property */ gtk_widget_queue_resize (GTK_WIDGET (box)); diff --git a/plugins/systray/systray-box.h b/plugins/systray/systray-box.h index d396344e..c640d768 100644 --- a/plugins/systray/systray-box.h +++ b/plugins/systray/systray-box.h @@ -56,6 +56,7 @@ void systray_box_set_show_hidden (SystrayBox *box, gboolean systray_box_get_show_hidden (SystrayBox *box); -void systray_box_update (SystrayBox *box); +void systray_box_update (SystrayBox *box, + GSList *names_ordered); #endif /* !__SYSTRAY_BOX_H__ */ diff --git a/plugins/systray/systray-dialog.glade b/plugins/systray/systray-dialog.glade index 05854a22..4a615b8d 100644 --- a/plugins/systray/systray-dialog.glade +++ b/plugins/systray/systray-dialog.glade @@ -30,8 +30,8 @@ False Notification Area - 325 - 425 + 400 + 500 gtk-properties normal @@ -202,63 +202,132 @@ vertical 6 - + True - True - True - in + False + 6 + horizontal + 6 - + True True - applications-store - False - True - False - - - + True + in - - 24 + + True + True + applications-store + False + True + False + + + - - - 0 - + + 24 + + + + 0 + + + + + + + Application + True + + + + 1 + + + + + + + Hidden + + + + 2 + + + + + + True + True + 0 + + + + + True + False + vertical + 6 - - Application - True + + True + False + True + True + Move currently selected item up by one row - - - 1 - + + True + False + gtk-go-up + + + False + True + 0 + - - Hidden + + True + False + True + True + Move currently selected item down by one row - - - 2 - + + True + False + gtk-go-down + + + False + True + 1 + + + False + True + 1 + - True + False True - 0 + 1 diff --git a/plugins/systray/systray.c b/plugins/systray/systray.c index 4d1ade47..37cdcc39 100644 --- a/plugins/systray/systray.c +++ b/plugins/systray/systray.c @@ -60,15 +60,11 @@ static void systray_plugin_box_draw (GtkWidget static void systray_plugin_button_toggled (GtkWidget *button, SystrayPlugin *plugin); static void systray_plugin_button_set_arrow (SystrayPlugin *plugin); -static void systray_plugin_names_collect_visible (gpointer key, - gpointer value, +static void systray_plugin_names_collect_ordered (gpointer data, gpointer user_data); static void systray_plugin_names_collect_hidden (gpointer key, gpointer value, gpointer user_data); -static gboolean systray_plugin_names_remove (gpointer key, - gpointer value, - gpointer user_data); static void systray_plugin_names_update (SystrayPlugin *plugin); static gboolean systray_plugin_names_get_hidden (SystrayPlugin *plugin, const gchar *name); @@ -80,14 +76,19 @@ static void systray_plugin_icon_removed (SystrayManager SystrayPlugin *plugin); static void systray_plugin_lost_selection (SystrayManager *manager, SystrayPlugin *plugin); -static void systray_plugin_dialog_add_application_names (gpointer key, - gpointer value, +static void systray_plugin_dialog_add_application_names (gpointer data, gpointer user_data); static void systray_plugin_dialog_hidden_toggled (GtkCellRendererToggle *renderer, const gchar *path_string, SystrayPlugin *plugin); +static void systray_plugin_dialog_selection_changed (GtkTreeSelection *selection, + SystrayPlugin *plugin); +static void systray_plugin_dialog_item_move_clicked (GtkWidget *button, + SystrayPlugin *plugin); static void systray_plugin_dialog_clear_clicked (GtkWidget *button, SystrayPlugin *plugin); +static void systray_plugin_dialog_cleanup (SystrayPlugin *plugin, + GtkBuilder *builder); @@ -113,7 +114,10 @@ struct _SystrayPlugin /* settings */ guint show_frame : 1; - GHashTable *names; + GSList *names_ordered; + GHashTable *names_hidden; + + GtkBuilder *configure_builder; }; enum @@ -121,8 +125,8 @@ enum PROP_0, PROP_SIZE_MAX, PROP_SHOW_FRAME, - PROP_NAMES_HIDDEN, - PROP_NAMES_VISIBLE + PROP_NAMES_ORDERED, + PROP_NAMES_HIDDEN }; enum @@ -192,15 +196,15 @@ systray_plugin_class_init (SystrayPluginClass *klass) G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); g_object_class_install_property (gobject_class, - PROP_NAMES_HIDDEN, - g_param_spec_boxed ("names-hidden", + PROP_NAMES_ORDERED, + g_param_spec_boxed ("names-ordered", NULL, NULL, PANEL_PROPERTIES_TYPE_VALUE_ARRAY, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); g_object_class_install_property (gobject_class, - PROP_NAMES_VISIBLE, - g_param_spec_boxed ("names-visible", + PROP_NAMES_HIDDEN, + g_param_spec_boxed ("names-hidden", NULL, NULL, PANEL_PROPERTIES_TYPE_VALUE_ARRAY, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); @@ -216,7 +220,8 @@ systray_plugin_init (SystrayPlugin *plugin) plugin->manager = NULL; plugin->show_frame = TRUE; plugin->idle_startup = 0; - plugin->names = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL); + plugin->names_ordered = NULL; + plugin->names_hidden = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL); plugin->frame = gtk_frame_new (NULL); gtk_container_add (GTK_CONTAINER (plugin), plugin->frame); @@ -273,16 +278,16 @@ systray_plugin_get_property (GObject *object, g_value_set_boolean (value, plugin->show_frame); break; - case PROP_NAMES_VISIBLE: + case PROP_NAMES_ORDERED: array = g_ptr_array_new (); - g_hash_table_foreach (plugin->names, systray_plugin_names_collect_visible, array); + g_slist_foreach (plugin->names_ordered, systray_plugin_names_collect_ordered, array); g_value_set_boxed (value, array); xfconf_array_free (array); break; case PROP_NAMES_HIDDEN: array = g_ptr_array_new (); - g_hash_table_foreach (plugin->names, systray_plugin_names_collect_hidden, array); + g_hash_table_foreach (plugin->names_hidden, systray_plugin_names_collect_hidden, array); g_value_set_boxed (value, array); xfconf_array_free (array); break; @@ -303,7 +308,6 @@ systray_plugin_set_property (GObject *object, { SystrayPlugin *plugin = XFCE_SYSTRAY_PLUGIN (object); gboolean show_frame; - gboolean hidden = TRUE; GPtrArray *array; const GValue *tmp; gchar *name; @@ -336,15 +340,31 @@ systray_plugin_set_property (GObject *object, } break; - case PROP_NAMES_VISIBLE: - hidden = FALSE; - /* fall-though */ + case PROP_NAMES_ORDERED: + g_slist_free_full (plugin->names_ordered, g_free); + plugin->names_ordered = NULL; + + /* add new values */ + array = g_value_get_boxed (value); + if (G_LIKELY (array != NULL)) + { + for (i = 0; i < array->len; i++) + { + tmp = g_ptr_array_index (array, i); + panel_assert (G_VALUE_HOLDS_STRING (tmp)); + name = g_value_dup_string (tmp); + plugin->names_ordered = g_slist_prepend (plugin->names_ordered, name); + } + + plugin->names_ordered = g_slist_reverse (plugin->names_ordered); + } + + /* update icons in the box */ + systray_plugin_names_update (plugin); + break; case PROP_NAMES_HIDDEN: - /* remove old names with this state */ - g_hash_table_foreach_remove (plugin->names, - systray_plugin_names_remove, - GUINT_TO_POINTER (hidden)); + g_hash_table_remove_all (plugin->names_hidden); /* add new values */ array = g_value_get_boxed (value); @@ -355,7 +375,7 @@ systray_plugin_set_property (GObject *object, tmp = g_ptr_array_index (array, i); panel_assert (G_VALUE_HOLDS_STRING (tmp)); name = g_value_dup_string (tmp); - g_hash_table_replace (plugin->names, name, GUINT_TO_POINTER (hidden)); + g_hash_table_replace (plugin->names_hidden, name, NULL); } } @@ -452,7 +472,7 @@ systray_plugin_construct (XfcePanelPlugin *panel_plugin) { { "size-max", G_TYPE_UINT }, { "show-frame", G_TYPE_BOOLEAN }, - { "names-visible", PANEL_PROPERTIES_TYPE_VALUE_ARRAY }, + { "names-ordered", PANEL_PROPERTIES_TYPE_VALUE_ARRAY }, { "names-hidden", PANEL_PROPERTIES_TYPE_VALUE_ARRAY }, { NULL } }; @@ -488,7 +508,8 @@ systray_plugin_free_data (XfcePanelPlugin *panel_plugin) g_signal_handlers_disconnect_by_func (G_OBJECT (plugin), systray_plugin_screen_changed, NULL); - g_hash_table_destroy (plugin->names); + g_slist_free_full (plugin->names_ordered, g_free); + g_hash_table_destroy (plugin->names_hidden); if (G_LIKELY (plugin->manager != NULL)) { @@ -555,9 +576,11 @@ systray_plugin_size_changed (XfcePanelPlugin *panel_plugin, static void systray_plugin_configure_plugin (XfcePanelPlugin *panel_plugin) { - SystrayPlugin *plugin = XFCE_SYSTRAY_PLUGIN (panel_plugin); - GtkBuilder *builder; - GObject *dialog, *object, *store; + SystrayPlugin *plugin = XFCE_SYSTRAY_PLUGIN (panel_plugin); + GtkBuilder *builder; + GObject *dialog, *object, *store; + GtkTreeSelection *selection; + gpointer user_data_array[2]; /* setup the dialog */ PANEL_UTILS_LINK_4UI @@ -566,6 +589,8 @@ systray_plugin_configure_plugin (XfcePanelPlugin *panel_plugin) if (G_UNLIKELY (builder == NULL)) return; + plugin->configure_builder = builder; + object = gtk_builder_get_object (builder, "size-max"); panel_return_if_fail (GTK_IS_WIDGET (object)); g_object_bind_property (G_OBJECT (plugin), "size-max", @@ -580,20 +605,42 @@ systray_plugin_configure_plugin (XfcePanelPlugin *panel_plugin) store = gtk_builder_get_object (builder, "applications-store"); panel_return_if_fail (GTK_IS_LIST_STORE (store)); - g_hash_table_foreach (plugin->names, - systray_plugin_dialog_add_application_names, store); - g_object_set_data (G_OBJECT (plugin), "applications-store", store); + user_data_array[0] = plugin; + user_data_array[1] = store; + g_slist_foreach (plugin->names_ordered, + systray_plugin_dialog_add_application_names, user_data_array); object = gtk_builder_get_object (builder, "hidden-toggle"); panel_return_if_fail (GTK_IS_CELL_RENDERER_TOGGLE (object)); g_signal_connect (G_OBJECT (object), "toggled", G_CALLBACK (systray_plugin_dialog_hidden_toggled), plugin); + object = gtk_builder_get_object (builder, "applications-treeview"); + panel_return_if_fail (GTK_IS_TREE_VIEW (object)); + + selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (object)); + g_signal_connect (G_OBJECT (selection), "changed", + G_CALLBACK (systray_plugin_dialog_selection_changed), plugin); + + object = gtk_builder_get_object (builder, "item-up"); + panel_return_if_fail (GTK_IS_BUTTON (object)); + g_signal_connect (G_OBJECT (object), "clicked", + G_CALLBACK (systray_plugin_dialog_item_move_clicked), plugin); + + object = gtk_builder_get_object (builder, "item-down"); + panel_return_if_fail (GTK_IS_BUTTON (object)); + g_signal_connect (G_OBJECT (object), "clicked", + G_CALLBACK (systray_plugin_dialog_item_move_clicked), plugin); + object = gtk_builder_get_object (builder, "applications-clear"); panel_return_if_fail (GTK_IS_BUTTON (object)); g_signal_connect (G_OBJECT (object), "clicked", G_CALLBACK (systray_plugin_dialog_clear_clicked), plugin); + g_object_weak_ref (G_OBJECT (builder), + (GWeakNotify) systray_plugin_dialog_cleanup, + plugin); + gtk_widget_show (GTK_WIDGET (dialog)); } @@ -692,13 +739,10 @@ systray_plugin_names_collect (GPtrArray *array, static void -systray_plugin_names_collect_visible (gpointer key, - gpointer value, +systray_plugin_names_collect_ordered (gpointer data, gpointer user_data) { - /* add all the visible names */ - if (!GPOINTER_TO_UINT (value)) - systray_plugin_names_collect (user_data, key); + systray_plugin_names_collect (user_data, data); } @@ -708,19 +752,7 @@ systray_plugin_names_collect_hidden (gpointer key, gpointer value, gpointer user_data) { - /* add all the hidden names */ - if (GPOINTER_TO_UINT (value)) - systray_plugin_names_collect (user_data, key); -} - - - -static gboolean -systray_plugin_names_remove (gpointer key, - gpointer value, - gpointer user_data) -{ - return GPOINTER_TO_UINT (value) == GPOINTER_TO_UINT (user_data); + systray_plugin_names_collect (user_data, key); } @@ -749,8 +781,9 @@ systray_plugin_names_update (SystrayPlugin *plugin) panel_return_if_fail (XFCE_IS_SYSTRAY_PLUGIN (plugin)); gtk_container_foreach (GTK_CONTAINER (plugin->box), - systray_plugin_names_update_icon, plugin); - systray_box_update (XFCE_SYSTRAY_BOX (plugin->box)); + systray_plugin_names_update_icon, plugin); + systray_box_update (XFCE_SYSTRAY_BOX (plugin->box), + plugin->names_ordered); } @@ -763,12 +796,13 @@ systray_plugin_names_set_hidden (SystrayPlugin *plugin, panel_return_if_fail (XFCE_IS_SYSTRAY_PLUGIN (plugin)); panel_return_if_fail (!panel_str_is_empty (name)); - g_hash_table_replace (plugin->names, g_strdup (name), - GUINT_TO_POINTER (hidden ? 1 : 0)); + if (g_hash_table_contains (plugin->names_hidden, name)) + g_hash_table_remove (plugin->names_hidden, name); + else + g_hash_table_replace (plugin->names_hidden, g_strdup (name), NULL); systray_plugin_names_update (plugin); - g_object_notify (G_OBJECT (plugin), "names-visible"); g_object_notify (G_OBJECT (plugin), "names-hidden"); } @@ -778,25 +812,22 @@ static gboolean systray_plugin_names_get_hidden (SystrayPlugin *plugin, const gchar *name) { - gpointer p; - if (panel_str_is_empty (name)) return FALSE; - /* lookup the name in the table */ - p = g_hash_table_lookup (plugin->names, name); - if (G_UNLIKELY (p == NULL)) + /* lookup the name in the list */ + if (g_slist_find_custom (plugin->names_ordered, name, (GCompareFunc)g_strcmp0) == NULL) { /* add the new name */ - g_hash_table_insert (plugin->names, g_strdup (name), GUINT_TO_POINTER (0)); - g_object_notify (G_OBJECT (plugin), "names-visible"); + plugin->names_ordered = g_slist_prepend (plugin->names_ordered, g_strdup (name)); + g_object_notify (G_OBJECT (plugin), "names-ordered"); /* do not hide the icon */ return FALSE; } else { - return (GPOINTER_TO_UINT (p) == 1 ? TRUE : FALSE); + return g_hash_table_contains (plugin->names_hidden, name); } } @@ -805,10 +836,12 @@ systray_plugin_names_get_hidden (SystrayPlugin *plugin, static void systray_plugin_names_clear (SystrayPlugin *plugin) { - g_hash_table_remove_all (plugin->names); + g_slist_free_full (plugin->names_ordered, g_free); + plugin->names_ordered = NULL; + g_hash_table_remove_all (plugin->names_hidden); + g_object_notify (G_OBJECT (plugin), "names-ordered"); g_object_notify (G_OBJECT (plugin), "names-hidden"); - g_object_notify (G_OBJECT (plugin), "names-visible"); systray_plugin_names_update (plugin); } @@ -915,19 +948,20 @@ systray_plugin_dialog_camel_case (const gchar *text) static void -systray_plugin_dialog_add_application_names (gpointer key, - gpointer value, +systray_plugin_dialog_add_application_names (gpointer data, gpointer user_data) { - GtkListStore *store = GTK_LIST_STORE (user_data); - const gchar *name = key; - gboolean hidden = GPOINTER_TO_UINT (value); - const gchar *title = NULL; - gchar *camelcase = NULL; - const gchar *icon_name = name; - GdkPixbuf *pixbuf; - guint i; - GtkTreeIter iter; + gpointer **user_data_array = user_data; + SystrayPlugin *plugin = (SystrayPlugin *)user_data_array[0]; + GtkListStore *store = (GtkListStore *)user_data_array[1]; + const gchar *name = data; + gboolean hidden = g_hash_table_contains (plugin->names_hidden, name); + const gchar *title = NULL; + gchar *camelcase = NULL; + const gchar *icon_name = name; + GdkPixbuf *pixbuf; + guint i; + GtkTreeIter iter; panel_return_if_fail (GTK_IS_LIST_STORE (store)); panel_return_if_fail (name == NULL || g_utf8_validate (name, -1, NULL)); @@ -989,7 +1023,7 @@ systray_plugin_dialog_hidden_toggled (GtkCellRendererToggle *renderer, panel_return_if_fail (XFCE_IS_SYSTRAY_PLUGIN (plugin)); panel_return_if_fail (XFCE_IS_SYSTRAY_BOX (plugin->box)); - model = g_object_get_data (G_OBJECT (plugin), "applications-store"); + model = GTK_TREE_MODEL (gtk_builder_get_object (plugin->configure_builder, "applications-store")); panel_return_if_fail (GTK_IS_LIST_STORE (model)); if (gtk_tree_model_get_iter_from_string (model, &iter, path_string)) { @@ -1011,6 +1045,117 @@ systray_plugin_dialog_hidden_toggled (GtkCellRendererToggle *renderer, static void +systray_plugin_dialog_selection_changed (GtkTreeSelection *selection, + SystrayPlugin *plugin) +{ + GtkTreeModel *model; + GtkTreeIter iter; + GtkTreePath *path; + gint *indices; + gint count = 0, position = -1, depth; + gboolean item_up_sensitive, item_down_sensitive; + GObject *object; + + panel_return_if_fail (XFCE_IS_SYSTRAY_PLUGIN (plugin)); + + if (gtk_tree_selection_get_selected (selection, &model, &iter)) + { + path = gtk_tree_model_get_path (model, &iter); + indices = gtk_tree_path_get_indices_with_depth (path, &depth); + + if (indices != NULL && depth > 0) + position = indices[0]; + + count = gtk_tree_model_iter_n_children (model, NULL); + + gtk_tree_path_free (path); + } + + item_up_sensitive = position > 0; + item_down_sensitive = position + 1 < count; + + object = gtk_builder_get_object (plugin->configure_builder, "item-up"); + if (GTK_IS_BUTTON (object)) + gtk_widget_set_sensitive (GTK_WIDGET (object), item_up_sensitive); + + object = gtk_builder_get_object (plugin->configure_builder, "item-down"); + if (GTK_IS_BUTTON (object)) + gtk_widget_set_sensitive (GTK_WIDGET (object), item_down_sensitive); +} + + + +static gboolean +systray_plugin_dialog_tree_iter_insert (GtkTreeModel *model, + GtkTreePath *path, + GtkTreeIter *iter, + gpointer user_data) +{ + SystrayPlugin *plugin = user_data; + gchar *name; + + gtk_tree_model_get (model, iter, COLUMN_INTERNAL_NAME, &name, -1); + plugin->names_ordered = g_slist_prepend (plugin->names_ordered, g_strdup (name)); + + return FALSE; +} + + + +static void +systray_plugin_dialog_item_move_clicked (GtkWidget *button, + SystrayPlugin *plugin) +{ + GObject *object; + GtkTreeSelection *selection; + GtkTreeModel *model; + GtkTreeIter iter, from_iter; + GtkTreePath *path; + gint direction; + + object = gtk_builder_get_object (plugin->configure_builder, "applications-treeview"); + panel_return_if_fail (GTK_IS_TREE_VIEW (object)); + + selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (object)); + + object = gtk_builder_get_object (plugin->configure_builder, "item-up"); + panel_return_if_fail (GTK_IS_BUTTON (object)); + direction = object == G_OBJECT (button) ? -1 : 1; + + if (gtk_tree_selection_get_selected (selection, &model, &iter)) + { + path = gtk_tree_model_get_path (model, &iter); + + if (direction > 0) + gtk_tree_path_next (path); + else + gtk_tree_path_prev (path); + + if (gtk_tree_model_get_iter (model, &from_iter, path)) + { + if (direction > 0) + gtk_list_store_move_after (GTK_LIST_STORE (model), &iter, &from_iter); + else + gtk_list_store_move_before (GTK_LIST_STORE (model), &iter, &from_iter); + + /* update buttons state */ + systray_plugin_dialog_selection_changed (selection, plugin); + + /* update order */ + g_slist_free_full (plugin->names_ordered, g_free); + plugin->names_ordered = NULL; + gtk_tree_model_foreach (model, systray_plugin_dialog_tree_iter_insert, plugin); + plugin->names_ordered = g_slist_reverse (plugin->names_ordered); + g_object_notify (G_OBJECT (plugin), "names-ordered"); + } + + gtk_tree_path_free (path); + } +} + + + +static void systray_plugin_dialog_clear_clicked (GtkWidget *button, SystrayPlugin *plugin) { @@ -1024,10 +1169,22 @@ systray_plugin_dialog_clear_clicked (GtkWidget *button, _("Are you sure you want to clear the list of " "known applications?"))) { - store = g_object_get_data (G_OBJECT (plugin), "applications-store"); + store = GTK_LIST_STORE (gtk_builder_get_object (plugin->configure_builder, "applications-store")); panel_return_if_fail (GTK_IS_LIST_STORE (store)); gtk_list_store_clear (store); systray_plugin_names_clear (plugin); } } + + + +static void +systray_plugin_dialog_cleanup (SystrayPlugin *plugin, + GtkBuilder *builder) +{ + panel_return_if_fail (XFCE_IS_SYSTRAY_PLUGIN (plugin)); + + if (plugin->configure_builder == builder) + plugin->configure_builder = NULL; +} -- 2.13.1