Skip to content

Commit

Permalink
c2: use list.h for condition lists
Browse files Browse the repository at this point in the history
Signed-off-by: Yuxuan Shui <[email protected]>
  • Loading branch information
yshui committed Aug 9, 2024
1 parent 0c5188e commit c1227b7
Show file tree
Hide file tree
Showing 9 changed files with 453 additions and 448 deletions.
581 changes: 285 additions & 296 deletions src/c2.c

Large diffs are not rendered by default.

55 changes: 35 additions & 20 deletions src/c2.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,9 @@
#include <stddef.h>
#include <xcb/xproto.h>

typedef struct _c2_lptr c2_lptr_t;
#include "utils/list.h"

typedef struct c2_condition c2_condition;
typedef struct session session_t;
struct c2_state;
/// Per-window state used for c2 condition matching.
Expand All @@ -19,19 +21,20 @@ struct c2_window_state {
};
struct atom;
struct win;
struct list_node;

typedef void (*c2_userdata_free)(void *);
c2_lptr_t *c2_parse(c2_lptr_t **pcondlst, const char *pattern, void *data);
struct c2_condition *c2_parse(struct list_node *list, const char *pattern, void *data);

/// Parse a condition that has a prefix. The prefix is parsed by `parse_prefix`. If
/// `free_value` is not NULL, it will be called to free the value returned by
/// `parse_prefix` when error occurs.
c2_lptr_t *
c2_parse_with_prefix(c2_lptr_t **pcondlst, const char *pattern,
c2_condition *
c2_parse_with_prefix(struct list_node *list, const char *pattern,
void *(*parse_prefix)(const char *input, const char **end, void *),
void (*free_value)(void *), void *user_data);

c2_lptr_t *c2_free_lptr(c2_lptr_t *lp, c2_userdata_free f);
void c2_free_condition(c2_condition *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
Expand All @@ -50,30 +53,42 @@ void c2_window_state_update(struct c2_state *state, struct c2_window_state *wind
xcb_connection_t *c, xcb_window_t client_win,
xcb_window_t frame_win);

bool c2_match(struct c2_state *state, const struct win *w, const c2_lptr_t *condlst,
void **pdata);
bool c2_match(struct c2_state *state, const struct win *w,
const struct list_node *conditions, void **pdata);
bool c2_match_one(const struct c2_state *state, const struct win *w,
const c2_lptr_t *condlst, void **pdata);
const c2_condition *condlst, void **pdata);

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);
bool c2_list_foreach(const c2_lptr_t *list, c2_list_foreach_cb_t cb, void *data);
bool c2_list_postprocess(struct c2_state *state, xcb_connection_t *c, struct list_node *list);
/// Return user data stored in a condition.
void *c2_list_get_data(const c2_lptr_t *condlist);
void *c2_condition_get_data(const c2_condition *condition);
/// Set user data stored in a condition. Return the old user data.
void *c2_list_set_data(c2_lptr_t *condlist, void *data);
/// Convert a c2_lptr_t to string. The returned string is only valid until the
void *c2_condition_set_data(c2_condition *condlist, void *data);
/// Convert a c2_condition to string. The returned string is only valid until the
/// next call to this function, and should not be freed.
const char *c2_lptr_to_str(const c2_lptr_t *);
void c2_condlist_insert(c2_lptr_t **pcondlst, c2_lptr_t *pnew);
const char *c2_condition_to_str(const c2_condition *);
c2_condition *c2_condition_list_next(struct list_node *list, c2_condition *condition);
c2_condition *c2_condition_list_prev(struct list_node *list, c2_condition *condition);
c2_condition *c2_condition_list_entry(struct list_node *list);
/// Create a new condition list with a single condition that is always true.
c2_lptr_t *c2_new_true(void);
c2_condition *c2_new_true(struct list_node *list);

#define c2_condition_list_foreach(list, i) \
for (c2_condition *i = \
list_is_empty((list)) ? NULL : c2_condition_list_entry((list)->next); \
i; i = c2_condition_list_next(list, i))

#define c2_condition_list_foreach_safe(list, i, n) \
for (c2_condition *i = \
list_is_empty((list)) ? NULL : c2_condition_list_entry((list)->next), \
*n = c2_condition_list_next(list, i); \
i; i = n, n = c2_condition_list_next(list, i))

