diff --git a/src/animation/client.h b/src/animation/client.h index af20b3ef..0e056e2b 100644 --- a/src/animation/client.h +++ b/src/animation/client.h @@ -995,6 +995,12 @@ void resize(Client *c, struct wlr_box geo, int32_t interact) { c->fake_no_border = true; } + if (config.blur && c->blur && !c->noblur) { + wlr_scene_blur_set_size(c->blur, + c->geom.width - 2 * c->bw, + c->geom.height - 2 * c->bw); + } + // c->geom 是真实的窗口大小和位置,跟过度的动画无关,用于计算布局 c->configure_serial = client_set_size(c, c->geom.width - 2 * c->bw, c->geom.height - 2 * c->bw); diff --git a/src/animation/common.h b/src/animation/common.h index 4b8f215f..3e8a520d 100644 --- a/src/animation/common.h +++ b/src/animation/common.h @@ -178,13 +178,6 @@ static bool scene_node_snapshot(struct wlr_scene_node *node, int32_t lx, wlr_scene_buffer_set_corner_radii(snapshot_buffer, scene_buffer->corners); - // Blur functions removed in scenefx 0.5 - // 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; struct wlr_scene_surface *scene_surface = @@ -221,6 +214,8 @@ static bool scene_node_snapshot(struct wlr_scene_node *node, int32_t lx, } case WLR_SCENE_NODE_OPTIMIZED_BLUR: return true; + case WLR_SCENE_NODE_BLUR: + return true; } if (snapshot_node != NULL) { @@ -259,4 +254,4 @@ void request_fresh_all_monitors(void) { } wlr_output_schedule_frame(m->wlr_output); } -} \ No newline at end of file +} diff --git a/src/mango.c b/src/mango.c index f050eedd..3544048e 100644 --- a/src/mango.c +++ b/src/mango.c @@ -92,6 +92,7 @@ #include #include #endif +#include "common/xdg-shell-protocol.h" #include "common/util.h" /* macros */ @@ -315,6 +316,7 @@ struct Client { struct wlr_scene_tree *scene; struct wlr_scene_rect *border; /* top, bottom, left, right */ struct wlr_scene_shadow *shadow; + struct wlr_scene_blur *blur; struct wlr_scene_tree *scene_surface; struct wl_list link; struct wl_list flink; @@ -465,6 +467,7 @@ typedef struct { struct wlr_scene_tree *scene; struct wlr_scene_tree *popups; struct wlr_scene_shadow *shadow; + struct wlr_scene_blur *blur; struct wlr_scene_layer_surface_v1 *scene_layer; struct wl_list link; struct wl_list fadeout_link; @@ -2393,20 +2396,21 @@ void closemon(Monitor *m) { static void iter_layer_scene_buffers(struct wlr_scene_buffer *buffer, int32_t sx, int32_t sy, void *user_data) { + LayerSurface *l = user_data; + struct wlr_scene_surface *scene_surface = wlr_scene_surface_try_from_buffer(buffer); if (!scene_surface) { return; } - // Blur functions removed in scenefx 0.5 - // wlr_scene_buffer_set_backdrop_blur(buffer, true); - // wlr_scene_buffer_set_backdrop_blur_ignore_transparent(buffer, true); - // if (config.blur_optimized) { - // wlr_scene_buffer_set_backdrop_blur_optimized(buffer, true); - // } else { - // wlr_scene_buffer_set_backdrop_blur_optimized(buffer, false); - // } + struct wlr_surface *surface = scene_surface->surface; + if (wlr_subsurface_try_from_wlr_surface(surface) != NULL) + return; + + if (config.blur && l && !l->noblur) { + wlr_scene_blur_set_transparency_mask_source(l->blur, buffer); + } } void layer_flush_blur_background(LayerSurface *l) { @@ -2473,6 +2477,15 @@ void maplayersurfacenotify(struct wl_listener *listener, void *data) { wlr_scene_node_set_enabled(&l->shadow->node, true); } + if (config.blur && config.blur_layer && + layer_surface->current.layer != ZWLR_LAYER_SHELL_V1_LAYER_BOTTOM && + layer_surface->current.layer != ZWLR_LAYER_SHELL_V1_LAYER_BACKGROUND) { + l->blur = wlr_scene_blur_create(l->scene, 0, 0); + wlr_scene_blur_set_should_only_blur_bottom_layer(l->blur, + config.blur_optimized); + wlr_scene_node_lower_to_bottom(&l->blur->node); + } + // 初始化动画 if (config.animations && config.layer_animations && !l->noanim) { l->animation.duration = config.animation_duration_open; @@ -2535,6 +2548,8 @@ void commitlayersurfacenotify(struct wl_listener *listener, void *data) { l->animation.duration = config.animation_duration_move; l->need_output_flush = true; layer_set_pending_state(l); + } else { + l->geom = box; } if (config.blur && config.blur_layer) { @@ -2544,6 +2559,9 @@ void commitlayersurfacenotify(struct wl_listener *listener, void *data) { layer_surface->current.layer != ZWLR_LAYER_SHELL_V1_LAYER_BACKGROUND) { + if (l->blur) { + wlr_scene_blur_set_size(l->blur, l->geom.width, l->geom.height); + } wlr_scene_node_for_each_buffer(&l->scene->node, iter_layer_scene_buffers, l); } @@ -4020,16 +4038,7 @@ static void iter_xdg_scene_buffers(struct wlr_scene_buffer *buffer, int32_t sx, return; if (config.blur && c && !c->noblur) { - // Blur functions removed in scenefx 0.5 - // wlr_scene_buffer_set_backdrop_blur(buffer, true); - // wlr_scene_buffer_set_backdrop_blur_ignore_transparent(buffer, false); - // if (config.blur_optimized) { - // wlr_scene_buffer_set_backdrop_blur_optimized(buffer, true); - // } else { - // wlr_scene_buffer_set_backdrop_blur_optimized(buffer, false); - // } - } else { - // wlr_scene_buffer_set_backdrop_blur(buffer, false); + wlr_scene_blur_set_transparency_mask_source(c->blur, buffer); } } @@ -4133,6 +4142,13 @@ mapnotify(struct wl_listener *listener, void *data) { : wlr_scene_subsurface_tree_create(c->scene, client_surface(c)); c->scene->node.data = c->scene_surface->node.data = c; + if (config.blur) { + c->blur = wlr_scene_blur_create(c->scene, 0, 0); + wlr_scene_blur_set_should_only_blur_bottom_layer(c->blur, + config.blur_optimized); + wlr_scene_node_lower_to_bottom(&c->blur->node); + } + client_get_geometry(c, &c->geom); if (client_is_x11(c)) @@ -4222,6 +4238,9 @@ mapnotify(struct wl_listener *listener, void *data) { } // apply buffer effects of client + if (config.blur && c && !c->noblur && c->blur) { + wlr_scene_blur_set_size(c->blur, c->geom.width, c->geom.height); + } wlr_scene_node_for_each_buffer(&c->scene_surface->node, iter_xdg_scene_buffers, c); @@ -5599,6 +5618,7 @@ void setup(void) { wlr_ext_image_copy_capture_manager_v1_create(dpy, 1); wlr_ext_output_image_capture_source_manager_v1_create(dpy, 1); wlr_data_control_manager_v1_create(dpy); + wlr_ext_data_control_manager_v1_create(dpy, 1); wlr_data_device_manager_create(dpy); wlr_primary_selection_v1_device_manager_create(dpy); wlr_viewporter_create(dpy); @@ -6026,6 +6046,10 @@ void unmaplayersurfacenotify(struct wl_listener *listener, void *data) { layer_flush_blur_background(l); wlr_scene_node_destroy(&l->shadow->node); l->shadow = NULL; + if (l->blur) { + wlr_scene_node_destroy(&l->blur->node); + l->blur = NULL; + } l->being_unmapped = false; } @@ -6630,11 +6654,10 @@ void xwaylandready(struct wl_listener *listener, void *data) { /* Set the default XWayland cursor to match the rest of dwl. */ /* XWayland cursor API changed in wlroots 0.20.0 - needs wlr_buffer instead * of raw pixels */ - /* if ((xcursor = wlr_xcursor_manager_get_xcursor(cursor_mgr, "default", - 1))) wlr_xwayland_set_cursor( xwayland, xcursor->images[0]->buffer, - xcursor->images[0]->width * 4, xcursor->images[0]->width, - xcursor->images[0]->height, xcursor->images[0]->hotspot_x, - xcursor->images[0]->hotspot_y); */ + if ((xcursor = wlr_xcursor_manager_get_xcursor(cursor_mgr, "default", 1))) + wlr_xwayland_set_cursor( + xwayland, wlr_xcursor_image_get_buffer(xcursor->images[0]), + xcursor->images[0]->hotspot_x, xcursor->images[0]->hotspot_y); /* xwayland can't auto sync the keymap, so we do it manually and we need to wait the xwayland completely inited */