c2: track frame property and client window property separately

A property might be matched against both on the frame and on the client
window, so they must have separate entries in window state.

Signed-off-by: Yuxuan Shui <yshuiv7@gmail.com>
This commit is contained in:
Yuxuan Shui 2024-02-16 12:40:00 +00:00
parent c475b95036
commit 1a5c80e353
No known key found for this signature in database
GPG Key ID: D3A4405BE6CC17F4
3 changed files with 31 additions and 9 deletions

View File

@ -56,9 +56,17 @@ typedef struct {
};
} c2_ptr_t;
struct c2_tracked_property_key {
xcb_atom_t property;
bool is_on_frame;
char padding[3];
};
static_assert(sizeof(struct c2_tracked_property_key) == 8, "Padding bytes in "
"c2_tracked_property_key");
struct c2_tracked_property {
UT_hash_handle hh;
xcb_atom_t property;
struct c2_tracked_property_key key;
bool is_string;
};
@ -1148,11 +1156,16 @@ static bool c2_l_postprocess(struct c2_state *state, xcb_connection_t *c, c2_l_t
// Insert target atom into tracked property name list
if (pleaf->tgtatom) {
struct c2_tracked_property *property;
HASH_FIND_INT(state->tracked_properties, &pleaf->tgtatom, property);
struct c2_tracked_property_key key = {
.property = pleaf->tgtatom,
.is_on_frame = pleaf->tgt_onframe,
};
HASH_FIND(hh, state->tracked_properties, &key, sizeof(key), property);
if (property == NULL) {
property = cmalloc(struct c2_tracked_property);
property->property = pleaf->tgtatom;
HASH_ADD_INT(state->tracked_properties, property, property);
property->key = key;
HASH_ADD_KEYPTR(hh, state->tracked_properties, &property->key,
sizeof(property->key), property);
property->is_string = pleaf->type == C2_L_TSTRING;
} else {
if (property->is_string != (pleaf->type == C2_L_TSTRING)) {
@ -1886,8 +1899,17 @@ void c2_state_free(struct c2_state *state) {
free(state);
}
bool c2_is_property_tracked(struct c2_state *state, xcb_atom_t property) {
bool c2_state_is_property_tracked(struct c2_state *state, xcb_atom_t property) {
struct c2_tracked_property *p;
HASH_FIND_INT(state->tracked_properties, &property, p);
struct c2_tracked_property_key key = {
.property = property,
.is_on_frame = true,
};
HASH_FIND(hh, state->tracked_properties, &key, sizeof(key), p);
if (p != NULL) {
return true;
}
key.is_on_frame = false;
HASH_FIND(hh, state->tracked_properties, &key, sizeof(key), p);
return p != NULL;
}
}

View File

@ -33,7 +33,7 @@ c2_lptr_t *c2_free_lptr(c2_lptr_t *lp, c2_userdata_free f);
struct c2_state *c2_state_new(struct atom *atoms);
void c2_state_free(struct c2_state *state);
/// Returns true if value of the property is used in any condition.
bool c2_is_property_tracked(struct c2_state *state, xcb_atom_t property);
bool c2_state_is_property_tracked(struct c2_state *state, xcb_atom_t property);
bool c2_match(session_t *ps, const struct managed_win *w, const c2_lptr_t *condlst,
void **pdata);

View File

@ -574,7 +574,7 @@ static inline void ev_property_notify(session_t *ps, xcb_property_notify_event_t
}
// Check for other atoms we are tracking
if (c2_is_property_tracked(ps->c2_state, ev->atom)) {
if (c2_state_is_property_tracked(ps->c2_state, ev->atom)) {
auto w = find_managed_win(ps, ev->window);
if (!w) {
w = find_toplevel(ps, ev->window);