mirror of
https://github.com/DreamMaoMao/maomaowm.git
synced 2026-05-20 21:38:15 -04:00
feat: add wlr_scene_blur support and fix wlroots 0.20 API compatibility
- Implement blur effect using `wlr_scene_blur` for both clients and layer surfaces - Add blur node creation and sizing in client/layer mapping and resize handlers - Fix XWayland cursor initialization for wlroots 0.20 (use `wlr_xcursor_image_get_buffer`) - Replace `wlr_scene_buffer` backdrop blur calls with `wlr_scene_blur_set_transparency_mask_source`
This commit is contained in:
parent
ec71fa8481
commit
0a8f92959d
3 changed files with 55 additions and 31 deletions
|
|
@ -995,6 +995,12 @@ void resize(Client *c, struct wlr_box geo, int32_t interact) {
|
||||||
c->fake_no_border = true;
|
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->geom 是真实的窗口大小和位置,跟过度的动画无关,用于计算布局
|
||||||
c->configure_serial = client_set_size(c, c->geom.width - 2 * c->bw,
|
c->configure_serial = client_set_size(c, c->geom.width - 2 * c->bw,
|
||||||
c->geom.height - 2 * c->bw);
|
c->geom.height - 2 * c->bw);
|
||||||
|
|
|
||||||
|
|
@ -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,
|
wlr_scene_buffer_set_corner_radii(snapshot_buffer,
|
||||||
scene_buffer->corners);
|
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;
|
snapshot_buffer->node.data = scene_buffer->node.data;
|
||||||
|
|
||||||
struct wlr_scene_surface *scene_surface =
|
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:
|
case WLR_SCENE_NODE_OPTIMIZED_BLUR:
|
||||||
return true;
|
return true;
|
||||||
|
case WLR_SCENE_NODE_BLUR:
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (snapshot_node != NULL) {
|
if (snapshot_node != NULL) {
|
||||||
|
|
@ -259,4 +254,4 @@ void request_fresh_all_monitors(void) {
|
||||||
}
|
}
|
||||||
wlr_output_schedule_frame(m->wlr_output);
|
wlr_output_schedule_frame(m->wlr_output);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
69
src/mango.c
69
src/mango.c
|
|
@ -92,6 +92,7 @@
|
||||||
#include <wlr/xwayland.h>
|
#include <wlr/xwayland.h>
|
||||||
#include <xcb/xcb_icccm.h>
|
#include <xcb/xcb_icccm.h>
|
||||||
#endif
|
#endif
|
||||||
|
#include "common/xdg-shell-protocol.h"
|
||||||
#include "common/util.h"
|
#include "common/util.h"
|
||||||
|
|
||||||
/* macros */
|
/* macros */
|
||||||
|
|
@ -315,6 +316,7 @@ struct Client {
|
||||||
struct wlr_scene_tree *scene;
|
struct wlr_scene_tree *scene;
|
||||||
struct wlr_scene_rect *border; /* top, bottom, left, right */
|
struct wlr_scene_rect *border; /* top, bottom, left, right */
|
||||||
struct wlr_scene_shadow *shadow;
|
struct wlr_scene_shadow *shadow;
|
||||||
|
struct wlr_scene_blur *blur;
|
||||||
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;
|
||||||
|
|
@ -465,6 +467,7 @@ typedef struct {
|
||||||
struct wlr_scene_tree *scene;
|
struct wlr_scene_tree *scene;
|
||||||
struct wlr_scene_tree *popups;
|
struct wlr_scene_tree *popups;
|
||||||
struct wlr_scene_shadow *shadow;
|
struct wlr_scene_shadow *shadow;
|
||||||
|
struct wlr_scene_blur *blur;
|
||||||
struct wlr_scene_layer_surface_v1 *scene_layer;
|
struct wlr_scene_layer_surface_v1 *scene_layer;
|
||||||
struct wl_list link;
|
struct wl_list link;
|
||||||
struct wl_list fadeout_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,
|
static void iter_layer_scene_buffers(struct wlr_scene_buffer *buffer,
|
||||||
int32_t sx, int32_t sy, void *user_data) {
|
int32_t sx, int32_t sy, void *user_data) {
|
||||||
|
LayerSurface *l = user_data;
|
||||||
|
|
||||||
struct wlr_scene_surface *scene_surface =
|
struct wlr_scene_surface *scene_surface =
|
||||||
wlr_scene_surface_try_from_buffer(buffer);
|
wlr_scene_surface_try_from_buffer(buffer);
|
||||||
if (!scene_surface) {
|
if (!scene_surface) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Blur functions removed in scenefx 0.5
|
struct wlr_surface *surface = scene_surface->surface;
|
||||||
// wlr_scene_buffer_set_backdrop_blur(buffer, true);
|
if (wlr_subsurface_try_from_wlr_surface(surface) != NULL)
|
||||||
// wlr_scene_buffer_set_backdrop_blur_ignore_transparent(buffer, true);
|
return;
|
||||||
// if (config.blur_optimized) {
|
|
||||||
// wlr_scene_buffer_set_backdrop_blur_optimized(buffer, true);
|
if (config.blur && l && !l->noblur) {
|
||||||
// } else {
|
wlr_scene_blur_set_transparency_mask_source(l->blur, buffer);
|
||||||
// wlr_scene_buffer_set_backdrop_blur_optimized(buffer, false);
|
}
|
||||||
// }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void layer_flush_blur_background(LayerSurface *l) {
|
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);
|
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) {
|
if (config.animations && config.layer_animations && !l->noanim) {
|
||||||
l->animation.duration = config.animation_duration_open;
|
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->animation.duration = config.animation_duration_move;
|
||||||
l->need_output_flush = true;
|
l->need_output_flush = true;
|
||||||
layer_set_pending_state(l);
|
layer_set_pending_state(l);
|
||||||
|
} else {
|
||||||
|
l->geom = box;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (config.blur && config.blur_layer) {
|
if (config.blur && config.blur_layer) {
|
||||||
|
|
@ -2544,6 +2559,9 @@ void commitlayersurfacenotify(struct wl_listener *listener, void *data) {
|
||||||
layer_surface->current.layer !=
|
layer_surface->current.layer !=
|
||||||
ZWLR_LAYER_SHELL_V1_LAYER_BACKGROUND) {
|
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,
|
wlr_scene_node_for_each_buffer(&l->scene->node,
|
||||||
iter_layer_scene_buffers, l);
|
iter_layer_scene_buffers, l);
|
||||||
}
|
}
|
||||||
|
|
@ -4020,16 +4038,7 @@ static void iter_xdg_scene_buffers(struct wlr_scene_buffer *buffer, int32_t sx,
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (config.blur && c && !c->noblur) {
|
if (config.blur && c && !c->noblur) {
|
||||||
// Blur functions removed in scenefx 0.5
|
wlr_scene_blur_set_transparency_mask_source(c->blur, buffer);
|
||||||
// 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);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -4133,6 +4142,13 @@ mapnotify(struct wl_listener *listener, void *data) {
|
||||||
: wlr_scene_subsurface_tree_create(c->scene, client_surface(c));
|
: wlr_scene_subsurface_tree_create(c->scene, client_surface(c));
|
||||||
c->scene->node.data = c->scene_surface->node.data = 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);
|
client_get_geometry(c, &c->geom);
|
||||||
|
|
||||||
if (client_is_x11(c))
|
if (client_is_x11(c))
|
||||||
|
|
@ -4222,6 +4238,9 @@ mapnotify(struct wl_listener *listener, void *data) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// apply buffer effects of client
|
// 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,
|
wlr_scene_node_for_each_buffer(&c->scene_surface->node,
|
||||||
iter_xdg_scene_buffers, c);
|
iter_xdg_scene_buffers, c);
|
||||||
|
|
||||||
|
|
@ -5599,6 +5618,7 @@ void setup(void) {
|
||||||
wlr_ext_image_copy_capture_manager_v1_create(dpy, 1);
|
wlr_ext_image_copy_capture_manager_v1_create(dpy, 1);
|
||||||
wlr_ext_output_image_capture_source_manager_v1_create(dpy, 1);
|
wlr_ext_output_image_capture_source_manager_v1_create(dpy, 1);
|
||||||
wlr_data_control_manager_v1_create(dpy);
|
wlr_data_control_manager_v1_create(dpy);
|
||||||
|
wlr_ext_data_control_manager_v1_create(dpy, 1);
|
||||||
wlr_data_device_manager_create(dpy);
|
wlr_data_device_manager_create(dpy);
|
||||||
wlr_primary_selection_v1_device_manager_create(dpy);
|
wlr_primary_selection_v1_device_manager_create(dpy);
|
||||||
wlr_viewporter_create(dpy);
|
wlr_viewporter_create(dpy);
|
||||||
|
|
@ -6026,6 +6046,10 @@ void unmaplayersurfacenotify(struct wl_listener *listener, void *data) {
|
||||||
layer_flush_blur_background(l);
|
layer_flush_blur_background(l);
|
||||||
wlr_scene_node_destroy(&l->shadow->node);
|
wlr_scene_node_destroy(&l->shadow->node);
|
||||||
l->shadow = NULL;
|
l->shadow = NULL;
|
||||||
|
if (l->blur) {
|
||||||
|
wlr_scene_node_destroy(&l->blur->node);
|
||||||
|
l->blur = NULL;
|
||||||
|
}
|
||||||
l->being_unmapped = false;
|
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. */
|
/* Set the default XWayland cursor to match the rest of dwl. */
|
||||||
/* XWayland cursor API changed in wlroots 0.20.0 - needs wlr_buffer instead
|
/* XWayland cursor API changed in wlroots 0.20.0 - needs wlr_buffer instead
|
||||||
* of raw pixels */
|
* of raw pixels */
|
||||||
/* if ((xcursor = wlr_xcursor_manager_get_xcursor(cursor_mgr, "default",
|
if ((xcursor = wlr_xcursor_manager_get_xcursor(cursor_mgr, "default", 1)))
|
||||||
1))) wlr_xwayland_set_cursor( xwayland, xcursor->images[0]->buffer,
|
wlr_xwayland_set_cursor(
|
||||||
xcursor->images[0]->width * 4, xcursor->images[0]->width,
|
xwayland, wlr_xcursor_image_get_buffer(xcursor->images[0]),
|
||||||
xcursor->images[0]->height, xcursor->images[0]->hotspot_x,
|
xcursor->images[0]->hotspot_x, xcursor->images[0]->hotspot_y);
|
||||||
xcursor->images[0]->hotspot_y); */
|
|
||||||
/* xwayland can't auto sync the keymap, so we do it manually
|
/* xwayland can't auto sync the keymap, so we do it manually
|
||||||
and we need to wait the xwayland completely inited
|
and we need to wait the xwayland completely inited
|
||||||
*/
|
*/
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue