mirror of
https://github.com/yshui/picom.git
synced 2024-11-11 13:51:02 -05:00
c2: start to separate some state out of session_t
This is just the beginning, c2_match still needs session_t, everything is just so tangled... Signed-off-by: Yuxuan Shui <yshuiv7@gmail.com>
This commit is contained in:
parent
b99c7db73e
commit
d19a7bc091
5 changed files with 90 additions and 64 deletions
71
src/c2.c
71
src/c2.c
|
@ -14,6 +14,7 @@
|
||||||
#include <fnmatch.h>
|
#include <fnmatch.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
#include <uthash.h>
|
||||||
|
|
||||||
// libpcre
|
// libpcre
|
||||||
#ifdef CONFIG_REGEX_PCRE
|
#ifdef CONFIG_REGEX_PCRE
|
||||||
|
@ -53,6 +54,16 @@ typedef struct {
|
||||||
};
|
};
|
||||||
} c2_ptr_t;
|
} c2_ptr_t;
|
||||||
|
|
||||||
|
struct c2_tracked_property {
|
||||||
|
UT_hash_handle hh;
|
||||||
|
xcb_atom_t property;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct c2_state {
|
||||||
|
struct c2_tracked_property *tracked_properties;
|
||||||
|
struct atom *atoms;
|
||||||
|
};
|
||||||
|
|
||||||
/// Initializer for c2_ptr_t.
|
/// Initializer for c2_ptr_t.
|
||||||
#define C2_PTR_INIT \
|
#define C2_PTR_INIT \
|
||||||
{ .isbranch = false, .l = NULL, }
|
{ .isbranch = false, .l = NULL, }
|
||||||
|
@ -1039,7 +1050,7 @@ fail:
|
||||||
/**
|
/**
|
||||||
* Do postprocessing on a condition leaf.
|
* Do postprocessing on a condition leaf.
|
||||||
*/
|
*/
|
||||||
static bool c2_l_postprocess(session_t *ps, c2_l_t *pleaf) {
|
static bool c2_l_postprocess(struct c2_state *state, xcb_connection_t *c, c2_l_t *pleaf) {
|
||||||
// Give a pattern type to a leaf with exists operator, if needed
|
// Give a pattern type to a leaf with exists operator, if needed
|
||||||
if (C2_L_OEXISTS == pleaf->op && !pleaf->ptntype) {
|
if (C2_L_OEXISTS == pleaf->op && !pleaf->ptntype) {
|
||||||
pleaf->ptntype = (C2_L_TSTRING == pleaf->type ? C2_L_PTSTRING : C2_L_PTINT);
|
pleaf->ptntype = (C2_L_TSTRING == pleaf->type ? C2_L_PTSTRING : C2_L_PTINT);
|
||||||
|
@ -1047,27 +1058,21 @@ static bool c2_l_postprocess(session_t *ps, c2_l_t *pleaf) {
|
||||||
|
|
||||||
// Get target atom if it's not a predefined one
|
// Get target atom if it's not a predefined one
|
||||||
if (pleaf->predef == C2_L_PUNDEFINED) {
|
if (pleaf->predef == C2_L_PUNDEFINED) {
|
||||||
pleaf->tgtatom = get_atom(ps->atoms, pleaf->tgt, ps->c.c);
|
pleaf->tgtatom = get_atom(state->atoms, pleaf->tgt, c);
|
||||||
if (!pleaf->tgtatom) {
|
if (!pleaf->tgtatom) {
|
||||||
log_error("Failed to get atom for target \"%s\".", pleaf->tgt);
|
log_error("Failed to get atom for target \"%s\".", pleaf->tgt);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Insert target Atom into atom track list
|
// Insert target atom into tracked property name list
|
||||||
if (pleaf->tgtatom) {
|
if (pleaf->tgtatom) {
|
||||||
bool found = false;
|
struct c2_tracked_property *property;
|
||||||
for (latom_t *platom = ps->track_atom_lst; platom; platom = platom->next) {
|
HASH_FIND_INT(state->tracked_properties, &pleaf->tgtatom, property);
|
||||||
if (pleaf->tgtatom == platom->atom) {
|
if (property == NULL) {
|
||||||
found = true;
|
property = cmalloc(struct c2_tracked_property);
|
||||||
break;
|
property->property = pleaf->tgtatom;
|
||||||
}
|
HASH_ADD_INT(state->tracked_properties, property, property);
|
||||||
}
|
|
||||||
if (!found) {
|
|
||||||
auto pnew = cmalloc(latom_t);
|
|
||||||
pnew->next = ps->track_atom_lst;
|
|
||||||
pnew->atom = pleaf->tgtatom;
|
|
||||||
ps->track_atom_lst = pnew;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1123,20 +1128,19 @@ static bool c2_l_postprocess(session_t *ps, c2_l_t *pleaf) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool c2_tree_postprocess(session_t *ps, c2_ptr_t node) {
|
static bool c2_tree_postprocess(struct c2_state *state, xcb_connection_t *c, c2_ptr_t node) {
|
||||||
if (!node.isbranch) {
|
if (!node.isbranch) {
|
||||||
return c2_l_postprocess(ps, node.l);
|
return c2_l_postprocess(state, c, node.l);
|
||||||
}
|
}
|
||||||
if (!c2_tree_postprocess(ps, node.b->opr1)) {
|
|
||||||
return false;
|
return c2_tree_postprocess(state, c, node.b->opr1) &&
|
||||||
}
|
c2_tree_postprocess(state, c, node.b->opr2);
|
||||||
return c2_tree_postprocess(ps, node.b->opr2);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool c2_list_postprocess(session_t *ps, c2_lptr_t *list) {
|
bool c2_list_postprocess(struct c2_state *state, xcb_connection_t *c, c2_lptr_t *list) {
|
||||||
c2_lptr_t *head = list;
|
c2_lptr_t *head = list;
|
||||||
while (head) {
|
while (head) {
|
||||||
if (!c2_tree_postprocess(ps, head->ptr)) {
|
if (!c2_tree_postprocess(state, c, head->ptr)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
head = head->next;
|
head = head->next;
|
||||||
|
@ -1729,3 +1733,24 @@ bool c2_list_foreach(const c2_lptr_t *condlist, c2_list_foreach_cb_t cb, void *d
|
||||||
void *c2_list_get_data(const c2_lptr_t *condlist) {
|
void *c2_list_get_data(const c2_lptr_t *condlist) {
|
||||||
return condlist->data;
|
return condlist->data;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct c2_state *c2_state_new(struct atom *atoms) {
|
||||||
|
auto ret = ccalloc(1, struct c2_state);
|
||||||
|
ret->atoms = atoms;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
void c2_state_free(struct c2_state *state) {
|
||||||
|
struct c2_tracked_property *property, *tmp;
|
||||||
|
HASH_ITER(hh, state->tracked_properties, property, tmp) {
|
||||||
|
HASH_DEL(state->tracked_properties, property);
|
||||||
|
free(property);
|
||||||
|
}
|
||||||
|
free(state);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool c2_is_property_tracked(struct c2_state *state, xcb_atom_t property) {
|
||||||
|
struct c2_tracked_property *p;
|
||||||
|
HASH_FIND_INT(state->tracked_properties, &property, p);
|
||||||
|
return p != NULL;
|
||||||
|
}
|
14
src/c2.h
14
src/c2.h
|
@ -13,9 +13,12 @@
|
||||||
|
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
|
#include <xcb/xproto.h>
|
||||||
|
|
||||||
typedef struct _c2_lptr c2_lptr_t;
|
typedef struct _c2_lptr c2_lptr_t;
|
||||||
typedef struct session session_t;
|
typedef struct session session_t;
|
||||||
|
struct c2_state;
|
||||||
|
struct atom;
|
||||||
struct managed_win;
|
struct managed_win;
|
||||||
|
|
||||||
typedef void (*c2_userdata_free)(void *);
|
typedef void (*c2_userdata_free)(void *);
|
||||||
|
@ -23,10 +26,19 @@ c2_lptr_t *c2_parse(c2_lptr_t **pcondlst, const char *pattern, void *data);
|
||||||
|
|
||||||
c2_lptr_t *c2_free_lptr(c2_lptr_t *lp, c2_userdata_free f);
|
c2_lptr_t *c2_free_lptr(c2_lptr_t *lp, c2_userdata_free f);
|
||||||
|
|
||||||
|
/// Create a new c2_state object. This is used for maintaining the internal state
|
||||||
|
/// used for c2 condition matching. This state object holds a reference to the
|
||||||
|
/// pass atom object, thus the atom object should be kept alive as long as the
|
||||||
|
/// state object is alive.
|
||||||
|
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_match(session_t *ps, const struct managed_win *w, const c2_lptr_t *condlst,
|
bool c2_match(session_t *ps, const struct managed_win *w, const c2_lptr_t *condlst,
|
||||||
void **pdata);
|
void **pdata);
|
||||||
|
|
||||||
bool c2_list_postprocess(session_t *ps, 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);
|
||||||
bool c2_list_foreach(const c2_lptr_t *list, c2_list_foreach_cb_t cb, void *data);
|
bool c2_list_foreach(const c2_lptr_t *list, c2_list_foreach_cb_t cb, void *data);
|
||||||
/// Return user data stored in a condition.
|
/// Return user data stored in a condition.
|
||||||
|
|
|
@ -234,6 +234,8 @@ typedef struct session {
|
||||||
uint64_t root_flags;
|
uint64_t root_flags;
|
||||||
/// Program options.
|
/// Program options.
|
||||||
options_t o;
|
options_t o;
|
||||||
|
/// State object for c2.
|
||||||
|
struct c2_state *c2_state;
|
||||||
/// Whether we have hit unredirection timeout.
|
/// Whether we have hit unredirection timeout.
|
||||||
bool tmout_unredir_hit;
|
bool tmout_unredir_hit;
|
||||||
/// If the backend is busy. This means two things:
|
/// If the backend is busy. This means two things:
|
||||||
|
@ -376,8 +378,6 @@ typedef struct session {
|
||||||
struct atom *atoms;
|
struct atom *atoms;
|
||||||
/// Array of atoms of all possible window types.
|
/// Array of atoms of all possible window types.
|
||||||
xcb_atom_t atoms_wintypes[NUM_WINTYPES];
|
xcb_atom_t atoms_wintypes[NUM_WINTYPES];
|
||||||
/// Linked list of additional atoms to track.
|
|
||||||
latom_t *track_atom_lst;
|
|
||||||
|
|
||||||
#ifdef CONFIG_DBUS
|
#ifdef CONFIG_DBUS
|
||||||
// === DBus related ===
|
// === DBus related ===
|
||||||
|
|
26
src/event.c
26
src/event.c
|
@ -11,6 +11,7 @@
|
||||||
#include <xcb/xcb_event.h>
|
#include <xcb/xcb_event.h>
|
||||||
|
|
||||||
#include "atom.h"
|
#include "atom.h"
|
||||||
|
#include "c2.h"
|
||||||
#include "common.h"
|
#include "common.h"
|
||||||
#include "compiler.h"
|
#include "compiler.h"
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
|
@ -573,20 +574,17 @@ static inline void ev_property_notify(session_t *ps, xcb_property_notify_event_t
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check for other atoms we are tracking
|
// Check for other atoms we are tracking
|
||||||
for (latom_t *platom = ps->track_atom_lst; platom; platom = platom->next) {
|
if (c2_is_property_tracked(ps->c2_state, ev->atom)) {
|
||||||
if (platom->atom == ev->atom) {
|
auto w = find_managed_win(ps, ev->window);
|
||||||
auto w = find_managed_win(ps, ev->window);
|
if (!w) {
|
||||||
if (!w) {
|
w = find_toplevel(ps, ev->window);
|
||||||
w = find_toplevel(ps, ev->window);
|
}
|
||||||
}
|
if (w) {
|
||||||
if (w) {
|
// Set FACTOR_CHANGED so rules based on properties will be
|
||||||
// Set FACTOR_CHANGED so rules based on properties will be
|
// re-evaluated.
|
||||||
// re-evaluated.
|
// Don't need to set property stale here, since that only
|
||||||
// Don't need to set property stale here, since that only
|
// concerns properties we explicitly check.
|
||||||
// concerns properties we explicitly check.
|
win_set_flags(w, WIN_FLAGS_FACTOR_CHANGED);
|
||||||
win_set_flags(w, WIN_FLAGS_FACTOR_CHANGED);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
39
src/picom.c
39
src/picom.c
|
@ -2071,7 +2071,6 @@ static session_t *session_init(int argc, char **argv, Display *dpy,
|
||||||
.xrfilter_convolution_exists = false,
|
.xrfilter_convolution_exists = false,
|
||||||
|
|
||||||
.atoms_wintypes = {0},
|
.atoms_wintypes = {0},
|
||||||
.track_atom_lst = NULL,
|
|
||||||
|
|
||||||
#ifdef CONFIG_DBUS
|
#ifdef CONFIG_DBUS
|
||||||
.dbus_data = NULL,
|
.dbus_data = NULL,
|
||||||
|
@ -2266,19 +2265,21 @@ static session_t *session_init(int argc, char **argv, Display *dpy,
|
||||||
SET_WM_TYPE_ATOM(DND);
|
SET_WM_TYPE_ATOM(DND);
|
||||||
#undef SET_WM_TYPE_ATOM
|
#undef SET_WM_TYPE_ATOM
|
||||||
|
|
||||||
|
ps->c2_state = c2_state_new(ps->atoms);
|
||||||
|
|
||||||
// Get needed atoms for c2 condition lists
|
// Get needed atoms for c2 condition lists
|
||||||
if (!(c2_list_postprocess(ps, ps->o.unredir_if_possible_blacklist) &&
|
if (!(c2_list_postprocess(ps->c2_state, ps->c.c, ps->o.unredir_if_possible_blacklist) &&
|
||||||
c2_list_postprocess(ps, ps->o.paint_blacklist) &&
|
c2_list_postprocess(ps->c2_state, ps->c.c, ps->o.paint_blacklist) &&
|
||||||
c2_list_postprocess(ps, ps->o.shadow_blacklist) &&
|
c2_list_postprocess(ps->c2_state, ps->c.c, ps->o.shadow_blacklist) &&
|
||||||
c2_list_postprocess(ps, ps->o.shadow_clip_list) &&
|
c2_list_postprocess(ps->c2_state, ps->c.c, ps->o.shadow_clip_list) &&
|
||||||
c2_list_postprocess(ps, ps->o.fade_blacklist) &&
|
c2_list_postprocess(ps->c2_state, ps->c.c, ps->o.fade_blacklist) &&
|
||||||
c2_list_postprocess(ps, ps->o.blur_background_blacklist) &&
|
c2_list_postprocess(ps->c2_state, ps->c.c, ps->o.blur_background_blacklist) &&
|
||||||
c2_list_postprocess(ps, ps->o.invert_color_list) &&
|
c2_list_postprocess(ps->c2_state, ps->c.c, ps->o.invert_color_list) &&
|
||||||
c2_list_postprocess(ps, ps->o.window_shader_fg_rules) &&
|
c2_list_postprocess(ps->c2_state, ps->c.c, ps->o.window_shader_fg_rules) &&
|
||||||
c2_list_postprocess(ps, ps->o.opacity_rules) &&
|
c2_list_postprocess(ps->c2_state, ps->c.c, ps->o.opacity_rules) &&
|
||||||
c2_list_postprocess(ps, ps->o.rounded_corners_blacklist) &&
|
c2_list_postprocess(ps->c2_state, ps->c.c, ps->o.rounded_corners_blacklist) &&
|
||||||
c2_list_postprocess(ps, ps->o.corner_radius_rules) &&
|
c2_list_postprocess(ps->c2_state, ps->c.c, ps->o.corner_radius_rules) &&
|
||||||
c2_list_postprocess(ps, ps->o.focus_blacklist))) {
|
c2_list_postprocess(ps->c2_state, ps->c.c, ps->o.focus_blacklist))) {
|
||||||
log_error("Post-processing of conditionals failed, some of your rules "
|
log_error("Post-processing of conditionals failed, some of your rules "
|
||||||
"might not work");
|
"might not work");
|
||||||
}
|
}
|
||||||
|
@ -2693,17 +2694,7 @@ static void session_destroy(session_t *ps) {
|
||||||
c2_list_free(&ps->o.rounded_corners_blacklist, NULL);
|
c2_list_free(&ps->o.rounded_corners_blacklist, NULL);
|
||||||
c2_list_free(&ps->o.corner_radius_rules, NULL);
|
c2_list_free(&ps->o.corner_radius_rules, NULL);
|
||||||
c2_list_free(&ps->o.window_shader_fg_rules, free);
|
c2_list_free(&ps->o.window_shader_fg_rules, free);
|
||||||
|
c2_state_free(ps->c2_state);
|
||||||
// Free tracked atom list
|
|
||||||
{
|
|
||||||
latom_t *next = NULL;
|
|
||||||
for (latom_t *this = ps->track_atom_lst; this; this = next) {
|
|
||||||
next = this->next;
|
|
||||||
free(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
ps->track_atom_lst = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Free tgt_{buffer,picture} and root_picture
|
// Free tgt_{buffer,picture} and root_picture
|
||||||
if (ps->tgt_buffer.pict == ps->tgt_picture) {
|
if (ps->tgt_buffer.pict == ps->tgt_picture) {
|
||||||
|
|
Loading…
Reference in a new issue