feat: use wlr_scene_tree_set_clip to clip monitor scene

This commit is contained in:
DreamMaoMao 2026-02-26 21:39:40 +08:00
parent 3642fafe49
commit b49d2ffd5f
4 changed files with 69 additions and 22 deletions

View file

@ -341,6 +341,7 @@ void apply_border(Client *c) {
struct ivec2 clip_to_hide(Client *c, struct wlr_box *clip_box) { struct ivec2 clip_to_hide(Client *c, struct wlr_box *clip_box) {
int32_t offsetx = 0, offsety = 0, offsetw = 0, offseth = 0; int32_t offsetx = 0, offsety = 0, offsetw = 0, offseth = 0;
struct ivec2 offset = {0, 0, 0, 0}; struct ivec2 offset = {0, 0, 0, 0};
return offset;
if (!ISSCROLLTILED(c) && !c->animation.tagining && !c->animation.tagouted && if (!ISSCROLLTILED(c) && !c->animation.tagining && !c->animation.tagouted &&
!c->animation.tagouting) !c->animation.tagouting)
@ -458,6 +459,8 @@ void client_apply_clip(Client *c, float factor) {
// 检测窗口是否需要剪切超出屏幕部分,如果需要就调整实际要剪切的矩形 // 检测窗口是否需要剪切超出屏幕部分,如果需要就调整实际要剪切的矩形
offset = clip_to_hide(c, &clip_box); offset = clip_to_hide(c, &clip_box);
wlr_scene_tree_set_clip(c->mon->scene_tree, &c->mon->m);
// 应用窗口装饰 // 应用窗口装饰
apply_border(c); apply_border(c);

View file

@ -1375,14 +1375,19 @@ int32_t toggleoverlay(const Arg *arg) {
selmon->sel->isoverlay ^= 1; selmon->sel->isoverlay ^= 1;
if (selmon->sel->isoverlay) { if (selmon->sel->isoverlay) {
wlr_scene_node_reparent(&selmon->sel->scene->node, layers[LyrOverlay]); wlr_scene_node_reparent(
&selmon->sel->scene->node,
selmon->sel->mon->layers_scene_tree[LyrOverlay]);
wlr_scene_node_raise_to_top(&selmon->sel->scene->node); wlr_scene_node_raise_to_top(&selmon->sel->scene->node);
} else if (client_should_overtop(selmon->sel) && selmon->sel->isfloating) { } else if (client_should_overtop(selmon->sel) && selmon->sel->isfloating) {
wlr_scene_node_reparent(&selmon->sel->scene->node, layers[LyrTop]); wlr_scene_node_reparent(&selmon->sel->scene->node,
selmon->sel->mon->layers_scene_tree[LyrTop]);
} else { } else {
wlr_scene_node_reparent( wlr_scene_node_reparent(
&selmon->sel->scene->node, &selmon->sel->scene->node,
layers[selmon->sel->isfloating ? LyrTop : LyrTile]); selmon->sel->mon
->layers_scene_tree[selmon->sel->isfloating ? LyrTop
: LyrTile]);
} }
setborder_color(selmon->sel); setborder_color(selmon->sel);
return 0; return 0;

View file

@ -82,15 +82,28 @@ void xytonode(double x, double y, struct wlr_surface **psurface, Client **pc,
struct wlr_scene_node *node, *pnode; struct wlr_scene_node *node, *pnode;
struct wlr_surface *surface = NULL; struct wlr_surface *surface = NULL;
Client *c = NULL; Client *c = NULL;
Monitor *m = NULL;
LayerSurface *l = NULL; LayerSurface *l = NULL;
int32_t layer; int32_t layer;
m = xytomon(x, y);
if (!m)
return;
for (layer = NUM_LAYERS - 1; !surface && layer >= 0; layer--) { for (layer = NUM_LAYERS - 1; !surface && layer >= 0; layer--) {
if (layer == LyrFadeOut) if (layer == LyrFadeOut)
continue; continue;
if (!(node = wlr_scene_node_at(&layers[layer]->node, x, y, nx, ny))) node = wlr_scene_node_at(&layers[layer]->node, x, y, nx, ny);
if (!node) {
node = wlr_scene_node_at(&m->layers_scene_tree[layer]->node, x, y,
nx, ny);
}
if (!node)
continue; continue;
if (!node->enabled) if (!node->enabled)

View file

@ -519,6 +519,8 @@ struct Monitor {
bool skiping_frame; bool skiping_frame;
uint32_t resizing_count_pending; uint32_t resizing_count_pending;
uint32_t resizing_count_current; uint32_t resizing_count_current;
struct wlr_scene_tree *scene_tree;
struct wlr_scene_tree *layers_scene_tree[NUM_LAYERS];
struct wl_list dwl_ipc_outputs; struct wl_list dwl_ipc_outputs;
int32_t gappih; /* horizontal gap between windows */ int32_t gappih; /* horizontal gap between windows */
@ -1538,6 +1540,11 @@ void applyrules(Client *c) {
(!c->istagsilent || !newtags || (!c->istagsilent || !newtags ||
newtags & mon->tagset[mon->seltags])); newtags & mon->tagset[mon->seltags]));
if (c->mon) {
wlr_scene_node_reparent(&c->scene->node,
c->mon->layers_scene_tree[LyrTile]);
}
if (c->mon && if (c->mon &&
!(c->mon == selmon && c->tags & c->mon->tagset[c->mon->seltags]) && !(c->mon == selmon && c->tags & c->mon->tagset[c->mon->seltags]) &&
!c->isopensilent && !c->istagsilent) { !c->isopensilent && !c->istagsilent) {
@ -1576,7 +1583,8 @@ void applyrules(Client *c) {
// apply overlay rule // apply overlay rule
if (c->isoverlay && c->scene) { if (c->isoverlay && c->scene) {
wlr_scene_node_reparent(&c->scene->node, layers[LyrOverlay]); wlr_scene_node_reparent(&c->scene->node,
c->mon->layers_scene_tree[LyrOverlay]);
wlr_scene_node_raise_to_top(&c->scene->node); wlr_scene_node_raise_to_top(&c->scene->node);
} }
} }
@ -2373,8 +2381,6 @@ void maplayersurfacenotify(struct wl_listener *listener, void *data) {
void commitlayersurfacenotify(struct wl_listener *listener, void *data) { void commitlayersurfacenotify(struct wl_listener *listener, void *data) {
LayerSurface *l = wl_container_of(listener, l, surface_commit); LayerSurface *l = wl_container_of(listener, l, surface_commit);
struct wlr_layer_surface_v1 *layer_surface = l->layer_surface; struct wlr_layer_surface_v1 *layer_surface = l->layer_surface;
struct wlr_scene_tree *scene_layer =
layers[layermap[layer_surface->current.layer]];
struct wlr_layer_surface_v1_state old_state; struct wlr_layer_surface_v1_state old_state;
struct wlr_box box; struct wlr_box box;
@ -2391,6 +2397,9 @@ void commitlayersurfacenotify(struct wl_listener *listener, void *data) {
return; return;
} }
struct wlr_scene_tree *scene_layer =
l->mon->layers_scene_tree[layermap[layer_surface->current.layer]];
// 检查surface是否有buffer // 检查surface是否有buffer
// 空buffer只是隐藏不改变mapped状态 // 空buffer只是隐藏不改变mapped状态
if (l->mapped && !layer_surface->surface->buffer) { if (l->mapped && !layer_surface->surface->buffer) {
@ -2434,7 +2443,7 @@ void commitlayersurfacenotify(struct wl_listener *listener, void *data) {
wlr_scene_node_reparent( wlr_scene_node_reparent(
&l->popups->node, &l->popups->node,
(layer_surface->current.layer < ZWLR_LAYER_SHELL_V1_LAYER_TOP (layer_surface->current.layer < ZWLR_LAYER_SHELL_V1_LAYER_TOP
? layers[LyrTop] ? l->mon->layers_scene_tree[LyrTop]
: scene_layer)); : scene_layer));
} }
@ -2723,8 +2732,6 @@ void createlayersurface(struct wl_listener *listener, void *data) {
struct wlr_layer_surface_v1 *layer_surface = data; struct wlr_layer_surface_v1 *layer_surface = data;
LayerSurface *l = NULL; LayerSurface *l = NULL;
struct wlr_surface *surface = layer_surface->surface; struct wlr_surface *surface = layer_surface->surface;
struct wlr_scene_tree *scene_layer =
layers[layermap[layer_surface->pending.layer]];
if (!layer_surface->output && if (!layer_surface->output &&
!(layer_surface->output = selmon ? selmon->wlr_output : NULL)) { !(layer_surface->output = selmon ? selmon->wlr_output : NULL)) {
@ -2732,6 +2739,10 @@ void createlayersurface(struct wl_listener *listener, void *data) {
return; return;
} }
Monitor *mon = layer_surface->output->data;
struct wlr_scene_tree *scene_layer =
mon->layers_scene_tree[layermap[layer_surface->pending.layer]];
l = layer_surface->data = ecalloc(1, sizeof(*l)); l = layer_surface->data = ecalloc(1, sizeof(*l));
l->type = LayerShell; l->type = LayerShell;
LISTEN(&surface->events.map, &l->map, maplayersurfacenotify); LISTEN(&surface->events.map, &l->map, maplayersurfacenotify);
@ -2740,14 +2751,15 @@ void createlayersurface(struct wl_listener *listener, void *data) {
LISTEN(&surface->events.unmap, &l->unmap, unmaplayersurfacenotify); LISTEN(&surface->events.unmap, &l->unmap, unmaplayersurfacenotify);
l->layer_surface = layer_surface; l->layer_surface = layer_surface;
l->mon = layer_surface->output->data; l->mon = mon;
l->scene_layer = l->scene_layer =
wlr_scene_layer_surface_v1_create(scene_layer, layer_surface); wlr_scene_layer_surface_v1_create(scene_layer, layer_surface);
l->scene = l->scene_layer->tree; l->scene = l->scene_layer->tree;
l->popups = surface->data = wlr_scene_tree_create( l->popups = surface->data = wlr_scene_tree_create(
layer_surface->current.layer < ZWLR_LAYER_SHELL_V1_LAYER_TOP layer_surface->current.layer < ZWLR_LAYER_SHELL_V1_LAYER_TOP
? layers[LyrTop] ? l->mon->layers_scene_tree[LyrTop]
: scene_layer); : scene_layer);
l->scene->node.data = l->popups->node.data = l; l->scene->node.data = l->popups->node.data = l;
LISTEN(&l->scene->node.events.destroy, &l->destroy, destroylayernodenotify); LISTEN(&l->scene->node.events.destroy, &l->destroy, destroylayernodenotify);
@ -2844,6 +2856,13 @@ void createmon(struct wl_listener *listener, void *data) {
m->wlr_output = wlr_output; m->wlr_output = wlr_output;
m->wlr_output->data = m; m->wlr_output->data = m;
m->scene_tree = wlr_scene_tree_create(&scene->tree);
for (i = 0; i < NUM_LAYERS; i++)
m->layers_scene_tree[i] = wlr_scene_tree_create(m->scene_tree);
wlr_scene_node_place_below(&m->scene_tree->node, &layers[LyrTile]->node);
wl_list_init(&m->dwl_ipc_outputs); wl_list_init(&m->dwl_ipc_outputs);
for (i = 0; i < LENGTH(m->layers); i++) for (i = 0; i < LENGTH(m->layers); i++)
@ -4993,12 +5012,15 @@ setfloating(Client *c, int32_t floating) {
} }
if (c->isoverlay) { if (c->isoverlay) {
wlr_scene_node_reparent(&c->scene->node, layers[LyrOverlay]);
} else if (client_should_overtop(c) && c->isfloating) {
wlr_scene_node_reparent(&c->scene->node, layers[LyrTop]);
} else {
wlr_scene_node_reparent(&c->scene->node, wlr_scene_node_reparent(&c->scene->node,
layers[c->isfloating ? LyrTop : LyrTile]); c->mon->layers_scene_tree[LyrOverlay]);
} else if (client_should_overtop(c) && c->isfloating) {
wlr_scene_node_reparent(&c->scene->node,
c->mon->layers_scene_tree[LyrTop]);
} else {
wlr_scene_node_reparent(
&c->scene->node,
c->mon->layers_scene_tree[c->isfloating ? LyrTop : LyrTile]);
} }
if (!c->isfloating && old_floating_state) { if (!c->isfloating && old_floating_state) {
@ -5085,8 +5107,9 @@ void setmaximizescreen(Client *c, int32_t maximizescreen) {
setfloating(c, 1); setfloating(c, 1);
} }
wlr_scene_node_reparent(&c->scene->node, wlr_scene_node_reparent(
layers[c->isfloating ? LyrTop : LyrTile]); &c->scene->node,
c->mon->layers_scene_tree[c->isfloating ? LyrTop : LyrTile]);
if (!c->ismaximizescreen && old_maximizescreen_state) { if (!c->ismaximizescreen && old_maximizescreen_state) {
restore_size_per(c->mon, c); restore_size_per(c->mon, c);
} }
@ -5149,13 +5172,16 @@ void setfullscreen(Client *c, int32_t fullscreen) // 用自定义全屏代理自
} }
if (c->isoverlay) { if (c->isoverlay) {
wlr_scene_node_reparent(&c->scene->node, layers[LyrOverlay]); wlr_scene_node_reparent(&c->scene->node,
c->mon->layers_scene_tree[LyrOverlay]);
} else if (client_should_overtop(c) && c->isfloating) { } else if (client_should_overtop(c) && c->isfloating) {
wlr_scene_node_reparent(&c->scene->node, layers[LyrTop]); wlr_scene_node_reparent(&c->scene->node,
c->mon->layers_scene_tree[LyrTop]);
} else { } else {
wlr_scene_node_reparent( wlr_scene_node_reparent(
&c->scene->node, &c->scene->node,
layers[fullscreen || c->isfloating ? LyrTop : LyrTile]); c->mon->layers_scene_tree[fullscreen || c->isfloating ? LyrTop
: LyrTile]);
} }
if (!c->isfullscreen && old_fullscreen_state) { if (!c->isfullscreen && old_fullscreen_state) {