mirror of
https://github.com/DreamMaoMao/maomaowm.git
synced 2026-05-12 23:51:28 -04:00
opt: repl scroller layout
This commit is contained in:
parent
cabafb2393
commit
90a5d12ed4
8 changed files with 1427 additions and 925 deletions
|
|
@ -629,15 +629,106 @@ int32_t set_proportion(const Arg *arg) {
|
|||
return 0;
|
||||
|
||||
Client *tc = selmon->sel;
|
||||
if (!tc)
|
||||
return 0;
|
||||
|
||||
if (tc) {
|
||||
tc = get_scroll_stack_head(tc);
|
||||
uint32_t max_client_width =
|
||||
selmon->w.width - 2 * config.scroller_structs - config.gappih;
|
||||
tc->scroller_proportion = arg->f;
|
||||
tc->geom.width = max_client_width * arg->f;
|
||||
arrange(selmon, false, false);
|
||||
/* 获取堆叠头部客户端 */
|
||||
tc = get_scroll_stack_head(tc);
|
||||
if (!tc)
|
||||
return 0;
|
||||
|
||||
Monitor *m = tc->mon;
|
||||
uint32_t tag = m->pertag->curtag;
|
||||
struct TagScrollerState *st = m->pertag->scroller_state[tag];
|
||||
struct ScrollerStackNode *node = NULL;
|
||||
|
||||
if (st)
|
||||
node = find_scroller_node(st, tc);
|
||||
|
||||
/* 同时更新节点和客户端字段 */
|
||||
if (node)
|
||||
node->scroller_proportion = arg->f;
|
||||
tc->scroller_proportion = arg->f;
|
||||
|
||||
/* 可选的即时几何更新,arrange 时会重新计算 */
|
||||
uint32_t max_client_width =
|
||||
m->w.width - 2 * config.scroller_structs - config.gappih;
|
||||
tc->geom.width = max_client_width * arg->f;
|
||||
|
||||
arrange(m, false, false);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32_t switch_proportion_preset(const Arg *arg) {
|
||||
float target_proportion = 0;
|
||||
if (!selmon)
|
||||
return 0;
|
||||
|
||||
if (config.scroller_proportion_preset_count == 0)
|
||||
return 0;
|
||||
|
||||
if (selmon->isoverview || !is_scroller_layout(selmon))
|
||||
return 0;
|
||||
|
||||
if (selmon->visible_tiling_clients == 1 &&
|
||||
!config.scroller_ignore_proportion_single)
|
||||
return 0;
|
||||
|
||||
Client *tc = selmon->sel;
|
||||
if (!tc)
|
||||
return 0;
|
||||
|
||||
tc = get_scroll_stack_head(tc);
|
||||
if (!tc)
|
||||
return 0;
|
||||
|
||||
Monitor *m = tc->mon;
|
||||
uint32_t tag = m->pertag->curtag;
|
||||
struct TagScrollerState *st = m->pertag->scroller_state[tag];
|
||||
struct ScrollerStackNode *node = NULL;
|
||||
|
||||
if (st)
|
||||
node = find_scroller_node(st, tc);
|
||||
|
||||
/* 优先从节点读取当前比例,以确保切换基于正确的值 */
|
||||
float current_proportion =
|
||||
node ? node->scroller_proportion : tc->scroller_proportion;
|
||||
|
||||
/* 查找预设目标 */
|
||||
for (int32_t i = 0; i < config.scroller_proportion_preset_count; i++) {
|
||||
if (config.scroller_proportion_preset[i] == current_proportion) {
|
||||
if (arg->i == NEXT) {
|
||||
if (i == config.scroller_proportion_preset_count - 1)
|
||||
target_proportion = config.scroller_proportion_preset[0];
|
||||
else
|
||||
target_proportion =
|
||||
config.scroller_proportion_preset[i + 1];
|
||||
} else {
|
||||
if (i == 0)
|
||||
target_proportion =
|
||||
config.scroller_proportion_preset
|
||||
[config.scroller_proportion_preset_count - 1];
|
||||
else
|
||||
target_proportion =
|
||||
config.scroller_proportion_preset[i - 1];
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (target_proportion == 0.0f)
|
||||
target_proportion = config.scroller_proportion_preset[0];
|
||||
|
||||
/* 更新节点和客户端 */
|
||||
if (node)
|
||||
node->scroller_proportion = target_proportion;
|
||||
tc->scroller_proportion = target_proportion;
|
||||
|
||||
uint32_t max_client_width =
|
||||
m->w.width - 2 * config.scroller_structs - config.gappih;
|
||||
tc->geom.width = max_client_width * target_proportion;
|
||||
|
||||
arrange(m, false, false);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -1042,68 +1133,6 @@ int32_t switch_layout(const Arg *arg) {
|
|||
return 0;
|
||||
}
|
||||
|
||||
int32_t switch_proportion_preset(const Arg *arg) {
|
||||
float target_proportion = 0;
|
||||
if (!selmon)
|
||||
return 0;
|
||||
|
||||
if (config.scroller_proportion_preset_count == 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (selmon->isoverview || !is_scroller_layout(selmon))
|
||||
return 0;
|
||||
|
||||
if (selmon->visible_tiling_clients == 1 &&
|
||||
!config.scroller_ignore_proportion_single)
|
||||
return 0;
|
||||
|
||||
Client *tc = selmon->sel;
|
||||
|
||||
if (tc) {
|
||||
tc = get_scroll_stack_head(tc);
|
||||
for (int32_t i = 0; i < config.scroller_proportion_preset_count; i++) {
|
||||
if (config.scroller_proportion_preset[i] ==
|
||||
tc->scroller_proportion) {
|
||||
|
||||
if (arg->i == NEXT) {
|
||||
if (i == config.scroller_proportion_preset_count - 1) {
|
||||
target_proportion =
|
||||
config.scroller_proportion_preset[0];
|
||||
break;
|
||||
} else {
|
||||
target_proportion =
|
||||
config.scroller_proportion_preset[i + 1];
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
if (i == 0) {
|
||||
target_proportion =
|
||||
config.scroller_proportion_preset
|
||||
[config.scroller_proportion_preset_count - 1];
|
||||
break;
|
||||
} else {
|
||||
target_proportion =
|
||||
config.scroller_proportion_preset[i - 1];
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (target_proportion == 0) {
|
||||
target_proportion = config.scroller_proportion_preset[0];
|
||||
}
|
||||
|
||||
uint32_t max_client_width =
|
||||
selmon->w.width - 2 * config.scroller_structs - config.gappih;
|
||||
tc->scroller_proportion = target_proportion;
|
||||
tc->geom.width = max_client_width * target_proportion;
|
||||
arrange(selmon, false, false);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32_t tag(const Arg *arg) {
|
||||
if (!selmon)
|
||||
return 0;
|
||||
|
|
@ -1202,7 +1231,6 @@ int32_t tagsilent(const Arg *arg) {
|
|||
clear_fullscreen_flag(fc);
|
||||
}
|
||||
}
|
||||
exit_scroller_stack(target_client);
|
||||
focusclient(focustop(selmon), 1);
|
||||
arrange(target_client->mon, false, false);
|
||||
return 0;
|
||||
|
|
@ -1355,7 +1383,6 @@ int32_t toggleglobal(const Arg *arg) {
|
|||
selmon->sel->isglobal ^= 1;
|
||||
if (selmon->sel->isglobal &&
|
||||
(selmon->sel->prev_in_stack || selmon->sel->next_in_stack)) {
|
||||
exit_scroller_stack(selmon->sel);
|
||||
arrange(selmon, false, false);
|
||||
}
|
||||
setborder_color(selmon->sel);
|
||||
|
|
@ -1780,76 +1807,69 @@ int32_t toggle_monitor(const Arg *arg) {
|
|||
|
||||
int32_t scroller_apply_stack(Client *c, Client *target_client,
|
||||
int32_t direction) {
|
||||
if (!c || !c->mon || c->isfloating || !is_scroller_layout(c->mon))
|
||||
return 0;
|
||||
|
||||
Client *source_stack_head = NULL;
|
||||
Client *stack_head = NULL;
|
||||
bool is_horizontal_layout =
|
||||
c->mon->pertag->ltidxs[c->mon->pertag->curtag]->id == SCROLLER ? true
|
||||
: false;
|
||||
Monitor *m = c->mon;
|
||||
uint32_t tag = m->pertag->curtag;
|
||||
struct TagScrollerState *st = ensure_scroller_state(m, tag);
|
||||
|
||||
if (target_client) {
|
||||
stack_head = get_scroll_stack_head(target_client);
|
||||
}
|
||||
/* 获取当前节点 */
|
||||
struct ScrollerStackNode *cnode = find_scroller_node(st, c);
|
||||
struct ScrollerStackNode *tnode =
|
||||
target_client ? find_scroller_node(st, target_client) : NULL;
|
||||
|
||||
source_stack_head = get_scroll_stack_head(c);
|
||||
bool is_horizontal = (m->pertag->ltidxs[tag]->id == SCROLLER);
|
||||
|
||||
if (source_stack_head == stack_head) {
|
||||
/* 若方向为 UNDIR 且有目标,直接插入到目标尾部 */
|
||||
if (direction == UNDIR && target_client && target_client->mon == c->mon) {
|
||||
scroller_insert_stack(c, target_client, false);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (c->isfullscreen) {
|
||||
setfullscreen(c, 0);
|
||||
}
|
||||
/* 处理从堆叠中移出的情况(方向 LEFT/UP 或 RIGHT/DOWN) */
|
||||
if (cnode && (cnode->prev_in_stack || cnode->next_in_stack)) {
|
||||
bool to_left_or_up = (is_horizontal && direction == LEFT) ||
|
||||
(!is_horizontal && direction == UP);
|
||||
bool to_right_or_down = (is_horizontal && direction == RIGHT) ||
|
||||
(!is_horizontal && direction == DOWN);
|
||||
|
||||
if (c->ismaximizescreen) {
|
||||
setmaximizescreen(c, 0);
|
||||
}
|
||||
if (to_left_or_up || to_right_or_down) {
|
||||
/* 找到当前堆叠的头节点,以便移动全局链表位置 */
|
||||
struct ScrollerStackNode *head = cnode;
|
||||
while (head->prev_in_stack)
|
||||
head = head->prev_in_stack;
|
||||
Client *source_stack_head = head->client;
|
||||
|
||||
if (c->prev_in_stack && direction != UNDIR) {
|
||||
if ((is_horizontal_layout && direction == LEFT) ||
|
||||
(!is_horizontal_layout && direction == UP)) {
|
||||
exit_scroller_stack(c);
|
||||
/* 从 tag 状态中移除该客户端对应的节点 */
|
||||
scroller_node_remove(st, cnode);
|
||||
/* 重新创建一个独立的节点(无堆叠关系) */
|
||||
scroller_node_create(st, c);
|
||||
|
||||
/* 调整全局客户端链表顺序:移到源堆叠头的前面或后面 */
|
||||
wl_list_remove(&c->link);
|
||||
wl_list_insert(source_stack_head->link.prev, &c->link);
|
||||
arrange(selmon, false, false);
|
||||
if (to_left_or_up)
|
||||
wl_list_insert(source_stack_head->link.prev, &c->link);
|
||||
else
|
||||
wl_list_insert(&source_stack_head->link, &c->link);
|
||||
|
||||
} else if ((is_horizontal_layout && direction == RIGHT) ||
|
||||
(!is_horizontal_layout && direction == DOWN)) {
|
||||
exit_scroller_stack(c);
|
||||
wl_list_remove(&c->link);
|
||||
wl_list_insert(&source_stack_head->link, &c->link);
|
||||
arrange(selmon, false, false);
|
||||
/* 同步到客户端字段并重排 */
|
||||
sync_scroller_state_to_clients(m, tag);
|
||||
arrange(m, false, false);
|
||||
return 0;
|
||||
}
|
||||
return 0;
|
||||
} else if (c->next_in_stack && direction != UNDIR) {
|
||||
Client *next_in_stack = c->next_in_stack;
|
||||
if ((is_horizontal_layout && direction == LEFT) ||
|
||||
(!is_horizontal_layout && direction == UP)) {
|
||||
exit_scroller_stack(c);
|
||||
wl_list_remove(&c->link);
|
||||
wl_list_insert(next_in_stack->link.prev, &c->link);
|
||||
arrange(selmon, false, false);
|
||||
} else if ((is_horizontal_layout && direction == RIGHT) ||
|
||||
(!is_horizontal_layout && direction == DOWN)) {
|
||||
exit_scroller_stack(c);
|
||||
wl_list_remove(&c->link);
|
||||
wl_list_insert(&next_in_stack->link, &c->link);
|
||||
arrange(selmon, false, false);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!target_client || target_client->mon != c->mon) {
|
||||
if (!target_client || target_client->mon != c->mon)
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Find the tail of target_client's stack
|
||||
Client *stack_tail = target_client;
|
||||
while (stack_tail->next_in_stack) {
|
||||
stack_tail = stack_tail->next_in_stack;
|
||||
}
|
||||
/* 找到目标堆叠的尾部节点 */
|
||||
struct ScrollerStackNode *tail = tnode;
|
||||
while (tail->next_in_stack)
|
||||
tail = tail->next_in_stack;
|
||||
|
||||
scroller_insert_stack(c, stack_tail, false);
|
||||
/* 通过封装好的插入函数实现(尾部插入) */
|
||||
scroller_insert_stack(c, tail->client, false);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue