feat: support group

feat: add dispatch groupleave

opt: optimize layer cover

fix: miss set client isgroupfocusing to false when it no group member

fix: fix miss hide bar node when disable animaitons

opt: allow floating window show group bar

opt: optimize layer cover when setfloating

opt: optimize size per set when setfloating

opt: optimize layer cover of floating group bar

opt: make groupbar same layer with its client

opt: optimize groupbar animation clip

fix: fix cant focus group membar when change mon

opt: optimize shadow and border drap when floating cross monitor

opt: optimize overlay layer set for group

fix: fix xytonode not exclue snapbuffer for client

opt: optmize structruing\

opt: add common for struct type

It must be placed first; otherwise, after the xytonode's null pointer is
forcibly converted, the reading type will encounter an incorrect address

fix: capture windows with subsurfaces
This commit is contained in:
DreamMaoMao 2026-06-20 18:44:28 +08:00
parent 722f6ab7bb
commit 1f9dbe7c3c
20 changed files with 863 additions and 456 deletions

View file

@ -230,11 +230,13 @@ void scene_buffer_apply_overview_effect(struct wlr_scene_buffer *buffer,
bool is_subsurface = false;
struct wlr_scene_tree *parent_tree = buffer->node.parent;
if (parent_tree->node.data != NULL) {
SnapshotMetadata *meta = (SnapshotMetadata *)parent_tree->node.data;
SnapshotMetadata *meta = (SnapshotMetadata *)parent_tree->node.data;
if (parent_tree->node.data != NULL && meta->type == Snapshot) {
surface_width = meta->orig_width;
surface_height = meta->orig_height;
is_subsurface = meta->is_subsurface;
} else {
return;
}
surface_height = surface_height * buffer_data->height_scale;
@ -273,6 +275,86 @@ void buffer_set_effect(Client *c, BufferData data) {
}
}
void client_draw_title(Client *c) {
if (!c || !c->group_bar)
return;
if (!c->group_next && !c->group_prev && c->group_bar &&
c->group_bar->scene_buffer->node.enabled) {
wlr_scene_node_set_enabled(&c->group_bar->scene_buffer->node, false);
return;
}
if (!c->group_next && !c->group_prev)
return;
Client *head = c;
while (head->group_prev)
head = head->group_prev;
int count = 0;
Client *cur = head;
while (cur) {
count++;
cur = cur->group_next;
}
int32_t tab_x = c->animation.current.x;
int32_t tab_y = c->animation.current.y - config.group_bar_height;
int32_t tw = c->animation.current.width;
int32_t th = config.group_bar_height;
int32_t left_over = c->mon->m.x - tab_x;
int32_t right_over = tab_x + tw - c->mon->m.x - c->mon->m.width;
int32_t top_over = c->mon->m.y - tab_y;
int32_t bottom_over =
tab_y + config.group_bar_height - c->mon->m.y - c->mon->m.height;
if (c != grabc &&
(ISSCROLLTILED(c) || c->animation.tagining || c->animation.tagouting)) {
if (top_over > 0) {
tab_y = c->mon->m.y;
th = config.group_bar_height - top_over;
}
if (bottom_over > 0) {
th = th - bottom_over;
}
if (right_over > 0) {
tw = tw - right_over;
}
if (left_over > 0) {
tab_x = c->mon->m.x;
tw = tw - left_over;
}
}
if (tw <= 0 || th <= 0) {
cur = head;
while (cur) {
if (cur->group_bar)
wlr_scene_node_set_enabled(&cur->group_bar->scene_buffer->node,
false);
cur = cur->group_next;
}
return;
} else {
client_check_tab_node_visible(c);
}
int32_t bar_w = tw / count;
int32_t rem = tw % count;
int32_t x = tab_x;
cur = head;
for (int i = 0; i < count && cur; i++) {
int32_t w = bar_w + (i < rem ? 1 : 0);
global_draw_group_bar(cur, x, tab_y, w, th);
x += w;
cur = cur->group_next;
}
}
void apply_shield(Client *c, struct wlr_box clip_box) {
if (active_capture_count > 0 && c->shield_when_capture) {
wlr_scene_node_raise_to_top(&c->shield->node);
@ -289,18 +371,17 @@ void apply_shield(Client *c, struct wlr_box clip_box) {
}
}
void global_draw_tab_bar(Client *c, int32_t x, int32_t y, int32_t width,
int32_t height) {
if (!c->tab_bar_node)
void global_draw_group_bar(Client *c, int32_t x, int32_t y, int32_t width,
int32_t height) {
if (!c->group_bar)
return;
if (height <= 0) {
wlr_scene_node_set_enabled(&c->tab_bar_node->scene_buffer->node, false);
wlr_scene_node_set_enabled(&c->group_bar->scene_buffer->node, false);
}
wlr_scene_node_set_position(&c->tab_bar_node->scene_buffer->node, x, y);
wlr_scene_node_set_enabled(&c->tab_bar_node->scene_buffer->node, true);
mango_tab_bar_node_set_size(c->tab_bar_node, width, height);
wlr_scene_node_set_position(&c->group_bar->scene_buffer->node, x, y);
mango_group_bar_set_size(c->group_bar, width, height);
}
void apply_split_border(Client *c, bool hit_no_border) {
@ -437,7 +518,8 @@ void apply_border(Client *c) {
int32_t right_offset, bottom_offset, left_offset, top_offset;
if (c == grabc) {
if (c == grabc ||
(!ISTILED(c) && !c->animation.tagining && !c->animation.tagouting)) {
right_offset = 0;
bottom_offset = 0;
left_offset = 0;
@ -558,10 +640,8 @@ struct ivec2 clip_to_hide(Client *c, struct wlr_box *clip_box) {
(ISSCROLLTILED(c) || c->animation.tagouting || c->animation.tagining)) {
c->is_clip_to_hide = true;
wlr_scene_node_set_enabled(&c->scene->node, false);
} else if (c->is_clip_to_hide && VISIBLEON(c, c->mon) &&
(!c->is_monocle_hide || !is_monocle_layout(c->mon))) {
} else if (c->is_clip_to_hide && VISIBLEON(c, c->mon)) {
c->is_clip_to_hide = false;
c->is_monocle_hide = false;
wlr_scene_node_set_enabled(&c->scene->node, true);
}
@ -782,6 +862,9 @@ void client_apply_clip(Client *c, float factor) {
apply_border(c);
client_draw_title(c);
apply_shield(c, clip_box);
if (clip_box.width <= 0 || clip_box.height <= 0) {
return;
}
@ -823,6 +906,9 @@ void client_apply_clip(Client *c, float factor) {
// 应用窗口装饰
apply_border(c);
client_draw_title(c);
apply_shield(c, clip_box);
// 如果窗口剪切区域已经剪切到0则不渲染窗口表面
if (clip_box.width <= 0 || clip_box.height <= 0) {
should_render_client_surface = false;
@ -999,7 +1085,7 @@ void client_animation_next_tick(Client *c) {
c->animation.current = c->geom;
}
xytonode(cursor->x, cursor->y, NULL, &pointer_c, NULL, &sx, &sy);
xytonode(cursor->x, cursor->y, NULL, &pointer_c, NULL, NULL, &sx, &sy);
surface =
pointer_c && pointer_c == c ? client_surface(pointer_c) : NULL;
@ -1274,6 +1360,8 @@ void resize(Client *c, struct wlr_box geo, int32_t interact) {
apply_border(c);
client_get_clip(c, &clip);
apply_shield(c, clip);
client_draw_title(c);
wlr_scene_subsurface_tree_set_clip(&c->scene_surface->node, &clip);
return;
}