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;
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];

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)
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);
}
}