summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--libmdock/mdock-widget.c171
1 files changed, 96 insertions, 75 deletions
diff --git a/libmdock/mdock-widget.c b/libmdock/mdock-widget.c
index 06080bf..1ce9a4d 100644
--- a/libmdock/mdock-widget.c
+++ b/libmdock/mdock-widget.c
@@ -35,6 +35,7 @@ struct _MDockWidgetPrivate
GHashTable *appid_to_item;
GHashTable *desktopid_to_item;
GHashTable *window_to_item;
+ gboolean loading_settings;
};
G_DEFINE_TYPE(MDockWidget, mdock_widget, GTK_TYPE_BOX)
@@ -49,6 +50,96 @@ enum {
static GParamSpec *obj_properties[N_PROPERTIES] = { NULL };
+static void save_items_to_settings(MDockWidget *self)
+{
+ GSettings *settings = self->priv->settings;
+ GSequenceIter *seq_iter = g_sequence_get_begin_iter(self->priv->items);
+ GVariantBuilder builder;
+
+ g_variant_builder_init(&builder, G_VARIANT_TYPE("as"));
+
+ while (!g_sequence_iter_is_end(seq_iter)) {
+ MDockItem *item = MDOCK_ITEM(g_sequence_get(seq_iter));
+
+ if (mdock_item_get_pinned(item)) {
+ GDesktopAppInfo *info = mdock_item_get_desktop_app_info(item);
+ if (info) {
+ g_variant_builder_add(&builder, "s", g_desktop_app_info_get_filename(info));
+ }
+ }
+
+ seq_iter = g_sequence_iter_next(seq_iter);
+ }
+
+ self->priv->loading_settings = TRUE;
+ g_settings_set(settings, "items", "as", &builder);
+ self->priv->loading_settings = FALSE;
+}
+
+static void handle_item_pinned_changed(MDockWidget *self, GParamSpec *spec, MDockItem *item)
+{
+ if (!self->priv->loading_settings) {
+ save_items_to_settings(self);
+ }
+}
+
+static void connect_item(MDockWidget *self, MDockItem *item)
+{
+ g_signal_connect_object(item, "notify::pinned",
+ G_CALLBACK(handle_item_pinned_changed), self,
+ G_CONNECT_SWAPPED);
+
+ g_settings_bind(self->priv->settings, "icon-size",
+ item, "icon-size",
+ G_SETTINGS_BIND_GET | G_SETTINGS_BIND_NO_SENSITIVITY);
+}
+
+
+static void reload_items_from_settings(MDockWidget *self)
+{
+ GSettings *settings = self->priv->settings;
+
+ self->priv->loading_settings = TRUE;
+
+ GVariantIter *set_iter;
+ g_settings_get(settings, "items", "as", &set_iter);
+
+ GSequenceIter *seq_iter = g_sequence_get_begin_iter(self->priv->items);
+
+ gchar *value;
+ while (g_variant_iter_next(set_iter, "s", &value)) {
+ GDesktopAppInfo *set_appinfo = g_desktop_app_info_new_from_filename(value);
+ const gchar *set_desktopid = g_app_info_get_id(G_APP_INFO(set_appinfo));
+
+ GSequenceIter *iter = g_hash_table_lookup(self->priv->desktopid_to_item, set_desktopid);
+ if (iter) {
+ // This item is already on the dock, let's move it to the front and pin it.
+ MDockItem *item = MDOCK_ITEM(g_sequence_get(iter));
+ mdock_item_set_pinned(item, TRUE);
+ g_sequence_move(iter, seq_iter);
+ } else {
+ // Item not already in the dock.
+ MDockItem *item = mdock_item_new();
+ mdock_item_set_desktop_app_info(item, set_appinfo);
+ mdock_item_set_pinned(item, TRUE);
+
+ connect_item(self, item);
+
+ iter = g_sequence_insert_before(seq_iter, item);
+ g_hash_table_insert(self->priv->desktopid_to_item, g_strdup(set_desktopid), iter);
+ gtk_widget_show(GTK_WIDGET(item));
+ gtk_box_pack_start(GTK_BOX(self), GTK_WIDGET(item), TRUE, FALSE, 0);
+ }
+
+ g_object_unref(set_appinfo);
+ g_free(value);
+ }
+
+ g_variant_iter_free(set_iter);
+
+ self->priv->loading_settings = FALSE;
+}
+
static void handle_active_window_changed(MDockWidget *self, WnckWindow *previous_window, WnckScreen *screen)
{
WnckWindow *window = wnck_screen_get_active_window(screen);
@@ -121,9 +212,7 @@ static void handle_window_opened(MDockWidget *self, WnckWindow *window, WnckScre
g_object_unref(app_info);
}
- g_settings_bind(self->priv->settings, "icon-size",
- item, "icon-size",
- G_SETTINGS_BIND_GET | G_SETTINGS_BIND_NO_SENSITIVITY);
+ connect_item(self, item);
mdock_item_add_window(item, window);
@@ -137,79 +226,11 @@ static void handle_window_opened(MDockWidget *self, WnckWindow *window, WnckScre
gtk_box_pack_start(GTK_BOX(self), GTK_WIDGET(item), TRUE, FALSE, 0);
}
-static void load_items_from_settings(MDockWidget *self, GSettings *settings)
-{
- GVariantIter *set_iter;
- GVariant *set_value;
- GSequenceIter *seq_iter = g_sequence_get_begin_iter(self->priv->items);
-
- g_settings_get(settings, "items", "as", &set_iter);
- set_value = g_variant_iter_next_value(set_iter);
-
- g_debug("Loading settings %p %p", set_value, seq_iter);
-
- while (set_value || !g_sequence_iter_is_end(seq_iter)) {
- gboolean advance_set = FALSE, advance_seq = FALSE;
- MDockItem *item = NULL;
- GDesktopAppInfo *seq_appinfo = NULL;
- GDesktopAppInfo *set_appinfo = NULL;
-
- g_debug("Iteration %p %p", set_value, seq_iter);
-
- if (!g_sequence_iter_is_end(seq_iter)) {
- item = MDOCK_ITEM(g_sequence_get(seq_iter));
- seq_appinfo = mdock_item_get_desktop_app_info(item);
- }
- if (set_value) {
- set_appinfo = g_desktop_app_info_new_from_filename(g_variant_get_string(set_value, NULL));
- }
-
- if (set_appinfo && seq_appinfo) {
- const gchar *set_desktopid = g_app_info_get_id(G_APP_INFO(set_appinfo));
- const gchar *seq_desktopid = g_app_info_get_id(G_APP_INFO(seq_appinfo));
- const gboolean seq_pinned = mdock_item_get_pinned(item);
-
- // TODO broken
- g_warning("broken");
- } else if (set_appinfo) {
- g_debug("from set only");
- item = mdock_item_new();
- mdock_item_set_desktop_app_info(item, set_appinfo);
- mdock_item_set_pinned(item, TRUE);
-
- GSequenceIter *iter = g_sequence_append(self->priv->items, item);
- const gchar *desktopid = g_app_info_get_id(G_APP_INFO(set_appinfo));
- g_hash_table_insert(self->priv->desktopid_to_item, g_strdup(desktopid), iter);
- gtk_widget_show(GTK_WIDGET(item));
- gtk_box_pack_start(GTK_BOX(self), GTK_WIDGET(item), TRUE, FALSE, 0);
-
- advance_set = TRUE;
- } else if (seq_appinfo) {
- g_debug("from seq only");
- if (mdock_item_get_pinned(item)) {
- mdock_item_set_pinned(item, FALSE);
- }
- advance_seq = TRUE;
- }
-
- g_object_unref(set_appinfo);
-
- if (advance_set && set_appinfo) {
- g_variant_unref(set_value);
- set_value = g_variant_iter_next_value(set_iter);
-
- }
- if (advance_seq && !g_sequence_iter_is_end(seq_iter)) {
- seq_iter = g_sequence_iter_next(seq_iter);
- }
- }
-
- g_variant_iter_free(set_iter);
-}
-
static void handle_settings_items_changed(MDockWidget *self, gchar *key, GSettings *settings)
{
- load_items_from_settings(self, settings);
+ if (!self->priv->loading_settings) {
+ reload_items_from_settings(self);
+ }
}
static void mdock_widget_constructed(GObject *obj)
@@ -238,7 +259,7 @@ static void mdock_widget_constructed(GObject *obj)
self->priv->window_to_item = g_hash_table_new_full(g_direct_hash, g_direct_equal,
NULL, NULL);
- load_items_from_settings(self, self->priv->settings);
+ reload_items_from_settings(self);
GList *windows = wnck_screen_get_windows_stacked(self->priv->wnck_screen);
for (GList *l = windows; l; l = g_list_next(l)) {