Feature #75: Invert window color
- Add window color inversion (--invert-color-include). It means 2-3 times extra painting, so performance issues are likely to appear. I hope I could find a faster way to invert colors. - Rename some functions. - Fix update of some window properties after window type/data change. Hopefully this will be helpful for #73. - Split win_build_picture() from win_blur_background(). - Correct memory leak of ps->focus_blacklist during reinitialization. - Add win_upd_t and win_upd_run(), to reduce duplicate window property updates. But is unused right now. - Limited tests are done overall. Bugs to be expected.
This commit is contained in:
parent
57c5854fd0
commit
2165c42d27
|
@ -48,6 +48,7 @@ unredir-if-possible = false;
|
||||||
focus-exclude = [ ];
|
focus-exclude = [ ];
|
||||||
detect-transient = true;
|
detect-transient = true;
|
||||||
detect-client-leader = true;
|
detect-client-leader = true;
|
||||||
|
invert-color-include = [ ];
|
||||||
|
|
||||||
# Window type settings
|
# Window type settings
|
||||||
wintypes:
|
wintypes:
|
||||||
|
|
232
src/compton.c
232
src/compton.c
|
@ -1242,7 +1242,7 @@ paint_preprocess(session_t *ps, win *list) {
|
||||||
if (to_paint) {
|
if (to_paint) {
|
||||||
// If opacity changes
|
// If opacity changes
|
||||||
if (w->opacity != opacity_old) {
|
if (w->opacity != opacity_old) {
|
||||||
determine_mode(ps, w);
|
win_determine_mode(ps, w);
|
||||||
add_damage_win(ps, w);
|
add_damage_win(ps, w);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1430,6 +1430,38 @@ win_paint_shadow(session_t *ps, win *w, Picture tgt_buffer) {
|
||||||
w->shadow_width, w->shadow_height);
|
w->shadow_width, w->shadow_height);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create an alternative picture for a window.
|
||||||
|
*/
|
||||||
|
static inline Picture
|
||||||
|
win_build_picture(session_t *ps, win *w, Visual *visual) {
|
||||||
|
const int wid = w->widthb;
|
||||||
|
const int hei = w->heightb;
|
||||||
|
int depth = 0;
|
||||||
|
XRenderPictFormat *pictformat = NULL;
|
||||||
|
|
||||||
|
if (visual && ps->vis != visual) {
|
||||||
|
pictformat = XRenderFindVisualFormat(ps->dpy, visual);
|
||||||
|
depth = pictformat->depth;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
pictformat = XRenderFindVisualFormat(ps->dpy, ps->vis);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!depth)
|
||||||
|
depth = ps->depth;
|
||||||
|
|
||||||
|
Pixmap tmp_pixmap = XCreatePixmap(ps->dpy, ps->root, wid, hei, depth);
|
||||||
|
if (!tmp_pixmap)
|
||||||
|
return None;
|
||||||
|
|
||||||
|
Picture tmp_picture = XRenderCreatePicture(ps->dpy, tmp_pixmap,
|
||||||
|
pictformat, 0, 0);
|
||||||
|
free_pixmap(ps, &tmp_pixmap);
|
||||||
|
|
||||||
|
return tmp_picture;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Blur the background of a window.
|
* Blur the background of a window.
|
||||||
*/
|
*/
|
||||||
|
@ -1451,24 +1483,17 @@ win_blur_background(session_t *ps, win *w, Picture tgt_buffer,
|
||||||
XDoubleToFixed(1), XDoubleToFixed(1), XDoubleToFixed(1),
|
XDoubleToFixed(1), XDoubleToFixed(1), XDoubleToFixed(1),
|
||||||
};
|
};
|
||||||
|
|
||||||
Pixmap tmp_pixmap = None;
|
const int x = w->a.x;
|
||||||
Picture tmp_picture = None;
|
const int y = w->a.y;
|
||||||
|
const int wid = w->widthb;
|
||||||
int x = w->a.x;
|
const int hei = w->heightb;
|
||||||
int y = w->a.y;
|
|
||||||
int wid = w->widthb;
|
|
||||||
int hei = w->heightb;
|
|
||||||
|
|
||||||
// Directly copying from tgt_buffer does not work, so we create a
|
// Directly copying from tgt_buffer does not work, so we create a
|
||||||
// Picture in the middle.
|
// Picture in the middle.
|
||||||
tmp_pixmap = XCreatePixmap(ps->dpy, ps->root, wid, hei, ps->depth);
|
Picture tmp_picture = win_build_picture(ps, w, NULL);
|
||||||
if (!tmp_pixmap)
|
|
||||||
goto win_blur_background_err;
|
|
||||||
|
|
||||||
tmp_picture = XRenderCreatePicture(ps->dpy, tmp_pixmap,
|
|
||||||
XRenderFindVisualFormat(ps->dpy, ps->vis), 0, 0);
|
|
||||||
if (!tmp_picture)
|
if (!tmp_picture)
|
||||||
goto win_blur_background_err;
|
return;
|
||||||
|
|
||||||
// Adjust blur strength according to window opacity, to make it appear
|
// Adjust blur strength according to window opacity, to make it appear
|
||||||
// better during fading
|
// better during fading
|
||||||
|
@ -1496,8 +1521,6 @@ win_blur_background(session_t *ps, win *w, Picture tgt_buffer,
|
||||||
xrfilter_reset(ps, tgt_buffer);
|
xrfilter_reset(ps, tgt_buffer);
|
||||||
XRenderComposite(ps->dpy, PictOpSrc, tmp_picture, None, tgt_buffer, 0, 0, 0, 0, x, y, wid, hei);
|
XRenderComposite(ps->dpy, PictOpSrc, tmp_picture, None, tgt_buffer, 0, 0, 0, 0, x, y, wid, hei);
|
||||||
|
|
||||||
win_blur_background_err:
|
|
||||||
free_pixmap(ps, &tmp_pixmap);
|
|
||||||
free_picture(ps, &tmp_picture);
|
free_picture(ps, &tmp_picture);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1513,9 +1536,27 @@ win_paint_win(session_t *ps, win *w, Picture tgt_buffer) {
|
||||||
|
|
||||||
Picture alpha_mask = (OPAQUE == w->opacity ? None: w->alpha_pict);
|
Picture alpha_mask = (OPAQUE == w->opacity ? None: w->alpha_pict);
|
||||||
int op = (w->mode == WMODE_SOLID ? PictOpSrc: PictOpOver);
|
int op = (w->mode == WMODE_SOLID ? PictOpSrc: PictOpOver);
|
||||||
|
Picture pict = w->picture;
|
||||||
|
|
||||||
|
// Invert window color, if required
|
||||||
|
if (w->invert_color) {
|
||||||
|
Picture newpict = win_build_picture(ps, w, w->a.visual);
|
||||||
|
if (newpict) {
|
||||||
|
XRenderComposite(ps->dpy, PictOpSrc, pict, None,
|
||||||
|
newpict, 0, 0, 0, 0, 0, 0, wid, hei);
|
||||||
|
XRenderComposite(ps->dpy, PictOpDifference, ps->white_picture, None,
|
||||||
|
newpict, 0, 0, 0, 0, 0, 0, wid, hei);
|
||||||
|
// We use an extra PictOpInReverse operation to get correct pixel
|
||||||
|
// alpha. There could be a better solution.
|
||||||
|
if (WMODE_ARGB == w->mode)
|
||||||
|
XRenderComposite(ps->dpy, PictOpInReverse, pict, None,
|
||||||
|
newpict, 0, 0, 0, 0, 0, 0, wid, hei);
|
||||||
|
pict = newpict;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (!w->frame_opacity) {
|
if (!w->frame_opacity) {
|
||||||
XRenderComposite(ps->dpy, op, w->picture, alpha_mask,
|
XRenderComposite(ps->dpy, op, pict, alpha_mask,
|
||||||
tgt_buffer, 0, 0, 0, 0, x, y, wid, hei);
|
tgt_buffer, 0, 0, 0, 0, x, y, wid, hei);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
@ -1526,7 +1567,7 @@ win_paint_win(session_t *ps, win *w, Picture tgt_buffer) {
|
||||||
const int r = w->a.border_width + w->right_width;
|
const int r = w->a.border_width + w->right_width;
|
||||||
|
|
||||||
#define COMP_BDR(cx, cy, cwid, chei) \
|
#define COMP_BDR(cx, cy, cwid, chei) \
|
||||||
XRenderComposite(ps->dpy, PictOpOver, w->picture, w->frame_alpha_pict, \
|
XRenderComposite(ps->dpy, PictOpOver, pict, w->frame_alpha_pict, \
|
||||||
tgt_buffer, (cx), (cy), 0, 0, x + (cx), y + (cy), (cwid), (chei))
|
tgt_buffer, (cx), (cy), 0, 0, x + (cx), y + (cy), (cwid), (chei))
|
||||||
|
|
||||||
// The following complicated logic is required because some broken
|
// The following complicated logic is required because some broken
|
||||||
|
@ -1562,7 +1603,7 @@ win_paint_win(session_t *ps, win *w, Picture tgt_buffer) {
|
||||||
pwid = wid - l - pwid;
|
pwid = wid - l - pwid;
|
||||||
if (pwid > 0) {
|
if (pwid > 0) {
|
||||||
// body
|
// body
|
||||||
XRenderComposite(ps->dpy, op, w->picture, alpha_mask,
|
XRenderComposite(ps->dpy, op, pict, alpha_mask,
|
||||||
tgt_buffer, l, t, 0, 0, x + l, y + t, pwid, phei);
|
tgt_buffer, l, t, 0, 0, x + l, y + t, pwid, phei);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1572,6 +1613,9 @@ win_paint_win(session_t *ps, win *w, Picture tgt_buffer) {
|
||||||
|
|
||||||
#undef COMP_BDR
|
#undef COMP_BDR
|
||||||
|
|
||||||
|
if (pict != w->picture)
|
||||||
|
free_picture(ps, &pict);
|
||||||
|
|
||||||
// Dimming the window if needed
|
// Dimming the window if needed
|
||||||
if (w->dim && w->dim_alpha_pict != ps->alpha_picts[0]) {
|
if (w->dim && w->dim_alpha_pict != ps->alpha_picts[0]) {
|
||||||
XRenderComposite(ps->dpy, PictOpOver, ps->black_picture,
|
XRenderComposite(ps->dpy, PictOpOver, ps->black_picture,
|
||||||
|
@ -1919,7 +1963,7 @@ map_win(session_t *ps, Window id) {
|
||||||
win_update_prop_shadow_raw(ps, w);
|
win_update_prop_shadow_raw(ps, w);
|
||||||
|
|
||||||
// Many things above could affect shadow
|
// Many things above could affect shadow
|
||||||
determine_shadow(ps, w);
|
win_determine_shadow(ps, w);
|
||||||
|
|
||||||
// Set fading state
|
// Set fading state
|
||||||
if (ps->o.no_fading_openclose) {
|
if (ps->o.no_fading_openclose) {
|
||||||
|
@ -1930,7 +1974,7 @@ map_win(session_t *ps, Window id) {
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
set_fade_callback(ps, w, NULL, true);
|
set_fade_callback(ps, w, NULL, true);
|
||||||
determine_fade(ps, w);
|
win_determine_fade(ps, w);
|
||||||
}
|
}
|
||||||
|
|
||||||
w->damaged = true;
|
w->damaged = true;
|
||||||
|
@ -1947,7 +1991,7 @@ map_win(session_t *ps, Window id) {
|
||||||
static void
|
static void
|
||||||
finish_map_win(session_t *ps, win *w) {
|
finish_map_win(session_t *ps, win *w) {
|
||||||
if (ps->o.no_fading_openclose)
|
if (ps->o.no_fading_openclose)
|
||||||
determine_fade(ps, w);
|
win_determine_fade(ps, w);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -2015,7 +2059,7 @@ get_opacity_percent(win *w) {
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
determine_mode(session_t *ps, win *w) {
|
win_determine_mode(session_t *ps, win *w) {
|
||||||
winmode_t mode = WMODE_SOLID;
|
winmode_t mode = WMODE_SOLID;
|
||||||
XRenderPictFormat *format;
|
XRenderPictFormat *format;
|
||||||
|
|
||||||
|
@ -2109,7 +2153,7 @@ calc_dim(session_t *ps, win *w) {
|
||||||
* Determine if a window should fade on opacity change.
|
* Determine if a window should fade on opacity change.
|
||||||
*/
|
*/
|
||||||
static void
|
static void
|
||||||
determine_fade(session_t *ps, win *w) {
|
win_determine_fade(session_t *ps, win *w) {
|
||||||
w->fade = ps->o.wintype_fade[w->window_type];
|
w->fade = ps->o.wintype_fade[w->window_type];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2136,7 +2180,7 @@ win_update_shape(session_t *ps, win *w) {
|
||||||
win_update_shape_raw(ps, w);
|
win_update_shape_raw(ps, w);
|
||||||
|
|
||||||
// Shadow state could be changed
|
// Shadow state could be changed
|
||||||
determine_shadow(ps, w);
|
win_determine_shadow(ps, w);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
// If clear_shadow state on the window possibly changed, destroy the old
|
// If clear_shadow state on the window possibly changed, destroy the old
|
||||||
|
@ -2178,7 +2222,7 @@ win_update_prop_shadow(session_t *ps, win *w) {
|
||||||
win_update_prop_shadow_raw(ps, w);
|
win_update_prop_shadow_raw(ps, w);
|
||||||
|
|
||||||
if (w->prop_shadow != attr_shadow_old)
|
if (w->prop_shadow != attr_shadow_old)
|
||||||
determine_shadow(ps, w);
|
win_determine_shadow(ps, w);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -2186,7 +2230,7 @@ win_update_prop_shadow(session_t *ps, win *w) {
|
||||||
* on shadow state.
|
* on shadow state.
|
||||||
*/
|
*/
|
||||||
static void
|
static void
|
||||||
determine_shadow(session_t *ps, win *w) {
|
win_determine_shadow(session_t *ps, win *w) {
|
||||||
bool shadow_old = w->shadow;
|
bool shadow_old = w->shadow;
|
||||||
|
|
||||||
w->shadow = (UNSET == w->shadow_force ?
|
w->shadow = (UNSET == w->shadow_force ?
|
||||||
|
@ -2215,10 +2259,73 @@ determine_shadow(session_t *ps, win *w) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Determine if a window should have color inverted.
|
||||||
|
*/
|
||||||
|
static void
|
||||||
|
win_determine_invert_color(session_t *ps, win *w) {
|
||||||
|
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(w, ps->o.invert_color_list, &w->cache_ivclst);
|
||||||
|
|
||||||
|
if (w->invert_color != invert_color_old)
|
||||||
|
add_damage_win(ps, w);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Function to be called on window type changes.
|
||||||
|
*/
|
||||||
|
static void
|
||||||
|
win_on_wtype_change(session_t *ps, win *w) {
|
||||||
|
win_determine_shadow(ps, w);
|
||||||
|
win_determine_fade(ps, w);
|
||||||
|
win_update_focused(ps, w);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Function to be called on window data changes.
|
||||||
|
*/
|
||||||
|
static void
|
||||||
|
win_on_wdata_change(session_t *ps, win *w) {
|
||||||
|
if (ps->o.shadow_blacklist)
|
||||||
|
win_determine_shadow(ps, w);
|
||||||
|
if (ps->o.fade_blacklist)
|
||||||
|
win_determine_fade(ps, w);
|
||||||
|
if (ps->o.invert_color_list)
|
||||||
|
win_determine_invert_color(ps, w);
|
||||||
|
if (ps->o.focus_blacklist)
|
||||||
|
win_update_focused(ps, w);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Process needed window updates.
|
||||||
|
*/
|
||||||
|
static void
|
||||||
|
win_upd_run(session_t *ps, win *w, win_upd_t *pupd) {
|
||||||
|
if (pupd->shadow) {
|
||||||
|
win_determine_shadow(ps, w);
|
||||||
|
pupd->shadow = false;
|
||||||
|
}
|
||||||
|
if (pupd->fade) {
|
||||||
|
win_determine_fade(ps, w);
|
||||||
|
pupd->fade = false;
|
||||||
|
}
|
||||||
|
if (pupd->invert_color) {
|
||||||
|
win_determine_invert_color(ps, w);
|
||||||
|
pupd->invert_color = false;
|
||||||
|
}
|
||||||
|
if (pupd->focus) {
|
||||||
|
win_update_focused(ps, w);
|
||||||
|
pupd->focus = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Update cache data in struct _win that depends on window size.
|
* Update cache data in struct _win that depends on window size.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static void
|
static void
|
||||||
calc_win_size(session_t *ps, win *w) {
|
calc_win_size(session_t *ps, win *w) {
|
||||||
w->widthb = w->a.width + w->a.border_width * 2;
|
w->widthb = w->a.width + w->a.border_width * 2;
|
||||||
|
@ -2254,7 +2361,8 @@ win_mark_client(session_t *ps, win *w, Window client) {
|
||||||
if (IsViewable != w->a.map_state)
|
if (IsViewable != w->a.map_state)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
XSelectInput(ps->dpy, client, determine_evmask(ps, client, WIN_EVMODE_CLIENT));
|
XSelectInput(ps->dpy, client,
|
||||||
|
determine_evmask(ps, client, WIN_EVMODE_CLIENT));
|
||||||
|
|
||||||
// Make sure the XSelectInput() requests are sent
|
// Make sure the XSelectInput() requests are sent
|
||||||
XSync(ps->dpy, False);
|
XSync(ps->dpy, False);
|
||||||
|
@ -2264,19 +2372,26 @@ win_mark_client(session_t *ps, win *w, Window client) {
|
||||||
get_frame_extents(ps, w, client);
|
get_frame_extents(ps, w, client);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Detect window type here
|
{
|
||||||
if (WINTYPE_UNKNOWN == w->window_type)
|
wintype_t wtype_old = w->window_type;
|
||||||
w->window_type = wid_get_prop_wintype(ps, w->client_win);
|
|
||||||
|
|
||||||
// Conform to EWMH standard, if _NET_WM_WINDOW_TYPE is not present, take
|
// Detect window type here
|
||||||
// override-redirect windows or windows without WM_TRANSIENT_FOR as
|
if (WINTYPE_UNKNOWN == w->window_type)
|
||||||
// _NET_WM_WINDOW_TYPE_NORMAL, otherwise as _NET_WM_WINDOW_TYPE_DIALOG.
|
w->window_type = wid_get_prop_wintype(ps, w->client_win);
|
||||||
if (WINTYPE_UNKNOWN == w->window_type) {
|
|
||||||
if (w->a.override_redirect
|
// Conform to EWMH standard, if _NET_WM_WINDOW_TYPE is not present, take
|
||||||
|| !wid_has_prop(ps, client, ps->atom_transient))
|
// override-redirect windows or windows without WM_TRANSIENT_FOR as
|
||||||
w->window_type = WINTYPE_NORMAL;
|
// _NET_WM_WINDOW_TYPE_NORMAL, otherwise as _NET_WM_WINDOW_TYPE_DIALOG.
|
||||||
else
|
if (WINTYPE_UNKNOWN == w->window_type) {
|
||||||
w->window_type = WINTYPE_DIALOG;
|
if (w->a.override_redirect
|
||||||
|
|| !wid_has_prop(ps, client, ps->atom_transient))
|
||||||
|
w->window_type = WINTYPE_NORMAL;
|
||||||
|
else
|
||||||
|
w->window_type = WINTYPE_DIALOG;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (w->window_type != wtype_old)
|
||||||
|
win_on_wtype_change(ps, w);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get window group
|
// Get window group
|
||||||
|
@ -2288,6 +2403,7 @@ win_mark_client(session_t *ps, win *w, Window client) {
|
||||||
win_get_name(ps, w);
|
win_get_name(ps, w);
|
||||||
win_get_class(ps, w);
|
win_get_class(ps, w);
|
||||||
win_get_role(ps, w);
|
win_get_role(ps, w);
|
||||||
|
win_on_wdata_change(ps, w);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Update window focus state
|
// Update window focus state
|
||||||
|
@ -2393,6 +2509,7 @@ add_win(session_t *ps, Window id, Window prev) {
|
||||||
.cache_sblst = NULL,
|
.cache_sblst = NULL,
|
||||||
.cache_fblst = NULL,
|
.cache_fblst = NULL,
|
||||||
.cache_fcblst = NULL,
|
.cache_fcblst = NULL,
|
||||||
|
.cache_ivclst = NULL,
|
||||||
|
|
||||||
.opacity = 0,
|
.opacity = 0,
|
||||||
.opacity_tgt = 0,
|
.opacity_tgt = 0,
|
||||||
|
@ -2423,6 +2540,9 @@ add_win(session_t *ps, Window id, Window prev) {
|
||||||
|
|
||||||
.dim = false,
|
.dim = false,
|
||||||
.dim_alpha_pict = None,
|
.dim_alpha_pict = None,
|
||||||
|
|
||||||
|
.invert_color = false,
|
||||||
|
.invert_color_force = UNSET,
|
||||||
};
|
};
|
||||||
|
|
||||||
// Reject overlay window and already added windows
|
// Reject overlay window and already added windows
|
||||||
|
@ -3480,8 +3600,7 @@ ev_property_notify(session_t *ps, XPropertyEvent *ev) {
|
||||||
&& (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);
|
win_on_wdata_change(ps, w);
|
||||||
win_update_focused(ps, w);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3490,8 +3609,7 @@ ev_property_notify(session_t *ps, XPropertyEvent *ev) {
|
||||||
win *w = find_toplevel(ps, ev->window);
|
win *w = find_toplevel(ps, ev->window);
|
||||||
if (w) {
|
if (w) {
|
||||||
win_get_class(ps, w);
|
win_get_class(ps, w);
|
||||||
determine_shadow(ps, w);
|
win_on_wdata_change(ps, w);
|
||||||
win_update_focused(ps, w);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3499,8 +3617,7 @@ ev_property_notify(session_t *ps, XPropertyEvent *ev) {
|
||||||
if (ps->o.track_wdata && ps->atom_role == ev->atom) {
|
if (ps->o.track_wdata && ps->atom_role == ev->atom) {
|
||||||
win *w = find_toplevel(ps, ev->window);
|
win *w = find_toplevel(ps, ev->window);
|
||||||
if (w && 1 == win_get_role(ps, w)) {
|
if (w && 1 == win_get_role(ps, w)) {
|
||||||
determine_shadow(ps, w);
|
win_on_wdata_change(ps, w);
|
||||||
win_update_focused(ps, w);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3816,6 +3933,9 @@ usage(void) {
|
||||||
"--blur-background-fixed\n"
|
"--blur-background-fixed\n"
|
||||||
" Use fixed blur strength instead of adjusting according to window\n"
|
" Use fixed blur strength instead of adjusting according to window\n"
|
||||||
" opacity.\n"
|
" opacity.\n"
|
||||||
|
"--invert-color-include condition\n"
|
||||||
|
" Specify a list of conditions of windows that should be painted with\n"
|
||||||
|
" inverted color. Resource-hogging, and is not well tested.\n"
|
||||||
"\n"
|
"\n"
|
||||||
"Format of a condition:\n"
|
"Format of a condition:\n"
|
||||||
"\n"
|
"\n"
|
||||||
|
@ -4242,6 +4362,8 @@ parse_config(session_t *ps, char *cpath, struct options_tmp *pcfgtmp) {
|
||||||
parse_cfg_condlst(&cfg, &ps->o.shadow_blacklist, "shadow-exclude");
|
parse_cfg_condlst(&cfg, &ps->o.shadow_blacklist, "shadow-exclude");
|
||||||
// --focus-exclude
|
// --focus-exclude
|
||||||
parse_cfg_condlst(&cfg, &ps->o.focus_blacklist, "focus-exclude");
|
parse_cfg_condlst(&cfg, &ps->o.focus_blacklist, "focus-exclude");
|
||||||
|
// --invert-color-include
|
||||||
|
parse_cfg_condlst(&cfg, &ps->o.invert_color_list, "invert-color-include");
|
||||||
// --blur-background
|
// --blur-background
|
||||||
lcfg_lookup_bool(&cfg, "blur-background", &ps->o.blur_background);
|
lcfg_lookup_bool(&cfg, "blur-background", &ps->o.blur_background);
|
||||||
// --blur-background-frame
|
// --blur-background-frame
|
||||||
|
@ -4315,6 +4437,7 @@ get_cfg(session_t *ps, int argc, char *const *argv) {
|
||||||
{ "blur-background-fixed", no_argument, NULL, 285 },
|
{ "blur-background-fixed", no_argument, NULL, 285 },
|
||||||
{ "dbus", no_argument, NULL, 286 },
|
{ "dbus", no_argument, NULL, 286 },
|
||||||
{ "logpath", required_argument, NULL, 287 },
|
{ "logpath", required_argument, NULL, 287 },
|
||||||
|
{ "invert-color-include", required_argument, NULL, 288 },
|
||||||
// Must terminate with a NULL entry
|
// Must terminate with a NULL entry
|
||||||
{ NULL, 0, NULL, 0 },
|
{ NULL, 0, NULL, 0 },
|
||||||
};
|
};
|
||||||
|
@ -4554,6 +4677,10 @@ get_cfg(session_t *ps, int argc, char *const *argv) {
|
||||||
// --logpath
|
// --logpath
|
||||||
ps->o.logpath = mstrcpy(optarg);
|
ps->o.logpath = mstrcpy(optarg);
|
||||||
break;
|
break;
|
||||||
|
case 288:
|
||||||
|
// --invert-color-include
|
||||||
|
condlst_add(&ps->o.invert_color_list, optarg);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
usage();
|
usage();
|
||||||
break;
|
break;
|
||||||
|
@ -5291,12 +5418,14 @@ session_init(session_t *ps_old, int argc, char **argv) {
|
||||||
.inactive_opacity_override = false,
|
.inactive_opacity_override = false,
|
||||||
.frame_opacity = 0.0,
|
.frame_opacity = 0.0,
|
||||||
.detect_client_opacity = false,
|
.detect_client_opacity = false,
|
||||||
.inactive_dim = 0.0,
|
|
||||||
.inactive_dim_fixed = false,
|
|
||||||
.alpha_step = 0.03,
|
.alpha_step = 0.03,
|
||||||
|
|
||||||
.blur_background = false,
|
.blur_background = false,
|
||||||
.blur_background_frame = false,
|
.blur_background_frame = false,
|
||||||
.blur_background_fixed = false,
|
.blur_background_fixed = false,
|
||||||
|
.inactive_dim = 0.0,
|
||||||
|
.inactive_dim_fixed = false,
|
||||||
|
.invert_color_list = NULL,
|
||||||
|
|
||||||
.wintype_focus = { false },
|
.wintype_focus = { false },
|
||||||
.use_ewmh_active_win = false,
|
.use_ewmh_active_win = false,
|
||||||
|
@ -5337,6 +5466,7 @@ session_init(session_t *ps_old, int argc, char **argv) {
|
||||||
|
|
||||||
.black_picture = None,
|
.black_picture = None,
|
||||||
.cshadow_picture = None,
|
.cshadow_picture = None,
|
||||||
|
.white_picture = None,
|
||||||
.gaussian_map = NULL,
|
.gaussian_map = NULL,
|
||||||
.cgsize = 0,
|
.cgsize = 0,
|
||||||
.shadow_corner = NULL,
|
.shadow_corner = NULL,
|
||||||
|
@ -5555,6 +5685,7 @@ session_init(session_t *ps_old, int argc, char **argv) {
|
||||||
init_filters(ps);
|
init_filters(ps);
|
||||||
|
|
||||||
ps->black_picture = solid_picture(ps, true, 1, 0, 0, 0);
|
ps->black_picture = solid_picture(ps, true, 1, 0, 0, 0);
|
||||||
|
ps->white_picture = solid_picture(ps, true, 1, 1, 1, 1);
|
||||||
|
|
||||||
// Generates another Picture for shadows if the color is modified by
|
// Generates another Picture for shadows if the color is modified by
|
||||||
// user
|
// user
|
||||||
|
@ -5658,6 +5789,8 @@ session_destroy(session_t *ps) {
|
||||||
// Free blacklists
|
// Free blacklists
|
||||||
free_wincondlst(&ps->o.shadow_blacklist);
|
free_wincondlst(&ps->o.shadow_blacklist);
|
||||||
free_wincondlst(&ps->o.fade_blacklist);
|
free_wincondlst(&ps->o.fade_blacklist);
|
||||||
|
free_wincondlst(&ps->o.focus_blacklist);
|
||||||
|
free_wincondlst(&ps->o.invert_color_list);
|
||||||
|
|
||||||
// Free ignore linked list
|
// Free ignore linked list
|
||||||
{
|
{
|
||||||
|
@ -5680,6 +5813,7 @@ session_destroy(session_t *ps) {
|
||||||
free_picture(ps, &ps->cshadow_picture);
|
free_picture(ps, &ps->cshadow_picture);
|
||||||
|
|
||||||
free_picture(ps, &ps->black_picture);
|
free_picture(ps, &ps->black_picture);
|
||||||
|
free_picture(ps, &ps->white_picture);
|
||||||
|
|
||||||
// Free tgt_{buffer,picture} and root_picture
|
// Free tgt_{buffer,picture} and root_picture
|
||||||
if (ps->tgt_buffer == ps->tgt_picture)
|
if (ps->tgt_buffer == ps->tgt_picture)
|
||||||
|
|
|
@ -211,6 +211,14 @@ typedef enum {
|
||||||
WMODE_ARGB
|
WMODE_ARGB
|
||||||
} winmode_t;
|
} winmode_t;
|
||||||
|
|
||||||
|
/// Structure representing needed window updates.
|
||||||
|
typedef struct {
|
||||||
|
bool shadow : 1;
|
||||||
|
bool fade : 1;
|
||||||
|
bool focus : 1;
|
||||||
|
bool invert_color : 1;
|
||||||
|
} win_upd_t;
|
||||||
|
|
||||||
/// Structure representing Window property value.
|
/// Structure representing Window property value.
|
||||||
typedef struct {
|
typedef struct {
|
||||||
// All pointers have the same length, right?
|
// All pointers have the same length, right?
|
||||||
|
@ -363,13 +371,10 @@ typedef struct {
|
||||||
/// Whether to detect _NET_WM_OPACITY on client windows. Used on window
|
/// Whether to detect _NET_WM_OPACITY on client windows. Used on window
|
||||||
/// managers that don't pass _NET_WM_OPACITY to frame windows.
|
/// managers that don't pass _NET_WM_OPACITY to frame windows.
|
||||||
bool detect_client_opacity;
|
bool detect_client_opacity;
|
||||||
/// How much to dim an inactive window. 0.0 - 1.0, 0 to disable.
|
|
||||||
double inactive_dim;
|
|
||||||
/// Whether to use fixed inactive dim opacity, instead of deciding
|
|
||||||
/// based on window opacity.
|
|
||||||
bool inactive_dim_fixed;
|
|
||||||
/// Step for pregenerating alpha pictures. 0.01 - 1.0.
|
/// Step for pregenerating alpha pictures. 0.01 - 1.0.
|
||||||
double alpha_step;
|
double alpha_step;
|
||||||
|
|
||||||
|
// === Other window processing ===
|
||||||
/// Whether to blur background of semi-transparent / ARGB windows.
|
/// Whether to blur background of semi-transparent / ARGB windows.
|
||||||
bool blur_background;
|
bool blur_background;
|
||||||
/// Whether to blur background when the window frame is not opaque.
|
/// Whether to blur background when the window frame is not opaque.
|
||||||
|
@ -378,6 +383,13 @@ typedef struct {
|
||||||
/// Whether to use fixed blur strength instead of adjusting according
|
/// Whether to use fixed blur strength instead of adjusting according
|
||||||
/// to window opacity.
|
/// to window opacity.
|
||||||
bool blur_background_fixed;
|
bool blur_background_fixed;
|
||||||
|
/// How much to dim an inactive window. 0.0 - 1.0, 0 to disable.
|
||||||
|
double inactive_dim;
|
||||||
|
/// Whether to use fixed inactive dim opacity, instead of deciding
|
||||||
|
/// based on window opacity.
|
||||||
|
bool inactive_dim_fixed;
|
||||||
|
/// Conditions of windows to have inverted colors.
|
||||||
|
wincond_t *invert_color_list;
|
||||||
|
|
||||||
// === Focus related ===
|
// === Focus related ===
|
||||||
/// Consider windows of specific types to be always focused.
|
/// Consider windows of specific types to be always focused.
|
||||||
|
@ -398,7 +410,6 @@ typedef struct {
|
||||||
bool track_wdata;
|
bool track_wdata;
|
||||||
/// Whether compton needs to track window leaders.
|
/// Whether compton needs to track window leaders.
|
||||||
bool track_leader;
|
bool track_leader;
|
||||||
|
|
||||||
} options_t;
|
} options_t;
|
||||||
|
|
||||||
/// Structure containing all necessary data for a compton session.
|
/// Structure containing all necessary data for a compton session.
|
||||||
|
@ -505,6 +516,8 @@ typedef struct {
|
||||||
Picture black_picture;
|
Picture black_picture;
|
||||||
/// 1x1 Picture of the shadow color.
|
/// 1x1 Picture of the shadow color.
|
||||||
Picture cshadow_picture;
|
Picture cshadow_picture;
|
||||||
|
/// 1x1 white Picture.
|
||||||
|
Picture white_picture;
|
||||||
/// Gaussian map of shadow.
|
/// Gaussian map of shadow.
|
||||||
conv *gaussian_map;
|
conv *gaussian_map;
|
||||||
// for shadow precomputation
|
// for shadow precomputation
|
||||||
|
@ -699,6 +712,7 @@ typedef struct _win {
|
||||||
wincond_t *cache_sblst;
|
wincond_t *cache_sblst;
|
||||||
wincond_t *cache_fblst;
|
wincond_t *cache_fblst;
|
||||||
wincond_t *cache_fcblst;
|
wincond_t *cache_fcblst;
|
||||||
|
wincond_t *cache_ivclst;
|
||||||
|
|
||||||
// Opacity-related members
|
// Opacity-related members
|
||||||
/// Current window opacity.
|
/// Current window opacity.
|
||||||
|
@ -758,6 +772,12 @@ typedef struct _win {
|
||||||
/// Picture for dimming. Affected by user-specified inactive dim
|
/// Picture for dimming. Affected by user-specified inactive dim
|
||||||
/// opacity and window opacity.
|
/// opacity and window opacity.
|
||||||
Picture dim_alpha_pict;
|
Picture dim_alpha_pict;
|
||||||
|
|
||||||
|
/// Whether to invert window color.
|
||||||
|
bool invert_color;
|
||||||
|
/// Override value of window color inversion state. Set by D-Bus method
|
||||||
|
/// calls.
|
||||||
|
switch_t invert_color_force;
|
||||||
} win;
|
} win;
|
||||||
|
|
||||||
/// Temporary structure used for communication between
|
/// Temporary structure used for communication between
|
||||||
|
@ -1860,7 +1880,7 @@ static double
|
||||||
get_opacity_percent(win *w);
|
get_opacity_percent(win *w);
|
||||||
|
|
||||||
static void
|
static void
|
||||||
determine_mode(session_t *ps, win *w);
|
win_determine_mode(session_t *ps, win *w);
|
||||||
|
|
||||||
static void
|
static void
|
||||||
calc_opacity(session_t *ps, win *w);
|
calc_opacity(session_t *ps, win *w);
|
||||||
|
@ -1902,7 +1922,7 @@ static inline void
|
||||||
win_set_focused(session_t *ps, win *w, bool focused);
|
win_set_focused(session_t *ps, win *w, bool focused);
|
||||||
|
|
||||||
static void
|
static void
|
||||||
determine_fade(session_t *ps, win *w);
|
win_determine_fade(session_t *ps, win *w);
|
||||||
|
|
||||||
static void
|
static void
|
||||||
win_update_shape_raw(session_t *ps, win *w);
|
win_update_shape_raw(session_t *ps, win *w);
|
||||||
|
@ -1917,7 +1937,16 @@ static void
|
||||||
win_update_prop_shadow(session_t *ps, win *w);
|
win_update_prop_shadow(session_t *ps, win *w);
|
||||||
|
|
||||||
static void
|
static void
|
||||||
determine_shadow(session_t *ps, win *w);
|
win_determine_shadow(session_t *ps, win *w);
|
||||||
|
|
||||||
|
static void
|
||||||
|
win_on_wtype_change(session_t *ps, win *w);
|
||||||
|
|
||||||
|
static void
|
||||||
|
win_on_wdata_change(session_t *ps, win *w);
|
||||||
|
|
||||||
|
static void
|
||||||
|
win_upd_run(session_t *ps, win *w, win_upd_t *pupd);
|
||||||
|
|
||||||
static void
|
static void
|
||||||
calc_win_size(session_t *ps, win *w);
|
calc_win_size(session_t *ps, win *w);
|
||||||
|
|
Loading…
Reference in New Issue