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.
This commit is contained in:
Richard Grenville 2012-09-12 21:01:06 +08:00
parent 6f079af2f0
commit 3abeb58690
2 changed files with 42 additions and 23 deletions

View File

@ -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);

View File

@ -152,6 +152,23 @@ extern int root_height, root_width;
// inline functions must be made static to compile correctly under clang:
// 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.
*