[nautilus/wip/antoniof/draw-shadow-directly: 8/10] list-view: Draw thumbnail shadow in advance
- From: António Fernandes <antoniof src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [nautilus/wip/antoniof/draw-shadow-directly: 8/10] list-view: Draw thumbnail shadow in advance
- Date: Fri, 4 Mar 2022 15:20:57 +0000 (UTC)
commit 404996a84bd4e1229ab0948a12f535d0583294b6
Author: António Fernandes <antoniof gnome org>
Date: Mon Feb 28 13:05:40 2022 +0000
list-view: Draw thumbnail shadow in advance
Cell renderers do not have their own style context, so style classes
are applied to the tree view widget as a whole.
In order to workaround this, the thumbnail shadows have been achieved
using a css class on the whole tree view which is flipped on/off
when getting the data for each row.
This was assumedly a fragile hack, but it turns out to be worse than
that: changing the view style repeatedly hurts the performance when
loading directories with many thumbnailable files, even freezing the
application.
Let's render the shadow ourselves and immediately restore the style
context to its original state, which fixes the performance bug and is
also a more solid solution.
Fixes https://gitlab.gnome.org/GNOME/nautilus/-/issues/2169
src/nautilus-list-view.c | 63 ++++++++++++++++++++++++++++++++++--------------
1 file changed, 45 insertions(+), 18 deletions(-)
---
diff --git a/src/nautilus-list-view.c b/src/nautilus-list-view.c
index 77278fab1..941d5f5f1 100644
--- a/src/nautilus-list-view.c
+++ b/src/nautilus-list-view.c
@@ -1578,16 +1578,6 @@ starred_cell_data_func (GtkTreeViewColumn *column,
g_autofree gchar *text = NULL;
g_autofree gchar *uri = NULL;
NautilusFile *file;
- GtkStyleContext *context;
-
- /* The "thumbnail" style class is set before rendering each icon cell with
- * a thumbnail. However, style classes are not applied to each cell, but
- * alwyas to the whole GtkTreeView widget. So, before the star icon is
- * rendered, we must ensure that the style is not set, otherwise the star
- * icon is going to get the styles meant only for thumbnail icons.
- */
- context = gtk_widget_get_style_context (GTK_WIDGET (view));
- gtk_style_context_remove_class (context, "thumbnail");
gtk_tree_model_get (model, iter,
view->details->file_name_column_num, &text,
@@ -1659,10 +1649,6 @@ icon_cell_data_func (GtkTreeViewColumn *column,
&file,
-1);
- /* Hack: Set/unset the style class in advance of rendering. This makes a
- * major assumption that's all but clearly stated in the documentation of
- * GtkCellLayout: that the DataFunc is called before rendering each cell.
- */
is_thumbnail = FALSE;
if (zoom_level_is_enough_for_thumbnails (view) && file != NULL)
{
@@ -1678,11 +1664,52 @@ icon_cell_data_func (GtkTreeViewColumn *column,
if (is_thumbnail)
{
+ cairo_surface_t *new_surface;
+ cairo_t *cr;
+ int w, h;
+
+ /* The shadow extends 1px up, 3px down, and 2px left and right. For that
+ * reason, the final surface must be 4px taller and 4px wider, with the
+ * original icon starting at (2, 1).
+ *
+ * ************************* -+
+ * *#. #* -+ |
+ * *# \ #* | |
+ * *# \ #* | |
+ * *# (2, 1) #* | |
+ * *# #* | h |
+ * *# #* | | h + 4
+ * *# #* | |
+ * *# #* | |
+ * *# #* -+ |
+ * *#######################* |
+ * *#######################* |
+ * ************************* -+
+ * | |
+ * +-------------------+ :¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨:
+ * w : #### --> Solid shadow :
+ * | | : :
+ * +-----------------------+ : **** --> Blur shadow :
+ * w + 4 '.......................'
+ */
+ w = cairo_image_surface_get_width (surface);
+ h = cairo_image_surface_get_height (surface);
+
+ new_surface = cairo_surface_create_similar (surface,
+ CAIRO_CONTENT_COLOR_ALPHA,
+ w + 4,
+ h + 4);
+ cr = cairo_create (new_surface);
+
+ gtk_style_context_save (context);
gtk_style_context_add_class (context, "thumbnail");
- }
- else
- {
- gtk_style_context_remove_class (context, "thumbnail");
+ gtk_render_icon_surface (context, cr, surface, 2, 1);
+ gtk_style_context_restore (context);
+
+ cairo_destroy (cr);
+
+ cairo_surface_destroy (surface);
+ surface = new_surface;
}
g_object_set (renderer,
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]