From d0ed1789332f6077b4a9f4492da8443e34f89333 Mon Sep 17 00:00:00 2001 From: DreamMaoMao <2523610504@qq.com> Date: Fri, 10 Oct 2025 15:35:56 +0800 Subject: [PATCH] fix drag action in virtical --- src/layout/layout.h | 3 - src/layout/vertical.h | 67 ------------------- src/mango.c | 148 ++++++++++++++++++++++++++++++++++++++---- 3 files changed, 137 insertions(+), 81 deletions(-) diff --git a/src/layout/layout.h b/src/layout/layout.h index db1353d..a0c9bd2 100644 --- a/src/layout/layout.h +++ b/src/layout/layout.h @@ -23,8 +23,6 @@ enum { CENTER_TILE, VERTICAL_SCROLLER, VERTICAL_TILE, - VERTICAL_GRID, - VERTICAL_DECK }; Layout layouts[] = { @@ -39,5 +37,4 @@ Layout layouts[] = { {"VS", vertical_scroller, "vertical_scroller", VERTICAL_SCROLLER}, // 垂直滚动布局 {"VT", vertical_tile, "vertical_tile", VERTICAL_TILE}, // 垂直平铺布局 - {"VK", vertical_deck, "vertical_deck", VERTICAL_DECK}, // 垂直卡片布局 }; \ No newline at end of file diff --git a/src/layout/vertical.h b/src/layout/vertical.h index 4986d9f..1d555bf 100644 --- a/src/layout/vertical.h +++ b/src/layout/vertical.h @@ -1,70 +1,3 @@ -void vertical_deck(Monitor *m) { - unsigned int mh, mx; - int i, n = 0; - Client *c = NULL; - Client *fc = NULL; - float mfact; - - unsigned int cur_gapiv = enablegaps ? m->gappiv : 0; - unsigned int cur_gapih = enablegaps ? m->gappih : 0; - unsigned int cur_gapov = enablegaps ? m->gappov : 0; - - cur_gapiv = smartgaps && m->visible_tiling_clients == 1 ? 0 : cur_gapiv; - cur_gapih = smartgaps && m->visible_tiling_clients == 1 ? 0 : cur_gapih; - cur_gapov = smartgaps && m->visible_tiling_clients == 1 ? 0 : cur_gapov; - - n = m->visible_tiling_clients; - - if (n == 0) - return; - - wl_list_for_each(fc, &clients, link) { - if (VISIBLEON(fc, m) && ISTILED(fc)) - break; - } - - // Calculate master height using mfact from pertag - mfact = fc->master_mfact_per > 0.0f ? fc->master_mfact_per - : m->pertag->mfacts[m->pertag->curtag]; - - // Calculate master height including outer gaps - if (n > m->nmaster) - mh = m->nmaster ? round((m->w.height - 2 * cur_gapov) * mfact) : 0; - else - mh = m->w.height - 2 * cur_gapov; - - i = mx = 0; - wl_list_for_each(c, &clients, link) { - if (!VISIBLEON(c, m) || !ISTILED(c)) - continue; - if (i < m->nmaster) { - c->master_mfact_per = mfact; - // Master area clients - resize(c, - (struct wlr_box){.x = m->w.x + cur_gapih, - .y = m->w.y + cur_gapov, - .width = (m->w.width - 2 * cur_gapih - mx) / - (MIN(n, m->nmaster) - i), - .height = mh}, - 0); - mx += c->geom.width; - } else { - // Stack area clients - c->master_mfact_per = mfact; - resize(c, - (struct wlr_box){.x = m->w.x + cur_gapih, - .y = m->w.y + mh + cur_gapov + cur_gapiv, - .width = m->w.width - 2 * cur_gapih, - .height = m->w.height - mh - 2 * cur_gapov - - cur_gapiv}, - 0); - if (c == focustop(m)) - wlr_scene_node_raise_to_top(&c->scene->node); - } - i++; - } -} - void vertical_tile(Monitor *m) { unsigned int i, n = 0, w, r, ie = enablegaps, mh, mx, tx; Client *c = NULL; diff --git a/src/mango.c b/src/mango.c index 45c4556..108697f 100644 --- a/src/mango.c +++ b/src/mango.c @@ -3941,12 +3941,11 @@ void motionabsolute(struct wl_listener *listener, void *data) { motionnotify(event->time_msec, &event->pointer->base, dx, dy, dx, dy); } -void resize_tile_master(Client *grabc, unsigned int time, int type) { +void resize_tile_master_horizontal(Client *grabc, unsigned int time, int type) { Client *tc = NULL; float delta_x, delta_y; Client *next = NULL; Client *prev = NULL; - int tempdelta = 0; double refresh_interval = 1000000.0 / grabc->mon->wlr_output->refresh; struct wl_list *node; @@ -4053,12 +4052,6 @@ void resize_tile_master(Client *grabc, unsigned int time, int type) { delta_x = delta_x * 2; } - if (type == VERTICAL_TILE || type == VERTICAL_DECK) { - tempdelta = delta_x; - delta_x = delta_y; - delta_y = tempdelta; - } - // 直接设置新的比例,基于初始值 + 变化量 float new_master_mfact_per = grabc->old_master_mfact_per + delta_x; float new_master_inner_per = grabc->old_master_inner_per + delta_y; @@ -4087,6 +4080,138 @@ void resize_tile_master(Client *grabc, unsigned int time, int type) { } } +void resize_tile_master_vertical(Client *grabc, unsigned int time, int type) { + Client *tc = NULL; + float delta_x, delta_y; + Client *next = NULL; + Client *prev = NULL; + double refresh_interval = 1000000.0 / grabc->mon->wlr_output->refresh; + struct wl_list *node; + + // 从当前节点的下一个开始遍历 + for (node = grabc->link.next; node != &clients; node = node->next) { + tc = wl_container_of(node, tc, link); + if (!tc->isfloating) { // 根据你的实际字段名调整 + next = tc; + break; + } + } + + // 从当前节点的上一个开始遍历 + for (node = grabc->link.prev; node != &clients; node = node->prev) { + tc = wl_container_of(node, tc, link); + if (!tc->isfloating) { // 根据你的实际字段名调整 + prev = tc; + break; + } + } + if (!start_drag_window) { + begin_cursorx = cursor->x; + begin_cursory = cursor->y; + start_drag_window = true; + + // 记录初始状态 + grabc->old_master_mfact_per = grabc->master_mfact_per; + grabc->old_master_inner_per = grabc->master_inner_per; + grabc->old_slave_innder_per = grabc->slave_innder_per; + grabc->cursor_in_upper_half = + cursor->y < grabc->geom.y + grabc->geom.height / 2; + grabc->cursor_in_left_half = + cursor->x < grabc->geom.x + grabc->geom.width / 2; + // 记录初始几何信息 + grabc->begin_geom = grabc->geom; + } else { + // 计算相对于屏幕尺寸的比例变化 + if (grabc->ismaster) { + // 垂直版本:左右移动调整高度比例,上下移动调整宽度比例 + delta_x = (float)(cursor->x - begin_cursorx) * + (grabc->old_master_inner_per) / grabc->begin_geom.width; + delta_y = (float)(cursor->y - begin_cursory) * + (grabc->old_master_mfact_per) / grabc->begin_geom.height; + } else { + delta_x = (float)(cursor->x - begin_cursorx) * + (grabc->old_slave_innder_per) / grabc->begin_geom.width; + delta_y = (float)(cursor->y - begin_cursory) * + (1 - grabc->old_master_mfact_per) / + grabc->begin_geom.height; + } + + bool moving_left = cursor->x < begin_cursorx; + bool moving_right = cursor->x > begin_cursorx; + + // 调整主区域和栈区域的高度比例(垂直分割) + if (grabc->ismaster && !prev) { + if (moving_left) { + delta_x = -fabsf(delta_x); // 向上移动减少主区域高度 + } else { + delta_x = fabsf(delta_x); // 向下移动增加主区域高度 + } + } else if (grabc->ismaster && next && !next->ismaster) { + if (moving_left) { + delta_x = fabsf(delta_x); // 向上移动增加主区域高度 + } else { + delta_x = -fabsf(delta_x); // 向下移动减少主区域高度 + } + } else if (!grabc->ismaster && prev && prev->ismaster) { + if (moving_left) { + delta_x = -fabsf(delta_x); // 向上移动减少栈区域高度 + } else { + delta_x = fabsf(delta_x); // 向下移动增加栈区域高度 + } + } else if (!grabc->ismaster && !next) { + if (moving_left) { + delta_x = fabsf(delta_x); // 向上移动增加栈区域高度 + } else { + delta_x = -fabsf(delta_x); // 向下移动减少栈区域高度 + } + } else if ((grabc->cursor_in_left_half && moving_left) || + (!grabc->cursor_in_left_half && moving_right)) { + // 光标在窗口左侧且向左移动,或在窗口右侧且向右移动 → 增加宽度 + delta_x = fabsf(delta_x); + } else { + // 其他情况 → 减小宽度 + delta_x = -fabsf(delta_x); + } + + if (!grabc->ismaster && grabc->isleftslave && type == CENTER_TILE) { + delta_x = delta_x * -1.0f; + } + + // if (grabc->ismaster && type == CENTER_TILE) { + // delta_x = delta_x * 2; + // } + + // 直接设置新的比例,基于初始值 + 变化量 + float new_master_mfact_per = grabc->old_master_mfact_per + + delta_y; // 垂直:delta_y调整主区域高度 + float new_master_inner_per = grabc->old_master_inner_per + + delta_x; // 垂直:delta_x调整主区域内部宽度 + float new_slave_innder_per = grabc->old_slave_innder_per + + delta_x; // 垂直:delta_x调整栈区域内部宽度 + + // 应用限制,确保比例在合理范围内 + new_master_mfact_per = fmaxf(0.1f, fminf(0.9f, new_master_mfact_per)); + new_master_inner_per = fmaxf(0.1f, fminf(0.9f, new_master_inner_per)); + new_slave_innder_per = fmaxf(0.1f, fminf(0.9f, new_slave_innder_per)); + + // 应用到所有平铺窗口 + wl_list_for_each(tc, &clients, link) { + if (VISIBLEON(tc, grabc->mon) && ISTILED(tc)) { + tc->master_mfact_per = new_master_mfact_per; + } + } + + grabc->master_inner_per = new_master_inner_per; + grabc->slave_innder_per = new_slave_innder_per; + + if (last_apply_drap_time == 0 || + time - last_apply_drap_time > refresh_interval) { + arrange(grabc->mon, false); + last_apply_drap_time = time; + } + } +} + void resize_tile_scroller(Client *grabc, unsigned int time, bool isvertical) { float delta_x, delta_y; float new_scroller_proportion; @@ -4158,12 +4283,13 @@ void resize_tile_scroller(Client *grabc, unsigned int time, bool isvertical) { void resize_tile_client(Client *grabc, unsigned int time) { const Layout *current_layout = grabc->mon->pertag->ltidxs[grabc->mon->pertag->curtag]; - if (current_layout->id == TILE || current_layout->id == VERTICAL_TILE || - current_layout->id == DECK || current_layout->id == VERTICAL_DECK || + if (current_layout->id == TILE || current_layout->id == DECK || current_layout->id == CENTER_TILE ) { - resize_tile_master(grabc, time, current_layout->id); + resize_tile_master_horizontal(grabc, time, current_layout->id); + } else if (current_layout->id == VERTICAL_TILE) { + resize_tile_master_vertical(grabc, time, current_layout->id); } else if (current_layout->id == SCROLLER) { resize_tile_scroller(grabc, time, false); } else if (current_layout->id == VERTICAL_SCROLLER) {