From 6086507c5ae355d63273ed4f3714158469b31ea6 Mon Sep 17 00:00:00 2001 From: Owen-sz Date: Sat, 6 Dec 2025 14:50:54 -0600 Subject: [PATCH 01/12] doc: add Fedora install instructions Signed-off-by: Owen-sz --- README.md | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index af1d2977..b2bd4964 100644 --- a/README.md +++ b/README.md @@ -82,7 +82,6 @@ yay -S mangowc-git ``` ## Gentoo Linux - The package is in the community-maintained repository called GURU. First, add GURU repository: @@ -100,6 +99,16 @@ Finally, install the package: emerge --ask --verbose gui-wm/mangowc ``` +## Fedora Linux +The package is in the third-party Terra repository. +First, add the [Terra Repository](https://terra.fyralabs.com/). + +Then, install the package: + +```bash +dnf install mangowc +``` + ## Other ```bash From f3f321579173805051333057cf65439c0e7972f6 Mon Sep 17 00:00:00 2001 From: DreamMaoMao <2523610504@qq.com> Date: Sun, 7 Dec 2025 21:12:45 +0800 Subject: [PATCH 02/12] fix: nmaster num caculate error in master layout --- src/fetch/client.h | 2 +- src/layout/arrange.h | 18 +++++++----------- src/layout/horizontal.h | 4 ++++ src/layout/vertical.h | 1 + 4 files changed, 13 insertions(+), 12 deletions(-) diff --git a/src/fetch/client.h b/src/fetch/client.h index 7b44344f..0bc84881 100644 --- a/src/fetch/client.h +++ b/src/fetch/client.h @@ -349,7 +349,7 @@ Client *find_client_by_direction(Client *tc, const Arg *arg, bool findfloating, } free(tempClients); // 释放内存 - if(tempSameMonitorFocusClients) { + if (tempSameMonitorFocusClients) { return tempSameMonitorFocusClients; } else { return tempFocusClients; diff --git a/src/layout/arrange.h b/src/layout/arrange.h index 3fb25a46..7a1d6205 100644 --- a/src/layout/arrange.h +++ b/src/layout/arrange.h @@ -516,17 +516,15 @@ void reset_size_per_mon(Monitor *m, int tile_cilent_num, wl_list_for_each(c, &clients, link) { if (VISIBLEON(c, m) && ISTILED(c)) { - - if (total_master_inner_percent <= 0.0) - return; - if (i < m->pertag->nmasters[m->pertag->curtag]) { + 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->master_inner_per = c->master_inner_per / total_master_inner_percent; } else { c->ismaster = false; - c->master_inner_per = 1.0f / master_num; + c->master_inner_per = + master_num > 0 ? 1.0f / master_num : 1.0f; c->stack_innder_per = total_stack_hight_percent ? c->stack_innder_per / total_stack_hight_percent @@ -538,10 +536,7 @@ void reset_size_per_mon(Monitor *m, int tile_cilent_num, } else { wl_list_for_each(c, &clients, link) { if (VISIBLEON(c, m) && ISTILED(c)) { - - if (total_master_inner_percent <= 0.0) - return; - if (i < m->pertag->nmasters[m->pertag->curtag]) { + 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 = @@ -558,7 +553,8 @@ void reset_size_per_mon(Monitor *m, int tile_cilent_num, stack_index = i - nmasters; c->ismaster = false; - c->master_inner_per = 1.0f / master_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 = total_right_stack_hight_percent @@ -637,7 +633,7 @@ arrange(Monitor *m, bool want_animation) { if (VISIBLEON(c, m)) { if (ISTILED(c)) { - if (i < m->pertag->nmasters[m->pertag->curtag]) { + if (i < nmasters) { master_num++; total_master_inner_percent += c->master_inner_per; } else { diff --git a/src/layout/horizontal.h b/src/layout/horizontal.h index 9a6a5950..7368ddb7 100644 --- a/src/layout/horizontal.h +++ b/src/layout/horizontal.h @@ -386,6 +386,8 @@ void center_tile(Monitor *m) { n = m->visible_tiling_clients; master_num = m->pertag->nmasters[m->pertag->curtag]; + master_num = n > master_num ? master_num : n; + stack_num = n - master_num; if (n == 0) @@ -595,6 +597,7 @@ void tile(Monitor *m) { n = m->visible_tiling_clients; master_num = m->pertag->nmasters[m->pertag->curtag]; + master_num = n > master_num ? master_num : n; stack_num = n - master_num; if (n == 0) @@ -692,6 +695,7 @@ void right_tile(Monitor *m) { n = m->visible_tiling_clients; master_num = m->pertag->nmasters[m->pertag->curtag]; + master_num = n > master_num ? master_num : n; stack_num = n - master_num; if (n == 0) diff --git a/src/layout/vertical.h b/src/layout/vertical.h index 5badc72b..07cb3ba8 100644 --- a/src/layout/vertical.h +++ b/src/layout/vertical.h @@ -8,6 +8,7 @@ void vertical_tile(Monitor *m) { n = m->visible_tiling_clients; master_num = m->pertag->nmasters[m->pertag->curtag]; + master_num = n > master_num ? master_num : n; stack_num = n - master_num; if (n == 0) From dd72e472bf75bc9cf0302e7ef3157063b50d8e63 Mon Sep 17 00:00:00 2001 From: DreamMaoMao <2523610504@qq.com> Date: Mon, 8 Dec 2025 09:42:18 +0800 Subject: [PATCH 03/12] update readme --- README.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index b2bd4964..9780ac6e 100644 --- a/README.md +++ b/README.md @@ -181,7 +181,9 @@ git clone https://github.com/DreamMaoMao/mango-config.git ~/.config/mango ## Config Documentation -Refer to the [wiki](https://github.com/DreamMaoMao/mango/wiki/) +Refer to the repo wiki [wiki](https://github.com/DreamMaoMao/mango/wiki/) + +or the website docs [docs](https://mangowc.vercel.app/docs) # NixOS + Home-manager From 9a2d2397c1cd1edb64a47f85ae8377ea0954e4c6 Mon Sep 17 00:00:00 2001 From: Mental-Vortex <206187961+Mental-Vortex@users.noreply.github.com> Date: Sun, 7 Dec 2025 17:35:50 +0800 Subject: [PATCH 04/12] feat: support centerwin in scroller window --- src/dispatch/bind_define.h | 26 +++++++++++++++++++------- 1 file changed, 19 insertions(+), 7 deletions(-) diff --git a/src/dispatch/bind_define.h b/src/dispatch/bind_define.h index c167915c..92e264e4 100644 --- a/src/dispatch/bind_define.h +++ b/src/dispatch/bind_define.h @@ -713,14 +713,26 @@ int centerwin(const Arg *arg) { Client *c = NULL; c = selmon->sel; - if (!c || c->isfullscreen) + if (!c || c->isfullscreen || c->ismaximizescreen) return 0; - if (!c->isfloating) - setfloating(c, true); - c->float_geom = setclient_coordinate_center(c, c->geom, 0, 0); - c->iscustomsize = 1; - resize(c, c->float_geom, 1); + if (c->isfloating) { + c->float_geom = setclient_coordinate_center(c, c->geom, 0, 0); + c->iscustomsize = 1; + resize(c, c->float_geom, 1); + return 0; + } + + if (!is_scroller_layout(selmon)) + return 0; + + if (selmon->pertag->ltidxs[selmon->pertag->curtag]->id == SCROLLER) { + c->geom.x = selmon->w.x + (selmon->w.width - c->geom.width) / 2; + } else { + c->geom.y = selmon->w.y + (selmon->w.height - c->geom.height) / 2; + } + + arrange(selmon, false); return 0; } @@ -1549,4 +1561,4 @@ int toggle_monitor(const Arg *arg) { } } return 0; -} \ No newline at end of file +} From dfb59d12c2b488d601792ea7c8108a7ff0b5ca11 Mon Sep 17 00:00:00 2001 From: DreamMaoMao <2523610504@qq.com> Date: Tue, 9 Dec 2025 09:40:22 +0800 Subject: [PATCH 05/12] fix: excrescent border in grid layout --- src/layout/horizontal.h | 13 +------------ src/layout/vertical.h | 12 ------------ 2 files changed, 1 insertion(+), 24 deletions(-) diff --git a/src/layout/horizontal.h b/src/layout/horizontal.h index 7368ddb7..3ded199c 100644 --- a/src/layout/horizontal.h +++ b/src/layout/horizontal.h @@ -23,10 +23,6 @@ void grid(Monitor *m) { if (c->mon != m) continue; - c->bw = m->visible_tiling_clients == 1 && no_border_when_single && - smartgaps - ? 0 - : borderpx; if (VISIBLEON(c, m) && !c->isunglobal && ((m->isoverview && !client_is_x11_popup(c)) || ISTILED(c))) { cw = (m->w.width - 2 * target_gappo) * single_width_ratio; @@ -49,10 +45,6 @@ void grid(Monitor *m) { if (c->mon != m) continue; - c->bw = m->visible_tiling_clients == 1 && no_border_when_single && - smartgaps - ? 0 - : borderpx; if (VISIBLEON(c, m) && !c->isunglobal && ((m->isoverview && !client_is_x11_popup(c)) || ISTILED(c))) { if (i == 0) { @@ -99,10 +91,7 @@ void grid(Monitor *m) { if (c->mon != m) continue; - c->bw = - m->visible_tiling_clients == 1 && no_border_when_single && smartgaps - ? 0 - : borderpx; + if (VISIBLEON(c, m) && !c->isunglobal && ((m->isoverview && !client_is_x11_popup(c)) || ISTILED(c))) { cx = m->w.x + (i % cols) * (cw + target_gappi); diff --git a/src/layout/vertical.h b/src/layout/vertical.h index 07cb3ba8..713c385f 100644 --- a/src/layout/vertical.h +++ b/src/layout/vertical.h @@ -364,10 +364,6 @@ void vertical_grid(Monitor *m) { if (c->mon != m) continue; - c->bw = m->visible_tiling_clients == 1 && no_border_when_single && - smartgaps - ? 0 - : borderpx; if (VISIBLEON(c, m) && !c->isunglobal && ((m->isoverview && !client_is_x11_popup(c)) || ISTILED(c))) { ch = (m->w.height - 2 * target_gappo) * single_height_ratio; @@ -391,10 +387,6 @@ void vertical_grid(Monitor *m) { if (c->mon != m) continue; - c->bw = m->visible_tiling_clients == 1 && no_border_when_single && - smartgaps - ? 0 - : borderpx; if (VISIBLEON(c, m) && !c->isunglobal && ((m->isoverview && !client_is_x11_popup(c)) || ISTILED(c))) { if (i == 0) { @@ -437,10 +429,6 @@ void vertical_grid(Monitor *m) { if (c->mon != m) continue; - c->bw = - m->visible_tiling_clients == 1 && no_border_when_single && smartgaps - ? 0 - : borderpx; if (VISIBLEON(c, m) && !c->isunglobal && ((m->isoverview && !client_is_x11_popup(c)) || ISTILED(c))) { cx = m->w.x + (i / rows) * (cw + target_gappi); From 318dc85b22cb66c6bc4fcdb2b39cf8cf14cee0d3 Mon Sep 17 00:00:00 2001 From: DreamMaoMao <2523610504@qq.com> Date: Tue, 9 Dec 2025 20:35:21 +0800 Subject: [PATCH 06/12] opt: eliminate the positional deviation in master layout --- src/layout/horizontal.h | 81 ++++++++++++++++++++++++++++++----------- src/layout/vertical.h | 24 +++++++++--- 2 files changed, 78 insertions(+), 27 deletions(-) diff --git a/src/layout/horizontal.h b/src/layout/horizontal.h index 3ded199c..c036cfbe 100644 --- a/src/layout/horizontal.h +++ b/src/layout/horizontal.h @@ -413,6 +413,21 @@ void center_tile(Monitor *m) { // 判断是否需要主区域铺满 int should_overspread = center_master_overspread && (n <= nmasters); + uint32_t master_surplus_height = + (m->w.height - 2 * cur_gappov - + cur_gappiv * ie * (master_num - 1)); + float master_surplus_ratio = 1.0; + + uint32_t slave_left_surplus_height = + (m->w.height - 2 * cur_gappov - + cur_gappiv * ie * (stack_num / 2 - 1)); + float slave_left_surplus_ratio = 1.0; + + uint32_t slave_right_surplus_height = + (m->w.height - 2 * cur_gappov - + cur_gappiv * ie * ((stack_num + 1) / 2 - 1)); + float slave_right_surplus_ratio = 1.0; + if (n > nmasters || !should_overspread) { // 计算主区域宽度(居中模式) mw = nmasters ? (m->w.width - 2 * cur_gappoh - cur_gappih * ie) * mfact @@ -457,9 +472,9 @@ void center_tile(Monitor *m) { // 主区域窗口 r = MIN(n, nmasters) - i; if (c->master_inner_per > 0.0f) { - h = (m->w.height - 2 * cur_gappov - - cur_gappiv * ie * (master_num - 1)) * - c->master_inner_per; + h = master_surplus_height * c->master_inner_per / master_surplus_ratio; + master_surplus_height = master_surplus_height - h; + master_surplus_ratio = master_surplus_ratio - c->master_inner_per; c->master_mfact_per = mfact; } else { h = (m->w.height - my - cur_gappov - @@ -521,9 +536,9 @@ void center_tile(Monitor *m) { if ((stack_index % 2) ^ (n % 2 == 0)) { // 右侧堆叠窗口 if (c->stack_innder_per > 0.0f) { - h = (m->w.height - 2 * cur_gappov - - cur_gappiv * ie * ((stack_num + 1) / 2 - 1)) * - c->stack_innder_per; + h = slave_right_surplus_height * c->stack_innder_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; c->master_mfact_per = mfact; } else { h = (m->w.height - ety - cur_gappov - @@ -547,9 +562,9 @@ void center_tile(Monitor *m) { } else { // 左侧堆叠窗口 if (c->stack_innder_per > 0.0f) { - h = (m->w.height - 2 * cur_gappov - - cur_gappiv * ie * (stack_num / 2 - 1)) * - c->stack_innder_per; + h = slave_left_surplus_height * c->stack_innder_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; c->master_mfact_per = mfact; } else { h = (m->w.height - oty - cur_gappov - @@ -619,15 +634,26 @@ void tile(Monitor *m) { mw = m->w.width - 2 * cur_gappoh + cur_gappih * ie; i = 0; my = ty = cur_gappov; + + uint32_t master_surplus_height = + (m->w.height - 2 * cur_gappov - cur_gappiv * ie * (master_num - 1)); + float master_surplus_ratio = 1.0; + + uint32_t slave_surplus_height = + (m->w.height - 2 * cur_gappov - cur_gappiv * ie * (stack_num - 1)); + float slave_surplus_ratio = 1.0; + wl_list_for_each(c, &clients, link) { if (!VISIBLEON(c, m) || !ISTILED(c)) continue; if (i < m->pertag->nmasters[m->pertag->curtag]) { r = MIN(n, m->pertag->nmasters[m->pertag->curtag]) - i; if (c->master_inner_per > 0.0f) { - h = (m->w.height - 2 * cur_gappov - - cur_gappiv * ie * (master_num - 1)) * - c->master_inner_per; + h = master_surplus_height * c->master_inner_per / + master_surplus_ratio; + master_surplus_height = master_surplus_height - h; + master_surplus_ratio = + master_surplus_ratio - c->master_inner_per; c->master_mfact_per = mfact; } else { h = (m->w.height - my - cur_gappov - @@ -647,9 +673,10 @@ void tile(Monitor *m) { } else { r = n - i; if (c->stack_innder_per > 0.0f) { - h = (m->w.height - 2 * cur_gappov - - cur_gappiv * ie * (stack_num - 1)) * - c->stack_innder_per; + h = slave_surplus_height * c->stack_innder_per / + slave_surplus_ratio; + slave_surplus_height = slave_surplus_height - h; + slave_surplus_ratio = slave_surplus_ratio - c->stack_innder_per; c->master_mfact_per = mfact; } else { h = (m->w.height - ty - cur_gappov - @@ -717,15 +744,26 @@ void right_tile(Monitor *m) { mw = m->w.width - 2 * cur_gappoh + cur_gappih * ie; i = 0; my = ty = cur_gappov; + + uint32_t master_surplus_height = + (m->w.height - 2 * cur_gappov - cur_gappiv * ie * (master_num - 1)); + float master_surplus_ratio = 1.0; + + uint32_t slave_surplus_height = + (m->w.height - 2 * cur_gappov - cur_gappiv * ie * (stack_num - 1)); + float slave_surplus_ratio = 1.0; + wl_list_for_each(c, &clients, link) { if (!VISIBLEON(c, m) || !ISTILED(c)) continue; if (i < m->pertag->nmasters[m->pertag->curtag]) { r = MIN(n, m->pertag->nmasters[m->pertag->curtag]) - i; if (c->master_inner_per > 0.0f) { - h = (m->w.height - 2 * cur_gappov - - cur_gappiv * ie * (master_num - 1)) * - c->master_inner_per; + h = master_surplus_height * c->master_inner_per / + master_surplus_ratio; + master_surplus_height = master_surplus_height - h; + master_surplus_ratio = + master_surplus_ratio - c->master_inner_per; c->master_mfact_per = mfact; } else { h = (m->w.height - my - cur_gappov - @@ -746,9 +784,10 @@ void right_tile(Monitor *m) { } else { r = n - i; if (c->stack_innder_per > 0.0f) { - h = (m->w.height - 2 * cur_gappov - - cur_gappiv * ie * (stack_num - 1)) * - c->stack_innder_per; + h = slave_surplus_height * c->stack_innder_per / + slave_surplus_ratio; + slave_surplus_height = slave_surplus_height - h; + slave_surplus_ratio = slave_surplus_ratio - c->stack_innder_per; c->master_mfact_per = mfact; } else { h = (m->w.height - ty - cur_gappov - diff --git a/src/layout/vertical.h b/src/layout/vertical.h index 713c385f..3893a4ca 100644 --- a/src/layout/vertical.h +++ b/src/layout/vertical.h @@ -41,15 +41,26 @@ void vertical_tile(Monitor *m) { i = 0; mx = tx = cur_gapih; + + uint32_t master_surplus_width = + (m->w.width - 2 * cur_gapih - cur_gapih * ie * (master_num - 1)); + float master_surplus_ratio = 1.0; + + uint32_t slave_surplus_width = + (m->w.width - 2 * cur_gapih - cur_gapih * ie * (stack_num - 1)); + float slave_surplus_ratio = 1.0; + wl_list_for_each(c, &clients, link) { if (!VISIBLEON(c, m) || !ISTILED(c)) continue; if (i < m->pertag->nmasters[m->pertag->curtag]) { r = MIN(n, m->pertag->nmasters[m->pertag->curtag]) - i; if (c->master_inner_per > 0.0f) { - w = (m->w.width - 2 * cur_gapih - - cur_gapih * ie * (master_num - 1)) * - c->master_inner_per; + w = master_surplus_width * c->master_inner_per / + master_surplus_ratio; + master_surplus_width = master_surplus_width - w; + master_surplus_ratio = + master_surplus_ratio - c->master_inner_per; c->master_mfact_per = mfact; } else { w = (m->w.width - mx - cur_gapih - cur_gapih * ie * (r - 1)) / @@ -68,9 +79,10 @@ void vertical_tile(Monitor *m) { } else { r = n - i; if (c->stack_innder_per > 0.0f) { - w = (m->w.width - 2 * cur_gapih - - cur_gapih * ie * (stack_num - 1)) * - c->stack_innder_per; + w = slave_surplus_width * c->stack_innder_per / + slave_surplus_ratio; + slave_surplus_width = slave_surplus_width - w; + slave_surplus_ratio = slave_surplus_ratio - c->stack_innder_per; c->master_mfact_per = mfact; } else { w = (m->w.width - tx - cur_gapih - cur_gapih * ie * (r - 1)) / From 01e957f2aeab745c4969e928a1ed2b9f0a0968b5 Mon Sep 17 00:00:00 2001 From: DreamMaoMao <2523610504@qq.com> Date: Wed, 10 Dec 2025 18:29:16 +0800 Subject: [PATCH 07/12] opt: allow layershell surface toggle shortcut inhibit --- src/mango.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/src/mango.c b/src/mango.c index 8811c849..8950d3bf 100644 --- a/src/mango.c +++ b/src/mango.c @@ -5700,8 +5700,15 @@ void handle_keyboard_shortcuts_inhibit_new_inhibitor( } // per-view, seat-agnostic config via criteria - Client *c = get_client_from_surface(inhibitor->surface); - if (c && !c->allow_shortcuts_inhibit) { + Client *c = NULL; + LayerSurface *l = NULL; + + int type = toplevel_from_wlr_surface(inhibitor->surface, &c, &l); + + if (type < 0) + return; + + if (type != LayerShell && c && !c->allow_shortcuts_inhibit) { return; } From 2aa7e58d7cb059ad56cdad0ab6eb266aae4734cc Mon Sep 17 00:00:00 2001 From: DreamMaoMao <2523610504@qq.com> Date: Wed, 10 Dec 2025 18:30:45 +0800 Subject: [PATCH 08/12] opt: optimize get client from surface --- src/client/client.h | 14 -------------- src/ext-protocol/tearing.h | 5 ++++- 2 files changed, 4 insertions(+), 15 deletions(-) diff --git a/src/client/client.h b/src/client/client.h index 10ecfdf7..bc7706d7 100644 --- a/src/client/client.h +++ b/src/client/client.h @@ -153,20 +153,6 @@ static inline void client_get_geometry(Client *c, struct wlr_box *geom) { *geom = c->surface.xdg->geometry; } -static inline Client *get_client_from_surface(struct wlr_surface *surface) { - if (!surface) - return NULL; - - // 从 surface 的 data 指针获取 scene tree - struct wlr_scene_tree *scene_tree = surface->data; - if (!scene_tree) - return NULL; - - // 从 scene tree 的 node data 获取 Client - Client *c = scene_tree->node.data; - return c; -} - static inline Client *client_get_parent(Client *c) { Client *p = NULL; #ifdef XWAYLAND diff --git a/src/ext-protocol/tearing.h b/src/ext-protocol/tearing.h index 5ad36e8a..8e02656a 100644 --- a/src/ext-protocol/tearing.h +++ b/src/ext-protocol/tearing.h @@ -13,7 +13,10 @@ static void handle_controller_set_hint(struct wl_listener *listener, void *data) { struct tearing_controller *controller = wl_container_of(listener, controller, set_hint); - Client *c = get_client_from_surface(controller->tearing_control->surface); + Client *c = NULL; + + toplevel_from_wlr_surface(controller->tearing_control->surface, &c, NULL); + if (c) { /* * tearing_control->current is actually an enum: From 31d29fb48cc97b2f7e8de51f4e0c7b268f2a39e4 Mon Sep 17 00:00:00 2001 From: DreamMaoMao <2523610504@qq.com> Date: Wed, 10 Dec 2025 18:32:06 +0800 Subject: [PATCH 09/12] opt: format code --- src/layout/horizontal.h | 34 ++++++++++++++++++++-------------- 1 file changed, 20 insertions(+), 14 deletions(-) diff --git a/src/layout/horizontal.h b/src/layout/horizontal.h index c036cfbe..0a7613da 100644 --- a/src/layout/horizontal.h +++ b/src/layout/horizontal.h @@ -414,18 +414,16 @@ void center_tile(Monitor *m) { int should_overspread = center_master_overspread && (n <= nmasters); uint32_t master_surplus_height = - (m->w.height - 2 * cur_gappov - - cur_gappiv * ie * (master_num - 1)); + (m->w.height - 2 * cur_gappov - cur_gappiv * ie * (master_num - 1)); float master_surplus_ratio = 1.0; uint32_t slave_left_surplus_height = - (m->w.height - 2 * cur_gappov - - cur_gappiv * ie * (stack_num / 2 - 1)); + (m->w.height - 2 * cur_gappov - cur_gappiv * ie * (stack_num / 2 - 1)); float slave_left_surplus_ratio = 1.0; uint32_t slave_right_surplus_height = - (m->w.height - 2 * cur_gappov - - cur_gappiv * ie * ((stack_num + 1) / 2 - 1)); + (m->w.height - 2 * cur_gappov - + cur_gappiv * ie * ((stack_num + 1) / 2 - 1)); float slave_right_surplus_ratio = 1.0; if (n > nmasters || !should_overspread) { @@ -472,9 +470,11 @@ void center_tile(Monitor *m) { // 主区域窗口 r = MIN(n, nmasters) - i; if (c->master_inner_per > 0.0f) { - h = master_surplus_height * c->master_inner_per / master_surplus_ratio; + h = master_surplus_height * c->master_inner_per / + master_surplus_ratio; master_surplus_height = master_surplus_height - h; - master_surplus_ratio = master_surplus_ratio - c->master_inner_per; + master_surplus_ratio = + master_surplus_ratio - c->master_inner_per; c->master_mfact_per = mfact; } else { h = (m->w.height - my - cur_gappov - @@ -536,9 +536,12 @@ 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 / 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; + h = slave_right_surplus_height * c->stack_innder_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; c->master_mfact_per = mfact; } else { h = (m->w.height - ety - cur_gappov - @@ -562,9 +565,12 @@ void center_tile(Monitor *m) { } else { // 左侧堆叠窗口 if (c->stack_innder_per > 0.0f) { - h = slave_left_surplus_height * c->stack_innder_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; + h = slave_left_surplus_height * c->stack_innder_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; c->master_mfact_per = mfact; } else { h = (m->w.height - oty - cur_gappov - From 4e296671c277a38cf31b5619bc96e2bf92ddaa8b Mon Sep 17 00:00:00 2001 From: DreamMaoMao <2523610504@qq.com> Date: Wed, 10 Dec 2025 19:36:32 +0800 Subject: [PATCH 10/12] feat: handle foreign toplevel minimize and maximize request --- src/ext-protocol/foreign-toplevel.h | 41 +++++++++++++++++++++++++---- src/mango.c | 2 ++ 2 files changed, 38 insertions(+), 5 deletions(-) diff --git a/src/ext-protocol/foreign-toplevel.h b/src/ext-protocol/foreign-toplevel.h index 3b819485..4a725796 100644 --- a/src/ext-protocol/foreign-toplevel.h +++ b/src/ext-protocol/foreign-toplevel.h @@ -6,6 +6,36 @@ void handle_foreign_activate_request(struct wl_listener *listener, void *data) { Client *c = wl_container_of(listener, c, foreign_activate_request); uint32_t target; + if (c && c->swallowing) + return; + + if (c->isminimized) { + c->is_in_scratchpad = 0; + c->isnamedscratchpad = 0; + c->is_scratchpad_show = 0; + setborder_color(c); + show_hide_client(c); + arrange(c->mon, true); + return; + } + + target = get_tags_first_tag(c->tags); + view_in_mon(&(Arg){.ui = target}, true, c->mon, true); + focusclient(c, 1); + wlr_foreign_toplevel_handle_v1_set_activated(c->foreign_toplevel, true); +} + +void handle_foreign_maximize_request(struct wl_listener *listener, void *data) { + Client *c = wl_container_of(listener, c, foreign_maximize_request); + if (c->ismaximizescreen) { + setmaximizescreen(c, 0); + } else { + setmaximizescreen(c, 1); + } +} + +void handle_foreign_minimize_request(struct wl_listener *listener, void *data) { + Client *c = wl_container_of(listener, c, foreign_minimize_request); if (c && c->swallowing) return; @@ -23,11 +53,6 @@ void handle_foreign_activate_request(struct wl_listener *listener, void *data) { arrange(c->mon, true); return; } - - target = get_tags_first_tag(c->tags); - view_in_mon(&(Arg){.ui = target}, true, c->mon, true); - focusclient(c, 1); - wlr_foreign_toplevel_handle_v1_set_activated(c->foreign_toplevel, true); } void handle_foreign_fullscreen_request(struct wl_listener *listener, @@ -46,6 +71,8 @@ void handle_foreign_destroy(struct wl_listener *listener, void *data) { Client *c = wl_container_of(listener, c, foreign_destroy); if (c) { wl_list_remove(&c->foreign_activate_request.link); + wl_list_remove(&c->foreign_minimize_request.link); + wl_list_remove(&c->foreign_maximize_request.link); wl_list_remove(&c->foreign_fullscreen_request.link); wl_list_remove(&c->foreign_close_request.link); wl_list_remove(&c->foreign_destroy.link); @@ -67,6 +94,10 @@ void add_foreign_toplevel(Client *c) { if (c->foreign_toplevel) { LISTEN(&(c->foreign_toplevel->events.request_activate), &c->foreign_activate_request, handle_foreign_activate_request); + LISTEN(&(c->foreign_toplevel->events.request_minimize), + &c->foreign_minimize_request, handle_foreign_minimize_request); + LISTEN(&(c->foreign_toplevel->events.request_maximize), + &c->foreign_maximize_request, handle_foreign_maximize_request); LISTEN(&(c->foreign_toplevel->events.request_fullscreen), &c->foreign_fullscreen_request, handle_foreign_fullscreen_request); diff --git a/src/mango.c b/src/mango.c index 8950d3bf..53fffeca 100644 --- a/src/mango.c +++ b/src/mango.c @@ -351,6 +351,8 @@ struct Client { struct wl_listener foreign_fullscreen_request; struct wl_listener foreign_close_request; struct wl_listener foreign_destroy; + struct wl_listener foreign_minimize_request; + struct wl_listener foreign_maximize_request; struct wl_listener set_decoration_mode; struct wl_listener destroy_decoration; From 64d350ee9b7f78ed06389dfc198e058b52c60336 Mon Sep 17 00:00:00 2001 From: DreamMaoMao <2523610504@qq.com> Date: Wed, 10 Dec 2025 20:11:55 +0800 Subject: [PATCH 11/12] feat: add bing flag p --- src/config/parse_config.h | 6 +++++- src/mango.c | 6 +++++- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/src/config/parse_config.h b/src/config/parse_config.h index d845e2ab..0479c6d2 100644 --- a/src/config/parse_config.h +++ b/src/config/parse_config.h @@ -43,6 +43,7 @@ typedef struct { bool isdefaultmode; bool islockapply; bool isreleaseapply; + bool ispassapply; } KeyBinding; typedef struct { @@ -443,6 +444,9 @@ void parse_bind_flags(const char *str, KeyBinding *kb) { case 'r': kb->isreleaseapply = true; break; + case 'p': + kb->ispassapply = true; + break; default: // 忽略其他字符或可根据需要处理错误 break; @@ -1956,7 +1960,7 @@ void parse_option(Config *config, char *key, char *value) { config->exec_once_count++; - } else if (regex_match("^bind[s|l|r]*$", key)) { + } else if (regex_match("^bind[s|l|r|p]*$", key)) { config->key_bindings = realloc(config->key_bindings, (config->key_bindings_count + 1) * sizeof(KeyBinding)); diff --git a/src/mango.c b/src/mango.c index 53fffeca..4a87c607 100644 --- a/src/mango.c +++ b/src/mango.c @@ -3434,7 +3434,11 @@ keybinding(uint32_t state, bool locked, uint32_t mods, xkb_keysym_t sym, k->func) { isbreak = k->func(&k->arg); - handled = 1; + + if (!k->ispassapply) + handled = 1; + else + handled = 0; if (isbreak) break; From f771e56c31f6febc6ce04f2fbc0697dc487fdef4 Mon Sep 17 00:00:00 2001 From: DreamMaoMao <2523610504@qq.com> Date: Wed, 10 Dec 2025 22:35:45 +0800 Subject: [PATCH 12/12] opt: optimize handle foreign toplevel --- src/ext-protocol/foreign-toplevel.h | 59 +++++++++++++++++++---------- src/layout/arrange.h | 2 + 2 files changed, 42 insertions(+), 19 deletions(-) diff --git a/src/ext-protocol/foreign-toplevel.h b/src/ext-protocol/foreign-toplevel.h index 4a725796..01c384fb 100644 --- a/src/ext-protocol/foreign-toplevel.h +++ b/src/ext-protocol/foreign-toplevel.h @@ -6,7 +6,7 @@ void handle_foreign_activate_request(struct wl_listener *listener, void *data) { Client *c = wl_container_of(listener, c, foreign_activate_request); uint32_t target; - if (c && c->swallowing) + if (c->swallowing) return; if (c->isminimized) { @@ -22,29 +22,39 @@ void handle_foreign_activate_request(struct wl_listener *listener, void *data) { target = get_tags_first_tag(c->tags); view_in_mon(&(Arg){.ui = target}, true, c->mon, true); focusclient(c, 1); - wlr_foreign_toplevel_handle_v1_set_activated(c->foreign_toplevel, true); } void handle_foreign_maximize_request(struct wl_listener *listener, void *data) { Client *c = wl_container_of(listener, c, foreign_maximize_request); - if (c->ismaximizescreen) { + struct wlr_foreign_toplevel_handle_v1_maximized_event *event = data; + + if (c->swallowing) + return; + + if (c->ismaximizescreen && !event->maximized) { setmaximizescreen(c, 0); - } else { + return; + } + + if (!c->ismaximizescreen && event->maximized) { setmaximizescreen(c, 1); + return; } } void handle_foreign_minimize_request(struct wl_listener *listener, void *data) { Client *c = wl_container_of(listener, c, foreign_minimize_request); - if (c && c->swallowing) + struct wlr_foreign_toplevel_handle_v1_minimized_event *event = data; + + if (c->swallowing) return; - if (c && !c->isminimized && c == selmon->sel) { + if (!c->isminimized && event->minimized) { set_minimized(c); return; } - if (c->isminimized) { + if (c->isminimized && !event->minimized) { c->is_in_scratchpad = 0; c->isnamedscratchpad = 0; c->is_scratchpad_show = 0; @@ -57,26 +67,37 @@ void handle_foreign_minimize_request(struct wl_listener *listener, void *data) { void handle_foreign_fullscreen_request(struct wl_listener *listener, void *data) { - return; + + Client *c = wl_container_of(listener, c, foreign_fullscreen_request); + struct wlr_foreign_toplevel_handle_v1_fullscreen_event *event = data; + + if (c->swallowing) + return; + + if (c->isfullscreen && !event->fullscreen) { + setfullscreen(c, 0); + return; + } + + if (!c->isfullscreen && event->fullscreen) { + setfullscreen(c, 1); + return; + } } void handle_foreign_close_request(struct wl_listener *listener, void *data) { Client *c = wl_container_of(listener, c, foreign_close_request); - if (c) { - pending_kill_client(c); - } + pending_kill_client(c); } void handle_foreign_destroy(struct wl_listener *listener, void *data) { Client *c = wl_container_of(listener, c, foreign_destroy); - if (c) { - wl_list_remove(&c->foreign_activate_request.link); - wl_list_remove(&c->foreign_minimize_request.link); - wl_list_remove(&c->foreign_maximize_request.link); - wl_list_remove(&c->foreign_fullscreen_request.link); - wl_list_remove(&c->foreign_close_request.link); - wl_list_remove(&c->foreign_destroy.link); - } + wl_list_remove(&c->foreign_activate_request.link); + wl_list_remove(&c->foreign_minimize_request.link); + wl_list_remove(&c->foreign_maximize_request.link); + wl_list_remove(&c->foreign_fullscreen_request.link); + wl_list_remove(&c->foreign_close_request.link); + wl_list_remove(&c->foreign_destroy.link); } void remove_foreign_topleve(Client *c) { diff --git a/src/layout/arrange.h b/src/layout/arrange.h index 7a1d6205..f8966733 100644 --- a/src/layout/arrange.h +++ b/src/layout/arrange.h @@ -682,4 +682,6 @@ arrange(Monitor *m, bool want_animation) { motionnotify(0, NULL, 0, 0, 0, 0); checkidleinhibitor(NULL); } + + printstatus(); }