mirror of
https://github.com/DreamMaoMao/maomaowm.git
synced 2026-06-25 13:14:13 -04:00
feat: support group
This commit is contained in:
parent
0fc7559c3c
commit
d1cab2c4b7
14 changed files with 483 additions and 233 deletions
|
|
@ -57,7 +57,18 @@ void client_tile_resize(Client *c, struct wlr_box geo, int32_t interact) {
|
|||
if (!ISFAKETILED(c))
|
||||
return;
|
||||
|
||||
if (!c->isfullscreen && !c->ismaximizescreen) {
|
||||
if (c->isfullscreen && c->tab_bar_node) {
|
||||
wlr_scene_node_set_enabled(&c->tab_bar_node->scene_buffer->node, false);
|
||||
}
|
||||
|
||||
if (!c->mon->isoverview && c->tab_bar_node && !c->isfullscreen &&
|
||||
(c->group_next || c->group_prev)) {
|
||||
geo.y = geo.y + config.tab_bar_height;
|
||||
geo.height -= config.tab_bar_height;
|
||||
}
|
||||
|
||||
if ((!c->isfullscreen && !c->ismaximizescreen) ||
|
||||
is_scroller_layout(c->mon)) {
|
||||
resize(c, geo, interact);
|
||||
}
|
||||
}
|
||||
|
|
@ -120,3 +131,63 @@ void client_add_tab_bar_node(Client *c) {
|
|||
wlr_scene_node_set_enabled(&c->tab_bar_node->scene_buffer->node, false);
|
||||
mango_tab_bar_node_update(c->tab_bar_node, client_get_title(c), 1.0);
|
||||
}
|
||||
|
||||
void client_focus_group_member(Client *c) {
|
||||
if (!c->group_prev && !c->group_next)
|
||||
return;
|
||||
|
||||
if (c->isgroupfocusing)
|
||||
return;
|
||||
|
||||
if (c->mon->isoverview)
|
||||
return;
|
||||
|
||||
Client *head = c;
|
||||
while (head->group_prev)
|
||||
head = head->group_prev;
|
||||
|
||||
Client *cur_focusing = NULL;
|
||||
while (head) {
|
||||
if (head->isgroupfocusing) {
|
||||
cur_focusing = head;
|
||||
break;
|
||||
}
|
||||
head = head->group_next;
|
||||
}
|
||||
|
||||
if (cur_focusing) {
|
||||
cur_focusing->isgroupfocusing = false;
|
||||
client_replace(c, cur_focusing, true);
|
||||
mango_tab_bar_node_set_focus(cur_focusing->tab_bar_node, false);
|
||||
}
|
||||
|
||||
c->isgroupfocusing = true;
|
||||
mango_tab_bar_node_set_focus(c->tab_bar_node, true);
|
||||
focusclient(c, 1);
|
||||
|
||||
arrange(c->mon, false, false);
|
||||
}
|
||||
|
||||
void client_set_tab_node_visible(Client *c) {
|
||||
|
||||
if (!c || c->iskilling)
|
||||
return;
|
||||
|
||||
Client *head = c;
|
||||
while (head->group_prev)
|
||||
head = head->group_prev;
|
||||
|
||||
Client *cur = head;
|
||||
while (cur) {
|
||||
if (!c->mon->isoverview && cur->tab_bar_node &&
|
||||
(cur->group_next || cur->group_prev) && VISIBLEON(c, c->mon) &&
|
||||
ISSCROLLTILED(c) && !c->isfullscreen) {
|
||||
wlr_scene_node_set_enabled(&cur->tab_bar_node->scene_buffer->node,
|
||||
true);
|
||||
} else {
|
||||
wlr_scene_node_set_enabled(&cur->tab_bar_node->scene_buffer->node,
|
||||
false);
|
||||
}
|
||||
cur = cur->group_next;
|
||||
}
|
||||
}
|
||||
|
|
@ -403,6 +403,79 @@ void client_draw_shadow(Client *c) {
|
|||
wlr_scene_shadow_set_clipped_region(c->shadow, clipped_region);
|
||||
}
|
||||
|
||||
void client_draw_title(Client *c) {
|
||||
|
||||
if (!c || !c->tab_bar_node)
|
||||
return;
|
||||
|
||||
if (!c->group_next && !c->group_prev && c->tab_bar_node &&
|
||||
c->tab_bar_node->scene_buffer->node.enabled) {
|
||||
wlr_scene_node_set_enabled(&c->tab_bar_node->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.tab_bar_height;
|
||||
int32_t tw = c->animation.current.width;
|
||||
int32_t th = config.tab_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.tab_bar_height - c->mon->m.y - c->mon->m.height;
|
||||
|
||||
if (top_over > 0)
|
||||
th = config.tab_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->tab_bar_node)
|
||||
wlr_scene_node_set_enabled(
|
||||
&cur->tab_bar_node->scene_buffer->node, false);
|
||||
cur = cur->group_next;
|
||||
}
|
||||
return;
|
||||
} else {
|
||||
client_set_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_tab_bar(cur, x, tab_y, w, th);
|
||||
x += w;
|
||||
cur = cur->group_next;
|
||||
}
|
||||
}
|
||||
|
||||
void apply_shield(Client *c, struct wlr_box clip_box) {
|
||||
|
||||
if (clip_box.width <= 0 || clip_box.height <= 0) {
|
||||
|
|
@ -453,7 +526,6 @@ void global_draw_tab_bar(Client *c, int32_t x, int32_t y, int32_t width,
|
|||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
|
|
@ -711,10 +783,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);
|
||||
}
|
||||
|
||||
|
|
@ -938,6 +1008,7 @@ void client_apply_clip(Client *c, float factor) {
|
|||
|
||||
apply_border(c);
|
||||
client_draw_shadow(c);
|
||||
client_draw_title(c);
|
||||
client_draw_blur(c, clip_box, offset);
|
||||
apply_shield(c, clip_box);
|
||||
|
||||
|
|
@ -981,6 +1052,7 @@ void client_apply_clip(Client *c, float factor) {
|
|||
// 应用窗口装饰
|
||||
apply_border(c);
|
||||
client_draw_shadow(c);
|
||||
client_draw_title(c);
|
||||
apply_shield(c, clip_box);
|
||||
client_draw_blur(c, clip_box, offset);
|
||||
|
||||
|
|
@ -1432,6 +1504,7 @@ void resize(Client *c, struct wlr_box geo, int32_t interact) {
|
|||
client_get_clip(c, &clip);
|
||||
apply_shield(c, clip);
|
||||
client_draw_shadow(c);
|
||||
client_draw_title(c);
|
||||
wlr_scene_subsurface_tree_set_clip(&c->scene_surface->node, &clip);
|
||||
if (config.blur && !c->noblur)
|
||||
wlr_scene_blur_set_size(c->blur,
|
||||
|
|
|
|||
|
|
@ -30,7 +30,7 @@ struct dvec2 calculate_animation_curve_at(double t, int32_t type) {
|
|||
|
||||
void handle_snapshot_meta_destroy(struct wl_listener *listener, void *data) {
|
||||
SnapshotMetadata *meta = wl_container_of(listener, meta, destroy);
|
||||
wl_list_remove(&meta->destroy.link); // 安全移除监听器
|
||||
wl_list_remove(&meta->destroy.link);
|
||||
free(meta);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -45,10 +45,8 @@ void set_tagin_animation(Monitor *m, Client *c) {
|
|||
|
||||
void set_arrange_visible(Monitor *m, Client *c, bool want_animation) {
|
||||
|
||||
if (!ISTILED(c) || ((!c->is_clip_to_hide || !is_scroller_layout(c->mon)) &&
|
||||
(!c->is_monocle_hide || !is_monocle_layout(c->mon)))) {
|
||||
if (!ISTILED(c) || (!c->is_clip_to_hide || !is_scroller_layout(c->mon))) {
|
||||
c->is_clip_to_hide = false;
|
||||
c->is_monocle_hide = false;
|
||||
wlr_scene_node_set_enabled(&c->scene->node, true);
|
||||
wlr_scene_node_set_enabled(&c->scene_surface->node, true);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1011,9 +1011,15 @@ FuncType parse_func_name(char *func_name, Arg *arg, char *arg_value,
|
|||
if (strcmp(func_name, "focusstack") == 0) {
|
||||
func = focusstack;
|
||||
(*arg).i = parse_circle_direction(arg_value);
|
||||
} else if (strcmp(func_name, "groupfocus") == 0) {
|
||||
func = groupfocus;
|
||||
(*arg).i = parse_circle_direction(arg_value);
|
||||
} else if (strcmp(func_name, "focusdir") == 0) {
|
||||
func = focusdir;
|
||||
(*arg).i = parse_direction(arg_value);
|
||||
} else if (strcmp(func_name, "groupjoin") == 0) {
|
||||
func = groupjoin;
|
||||
(*arg).i = parse_direction(arg_value);
|
||||
} else if (strcmp(func_name, "focusid") == 0) {
|
||||
func = focusid;
|
||||
} else if (strcmp(func_name, "incnmaster") == 0) {
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@ int32_t minimized(const Arg *arg);
|
|||
int32_t restore_minimized(const Arg *arg);
|
||||
int32_t toggle_scratchpad(const Arg *arg);
|
||||
int32_t focusdir(const Arg *arg);
|
||||
int32_t groupjoin(const Arg *arg);
|
||||
int32_t toggleoverview(const Arg *arg);
|
||||
int32_t togglejump(const Arg *arg);
|
||||
int32_t set_proportion(const Arg *arg);
|
||||
|
|
@ -38,6 +39,7 @@ int32_t toggleglobal(const Arg *arg);
|
|||
int32_t incnmaster(const Arg *arg);
|
||||
int32_t focusmon(const Arg *arg);
|
||||
int32_t focusstack(const Arg *arg);
|
||||
int32_t groupfocus(const Arg *arg);
|
||||
int32_t chvt(const Arg *arg);
|
||||
int32_t reload_config(const Arg *arg);
|
||||
int32_t smartmovewin(const Arg *arg);
|
||||
|
|
|
|||
|
|
@ -156,6 +156,48 @@ int32_t focusdir(const Arg *arg) {
|
|||
return 0;
|
||||
}
|
||||
|
||||
int32_t groupjoin(const Arg *arg) {
|
||||
|
||||
if (!selmon)
|
||||
return 0;
|
||||
|
||||
Client *need_join_client = arg->tc ? arg->tc : selmon->sel;
|
||||
if (!need_join_client)
|
||||
return 0;
|
||||
|
||||
if (need_join_client->group_next || need_join_client->group_prev) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
Client *need_replace_client = NULL;
|
||||
need_replace_client = direction_select(arg);
|
||||
|
||||
if (!need_replace_client ||
|
||||
need_replace_client->mon != need_join_client->mon)
|
||||
return 0;
|
||||
|
||||
if (!need_join_client->group_next && !need_join_client->group_prev) {
|
||||
|
||||
if (!need_replace_client->group_prev &&
|
||||
!need_replace_client->group_next) {
|
||||
need_replace_client->isgroupfocusing = true;
|
||||
}
|
||||
|
||||
need_join_client->group_next = need_replace_client;
|
||||
if (need_replace_client->group_prev) {
|
||||
need_replace_client->group_prev->group_next = need_join_client;
|
||||
}
|
||||
need_join_client->group_prev = need_replace_client->group_prev;
|
||||
need_replace_client->group_prev = need_join_client;
|
||||
|
||||
client_focus_group_member(need_join_client);
|
||||
arrange(need_join_client->mon, false, false);
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32_t focuslast(const Arg *arg) {
|
||||
Client *c = NULL;
|
||||
Client *tc = NULL;
|
||||
|
|
@ -261,6 +303,31 @@ int32_t focusstack(const Arg *arg) {
|
|||
return 0;
|
||||
}
|
||||
|
||||
int32_t groupfocus(const Arg *arg) {
|
||||
Client *c = arg->tc ? arg->tc : selmon->sel;
|
||||
if (!c)
|
||||
return 0;
|
||||
|
||||
if (!c->group_prev && !c->group_next) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
Client *tc = NULL;
|
||||
|
||||
if (arg->i == NEXT) {
|
||||
tc = c->group_next;
|
||||
} else {
|
||||
tc = c->group_prev;
|
||||
}
|
||||
|
||||
if (!tc)
|
||||
return 0;
|
||||
|
||||
client_focus_group_member(tc);
|
||||
arrange(tc->mon, false, false);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32_t incnmaster(const Arg *arg) {
|
||||
if (!arg || !selmon)
|
||||
return 0;
|
||||
|
|
|
|||
|
|
@ -188,8 +188,6 @@ Client *find_client_by_direction(Client *tc, const Arg *arg,
|
|||
continue;
|
||||
if (!findfloating && c->isfloating)
|
||||
continue;
|
||||
if (c->is_monocle_hide)
|
||||
continue;
|
||||
if (c->isunglobal)
|
||||
continue;
|
||||
if (!config.focus_cross_monitor && c->mon != tc->mon)
|
||||
|
|
@ -197,11 +195,6 @@ Client *find_client_by_direction(Client *tc, const Arg *arg,
|
|||
if (!(c->tags & c->mon->tagset[c->mon->seltags]))
|
||||
continue;
|
||||
|
||||
if (step == 0 && ((!tc->mon->isoverview &&
|
||||
!client_is_in_same_stack(tc, c, NULL)) ||
|
||||
c->mon != tc->mon))
|
||||
continue;
|
||||
|
||||
int32_t c_l = c->geom.x;
|
||||
int32_t c_r = c->geom.x + c->geom.width;
|
||||
int32_t c_t = c->geom.y;
|
||||
|
|
@ -257,17 +250,24 @@ Client *find_client_by_direction(Client *tc, const Arg *arg,
|
|||
if (!match_dir)
|
||||
continue;
|
||||
|
||||
if (step == 0) {
|
||||
if (c->mon != tc->mon)
|
||||
continue;
|
||||
if (!tc->mon->isoverview &&
|
||||
!client_is_in_same_stack(tc, c, NULL))
|
||||
continue;
|
||||
if (orth_dist != 0)
|
||||
continue;
|
||||
}
|
||||
|
||||
int64_t penalty = 0;
|
||||
if (main_dist < 0) {
|
||||
penalty = 10000000000LL; // 主方向重叠(反方向)的极大惩罚
|
||||
penalty = 10000000000LL;
|
||||
main_dist = -main_dist;
|
||||
}
|
||||
|
||||
// 正交方向无重叠惩罚,优先选择在同一行/列的窗口
|
||||
int64_t no_overlap_penalty = 0;
|
||||
if (orth_dist > 0) {
|
||||
// LEFT/RIGHT 时 orth_dist 是垂直间距,>0 表示垂直无重叠
|
||||
// UP/DOWN 时 orth_dist 是水平间距,>0 表示水平无重叠
|
||||
no_overlap_penalty = 10000000LL;
|
||||
}
|
||||
|
||||
|
|
@ -442,7 +442,7 @@ Client *get_focused_stack_client(Client *sc, Client *custom_focus_client) {
|
|||
return sc;
|
||||
|
||||
wl_list_for_each(tc, &fstack, flink) {
|
||||
if (tc->iskilling || tc->isunglobal || tc->is_monocle_hide)
|
||||
if (tc->iskilling || tc->isunglobal)
|
||||
continue;
|
||||
if (!VISIBLEON(tc, sc->mon))
|
||||
continue;
|
||||
|
|
|
|||
|
|
@ -37,21 +37,6 @@ void set_size_per(Monitor *m, Client *c) {
|
|||
}
|
||||
}
|
||||
|
||||
void monocle_set_focus(Client *c, bool focused) {
|
||||
|
||||
if (!c || !c->mon)
|
||||
return;
|
||||
|
||||
c->is_monocle_hide = !focused;
|
||||
mango_tab_bar_node_set_focus(c->tab_bar_node, focused);
|
||||
wlr_scene_node_set_enabled(&c->scene->node, focused);
|
||||
|
||||
if (!focused) {
|
||||
c->animation.current = c->animainit_geom = c->animation.initial =
|
||||
c->pending = c->current = c->geom;
|
||||
}
|
||||
}
|
||||
|
||||
void resize_tile_master_horizontal(Client *grabc, bool isdrag, int32_t offsetx,
|
||||
int32_t offsety, uint32_t time,
|
||||
int32_t type) {
|
||||
|
|
@ -1147,16 +1132,6 @@ void pre_caculate_before_arrange(Monitor *m, bool want_animation,
|
|||
client_add_jump_label_node(c);
|
||||
}
|
||||
|
||||
if (m->pertag->ltidxs[m->pertag->curtag]->id == MONOCLE &&
|
||||
!c->tab_bar_node) {
|
||||
client_add_tab_bar_node(c);
|
||||
}
|
||||
|
||||
if (c->tab_bar_node && c->mon == m) {
|
||||
wlr_scene_node_set_enabled(&c->tab_bar_node->scene_buffer->node,
|
||||
false);
|
||||
}
|
||||
|
||||
if (c->mon == m && (c->isglobal || c->isunglobal)) {
|
||||
c->tags = m->tagset[m->seltags];
|
||||
}
|
||||
|
|
|
|||
|
|
@ -261,7 +261,7 @@ static void dwindle_assign(DwindleNode *node, int32_t ax, int32_t ay,
|
|||
!node->client->ismaximizescreen) {
|
||||
struct wlr_box box = {ax, ay, MANGO_MAX(1, aw),
|
||||
MANGO_MAX(1, ah)};
|
||||
resize(node->client, box, 0);
|
||||
client_tile_resize(node->client, box, 0);
|
||||
}
|
||||
}
|
||||
return;
|
||||
|
|
|
|||
|
|
@ -545,83 +545,32 @@ void deck(Monitor *m) {
|
|||
}
|
||||
}
|
||||
|
||||
void monocle(Monitor *m) {
|
||||
Client *c = NULL, *fc = NULL;
|
||||
void // 17
|
||||
monocle(Monitor *m) {
|
||||
Client *c = NULL;
|
||||
struct wlr_box geom;
|
||||
|
||||
int32_t cur_gappov = enablegaps ? m->gappov : 0;
|
||||
int32_t cur_gappoh = enablegaps ? m->gappoh : 0;
|
||||
int32_t cur_gapiv = enablegaps ? m->gappiv : 0;
|
||||
int32_t cur_gapih = enablegaps ? m->gappih : 0;
|
||||
|
||||
if (config.smartgaps && m->visible_fake_tiling_clients == 1) {
|
||||
cur_gappov = cur_gappoh = cur_gapiv = cur_gapih = 0;
|
||||
}
|
||||
|
||||
int n = m->visible_fake_tiling_clients;
|
||||
if (n == 0)
|
||||
return;
|
||||
|
||||
wl_list_for_each(c, &fstack, flink) {
|
||||
if (c->iskilling || c->isunglobal || !ISFAKETILED(c))
|
||||
continue;
|
||||
if (VISIBLEON(c, m)) {
|
||||
fc = c;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (n == 1) {
|
||||
geom.x = m->w.x + cur_gappoh;
|
||||
geom.y = m->w.y + cur_gappov;
|
||||
geom.width = m->w.width - 2 * cur_gappoh;
|
||||
geom.height = m->w.height - 2 * cur_gappov;
|
||||
client_tile_resize(fc, geom, 0);
|
||||
monocle_set_focus(fc, true);
|
||||
return;
|
||||
}
|
||||
|
||||
int tab_bar_height = config.tab_bar_height;
|
||||
|
||||
int tab_bar_inner_gap_height =
|
||||
config.tab_bar_height > 0 ? 2 * cur_gapiv : 0;
|
||||
int tab_bar_y_offset = config.tab_bar_height > 0 ? cur_gapiv : 0;
|
||||
|
||||
int tab_y = m->w.y + cur_gappov;
|
||||
int main_y = tab_y + tab_bar_height + tab_bar_y_offset;
|
||||
int main_height = m->w.height - 2 * cur_gappov - tab_bar_inner_gap_height -
|
||||
tab_bar_height;
|
||||
|
||||
int tab_area_width = m->w.width - 2 * cur_gappoh;
|
||||
|
||||
int total_gaps = (n - 1) * cur_gapih;
|
||||
int base_width = (tab_area_width - total_gaps) / n;
|
||||
int remainder = (tab_area_width - total_gaps) % n;
|
||||
|
||||
int tab_x = m->w.x + cur_gappoh;
|
||||
int idx = 0;
|
||||
cur_gappoh = config.smartgaps && m->visible_fake_tiling_clients == 1
|
||||
? 0
|
||||
: cur_gappoh;
|
||||
cur_gappov = config.smartgaps && m->visible_fake_tiling_clients == 1
|
||||
? 0
|
||||
: cur_gappov;
|
||||
|
||||
wl_list_for_each(c, &clients, link) {
|
||||
if (!VISIBLEON(c, m) || !ISFAKETILED(c))
|
||||
continue;
|
||||
|
||||
if (c == fc) {
|
||||
monocle_set_focus(c, true);
|
||||
} else {
|
||||
monocle_set_focus(c, false);
|
||||
}
|
||||
|
||||
geom.x = m->w.x + cur_gappoh;
|
||||
geom.y = main_y;
|
||||
geom.y = m->w.y + cur_gappov;
|
||||
geom.width = m->w.width - 2 * cur_gappoh;
|
||||
geom.height = main_height;
|
||||
geom.height = m->w.height - 2 * cur_gappov;
|
||||
client_tile_resize(c, geom, 0);
|
||||
|
||||
int tw = base_width + (idx < remainder ? 1 : 0);
|
||||
global_draw_tab_bar(c, tab_x, tab_y, tw, tab_bar_height);
|
||||
|
||||
tab_x += tw + cur_gapih;
|
||||
idx++;
|
||||
}
|
||||
if ((c = focustop(m)))
|
||||
wlr_scene_node_raise_to_top(&c->scene->node);
|
||||
}
|
||||
|
||||
// 网格布局窗口大小和位置计算
|
||||
|
|
|
|||
|
|
@ -1,4 +1,3 @@
|
|||
|
||||
typedef struct {
|
||||
float x, y, w, h;
|
||||
} OvPlacedRect;
|
||||
|
|
@ -232,16 +231,20 @@ void overview_scale(Monitor *m) {
|
|||
float base_x = m->w.x + target_gappo + dx;
|
||||
float base_y = m->w.y + target_gappo + dy;
|
||||
|
||||
// 收集所有客户端的目标几何,最后统一调用 client_tile_resize
|
||||
struct wlr_box overview_boxes[n]; // C99 VLA,n > 0 时有效
|
||||
for (int k = 0; k < n; k++) {
|
||||
Client *cl = items[k].c;
|
||||
struct wlr_box geom;
|
||||
geom.x = (int)(base_x + placed[k].x + 0.5f);
|
||||
geom.y = (int)(base_y + placed[k].y + 0.5f);
|
||||
float w = items[k].orig_w * best_s;
|
||||
float h = items[k].orig_h * best_s;
|
||||
geom.width = (int)(geom.x + w + 0.5f) - geom.x;
|
||||
geom.height = (int)(geom.y + h + 0.5f) - geom.y;
|
||||
resize(cl, geom, 0);
|
||||
int ix = (int)(base_x + placed[k].x + 0.5f);
|
||||
int iy = (int)(base_y + placed[k].y + 0.5f);
|
||||
int iw = (int)(ix + w + 0.5f) - ix;
|
||||
int ih = (int)(iy + h + 0.5f) - iy;
|
||||
overview_boxes[k] = (struct wlr_box){ix, iy, iw, ih};
|
||||
}
|
||||
|
||||
for (int k = 0; k < n; k++) {
|
||||
client_tile_resize(items[k].c, overview_boxes[k], 0);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -280,74 +283,69 @@ void overview_resize(Monitor *m) {
|
|||
return;
|
||||
}
|
||||
|
||||
// 临时存储每个客户端的目标几何
|
||||
struct wlr_box boxes[n]; // C99 VLA
|
||||
|
||||
if (n == 1) {
|
||||
int32_t cw = (m->w.width - 2 * target_gappo) * single_width_ratio;
|
||||
int32_t ch = (m->w.height - 2 * target_gappo) * single_height_ratio;
|
||||
c_arr[0]->geom.x = m->w.x + (m->w.width - cw) / 2;
|
||||
c_arr[0]->geom.y = m->w.y + (m->w.height - ch) / 2;
|
||||
c_arr[0]->geom.width = cw;
|
||||
c_arr[0]->geom.height = ch;
|
||||
resize(c_arr[0], c_arr[0]->geom, 0);
|
||||
free(c_arr);
|
||||
return;
|
||||
}
|
||||
|
||||
if (n == 2) {
|
||||
boxes[0].x = m->w.x + (m->w.width - cw) / 2;
|
||||
boxes[0].y = m->w.y + (m->w.height - ch) / 2;
|
||||
boxes[0].width = cw;
|
||||
boxes[0].height = ch;
|
||||
} else if (n == 2) {
|
||||
int32_t cw = (m->w.width - 2 * target_gappo - target_gappi) / 2;
|
||||
int32_t ch = (m->w.height - 2 * target_gappo) * 0.65f;
|
||||
|
||||
c_arr[0]->geom.x = m->w.x + target_gappo;
|
||||
c_arr[0]->geom.y = m->w.y + (m->w.height - ch) / 2 + target_gappo;
|
||||
c_arr[0]->geom.width = cw;
|
||||
c_arr[0]->geom.height = ch;
|
||||
resize(c_arr[0], c_arr[0]->geom, 0);
|
||||
boxes[0].x = m->w.x + target_gappo;
|
||||
boxes[0].y = m->w.y + (m->w.height - ch) / 2 + target_gappo;
|
||||
boxes[0].width = cw;
|
||||
boxes[0].height = ch;
|
||||
|
||||
c_arr[1]->geom.x = m->w.x + cw + target_gappo + target_gappi;
|
||||
c_arr[1]->geom.y = m->w.y + (m->w.height - ch) / 2 + target_gappo;
|
||||
c_arr[1]->geom.width = cw;
|
||||
c_arr[1]->geom.height = ch;
|
||||
resize(c_arr[1], c_arr[1]->geom, 0);
|
||||
boxes[1].x = m->w.x + cw + target_gappo + target_gappi;
|
||||
boxes[1].y = m->w.y + (m->w.height - ch) / 2 + target_gappo;
|
||||
boxes[1].width = cw;
|
||||
boxes[1].height = ch;
|
||||
} else {
|
||||
int32_t cols = 1;
|
||||
while (cols * cols < n)
|
||||
cols++;
|
||||
int32_t rows = (n + cols - 1) / cols;
|
||||
|
||||
free(c_arr);
|
||||
return;
|
||||
}
|
||||
int32_t ch =
|
||||
(m->w.height - 2 * target_gappo - (rows - 1) * target_gappi) / rows;
|
||||
int32_t cw =
|
||||
(m->w.width - 2 * target_gappo - (cols - 1) * target_gappi) / cols;
|
||||
|
||||
int32_t cols = 1;
|
||||
while (cols * cols < n) {
|
||||
cols++;
|
||||
}
|
||||
int32_t rows = (n + cols - 1) / cols;
|
||||
if (ch < 1)
|
||||
ch = 1;
|
||||
if (cw < 1)
|
||||
cw = 1;
|
||||
|
||||
int32_t ch =
|
||||
(m->w.height - 2 * target_gappo - (rows - 1) * target_gappi) / rows;
|
||||
int32_t cw =
|
||||
(m->w.width - 2 * target_gappo - (cols - 1) * target_gappi) / cols;
|
||||
|
||||
if (ch < 1)
|
||||
ch = 1;
|
||||
if (cw < 1)
|
||||
cw = 1;
|
||||
|
||||
int32_t overcols = n % cols;
|
||||
int32_t dx = 0;
|
||||
if (overcols) {
|
||||
dx = (m->w.width - overcols * cw - (overcols - 1) * target_gappi) / 2 -
|
||||
target_gappo;
|
||||
}
|
||||
|
||||
for (int i = 0; i < n; i++) {
|
||||
int32_t cx = m->w.x + (i % cols) * (cw + target_gappi);
|
||||
int32_t cy = m->w.y + (i / cols) * (ch + target_gappi);
|
||||
|
||||
if (overcols && i >= n - overcols) {
|
||||
cx += dx;
|
||||
int32_t overcols = n % cols;
|
||||
int32_t dx = 0;
|
||||
if (overcols) {
|
||||
dx = (m->w.width - overcols * cw - (overcols - 1) * target_gappi) /
|
||||
2 -
|
||||
target_gappo;
|
||||
}
|
||||
|
||||
c_arr[i]->geom.x = cx + target_gappo;
|
||||
c_arr[i]->geom.y = cy + target_gappo;
|
||||
c_arr[i]->geom.width = cw;
|
||||
c_arr[i]->geom.height = ch;
|
||||
resize(c_arr[i], c_arr[i]->geom, 0);
|
||||
for (int i = 0; i < n; i++) {
|
||||
int32_t cx = m->w.x + (i % cols) * (cw + target_gappi);
|
||||
int32_t cy = m->w.y + (i / cols) * (ch + target_gappi);
|
||||
if (overcols && i >= n - overcols)
|
||||
cx += dx;
|
||||
|
||||
boxes[i].x = cx + target_gappo;
|
||||
boxes[i].y = cy + target_gappo;
|
||||
boxes[i].width = cw;
|
||||
boxes[i].height = ch;
|
||||
}
|
||||
}
|
||||
|
||||
// 统一应用所有几何变更,使用 client_tile_resize
|
||||
for (int k = 0; k < n; k++) {
|
||||
client_tile_resize(c_arr[k], boxes[k], 0);
|
||||
}
|
||||
|
||||
free(c_arr);
|
||||
|
|
@ -365,9 +363,7 @@ void create_jump_hints(Monitor *m) {
|
|||
char c_char = jump_labels[label_idx];
|
||||
c->jump_char = c_char;
|
||||
|
||||
// 把字符变成字符串
|
||||
char label_text[2] = {c_char, '\0'};
|
||||
|
||||
mango_jump_label_node_update(c->jump_label_node, label_text, 1.0f);
|
||||
wlr_scene_node_set_enabled(&c->jump_label_node->scene_buffer->node,
|
||||
true);
|
||||
|
|
@ -385,12 +381,10 @@ void create_jump_hints(Monitor *m) {
|
|||
void begin_jump_mode(Monitor *m) { m->is_jump_mode = 1; }
|
||||
|
||||
void finish_jump_mode(Monitor *m) {
|
||||
Client *c = NULL;
|
||||
|
||||
if (!m->is_jump_mode) {
|
||||
if (!m->is_jump_mode)
|
||||
return;
|
||||
}
|
||||
|
||||
Client *c;
|
||||
wl_list_for_each(c, &clients, link) {
|
||||
if (VISIBLEON(c, m)) {
|
||||
if (c->jump_label_node->scene_buffer->node.enabled) {
|
||||
|
|
@ -400,12 +394,10 @@ void finish_jump_mode(Monitor *m) {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
m->is_jump_mode = 0;
|
||||
}
|
||||
|
||||
void overview(Monitor *m) {
|
||||
|
||||
if (config.ov_no_resize) {
|
||||
overview_scale(m);
|
||||
} else {
|
||||
|
|
@ -415,4 +407,4 @@ void overview(Monitor *m) {
|
|||
if (m->is_jump_mode) {
|
||||
create_jump_hints(m);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -36,7 +36,6 @@ scroller_node_create(struct TagScrollerState *st, Client *c) {
|
|||
return n;
|
||||
}
|
||||
|
||||
/* 从 tag 状态中移除一个节点并释放 */
|
||||
static void scroller_node_remove(struct TagScrollerState *st,
|
||||
struct ScrollerStackNode *target) {
|
||||
if (!st || !target)
|
||||
|
|
@ -223,7 +222,7 @@ void arrange_stack_node(struct ScrollerStackNode *head, struct wlr_box geometry,
|
|||
.y = current_y,
|
||||
.width = geometry.width,
|
||||
.height = client_height};
|
||||
resize(iter->client, client_geom, 0);
|
||||
client_tile_resize(iter->client, client_geom, 0);
|
||||
remain_proportion -= iter->stack_proportion;
|
||||
remain_client_height -= client_height;
|
||||
current_y += client_height + gappiv;
|
||||
|
|
@ -272,7 +271,7 @@ void arrange_stack_vertical_node(struct ScrollerStackNode *head,
|
|||
.x = current_x,
|
||||
.height = geometry.height,
|
||||
.width = client_width};
|
||||
resize(iter->client, client_geom, 0);
|
||||
client_tile_resize(iter->client, client_geom, 0);
|
||||
remain_proportion -= iter->stack_proportion;
|
||||
remain_client_width -= client_width;
|
||||
current_x += client_width + gappih;
|
||||
|
|
@ -508,6 +507,7 @@ void scroller(Monitor *m) {
|
|||
|
||||
void vertical_scroller(Monitor *m) {
|
||||
uint32_t tag = m->pertag->curtag;
|
||||
int32_t bar_height = 0;
|
||||
struct TagScrollerState *st = ensure_scroller_state(m, tag);
|
||||
Client *c = NULL;
|
||||
float scroller_default_proportion_single =
|
||||
|
|
@ -696,7 +696,12 @@ void vertical_scroller(Monitor *m) {
|
|||
arrange_stack_vertical_node(heads[focus_index], target_geom,
|
||||
cur_gappih);
|
||||
} else {
|
||||
target_geom.y = root_client->geom.y;
|
||||
bar_height = !root_client->isfullscreen && (root_client->group_prev ||
|
||||
root_client->group_next)
|
||||
? config.tab_bar_height
|
||||
: 0;
|
||||
|
||||
target_geom.y = root_client->geom.y - bar_height;
|
||||
vertical_check_scroller_root_inside_mon(heads[focus_index]->client,
|
||||
&target_geom);
|
||||
arrange_stack_vertical_node(heads[focus_index], target_geom,
|
||||
|
|
@ -709,8 +714,15 @@ void vertical_scroller(Monitor *m) {
|
|||
up_geom.width = m->w.width - 2 * cur_gappoh;
|
||||
up_geom.height = max_client_height * cur->scroller_proportion;
|
||||
vertical_scroll_adjust_fullandmax(cur->client, &up_geom);
|
||||
|
||||
bar_height = !heads[focus_index - i + 1]->client->isfullscreen &&
|
||||
(heads[focus_index - i + 1]->client->group_prev ||
|
||||
heads[focus_index - i + 1]->client->group_next)
|
||||
? config.tab_bar_height
|
||||
: 0;
|
||||
|
||||
up_geom.y = heads[focus_index - i + 1]->client->geom.y - cur_gappiv -
|
||||
up_geom.height;
|
||||
up_geom.height - bar_height;
|
||||
arrange_stack_vertical_node(cur, up_geom, cur_gappih);
|
||||
}
|
||||
|
||||
|
|
@ -902,7 +914,6 @@ static void update_scroller_state(Monitor *m) {
|
|||
break;
|
||||
}
|
||||
|
||||
/* 移除不再可见的节点 */
|
||||
struct ScrollerStackNode *n = st->all_first;
|
||||
while (n) {
|
||||
bool found = false;
|
||||
|
|
|
|||
190
src/mango.c
190
src/mango.c
|
|
@ -414,7 +414,6 @@ struct Client {
|
|||
int32_t istagswitching;
|
||||
int32_t isnamedscratchpad;
|
||||
int32_t shield_when_capture;
|
||||
bool is_monocle_hide;
|
||||
bool is_pending_open_animation;
|
||||
bool is_restoring_from_ov;
|
||||
float scroller_proportion;
|
||||
|
|
@ -466,6 +465,9 @@ struct Client {
|
|||
int32_t grid_col_idx;
|
||||
int32_t grid_row_idx;
|
||||
uint32_t id;
|
||||
Client *group_prev;
|
||||
Client *group_next;
|
||||
bool isgroupfocusing;
|
||||
};
|
||||
|
||||
typedef struct {
|
||||
|
|
@ -804,7 +806,7 @@ static void clear_fullscreen_flag(Client *c);
|
|||
static pid_t getparentprocess(pid_t p);
|
||||
static int32_t isdescprocess(pid_t p, pid_t c);
|
||||
static Client *termforwin(Client *w);
|
||||
static void swallow(Client *c, Client *w);
|
||||
static void client_replace(Client *c, Client *w, bool isgroupaction);
|
||||
|
||||
static void warp_cursor_to_selmon(Monitor *m);
|
||||
uint32_t want_restore_fullscreen(Client *target_client);
|
||||
|
|
@ -936,6 +938,8 @@ static void overview_backup_surface(Client *c);
|
|||
static void create_jump_hints(Monitor *m);
|
||||
static void finish_jump_mode(Monitor *m);
|
||||
static void begin_jump_mode(Monitor *m);
|
||||
static void global_draw_tab_bar(Client *c, int32_t x, int32_t y, int32_t width,
|
||||
int32_t height);
|
||||
|
||||
#include "data/static_keymap.h"
|
||||
#include "dispatch/bind_declare.h"
|
||||
|
|
@ -1273,7 +1277,7 @@ void client_update_oldmonname_record(Client *c, Monitor *m) {
|
|||
c->oldmonname[sizeof(c->oldmonname) - 1] = '\0';
|
||||
}
|
||||
|
||||
void swallow(Client *c, Client *w) {
|
||||
void client_replace(Client *c, Client *w, bool isgroupaction) {
|
||||
c->bw = w->bw;
|
||||
c->isfloating = w->isfloating;
|
||||
c->isurgent = w->isurgent;
|
||||
|
|
@ -1288,10 +1292,43 @@ void swallow(Client *c, Client *w) {
|
|||
c->scroller_proportion = w->scroller_proportion;
|
||||
c->isglobal = w->isglobal;
|
||||
c->overview_backup_geom = w->overview_backup_geom;
|
||||
|
||||
/* 调整 w 的邻居指针,让它们指向 c */
|
||||
c->animation.current = w->animation.current;
|
||||
c->stack_proportion = w->stack_proportion;
|
||||
|
||||
if (!isgroupaction) {
|
||||
|
||||
if (w->group_prev == c) {
|
||||
c->group_next = w->group_next;
|
||||
if (w->group_next) {
|
||||
w->group_next->group_prev = c;
|
||||
}
|
||||
} else if (w->group_next == c) {
|
||||
c->group_prev = w->group_prev;
|
||||
if (w->group_prev) {
|
||||
w->group_prev->group_next = c;
|
||||
}
|
||||
} else {
|
||||
c->group_prev = w->group_prev;
|
||||
c->group_next = w->group_next;
|
||||
if (w->group_prev) {
|
||||
w->group_prev->group_next = c;
|
||||
}
|
||||
|
||||
if (w->group_next) {
|
||||
w->group_next->group_prev = c;
|
||||
}
|
||||
}
|
||||
|
||||
if (!c->group_prev && !c->group_next) {
|
||||
c->isgroupfocusing = false;
|
||||
} else {
|
||||
c->isgroupfocusing = w->isgroupfocusing;
|
||||
}
|
||||
|
||||
if (c->isgroupfocusing)
|
||||
mango_tab_bar_node_set_focus(c->tab_bar_node, true);
|
||||
}
|
||||
|
||||
if (w->overview_scene_surface) {
|
||||
wlr_scene_node_destroy(&w->scene_surface->node);
|
||||
w->scene_surface = w->overview_scene_surface;
|
||||
|
|
@ -1302,13 +1339,36 @@ void swallow(Client *c, Client *w) {
|
|||
overview_backup_surface(c);
|
||||
}
|
||||
|
||||
if (w->tab_bar_node) {
|
||||
if (w->tab_bar_node && !isgroupaction) {
|
||||
wlr_scene_node_set_enabled(&w->tab_bar_node->scene_buffer->node, false);
|
||||
}
|
||||
|
||||
/* 全局链表替换 */
|
||||
wl_list_insert(&w->link, &c->link);
|
||||
wl_list_insert(&w->flink, &c->flink);
|
||||
if (c->link.prev && c->link.next && c->link.prev != &c->link) {
|
||||
wl_list_remove(&c->link);
|
||||
}
|
||||
wl_list_init(&c->link);
|
||||
|
||||
if (c->flink.prev && c->flink.next && c->flink.prev != &c->flink) {
|
||||
wl_list_remove(&c->flink);
|
||||
}
|
||||
wl_list_init(&c->flink);
|
||||
|
||||
if (w->link.prev && w->link.next && w->link.prev != &w->link) {
|
||||
wl_list_insert(w->link.prev, &c->link);
|
||||
wl_list_remove(&w->link);
|
||||
wl_list_init(&w->link);
|
||||
}
|
||||
|
||||
if (w->flink.prev && w->flink.next && w->flink.prev != &w->flink) {
|
||||
if (selmon && c == selmon->sel) {
|
||||
wl_list_insert(&fstack, &c->flink);
|
||||
} else {
|
||||
wl_list_insert(w->flink.prev, &c->flink);
|
||||
}
|
||||
wl_list_remove(&w->flink);
|
||||
wl_list_init(&w->flink);
|
||||
}
|
||||
/* --------------------------------------------------------------------- */
|
||||
|
||||
if (w->foreign_toplevel) {
|
||||
wlr_foreign_toplevel_handle_v1_output_leave(w->foreign_toplevel,
|
||||
|
|
@ -1357,12 +1417,10 @@ void swallow(Client *c, Client *w) {
|
|||
struct TagScrollerState *st = w->mon->pertag->scroller_state[t];
|
||||
if (!st)
|
||||
continue;
|
||||
/* 先移除 c 在任意 tag 中的旧节点 */
|
||||
struct ScrollerStackNode *cn = find_scroller_node(st, c);
|
||||
if (cn)
|
||||
scroller_node_remove(st, cn);
|
||||
|
||||
/* 将 w 的节点(如果存在)转给 c */
|
||||
struct ScrollerStackNode *wn = find_scroller_node(st, w);
|
||||
if (wn)
|
||||
wn->client = c;
|
||||
|
|
@ -1780,11 +1838,9 @@ void applyrules(Client *c) {
|
|||
if (p && !p->isminimized) {
|
||||
c->swallowedby = p;
|
||||
p->swallowing = c;
|
||||
wl_list_remove(&c->link);
|
||||
wl_list_remove(&c->flink);
|
||||
swallow(c, p);
|
||||
wl_list_remove(&p->link);
|
||||
wl_list_remove(&p->flink);
|
||||
|
||||
client_replace(c, p, false);
|
||||
|
||||
mon = p->mon;
|
||||
newtags = p->tags;
|
||||
}
|
||||
|
|
@ -1799,7 +1855,10 @@ void applyrules(Client *c) {
|
|||
(!c->istagsilent || !newtags || newtags & mon->tagset[mon->seltags]);
|
||||
|
||||
if (!should_init_get_focus) {
|
||||
wl_list_remove(&c->flink);
|
||||
if (c->flink.prev && c->flink.next && c->flink.prev != &c->flink) {
|
||||
wl_list_remove(&c->flink);
|
||||
wl_list_init(&c->flink);
|
||||
}
|
||||
wl_list_insert(fstack.prev, &c->flink);
|
||||
}
|
||||
|
||||
|
|
@ -1836,7 +1895,10 @@ void applyrules(Client *c) {
|
|||
}
|
||||
|
||||
if (c->isfloating && !c->iscustompos && !c->isnamedscratchpad) {
|
||||
wl_list_remove(&c->link);
|
||||
if (c->link.prev && c->link.next && c->link.prev != &c->link) {
|
||||
wl_list_remove(&c->link);
|
||||
wl_list_init(&c->link);
|
||||
}
|
||||
wl_list_insert(clients.prev, &c->link);
|
||||
set_float_malposition(c);
|
||||
}
|
||||
|
|
@ -2425,7 +2487,7 @@ bool handle_buttonpress(struct wlr_pointer_button_event *event) {
|
|||
MangoNodeData *mangonodedata = (MangoNodeData *)node->data;
|
||||
if (mangonodedata->type == MANGO_TITLE_NODE) {
|
||||
Client *c = mangonodedata->node_data;
|
||||
focusclient(c, 1);
|
||||
client_focus_group_member(c);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -2592,6 +2654,7 @@ void cleanuplisteners(void) {
|
|||
wl_list_remove(&new_foreign_toplevel_capture_request.link);
|
||||
wl_list_remove(&tearing_new_object.link);
|
||||
wl_list_remove(&keyboard_shortcuts_inhibit_new_inhibitor.link);
|
||||
wl_list_remove(&ext_image_copy_capture_mgr_new_session.link);
|
||||
if (drm_lease_manager) {
|
||||
wl_list_remove(&drm_lease_request.link);
|
||||
}
|
||||
|
|
@ -2602,6 +2665,8 @@ void cleanuplisteners(void) {
|
|||
}
|
||||
|
||||
void cleanup(void) {
|
||||
allow_frame_scheduling = false;
|
||||
|
||||
ipc_cleanup();
|
||||
cleanuplisteners();
|
||||
#ifdef XWAYLAND
|
||||
|
|
@ -3519,30 +3584,22 @@ void destroyinputdevice(struct wl_listener *listener, void *data) {
|
|||
InputDevice *input_dev =
|
||||
wl_container_of(listener, input_dev, destroy_listener);
|
||||
|
||||
// 清理设备特定数据
|
||||
if (input_dev->device_data) {
|
||||
// 根据设备类型进行特定清理
|
||||
switch (input_dev->wlr_device->type) {
|
||||
case WLR_INPUT_DEVICE_SWITCH: {
|
||||
Switch *sw = (Switch *)input_dev->device_data;
|
||||
// 移除 toggle 监听器
|
||||
wl_list_remove(&sw->toggle.link);
|
||||
// 释放 Switch 内存
|
||||
free(sw);
|
||||
break;
|
||||
}
|
||||
// 可以添加其他设备类型的清理代码
|
||||
default:
|
||||
break;
|
||||
}
|
||||
input_dev->device_data = NULL;
|
||||
}
|
||||
|
||||
// 从设备列表中移除
|
||||
wl_list_remove(&input_dev->link);
|
||||
// 移除 destroy 监听器
|
||||
wl_list_remove(&input_dev->destroy_listener.link);
|
||||
// 释放内存
|
||||
free(input_dev);
|
||||
}
|
||||
|
||||
|
|
@ -4456,9 +4513,11 @@ static void iter_xdg_scene_buffers(struct wlr_scene_buffer *buffer, int32_t sx,
|
|||
}
|
||||
|
||||
void init_client_properties(Client *c) {
|
||||
c->isgroupfocusing = false;
|
||||
c->group_prev = NULL;
|
||||
c->group_next = NULL;
|
||||
c->grid_col_per = 1.0f;
|
||||
c->grid_row_per = 1.0f;
|
||||
c->is_monocle_hide = false;
|
||||
c->jump_label_node = NULL;
|
||||
c->tab_bar_node = NULL;
|
||||
c->overview_scene_surface = NULL;
|
||||
|
|
@ -4637,6 +4696,8 @@ mapnotify(struct wl_listener *listener, void *data) {
|
|||
wlr_scene_node_set_enabled(&c->splitindicator[i]->node, false);
|
||||
}
|
||||
|
||||
client_add_tab_bar_node(c);
|
||||
|
||||
c->droparea = wlr_scene_rect_create(c->scene, 0, 0, config.dropcolor);
|
||||
wlr_scene_node_lower_to_bottom(&c->droparea->node);
|
||||
wlr_scene_node_set_position(&c->droparea->node, 0, 0);
|
||||
|
|
@ -5641,11 +5702,18 @@ setfloating(Client *c, int32_t floating) {
|
|||
}
|
||||
|
||||
void reset_maximizescreen_size(Client *c) {
|
||||
c->geom.x = c->mon->w.x + config.gappoh;
|
||||
c->geom.y = c->mon->w.y + config.gappov;
|
||||
c->geom.width = c->mon->w.width - 2 * config.gappoh;
|
||||
c->geom.height = c->mon->w.height - 2 * config.gappov;
|
||||
resize(c, c->geom, 0);
|
||||
struct wlr_box geom;
|
||||
geom.x = c->mon->w.x + config.gappoh;
|
||||
geom.y = c->mon->w.y + config.gappov;
|
||||
geom.width = c->mon->w.width - 2 * config.gappoh;
|
||||
geom.height = c->mon->w.height - 2 * config.gappov;
|
||||
|
||||
if ((c->group_next || c->group_prev) && c->tab_bar_node) {
|
||||
geom.height -= config.tab_bar_height;
|
||||
geom.y += config.tab_bar_height;
|
||||
}
|
||||
|
||||
resize(c, geom, 0);
|
||||
}
|
||||
|
||||
void exit_scroller_stack(Client *c) {
|
||||
|
|
@ -5658,7 +5726,7 @@ void exit_scroller_stack(Client *c) {
|
|||
struct ScrollerStackNode *n = find_scroller_node(st, c);
|
||||
if (n) {
|
||||
scroller_node_remove(st, n);
|
||||
return; /* 节点已移除,客户端指针已在函数内清空 */
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -5686,6 +5754,12 @@ void setmaximizescreen(Client *c, int32_t maximizescreen, bool rearrange) {
|
|||
maximizescreen_box.y = c->mon->w.y + config.gappov;
|
||||
maximizescreen_box.width = c->mon->w.width - 2 * config.gappoh;
|
||||
maximizescreen_box.height = c->mon->w.height - 2 * config.gappov;
|
||||
|
||||
if ((c->group_next || c->group_prev) && c->tab_bar_node) {
|
||||
maximizescreen_box.height -= config.tab_bar_height;
|
||||
maximizescreen_box.y += config.tab_bar_height;
|
||||
}
|
||||
|
||||
wlr_scene_node_raise_to_top(&c->scene->node);
|
||||
if (!is_scroller_layout(c->mon) || c->isfloating)
|
||||
resize(c, maximizescreen_box, 0);
|
||||
|
|
@ -6650,7 +6724,12 @@ void unmapnotify(struct wl_listener *listener, void *data) {
|
|||
|
||||
if (c->swallowedby) {
|
||||
c->swallowedby->mon = c->mon;
|
||||
swallow(c->swallowedby, c);
|
||||
client_replace(c->swallowedby, c, false);
|
||||
} else if ((c->group_next || c->group_prev) && c->isgroupfocusing) {
|
||||
Client *group_replacement =
|
||||
c->group_next ? c->group_next : c->group_prev;
|
||||
group_replacement->mon = c->mon;
|
||||
client_replace(group_replacement, c, false);
|
||||
} else {
|
||||
scroller_remove_client(c);
|
||||
dwindle_remove_client(c);
|
||||
|
|
@ -6699,7 +6778,11 @@ void unmapnotify(struct wl_listener *listener, void *data) {
|
|||
if (client_is_unmanaged(c)) {
|
||||
#ifdef XWAYLAND
|
||||
if (client_is_x11(c)) {
|
||||
wl_list_remove(&c->set_geometry.link);
|
||||
if (c->set_geometry.link.prev && c->set_geometry.link.next &&
|
||||
c->set_geometry.link.prev != &c->set_geometry.link) {
|
||||
wl_list_remove(&c->set_geometry.link);
|
||||
wl_list_init(&c->set_geometry.link);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
if (c == exclusive_focus)
|
||||
|
|
@ -6707,11 +6790,33 @@ void unmapnotify(struct wl_listener *listener, void *data) {
|
|||
if (client_surface(c) == seat->keyboard_state.focused_surface)
|
||||
focusclient(focustop(selmon), 1);
|
||||
} else {
|
||||
if (!c->swallowing)
|
||||
wl_list_remove(&c->link);
|
||||
|
||||
bool is_in_group = c->group_next || c->group_prev;
|
||||
|
||||
if (c->group_next && !c->isgroupfocusing) {
|
||||
c->group_next->group_prev = c->group_prev;
|
||||
}
|
||||
|
||||
if (c->group_prev && !c->isgroupfocusing) {
|
||||
c->group_prev->group_next = c->group_next;
|
||||
}
|
||||
|
||||
c->group_next = NULL;
|
||||
c->group_prev = NULL;
|
||||
|
||||
if (!c->swallowing && (!is_in_group || c->isgroupfocusing)) {
|
||||
if (c->link.prev && c->link.next && c->link.prev != &c->link) {
|
||||
wl_list_remove(&c->link);
|
||||
wl_list_init(&c->link);
|
||||
}
|
||||
}
|
||||
setmon(c, NULL, 0, true);
|
||||
if (!c->swallowing)
|
||||
wl_list_remove(&c->flink);
|
||||
if (!c->swallowing && (!is_in_group || c->isgroupfocusing)) {
|
||||
if (c->flink.prev && c->flink.next && c->flink.prev != &c->flink) {
|
||||
wl_list_remove(&c->flink);
|
||||
wl_list_init(&c->flink);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (c->foreign_toplevel) {
|
||||
|
|
@ -6731,8 +6836,6 @@ void unmapnotify(struct wl_listener *listener, void *data) {
|
|||
c->swallowing = NULL;
|
||||
}
|
||||
|
||||
c->stack_proportion = 0.0f;
|
||||
|
||||
if (c->jump_label_node) {
|
||||
mango_jump_label_node_destroy(c->jump_label_node);
|
||||
c->jump_label_node = NULL;
|
||||
|
|
@ -6744,6 +6847,9 @@ void unmapnotify(struct wl_listener *listener, void *data) {
|
|||
|
||||
wlr_scene_node_destroy(&c->image_capture_scene_surface->buffer->node);
|
||||
wlr_scene_node_destroy(&c->image_capture_scene->tree.node);
|
||||
|
||||
init_client_properties(c);
|
||||
|
||||
wlr_scene_node_destroy(&c->scene->node);
|
||||
printstatus(IPC_WATCH_ARRANGGE);
|
||||
motionnotify(0, NULL, 0, 0, 0, 0);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue