From cdf7db750da50122afebbb9f3b0259397e9eddde Mon Sep 17 00:00:00 2001 From: Richard Grenville Date: Mon, 17 Sep 2012 16:04:04 +0800 Subject: [PATCH] Improvement: Change painting sequence - Now compton paints windows from the lowest to the highest. Warning: I'm not completely certain that the change won't introduce unexpected glitches. This commit may be revoked in the future. - Remove w->border_clip since it's no longer needed. - Correct a mistake in find_toplevel2(). (clang --analyze found it out.) - Change "func_name()" prototypes to "func_name(void)". If I remember correctly, "func_name()" means you are remaining silent about this function's parameters instead of stating it has no parameter in ANSI C. - Add timestamps to error messages. - Suppress error messages caused by free_damage(). --- src/compton.c | 175 +++++++++++++++++++------------------------------- src/compton.h | 34 +++++----- 2 files changed, 82 insertions(+), 127 deletions(-) diff --git a/src/compton.c b/src/compton.c index a6a99a8..544121e 100644 --- a/src/compton.c +++ b/src/compton.c @@ -14,9 +14,7 @@ * Shared */ -#ifdef DEBUG_EVENTS struct timeval time_start = { 0, 0 }; -#endif win *list; fade *fades; @@ -774,7 +772,7 @@ find_toplevel2(Display *dpy, Window wid) { // just leave it alone. if (!XQueryTree(dpy, wid, &troot, &parent, &tchildren, &tnchildren)) { - wid = 0; + parent = 0; break; } @@ -1114,7 +1112,6 @@ paint_all(Display *dpy, XserverRegion region) { if (clip_changed) { free_region(dpy, &w->border_size); free_region(dpy, &w->extents); - free_region(dpy, &w->border_clip); } if (!w->border_size) { @@ -1150,43 +1147,6 @@ paint_all(Display *dpy, XserverRegion region) { w->frame_opacity_cur = w->frame_opacity; } - if (w->mode == WINDOW_SOLID && !w->frame_opacity) { - int x, y, wid, hei; - -#if HAS_NAME_WINDOW_PIXMAP - x = w->a.x; - y = w->a.y; - wid = w->a.width + w->a.border_width * 2; - hei = w->a.height + w->a.border_width * 2; -#else - x = w->a.x + w->a.border_width; - y = w->a.y + w->a.border_width; - wid = w->a.width; - hei = w->a.height; -#endif - - XFixesSetPictureClipRegion(dpy, root_buffer, 0, 0, region); - set_ignore(dpy, NextRequest(dpy)); - - XFixesSubtractRegion(dpy, region, region, w->border_size); - set_ignore(dpy, NextRequest(dpy)); - - XRenderComposite( - dpy, PictOpSrc, w->picture, - None, root_buffer, 0, 0, 0, 0, - x, y, wid, hei); - - if (w->dim) { - XRenderComposite(dpy, PictOpOver, dim_picture, None, - root_buffer, 0, 0, 0, 0, x, y, wid, hei); - } - } - - if (!w->border_clip) { - w->border_clip = XFixesCreateRegion(dpy, 0, 0); - XFixesCopyRegion(dpy, w->border_clip, region); - } - w->prev_trans = t; t = w; } @@ -1196,15 +1156,29 @@ paint_all(Display *dpy, XserverRegion region) { fflush(stdout); #endif - XFixesSetPictureClipRegion(dpy, - root_buffer, 0, 0, region); + XFixesSetPictureClipRegion(dpy, root_buffer, 0, 0, region); paint_root(dpy); for (w = t; w; w = w->prev_trans) { - XFixesSetPictureClipRegion(dpy, - root_buffer, 0, 0, w->border_clip); + int x, y, wid, hei; +#if HAS_NAME_WINDOW_PIXMAP + x = w->a.x; + y = w->a.y; + wid = w->a.width + w->a.border_width * 2; + hei = w->a.height + w->a.border_width * 2; +#else + x = w->a.x + w->a.border_width; + y = w->a.y + w->a.border_width; + wid = w->a.width; + hei = w->a.height; +#endif + + // Allow shadow to be painted anywhere in the damaged region + XFixesSetPictureClipRegion(dpy, root_buffer, 0, 0, region); + + // Painting shadow if (win_type_shadow[w->window_type]) { XRenderComposite( dpy, PictOpOver, cshadow_picture, w->shadow_pict, @@ -1213,72 +1187,59 @@ paint_all(Display *dpy, XserverRegion region) { w->shadow_width, w->shadow_height); } - if (w->mode != WINDOW_SOLID || w->frame_opacity) { - int x, y, wid, hei; + // The window only could be painted in its bounding region + XserverRegion paint_reg = XFixesCreateRegion(dpy, NULL, 0); + XFixesIntersectRegion(dpy, paint_reg, region, w->border_size); + XFixesSetPictureClipRegion(dpy, root_buffer, 0, 0, paint_reg); - // Necessary to make sure specially-shaped windows are - // painted correctly - XFixesIntersectRegion(dpy, w->border_clip, w->border_clip, w->border_size); - XFixesSetPictureClipRegion(dpy, root_buffer, 0, 0, w->border_clip); -#if HAS_NAME_WINDOW_PIXMAP - x = w->a.x; - y = w->a.y; - wid = w->a.width + w->a.border_width * 2; - hei = w->a.height + w->a.border_width * 2; -#else - x = w->a.x + w->a.border_width; - y = w->a.y + w->a.border_width; - wid = w->a.width; - hei = w->a.height; -#endif + Picture alpha_mask = (OPAQUE == w->opacity ? None: w->alpha_pict); + int op = (w->mode == WINDOW_SOLID ? PictOpSrc: PictOpOver); - set_ignore(dpy, NextRequest(dpy)); - - Picture alpha_mask = (OPAQUE == w->opacity ? None: w->alpha_pict); - - if (!w->frame_opacity) { - XRenderComposite( - dpy, PictOpOver, w->picture, alpha_mask, + // Painting the window + if (!w->frame_opacity) { + XRenderComposite(dpy, op, w->picture, alpha_mask, root_buffer, 0, 0, 0, 0, x, y, wid, hei); - } else { - unsigned int t = w->top_width; - unsigned int l = w->left_width; - unsigned int b = w->bottom_width; - unsigned int r = w->right_width; + } + else { + unsigned int t = w->top_width; + unsigned int l = w->left_width; + unsigned int b = w->bottom_width; + unsigned int r = w->right_width; - /* top */ - XRenderComposite( - dpy, PictOpOver, w->picture, w->frame_alpha_pict, root_buffer, - 0, 0, 0, 0, x, y, wid, t); + /* top */ + XRenderComposite( + dpy, PictOpOver, w->picture, w->frame_alpha_pict, root_buffer, + 0, 0, 0, 0, x, y, wid, t); - /* left */ - XRenderComposite( - dpy, PictOpOver, w->picture, w->frame_alpha_pict, root_buffer, - 0, t, 0, t, x, y + t, l, hei - t); + /* left */ + XRenderComposite( + dpy, PictOpOver, w->picture, w->frame_alpha_pict, root_buffer, + 0, t, 0, t, x, y + t, l, hei - t); - /* bottom */ - XRenderComposite( - dpy, PictOpOver, w->picture, w->frame_alpha_pict, root_buffer, - l, hei - b, l, hei - b, x + l, y + hei - b, wid - l - r, b); + /* bottom */ + XRenderComposite( + dpy, PictOpOver, w->picture, w->frame_alpha_pict, root_buffer, + l, hei - b, l, hei - b, x + l, y + hei - b, wid - l - r, b); - /* right */ - XRenderComposite( - dpy, PictOpOver, w->picture, w->frame_alpha_pict, root_buffer, - wid - r, t, wid - r, t, x + wid - r, y + t, r, hei - t); + /* right */ + XRenderComposite( + dpy, PictOpOver, w->picture, w->frame_alpha_pict, root_buffer, + wid - r, t, wid - r, t, x + wid - r, y + t, r, hei - t); - /* body */ - XRenderComposite( - dpy, PictOpOver, w->picture, alpha_mask, root_buffer, - l, t, l, t, x + l, y + t, wid - l - r, hei - t - b); - } + /* body */ + XRenderComposite( + dpy, op, w->picture, alpha_mask, root_buffer, + l, t, l, t, x + l, y + t, wid - l - r, hei - t - b); - if (w->dim) { - XRenderComposite(dpy, PictOpOver, dim_picture, None, - root_buffer, 0, 0, 0, 0, x, y, wid, hei); - } } - free_region(dpy, &w->border_clip); + // Dimming the window if needed + if (w->dim) { + XRenderComposite(dpy, PictOpOver, dim_picture, None, + root_buffer, 0, 0, 0, 0, x, y, wid, hei); + } + + XFixesDestroyRegion(dpy, paint_reg); } XFixesDestroyRegion(dpy, region); @@ -1547,7 +1508,6 @@ finish_unmap_win(Display *dpy, win *w) { free_picture(dpy, &w->picture); free_region(dpy, &w->border_size); free_picture(dpy, &w->shadow_pict); - free_region(dpy, &w->border_clip); clip_changed = True; } @@ -1567,7 +1527,8 @@ unmap_win(Display *dpy, Window id, Bool fade) { w->a.map_state = IsUnmapped; - /* don't care about properties anymore */ + // don't care about properties anymore + // Will get BadWindow if the window is destroyed set_ignore(dpy, NextRequest(dpy)); XSelectInput(dpy, w->id, 0); @@ -1809,7 +1770,6 @@ add_win(Display *dpy, Window id, Window prev, Bool override_redirect) { new->need_configure = False; new->window_type = WINTYPE_UNKNOWN; - new->border_clip = None; new->prev_trans = 0; new->left_width = 0; @@ -2178,6 +2138,7 @@ error(Display *dpy, XErrorEvent *ev) { break; } + print_timestamp(); printf("error %d (%s) request %d minor %d serial %lu\n", ev->error_code, name, ev->request_code, ev->minor_code, ev->serial); @@ -2577,7 +2538,7 @@ ev_handle(XEvent *ev) { */ static void -usage() { +usage(void) { fprintf(stderr, "compton v0.0.1\n"); fprintf(stderr, "usage: compton [options]\n"); fprintf(stderr, @@ -2669,7 +2630,7 @@ register_cm(int scr) { } static void -fork_after() { +fork_after(void) { if (getppid() == 1) return; int pid = fork(); @@ -2689,7 +2650,7 @@ fork_after() { } static void -get_atoms() { +get_atoms(void) { extents_atom = XInternAtom(dpy, "_NET_FRAME_EXTENTS", False); opacity_atom = XInternAtom(dpy, @@ -2758,9 +2719,7 @@ main(int argc, char **argv) { double shadow_green = 0.0; double shadow_blue = 0.0; -#ifdef DEBUG_EVENTS gettimeofday(&time_start, NULL); -#endif for (i = 0; i < NUM_WINTYPES; ++i) { win_type_fade[i] = False; diff --git a/src/compton.h b/src/compton.h index ef49acb..3ca318f 100644 --- a/src/compton.h +++ b/src/compton.h @@ -36,11 +36,9 @@ // #define DEBUG_WINTYPE 1 // #define MONITOR_REPAINT 1 -#ifdef DEBUG_EVENTS // For printing timestamps #include extern struct timeval time_start; -#endif #define OPAQUE 0xffffffff #define REGISTER_PROP "_NET_WM_CM_S" @@ -135,8 +133,6 @@ typedef struct _win { Bool need_configure; XConfigureEvent queue_configure; - /* for drawing translucent windows */ - XserverRegion border_clip; struct _win *prev_trans; } win; @@ -173,6 +169,15 @@ extern Atom atom_client_attr; // Helper functions +static void +discard_ignore(Display *dpy, unsigned long sequence); + +static void +set_ignore(Display *dpy, unsigned long sequence); + +static int +should_ignore(Display *dpy, unsigned long sequence); + /** * Normalize an int value to a specific range. * @@ -218,7 +223,6 @@ array_wid_exists(const Window *arr, int count, Window wid) { return False; } -#ifdef DEBUG_EVENTS /* * Subtracting two struct timeval values. * @@ -267,7 +271,6 @@ print_timestamp(void) { timeval_subtract(&diff, &tm, &time_start); printf("[ %5ld.%02ld ] ", diff.tv_sec, diff.tv_usec / 10000); } -#endif /** * Destroy a XserverRegion. @@ -308,6 +311,8 @@ free_pixmap(Display *dpy, Pixmap *p) { inline static void free_damage(Display *dpy, Damage *p) { if (*p) { + // BadDamage will be thrown if the window is destroyed + set_ignore(dpy, NextRequest(dpy)); XDamageDestroy(dpy, *p); *p = None; } @@ -360,7 +365,7 @@ win_get_children(Display *dpy, Window w, } static int -get_time_in_milliseconds(); +get_time_in_milliseconds(void); static fade * find_fade(win *w); @@ -411,15 +416,6 @@ static Picture solid_picture(Display *dpy, Bool argb, double a, double r, double g, double b); -static void -discard_ignore(Display *dpy, unsigned long sequence); - -static void -set_ignore(Display *dpy, unsigned long sequence); - -static int -should_ignore(Display *dpy, unsigned long sequence); - static long determine_evmask(Display *dpy, Window wid, win_evmode_t mode); @@ -558,7 +554,7 @@ ev_window(XEvent *ev); #endif static void -usage(); +usage(void); static void register_cm(int scr); @@ -645,7 +641,7 @@ inline static void ev_handle(XEvent *ev); static void -fork_after(); +fork_after(void); static void -get_atoms(); +get_atoms(void);