diff options
Diffstat (limited to 'src/compositor/compositor-xrender.c')
-rw-r--r-- | src/compositor/compositor-xrender.c | 110 |
1 files changed, 56 insertions, 54 deletions
diff --git a/src/compositor/compositor-xrender.c b/src/compositor/compositor-xrender.c index fa85105d..0d8b3b6c 100644 --- a/src/compositor/compositor-xrender.c +++ b/src/compositor/compositor-xrender.c @@ -626,55 +626,59 @@ cairo_region_to_xserver_region (Display *xdisplay, } static void -shadow_clip (Display *xdisplay, - Picture shadow_picture, - XImage *shadow_image, - MetaShadowType shadow_type, - MetaFrameBorders borders, - int width, - int height) -{ - int shadow_dx = -1 * shadow_offsets_x [shadow_type]; - int shadow_dy = -1 * shadow_offsets_y [shadow_type]; - XRectangle clip[4]; - - /* Top */ - clip[0].x = 0; - clip[0].y = 0; - clip[0].width = shadow_image->width; - clip[0].height = shadow_dy + borders.visible.top; - - /* Bottom */ - clip[1].x = 0; - clip[1].y = shadow_dy + (height - borders.visible.bottom); - clip[1].width = shadow_image->width; - clip[1].height = shadow_image->height - (shadow_dy + (height - borders.visible.bottom)); - - /* Left */ - clip[2].x = 0; - clip[2].y = shadow_dy + borders.visible.top; - clip[2].width = shadow_dx + borders.visible.left; - clip[2].height = height - borders.visible.top - borders.visible.bottom; - - /* Right */ - clip[3].x = width + shadow_dx; - clip[3].y = shadow_dy + borders.visible.top; - clip[3].width = shadow_image->width - (width + shadow_dx); - clip[3].height = height - borders.visible.top - borders.visible.bottom; - - XRenderSetPictureClipRectangles (xdisplay, shadow_picture, 0, 0, clip, 4); +shadow_picture_clip (Display *xdisplay, + Picture shadow_picture, + MetaCompWindow *cw, + MetaFrameBorders borders, + int width, + int height) +{ + int shadow_dx; + int shadow_dy; + cairo_region_t *visible_region; + XRectangle rect; + XserverRegion region1; + XserverRegion region2; + + if (!cw->window) + return; + + visible_region = meta_window_get_frame_bounds (cw->window); + + if (!visible_region) + return; + + shadow_dx = -1 * shadow_offsets_x [cw->shadow_type]; + shadow_dy = -1 * shadow_offsets_y [cw->shadow_type]; + + rect.x = 0; + rect.y = 0; + rect.width = width; + rect.height = height; + + region1 = XFixesCreateRegion (xdisplay, &rect, 1); + region2 = cairo_region_to_xserver_region (xdisplay, visible_region); + + XFixesTranslateRegion (xdisplay, region2, + shadow_dx, shadow_dy); + + XFixesSubtractRegion (xdisplay, region1, region1, region2); + XFixesSetPictureClipRegion (xdisplay, shadow_picture, 0, 0, region1); + + XFixesDestroyRegion (xdisplay, region1); + XFixesDestroyRegion (xdisplay, region2); } + static Picture -shadow_picture (MetaDisplay *display, - MetaScreen *screen, - MetaShadowType shadow_type, - double opacity, - Picture alpha_pict, +shadow_picture (MetaDisplay *display, + MetaScreen *screen, + MetaCompWindow *cw, + double opacity, MetaFrameBorders borders, - int width, - int height, - int *wp, - int *hp) + int width, + int height, + int *wp, + int *hp) { Display *xdisplay = meta_display_get_xdisplay (display); XImage *shadow_image; @@ -683,7 +687,7 @@ shadow_picture (MetaDisplay *display, Window xroot = meta_screen_get_xroot (screen); GC gc; - shadow_image = make_shadow (display, screen, shadow_type, + shadow_image = make_shadow (display, screen, cw->shadow_type, opacity, width, height); if (!shadow_image) return None; @@ -705,10 +709,9 @@ shadow_picture (MetaDisplay *display, XFreePixmap (xdisplay, shadow_pixmap); return None; } - shadow_clip (xdisplay, - shadow_picture, shadow_image, shadow_type, - borders, - width, height); + + shadow_picture_clip (xdisplay, shadow_picture, cw, borders, + shadow_image->width, shadow_image->height); gc = XCreateGC (xdisplay, shadow_pixmap, 0, 0); if (!gc) @@ -1090,6 +1093,7 @@ win_extents (MetaCompWindow *cw) if (frame) meta_frame_calc_borders (frame, &borders); } + cw->shadow_dx = shadow_offsets_x [cw->shadow_type]; cw->shadow_dy = shadow_offsets_y [cw->shadow_type]; @@ -1099,9 +1103,7 @@ win_extents (MetaCompWindow *cw) if (cw->opacity != (guint) OPAQUE) opacity = opacity * ((double) cw->opacity) / ((double) OPAQUE); - cw->shadow = shadow_picture (display, screen, cw->shadow_type, - opacity, cw->alpha_pict, - borders, + cw->shadow = shadow_picture (display, screen, cw, opacity, borders, cw->attrs.width + cw->attrs.border_width * 2, cw->attrs.height + cw->attrs.border_width * 2, &cw->shadow_width, &cw->shadow_height); |