From 67334cfeb60d3a0d3c490e6714ab7e47d8242980 Mon Sep 17 00:00:00 2001 From: DreamMaoMao <2523610504@qq.com> Date: Fri, 10 Oct 2025 13:26:35 +0800 Subject: [PATCH] feat: center_tile support resize in tile --- src/layout/horizontal.h | 180 +++++++++++++++++++++++++++++----------- src/mango.c | 9 -- 2 files changed, 130 insertions(+), 59 deletions(-) diff --git a/src/layout/horizontal.h b/src/layout/horizontal.h index 3c164d1..4c3fd24 100644 --- a/src/layout/horizontal.h +++ b/src/layout/horizontal.h @@ -122,6 +122,9 @@ void deck(Monitor *m) { unsigned int mw, my; int i, n = 0; Client *c = NULL; + Client *fc = NULL; + float mfact; + unsigned int cur_gappih = enablegaps ? m->gappih : 0; unsigned int cur_gappoh = enablegaps ? m->gappoh : 0; unsigned int cur_gappov = enablegaps ? m->gappov : 0; @@ -135,8 +138,15 @@ void deck(Monitor *m) { if (n == 0) return; + wl_list_for_each(fc, &clients, link) { + + if (VISIBLEON(fc, m) && ISTILED(fc)) + break; + } + // Calculate master width using mfact from pertag - float mfact = m->pertag ? m->pertag->mfacts[m->pertag->curtag] : m->mfact; + mfact = fc->master_width_per > 0.0f ? fc->master_width_per + : m->pertag->mfacts[m->pertag->curtag]; // Calculate master width including outer gaps if (n > m->nmaster) @@ -149,6 +159,7 @@ void deck(Monitor *m) { if (!VISIBLEON(c, m) || !ISTILED(c)) continue; if (i < m->nmaster) { + c->master_width_per = mfact; // Master area clients resize( c, @@ -161,6 +172,7 @@ void deck(Monitor *m) { my += c->geom.height; } else { // Stack area clients + c->master_width_per = mfact; resize(c, (struct wlr_box){.x = m->w.x + mw + cur_gappoh + cur_gappih, .y = m->w.y + cur_gappov, @@ -260,6 +272,9 @@ void scroller(Monitor *m) { } } + if (start_drag_window) + need_scroller = false; + target_geom.height = m->w.height - 2 * cur_gappov; target_geom.width = max_client_width * c->scroller_proportion; target_geom.y = m->w.y + (m->w.height - target_geom.height) / 2; @@ -308,31 +323,41 @@ void scroller(Monitor *m) { } void center_tile(Monitor *m) { - unsigned int i, n = 0, h, mw, mx, my, oty, ety, tw; + unsigned int i, n = 0, h, r, ie = enablegaps, mw, mx, my, oty, ety, tw; Client *c = NULL; + Client *fc = NULL; + double mfact = 0; n = m->visible_tiling_clients; if (n == 0) return; - // 间隙参数处理 - unsigned int gappiv = enablegaps ? m->gappiv : 0; // 内部垂直间隙 - unsigned int gappih = enablegaps ? m->gappih : 0; // 内部水平间隙 - unsigned int gappov = enablegaps ? m->gappov : 0; // 外部垂直间隙 - unsigned int gappoh = enablegaps ? m->gappoh : 0; // 外部水平间隙 - - // 智能间隙处理 - if (smartgaps && n == 1) { - gappiv = gappih = gappov = gappoh = 0; + // 获取第一个可见的平铺客户端用于主区域宽度百分比 + wl_list_for_each(fc, &clients, link) { + if (VISIBLEON(fc, m) && ISTILED(fc)) + break; } + // 间隙参数处理 + unsigned int cur_gappiv = enablegaps ? m->gappiv : 0; // 内部垂直间隙 + unsigned int cur_gappih = enablegaps ? m->gappih : 0; // 内部水平间隙 + unsigned int cur_gappov = enablegaps ? m->gappov : 0; // 外部垂直间隙 + unsigned int cur_gappoh = enablegaps ? m->gappoh : 0; // 外部水平间隙 + + // 智能间隙处理 + cur_gappiv = smartgaps && m->visible_tiling_clients == 1 ? 0 : cur_gappiv; + cur_gappih = smartgaps && m->visible_tiling_clients == 1 ? 0 : cur_gappih; + cur_gappov = smartgaps && m->visible_tiling_clients == 1 ? 0 : cur_gappov; + cur_gappoh = smartgaps && m->visible_tiling_clients == 1 ? 0 : cur_gappoh; + unsigned int nmasters = m->pertag->nmasters[m->pertag->curtag]; - float mfact = m->pertag->mfacts[m->pertag->curtag]; + mfact = fc->master_width_per > 0.0f ? fc->master_width_per + : m->pertag->mfacts[m->pertag->curtag]; // 初始化区域 mw = m->w.width; - mx = gappoh; - my = gappov; + mx = cur_gappoh; + my = cur_gappov; tw = mw; // 判断是否需要主区域铺满 @@ -340,37 +365,38 @@ void center_tile(Monitor *m) { if (n > nmasters || !should_overspread) { // 计算主区域宽度(居中模式) - mw = nmasters ? (m->w.width - 2 * gappoh - gappih) * mfact : 0; + mw = nmasters ? (m->w.width - 2 * cur_gappoh - cur_gappih * ie) * mfact + : 0; if (n - nmasters > 1) { // 多个堆叠窗口:主区域居中,左右两侧各有一个堆叠区域 - tw = (m->w.width - mw) / 2 - gappoh - gappih; - mx = gappoh + tw + gappih; + tw = (m->w.width - mw) / 2 - cur_gappoh - cur_gappih * ie; + mx = cur_gappoh + tw + cur_gappih * ie; } else if (n - nmasters == 1) { // 单个堆叠窗口的处理 if (center_when_single_slave) { - // 修改:slave在右边,master居中,左边空着 - tw = (m->w.width - mw) / 2 - gappoh - gappih; - mx = gappoh + tw + gappih; // master居中 + // slave在右边,master居中,左边空着 + tw = (m->w.width - mw) / 2 - cur_gappoh - cur_gappih * ie; + mx = cur_gappoh + tw + cur_gappih * ie; // master居中 } else { // slave在右边,master在左边 - tw = m->w.width - mw - 2 * gappoh - gappih; - mx = gappoh; // master在左边 + tw = m->w.width - mw - 2 * cur_gappoh - cur_gappih * ie; + mx = cur_gappoh; // master在左边 } } else { // 只有主区域窗口:居中显示 - tw = (m->w.width - mw) / 2 - gappoh - gappih; - mx = gappoh + tw + gappih; + tw = (m->w.width - mw) / 2 - cur_gappoh - cur_gappih * ie; + mx = cur_gappoh + tw + cur_gappih * ie; } } else { // 主区域铺满模式(只有主区域窗口时) - mw = m->w.width - 2 * gappoh; - mx = gappoh; + mw = m->w.width - 2 * cur_gappoh; + mx = cur_gappoh; tw = 0; // 堆叠区域宽度为0 } - oty = gappov; - ety = gappov; + oty = cur_gappov; + ety = cur_gappov; i = 0; wl_list_for_each(c, &clients, link) { @@ -379,68 +405,118 @@ void center_tile(Monitor *m) { if (i < nmasters) { // 主区域窗口 - unsigned int r = MIN(n, nmasters) - i; - h = (m->w.height - my - gappov - gappiv * (r - 1)) / r; + r = MIN(n, nmasters) - i; + if (c->master_height_per > 0.0f) { + h = (m->w.height - 2 * cur_gappov - cur_gappiv * ie * (r - 1)) * + c->master_height_per; + c->master_width_per = mfact; + } else { + h = (m->w.height - my - cur_gappov - + cur_gappiv * ie * (r - 1)) / + r; + c->master_height_per = h / (m->w.height - my - cur_gappov - + cur_gappiv * ie * (r - 1)); + c->master_width_per = mfact; + } resize(c, (struct wlr_box){.x = m->w.x + mx, .y = m->w.y + my, - .width = mw, + .width = mw - cur_gappih * ie, .height = h}, 0); - my += c->geom.height + gappiv; + my += c->geom.height + cur_gappiv * ie; } else { // 堆叠区域窗口 unsigned int stack_index = i - nmasters; if (n - nmasters == 1) { // 单个堆叠窗口 - unsigned int r = n - i; - h = (m->w.height - ety - gappov - gappiv * (r - 1)) / r; + r = n - i; + if (c->slave_height_per > 0.0f) { + h = (m->w.height - 2 * cur_gappov - + cur_gappiv * ie * (r - 1)) * + c->slave_height_per; + c->master_width_per = mfact; + } else { + h = (m->w.height - ety - cur_gappov - + cur_gappiv * ie * (r - 1)) / + r; + c->slave_height_per = h / (m->w.height - ety - cur_gappov - + cur_gappiv * ie * (r - 1)); + c->master_width_per = mfact; + } int stack_x; if (center_when_single_slave) { - // 修改:放在右侧(master居中时,slave在右边) - stack_x = m->w.x + mx + mw + gappih; + // 放在右侧(master居中时,slave在右边) + stack_x = m->w.x + mx + mw + cur_gappih * ie; } else { // 放在右侧(master在左边时,slave在右边) - stack_x = m->w.x + mx + mw + gappih; + stack_x = m->w.x + mx + mw + cur_gappih * ie; } resize(c, (struct wlr_box){.x = stack_x, .y = m->w.y + ety, - .width = tw, + .width = tw - cur_gappih * ie, .height = h}, 0); - ety += c->geom.height + gappiv; + ety += c->geom.height + cur_gappiv * ie; } else { // 多个堆叠窗口:交替放在左右两侧 - unsigned int r = (n - i + 1) / 2; + r = (n - i + 1) / 2; - // 当n为偶数时翻转判断逻辑 if ((stack_index % 2) ^ (n % 2 == 0)) { // 右侧堆叠窗口 - h = (m->w.height - ety - gappov - gappiv * (r - 1)) / r; - int stack_x = m->w.x + mx + mw + gappih; + if (c->slave_height_per > 0.0f) { + h = (m->w.height - 2 * cur_gappov - + cur_gappiv * ie * (r - 1)) * + c->slave_height_per; + c->master_width_per = mfact; + } else { + h = (m->w.height - ety - cur_gappov - + cur_gappiv * ie * (r - 1)) / + r; + c->slave_height_per = + h / (m->w.height - ety - cur_gappov - + cur_gappiv * ie * (r - 1)); + c->master_width_per = mfact; + } + + int stack_x = m->w.x + mx + mw + cur_gappih * ie; resize(c, (struct wlr_box){.x = stack_x, .y = m->w.y + ety, - .width = tw, + .width = tw - cur_gappih * ie, .height = h}, 0); - ety += c->geom.height + gappiv; + ety += c->geom.height + cur_gappiv * ie; } else { // 左侧堆叠窗口 - h = (m->w.height - oty - gappov - gappiv * (r - 1)) / r; - int stack_x = m->w.x + gappoh; + if (c->slave_height_per > 0.0f) { + h = (m->w.height - 2 * cur_gappov - + cur_gappiv * ie * (r - 1)) * + c->slave_height_per; + c->master_width_per = mfact; + } else { + h = (m->w.height - oty - cur_gappov - + cur_gappiv * ie * (r - 1)) / + r; + c->slave_height_per = + h / (m->w.height - oty - cur_gappov - + cur_gappiv * ie * (r - 1)); + c->master_width_per = mfact; + } + + int stack_x = m->w.x + cur_gappoh; resize(c, (struct wlr_box){.x = stack_x, .y = m->w.y + oty, - .width = tw, + .width = tw - cur_gappih * ie, .height = h}, 0); - oty += c->geom.height + gappiv; + oty += c->geom.height + cur_gappiv * ie; } } } @@ -469,7 +545,11 @@ void tile(Monitor *m) { cur_gappov = smartgaps && m->visible_tiling_clients == 1 ? 0 : cur_gappov; cur_gappoh = smartgaps && m->visible_tiling_clients == 1 ? 0 : cur_gappoh; - wl_list_for_each(fc, &clients, link) { break; } + wl_list_for_each(fc, &clients, link) { + + if (VISIBLEON(fc, m) && ISTILED(fc)) + break; + } mfact = fc->master_width_per > 0.0f ? fc->master_width_per : m->pertag->mfacts[m->pertag->curtag]; diff --git a/src/mango.c b/src/mango.c index bfeb973..74eef90 100644 --- a/src/mango.c +++ b/src/mango.c @@ -1389,25 +1389,16 @@ void reset_size_per_mon(Monitor *m, double total_slave_hight_percent, if (total_master_height_percent <= 0.0) return; - // wlr_log(WLR_ERROR,"reset before: %f %f", c->slave_height_per, - // total_slave_hight_percent); - if (i < m->pertag->nmasters[m->pertag->curtag]) { c->ismaster = true; c->slave_height_per = slave_num ? 1.0f / slave_num : 1.0f; c->master_height_per = c->master_height_per / total_master_height_percent; } else { - // wlr_log(WLR_ERROR,"###### reset before: %f %f", - // c->slave_height_per, - // total_slave_hight_percent); c->ismaster = false; c->master_height_per = 1.0f / master_num; c->slave_height_per = c->slave_height_per / total_slave_hight_percent; - // wlr_log(WLR_ERROR,"------reset after: %f %f", - // c->slave_height_per, - // total_slave_hight_percent); } }