diff --git a/xcompmgr.c b/xcompmgr.c index ef4259b..1ed3801 100644 --- a/xcompmgr.c +++ b/xcompmgr.c @@ -71,14 +71,8 @@ typedef struct _win { Damage damage; Picture picture; Picture alphaPict; - Picture shadowPict; XserverRegion borderSize; XserverRegion extents; - Picture shadow; - int shadow_dx; - int shadow_dy; - int shadow_width; - int shadow_height; unsigned int opacity; Atom windowType; unsigned long damage_sequence; /* sequence when damage was created */ @@ -88,593 +82,59 @@ typedef struct _win { struct _win *prev_trans; } win; -typedef struct _conv { - int size; - double *data; -} conv; - -typedef struct _fade { - struct _fade *next; - win *w; - double cur; - double finish; - double step; - void (*callback) (Display *dpy, win *w, Bool gone); - Display *dpy; - Bool gone; -} fade; - -win *list; -fade *fades; -Display *dpy; -int scr; -Window root; -Picture rootPicture; -Picture rootBuffer; -Picture blackPicture; -Picture transBlackPicture; -Picture rootTile; -XserverRegion allDamage; -Bool clipChanged; +static win *list; +static Display *dpy; +static int scr; +static Window root; +static Picture rootPicture; +static Picture rootBuffer; +static Picture blackPicture; +static Picture rootTile; +static XserverRegion allDamage; +static Bool clipChanged; #if HAS_NAME_WINDOW_PIXMAP -Bool hasNamePixmap; +static Bool hasNamePixmap; #endif -int root_height, root_width; -ignore *ignore_head, **ignore_tail = &ignore_head; -int xfixes_event, xfixes_error; -int damage_event, damage_error; -int composite_event, composite_error; -int render_event, render_error; -Bool synchronize; -int composite_opcode; +static int root_height, root_width; +static ignore *ignore_head, **ignore_tail = &ignore_head; +static int xfixes_event, xfixes_error; +static int damage_event, damage_error; +static int composite_event, composite_error; +static int render_event, render_error; +static int composite_opcode; /* find these once and be done with it */ -Atom opacityAtom; -Atom winTypeAtom; -Atom winDesktopAtom; -Atom winDockAtom; -Atom winToolbarAtom; -Atom winMenuAtom; -Atom winUtilAtom; -Atom winSplashAtom; -Atom winDialogAtom; -Atom winNormalAtom; +static Atom opacityAtom; +static Atom winTypeAtom; +static Atom winDesktopAtom; +static Atom winDockAtom; +static Atom winToolbarAtom; +static Atom winMenuAtom; +static Atom winUtilAtom; +static Atom winSplashAtom; +static Atom winDialogAtom; +static Atom winNormalAtom; /* opacity property name; sometime soon I'll write up an EWMH spec for it */ #define OPACITY_PROP "_NET_WM_WINDOW_OPACITY" -#define TRANSLUCENT 0xe0000000 #define OPAQUE 0xffffffff -conv *gaussianMap; - #define WINDOW_SOLID 0 #define WINDOW_TRANS 1 #define WINDOW_ARGB 2 -#define TRANS_OPACITY 0.75 - #define DEBUG_REPAINT 0 #define DEBUG_EVENTS 0 #define MONITOR_REPAINT 0 -#define SHADOWS 1 -#define SHARP_SHADOW 0 - -typedef enum _compMode { - CompSimple, /* looks like a regular X server */ - CompServerShadows, /* use window alpha for shadow; sharp, but precise */ - CompClientShadows, /* use window extents for shadow, blurred */ -} CompMode; - static void determine_mode(Display *dpy, win *w); - -static double -get_opacity_percent(Display *dpy, win *w, double def); static XserverRegion win_extents (Display *dpy, win *w); -CompMode compMode = CompSimple; - -int shadowRadius = 12; -int shadowOffsetX = -15; -int shadowOffsetY = -15; -double shadowOpacity = .75; - -double fade_in_step = 0.028; -double fade_out_step = 0.03; -int fade_delta = 10; -int fade_time = 0; -Bool fadeWindows = False; -Bool excludeDockShadows = False; -Bool fadeTrans = False; - -Bool autoRedirect = False; - -/* For shadow precomputation */ -int Gsize = -1; -unsigned char *shadowCorner = NULL; -unsigned char *shadowTop = NULL; - -int -get_time_in_milliseconds () -{ - struct timeval tv; - - gettimeofday (&tv, NULL); - return tv.tv_sec * 1000 + tv.tv_usec / 1000; -} - -fade * -find_fade (win *w) -{ - fade *f; - - for (f = fades; f; f = f->next) - { - if (f->w == w) - return f; - } - return 0; -} - -void -dequeue_fade (Display *dpy, fade *f) -{ - fade **prev; - - for (prev = &fades; *prev; prev = &(*prev)->next) - if (*prev == f) - { - *prev = f->next; - if (f->callback) - (*f->callback) (dpy, f->w, f->gone); - free (f); - break; - } -} - -void -cleanup_fade (Display *dpy, win *w) -{ - fade *f = find_fade (w); - if (f) - dequeue_fade (dpy, f); -} - -void -enqueue_fade (Display *dpy, fade *f) -{ - if (!fades) - fade_time = get_time_in_milliseconds () + fade_delta; - f->next = fades; - fades = f; -} - -static void -set_fade (Display *dpy, win *w, double start, double finish, double step, - void (*callback) (Display *dpy, win *w, Bool gone), - Bool gone, Bool exec_callback, Bool override) -{ - fade *f; - - f = find_fade (w); - if (!f) - { - f = malloc (sizeof (fade)); - f->next = 0; - f->w = w; - f->cur = start; - enqueue_fade (dpy, f); - } - else if(!override) - return; - else - { - if (exec_callback) - if (f->callback) - (*f->callback)(dpy, f->w, f->gone); - } - - if (finish < 0) - finish = 0; - if (finish > 1) - finish = 1; - f->finish = finish; - if (f->cur < finish) - f->step = step; - else if (f->cur > finish) - f->step = -step; - f->callback = callback; - f->gone = gone; - w->opacity = f->cur * OPAQUE; -#if 0 - printf ("set_fade start %g step %g\n", f->cur, f->step); -#endif - determine_mode (dpy, w); - if (w->shadow) - { - XRenderFreePicture (dpy, w->shadow); - w->shadow = None; - w->extents = win_extents (dpy, w); - } -} - -int -fade_timeout (void) -{ - int now; - int delta; - if (!fades) - return -1; - now = get_time_in_milliseconds(); - delta = fade_time - now; - if (delta < 0) - delta = 0; -/* printf ("timeout %d\n", delta); */ - return delta; -} - -void -run_fades (Display *dpy) -{ - int now = get_time_in_milliseconds(); - fade *next = fades; - int steps; - Bool need_dequeue; - -#if 0 - printf ("run fades\n"); -#endif - if (fade_time - now > 0) - return; - steps = 1 + (now - fade_time) / fade_delta; - - while (next) - { - fade *f = next; - win *w = f->w; - next = f->next; - f->cur += f->step * steps; - if (f->cur >= 1) - f->cur = 1; - else if (f->cur < 0) - f->cur = 0; -#if 0 - printf ("opacity now %g\n", f->cur); -#endif - w->opacity = f->cur * OPAQUE; - need_dequeue = False; - if (f->step > 0) - { - if (f->cur >= f->finish) - { - w->opacity = f->finish*OPAQUE; - need_dequeue = True; - } - } - else - { - if (f->cur <= f->finish) - { - w->opacity = f->finish*OPAQUE; - need_dequeue = True; - } - } - determine_mode (dpy, w); - if (w->shadow) - { - XRenderFreePicture (dpy, w->shadow); - w->shadow = None; - w->extents = win_extents(dpy, w); - } - /* Must do this last as it might destroy f->w in callbacks */ - if (need_dequeue) - dequeue_fade (dpy, f); - } - fade_time = now + fade_delta; -} - -static double -gaussian (double r, double x, double y) -{ - return ((1 / (sqrt (2 * M_PI * r))) * - exp ((- (x * x + y * y)) / (2 * r * r))); -} - - -static conv * -make_gaussian_map (Display *dpy, double r) -{ - conv *c; - int size = ((int) ceil ((r * 3)) + 1) & ~1; - int center = size / 2; - int x, y; - double t; - double g; - - c = malloc (sizeof (conv) + size * size * sizeof (double)); - c->size = size; - c->data = (double *) (c + 1); - t = 0.0; - for (y = 0; y < size; y++) - for (x = 0; x < size; x++) - { - g = gaussian (r, (double) (x - center), (double) (y - center)); - t += g; - c->data[y * size + x] = g; - } -/* printf ("gaussian total %f\n", t); */ - for (y = 0; y < size; y++) - for (x = 0; x < size; x++) - { - c->data[y*size + x] /= t; - } - return c; -} - -/* - * A picture will help - * - * -center 0 width width+center - * -center +-----+-------------------+-----+ - * | | | | - * | | | | - * 0 +-----+-------------------+-----+ - * | | | | - * | | | | - * | | | | - * height +-----+-------------------+-----+ - * | | | | - * height+ | | | | - * center +-----+-------------------+-----+ - */ - -static unsigned char -sum_gaussian (conv *map, double opacity, int x, int y, int width, int height) -{ - int fx, fy; - double *g_data; - double *g_line = map->data; - int g_size = map->size; - int center = g_size / 2; - int fx_start, fx_end; - int fy_start, fy_end; - double v; - - /* - * Compute set of filter values which are "in range", - * that's the set with: - * 0 <= x + (fx-center) && x + (fx-center) < width && - * 0 <= y + (fy-center) && y + (fy-center) < height - * - * 0 <= x + (fx - center) x + fx - center < width - * center - x <= fx fx < width + center - x - */ - - fx_start = center - x; - if (fx_start < 0) - fx_start = 0; - fx_end = width + center - x; - if (fx_end > g_size) - fx_end = g_size; - - fy_start = center - y; - if (fy_start < 0) - fy_start = 0; - fy_end = height + center - y; - if (fy_end > g_size) - fy_end = g_size; - - g_line = g_line + fy_start * g_size + fx_start; - - v = 0; - for (fy = fy_start; fy < fy_end; fy++) - { - g_data = g_line; - g_line += g_size; - - for (fx = fx_start; fx < fx_end; fx++) - v += *g_data++; - } - if (v > 1) - v = 1; - - return ((unsigned char) (v * opacity * 255.0)); -} - -/* precompute shadow corners and sides to save time for large windows */ -static void -presum_gaussian (conv *map) -{ - int center = map->size/2; - int opacity, x, y; - - Gsize = map->size; - - if (shadowCorner) - free ((void *)shadowCorner); - if (shadowTop) - free ((void *)shadowTop); - - shadowCorner = (unsigned char *)(malloc ((Gsize + 1) * (Gsize + 1) * 26)); - shadowTop = (unsigned char *)(malloc ((Gsize + 1) * 26)); - - for (x = 0; x <= Gsize; x++) - { - shadowTop[25 * (Gsize + 1) + x] = sum_gaussian (map, 1, x - center, center, Gsize * 2, Gsize * 2); - for(opacity = 0; opacity < 25; opacity++) - shadowTop[opacity * (Gsize + 1) + x] = shadowTop[25 * (Gsize + 1) + x] * opacity / 25; - for(y = 0; y <= x; y++) - { - shadowCorner[25 * (Gsize + 1) * (Gsize + 1) + y * (Gsize + 1) + x] - = sum_gaussian (map, 1, x - center, y - center, Gsize * 2, Gsize * 2); - shadowCorner[25 * (Gsize + 1) * (Gsize + 1) + x * (Gsize + 1) + y] - = shadowCorner[25 * (Gsize + 1) * (Gsize + 1) + y * (Gsize + 1) + x]; - for(opacity = 0; opacity < 25; opacity++) - shadowCorner[opacity * (Gsize + 1) * (Gsize + 1) + y * (Gsize + 1) + x] - = shadowCorner[opacity * (Gsize + 1) * (Gsize + 1) + x * (Gsize + 1) + y] - = shadowCorner[25 * (Gsize + 1) * (Gsize + 1) + y * (Gsize + 1) + x] * opacity / 25; - } - } -} - -static XImage * -make_shadow (Display *dpy, double opacity, int width, int height) -{ - XImage *ximage; - unsigned char *data; - int gsize = gaussianMap->size; - int ylimit, xlimit; - int swidth = width + gsize; - int sheight = height + gsize; - int center = gsize / 2; - int x, y; - unsigned char d; - int x_diff; - int opacity_int = (int)(opacity * 25); - data = malloc (swidth * sheight * sizeof (unsigned char)); - if (!data) - return 0; - ximage = XCreateImage (dpy, - DefaultVisual(dpy, DefaultScreen(dpy)), - 8, - ZPixmap, - 0, - (char *) data, - swidth, sheight, 8, swidth * sizeof (unsigned char)); - if (!ximage) - { - free (data); - return 0; - } - /* - * Build the gaussian in sections - */ - - /* - * center (fill the complete data array) - */ - if (Gsize > 0) - d = shadowTop[opacity_int * (Gsize + 1) + Gsize]; - else - d = sum_gaussian (gaussianMap, opacity, center, center, width, height); - memset(data, d, sheight * swidth); - - /* - * corners - */ - ylimit = gsize; - if (ylimit > sheight / 2) - ylimit = (sheight + 1) / 2; - xlimit = gsize; - if (xlimit > swidth / 2) - xlimit = (swidth + 1) / 2; - - for (y = 0; y < ylimit; y++) - for (x = 0; x < xlimit; x++) - { - if (xlimit == Gsize && ylimit == Gsize) - d = shadowCorner[opacity_int * (Gsize + 1) * (Gsize + 1) + y * (Gsize + 1) + x]; - else - d = sum_gaussian (gaussianMap, opacity, x - center, y - center, width, height); - data[y * swidth + x] = d; - data[(sheight - y - 1) * swidth + x] = d; - data[(sheight - y - 1) * swidth + (swidth - x - 1)] = d; - data[y * swidth + (swidth - x - 1)] = d; - } - - /* - * top/bottom - */ - x_diff = swidth - (gsize * 2); - if (x_diff > 0 && ylimit > 0) - { - for (y = 0; y < ylimit; y++) - { - if (ylimit == Gsize) - d = shadowTop[opacity_int * (Gsize + 1) + y]; - else - d = sum_gaussian (gaussianMap, opacity, center, y - center, width, height); - memset (&data[y * swidth + gsize], d, x_diff); - memset (&data[(sheight - y - 1) * swidth + gsize], d, x_diff); - } - } - - /* - * sides - */ - - for (x = 0; x < xlimit; x++) - { - if (xlimit == Gsize) - d = shadowTop[opacity_int * (Gsize + 1) + x]; - else - d = sum_gaussian (gaussianMap, opacity, x - center, center, width, height); - for (y = gsize; y < sheight - gsize; y++) - { - data[y * swidth + x] = d; - data[y * swidth + (swidth - x - 1)] = d; - } - } - - return ximage; -} - static Picture -shadow_picture (Display *dpy, double opacity, Picture alpha_pict, int width, int height, int *wp, int *hp) -{ - XImage *shadowImage; - Pixmap shadowPixmap; - Picture shadowPicture; - GC gc; - - shadowImage = make_shadow (dpy, opacity, width, height); - if (!shadowImage) - return None; - shadowPixmap = XCreatePixmap (dpy, root, - shadowImage->width, - shadowImage->height, - 8); - if (!shadowPixmap) - { - XDestroyImage (shadowImage); - return None; - } - - shadowPicture = XRenderCreatePicture (dpy, shadowPixmap, - XRenderFindStandardFormat (dpy, PictStandardA8), - 0, 0); - if (!shadowPicture) - { - XDestroyImage (shadowImage); - XFreePixmap (dpy, shadowPixmap); - return None; - } - - gc = XCreateGC (dpy, shadowPixmap, 0, 0); - if (!gc) - { - XDestroyImage (shadowImage); - XFreePixmap (dpy, shadowPixmap); - XRenderFreePicture (dpy, shadowPicture); - return None; - } - - XPutImage (dpy, shadowPixmap, gc, shadowImage, 0, 0, 0, 0, - shadowImage->width, - shadowImage->height); - *wp = shadowImage->width; - *hp = shadowImage->height; - XFreeGC (dpy, gc); - XDestroyImage (shadowImage); - XFreePixmap (dpy, shadowPixmap); - return shadowPicture; -} - -Picture solid_picture (Display *dpy, Bool argb, double a, double r, double g, double b) { Pixmap pixmap; @@ -706,7 +166,7 @@ solid_picture (Display *dpy, Bool argb, double a, double r, double g, double b) return picture; } -void +static void discard_ignore (Display *dpy, unsigned long sequence) { while (ignore_head) @@ -724,7 +184,7 @@ discard_ignore (Display *dpy, unsigned long sequence) } } -void +static void set_ignore (Display *dpy, unsigned long sequence) { ignore *i = malloc (sizeof (ignore)); @@ -736,7 +196,7 @@ set_ignore (Display *dpy, unsigned long sequence) ignore_tail = &i->next; } -int +static int should_ignore (Display *dpy, unsigned long sequence) { discard_ignore (dpy, sequence); @@ -830,54 +290,7 @@ win_extents (Display *dpy, win *w) r.y = w->a.y; r.width = w->a.width + w->a.border_width * 2; r.height = w->a.height + w->a.border_width * 2; - if (compMode != CompSimple && !(w->windowType == winDockAtom && excludeDockShadows)) - { - if (compMode == CompServerShadows || w->mode != WINDOW_ARGB) - { - XRectangle sr; - if (compMode == CompServerShadows) - { - w->shadow_dx = 2; - w->shadow_dy = 7; - w->shadow_width = w->a.width; - w->shadow_height = w->a.height; - } - else - { - w->shadow_dx = shadowOffsetX; - w->shadow_dy = shadowOffsetY; - if (!w->shadow) - { - double opacity = shadowOpacity; - if (w->mode == WINDOW_TRANS) - opacity = opacity * ((double)w->opacity)/((double)OPAQUE); - w->shadow = shadow_picture (dpy, opacity, w->alphaPict, - w->a.width + w->a.border_width * 2, - w->a.height + w->a.border_width * 2, - &w->shadow_width, &w->shadow_height); - } - } - sr.x = w->a.x + w->shadow_dx; - sr.y = w->a.y + w->shadow_dy; - sr.width = w->shadow_width; - sr.height = w->shadow_height; - if (sr.x < r.x) - { - r.width = (r.x + r.width) - sr.x; - r.x = sr.x; - } - if (sr.y < r.y) - { - r.height = (r.y + r.height) - sr.y; - r.y = sr.y; - } - if (sr.x + sr.width > r.x + r.width) - r.width = sr.x + sr.width - r.x; - if (sr.y + sr.height > r.y + r.height) - r.height = sr.y + sr.height - r.y; - } - } return XFixesCreateRegion (dpy, &r, 1); } @@ -1036,38 +449,7 @@ paint_all (Display *dpy, XserverRegion region) for (w = t; w; w = w->prev_trans) { XFixesSetPictureClipRegion (dpy, rootBuffer, 0, 0, w->borderClip); - switch (compMode) { - case CompSimple: - break; - case CompServerShadows: - /* dont' bother drawing shadows on desktop windows */ - if (w->windowType == winDesktopAtom) - break; - set_ignore (dpy, NextRequest (dpy)); - if (w->opacity != OPAQUE && !w->shadowPict) - w->shadowPict = solid_picture (dpy, True, - (double) w->opacity / OPAQUE * 0.3, - 0, 0, 0); - XRenderComposite (dpy, PictOpOver, - w->shadowPict ? w->shadowPict : transBlackPicture, - w->picture, rootBuffer, - 0, 0, 0, 0, - w->a.x + w->shadow_dx, - w->a.y + w->shadow_dy, - w->shadow_width, w->shadow_height); - break; - case CompClientShadows: - /* don't bother drawing shadows on desktop windows */ - if (w->shadow && w->windowType != winDesktopAtom) - { - XRenderComposite (dpy, PictOpOver, blackPicture, w->shadow, rootBuffer, - 0, 0, 0, 0, - w->a.x + w->shadow_dx, - w->a.y + w->shadow_dy, - w->shadow_width, w->shadow_height); - } - break; - } + if (w->opacity != OPAQUE && !w->alphaPict) w->alphaPict = solid_picture (dpy, False, (double) w->opacity / OPAQUE, 0, 0, 0); @@ -1146,21 +528,12 @@ repair_win (Display *dpy, win *w) } else { - XserverRegion o; parts = XFixesCreateRegion (dpy, 0, 0); set_ignore (dpy, NextRequest (dpy)); XDamageSubtract (dpy, w->damage, None, parts); XFixesTranslateRegion (dpy, parts, w->a.x + w->a.border_width, w->a.y + w->a.border_width); - if (compMode == CompServerShadows) - { - o = XFixesCreateRegion (dpy, 0, 0); - XFixesCopyRegion (dpy, o, parts); - XFixesTranslateRegion (dpy, o, w->shadow_dx, w->shadow_dy); - XFixesUnionRegion (dpy, parts, parts, o); - XFixesDestroyRegion (dpy, o); - } } add_damage (dpy, parts); w->damaged = 1; @@ -1170,7 +543,7 @@ static unsigned int get_opacity_prop (Display *dpy, win *w, unsigned int def); static void -map_win (Display *dpy, Window id, unsigned long sequence, Bool fade) +map_win (Display *dpy, Window id, unsigned long sequence) { win *w = find_win (dpy, id); @@ -1191,9 +564,6 @@ map_win (Display *dpy, Window id, unsigned long sequence, Bool fade) w->damage_bounds.width = w->damage_bounds.height = 0; #endif w->damaged = 0; - - if (fade && fadeWindows) - set_fade (dpy, w, 0, get_opacity_percent (dpy, w, 1.0), fade_in_step, 0, False, True, True); } static void @@ -1234,11 +604,6 @@ finish_unmap_win (Display *dpy, win *w) XFixesDestroyRegion (dpy, w->borderSize); w->borderSize = None; } - if (w->shadow) - { - XRenderFreePicture (dpy, w->shadow); - w->shadow = None; - } if (w->borderClip) { XFixesDestroyRegion (dpy, w->borderClip); @@ -1248,27 +613,14 @@ finish_unmap_win (Display *dpy, win *w) clipChanged = True; } -#if HAS_NAME_WINDOW_PIXMAP static void -unmap_callback (Display *dpy, win *w, Bool gone) -{ - finish_unmap_win (dpy, w); -} -#endif - -static void -unmap_win (Display *dpy, Window id, Bool fade) +unmap_win (Display *dpy, Window id) { win *w = find_win (dpy, id); if (!w) return; w->a.map_state = IsUnmapped; -#if HAS_NAME_WINDOW_PIXMAP - if (w->pixmap && fade && fadeWindows) - set_fade (dpy, w, w->opacity*1.0/OPAQUE, 0.0, fade_out_step, unmap_callback, False, False, True); - else -#endif - finish_unmap_win (dpy, w); + finish_unmap_win (dpy, w); } /* Get the opacity prop from window @@ -1296,18 +648,6 @@ get_opacity_prop(Display *dpy, win *w, unsigned int def) return def; } -/* Get the opacity property from the window in a percent format - not found: default - otherwise: the value -*/ -static double -get_opacity_percent(Display *dpy, win *w, double def) -{ - unsigned int opacity = get_opacity_prop (dpy, w, (unsigned int)(OPAQUE*def)); - - return opacity*1.0/OPAQUE; -} - /* determine mode for window all in one place. Future might check for menu flag and other cool things */ @@ -1347,11 +687,6 @@ determine_mode(Display *dpy, win *w) XRenderFreePicture (dpy, w->alphaPict); w->alphaPict = None; } - if (w->shadowPict) - { - XRenderFreePicture (dpy, w->shadowPict); - w->shadowPict = None; - } if (w->a.class == InputOnly) { @@ -1460,14 +795,8 @@ add_win (Display *dpy, Window id, Window prev) new->damage = XDamageCreate (dpy, id, XDamageReportNonEmpty); } new->alphaPict = None; - new->shadowPict = None; new->borderSize = None; new->extents = None; - new->shadow = None; - new->shadow_dx = 0; - new->shadow_dy = 0; - new->shadow_width = 0; - new->shadow_height = 0; new->opacity = OPAQUE; new->borderClip = None; @@ -1478,7 +807,7 @@ add_win (Display *dpy, Window id, Window prev) new->next = *p; *p = new; if (new->a.map_state == IsViewable) - map_win (dpy, id, new->damage_sequence - 1, True); + map_win (dpy, id, new->damage_sequence - 1); } void @@ -1555,11 +884,6 @@ configure_win (Display *dpy, XConfigureEvent *ce) } } #endif - if (w->shadow) - { - XRenderFreePicture (dpy, w->shadow); - w->shadow = None; - } } w->a.width = ce->width; w->a.height = ce->height; @@ -1615,43 +939,21 @@ finish_destroy_win (Display *dpy, Window id, Bool gone) XRenderFreePicture (dpy, w->alphaPict); w->alphaPict = None; } - if (w->shadowPict) - { - XRenderFreePicture (dpy, w->shadowPict); - w->shadowPict = None; - } if (w->damage != None) { set_ignore (dpy, NextRequest (dpy)); XDamageDestroy (dpy, w->damage); w->damage = None; } - cleanup_fade (dpy, w); free (w); break; } } -#if HAS_NAME_WINDOW_PIXMAP static void -destroy_callback (Display *dpy, win *w, Bool gone) +destroy_win (Display *dpy, Window id, Bool gone) { - finish_destroy_win (dpy, w->id, gone); -} -#endif - -static void -destroy_win (Display *dpy, Window id, Bool gone, Bool fade) -{ - win *w = find_win (dpy, id); -#if HAS_NAME_WINDOW_PIXMAP - if (w && w->pixmap && fade && fadeWindows) - set_fade (dpy, w, w->opacity*1.0/OPAQUE, 0.0, fade_out_step, destroy_callback, gone, False, True); - else -#endif - { - finish_destroy_win (dpy, id, gone); - } + finish_destroy_win (dpy, id, gone); } /* @@ -1722,8 +1024,6 @@ damage_win (Display *dpy, XDamageNotifyEvent *de) w->a.height <= w->damage_bounds.y + w->damage_bounds.height) { clipChanged = True; - if (fadeWindows) - set_fade (dpy, w, 0, get_opacity_percent (dpy, w, 1.0), fade_in_step, 0, False, True, True); w->usable = True; } } @@ -1844,21 +1144,6 @@ usage (char *program) fprintf (stderr, "usage: %s [options]\n", program); fprintf (stderr, "Options\n"); fprintf (stderr, " -d display\n Specifies which display should be managed.\n"); - fprintf (stderr, " -r radius\n Specifies the blur radius for client-side shadows. (default 12)\n"); - fprintf (stderr, " -o opacity\n Specifies the translucency for client-side shadows. (default .75)\n"); - fprintf (stderr, " -l left-offset\n Specifies the left offset for client-side shadows. (default -15)\n"); - fprintf (stderr, " -t top-offset\n Specifies the top offset for clinet-side shadows. (default -15)\n"); - fprintf (stderr, " -I fade-in-step\n Specifies the opacity change between steps while fading in. (default 0.028)\n"); - fprintf (stderr, " -O fade-out-step\n Specifies the opacity change between steps while fading out. (default 0.03)\n"); - fprintf (stderr, " -D fade-delta-time\n Specifies the time between steps in a fade in milliseconds. (default 10)\n"); - fprintf (stderr, " -a\n Use automatic server-side compositing. Faster, but no special effects.\n"); - fprintf (stderr, " -c\n Draw client-side shadows with fuzzy edges.\n"); - fprintf (stderr, " -C\n Avoid drawing shadows on dock/panel windows.\n"); - fprintf (stderr, " -f\n Fade windows in/out when opening/closing.\n"); - fprintf (stderr, " -F\n Fade windows during opacity changes.\n"); - fprintf (stderr, " -n\n Normal client-side compositing with transparency support\n"); - fprintf (stderr, " -s\n Draw server-side shadows with sharp edges.\n"); - fprintf (stderr, " -S\n Enable synchronous operation (for debugging).\n"); exit (1); } @@ -1898,63 +1183,12 @@ main (int argc, char **argv) char *display = 0; int o; - while ((o = getopt (argc, argv, "D:I:O:d:r:o:l:t:scnfFCaS")) != -1) + while ((o = getopt (argc, argv, "d:")) != -1) { switch (o) { case 'd': display = optarg; break; - case 'D': - fade_delta = atoi (optarg); - if (fade_delta < 1) - fade_delta = 10; - break; - case 'I': - fade_in_step = atof (optarg); - if (fade_in_step <= 0) - fade_in_step = 0.01; - break; - case 'O': - fade_out_step = atof (optarg); - if (fade_out_step <= 0) - fade_out_step = 0.01; - break; - case 's': - compMode = CompServerShadows; - break; - case 'c': - compMode = CompClientShadows; - break; - case 'C': - excludeDockShadows = True; - break; - case 'n': - compMode = CompSimple; - break; - case 'f': - fadeWindows = True; - break; - case 'F': - fadeTrans = True; - break; - case 'a': - autoRedirect = True; - break; - case 'S': - synchronize = True; - break; - case 'r': - shadowRadius = atoi (optarg); - break; - case 'o': - shadowOpacity = atof (optarg); - break; - case 'l': - shadowOffsetX = atoi (optarg); - break; - case 't': - shadowOffsetY = atoi (optarg); - break; default: usage (argv[0]); break; @@ -1968,8 +1202,6 @@ main (int argc, char **argv) exit (1); } XSetErrorHandler (error); - if (synchronize) - XSynchronize (dpy, 1); scr = DefaultScreen (dpy); root = RootWindow (dpy, scr); @@ -2017,12 +1249,6 @@ main (int argc, char **argv) pa.subwindow_mode = IncludeInferiors; - if (compMode == CompClientShadows) - { - gaussianMap = make_gaussian_map(dpy, shadowRadius); - presum_gaussian (gaussianMap); - } - root_width = DisplayWidth (dpy, scr); root_height = DisplayHeight (dpy, scr); @@ -2032,15 +1258,10 @@ main (int argc, char **argv) CPSubwindowMode, &pa); blackPicture = solid_picture (dpy, True, 1, 0, 0, 0); - if (compMode == CompServerShadows) - transBlackPicture = solid_picture (dpy, True, 0.3, 0, 0, 0); allDamage = None; clipChanged = True; XGrabServer (dpy); - if (autoRedirect) - XCompositeRedirectSubwindows (dpy, root, CompositeRedirectAutomatic); - else - { + XCompositeRedirectSubwindows (dpy, root, CompositeRedirectManual); XSelectInput (dpy, root, SubstructureNotifyMask| @@ -2051,27 +1272,15 @@ main (int argc, char **argv) for (i = 0; i < nchildren; i++) add_win (dpy, children[i], i ? children[i-1] : None); XFree (children); - } + XUngrabServer (dpy); ufd.fd = ConnectionNumber (dpy); ufd.events = POLLIN; - if (!autoRedirect) - paint_all (dpy, None); + paint_all (dpy, None); for (;;) { /* dump_wins (); */ do { - if (autoRedirect) - XFlush (dpy); - if (!QLength (dpy)) - { - if (poll (&ufd, 1, fade_timeout()) == 0) - { - run_fades (dpy); - break; - } - } - XNextEvent (dpy, &ev); if ((ev.type & 0x7f) != KeymapNotify) discard_ignore (dpy, ev.xany.serial); @@ -2079,7 +1288,7 @@ main (int argc, char **argv) printf ("event %10.10s serial 0x%08x window 0x%08x\n", ev_name(&ev), ev_serial (&ev), ev_window (&ev)); #endif - if (!autoRedirect) switch (ev.type) { + switch (ev.type) { case CreateNotify: add_win (dpy, ev.xcreatewindow.window, 0); break; @@ -2087,19 +1296,19 @@ main (int argc, char **argv) configure_win (dpy, &ev.xconfigure); break; case DestroyNotify: - destroy_win (dpy, ev.xdestroywindow.window, True, True); + destroy_win (dpy, ev.xdestroywindow.window, True); break; case MapNotify: - map_win (dpy, ev.xmap.window, ev.xmap.serial, True); + map_win (dpy, ev.xmap.window, ev.xmap.serial); break; case UnmapNotify: - unmap_win (dpy, ev.xunmap.window, True); + unmap_win (dpy, ev.xunmap.window); break; case ReparentNotify: if (ev.xreparent.parent == root) add_win (dpy, ev.xreparent.window, 0); else - destroy_win (dpy, ev.xreparent.window, False, True); + destroy_win (dpy, ev.xreparent.window, False); break; case CirculateNotify: circulate_win (dpy, &ev.xcirculate); @@ -2156,20 +1365,8 @@ main (int argc, char **argv) win * w = find_win(dpy, ev.xproperty.window); if (w) { - if (fadeTrans) - set_fade (dpy, w, w->opacity*1.0/OPAQUE, get_opacity_percent (dpy, w, 1.0), - fade_out_step, 0, False, True, False); - else - { w->opacity = get_opacity_prop(dpy, w, OPAQUE); determine_mode(dpy, w); - if (w->shadow) - { - XRenderFreePicture (dpy, w->shadow); - w->shadow = None; - w->extents = win_extents (dpy, w); - } - } } } break; @@ -2179,11 +1376,9 @@ main (int argc, char **argv) break; } } while (QLength (dpy)); - if (allDamage && !autoRedirect) + if (allDamage) { - static int paint; paint_all (dpy, allDamage); - paint++; XSync (dpy, False); allDamage = None; clipChanged = False;