From d8aa230d1289b83b782b69185d761659556e5a4b Mon Sep 17 00:00:00 2001 From: Eric Koegel Date: Sun, 15 Feb 2015 17:43:07 +0300 Subject: [PATCH] Sort pending icons on resize (Bug #11266) The icon view now emits a resize-event when the grid size changes. When that happens, the file icon manager will update the pending icons to their new location based on the cache file it reads from. --- src/xfdesktop-file-icon-manager.c | 115 +++++++++++++++++++++++++++++++------- src/xfdesktop-icon-view.c | 15 ++++- src/xfdesktop-icon-view.h | 2 + 3 files changed, 111 insertions(+), 21 deletions(-) diff --git a/src/xfdesktop-file-icon-manager.c b/src/xfdesktop-file-icon-manager.c index be93a3b..e2c004e 100644 --- a/src/xfdesktop-file-icon-manager.c +++ b/src/xfdesktop-file-icon-manager.c @@ -2009,6 +2009,25 @@ xfdesktop_file_icon_manager_queue_thumbnail(XfdesktopFileIconManager *fmanager, } } +static void +add_icon_to_iconview(XfdesktopFileIconManager *fmanager, + XfdesktopIcon *icon) +{ + /* Pay attention to position changes and add the icon to the icon view */ + g_signal_connect(G_OBJECT(icon), "position-changed", + G_CALLBACK(xfdesktop_file_icon_position_changed), + fmanager); + + /* Tell the icon view about the icon */ + xfdesktop_icon_view_add_item(fmanager->priv->icon_view, + XFDESKTOP_ICON(icon)); + +#if defined(DEBUG) && DEBUG > 0 + _alive_icon_list = g_list_prepend(_alive_icon_list, icon); + g_object_weak_ref(G_OBJECT(icon), _icon_notify_destroy, NULL); +#endif +} + /* Adds a single icon to the icon view, popping from the top of the stack. * Will continue to run until it runs out of icons to add at which point * it will free the queue and return FALSE */ @@ -2036,21 +2055,64 @@ process_icon_from_queue(gpointer user_data) if(icon == NULL || !XFDESKTOP_IS_FILE_ICON(icon)) return TRUE; - /* Pay attention to position changes and add the icon to the icon view */ - g_signal_connect(G_OBJECT(icon), "position-changed", - G_CALLBACK(xfdesktop_file_icon_position_changed), - fmanager); - xfdesktop_icon_view_add_item(fmanager->priv->icon_view, - XFDESKTOP_ICON(icon)); - -#if defined(DEBUG) && DEBUG > 0 - _alive_icon_list = g_list_prepend(_alive_icon_list, icon); - g_object_weak_ref(G_OBJECT(icon), _icon_notify_destroy, NULL); -#endif + add_icon_to_iconview(fmanager, XFDESKTOP_ICON(icon)); return TRUE; } +/* When the icon view gets resized we need to sort all the icons so they + * are placed in the correct spot for the new resolution */ +static void +icon_view_resized(XfdesktopIconView *icon_view, + XfdesktopFileIconManager *fmanager) +{ + GQueue *new_queue; + XfdesktopIcon *icon; + XfdesktopFileIconManagerPrivate *priv = XFDESKTOP_FILE_ICON_MANAGER_GET_PRIVATE(fmanager); + const gchar *name; + gchar *identifier; + gint16 row, col; + + XF_DEBUG("icon view - resize event!"); + + if(!XFDESKTOP_IS_FILE_ICON_MANAGER(fmanager) || !XFDESKTOP_IS_ICON_VIEW(icon_view)) + return; + + /* No pending icons, nothing to do */ + if(priv == NULL || priv->pending_icons == NULL || g_queue_is_empty(priv->pending_icons)) + return; + + new_queue = g_queue_new(); + + while((icon = g_queue_pop_head(priv->pending_icons))) { + name = xfdesktop_icon_peek_label(XFDESKTOP_ICON(icon)); + identifier = xfdesktop_icon_get_identifier(XFDESKTOP_ICON(icon)); + + if(xfdesktop_file_icon_manager_get_cached_icon_position(fmanager, + name, identifier, + &row, &col)) + { + /* The icon has spot in the new resolution, add it to the front of + * the queue. */ + XF_DEBUG("attempting to set icon '%s' to position (%d,%d) [location in cache]", name, row, col); + xfdesktop_icon_set_position(XFDESKTOP_ICON(icon), row, col); + g_queue_push_head(new_queue, icon); + } else { + /* Didn't have a spot, push it to the end of the stack. These will be + * added last. */ + XF_DEBUG("icon '%s' didn't have a previous position", name); + g_queue_push_tail(new_queue, icon); + } + + if(identifier) + g_free(identifier); + } + + /* Free the old queue and replace it with the new one */ + g_queue_free(priv->pending_icons); + priv->pending_icons = new_queue; +} + static void xfdesktop_file_icon_manager_add_icon(XfdesktopFileIconManager *fmanager, XfdesktopFileIcon *icon, @@ -2069,23 +2131,28 @@ xfdesktop_file_icon_manager_add_icon(XfdesktopFileIconManager *fmanager, if(fmanager->priv->pending_icons == NULL) fmanager->priv->pending_icons = g_queue_new(); - /* See if our icon had a spot on in the icon view, if it did then it goes - * to the front of the pending icon queue, if it didn't then we place it - * on the end */ if(row >= 0 && col >= 0) { - XF_DEBUG("attempting to set icon '%s' to position (%d,%d)", name, row, col); + /* The row and col have been hard-set when adding the icon to the + * icon view, probably by the user (like an icon rename). We assume + * this is a top priority so bypass the queue and add it now */ + XF_DEBUG("attempting to set icon '%s' to position (%d,%d) [assigned location]", name, row, col); xfdesktop_icon_set_position(XFDESKTOP_ICON(icon), row, col); - g_queue_push_head(fmanager->priv->pending_icons, icon); + add_icon_to_iconview(fmanager, XFDESKTOP_ICON(icon)); } else if(xfdesktop_file_icon_manager_get_cached_icon_position(fmanager, name, identifier, &row, &col)) { - XF_DEBUG("attempting to set icon '%s' to position (%d,%d)", name, row, col); + /* The icon has been looked up in the cache add it to the front of + * the queue. The queue may get sorted if the icon view sends a + * resize-event */ + XF_DEBUG("attempting to set icon '%s' to position (%d,%d) [location in cache]", name, row, col); xfdesktop_icon_set_position(XFDESKTOP_ICON(icon), row, col); g_queue_push_head(fmanager->priv->pending_icons, icon); } else { - /* Didn't have a spot, push it to the end of the stack */ + /* Didn't have a spot, push it to the end of the stack. These will be + * added last. */ g_queue_push_tail(fmanager->priv->pending_icons, icon); + XF_DEBUG("icon '%s' didn't have a previous position", name); } if(fmanager->priv->pending_icons_id != 0) @@ -2957,7 +3024,11 @@ xfdesktop_file_icon_manager_real_init(XfdesktopIconViewManager *manager, } fmanager->priv->icon_view = icon_view; - + + /* Hook up to the resize-event so we can sort the icon queue and place + * new icons where they belong */ + g_signal_connect(G_OBJECT(fmanager->priv->icon_view), "resize-event", G_CALLBACK(icon_view_resized), fmanager); + fmanager->priv->desktop = gtk_widget_get_toplevel(GTK_WIDGET(icon_view)); g_signal_connect(G_OBJECT(fmanager->priv->desktop), "populate-root-menu", G_CALLBACK(xfdesktop_file_icon_manager_populate_context_menu), @@ -3061,7 +3132,11 @@ xfdesktop_file_icon_manager_fini(XfdesktopIconViewManager *manager) g_object_unref(fmanager->priv->enumerator); fmanager->priv->enumerator = NULL; } - + + g_signal_handlers_disconnect_by_func(G_OBJECT(fmanager->priv->icon_view), + G_CALLBACK(icon_view_resized), + fmanager); + g_signal_handlers_disconnect_by_func(G_OBJECT(fmanager->priv->desktop), G_CALLBACK(xfdesktop_file_icon_manager_populate_context_menu), fmanager); diff --git a/src/xfdesktop-icon-view.c b/src/xfdesktop-icon-view.c index bf76891..17dea70 100644 --- a/src/xfdesktop-icon-view.c +++ b/src/xfdesktop-icon-view.c @@ -93,6 +93,7 @@ enum SIG_TOGGLE_CURSOR_ITEM, SIG_MOVE_CURSOR, SIG_ACTIVATE_CURSOR_ITEM, + SIG_RESIZE_EVENT, SIG_N_SIGNALS, }; @@ -499,6 +500,15 @@ xfdesktop_icon_view_class_init(XfdesktopIconViewClass *klass) GTK_TYPE_MOVEMENT_STEP, G_TYPE_INT); + __signals[SIG_RESIZE_EVENT] = g_signal_new(I_("resize-event"), + XFDESKTOP_TYPE_ICON_VIEW, + G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION, + G_STRUCT_OFFSET(XfdesktopIconViewClass, + resize_event), + NULL, NULL, + g_cclosure_marshal_VOID__VOID, + G_TYPE_NONE, 0); + gtk_widget_class_install_style_property(widget_class, g_param_spec_uchar("label-alpha", "Label alpha", @@ -3374,13 +3384,16 @@ xfdesktop_grid_do_resize(XfdesktopIconView *icon_view) DUMP_GRID_LAYOUT(icon_view); #endif - /* Grid size did chang/e */ + /* Grid size did change */ xfdesktop_move_all_icons_to_pending_icons_list(icon_view); xfdesktop_move_all_pending_icons_to_desktop(icon_view); #if 0 /*def DEBUG*/ DUMP_GRID_LAYOUT(icon_view); #endif + + /* Fire off an event to notify others of the change */ + g_signal_emit(G_OBJECT(icon_view), __signals[SIG_RESIZE_EVENT], 0, NULL); } else { DBG("old_size == new_size updating grid"); diff --git a/src/xfdesktop-icon-view.h b/src/xfdesktop-icon-view.h index 0e4e129..41e9d26 100644 --- a/src/xfdesktop-icon-view.h +++ b/src/xfdesktop-icon-view.h @@ -66,6 +66,8 @@ struct _XfdesktopIconViewClass gboolean (*move_cursor)(XfdesktopIconView *icon_view, GtkMovementStep step, gint count); + + void (*resize_event)(XfdesktopIconView *icon_view); }; GType xfdesktop_icon_view_get_type(void) G_GNUC_CONST; -- 2.3.0