From b0fb99b95e498a381f174fd29733661e98b14fa5 Mon Sep 17 00:00:00 2001 From: DreamMaoMao <2523610504@qq.com> Date: Mon, 15 Jun 2026 16:49:42 +0800 Subject: [PATCH] feat: add scroller property to tagrule --- src/config/parse_config.h | 32 ++++++++++++++++++++++++++++++++ src/layout/arrange.h | 3 +++ src/layout/scroll.h | 30 ++++++++++++++++++------------ src/mango.c | 3 +++ 4 files changed, 56 insertions(+), 12 deletions(-) diff --git a/src/config/parse_config.h b/src/config/parse_config.h index 72196c5f..849da3c1 100644 --- a/src/config/parse_config.h +++ b/src/config/parse_config.h @@ -167,6 +167,9 @@ typedef struct { char *monitor_serial; float mfact; int32_t nmaster; + float scroller_default_proportion; + float scroller_default_proportion_single; + int32_t scroller_ignore_proportion_single; int32_t no_render_border; int32_t open_as_floating; int32_t no_hide; @@ -2041,6 +2044,9 @@ bool parse_option(Config *config, char *key, char *value) { rule->no_render_border = 0; rule->open_as_floating = 0; rule->no_hide = 0; + rule->scroller_default_proportion = 0.0f; + rule->scroller_default_proportion_single = 0.0f; + rule->scroller_ignore_proportion_single = -1; bool parse_error = false; char *token = strtok(value, ","); @@ -2076,6 +2082,17 @@ bool parse_option(Config *config, char *key, char *value) { rule->nmaster = CLAMP_INT(atoi(val), 1, 99); } else if (strcmp(key, "mfact") == 0) { rule->mfact = CLAMP_FLOAT(atof(val), 0.1f, 0.9f); + } else if (strcmp(key, "scroller_default_proportion") == 0) { + rule->scroller_default_proportion = + CLAMP_FLOAT(atof(val), 0.0f, 1.0f); + } else if (strcmp(key, "scroller_default_proportion_single") == + 0) { + rule->scroller_default_proportion_single = + CLAMP_FLOAT(atof(val), 0.0f, 1.0f); + } else if (strcmp(key, "scroller_ignore_proportion_single") == + 0) { + rule->scroller_ignore_proportion_single = + CLAMP_INT(atoi(val), 0, 1); } else { fprintf(stderr, "\033[1m\033[31m[ERROR]:\033[33m Unknown " @@ -3934,6 +3951,12 @@ void parse_tagrule(Monitor *m) { for (i = 0; i <= LENGTH(tags); i++) { m->pertag->nmasters[i] = config.default_nmaster; m->pertag->mfacts[i] = config.default_mfact; + m->pertag->scroller_default_proportion[i] = + config.scroller_default_proportion; + m->pertag->scroller_default_proportion_single[i] = + config.scroller_default_proportion_single; + m->pertag->scroller_ignore_proportion_single[i] = + config.scroller_ignore_proportion_single; } for (i = 0; i < config.tag_rules_count; i++) { @@ -3988,6 +4011,15 @@ void parse_tagrule(Monitor *m) { m->pertag->no_render_border[tr.id] = tr.no_render_border; if (tr.open_as_floating >= 0) m->pertag->open_as_floating[tr.id] = tr.open_as_floating; + if (tr.scroller_default_proportion > 0.0f) + m->pertag->scroller_default_proportion[tr.id] = + tr.scroller_default_proportion; + if (tr.scroller_default_proportion_single > 0.0f) + m->pertag->scroller_default_proportion_single[tr.id] = + tr.scroller_default_proportion_single; + if (tr.scroller_ignore_proportion_single >= 0) + m->pertag->scroller_ignore_proportion_single[tr.id] = + tr.scroller_ignore_proportion_single; } } diff --git a/src/layout/arrange.h b/src/layout/arrange.h index eab3ac00..0a39b248 100644 --- a/src/layout/arrange.h +++ b/src/layout/arrange.h @@ -25,6 +25,9 @@ void set_size_per(Monitor *m, Client *c) { c->master_inner_per = 1.0f; c->stack_inner_per = 1.0f; } + + c->scroller_proportion = + m->pertag->scroller_default_proportion[m->pertag->curtag]; } void resize_tile_master_horizontal(Client *grabc, bool isdrag, int32_t offsetx, diff --git a/src/layout/scroll.h b/src/layout/scroll.h index ce6defd5..b800c5cf 100644 --- a/src/layout/scroll.h +++ b/src/layout/scroll.h @@ -284,6 +284,10 @@ void scroller(Monitor *m) { uint32_t tag = m->pertag->curtag; struct TagScrollerState *st = ensure_scroller_state(m, tag); Client *c = NULL; + float scroller_default_proportion_single = + m->pertag->scroller_default_proportion_single[tag]; + int32_t scroller_ignore_proportion_single = + m->pertag->scroller_ignore_proportion_single[tag]; /* 按全局客户端链表顺序收集所有堆叠头,确保视觉顺序正确 */ struct ScrollerStackNode *heads[64]; @@ -323,14 +327,13 @@ void scroller(Monitor *m) { m->w.width - 2 * config.scroller_structs - cur_gappih; /* 单客户端特例 */ - if (n_heads == 1 && !config.scroller_ignore_proportion_single && + if (n_heads == 1 && !scroller_ignore_proportion_single && !heads[0]->client->isfullscreen && !heads[0]->client->ismaximizescreen) { struct ScrollerStackNode *head = heads[0]; - float single_proportion = - head->scroller_proportion_single > 0.0f - ? head->scroller_proportion_single - : config.scroller_default_proportion_single; + float single_proportion = head->scroller_proportion_single > 0.0f + ? head->scroller_proportion_single + : scroller_default_proportion_single; struct wlr_box target_geom; target_geom.height = m->w.height - 2 * cur_gappov; target_geom.width = (m->w.width - 2 * cur_gappoh) * single_proportion; @@ -420,7 +423,7 @@ void scroller(Monitor *m) { max_client_width) > m->w.width - 2 * config.scroller_structs - cur_gappih))); - if (n_heads == 1 && config.scroller_ignore_proportion_single) { + if (n_heads == 1 && scroller_ignore_proportion_single) { need_scroller = true; } if (start_drag_window) @@ -507,6 +510,10 @@ void vertical_scroller(Monitor *m) { uint32_t tag = m->pertag->curtag; struct TagScrollerState *st = ensure_scroller_state(m, tag); Client *c = NULL; + float scroller_default_proportion_single = + m->pertag->scroller_default_proportion_single[tag]; + int32_t scroller_ignore_proportion_single = + m->pertag->scroller_ignore_proportion_single[tag]; /* 按全局顺序收集堆叠头 */ struct ScrollerStackNode *heads[64]; @@ -542,14 +549,13 @@ void vertical_scroller(Monitor *m) { int32_t max_client_height = m->w.height - 2 * config.scroller_structs - cur_gappiv; - if (n_heads == 1 && !config.scroller_ignore_proportion_single && + if (n_heads == 1 && !scroller_ignore_proportion_single && !heads[0]->client->isfullscreen && !heads[0]->client->ismaximizescreen) { struct ScrollerStackNode *head = heads[0]; - float single_proportion = - head->scroller_proportion_single > 0.0f - ? head->scroller_proportion_single - : config.scroller_default_proportion_single; + float single_proportion = head->scroller_proportion_single > 0.0f + ? head->scroller_proportion_single + : scroller_default_proportion_single; struct wlr_box target_geom; target_geom.width = m->w.width - 2 * cur_gappoh; target_geom.height = (m->w.height - 2 * cur_gappov) * single_proportion; @@ -638,7 +644,7 @@ void vertical_scroller(Monitor *m) { max_client_height) > m->w.height - 2 * config.scroller_structs - cur_gappiv))); - if (n_heads == 1 && config.scroller_ignore_proportion_single) { + if (n_heads == 1 && scroller_ignore_proportion_single) { need_scroller = true; } if (start_drag_window) diff --git a/src/mango.c b/src/mango.c index eb184e6d..fe32761a 100644 --- a/src/mango.c +++ b/src/mango.c @@ -1027,6 +1027,9 @@ struct Pertag { int32_t no_hide[LENGTH(tags) + 1]; int32_t no_render_border[LENGTH(tags) + 1]; int32_t open_as_floating[LENGTH(tags) + 1]; + float scroller_default_proportion[LENGTH(tags) + 1]; + float scroller_default_proportion_single[LENGTH(tags) + 1]; + int32_t scroller_ignore_proportion_single[LENGTH(tags) + 1]; struct DwindleNode *dwindle_root[LENGTH(tags) + 1]; const Layout *ltidxs[LENGTH(tags) + 1]; struct TagScrollerState *scroller_state[LENGTH(tags) + 1];