Feature #65: --focus-exclude
- Add --focus-exclude, which should be used with a list of conditions to set certain windows to always be considered focused. - Change focus determination process, with a newly added w->focused_real that reflects whether the window is actually focused, while w->focused represents whether compton considers it focused. The primary difference is now when a window considered focused because of --mark-wmwin-focused or --mark-ovredir-focused receives a FocusOut event, it's still considered focused by compton. - Change opacity target and dim state calculation so that it's done at most once every paint. - Split window opacity property fetching from calc_opacity() to a new function win_update_opacity_prop(). - Silence a warning in wid_get_prop_wintype(). - Rename a few functions. Code clean-up. - My time is very limited currently, few tests are done, so this commit may very well introduce bugs. - Known issue: Dim picture opacity does not change based on window opacity, causing somehow annoying effects when a window fades off.
This commit is contained in:
parent
0f851b17a2
commit
72c18b6219
|
@ -40,6 +40,7 @@ dbe = false;
|
||||||
paint-on-overlay = false;
|
paint-on-overlay = false;
|
||||||
sw-opti = false;
|
sw-opti = false;
|
||||||
unredir-if-possible = false;
|
unredir-if-possible = false;
|
||||||
|
focus-exclude = [ ];
|
||||||
|
|
||||||
# Window type settings
|
# Window type settings
|
||||||
wintypes:
|
wintypes:
|
||||||
|
|
178
src/compton.c
178
src/compton.c
|
@ -948,7 +948,7 @@ recheck_focus(session_t *ps) {
|
||||||
|
|
||||||
// And we set the focus state and opacity here
|
// And we set the focus state and opacity here
|
||||||
if (w) {
|
if (w) {
|
||||||
set_focused(ps, w, true);
|
win_set_focused(ps, w, true);
|
||||||
return w;
|
return w;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1241,6 +1241,12 @@ paint_preprocess(session_t *ps, win *list) {
|
||||||
if (ps->reg_ignore_expire)
|
if (ps->reg_ignore_expire)
|
||||||
free_region(ps, &w->reg_ignore);
|
free_region(ps, &w->reg_ignore);
|
||||||
|
|
||||||
|
// Update window opacity target and dim state if asked
|
||||||
|
if (WFLAG_OPCT_CHANGE & w->flags) {
|
||||||
|
calc_opacity(ps, w);
|
||||||
|
calc_dim(ps, w);
|
||||||
|
}
|
||||||
|
|
||||||
// Run fading
|
// Run fading
|
||||||
run_fade(ps, w, steps);
|
run_fade(ps, w, steps);
|
||||||
|
|
||||||
|
@ -1754,13 +1760,13 @@ repair_win(session_t *ps, win *w) {
|
||||||
|
|
||||||
static wintype_t
|
static wintype_t
|
||||||
wid_get_prop_wintype(session_t *ps, Window wid) {
|
wid_get_prop_wintype(session_t *ps, Window wid) {
|
||||||
int i, j;
|
int i;
|
||||||
|
|
||||||
set_ignore_next(ps);
|
set_ignore_next(ps);
|
||||||
winprop_t prop = wid_get_prop(ps, wid, ps->atom_win_type, 32L, XA_ATOM, 32);
|
winprop_t prop = wid_get_prop(ps, wid, ps->atom_win_type, 32L, XA_ATOM, 32);
|
||||||
|
|
||||||
for (i = 0; i < prop.nitems; ++i) {
|
for (i = 0; i < prop.nitems; ++i) {
|
||||||
for (j = 1; j < NUM_WINTYPES; ++j) {
|
for (wintype_t j = 1; j < NUM_WINTYPES; ++j) {
|
||||||
if (ps->atoms_wintypes[j] == (Atom) prop.data.p32[i]) {
|
if (ps->atoms_wintypes[j] == (Atom) prop.data.p32[i]) {
|
||||||
free_winprop(&prop);
|
free_winprop(&prop);
|
||||||
return j;
|
return j;
|
||||||
|
@ -1780,9 +1786,10 @@ map_win(session_t *ps, Window id) {
|
||||||
// Don't care about window mapping if it's an InputOnly window
|
// Don't care about window mapping if it's an InputOnly window
|
||||||
if (!w || InputOnly == w->a.class) return;
|
if (!w || InputOnly == w->a.class) return;
|
||||||
|
|
||||||
w->focused = false;
|
w->focused_real = false;
|
||||||
if (ps->o.use_ewmh_active_win && w == ps->active_win)
|
if (ps->o.track_focus && ps->o.use_ewmh_active_win
|
||||||
w->focused = true;
|
&& w == ps->active_win)
|
||||||
|
w->focused_real = true;
|
||||||
|
|
||||||
w->a.map_state = IsViewable;
|
w->a.map_state = IsViewable;
|
||||||
|
|
||||||
|
@ -1841,23 +1848,22 @@ map_win(session_t *ps, Window id) {
|
||||||
win_get_class(ps, w);
|
win_get_class(ps, w);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ps->o.track_focus) {
|
// Occasionally compton does not seem able to get a FocusIn event from
|
||||||
// Occasionally compton does not seem able to get a FocusIn event from
|
// a window just mapped. I suspect it's a timing issue again when the
|
||||||
// a window just mapped. I suspect it's a timing issue again when the
|
// XSelectInput() is called too late. We have to recheck the focused
|
||||||
// XSelectInput() is called too late. We have to recheck the focused
|
// window here. It makes no sense if we are using EWMH
|
||||||
// window here. It makes no sense if we are using EWMH
|
// _NET_ACTIVE_WINDOW.
|
||||||
// _NET_ACTIVE_WINDOW.
|
if (ps->o.track_focus && !ps->o.use_ewmh_active_win) {
|
||||||
if (!ps->o.use_ewmh_active_win)
|
recheck_focus(ps);
|
||||||
recheck_focus(ps);
|
|
||||||
|
|
||||||
// Consider a window without client window a WM window and mark it
|
|
||||||
// focused if mark_wmwin_focused is on, or it's over-redirected and
|
|
||||||
// mark_ovredir_focused is on
|
|
||||||
if ((ps->o.mark_wmwin_focused && !w->client_win)
|
|
||||||
|| (ps->o.mark_ovredir_focused && w->id == w->client_win))
|
|
||||||
w->focused = true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Update window focus state
|
||||||
|
win_update_focused(ps, w);
|
||||||
|
|
||||||
|
// Update opacity and dim state
|
||||||
|
win_update_opacity_prop(ps, w);
|
||||||
|
w->flags |= WFLAG_OPCT_CHANGE;
|
||||||
|
|
||||||
// Check for _COMPTON_SHADOW
|
// Check for _COMPTON_SHADOW
|
||||||
if (ps->o.respect_prop_shadow)
|
if (ps->o.respect_prop_shadow)
|
||||||
win_update_attr_shadow_raw(ps, w);
|
win_update_attr_shadow_raw(ps, w);
|
||||||
|
@ -1865,9 +1871,6 @@ map_win(session_t *ps, Window id) {
|
||||||
// Many things above could affect shadow
|
// Many things above could affect shadow
|
||||||
determine_shadow(ps, w);
|
determine_shadow(ps, w);
|
||||||
|
|
||||||
// Fading in
|
|
||||||
calc_opacity(ps, w, true);
|
|
||||||
|
|
||||||
// Set fading state
|
// Set fading state
|
||||||
if (ps->o.no_fading_openclose) {
|
if (ps->o.no_fading_openclose) {
|
||||||
set_fade_callback(ps, w, finish_map_win, true);
|
set_fade_callback(ps, w, finish_map_win, true);
|
||||||
|
@ -1880,8 +1883,6 @@ map_win(session_t *ps, Window id) {
|
||||||
determine_fade(ps, w);
|
determine_fade(ps, w);
|
||||||
}
|
}
|
||||||
|
|
||||||
calc_dim(ps, w);
|
|
||||||
|
|
||||||
w->damaged = 1;
|
w->damaged = 1;
|
||||||
|
|
||||||
|
|
||||||
|
@ -1931,7 +1932,7 @@ unmap_win(session_t *ps, Window id) {
|
||||||
w->a.map_state = IsUnmapped;
|
w->a.map_state = IsUnmapped;
|
||||||
|
|
||||||
// Fading out
|
// Fading out
|
||||||
w->opacity_tgt = 0;
|
w->flags |= WFLAG_OPCT_CHANGE;
|
||||||
set_fade_callback(ps, w, unmap_callback, false);
|
set_fade_callback(ps, w, unmap_callback, false);
|
||||||
if (ps->o.no_fading_openclose)
|
if (ps->o.no_fading_openclose)
|
||||||
w->fade = false;
|
w->fade = false;
|
||||||
|
@ -2006,35 +2007,23 @@ determine_mode(session_t *ps, win *w) {
|
||||||
* refetched
|
* refetched
|
||||||
*/
|
*/
|
||||||
static void
|
static void
|
||||||
calc_opacity(session_t *ps, win *w, bool refetch_prop) {
|
calc_opacity(session_t *ps, win *w) {
|
||||||
opacity_t opacity;
|
opacity_t opacity = OPAQUE;
|
||||||
|
|
||||||
// Do nothing for unmapped window, calc_opacity() will be called
|
if (w->destroyed || IsViewable != w->a.map_state)
|
||||||
// when it's mapped
|
opacity = 0;
|
||||||
// I suppose I need not to check for IsUnviewable here?
|
else {
|
||||||
if (IsViewable != w->a.map_state) return;
|
// Try obeying opacity property and window type opacity firstly
|
||||||
|
if (OPAQUE == (opacity = w->opacity_prop)
|
||||||
|
&& OPAQUE == (opacity = w->opacity_prop_client)) {
|
||||||
|
opacity = ps->o.wintype_opacity[w->window_type] * OPAQUE;
|
||||||
|
}
|
||||||
|
|
||||||
// Do not refetch the opacity window attribute unless necessary, this
|
// Respect inactive_opacity in some cases
|
||||||
// is probably an expensive operation in some cases
|
if (ps->o.inactive_opacity && is_normal_win(w) && false == w->focused
|
||||||
if (refetch_prop) {
|
&& (OPAQUE == opacity || ps->o.inactive_opacity_override)) {
|
||||||
w->opacity_prop = wid_get_opacity_prop(ps, w->id, OPAQUE);
|
opacity = ps->o.inactive_opacity;
|
||||||
if (!ps->o.detect_client_opacity || !w->client_win
|
}
|
||||||
|| w->id == w->client_win)
|
|
||||||
w->opacity_prop_client = OPAQUE;
|
|
||||||
else
|
|
||||||
w->opacity_prop_client = wid_get_opacity_prop(ps, w->client_win,
|
|
||||||
OPAQUE);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (OPAQUE == (opacity = w->opacity_prop)
|
|
||||||
&& OPAQUE == (opacity = w->opacity_prop_client)) {
|
|
||||||
opacity = ps->o.wintype_opacity[w->window_type] * OPAQUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Respect inactive_opacity in some cases
|
|
||||||
if (ps->o.inactive_opacity && is_normal_win(w) && false == w->focused
|
|
||||||
&& (OPAQUE == opacity || ps->o.inactive_opacity_override)) {
|
|
||||||
opacity = ps->o.inactive_opacity;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
w->opacity_tgt = opacity;
|
w->opacity_tgt = opacity;
|
||||||
|
@ -2047,6 +2036,10 @@ static void
|
||||||
calc_dim(session_t *ps, win *w) {
|
calc_dim(session_t *ps, win *w) {
|
||||||
bool dim;
|
bool dim;
|
||||||
|
|
||||||
|
// Make sure we do nothing if the window is unmapped / destroyed
|
||||||
|
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 && is_normal_win(w) && !(w->focused)) {
|
||||||
dim = true;
|
dim = true;
|
||||||
} else {
|
} else {
|
||||||
|
@ -2273,6 +2266,7 @@ add_win(session_t *ps, Window id, Window prev) {
|
||||||
new->class_general = NULL;
|
new->class_general = NULL;
|
||||||
new->cache_sblst = NULL;
|
new->cache_sblst = NULL;
|
||||||
new->cache_fblst = NULL;
|
new->cache_fblst = NULL;
|
||||||
|
new->cache_fcblst = NULL;
|
||||||
new->bounding_shaped = false;
|
new->bounding_shaped = false;
|
||||||
new->rounded_corners = false;
|
new->rounded_corners = false;
|
||||||
|
|
||||||
|
@ -2298,6 +2292,7 @@ add_win(session_t *ps, Window id, Window prev) {
|
||||||
new->frame_alpha_pict = None;
|
new->frame_alpha_pict = None;
|
||||||
new->dim = false;
|
new->dim = false;
|
||||||
new->focused = false;
|
new->focused = false;
|
||||||
|
new->focused_real = false;
|
||||||
new->destroyed = false;
|
new->destroyed = false;
|
||||||
new->need_configure = false;
|
new->need_configure = false;
|
||||||
new->window_type = WINTYPE_UNKNOWN;
|
new->window_type = WINTYPE_UNKNOWN;
|
||||||
|
@ -2517,7 +2512,7 @@ destroy_win(session_t *ps, Window id) {
|
||||||
w->destroyed = true;
|
w->destroyed = true;
|
||||||
|
|
||||||
// Fading out the window
|
// Fading out the window
|
||||||
w->opacity_tgt = 0;
|
w->flags |= WFLAG_OPCT_CHANGE;
|
||||||
set_fade_callback(ps, w, destroy_callback, false);
|
set_fade_callback(ps, w, destroy_callback, false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2909,7 +2904,7 @@ ev_focus_in(session_t *ps, XFocusChangeEvent *ev) {
|
||||||
// To deal with events sent from windows just destroyed
|
// To deal with events sent from windows just destroyed
|
||||||
if (!w) return;
|
if (!w) return;
|
||||||
|
|
||||||
set_focused(ps, w, true);
|
win_set_focused(ps, w, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline static void
|
inline static void
|
||||||
|
@ -2926,7 +2921,7 @@ ev_focus_out(session_t *ps, XFocusChangeEvent *ev) {
|
||||||
// To deal with events sent from windows just destroyed
|
// To deal with events sent from windows just destroyed
|
||||||
if (!w) return;
|
if (!w) return;
|
||||||
|
|
||||||
set_focused(ps, w, false);
|
win_set_focused(ps, w, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline static void
|
inline static void
|
||||||
|
@ -3039,10 +3034,9 @@ update_ewmh_active_win(session_t *ps) {
|
||||||
|
|
||||||
// Mark the window focused
|
// Mark the window focused
|
||||||
if (w) {
|
if (w) {
|
||||||
if (!w->focused)
|
win_set_focused(ps, w, true);
|
||||||
set_focused(ps, w, true);
|
|
||||||
if (ps->active_win && w != ps->active_win)
|
if (ps->active_win && w != ps->active_win)
|
||||||
set_focused(ps, ps->active_win, false);
|
win_set_focused(ps, ps->active_win, false);
|
||||||
ps->active_win = w;
|
ps->active_win = w;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3079,7 +3073,7 @@ ev_property_notify(session_t *ps, XPropertyEvent *ev) {
|
||||||
w->opacity_prop_client = wid_get_opacity_prop(ps, w->client_win,
|
w->opacity_prop_client = wid_get_opacity_prop(ps, w->client_win,
|
||||||
OPAQUE);
|
OPAQUE);
|
||||||
if (w) {
|
if (w) {
|
||||||
calc_opacity(ps, w, false);
|
w->flags |= WFLAG_OPCT_CHANGE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3097,8 +3091,10 @@ ev_property_notify(session_t *ps, XPropertyEvent *ev) {
|
||||||
if (ps->o.track_wdata
|
if (ps->o.track_wdata
|
||||||
&& (ps->atom_name == ev->atom || ps->atom_name_ewmh == ev->atom)) {
|
&& (ps->atom_name == ev->atom || ps->atom_name_ewmh == ev->atom)) {
|
||||||
win *w = find_toplevel(ps, ev->window);
|
win *w = find_toplevel(ps, ev->window);
|
||||||
if (w && 1 == win_get_name(ps, w))
|
if (w && 1 == win_get_name(ps, w)) {
|
||||||
determine_shadow(ps, w);
|
determine_shadow(ps, w);
|
||||||
|
win_update_focused(ps, w);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// If class changes
|
// If class changes
|
||||||
|
@ -3107,6 +3103,7 @@ ev_property_notify(session_t *ps, XPropertyEvent *ev) {
|
||||||
if (w) {
|
if (w) {
|
||||||
win_get_class(ps, w);
|
win_get_class(ps, w);
|
||||||
determine_shadow(ps, w);
|
determine_shadow(ps, w);
|
||||||
|
win_update_focused(ps, w);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3354,7 +3351,6 @@ usage(void) {
|
||||||
" Detect _NET_WM_OPACITY on client windows, useful for window\n"
|
" Detect _NET_WM_OPACITY on client windows, useful for window\n"
|
||||||
" managers not passing _NET_WM_OPACITY of client windows to frame\n"
|
" managers not passing _NET_WM_OPACITY of client windows to frame\n"
|
||||||
" windows.\n"
|
" windows.\n"
|
||||||
"\n"
|
|
||||||
"--refresh-rate val\n"
|
"--refresh-rate val\n"
|
||||||
" Specify refresh rate of the screen. If not specified or 0, compton\n"
|
" Specify refresh rate of the screen. If not specified or 0, compton\n"
|
||||||
" will try detecting this with X RandR extension.\n"
|
" will try detecting this with X RandR extension.\n"
|
||||||
|
@ -3390,6 +3386,9 @@ usage(void) {
|
||||||
" Unredirect all windows if a full-screen opaque window is\n"
|
" Unredirect all windows if a full-screen opaque window is\n"
|
||||||
" detected, to maximize performance for full-screen windows.\n"
|
" detected, to maximize performance for full-screen windows.\n"
|
||||||
" Experimental.\n"
|
" Experimental.\n"
|
||||||
|
"--focus-exclude condition\n"
|
||||||
|
" Specify a list of conditions of windows that should always be\n"
|
||||||
|
" considered focused.\n"
|
||||||
"\n"
|
"\n"
|
||||||
"Format of a condition:\n"
|
"Format of a condition:\n"
|
||||||
"\n"
|
"\n"
|
||||||
|
@ -3632,6 +3631,28 @@ parse_vsync(session_t *ps, const char *optarg) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Parse a condition list in configuration file.
|
||||||
|
*/
|
||||||
|
static void
|
||||||
|
parse_cfg_condlst(const config_t *pcfg, wincond_t **pcondlst,
|
||||||
|
const char *name) {
|
||||||
|
config_setting_t *setting = config_lookup(pcfg, name);
|
||||||
|
if (setting) {
|
||||||
|
// Parse an array of options
|
||||||
|
if (config_setting_is_array(setting)) {
|
||||||
|
int i = config_setting_length(setting);
|
||||||
|
while (i--) {
|
||||||
|
condlst_add(pcondlst, config_setting_get_string_elem(setting, i));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Treat it as a single pattern if it's a string
|
||||||
|
else if (CONFIG_TYPE_STRING == config_setting_type(setting)) {
|
||||||
|
condlst_add(pcondlst, config_setting_get_string(setting));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Parse a configuration file from default location.
|
* Parse a configuration file from default location.
|
||||||
*/
|
*/
|
||||||
|
@ -3763,25 +3784,9 @@ parse_config(session_t *ps, char *cpath, struct options_tmp *pcfgtmp) {
|
||||||
lcfg_lookup_bool(&cfg, "unredir-if-possible",
|
lcfg_lookup_bool(&cfg, "unredir-if-possible",
|
||||||
&ps->o.unredir_if_possible);
|
&ps->o.unredir_if_possible);
|
||||||
// --shadow-exclude
|
// --shadow-exclude
|
||||||
{
|
parse_cfg_condlst(&cfg, &ps->o.shadow_blacklist, "shadow-exclude");
|
||||||
config_setting_t *setting =
|
// --focus-exclude
|
||||||
config_lookup(&cfg, "shadow-exclude");
|
parse_cfg_condlst(&cfg, &ps->o.focus_blacklist, "focus-exclude");
|
||||||
if (setting) {
|
|
||||||
// Parse an array of shadow-exclude
|
|
||||||
if (config_setting_is_array(setting)) {
|
|
||||||
int i = config_setting_length(setting);
|
|
||||||
while (i--) {
|
|
||||||
condlst_add(&ps->o.shadow_blacklist,
|
|
||||||
config_setting_get_string_elem(setting, i));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// Treat it as a single pattern if it's a string
|
|
||||||
else if (CONFIG_TYPE_STRING == config_setting_type(setting)) {
|
|
||||||
condlst_add(&ps->o.shadow_blacklist,
|
|
||||||
config_setting_get_string(setting));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// Wintype settings
|
// Wintype settings
|
||||||
{
|
{
|
||||||
wintype_t i;
|
wintype_t i;
|
||||||
|
@ -3835,6 +3840,7 @@ get_cfg(session_t *ps, int argc, char *const *argv) {
|
||||||
{ "use-ewmh-active-win", no_argument, NULL, 276 },
|
{ "use-ewmh-active-win", no_argument, NULL, 276 },
|
||||||
{ "respect-prop-shadow", no_argument, NULL, 277 },
|
{ "respect-prop-shadow", no_argument, NULL, 277 },
|
||||||
{ "unredir-if-possible", no_argument, NULL, 278 },
|
{ "unredir-if-possible", no_argument, NULL, 278 },
|
||||||
|
{ "focus-exclude", required_argument, NULL, 279 },
|
||||||
// Must terminate with a NULL entry
|
// Must terminate with a NULL entry
|
||||||
{ NULL, 0, NULL, 0 },
|
{ NULL, 0, NULL, 0 },
|
||||||
};
|
};
|
||||||
|
@ -4036,6 +4042,10 @@ get_cfg(session_t *ps, int argc, char *const *argv) {
|
||||||
// --unredir-if-possible
|
// --unredir-if-possible
|
||||||
ps->o.unredir_if_possible = true;
|
ps->o.unredir_if_possible = true;
|
||||||
break;
|
break;
|
||||||
|
case 279:
|
||||||
|
// --focus-exclude
|
||||||
|
condlst_add(&ps->o.focus_blacklist, optarg);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
usage();
|
usage();
|
||||||
}
|
}
|
||||||
|
@ -4082,7 +4092,8 @@ get_cfg(session_t *ps, int argc, char *const *argv) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Determine whether we need to track window name and class
|
// Determine whether we need to track window name and class
|
||||||
if (ps->o.shadow_blacklist || ps->o.fade_blacklist)
|
if (ps->o.shadow_blacklist || ps->o.fade_blacklist
|
||||||
|
|| ps->o.focus_blacklist)
|
||||||
ps->o.track_wdata = true;
|
ps->o.track_wdata = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4564,6 +4575,7 @@ session_init(session_t *ps_old, int argc, char **argv) {
|
||||||
.inactive_dim = 0.0,
|
.inactive_dim = 0.0,
|
||||||
.alpha_step = 0.03,
|
.alpha_step = 0.03,
|
||||||
.use_ewmh_active_win = false,
|
.use_ewmh_active_win = false,
|
||||||
|
.focus_blacklist = NULL,
|
||||||
|
|
||||||
.track_focus = false,
|
.track_focus = false,
|
||||||
.track_wdata = false,
|
.track_wdata = false,
|
||||||
|
|
|
@ -116,6 +116,8 @@
|
||||||
#define WFLAG_SIZE_CHANGE 0x0001
|
#define WFLAG_SIZE_CHANGE 0x0001
|
||||||
// Window size/position is changed
|
// Window size/position is changed
|
||||||
#define WFLAG_POS_CHANGE 0x0002
|
#define WFLAG_POS_CHANGE 0x0002
|
||||||
|
// Window opacity / dim state changed
|
||||||
|
#define WFLAG_OPCT_CHANGE 0x0004
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Types
|
* Types
|
||||||
|
@ -290,8 +292,12 @@ typedef struct {
|
||||||
double inactive_dim;
|
double inactive_dim;
|
||||||
/// Step for pregenerating alpha pictures. 0.01 - 1.0.
|
/// Step for pregenerating alpha pictures. 0.01 - 1.0.
|
||||||
double alpha_step;
|
double alpha_step;
|
||||||
|
|
||||||
|
// === Focus related ===
|
||||||
/// Whether to use EWMH _NET_ACTIVE_WINDOW to find active window.
|
/// Whether to use EWMH _NET_ACTIVE_WINDOW to find active window.
|
||||||
bool use_ewmh_active_win;
|
bool use_ewmh_active_win;
|
||||||
|
/// A list of windows always to be considered focused.
|
||||||
|
wincond_t *focus_blacklist;
|
||||||
|
|
||||||
// === Calculated ===
|
// === Calculated ===
|
||||||
/// Whether compton needs to track focus changes.
|
/// Whether compton needs to track focus changes.
|
||||||
|
@ -512,8 +518,10 @@ typedef struct _win {
|
||||||
XserverRegion extents;
|
XserverRegion extents;
|
||||||
// Type of the window.
|
// Type of the window.
|
||||||
wintype_t window_type;
|
wintype_t window_type;
|
||||||
/// Whether the window is focused.
|
/// Whether the window is to be considered focused.
|
||||||
bool focused;
|
bool focused;
|
||||||
|
/// Whether the window is actually focused.
|
||||||
|
bool focused_real;
|
||||||
/// Whether the window has been destroyed.
|
/// Whether the window has been destroyed.
|
||||||
bool destroyed;
|
bool destroyed;
|
||||||
/// Cached width/height of the window including border.
|
/// Cached width/height of the window including border.
|
||||||
|
@ -531,6 +539,7 @@ typedef struct _win {
|
||||||
char *class_general;
|
char *class_general;
|
||||||
wincond_t *cache_sblst;
|
wincond_t *cache_sblst;
|
||||||
wincond_t *cache_fblst;
|
wincond_t *cache_fblst;
|
||||||
|
wincond_t *cache_fcblst;
|
||||||
|
|
||||||
// Opacity-related members
|
// Opacity-related members
|
||||||
/// Current window opacity.
|
/// Current window opacity.
|
||||||
|
@ -1354,6 +1363,20 @@ unmap_win(session_t *ps, Window id);
|
||||||
static opacity_t
|
static opacity_t
|
||||||
wid_get_opacity_prop(session_t *ps, Window wid, opacity_t def);
|
wid_get_opacity_prop(session_t *ps, Window wid, opacity_t def);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reread opacity property of a window.
|
||||||
|
*/
|
||||||
|
static inline void
|
||||||
|
win_update_opacity_prop(session_t *ps, win *w) {
|
||||||
|
w->opacity_prop = wid_get_opacity_prop(ps, w->id, OPAQUE);
|
||||||
|
if (!ps->o.detect_client_opacity || !w->client_win
|
||||||
|
|| w->id == w->client_win)
|
||||||
|
w->opacity_prop_client = OPAQUE;
|
||||||
|
else
|
||||||
|
w->opacity_prop_client = wid_get_opacity_prop(ps, w->client_win,
|
||||||
|
OPAQUE);
|
||||||
|
}
|
||||||
|
|
||||||
static double
|
static double
|
||||||
get_opacity_percent(win *w);
|
get_opacity_percent(win *w);
|
||||||
|
|
||||||
|
@ -1361,16 +1384,39 @@ static void
|
||||||
determine_mode(session_t *ps, win *w);
|
determine_mode(session_t *ps, win *w);
|
||||||
|
|
||||||
static void
|
static void
|
||||||
calc_opacity(session_t *ps, win *w, bool refetch_prop);
|
calc_opacity(session_t *ps, win *w);
|
||||||
|
|
||||||
static void
|
static void
|
||||||
calc_dim(session_t *ps, win *w);
|
calc_dim(session_t *ps, win *w);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Update focused state of a window.
|
||||||
|
*/
|
||||||
static inline void
|
static inline void
|
||||||
set_focused(session_t *ps, win *w, bool focused) {
|
win_update_focused(session_t *ps, win *w) {
|
||||||
w->focused = focused;
|
bool focused_old = w->focused;
|
||||||
calc_opacity(ps, w, false);
|
|
||||||
calc_dim(ps, w);
|
w->focused = w->focused_real;
|
||||||
|
|
||||||
|
// Consider a window without client window a WM window and mark it
|
||||||
|
// focused if mark_wmwin_focused is on, or it's over-redirected and
|
||||||
|
// mark_ovredir_focused is on
|
||||||
|
if ((ps->o.mark_wmwin_focused && !w->client_win)
|
||||||
|
|| (ps->o.mark_ovredir_focused && w->id == w->client_win)
|
||||||
|
|| win_match(w, ps->o.focus_blacklist, &w->cache_fcblst))
|
||||||
|
w->focused = true;
|
||||||
|
|
||||||
|
if (w->focused != focused_old)
|
||||||
|
w->flags |= WFLAG_OPCT_CHANGE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set real focused state of a window.
|
||||||
|
*/
|
||||||
|
static inline void
|
||||||
|
win_set_focused(session_t *ps, win *w, bool focused) {
|
||||||
|
w->focused_real = focused;
|
||||||
|
win_update_focused(ps, w);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -1628,6 +1674,10 @@ lcfg_lookup_int(const config_t *config, const char *path, int *value) {
|
||||||
static FILE *
|
static FILE *
|
||||||
open_config_file(char *cpath, char **path);
|
open_config_file(char *cpath, char **path);
|
||||||
|
|
||||||
|
static void
|
||||||
|
parse_cfg_condlst(const config_t *pcfg, wincond_t **pcondlst,
|
||||||
|
const char *name);
|
||||||
|
|
||||||
static void
|
static void
|
||||||
parse_config(session_t *ps, char *cpath, struct options_tmp *pcfgtmp);
|
parse_config(session_t *ps, char *cpath, struct options_tmp *pcfgtmp);
|
||||||
#endif
|
#endif
|
||||||
|
|
Loading…
Reference in New Issue