c2: match using stored window properties

And removing the session_t parameter from c2_match.

Signed-off-by: Yuxuan Shui <yshuiv7@gmail.com>
This commit is contained in:
Yuxuan Shui 2024-02-16 15:19:36 +00:00
parent 3246cd1e31
commit 008720fbc8
No known key found for this signature in database
GPG Key ID: D3A4405BE6CC17F4
3 changed files with 165 additions and 207 deletions

339
src/c2.c
View File

@ -150,6 +150,7 @@ struct _c2_l {
} match : 3; } match : 3;
bool match_ignorecase : 1; bool match_ignorecase : 1;
char *tgt; char *tgt;
unsigned int target_id;
xcb_atom_t tgtatom; xcb_atom_t tgtatom;
bool tgt_onframe; bool tgt_onframe;
int index; int index;
@ -259,26 +260,6 @@ static const c2_predef_t C2_PREDEFS[] = {
[C2_L_PROLE] = {"role", C2_L_TSTRING, 0}, [C2_L_PROLE] = {"role", C2_L_TSTRING, 0},
}; };
/**
* Get the numeric property value from a win_prop_t.
*/
static inline long winprop_get_int(winprop_t prop, size_t index) {
long tgt = 0;
if (!prop.nitems || index >= prop.nitems) {
return 0;
}
switch (prop.format) {
case 8: tgt = *(prop.p8 + index); break;
case 16: tgt = *(prop.p16 + index); break;
case 32: tgt = *(prop.p32 + index); break;
default: assert(0); break;
}
return tgt;
}
/** /**
* Compare next word in a string with another string. * Compare next word in a string with another string.
*/ */
@ -382,10 +363,6 @@ static const char *c2h_dump_str_tgt(const c2_l_t *pleaf);
static const char *c2h_dump_str_type(const c2_l_t *pleaf); static const char *c2h_dump_str_type(const c2_l_t *pleaf);
static xcb_atom_t c2_get_atom_type(const c2_l_t *pleaf);
static bool c2_match_once(session_t *ps, const struct managed_win *w, const c2_ptr_t cond);
/** /**
* Parse a condition string. * Parse a condition string.
*/ */
@ -1217,6 +1194,7 @@ static bool c2_l_postprocess(struct c2_state *state, xcb_connection_t *c, c2_l_t
property->max_indices = pleaf->index; property->max_indices = pleaf->index;
} }
} }
pleaf->target_id = property->id;
} }
// Warn about lower case characters in target name // Warn about lower case characters in target name
@ -1371,7 +1349,7 @@ static const char *c2h_dump_str_type(const c2_l_t *pleaf) {
* the null terminator. * the null terminator.
* null terminator will not be written to the output. * null terminator will not be written to the output.
*/ */
static size_t c2_condition_to_str(c2_ptr_t p, char *output, size_t len) { static size_t c2_condition_to_str(const c2_ptr_t p, char *output, size_t len) {
#define push_char(c) \ #define push_char(c) \
if (offset < len) \ if (offset < len) \
output[offset] = (c); \ output[offset] = (c); \
@ -1514,32 +1492,49 @@ static size_t c2_condition_to_str(c2_ptr_t p, char *output, size_t len) {
return offset; return offset;
} }
/** /// Like `c2_condition_to_str`, but uses a internal static buffer, and adds a
* Get the type atom of a condition. /// nul byte to the end of the string. The returned string is only valid until
*/ /// the next call to this function, and shouldn't be freed.
static xcb_atom_t c2_get_atom_type(const c2_l_t *pleaf) { static const char *c2_condition_to_str2(const c2_ptr_t ptr) {
switch (pleaf->type) { static thread_local char buf[4096];
case C2_L_TCARDINAL: return XCB_ATOM_CARDINAL; size_t len = c2_condition_to_str(ptr, buf, sizeof(buf));
case C2_L_TWINDOW: return XCB_ATOM_WINDOW; if (len >= sizeof(buf)) {
case C2_L_TSTRING: return XCB_ATOM_STRING; buf[sizeof(buf) - 1] = '\0';
case C2_L_TATOM: return XCB_ATOM_ATOM; } else {
case C2_L_TDRAWABLE: return XCB_ATOM_DRAWABLE; buf[len] = '\0';
default: assert(0); break;
} }
unreachable(); return buf;
} }
static bool static inline bool c2_int_op(const c2_l_t *leaf, size_t ntargets, const int64_t *targets) {
c2_match_once_leaf_int(session_t *ps, const struct managed_win *w, const c2_l_t *leaf) { for (size_t i = 0; i < ntargets; ++i) {
long long *targets = NULL; long long tgt = targets[i];
long long *targets_free = NULL; bool matches;
size_t ntargets = 0; switch (leaf->op) {
case C2_L_OEXISTS:
matches = (leaf->predef != C2_L_PUNDEFINED ? tgt : true);
break;
case C2_L_OEQ: matches = (tgt == leaf->ptnint); break;
case C2_L_OGT: matches = (tgt > leaf->ptnint); break;
case C2_L_OGTEQ: matches = (tgt >= leaf->ptnint); break;
case C2_L_OLT: matches = (tgt < leaf->ptnint); break;
case C2_L_OLTEQ: matches = (tgt <= leaf->ptnint); break;
case C2_L_OFALSE: unreachable();
}
if (matches) {
return true;
}
}
return false;
}
static bool c2_match_once_leaf_int(const struct managed_win *w, const c2_l_t *leaf) {
const xcb_window_t wid = (leaf->tgt_onframe ? w->client_win : w->base.id); const xcb_window_t wid = (leaf->tgt_onframe ? w->client_win : w->base.id);
// Get the value // Get the value
// A predefined target
long long predef_target = 0;
if (leaf->predef != C2_L_PUNDEFINED) { if (leaf->predef != C2_L_PUNDEFINED) {
// A predefined target
int64_t predef_target = 0;
switch (leaf->predef) { switch (leaf->predef) {
case C2_L_PID: predef_target = wid; break; case C2_L_PID: predef_target = wid; break;
case C2_L_PX: predef_target = w->g.x; break; case C2_L_PX: predef_target = w->g.x; break;
@ -1565,58 +1560,41 @@ c2_match_once_leaf_int(session_t *ps, const struct managed_win *w, const c2_l_t
assert(false); assert(false);
return false; return false;
} }
ntargets = 1; return c2_int_op(leaf, 1, &predef_target);
targets = &predef_target; }
// A raw window property
auto values = &w->c2_state.values[leaf->target_id];
assert(!values->needs_update);
if (!values->valid) {
log_verbose("Property %s not found on window %#010x (%s)", leaf->tgt,
w->client_win, w->name);
return false;
}
int64_t *targets = NULL;
size_t ntargets = 0;
if (leaf->index < 0) {
if (values->length > ARR_SIZE(values->numbers)) {
targets = values->array;
} else {
targets = values->numbers;
}
ntargets = values->length;
} else { } else {
// A raw window property if ((size_t)leaf->index >= values->length) {
int word_count = 1; // index is out of bounds
int offset = leaf->index; return false;
if (leaf->index < 0) {
// index < 0 means match any index
// Get length of property in 32-bit multiples
auto prop_info = x_get_prop_info(&ps->c, wid, leaf->tgtatom);
word_count = to_int_checked((prop_info.length + 4 - 1) / 4);
offset = 0;
} }
winprop_t prop = if (values->length > ARR_SIZE(values->numbers)) {
x_get_prop_with_offset(&ps->c, wid, leaf->tgtatom, offset, word_count, targets = &values->array[leaf->index];
c2_get_atom_type(leaf), leaf->format); } else {
targets = &values->numbers[leaf->index];
ntargets = (leaf->index < 0 ? prop.nitems : min2(prop.nitems, 1));
if (ntargets > 0) {
targets = targets_free = ccalloc(ntargets, long long);
for (size_t i = 0; i < ntargets; ++i) {
targets[i] = winprop_get_int(prop, i);
}
} }
free_winprop(&prop); ntargets = 1;
} }
// Do comparison return c2_int_op(leaf, ntargets, targets);
bool matches = false;
for (size_t i = 0; i < ntargets; ++i) {
long long tgt = targets[i];
switch (leaf->op) {
case C2_L_OEXISTS:
matches = (leaf->predef != C2_L_PUNDEFINED ? tgt : true);
break;
case C2_L_OEQ: matches = (tgt == leaf->ptnint); break;
case C2_L_OGT: matches = (tgt > leaf->ptnint); break;
case C2_L_OGTEQ: matches = (tgt >= leaf->ptnint); break;
case C2_L_OLT: matches = (tgt < leaf->ptnint); break;
case C2_L_OLTEQ: matches = (tgt <= leaf->ptnint); break;
default: log_error("Unknown operator %d.", leaf->op); assert(false);
}
if (matches) {
break;
}
}
// Free property values after usage, if necessary
if (targets_free) {
free(targets_free);
}
return matches;
} }
static bool c2_string_op(const c2_l_t *leaf, const char *target) { static bool c2_string_op(const c2_l_t *leaf, const char *target) {
@ -1662,14 +1640,8 @@ static bool c2_string_op(const c2_l_t *leaf, const char *target) {
unreachable(); unreachable();
} }
static bool static bool c2_match_once_leaf_string(struct atom *atoms, const struct managed_win *w,
c2_match_once_leaf_string(session_t *ps, const struct managed_win *w, const c2_l_t *leaf) { const c2_l_t *leaf) {
const char **targets = NULL;
const char **targets_free = NULL;
const char **targets_free_inner = NULL;
size_t ntargets = 0;
const xcb_window_t wid = (leaf->tgt_onframe ? w->client_win : w->base.id);
// A predefined target // A predefined target
const char *predef_target = NULL; const char *predef_target = NULL;
@ -1680,94 +1652,72 @@ c2_match_once_leaf_string(session_t *ps, const struct managed_win *w, const c2_l
case C2_L_PCLASSG: predef_target = w->class_general; break; case C2_L_PCLASSG: predef_target = w->class_general; break;
case C2_L_PCLASSI: predef_target = w->class_instance; break; case C2_L_PCLASSI: predef_target = w->class_instance; break;
case C2_L_PROLE: predef_target = w->role; break; case C2_L_PROLE: predef_target = w->role; break;
default: assert(0); break; default: unreachable();
} }
ntargets = 1; if (!predef_target) {
targets = &predef_target; return false;
} else if (leaf->type == C2_L_TATOM) { }
// An atom type property, convert it to string log_verbose("Matching against predefined target %s", predef_target);
int word_count = 1; return c2_string_op(leaf, predef_target);
int offset = leaf->index; }
auto values = &w->c2_state.values[leaf->target_id];
assert(!values->needs_update);
if (!values->valid) {
log_verbose("Property %s not found on window %#010x (%s)", leaf->tgt,
w->client_win, w->name);
return false;
}
if (leaf->type == C2_L_TATOM) {
size_t ntargets = 0;
int64_t *targets;
if (leaf->index < 0) { if (leaf->index < 0) {
// index < 0 means match any index ntargets = values->length;
// Get length of property in 32-bit multiples if (ntargets > ARR_SIZE(w->c2_state.values->numbers)) {
auto prop_info = x_get_prop_info(&ps->c, wid, leaf->tgtatom); targets = values->array;
word_count = to_int_checked((prop_info.length + 4 - 1) / 4); } else {
offset = 0; targets = values->numbers;
}
} else {
ntargets = 1;
targets = &values->numbers[leaf->index];
} }
winprop_t prop =
x_get_prop_with_offset(&ps->c, wid, leaf->tgtatom, offset, word_count,
c2_get_atom_type(leaf), leaf->format);
ntargets = (leaf->index < 0 ? prop.nitems : min2(prop.nitems, 1));
targets = targets_free = (const char **)ccalloc(2 * ntargets, char *);
targets_free_inner = targets + ntargets;
for (size_t i = 0; i < ntargets; ++i) { for (size_t i = 0; i < ntargets; ++i) {
xcb_atom_t atom = (xcb_atom_t)winprop_get_int(prop, i); auto atom = (xcb_atom_t)targets[i];
if (atom) { const char *atom_name = get_atom_name_cached(atoms, atom);
xcb_get_atom_name_reply_t *reply = xcb_get_atom_name_reply( log_verbose("(%zu/%zu) Atom %u is %s", i, ntargets, atom, atom_name);
ps->c.c, xcb_get_atom_name(ps->c.c, atom), NULL); assert(atom_name != NULL);
if (reply) { if (atom_name && c2_string_op(leaf, atom_name)) {
targets[i] = targets_free_inner[i] = strndup( return true;
xcb_get_atom_name_name(reply),
(size_t)xcb_get_atom_name_name_length(reply));
free(reply);
}
} }
} }
free_winprop(&prop); return false;
} else { }
// Not an atom type, just fetch the string list
char **strlst = NULL; // Not an atom type, value is a list of nul separated strings
int nstr = 0; if (leaf->index < 0) {
int index = max2(0, leaf->index); size_t offset = 0;
if (wid_get_text_prop(&ps->c, ps->atoms, wid, leaf->tgtatom, &strlst, &nstr)) { while (offset < values->length) {
if (leaf->index < 0 && nstr > 0 && strlen(strlst[0]) > 0) { if (c2_string_op(leaf, values->string + offset)) {
ntargets = to_u32_checked(nstr); return true;
targets = (const char **)strlst;
} else if (nstr > index) {
ntargets = 1;
targets = (const char **)strlst + index;
} }
offset += strlen(values->string + offset) + 1;
} }
if (strlst) { return false;
targets_free = (const char **)strlst;
}
} }
size_t offset = 0;
bool matches = false; int index = leaf->index;
if (ntargets == 0) { while (offset < values->length && index != 0) {
goto fail; offset += strlen(values->string + offset) + 1;
index -= 1;
} }
for (size_t i = 0; i < ntargets; ++i) { if (index != 0 || values->length == 0) {
if (!targets[i]) { // index is out of bounds
goto fail; return false;
}
} }
return c2_string_op(leaf, values->string + offset);
// Actual matching
for (size_t i = 0; i < ntargets; ++i) {
if (c2_string_op(leaf, targets[i])) {
matches = true;
break;
}
}
fail:
// Free the string after usage, if necessary
if (targets_free_inner) {
for (size_t i = 0; i < ntargets; ++i) {
if (targets_free_inner[i]) {
free((void *)targets_free_inner[i]);
}
}
}
// Free property values after usage, if necessary
if (targets_free) {
free(targets_free);
}
return matches;
} }
/** /**
@ -1776,7 +1726,7 @@ fail:
* For internal use. * For internal use.
*/ */
static inline bool static inline bool
c2_match_once_leaf(session_t *ps, const struct managed_win *w, const c2_l_t *leaf) { c2_match_once_leaf(struct c2_state *state, const struct managed_win *w, const c2_l_t *leaf) {
assert(leaf); assert(leaf);
const xcb_window_t wid = (leaf->tgt_onframe ? w->client_win : w->base.id); const xcb_window_t wid = (leaf->tgt_onframe ? w->client_win : w->base.id);
@ -1789,14 +1739,18 @@ c2_match_once_leaf(session_t *ps, const struct managed_win *w, const c2_l_t *lea
} }
if (leaf->op == C2_L_OFALSE) { if (leaf->op == C2_L_OFALSE) {
return leaf->neg; log_debug("Condition is annulled.");
return false;
} }
log_verbose("Matching window %#010x (%s) against condition %s", wid, w->name,
c2_condition_to_str2((c2_ptr_t){.l = (c2_l_t *)leaf, .isbranch = false}));
switch (leaf->ptntype) { switch (leaf->ptntype) {
// Deal with integer patterns // Deal with integer patterns
case C2_L_PTINT: return c2_match_once_leaf_int(ps, w, leaf); case C2_L_PTINT: return c2_match_once_leaf_int(w, leaf);
// String patterns // String patterns
case C2_L_PTSTRING: return c2_match_once_leaf_string(ps, w, leaf); case C2_L_PTSTRING: return c2_match_once_leaf_string(state->atoms, w, leaf);
default: default:
log_error("Unknown pattern type %d.", leaf->ptntype); log_error("Unknown pattern type %d.", leaf->ptntype);
assert(false); assert(false);
@ -1809,7 +1763,8 @@ c2_match_once_leaf(session_t *ps, const struct managed_win *w, const c2_l_t *lea
* *
* @return true if matched, false otherwise. * @return true if matched, false otherwise.
*/ */
static bool c2_match_once(session_t *ps, const struct managed_win *w, const c2_ptr_t cond) { static bool
c2_match_once(struct c2_state *state, const struct managed_win *w, const c2_ptr_t cond) {
bool result = false; bool result = false;
char condition_str[1024]; char condition_str[1024];
@ -1821,18 +1776,21 @@ static bool c2_match_once(session_t *ps, const struct managed_win *w, const c2_p
return false; return false;
} }
log_verbose("Matching window %#010x (%s) against condition %s",
w->base.id, w->name, c2_condition_to_str2(cond));
switch (pb->op) { switch (pb->op) {
case C2_B_OAND: case C2_B_OAND:
result = (c2_match_once(ps, w, pb->opr1) && result = (c2_match_once(state, w, pb->opr1) &&
c2_match_once(ps, w, pb->opr2)); c2_match_once(state, w, pb->opr2));
break; break;
case C2_B_OOR: case C2_B_OOR:
result = (c2_match_once(ps, w, pb->opr1) || result = (c2_match_once(state, w, pb->opr1) ||
c2_match_once(ps, w, pb->opr2)); c2_match_once(state, w, pb->opr2));
break; break;
case C2_B_OXOR: case C2_B_OXOR:
result = (c2_match_once(ps, w, pb->opr1) != result = (c2_match_once(state, w, pb->opr1) !=
c2_match_once(ps, w, pb->opr2)); c2_match_once(state, w, pb->opr2));
break; break;
default: default:
log_error("Unknown boolean operator %d.", pb->op); log_error("Unknown boolean operator %d.", pb->op);
@ -1855,7 +1813,7 @@ static bool c2_match_once(session_t *ps, const struct managed_win *w, const c2_p
return false; return false;
} }
result = c2_match_once_leaf(ps, w, pleaf); result = c2_match_once_leaf(state, w, pleaf);
if (unlikely(log_get_level_tls() <= LOG_LEVEL_TRACE)) { if (unlikely(log_get_level_tls() <= LOG_LEVEL_TRACE)) {
size_t len = size_t len =
@ -1882,12 +1840,11 @@ static bool c2_match_once(session_t *ps, const struct managed_win *w, const c2_p
* @param pdata a place to return the data * @param pdata a place to return the data
* @return true if matched, false otherwise. * @return true if matched, false otherwise.
*/ */
bool c2_match(session_t *ps, const struct managed_win *w, const c2_lptr_t *condlst, bool c2_match(struct c2_state *state, const struct managed_win *w,
void **pdata) { const c2_lptr_t *condlst, void **pdata) {
assert(ps->server_grabbed);
// Then go through the whole linked list // Then go through the whole linked list
for (; condlst; condlst = condlst->next) { for (; condlst; condlst = condlst->next) {
if (c2_match_once(ps, w, condlst->ptr)) { if (c2_match_once(state, w, condlst->ptr)) {
if (pdata) { if (pdata) {
*pdata = condlst->data; *pdata = condlst->data;
} }

View File

@ -49,8 +49,8 @@ void c2_window_state_update(struct c2_state *state, struct c2_window_state *wind
xcb_connection_t *c, xcb_window_t client_win, xcb_connection_t *c, xcb_window_t client_win,
xcb_window_t frame_win); xcb_window_t frame_win);
bool c2_match(session_t *ps, const struct managed_win *w, const c2_lptr_t *condlst, bool c2_match(struct c2_state *state, const struct managed_win *w,
void **pdata); const c2_lptr_t *condlst, void **pdata);
bool c2_list_postprocess(struct c2_state *state, xcb_connection_t *c, c2_lptr_t *list); bool c2_list_postprocess(struct c2_state *state, xcb_connection_t *c, c2_lptr_t *list);
typedef bool (*c2_list_foreach_cb_t)(const c2_lptr_t *cond, void *data); typedef bool (*c2_list_foreach_cb_t)(const c2_lptr_t *cond, void *data);

View File

@ -150,7 +150,7 @@ static void win_update_focused(session_t *ps, struct managed_win *w) {
(ps->o.mark_wmwin_focused && w->wmwin) || (ps->o.mark_wmwin_focused && w->wmwin) ||
(ps->o.mark_ovredir_focused && w->base.id == w->client_win && !w->wmwin) || (ps->o.mark_ovredir_focused && w->base.id == w->client_win && !w->wmwin) ||
(w->a.map_state == XCB_MAP_STATE_VIEWABLE && (w->a.map_state == XCB_MAP_STATE_VIEWABLE &&
c2_match(ps, w, ps->o.focus_blacklist, NULL))) { c2_match(ps->c2_state, w, ps->o.focus_blacklist, NULL))) {
w->focused = true; w->focused = true;
} }
@ -999,7 +999,7 @@ static void win_determine_shadow(session_t *ps, struct managed_win *w) {
if (!ps->o.wintype_option[w->window_type].shadow) { if (!ps->o.wintype_option[w->window_type].shadow) {
log_debug("Shadow disabled by wintypes"); log_debug("Shadow disabled by wintypes");
shadow_new = false; shadow_new = false;
} else if (c2_match(ps, w, ps->o.shadow_blacklist, NULL)) { } else if (c2_match(ps->c2_state, w, ps->o.shadow_blacklist, NULL)) {
log_debug("Shadow disabled by shadow-exclude"); log_debug("Shadow disabled by shadow-exclude");
shadow_new = false; shadow_new = false;
} else if (ps->o.shadow_ignore_shaped && w->bounding_shaped && } else if (ps->o.shadow_ignore_shaped && w->bounding_shaped &&
@ -1055,7 +1055,7 @@ bool win_update_prop_fullscreen(struct x_connection *c, const struct atom *atoms
static void win_determine_clip_shadow_above(session_t *ps, struct managed_win *w) { static void win_determine_clip_shadow_above(session_t *ps, struct managed_win *w) {
bool should_crop = (ps->o.wintype_option[w->window_type].clip_shadow_above || bool should_crop = (ps->o.wintype_option[w->window_type].clip_shadow_above ||
c2_match(ps, w, ps->o.shadow_clip_list, NULL)); c2_match(ps->c2_state, w, ps->o.shadow_clip_list, NULL));
w->clip_shadow_above = should_crop; w->clip_shadow_above = should_crop;
} }
@ -1078,7 +1078,7 @@ static void win_determine_invert_color(session_t *ps, struct managed_win *w) {
if (UNSET != w->invert_color_force) { if (UNSET != w->invert_color_force) {
invert_color_new = w->invert_color_force; invert_color_new = w->invert_color_force;
} else if (w->a.map_state == XCB_MAP_STATE_VIEWABLE) { } else if (w->a.map_state == XCB_MAP_STATE_VIEWABLE) {
invert_color_new = c2_match(ps, w, ps->o.invert_color_list, NULL); invert_color_new = c2_match(ps->c2_state, w, ps->o.invert_color_list, NULL);
} }
win_set_invert_color(ps, w, invert_color_new); win_set_invert_color(ps, w, invert_color_new);
@ -1167,7 +1167,7 @@ static void win_determine_blur_background(session_t *ps, struct managed_win *w)
if (!ps->o.wintype_option[w->window_type].blur_background) { if (!ps->o.wintype_option[w->window_type].blur_background) {
log_debug("Blur background disabled by wintypes"); log_debug("Blur background disabled by wintypes");
blur_background_new = false; blur_background_new = false;
} else if (c2_match(ps, w, ps->o.blur_background_blacklist, NULL)) { } else if (c2_match(ps->c2_state, w, ps->o.blur_background_blacklist, NULL)) {
log_debug("Blur background disabled by " log_debug("Blur background disabled by "
"blur-background-exclude"); "blur-background-exclude");
blur_background_new = false; blur_background_new = false;
@ -1182,7 +1182,7 @@ static void win_determine_blur_background(session_t *ps, struct managed_win *w)
*/ */
static void win_determine_rounded_corners(session_t *ps, struct managed_win *w) { static void win_determine_rounded_corners(session_t *ps, struct managed_win *w) {
void *radius_override = NULL; void *radius_override = NULL;
if (c2_match(ps, w, ps->o.corner_radius_rules, &radius_override)) { if (c2_match(ps->c2_state, w, ps->o.corner_radius_rules, &radius_override)) {
log_debug("Matched corner rule! %d", w->corner_radius); log_debug("Matched corner rule! %d", w->corner_radius);
} }
@ -1193,8 +1193,9 @@ static void win_determine_rounded_corners(session_t *ps, struct managed_win *w)
// Don't round full screen windows & excluded windows, // Don't round full screen windows & excluded windows,
// unless we find a corner override in corner_radius_rules // unless we find a corner override in corner_radius_rules
if (!radius_override && ((w && w->is_fullscreen) || if (!radius_override &&
c2_match(ps, w, ps->o.rounded_corners_blacklist, NULL))) { ((w && w->is_fullscreen) ||
c2_match(ps->c2_state, w, ps->o.rounded_corners_blacklist, NULL))) {
w->corner_radius = 0; w->corner_radius = 0;
log_debug("Not rounding corners for window %#010x", w->base.id); log_debug("Not rounding corners for window %#010x", w->base.id);
} else { } else {
@ -1221,7 +1222,7 @@ static void win_determine_fg_shader(session_t *ps, struct managed_win *w) {
auto shader_new = ps->o.window_shader_fg; auto shader_new = ps->o.window_shader_fg;
void *val = NULL; void *val = NULL;
if (c2_match(ps, w, ps->o.window_shader_fg_rules, &val)) { if (c2_match(ps->c2_state, w, ps->o.window_shader_fg_rules, &val)) {
shader_new = val; shader_new = val;
} }
@ -1244,7 +1245,7 @@ void win_update_opacity_rule(session_t *ps, struct managed_win *w) {
double opacity = 1.0; double opacity = 1.0;
bool is_set = false; bool is_set = false;
void *val = NULL; void *val = NULL;
if (c2_match(ps, w, ps->o.opacity_rules, &val)) { if (c2_match(ps->c2_state, w, ps->o.opacity_rules, &val)) {
opacity = ((double)(long)val) / 100.0; opacity = ((double)(long)val) / 100.0;
is_set = true; is_set = true;
} }
@ -1276,17 +1277,17 @@ void win_on_factor_change(session_t *ps, struct managed_win *w) {
log_debug("Window mode changed to %d", w->mode); log_debug("Window mode changed to %d", w->mode);
win_update_opacity_rule(ps, w); win_update_opacity_rule(ps, w);
if (w->a.map_state == XCB_MAP_STATE_VIEWABLE) { if (w->a.map_state == XCB_MAP_STATE_VIEWABLE) {
w->paint_excluded = c2_match(ps, w, ps->o.paint_blacklist, NULL); w->paint_excluded = c2_match(ps->c2_state, w, ps->o.paint_blacklist, NULL);
} }
if (w->a.map_state == XCB_MAP_STATE_VIEWABLE) { if (w->a.map_state == XCB_MAP_STATE_VIEWABLE) {
w->unredir_if_possible_excluded = w->unredir_if_possible_excluded =
c2_match(ps, w, ps->o.unredir_if_possible_blacklist, NULL); c2_match(ps->c2_state, w, ps->o.unredir_if_possible_blacklist, NULL);
} }
w->fade_excluded = c2_match(ps, w, ps->o.fade_blacklist, NULL); w->fade_excluded = c2_match(ps->c2_state, w, ps->o.fade_blacklist, NULL);
w->transparent_clipping_excluded = w->transparent_clipping_excluded =
c2_match(ps, w, ps->o.transparent_clipping_blacklist, NULL); c2_match(ps->c2_state, w, ps->o.transparent_clipping_blacklist, NULL);
win_update_opacity_target(ps, w); win_update_opacity_target(ps, w);