This commit is contained in:
Reza 2026-05-09 07:00:41 +02:00 committed by GitHub
commit e5187e3528
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
7 changed files with 103 additions and 66 deletions

View file

@ -33,12 +33,12 @@ libm = cc.find_library('m')
xcb = dependency('xcb', required : get_option('xwayland'))
xlibs = dependency('xcb-icccm', required : get_option('xwayland'))
wayland_server_dep = dependency('wayland-server',version: '>=1.23.1')
wlroots_dep = dependency('wlroots-0.19',version: '>=0.19.0')
wlroots_dep = dependency('wlroots-0.20',version: '>=0.20.0')
xkbcommon_dep = dependency('xkbcommon')
libinput_dep = dependency('libinput',version: '>=1.27.1')
libwayland_client_dep = dependency('wayland-client')
pcre2_dep = dependency('libpcre2-8')
libscenefx_dep = dependency('scenefx-0.4',version: '>=0.4.1')
libscenefx_dep = dependency('scenefx-0.5',version: '>=0.5.0')
# 获取版本信息

View file

@ -1,3 +1,5 @@
#include <scenefx/types/fx/clipped_region.h>
void client_actual_size(Client *c, int32_t *width, int32_t *height) {
*width = c->animation.current.width - 2 * (int32_t)c->bw;
@ -8,25 +10,38 @@ void set_rect_size(struct wlr_scene_rect *rect, int32_t width, int32_t height) {
wlr_scene_rect_set_size(rect, GEZERO(width), GEZERO(height));
}
enum corner_location set_client_corner_location(Client *c) {
enum corner_location current_corner_location = CORNER_LOCATION_ALL;
struct fx_corner_radii set_client_corner_radii(Client *c) {
struct fx_corner_radii corners = corner_radii_all(config.border_radius);
struct wlr_box target_geom =
config.animations ? c->animation.current : c->geom;
// If window is touching left edge, disable left corners
if (target_geom.x + config.border_radius <= c->mon->m.x) {
current_corner_location &= ~CORNER_LOCATION_LEFT;
corners.top_left = 0;
corners.bottom_left = 0;
}
// If window is touching right edge, disable right corners
if (target_geom.x + target_geom.width - config.border_radius >=
c->mon->m.x + c->mon->m.width) {
current_corner_location &= ~CORNER_LOCATION_RIGHT;
corners.top_right = 0;
corners.bottom_right = 0;
}
// If window is touching top edge, disable top corners
if (target_geom.y + config.border_radius <= c->mon->m.y) {
current_corner_location &= ~CORNER_LOCATION_TOP;
corners.top_left = 0;
corners.top_right = 0;
}
// If window is touching bottom edge, disable bottom corners
if (target_geom.y + target_geom.height - config.border_radius >=
c->mon->m.y + c->mon->m.height) {
current_corner_location &= ~CORNER_LOCATION_BOTTOM;
corners.bottom_left = 0;
corners.bottom_right = 0;
}
return current_corner_location;
return corners;
}
bool is_horizontal_stack_layout(Monitor *m) {
@ -226,8 +241,7 @@ void scene_buffer_apply_effect(struct wlr_scene_buffer *buffer, int32_t sx,
if (wlr_xdg_popup_try_from_wlr_surface(surface) != NULL)
return;
wlr_scene_buffer_set_corner_radius(buffer, config.border_radius,
buffer_data->corner_location);
wlr_scene_buffer_set_corner_radii(buffer, buffer_data->corner_radii);
}
void buffer_set_effect(Client *c, BufferData data) {
@ -246,7 +260,7 @@ void buffer_set_effect(Client *c, BufferData data) {
if (c->isnoradius || c->isfullscreen ||
(config.no_radius_when_single && c->mon &&
c->mon->visible_tiling_clients == 1)) {
data.corner_location = CORNER_LOCATION_NONE;
data.corner_radii = corner_radii_none();
}
wlr_scene_node_for_each_buffer(&c->scene_surface->node,
@ -268,11 +282,11 @@ void client_draw_shadow(Client *c) {
}
bool hit_no_border = check_hit_no_border(c);
enum corner_location current_corner_location =
struct fx_corner_radii current_corner_radii =
c->isfullscreen || (config.no_radius_when_single && c->mon &&
c->mon->visible_tiling_clients == 1)
? CORNER_LOCATION_NONE
: CORNER_LOCATION_ALL;
? corner_radii_none()
: corner_radii_all(config.border_radius);
int32_t bwoffset = c->bw != 0 && hit_no_border ? (int32_t)c->bw : 0;
@ -302,8 +316,7 @@ void client_draw_shadow(Client *c) {
struct clipped_region clipped_region = {
.area = intersection_box,
.corner_radius = config.border_radius,
.corners = current_corner_location,
.corners = current_corner_radii,
};
struct wlr_box absolute_shadow_box = {
@ -355,12 +368,12 @@ void apply_border(Client *c) {
return;
bool hit_no_border = check_hit_no_border(c);
enum corner_location current_corner_location;
struct fx_corner_radii current_corner_radii;
if (c->isfullscreen || (config.no_radius_when_single && c->mon &&
c->mon->visible_tiling_clients == 1)) {
current_corner_location = CORNER_LOCATION_NONE;
current_corner_radii = corner_radii_none();
} else {
current_corner_location = set_client_corner_location(c);
current_corner_radii = set_client_corner_radii(c);
}
if (hit_no_border && config.smartgaps) {
@ -434,15 +447,13 @@ void apply_border(Client *c) {
struct clipped_region clipped_region = {
.area = {inner_surface_x, inner_surface_y, inner_surface_width,
inner_surface_height},
.corner_radius = config.border_radius,
.corners = current_corner_location,
.corners = current_corner_radii,
};
wlr_scene_node_set_position(&c->scene_surface->node, c->bw, c->bw);
wlr_scene_rect_set_size(c->border, rect_width, rect_height);
wlr_scene_node_set_position(&c->border->node, rect_x, rect_y);
wlr_scene_rect_set_corner_radius(c->border, config.border_radius,
current_corner_location);
wlr_scene_rect_set_corner_radius(c->border, config.border_radius);
wlr_scene_rect_set_clipped_region(c->border, clipped_region);
}
@ -602,8 +613,7 @@ void client_apply_clip(Client *c, float factor) {
struct ivec2 offset;
BufferData buffer_data;
enum corner_location current_corner_location =
set_client_corner_location(c);
struct fx_corner_radii current_corner_radii = set_client_corner_radii(c);
if (!config.animations) {
c->animation.running = false;
@ -624,8 +634,8 @@ void client_apply_clip(Client *c, float factor) {
wlr_scene_subsurface_tree_set_clip(&c->scene_surface->node, &clip_box);
buffer_set_effect(c, (BufferData){1.0f, 1.0f, clip_box.width,
clip_box.height,
current_corner_location, true});
clip_box.height, current_corner_radii,
true});
return;
}
@ -682,7 +692,7 @@ void client_apply_clip(Client *c, float factor) {
buffer_data.should_scale = true;
buffer_data.width = clip_box.width;
buffer_data.height = clip_box.height;
buffer_data.corner_location = current_corner_location;
buffer_data.corner_radii = current_corner_radii;
if (factor == 1.0) {
buffer_data.width_scale = 1.0;
@ -1067,6 +1077,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);

View file

@ -175,15 +175,8 @@ static bool scene_node_snapshot(struct wlr_scene_node *node, int32_t lx,
// Effects
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);
wlr_scene_buffer_set_corner_radii(snapshot_buffer,
scene_buffer->corners);
snapshot_buffer->node.data = scene_buffer->node.data;
@ -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);
}
}
}

View file

@ -187,8 +187,7 @@ void layer_draw_shadow(LayerSurface *l) {
struct clipped_region clipped_region = {
.area = intersection_box,
.corner_radius = config.border_radius,
.corners = config.border_radius_location_default,
.corners = corner_radii_all(config.border_radius),
};
wlr_scene_node_set_position(&l->shadow->node, shadow_box.x, shadow_box.y);

View file

@ -3404,7 +3404,8 @@ void set_value_default() {
config.blur_layer = 0;
config.blur_optimized = 1;
config.border_radius = 0;
config.border_radius_location_default = CORNER_LOCATION_ALL;
config.border_radius_location_default =
0; // CORNER_LOCATION_ALL no longer exists
config.blur_params.num_passes = 1;
config.blur_params.radius = 5;
config.blur_params.noise = 0.02f;

View file

@ -562,11 +562,11 @@ struct dwl_input_method_relay *dwl_im_relay_create() {
relay->popup_tree = wlr_scene_tree_create(&scene->tree);
relay->new_text_input.notify = handle_new_text_input;
wl_signal_add(&text_input_manager->events.text_input,
wl_signal_add(&text_input_manager->events.new_text_input,
&relay->new_text_input);
relay->new_input_method.notify = handle_new_input_method;
wl_signal_add(&input_method_manager->events.input_method,
wl_signal_add(&input_method_manager->events.new_input_method,
&relay->new_input_method);
relay->focused_surface_destroy.notify = handle_focused_surface_destroy;

View file

@ -11,7 +11,7 @@
#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 <stdbool.h>
@ -92,6 +92,7 @@
#include <wlr/xwayland.h>
#include <xcb/xcb_icccm.h>
#endif
#include "common/xdg-shell-protocol.h"
#include "common/util.h"
/* macros */
@ -301,7 +302,7 @@ typedef struct {
float height_scale;
int32_t width;
int32_t height;
enum corner_location corner_location;
struct fx_corner_radii corner_radii;
bool should_scale;
} BufferData;
@ -316,6 +317,7 @@ struct Client {
struct wlr_scene_rect *border; /* top, bottom, left, right */
struct wlr_scene_rect *droparea;
struct wlr_scene_shadow *shadow;
struct wlr_scene_blur *blur;
struct wlr_scene_tree *scene_surface;
struct wl_list link;
struct wl_list flink;
@ -469,6 +471,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;
@ -767,7 +770,7 @@ static double find_animation_curve_at(double t, int32_t type);
static void apply_opacity_to_rect_nodes(Client *c, struct wlr_scene_node *node,
double animation_passed);
static enum corner_location set_client_corner_location(Client *c);
static struct fx_corner_radii set_client_corner_radii(Client *c);
static double all_output_frame_duration_ms();
static struct wlr_scene_tree *
wlr_scene_tree_snapshot(struct wlr_scene_node *node,
@ -2556,18 +2559,20 @@ 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;
}
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);
}
}
@ -2635,6 +2640,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;
@ -2697,6 +2711,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) {
@ -2706,6 +2722,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);
}
@ -4195,15 +4214,7 @@ static void iter_xdg_scene_buffers(struct wlr_scene_buffer *buffer, int32_t sx,
return;
if (config.blur && c && !c->noblur) {
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);
}
}
@ -4309,6 +4320,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))
@ -4361,8 +4379,7 @@ mapnotify(struct wl_listener *listener, void *data) {
c->scene, 0, 0, c->isurgent ? config.urgentcolor : config.bordercolor);
wlr_scene_node_lower_to_bottom(&c->border->node);
wlr_scene_node_set_position(&c->border->node, 0, 0);
wlr_scene_rect_set_corner_radius(c->border, config.border_radius,
config.border_radius_location_default);
wlr_scene_rect_set_corner_radius(c->border, config.border_radius);
wlr_scene_node_set_enabled(&c->border->node, true);
c->shadow =
@ -4406,6 +4423,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);
@ -5811,6 +5831,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);
@ -6238,6 +6259,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;
}
@ -6848,10 +6873,11 @@ void xwaylandready(struct wl_listener *listener, void *data) {
wlr_xwayland_set_seat(xwayland, seat);
/* 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,
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