diff options
author | Richard Grenville <[email protected]> | 2012-09-12 21:01:06 +0800 |
---|---|---|
committer | Richard Grenville <[email protected]> | 2012-09-12 21:01:06 +0800 |
commit | 73342d1ff233aa74999998e8cf628d8e956d394f (patch) | |
tree | cf0bd3bd6cd0c645e21620b48f02c2bdbb0b95d6 | |
parent | 17b8a50161ab84a7b1d05d69b14a81d9a98e4432 (diff) | |
download | tdebase-73342d1ff233aa74999998e8cf628d8e956d394f.tar.gz tdebase-73342d1ff233aa74999998e8cf628d8e956d394f.zip |
Bug fix: Issue #40: -z does not work as expected
More information in the issue report.
- Let window opacity affect the opacity of its shadow and frames even if
-z is enabled.
- Check for the range of -o to eliminate potential segfault.
-rw-r--r-- | compton.c | 48 | ||||
-rw-r--r-- | compton.h | 17 |
2 files changed, 42 insertions, 23 deletions
@@ -481,18 +481,19 @@ make_shadow(Display *dpy, double opacity, * center (fill the complete data array) */ - if (!clear_shadow) { + // If clear_shadow is enabled and the border & corner shadow (which + // later will be filled) could entirely cover the area of the shadow + // that will be displayed, do not bother filling other pixels. If it + // can't, we must fill the other pixels here. + if (!(clear_shadow && shadow_offset_x <= 0 && shadow_offset_x >= -cgsize + && shadow_offset_y <= 0 && shadow_offset_y >= -cgsize)) { if (cgsize > 0) { d = shadow_top[opacity_int * (cgsize + 1) + cgsize]; } else { d = sum_gaussian(gaussian_map, opacity, center, center, width, height); } - memset(data, d, sheight * swidth); - } else { - // zero the pixmap - memset(data, 0, sheight * swidth); } /* @@ -556,16 +557,19 @@ make_shadow(Display *dpy, double opacity, } } - // zero extra pixels - if (clear_shadow && width > gsize && height > gsize) { - int r = gsize / 2; - int sr = r - 2; - int er = r + 4; - for (y = sr; y < (sheight - er); y++) { - for (x = sr; x < (swidth - er); x++) { - data[y * swidth + x] = 0; - } - } + if (clear_shadow) { + // Clear the region in the shadow that the window would cover based + // on shadow_offset_{x,y} user provides + int xstart = normalize_i_range(- (int) shadow_offset_x, 0, swidth); + int xrange = normalize_i_range(width - (int) shadow_offset_x, + 0, swidth) - xstart; + int ystart = normalize_i_range(- (int) shadow_offset_y, 0, sheight); + int yend = normalize_i_range(height - (int) shadow_offset_y, + 0, sheight); + int y; + + for (y = ystart; y < yend; y++) + memset(&data[y * swidth + xstart], 0, xrange); } return ximage; @@ -802,14 +806,12 @@ win_extents(Display *dpy, win *w) { if (!w->shadow) { double opacity = shadow_opacity; - if (!clear_shadow) { - if (w->mode != WINDOW_SOLID) { - opacity = opacity * ((double)w->opacity) / ((double)OPAQUE); - } + if (w->mode != WINDOW_SOLID) { + opacity = opacity * ((double)w->opacity) / ((double)OPAQUE); + } - if (HAS_FRAME_OPACITY(w)) { - opacity = opacity * frame_opacity; - } + if (HAS_FRAME_OPACITY(w)) { + opacity = opacity * frame_opacity; } w->shadow = shadow_picture( @@ -2784,7 +2786,7 @@ main(int argc, char **argv) { shadow_radius = atoi(optarg); break; case 'o': - shadow_opacity = atof(optarg); + shadow_opacity = normalize_d(atof(optarg)); break; case 'l': shadow_offset_x = atoi(optarg); @@ -153,6 +153,23 @@ extern int root_height, root_width; // http://clang.llvm.org/compatibility.html#inline /** + * Normalize an int value to a specific range. + * + * @param i int value to normalize + * @param min minimal value + * @param max maximum value + * @return normalized value + */ +static inline double normalize_i_range(int i, int min, int max) { + if (i > max) + return max; + if (i < min) + return min; + + return i; +} + +/** * Normalize a double value to 0.\ 0 - 1.\ 0. * * @param d double value to normalize |