From 4da68b43f3e86a4e53815b147176942d118f8eab Mon Sep 17 00:00:00 2001 From: Javier Date: Sun, 25 Jan 2015 17:52:24 +0100 Subject: fix applet settings path --- libmdock/mdock-item-menu.c | 11 ++ libmdock/mdock-widget.c | 228 +++++++++++++++++++--------------- libmdock/mdock-widget.h | 3 + mate-applet/mdock-mate-panel-applet.c | 28 ++--- mate-applet/mdock-mate-panel-applet.h | 1 - test/mdock-standalone.c | 2 +- 6 files changed, 156 insertions(+), 117 deletions(-) diff --git a/libmdock/mdock-item-menu.c b/libmdock/mdock-item-menu.c index 39495af..02de0bb 100644 --- a/libmdock/mdock-item-menu.c +++ b/libmdock/mdock-item-menu.c @@ -53,6 +53,7 @@ static GParamSpec *obj_properties[N_PROPERTIES] = { NULL }; #ifdef HAVE_ZEITGEIST +#define INITIAL_REFRESH_DELAY 3 #define RECENT_FETCH_MIN_INTERVAL 15 G_DEFINE_QUARK(mdock-item-menu-file, mdock_item_menu_file) @@ -205,6 +206,15 @@ static gboolean handle_menu_map(MDockItemMenu *self, GdkEventAny *event) return FALSE; } +static gboolean initial_menu_refresh(gpointer user_data) +{ + MDockItemMenu *self = MDOCK_ITEM_MENU(user_data); + // If we have never refreshed the menu so far, do an initial one now. + if (self->priv->recent_fetch_time == 0) { + refresh_recent_menu(self); + } +} + #endif static void handle_item_pinned(MDockItemMenu *self, GParamSpec *spec, MDockItem *item) @@ -304,6 +314,7 @@ mdock_item_menu_constructed(GObject *object) #ifdef HAVE_ZEITGEIST g_signal_connect(self, "map-event", G_CALLBACK(handle_menu_map), self); + g_timeout_add_seconds(INITIAL_REFRESH_DELAY, initial_menu_refresh, self); #endif } diff --git a/libmdock/mdock-widget.c b/libmdock/mdock-widget.c index 6507fbb..8efaf19 100644 --- a/libmdock/mdock-widget.c +++ b/libmdock/mdock-widget.c @@ -39,7 +39,6 @@ struct _MDockWidgetPrivate { - gchar *settings_path; GSettings *settings; WnckScreen *wnck_screen; GSequence *items; @@ -59,7 +58,7 @@ G_DEFINE_TYPE(MDockWidget, mdock_widget, GTK_TYPE_BOX) enum { PROP_0, - PROP_SETTINGS_PATH, + PROP_SETTINGS, N_PROPERTIES }; @@ -190,10 +189,33 @@ static void show_item_popup(MDockWidget *self, MDockItem *item) self->priv->current_popup_item = item; } +static gboolean filter_deleted_group(gpointer key, gpointer value, gpointer user_data) +{ + return value == user_data; +} + +static void remove_item(MDockWidget *self, GSequenceIter *iter) +{ + MDockItem *item = MDOCK_ITEM(g_sequence_get(iter)); + g_hash_table_foreach_remove(self->priv->appid_to_item, filter_deleted_group, iter); + g_hash_table_foreach_remove(self->priv->desktopid_to_item, filter_deleted_group, iter); + g_sequence_remove(iter); + if (self->priv->current_popup_item == item) { + hide_item_popup(self); + } + gtk_widget_destroy(GTK_WIDGET(item)); +} + static void handle_item_pinned_changed(MDockWidget *self, GParamSpec *spec, MDockItem *item) { if (!self->priv->loading_settings) { save_items_to_settings(self); + + if (!mdock_item_get_pinned(item) && mdock_item_get_num_windows(item) == 0) { + // Not pinned and without windows? + GSequenceIter *iter = g_object_get_qdata(G_OBJECT(item), mdock_widget_item_iter_quark()); + remove_item(self, iter); + } } } @@ -531,51 +553,68 @@ static void connect_item(MDockWidget *self, MDockItem *item, GSequenceIter *posi 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)); + if (self->priv->settings) { + GVariantIter *set_iter; + g_settings_get(self->priv->settings, "items", "as", &set_iter); + + 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); + MDockItem *item; + if (iter) { + // This item is already on the dock, let's move it to the front and pin it. + 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. + item = mdock_item_new(); + mdock_item_set_desktop_app_info(item, set_appinfo); + mdock_item_set_pinned(item, TRUE); - 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); - - iter = g_sequence_insert_before(seq_iter, item); - g_hash_table_insert(self->priv->desktopid_to_item, g_strdup(set_desktopid), iter); - - connect_item(self, item, iter); - - gtk_widget_show(GTK_WIDGET(item)); - gtk_box_pack_start(GTK_BOX(self), GTK_WIDGET(item), TRUE, TRUE, 0); - if (!g_sequence_iter_is_end(seq_iter)) { - // Fix the order! - gtk_box_reorder_child(GTK_BOX(self), GTK_WIDGET(item), - g_sequence_iter_get_position(iter)); + iter = g_sequence_insert_before(seq_iter, item); + g_hash_table_insert(self->priv->desktopid_to_item, g_strdup(set_desktopid), iter); + + connect_item(self, item, iter); + + gtk_widget_show(GTK_WIDGET(item)); + gtk_box_pack_start(GTK_BOX(self), GTK_WIDGET(item), TRUE, TRUE, 0); } + + // Fix the box order of the item... + gtk_box_reorder_child(GTK_BOX(self), GTK_WIDGET(item), + g_sequence_iter_get_position(iter)); + + g_object_unref(set_appinfo); + g_free(value); } - g_object_unref(set_appinfo); - g_free(value); + g_variant_iter_free(set_iter); } - g_variant_iter_free(set_iter); + while (!g_sequence_iter_is_end(seq_iter)) { + MDockItem *item = g_sequence_get(seq_iter); + if (mdock_item_get_pinned(item)) { + mdock_item_set_pinned(item, FALSE); + if (mdock_item_get_num_windows(item) == 0) { + // Remove this item + // The iterator will be destroyed, so take care. + GSequenceIter *iter = seq_iter; + seq_iter = g_sequence_iter_next(iter); + remove_item(self, iter); + continue; + } + } + + seq_iter = g_sequence_iter_next(seq_iter); + } self->priv->loading_settings = FALSE; } @@ -591,11 +630,6 @@ static void handle_active_window_changed(MDockWidget *self, WnckWindow *previous } } -static gboolean filter_deleted_group(gpointer key, gpointer value, gpointer user_data) -{ - return value == user_data; -} - static void handle_window_closed(MDockWidget *self, WnckWindow *window, WnckScreen *screen) { GSequenceIter *iter = g_hash_table_lookup(self->priv->window_to_item, window); @@ -611,13 +645,7 @@ static void handle_window_closed(MDockWidget *self, WnckWindow *window, WnckScre if (!mdock_item_has_windows(item) && !mdock_item_get_pinned(item)) { // Removing item from dock - g_hash_table_foreach_remove(self->priv->appid_to_item, filter_deleted_group, iter); - g_hash_table_foreach_remove(self->priv->desktopid_to_item, filter_deleted_group, iter); - g_sequence_remove(iter); - if (self->priv->current_popup_item == item) { - hide_item_popup(self); - } - gtk_widget_destroy(GTK_WIDGET(item)); + remove_item(self, iter); } } @@ -681,49 +709,10 @@ static void handle_settings_items_changed(MDockWidget *self, gchar *key, GSettin } } -static void mdock_widget_constructed(GObject *obj) -{ - MDockWidget *self = MDOCK_WIDGET(obj); - - G_OBJECT_CLASS(mdock_widget_parent_class)->constructed(obj); - - g_debug("Constructing with path: %s", self->priv->settings_path); - self->priv->settings = g_settings_new_with_path("com.javispedro.mdock.widget", - self->priv->settings_path); - g_signal_connect_object(self->priv->settings, "changed::items", - G_CALLBACK(handle_settings_items_changed), self, G_CONNECT_SWAPPED); - - self->priv->wnck_screen = wnck_screen_get_default(); - g_signal_connect_object(self->priv->wnck_screen, "active-window-changed", - G_CALLBACK(handle_active_window_changed), self, G_CONNECT_SWAPPED); - g_signal_connect_object(self->priv->wnck_screen, "window-closed", - G_CALLBACK(handle_window_closed), self, G_CONNECT_SWAPPED); - g_signal_connect_object(self->priv->wnck_screen, "window-opened", - G_CALLBACK(handle_window_opened), self, G_CONNECT_SWAPPED); - - self->priv->items = g_sequence_new(NULL); - self->priv->appid_to_item = g_hash_table_new_full(app_id_hash, app_id_equal, - (GDestroyNotify)app_id_destroy, NULL); - self->priv->desktopid_to_item = g_hash_table_new_full(g_str_hash, g_str_equal, - g_free, NULL); - self->priv->window_to_item = g_hash_table_new_full(g_direct_hash, g_direct_equal, - NULL, NULL); - - 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)) { - WnckWindow *window = l->data; - handle_window_opened(self, window, self->priv->wnck_screen); - } -} - static void mdock_widget_dispose(GObject *obj) { MDockWidget *self = MDOCK_WIDGET(obj); - if (self->priv->settings) { - g_clear_object(&self->priv->settings); - } + g_clear_object(&self->priv->settings); if (self->priv->wnck_screen) { g_signal_handlers_disconnect_by_data(self->priv->wnck_screen, self); self->priv->wnck_screen = NULL; @@ -734,7 +723,6 @@ static void mdock_widget_dispose(GObject *obj) static void mdock_widget_finalize(GObject *obj) { MDockWidget *self = MDOCK_WIDGET(obj); - g_free(self->priv->settings_path); g_sequence_free(self->priv->items); g_hash_table_destroy(self->priv->appid_to_item); g_hash_table_destroy(self->priv->desktopid_to_item); @@ -749,8 +737,17 @@ static void mdock_widget_set_property(GObject *object, { MDockWidget *self = MDOCK_WIDGET(object); switch (property_id) { - case PROP_SETTINGS_PATH: - self->priv->settings_path = g_value_dup_string(value); + case PROP_SETTINGS: + if (self->priv->settings) { + g_signal_handlers_disconnect_by_data(self->priv->settings, self); + g_object_unref(self->priv->settings); + } + self->priv->settings = g_value_dup_object(value); + if (self->priv->settings) { + g_signal_connect_object(self->priv->settings, "changed::items", + G_CALLBACK(handle_settings_items_changed), self, G_CONNECT_SWAPPED); + } + reload_items_from_settings(self); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID(object, property_id, pspec); @@ -765,8 +762,8 @@ static void mdock_widget_get_property(GObject *object, { MDockWidget *self = MDOCK_WIDGET(object); switch (property_id) { - case PROP_SETTINGS_PATH: - g_value_set_string(value, self->priv->settings_path); + case PROP_SETTINGS: + g_value_set_object(value, self->priv->settings); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID(object, property_id, pspec); @@ -787,6 +784,28 @@ static void mdock_widget_init(MDockWidget *self) gtk_drag_dest_set(GTK_WIDGET(self), 0, drag_types, G_N_ELEMENTS(drag_types), GDK_ACTION_MOVE); + + self->priv->wnck_screen = wnck_screen_get_default(); + g_signal_connect_object(self->priv->wnck_screen, "active-window-changed", + G_CALLBACK(handle_active_window_changed), self, G_CONNECT_SWAPPED); + g_signal_connect_object(self->priv->wnck_screen, "window-closed", + G_CALLBACK(handle_window_closed), self, G_CONNECT_SWAPPED); + g_signal_connect_object(self->priv->wnck_screen, "window-opened", + G_CALLBACK(handle_window_opened), self, G_CONNECT_SWAPPED); + + self->priv->items = g_sequence_new(NULL); + self->priv->appid_to_item = g_hash_table_new_full(app_id_hash, app_id_equal, + (GDestroyNotify)app_id_destroy, NULL); + self->priv->desktopid_to_item = g_hash_table_new_full(g_str_hash, g_str_equal, + g_free, NULL); + self->priv->window_to_item = g_hash_table_new_full(g_direct_hash, g_direct_equal, + NULL, NULL); + + GList *windows = wnck_screen_get_windows_stacked(self->priv->wnck_screen); + for (GList *l = windows; l; l = g_list_next(l)) { + WnckWindow *window = l->data; + handle_window_opened(self, window, self->priv->wnck_screen); + } } static void mdock_widget_class_init(MDockWidgetClass *klass) @@ -797,17 +816,16 @@ static void mdock_widget_class_init(MDockWidgetClass *klass) widget_class->drag_motion = mdock_widget_drag_motion; GObjectClass *obj_class = G_OBJECT_CLASS(klass); - obj_class->constructed = mdock_widget_constructed; obj_class->dispose = mdock_widget_dispose; obj_class->finalize = mdock_widget_finalize; obj_class->set_property = mdock_widget_set_property; obj_class->get_property = mdock_widget_get_property; - obj_properties[PROP_SETTINGS_PATH] = g_param_spec_string("settings-path", - "Path to GSettings for this widget", - "Set the path to GSettings for this widget", - "/com/javispedro/mdock/standalone/", - G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + obj_properties[PROP_SETTINGS] = g_param_spec_object("settings", + "GSettings object this widget will use", + "Set the path to GSettings for this widget", + G_TYPE_SETTINGS, + G_PARAM_CONSTRUCT | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); g_object_class_install_properties(obj_class, N_PROPERTIES, obj_properties); @@ -824,7 +842,15 @@ GtkWidget *mdock_widget_new(void) return GTK_WIDGET(g_object_new(MDOCK_TYPE_WIDGET, NULL)); } +GtkWidget *mdock_widget_new_with_settings(GSettings *settings) +{ + return GTK_WIDGET(g_object_new(MDOCK_TYPE_WIDGET, "settings", settings, NULL)); +} + GtkWidget *mdock_widget_new_with_settings_path(const gchar *path) { - return GTK_WIDGET(g_object_new(MDOCK_TYPE_WIDGET, "settings-path", path, NULL)); + GSettings *settings = g_settings_new_with_path(MDOCK_WIDGET_GSETTINGS_SCHEMA, path); + GtkWidget *self = mdock_widget_new_with_settings(settings); + g_object_unref(settings); + return self; } diff --git a/libmdock/mdock-widget.h b/libmdock/mdock-widget.h index 2771095..2c49b04 100644 --- a/libmdock/mdock-widget.h +++ b/libmdock/mdock-widget.h @@ -31,6 +31,8 @@ G_BEGIN_DECLS #define MDOCK_IS_WIDGET_CLASS(c) (G_TYPE_CHECK_CLASS_TYPE((c), MDOCK_TYPE_WIDGET)) #define MDOCK_WIDGET_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), MDOCK_TYPE_WIDGET, MDockWidgetClass)) +#define MDOCK_WIDGET_GSETTINGS_SCHEMA "com.javispedro.mdock.widget" + typedef struct _MDockWidget MDockWidget; typedef struct _MDockWidgetClass MDockWidgetClass; typedef struct _MDockWidgetPrivate MDockWidgetPrivate; @@ -52,6 +54,7 @@ GType mdock_widget_get_type(void); gint mdock_widget_get_n_items(MDockWidget *widget); GtkWidget *mdock_widget_new(void); +GtkWidget *mdock_widget_new_with_settings(GSettings *settings); GtkWidget *mdock_widget_new_with_settings_path(const gchar *path); G_END_DECLS diff --git a/mate-applet/mdock-mate-panel-applet.c b/mate-applet/mdock-mate-panel-applet.c index ba18f43..62d0bde 100644 --- a/mate-applet/mdock-mate-panel-applet.c +++ b/mate-applet/mdock-mate-panel-applet.c @@ -17,6 +17,8 @@ * along with MDock. If not, see . */ +#include + #include "mdock-mate-panel-applet.h" #include @@ -71,6 +73,13 @@ static gboolean transform_applet_orient_to_orientation(GBinding *binding, const g_value_set_enum(to_value, applet_orient_to_orientation(orient)); } +static gboolean transform_prefs_path_to_gsettings(GBinding *binding, const GValue *from_value, GValue *to_value, gpointer user_data) +{ + const gchar *prefs_path = g_value_get_string(from_value); + GSettings *settings = g_settings_new_with_path(MDOCK_WIDGET_GSETTINGS_SCHEMA, prefs_path); + g_value_take_object(to_value, settings); +} + static GtkOrientation mdock_mate_panel_applet_get_orientation(MDockMatePanelApplet *self) { MatePanelAppletOrient orient = mate_panel_applet_get_orient(MATE_PANEL_APPLET(self)); @@ -91,8 +100,6 @@ static void mdock_mate_panel_applet_size_request(GtkWidget *widget, GtkRequisiti gtk_widget_size_request(GTK_WIDGET(self->dock), requisition); - g_debug("size request %dx%d", requisition->width, requisition->height); - // Try to force a square aspect ratio for the icons // by requesting a big enough major panel dimension GtkAllocation allocation; @@ -106,8 +113,6 @@ static void mdock_mate_panel_applet_size_request(GtkWidget *widget, GtkRequisiti requisition->width = MAX(requisition->width, allocation.width); requisition->height = MAX(requisition->height, nitems * (requisition->width + spacing)); } - - g_debug("size request %dx%d", requisition->width, requisition->height); } static void mdock_mate_panel_applet_class_init(MDockMatePanelAppletClass *klass) @@ -120,23 +125,18 @@ static void mdock_mate_panel_applet_class_init(MDockMatePanelAppletClass *klass) static void mdock_mate_panel_applet_init(MDockMatePanelApplet *self) { MatePanelApplet *applet = MATE_PANEL_APPLET(self); - gchar *prefs_path = mate_panel_applet_get_preferences_path(applet); - g_warn_if_fail(prefs_path); - - if (prefs_path) { - self->dock = MDOCK_WIDGET(mdock_widget_new_with_settings_path(prefs_path)); - } else { - self->dock = MDOCK_WIDGET(mdock_widget_new()); - } + self->dock = MDOCK_WIDGET(mdock_widget_new()); gtk_container_add(GTK_CONTAINER(self), GTK_WIDGET(self->dock)); - g_free(prefs_path); - g_object_bind_property_full(self, "orient", self->dock, "orientation", G_BINDING_DEFAULT, transform_applet_orient_to_orientation, NULL, NULL, NULL); + g_object_bind_property_full(self, "prefs-path", self->dock, "settings", + G_BINDING_DEFAULT, + transform_prefs_path_to_gsettings, + NULL, NULL, NULL); GtkActionGroup *action_group = gtk_action_group_new("MDock Mate Panel Applet Actions"); gtk_action_group_add_actions(action_group, diff --git a/mate-applet/mdock-mate-panel-applet.h b/mate-applet/mdock-mate-panel-applet.h index a9c57db..b7cd4d9 100644 --- a/mate-applet/mdock-mate-panel-applet.h +++ b/mate-applet/mdock-mate-panel-applet.h @@ -39,7 +39,6 @@ struct _MDockMatePanelApplet { MatePanelApplet parent_instance; MDockWidget *dock; - GtkActionGroup *actions; }; struct _MDockMatePanelAppletClass diff --git a/test/mdock-standalone.c b/test/mdock-standalone.c index e1f12d3..af1a3dd 100644 --- a/test/mdock-standalone.c +++ b/test/mdock-standalone.c @@ -27,7 +27,7 @@ static MDockWidget *mdock; static void construct_main_window() { mainwin = GTK_WINDOW(gtk_window_new(GTK_WINDOW_TOPLEVEL)); - mdock = MDOCK_WIDGET(mdock_widget_new()); + mdock = MDOCK_WIDGET(mdock_widget_new_with_settings_path("/com/javispedro/mdock/standalone/")); gtk_container_add(GTK_CONTAINER(mainwin), GTK_WIDGET(mdock)); gtk_window_set_title(mainwin, "MDock standalone"); } -- cgit v1.2.3