feat: center_tile support resize in tile

This commit is contained in:
DreamMaoMao 2025-10-10 13:26:35 +08:00
parent 86b80f06f2
commit 67334cfeb6
2 changed files with 130 additions and 59 deletions

View file

@ -122,6 +122,9 @@ void deck(Monitor *m) {
unsigned int mw, my; unsigned int mw, my;
int i, n = 0; int i, n = 0;
Client *c = NULL; Client *c = NULL;
Client *fc = NULL;
float mfact;
unsigned int cur_gappih = enablegaps ? m->gappih : 0; unsigned int cur_gappih = enablegaps ? m->gappih : 0;
unsigned int cur_gappoh = enablegaps ? m->gappoh : 0; unsigned int cur_gappoh = enablegaps ? m->gappoh : 0;
unsigned int cur_gappov = enablegaps ? m->gappov : 0; unsigned int cur_gappov = enablegaps ? m->gappov : 0;
@ -135,8 +138,15 @@ void deck(Monitor *m) {
if (n == 0) if (n == 0)
return; return;
wl_list_for_each(fc, &clients, link) {
if (VISIBLEON(fc, m) && ISTILED(fc))
break;
}
// Calculate master width using mfact from pertag // 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 // Calculate master width including outer gaps
if (n > m->nmaster) if (n > m->nmaster)
@ -149,6 +159,7 @@ void deck(Monitor *m) {
if (!VISIBLEON(c, m) || !ISTILED(c)) if (!VISIBLEON(c, m) || !ISTILED(c))
continue; continue;
if (i < m->nmaster) { if (i < m->nmaster) {
c->master_width_per = mfact;
// Master area clients // Master area clients
resize( resize(
c, c,
@ -161,6 +172,7 @@ void deck(Monitor *m) {
my += c->geom.height; my += c->geom.height;
} else { } else {
// Stack area clients // Stack area clients
c->master_width_per = mfact;
resize(c, resize(c,
(struct wlr_box){.x = m->w.x + mw + cur_gappoh + cur_gappih, (struct wlr_box){.x = m->w.x + mw + cur_gappoh + cur_gappih,
.y = m->w.y + cur_gappov, .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.height = m->w.height - 2 * cur_gappov;
target_geom.width = max_client_width * c->scroller_proportion; target_geom.width = max_client_width * c->scroller_proportion;
target_geom.y = m->w.y + (m->w.height - target_geom.height) / 2; 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) { 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 *c = NULL;
Client *fc = NULL;
double mfact = 0;
n = m->visible_tiling_clients; n = m->visible_tiling_clients;
if (n == 0) if (n == 0)
return; return;
// 间隙参数处理 // 获取第一个可见的平铺客户端用于主区域宽度百分比
unsigned int gappiv = enablegaps ? m->gappiv : 0; // 内部垂直间隙 wl_list_for_each(fc, &clients, link) {
unsigned int gappih = enablegaps ? m->gappih : 0; // 内部水平间隙 if (VISIBLEON(fc, m) && ISTILED(fc))
unsigned int gappov = enablegaps ? m->gappov : 0; // 外部垂直间隙 break;
unsigned int gappoh = enablegaps ? m->gappoh : 0; // 外部水平间隙
// 智能间隙处理
if (smartgaps && n == 1) {
gappiv = gappih = gappov = gappoh = 0;
} }
// 间隙参数处理
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]; 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; mw = m->w.width;
mx = gappoh; mx = cur_gappoh;
my = gappov; my = cur_gappov;
tw = mw; tw = mw;
// 判断是否需要主区域铺满 // 判断是否需要主区域铺满
@ -340,37 +365,38 @@ void center_tile(Monitor *m) {
if (n > nmasters || !should_overspread) { 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) { if (n - nmasters > 1) {
// 多个堆叠窗口:主区域居中,左右两侧各有一个堆叠区域 // 多个堆叠窗口:主区域居中,左右两侧各有一个堆叠区域
tw = (m->w.width - mw) / 2 - gappoh - gappih; tw = (m->w.width - mw) / 2 - cur_gappoh - cur_gappih * ie;
mx = gappoh + tw + gappih; mx = cur_gappoh + tw + cur_gappih * ie;
} else if (n - nmasters == 1) { } else if (n - nmasters == 1) {
// 单个堆叠窗口的处理 // 单个堆叠窗口的处理
if (center_when_single_slave) { if (center_when_single_slave) {
// 修改:slave在右边master居中左边空着 // slave在右边master居中左边空着
tw = (m->w.width - mw) / 2 - gappoh - gappih; tw = (m->w.width - mw) / 2 - cur_gappoh - cur_gappih * ie;
mx = gappoh + tw + gappih; // master居中 mx = cur_gappoh + tw + cur_gappih * ie; // master居中
} else { } else {
// slave在右边master在左边 // slave在右边master在左边
tw = m->w.width - mw - 2 * gappoh - gappih; tw = m->w.width - mw - 2 * cur_gappoh - cur_gappih * ie;
mx = gappoh; // master在左边 mx = cur_gappoh; // master在左边
} }
} else { } else {
// 只有主区域窗口:居中显示 // 只有主区域窗口:居中显示
tw = (m->w.width - mw) / 2 - gappoh - gappih; tw = (m->w.width - mw) / 2 - cur_gappoh - cur_gappih * ie;
mx = gappoh + tw + gappih; mx = cur_gappoh + tw + cur_gappih * ie;
} }
} else { } else {
// 主区域铺满模式(只有主区域窗口时) // 主区域铺满模式(只有主区域窗口时)
mw = m->w.width - 2 * gappoh; mw = m->w.width - 2 * cur_gappoh;
mx = gappoh; mx = cur_gappoh;
tw = 0; // 堆叠区域宽度为0 tw = 0; // 堆叠区域宽度为0
} }
oty = gappov; oty = cur_gappov;
ety = gappov; ety = cur_gappov;
i = 0; i = 0;
wl_list_for_each(c, &clients, link) { wl_list_for_each(c, &clients, link) {
@ -379,68 +405,118 @@ void center_tile(Monitor *m) {
if (i < nmasters) { if (i < nmasters) {
// 主区域窗口 // 主区域窗口
unsigned int r = MIN(n, nmasters) - i; r = MIN(n, nmasters) - i;
h = (m->w.height - my - gappov - gappiv * (r - 1)) / r; 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, resize(c,
(struct wlr_box){.x = m->w.x + mx, (struct wlr_box){.x = m->w.x + mx,
.y = m->w.y + my, .y = m->w.y + my,
.width = mw, .width = mw - cur_gappih * ie,
.height = h}, .height = h},
0); 0);
my += c->geom.height + gappiv; my += c->geom.height + cur_gappiv * ie;
} else { } else {
// 堆叠区域窗口 // 堆叠区域窗口
unsigned int stack_index = i - nmasters; unsigned int stack_index = i - nmasters;
if (n - nmasters == 1) { if (n - nmasters == 1) {
// 单个堆叠窗口 // 单个堆叠窗口
unsigned int r = n - i; r = n - i;
h = (m->w.height - ety - gappov - gappiv * (r - 1)) / r; 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; int stack_x;
if (center_when_single_slave) { if (center_when_single_slave) {
// 修改放在右侧master居中时slave在右边 // 放在右侧master居中时slave在右边
stack_x = m->w.x + mx + mw + gappih; stack_x = m->w.x + mx + mw + cur_gappih * ie;
} else { } else {
// 放在右侧master在左边时slave在右边 // 放在右侧master在左边时slave在右边
stack_x = m->w.x + mx + mw + gappih; stack_x = m->w.x + mx + mw + cur_gappih * ie;
} }
resize(c, resize(c,
(struct wlr_box){.x = stack_x, (struct wlr_box){.x = stack_x,
.y = m->w.y + ety, .y = m->w.y + ety,
.width = tw, .width = tw - cur_gappih * ie,
.height = h}, .height = h},
0); 0);
ety += c->geom.height + gappiv; ety += c->geom.height + cur_gappiv * ie;
} else { } else {
// 多个堆叠窗口:交替放在左右两侧 // 多个堆叠窗口:交替放在左右两侧
unsigned int r = (n - i + 1) / 2; r = (n - i + 1) / 2;
// 当n为偶数时翻转判断逻辑
if ((stack_index % 2) ^ (n % 2 == 0)) { if ((stack_index % 2) ^ (n % 2 == 0)) {
// 右侧堆叠窗口 // 右侧堆叠窗口
h = (m->w.height - ety - gappov - gappiv * (r - 1)) / r; if (c->slave_height_per > 0.0f) {
int stack_x = m->w.x + mx + mw + gappih; 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, resize(c,
(struct wlr_box){.x = stack_x, (struct wlr_box){.x = stack_x,
.y = m->w.y + ety, .y = m->w.y + ety,
.width = tw, .width = tw - cur_gappih * ie,
.height = h}, .height = h},
0); 0);
ety += c->geom.height + gappiv; ety += c->geom.height + cur_gappiv * ie;
} else { } else {
// 左侧堆叠窗口 // 左侧堆叠窗口
h = (m->w.height - oty - gappov - gappiv * (r - 1)) / r; if (c->slave_height_per > 0.0f) {
int stack_x = m->w.x + gappoh; 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, resize(c,
(struct wlr_box){.x = stack_x, (struct wlr_box){.x = stack_x,
.y = m->w.y + oty, .y = m->w.y + oty,
.width = tw, .width = tw - cur_gappih * ie,
.height = h}, .height = h},
0); 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_gappov = smartgaps && m->visible_tiling_clients == 1 ? 0 : cur_gappov;
cur_gappoh = smartgaps && m->visible_tiling_clients == 1 ? 0 : cur_gappoh; 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 mfact = fc->master_width_per > 0.0f ? fc->master_width_per
: m->pertag->mfacts[m->pertag->curtag]; : m->pertag->mfacts[m->pertag->curtag];

View file

@ -1389,25 +1389,16 @@ void reset_size_per_mon(Monitor *m, double total_slave_hight_percent,
if (total_master_height_percent <= 0.0) if (total_master_height_percent <= 0.0)
return; 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]) { if (i < m->pertag->nmasters[m->pertag->curtag]) {
c->ismaster = true; c->ismaster = true;
c->slave_height_per = slave_num ? 1.0f / slave_num : 1.0f; c->slave_height_per = slave_num ? 1.0f / slave_num : 1.0f;
c->master_height_per = c->master_height_per =
c->master_height_per / total_master_height_percent; c->master_height_per / total_master_height_percent;
} else { } else {
// wlr_log(WLR_ERROR,"###### reset before: %f %f",
// c->slave_height_per,
// total_slave_hight_percent);
c->ismaster = false; c->ismaster = false;
c->master_height_per = 1.0f / master_num; c->master_height_per = 1.0f / master_num;
c->slave_height_per = c->slave_height_per =
c->slave_height_per / total_slave_hight_percent; c->slave_height_per / total_slave_hight_percent;
// wlr_log(WLR_ERROR,"------reset after: %f %f",
// c->slave_height_per,
// total_slave_hight_percent);
} }
} }