feat: add blur_lockscreen option to apply blur to lock surfaces

Adds a new `blur_lockscreen` config option (default: 1) that, when
enabled alongside the existing `blur` option, applies scenefx blur
to wlr-session-lock surfaces on each commit.

Implementation adds:
- `commit_lock_surface` listener and `lock_scene_tree` pointer to
  the Monitor struct
- `commitlocksurface` handler that calls iter_layer_scene_buffers
  on the lock scene tree
- Cleanup of both fields in destroylocksurface
This commit is contained in:
StaszeKrk 2026-05-05 17:18:11 +02:00
parent ef7a1c61e5
commit a582db1f0b
2 changed files with 20 additions and 0 deletions

View file

@ -372,6 +372,7 @@ typedef struct {
int32_t allow_tearing;
int32_t allow_shortcuts_inhibit;
int32_t allow_lock_transparent;
int32_t blur_lockscreen;
struct xkb_rule_names xkb_rules;
char xkb_rules_rules[128];
@ -1434,6 +1435,8 @@ bool parse_option(Config *config, char *key, char *value) {
config->allow_shortcuts_inhibit = atoi(value);
} else if (strcmp(key, "allow_lock_transparent") == 0) {
config->allow_lock_transparent = atoi(value);
} else if (strcmp(key, "blur_lockscreen") == 0) {
config->blur_lockscreen = atoi(value);
} else if (strcmp(key, "no_border_when_single") == 0) {
config->no_border_when_single = atoi(value);
} else if (strcmp(key, "no_radius_when_single") == 0) {
@ -3182,6 +3185,7 @@ void override_config(void) {
CLAMP_INT(config.allow_shortcuts_inhibit, 0, 1);
config.allow_lock_transparent =
CLAMP_INT(config.allow_lock_transparent, 0, 1);
config.blur_lockscreen = CLAMP_INT(config.blur_lockscreen, 0, 1);
config.axis_bind_apply_timeout =
CLAMP_INT(config.axis_bind_apply_timeout, 0, 1000);
config.focus_on_activate = CLAMP_INT(config.focus_on_activate, 0, 1);
@ -3342,6 +3346,7 @@ void set_value_default() {
config.allow_tearing = TEARING_DISABLED;
config.allow_shortcuts_inhibit = SHORTCUTS_INHIBIT_ENABLE;
config.allow_lock_transparent = 0;
config.blur_lockscreen = 1;
config.no_border_when_single = 0;
config.no_radius_when_single = 0;
config.snap_distance = 30;

View file

@ -510,7 +510,9 @@ struct Monitor {
struct wl_listener destroy;
struct wl_listener request_state;
struct wl_listener destroy_lock_surface;
struct wl_listener commit_lock_surface;
struct wlr_session_lock_surface_v1 *lock_surface;
struct wlr_scene_tree *lock_scene_tree;
struct wl_event_source *skip_frame_timeout;
struct wlr_box m; /* monitor area, layout-relative */
struct wlr_box w; /* window area, layout-relative */
@ -2912,6 +2914,14 @@ void createlayersurface(struct wl_listener *listener, void *data) {
wlr_surface_send_enter(surface, layer_surface->output);
}
void commitlocksurface(struct wl_listener *listener, void *data) {
Monitor *m = wl_container_of(listener, m, commit_lock_surface);
if (!m->lock_scene_tree || !config.blur || !config.blur_lockscreen)
return;
wlr_scene_node_for_each_buffer(&m->lock_scene_tree->node,
iter_layer_scene_buffers, NULL);
}
void createlocksurface(struct wl_listener *listener, void *data) {
SessionLock *lock = wl_container_of(listener, lock, new_surface);
struct wlr_session_lock_surface_v1 *lock_surface = data;
@ -2919,11 +2929,14 @@ void createlocksurface(struct wl_listener *listener, void *data) {
struct wlr_scene_tree *scene_tree = lock_surface->surface->data =
wlr_scene_subsurface_tree_create(lock->scene, lock_surface->surface);
m->lock_surface = lock_surface;
m->lock_scene_tree = scene_tree;
wlr_scene_node_set_position(&scene_tree->node, m->m.x, m->m.y);
wlr_session_lock_surface_v1_configure(lock_surface, m->m.width,
m->m.height);
LISTEN(&lock_surface->surface->events.commit, &m->commit_lock_surface,
commitlocksurface);
LISTEN(&lock_surface->events.destroy, &m->destroy_lock_surface,
destroylocksurface);
@ -3447,6 +3460,8 @@ void destroylocksurface(struct wl_listener *listener, void *data) {
*lock_surface = m->lock_surface;
m->lock_surface = NULL;
m->lock_scene_tree = NULL;
wl_list_remove(&m->commit_lock_surface.link);
wl_list_remove(&m->destroy_lock_surface.link);
if (lock_surface->surface != seat->keyboard_state.focused_surface) {