From 8d4a3f899f8efb03da4c1ab52234e463c45396df Mon Sep 17 00:00:00 2001 From: Richard Grenville Date: Mon, 10 Dec 2012 10:31:24 +0800 Subject: [PATCH] Feature: Wintype-based focus exclusion - Add "focus" to the wintypes settings in compton.conf, to mark windows of certain window types to be always focused. Replaces the ugly is_normal_win(). - Add a ON/OFF/UNSET switch_t type, but it's unused currently. - Mark client_win if the window client detection hasn't been performed when we detect WM_STATE's presence in ev_property_notify(), for performance. --- compton.c | 16 +++++++++++++--- compton.h | 37 +++++++++++++++++++++++++++++-------- 2 files changed, 42 insertions(+), 11 deletions(-) diff --git a/compton.c b/compton.c index b535383b0..cdf321d54 100644 --- a/compton.c +++ b/compton.c @@ -2034,7 +2034,7 @@ calc_opacity(session_t *ps, win *w) { } // Respect inactive_opacity in some cases - if (ps->o.inactive_opacity && is_normal_win(w) && false == w->focused + if (ps->o.inactive_opacity && false == w->focused && (OPAQUE == opacity || ps->o.inactive_opacity_override)) { opacity = ps->o.inactive_opacity; } @@ -2054,7 +2054,7 @@ calc_dim(session_t *ps, win *w) { if (w->destroyed || IsViewable != w->a.map_state) return; - if (ps->o.inactive_dim && is_normal_win(w) && !(w->focused)) { + if (ps->o.inactive_dim && !(w->focused)) { dim = true; } else { dim = false; @@ -3211,7 +3211,8 @@ ev_property_notify(session_t *ps, XPropertyEvent *ev) { determine_evmask(ps, ev->window, WIN_EVMODE_UNKNOWN)); win *w_top = find_toplevel2(ps, ev->window); - if (w_top && w_top->client_win == w_top->id + // Initialize client_win as early as possible + if (w_top && (!w_top->client_win || w_top->client_win == w_top->id) && wid_has_prop(ps, ev->window, ps->atom_client)) { w_top->wmwin = false; win_unmark_client(ps, w_top); @@ -3971,6 +3972,8 @@ parse_config(session_t *ps, char *cpath, struct options_tmp *pcfgtmp) { ps->o.wintype_shadow[i] = (bool) ival; if (config_setting_lookup_bool(setting, "fade", &ival)) ps->o.wintype_fade[i] = (bool) ival; + if (config_setting_lookup_bool(setting, "focus", &ival)) + ps->o.wintype_focus[i] = (bool) ival; config_setting_lookup_float(setting, "opacity", &ps->o.wintype_opacity[i]); } @@ -4752,6 +4755,8 @@ session_init(session_t *ps_old, int argc, char **argv) { .inactive_dim = 0.0, .inactive_dim_fixed = false, .alpha_step = 0.03, + + .wintype_focus = { false }, .use_ewmh_active_win = false, .focus_blacklist = NULL, @@ -4836,6 +4841,11 @@ session_init(session_t *ps_old, int argc, char **argv) { ps->ignore_tail = &ps->ignore_head; gettimeofday(&ps->time_start, NULL); + wintype_arr_enable(ps->o.wintype_focus); + ps->o.wintype_focus[WINTYPE_UNKNOWN] = false; + ps->o.wintype_focus[WINTYPE_NORMAL] = false; + ps->o.wintype_focus[WINTYPE_UTILITY] = false; + get_cfg(ps, argc, argv); // Inherit old Display if possible, primarily for resource leak checking diff --git a/compton.h b/compton.h index 6b4eed221..0ff235432 100644 --- a/compton.h +++ b/compton.h @@ -162,6 +162,13 @@ typedef enum { NUM_WINTYPES } wintype_t; +/// Enumeration type to represent switches. +typedef enum { + OFF, // false + ON, // true + UNSET +} switch_t; + typedef enum { WINDOW_SOLID, WINDOW_TRANS, @@ -266,6 +273,7 @@ typedef struct { bool vsync_aggressive; // === Shadow === + /// Enable/disable shadow for specific window types. bool wintype_shadow[NUM_WINTYPES]; /// Red, green and blue tone of the shadow. double shadow_red, shadow_green, shadow_blue; @@ -281,6 +289,7 @@ typedef struct { bool respect_prop_shadow; // === Fading === + /// Enable/disable fading for specific window types. bool wintype_fade[NUM_WINTYPES]; /// How much to fade in in a single fading step. opacity_t fade_in_step; @@ -293,6 +302,7 @@ typedef struct { wincond_t *fade_blacklist; // === Opacity === + /// Default opacity for specific window types double wintype_opacity[NUM_WINTYPES]; /// Default opacity for inactive windows. /// 32-bit integer with the format of _NET_WM_OPACITY. 0 stands for @@ -316,6 +326,8 @@ typedef struct { double alpha_step; // === Focus related === + /// Consider windows of specific types to be always focused. + bool wintype_focus[NUM_WINTYPES]; /// Whether to use EWMH _NET_ACTIVE_WINDOW to find active window. bool use_ewmh_active_win; /// A list of windows always to be considered focused. @@ -764,7 +776,7 @@ sub_unslong(unsigned long a, unsigned long b) { /** * Set a bool array of all wintypes to true. */ -static void +static inline void wintype_arr_enable(bool arr[]) { wintype_t i; @@ -773,6 +785,18 @@ wintype_arr_enable(bool arr[]) { } } +/** + * Set a switch_t array of all unset wintypes to true. + */ +static inline void +wintype_arr_enable_unset(switch_t arr[]) { + wintype_t i; + + for (i = 0; i < NUM_WINTYPES; ++i) + if (UNSET == arr[i]) + arr[i] = ON; +} + /** * Allocate the space and copy a string. */ @@ -1147,11 +1171,6 @@ static Picture solid_picture(session_t *ps, bool argb, double a, double r, double g, double b); -static inline bool is_normal_win(const win *w) { - return (WINTYPE_NORMAL == w->window_type - || WINTYPE_UTILITY == w->window_type); -} - /** * Determine if a window has a specific property. * @@ -1439,8 +1458,10 @@ win_update_focused(session_t *ps, win *w) { w->focused = w->focused_real; - // Treat WM windows and override-redirected windows specially - if ((ps->o.mark_wmwin_focused && w->wmwin) + // Use wintype_focus, and treat WM windows and override-redirected + // windows specially + if (ps->o.wintype_focus[w->window_type] + || (ps->o.mark_wmwin_focused && w->wmwin) || (ps->o.mark_ovredir_focused && w->id == w->client_win && !w->wmwin) || win_match(w, ps->o.focus_blacklist, &w->cache_fcblst))