Skip to content

Commit

Permalink
wm/win: fix window-shader-fg/window-shader-fg-rules not working
Browse files Browse the repository at this point in the history
Fixes: cdf25b0
Signed-off-by: Yuxuan Shui <[email protected]>
  • Loading branch information
yshui committed Aug 13, 2024
1 parent 6b858b8 commit 636cb5b
Show file tree
Hide file tree
Showing 8 changed files with 45 additions and 28 deletions.
6 changes: 3 additions & 3 deletions src/config.h
Original file line number Diff line number Diff line change
Expand Up @@ -173,8 +173,8 @@ struct window_maybe_options {
/// Window dim level, NaN means not set.
double dim;

/// Name of the custom fragment shader for this window. NULL means not set.
const struct shader_info *shader;
/// The name of the custom fragment shader for this window. NULL means not set.
const char *shader;

/// Whether transparent clipping is excluded by the rules.
enum tristate transparent_clipping;
Expand Down Expand Up @@ -206,7 +206,7 @@ struct window_maybe_options {
struct window_options {
double opacity;
double dim;
const struct shader_info *shader;
const char *shader;
unsigned int corner_radius;
enum window_unredir_option unredir;
bool transparent_clipping;
Expand Down
8 changes: 7 additions & 1 deletion src/options.c
Original file line number Diff line number Diff line change
Expand Up @@ -1054,6 +1054,12 @@ void options_postprocess_c2_lists(struct c2_state *state, struct x_connection *c
}
}

static void free_window_maybe_options(void *data) {
auto wopts = (struct window_maybe_options *)data;
free((void *)wopts->shader);
free(wopts);
}

void options_destroy(struct options *options) {
// Free blacklists
c2_list_free(&options->shadow_blacklist, NULL);
Expand All @@ -1069,7 +1075,7 @@ void options_destroy(struct options *options) {
c2_list_free(&options->corner_radius_rules, NULL);
c2_list_free(&options->window_shader_fg_rules, free);
c2_list_free(&options->transparent_clipping_blacklist, NULL);
c2_list_free(&options->rules, free);
c2_list_free(&options->rules, free_window_maybe_options);

free(options->config_file_path);
free(options->write_pid_path);
Expand Down
10 changes: 7 additions & 3 deletions src/picom.c
Original file line number Diff line number Diff line change
Expand Up @@ -799,7 +799,11 @@ static bool paint_preprocess(session_t *ps, bool *animation, struct win **out_bo
const double window_opacity = win_animatable_get(w, WIN_SCRIPT_OPACITY);
const double blur_opacity = win_animatable_get(w, WIN_SCRIPT_BLUR_OPACITY);
auto window_options = win_options(w);
if (window_options.shader->attributes & SHADER_ATTRIBUTE_ANIMATED) {
struct shader_info *fg_shader = NULL;
if (window_options.shader != NULL) {
HASH_FIND_STR(ps->shaders, window_options.shader, fg_shader);
}
if (fg_shader != NULL && fg_shader->attributes & SHADER_ATTRIBUTE_ANIMATED) {
add_damage_from_win(ps, w);
*animation = true;
}
Expand Down Expand Up @@ -1852,7 +1856,7 @@ static void draw_callback_impl(EV_P_ session_t *ps, int revents attr_unused) {
ps->o.force_win_blend, ps->o.blur_background_frame,
ps->o.inactive_dim_fixed, ps->o.max_brightness,
ps->o.crop_shadow_to_monitor ? &ps->monitors : NULL,
&after_damage_us);
ps->shaders, &after_damage_us);
if (!succeeded) {
log_fatal("Render failure");
abort();
Expand Down Expand Up @@ -2000,7 +2004,7 @@ static struct window_options win_options_from_config(const struct options *opts)
.transparent_clipping = opts->transparent_clipping,
.dim = opts->inactive_dim > 0,
.fade = opts->fading_enable,
.shader = &null_shader,
.shader = opts->window_shader_fg,
.invert_color = false,
.paint = true,
.clip_shadow_above = false,
Expand Down
15 changes: 10 additions & 5 deletions src/renderer/command_builder.c
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
static inline unsigned
commands_for_window_body(struct layer *layer, struct backend_command *cmd_base,
const region_t *frame_region, bool inactive_dim_fixed,
double max_brightness) {
double max_brightness, const struct shader_info *shaders) {
auto w = layer->win;
auto cmd = cmd_base;
scoped_region_t crop = region_from_box(layer->crop);
Expand Down Expand Up @@ -49,6 +49,10 @@ commands_for_window_body(struct layer *layer, struct backend_command *cmd_base,
if (layer->options.corner_radius > 0) {
win_region_remove_corners(w, layer->window.origin, &cmd->opaque_region);
}
struct shader_info *shader = &null_shader;
if (layer->options.shader != NULL) {
HASH_FIND_STR(shaders, layer->options.shader, shader);
}

float opacity = layer->opacity * (1 - layer->saved_image_blend);
if (opacity > (1. - 1. / MAX_ALPHA)) {
Expand All @@ -66,7 +70,7 @@ commands_for_window_body(struct layer *layer, struct backend_command *cmd_base,
.dim = dim,
.scale = layer->scale,
.effective_size = layer->window.size,
.shader = layer->options.shader->backend_shader,
.shader = shader->backend_shader,
.color_inverted = layer->options.invert_color,
.source_mask = NULL,
.max_brightness = max_brightness,
Expand Down Expand Up @@ -408,7 +412,8 @@ void command_builder_free(struct command_builder *cb) {
// value in `struct managed_win`.
void command_builder_build(struct command_builder *cb, struct layout *layout,
bool force_blend, bool blur_frame, bool inactive_dim_fixed,
double max_brightness, const struct x_monitors *monitors) {
double max_brightness, const struct x_monitors *monitors,
const struct shader_info *shaders) {

unsigned ncmds = 1;
dynarr_foreach(layout->layers, layer) {
Expand Down Expand Up @@ -445,8 +450,8 @@ void command_builder_build(struct command_builder *cb, struct layout *layout,
layer->window.origin.y);

// Add window body
cmd -= commands_for_window_body(layer, cmd, &frame_region,
inactive_dim_fixed, max_brightness);
cmd -= commands_for_window_body(
layer, cmd, &frame_region, inactive_dim_fixed, max_brightness, shaders);

// Add shadow
cmd -= command_for_shadow(layer, cmd, monitors, last + 1);
Expand Down
4 changes: 3 additions & 1 deletion src/renderer/command_builder.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ struct backend_command;
struct layout;
struct x_monitors;
struct win_option;
struct shader_info;

struct command_builder *command_builder_new(void);
void command_builder_free(struct command_builder *);
Expand All @@ -25,4 +26,5 @@ void command_builder_command_list_free(struct backend_command *cmds);
/// stay true after further passes.
void command_builder_build(struct command_builder *cb, struct layout *layout,
bool force_blend, bool blur_frame, bool inactive_dim_fixed,
double max_brightness, const struct x_monitors *monitors);
double max_brightness, const struct x_monitors *monitors,
const struct shader_info *shaders);
12 changes: 6 additions & 6 deletions src/renderer/renderer.c
Original file line number Diff line number Diff line change
Expand Up @@ -489,11 +489,11 @@ void renderer_ensure_images_ready(struct renderer *r, struct backend_base *backe
/// @return true if a frame is rendered, false if this frame is skipped.
bool renderer_render(struct renderer *r, struct backend_base *backend,
image_handle root_image, struct layout_manager *lm,
struct command_builder *cb, void *blur_context,
uint64_t render_start_us, xcb_sync_fence_t xsync_fence,
bool use_damage, bool monitor_repaint, bool force_blend,
bool blur_frame, bool inactive_dim_fixed, double max_brightness,
const struct x_monitors *monitors, uint64_t *after_damage_us) {
struct command_builder *cb, void *blur_context, uint64_t render_start_us,
xcb_sync_fence_t xsync_fence, bool use_damage, bool monitor_repaint,
bool force_blend, bool blur_frame, bool inactive_dim_fixed,
double max_brightness, const struct x_monitors *monitors,
const struct shader_info *shaders, uint64_t *after_damage_us) {
if (xsync_fence != XCB_NONE) {
// Trigger the fence but don't immediately wait on it. Let it run
// concurrent with our CPU tasks to save time.
Expand All @@ -514,7 +514,7 @@ bool renderer_render(struct renderer *r, struct backend_base *backend,
renderer_ensure_images_ready(r, backend, monitor_repaint);

command_builder_build(cb, layout, force_blend, blur_frame, inactive_dim_fixed,
max_brightness, monitors);
max_brightness, monitors, shaders);
if (log_get_level_tls() <= LOG_LEVEL_TRACE) {
auto layer = layout->layers - 1;
auto layer_end = &layout->commands[layout->first_layer_start];
Expand Down
11 changes: 6 additions & 5 deletions src/renderer/renderer.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ struct renderer;
struct layout_manager;
struct backend_base;
struct command_builder;
struct shader_info;
typedef struct image_handle *image_handle;
struct x_monitors;
struct wm;
Expand All @@ -22,8 +23,8 @@ struct renderer *renderer_new(struct backend_base *backend, double shadow_radius
struct color shadow_color, bool dithered_present);
bool renderer_render(struct renderer *r, struct backend_base *backend,
image_handle root_image, struct layout_manager *lm,
struct command_builder *cb, void *blur_context,
uint64_t render_start_us, xcb_sync_fence_t xsync_fence,
bool use_damage, bool monitor_repaint, bool force_blend,
bool blur_frame, bool inactive_dim_fixed, double max_brightness,
const struct x_monitors *monitors, uint64_t *after_damage_us);
struct command_builder *cb, void *blur_context, uint64_t render_start_us,
xcb_sync_fence_t xsync_fence, bool use_damage, bool monitor_repaint,
bool force_blend, bool blur_frame, bool inactive_dim_fixed,
double max_brightness, const struct x_monitors *monitors,
const struct shader_info *shaders, uint64_t *after_damage_us);
7 changes: 3 additions & 4 deletions src/wm/win.c
Original file line number Diff line number Diff line change
Expand Up @@ -980,12 +980,11 @@ static void win_determine_fg_shader(session_t *ps, struct win *w) {
return;
}

void *val = NULL;
w->options.shader = NULL;

void *val = NULL;
if (c2_match(ps->c2_state, w, &ps->o.window_shader_fg_rules, &val)) {
struct shader_info *shader = NULL;
HASH_FIND_STR(ps->shaders, val, shader);
w->options.shader = shader;
w->options.shader = val;
}
}

Expand Down

0 comments on commit 636cb5b

Please sign in to comment.