[Xfce4-commits] <xfdesktop:master> Clip overlapping backdrops (Bug #9052)

Eric Koegel noreply at xfce.org
Sun Aug 4 10:36:10 CEST 2013


Updating branch refs/heads/master
         to 963d829f123b7cd4da36c25fa03cf5754897e195 (commit)
       from 594ea3b79117c866b8d2358dc2b44303572e0578 (commit)

commit 963d829f123b7cd4da36c25fa03cf5754897e195
Author: Eric Koegel <eric.koegel at gmail.com>
Date:   Sun Mar 17 14:45:27 2013 +0300

    Clip overlapping backdrops (Bug #9052)
    
    In a multi-monitor setup each successive wallpaper drawn has the
    previous area subtracted from it so that the wallpapers aren't
    drawn over each other.

 src/xfce-desktop.c   |   89 ++++++++++++++++++++++++++++++++++++++------------
 src/xfce-workspace.c |    1 -
 2 files changed, 69 insertions(+), 21 deletions(-)

diff --git a/src/xfce-desktop.c b/src/xfce-desktop.c
index 09f2e53..2623547 100644
--- a/src/xfce-desktop.c
+++ b/src/xfce-desktop.c
@@ -321,6 +321,7 @@ backdrop_changed_cb(XfceBackdrop *backdrop, gpointer user_data)
     cairo_t *cr;
     GdkPixbuf *pix;
     GdkRectangle rect;
+    GdkRegion *clip_region = NULL;
     gint i, monitor = -1, current_workspace;
     
     TRACE("entering");
@@ -376,27 +377,75 @@ backdrop_changed_cb(XfceBackdrop *backdrop, gpointer user_data)
 
     xfce_backdrop_set_size(backdrop, rect.width, rect.height);
 
-    /* create/get the composited backdrop pixmap */
-    pix = xfce_backdrop_get_pixbuf(backdrop);
-    if(!pix)
-        return;
+    if(monitor > 0
+       && !xfce_workspace_get_xinerama_stretch(desktop->priv->workspaces[current_workspace])) {
+        clip_region = gdk_region_rectangle(&rect);
 
-    cr = gdk_cairo_create(GDK_DRAWABLE(pmap));
-    gdk_cairo_set_source_pixbuf(cr, pix, rect.x, rect.y);
-    cairo_paint(cr);
-    g_object_unref(G_OBJECT(pix));
-    cairo_destroy(cr);
-    
-    /* tell gtk to redraw the repainted area */
-    gtk_widget_queue_draw_area(GTK_WIDGET(desktop), rect.x, rect.y,
-                               rect.width, rect.height);
-    
-    set_imgfile_root_property(desktop,
-                              xfce_backdrop_get_image_filename(backdrop),
-                              monitor);
-    
-    /* do this again so apps watching the root win notice the update */
-    set_real_root_window_pixmap(gscreen, pmap);
+        DBG("clip_region: x: %d, y: %d, w: %d, h: %d",
+            rect.x, rect.y, rect.width, rect.height);
+
+        /* If we are not monitor 0 on a multi-monitor setup we need to subtract
+         * all the previous monitor regions so we don't draw over them. This
+         * should prevent the overlap and double backdrop drawing bugs.
+         */
+        for(i = 0; i < monitor; i++) {
+            GdkRectangle previous_monitor;
+            GdkRegion *previous_region;
+            gdk_screen_get_monitor_geometry(gscreen, i, &previous_monitor);
+
+            DBG("previous_monitor: x: %d, y: %d, w: %d, h: %d",
+                previous_monitor.x, previous_monitor.y,
+                previous_monitor.width, previous_monitor.height);
+
+            previous_region = gdk_region_rectangle(&previous_monitor);
+
+            gdk_region_subtract(clip_region, previous_region);
+
+            gdk_region_destroy(previous_region);
+        }
+    }
+
+    if(clip_region != NULL) {
+        /* Update the area to redraw to limit the icons/area painted */
+        gdk_region_get_clipbox(clip_region, &rect);
+        DBG("area to update: x: %d, y: %d, w: %d, h: %d",
+            rect.x, rect.y, rect.width, rect.height);
+    }
+
+    if(rect.width != 0 && rect.height != 0) {
+        /* create/get the composited backdrop pixmap */
+        pix = xfce_backdrop_get_pixbuf(backdrop);
+        if(!pix)
+            return;
+
+        cr = gdk_cairo_create(GDK_DRAWABLE(pmap));
+        gdk_cairo_set_source_pixbuf(cr, pix, rect.x, rect.y);
+
+        /* clip the area so we don't draw over a previous wallpaper */
+        if(clip_region != NULL) {
+            gdk_cairo_region(cr, clip_region);
+            cairo_clip(cr);
+        }
+
+        cairo_paint(cr);
+        g_object_unref(G_OBJECT(pix));
+
+        cairo_destroy(cr);
+
+        /* tell gtk to redraw the repainted area */
+        gtk_widget_queue_draw_area(GTK_WIDGET(desktop), rect.x, rect.y,
+                                   rect.width, rect.height);
+
+        set_imgfile_root_property(desktop,
+                                  xfce_backdrop_get_image_filename(backdrop),
+                                  monitor);
+
+        /* do this again so apps watching the root win notice the update */
+        set_real_root_window_pixmap(gscreen, pmap);
+    }
+
+    if(clip_region != NULL)
+        gdk_region_destroy(clip_region);
 }
 
 static void
diff --git a/src/xfce-workspace.c b/src/xfce-workspace.c
index eeb131b..cdcae08 100644
--- a/src/xfce-workspace.c
+++ b/src/xfce-workspace.c
@@ -149,7 +149,6 @@ backdrop_cycle_cb(XfceBackdrop *backdrop, gpointer user_data)
     if(g_strcmp0(backdrop_file, new_backdrop) != 0) {
         xfce_backdrop_set_image_filename(backdrop, new_backdrop);
         g_free(new_backdrop);
-        g_signal_emit(G_OBJECT(user_data), signals[WORKSPACE_BACKDROP_CHANGED], 0, backdrop);
     }
 }
 


More information about the Xfce4-commits mailing list