feat: scenefx blur shadow corner radius and opacity

This commit is contained in:
DreamMaoMao
2025-06-14 09:29:12 +08:00
parent d892b1048f
commit 55f82231a6
5 changed files with 588 additions and 230 deletions

View File

@@ -38,6 +38,8 @@ xkbcommon_dep = dependency('xkbcommon')
libinput_dep = dependency('libinput') libinput_dep = dependency('libinput')
libwayland_client_dep = dependency('wayland-client') libwayland_client_dep = dependency('wayland-client')
pcre2_dep = dependency('libpcre2-8') pcre2_dep = dependency('libpcre2-8')
libscenefx_dep = dependency('scenefx-0.3')
# 获取 Git Commit Hash 和最新的 tag # 获取 Git Commit Hash 和最新的 tag
git = find_program('git', required : false) git = find_program('git', required : false)
@@ -75,6 +77,7 @@ executable('maomao',
libm, libm,
xcb, xcb,
xlibs, xlibs,
libscenefx_dep,
wayland_server_dep, wayland_server_dep,
wlroots_dep, wlroots_dep,
xkbcommon_dep, xkbcommon_dep,

View File

@@ -308,9 +308,7 @@ static inline void client_send_close(Client *c) {
static inline void client_set_border_color(Client *c, static inline void client_set_border_color(Client *c,
const float color[static 4]) { const float color[static 4]) {
int i; wlr_scene_rect_set_color(c->border, color);
for (i = 0; i < 4; i++)
wlr_scene_rect_set_color(c->border[i], color);
} }
static inline void client_set_fullscreen(Client *c, int fullscreen) { static inline void client_set_fullscreen(Client *c, int fullscreen) {

View File

@@ -60,6 +60,8 @@ typedef struct {
int noswallow; int noswallow;
int scratchpad_width; int scratchpad_width;
int scratchpad_height; int scratchpad_height;
float focused_opacity;
float unfocused_opacity;
uint32_t passmod; uint32_t passmod;
xkb_keysym_t keysym; xkb_keysym_t keysym;
KeyBinding globalkeybinding; KeyBinding globalkeybinding;
@@ -151,6 +153,8 @@ typedef struct {
int enable_floating_snap; int enable_floating_snap;
int drag_tile_to_tile; int drag_tile_to_tile;
unsigned int swipe_min_threshold; unsigned int swipe_min_threshold;
float focused_opacity;
float unfocused_opacity;
float *scroller_proportion_preset; float *scroller_proportion_preset;
int scroller_proportion_preset_count; int scroller_proportion_preset_count;
@@ -192,6 +196,16 @@ typedef struct {
unsigned int accel_profile; unsigned int accel_profile;
double accel_speed; double accel_speed;
int blur;
int border_radius;
struct blur_data blur_params;
int shadows;
unsigned int shadows_size;
float shadows_blur;
int shadows_position_x;
int shadows_position_y;
float shadowscolor[4];
int smartgaps; int smartgaps;
unsigned int gappih; unsigned int gappih;
unsigned int gappiv; unsigned int gappiv;
@@ -866,6 +880,34 @@ void parse_config_line(Config *config, const char *line) {
config->focus_cross_monitor = atoi(value); config->focus_cross_monitor = atoi(value);
} else if (strcmp(key, "focus_cross_tag") == 0) { } else if (strcmp(key, "focus_cross_tag") == 0) {
config->focus_cross_tag = atoi(value); config->focus_cross_tag = atoi(value);
} else if (strcmp(key, "focus_cross_tag") == 0) {
config->focus_cross_tag = atoi(value);
} else if (strcmp(key, "blur") == 0) {
config->blur = atoi(value);
} else if (strcmp(key, "border_radius") == 0) {
config->border_radius = atoi(value);
} else if (strcmp(key, "blur_params_num_passes") == 0) {
config->blur_params.num_passes = atoi(value);
} else if (strcmp(key, "blur_params_radius") == 0) {
config->blur_params.radius = atoi(value);
} else if (strcmp(key, "blur_params_noise") == 0) {
config->blur_params.noise = atof(value);
} else if (strcmp(key, "blur_params_brightness") == 0) {
config->blur_params.brightness = atof(value);
} else if (strcmp(key, "blur_params_contrast") == 0) {
config->blur_params.contrast = atof(value);
} else if (strcmp(key, "blur_params_saturation") == 0) {
config->blur_params.saturation = atof(value);
} else if (strcmp(key, "shadows") == 0) {
config->shadows = atoi(value);
} else if (strcmp(key, "shadows_size") == 0) {
config->shadows_size = atoi(value);
} else if (strcmp(key, "shadows_blur") == 0) {
config->shadows_blur = atof(value);
} else if (strcmp(key, "shadows_position_x") == 0) {
config->shadows_position_x = atoi(value);
} else if (strcmp(key, "shadows_position_y") == 0) {
config->shadows_position_y = atoi(value);
} else if (strcmp(key, "single_scratchpad") == 0) { } else if (strcmp(key, "single_scratchpad") == 0) {
config->single_scratchpad = atoi(value); config->single_scratchpad = atoi(value);
} else if (strcmp(key, "xwayland_persistence") == 0) { } else if (strcmp(key, "xwayland_persistence") == 0) {
@@ -880,6 +922,10 @@ void parse_config_line(Config *config, const char *line) {
config->drag_tile_to_tile = atoi(value); config->drag_tile_to_tile = atoi(value);
} else if (strcmp(key, "swipe_min_threshold") == 0) { } else if (strcmp(key, "swipe_min_threshold") == 0) {
config->swipe_min_threshold = atoi(value); config->swipe_min_threshold = atoi(value);
} else if (strcmp(key, "focused_opacity") == 0) {
config->focused_opacity = atof(value);
} else if (strcmp(key, "unfocused_opacity") == 0) {
config->unfocused_opacity = atof(value);
} else if (strcmp(key, "xkb_rules_rules") == 0) { } else if (strcmp(key, "xkb_rules_rules") == 0) {
strncpy(xkb_rules_rules, value, sizeof(xkb_rules_rules) - 1); strncpy(xkb_rules_rules, value, sizeof(xkb_rules_rules) - 1);
xkb_rules_rules[sizeof(xkb_rules_rules) - 1] = xkb_rules_rules[sizeof(xkb_rules_rules) - 1] =
@@ -1100,6 +1146,14 @@ void parse_config_line(Config *config, const char *line) {
} else { } else {
convert_hex_to_rgba(config->rootcolor, color); convert_hex_to_rgba(config->rootcolor, color);
} }
} else if (strcmp(key, "shadowscolor") == 0) {
long int color = parse_color(value);
if (color == -1) {
fprintf(stderr, "Error: Invalid shadowscolor format: %s\n", value);
} else {
convert_hex_to_rgba(config->shadowscolor, color);
}
} else if (strcmp(key, "bordercolor") == 0) { } else if (strcmp(key, "bordercolor") == 0) {
long int color = parse_color(value); long int color = parse_color(value);
if (color == -1) { if (color == -1) {
@@ -1229,6 +1283,8 @@ void parse_config_line(Config *config, const char *line) {
rule->no_force_center = -1; rule->no_force_center = -1;
rule->scratchpad_width = 0; rule->scratchpad_width = 0;
rule->scratchpad_height = 0; rule->scratchpad_height = 0;
rule->focused_opacity = 0;
rule->unfocused_opacity = 0;
rule->width = 0; rule->width = 0;
rule->height = 0; rule->height = 0;
rule->animation_type_open = NULL; rule->animation_type_open = NULL;
@@ -2010,6 +2066,23 @@ void override_config(void) {
borderpx = CLAMP_INT(config.borderpx, 0, 200); borderpx = CLAMP_INT(config.borderpx, 0, 200);
smartgaps = CLAMP_INT(config.smartgaps, 0, 1); smartgaps = CLAMP_INT(config.smartgaps, 0, 1);
blur = CLAMP_INT(config.blur, 0, 1);
border_radius = CLAMP_INT(config.border_radius, 0, 100);
blur_params.num_passes = CLAMP_INT(config.blur_params.num_passes, 0, 10);
blur_params.radius = CLAMP_INT(config.blur_params.radius, 0, 100);
blur_params.noise = CLAMP_FLOAT(config.blur_params.noise, 0, 1);
blur_params.brightness = CLAMP_FLOAT(config.blur_params.brightness, 0, 1);
blur_params.contrast = CLAMP_FLOAT(config.blur_params.contrast, 0, 1);
blur_params.saturation = CLAMP_FLOAT(config.blur_params.saturation, 0, 1);
shadows = CLAMP_INT(config.shadows, 0, 1);
shadows_size = CLAMP_INT(config.shadows_size, 0, 100);
shadows_blur = CLAMP_INT(config.shadows_blur, 0, 100);
shadows_position_x = CLAMP_INT(config.shadows_position_x, 0, 100);
shadows_position_y = CLAMP_INT(config.shadows_position_y, 0, 100);
focused_opacity = CLAMP_FLOAT(config.focused_opacity, 0.0f, 1.0f);
unfocused_opacity = CLAMP_FLOAT(config.unfocused_opacity, 0.0f, 1.0f);
memcpy(shadowscolor, config.shadowscolor, sizeof(shadowscolor));
// 复制颜色数组 // 复制颜色数组
memcpy(rootcolor, config.rootcolor, sizeof(rootcolor)); memcpy(rootcolor, config.rootcolor, sizeof(rootcolor));
memcpy(bordercolor, config.bordercolor, sizeof(bordercolor)); memcpy(bordercolor, config.bordercolor, sizeof(bordercolor));
@@ -2120,6 +2193,23 @@ void set_value_default() {
config.accel_profile = accel_profile; config.accel_profile = accel_profile;
config.accel_speed = accel_speed; config.accel_speed = accel_speed;
config.blur = blur;
config.border_radius = border_radius;
config.blur_params.num_passes = blur_params_num_passes;
config.blur_params.radius = blur_params_radius;
config.blur_params.noise = blur_params_noise;
config.blur_params.brightness = blur_params_brightness;
config.blur_params.contrast = blur_params_contrast;
config.blur_params.saturation = blur_params_saturation;
config.shadows = shadows;
config.shadows_size = shadows_size;
config.shadows_blur = shadows_blur;
config.shadows_position_x = shadows_position_x;
config.shadows_position_y = shadows_position_y;
config.focused_opacity = focused_opacity;
config.unfocused_opacity = unfocused_opacity;
memcpy(config.shadowscolor, shadowscolor, sizeof(shadowscolor));
memcpy(config.animation_curve_move, animation_curve_move, memcpy(config.animation_curve_move, animation_curve_move,
sizeof(animation_curve_move)); sizeof(animation_curve_move));
memcpy(config.animation_curve_open, animation_curve_open, memcpy(config.animation_curve_open, animation_curve_open,
@@ -2230,6 +2320,30 @@ void parse_config(void) {
override_config(); override_config();
} }
void reset_blur_params(void) {
if (blur) {
Monitor *m;
wl_list_for_each(m, &mons, link) {
if (m->blur != NULL) {
wlr_scene_node_destroy(&m->blur->node);
}
m->blur = wlr_scene_optimized_blur_create(&scene->tree, 0, 0);
wlr_scene_node_reparent(&m->blur->node, layers[LyrBlur]);
wlr_scene_optimized_blur_set_size(m->blur, m->m.width, m->m.height);
wlr_scene_set_blur_data(scene, blur_params);
}
} else {
Monitor *m;
wl_list_for_each(m, &mons, link) {
if (m->blur) {
wlr_scene_node_destroy(&m->blur->node);
m->blur = NULL;
}
}
}
}
void reload_config(const Arg *arg) { void reload_config(const Arg *arg) {
Client *c; Client *c;
Monitor *m; Monitor *m;
@@ -2239,6 +2353,7 @@ void reload_config(const Arg *arg) {
init_baked_points(); init_baked_points();
handlecursoractivity(); handlecursoractivity();
reset_keyboard_layout(); reset_keyboard_layout();
reset_blur_params();
run_exec(); run_exec();
// reset border width when config change // reset border width when config change
@@ -2246,6 +2361,8 @@ void reload_config(const Arg *arg) {
if (c && !c->iskilling) { if (c && !c->iskilling) {
if (c->bw) { if (c->bw) {
c->bw = borderpx; c->bw = borderpx;
c->focused_opacity = focused_opacity;
c->unfocused_opacity = unfocused_opacity;
} }
} }
} }

View File

@@ -179,3 +179,35 @@ enum libinput_config_tap_button_map button_map = LIBINPUT_CONFIG_TAP_MAP_LRM;
static const char *tags[] = { static const char *tags[] = {
"1", "2", "3", "4", "5", "6", "7", "8", "9", "1", "2", "3", "4", "5", "6", "7", "8", "9",
}; };
float focused_opacity = 1.0;
float unfocused_opacity = 0.8;
int border_radius = 0;
int border_radius_location_default = CORNER_LOCATION_ALL;
int blur = 0;
struct blur_data {
int num_passes;
int radius;
float noise;
float brightness;
float contrast;
float saturation;
};
struct blur_data blur_params;
int blur_params_num_passes = 1;
int blur_params_radius = 5;
float blur_params_noise = 0.02;
float blur_params_brightness = 0.9;
float blur_params_contrast = 0.9;
float blur_params_saturation = 1.2;
int shadows = 0;
unsigned int shadows_size = 10;
double shadows_blur = 15;
int shadows_position_x = 0;
int shadows_position_y = 0;
float shadowscolor[] = COLOR(0x000000ff);
;

View File

@@ -6,6 +6,11 @@
#include <libinput.h> #include <libinput.h>
#include <limits.h> #include <limits.h>
#include <linux/input-event-codes.h> #include <linux/input-event-codes.h>
#include <scenefx/render/fx_renderer/fx_renderer.h>
#include <scenefx/types/fx/blur_data.h>
#include <scenefx/types/fx/clipped_region.h>
#include <scenefx/types/fx/corner_location.h>
#include <scenefx/types/wlr_scene.h>
#include <signal.h> #include <signal.h>
#include <stdbool.h> #include <stdbool.h>
#include <stdint.h> #include <stdint.h>
@@ -54,7 +59,6 @@
#include <wlr/types/wlr_primary_selection.h> #include <wlr/types/wlr_primary_selection.h>
#include <wlr/types/wlr_primary_selection_v1.h> #include <wlr/types/wlr_primary_selection_v1.h>
#include <wlr/types/wlr_relative_pointer_v1.h> #include <wlr/types/wlr_relative_pointer_v1.h>
#include <wlr/types/wlr_scene.h>
#include <wlr/types/wlr_screencopy_v1.h> #include <wlr/types/wlr_screencopy_v1.h>
#include <wlr/types/wlr_seat.h> #include <wlr/types/wlr_seat.h>
#include <wlr/types/wlr_server_decoration.h> #include <wlr/types/wlr_server_decoration.h>
@@ -121,6 +125,7 @@ enum { XDGShell, LayerShell, X11 }; /* client types */
enum { AxisUp, AxisDown, AxisLeft, AxisRight }; // 滚轮滚动的方向 enum { AxisUp, AxisDown, AxisLeft, AxisRight }; // 滚轮滚动的方向
enum { enum {
LyrBg, LyrBg,
LyrBlur,
LyrBottom, LyrBottom,
LyrTile, LyrTile,
LyrFloat, LyrFloat,
@@ -202,6 +207,9 @@ typedef struct {
float height_scale; float height_scale;
int width; int width;
int height; int height;
double percent;
float opacity;
enum corner_location corner_location;
bool should_scale; bool should_scale;
} animationScale; } animationScale;
@@ -213,7 +221,8 @@ struct Client {
overview_backup_geom, current; /* layout-relative, includes border */ overview_backup_geom, current; /* layout-relative, includes border */
Monitor *mon; Monitor *mon;
struct wlr_scene_tree *scene; struct wlr_scene_tree *scene;
struct wlr_scene_rect *border[4]; /* top, bottom, left, right */ struct wlr_scene_rect *border; /* top, bottom, left, right */
struct wlr_scene_shadow *shadow;
struct wlr_scene_tree *scene_surface; struct wlr_scene_tree *scene_surface;
struct wl_list link; struct wl_list link;
struct wl_list flink; struct wl_list flink;
@@ -286,6 +295,8 @@ struct Client {
int nofadeout; int nofadeout;
int no_force_center; int no_force_center;
int isunglobal; int isunglobal;
float focused_opacity;
float unfocused_opacity;
}; };
typedef struct { typedef struct {
@@ -384,6 +395,7 @@ struct Monitor {
int gamma_lut_changed; int gamma_lut_changed;
int asleep; int asleep;
unsigned int visible_clients; unsigned int visible_clients;
struct wlr_scene_optimized_blur *blur;
}; };
typedef struct { typedef struct {
@@ -632,7 +644,8 @@ static unsigned int get_tags_first_tag(unsigned int tags);
static void client_commit(Client *c); static void client_commit(Client *c);
static void apply_border(Client *c, struct wlr_box clip_box, int offsetx, static void apply_border(Client *c, struct wlr_box clip_box, int offsetx,
int offsety); int offsety,
enum corner_location current_corner_location);
static void client_set_opacity(Client *c, double opacity); static void client_set_opacity(Client *c, double opacity);
static void init_baked_points(void); static void init_baked_points(void);
static void scene_buffer_apply_opacity(struct wlr_scene_buffer *buffer, int sx, static void scene_buffer_apply_opacity(struct wlr_scene_buffer *buffer, int sx,
@@ -1030,19 +1043,9 @@ void client_animation_next_tick(Client *c) {
.height = height, .height = height,
}; };
if (!c->iskilling && (c->is_open_animation || c->animation.begin_fade_in) &&
animation_fade_in && !c->nofadein) {
c->animation.begin_fade_in = true;
client_set_opacity(c,
MIN(animation_passed + fadein_begin_opacity, 1.0));
}
c->is_open_animation = false; c->is_open_animation = false;
if (animation_passed == 1.0) { if (animation_passed == 1.0) {
if (c->animation.begin_fade_in) {
c->animation.begin_fade_in = false;
}
// clear the open action state // clear the open action state
// To prevent him from being mistaken that // To prevent him from being mistaken that
@@ -1105,8 +1108,57 @@ bool check_hit_no_border(Client *c) {
return hit_no_border; return hit_no_border;
} }
void
client_draw_shadow(Client *c) {
if (c->iskilling || !client_surface(c)->mapped)
return;
if(!shadows || !c->isfloating) {
wlr_scene_shadow_set_size(c->shadow, 0, 0);
return;
}
uint32_t width, height;
client_actual_size(c, &width, &height);
uint32_t delta = shadows_size + c->bw;
/* we calculate where to clip the shadow */
struct wlr_box client_box = {
.x = 0,
.y = 0,
.width = width,
.height = height,
};
struct wlr_box shadow_box = {
.x = shadows_position_x,
.y = shadows_position_y,
.width = width + 2 * delta,
.height = height + 2 * delta,
};
struct wlr_box intersection_box;
wlr_box_intersection(&intersection_box, &client_box, &shadow_box);
/* clipped region takes shadow relative coords, so we translate everything by its position */
intersection_box.x -= shadows_position_x;
intersection_box.y -= shadows_position_y;
struct clipped_region clipped_region = {
.area = intersection_box,
.corner_radius = border_radius,
.corners = border_radius_location_default,
};
wlr_scene_node_set_position(&c->shadow->node, shadow_box.x, shadow_box.y);
wlr_scene_shadow_set_size(c->shadow, shadow_box.width, shadow_box.height);
wlr_scene_shadow_set_clipped_region(c->shadow, clipped_region);
}
void apply_border(Client *c, struct wlr_box clip_box, int offsetx, void apply_border(Client *c, struct wlr_box clip_box, int offsetx,
int offsety) { int offsety, enum corner_location border_radius_location) {
bool hit_no_border = false; bool hit_no_border = false;
if (c->iskilling || !client_surface(c)->mapped) if (c->iskilling || !client_surface(c)->mapped)
@@ -1126,10 +1178,7 @@ void apply_border(Client *c, struct wlr_box clip_box, int offsetx,
c->bw = 0; c->bw = 0;
c->fake_no_border = true; c->fake_no_border = true;
} else if (hit_no_border && !smartgaps) { } else if (hit_no_border && !smartgaps) {
set_rect_size(c->border[0], 0, 0); wlr_scene_rect_set_size(c->border, 0, 0);
set_rect_size(c->border[1], 0, 0);
set_rect_size(c->border[2], 0, 0);
set_rect_size(c->border[3], 0, 0);
wlr_scene_node_set_position(&c->scene_surface->node, c->bw, c->bw); wlr_scene_node_set_position(&c->scene_surface->node, c->bw, c->bw);
c->fake_no_border = true; c->fake_no_border = true;
return; return;
@@ -1138,63 +1187,79 @@ void apply_border(Client *c, struct wlr_box clip_box, int offsetx,
c->fake_no_border = false; c->fake_no_border = false;
} }
int clip_box_width = clip_box.width - 2 * c->bw;
int clip_box_height = clip_box.height - 2 * c->bw;
if(clip_box_width < 0) {
clip_box_width = 0;
}
if(clip_box_height < 0) {
clip_box_height = 0;
}
int clip_x = c->bw - offsetx;
int clip_y = c->bw - offsety;
clip_x = clip_x < 0 ? 0 : clip_x;
clip_y = clip_y < 0 ? 0 : clip_y;
struct clipped_region clipped_region = {
.area = { clip_x, clip_y, clip_box_width, clip_box_height },
.corner_radius = border_radius,
.corners = border_radius_location,
};
int right_offset = GEZERO(c->animation.current.x + c->animation.current.width - c->mon->m.x - c->mon->m.width);
int bottom_offset = GEZERO(c->animation.current.y + c->animation.current.height - c->mon->m.y - c->mon->m.height);
int rect_width = clip_box.width;
int rect_height = clip_box.height;
if(right_offset > 0) {
clipped_region.area.width = MIN(clip_box.width,clipped_region.area.width + right_offset);
}
if(bottom_offset > 0) {
clipped_region.area.height = MIN(clip_box.height,clipped_region.area.height + bottom_offset);
}
if(rect_width < 0) {
rect_width = 0;
}
if(rect_height < 0) {
rect_height = 0;
}
int node_x = offsetx;
int node_y = offsety;
wlr_scene_node_set_position(&c->scene_surface->node, c->bw, c->bw); wlr_scene_node_set_position(&c->scene_surface->node, c->bw, c->bw);
set_rect_size(c->border[0], clip_box.width, c->bw); wlr_scene_rect_set_size(c->border, rect_width, rect_height);
set_rect_size(c->border[1], clip_box.width, c->bw); wlr_scene_node_set_position(&c->border->node, node_x, node_y);
set_rect_size(c->border[2], c->bw, clip_box.height - 2 * c->bw); wlr_scene_rect_set_corner_radius(c->border, border_radius, border_radius_location);
set_rect_size(c->border[3], c->bw, clip_box.height - 2 * c->bw); wlr_scene_rect_set_clipped_region(c->border, clipped_region);
wlr_scene_node_set_position(&c->border[0]->node, 0, 0); }
wlr_scene_node_set_position(&c->border[2]->node, 0, c->bw);
wlr_scene_node_set_position(&c->border[1]->node, 0,
clip_box.height - c->bw);
wlr_scene_node_set_position(&c->border[3]->node, clip_box.width - c->bw,
c->bw);
if (ISTILED(c) || c->animation.tagining || c->animation.tagouted || enum corner_location set_client_corner_location(Client *c) {
c->animation.tagouting) { enum corner_location current_corner_location = CORNER_LOCATION_ALL;
if (c->animation.current.x < c->mon->m.x) { struct wlr_box target_geom = animations ? c->animation.current : c->geom;
set_rect_size(c->border[2], GEZERO(c->bw - offsetx), if (target_geom.x + border_radius <= c->mon->m.x) {
clip_box.height - 2 * c->bw); current_corner_location &= ~CORNER_LOCATION_LEFT; // 清除左标志位
} else if (c->animation.current.x + c->animation.current.width > }
if (target_geom.x + target_geom.width - border_radius >=
c->mon->m.x + c->mon->m.width) { c->mon->m.x + c->mon->m.width) {
set_rect_size(c->border[3], current_corner_location &= ~CORNER_LOCATION_RIGHT; // 清除右标志位
GEZERO(c->bw - GEZERO(c->animation.current.x + }
c->animation.current.width - if (target_geom.y + border_radius <= c->mon->m.y) {
c->mon->m.x - c->mon->m.width)), current_corner_location &= ~CORNER_LOCATION_TOP; // 清除上标志位
clip_box.height - 2 * c->bw); }
set_rect_size(c->border[0], clip_box.width + c->bw, if (target_geom.y + target_geom.height - border_radius >=
GEZERO(c->bw - offsety));
set_rect_size(
c->border[1], clip_box.width + c->bw,
GEZERO(c->bw - GEZERO(c->animation.current.y +
c->animation.current.height -
c->mon->m.y - c->mon->m.height)));
} else if (c->animation.current.y < c->mon->m.y) {
set_rect_size(c->border[0], clip_box.width,
GEZERO(c->bw - offsety));
} else if (c->animation.current.y + c->animation.current.height >
c->mon->m.y + c->mon->m.height) { c->mon->m.y + c->mon->m.height) {
set_rect_size( current_corner_location &= ~CORNER_LOCATION_BOTTOM; // 清除下标志位
c->border[1], clip_box.width,
GEZERO(c->bw - GEZERO(c->animation.current.y +
c->animation.current.height -
c->mon->m.y - c->mon->m.height)));
set_rect_size(c->border[2], GEZERO(c->bw - offsetx),
clip_box.height - c->bw);
set_rect_size(c->border[3],
GEZERO(c->bw - GEZERO(c->animation.current.x +
c->animation.current.width -
c->mon->m.x - c->mon->m.width)),
clip_box.height - c->bw);
} }
} return current_corner_location;
wlr_scene_node_set_position(&c->border[0]->node, offsetx, offsety);
wlr_scene_node_set_position(&c->border[2]->node, offsetx, c->bw + offsety);
wlr_scene_node_set_position(&c->border[1]->node, offsetx,
clip_box.height - c->bw + offsety);
wlr_scene_node_set_position(
&c->border[3]->node, clip_box.width - c->bw + offsetx, c->bw + offsety);
} }
struct uvec2 clip_to_hide(Client *c, struct wlr_box *clip_box) { struct uvec2 clip_to_hide(Client *c, struct wlr_box *clip_box) {
@@ -1218,8 +1283,7 @@ struct uvec2 clip_to_hide(Client *c, struct wlr_box *clip_box) {
clip_box->width = clip_box->width - offsetx; clip_box->width = clip_box->width - offsetx;
} else if (c->animation.current.x + c->animation.current.width > } else if (c->animation.current.x + c->animation.current.width >
c->mon->m.x + c->mon->m.width) { c->mon->m.x + c->mon->m.width) {
clip_box->width = clip_box->width = clip_box->width -
clip_box->width -
(c->animation.current.x + c->animation.current.width - (c->animation.current.x + c->animation.current.width -
c->mon->m.x - c->mon->m.width) + c->mon->m.x - c->mon->m.width) +
c->bw; c->bw;
@@ -1232,8 +1296,7 @@ struct uvec2 clip_to_hide(Client *c, struct wlr_box *clip_box) {
clip_box->height = clip_box->height - offsety; clip_box->height = clip_box->height - offsety;
} else if (c->animation.current.y + c->animation.current.height > } else if (c->animation.current.y + c->animation.current.height >
c->mon->m.y + c->mon->m.height) { c->mon->m.y + c->mon->m.height) {
clip_box->height = clip_box->height = clip_box->height -
clip_box->height -
(c->animation.current.y + c->animation.current.height - (c->animation.current.y + c->animation.current.height -
c->mon->m.y - c->mon->m.height) + c->mon->m.y - c->mon->m.height) +
c->bw; c->bw;
@@ -1270,6 +1333,8 @@ void client_apply_clip(Client *c) {
struct wlr_box clip_box; struct wlr_box clip_box;
struct uvec2 offset; struct uvec2 offset;
animationScale scale_data; animationScale scale_data;
struct wlr_box surface_clip;
enum corner_location current_corner_location = set_client_corner_location(c);
if (!animations) { if (!animations) {
c->animation.running = false; c->animation.running = false;
@@ -1277,14 +1342,22 @@ void client_apply_clip(Client *c) {
c->animainit_geom = c->current = c->pending = c->animation.current = c->animainit_geom = c->current = c->pending = c->animation.current =
c->geom; c->geom;
client_get_clip(c, &clip_box); client_get_clip(c, &clip_box);
offset = clip_to_hide(c, &clip_box); offset = clip_to_hide(c, &clip_box);
apply_border(c, clip_box, offset.x, offset.y);
if (clip_box.width <= 0 || clip_box.height <= 0) apply_border(c, clip_box, offset.x, offset.y, current_corner_location);
client_draw_shadow(c);
surface_clip = clip_box;
surface_clip.width = surface_clip.width - 2 * c->bw;
surface_clip.height = surface_clip.height - 2 * c->bw;
if(surface_clip.width <= 0 || surface_clip.height <= 0) {
return; return;
}
wlr_scene_subsurface_tree_set_clip(&c->scene_surface->node, &clip_box); wlr_scene_subsurface_tree_set_clip(&c->scene_surface->node, &surface_clip);
buffer_set_effect(c, (animationScale){0, 0, 0, 0, false}); buffer_set_effect(c, (animationScale){0, 0, 0, 0, current_corner_location,false});
return; return;
} }
@@ -1306,20 +1379,26 @@ void client_apply_clip(Client *c) {
} }
offset = clip_to_hide(c, &clip_box); offset = clip_to_hide(c, &clip_box);
apply_border(c, clip_box, offset.x, offset.y); apply_border(c, clip_box, offset.x, offset.y, current_corner_location);
client_draw_shadow(c);
if (clip_box.width <= 0 || clip_box.height <= 0) surface_clip = clip_box;
surface_clip.width = surface_clip.width - 2 * c->bw;
surface_clip.height = surface_clip.height - 2 * c->bw;
if(surface_clip.width <= 0 || surface_clip.height <= 0) {
return; return;
}
wlr_scene_subsurface_tree_set_clip(&c->scene_surface->node, &clip_box); wlr_scene_subsurface_tree_set_clip(&c->scene_surface->node, &surface_clip);
scale_data.should_scale = true; scale_data.should_scale = true;
scale_data.width = clip_box.width - 2 * c->bw; scale_data.width = clip_box.width - 2 * c->bw;
scale_data.height = clip_box.height - 2 * c->bw; scale_data.height = clip_box.height - 2 * c->bw;
scale_data.width_scale = scale_data.width_scale = (float)scale_data.width / (geometry.width - offset.x);
(float)scale_data.width / (geometry.width - offset.x); scale_data.height_scale = (float)scale_data.height / (geometry.height - offset.y);
scale_data.height_scale = scale_data.corner_location = current_corner_location;
(float)scale_data.height / (geometry.height - offset.y); scale_data.percent = c->is_open_animation && animation_fade_in ? (double)c->animation.passed_frames / c->animation.total_frames : 1.0;
scale_data.opacity = c->isfullscreen ? 1 : c == selmon->sel ? c->focused_opacity : c->unfocused_opacity;
buffer_set_effect(c, scale_data); buffer_set_effect(c, scale_data);
} }
@@ -1328,6 +1407,14 @@ bool client_draw_frame(Client *c) {
if (!c || !client_surface(c)->mapped) if (!c || !client_surface(c)->mapped)
return false; return false;
if (c->isfullscreen)
client_set_opacity(c, 1);
else if (c == selmon->sel && !c->animation.running) {
client_set_opacity(c, c->focused_opacity);
} else if (!c->animation.running) {
client_set_opacity(c, c->unfocused_opacity);
}
if (!c->need_output_flush) if (!c->need_output_flush)
return false; return false;
@@ -1335,6 +1422,7 @@ bool client_draw_frame(Client *c) {
client_animation_next_tick(c); client_animation_next_tick(c);
client_apply_clip(c); client_apply_clip(c);
} else { } else {
if (!c->is_clip_to_hide)
wlr_scene_node_set_position(&c->scene->node, c->pending.x, wlr_scene_node_set_position(&c->scene->node, c->pending.x,
c->pending.y); c->pending.y);
c->animainit_geom = c->animation.initial = c->pending = c->current = c->animainit_geom = c->animation.initial = c->pending = c->current =
@@ -1712,7 +1800,7 @@ void gpureset(struct wl_listener *listener, void *data) {
wlr_log(WLR_DEBUG, "gpu reset"); wlr_log(WLR_DEBUG, "gpu reset");
if (!(drw = wlr_renderer_autocreate(backend))) if (!(drw = fx_renderer_create(backend)))
die("couldn't recreate renderer"); die("couldn't recreate renderer");
if (!(alloc = wlr_allocator_autocreate(backend, drw))) if (!(alloc = wlr_allocator_autocreate(backend, drw)))
@@ -1914,6 +2002,11 @@ applyrules(Client *c) {
c->isglobal = r->isglobal >= 0 ? r->isglobal : c->isglobal; c->isglobal = r->isglobal >= 0 ? r->isglobal : c->isglobal;
c->isoverlay = r->isoverlay >= 0 ? r->isoverlay : c->isoverlay; c->isoverlay = r->isoverlay >= 0 ? r->isoverlay : c->isoverlay;
c->isunglobal = r->isunglobal >= 0 ? r->isunglobal : c->isunglobal; c->isunglobal = r->isunglobal >= 0 ? r->isunglobal : c->isunglobal;
c->focused_opacity = r->focused_opacity > 0 ? r->focused_opacity
: c->focused_opacity;
c->unfocused_opacity = r->unfocused_opacity > 0
? r->unfocused_opacity
: c->unfocused_opacity;
newtags = r->tags > 0 ? r->tags | newtags : newtags; newtags = r->tags > 0 ? r->tags | newtags : newtags;
i = 0; i = 0;
@@ -2958,6 +3051,10 @@ void cleanupmon(struct wl_listener *listener, void *data) {
wlr_scene_output_destroy(m->scene_output); wlr_scene_output_destroy(m->scene_output);
closemon(m); closemon(m);
if (m->blur) {
wlr_scene_node_destroy(&m->blur->node);
m->blur = NULL;
}
// wlr_scene_node_destroy(&m->fullscreen_bg->node); // wlr_scene_node_destroy(&m->fullscreen_bg->node);
free(m); free(m);
} }
@@ -3043,6 +3140,19 @@ void commitlayersurfacenotify(struct wl_listener *listener, void *data) {
} }
arrangelayers(l->mon); arrangelayers(l->mon);
if (blur) {
// Rerender the optimized blur on change
struct wlr_layer_surface_v1 *wlr_layer_surface = l->layer_surface;
if (wlr_layer_surface->current.layer ==
ZWLR_LAYER_SHELL_V1_LAYER_BACKGROUND ||
wlr_layer_surface->current.layer ==
ZWLR_LAYER_SHELL_V1_LAYER_BOTTOM) {
if (l->mon) {
wlr_scene_optimized_blur_mark_dirty(l->mon->blur);
}
}
}
} }
void client_set_pending_state(Client *c) { void client_set_pending_state(Client *c) {
@@ -3459,6 +3569,14 @@ void createmon(struct wl_listener *listener, void *data) {
wlr_output_layout_add_auto(output_layout, wlr_output); wlr_output_layout_add_auto(output_layout, wlr_output);
else else
wlr_output_layout_add(output_layout, wlr_output, m->m.x, m->m.y); wlr_output_layout_add(output_layout, wlr_output, m->m.x, m->m.y);
if (blur) {
m->blur = wlr_scene_optimized_blur_create(&scene->tree, 0, 0);
// wlr_scene_node_set_position(&m->blur->node, m->m.x, m->m.y);
wlr_scene_node_reparent(&m->blur->node, layers[LyrBlur]);
wlr_scene_optimized_blur_set_size(m->blur, m->m.width, m->m.height);
// wlr_scene_node_set_enabled(&m->blur->node, 1);
}
} }
void // fix for 0.5 void // fix for 0.5
@@ -4170,7 +4288,12 @@ void incovgaps(const Arg *arg) {
void requestmonstate(struct wl_listener *listener, void *data) { void requestmonstate(struct wl_listener *listener, void *data) {
struct wlr_output_event_request_state *event = data; struct wlr_output_event_request_state *event = data;
Monitor *m = wl_container_of(listener, m, frame);
wlr_output_commit_state(event->output, event->state); wlr_output_commit_state(event->output, event->state);
if (blur) {
wlr_scene_optimized_blur_set_size(m->blur, m->m.width, m->m.height);
}
updatemons(NULL, NULL); updatemons(NULL, NULL);
} }
@@ -4417,15 +4540,16 @@ static bool scene_node_snapshot(struct wlr_scene_node *node, int lx, int ly,
struct wlr_scene_node *snapshot_node = NULL; struct wlr_scene_node *snapshot_node = NULL;
switch (node->type) { switch (node->type) {
case WLR_SCENE_NODE_TREE:; case WLR_SCENE_NODE_TREE: {
struct wlr_scene_tree *scene_tree = wlr_scene_tree_from_node(node); struct wlr_scene_tree *scene_tree = wlr_scene_tree_from_node(node);
struct wlr_scene_node *child; struct wlr_scene_node *child;
wl_list_for_each(child, &scene_tree->children, link) { wl_list_for_each(child, &scene_tree->children, link) {
scene_node_snapshot(child, lx, ly, snapshot_tree); scene_node_snapshot(child, lx, ly, snapshot_tree);
} }
break; break;
case WLR_SCENE_NODE_RECT:; }
case WLR_SCENE_NODE_RECT: {
struct wlr_scene_rect *scene_rect = wlr_scene_rect_from_node(node); struct wlr_scene_rect *scene_rect = wlr_scene_rect_from_node(node);
struct wlr_scene_rect *snapshot_rect = struct wlr_scene_rect *snapshot_rect =
@@ -4435,10 +4559,20 @@ static bool scene_node_snapshot(struct wlr_scene_node *node, int lx, int ly,
if (snapshot_rect == NULL) { if (snapshot_rect == NULL) {
return false; return false;
} }
wlr_scene_rect_set_clipped_region(scene_rect,
snapshot_rect->clipped_region);
wlr_scene_rect_set_backdrop_blur(scene_rect, false);
// wlr_scene_rect_set_backdrop_blur_optimized(
// scene_rect, snapshot_rect->backdrop_blur_optimized);
wlr_scene_rect_set_corner_radius(
scene_rect, snapshot_rect->corner_radius, snapshot_rect->corners);
wlr_scene_rect_set_color(scene_rect, snapshot_rect->color);
snapshot_node = &snapshot_rect->node; snapshot_node = &snapshot_rect->node;
break; break;
case WLR_SCENE_NODE_BUFFER:; }
case WLR_SCENE_NODE_BUFFER: {
struct wlr_scene_buffer *scene_buffer = struct wlr_scene_buffer *scene_buffer =
wlr_scene_buffer_from_node(node); wlr_scene_buffer_from_node(node);
@@ -4463,6 +4597,15 @@ static bool scene_node_snapshot(struct wlr_scene_node *node, int lx, int ly,
// Effects // Effects
wlr_scene_buffer_set_opacity(snapshot_buffer, scene_buffer->opacity); wlr_scene_buffer_set_opacity(snapshot_buffer, scene_buffer->opacity);
wlr_scene_buffer_set_corner_radius(snapshot_buffer,
scene_buffer->corner_radius,
scene_buffer->corners);
// wlr_scene_buffer_set_backdrop_blur_optimized(
// snapshot_buffer, scene_buffer->backdrop_blur_optimized);
// wlr_scene_buffer_set_backdrop_blur_ignore_transparent(
// snapshot_buffer, scene_buffer->backdrop_blur_ignore_transparent);
wlr_scene_buffer_set_backdrop_blur(snapshot_buffer, false);
snapshot_buffer->node.data = scene_buffer->node.data; snapshot_buffer->node.data = scene_buffer->node.data;
@@ -4476,6 +4619,31 @@ static bool scene_node_snapshot(struct wlr_scene_node *node, int lx, int ly,
} }
break; break;
} }
case WLR_SCENE_NODE_SHADOW: {
struct wlr_scene_shadow *scene_shadow =
wlr_scene_shadow_from_node(node);
struct wlr_scene_shadow *snapshot_shadow = wlr_scene_shadow_create(
snapshot_tree, scene_shadow->width, scene_shadow->height,
scene_shadow->corner_radius, scene_shadow->blur_sigma,
scene_shadow->color);
if (snapshot_shadow == NULL) {
return false;
}
snapshot_node = &snapshot_shadow->node;
wlr_scene_shadow_set_clipped_region(snapshot_shadow,
scene_shadow->clipped_region);
snapshot_shadow->node.data = scene_shadow->node.data;
wlr_scene_node_set_enabled(&snapshot_shadow->node, false);
break;
}
case WLR_SCENE_NODE_OPTIMIZED_BLUR:
return true;
}
if (snapshot_node != NULL) { if (snapshot_node != NULL) {
wlr_scene_node_set_position(snapshot_node, lx, ly); wlr_scene_node_set_position(snapshot_node, lx, ly);
@@ -4541,12 +4709,33 @@ void locksession(struct wl_listener *listener, void *data) {
wlr_session_lock_v1_send_locked(session_lock); wlr_session_lock_v1_send_locked(session_lock);
} }
static void iter_xdg_scene_buffers(struct wlr_scene_buffer *buffer, int sx,
int sy, void *user_data) {
Client *c = user_data;
struct wlr_scene_surface * scene_surface = wlr_scene_surface_try_from_buffer(buffer);
if (!scene_surface) {
return;
}
struct wlr_surface *surface = scene_surface->surface;
/* we dont blur subsurfaces */
if(wlr_subsurface_try_from_wlr_surface(surface) != NULL) return;
if (blur && c) {
wlr_scene_buffer_set_backdrop_blur(buffer, true);
wlr_scene_buffer_set_backdrop_blur_optimized(buffer, true);
wlr_scene_buffer_set_backdrop_blur_ignore_transparent(buffer, true);
} else {
wlr_scene_buffer_set_backdrop_blur(buffer, false);
}
}
void // old fix to 0.5 void // old fix to 0.5
mapnotify(struct wl_listener *listener, void *data) { mapnotify(struct wl_listener *listener, void *data) {
/* Called when the surface is mapped, or ready to display on-screen. */ /* Called when the surface is mapped, or ready to display on-screen. */
Client *p = NULL; Client *p = NULL;
Client *c = wl_container_of(listener, c, map); Client *c = wl_container_of(listener, c, map);
int i;
/* Create scene tree for this client and its border */ /* Create scene tree for this client and its border */
c->scene = client_surface(c)->data = wlr_scene_tree_create(layers[LyrTile]); c->scene = client_surface(c)->data = wlr_scene_tree_create(layers[LyrTile]);
wlr_scene_node_set_enabled(&c->scene->node, c->type != XDGShell); wlr_scene_node_set_enabled(&c->scene->node, c->type != XDGShell);
@@ -4583,11 +4772,22 @@ mapnotify(struct wl_listener *listener, void *data) {
return; return;
} }
for (i = 0; i < 4; i++) { c->border = wlr_scene_rect_create(c->scene, 0, 0,
c->border[i] = wlr_scene_rect_create( c->isurgent ? urgentcolor : bordercolor);
c->scene, 0, 0, c->isurgent ? urgentcolor : bordercolor); wlr_scene_node_lower_to_bottom(&c->border->node);
c->border[i]->node.data = c; wlr_scene_node_set_position(&c->border->node, 0, 0);
} wlr_scene_rect_set_corner_radius(c->border, border_radius,
border_radius_location_default);
wlr_scene_node_set_enabled(&c->border->node, true);
c->shadow = wlr_scene_shadow_create(c->scene, 0, 0, border_radius,
shadows_blur, shadowscolor);
wlr_scene_node_lower_to_bottom(&c->shadow->node);
wlr_scene_node_set_enabled(&c->shadow->node, true);
wlr_scene_node_for_each_buffer(&c->scene_surface->node,
iter_xdg_scene_buffers, c);
/* Initialize client geometry with room for border */ /* Initialize client geometry with room for border */
client_set_tiled(c, WLR_EDGE_TOP | WLR_EDGE_BOTTOM | WLR_EDGE_LEFT | client_set_tiled(c, WLR_EDGE_TOP | WLR_EDGE_BOTTOM | WLR_EDGE_LEFT |
@@ -4614,6 +4814,8 @@ mapnotify(struct wl_listener *listener, void *data) {
c->is_open_animation = true; c->is_open_animation = true;
c->drag_to_tile = false; c->drag_to_tile = false;
c->fake_no_border = false; c->fake_no_border = false;
c->focused_opacity = focused_opacity;
c->unfocused_opacity = unfocused_opacity;
c->nofadein = 0; c->nofadein = 0;
c->nofadeout = 0; c->nofadeout = 0;
c->no_force_center = 0; c->no_force_center = 0;
@@ -5105,6 +5307,18 @@ void scene_buffer_apply_effect(struct wlr_scene_buffer *buffer, int sx, int sy,
} }
} }
// TODO: blur set, opacity set // TODO: blur set, opacity set
if (wlr_xdg_popup_try_from_wlr_surface(surface) != NULL)
return;
wlr_scene_buffer_set_corner_radius(buffer, border_radius,
scale_data->corner_location);
float target_opacity = scale_data->percent + fadein_begin_opacity;
if (target_opacity > scale_data->opacity) {
target_opacity = scale_data->opacity;
}
wlr_scene_buffer_set_opacity(buffer, target_opacity);
} }
void snap_scene_buffer_apply_effect(struct wlr_scene_buffer *buffer, int sx, void snap_scene_buffer_apply_effect(struct wlr_scene_buffer *buffer, int sx,
@@ -5138,18 +5352,6 @@ void client_set_opacity(Client *c, double opacity) {
scene_buffer_apply_opacity, &opacity); scene_buffer_apply_opacity, &opacity);
} }
void client_handle_opacity(Client *c) {
if (!c || !c->mon || !client_surface(c)->mapped)
return;
double opacity = c->isfullscreen || c->ismaxmizescreen ? 1.0
: c == selmon->sel ? 0.8
: 0.5;
wlr_scene_node_for_each_buffer(&c->scene_surface->node,
scene_buffer_apply_opacity, &opacity);
}
void rendermon(struct wl_listener *listener, void *data) { void rendermon(struct wl_listener *listener, void *data) {
Monitor *m = wl_container_of(listener, m, frame); Monitor *m = wl_container_of(listener, m, frame);
Client *c, *tmp; Client *c, *tmp;
@@ -5402,7 +5604,6 @@ void resize(Client *c, struct wlr_box geo, int interact) {
if (!c->is_open_animation) { if (!c->is_open_animation) {
c->animation.begin_fade_in = false; c->animation.begin_fade_in = false;
client_set_opacity(c, 1);
} }
if (c->animation.action == OPEN && !c->animation.tagining && if (c->animation.action == OPEN && !c->animation.tagining &&
@@ -5447,8 +5648,8 @@ void resize(Client *c, struct wlr_box geo, int interact) {
c->need_output_flush = false; c->need_output_flush = false;
c->animainit_geom = c->current = c->pending = c->animation.current = c->animainit_geom = c->current = c->pending = c->animation.current =
c->geom; c->geom;
wlr_scene_node_set_position(&c->scene->node, c->geom.x, c->geom.y); apply_border(c, c->geom, 0, 0, CORNER_LOCATION_ALL);
apply_border(c, c->geom, 0, 0); client_draw_shadow(c);
client_get_clip(c, &clip); client_get_clip(c, &clip);
wlr_scene_subsurface_tree_set_clip(&c->scene_surface->node, &clip); wlr_scene_subsurface_tree_set_clip(&c->scene_surface->node, &clip);
return; return;
@@ -6348,7 +6549,7 @@ void setup(void) {
wlr_scene_node_place_below(&drag_icon->node, &layers[LyrBlock]->node); wlr_scene_node_place_below(&drag_icon->node, &layers[LyrBlock]->node);
/* Create a renderer with the default implementation */ /* Create a renderer with the default implementation */
if (!(drw = wlr_renderer_autocreate(backend))) if (!(drw = fx_renderer_create(backend)))
die("couldn't create renderer"); die("couldn't create renderer");
wl_signal_add(&drw->events.lost, &gpu_reset); wl_signal_add(&drw->events.lost, &gpu_reset);
@@ -6539,6 +6740,9 @@ void setup(void) {
wl_signal_add(&output_mgr->events.apply, &output_mgr_apply); wl_signal_add(&output_mgr->events.apply, &output_mgr_apply);
wl_signal_add(&output_mgr->events.test, &output_mgr_test); wl_signal_add(&output_mgr->events.test, &output_mgr_test);
// blur
wlr_scene_set_blur_data(scene, blur_params);
/* create text_input-, and input_method-protocol relevant globals */ /* create text_input-, and input_method-protocol relevant globals */
input_method_manager = wlr_input_method_manager_v2_create(dpy); input_method_manager = wlr_input_method_manager_v2_create(dpy);
text_input_manager = wlr_text_input_manager_v3_create(dpy); text_input_manager = wlr_text_input_manager_v3_create(dpy);
@@ -7245,6 +7449,10 @@ void updatemons(struct wl_listener *listener, void *data) {
// wlr_scene_node_set_position(&m->fullscreen_bg->node, m->m.x, m->m.y); // wlr_scene_node_set_position(&m->fullscreen_bg->node, m->m.x, m->m.y);
// wlr_scene_rect_set_size(m->fullscreen_bg, m->m.width, m->m.height); // wlr_scene_rect_set_size(m->fullscreen_bg, m->m.width, m->m.height);
if (blur && m->blur) {
wlr_scene_optimized_blur_set_size(m->blur, m->m.width, m->m.height);
}
if (m->lock_surface) { if (m->lock_surface) {
struct wlr_scene_tree *scene_tree = m->lock_surface->surface->data; struct wlr_scene_tree *scene_tree = m->lock_surface->surface->data;
wlr_scene_node_set_position(&scene_tree->node, m->m.x, m->m.y); wlr_scene_node_set_position(&scene_tree->node, m->m.x, m->m.y);