Merge branch 'main' into feature/dual-row-scroller

This commit is contained in:
2025-12-22 14:55:39 +01:00
20 changed files with 695 additions and 444 deletions

View File

@@ -5,7 +5,7 @@ void set_size_per(Monitor *m, Client *c) {
if (VISIBLEON(fc, m) && ISTILED(fc) && fc != c) {
c->master_mfact_per = fc->master_mfact_per;
c->master_inner_per = fc->master_inner_per;
c->stack_innder_per = fc->stack_innder_per;
c->stack_inner_per = fc->stack_inner_per;
found = true;
break;
}
@@ -14,7 +14,7 @@ void set_size_per(Monitor *m, Client *c) {
if (!found) {
c->master_mfact_per = m->pertag->mfacts[m->pertag->curtag];
c->master_inner_per = 1.0f;
c->stack_innder_per = 1.0f;
c->stack_inner_per = 1.0f;
}
}
@@ -70,7 +70,7 @@ void resize_tile_master_horizontal(Client *grabc, bool isdrag, int offsetx,
// 记录初始状态
grabc->old_master_mfact_per = grabc->master_mfact_per;
grabc->old_master_inner_per = grabc->master_inner_per;
grabc->old_stack_innder_per = grabc->stack_innder_per;
grabc->old_stack_inner_per = grabc->stack_inner_per;
grabc->cursor_in_upper_half =
cursor->y < grabc->geom.y + grabc->geom.height / 2;
grabc->cursor_in_left_half =
@@ -86,7 +86,7 @@ void resize_tile_master_horizontal(Client *grabc, bool isdrag, int offsetx,
} else {
grabc->old_master_mfact_per = grabc->master_mfact_per;
grabc->old_master_inner_per = grabc->master_inner_per;
grabc->old_stack_innder_per = grabc->stack_innder_per;
grabc->old_stack_inner_per = grabc->stack_inner_per;
grabc->drag_begin_geom = grabc->geom;
grabc->cursor_in_upper_half = true;
grabc->cursor_in_left_half = false;
@@ -100,7 +100,7 @@ void resize_tile_master_horizontal(Client *grabc, bool isdrag, int offsetx,
} else {
delta_x = (float)(offsetx) * (1 - grabc->old_master_mfact_per) /
grabc->drag_begin_geom.width;
delta_y = (float)(offsety) * (grabc->old_stack_innder_per) /
delta_y = (float)(offsety) * (grabc->old_stack_inner_per) /
grabc->drag_begin_geom.height;
}
bool moving_up;
@@ -182,12 +182,12 @@ void resize_tile_master_horizontal(Client *grabc, bool isdrag, int offsetx,
// 直接设置新的比例,基于初始值 + 变化量
float new_master_mfact_per = grabc->old_master_mfact_per + delta_x;
float new_master_inner_per = grabc->old_master_inner_per + delta_y;
float new_stack_innder_per = grabc->old_stack_innder_per + delta_y;
float new_stack_inner_per = grabc->old_stack_inner_per + delta_y;
// 应用限制,确保比例在合理范围内
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_stack_innder_per = fmaxf(0.1f, fminf(0.9f, new_stack_innder_per));
new_stack_inner_per = fmaxf(0.1f, fminf(0.9f, new_stack_inner_per));
// 应用到所有平铺窗口
wl_list_for_each(tc, &clients, link) {
@@ -197,7 +197,7 @@ void resize_tile_master_horizontal(Client *grabc, bool isdrag, int offsetx,
}
grabc->master_inner_per = new_master_inner_per;
grabc->stack_innder_per = new_stack_innder_per;
grabc->stack_inner_per = new_stack_inner_per;
if (!isdrag) {
arrange(grabc->mon, false);
@@ -250,7 +250,7 @@ void resize_tile_master_vertical(Client *grabc, bool isdrag, int offsetx,
// 记录初始状态
grabc->old_master_mfact_per = grabc->master_mfact_per;
grabc->old_master_inner_per = grabc->master_inner_per;
grabc->old_stack_innder_per = grabc->stack_innder_per;
grabc->old_stack_inner_per = grabc->stack_inner_per;
grabc->cursor_in_upper_half =
cursor->y < grabc->geom.y + grabc->geom.height / 2;
grabc->cursor_in_left_half =
@@ -267,7 +267,7 @@ void resize_tile_master_vertical(Client *grabc, bool isdrag, int offsetx,
} else {
grabc->old_master_mfact_per = grabc->master_mfact_per;
grabc->old_master_inner_per = grabc->master_inner_per;
grabc->old_stack_innder_per = grabc->stack_innder_per;
grabc->old_stack_inner_per = grabc->stack_inner_per;
grabc->drag_begin_geom = grabc->geom;
grabc->cursor_in_upper_half = true;
grabc->cursor_in_left_half = false;
@@ -280,7 +280,7 @@ void resize_tile_master_vertical(Client *grabc, bool isdrag, int offsetx,
delta_y = (float)(offsety) * (grabc->old_master_mfact_per) /
grabc->drag_begin_geom.height;
} else {
delta_x = (float)(offsetx) * (grabc->old_stack_innder_per) /
delta_x = (float)(offsetx) * (grabc->old_stack_inner_per) /
grabc->drag_begin_geom.width;
delta_y = (float)(offsety) * (1 - grabc->old_master_mfact_per) /
grabc->drag_begin_geom.height;
@@ -338,13 +338,13 @@ void resize_tile_master_vertical(Client *grabc, bool isdrag, int offsetx,
delta_y; // 垂直delta_y调整主区域高度
float new_master_inner_per = grabc->old_master_inner_per +
delta_x; // 垂直delta_x调整主区域内部宽度
float new_stack_innder_per = grabc->old_stack_innder_per +
delta_x; // 垂直delta_x调整栈区域内部宽度
float new_stack_inner_per = grabc->old_stack_inner_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_stack_innder_per = fmaxf(0.1f, fminf(0.9f, new_stack_innder_per));
new_stack_inner_per = fmaxf(0.1f, fminf(0.9f, new_stack_inner_per));
// 应用到所有平铺窗口
wl_list_for_each(tc, &clients, link) {
@@ -354,7 +354,7 @@ void resize_tile_master_vertical(Client *grabc, bool isdrag, int offsetx,
}
grabc->master_inner_per = new_master_inner_per;
grabc->stack_innder_per = new_stack_innder_per;
grabc->stack_inner_per = new_stack_inner_per;
if (!isdrag) {
arrange(grabc->mon, false);
@@ -402,7 +402,7 @@ void resize_tile_scroller(Client *grabc, bool isdrag, int offsetx, int offsety,
} else {
grabc->old_master_mfact_per = grabc->master_mfact_per;
grabc->old_master_inner_per = grabc->master_inner_per;
grabc->old_stack_innder_per = grabc->stack_innder_per;
grabc->old_stack_inner_per = grabc->stack_inner_per;
grabc->drag_begin_geom = grabc->geom;
grabc->old_scroller_pproportion = grabc->scroller_proportion;
grabc->cursor_in_upper_half = false;
@@ -485,7 +485,8 @@ void resize_tile_client(Client *grabc, bool isdrag, int offsetx, int offsety,
const Layout *current_layout =
grabc->mon->pertag->ltidxs[grabc->mon->pertag->curtag];
if (current_layout->id == TILE || current_layout->id == DECK ||
current_layout->id == CENTER_TILE || current_layout->id == RIGHT_TILE
current_layout->id == CENTER_TILE || current_layout->id == RIGHT_TILE ||
(current_layout->id == TGMIX && grabc->mon->visible_tiling_clients <= 3)
) {
resize_tile_master_horizontal(grabc, isdrag, offsetx, offsety, time,
@@ -520,16 +521,16 @@ void reset_size_per_mon(Monitor *m, int tile_cilent_num,
if (VISIBLEON(c, m) && ISTILED(c)) {
if (total_master_inner_percent > 0.0 && i < nmasters) {
c->ismaster = true;
c->stack_innder_per = stack_num ? 1.0f / stack_num : 1.0f;
c->stack_inner_per = stack_num ? 1.0f / stack_num : 1.0f;
c->master_inner_per =
c->master_inner_per / total_master_inner_percent;
} else {
c->ismaster = false;
c->master_inner_per =
master_num > 0 ? 1.0f / master_num : 1.0f;
c->stack_innder_per =
c->stack_inner_per =
total_stack_hight_percent
? c->stack_innder_per / total_stack_hight_percent
? c->stack_inner_per / total_stack_hight_percent
: 1.0f;
}
i++;
@@ -541,11 +542,11 @@ void reset_size_per_mon(Monitor *m, int tile_cilent_num,
if (total_master_inner_percent > 0.0 && i < nmasters) {
c->ismaster = true;
if ((stack_index % 2) ^ (tile_cilent_num % 2 == 0)) {
c->stack_innder_per =
c->stack_inner_per =
stack_num > 1 ? 1.0f / ((stack_num - 1) / 2) : 1.0f;
} else {
c->stack_innder_per =
c->stack_inner_per =
stack_num > 1 ? 2.0f / stack_num : 1.0f;
}
@@ -558,15 +559,15 @@ void reset_size_per_mon(Monitor *m, int tile_cilent_num,
c->master_inner_per =
master_num > 0 ? 1.0f / master_num : 1.0f;
if ((stack_index % 2) ^ (tile_cilent_num % 2 == 0)) {
c->stack_innder_per =
c->stack_inner_per =
total_right_stack_hight_percent
? c->stack_innder_per /
? c->stack_inner_per /
total_right_stack_hight_percent
: 1.0f;
} else {
c->stack_innder_per =
c->stack_inner_per =
total_left_stack_hight_percent
? c->stack_innder_per /
? c->stack_inner_per /
total_left_stack_hight_percent
: 1.0f;
}
@@ -580,7 +581,7 @@ void reset_size_per_mon(Monitor *m, int tile_cilent_num,
void // 17
arrange(Monitor *m, bool want_animation) {
Client *c = NULL;
double total_stack_innder_percent = 0;
double total_stack_inner_percent = 0;
double total_master_inner_percent = 0;
double total_right_stack_hight_percent = 0;
double total_left_stack_hight_percent = 0;
@@ -598,7 +599,6 @@ arrange(Monitor *m, bool want_animation) {
m->visible_clients = 0;
m->visible_tiling_clients = 0;
m->visible_scroll_tiling_clients = 0;
m->has_visible_fullscreen_client = false;
wl_list_for_each(c, &clients, link) {
@@ -612,9 +612,6 @@ arrange(Monitor *m, bool want_animation) {
if (!c->isunglobal)
m->visible_clients++;
if (c->isfullscreen)
m->has_visible_fullscreen_client = true;
if (ISTILED(c)) {
m->visible_tiling_clients++;
}
@@ -640,17 +637,17 @@ arrange(Monitor *m, bool want_animation) {
total_master_inner_percent += c->master_inner_per;
} else {
stack_num++;
total_stack_innder_percent += c->stack_innder_per;
total_stack_inner_percent += c->stack_inner_per;
stack_index = i - nmasters;
if ((stack_index % 2) ^
(m->visible_tiling_clients % 2 == 0)) {
c->isleftstack = false;
total_right_stack_hight_percent +=
c->stack_innder_per;
c->stack_inner_per;
} else {
c->isleftstack = true;
total_left_stack_hight_percent +=
c->stack_innder_per;
c->stack_inner_per;
}
}
@@ -671,7 +668,7 @@ arrange(Monitor *m, bool want_animation) {
reset_size_per_mon(
m, m->visible_tiling_clients, total_left_stack_hight_percent,
total_right_stack_hight_percent, total_stack_innder_percent,
total_right_stack_hight_percent, total_stack_inner_percent,
total_master_inner_percent, master_num, stack_num);
if (m->isoverview) {

View File

@@ -705,17 +705,17 @@ void center_tile(Monitor *m) {
if (n - nmasters == 1) {
// 单个堆叠窗口
r = n - i;
if (c->stack_innder_per > 0.0f) {
if (c->stack_inner_per > 0.0f) {
h = (m->w.height - 2 * cur_gappov -
cur_gappiv * ie * (stack_num - 1)) *
c->stack_innder_per;
c->stack_inner_per;
c->master_mfact_per = mfact;
} else {
h = (m->w.height - ety - cur_gappov -
cur_gappiv * ie * (r - 1)) /
r;
c->stack_innder_per = h / (m->w.height - ety - cur_gappov -
cur_gappiv * ie * (r - 1));
c->stack_inner_per = h / (m->w.height - ety - cur_gappov -
cur_gappiv * ie * (r - 1));
c->master_mfact_per = mfact;
}
@@ -741,19 +741,19 @@ void center_tile(Monitor *m) {
if ((stack_index % 2) ^ (n % 2 == 0)) {
// 右侧堆叠窗口
if (c->stack_innder_per > 0.0f) {
h = slave_right_surplus_height * c->stack_innder_per /
if (c->stack_inner_per > 0.0f) {
h = slave_right_surplus_height * c->stack_inner_per /
slave_right_surplus_ratio;
slave_right_surplus_height =
slave_right_surplus_height - h;
slave_right_surplus_ratio =
slave_right_surplus_ratio - c->stack_innder_per;
slave_right_surplus_ratio - c->stack_inner_per;
c->master_mfact_per = mfact;
} else {
h = (m->w.height - ety - cur_gappov -
cur_gappiv * ie * (r - 1)) /
r;
c->stack_innder_per =
c->stack_inner_per =
h / (m->w.height - ety - cur_gappov -
cur_gappiv * ie * (r - 1));
c->master_mfact_per = mfact;
@@ -770,19 +770,19 @@ void center_tile(Monitor *m) {
ety += c->geom.height + cur_gappiv * ie;
} else {
// 左侧堆叠窗口
if (c->stack_innder_per > 0.0f) {
h = slave_left_surplus_height * c->stack_innder_per /
if (c->stack_inner_per > 0.0f) {
h = slave_left_surplus_height * c->stack_inner_per /
slave_left_surplus_ratio;
slave_left_surplus_height =
slave_left_surplus_height - h;
slave_left_surplus_ratio =
slave_left_surplus_ratio - c->stack_innder_per;
slave_left_surplus_ratio - c->stack_inner_per;
c->master_mfact_per = mfact;
} else {
h = (m->w.height - oty - cur_gappov -
cur_gappiv * ie * (r - 1)) /
r;
c->stack_innder_per =
c->stack_inner_per =
h / (m->w.height - oty - cur_gappov -
cur_gappiv * ie * (r - 1));
c->master_mfact_per = mfact;
@@ -884,22 +884,22 @@ void tile(Monitor *m) {
my += c->geom.height + cur_gappiv * ie;
} else {
r = n - i;
if (c->stack_innder_per > 0.0f) {
h = slave_surplus_height * c->stack_innder_per /
if (c->stack_inner_per > 0.0f) {
h = slave_surplus_height * c->stack_inner_per /
slave_surplus_ratio;
slave_surplus_height = slave_surplus_height - h;
slave_surplus_ratio = slave_surplus_ratio - c->stack_innder_per;
slave_surplus_ratio = slave_surplus_ratio - c->stack_inner_per;
c->master_mfact_per = mfact;
} else {
h = (m->w.height - ty - cur_gappov -
cur_gappiv * ie * (r - 1)) /
r;
c->stack_innder_per = h / (m->w.height - ty - cur_gappov -
cur_gappiv * ie * (r - 1));
c->stack_inner_per = h / (m->w.height - ty - cur_gappov -
cur_gappiv * ie * (r - 1));
c->master_mfact_per = mfact;
}
// wlr_log(WLR_ERROR, "stack_innder_per: %f", c->stack_innder_per);
// wlr_log(WLR_ERROR, "stack_inner_per: %f", c->stack_inner_per);
resize(c,
(struct wlr_box){.x = m->w.x + mw + cur_gappoh,
@@ -995,22 +995,22 @@ void right_tile(Monitor *m) {
my += c->geom.height + cur_gappiv * ie;
} else {
r = n - i;
if (c->stack_innder_per > 0.0f) {
h = slave_surplus_height * c->stack_innder_per /
if (c->stack_inner_per > 0.0f) {
h = slave_surplus_height * c->stack_inner_per /
slave_surplus_ratio;
slave_surplus_height = slave_surplus_height - h;
slave_surplus_ratio = slave_surplus_ratio - c->stack_innder_per;
slave_surplus_ratio = slave_surplus_ratio - c->stack_inner_per;
c->master_mfact_per = mfact;
} else {
h = (m->w.height - ty - cur_gappov -
cur_gappiv * ie * (r - 1)) /
r;
c->stack_innder_per = h / (m->w.height - ty - cur_gappov -
cur_gappiv * ie * (r - 1));
c->stack_inner_per = h / (m->w.height - ty - cur_gappov -
cur_gappiv * ie * (r - 1));
c->master_mfact_per = mfact;
}
// wlr_log(WLR_ERROR, "stack_innder_per: %f", c->stack_innder_per);
// wlr_log(WLR_ERROR, "stack_inner_per: %f", c->stack_inner_per);
resize(c,
(struct wlr_box){.x = m->w.x + cur_gappoh,
@@ -1047,3 +1047,14 @@ monocle(Monitor *m) {
if ((c = focustop(m)))
wlr_scene_node_raise_to_top(&c->scene->node);
}
void tgmix(Monitor *m) {
uint32_t n = m->visible_tiling_clients;
if (n <= 3) {
tile(m);
return;
} else {
grid(m);
return;
}
}

View File

@@ -12,6 +12,7 @@ static void vertical_grid(Monitor *m);
static void vertical_scroller(Monitor *m);
static void vertical_deck(Monitor *mon);
static void dual_scroller(Monitor *mon);
static void tgmix(Monitor *m);
/* layout(s) */
Layout overviewlayout = {"󰃇", overview, "overview"};
@@ -29,6 +30,7 @@ enum {
VERTICAL_DECK,
RIGHT_TILE,
DUAL_SCROLLER,
TGMIX,
};
Layout layouts[] = {
@@ -47,4 +49,5 @@ Layout layouts[] = {
{"VG", vertical_grid, "vertical_grid", VERTICAL_GRID}, // 垂直格子布局
{"VK", vertical_deck, "vertical_deck", VERTICAL_DECK}, // 垂直卡片布局
{"DS", dual_scroller, "dual_scroller", DUAL_SCROLLER}, // 双行滚动布局
};
{"TG", tgmix, "tgmix", TGMIX}, // 混合布局
};

View File

@@ -78,17 +78,17 @@ void vertical_tile(Monitor *m) {
mx += c->geom.width + cur_gapih * ie;
} else {
r = n - i;
if (c->stack_innder_per > 0.0f) {
w = slave_surplus_width * c->stack_innder_per /
if (c->stack_inner_per > 0.0f) {
w = slave_surplus_width * c->stack_inner_per /
slave_surplus_ratio;
slave_surplus_width = slave_surplus_width - w;
slave_surplus_ratio = slave_surplus_ratio - c->stack_innder_per;
slave_surplus_ratio = slave_surplus_ratio - c->stack_inner_per;
c->master_mfact_per = mfact;
} else {
w = (m->w.width - tx - cur_gapih - cur_gapih * ie * (r - 1)) /
r;
c->stack_innder_per = w / (m->w.width - tx - cur_gapih -
cur_gapih * ie * (r - 1));
c->stack_inner_per = w / (m->w.width - tx - cur_gapih -
cur_gapih * ie * (r - 1));
c->master_mfact_per = mfact;
}