/**
* Destroy a condition list.
*/
static inline void c2_list_free(c2_lptr_t **pcondlst, c2_userdata_free f) {
while ((*pcondlst = c2_free_lptr(*pcondlst, f))) {
static inline void c2_list_free(struct list_node *list, c2_userdata_free f) {
c2_condition_list_foreach_safe(list, i, ni) {
c2_free_condition(i, f);
}
*pcondlst = NULL;
list_init_head(list);
}
15 changes: 15 additions & 0 deletions src/config.c
Original file line number Diff line number Diff line change
Expand Up @@ -724,6 +724,21 @@ bool parse_config(options_t *opt, const char *config_file) {
// clang-format on

list_init_head(&opt->included_config_files);
list_init_head(&opt->unredir_if_possible_blacklist);
list_init_head(&opt->paint_blacklist);
list_init_head(&opt->shadow_blacklist);
list_init_head(&opt->shadow_clip_list);
list_init_head(&opt->fade_blacklist);
list_init_head(&opt->blur_background_blacklist);
list_init_head(&opt->invert_color_list);
list_init_head(&opt->window_shader_fg_rules);
list_init_head(&opt->opacity_rules);
list_init_head(&opt->rounded_corners_blacklist);
list_init_head(&opt->corner_radius_rules);
list_init_head(&opt->focus_blacklist);
list_init_head(&opt->transparent_clipping_blacklist);
list_init_head(&opt->rules);

opt->all_scripts = dynarr_new(struct script *, 4);
return parse_config_libconfig(opt, config_file);
}
30 changes: 14 additions & 16 deletions src/config.h
Original file line number Diff line number Diff line change
Expand Up @@ -59,8 +59,6 @@ typedef struct win_option {
bool clip_shadow_above;
} win_option_t;

typedef struct _c2_lptr c2_lptr_t;

enum vblank_scheduler_type {
/// X Present extension based vblank events
VBLANK_SCHEDULER_PRESENT,
Expand Down Expand Up @@ -276,7 +274,7 @@ typedef struct options {
bool unredir_if_possible;
/// List of conditions of windows to ignore as a full-screen window
/// when determining if a window could be unredirected.
c2_lptr_t *unredir_if_possible_blacklist;
struct list_node unredir_if_possible_blacklist;
/// Delay before unredirecting screen, in milliseconds.
int unredir_if_possible_delay;
/// Forced redirection setting through D-Bus.
Expand All @@ -292,7 +290,7 @@ typedef struct options {
/// Window to constantly repaint in benchmark mode. 0 for full-screen.
xcb_window_t benchmark_wid;
/// A list of conditions of windows not to paint.
c2_lptr_t *paint_blacklist;
struct list_node paint_blacklist;
/// Whether to show all X errors.
bool show_all_xerrors;
/// Whether to avoid acquiring X Selection.
Expand Down Expand Up @@ -321,13 +319,13 @@ typedef struct options {
int shadow_offset_x, shadow_offset_y;
double shadow_opacity;
/// Shadow blacklist. A linked list of conditions.
c2_lptr_t *shadow_blacklist;
struct list_node shadow_blacklist;
/// Whether bounding-shaped window should be ignored.
bool shadow_ignore_shaped;
/// Whether to crop shadow to the very X RandR monitor.
bool crop_shadow_to_monitor;
/// Don't draw shadow over these windows. A linked list of conditions.
c2_lptr_t *shadow_clip_list;
struct list_node shadow_clip_list;
bool shadow_enable;

// === Fading ===
Expand All @@ -342,7 +340,7 @@ typedef struct options {
/// Whether to disable fading on ARGB managed destroyed windows.
bool no_fading_destroyed_argb;
/// Fading blacklist. A linked list of conditions.
c2_lptr_t *fade_blacklist;
struct list_node fade_blacklist;
bool fading_enable;

// === Opacity ===
Expand Down Expand Up @@ -377,32 +375,32 @@ typedef struct options {
/// to window opacity.
bool blur_background_fixed;
/// Background blur blacklist. A linked list of conditions.
c2_lptr_t *blur_background_blacklist;
struct list_node blur_background_blacklist;
/// Blur convolution kernel.
struct conv **blur_kerns;
/// Number of convolution kernels
int blur_kernel_count;
/// Custom fragment shader for painting windows
char *window_shader_fg;
/// Rules to change custom fragment shader for painting windows.
c2_lptr_t *window_shader_fg_rules;
struct list_node window_shader_fg_rules;
/// 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.
c2_lptr_t *invert_color_list;
struct list_node invert_color_list;
/// Rules to change window opacity.
c2_lptr_t *opacity_rules;
struct list_node opacity_rules;
/// Limit window brightness
double max_brightness;
// Radius of rounded window corners
int corner_radius;
/// Rounded corners blacklist. A linked list of conditions.
c2_lptr_t *rounded_corners_blacklist;
struct list_node rounded_corners_blacklist;
/// Rounded corner rules. A linked list of conditions.
c2_lptr_t *corner_radius_rules;
struct list_node corner_radius_rules;

// === Focus related ===
/// Whether to try to detect WM windows and mark them as focused.
Expand All @@ -412,7 +410,7 @@ typedef struct options {
/// Whether to use EWMH _NET_ACTIVE_WINDOW to find active window.
bool use_ewmh_active_win;
/// A list of windows always to be considered focused.
c2_lptr_t *focus_blacklist;
struct list_node focus_blacklist;
/// Whether to do window grouping with <code>WM_TRANSIENT_FOR</code>.
bool detect_transient;
/// Whether to do window grouping with <code>WM_CLIENT_LEADER</code>.
Expand All @@ -430,15 +428,15 @@ typedef struct options {
bool transparent_clipping;
/// A list of conditions of windows to which transparent clipping
/// should not apply
c2_lptr_t *transparent_clipping_blacklist;
struct list_node transparent_clipping_blacklist;

bool dithered_present;
// === Animation ===
struct win_script animations[ANIMATION_TRIGGER_LAST + 1];
/// Array of all the scripts used in `animations`. This is a dynarr.
struct script **all_scripts;

c2_lptr_t *rules;
struct list_node rules;
bool has_both_style_of_rules;
} options_t;

Expand Down
Loading

0 comments on commit c1227b7

Please sign in to comment.