summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSøren Sandmann <sandmann@redhat.com>2005-01-14 22:12:43 +0000
committerSøren Sandmann Pedersen <ssp@src.gnome.org>2005-01-14 22:12:43 +0000
commit88fcb915c388324eb81d11c422df1f650da62e93 (patch)
tree93d49a99ce3c9f57aaf3c9777863e19f4424f13a
parent0736eb1733f155276ba1e7b3c0a4e16a31f16e24 (diff)
downloadmetacity-88fcb915c388324eb81d11c422df1f650da62e93.tar.gz
Carefully avoid drawing windows that are obscured by other windows.
Fri Jan 14 17:09:32 2005 Søren Sandmann <sandmann@redhat.com> * src/compositor.c (draw_windows): Carefully avoid drawing windows that are obscured by other windows.
-rw-r--r--src/compositor.c97
-rw-r--r--src/cwindow.c78
-rw-r--r--src/cwindow.h9
3 files changed, 122 insertions, 62 deletions
diff --git a/src/compositor.c b/src/compositor.c
index c04c58bc..e64515ef 100644
--- a/src/compositor.c
+++ b/src/compositor.c
@@ -75,6 +75,20 @@ free_window_hash_value (void *v)
}
#endif /* HAVE_COMPOSITE_EXTENSIONS */
+static void
+print_region (Display *dpy, const char *name, XserverRegion region)
+{
+ XRectangle *rects;
+ int i, n_rects;
+
+ rects = XFixesFetchRegion (dpy, region, &n_rects);
+
+ g_print ("region \"%s\":\n", name);
+ for (i = 0; i < n_rects; ++i)
+ g_print (" %d %d %d %d\n", rects[i].x, rects[i].y, rects[i].width, rects[i].height);
+ XFree (rects);
+}
+
MetaCompositor*
meta_compositor_new (MetaDisplay *display)
{
@@ -215,7 +229,6 @@ draw_windows (MetaCompositor *compositor,
CWindow *cwindow;
XserverRegion region_below;
Display *dpy = compositor->display->xdisplay;
- int x, y, w, h;
if (!list)
return;
@@ -225,26 +238,48 @@ draw_windows (MetaCompositor *compositor,
region_below = XFixesCreateRegion (dpy, NULL, 0);
XFixesCopyRegion (dpy, region_below, damaged_region);
- cwindow_get_paint_bounds (cwindow, &x, &y, &w, &h);
-
if (!cwindow_is_translucent (cwindow) && !cwindow_get_input_only (cwindow) && cwindow_get_viewable (cwindow))
{
- XRectangle rect = { x, y, w, h };
- XserverRegion window_region = XFixesCreateRegion (dpy, &rect, 1);
- XFixesSubtractRegion (dpy, region_below, region_below, window_region);
- XFixesDestroyRegion (dpy, window_region);
-
-#if 0
- XSetForeground (xdisplay, gc, 0x00ffff00);
- XFillRectangle (xdisplay, screen->xroot, gc, 0, 0, screen->width, screen->height);
-#endif
+ XserverRegion opaque = cwindow_get_opaque_region (cwindow);
+
+ XFixesSubtractRegion (dpy, region_below, region_below, opaque);
+
+ XFixesDestroyRegion (dpy, opaque);
}
-
+
draw_windows (compositor, screen, list->next, region_below, picture);
-
+
XFixesDestroyRegion (dpy, region_below);
-
- cwindow_new_draw (cwindow, picture, damaged_region);
+
+#if 0
+ if (window_region)
+ {
+ XserverRegion clip = XFixesCreateRegion (dpy, NULL, 0);
+ XFixesCopyRegion (dpy, clip, damaged_region);
+ XFixesIntersectRegion (dpy, clip, clip, window_region);
+
+#if 0
+ print_region (dpy, "clip1", clip);
+#endif
+
+ XRenderColor hilit = { rand(), rand(), rand(), 0xffff };
+
+ XFixesSetPictureClipRegion (dpy, screen->root_picture, 0, 0, clip);
+ XRenderFillRectangle (compositor->display->xdisplay,
+ PictOpSrc,
+ screen->root_picture, &hilit,
+ 0, 0,
+ screen->width, screen->height);
+ XSync (compositor->display->xdisplay, False);
+ g_usleep (50000);
+
+#if 0
+ print_region (dpy, "clip2", clip);
+ }
+#endif
+#endif
+ XFixesSetPictureClipRegion (dpy, picture, 0, 0, damaged_region);
+ cwindow_new_draw (cwindow, picture);
}
static Picture
@@ -293,6 +328,11 @@ create_root_buffer (MetaScreen *screen)
static void
paint_buffer (MetaScreen *screen, Picture buffer)
{
+#if 0
+ XFixesSetPictureClipRegion (screen->display->xdisplay,
+ screen->root_picture, 0, 0, damaged_region);
+#endif
+
XRenderComposite (screen->display->xdisplay,
PictOpSrc,
buffer, None,
@@ -334,10 +374,10 @@ do_paint_screen (MetaCompositor *compositor,
XFixesSetPictureClipRegion (xdisplay,
picture, 0, 0,
region);
-
draw_windows (compositor, screen, screen->compositor_windows, region, picture);
meta_error_trap_pop (compositor->display, FALSE);
+
return region;
}
@@ -358,8 +398,8 @@ paint_screen (MetaCompositor *compositor,
xdisplay = screen->display->xdisplay;
buffer_picture = create_root_buffer (screen);
-
- /* set clip */
+
+ /* set clip */
region = do_paint_screen (compositor, screen, buffer_picture, damage_region);
/* Copy buffer to root window */
@@ -369,6 +409,21 @@ paint_screen (MetaCompositor *compositor,
XFixesSetPictureClipRegion (xdisplay,
screen->root_picture,
0, 0, region);
+
+#if 0
+ XRenderColor hilit = { 0xFFFF, 0x0000, 0x0000, 0xFFFF } ;
+ XRenderFillRectangle (compositor->display->xdisplay,
+ PictOpSrc,
+ screen->root_picture, &hilit, 0, 0, screen->width, screen->height);
+#endif
+
+ XSync (xdisplay, False);
+
+#if 0
+ g_usleep (370000);
+#endif
+
+ XFixesSetPictureClipRegion (xdisplay, buffer_picture, 0, 0, None);
paint_buffer (screen, buffer_picture);
@@ -1227,6 +1282,7 @@ quad_to_quad_interpolate (Quad *start, Quad *end, Quad *dest, gdouble t)
}
}
+#if 0
void
meta_compositor_old_genie (MetaCompositor *compositor,
MetaWindow *window)
@@ -1358,6 +1414,7 @@ meta_compositor_old_genie (MetaCompositor *compositor,
}
#endif
}
+#endif
void
meta_compositor_genie (MetaCompositor *compositor,
@@ -1461,7 +1518,7 @@ meta_compositor_genie (MetaCompositor *compositor,
XFixesDestroyRegion (compositor->display->xdisplay, region);
}
- cwindow_new_draw (cwindow, buffer, None);
+ cwindow_new_draw (cwindow, buffer);
XFixesSetPictureClipRegion (compositor->display->xdisplay,
window->screen->root_picture, 0, 0, None);
diff --git a/src/cwindow.c b/src/cwindow.c
index 3c9c259c..039b2010 100644
--- a/src/cwindow.c
+++ b/src/cwindow.c
@@ -4,7 +4,7 @@
#include "compositor.h"
#include "matrix.h"
-#define SHADOW_OFFSET 10
+#define SHADOW_OFFSET 3
/* Unlike MetaWindow, there's one of these for _all_ toplevel windows,
* override redirect or not. We also track unmapped windows as
* otherwise on window map we'd have to determine where the
@@ -94,27 +94,16 @@ cwindow_extents (CWindow *cwindow)
}
#endif /* HAVE_COMPOSITE_EXTENSIONS */
-void
-cwindow_get_paint_bounds (CWindow *cwindow,
- int *x,
- int *y,
- int *w,
- int *h)
+XserverRegion
+cwindow_get_opaque_region (CWindow *cwindow)
{
- if (cwindow->pixmap != None)
- {
- *x = cwindow->x;
- *y = cwindow->y;
- *w = cwindow->width + cwindow->border_width * 2;
- *h = cwindow->height + cwindow->border_width * 2;
- }
- else
- {
- *x = cwindow->x + cwindow->border_width;
- *y = cwindow->y + cwindow->border_width;
- *w = cwindow->width;
- *h = cwindow->height;
- }
+ XRectangle rect;
+ rect.x = cwindow->x;
+ rect.y = cwindow->y;
+ rect.width = cwindow->width;
+ rect.height = cwindow->height;
+
+ return XFixesCreateRegion (cwindow_get_xdisplay (cwindow), &rect, 1);
}
Drawable
@@ -423,8 +412,9 @@ get_transform (XTransform *trans, int x, int y, int w, int h)
convert_matrix (&tmp, trans);
}
+#if 0
void
-cwindow_draw (CWindow *cwindow, Picture picture, XserverRegion damaged_region)
+cwindow_draw (CWindow *cwindow, Picture picture)
{
/* Actually draw the window */
XRenderPictFormat *format;
@@ -549,10 +539,12 @@ cwindow_draw (CWindow *cwindow, Picture picture, XserverRegion damaged_region)
}
XRenderFreePicture (cwindow_get_xdisplay (cwindow), wpicture);
}
+#endif
gboolean
cwindow_is_translucent (CWindow *cwindow)
{
+ return FALSE;
MetaCompositor *compositor = cwindow_get_compositor (cwindow);
MetaWindow *window = meta_display_lookup_x_window (meta_compositor_get_display (compositor), cwindow_get_xwindow (cwindow));
return (window != NULL &&
@@ -831,7 +823,7 @@ cwindow_set_transformation (CWindow *cwindow,
}
void
-cwindow_new_draw (CWindow *cwindow, Picture destination, XserverRegion damaged_region)
+cwindow_new_draw (CWindow *cwindow, Picture destination)
{
XRenderPictFormat *format;
int i;
@@ -883,21 +875,26 @@ cwindow_new_draw (CWindow *cwindow, Picture destination, XserverRegion damaged_r
}
else
{
- int x, y, w, h;
+ Display *dpy = cwindow_get_xdisplay (cwindow);
XRenderColor shadow_color = { 0x0000, 0x000, 0x0000, 0x70c0 };
+ XserverRegion shadow_clip;
+ XserverRegion old_clip = XFixesCreateRegionFromPicture (dpy, destination);
+
+ shadow_clip = cwindow_get_opaque_region (cwindow);
+
+ XFixesSubtractRegion (dpy, shadow_clip, old_clip, shadow_clip);
+
+ XFixesSetPictureClipRegion (dpy, destination, 0, 0, shadow_clip);
- cwindow_get_paint_bounds (cwindow, &x, &y, &w, &h);
-
/* superlame drop shadow */
-#if 0
- XRenderFillRectangle (cwindow_get_xdisplay (cwindow), PictOpOver,
- picture,
+ XRenderFillRectangle (cwindow_get_xdisplay (cwindow),
+ PictOpOver,
+ destination,
&shadow_color,
- cwindow_get_x (cwindow) + SHADOW_OFFSET,
- cwindow_get_y (cwindow) + SHADOW_OFFSET,
- cwindow_get_width (cwindow),
- cwindow_get_height (cwindow));
-#endif
+ cwindow->x + SHADOW_OFFSET, cwindow->y + SHADOW_OFFSET,
+ cwindow->width, cwindow->height);
+
+ XFixesSetPictureClipRegion (dpy, destination, 0, 0, old_clip);
XRenderComposite (cwindow_get_xdisplay (cwindow),
PictOpOver, /* PictOpOver for alpha, PictOpSrc without */
@@ -905,8 +902,19 @@ cwindow_new_draw (CWindow *cwindow, Picture destination, XserverRegion damaged_r
None,
destination,
0, 0, 0, 0,
- x, y, w, h);
+ cwindow->x,
+ cwindow->y,
+ cwindow->width,
+ cwindow->height);
+
+ XFixesDestroyRegion (dpy, old_clip);
+ XFixesDestroyRegion (dpy, shadow_clip);
}
+ if (cwindow_get_last_painted_extents (cwindow))
+ cwindow_destroy_last_painted_extents (cwindow);
+
+ cwindow_set_last_painted_extents (cwindow, cwindow_extents (cwindow));
+
XRenderFreePicture (cwindow_get_xdisplay (cwindow), picture);
}
diff --git a/src/cwindow.h b/src/cwindow.h
index 95ae9414..b57f8efa 100644
--- a/src/cwindow.h
+++ b/src/cwindow.h
@@ -38,11 +38,7 @@ void cwindow_set_transformation (CWindow *window
int n_distortions);
void cwindow_free (CWindow *cwindow);
XserverRegion cwindow_extents (CWindow *cwindow);
-void cwindow_get_paint_bounds (CWindow *cwindow,
- int *x,
- int *y,
- int *w,
- int *h);
+XserverRegion cwindow_get_opaque_region (CWindow *cwindow);
Drawable cwindow_get_drawable (CWindow *cwindow);
Window cwindow_get_xwindow (CWindow *cwindow);
gboolean cwindow_get_viewable (CWindow *cwindow);
@@ -102,5 +98,4 @@ void cwindow_process_damage_notify (CWindow *cwindo
void cwindow_process_configure_notify (CWindow *cwindow,
XConfigureEvent *event);
void cwindow_new_draw (CWindow *cwindow,
- Picture destination,
- XserverRegion damaged_region);
+ Picture destination);