From a582db1f0bf1015d3079b8879f8cd2fef905e620 Mon Sep 17 00:00:00 2001 From: StaszeKrk Date: Tue, 5 May 2026 17:18:11 +0200 Subject: [PATCH] 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 --- src/config/parse_config.h | 5 +++++ src/mango.c | 15 +++++++++++++++ 2 files changed, 20 insertions(+) diff --git a/src/config/parse_config.h b/src/config/parse_config.h index b16cf476..5f64ed2e 100644 --- a/src/config/parse_config.h +++ b/src/config/parse_config.h @@ -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; diff --git a/src/mango.c b/src/mango.c index 2a946ebe..9c154eec 100644 --- a/src/mango.c +++ b/src/mango.c @@ -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) {