Your message dated Sat, 03 Jun 2017 20:56:00 +0000
with message-id <[email protected]>
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 [email protected]
immediately.)


-- 
863792: http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=863792
Debian Bug Tracking System
Contact [email protected] with problems
--- Begin Message ---
Package: release.debian.org
Severity: normal
User: [email protected]
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 <[email protected]>  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 via email to