From 9a99e7a0dd752669c4bb9d23bddacbf69eaf79c8 Mon Sep 17 00:00:00 2001 From: Richard Grenville Date: Sat, 19 Apr 2014 19:41:26 +0800 Subject: [PATCH] Misc: Try to avoid evaluating conditions after window unmap & others - Try to avoid evaluating conditions after window unmap/destruction. Unfortunately, frequently this doesn't work due to the asynchronous nature of X. - Add _GTK_FRAME_EXTENTS exclusion rules to compton.sample.conf. Thanks to memeplex, hexchain, and others for info. (#189) - Add debugging option --show-all-xerrors, and other debugging changes. Doc update. --- compton.sample.conf | 14 ++++++++-- man/compton.1.asciidoc | 11 +++++++- src/c2.c | 2 ++ src/common.h | 19 +++++++++++--- src/compton.c | 58 ++++++++++++++++++++++++++++-------------- 5 files changed, 78 insertions(+), 26 deletions(-) diff --git a/compton.sample.conf b/compton.sample.conf index 2e656a1..c84ef04 100644 --- a/compton.sample.conf +++ b/compton.sample.conf @@ -10,7 +10,13 @@ shadow-offset-y = -7; # shadow-red = 0.0; # shadow-green = 0.0; # shadow-blue = 0.0; -shadow-exclude = [ "name = 'Notification'", "class_g = 'Conky'", "class_g ?= 'Notify-osd'", "class_g = 'Cairo-clock'" ]; +shadow-exclude = [ + "name = 'Notification'", + "class_g = 'Conky'", + "class_g ?= 'Notify-osd'", + "class_g = 'Cairo-clock'", + "_GTK_FRAME_EXTENTS@:c" +]; # shadow-exclude = "n:e:Notification"; shadow-ignore-shaped = false; # shadow-exclude-reg = "x10+0+0"; @@ -30,7 +36,11 @@ alpha-step = 0.06; blur-kern = "3x3box" # blur-kern = "5,5,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1" # blur-background-fixed = true; -blur-background-exclude = [ "window_type = 'dock'", "window_type = 'desktop'" ]; +blur-background-exclude = [ + "window_type = 'dock'", + "window_type = 'desktop'", + "_GTK_FRAME_EXTENTS@:c" +]; # opacity-rule = [ "80:class_g = 'URxvt'" ]; # Fading diff --git a/man/compton.1.asciidoc b/man/compton.1.asciidoc index 3b5773a..35d0d21 100644 --- a/man/compton.1.asciidoc +++ b/man/compton.1.asciidoc @@ -2,7 +2,7 @@ compton(1) ========== :doctype: manpage :man source: compton -:man version: nightly-20130421 +:man version: nightly-20140419 :man manual: LOCAL USER COMMANDS NAME @@ -83,6 +83,9 @@ OPTIONS *-S*:: Enable synchronous X operation (for debugging). +*--show-all-xerrors*:: + Show all X errors (for debugging). + *--config* 'PATH':: Look for configuration file at the path. See *CONFIGURATION FILES* section below for where compton looks for a configuration file by default. @@ -255,6 +258,12 @@ May also be one of the predefined kernels: `3x3box` (default), `5x5box`, `7x7box *--glx-use-gpushader4*:: GLX backend: Use 'GL_EXT_gpu_shader4' for some optimization on blur GLSL code. My tests on GTX 670 show no noticeable effect. +*--xrender-sync*:: + Attempt to synchronize client applications' draw calls with `XSync()`, used on GLX backend to ensure up-to-date window content is painted. + +*--xrender-sync-fence*:: + Additionally use X Sync fence to sync clients' draw calls. Needed on nvidia-drivers with GLX backend for some users. May be disabled at compile time with `NO_XSYNC=1`. + *--dbus*:: Enable remote control via D-Bus. See the *D-BUS API* section below for more details. diff --git a/src/c2.c b/src/c2.c index de221c0..f70dcb5 100644 --- a/src/c2.c +++ b/src/c2.c @@ -1292,6 +1292,8 @@ c2_match_once(session_t *ps, win *w, const c2_ptr_t cond) { bool c2_matchd(session_t *ps, win *w, const c2_lptr_t *condlst, const c2_lptr_t **cache, void **pdata) { + assert(IsViewable == w->a.map_state); + // Check if the cached entry matches firstly if (cache && *cache && c2_match_once(ps, w, (*cache)->ptr)) { if (pdata) diff --git a/src/common.h b/src/common.h index 525b9a9..5b6a266 100644 --- a/src/common.h +++ b/src/common.h @@ -14,6 +14,7 @@ // === Options === // Debug options, enable them using -D in CFLAGS +// #define DEBUG_BACKTRACE 1 // #define DEBUG_REPAINT 1 // #define DEBUG_EVENTS 1 // #define DEBUG_RESTACK 1 @@ -72,6 +73,10 @@ #define COMPTON_VERSION "unknown" #endif +#if defined(DEBUG_ALLOC_REG) +#define DEBUG_BACKTRACE 1 +#endif + // === Includes === // For some special functions @@ -568,6 +573,8 @@ typedef struct _options_t { c2_lptr_t *paint_blacklist; /// Whether to work under synchronized mode for debugging. bool synchronize; + /// Whether to show all X errors. + bool show_all_xerrors; // === VSync & software optimization === /// User-specified refresh rate. @@ -1192,13 +1199,13 @@ extern session_t *ps_g; static inline void print_timestamp(session_t *ps); -#ifdef DEBUG_ALLOC_REG +#ifdef DEBUG_BACKTRACE #include -#define BACKTRACE_SIZE 5 +#define BACKTRACE_SIZE 25 /** - * Print current backtrace, excluding the first two items. + * Print current backtrace. * * Stolen from glibc manual. */ @@ -1211,12 +1218,14 @@ print_backtrace(void) { size = backtrace(array, BACKTRACE_SIZE); strings = backtrace_symbols(array, size); - for (size_t i = 2; i < size; i++) + for (size_t i = 0; i < size; i++) printf ("%s\n", strings[i]); free(strings); } +#ifdef DEBUG_ALLOC_REG + /** * Wrapper of XFixesCreateRegion, for debugging. */ @@ -1247,6 +1256,8 @@ XFixesDestroyRegion_(Display *dpy, XserverRegion reg, #define XFixesDestroyRegion(dpy, reg) XFixesDestroyRegion_(dpy, reg, __func__, __LINE__) #endif +#endif + // === Functions === /** diff --git a/src/compton.c b/src/compton.c index 1da926b..f58661b 100644 --- a/src/compton.c +++ b/src/compton.c @@ -576,6 +576,9 @@ discard_ignore(session_t *ps, unsigned long sequence) { static void set_ignore(session_t *ps, unsigned long sequence) { + if (ps->o.show_all_xerrors) + return; + ignore_t *i = malloc(sizeof(ignore_t)); if (!i) return; @@ -2374,8 +2377,13 @@ static void win_determine_fade(session_t *ps, win *w) { if (UNSET != w->fade_force) w->fade = w->fade_force; - else if ((ps->o.no_fading_openclose && w->in_openclose) - || win_match(ps, w, ps->o.fade_blacklist, &w->cache_fblst)) + else if (ps->o.no_fading_openclose && w->in_openclose) + w->fade = false; + // Ignore other possible causes of fading state changes after window + // gets unmapped + else if (IsViewable != w->a.map_state) { + } + else if (win_match(ps, w, ps->o.fade_blacklist, &w->cache_fblst)) w->fade = false; else w->fade = ps->o.wintype_fade[w->window_type]; @@ -2403,8 +2411,7 @@ win_update_shape(session_t *ps, win *w) { win_update_shape_raw(ps, w); - // Shadow state could be changed - win_determine_shadow(ps, w); + win_on_factor_change(ps, w); /* // If clear_shadow state on the window possibly changed, destroy the old @@ -2457,13 +2464,14 @@ static void win_determine_shadow(session_t *ps, win *w) { bool shadow_old = w->shadow; - w->shadow = (UNSET == w->shadow_force ? - (ps->o.wintype_shadow[w->window_type] - && !win_match(ps, w, ps->o.shadow_blacklist, &w->cache_sblst) - && !(ps->o.shadow_ignore_shaped && w->bounding_shaped - && !w->rounded_corners) - && !(ps->o.respect_prop_shadow && 0 == w->prop_shadow)) - : w->shadow_force); + if (UNSET != w->shadow_force) + w->shadow = w->shadow_force; + else if (IsViewable == w->a.map_state) + w->shadow = (ps->o.wintype_shadow[w->window_type] + && !win_match(ps, w, ps->o.shadow_blacklist, &w->cache_sblst) + && !(ps->o.shadow_ignore_shaped && w->bounding_shaped + && !w->rounded_corners) + && !(ps->o.respect_prop_shadow && 0 == w->prop_shadow)); // Window extents need update on shadow state change if (w->shadow != shadow_old) { @@ -2488,17 +2496,13 @@ win_determine_shadow(session_t *ps, win *w) { */ static void win_determine_invert_color(session_t *ps, win *w) { - // Do not change window invert color state when the window is unmapped, - // unless it comes from w->invert_color_force. - if (UNSET == w->invert_color_force && IsViewable != w->a.map_state) - return; - bool invert_color_old = w->invert_color; if (UNSET != w->invert_color_force) w->invert_color = w->invert_color_force; - else - w->invert_color = win_match(ps, w, ps->o.invert_color_list, &w->cache_ivclst); + else if (IsViewable == w->a.map_state) + w->invert_color = win_match(ps, w, ps->o.invert_color_list, + &w->cache_ivclst); if (w->invert_color != invert_color_old) add_damage_win(ps, w); @@ -2509,6 +2513,9 @@ win_determine_invert_color(session_t *ps, win *w) { */ static void win_determine_blur_background(session_t *ps, win *w) { + if (IsViewable != w->a.map_state) + return; + bool blur_background_old = w->blur_background; w->blur_background = ps->o.blur_background @@ -2526,6 +2533,9 @@ win_determine_blur_background(session_t *ps, win *w) { */ static void win_update_opacity_rule(session_t *ps, win *w) { + if (IsViewable != w->a.map_state) + return; + // If long is 32-bit, unfortunately there's no way could we express "unset", // so we just entirely don't distinguish "unset" and OPAQUE opacity_t opacity = OPAQUE; @@ -3295,11 +3305,13 @@ xerror(Display __attribute__((unused)) *dpy, XErrorEvent *ev) { { char buf[BUF_LEN] = ""; XGetErrorText(ps->dpy, ev->error_code, buf, BUF_LEN); - printf("error %d (%s) request %d minor %d serial %lu (\"%s\")\n", + printf("error %4d %-12s request %4d minor %4d serial %6lu: \"%s\"\n", ev->error_code, name, ev->request_code, ev->minor_code, ev->serial, buf); } + // print_backtrace(); + return 0; } @@ -3904,10 +3916,12 @@ ev_focus_report(XFocusChangeEvent* ev) { * Determine whether we should respond to a FocusIn/Out * event. */ +/* inline static bool ev_focus_accept(XFocusChangeEvent *ev) { return NotifyNormal == ev->mode || NotifyUngrab == ev->mode; } +*/ static inline void ev_focus_in(session_t *ps, XFocusChangeEvent *ev) { @@ -4401,6 +4415,8 @@ usage(int ret) { " Daemonize process.\n" "-S\n" " Enable synchronous operation (for debugging).\n" + "--show-all-xerrors\n" + " Show all X errors (for debugging).\n" "--config path\n" " Look for configuration file at the path.\n" "--write-pid-path path\n" @@ -5522,6 +5538,7 @@ get_cfg(session_t *ps, int argc, char *const *argv, bool first_pass) { { "vsync-use-glfinish", no_argument, NULL, 311 }, { "xrender-sync", no_argument, NULL, 312 }, { "xrender-sync-fence", no_argument, NULL, 313 }, + { "show-all-xerrors", no_argument, NULL, 314 }, // Must terminate with a NULL entry { NULL, 0, NULL, 0 }, }; @@ -5542,6 +5559,8 @@ get_cfg(session_t *ps, int argc, char *const *argv, bool first_pass) { ps->o.display = mstrcpy(optarg); else if ('S' == o) ps->o.synchronize = true; + else if (314 == o) + ps->o.show_all_xerrors = true; else if ('?' == o || ':' == o) usage(1); } @@ -5595,6 +5614,7 @@ get_cfg(session_t *ps, int argc, char *const *argv, bool first_pass) { break; case 'd': case 'S': + case 314: break; P_CASELONG('D', fade_delta); case 'I':