diff options
author | Søren Sandmann <sandmann@redhat.com> | 2005-01-14 22:12:43 +0000 |
---|---|---|
committer | Søren Sandmann Pedersen <ssp@src.gnome.org> | 2005-01-14 22:12:43 +0000 |
commit | 88fcb915c388324eb81d11c422df1f650da62e93 (patch) | |
tree | 93d49a99ce3c9f57aaf3c9777863e19f4424f13a | |
parent | 0736eb1733f155276ba1e7b3c0a4e16a31f16e24 (diff) | |
download | metacity-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.c | 97 | ||||
-rw-r--r-- | src/cwindow.c | 78 | ||||
-rw-r--r-- | src/cwindow.h | 9 |
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); |