[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Bug#863792: marked as done (unblock: mate-desktop/1.16.2-1)



Your message dated Sat, 03 Jun 2017 20:56:00 +0000
with message-id <e091fd08-86cb-7f81-3d2d-7b0b02e44091@thykier.net>
and subject line Re: Bug#863792: unblock: mate-desktop/1.16.2-1
has caused the Debian Bug report #863792,
regarding unblock: mate-desktop/1.16.2-1
to be marked as done.

This means that you claim that the problem has been dealt with.
If this is not the case it is now your responsibility to reopen the
Bug report if necessary, and/or fix the problem forthwith.

(NB: If you are a system administrator and have no idea what this
message is talking about, this may indicate a serious mail system
misconfiguration somewhere. Please contact owner@bugs.debian.org
immediately.)


-- 
863792: http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=863792
Debian Bug Tracking System
Contact owner@bugs.debian.org with problems
--- Begin Message ---
Package: release.debian.org
Severity: normal
User: release.debian.org@packages.debian.org
Usertags: unblock

Please consider unblocking of not-yet-uploaded package mate-desktop

This version will fix observed problems with solid background colors
currently existing in Debian 9's MATE desktop.

This unblock is needed for getting last minute caja/1.16.6-1 fixes in.
See: https://bugs.debian.org/863791 for further details.

unblock mate-desktop/1.16.2-1

-- System Information:
Debian Release: 9.0
  APT prefers testing
  APT policy: (990, 'testing')
Architecture: amd64
 (x86_64)
Foreign Architectures: i386

Kernel: Linux 4.9.0-2-amd64 (SMP w/4 CPU cores)
Locale: LANG=en_US.UTF-8, LC_CTYPE=en_US.UTF-8 (charmap=UTF-8)
Shell: /bin/sh linked to /bin/dash
Init: systemd (via /run/systemd/system)
diff -Nru mate-desktop-1.16.1/configure.ac mate-desktop-1.16.2/configure.ac
--- mate-desktop-1.16.1/configure.ac	2016-10-18 14:36:21.000000000 +0200
+++ mate-desktop-1.16.2/configure.ac	2017-03-25 22:30:16.000000000 +0100
@@ -1,6 +1,6 @@
 m4_define([mate_platform], [1])
 m4_define([mate_minor], [16])
-m4_define([mate_micro], [1])
+m4_define([mate_micro], [2])
 
 m4_define(mate_version, [mate_platform.mate_minor.mate_micro]),
 
diff -Nru mate-desktop-1.16.1/debian/changelog mate-desktop-1.16.2/debian/changelog
--- mate-desktop-1.16.1/debian/changelog	2016-10-20 13:19:38.000000000 +0200
+++ mate-desktop-1.16.2/debian/changelog	2017-04-28 22:28:53.000000000 +0200
@@ -1,3 +1,11 @@
+mate-desktop (1.16.2-1) unstable; urgency=medium
+
+  * New upstream release.
+    - Fix desktops look'n'feel with solid background color. (Closes:
+      #856027).
+
+ -- Mike Gabriel <sunweaver@debian.org>  Fri, 28 Apr 2017 22:28:53 +0200
+
 mate-desktop (1.16.1-1) unstable; urgency=medium
 
   * New upstream release.
diff -Nru mate-desktop-1.16.1/libmate-desktop/mate-aboutdialog.c mate-desktop-1.16.2/libmate-desktop/mate-aboutdialog.c
--- mate-desktop-1.16.1/libmate-desktop/mate-aboutdialog.c	2016-10-18 14:36:21.000000000 +0200
+++ mate-desktop-1.16.2/libmate-desktop/mate-aboutdialog.c	2017-03-25 22:30:16.000000000 +0100
@@ -537,7 +537,7 @@
   priv->website_label = button = gtk_label_new ("");
   gtk_widget_set_no_show_all (button, TRUE);
   gtk_label_set_selectable (GTK_LABEL (button), TRUE);
-  gtk_box_pack_start (GTK_BOX (hbox), button, FALSE, FALSE, 0);
+  gtk_box_pack_start (GTK_BOX (hbox), button, TRUE, FALSE, 0);
   g_signal_connect_swapped (button, "activate-link",
                             G_CALLBACK (mate_about_dialog_activate_link), about);
 
diff -Nru mate-desktop-1.16.1/libmate-desktop/mate-bg.c mate-desktop-1.16.2/libmate-desktop/mate-bg.c
--- mate-desktop-1.16.1/libmate-desktop/mate-bg.c	2016-10-18 14:36:21.000000000 +0200
+++ mate-desktop-1.16.2/libmate-desktop/mate-bg.c	2017-03-25 22:30:16.000000000 +0100
@@ -49,15 +49,6 @@
 
 #if GTK_CHECK_VERSION (3, 0, 0)
 # include <cairo-xlib.h>
-#else
-#define cairo_surface_t		GdkPixmap
-#define cairo_create		gdk_cairo_create
-#define cairo_surface_destroy	g_object_unref
-#define cairo_xlib_surface_get_drawable	GDK_DRAWABLE_XID
-#define gdk_error_trap_pop_ignored	gdk_error_trap_pop
-#define mate_bg_get_surface_from_root		mate_bg_get_pixmap_from_root
-#define mate_bg_crossfade_set_start_surface	mate_bg_crossfade_set_start_pixmap
-#define mate_bg_crossfade_set_end_surface	mate_bg_crossfade_set_end_pixmap
 #endif
 
 #define MATE_BG_CACHE_DIR "mate/background"
@@ -879,9 +870,9 @@
 	case MATE_BG_COLOR_SOLID:
 		/* not really a big deal to ignore the area of interest */
 #if GTK_CHECK_VERSION (3, 0, 0)
-		pixel = (((guint) bg->primary.red * 65535) >> 8) << 24      |
-			(((guint) bg->primary.green * 65535) >> 8) << 24    |
-			(((guint) bg->primary.blue * 65535) >> 8) << 24      |
+		pixel = ((guint) (bg->primary.red * 0xff) << 24)   |
+			((guint) (bg->primary.green * 0xff) << 16) |
+			((guint) (bg->primary.blue * 0xff) << 8)   |
 #else
 		pixel = ((bg->primary.red >> 8) << 24)      |
 			((bg->primary.green >> 8) << 16)    |
@@ -1219,7 +1210,11 @@
 {
 	int pm_width, pm_height;
 
+#if GTK_CHECK_VERSION (3, 0, 0)
 	cairo_surface_t *surface;
+#else
+	GdkPixmap *pixmap;
+#endif
 	cairo_t *cr;
 
 	g_return_val_if_fail (bg != NULL, NULL);
@@ -1238,19 +1233,27 @@
 
 	if (root)
 	{
+#if GTK_CHECK_VERSION (3, 0, 0)
 		surface = make_root_pixmap (window, pm_width, pm_height);
+#else
+		pixmap = make_root_pixmap (window, pm_width, pm_height);
+#endif
 	}
 	else
 	{
-#  if GTK_CHECK_VERSION (3, 0, 0)
+#if GTK_CHECK_VERSION (3, 0, 0)
 		surface = gdk_window_create_similar_surface (window, CAIRO_CONTENT_COLOR,
 							     pm_width, pm_height);
-#  else
-		surface = gdk_pixmap_new (window, pm_width, pm_height, -1);
-#  endif
+#else
+		pixmap = gdk_pixmap_new (window, pm_width, pm_height, -1);
+#endif
 	}
 
+#if GTK_CHECK_VERSION (3, 0, 0)
 	cr = cairo_create (surface);
+#else
+	cr = gdk_cairo_create (pixmap);
+#endif
 	if (!bg->filename && bg->color_type == MATE_BG_COLOR_SOLID) {
 #if GTK_CHECK_VERSION (3, 0, 0)
 		gdk_cairo_set_source_rgba (cr, &(bg->primary));
@@ -1273,7 +1276,11 @@
 
 	cairo_destroy (cr);
 
+#if GTK_CHECK_VERSION (3, 0, 0)
 	return surface;
+#else
+	return pixmap;
+#endif
 }
 
 
@@ -1355,7 +1362,11 @@
 	char *disp_name = DisplayString (GDK_WINDOW_XDISPLAY (window));
 	Display *display;
 	Pixmap xpixmap;
+#if GTK_CHECK_VERSION (3, 0, 0)
 	cairo_surface_t *surface;
+#else
+	GdkPixmap *pixmap;
+#endif
 	int depth;
 
 	/* Desktop background pixmap should be created from dummy X client since most
@@ -1376,16 +1387,18 @@
 	XSetCloseDownMode (display, RetainPermanent);
 	XCloseDisplay (display);
 
-#  if GTK_CHECK_VERSION (3, 0, 0)
+#if GTK_CHECK_VERSION (3, 0, 0)
 	surface = cairo_xlib_surface_create (GDK_SCREEN_XDISPLAY (screen), xpixmap,
                                              GDK_VISUAL_XVISUAL (gdk_screen_get_system_visual (screen)),
         				     width, height);
-#  else
-	surface = gdk_pixmap_foreign_new_for_screen (screen, xpixmap, width, height, depth);
-	gdk_drawable_set_colormap (surface, gdk_drawable_get_colormap (window));
-#  endif
 
 	return surface;
+#else
+	pixmap = gdk_pixmap_foreign_new_for_screen (screen, xpixmap, width, height, depth);
+	gdk_drawable_set_colormap (pixmap, gdk_drawable_get_colormap (window));
+
+	return pixmap;
+#endif
 }
 
 static gboolean
@@ -1527,8 +1540,13 @@
 	Atom type;
 	Display *display;
 	int screen_num;
+#if GTK_CHECK_VERSION (3, 0, 0)
 	cairo_surface_t *surface;
 	cairo_surface_t *source_pixmap;
+#else
+	GdkPixmap *pixmap;
+	GdkPixmap *source_pixmap;
+#endif
 	int width, height;
 	cairo_t *cr;
 
@@ -1541,7 +1559,11 @@
 				     0L, 1L, False, XA_PIXMAP,
 				     &type, &format, &nitems, &bytes_after,
 				     &data);
+#if GTK_CHECK_VERSION (3, 0, 0)
 	surface = NULL;
+#else
+	pixmap = NULL;
+#endif
 	source_pixmap = NULL;
 
 	if (result != Success || type != XA_PIXMAP ||
@@ -1551,14 +1573,14 @@
 	}
 
 	if (data != NULL) {
-		gdk_error_trap_push ();
-
 #  if GTK_CHECK_VERSION (3, 0, 0)
 		Pixmap xpixmap = *(Pixmap *) data;
 		Window root_return;
 		int x_ret, y_ret;
 		unsigned int w_ret, h_ret, bw_ret, depth_ret;
 
+		gdk_error_trap_push ();
+
 		if (XGetGeometry (GDK_SCREEN_XDISPLAY (screen),
 				  xpixmap,
 				  &root_return,
@@ -1572,6 +1594,7 @@
 
 		gdk_error_trap_pop_ignored ();
 #  else
+		gdk_error_trap_push ();
 		source_pixmap = gdk_pixmap_foreign_new (*(Pixmap *) data);
 		gdk_error_trap_pop ();
 
@@ -1608,15 +1631,19 @@
 							     CAIRO_CONTENT_COLOR,
 							     width, height);
 	}
+
+	if (source_pixmap != NULL)
+		cairo_surface_destroy (source_pixmap);
 #  else
-	surface = gdk_pixmap_new (source_pixmap != NULL? source_pixmap :
+	pixmap = gdk_pixmap_new (source_pixmap != NULL? source_pixmap :
 				 gdk_screen_get_root_window (screen),
 				 width, height, -1);
 
-	cr = gdk_cairo_create (surface);
+	cr = gdk_cairo_create (pixmap);
 	if (source_pixmap != NULL) {
+		cairo_pattern_t *pattern;
 		gdk_cairo_set_source_pixmap (cr, source_pixmap, 0, 0);
-		cairo_pattern_t *pattern = cairo_get_source (cr);
+		pattern = cairo_get_source (cr);
 		cairo_pattern_set_extend (pattern, CAIRO_EXTEND_REPEAT);
 	} else {
 		cairo_set_source_rgb (cr, 0.0, 0.0, 0.0);
@@ -1624,19 +1651,23 @@
 	cairo_paint (cr);
 
 	if (cairo_status (cr) != CAIRO_STATUS_SUCCESS) {
-		g_object_unref (surface);
-		surface = NULL;
+		g_object_unref (pixmap);
+		pixmap = NULL;
 	}
 	cairo_destroy (cr);
-#  endif
 
 	if (source_pixmap != NULL)
-		cairo_surface_destroy (source_pixmap);
+		g_object_unref (source_pixmap);
+#  endif
 
 	if (data != NULL)
 		XFree (data);
 
+#if GTK_CHECK_VERSION (3, 0, 0)
 	return surface;
+#else
+	return pixmap;
+#endif
 }
 
 /* Sets the "ESETROOT_PMAP_ID" property to later be used to free the pixmap,
@@ -1651,7 +1682,7 @@
 	Atom     atoms[G_N_ELEMENTS(atom_names)] = {0};
 
 	Atom     type;
-	int      format;
+	int      format, result;
 	unsigned long nitems, after;
 	unsigned char *data_root, *data_esetroot;
 
@@ -1659,20 +1690,24 @@
 	 * This method is to avoid multiple round-trips to Xserver
 	 */
 	if (XInternAtoms (display, atom_names, G_N_ELEMENTS(atom_names), True, atoms) &&
-	    atoms[0] != None && atoms[1] != None)
-	{
-		XGetWindowProperty (display, xroot, atoms[0], 0L, 1L, False, AnyPropertyType,
-				    &type, &format, &nitems, &after, &data_root);
-		if (data_root && type == XA_PIXMAP && format == 32 && nitems == 1)
-		{
-			XGetWindowProperty (display, xroot, atoms[1], 0L, 1L, False, AnyPropertyType,
-					    &type, &format, &nitems, &after, &data_esetroot);
-			if (data_esetroot && type == XA_PIXMAP && format == 32 && nitems == 1)
-			{
+	    atoms[0] != None && atoms[1] != None) {
+		result = XGetWindowProperty (display, xroot, atoms[0], 0L, 1L,
+		                             False, AnyPropertyType,
+		                             &type, &format, &nitems, &after,
+		                             &data_root);
+
+		if (data_root != NULL && result == Success &&
+		    type == XA_PIXMAP && format == 32 && nitems == 1) {
+			result = XGetWindowProperty (display, xroot, atoms[1],
+			                             0L, 1L, False,
+			                             AnyPropertyType,
+			                             &type, &format, &nitems,
+			                             &after, &data_esetroot);
+
+			if (data_esetroot != NULL && result == Success &&
+			    type == XA_PIXMAP && format == 32 && nitems == 1) {
 				Pixmap xrootpmap = *((Pixmap *) data_root);
 				Pixmap esetrootpmap = *((Pixmap *) data_esetroot);
-				XFree (data_root);
-				XFree (data_esetroot);
 
 				gdk_error_trap_push ();
 				if (xrootpmap && xrootpmap == esetrootpmap) {
@@ -1681,12 +1716,20 @@
 				if (esetrootpmap && esetrootpmap != xrootpmap) {
 					XKillClient (display, esetrootpmap);
 				}
-#			    if !GTK_CHECK_VERSION (3, 0, 0)
-				XSync (display, False);
-#			    endif
+#if GTK_CHECK_VERSION (3, 0, 0)
 				gdk_error_trap_pop_ignored ();
+#else
+				XSync (display, False);
+				gdk_error_trap_pop ();
+#endif
+			}
+			if (data_esetroot != NULL) {
+				XFree (data_esetroot);
 			}
 		}
+		if (data_root != NULL) {
+			XFree (data_root);
+		}
 	}
 
 	/* Get atoms for both properties in an array, create them if needed.
@@ -1723,21 +1766,25 @@
 #if GTK_CHECK_VERSION (3, 0, 0)
 mate_bg_set_surface_as_root (GdkScreen *screen, cairo_surface_t *surface)
 #else
-mate_bg_set_pixmap_as_root  (GdkScreen *screen, GdkPixmap *surface)
+mate_bg_set_pixmap_as_root  (GdkScreen *screen, GdkPixmap *pixmap)
 #endif
 {
 	g_return_if_fail (screen != NULL);
 #  if GTK_CHECK_VERSION (3, 0, 0)
 	g_return_if_fail (cairo_surface_get_type (surface) == CAIRO_SURFACE_TYPE_XLIB);
 #  else
-	g_return_if_fail (surface != NULL);
+	g_return_if_fail (pixmap != NULL);
 #  endif
 
 	/* Desktop background pixmap should be created from dummy X client since most
 	 * applications will try to kill it with XKillClient later when changing pixmap
 	 */
 	Display    *display      = GDK_DISPLAY_XDISPLAY (gdk_screen_get_display (screen));
+#if GTK_CHECK_VERSION (3, 0, 0)
 	Pixmap      pixmap_id    = cairo_xlib_surface_get_drawable (surface);
+#else
+	Pixmap      pixmap_id    = GDK_DRAWABLE_XID (pixmap);
+#endif
 	Window      xroot        = RootWindow (display, gdk_screen_get_number (screen));
 
 	XGrabServer (display);
@@ -1768,32 +1815,65 @@
 		 			    cairo_surface_t *surface)
 #else
 mate_bg_set_pixmap_as_root_with_crossfade (GdkScreen *screen,
-		 			   GdkPixmap *surface)
+		 			   GdkPixmap *pixmap)
 #endif
 {
+	GdkWindow       *root_window;
+	int              width, height;
+	MateBGCrossfade *fade;
+	cairo_t         *cr;
+#if GTK_CHECK_VERSION (3, 0, 0)
+	cairo_surface_t *old_surface;
+#else
+	GdkPixmap       *old_pixmap;
+#endif
+
 	g_return_val_if_fail (screen != NULL, NULL);
+#if GTK_CHECK_VERSION (3, 0, 0)
 	g_return_val_if_fail (surface != NULL, NULL);
+#else
+	g_return_val_if_fail (pixmap != NULL, NULL);
+#endif
 
-	GdkWindow  *root_window  = gdk_screen_get_root_window (screen);
-	int         width        = gdk_screen_get_width (screen);
-	int         height       = gdk_screen_get_height (screen);
-
-	MateBGCrossfade *fade    = mate_bg_crossfade_new (width, height);
+	root_window = gdk_screen_get_root_window (screen);
+	width       = gdk_window_get_width (root_window);
+	height      = gdk_window_get_height (root_window);
+	fade        = mate_bg_crossfade_new (width, height);
+#if GTK_CHECK_VERSION (3, 0, 0)
+	old_surface = mate_bg_get_surface_from_root (screen);
 
-	Display    *display      = GDK_DISPLAY_XDISPLAY (gdk_screen_get_display (screen));
-	Pixmap      pixmap_id    = cairo_xlib_surface_get_drawable (surface);
+	mate_bg_crossfade_set_start_surface (fade, old_surface);
+	mate_bg_crossfade_set_end_surface (fade, surface);
+#else
+	old_pixmap = mate_bg_get_pixmap_from_root (screen);
 
-	XGrabServer (display);
-	cairo_surface_t *old_surface = mate_bg_get_surface_from_root (screen);
-	mate_bg_set_root_pixmap_id (screen, display, pixmap_id);
+	mate_bg_crossfade_set_start_pixmap (fade, old_pixmap);
+	mate_bg_crossfade_set_end_pixmap (fade, pixmap);
+#endif
 
-	mate_bg_crossfade_set_start_surface (fade, old_surface);
+	/* Before setting the surface as a root pixmap, let's have it draw
+	 * the old stuff, just so it won't be noticable
+	 * (crossfade will later get it back)
+	 */
+#if GTK_CHECK_VERSION (3, 0, 0)
+	cr = cairo_create (surface);
+	cairo_set_source_surface (cr, old_surface, 0, 0);
+#else
+	cr = gdk_cairo_create (pixmap);
+	gdk_cairo_set_source_pixmap (cr, old_pixmap, 0, 0);
+#endif
+	cairo_pattern_set_extend (cairo_get_source (cr), CAIRO_EXTEND_REPEAT);
+	cairo_paint (cr);
+	cairo_destroy (cr);
+#if GTK_CHECK_VERSION (3, 0, 0)
 	cairo_surface_destroy (old_surface);
-	mate_bg_crossfade_set_end_surface (fade, surface);
 
-	XFlush (display);
-	XUngrabServer (display);
+	mate_bg_set_surface_as_root (screen, surface);
+#else
+	g_object_unref (old_pixmap);
 
+	mate_bg_set_pixmap_as_root (screen, pixmap);
+#endif
 	mate_bg_crossfade_start (fade, root_window);
 
 	return fade;
diff -Nru mate-desktop-1.16.1/libmate-desktop/mate-bg-crossfade.c mate-desktop-1.16.2/libmate-desktop/mate-bg-crossfade.c
--- mate-desktop-1.16.1/libmate-desktop/mate-bg-crossfade.c	2016-10-18 14:36:21.000000000 +0200
+++ mate-desktop-1.16.2/libmate-desktop/mate-bg-crossfade.c	2017-03-25 22:30:16.000000000 +0100
@@ -38,19 +38,14 @@
 #include <mate-bg.h>
 #include "mate-bg-crossfade.h"
 
-#if !GTK_CHECK_VERSION(3, 0, 0)
-#define cairo_surface_t GdkPixmap
-#define cairo_create gdk_cairo_create
-#define cairo_set_source_surface gdk_cairo_set_source_pixmap
-#define cairo_surface_destroy g_object_unref
-#endif
-
 struct _MateBGCrossfadePrivate
 {
 	GdkWindow       *window;
+	GtkWidget       *widget;
 	int              width;
 	int              height;
 	cairo_surface_t *fading_surface;
+	cairo_surface_t *start_surface;
 	cairo_surface_t *end_surface;
 	gdouble          start_time;
 	gdouble          total_duration;
@@ -143,6 +138,11 @@
 		fade->priv->fading_surface = NULL;
 	}
 
+	if (fade->priv->start_surface != NULL) {
+		cairo_surface_destroy (fade->priv->start_surface);
+		fade->priv->start_surface = NULL;
+	}
+
 	if (fade->priv->end_surface != NULL) {
 		cairo_surface_destroy (fade->priv->end_surface);
 		fade->priv->end_surface = NULL;
@@ -210,7 +210,10 @@
 {
 	fade->priv = MATE_BG_CROSSFADE_GET_PRIVATE (fade);
 
+	fade->priv->window = NULL;
+	fade->priv->widget = NULL;
 	fade->priv->fading_surface = NULL;
+	fade->priv->start_surface = NULL;
 	fade->priv->end_surface = NULL;
 	fade->priv->timeout_id = 0;
 }
@@ -245,7 +248,6 @@
 	cairo_surface_t *copy;
 	cairo_t *cr;
 
-#if GTK_CHECK_VERSION (3, 0, 0)
 	if (surface == NULL)
 	{
 		copy = gdk_window_create_similar_surface (gdk_get_default_root_window (),
@@ -258,9 +260,6 @@
 		                                     cairo_surface_get_content (surface),
 		                                     width, height);
 	}
-#else
-	copy = gdk_pixmap_new(surface, width, height, surface == NULL? 24 : -1);
-#endif
 
 	cr = cairo_create (copy);
 
@@ -303,6 +302,48 @@
 	return copy;
 }
 
+#if !GTK_CHECK_VERSION (3, 0, 0)
+static cairo_surface_t *
+tile_pixmap (GdkPixmap *pixmap,
+             int        width,
+             int        height)
+{
+	cairo_surface_t *copy;
+	cairo_t *cr;
+
+	copy = gdk_window_create_similar_surface (gdk_get_default_root_window (),
+	                                          CAIRO_CONTENT_COLOR,
+	                                          width, height);
+	cr = cairo_create (copy);
+
+	if (pixmap != NULL)
+	{
+		cairo_pattern_t *pattern;
+		gdk_cairo_set_source_pixmap (cr, pixmap, 0.0, 0.0);
+		pattern = cairo_get_source (cr);
+		cairo_pattern_set_extend (pattern, CAIRO_EXTEND_REPEAT);
+	}
+	else
+	{
+		GtkStyle *style;
+		style = gtk_widget_get_default_style ();
+		gdk_cairo_set_source_color (cr, &style->bg[GTK_STATE_NORMAL]);
+	}
+
+	cairo_paint (cr);
+
+	if (cairo_status (cr) != CAIRO_STATUS_SUCCESS)
+	{
+		cairo_surface_destroy (copy);
+		copy = NULL;
+	}
+
+	cairo_destroy(cr);
+
+	return copy;
+}
+#endif
+
 /**
  * mate_bg_crossfade_set_start_surface:
  * @fade: a #MateBGCrossfade
@@ -319,22 +360,26 @@
 #if GTK_CHECK_VERSION(3, 0, 0)
 mate_bg_crossfade_set_start_surface (MateBGCrossfade* fade, cairo_surface_t *surface)
 #else
-mate_bg_crossfade_set_start_pixmap (MateBGCrossfade* fade, GdkPixmap *surface)
+mate_bg_crossfade_set_start_pixmap (MateBGCrossfade* fade, GdkPixmap *pixmap)
 #endif
 {
 	g_return_val_if_fail (MATE_IS_BG_CROSSFADE (fade), FALSE);
 
-	if (fade->priv->fading_surface != NULL)
+	if (fade->priv->start_surface != NULL)
 	{
-		cairo_surface_destroy (fade->priv->fading_surface);
-		fade->priv->fading_surface = NULL;
+		cairo_surface_destroy (fade->priv->start_surface);
+		fade->priv->start_surface = NULL;
 	}
 
-	fade->priv->fading_surface = tile_surface (surface,
-						   fade->priv->width,
-						   fade->priv->height);
+#if GTK_CHECK_VERSION(3, 0, 0)
+	fade->priv->start_surface = tile_surface (surface,
+#else
+	fade->priv->start_surface = tile_pixmap  (pixmap,
+#endif
+	                                          fade->priv->width,
+	                                          fade->priv->height);
 
-	return fade->priv->fading_surface != NULL;
+	return fade->priv->start_surface != NULL;
 }
 
 static gdouble
@@ -368,7 +413,7 @@
 #if GTK_CHECK_VERSION(3, 0, 0)
 mate_bg_crossfade_set_end_surface (MateBGCrossfade* fade, cairo_surface_t *surface)
 #else
-mate_bg_crossfade_set_end_pixmap (MateBGCrossfade* fade, GdkPixmap *surface)
+mate_bg_crossfade_set_end_pixmap (MateBGCrossfade* fade, GdkPixmap *pixmap)
 #endif
 {
 	g_return_val_if_fail (MATE_IS_BG_CROSSFADE (fade), FALSE);
@@ -378,9 +423,13 @@
 		fade->priv->end_surface = NULL;
 	}
 
+#if GTK_CHECK_VERSION(3, 0, 0)
 	fade->priv->end_surface = tile_surface (surface,
-					        fade->priv->width,
-					        fade->priv->height);
+#else
+	fade->priv->end_surface = tile_pixmap  (pixmap,
+#endif
+	                                        fade->priv->width,
+	                                        fade->priv->height);
 
 	/* Reset timer in case we're called while animating
 	 */
@@ -407,23 +456,114 @@
 }
 
 static void
+send_root_property_change_notification (MateBGCrossfade *fade)
+{
+        long zero_length_pixmap = 0;
+
+        /* We do a zero length append to force a change notification,
+         * without changing the value */
+        XChangeProperty (GDK_WINDOW_XDISPLAY (fade->priv->window),
+                         GDK_WINDOW_XID (fade->priv->window),
+                         gdk_x11_get_xatom_by_name ("_XROOTPMAP_ID"),
+                         XA_PIXMAP, 32, PropModeAppend,
+                         (unsigned char *) &zero_length_pixmap, 0);
+}
+
+static void
 draw_background (MateBGCrossfade *fade)
 {
-	if (gdk_window_get_window_type (fade->priv->window) == GDK_WINDOW_ROOT) {
-		XClearArea (GDK_WINDOW_XDISPLAY (fade->priv->window),
-			    GDK_WINDOW_XID (fade->priv->window),
-			    0, 0,
-			    gdk_window_get_width (fade->priv->window),
-			    gdk_window_get_height (fade->priv->window),
-			    False);
-		gdk_flush ();
-	} else {
+	if (fade->priv->widget != NULL) {
+		gtk_widget_queue_draw (fade->priv->widget);
+	} else if (gdk_window_get_window_type (fade->priv->window) != GDK_WINDOW_ROOT) {
+#if GTK_CHECK_VERSION (3, 22, 0)
+		cairo_t           *cr;
+		cairo_region_t    *region;
+		GdkDrawingContext *draw_context;
+
+		region = gdk_window_get_visible_region (fade->priv->window);
+		draw_context = gdk_window_begin_draw_frame (fade->priv->window,
+		                                            region);
+		cr = gdk_drawing_context_get_cairo_context (draw_context);
+		cairo_set_operator (cr, CAIRO_OPERATOR_OVER);
+		cairo_set_source_surface (cr, fade->priv->fading_surface, 0, 0);
+		cairo_paint (cr);
+		gdk_window_end_draw_frame (fade->priv->window, draw_context);
+		cairo_region_destroy (region);
+#elif GTK_CHECK_VERSION (3, 0, 0)
+		cairo_pattern_t *pattern;
+
+		pattern =
+		  cairo_pattern_create_for_surface (fade->priv->fading_surface);
+		gdk_window_set_background_pattern (fade->priv->window, pattern);
+		cairo_pattern_destroy (pattern);
 		gdk_window_invalidate_rect (fade->priv->window, NULL, FALSE);
 		gdk_window_process_updates (fade->priv->window, FALSE);
+#else
+		cairo_t   *cr;
+		GdkPixmap *pixmap;
+
+		pixmap = gdk_pixmap_new (fade->priv->window,
+		                         fade->priv->width, fade->priv->height,
+		                         -1);
+		cr = gdk_cairo_create (pixmap);
+		cairo_set_operator (cr, CAIRO_OPERATOR_OVER);
+		cairo_set_source_surface (cr, fade->priv->fading_surface, 0, 0);
+		cairo_paint (cr);
+		cairo_destroy (cr);
+		gdk_window_set_back_pixmap (fade->priv->window, pixmap, FALSE);
+		g_object_unref (pixmap);
+		gdk_window_invalidate_rect (fade->priv->window, NULL, FALSE);
+		gdk_window_process_updates (fade->priv->window, FALSE);
+#endif
+	} else {
+		Display *xdisplay = GDK_WINDOW_XDISPLAY (fade->priv->window);
+		gdk_error_trap_push ();
+		XGrabServer (xdisplay);
+		XClearWindow (xdisplay, GDK_WINDOW_XID (fade->priv->window));
+		send_root_property_change_notification (fade);
+		XFlush (xdisplay);
+		XUngrabServer (xdisplay);
+#if GTK_CHECK_VERSION (3, 0, 0)
+		gdk_error_trap_pop_ignored ();
+#else
+		gdk_error_trap_pop ();
+#endif
 	}
 }
 
 static gboolean
+on_widget_draw (GtkWidget       *widget,
+#if GTK_CHECK_VERSION (3, 0, 0)
+                cairo_t         *cr,
+#else
+                GdkEventExpose  *event,
+#endif
+                MateBGCrossfade *fade)
+{
+#if !GTK_CHECK_VERSION (3, 0, 0)
+	cairo_t *cr;
+
+#endif
+	g_assert (fade->priv->fading_surface != NULL);
+
+#if !GTK_CHECK_VERSION (3, 0, 0)
+	cr = gdk_cairo_create (event->window);
+
+	gdk_cairo_rectangle (cr, &event->area);
+	cairo_clip (cr);
+
+#endif
+	cairo_set_source_surface (cr, fade->priv->fading_surface, 0, 0);
+	cairo_pattern_set_extend (cairo_get_source (cr), CAIRO_EXTEND_REPEAT);
+	cairo_paint (cr);
+
+#if !GTK_CHECK_VERSION (3, 0, 0)
+	cairo_destroy (cr);
+#endif
+	return FALSE;
+}
+
+static gboolean
 on_tick (MateBGCrossfade *fade)
 {
 	gdouble now, percent_done;
@@ -447,7 +587,8 @@
 		return on_tick (fade);
 	}
 
-	if (fade->priv->fading_surface == NULL) {
+	if (fade->priv->fading_surface == NULL ||
+	    fade->priv->end_surface == NULL) {
 		return FALSE;
 	}
 
@@ -481,60 +622,175 @@
 static void
 on_finished (MateBGCrossfade *fade)
 {
+	cairo_t *cr;
+
 	if (fade->priv->timeout_id == 0)
 		return;
 
+	g_assert (fade->priv->fading_surface != NULL);
 	g_assert (fade->priv->end_surface != NULL);
 
-#if GTK_CHECK_VERSION (3, 0, 0)
-	cairo_pattern_t *pattern;
-	pattern = cairo_pattern_create_for_surface (fade->priv->end_surface);
-	gdk_window_set_background_pattern (fade->priv->window, pattern);
-	cairo_pattern_destroy (pattern);
-#else
-	gdk_window_set_back_pixmap (fade->priv->window,
-				    fade->priv->end_surface,
-				    FALSE);
-#endif
+	cr = cairo_create (fade->priv->fading_surface);
+	cairo_set_source_surface (cr, fade->priv->end_surface, 0, 0);
+	cairo_paint (cr);
+	cairo_destroy (cr);
 	draw_background (fade);
 
+	cairo_surface_destroy (fade->priv->fading_surface);
+	fade->priv->fading_surface = NULL;
+
 	cairo_surface_destroy (fade->priv->end_surface);
 	fade->priv->end_surface = NULL;
 
-	g_assert (fade->priv->fading_surface != NULL);
+	g_assert (fade->priv->start_surface != NULL);
 
-	cairo_surface_destroy (fade->priv->fading_surface);
-	fade->priv->fading_surface = NULL;
+	cairo_surface_destroy (fade->priv->start_surface);
+	fade->priv->start_surface = NULL;
+
+	if (fade->priv->widget != NULL) {
+		g_signal_handlers_disconnect_by_func (fade->priv->widget,
+		                                      (GCallback) on_widget_draw,
+		                                      fade);
+	}
+	fade->priv->widget = NULL;
 
 	fade->priv->timeout_id = 0;
 	g_signal_emit (fade, signals[FINISHED], 0, fade->priv->window);
 }
 
+/* This function queries the _XROOTPMAP_ID property from the root window
+ * to determine the current root window background pixmap and returns a
+ * surface to draw directly to it.
+ * If _XROOTPMAP_ID is not set, then NULL returned.
+ */
+static cairo_surface_t *
+get_root_pixmap_id_surface (GdkDisplay *display)
+{
+	GdkScreen       *screen;
+	Display         *xdisplay;
+	Visual          *xvisual;
+	Window           xroot;
+	Atom             type;
+	int              format, result;
+	unsigned long    nitems, bytes_after;
+	unsigned char   *data;
+	cairo_surface_t *surface = NULL;
+
+	g_return_val_if_fail (display != NULL, NULL);
+
+	screen   = gdk_display_get_default_screen (display);
+	xdisplay = GDK_DISPLAY_XDISPLAY (display);
+	xvisual  = GDK_VISUAL_XVISUAL (gdk_screen_get_system_visual (screen));
+	xroot    = RootWindow (xdisplay, GDK_SCREEN_XNUMBER (screen));
+
+	result = XGetWindowProperty (xdisplay, xroot,
+				     gdk_x11_get_xatom_by_name ("_XROOTPMAP_ID"),
+				     0L, 1L, False, XA_PIXMAP,
+				     &type, &format, &nitems, &bytes_after,
+				     &data);
+
+	if (result != Success || type != XA_PIXMAP ||
+	    format != 32 || nitems != 1) {
+		XFree (data);
+		data = NULL;
+	}
+
+	if (data != NULL) {
+		Pixmap pixmap = *(Pixmap *) data;
+		Window root_ret;
+		int x_ret, y_ret;
+		unsigned int w_ret, h_ret, bw_ret, depth_ret;
+
+		gdk_error_trap_push ();
+		if (XGetGeometry (xdisplay, pixmap, &root_ret,
+		                  &x_ret, &y_ret, &w_ret, &h_ret,
+		                  &bw_ret, &depth_ret))
+		{
+			surface = cairo_xlib_surface_create (xdisplay,
+			                                     pixmap, xvisual,
+			                                     w_ret, h_ret);
+		}
+
+#if GTK_CHECK_VERSION (3, 0, 0)
+		gdk_error_trap_pop_ignored ();
+#else
+		gdk_error_trap_pop ();
+#endif
+		XFree (data);
+	}
+
+	gdk_display_flush (display);
+	return surface;
+}
+
 /**
  * mate_bg_crossfade_start:
  * @fade: a #MateBGCrossfade
  * @window: The #GdkWindow to draw crossfade on
  *
  * This function initiates a quick crossfade between two surfaces on
- * the background of @window.  Before initiating the crossfade both
- * mate_bg_crossfade_start() and mate_bg_crossfade_end() need to
- * be called. If animations are disabled, the crossfade is skipped,
- * and the window background is set immediately to the end surface.
+ * the background of @window. Before initiating the crossfade both
+ * mate_bg_crossfade_set_start_surface() and
+ * mate_bg_crossfade_set_end_surface() need to be called. If animations
+ * are disabled, the crossfade is skipped, and the window background is
+ * set immediately to the end surface.
  **/
 void
 mate_bg_crossfade_start (MateBGCrossfade *fade,
-			  GdkWindow        *window)
+                         GdkWindow        *window)
 {
 	GSource *source;
 	GMainContext *context;
 
 	g_return_if_fail (MATE_IS_BG_CROSSFADE (fade));
 	g_return_if_fail (window != NULL);
-	g_return_if_fail (fade->priv->fading_surface != NULL);
+	g_return_if_fail (fade->priv->start_surface != NULL);
 	g_return_if_fail (fade->priv->end_surface != NULL);
 	g_return_if_fail (!mate_bg_crossfade_is_started (fade));
 	g_return_if_fail (gdk_window_get_window_type (window) != GDK_WINDOW_FOREIGN);
 
+	/* If drawing is done on the root window,
+	 * it is essential to have the root pixmap.
+	 */
+	if (gdk_window_get_window_type (window) == GDK_WINDOW_ROOT) {
+		GdkDisplay *display = gdk_window_get_display (window);
+		cairo_surface_t *surface = get_root_pixmap_id_surface (display);
+
+		g_return_if_fail (surface != NULL);
+		cairo_surface_destroy (surface);
+	}
+
+	if (fade->priv->fading_surface != NULL) {
+		cairo_surface_destroy (fade->priv->fading_surface);
+		fade->priv->fading_surface = NULL;
+	}
+
+	fade->priv->window = window;
+	if (gdk_window_get_window_type (fade->priv->window) != GDK_WINDOW_ROOT) {
+		fade->priv->fading_surface = tile_surface (fade->priv->start_surface,
+		                                           fade->priv->width,
+		                                           fade->priv->height);
+		if (fade->priv->widget != NULL) {
+#if GTK_CHECK_VERSION (3, 0, 0)
+			g_signal_connect (fade->priv->widget, "draw",
+			                  (GCallback) on_widget_draw, fade);
+#else
+			g_signal_connect (fade->priv->widget, "expose-event",
+			                  (GCallback) on_widget_draw, fade);
+#endif
+		}
+	} else {
+		cairo_t   *cr;
+		GdkDisplay *display = gdk_window_get_display (fade->priv->window);
+
+		fade->priv->fading_surface = get_root_pixmap_id_surface (display);
+		cr = cairo_create (fade->priv->fading_surface);
+		cairo_set_source_surface (cr, fade->priv->start_surface, 0, 0);
+		cairo_paint (cr);
+		cairo_destroy (cr);
+	}
+	draw_background (fade);
+
 	source = g_timeout_source_new (1000 / 60.0);
 	g_source_set_callback (source,
 			       (GSourceFunc) on_tick,
@@ -544,24 +800,38 @@
 	fade->priv->timeout_id = g_source_attach (source, context);
 	g_source_unref (source);
 
-	fade->priv->window = window;
-#if GTK_CHECK_VERSION (3, 0, 0)
-	cairo_pattern_t *pattern;
-	pattern = cairo_pattern_create_for_surface (fade->priv->fading_surface);
-	gdk_window_set_background_pattern (fade->priv->window, pattern);
-	cairo_pattern_destroy (pattern);
-#else
-	gdk_window_set_back_pixmap (fade->priv->window,
-				    fade->priv->fading_surface,
-				    FALSE);
-#endif
-	draw_background (fade);
-
 	fade->priv->is_first_frame = TRUE;
 	fade->priv->total_duration = .75;
 	fade->priv->start_time = get_current_time ();
 }
 
+/**
+ * mate_bg_crossfade_start_widget:
+ * @fade: a #MateBGCrossfade
+ * @widget: The #GtkWidget to draw crossfade on
+ *
+ * This function initiates a quick crossfade between two surfaces on
+ * the background of @widget. Before initiating the crossfade both
+ * mate_bg_crossfade_set_start_surface() and
+ * mate_bg_crossfade_set_end_surface() need to be called. If animations
+ * are disabled, the crossfade is skipped, and the window background is
+ * set immediately to the end surface.
+ **/
+void
+mate_bg_crossfade_start_widget (MateBGCrossfade *fade,
+                                GtkWidget       *widget)
+{
+	GdkWindow *window;
+
+	g_return_if_fail (MATE_IS_BG_CROSSFADE (fade));
+	g_return_if_fail (widget != NULL);
+
+	fade->priv->widget = widget;
+	gtk_widget_realize (fade->priv->widget);
+	window = gtk_widget_get_window (fade->priv->widget);
+
+	mate_bg_crossfade_start (fade, window);
+}
 
 /**
  * mate_bg_crossfade_is_started:
diff -Nru mate-desktop-1.16.1/libmate-desktop/mate-bg-crossfade.h mate-desktop-1.16.2/libmate-desktop/mate-bg-crossfade.h
--- mate-desktop-1.16.1/libmate-desktop/mate-bg-crossfade.h	2016-10-18 14:36:21.000000000 +0200
+++ mate-desktop-1.16.2/libmate-desktop/mate-bg-crossfade.h	2017-03-25 22:30:16.000000000 +0100
@@ -77,7 +77,9 @@
 #endif
 
 void              mate_bg_crossfade_start (MateBGCrossfade *fade,
-                                            GdkWindow        *window);
+                                           GdkWindow       *window);
+void              mate_bg_crossfade_start_widget (MateBGCrossfade *fade,
+                                                  GtkWidget       *widget);
 gboolean          mate_bg_crossfade_is_started (MateBGCrossfade *fade);
 void              mate_bg_crossfade_stop (MateBGCrossfade *fade);
 
diff -Nru mate-desktop-1.16.1/NEWS mate-desktop-1.16.2/NEWS
--- mate-desktop-1.16.1/NEWS	2016-10-18 14:36:21.000000000 +0200
+++ mate-desktop-1.16.2/NEWS	2017-03-25 22:30:16.000000000 +0100
@@ -1,3 +1,11 @@
+mate-desktop 1.16.2
+
+  * Background: fix crossfade issues with recent GTK+3 versions
+  * Background: fix more graphics issues to allow Caja to use background
+    for directory windows in GTK+3 build
+  * Background: fix memleaks and other misc issues
+  * mate-about: fix URL centering in GTK+3 build
+
 mate-desktop 1.16.1
 
   * mate-bg: fix regression that caused font color in Caja to be

--- End Message ---
--- Begin Message ---
reopen 864049
tags 864049 confirmed moreinfo
done

Mike Gabriel:
> On  Sa 03 Jun 2017 10:33:00 CEST, Niels Thykier wrote:
> 
>> Control: tags -1 confirmed moreinfo
>>
>> [...]
> 
> This one has been superseded by #864049 (mate-desktop/1.16.2-2) and can
> be closed, too.
> 
> Mike


Agreed, this one can be closed.  But #864049 was wrongly closed - it is
still waiting for the mate-desktop/1.16.2-2 last I checked (I meant to
close #864051 instead).

Thanks,
~Niels

--- End Message ---

Reply to: