[Xfce4-commits] <thunar:nick/1.8> Load and prepare background images in separate thread.
Nick Schermer
noreply at xfce.org
Sun Aug 4 21:52:21 CEST 2013
Updating branch refs/heads/nick/1.8
to e9189f5a3139631d0ef35a63c189e5d9167712d1 (commit)
from 889ca5316b69933347ce222fcc50177c76559f74 (commit)
commit e9189f5a3139631d0ef35a63c189e5d9167712d1
Author: Nick Schermer <nick at xfce.org>
Date: Sun Aug 4 21:28:07 2013 +0200
Load and prepare background images in separate thread.
thunar/thunar-desktop-background.c | 604 ++++++++++++++++++++++--------------
thunar/thunar-gdk-extensions.c | 3 +-
2 files changed, 376 insertions(+), 231 deletions(-)
diff --git a/thunar/thunar-desktop-background.c b/thunar/thunar-desktop-background.c
index a99661a..9259a65 100644
--- a/thunar/thunar-desktop-background.c
+++ b/thunar/thunar-desktop-background.c
@@ -36,6 +36,7 @@
#include <thunar/thunar-private.h>
#include <thunar/thunar-desktop-background.h>
#include <thunar/thunar-enum-types.h>
+#include <thunar/thunar-tasks.h>
#include <thunar/thunar-gdk-extensions.h>
#define FADE_ANIMATION_USEC ((gdouble) G_USEC_PER_SEC / 2.0) /* 0.5 second */
@@ -88,6 +89,9 @@ struct _ThunarDesktopBackground
GdkWindow *source_window;
GdkPixmap *pixmap;
+ /* async to prepare images in a thread */
+ GTask *task;
+
/* fade timeout for paint() */
guint fade_timeout_id;
@@ -107,6 +111,29 @@ typedef struct
}
BackgroundFade;
+typedef struct
+{
+ /* base property for xfconf */
+ gchar *base_prop;
+
+ /* size of the monitor */
+ GdkRectangle geometry;
+
+ /* bckground style */
+ ThunarBackgroundStyle bg_style;
+
+ /* not per-monitor, but we need this later */
+ gboolean fade_animation;
+
+ /* location loaded during the async */
+ GFile *image_file;
+ GdkInterpType image_interp;
+
+ /* this is returned from the thread */
+ GdkPixbuf *pixbuf;
+}
+BackgroundAsync;
+
G_DEFINE_TYPE (ThunarDesktopBackground, thunar_desktop_background, G_TYPE_OBJECT)
@@ -183,6 +210,10 @@ thunar_desktop_background_finalize (GObject *object)
ThunarDesktopBackground *background = THUNAR_DESKTOP_BACKGROUND (object);
GdkWindow *root_window;
+ /* stop running task */
+ if (background->task != NULL)
+ thunar_tasks_cancel (background->task);
+
/* unset the backgrounds */
gdk_window_set_back_pixmap (background->source_window, NULL, FALSE);
root_window = gdk_screen_get_root_window (gdk_window_get_screen (background->source_window));
@@ -275,126 +306,6 @@ thunar_desktop_background_get_monitor_name (GdkScreen *screen,
static void
-thunar_desktop_background_paint_image (cairo_t *cr,
- const GdkRectangle *area,
- GdkInterpType interp,
- ThunarBackgroundStyle style,
- const GdkPixbuf *src_pixbuf)
-{
- gint src_w, src_h;
- GdkPixbuf *dst_pixbuf = NULL;
- gint dx, dy;
- gint dst_w, dst_h;
- gdouble wratio, hratio;
- gboolean scale_dst = FALSE;
- cairo_pattern_t *pattern;
-
- _thunar_return_if_fail (GDK_IS_PIXBUF (src_pixbuf));
-
- src_w = gdk_pixbuf_get_width (src_pixbuf);
- src_h = gdk_pixbuf_get_height (src_pixbuf);
-
- dx = area->x;
- dy = area->y;
-
- dst_w = area->width;
- dst_h = area->height;
-
- switch (style)
- {
- case THUNAR_BACKGROUND_STYLE_NONE:
- return;
-
- case THUNAR_BACKGROUND_STYLE_TILED:
- break;
-
- case THUNAR_BACKGROUND_STYLE_CENTERED:
- dx += (area->width - src_w) / 2;
- dy += (area->height - src_h) / 2;
- break;
-
- case THUNAR_BACKGROUND_STYLE_STRETCHED:
- if (src_w != dst_w || src_h != dst_h)
- {
- /* scale to fill screen */
- scale_dst = TRUE;
- }
- break;
-
- case THUNAR_BACKGROUND_STYLE_SCALED:
- if (src_w != dst_w || src_h != dst_h)
- {
- /* calculate the new dimensions */
- wratio = (gdouble) src_w / (gdouble) dst_w;
- hratio = (gdouble) src_h / (gdouble) dst_h;
-
- if (hratio > wratio)
- dst_w = rint (src_w / hratio);
- else
- dst_h = rint (src_h / wratio);
-
- /* scale to monitor, no corp */
- scale_dst = TRUE;
- }
- break;
-
- case THUNAR_BACKGROUND_STYLE_SPANNED:
- case THUNAR_BACKGROUND_STYLE_ZOOMED:
- if (src_w != dst_w || src_h != dst_h)
- {
- /* calculate the new dimensions */
- wratio = (gdouble) src_w / (gdouble) dst_w;
- hratio = (gdouble) src_h / (gdouble) dst_h;
-
- if (hratio < wratio)
- dst_w = rint (src_w / hratio);
- else
- dst_h = rint (src_h / wratio);
-
- /* scale to monitor, no corp */
- scale_dst = TRUE;
- }
- break;
- }
-
- if (scale_dst)
- {
- /* scale source */
- dst_pixbuf = gdk_pixbuf_scale_simple (src_pixbuf, MAX (1, dst_w), MAX (1, dst_h), interp);
-
- /* center on monitor */
- dx += (area->width - dst_w) / 2;
- dy += (area->height - dst_h) / 2;
- }
- else
- {
- /* no scaling was required, ref source */
- dst_pixbuf = g_object_ref (G_OBJECT (src_pixbuf));
- }
-
- /* clip area */
- cairo_save (cr);
- gdk_cairo_rectangle (cr, area);
- cairo_clip (cr);
-
- /* paint the image */
- thunar_gdk_cairo_set_source_pixbuf (cr, dst_pixbuf, dx, dy);
-
- if (style == THUNAR_BACKGROUND_STYLE_TILED)
- {
- pattern = cairo_get_source (cr);
- cairo_pattern_set_extend (pattern, CAIRO_EXTEND_REPEAT);
- }
-
- cairo_paint (cr);
- cairo_restore (cr);
-
- g_object_unref (G_OBJECT (dst_pixbuf));
-}
-
-
-
-static void
thunar_desktop_background_paint_color_fill (cairo_t *cr,
const GdkRectangle *area,
ThunarBackgroundColorStyle style,
@@ -600,161 +511,146 @@ thunar_desktop_background_fade_completed (gpointer data)
static void
-thunar_desktop_background_paint (ThunarDesktopBackground *background,
- gboolean fade_animation)
+thunar_desktop_background_paint_finished (GObject *source_object,
+ GAsyncResult *result,
+ gpointer user_data)
{
+ ThunarDesktopBackground *background = THUNAR_DESKTOP_BACKGROUND (source_object);
+ GPtrArray *monitors = user_data;
cairo_t *cr;
- GdkScreen *screen;
- gint n, n_monitors;
- GdkRectangle area;
- GdkInterpType interp;
- GdkPixbuf *pixbuf;
- cairo_surface_t *start_surface;
- cairo_surface_t *end_surface;
- BackgroundFade *fade;
- ThunarBackgroundStyle bg_style;
+ BackgroundAsync *data = g_ptr_array_index (monitors, 0);
+ guint n;
ThunarBackgroundColorStyle color_style;
- GError *error = NULL;
- gchar *monitor_name;
- gint screen_num;
gchar prop[128];
GdkColor color_start;
GdkColor color_end;
- gchar *filename;
- gchar *uri;
- gchar *base_prop;
+ cairo_surface_t *start_surface;
+ BackgroundFade *fade;
+ cairo_surface_t *end_surface;
+ cairo_pattern_t *pattern;
+ gint dx, dy;
+ gboolean fade_animation;
_thunar_return_if_fail (THUNAR_IS_DESKTOP_BACKGROUND (background));
- _thunar_return_if_fail (GDK_IS_DRAWABLE (background->pixmap));
+ _thunar_return_if_fail (background->task == G_TASK (result));
- /* stop pending animation */
- if (background->fade_timeout_id != 0)
- g_source_remove (background->fade_timeout_id);
+ /* abort on an error or cancellation */
+ if (g_task_had_error (G_TASK (result)))
+ {
+ for (n = 0; n < monitors->len; n++)
+ {
+ data = g_ptr_array_index (monitors, n);
+ if (data != NULL)
+ {
+ g_clear_object (&data->image_file);
+ g_clear_object (&data->pixbuf);
+ g_free (data->base_prop);
+ g_slice_free (BackgroundAsync, data);
+ }
+ }
+
+ g_ptr_array_free (monitors, TRUE);
+ g_object_unref (G_OBJECT (result));
+ background->task = NULL;
+
+ return;
+ }
/* prepare cairo context */
cr = gdk_cairo_create (GDK_DRAWABLE (background->pixmap));
g_assert (cairo_status (cr) == CAIRO_STATUS_SUCCESS);
/* cache the old surface for the fade animation */
+ fade_animation = data->fade_animation;
if (fade_animation
&& xfconf_channel_get_bool (background->settings, "/background/fade-animation", TRUE))
start_surface = thunar_desktop_background_get_surface (background, cr);
else
start_surface = NULL;
- /* screen info */
- screen = gdk_window_get_screen (background->source_window);
- screen_num = gdk_screen_get_number (screen);
- n_monitors = gdk_screen_get_n_monitors (screen);
-
- /* if the screen has a bit depth of less than 24bpp, using bilinear
- * filtering looks crappy (mainly with gradients). */
- if (gdk_drawable_get_depth (GDK_DRAWABLE (background->source_window)) < 24)
- interp = GDK_INTERP_HYPER;
- else
- interp = GDK_INTERP_BILINEAR;
-
- /* draw each monitor */
- for (n = 0; n < n_monitors; n++)
+ for (n = 0; n < monitors->len; n++)
{
- /* get the monitor name */
- monitor_name = thunar_desktop_background_get_monitor_name (screen, n);
-
- base_prop = g_strdup_printf ("/background/screen-%d/%s", screen_num, monitor_name);
-
- /* get background style */
- g_snprintf (prop, sizeof (prop), "%s/style", base_prop);
- bg_style = thunar_desktop_background_settings_enum (background->settings,
- THUNAR_TYPE_BACKGROUND_STYLE,
- prop, DEFAULT_BACKGROUND_STYLE);
-
- /* spanning works only on settings of the 1st monitor */
- if (bg_style == THUNAR_BACKGROUND_STYLE_SPANNED)
- {
- area.x = area.y = 0;
- area.width = gdk_screen_get_width (screen);
- area.height = gdk_screen_get_height (screen);
- }
- else
- {
- /* get area of the monitor */
- gdk_screen_get_monitor_geometry (screen, n, &area);
- }
-
- pixbuf = NULL;
-
- if (bg_style != THUNAR_BACKGROUND_STYLE_NONE)
- {
- /* get file name */
- g_snprintf (prop, sizeof (prop), "%s/uri", base_prop);
- uri = xfconf_channel_get_string (background->settings, prop, DEFAULT_BACKGROUND_URI);
-
- /* only support local files */
- if (G_LIKELY (uri != NULL
- && g_str_has_prefix (uri, "file:///")))
- {
- filename = g_filename_from_uri (uri, NULL, NULL);
- if (G_LIKELY (filename != NULL))
- {
- /* load the image into the memory (exo uses mmap) */
- pixbuf = exo_gdk_pixbuf_new_from_file_at_max_size (filename, G_MAXINT, G_MAXINT, TRUE, &error);
- if (G_UNLIKELY (pixbuf == NULL))
- {
- g_warning ("Unable to load image \"%s\": %s",
- filename, error != NULL ? error->message : "No error");
- g_error_free (error);
- }
- g_free (filename);
- }
- }
- g_free (uri);
- }
+ data = g_ptr_array_index (monitors, n);
+ if (data == NULL)
+ break;
/* check if we should draw a background color (if we are not sure the background
* image is not going to overlap the color anyway) */
- if (pixbuf == NULL
- || gdk_pixbuf_get_has_alpha (pixbuf)
- || bg_style == THUNAR_BACKGROUND_STYLE_NONE
- || bg_style == THUNAR_BACKGROUND_STYLE_TILED
- || bg_style == THUNAR_BACKGROUND_STYLE_CENTERED
- || bg_style == THUNAR_BACKGROUND_STYLE_SCALED)
+ if (data->pixbuf == NULL
+ || gdk_pixbuf_get_has_alpha (data->pixbuf)
+ || data->bg_style == THUNAR_BACKGROUND_STYLE_NONE
+ || data->bg_style == THUNAR_BACKGROUND_STYLE_TILED
+ || data->bg_style == THUNAR_BACKGROUND_STYLE_CENTERED
+ || data->bg_style == THUNAR_BACKGROUND_STYLE_SCALED)
{
/* get background style */
- g_snprintf (prop, sizeof (prop), "%s/color-style", base_prop);
+ g_snprintf (prop, sizeof (prop), "%s/color-style", data->base_prop);
color_style = thunar_desktop_background_settings_enum (background->settings,
THUNAR_TYPE_BACKGROUND_COLOR_STYLE,
prop, DEFAULT_BACKGROUND_COLOR_STYLE);
/* load the colors */
- g_snprintf (prop, sizeof (prop), "%s/color-start", base_prop);
+ g_snprintf (prop, sizeof (prop), "%s/color-start", data->base_prop);
thunar_desktop_background_settings_color (background->settings, prop,
&color_start,
DEFAULT_BACKGROUND_COLOR_START);
- g_snprintf (prop, sizeof (prop), "%s/color-end", base_prop);
- thunar_desktop_background_settings_color (background->settings, prop,
- &color_end,
- DEFAULT_BACKGROUND_COLOR_END);
+
+ if (color_style != THUNAR_BACKGROUND_COLOR_STYLE_SOLID)
+ {
+ g_snprintf (prop, sizeof (prop), "%s/color-end", data->base_prop);
+ thunar_desktop_background_settings_color (background->settings, prop,
+ &color_end,
+ DEFAULT_BACKGROUND_COLOR_END);
+ }
/* paint */
- thunar_desktop_background_paint_color_fill (cr, &area, color_style, &color_start, &color_end);
+ thunar_desktop_background_paint_color_fill (cr, &data->geometry, color_style,
+ &color_start, &color_end);
}
- if (G_LIKELY (pixbuf != NULL))
+ if (data->pixbuf != NULL)
{
+ dx = data->geometry.x;
+ dy = data->geometry.y;
+
+ if (data->bg_style != THUNAR_BACKGROUND_STYLE_TILED)
+ {
+ /* center on monitor */
+ dx += (data->geometry.width - gdk_pixbuf_get_width (data->pixbuf)) / 2;
+ dy += (data->geometry.height - gdk_pixbuf_get_height (data->pixbuf)) / 2;
+ }
+
+ /* clip the drawing area */
+ cairo_save (cr);
+ gdk_cairo_rectangle (cr, &data->geometry);
+ cairo_clip (cr);
+
/* paint the image */
- thunar_desktop_background_paint_image (cr, &area, interp, bg_style, pixbuf);
- g_object_unref (G_OBJECT (pixbuf));
- }
+ thunar_gdk_cairo_set_source_pixbuf (cr, data->pixbuf, dx, dy);
- g_free (monitor_name);
- g_free (base_prop);
+ if (data->bg_style == THUNAR_BACKGROUND_STYLE_TILED)
+ {
+ pattern = cairo_get_source (cr);
+ cairo_pattern_set_extend (pattern, CAIRO_EXTEND_REPEAT);
+ }
- /* only need to draw once for spanning */
- if (bg_style == THUNAR_BACKGROUND_STYLE_SPANNED)
- break;
+ cairo_paint (cr);
+ cairo_restore (cr);
+
+ /* drop the image */
+ g_object_unref (G_OBJECT (data->pixbuf));
+ }
+
+ /* clean the context data */
+ g_clear_object (&data->image_file);
+ g_free (data->base_prop);
+ g_slice_free (BackgroundAsync, data);
}
- /* if a fade animation was requested, start the timeout */
+ /* cleanup */
+ g_ptr_array_free (monitors, TRUE);
+
+ /* if a fade animation was requested, start the timeout */
if (start_surface != NULL)
{
end_surface = thunar_desktop_background_get_surface (background, cr);
@@ -788,6 +684,254 @@ thunar_desktop_background_paint (ThunarDesktopBackground *background,
}
cairo_destroy (cr);
+
+ g_object_unref (G_OBJECT (result));
+ background->task = NULL;
+}
+
+
+
+static void
+thunar_desktop_background_paint_thread (GTask *task,
+ gpointer source_object,
+ gpointer task_data,
+ GCancellable *cancellable)
+{
+ GPtrArray *monitors = task_data;
+ BackgroundAsync *data;
+ GFileInputStream *stream;
+ GError *error = NULL;
+ gchar *path;
+ GdkPixbuf *pixbuf;
+ GdkPixbuf *scaled;
+ guint n;
+ gboolean scale_image;
+ gint src_w, src_h;
+ gint dst_w, dst_h;
+ gdouble wratio, hratio;
+
+ for (n = 0; n < monitors->len; n++)
+ {
+ data = g_ptr_array_index (monitors, n);
+ if (data == NULL)
+ break;
+
+ /* no image on this monitor */
+ if (data->image_file == NULL)
+ continue;
+
+ pixbuf = NULL;
+
+
+ /* create the input stream */
+ stream = g_file_read (data->image_file, cancellable, &error);
+ if (stream != NULL)
+ {
+ /* load the pixbuf in all its glory */
+ pixbuf = gdk_pixbuf_new_from_stream (G_INPUT_STREAM (stream), cancellable, &error);
+ g_object_unref (G_OBJECT (stream));
+
+ /* scale if needed */
+ if (pixbuf != NULL
+ && !g_cancellable_is_cancelled (cancellable))
+ {
+ src_w = gdk_pixbuf_get_width (pixbuf);
+ src_h = gdk_pixbuf_get_height (pixbuf);
+
+ dst_w = data->geometry.width;
+ dst_h = data->geometry.height;
+
+ scale_image = FALSE;
+
+ if (src_w != dst_w || src_h != dst_h)
+ {
+ switch (data->bg_style)
+ {
+ case THUNAR_BACKGROUND_STYLE_TILED:
+ case THUNAR_BACKGROUND_STYLE_CENTERED:
+ case THUNAR_BACKGROUND_STYLE_NONE:
+ /* no need to scale */
+ break;
+
+ case THUNAR_BACKGROUND_STYLE_STRETCHED:
+ /* resize to monitor size */
+ scale_image = TRUE;
+ break;
+
+ case THUNAR_BACKGROUND_STYLE_SCALED:
+ /* calculate the new dimensions */
+ wratio = (gdouble) src_w / (gdouble) dst_w;
+ hratio = (gdouble) src_h / (gdouble) dst_h;
+
+ if (hratio > wratio)
+ dst_w = rint (src_w / hratio);
+ else
+ dst_h = rint (src_h / wratio);
+
+ scale_image = TRUE;
+ break;
+
+ case THUNAR_BACKGROUND_STYLE_SPANNED:
+ case THUNAR_BACKGROUND_STYLE_ZOOMED:
+ /* calculate the new dimensions */
+ wratio = (gdouble) src_w / (gdouble) dst_w;
+ hratio = (gdouble) src_h / (gdouble) dst_h;
+
+ if (hratio < wratio)
+ dst_w = rint (src_w / hratio);
+ else
+ dst_h = rint (src_h / wratio);
+
+ scale_image = TRUE;
+ break;
+ }
+ }
+
+ if (scale_image)
+ {
+ /* scale now, we do this for the higher
+ * resize quality we can get */
+ scaled = gdk_pixbuf_scale_simple (pixbuf,
+ dst_w, dst_h,
+ data->image_interp);
+
+ /* take over */
+ g_object_unref (G_OBJECT (pixbuf));
+ pixbuf = scaled;
+ }
+ }
+ }
+
+ if (G_UNLIKELY (error != NULL))
+ {
+ /* we don't abort the thread for this, maybe the file is
+ * removed or something like that; this does not mean
+ * we should not try to render the background for the other
+ * screens */
+ path = g_file_get_parse_name (data->image_file);
+ g_warning ("Unable to load image \"%s\": %s",
+ path, error->message);
+ g_free (path);
+ g_error_free (error);
+ }
+ else if (!g_cancellable_is_cancelled (cancellable))
+ {
+ /* store the image */
+ data->pixbuf = g_object_ref (G_OBJECT (pixbuf));
+
+ /* prepare the cairo surface */
+ if (!g_cancellable_is_cancelled (cancellable))
+ thunar_gdk_cairo_set_source_pixbuf (NULL, data->pixbuf, 0, 0);
+ }
+
+ g_clear_object (&pixbuf);
+ }
+
+ g_task_return_pointer (task, NULL, NULL);
+}
+
+
+
+static void
+thunar_desktop_background_paint (ThunarDesktopBackground *background,
+ gboolean fade_animation)
+{
+ GdkScreen *screen;
+ gint n, n_monitors;
+ GdkInterpType interp;
+ gchar *monitor_name;
+ gint screen_num;
+ gchar prop[128];
+ gchar *uri;
+ GPtrArray *monitors;
+ BackgroundAsync *data;
+
+ _thunar_return_if_fail (THUNAR_IS_DESKTOP_BACKGROUND (background));
+ _thunar_return_if_fail (GDK_IS_DRAWABLE (background->pixmap));
+
+ /* stop pending animation */
+ if (background->fade_timeout_id != 0)
+ g_source_remove (background->fade_timeout_id);
+
+ /* stop running task */
+ if (background->task != NULL)
+ {
+ thunar_tasks_cancel (background->task);
+ background->task = NULL;
+ }
+
+ /* screen info */
+ screen = gdk_window_get_screen (background->source_window);
+ screen_num = gdk_screen_get_number (screen);
+ n_monitors = gdk_screen_get_n_monitors (screen);
+
+ /* if the screen has a bit depth of less than 24bpp, using bilinear
+ * filtering looks crappy (mainly with gradients). */
+ if (gdk_drawable_get_depth (GDK_DRAWABLE (background->source_window)) < 24)
+ interp = GDK_INTERP_HYPER;
+ else
+ interp = GDK_INTERP_BILINEAR;
+
+ /* load loading structure */
+ monitors = g_ptr_array_sized_new (n_monitors);
+
+ /* draw each monitor */
+ for (n = 0; n < n_monitors; n++)
+ {
+ /* create the data structure */
+ data = g_slice_new0 (BackgroundAsync);
+ data->fade_animation = fade_animation;
+ data->image_interp = interp;
+ g_ptr_array_add (monitors, data);
+
+ /* get the base property for xfconf */
+ monitor_name = thunar_desktop_background_get_monitor_name (screen, n);
+ data->base_prop = g_strdup_printf ("/background/screen-%d/%s", screen_num, monitor_name);
+ g_free (monitor_name);
+
+ /* get background style */
+ g_snprintf (prop, sizeof (prop), "%s/style", data->base_prop);
+ data->bg_style = thunar_desktop_background_settings_enum (background->settings,
+ THUNAR_TYPE_BACKGROUND_STYLE,
+ prop, DEFAULT_BACKGROUND_STYLE);
+
+ /* spanning works only on settings of the 1st monitor */
+ if (data->bg_style == THUNAR_BACKGROUND_STYLE_SPANNED)
+ {
+ data->geometry.x = data->geometry.y = 0;
+ data->geometry.width = gdk_screen_get_width (screen);
+ data->geometry.height = gdk_screen_get_height (screen);
+ }
+ else
+ {
+ /* get area of the monitor */
+ gdk_screen_get_monitor_geometry (screen, n, &data->geometry);
+ }
+
+ if (data->bg_style != THUNAR_BACKGROUND_STYLE_NONE)
+ {
+ /* get file name */
+ g_snprintf (prop, sizeof (prop), "%s/uri", data->base_prop);
+ uri = xfconf_channel_get_string (background->settings, prop, DEFAULT_BACKGROUND_URI);
+
+ if (G_LIKELY (uri != NULL))
+ {
+ /* the image we're going to load in the thread */
+ data->image_file = g_file_new_for_uri (uri);
+ g_free (uri);
+ }
+ }
+
+ /* when an image is spanned, we only draw it once */
+ if (data->bg_style == THUNAR_BACKGROUND_STYLE_SPANNED)
+ break;
+ }
+
+ /* start a thread to load and scale the images */
+ background->task = thunar_tasks_new (background, thunar_desktop_background_paint_finished, monitors);
+ g_task_set_priority (background->task, G_PRIORITY_LOW);
+ g_task_set_task_data (background->task, monitors, NULL);
+ g_task_run_in_thread (background->task, thunar_desktop_background_paint_thread);
}
diff --git a/thunar/thunar-gdk-extensions.c b/thunar/thunar-gdk-extensions.c
index 8c1fb73..940a4ae 100644
--- a/thunar/thunar-gdk-extensions.c
+++ b/thunar/thunar-gdk-extensions.c
@@ -274,5 +274,6 @@ thunar_gdk_cairo_set_source_pixbuf (cairo_t *cr,
}
/* apply */
- cairo_set_source_surface (cr, surface, pixbuf_x, pixbuf_y);
+ if (cr != NULL)
+ cairo_set_source_surface (cr, surface, pixbuf_x, pixbuf_y);
}
More information about the Xfce4-commits
mailing list