From 1029936b18f9e40be424ad1d542573f4c79398b4 Mon Sep 17 00:00:00 2001 From: eater <=@eater.me> Date: Fri, 7 Nov 2025 15:44:47 +0100 Subject: [PATCH 01/70] check is drm_release_manager is set before cleaning up to avoid segfault --- src/mango.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/mango.c b/src/mango.c index 36cbbbfa..09625204 100644 --- a/src/mango.c +++ b/src/mango.c @@ -1964,7 +1964,9 @@ void cleanuplisteners(void) { wl_list_remove(&request_start_drag.link); wl_list_remove(&start_drag.link); wl_list_remove(&new_session_lock.link); - wl_list_remove(&drm_lease_request.link); + if (drm_lease_manager) { + wl_list_remove(&drm_lease_request.link); + } wl_list_remove(&tearing_new_object.link); #ifdef XWAYLAND wl_list_remove(&new_xwayland_surface.link); From e0bc7fb5e47c545ce15e2be012a6c18b76894a55 Mon Sep 17 00:00:00 2001 From: DreamMaoMao <2523610504@qq.com> Date: Fri, 7 Nov 2025 21:56:25 +0800 Subject: [PATCH 02/70] fix: crash when click waybar overview button --- src/ext-protocol/ext-workspace.h | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/ext-protocol/ext-workspace.h b/src/ext-protocol/ext-workspace.h index 61e36da3..930e6c98 100644 --- a/src/ext-protocol/ext-workspace.h +++ b/src/ext-protocol/ext-workspace.h @@ -47,6 +47,11 @@ static void handle_ext_workspace_activate(struct wl_listener *listener, void *data) { struct workspace *workspace = wl_container_of(listener, workspace, activate); + + if (workspace->m->isoverview) { + return; + } + goto_workspace(workspace); wlr_log(WLR_INFO, "ext activating workspace %d", workspace->tag); } @@ -55,6 +60,11 @@ static void handle_ext_workspace_deactivate(struct wl_listener *listener, void *data) { struct workspace *workspace = wl_container_of(listener, workspace, deactivate); + + if (workspace->m->isoverview) { + return; + } + toggle_workspace(workspace); wlr_log(WLR_INFO, "ext deactivating workspace %d", workspace->tag); } From 9d6436cf42e89835f40664d5aa93c44b016ed679 Mon Sep 17 00:00:00 2001 From: DreamMaoMao <2523610504@qq.com> Date: Wed, 12 Nov 2025 12:55:06 +0800 Subject: [PATCH 03/70] feat: support keyboard shortcut inhibitor --- src/config/parse_config.h | 9 ++++ src/config/preset.h | 1 + src/mango.c | 88 ++++++++++++++++++++++++++++++++++++++- 3 files changed, 97 insertions(+), 1 deletion(-) diff --git a/src/config/parse_config.h b/src/config/parse_config.h index 0e9e15c5..a71d4f1e 100644 --- a/src/config/parse_config.h +++ b/src/config/parse_config.h @@ -69,6 +69,7 @@ typedef struct { int isunglobal; int isglobal; int isoverlay; + int allow_shortcuts_inhibit; int ignore_maximize; int ignore_minimize; int isnosizehint; @@ -336,6 +337,7 @@ typedef struct { int syncobj_enable; int adaptive_sync; int allow_tearing; + int allow_shortcuts_inhibit; struct xkb_rule_names xkb_rules; @@ -1271,6 +1273,8 @@ void parse_option(Config *config, char *key, char *value) { config->adaptive_sync = atoi(value); } else if (strcmp(key, "allow_tearing") == 0) { config->allow_tearing = atoi(value); + } else if (strcmp(key, "allow_shortcuts_inhibit") == 0) { + config->allow_shortcuts_inhibit = atoi(value); } else if (strcmp(key, "no_border_when_single") == 0) { config->no_border_when_single = atoi(value); } else if (strcmp(key, "no_radius_when_single") == 0) { @@ -1708,6 +1712,7 @@ void parse_option(Config *config, char *key, char *value) { rule->isunglobal = -1; rule->isglobal = -1; rule->isoverlay = -1; + rule->allow_shortcuts_inhibit = -1; rule->ignore_maximize = -1; rule->ignore_minimize = -1; rule->isnosizehint = -1; @@ -1806,6 +1811,8 @@ void parse_option(Config *config, char *key, char *value) { rule->focused_opacity = atof(val); } else if (strcmp(key, "isoverlay") == 0) { rule->isoverlay = atoi(val); + } else if (strcmp(key, "allow_shortcuts_inhibit") == 0) { + rule->allow_shortcuts_inhibit = atoi(val); } else if (strcmp(key, "ignore_maximize") == 0) { rule->ignore_maximize = atoi(val); } else if (strcmp(key, "ignore_minimize") == 0) { @@ -2696,6 +2703,7 @@ void override_config(void) { syncobj_enable = CLAMP_INT(config.syncobj_enable, 0, 1); adaptive_sync = CLAMP_INT(config.adaptive_sync, 0, 1); allow_tearing = CLAMP_INT(config.allow_tearing, 0, 2); + allow_shortcuts_inhibit = CLAMP_INT(config.allow_shortcuts_inhibit, 0, 1); axis_bind_apply_timeout = CLAMP_INT(config.axis_bind_apply_timeout, 0, 1000); focus_on_activate = CLAMP_INT(config.focus_on_activate, 0, 1); @@ -2873,6 +2881,7 @@ void set_value_default() { config.syncobj_enable = syncobj_enable; config.adaptive_sync = adaptive_sync; config.allow_tearing = allow_tearing; + config.allow_shortcuts_inhibit = allow_shortcuts_inhibit; config.no_border_when_single = no_border_when_single; config.no_radius_when_single = no_radius_when_single; config.snap_distance = snap_distance; diff --git a/src/config/preset.h b/src/config/preset.h index be1c1b0a..eaa7be22 100644 --- a/src/config/preset.h +++ b/src/config/preset.h @@ -105,6 +105,7 @@ int syncobj_enable = 0; int adaptive_sync = 0; double drag_refresh_interval = 30.0; int allow_tearing = TEARING_DISABLED; +int allow_shortcuts_inhibit = SHORTCUTS_INHIBIT_ENABLE; /* keyboard */ diff --git a/src/mango.c b/src/mango.c index 7ad9aa6f..6a66d0a4 100644 --- a/src/mango.c +++ b/src/mango.c @@ -48,6 +48,7 @@ #include #include #include +#include #include #include #include @@ -172,6 +173,11 @@ enum tearing_mode { TEARING_FULLSCREEN_ONLY, }; +enum seat_config_shortcuts_inhibit { + SHORTCUTS_INHIBIT_DISABLE, + SHORTCUTS_INHIBIT_ENABLE, +}; + typedef struct Pertag Pertag; typedef struct Monitor Monitor; typedef struct Client Client; @@ -369,6 +375,7 @@ struct Client { bool isleftstack; int tearing_hint; int force_tearing; + int allow_shortcuts_inhibit; }; typedef struct { @@ -398,6 +405,12 @@ typedef struct { struct wl_listener destroy; } KeyboardGroup; +typedef struct { + struct wlr_keyboard_shortcuts_inhibitor_v1 *inhibitor; + struct wl_listener destroy; + struct wl_list link; +} KeyboardShortcutsInhibitor; + typedef struct { /* Must keep these three elements in this order */ unsigned int type; /* LayerShell */ @@ -622,7 +635,9 @@ static void urgent(struct wl_listener *listener, void *data); static void view(const Arg *arg, bool want_animation); static void handlesig(int signo); - +static void +handle_keyboard_shortcuts_inhibit_new_inhibitor(struct wl_listener *listener, + void *data); static void virtualkeyboard(struct wl_listener *listener, void *data); static void virtualpointer(struct wl_listener *listener, void *data); static void warp_cursor(const Client *c); @@ -750,6 +765,8 @@ static struct wlr_idle_inhibit_manager_v1 *idle_inhibit_mgr; static struct wlr_layer_shell_v1 *layer_shell; static struct wlr_output_manager_v1 *output_mgr; static struct wlr_virtual_keyboard_manager_v1 *virtual_keyboard_mgr; +static struct wlr_keyboard_shortcuts_inhibit_manager_v1 + *keyboard_shortcuts_inhibit; static struct wlr_virtual_pointer_manager_v1 *virtual_pointer_mgr; static struct wlr_output_power_manager_v1 *power_mgr; static struct wlr_pointer_gestures_v1 *pointer_gestures; @@ -773,6 +790,7 @@ static struct wlr_pointer_constraint_v1 *active_constraint; static struct wlr_seat *seat; static KeyboardGroup *kb_group; static struct wl_list inputdevices; +static struct wl_list keyboard_shortcut_inhibitors; static unsigned int cursor_mode; static Client *grabc; static int grabcx, grabcy; /* client-relative */ @@ -859,6 +877,8 @@ static struct wl_listener request_start_drag = {.notify = requeststartdrag}; static struct wl_listener start_drag = {.notify = startdrag}; static struct wl_listener new_session_lock = {.notify = locksession}; static struct wl_listener drm_lease_request = {.notify = requestdrmlease}; +static struct wl_listener keyboard_shortcuts_inhibit_new_inhibitor = { + .notify = handle_keyboard_shortcuts_inhibit_new_inhibitor}; #ifdef XWAYLAND static void activatex11(struct wl_listener *listener, void *data); @@ -1150,6 +1170,7 @@ static void apply_rule_properties(Client *c, const ConfigWinRule *r) { APPLY_INT_PROP(c, r, isnosizehint); APPLY_INT_PROP(c, r, isunglobal); APPLY_INT_PROP(c, r, noblur); + APPLY_INT_PROP(c, r, allow_shortcuts_inhibit); APPLY_FLOAT_PROP(c, r, scroller_proportion); APPLY_FLOAT_PROP(c, r, focused_opacity); @@ -1977,6 +1998,7 @@ void cleanuplisteners(void) { wl_list_remove(&start_drag.link); wl_list_remove(&new_session_lock.link); wl_list_remove(&tearing_new_object.link); + wl_list_remove(&keyboard_shortcuts_inhibit_new_inhibitor.link); if (drm_lease_manager) { wl_list_remove(&drm_lease_request.link); } @@ -3266,6 +3288,17 @@ int keyrepeat(void *data) { return 0; } +bool is_keyboard_shortcut_inhibitor(struct wlr_surface *surface) { + KeyboardShortcutsInhibitor *kbsinhibitor; + + wl_list_for_each(kbsinhibitor, &keyboard_shortcut_inhibitors, link) { + if (kbsinhibitor->inhibitor->surface == surface) { + return true; + } + } + return false; +} + int // 17 keybinding(unsigned int state, bool locked, unsigned int mods, xkb_keysym_t sym, unsigned int keycode) { @@ -3284,6 +3317,10 @@ keybinding(unsigned int state, bool locked, unsigned int mods, xkb_keysym_t sym, keycode == 62 || keycode == 108 || keycode == 105 || keycode == 134) return false; + if (is_keyboard_shortcut_inhibitor(seat->keyboard_state.focused_surface)) { + return false; + } + for (ji = 0; ji < config.key_bindings_count; ji++) { if (config.key_bindings_count < 1) break; @@ -3591,6 +3628,7 @@ void init_client_properties(Client *c) { c->allow_csd = 0; c->force_maximize = 0; c->force_tearing = 0; + c->allow_shortcuts_inhibit = SHORTCUTS_INHIBIT_ENABLE; } void // old fix to 0.5 @@ -5003,6 +5041,7 @@ void setup(void) { * to let us know when new input devices are available on the backend. */ wl_list_init(&inputdevices); + wl_list_init(&keyboard_shortcut_inhibitors); wl_signal_add(&backend->events.new_input, &new_input_device); virtual_keyboard_mgr = wlr_virtual_keyboard_manager_v1_create(dpy); wl_signal_add(&virtual_keyboard_mgr->events.new_virtual_keyboard, @@ -5032,6 +5071,10 @@ void setup(void) { kb_group = createkeyboardgroup(); wl_list_init(&kb_group->destroy.link); + keyboard_shortcuts_inhibit = wlr_keyboard_shortcuts_inhibit_v1_create(dpy); + wl_signal_add(&keyboard_shortcuts_inhibit->events.new_inhibitor, + &keyboard_shortcuts_inhibit_new_inhibitor); + output_mgr = wlr_output_manager_v1_create(dpy); wl_signal_add(&output_mgr->events.apply, &output_mgr_apply); wl_signal_add(&output_mgr->events.test, &output_mgr_test); @@ -5559,6 +5602,49 @@ void view(const Arg *arg, bool want_animation) { } } +static void +handle_keyboard_shortcuts_inhibitor_destroy(struct wl_listener *listener, + void *data) { + KeyboardShortcutsInhibitor *inhibitor = + wl_container_of(listener, inhibitor, destroy); + + wlr_log(WLR_DEBUG, "Removing keyboard shortcuts inhibitor"); + + wl_list_remove(&inhibitor->link); + wl_list_remove(&inhibitor->destroy.link); + free(inhibitor); +} + +void handle_keyboard_shortcuts_inhibit_new_inhibitor( + struct wl_listener *listener, void *data) { + + struct wlr_keyboard_shortcuts_inhibitor_v1 *inhibitor = data; + + if (allow_shortcuts_inhibit == SHORTCUTS_INHIBIT_DISABLE) { + return; + } + + // per-view, seat-agnostic config via criteria + Client *c = get_client_from_surface(inhibitor->surface); + if (c && !c->allow_shortcuts_inhibit) { + return; + } + + wlr_log(WLR_DEBUG, "Adding keyboard shortcuts inhibitor"); + + KeyboardShortcutsInhibitor *kbsinhibitor = + calloc(1, sizeof(KeyboardShortcutsInhibitor)); + + kbsinhibitor->inhibitor = inhibitor; + + kbsinhibitor->destroy.notify = handle_keyboard_shortcuts_inhibitor_destroy; + wl_signal_add(&inhibitor->events.destroy, &kbsinhibitor->destroy); + + wl_list_insert(&keyboard_shortcut_inhibitors, &kbsinhibitor->link); + + wlr_keyboard_shortcuts_inhibitor_v1_activate(inhibitor); +} + void virtualkeyboard(struct wl_listener *listener, void *data) { struct wlr_virtual_keyboard_v1 *kb = data; /* virtual keyboards shouldn't share keyboard group */ From 18ad32384b1ab75c2e92d42b4d8775ff11c31d2e Mon Sep 17 00:00:00 2001 From: DreamMaoMao <2523610504@qq.com> Date: Sat, 8 Nov 2025 10:35:16 +0800 Subject: [PATCH 04/70] feat: add global option scroller_ignore_proportion_single --- src/config/parse_config.h | 7 +++++++ src/config/preset.h | 1 + src/layout/horizontal.h | 6 +++++- src/layout/vertical.h | 9 ++++++++- 4 files changed, 21 insertions(+), 2 deletions(-) diff --git a/src/config/parse_config.h b/src/config/parse_config.h index 19e64b70..30e118e8 100644 --- a/src/config/parse_config.h +++ b/src/config/parse_config.h @@ -193,6 +193,7 @@ typedef struct { int scroller_structs; float scroller_default_proportion; float scroller_default_proportion_single; + int scroller_ignore_proportion_single; int scroller_focus_center; int scroller_prefer_center; int edge_scroller_pointer_focus; @@ -1210,6 +1211,8 @@ void parse_option(Config *config, char *key, char *value) { config->scroller_default_proportion = atof(value); } else if (strcmp(key, "scroller_default_proportion_single") == 0) { config->scroller_default_proportion_single = atof(value); + } else if (strcmp(key, "scroller_ignore_proportion_single") == 0) { + config->scroller_ignore_proportion_single = atoi(value); } else if (strcmp(key, "scroller_focus_center") == 0) { config->scroller_focus_center = atoi(value); } else if (strcmp(key, "scroller_prefer_center") == 0) { @@ -2665,6 +2668,8 @@ void override_config(void) { CLAMP_FLOAT(config.scroller_default_proportion, 0.1f, 1.0f); scroller_default_proportion_single = CLAMP_FLOAT(config.scroller_default_proportion_single, 0.1f, 1.0f); + scroller_ignore_proportion_single = + CLAMP_INT(config.scroller_ignore_proportion_single, 0, 1); scroller_focus_center = CLAMP_INT(config.scroller_focus_center, 0, 1); scroller_prefer_center = CLAMP_INT(config.scroller_prefer_center, 0, 1); edge_scroller_pointer_focus = @@ -2852,6 +2857,8 @@ void set_value_default() { config.scroller_default_proportion = scroller_default_proportion; config.scroller_default_proportion_single = scroller_default_proportion_single; + config.scroller_ignore_proportion_single = + scroller_ignore_proportion_single; config.scroller_focus_center = scroller_focus_center; config.scroller_prefer_center = scroller_prefer_center; config.edge_scroller_pointer_focus = edge_scroller_pointer_focus; diff --git a/src/config/preset.h b/src/config/preset.h index 2f994ec1..be1c1b0a 100644 --- a/src/config/preset.h +++ b/src/config/preset.h @@ -60,6 +60,7 @@ float scratchpad_height_ratio = 0.9; int scroller_structs = 20; float scroller_default_proportion = 0.9; float scroller_default_proportion_single = 1.0; +int scroller_ignore_proportion_single = 0; int scroller_focus_center = 0; int scroller_prefer_center = 0; int focus_cross_monitor = 0; diff --git a/src/layout/horizontal.h b/src/layout/horizontal.h index b2d76bb3..178ae9e0 100644 --- a/src/layout/horizontal.h +++ b/src/layout/horizontal.h @@ -231,7 +231,7 @@ void scroller(Monitor *m) { } } - if (n == 1) { + if (n == 1 && !scroller_ignore_proportion_single) { c = tempClients[0]; target_geom.height = m->w.height - 2 * cur_gappov; target_geom.width = @@ -274,6 +274,10 @@ void scroller(Monitor *m) { } } + if (n == 1 && scroller_ignore_proportion_single) { + need_scroller = true; + } + if (start_drag_window) need_scroller = false; diff --git a/src/layout/vertical.h b/src/layout/vertical.h index 3c744639..6ae21a6c 100644 --- a/src/layout/vertical.h +++ b/src/layout/vertical.h @@ -192,7 +192,7 @@ void vertical_scroller(Monitor *m) { } } - if (n == 1) { + if (n == 1 && !scroller_ignore_proportion_single) { c = tempClients[0]; target_geom.width = m->w.width - 2 * cur_gappoh; target_geom.height = @@ -235,6 +235,13 @@ void vertical_scroller(Monitor *m) { } } + if (n == 1 && scroller_ignore_proportion_single) { + need_scroller = true; + } + + if (start_drag_window) + need_scroller = false; + target_geom.width = m->w.width - 2 * cur_gappoh; target_geom.height = max_client_height * c->scroller_proportion; target_geom.x = m->w.x + (m->w.width - target_geom.width) / 2; From d32fecfd2375ec9f89662b224230e23c13447be3 Mon Sep 17 00:00:00 2001 From: DreamMaoMao <2523610504@qq.com> Date: Wed, 12 Nov 2025 23:10:09 +0800 Subject: [PATCH 05/70] fix: crash in some crossmon dispatch --- src/dispatch/bind_define.h | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/dispatch/bind_define.h b/src/dispatch/bind_define.h index 65c2b03e..168852f4 100644 --- a/src/dispatch/bind_define.h +++ b/src/dispatch/bind_define.h @@ -971,7 +971,7 @@ int tag(const Arg *arg) { } int tagmon(const Arg *arg) { - Monitor *m = NULL; + Monitor *m = NULL,*cm = NULL; Client *c = focustop(selmon); if (!c) @@ -980,11 +980,12 @@ int tagmon(const Arg *arg) { if (arg->i != UNDIR) { m = dirtomon(arg->i); } else if (arg->v) { - wl_list_for_each(m, &mons, link) { - if (!m->wlr_output->enabled) { + wl_list_for_each(cm, &mons, link) { + if (!cm->wlr_output->enabled) { continue; } - if (regex_match(arg->v, m->wlr_output->name)) { + if (regex_match(arg->v, cm->wlr_output->name)) { + m = cm; break; } } From 5774df00e09d43ffe6148e6c84541a31793786bf Mon Sep 17 00:00:00 2001 From: DreamMaoMao <2523610504@qq.com> Date: Sat, 8 Nov 2025 12:39:41 +0800 Subject: [PATCH 06/70] opt:optimize code struct --- src/mango.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/mango.c b/src/mango.c index 09625204..96970aa2 100644 --- a/src/mango.c +++ b/src/mango.c @@ -1964,10 +1964,10 @@ void cleanuplisteners(void) { wl_list_remove(&request_start_drag.link); wl_list_remove(&start_drag.link); wl_list_remove(&new_session_lock.link); + wl_list_remove(&tearing_new_object.link); if (drm_lease_manager) { wl_list_remove(&drm_lease_request.link); } - wl_list_remove(&tearing_new_object.link); #ifdef XWAYLAND wl_list_remove(&new_xwayland_surface.link); wl_list_remove(&xwayland_ready.link); From e09748764d7f6501eeef71a4fff5b65cace0b88e Mon Sep 17 00:00:00 2001 From: DreamMaoMao <2523610504@qq.com> Date: Thu, 13 Nov 2025 10:42:35 +0800 Subject: [PATCH 07/70] opt: remove useless normalize keysym convert --- src/config/parse_config.h | 55 -------------------------------------- src/dispatch/bind_define.h | 2 +- src/mango.c | 4 +-- 3 files changed, 3 insertions(+), 58 deletions(-) diff --git a/src/config/parse_config.h b/src/config/parse_config.h index a71d4f1e..a6cfb647 100644 --- a/src/config/parse_config.h +++ b/src/config/parse_config.h @@ -517,61 +517,6 @@ long int parse_color(const char *hex_str) { return hex_num; } -xkb_keysym_t normalize_keysym(xkb_keysym_t sym) { - // 首先转换为小写(主要影响字母键) - sym = xkb_keysym_to_lower(sym); - - // 将数字小键盘键转换为普通数字键 - switch (sym) { - // 小键盘数字转换 - case XKB_KEY_KP_0: - return XKB_KEY_0; - case XKB_KEY_KP_1: - return XKB_KEY_1; - case XKB_KEY_KP_2: - return XKB_KEY_2; - case XKB_KEY_KP_3: - return XKB_KEY_3; - case XKB_KEY_KP_4: - return XKB_KEY_4; - case XKB_KEY_KP_5: - return XKB_KEY_5; - case XKB_KEY_KP_6: - return XKB_KEY_6; - case XKB_KEY_KP_7: - return XKB_KEY_7; - case XKB_KEY_KP_8: - return XKB_KEY_8; - case XKB_KEY_KP_9: - return XKB_KEY_9; - - // 将 Shift+数字 的符号转换回基础数字 - case XKB_KEY_exclam: - return XKB_KEY_1; // ! - case XKB_KEY_at: - return XKB_KEY_2; // @ - case XKB_KEY_numbersign: - return XKB_KEY_3; // # - case XKB_KEY_dollar: - return XKB_KEY_4; // $ - case XKB_KEY_percent: - return XKB_KEY_5; // % - case XKB_KEY_asciicircum: - return XKB_KEY_6; // ^ - case XKB_KEY_ampersand: - return XKB_KEY_7; // & - case XKB_KEY_asterisk: - return XKB_KEY_8; // * - case XKB_KEY_parenleft: - return XKB_KEY_9; // ( - case XKB_KEY_parenright: - return XKB_KEY_0; // ) - - default: - return sym; - } -} - // 辅助函数:检查字符串是否以指定的前缀开头(忽略大小写) static bool starts_with_ignore_case(const char *str, const char *prefix) { while (*prefix) { diff --git a/src/dispatch/bind_define.h b/src/dispatch/bind_define.h index 168852f4..d3ab6298 100644 --- a/src/dispatch/bind_define.h +++ b/src/dispatch/bind_define.h @@ -971,7 +971,7 @@ int tag(const Arg *arg) { } int tagmon(const Arg *arg) { - Monitor *m = NULL,*cm = NULL; + Monitor *m = NULL, *cm = NULL; Client *c = focustop(selmon); if (!c) diff --git a/src/mango.c b/src/mango.c index 6a66d0a4..eff7dde9 100644 --- a/src/mango.c +++ b/src/mango.c @@ -3345,8 +3345,8 @@ keybinding(unsigned int state, bool locked, unsigned int mods, xkb_keysym_t sym, (strcmp(keymode.mode, k->mode) == 0)) && CLEANMASK(mods) == CLEANMASK(k->mod) && ((k->keysymcode.type == KEY_TYPE_SYM && - normalize_keysym(sym) == - normalize_keysym(k->keysymcode.keysym)) || + xkb_keysym_to_lower(sym) == + xkb_keysym_to_lower(k->keysymcode.keysym)) || (k->keysymcode.type == KEY_TYPE_CODE && (keycode == k->keysymcode.keycode.keycode1 || keycode == k->keysymcode.keycode.keycode2 || From 6010cea8051b82004392b092958b960d280271ce Mon Sep 17 00:00:00 2001 From: DreamMaoMao <2523610504@qq.com> Date: Sat, 8 Nov 2025 20:10:11 +0800 Subject: [PATCH 08/70] opt: optimize shadow node and blur node enable --- src/animation/client.h | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/animation/client.h b/src/animation/client.h index 90b664b5..bf8864bd 100644 --- a/src/animation/client.h +++ b/src/animation/client.h @@ -255,8 +255,12 @@ void client_draw_shadow(Client *c) { return; if (!shadows || (!c->isfloating && shadow_only_floating)) { - wlr_scene_shadow_set_size(c->shadow, 0, 0); + if (c->shadow->node.enabled) + wlr_scene_node_set_enabled(&c->shadow->node, false); return; + } else { + if (c->scene_surface->node.enabled && !c->shadow->node.enabled) + wlr_scene_node_set_enabled(&c->shadow->node, true); } bool hit_no_border = check_hit_no_border(c); From 050171960420c438d7345395f4752fa5232cda59 Mon Sep 17 00:00:00 2001 From: DreamMaoMao <2523610504@qq.com> Date: Thu, 13 Nov 2025 10:49:44 +0800 Subject: [PATCH 09/70] opt: spawn_on_empty and toggle_named_scratchapd use spawn_shell --- src/dispatch/bind_define.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/dispatch/bind_define.h b/src/dispatch/bind_define.h index d3ab6298..27f79775 100644 --- a/src/dispatch/bind_define.h +++ b/src/dispatch/bind_define.h @@ -805,7 +805,7 @@ int spawn_on_empty(const Arg *arg) { return 0; } else { view(arg, true); - spawn(arg); + spawn_shell(arg); } return 0; } @@ -1088,7 +1088,7 @@ int toggle_named_scratchpad(const Arg *arg) { if (!target_client && arg->v3) { Arg arg_spawn = {.v = arg->v3}; - spawn(&arg_spawn); + spawn_shell(&arg_spawn); return 0; } From 64dc30dc31d585e6e5d2c3547488282b124130f6 Mon Sep 17 00:00:00 2001 From: DreamMaoMao <2523610504@qq.com> Date: Sat, 8 Nov 2025 20:17:16 +0800 Subject: [PATCH 10/70] opt: disable resize scroller window when it force to default single size --- src/layout/arrange.h | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/layout/arrange.h b/src/layout/arrange.h index 4df97865..b53592f3 100644 --- a/src/layout/arrange.h +++ b/src/layout/arrange.h @@ -374,6 +374,10 @@ void resize_tile_scroller(Client *grabc, bool isdrag, int offsetx, int offsety, float delta_x, delta_y; float new_scroller_proportion; + if (grabc && grabc->mon->visible_tiling_clients == 1 && + !scroller_ignore_proportion_single) + return; + if (!start_drag_window && isdrag) { drag_begin_cursorx = cursor->x; drag_begin_cursory = cursor->y; From 17f1ae2463146d2525a389121df5129316a538fa Mon Sep 17 00:00:00 2001 From: DreamMaoMao <2523610504@qq.com> Date: Thu, 13 Nov 2025 10:55:44 +0800 Subject: [PATCH 11/70] opt: optmize restore_minimized size and not restore namedscratchpad --- src/dispatch/bind_define.h | 2 +- src/mango.c | 5 ++++- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/src/dispatch/bind_define.h b/src/dispatch/bind_define.h index 27f79775..d653bb18 100644 --- a/src/dispatch/bind_define.h +++ b/src/dispatch/bind_define.h @@ -476,7 +476,7 @@ int restore_minimized(const Arg *arg) { } wl_list_for_each(c, &clients, link) { - if (c->isminied) { + if (c->isminied && !c->isnamedscratchpad) { c->is_scratchpad_show = 0; c->is_in_scratchpad = 0; c->isnamedscratchpad = 0; diff --git a/src/mango.c b/src/mango.c index eff7dde9..aa22de3c 100644 --- a/src/mango.c +++ b/src/mango.c @@ -4793,8 +4793,11 @@ void setsel(struct wl_listener *listener, void *data) { } void show_hide_client(Client *c) { + unsigned int target = 1; + + set_size_per(c->mon, c); + target = get_tags_first_tag(c->oldtags); - unsigned int target = get_tags_first_tag(c->oldtags); if (!c->is_in_scratchpad) { tag_client(&(Arg){.ui = target}, c); } else { From 5ba7da0570b0f66e69604e1a06b24b45114d455c Mon Sep 17 00:00:00 2001 From: DreamMaoMao <2523610504@qq.com> Date: Sat, 8 Nov 2025 22:47:18 +0800 Subject: [PATCH 12/70] opt: remove increase_proportion dispatch should use resizewin to replace it --- src/config/parse_config.h | 3 --- src/dispatch/bind_declare.h | 1 - src/dispatch/bind_define.h | 12 ------------ 3 files changed, 16 deletions(-) diff --git a/src/config/parse_config.h b/src/config/parse_config.h index 30e118e8..321de209 100644 --- a/src/config/parse_config.h +++ b/src/config/parse_config.h @@ -887,9 +887,6 @@ FuncType parse_func_name(char *func_name, Arg *arg, char *arg_value, } else if (strcmp(func_name, "set_proportion") == 0) { func = set_proportion; (*arg).f = atof(arg_value); - } else if (strcmp(func_name, "increase_proportion") == 0) { - func = increase_proportion; - (*arg).f = atof(arg_value); } else if (strcmp(func_name, "switch_proportion_preset") == 0) { func = switch_proportion_preset; } else if (strcmp(func_name, "viewtoleft") == 0) { diff --git a/src/dispatch/bind_declare.h b/src/dispatch/bind_declare.h index b38e2da5..5bc215a2 100644 --- a/src/dispatch/bind_declare.h +++ b/src/dispatch/bind_declare.h @@ -4,7 +4,6 @@ int toggle_scratchpad(const Arg *arg); int focusdir(const Arg *arg); int toggleoverview(const Arg *arg); int set_proportion(const Arg *arg); -int increase_proportion(const Arg *arg); int switch_proportion_preset(const Arg *arg); int zoom(const Arg *arg); int tagsilent(const Arg *arg); diff --git a/src/dispatch/bind_define.h b/src/dispatch/bind_define.h index 57288b4c..464e2a6c 100644 --- a/src/dispatch/bind_define.h +++ b/src/dispatch/bind_define.h @@ -281,18 +281,6 @@ int incovgaps(const Arg *arg) { return 0; } -int increase_proportion(const Arg *arg) { - if (selmon->sel) { - unsigned int max_client_width = - selmon->w.width - 2 * scroller_structs - gappih; - selmon->sel->scroller_proportion = - MIN(MAX(arg->f + selmon->sel->scroller_proportion, 0.1), 1.0); - selmon->sel->geom.width = max_client_width * arg->f; - arrange(selmon, false); - } - return 0; -} - int setmfact(const Arg *arg) { float f; Client *c = NULL; From 16296898ce694ced439b1bd2aa2080b45859c51f Mon Sep 17 00:00:00 2001 From: DreamMaoMao <2523610504@qq.com> Date: Fri, 14 Nov 2025 11:53:41 +0800 Subject: [PATCH 13/70] fix: tagrule not apply correctly --- src/config/parse_config.h | 46 +++++++++++++++++++++------------------ src/mango.c | 13 +---------- 2 files changed, 26 insertions(+), 33 deletions(-) diff --git a/src/config/parse_config.h b/src/config/parse_config.h index a6cfb647..59cb37bc 100644 --- a/src/config/parse_config.h +++ b/src/config/parse_config.h @@ -3165,33 +3165,37 @@ void reapply_master(void) { } } +void parse_tagrule(Monitor *m) { + int i, jk; + + for (i = 0; i < config.tag_rules_count; i++) { + + if (config.tag_rules_count > 0 && + (!config.tag_rules[i].monitor_name || + regex_match(config.tag_rules[i].monitor_name, + m->wlr_output->name))) { + + for (jk = 0; jk < LENGTH(layouts); jk++) { + if (config.tag_rules[i].layout_name && + strcmp(layouts[jk].name, config.tag_rules[i].layout_name) == + 0) { + m->pertag->ltidxs[config.tag_rules[i].id] = &layouts[jk]; + } + } + + m->pertag->no_hide[config.tag_rules[i].id] = + config.tag_rules[i].no_hide; + } + } +} + void reapply_tagrule(void) { Monitor *m = NULL; - int i, jk; - char *rule_monitor_name = NULL; wl_list_for_each(m, &mons, link) { if (!m->wlr_output->enabled) { continue; } - - // apply tag rule - for (i = 1; i <= config.tag_rules_count; i++) { - rule_monitor_name = config.tag_rules[i - 1].monitor_name; - if (regex_match(rule_monitor_name, m->wlr_output->name) || - !rule_monitor_name) { - for (jk = 0; jk < LENGTH(layouts); jk++) { - if (config.tag_rules_count > 0 && - config.tag_rules[i - 1].layout_name && - strcmp(layouts[jk].name, - config.tag_rules[i - 1].layout_name) == 0) { - m->pertag->ltidxs[config.tag_rules[i - 1].id] = - &layouts[jk]; - m->pertag->no_hide[config.tag_rules[i - 1].id] = - config.tag_rules[i - 1].no_hide; - } - } - } - } + parse_tagrule(m); } } diff --git a/src/mango.c b/src/mango.c index aa22de3c..2ab3eabe 100644 --- a/src/mango.c +++ b/src/mango.c @@ -2694,18 +2694,7 @@ void createmon(struct wl_listener *listener, void *data) { } // apply tag rule - for (i = 1; i <= config.tag_rules_count; i++) { - for (jk = 0; jk < LENGTH(layouts); jk++) { - if (config.tag_rules_count > 0 && - config.tag_rules[i - 1].layout_name && - strcmp(layouts[jk].name, config.tag_rules[i - 1].layout_name) == - 0) { - m->pertag->ltidxs[config.tag_rules[i - 1].id] = &layouts[jk]; - m->pertag->no_hide[config.tag_rules[i - 1].id] = - config.tag_rules[i - 1].no_hide; - } - } - } + parse_tagrule(m); /* The xdg-protocol specifies: * From 33a0fe24850785b57c97308d3c15553a41920f8a Mon Sep 17 00:00:00 2001 From: DreamMaoMao <2523610504@qq.com> Date: Sat, 8 Nov 2025 22:48:53 +0800 Subject: [PATCH 14/70] opt: not resizewin in overview --- src/layout/arrange.h | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/layout/arrange.h b/src/layout/arrange.h index b53592f3..aafb79e0 100644 --- a/src/layout/arrange.h +++ b/src/layout/arrange.h @@ -479,6 +479,9 @@ void resize_tile_client(Client *grabc, bool isdrag, int offsetx, int offsety, if (!grabc || grabc->isfullscreen || grabc->ismaximizescreen) return; + if (grabc->mon->isoverview) + return; + const Layout *current_layout = grabc->mon->pertag->ltidxs[grabc->mon->pertag->curtag]; if (current_layout->id == TILE || current_layout->id == DECK || From d85f4375c8fee672e376e81df6e42f2043176988 Mon Sep 17 00:00:00 2001 From: DreamMaoMao <2523610504@qq.com> Date: Fri, 14 Nov 2025 12:15:34 +0800 Subject: [PATCH 15/70] fix: fix border color change when swithc mon focus --- src/animation/client.h | 2 +- src/dispatch/bind_define.h | 2 +- src/fetch/client.h | 5 ++++- src/mango.c | 9 +++++++-- 4 files changed, 13 insertions(+), 5 deletions(-) diff --git a/src/animation/client.h b/src/animation/client.h index bf8864bd..e3673a20 100644 --- a/src/animation/client.h +++ b/src/animation/client.h @@ -1060,7 +1060,7 @@ void client_set_focused_opacity_animation(Client *c) { c->opacity_animation.running = true; } -void cleint_set_unfocused_opacity_animation(Client *c) { +void client_set_unfocused_opacity_animation(Client *c) { // Start border color animation to unfocused float *border_color = get_border_color(c); diff --git a/src/dispatch/bind_define.h b/src/dispatch/bind_define.h index d653bb18..c812bf14 100644 --- a/src/dispatch/bind_define.h +++ b/src/dispatch/bind_define.h @@ -202,7 +202,7 @@ int focusmon(const Arg *arg) { focusclient(c, 1); if (old_selmon_sel) { - setborder_color(old_selmon_sel); + client_set_unfocused_opacity_animation(old_selmon_sel); } return 0; } diff --git a/src/fetch/client.h b/src/fetch/client.h index 6e675223..5f62d234 100644 --- a/src/fetch/client.h +++ b/src/fetch/client.h @@ -374,7 +374,10 @@ Client *get_next_stack_client(Client *c, bool reverse) { } float *get_border_color(Client *c) { - if (c->isurgent) { + + if (c->mon != selmon) { + return bordercolor; + } else if (c->isurgent) { return urgentcolor; } else if (c->is_in_scratchpad && selmon && c == selmon->sel) { return scratchpadcolor; diff --git a/src/mango.c b/src/mango.c index 2ab3eabe..7bb3bb24 100644 --- a/src/mango.c +++ b/src/mango.c @@ -3092,6 +3092,9 @@ void destroykeyboardgroup(struct wl_listener *listener, void *data) { } void focusclient(Client *c, int lift) { + + Client *last_focus_client = NULL; + struct wlr_surface *old_keyboard_focus_surface = seat->keyboard_state.focused_surface; @@ -3126,12 +3129,14 @@ void focusclient(Client *c, int lift) { if (c && !c->iskilling && !client_is_unmanaged(c) && c->mon) { + last_focus_client = selmon->sel; selmon = c->mon; selmon->prevsel = selmon->sel; selmon->sel = c; - if (selmon->prevsel && !selmon->prevsel->iskilling) { - cleint_set_unfocused_opacity_animation(selmon->prevsel); + if (last_focus_client && !last_focus_client->iskilling && + last_focus_client != c) { + client_set_unfocused_opacity_animation(last_focus_client); } client_set_focused_opacity_animation(c); From f542d5d5e6d9999b627ffd5f55bf4a2085a36041 Mon Sep 17 00:00:00 2001 From: DreamMaoMao <2523610504@qq.com> Date: Sat, 8 Nov 2025 23:26:52 +0800 Subject: [PATCH 16/70] opt: disable switch proportion action in some case --- src/dispatch/bind_define.h | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/src/dispatch/bind_define.h b/src/dispatch/bind_define.h index 464e2a6c..65c2b03e 100644 --- a/src/dispatch/bind_define.h +++ b/src/dispatch/bind_define.h @@ -518,6 +518,14 @@ int setkeymode(const Arg *arg) { } int set_proportion(const Arg *arg) { + + if (selmon->isoverview || !is_scroller_layout(selmon)) + return 0; + + if (selmon->visible_tiling_clients == 1 && + !scroller_ignore_proportion_single) + return 0; + if (selmon->sel) { unsigned int max_client_width = selmon->w.width - 2 * scroller_structs - gappih; @@ -919,6 +927,13 @@ int switch_proportion_preset(const Arg *arg) { return 0; } + if (selmon->isoverview || !is_scroller_layout(selmon)) + return 0; + + if (selmon->visible_tiling_clients == 1 && + !scroller_ignore_proportion_single) + return 0; + if (selmon->sel) { for (int i = 0; i < config.scroller_proportion_preset_count; i++) { From 514c9166785274ed525ecc3ef4697d71c47b2ab4 Mon Sep 17 00:00:00 2001 From: DreamMaoMao <2523610504@qq.com> Date: Fri, 14 Nov 2025 12:32:07 +0800 Subject: [PATCH 17/70] opt: optimize code struct --- src/config/parse_config.h | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/src/config/parse_config.h b/src/config/parse_config.h index 59cb37bc..63580830 100644 --- a/src/config/parse_config.h +++ b/src/config/parse_config.h @@ -3167,24 +3167,24 @@ void reapply_master(void) { void parse_tagrule(Monitor *m) { int i, jk; + ConfigTagRule tr; for (i = 0; i < config.tag_rules_count; i++) { + tr = config.tag_rules[i]; + if (config.tag_rules_count > 0 && - (!config.tag_rules[i].monitor_name || - regex_match(config.tag_rules[i].monitor_name, - m->wlr_output->name))) { + (!tr.monitor_name || + regex_match(tr.monitor_name, m->wlr_output->name))) { for (jk = 0; jk < LENGTH(layouts); jk++) { - if (config.tag_rules[i].layout_name && - strcmp(layouts[jk].name, config.tag_rules[i].layout_name) == - 0) { - m->pertag->ltidxs[config.tag_rules[i].id] = &layouts[jk]; + if (tr.layout_name && + strcmp(layouts[jk].name, tr.layout_name) == 0) { + m->pertag->ltidxs[tr.id] = &layouts[jk]; } } - m->pertag->no_hide[config.tag_rules[i].id] = - config.tag_rules[i].no_hide; + m->pertag->no_hide[tr.id] = tr.no_hide; } } } From 8875156760b48d82c209cff895b61aa5b3817f4a Mon Sep 17 00:00:00 2001 From: DreamMaoMao <2523610504@qq.com> Date: Sun, 9 Nov 2025 15:40:51 +0800 Subject: [PATCH 18/70] feat: support nofucs rule for some special window --- src/config/parse_config.h | 4 ++++ src/mango.c | 42 +++++++++++++++++++++++---------------- 2 files changed, 29 insertions(+), 17 deletions(-) diff --git a/src/config/parse_config.h b/src/config/parse_config.h index 321de209..0e9e15c5 100644 --- a/src/config/parse_config.h +++ b/src/config/parse_config.h @@ -77,6 +77,7 @@ typedef struct { int offsety; int width; int height; + int nofocus; int nofadein; int nofadeout; int no_force_center; @@ -1716,6 +1717,7 @@ void parse_option(Config *config, char *key, char *value) { rule->force_tearing = -1; rule->noswallow = -1; rule->noblur = -1; + rule->nofocus = -1; rule->nofadein = -1; rule->nofadeout = -1; rule->no_force_center = -1; @@ -1770,6 +1772,8 @@ void parse_option(Config *config, char *key, char *value) { rule->offsetx = atoi(val); } else if (strcmp(key, "offsety") == 0) { rule->offsety = atoi(val); + } else if (strcmp(key, "nofocus") == 0) { + rule->nofocus = atoi(val); } else if (strcmp(key, "nofadein") == 0) { rule->nofadein = atoi(val); } else if (strcmp(key, "nofadeout") == 0) { diff --git a/src/mango.c b/src/mango.c index 96970aa2..f7440f49 100644 --- a/src/mango.c +++ b/src/mango.c @@ -352,6 +352,7 @@ struct Client { bool drag_to_tile; bool scratchpad_switching_mon; bool fake_no_border; + int nofocus; int nofadein; int nofadeout; int no_force_center; @@ -1130,6 +1131,7 @@ static void apply_rule_properties(Client *c, const ConfigWinRule *r) { APPLY_INT_PROP(c, r, force_maximize); APPLY_INT_PROP(c, r, force_tearing); APPLY_INT_PROP(c, r, noswallow); + APPLY_INT_PROP(c, r, nofocus); APPLY_INT_PROP(c, r, nofadein); APPLY_INT_PROP(c, r, nofadeout); APPLY_INT_PROP(c, r, no_force_center); @@ -1243,11 +1245,16 @@ void applyrules(Client *c) { const char *appid, *title; unsigned int i, newtags = 0; const ConfigWinRule *r; - Monitor *mon = selmon, *m = NULL; + Monitor *m = NULL; Client *fc = NULL; bool hit_rule_pos = false; + Client *parent = NULL; - c->isfloating = client_is_float_type(c); + parent = client_get_parent(c); + + Monitor *mon = parent && parent->mon ? parent->mon : selmon; + + c->isfloating = client_is_float_type(c) || parent; if (!(appid = client_get_appid(c))) appid = broken; if (!(title = client_get_title(c))) @@ -1264,8 +1271,14 @@ void applyrules(Client *c) { // set general properties apply_rule_properties(c, r); - // set tags - newtags |= (r->tags > 0) ? r->tags : 0; + // // set tags + if (r->tags > 0) { + newtags |= r->tags; + } else if (parent) { + newtags = parent->tags; + } else { + newtags |= 0; + } // set monitor of client wl_list_for_each(m, &mons, link) { @@ -1334,8 +1347,9 @@ void applyrules(Client *c) { int fullscreen_state_backup = c->isfullscreen || client_wants_fullscreen(c); setmon(c, mon, newtags, - !c->isopensilent && (!c->istagsilent || !newtags || - newtags & mon->tagset[mon->seltags])); + !c->isopensilent && !client_should_ignore_focus(c) && + (!c->istagsilent || !newtags || + newtags & mon->tagset[mon->seltags])); if (c->mon && !(c->mon == selmon && c->tags & c->mon->tagset[c->mon->seltags]) && @@ -3084,6 +3098,9 @@ void focusclient(Client *c, int lift) { if (c && client_should_ignore_focus(c) && client_is_x11_popup(c)) return; + if (c && c->nofocus) + return; + /* Raise client in stacking order if requested */ if (c && lift) wlr_scene_node_raise_to_top(&c->scene->node); // 将视图提升到顶层 @@ -3560,6 +3577,7 @@ void init_client_properties(Client *c) { c->fake_no_border = false; c->focused_opacity = focused_opacity; c->unfocused_opacity = unfocused_opacity; + c->nofocus = 0; c->nofadein = 0; c->nofadeout = 0; c->no_force_center = 0; @@ -3580,7 +3598,6 @@ void init_client_properties(Client *c) { void // old fix to 0.5 mapnotify(struct wl_listener *listener, void *data) { /* Called when the surface is mapped, or ready to display on-screen. */ - Client *p = NULL; Client *at_client = NULL; Client *c = wl_container_of(listener, c, map); /* Create scene tree for this client and its border */ @@ -3672,16 +3689,7 @@ mapnotify(struct wl_listener *listener, void *data) { wl_list_insert(clients.prev, &c->link); // 尾部入栈 wl_list_insert(&fstack, &c->flink); - /* Set initial monitor, tags, floating status, and focus: - * we always consider floating, clients that have parent and thus - * we set the same tags and monitor than its parent, if not - * try to apply rules for them */ - if ((p = client_get_parent(c))) { - c->isfloating = 1; - setmon(c, p->mon, p->tags, true); - } else { - applyrules(c); - } + applyrules(c); client_set_tiled(c, WLR_EDGE_TOP | WLR_EDGE_BOTTOM | WLR_EDGE_LEFT | WLR_EDGE_RIGHT); From 407c9d74a42763f56817af2ee4821c92e9eba4f7 Mon Sep 17 00:00:00 2001 From: DreamMaoMao <2523610504@qq.com> Date: Fri, 14 Nov 2025 15:39:04 +0800 Subject: [PATCH 19/70] feat: add windowrule option scroller_proportion_single --- src/config/parse_config.h | 4 ++++ src/layout/horizontal.h | 9 +++++++-- src/layout/vertical.h | 10 ++++++++-- src/mango.c | 3 +++ 4 files changed, 22 insertions(+), 4 deletions(-) diff --git a/src/config/parse_config.h b/src/config/parse_config.h index 63580830..074660bf 100644 --- a/src/config/parse_config.h +++ b/src/config/parse_config.h @@ -90,6 +90,7 @@ typedef struct { int noblur; float focused_opacity; float unfocused_opacity; + float scroller_proportion_single; uint32_t passmod; xkb_keysym_t keysym; KeyBinding globalkeybinding; @@ -1679,6 +1680,7 @@ void parse_option(Config *config, char *key, char *value) { // float rule value, relay to a client property rule->focused_opacity = 0; rule->unfocused_opacity = 0; + rule->scroller_proportion_single = 0.0f; rule->scroller_proportion = 0; // special rule value,not directly set to client property @@ -1750,6 +1752,8 @@ void parse_option(Config *config, char *key, char *value) { rule->isunglobal = atoi(val); } else if (strcmp(key, "isglobal") == 0) { rule->isglobal = atoi(val); + } else if (strcmp(key, "scroller_proportion_single") == 0) { + rule->scroller_proportion_single = atof(val); } else if (strcmp(key, "unfocused_opacity") == 0) { rule->unfocused_opacity = atof(val); } else if (strcmp(key, "focused_opacity") == 0) { diff --git a/src/layout/horizontal.h b/src/layout/horizontal.h index 178ae9e0..934dc136 100644 --- a/src/layout/horizontal.h +++ b/src/layout/horizontal.h @@ -192,6 +192,7 @@ void deck(Monitor *m) { // 滚动布局 void scroller(Monitor *m) { unsigned int i, n, j; + float single_proportion = 1.0; Client *c = NULL, *root_client = NULL; Client **tempClients = NULL; // 初始化为 NULL @@ -233,9 +234,13 @@ void scroller(Monitor *m) { if (n == 1 && !scroller_ignore_proportion_single) { c = tempClients[0]; + + single_proportion = c->scroller_proportion_single > 0.0f + ? c->scroller_proportion_single + : scroller_default_proportion_single; + target_geom.height = m->w.height - 2 * cur_gappov; - target_geom.width = - (m->w.width - 2 * cur_gappoh) * scroller_default_proportion_single; + target_geom.width = (m->w.width - 2 * cur_gappoh) * single_proportion; target_geom.x = m->w.x + (m->w.width - target_geom.width) / 2; target_geom.y = m->w.y + (m->w.height - target_geom.height) / 2; resize(c, target_geom, 0); diff --git a/src/layout/vertical.h b/src/layout/vertical.h index 6ae21a6c..46ca3b65 100644 --- a/src/layout/vertical.h +++ b/src/layout/vertical.h @@ -157,6 +157,8 @@ void vertical_deck(Monitor *m) { void vertical_scroller(Monitor *m) { unsigned int i, n, j; + float single_proportion = 1.0; + Client *c = NULL, *root_client = NULL; Client **tempClients = NULL; struct wlr_box target_geom; @@ -194,9 +196,13 @@ void vertical_scroller(Monitor *m) { if (n == 1 && !scroller_ignore_proportion_single) { c = tempClients[0]; + + single_proportion = c->scroller_proportion_single > 0.0f + ? c->scroller_proportion_single + : scroller_default_proportion_single; + target_geom.width = m->w.width - 2 * cur_gappoh; - target_geom.height = - (m->w.height - 2 * cur_gappov) * scroller_default_proportion_single; + target_geom.height = (m->w.height - 2 * cur_gappov) * single_proportion; target_geom.x = m->w.x + (m->w.width - target_geom.width) / 2; target_geom.y = m->w.y + (m->w.height - target_geom.height) / 2; resize(c, target_geom, 0); diff --git a/src/mango.c b/src/mango.c index 7bb3bb24..601c36f5 100644 --- a/src/mango.c +++ b/src/mango.c @@ -376,6 +376,7 @@ struct Client { int tearing_hint; int force_tearing; int allow_shortcuts_inhibit; + float scroller_proportion_single; }; typedef struct { @@ -1173,6 +1174,7 @@ static void apply_rule_properties(Client *c, const ConfigWinRule *r) { APPLY_INT_PROP(c, r, allow_shortcuts_inhibit); APPLY_FLOAT_PROP(c, r, scroller_proportion); + APPLY_FLOAT_PROP(c, r, scroller_proportion_single); APPLY_FLOAT_PROP(c, r, focused_opacity); APPLY_FLOAT_PROP(c, r, unfocused_opacity); @@ -3623,6 +3625,7 @@ void init_client_properties(Client *c) { c->force_maximize = 0; c->force_tearing = 0; c->allow_shortcuts_inhibit = SHORTCUTS_INHIBIT_ENABLE; + c->scroller_proportion_single = 0.0f; } void // old fix to 0.5 From f2b98352431838fdadd60e4fb5b8475027ffe2fe Mon Sep 17 00:00:00 2001 From: DreamMaoMao <2523610504@qq.com> Date: Sun, 9 Nov 2025 23:19:49 +0800 Subject: [PATCH 20/70] opt: remove useless code --- src/mango.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/mango.c b/src/mango.c index f7440f49..7ad9aa6f 100644 --- a/src/mango.c +++ b/src/mango.c @@ -1276,8 +1276,6 @@ void applyrules(Client *c) { newtags |= r->tags; } else if (parent) { newtags = parent->tags; - } else { - newtags |= 0; } // set monitor of client From fce47b37d941808260c757fc68658d1b54fd1f01 Mon Sep 17 00:00:00 2001 From: DreamMaoMao <2523610504@qq.com> Date: Fri, 14 Nov 2025 17:13:26 +0800 Subject: [PATCH 21/70] opt: optimize init focus for x11 window --- src/mango.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/mango.c b/src/mango.c index 601c36f5..06e1d616 100644 --- a/src/mango.c +++ b/src/mango.c @@ -1368,7 +1368,8 @@ void applyrules(Client *c) { int fullscreen_state_backup = c->isfullscreen || client_wants_fullscreen(c); setmon(c, mon, newtags, - !c->isopensilent && !client_should_ignore_focus(c) && + !c->isopensilent && + !(client_is_x11_popup(c) && client_should_ignore_focus(c)) && (!c->istagsilent || !newtags || newtags & mon->tagset[mon->seltags])); From ecab47fe929519349735ce489b69b8e8744387fb Mon Sep 17 00:00:00 2001 From: DreamMaoMao <2523610504@qq.com> Date: Mon, 10 Nov 2025 14:30:20 +0800 Subject: [PATCH 22/70] update readme --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index c90cee1f..8e982b60 100644 --- a/README.md +++ b/README.md @@ -101,7 +101,7 @@ emerge --ask --verbose gui-wm/mangowc ## Other ```bash -git clone -b 0.19.1 https://gitlab.freedesktop.org/wlroots/wlroots.git +git clone -b 0.19.2 https://gitlab.freedesktop.org/wlroots/wlroots.git cd wlroots meson build -Dprefix=/usr sudo ninja -C build install @@ -119,7 +119,7 @@ sudo ninja -C build install ## Suggested Tools -### integrated component +### Hybrid component - [dms-shell](https://github.com/AvengeMedia/DankMaterialShell) ### Independent component From cdcc64ab5fc656e1d314f719f5a6e416bbdcb04c Mon Sep 17 00:00:00 2001 From: DreamMaoMao <2523610504@qq.com> Date: Sat, 15 Nov 2025 00:08:57 +0800 Subject: [PATCH 23/70] feat: support scroll maximize and fullscreen window --- src/dispatch/bind_define.h | 11 +++- src/ext-protocol/dwl-ipc.h | 1 + src/fetch/client.h | 113 ++++++++++++++++++++----------------- src/layout/arrange.h | 5 ++ src/layout/horizontal.h | 71 ++++++++++++++++++----- src/layout/vertical.h | 72 ++++++++++++++++++----- src/mango.c | 45 ++++++++++++--- 7 files changed, 228 insertions(+), 90 deletions(-) diff --git a/src/dispatch/bind_define.h b/src/dispatch/bind_define.h index c812bf14..d79a7c65 100644 --- a/src/dispatch/bind_define.h +++ b/src/dispatch/bind_define.h @@ -80,8 +80,12 @@ int defaultgaps(const Arg *arg) { int exchange_client(const Arg *arg) { Client *c = selmon->sel; - if (!c || c->isfloating || c->isfullscreen || c->ismaximizescreen) + if (!c || c->isfloating) return 0; + + if ((c->isfullscreen || c->ismaximizescreen) && !is_scroller_layout(c->mon)) + return 0; + exchange_two_client(c, direction_select(arg)); return 0; } @@ -497,7 +501,7 @@ int setlayout(const Arg *arg) { for (jk = 0; jk < LENGTH(layouts); jk++) { if (strcmp(layouts[jk].name, arg->v) == 0) { selmon->pertag->ltidxs[selmon->pertag->curtag] = &layouts[jk]; - + clear_fullscreen_and_maximized_state(selmon); arrange(selmon, false); printstatus(); return 0; @@ -901,7 +905,7 @@ int switch_layout(const Arg *arg) { break; } } - + clear_fullscreen_and_maximized_state(selmon); arrange(selmon, false); printstatus(); return 0; @@ -912,6 +916,7 @@ int switch_layout(const Arg *arg) { selmon->pertag->ltidxs[selmon->pertag->curtag]->name) == 0) { selmon->pertag->ltidxs[selmon->pertag->curtag] = jk == LENGTH(layouts) - 1 ? &layouts[0] : &layouts[jk + 1]; + clear_fullscreen_and_maximized_state(selmon); arrange(selmon, false); printstatus(); return 0; diff --git a/src/ext-protocol/dwl-ipc.h b/src/ext-protocol/dwl-ipc.h index 6b0c4c54..15b2376a 100644 --- a/src/ext-protocol/dwl-ipc.h +++ b/src/ext-protocol/dwl-ipc.h @@ -258,6 +258,7 @@ void dwl_ipc_output_set_layout(struct wl_client *client, index = 0; monitor->pertag->ltidxs[monitor->pertag->curtag] = &layouts[index]; + clear_fullscreen_and_maximized_state(monitor); arrange(monitor, false); printstatus(); } diff --git a/src/fetch/client.h b/src/fetch/client.h index 5f62d234..c2b0abdd 100644 --- a/src/fetch/client.h +++ b/src/fetch/client.h @@ -142,7 +142,7 @@ Client *center_tiled_select(Monitor *m) { return target_c; } Client *find_client_by_direction(Client *tc, const Arg *arg, bool findfloating, - bool align) { + bool ignore_align) { Client *c = NULL; Client **tempClients = NULL; // 初始化为 NULL int last = -1; @@ -185,21 +185,23 @@ Client *find_client_by_direction(Client *tc, const Arg *arg, bool findfloating, switch (arg->i) { case UP: - for (int _i = 0; _i <= last; _i++) { - if (tempClients[_i]->geom.y < sel_y && - tempClients[_i]->geom.x == sel_x && - tempClients[_i]->mon == tc->mon) { - int dis_x = tempClients[_i]->geom.x - sel_x; - int dis_y = tempClients[_i]->geom.y - sel_y; - long long int tmp_distance = - dis_x * dis_x + dis_y * dis_y; // 计算距离 - if (tmp_distance < distance) { - distance = tmp_distance; - tempFocusClients = tempClients[_i]; + if (!ignore_align) { + for (int _i = 0; _i <= last; _i++) { + if (tempClients[_i]->geom.y < sel_y && + tempClients[_i]->geom.x == sel_x && + tempClients[_i]->mon == tc->mon) { + int dis_x = tempClients[_i]->geom.x - sel_x; + int dis_y = tempClients[_i]->geom.y - sel_y; + long long int tmp_distance = + dis_x * dis_x + dis_y * dis_y; // 计算距离 + if (tmp_distance < distance) { + distance = tmp_distance; + tempFocusClients = tempClients[_i]; + } } } } - if (!tempFocusClients && !align) { + if (!tempFocusClients) { for (int _i = 0; _i <= last; _i++) { if (tempClients[_i]->geom.y < sel_y) { int dis_x = tempClients[_i]->geom.x - sel_x; @@ -215,21 +217,23 @@ Client *find_client_by_direction(Client *tc, const Arg *arg, bool findfloating, } break; case DOWN: - for (int _i = 0; _i <= last; _i++) { - if (tempClients[_i]->geom.y > sel_y && - tempClients[_i]->geom.x == sel_x && - tempClients[_i]->mon == tc->mon) { - int dis_x = tempClients[_i]->geom.x - sel_x; - int dis_y = tempClients[_i]->geom.y - sel_y; - long long int tmp_distance = - dis_x * dis_x + dis_y * dis_y; // 计算距离 - if (tmp_distance < distance) { - distance = tmp_distance; - tempFocusClients = tempClients[_i]; + if (!ignore_align) { + for (int _i = 0; _i <= last; _i++) { + if (tempClients[_i]->geom.y > sel_y && + tempClients[_i]->geom.x == sel_x && + tempClients[_i]->mon == tc->mon) { + int dis_x = tempClients[_i]->geom.x - sel_x; + int dis_y = tempClients[_i]->geom.y - sel_y; + long long int tmp_distance = + dis_x * dis_x + dis_y * dis_y; // 计算距离 + if (tmp_distance < distance) { + distance = tmp_distance; + tempFocusClients = tempClients[_i]; + } } } } - if (!tempFocusClients && !align) { + if (!tempFocusClients) { for (int _i = 0; _i <= last; _i++) { if (tempClients[_i]->geom.y > sel_y) { int dis_x = tempClients[_i]->geom.x - sel_x; @@ -245,21 +249,23 @@ Client *find_client_by_direction(Client *tc, const Arg *arg, bool findfloating, } break; case LEFT: - for (int _i = 0; _i <= last; _i++) { - if (tempClients[_i]->geom.x < sel_x && - tempClients[_i]->geom.y == sel_y && - tempClients[_i]->mon == tc->mon) { - int dis_x = tempClients[_i]->geom.x - sel_x; - int dis_y = tempClients[_i]->geom.y - sel_y; - long long int tmp_distance = - dis_x * dis_x + dis_y * dis_y; // 计算距离 - if (tmp_distance < distance) { - distance = tmp_distance; - tempFocusClients = tempClients[_i]; + if (!ignore_align) { + for (int _i = 0; _i <= last; _i++) { + if (tempClients[_i]->geom.x < sel_x && + tempClients[_i]->geom.y == sel_y && + tempClients[_i]->mon == tc->mon) { + int dis_x = tempClients[_i]->geom.x - sel_x; + int dis_y = tempClients[_i]->geom.y - sel_y; + long long int tmp_distance = + dis_x * dis_x + dis_y * dis_y; // 计算距离 + if (tmp_distance < distance) { + distance = tmp_distance; + tempFocusClients = tempClients[_i]; + } } } } - if (!tempFocusClients && !align) { + if (!tempFocusClients) { for (int _i = 0; _i <= last; _i++) { if (tempClients[_i]->geom.x < sel_x) { int dis_x = tempClients[_i]->geom.x - sel_x; @@ -275,21 +281,23 @@ Client *find_client_by_direction(Client *tc, const Arg *arg, bool findfloating, } break; case RIGHT: - for (int _i = 0; _i <= last; _i++) { - if (tempClients[_i]->geom.x > sel_x && - tempClients[_i]->geom.y == sel_y && - tempClients[_i]->mon == tc->mon) { - int dis_x = tempClients[_i]->geom.x - sel_x; - int dis_y = tempClients[_i]->geom.y - sel_y; - long long int tmp_distance = - dis_x * dis_x + dis_y * dis_y; // 计算距离 - if (tmp_distance < distance) { - distance = tmp_distance; - tempFocusClients = tempClients[_i]; + if (!ignore_align) { + for (int _i = 0; _i <= last; _i++) { + if (tempClients[_i]->geom.x > sel_x && + tempClients[_i]->geom.y == sel_y && + tempClients[_i]->mon == tc->mon) { + int dis_x = tempClients[_i]->geom.x - sel_x; + int dis_y = tempClients[_i]->geom.y - sel_y; + long long int tmp_distance = + dis_x * dis_x + dis_y * dis_y; // 计算距离 + if (tmp_distance < distance) { + distance = tmp_distance; + tempFocusClients = tempClients[_i]; + } } } } - if (!tempFocusClients && !align) { + if (!tempFocusClients) { for (int _i = 0; _i <= last; _i++) { if (tempClients[_i]->geom.x > sel_x) { int dis_x = tempClients[_i]->geom.x - sel_x; @@ -317,12 +325,13 @@ Client *direction_select(const Arg *arg) { if (!tc) return NULL; - if (tc && (tc->isfullscreen || tc->ismaximizescreen)) { - // 不支持全屏窗口的焦点切换 + if (tc && (tc->isfullscreen || tc->ismaximizescreen) && + (!is_scroller_layout(selmon) || tc->isfloating)) { return NULL; } - return find_client_by_direction(tc, arg, true, false); + return find_client_by_direction( + tc, arg, true, is_scroller_layout(selmon) && !selmon->isoverview); } /* We probably should change the name of this, it sounds like diff --git a/src/layout/arrange.h b/src/layout/arrange.h index aafb79e0..ba1391e6 100644 --- a/src/layout/arrange.h +++ b/src/layout/arrange.h @@ -599,6 +599,7 @@ arrange(Monitor *m, bool want_animation) { return; 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) { @@ -619,6 +620,10 @@ arrange(Monitor *m, bool want_animation) { if (ISTILED(c)) { m->visible_tiling_clients++; } + + if (ISSCROLLTILED(c)) { + m->visible_scroll_tiling_clients++; + } } } diff --git a/src/layout/horizontal.h b/src/layout/horizontal.h index 934dc136..ff517cc1 100644 --- a/src/layout/horizontal.h +++ b/src/layout/horizontal.h @@ -189,6 +189,38 @@ void deck(Monitor *m) { } } +void horizontal_scroll_adjust_fullandmax(Client *c, + struct wlr_box *target_geom) { + Monitor *m = c->mon; + unsigned int cur_gappih = enablegaps ? m->gappih : 0; + unsigned int cur_gappoh = enablegaps ? m->gappoh : 0; + unsigned int cur_gappov = enablegaps ? m->gappov : 0; + + cur_gappih = + smartgaps && m->visible_scroll_tiling_clients == 1 ? 0 : cur_gappih; + cur_gappoh = + smartgaps && m->visible_scroll_tiling_clients == 1 ? 0 : cur_gappoh; + cur_gappov = + smartgaps && m->visible_scroll_tiling_clients == 1 ? 0 : cur_gappov; + + if (c->isfullscreen) { + target_geom->height = m->m.height; + target_geom->width = m->m.width; + target_geom->y = m->m.y; + return; + } + + if (c->ismaximizescreen) { + target_geom->height = m->w.height - 2 * cur_gappov; + target_geom->width = m->w.width - 2 * cur_gappoh; + target_geom->y = m->w.y + cur_gappov; + return; + } + + target_geom->height = m->w.height - 2 * cur_gappov; + target_geom->y = m->w.y + (m->w.height - target_geom->height) / 2; +} + // 滚动布局 void scroller(Monitor *m) { unsigned int i, n, j; @@ -203,14 +235,17 @@ void scroller(Monitor *m) { unsigned int cur_gappoh = enablegaps ? m->gappoh : 0; unsigned int cur_gappov = enablegaps ? m->gappov : 0; - cur_gappih = smartgaps && m->visible_tiling_clients == 1 ? 0 : cur_gappih; - cur_gappoh = smartgaps && m->visible_tiling_clients == 1 ? 0 : cur_gappoh; - cur_gappov = smartgaps && m->visible_tiling_clients == 1 ? 0 : cur_gappov; + cur_gappih = + smartgaps && m->visible_scroll_tiling_clients == 1 ? 0 : cur_gappih; + cur_gappoh = + smartgaps && m->visible_scroll_tiling_clients == 1 ? 0 : cur_gappoh; + cur_gappov = + smartgaps && m->visible_scroll_tiling_clients == 1 ? 0 : cur_gappov; unsigned int max_client_width = m->w.width - 2 * scroller_structs - cur_gappih; - n = m->visible_tiling_clients; + n = m->visible_scroll_tiling_clients; if (n == 0) { return; // 没有需要处理的客户端,直接返回 @@ -226,13 +261,14 @@ void scroller(Monitor *m) { // 第二次遍历,填充 tempClients j = 0; wl_list_for_each(c, &clients, link) { - if (VISIBLEON(c, m) && ISTILED(c)) { + if (VISIBLEON(c, m) && ISSCROLLTILED(c)) { tempClients[j] = c; j++; } } - if (n == 1 && !scroller_ignore_proportion_single) { + if (n == 1 && !scroller_ignore_proportion_single && + !tempClients[0]->isfullscreen && !tempClients[0]->ismaximizescreen) { c = tempClients[0]; single_proportion = c->scroller_proportion_single > 0.0f @@ -248,11 +284,10 @@ void scroller(Monitor *m) { return; } - if (m->sel && !client_is_unmanaged(m->sel) && !m->sel->isfloating && - !m->sel->ismaximizescreen && !m->sel->isfullscreen) { + if (m->sel && !client_is_unmanaged(m->sel) && !m->sel->isfloating) { root_client = m->sel; - } else if (m->prevsel && ISTILED(m->prevsel) && VISIBLEON(m->prevsel, m) && - !client_is_unmanaged(m->prevsel)) { + } else if (m->prevsel && ISSCROLLTILED(m->prevsel) && + VISIBLEON(m->prevsel, m) && !client_is_unmanaged(m->prevsel)) { root_client = m->prevsel; } else { root_client = center_tiled_select(m); @@ -289,11 +324,18 @@ void scroller(Monitor *m) { 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; - - if (need_scroller) { + horizontal_scroll_adjust_fullandmax(tempClients[focus_client_index], + &target_geom); + if (tempClients[focus_client_index]->isfullscreen) { + target_geom.x = m->m.x; + resize(tempClients[focus_client_index], target_geom, 0); + } else if (tempClients[focus_client_index]->ismaximizescreen) { + target_geom.x = m->w.x + cur_gappoh; + resize(tempClients[focus_client_index], target_geom, 0); + } else if (need_scroller) { if (scroller_focus_center || ((!m->prevsel || - (ISTILED(m->prevsel) && + (ISSCROLLTILED(m->prevsel) && (m->prevsel->scroller_proportion * max_client_width) + (root_client->scroller_proportion * max_client_width) > m->w.width - 2 * scroller_structs - cur_gappih)) && @@ -316,14 +358,17 @@ void scroller(Monitor *m) { for (i = 1; i <= focus_client_index; i++) { c = tempClients[focus_client_index - i]; target_geom.width = max_client_width * c->scroller_proportion; + horizontal_scroll_adjust_fullandmax(c, &target_geom); target_geom.x = tempClients[focus_client_index - i + 1]->geom.x - cur_gappih - target_geom.width; + resize(c, target_geom, 0); } for (i = 1; i < n - focus_client_index; i++) { c = tempClients[focus_client_index + i]; target_geom.width = max_client_width * c->scroller_proportion; + horizontal_scroll_adjust_fullandmax(c, &target_geom); target_geom.x = tempClients[focus_client_index + i - 1]->geom.x + cur_gappih + tempClients[focus_client_index + i - 1]->geom.width; diff --git a/src/layout/vertical.h b/src/layout/vertical.h index 46ca3b65..cef0e3bb 100644 --- a/src/layout/vertical.h +++ b/src/layout/vertical.h @@ -155,6 +155,38 @@ void vertical_deck(Monitor *m) { } } +void vertical_scroll_adjust_fullandmax(Client *c, struct wlr_box *target_geom) { + Monitor *m = c->mon; + unsigned int cur_gappiv = enablegaps ? m->gappiv : 0; + unsigned int cur_gappov = enablegaps ? m->gappov : 0; + unsigned int cur_gappoh = enablegaps ? m->gappoh : 0; + + cur_gappiv = + smartgaps && m->visible_scroll_tiling_clients == 1 ? 0 : cur_gappiv; + cur_gappov = + smartgaps && m->visible_scroll_tiling_clients == 1 ? 0 : cur_gappov; + cur_gappoh = + smartgaps && m->visible_scroll_tiling_clients == 1 ? 0 : cur_gappoh; + + if (c->isfullscreen) { + target_geom->width = m->m.width; + target_geom->height = m->m.height; + target_geom->x = m->m.x; + return; + } + + if (c->ismaximizescreen) { + target_geom->width = m->w.width - 2 * cur_gappoh; + target_geom->height = m->w.height - 2 * cur_gappov; + target_geom->x = m->w.x + cur_gappoh; + return; + } + + target_geom->width = m->w.width - 2 * cur_gappoh; + target_geom->x = m->w.x + (m->w.width - target_geom->width) / 2; +} + +// 竖屏滚动布局 void vertical_scroller(Monitor *m) { unsigned int i, n, j; float single_proportion = 1.0; @@ -168,14 +200,17 @@ void vertical_scroller(Monitor *m) { 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_gappov = smartgaps && m->visible_tiling_clients == 1 ? 0 : cur_gappov; - cur_gappoh = smartgaps && m->visible_tiling_clients == 1 ? 0 : cur_gappoh; + cur_gappiv = + smartgaps && m->visible_scroll_tiling_clients == 1 ? 0 : cur_gappiv; + cur_gappov = + smartgaps && m->visible_scroll_tiling_clients == 1 ? 0 : cur_gappov; + cur_gappoh = + smartgaps && m->visible_scroll_tiling_clients == 1 ? 0 : cur_gappoh; unsigned int max_client_height = m->w.height - 2 * scroller_structs - cur_gappiv; - n = m->visible_tiling_clients; + n = m->visible_scroll_tiling_clients; if (n == 0) { return; @@ -188,13 +223,14 @@ void vertical_scroller(Monitor *m) { j = 0; wl_list_for_each(c, &clients, link) { - if (VISIBLEON(c, m) && ISTILED(c)) { + if (VISIBLEON(c, m) && ISSCROLLTILED(c)) { tempClients[j] = c; j++; } } - if (n == 1 && !scroller_ignore_proportion_single) { + if (n == 1 && !scroller_ignore_proportion_single && + !tempClients[0]->isfullscreen && !tempClients[0]->ismaximizescreen) { c = tempClients[0]; single_proportion = c->scroller_proportion_single > 0.0f @@ -203,18 +239,17 @@ void vertical_scroller(Monitor *m) { target_geom.width = m->w.width - 2 * cur_gappoh; target_geom.height = (m->w.height - 2 * cur_gappov) * single_proportion; - target_geom.x = m->w.x + (m->w.width - target_geom.width) / 2; target_geom.y = m->w.y + (m->w.height - target_geom.height) / 2; + target_geom.x = m->w.x + (m->w.width - target_geom.width) / 2; resize(c, target_geom, 0); free(tempClients); return; } - if (m->sel && !client_is_unmanaged(m->sel) && !m->sel->isfloating && - !m->sel->ismaximizescreen && !m->sel->isfullscreen) { + if (m->sel && !client_is_unmanaged(m->sel) && !m->sel->isfloating) { root_client = m->sel; - } else if (m->prevsel && ISTILED(m->prevsel) && VISIBLEON(m->prevsel, m) && - !client_is_unmanaged(m->prevsel)) { + } else if (m->prevsel && ISSCROLLTILED(m->prevsel) && + VISIBLEON(m->prevsel, m) && !client_is_unmanaged(m->prevsel)) { root_client = m->prevsel; } else { root_client = center_tiled_select(m); @@ -251,11 +286,19 @@ void vertical_scroller(Monitor *m) { target_geom.width = m->w.width - 2 * cur_gappoh; target_geom.height = max_client_height * c->scroller_proportion; target_geom.x = m->w.x + (m->w.width - target_geom.width) / 2; + vertical_scroll_adjust_fullandmax(tempClients[focus_client_index], + &target_geom); - if (need_scroller) { + if (tempClients[focus_client_index]->isfullscreen) { + target_geom.y = m->m.y; + resize(tempClients[focus_client_index], target_geom, 0); + } else if (tempClients[focus_client_index]->ismaximizescreen) { + target_geom.y = m->w.y + cur_gappov; + resize(tempClients[focus_client_index], target_geom, 0); + } else if (need_scroller) { if (scroller_focus_center || ((!m->prevsel || - (ISTILED(m->prevsel) && + (ISSCROLLTILED(m->prevsel) && (m->prevsel->scroller_proportion * max_client_height) + (root_client->scroller_proportion * max_client_height) > m->w.height - 2 * scroller_structs - cur_gappiv)) && @@ -278,14 +321,17 @@ void vertical_scroller(Monitor *m) { for (i = 1; i <= focus_client_index; i++) { c = tempClients[focus_client_index - i]; target_geom.height = max_client_height * c->scroller_proportion; + vertical_scroll_adjust_fullandmax(c, &target_geom); target_geom.y = tempClients[focus_client_index - i + 1]->geom.y - cur_gappiv - target_geom.height; + resize(c, target_geom, 0); } for (i = 1; i < n - focus_client_index; i++) { c = tempClients[focus_client_index + i]; target_geom.height = max_client_height * c->scroller_proportion; + vertical_scroll_adjust_fullandmax(c, &target_geom); target_geom.y = tempClients[focus_client_index + i - 1]->geom.y + cur_gappiv + tempClients[focus_client_index + i - 1]->geom.height; diff --git a/src/mango.c b/src/mango.c index 06e1d616..540a0257 100644 --- a/src/mango.c +++ b/src/mango.c @@ -104,6 +104,9 @@ #define ISTILED(A) \ (A && !(A)->isfloating && !(A)->isminied && !(A)->iskilling && \ !(A)->ismaximizescreen && !(A)->isfullscreen && !(A)->isunglobal) +#define ISSCROLLTILED(A) \ + (A && !(A)->isfloating && !(A)->isminied && !(A)->iskilling && \ + !(A)->isunglobal) #define VISIBLEON(C, M) \ ((C) && (M) && (C)->mon == (M) && ((C)->tags & (M)->tagset[(M)->seltags])) #define LENGTH(X) (sizeof X / sizeof X[0]) @@ -479,6 +482,7 @@ struct Monitor { int asleep; unsigned int visible_clients; unsigned int visible_tiling_clients; + unsigned int visible_scroll_tiling_clients; bool has_visible_fullscreen_client; struct wlr_scene_optimized_blur *blur; char last_surface_ws_name[256]; @@ -733,6 +737,7 @@ static void refresh_monitors_workspaces_status(Monitor *m); static void init_client_properties(Client *c); static float *get_border_color(Client *c); static void request_fresh_all_monitors(void); +static void clear_fullscreen_and_maximized_state(Monitor *m); #include "data/static_keymap.h" #include "dispatch/bind_declare.h" @@ -930,8 +935,26 @@ void applybounds(Client *c, struct wlr_box *bbox) { c->geom.y = bbox->y; } +void clear_fullscreen_and_maximized_state(Monitor *m) { + Client *fc = NULL; + wl_list_for_each(fc, &clients, link) { + if (fc && VISIBLEON(fc, m) && ISFULLSCREEN(fc)) { + clear_fullscreen_flag(fc); + } + } +} + /*清除全屏标志,还原全屏时清0的border*/ void clear_fullscreen_flag(Client *c) { + + if ((c->mon->pertag->ltidxs[get_tags_first_tag_num(c->tags)]->id == + SCROLLER || + c->mon->pertag->ltidxs[get_tags_first_tag_num(c->tags)]->id == + VERTICAL_SCROLLER) && + !c->isfloating) { + return; + } + if (c->isfullscreen) { setfullscreen(c, false); } @@ -3149,7 +3172,6 @@ void focusclient(Client *c, int lift) { if (c && selmon->prevsel && (selmon->prevsel->tags & selmon->tagset[selmon->seltags]) && (c->tags & selmon->tagset[selmon->seltags]) && !c->isfloating && - !c->isfullscreen && !c->ismaximizescreen && is_scroller_layout(selmon)) { arrange(selmon, false); } @@ -3702,9 +3724,9 @@ mapnotify(struct wl_listener *listener, void *data) { // tile at the top wl_list_insert(&clients, &c->link); // 新窗口是master,头部入栈 else if (selmon && is_scroller_layout(selmon) && - selmon->visible_tiling_clients > 0) { + selmon->visible_scroll_tiling_clients > 0) { - if (selmon->sel && ISTILED(selmon->sel) && + if (selmon->sel && ISSCROLLTILED(selmon->sel) && VISIBLEON(selmon->sel, selmon)) { at_client = selmon->sel; } else { @@ -4536,7 +4558,8 @@ void setmaximizescreen(Client *c, int maximizescreen) { maximizescreen_box.width = c->mon->w.width - 2 * gappoh; maximizescreen_box.height = c->mon->w.height - 2 * gappov; wlr_scene_node_raise_to_top(&c->scene->node); // 将视图提升到顶层 - resize(c, maximizescreen_box, 0); + if (!is_scroller_layout(c->mon) || c->isfloating) + resize(c, maximizescreen_box, 0); c->ismaximizescreen = 1; } else { c->bw = c->isnoborder ? 0 : borderpx; @@ -4545,9 +4568,8 @@ void setmaximizescreen(Client *c, int maximizescreen) { setfloating(c, 1); } - wlr_scene_node_reparent(&c->scene->node, layers[maximizescreen ? LyrTile - : c->isfloating ? LyrTop - : LyrTile]); + wlr_scene_node_reparent(&c->scene->node, + layers[c->isfloating ? LyrTop : LyrTile]); if (!c->ismaximizescreen) { set_size_per(c->mon, c); } @@ -4593,7 +4615,8 @@ void setfullscreen(Client *c, int fullscreen) // 用自定义全屏代理自带 c->bw = 0; wlr_scene_node_raise_to_top(&c->scene->node); // 将视图提升到顶层 - resize(c, c->mon->m, 1); + if (!is_scroller_layout(c->mon) || c->isfloating) + resize(c, c->mon->m, 1); c->isfullscreen = 1; } else { c->bw = c->isnoborder ? 0 : borderpx; @@ -5168,7 +5191,11 @@ unsigned int want_restore_fullscreen(Client *target_client) { Client *c = NULL; wl_list_for_each(c, &clients, link) { if (c && c != target_client && c->tags == target_client->tags && - c == selmon->sel) { + c == selmon->sel && + c->mon->pertag->ltidxs[get_tags_first_tag_num(c->tags)]->id != + SCROLLER && + c->mon->pertag->ltidxs[get_tags_first_tag_num(c->tags)]->id != + VERTICAL_SCROLLER) { return 0; } } From 9c8f9e3b38f64b5aeee09ebc60d1468f3975dee9 Mon Sep 17 00:00:00 2001 From: Jorrit van der Heide Date: Tue, 11 Nov 2025 17:03:43 +0100 Subject: [PATCH 24/70] fix: nixos example --- README.md | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 8e982b60..967e66a7 100644 --- a/README.md +++ b/README.md @@ -189,7 +189,10 @@ Here's an example of using the modules in a flake: inputs.nixpkgs.follows = "nixpkgs"; }; flake-parts.url = "github:hercules-ci/flake-parts"; - mango.url = "github:DreamMaoMao/mango"; + mango = { + url = "github:DreamMaoMao/mango"; + inputs.nixpkgs.follows = "nixpkgs"; + }; }; outputs = inputs@{ self, flake-parts, ... }: From d941e0078eb7773a27f72890425eb62f085e417d Mon Sep 17 00:00:00 2001 From: DreamMaoMao <2523610504@qq.com> Date: Sun, 16 Nov 2025 07:19:29 +0800 Subject: [PATCH 25/70] fix: fullscreen and maximize window overflow screen --- src/animation/client.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/animation/client.h b/src/animation/client.h index e3673a20..d26265bb 100644 --- a/src/animation/client.h +++ b/src/animation/client.h @@ -446,7 +446,7 @@ struct ivec2 clip_to_hide(Client *c, struct wlr_box *clip_box) { int offsetx = 0, offsety = 0, offsetw = 0, offseth = 0; struct ivec2 offset = {0, 0, 0, 0}; - if (!ISTILED(c) && !c->animation.tagining && !c->animation.tagouted && + if (!ISSCROLLTILED(c) && !c->animation.tagining && !c->animation.tagouted && !c->animation.tagouting) return offset; @@ -467,7 +467,7 @@ struct ivec2 clip_to_hide(Client *c, struct wlr_box *clip_box) { 需要主要border超出屏幕的时候不计算如偏差之内而是 要等窗口表面超出才开始计算偏差 */ - if (ISTILED(c) || c->animation.tagining || c->animation.tagouted || + if (ISSCROLLTILED(c) || c->animation.tagining || c->animation.tagouted || c->animation.tagouting) { if (left_out_offset > 0) { offsetx = GEZERO(left_out_offset - bw); @@ -495,7 +495,7 @@ struct ivec2 clip_to_hide(Client *c, struct wlr_box *clip_box) { offset.height = offseth; if ((clip_box->width + bw <= 0 || clip_box->height + bw <= 0) && - (ISTILED(c) || c->animation.tagouting || c->animation.tagining)) { + (ISSCROLLTILED(c) || c->animation.tagouting || c->animation.tagining)) { c->is_clip_to_hide = true; wlr_scene_node_set_enabled(&c->scene->node, false); } else if (c->is_clip_to_hide && VISIBLEON(c, c->mon)) { From 58d5938e147bb2b1173ffd69ef00dc18d0e87c54 Mon Sep 17 00:00:00 2001 From: DreamMaoMao <2523610504@qq.com> Date: Tue, 18 Nov 2025 19:21:19 +0800 Subject: [PATCH 26/70] opt: support hot reload cursor config --- src/config/parse_config.h | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/config/parse_config.h b/src/config/parse_config.h index 074660bf..d7b32234 100644 --- a/src/config/parse_config.h +++ b/src/config/parse_config.h @@ -3110,6 +3110,12 @@ void reapply_monitor_rules(void) { } } +void reapply_cursor_style(void) { + if (cursor_mgr) + wlr_xcursor_manager_destroy(cursor_mgr); + cursor_mgr = wlr_xcursor_manager_create(config.cursor_theme, cursor_size); +} + void reapply_border(void) { Client *c = NULL; @@ -3211,6 +3217,7 @@ void reset_option(void) { set_env(); run_exec(); + reapply_cursor_style(); reapply_border(); reapply_keyboard(); reapply_pointer(); From 8e4d3b7aac483c31514fe93c9898037889620475 Mon Sep 17 00:00:00 2001 From: DreamMaoMao <2523610504@qq.com> Date: Wed, 19 Nov 2025 12:45:04 +0800 Subject: [PATCH 27/70] update readme --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 967e66a7..b321be5b 100644 --- a/README.md +++ b/README.md @@ -106,7 +106,7 @@ cd wlroots meson build -Dprefix=/usr sudo ninja -C build install -git clone https://github.com/wlrfx/scenefx.git +git clone -b 0.4.1 https://github.com/wlrfx/scenefx.git cd scenefx meson build -Dprefix=/usr sudo ninja -C build install From e22cf99e742bfc93f73c862b351ee2557f20b1ab Mon Sep 17 00:00:00 2001 From: DreamMaoMao <2523610504@qq.com> Date: Thu, 20 Nov 2025 10:34:32 +0800 Subject: [PATCH 28/70] feat: support relative path for source keyword --- src/config/parse_config.h | 48 +++++++++++++++++++++++++++------------ 1 file changed, 33 insertions(+), 15 deletions(-) diff --git a/src/config/parse_config.h b/src/config/parse_config.h index d7b32234..a58a106f 100644 --- a/src/config/parse_config.h +++ b/src/config/parse_config.h @@ -2274,35 +2274,53 @@ void parse_config_line(Config *config, const char *line) { void parse_config_file(Config *config, const char *file_path) { FILE *file; - // 检查路径是否以 ~/ 开头 - if (file_path[0] == '~' && (file_path[1] == '/' || file_path[1] == '\0')) { + char full_path[1024]; + + if (file_path[0] == '.' && file_path[1] == '/') { + // Relative path + + const char *mangoconfig = getenv("MANGOCONFIG"); + if (mangoconfig && mangoconfig[0] != '\0') { + snprintf(full_path, sizeof(full_path), "%s/%s", mangoconfig, + file_path + 1); + } else { + const char *home = getenv("HOME"); + if (!home) { + fprintf(stderr, "Error: HOME environment variable not set.\n"); + return; + } + snprintf(full_path, sizeof(full_path), "%s/.config/mango/%s", home, + file_path + 1); + } + file = fopen(full_path, "r"); + + } else if (file_path[0] == '~' && + (file_path[1] == '/' || file_path[1] == '\0')) { + // Home directory + const char *home = getenv("HOME"); if (!home) { fprintf(stderr, "Error: HOME environment variable not set.\n"); return; } - - // 构建完整路径(家目录 + / + 原路径去掉 ~) - char full_path[1024]; snprintf(full_path, sizeof(full_path), "%s%s", home, file_path + 1); - file = fopen(full_path, "r"); - if (!file) { - perror("Error opening file"); - return; - } + } else { + // Absolute path file = fopen(file_path, "r"); - if (!file) { - perror("Error opening file"); - return; - } + } + + if (!file) { + perror("Error opening file"); + return; } char line[512]; while (fgets(line, sizeof(line), file)) { - if (line[0] == '#' || line[0] == '\n') + if (line[0] == '#' || line[0] == '\n') { continue; + } parse_config_line(config, line); } From e7cb4f77f37c3ebb15bcd803adcadd9d64f92039 Mon Sep 17 00:00:00 2001 From: DreamMaoMao <2523610504@qq.com> Date: Thu, 20 Nov 2025 21:21:29 +0800 Subject: [PATCH 29/70] fix: wrong scroll judge when disable animaitons --- src/layout/horizontal.h | 2 +- src/layout/vertical.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/layout/horizontal.h b/src/layout/horizontal.h index ff517cc1..99bb0926 100644 --- a/src/layout/horizontal.h +++ b/src/layout/horizontal.h @@ -301,7 +301,7 @@ void scroller(Monitor *m) { for (i = 0; i < n; i++) { c = tempClients[i]; if (root_client == c) { - if (!c->is_pending_open_animation && + if ((!c->is_pending_open_animation || !animations) && c->geom.x >= m->w.x + scroller_structs && c->geom.x + c->geom.width <= m->w.x + m->w.width - scroller_structs) { diff --git a/src/layout/vertical.h b/src/layout/vertical.h index cef0e3bb..5cc8ceb1 100644 --- a/src/layout/vertical.h +++ b/src/layout/vertical.h @@ -263,7 +263,7 @@ void vertical_scroller(Monitor *m) { for (i = 0; i < n; i++) { c = tempClients[i]; if (root_client == c) { - if (!c->is_pending_open_animation && + if ((!c->is_pending_open_animation || !animations) && c->geom.y >= m->w.y + scroller_structs && c->geom.y + c->geom.height <= m->w.y + m->w.height - scroller_structs) { From a0824c05df5482fde37898b9a5d81f779167b60e Mon Sep 17 00:00:00 2001 From: DreamMaoMao <2523610504@qq.com> Date: Thu, 20 Nov 2025 22:47:12 +0800 Subject: [PATCH 30/70] opt: optimize scroll judge when open new client --- src/layout/horizontal.h | 3 +-- src/layout/vertical.h | 3 +-- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/src/layout/horizontal.h b/src/layout/horizontal.h index 99bb0926..2385c848 100644 --- a/src/layout/horizontal.h +++ b/src/layout/horizontal.h @@ -301,8 +301,7 @@ void scroller(Monitor *m) { for (i = 0; i < n; i++) { c = tempClients[i]; if (root_client == c) { - if ((!c->is_pending_open_animation || !animations) && - c->geom.x >= m->w.x + scroller_structs && + if (c->geom.x >= m->w.x + scroller_structs && c->geom.x + c->geom.width <= m->w.x + m->w.width - scroller_structs) { need_scroller = false; diff --git a/src/layout/vertical.h b/src/layout/vertical.h index 5cc8ceb1..7eb95291 100644 --- a/src/layout/vertical.h +++ b/src/layout/vertical.h @@ -263,8 +263,7 @@ void vertical_scroller(Monitor *m) { for (i = 0; i < n; i++) { c = tempClients[i]; if (root_client == c) { - if ((!c->is_pending_open_animation || !animations) && - c->geom.y >= m->w.y + scroller_structs && + if (c->geom.y >= m->w.y + scroller_structs && c->geom.y + c->geom.height <= m->w.y + m->w.height - scroller_structs) { need_scroller = false; From 03ee277ef604639e623a2c7a5cbafa7ecf3c76d4 Mon Sep 17 00:00:00 2001 From: DreamMaoMao <2523610504@qq.com> Date: Fri, 21 Nov 2025 14:50:27 +0800 Subject: [PATCH 31/70] opt: allow init focus to on-demand-focus layer --- src/mango.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/mango.c b/src/mango.c index 540a0257..8a27b751 100644 --- a/src/mango.c +++ b/src/mango.c @@ -2210,6 +2210,15 @@ void maplayersurfacenotify(struct wl_listener *listener, void *data) { } // 刷新布局,让窗口能感应到exclude_zone变化以及设置独占表面 arrangelayers(l->mon); + + // 按需交互layer需要像正常窗口一样抢占非独占layer的焦点 + if (!exclusive_focus && + l->layer_surface->current.keyboard_interactive == + ZWLR_LAYER_SURFACE_V1_KEYBOARD_INTERACTIVITY_ON_DEMAND) { + focusclient(NULL, 0); + client_notify_enter(l->layer_surface->surface, + wlr_seat_get_keyboard(seat)); + } } void commitlayersurfacenotify(struct wl_listener *listener, void *data) { From c004f7460c48a5c317df1ec2b4cb4ed6c3ca57a6 Mon Sep 17 00:00:00 2001 From: David Delarosa Date: Thu, 20 Nov 2025 14:40:34 +0200 Subject: [PATCH 32/70] nix: add portals.conf file --- nix/nixos-modules.nix | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/nix/nixos-modules.nix b/nix/nixos-modules.nix index 5d0aa61e..33811022 100644 --- a/nix/nixos-modules.nix +++ b/nix/nixos-modules.nix @@ -26,6 +26,25 @@ in { xdg.portal = { enable = lib.mkDefault true; + config = { + mango = { + default = [ + "gtk" + ]; + # except those + "org.freedesktop.impl.portal.Secret" = ["gnome-keyring"]; + "org.freedesktop.impl.portal.ScreenCast" = ["wlr"]; + "org.freedesktop.impl.portal.ScreenShot" = ["wlr"]; + + # wlr does not have this interface + "org.freedesktop.impl.portal.Inhibit" = []; + }; + }; + extraPortals = with pkgs; [ + xdg-desktop-portal-wlr + xdg-desktop-portal-gtk + ]; + wlr.enable = lib.mkDefault true; configPackages = [cfg.package]; From e2ee985b8fa72aa4755718187de4e520cdbf63e4 Mon Sep 17 00:00:00 2001 From: DreamMaoMao <2523610504@qq.com> Date: Wed, 26 Nov 2025 10:09:06 +0800 Subject: [PATCH 33/70] bump version to 0.10.6 --- meson.build | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/meson.build b/meson.build index 041a1fdf..b02e0fd1 100644 --- a/meson.build +++ b/meson.build @@ -1,5 +1,5 @@ project('mango', ['c', 'cpp'], - version : '0.10.5', + version : '0.10.6', ) subdir('protocols') From 2f9cabe4b23cb91ebda707b27df12fe30ddeb86e Mon Sep 17 00:00:00 2001 From: DreamMaoMao <2523610504@qq.com> Date: Thu, 27 Nov 2025 22:40:41 +0800 Subject: [PATCH 34/70] fix: sloppyfocus not work when move cursor slowly --- src/fetch/common.h | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/fetch/common.h b/src/fetch/common.h index 33d7272f..41dc9944 100644 --- a/src/fetch/common.h +++ b/src/fetch/common.h @@ -115,6 +115,10 @@ void xytonode(double x, double y, struct wlr_surface **psurface, Client **pc, surface = wlr_scene_surface_try_from_buffer( wlr_scene_buffer_from_node(node)) ->surface; + else if (node->type == WLR_SCENE_NODE_RECT) { + surface = NULL; + break; + } /* start from the topmost layer, find a sureface that can be focused by pointer, From 28ab0e6343a701d552a755ff41ff128a42ede8a8 Mon Sep 17 00:00:00 2001 From: DreamMaoMao <2523610504@qq.com> Date: Fri, 28 Nov 2025 11:34:48 +0800 Subject: [PATCH 35/70] opt: re-judge the focus strategy of the layer when re-arrangelayer --- src/mango.c | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/src/mango.c b/src/mango.c index 8a27b751..02b6ffc7 100644 --- a/src/mango.c +++ b/src/mango.c @@ -1563,6 +1563,7 @@ void reset_exclusive_layer(Monitor *m) { unsigned int layers_above_shell[] = { ZWLR_LAYER_SHELL_V1_LAYER_OVERLAY, ZWLR_LAYER_SHELL_V1_LAYER_TOP, + ZWLR_LAYER_SHELL_V1_LAYER_BOTTOM, }; if (!m) @@ -1570,6 +1571,16 @@ void reset_exclusive_layer(Monitor *m) { for (i = 0; i < (int)LENGTH(layers_above_shell); i++) { wl_list_for_each_reverse(l, &m->layers[layers_above_shell[i]], link) { + if (l == exclusive_focus && + l->layer_surface->current.keyboard_interactive != + ZWLR_LAYER_SURFACE_V1_KEYBOARD_INTERACTIVITY_EXCLUSIVE) + exclusive_focus = NULL; + if (l->layer_surface->current.keyboard_interactive == + ZWLR_LAYER_SURFACE_V1_KEYBOARD_INTERACTIVITY_NONE && + l->layer_surface->surface == + seat->keyboard_state.focused_surface) + focusclient(focustop(selmon), 1); + if (locked || l->layer_surface->current.keyboard_interactive != ZWLR_LAYER_SURFACE_V1_KEYBOARD_INTERACTIVITY_EXCLUSIVE || From b768f72eaa82eec6ea75811e2a45253671eda472 Mon Sep 17 00:00:00 2001 From: DreamMaoMao <2523610504@qq.com> Date: Fri, 28 Nov 2025 12:42:18 +0800 Subject: [PATCH 36/70] opt: allow ime in on-demand layer --- src/mango.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/mango.c b/src/mango.c index 02b6ffc7..ee3b4280 100644 --- a/src/mango.c +++ b/src/mango.c @@ -2227,6 +2227,8 @@ void maplayersurfacenotify(struct wl_listener *listener, void *data) { l->layer_surface->current.keyboard_interactive == ZWLR_LAYER_SURFACE_V1_KEYBOARD_INTERACTIVITY_ON_DEMAND) { focusclient(NULL, 0); + dwl_im_relay_set_focus(dwl_input_method_relay, + l->layer_surface->surface); client_notify_enter(l->layer_surface->surface, wlr_seat_get_keyboard(seat)); } From 16368a8781b278fd76eb3757dc9692967e9db19f Mon Sep 17 00:00:00 2001 From: DreamMaoMao <2523610504@qq.com> Date: Fri, 28 Nov 2025 12:49:06 +0800 Subject: [PATCH 37/70] opt: optimize code struct --- src/mango.c | 24 +++++++++--------------- 1 file changed, 9 insertions(+), 15 deletions(-) diff --git a/src/mango.c b/src/mango.c index ee3b4280..016f06c6 100644 --- a/src/mango.c +++ b/src/mango.c @@ -1557,6 +1557,12 @@ void apply_window_snap(Client *c) { resize(c, c->geom, 0); } +void focuslayer(LayerSurface *l) { + focusclient(NULL, 0); + dwl_im_relay_set_focus(dwl_input_method_relay, l->layer_surface->surface); + client_notify_enter(l->layer_surface->surface, wlr_seat_get_keyboard(seat)); +} + void reset_exclusive_layer(Monitor *m) { LayerSurface *l = NULL; int i; @@ -1587,12 +1593,8 @@ void reset_exclusive_layer(Monitor *m) { !l->mapped || l == exclusive_focus) continue; /* Deactivate the focused client. */ - focusclient(NULL, 0); exclusive_focus = l; - dwl_im_relay_set_focus(dwl_input_method_relay, - l->layer_surface->surface); - client_notify_enter(l->layer_surface->surface, - wlr_seat_get_keyboard(seat)); + focuslayer(l); return; } } @@ -1893,11 +1895,7 @@ buttonpress(struct wl_listener *listener, void *data) { if (l && !exclusive_focus && l->layer_surface->current.keyboard_interactive == ZWLR_LAYER_SURFACE_V1_KEYBOARD_INTERACTIVITY_ON_DEMAND) { - focusclient(NULL, 0); - dwl_im_relay_set_focus(dwl_input_method_relay, - l->layer_surface->surface); - client_notify_enter(l->layer_surface->surface, - wlr_seat_get_keyboard(seat)); + focuslayer(l); } } @@ -2226,11 +2224,7 @@ void maplayersurfacenotify(struct wl_listener *listener, void *data) { if (!exclusive_focus && l->layer_surface->current.keyboard_interactive == ZWLR_LAYER_SURFACE_V1_KEYBOARD_INTERACTIVITY_ON_DEMAND) { - focusclient(NULL, 0); - dwl_im_relay_set_focus(dwl_input_method_relay, - l->layer_surface->surface); - client_notify_enter(l->layer_surface->surface, - wlr_seat_get_keyboard(seat)); + focuslayer(l); } } From 006cf46c52467ba44b7a0e23cc4a981c0f34e9dc Mon Sep 17 00:00:00 2001 From: Rexiel Scarlet <37258415+Rexcrazy804@users.noreply.github.com> Date: Sun, 23 Nov 2025 20:20:47 +0400 Subject: [PATCH 38/70] feat: support transparent wlr session lock --- src/config/parse_config.h | 5 +++++ src/config/preset.h | 1 + src/mango.c | 8 ++++++-- 3 files changed, 12 insertions(+), 2 deletions(-) diff --git a/src/config/parse_config.h b/src/config/parse_config.h index a58a106f..b750c7c2 100644 --- a/src/config/parse_config.h +++ b/src/config/parse_config.h @@ -339,6 +339,7 @@ typedef struct { int adaptive_sync; int allow_tearing; int allow_shortcuts_inhibit; + int transparent_wlr_lock; struct xkb_rule_names xkb_rules; @@ -1221,6 +1222,8 @@ void parse_option(Config *config, char *key, char *value) { config->allow_tearing = atoi(value); } else if (strcmp(key, "allow_shortcuts_inhibit") == 0) { config->allow_shortcuts_inhibit = atoi(value); + } else if (strcmp(key, "transparent_wlr_lock") == 0) { + config->transparent_wlr_lock = atoi(value); } else if (strcmp(key, "no_border_when_single") == 0) { config->no_border_when_single = atoi(value); } else if (strcmp(key, "no_radius_when_single") == 0) { @@ -2671,6 +2674,7 @@ void override_config(void) { adaptive_sync = CLAMP_INT(config.adaptive_sync, 0, 1); allow_tearing = CLAMP_INT(config.allow_tearing, 0, 2); allow_shortcuts_inhibit = CLAMP_INT(config.allow_shortcuts_inhibit, 0, 1); + transparent_wlr_lock = CLAMP_INT(config.transparent_wlr_lock, 0, 1); axis_bind_apply_timeout = CLAMP_INT(config.axis_bind_apply_timeout, 0, 1000); focus_on_activate = CLAMP_INT(config.focus_on_activate, 0, 1); @@ -2849,6 +2853,7 @@ void set_value_default() { config.adaptive_sync = adaptive_sync; config.allow_tearing = allow_tearing; config.allow_shortcuts_inhibit = allow_shortcuts_inhibit; + config.transparent_wlr_lock = transparent_wlr_lock; config.no_border_when_single = no_border_when_single; config.no_radius_when_single = no_radius_when_single; config.snap_distance = snap_distance; diff --git a/src/config/preset.h b/src/config/preset.h index eaa7be22..da8100ab 100644 --- a/src/config/preset.h +++ b/src/config/preset.h @@ -103,6 +103,7 @@ int warpcursor = 1; /* Warp cursor to focused client */ int xwayland_persistence = 1; /* xwayland persistence */ int syncobj_enable = 0; int adaptive_sync = 0; +int transparent_wlr_lock = 0; double drag_refresh_interval = 30.0; int allow_tearing = TEARING_DISABLED; int allow_shortcuts_inhibit = SHORTCUTS_INHIBIT_ENABLE; diff --git a/src/mango.c b/src/mango.c index 8a27b751..287e4a6b 100644 --- a/src/mango.c +++ b/src/mango.c @@ -3029,7 +3029,9 @@ void destroylock(SessionLock *lock, int unlock) { if ((locked = !unlock)) goto destroy; - wlr_scene_node_set_enabled(&locked_bg->node, false); + if (locked_bg->node.enabled) { + wlr_scene_node_set_enabled(&locked_bg->node, false); + } focusclient(focustop(selmon), 0); motionnotify(0, NULL, 0, 0, 0, 0); @@ -3567,7 +3569,9 @@ void pending_kill_client(Client *c) { void locksession(struct wl_listener *listener, void *data) { struct wlr_session_lock_v1 *session_lock = data; SessionLock *lock; - wlr_scene_node_set_enabled(&locked_bg->node, true); + if (!transparent_wlr_lock) { + wlr_scene_node_set_enabled(&locked_bg->node, true); + } if (cur_lock) { wlr_session_lock_v1_destroy(session_lock); return; From 7c7a9437e67b120df24fd4aa0d6ab5a963bc934d Mon Sep 17 00:00:00 2001 From: DreamMaoMao <2523610504@qq.com> Date: Sat, 29 Nov 2025 16:31:09 +0800 Subject: [PATCH 39/70] opt: optimize option name transparent_wlr_lock to allow_lock_transparent --- src/config/parse_config.h | 10 +++++----- src/config/preset.h | 2 +- src/mango.c | 2 +- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/config/parse_config.h b/src/config/parse_config.h index b750c7c2..7196270d 100644 --- a/src/config/parse_config.h +++ b/src/config/parse_config.h @@ -339,7 +339,7 @@ typedef struct { int adaptive_sync; int allow_tearing; int allow_shortcuts_inhibit; - int transparent_wlr_lock; + int allow_lock_transparent; struct xkb_rule_names xkb_rules; @@ -1222,8 +1222,8 @@ void parse_option(Config *config, char *key, char *value) { config->allow_tearing = atoi(value); } else if (strcmp(key, "allow_shortcuts_inhibit") == 0) { config->allow_shortcuts_inhibit = atoi(value); - } else if (strcmp(key, "transparent_wlr_lock") == 0) { - config->transparent_wlr_lock = atoi(value); + } else if (strcmp(key, "allow_lock_transparent") == 0) { + config->allow_lock_transparent = atoi(value); } else if (strcmp(key, "no_border_when_single") == 0) { config->no_border_when_single = atoi(value); } else if (strcmp(key, "no_radius_when_single") == 0) { @@ -2674,7 +2674,7 @@ void override_config(void) { adaptive_sync = CLAMP_INT(config.adaptive_sync, 0, 1); allow_tearing = CLAMP_INT(config.allow_tearing, 0, 2); allow_shortcuts_inhibit = CLAMP_INT(config.allow_shortcuts_inhibit, 0, 1); - transparent_wlr_lock = CLAMP_INT(config.transparent_wlr_lock, 0, 1); + allow_lock_transparent = CLAMP_INT(config.allow_lock_transparent, 0, 1); axis_bind_apply_timeout = CLAMP_INT(config.axis_bind_apply_timeout, 0, 1000); focus_on_activate = CLAMP_INT(config.focus_on_activate, 0, 1); @@ -2853,7 +2853,7 @@ void set_value_default() { config.adaptive_sync = adaptive_sync; config.allow_tearing = allow_tearing; config.allow_shortcuts_inhibit = allow_shortcuts_inhibit; - config.transparent_wlr_lock = transparent_wlr_lock; + config.allow_lock_transparent = allow_lock_transparent; config.no_border_when_single = no_border_when_single; config.no_radius_when_single = no_radius_when_single; config.snap_distance = snap_distance; diff --git a/src/config/preset.h b/src/config/preset.h index da8100ab..4032a757 100644 --- a/src/config/preset.h +++ b/src/config/preset.h @@ -103,7 +103,7 @@ int warpcursor = 1; /* Warp cursor to focused client */ int xwayland_persistence = 1; /* xwayland persistence */ int syncobj_enable = 0; int adaptive_sync = 0; -int transparent_wlr_lock = 0; +int allow_lock_transparent = 0; double drag_refresh_interval = 30.0; int allow_tearing = TEARING_DISABLED; int allow_shortcuts_inhibit = SHORTCUTS_INHIBIT_ENABLE; diff --git a/src/mango.c b/src/mango.c index ca8d8c9b..ff9ed6eb 100644 --- a/src/mango.c +++ b/src/mango.c @@ -3576,7 +3576,7 @@ void pending_kill_client(Client *c) { void locksession(struct wl_listener *listener, void *data) { struct wlr_session_lock_v1 *session_lock = data; SessionLock *lock; - if (!transparent_wlr_lock) { + if (!allow_lock_transparent) { wlr_scene_node_set_enabled(&locked_bg->node, true); } if (cur_lock) { From b3ccf43453491196be8a94c672394dcc527803a0 Mon Sep 17 00:00:00 2001 From: DreamMaoMao <2523610504@qq.com> Date: Sat, 29 Nov 2025 17:30:01 +0800 Subject: [PATCH 40/70] opt: not swallow the isminied window --- src/mango.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/mango.c b/src/mango.c index ff9ed6eb..b80d3d89 100644 --- a/src/mango.c +++ b/src/mango.c @@ -1376,7 +1376,7 @@ void applyrules(Client *c) { if (!c->noswallow && !c->isfloating && !client_is_float_type(c) && !c->surface.xdg->initial_commit) { Client *p = termforwin(c); - if (p) { + if (p && !p->isminied) { c->swallowedby = p; p->swallowing = c; wl_list_remove(&c->link); From 09c19205150f067fd524feafebbaa8744a3e0885 Mon Sep 17 00:00:00 2001 From: DreamMaoMao <2523610504@qq.com> Date: Sat, 29 Nov 2025 17:33:57 +0800 Subject: [PATCH 41/70] opt: correct var isminized to isminimized --- src/dispatch/bind_define.h | 12 +++++----- src/ext-protocol/foreign-toplevel.h | 4 ++-- src/mango.c | 34 ++++++++++++++--------------- 3 files changed, 25 insertions(+), 25 deletions(-) diff --git a/src/dispatch/bind_define.h b/src/dispatch/bind_define.h index d79a7c65..a1418300 100644 --- a/src/dispatch/bind_define.h +++ b/src/dispatch/bind_define.h @@ -133,7 +133,7 @@ int focuslast(const Arg *arg) { unsigned int target = 0; wl_list_for_each(c, &fstack, flink) { - if (c->iskilling || c->isminied || c->isunglobal || + if (c->iskilling || c->isminimized || c->isunglobal || !client_surface(c)->mapped || client_is_unmanaged(c) || client_is_x11_popup(c)) continue; @@ -471,7 +471,7 @@ int restore_minimized(const Arg *arg) { if (selmon && selmon->sel && selmon->sel->is_in_scratchpad && selmon->sel->is_scratchpad_show) { - selmon->sel->isminied = 0; + selmon->sel->isminimized = 0; selmon->sel->is_scratchpad_show = 0; selmon->sel->is_in_scratchpad = 0; selmon->sel->isnamedscratchpad = 0; @@ -480,7 +480,7 @@ int restore_minimized(const Arg *arg) { } wl_list_for_each(c, &clients, link) { - if (c->isminied && !c->isnamedscratchpad) { + if (c->isminimized && !c->isnamedscratchpad) { c->is_scratchpad_show = 0; c->is_in_scratchpad = 0; c->isnamedscratchpad = 0; @@ -1122,7 +1122,7 @@ int toggle_scratchpad(const Arg *arg) { continue; } - if (single_scratchpad && c->isnamedscratchpad && !c->isminied) { + if (single_scratchpad && c->isnamedscratchpad && !c->isminimized) { set_minimized(c); continue; } @@ -1447,7 +1447,7 @@ int minimized(const Arg *arg) { if (selmon && selmon->isoverview) return 0; - if (selmon->sel && !selmon->sel->isminied) { + if (selmon->sel && !selmon->sel->isminimized) { set_minimized(selmon->sel); } return 0; @@ -1469,7 +1469,7 @@ int toggleoverview(const Arg *arg) { wl_list_for_each(c, &clients, link) if (c && c->mon == selmon && !client_is_unmanaged(c) && !client_is_x11_popup(c) && - !c->isminied && + !c->isminimized && !c->isunglobal) { visible_client_number++; } diff --git a/src/ext-protocol/foreign-toplevel.h b/src/ext-protocol/foreign-toplevel.h index adfcd21b..0bb649e0 100644 --- a/src/ext-protocol/foreign-toplevel.h +++ b/src/ext-protocol/foreign-toplevel.h @@ -9,12 +9,12 @@ void handle_foreign_activate_request(struct wl_listener *listener, void *data) { if (c && c->swallowing) return; - if (c && !c->isminied && c == selmon->sel) { + if (c && !c->isminimized && c == selmon->sel) { set_minimized(c); return; } - if (c->isminied) { + if (c->isminimized) { c->is_in_scratchpad = 0; c->isnamedscratchpad = 0; c->is_scratchpad_show = 0; diff --git a/src/mango.c b/src/mango.c index b80d3d89..5c804a0a 100644 --- a/src/mango.c +++ b/src/mango.c @@ -102,10 +102,10 @@ A->geom.x + A->geom.width <= A->mon->m.x + A->mon->m.width && \ A->geom.y + A->geom.height <= A->mon->m.y + A->mon->m.height) #define ISTILED(A) \ - (A && !(A)->isfloating && !(A)->isminied && !(A)->iskilling && \ + (A && !(A)->isfloating && !(A)->isminimized && !(A)->iskilling && \ !(A)->ismaximizescreen && !(A)->isfullscreen && !(A)->isunglobal) #define ISSCROLLTILED(A) \ - (A && !(A)->isfloating && !(A)->isminied && !(A)->iskilling && \ + (A && !(A)->isfloating && !(A)->isminimized && !(A)->iskilling && \ !(A)->isunglobal) #define VISIBLEON(C, M) \ ((C) && (M) && (C)->mon == (M) && ((C)->tags & (M)->tagset[(M)->seltags])) @@ -315,7 +315,7 @@ struct Client { unsigned int configure_serial; struct wlr_foreign_toplevel_handle_v1 *foreign_toplevel; int isfloating, isurgent, isfullscreen, isfakefullscreen, - need_float_size_reduce, isminied, isoverlay, isnosizehint, + need_float_size_reduce, isminimized, isoverlay, isnosizehint, ignore_maximize, ignore_minimize; int ismaximizescreen; int overview_backup_bw; @@ -1009,7 +1009,7 @@ void swallow(Client *c, Client *w) { c->isurgent = w->isurgent; c->isfullscreen = w->isfullscreen; c->ismaximizescreen = w->ismaximizescreen; - c->isminied = w->isminied; + c->isminimized = w->isminimized; c->is_in_scratchpad = w->is_in_scratchpad; c->is_scratchpad_show = w->is_scratchpad_show; c->tags = w->tags; @@ -1029,7 +1029,7 @@ void swallow(Client *c, Client *w) { if (!c->foreign_toplevel && c->mon) add_foreign_toplevel(c); - if (c->isminied && c->foreign_toplevel) { + if (c->isminimized && c->foreign_toplevel) { wlr_foreign_toplevel_handle_v1_set_activated(c->foreign_toplevel, false); wlr_foreign_toplevel_handle_v1_set_minimized(c->foreign_toplevel, true); @@ -1376,7 +1376,7 @@ void applyrules(Client *c) { if (!c->noswallow && !c->isfloating && !client_is_float_type(c) && !c->surface.xdg->initial_commit) { Client *p = termforwin(c); - if (p && !p->isminied) { + if (p && !p->isminimized) { c->swallowedby = p; p->swallowing = c; wl_list_remove(&c->link); @@ -3633,7 +3633,7 @@ void init_client_properties(Client *c) { c->iskilling = 0; c->istagswitching = 0; c->isglobal = 0; - c->isminied = 0; + c->isminimized = 0; c->isoverlay = 0; c->isunglobal = 0; c->is_in_scratchpad = 0; @@ -3803,7 +3803,7 @@ void maximizenotify(struct wl_listener *listener, void *data) { void unminimize(Client *c) { if (c && c->is_in_scratchpad && c->is_scratchpad_show) { - c->isminied = 0; + c->isminimized = 0; c->is_scratchpad_show = 0; c->is_in_scratchpad = 0; c->isnamedscratchpad = 0; @@ -3811,7 +3811,7 @@ void unminimize(Client *c) { return; } - if (c && c->isminied) { + if (c && c->isminimized) { show_hide_client(c); c->is_scratchpad_show = 0; c->is_in_scratchpad = 0; @@ -3831,7 +3831,7 @@ void set_minimized(Client *c) { c->oldtags = c->mon->tagset[c->mon->seltags]; c->mini_restore_tag = c->tags; c->tags = 0; - c->isminied = 1; + c->isminimized = 1; c->is_in_scratchpad = 1; c->is_scratchpad_show = 0; focusclient(focustop(selmon), 1); @@ -3846,15 +3846,15 @@ void minimizenotify(struct wl_listener *listener, void *data) { Client *c = wl_container_of(listener, c, minimize); - if (!c || !c->mon || c->iskilling || c->isminied) + if (!c || !c->mon || c->iskilling || c->isminimized) return; if (client_request_minimize(c, data) && !c->ignore_minimize) { - if (!c->isminied) + if (!c->isminimized) set_minimized(c); client_set_minimized(c, true); } else { - if (c->isminied) + if (c->isminimized) unminimize(c); client_set_minimized(c, false); } @@ -4845,7 +4845,7 @@ void show_hide_client(Client *c) { c->tags = c->oldtags; arrange(c->mon, false); } - c->isminied = 0; + c->isminimized = 0; wlr_foreign_toplevel_handle_v1_set_minimized(c->foreign_toplevel, false); focusclient(c, 1); wlr_foreign_toplevel_handle_v1_set_activated(c->foreign_toplevel, true); @@ -5334,7 +5334,7 @@ void unmapnotify(struct wl_listener *listener, void *data) { Monitor *m = NULL; c->iskilling = 1; - if (animations && !c->is_clip_to_hide && !c->isminied && + if (animations && !c->is_clip_to_hide && !c->isminimized && (!c->mon || VISIBLEON(c, c->mon))) init_fadeout_client(c); @@ -5745,8 +5745,8 @@ void activatex11(struct wl_listener *listener, void *data) { if (c && c->swallowing) return; - if (c->isminied) { - c->isminied = 0; + if (c->isminimized) { + c->isminimized = 0; c->tags = c->mini_restore_tag; c->is_scratchpad_show = 0; c->is_in_scratchpad = 0; From 113e73fe4acc721c95f7f2a8dc68d75262ec258b Mon Sep 17 00:00:00 2001 From: DreamMaoMao <2523610504@qq.com> Date: Sat, 29 Nov 2025 22:46:47 +0800 Subject: [PATCH 42/70] opt: avoid toggle overview when setfullscreen and setmaximziescreen --- src/mango.c | 21 ++++++++++----------- 1 file changed, 10 insertions(+), 11 deletions(-) diff --git a/src/mango.c b/src/mango.c index 5c804a0a..70b22187 100644 --- a/src/mango.c +++ b/src/mango.c @@ -102,10 +102,10 @@ A->geom.x + A->geom.width <= A->mon->m.x + A->mon->m.width && \ A->geom.y + A->geom.height <= A->mon->m.y + A->mon->m.height) #define ISTILED(A) \ - (A && !(A)->isfloating && !(A)->isminimized && !(A)->iskilling && \ + (A && !(A)->isfloating && !(A)->isminimized && !(A)->iskilling && \ !(A)->ismaximizescreen && !(A)->isfullscreen && !(A)->isunglobal) #define ISSCROLLTILED(A) \ - (A && !(A)->isfloating && !(A)->isminimized && !(A)->iskilling && \ + (A && !(A)->isfloating && !(A)->isminimized && !(A)->iskilling && \ !(A)->isunglobal) #define VISIBLEON(C, M) \ ((C) && (M) && (C)->mon == (M) && ((C)->tags & (M)->tagset[(M)->seltags])) @@ -4559,6 +4559,9 @@ void setmaximizescreen(Client *c, int maximizescreen) { if (!c || !c->mon || !client_surface(c)->mapped || c->iskilling) return; + if (c->mon->isoverview) + return; + c->ismaximizescreen = maximizescreen; if (maximizescreen) { @@ -4568,10 +4571,6 @@ void setmaximizescreen(Client *c, int maximizescreen) { if (c->isfloating) c->float_geom = c->geom; - if (selmon->isoverview) { - Arg arg = {0}; - toggleoverview(&arg); - } maximizescreen_box.x = c->mon->w.x + gappoh; maximizescreen_box.y = c->mon->w.y + gappov; @@ -4615,11 +4614,15 @@ void setfakefullscreen(Client *c, int fakefullscreen) { void setfullscreen(Client *c, int fullscreen) // 用自定义全屏代理自带全屏 { - c->isfullscreen = fullscreen; if (!c || !c->mon || !client_surface(c)->mapped || c->iskilling) return; + if (c->mon->isoverview) + return; + + c->isfullscreen = fullscreen; + client_set_fullscreen(c, fullscreen); if (fullscreen) { @@ -4628,10 +4631,6 @@ void setfullscreen(Client *c, int fullscreen) // 用自定义全屏代理自带 if (c->isfloating) c->float_geom = c->geom; - if (selmon->isoverview) { - Arg arg = {0}; - toggleoverview(&arg); - } c->bw = 0; wlr_scene_node_raise_to_top(&c->scene->node); // 将视图提升到顶层 From 992822e309a814c003d3dc62bf1b56da2ee8765c Mon Sep 17 00:00:00 2001 From: DreamMaoMao <2523610504@qq.com> Date: Sun, 30 Nov 2025 10:52:02 +0800 Subject: [PATCH 43/70] opt: not handle virtual group keyborad ov_tab_mode detect --- src/mango.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/mango.c b/src/mango.c index 70b22187..c80eed1d 100644 --- a/src/mango.c +++ b/src/mango.c @@ -3493,7 +3493,7 @@ void keypress(struct wl_listener *listener, void *data) { wlr_idle_notifier_v1_notify_activity(idle_notifier, seat); // ov tab mode detect moe key release - if (ov_tab_mode && !locked && + if (ov_tab_mode && !locked && group == kb_group && event->state == WL_KEYBOARD_KEY_STATE_RELEASED && (keycode == 133 || keycode == 37 || keycode == 64 || keycode == 50 || keycode == 134 || keycode == 105 || keycode == 108 || keycode == 62) && From 1b7e998b678ef040adb384a308772da5d3dee3f7 Mon Sep 17 00:00:00 2001 From: DreamMaoMao <2523610504@qq.com> Date: Sun, 30 Nov 2025 11:57:34 +0800 Subject: [PATCH 44/70] opt: optimize scroller layout center client judge --- src/fetch/client.h | 5 +++-- src/layout/horizontal.h | 2 +- src/layout/vertical.h | 2 +- 3 files changed, 5 insertions(+), 4 deletions(-) diff --git a/src/fetch/client.h b/src/fetch/client.h index c2b0abdd..a9cfed07 100644 --- a/src/fetch/client.h +++ b/src/fetch/client.h @@ -128,8 +128,9 @@ Client *center_tiled_select(Monitor *m) { int dirx, diry; long int distance; wl_list_for_each(c, &clients, link) { - if (c && VISIBLEON(c, m) && ISTILED(c) && client_surface(c)->mapped && - !c->isfloating && !client_is_unmanaged(c)) { + if (c && VISIBLEON(c, m) && ISSCROLLTILED(c) && + client_surface(c)->mapped && !c->isfloating && + !client_is_unmanaged(c)) { dirx = c->geom.x + c->geom.width / 2 - (m->w.x + m->w.width / 2); diry = c->geom.y + c->geom.height / 2 - (m->w.y + m->w.height / 2); distance = dirx * dirx + diry * diry; diff --git a/src/layout/horizontal.h b/src/layout/horizontal.h index 2385c848..3471fdf7 100644 --- a/src/layout/horizontal.h +++ b/src/layout/horizontal.h @@ -284,7 +284,7 @@ void scroller(Monitor *m) { return; } - if (m->sel && !client_is_unmanaged(m->sel) && !m->sel->isfloating) { + if (m->sel && !client_is_unmanaged(m->sel) && ISSCROLLTILED(m->sel)) { root_client = m->sel; } else if (m->prevsel && ISSCROLLTILED(m->prevsel) && VISIBLEON(m->prevsel, m) && !client_is_unmanaged(m->prevsel)) { diff --git a/src/layout/vertical.h b/src/layout/vertical.h index 7eb95291..f6aa6b86 100644 --- a/src/layout/vertical.h +++ b/src/layout/vertical.h @@ -246,7 +246,7 @@ void vertical_scroller(Monitor *m) { return; } - if (m->sel && !client_is_unmanaged(m->sel) && !m->sel->isfloating) { + if (m->sel && !client_is_unmanaged(m->sel) && ISSCROLLTILED(m->sel)) { root_client = m->sel; } else if (m->prevsel && ISSCROLLTILED(m->prevsel) && VISIBLEON(m->prevsel, m) && !client_is_unmanaged(m->prevsel)) { From e0c80af6b17f8a875de9fdf97bcb736447287843 Mon Sep 17 00:00:00 2001 From: DreamMaoMao <2523610504@qq.com> Date: Mon, 1 Dec 2025 11:23:18 +0800 Subject: [PATCH 45/70] update readme --- README.md | 8 -------- 1 file changed, 8 deletions(-) diff --git a/README.md b/README.md index b321be5b..5701178b 100644 --- a/README.md +++ b/README.md @@ -248,14 +248,6 @@ Here's an example of using the modules in a flake: } ``` - -# Sponsor - -My current device is a bit outdated and doesn't support certain features like HDR or VRR. If you'd like to support this project, here's how you can help. Thanks! - -![Screenshot_2025-10-13-20-06-49-26_ee1cec40dcf6eb3](https://github.com/user-attachments/assets/240a0727-9eb5-4212-a84c-10fa9f093147) - - # Packaging mango To package mango for other distributions, you can check the reference setup for: From 075d4979b6750e46b034573a662f1846c37faedb Mon Sep 17 00:00:00 2001 From: DreamMaoMao <2523610504@qq.com> Date: Tue, 2 Dec 2025 16:19:31 +0800 Subject: [PATCH 46/70] opt: use signal to handle printstauts --- src/mango.c | 56 ++++++++++++++++++++++++++++++++++++++++------------- 1 file changed, 43 insertions(+), 13 deletions(-) diff --git a/src/mango.c b/src/mango.c index c80eed1d..62656dbc 100644 --- a/src/mango.c +++ b/src/mango.c @@ -204,6 +204,9 @@ typedef struct { unsigned int ui; unsigned int ui2; } Arg; +struct mango_print_status_manager { + struct wl_signal print_status; +}; typedef struct { unsigned int mod; @@ -515,6 +518,7 @@ static void arrangelayer(Monitor *m, struct wl_list *list, struct wlr_box *usable_area, int exclusive); static void arrangelayers(Monitor *m); static char *get_autostart_path(char *, unsigned int); // 自启动命令执行 +static void handle_print_status(struct wl_listener *listener, void *data); static void axisnotify(struct wl_listener *listener, void *data); // 滚轮事件处理 static void buttonpress(struct wl_listener *listener, @@ -777,6 +781,7 @@ static struct wlr_virtual_pointer_manager_v1 *virtual_pointer_mgr; static struct wlr_output_power_manager_v1 *power_mgr; static struct wlr_pointer_gestures_v1 *pointer_gestures; static struct wlr_drm_lease_v1_manager *drm_lease_manager; +struct mango_print_status_manager *print_status_manager; static struct wlr_cursor *cursor; static struct wlr_xcursor_manager *cursor_mgr; @@ -852,6 +857,8 @@ struct Pertag { *ltidxs[LENGTH(tags) + 1]; /* matrix of tags and layouts indexes */ }; +static struct wl_listener print_status_listener = {.notify = + handle_print_status}; static struct wl_listener cursor_axis = {.notify = axisnotify}; static struct wl_listener cursor_button = {.notify = buttonpress}; static struct wl_listener cursor_frame = {.notify = cursorframe}; @@ -2004,6 +2011,7 @@ void setcursorshape(struct wl_listener *listener, void *data) { } void cleanuplisteners(void) { + wl_list_remove(&print_status_listener.link); wl_list_remove(&cursor_axis.link); wl_list_remove(&cursor_button.link); wl_list_remove(&cursor_frame.link); @@ -4135,19 +4143,8 @@ void pointerfocus(Client *c, struct wlr_surface *surface, double sx, double sy, wlr_seat_pointer_notify_motion(seat, time, sx, sy); } -void // 17 -printstatus(void) { - Monitor *m = NULL; - wl_list_for_each(m, &mons, link) { - if (!m->wlr_output->enabled) { - continue; - } - // Update workspace active states - dwl_ext_workspace_printstatus(m); - - // Update IPC output status - dwl_ipc_output_printstatus(m); - } +void printstatus(void) { + wl_signal_emit(&print_status_manager->print_status, NULL); } void powermgrsetmode(struct wl_listener *listener, void *data) { @@ -4871,6 +4868,35 @@ void create_output(struct wlr_backend *backend, void *data) { #endif } +// 创建函数 +struct mango_print_status_manager *mango_print_status_manager_create() { + struct mango_print_status_manager *manager = calloc(1, sizeof(*manager)); + if (!manager) + return NULL; + + // 初始化 print_status 信号,不是 event_signal + wl_signal_init(&manager->print_status); + + return manager; +} + +void handle_print_status(struct wl_listener *listener, void *data) { + struct mango_print_status_manager *manager = + wl_container_of(listener, manager, print_status); + // struct wlr_print_status *status = data; + Monitor *m = NULL; + wl_list_for_each(m, &mons, link) { + if (!m->wlr_output->enabled) { + continue; + } + // Update workspace active states + dwl_ext_workspace_printstatus(m); + + // Update IPC output status + dwl_ipc_output_printstatus(m); + } +} + void setup(void) { setenv("XCURSOR_SIZE", "24", 1); @@ -4966,6 +4992,10 @@ void setup(void) { wlr_alpha_modifier_v1_create(dpy); wlr_ext_data_control_manager_v1_create(dpy, 1); + // 在 setup 函数中 + print_status_manager = mango_print_status_manager_create(); + wl_signal_add(&print_status_manager->print_status, &print_status_listener); + /* Initializes the interface used to implement urgency hints */ activation = wlr_xdg_activation_v1_create(dpy); wl_signal_add(&activation->events.request_activate, &request_activate); From 9196e2a50be7c1de84da08ef50fba8c440f1c6b2 Mon Sep 17 00:00:00 2001 From: DreamMaoMao <2523610504@qq.com> Date: Tue, 2 Dec 2025 16:46:11 +0800 Subject: [PATCH 47/70] opt: use event mask to decide whether print ipc message --- src/config/parse_config.h | 2 +- src/dispatch/bind_define.h | 16 +-- src/ext-protocol/dwl-ipc.h | 208 +++++++++++++++++++++++++------------ src/mango.c | 75 +++++++++---- 4 files changed, 205 insertions(+), 96 deletions(-) diff --git a/src/config/parse_config.h b/src/config/parse_config.h index 7196270d..afc9acb8 100644 --- a/src/config/parse_config.h +++ b/src/config/parse_config.h @@ -3255,6 +3255,6 @@ void reset_option(void) { int reload_config(const Arg *arg) { parse_config(); reset_option(); - printstatus(); + printstatus(PRINT_ALL); return 0; } diff --git a/src/dispatch/bind_define.h b/src/dispatch/bind_define.h index a1418300..a782d4f1 100644 --- a/src/dispatch/bind_define.h +++ b/src/dispatch/bind_define.h @@ -503,7 +503,7 @@ int setlayout(const Arg *arg) { selmon->pertag->ltidxs[selmon->pertag->curtag] = &layouts[jk]; clear_fullscreen_and_maximized_state(selmon); arrange(selmon, false); - printstatus(); + printstatus(PRINT_ALL); return 0; } } @@ -517,7 +517,7 @@ int setkeymode(const Arg *arg) { } else { keymode.isdefault = false; } - printstatus(); + printstatus(PRINT_KEYMODE); return 1; } @@ -866,7 +866,7 @@ int switch_keyboard_layout(const Arg *arg) { wlr_seat_keyboard_notify_modifiers(seat, &tkb->modifiers); } - printstatus(); + printstatus(PRINT_KB_LAYOUT); return 0; } @@ -907,7 +907,7 @@ int switch_layout(const Arg *arg) { } clear_fullscreen_and_maximized_state(selmon); arrange(selmon, false); - printstatus(); + printstatus(PRINT_ALL); return 0; } @@ -918,7 +918,7 @@ int switch_layout(const Arg *arg) { jk == LENGTH(layouts) - 1 ? &layouts[0] : &layouts[jk + 1]; clear_fullscreen_and_maximized_state(selmon); arrange(selmon, false); - printstatus(); + printstatus(PRINT_ALL); return 0; } } @@ -1260,7 +1260,7 @@ int toggletag(const Arg *arg) { focusclient(focustop(selmon), 1); arrange(selmon, false); } - printstatus(); + printstatus(PRINT_ALL); return 0; } @@ -1278,7 +1278,7 @@ int toggleview(const Arg *arg) { focusclient(focustop(selmon), 1); arrange(selmon, false); } - printstatus(); + printstatus(PRINT_ALL); return 0; } @@ -1398,7 +1398,7 @@ int comboview(const Arg *arg) { view(&(Arg){.ui = newtags}, false); } - printstatus(); + printstatus(PRINT_ALL); return 0; } diff --git a/src/ext-protocol/dwl-ipc.h b/src/ext-protocol/dwl-ipc.h index 15b2376a..1d861b91 100644 --- a/src/ext-protocol/dwl-ipc.h +++ b/src/ext-protocol/dwl-ipc.h @@ -10,8 +10,9 @@ static void dwl_ipc_manager_get_output(struct wl_client *client, static void dwl_ipc_manager_release(struct wl_client *client, struct wl_resource *resource); static void dwl_ipc_output_destroy(struct wl_resource *resource); -static void dwl_ipc_output_printstatus(Monitor *monitor); -static void dwl_ipc_output_printstatus_to(DwlIpcOutput *ipc_output); +static void dwl_ipc_output_printstatus(Monitor *monitor, uint32_t event_mask); +static void dwl_ipc_output_printstatus_to(DwlIpcOutput *ipc_output, + uint32_t event_mask); static void dwl_ipc_output_set_client_tags(struct wl_client *client, struct wl_resource *resource, unsigned int and_tags, @@ -87,7 +88,7 @@ void dwl_ipc_manager_get_output(struct wl_client *client, wl_resource_set_implementation(output_resource, &dwl_output_implementation, ipc_output, dwl_ipc_output_destroy); wl_list_insert(&monitor->dwl_ipc_outputs, &ipc_output->link); - dwl_ipc_output_printstatus_to(ipc_output); + dwl_ipc_output_printstatus_to(ipc_output, PRINT_ALL); } void dwl_ipc_manager_release(struct wl_client *client, @@ -101,13 +102,16 @@ static void dwl_ipc_output_destroy(struct wl_resource *resource) { free(ipc_output); } -void dwl_ipc_output_printstatus(Monitor *monitor) { +// 修改IPC输出函数,接受掩码参数 +void dwl_ipc_output_printstatus(Monitor *monitor, uint32_t event_mask) { DwlIpcOutput *ipc_output; wl_list_for_each(ipc_output, &monitor->dwl_ipc_outputs, link) - dwl_ipc_output_printstatus_to(ipc_output); + dwl_ipc_output_printstatus_to(ipc_output, event_mask); } -void dwl_ipc_output_printstatus_to(DwlIpcOutput *ipc_output) { +// 修改主IPC输出函数,根据掩码发送相应事件 +void dwl_ipc_output_printstatus_to(DwlIpcOutput *ipc_output, + uint32_t event_mask) { Monitor *monitor = ipc_output->mon; Client *c = NULL, *focused = NULL; struct wlr_keyboard *keyboard; @@ -115,103 +119,175 @@ void dwl_ipc_output_printstatus_to(DwlIpcOutput *ipc_output) { int tagmask, state, numclients, focused_client, tag; const char *title, *appid, *symbol; char kb_layout[32]; - focused = focustop(monitor); - zdwl_ipc_output_v2_send_active(ipc_output->resource, monitor == selmon); - for (tag = 0; tag < LENGTH(tags); tag++) { - numclients = state = focused_client = 0; - tagmask = 1 << tag; - if ((tagmask & monitor->tagset[monitor->seltags]) != 0) - state |= ZDWL_IPC_OUTPUT_V2_TAG_STATE_ACTIVE; - wl_list_for_each(c, &clients, link) { - if (c->mon != monitor) - continue; - if (!(c->tags & tagmask)) - continue; - if (c == focused) - focused_client = 1; - if (c->isurgent) - state |= ZDWL_IPC_OUTPUT_V2_TAG_STATE_URGENT; - numclients++; + // 只在需要时才获取这些数据 + if (event_mask & (PRINT_ACTIVE | PRINT_TAG | PRINT_TITLE | PRINT_APPID | + PRINT_FULLSCREEN | PRINT_FLOATING | PRINT_X | PRINT_Y | + PRINT_WIDTH | PRINT_HEIGHT)) { + focused = focustop(monitor); + } + + // 发送活动状态 + if (event_mask & PRINT_ACTIVE) { + zdwl_ipc_output_v2_send_active(ipc_output->resource, monitor == selmon); + } + + // 发送标签状态 + if (event_mask & PRINT_TAG) { + for (tag = 0; tag < LENGTH(tags); tag++) { + numclients = state = focused_client = 0; + tagmask = 1 << tag; + if ((tagmask & monitor->tagset[monitor->seltags]) != 0) + state |= ZDWL_IPC_OUTPUT_V2_TAG_STATE_ACTIVE; + + if (focused) { + wl_list_for_each(c, &clients, link) { + if (c->mon != monitor) + continue; + if (!(c->tags & tagmask)) + continue; + if (c == focused) + focused_client = 1; + if (c->isurgent) + state |= ZDWL_IPC_OUTPUT_V2_TAG_STATE_URGENT; + numclients++; + } + } + zdwl_ipc_output_v2_send_tag(ipc_output->resource, tag, state, + numclients, focused_client); } - zdwl_ipc_output_v2_send_tag(ipc_output->resource, tag, state, - numclients, focused_client); } - title = focused ? client_get_title(focused) : ""; - appid = focused ? client_get_appid(focused) : ""; - - if (monitor->isoverview) { - symbol = overviewlayout.symbol; - } else { - symbol = monitor->pertag->ltidxs[monitor->pertag->curtag]->symbol; + // 只在需要时才获取标题和应用ID + if (event_mask & (PRINT_TITLE | PRINT_APPID)) { + title = focused ? client_get_title(focused) : ""; + appid = focused ? client_get_appid(focused) : ""; } - keyboard = &kb_group->wlr_group->keyboard; - current = xkb_state_serialize_layout(keyboard->xkb_state, - XKB_STATE_LAYOUT_EFFECTIVE); - get_layout_abbr(kb_layout, - xkb_keymap_layout_get_name(keyboard->keymap, current)); + // 获取布局符号 + if (event_mask & PRINT_LAYOUT_SYMBOL) { + if (monitor->isoverview) { + symbol = overviewlayout.symbol; + } else { + symbol = monitor->pertag->ltidxs[monitor->pertag->curtag]->symbol; + } + } - zdwl_ipc_output_v2_send_layout( - ipc_output->resource, - monitor->pertag->ltidxs[monitor->pertag->curtag] - layouts); - zdwl_ipc_output_v2_send_title(ipc_output->resource, title ? title : broken); - zdwl_ipc_output_v2_send_appid(ipc_output->resource, appid ? appid : broken); - zdwl_ipc_output_v2_send_layout_symbol(ipc_output->resource, symbol); - if (wl_resource_get_version(ipc_output->resource) >= - ZDWL_IPC_OUTPUT_V2_FULLSCREEN_SINCE_VERSION) { + // 发送布局索引 + if (event_mask & PRINT_LAYOUT) { + zdwl_ipc_output_v2_send_layout( + ipc_output->resource, + monitor->pertag->ltidxs[monitor->pertag->curtag] - layouts); + } + + // 发送标题 + if (event_mask & PRINT_TITLE) { + zdwl_ipc_output_v2_send_title(ipc_output->resource, + title ? title : broken); + } + + // 发送应用ID + if (event_mask & PRINT_APPID) { + zdwl_ipc_output_v2_send_appid(ipc_output->resource, + appid ? appid : broken); + } + + // 发送布局符号 + if (event_mask & PRINT_LAYOUT_SYMBOL) { + zdwl_ipc_output_v2_send_layout_symbol(ipc_output->resource, symbol); + } + + // 发送全屏状态 + if ((event_mask & PRINT_FULLSCREEN) && + wl_resource_get_version(ipc_output->resource) >= + ZDWL_IPC_OUTPUT_V2_FULLSCREEN_SINCE_VERSION) { zdwl_ipc_output_v2_send_fullscreen(ipc_output->resource, focused ? focused->isfullscreen : 0); } - if (wl_resource_get_version(ipc_output->resource) >= - ZDWL_IPC_OUTPUT_V2_FLOATING_SINCE_VERSION) { + + // 发送浮动状态 + if ((event_mask & PRINT_FLOATING) && + wl_resource_get_version(ipc_output->resource) >= + ZDWL_IPC_OUTPUT_V2_FLOATING_SINCE_VERSION) { zdwl_ipc_output_v2_send_floating(ipc_output->resource, focused ? focused->isfloating : 0); } - if (wl_resource_get_version(ipc_output->resource) >= - ZDWL_IPC_OUTPUT_V2_X_SINCE_VERSION) { + + // 发送X坐标 + if ((event_mask & PRINT_X) && + wl_resource_get_version(ipc_output->resource) >= + ZDWL_IPC_OUTPUT_V2_X_SINCE_VERSION) { zdwl_ipc_output_v2_send_x(ipc_output->resource, focused ? focused->geom.x : 0); } - if (wl_resource_get_version(ipc_output->resource) >= - ZDWL_IPC_OUTPUT_V2_Y_SINCE_VERSION) { + + // 发送Y坐标 + if ((event_mask & PRINT_Y) && + wl_resource_get_version(ipc_output->resource) >= + ZDWL_IPC_OUTPUT_V2_Y_SINCE_VERSION) { zdwl_ipc_output_v2_send_y(ipc_output->resource, focused ? focused->geom.y : 0); } - if (wl_resource_get_version(ipc_output->resource) >= - ZDWL_IPC_OUTPUT_V2_WIDTH_SINCE_VERSION) { + + // 发送宽度 + if ((event_mask & PRINT_WIDTH) && + wl_resource_get_version(ipc_output->resource) >= + ZDWL_IPC_OUTPUT_V2_WIDTH_SINCE_VERSION) { zdwl_ipc_output_v2_send_width(ipc_output->resource, focused ? focused->geom.width : 0); } - if (wl_resource_get_version(ipc_output->resource) >= - ZDWL_IPC_OUTPUT_V2_HEIGHT_SINCE_VERSION) { + + // 发送高度 + if ((event_mask & PRINT_HEIGHT) && + wl_resource_get_version(ipc_output->resource) >= + ZDWL_IPC_OUTPUT_V2_HEIGHT_SINCE_VERSION) { zdwl_ipc_output_v2_send_height(ipc_output->resource, focused ? focused->geom.height : 0); } - if (wl_resource_get_version(ipc_output->resource) >= - ZDWL_IPC_OUTPUT_V2_LAST_LAYER_SINCE_VERSION) { + + // 发送最后图层 + if ((event_mask & PRINT_LAST_LAYER) && + wl_resource_get_version(ipc_output->resource) >= + ZDWL_IPC_OUTPUT_V2_LAST_LAYER_SINCE_VERSION) { zdwl_ipc_output_v2_send_last_layer(ipc_output->resource, monitor->last_surface_ws_name); } - if (wl_resource_get_version(ipc_output->resource) >= - ZDWL_IPC_OUTPUT_V2_KB_LAYOUT_SINCE_VERSION) { + // 获取键盘布局(只在需要时) + if (event_mask & PRINT_KB_LAYOUT) { + keyboard = &kb_group->wlr_group->keyboard; + current = xkb_state_serialize_layout(keyboard->xkb_state, + XKB_STATE_LAYOUT_EFFECTIVE); + get_layout_abbr(kb_layout, + xkb_keymap_layout_get_name(keyboard->keymap, current)); + } + + // 发送键盘布局 + if ((event_mask & PRINT_KB_LAYOUT) && + wl_resource_get_version(ipc_output->resource) >= + ZDWL_IPC_OUTPUT_V2_KB_LAYOUT_SINCE_VERSION) { zdwl_ipc_output_v2_send_kb_layout(ipc_output->resource, kb_layout); } - if (wl_resource_get_version(ipc_output->resource) >= - ZDWL_IPC_OUTPUT_V2_KEYMODE_SINCE_VERSION) { + // 发送键模式 + if ((event_mask & PRINT_KEYMODE) && + wl_resource_get_version(ipc_output->resource) >= + ZDWL_IPC_OUTPUT_V2_KEYMODE_SINCE_VERSION) { zdwl_ipc_output_v2_send_keymode(ipc_output->resource, keymode.mode); } - if (wl_resource_get_version(ipc_output->resource) >= - ZDWL_IPC_OUTPUT_V2_SCALEFACTOR_SINCE_VERSION) { + // 发送缩放因子 + if ((event_mask & PRINT_SCALEFACTOR) && + wl_resource_get_version(ipc_output->resource) >= + ZDWL_IPC_OUTPUT_V2_SCALEFACTOR_SINCE_VERSION) { zdwl_ipc_output_v2_send_scalefactor(ipc_output->resource, monitor->wlr_output->scale * 100); } - zdwl_ipc_output_v2_send_frame(ipc_output->resource); + // 发送帧结束标记 + if (event_mask & PRINT_FRAME) { + zdwl_ipc_output_v2_send_frame(ipc_output->resource); + } } void dwl_ipc_output_set_client_tags(struct wl_client *client, @@ -240,7 +316,7 @@ void dwl_ipc_output_set_client_tags(struct wl_client *client, if (selmon == monitor) focusclient(focustop(monitor), 1); arrange(selmon, false); - printstatus(); + printstatus(PRINT_ALL); } void dwl_ipc_output_set_layout(struct wl_client *client, @@ -260,7 +336,7 @@ void dwl_ipc_output_set_layout(struct wl_client *client, monitor->pertag->ltidxs[monitor->pertag->curtag] = &layouts[index]; clear_fullscreen_and_maximized_state(monitor); arrange(monitor, false); - printstatus(); + printstatus(PRINT_ALL); } void dwl_ipc_output_set_tags(struct wl_client *client, diff --git a/src/mango.c b/src/mango.c index 62656dbc..1a1ea665 100644 --- a/src/mango.c +++ b/src/mango.c @@ -181,6 +181,28 @@ enum seat_config_shortcuts_inhibit { SHORTCUTS_INHIBIT_ENABLE, }; +// 事件掩码枚举 +enum print_event_type { + PRINT_ACTIVE = 1 << 0, + PRINT_TAG = 1 << 1, + PRINT_LAYOUT = 1 << 2, + PRINT_TITLE = 1 << 3, + PRINT_APPID = 1 << 4, + PRINT_LAYOUT_SYMBOL = 1 << 5, + PRINT_FULLSCREEN = 1 << 6, + PRINT_FLOATING = 1 << 7, + PRINT_X = 1 << 8, + PRINT_Y = 1 << 9, + PRINT_WIDTH = 1 << 10, + PRINT_HEIGHT = 1 << 11, + PRINT_LAST_LAYER = 1 << 12, + PRINT_KB_LAYOUT = 1 << 13, + PRINT_KEYMODE = 1 << 14, + PRINT_SCALEFACTOR = 1 << 15, + PRINT_FRAME = 1 << 16, + PRINT_ALL = (1 << 17) - 1 // 所有位都设为1 +}; + typedef struct Pertag Pertag; typedef struct Monitor Monitor; typedef struct Client Client; @@ -612,7 +634,7 @@ static void outputmgrapplyortest(struct wlr_output_configuration_v1 *config, static void outputmgrtest(struct wl_listener *listener, void *data); static void pointerfocus(Client *c, struct wlr_surface *surface, double sx, double sy, unsigned int time); -static void printstatus(void); +static void printstatus(unsigned int event_mask); static void quitsignal(int signo); static void powermgrsetmode(struct wl_listener *listener, void *data); static void rendermon(struct wl_listener *listener, void *data); @@ -2148,7 +2170,7 @@ void closemon(Monitor *m) { } if (selmon) { focusclient(focustop(selmon), 1); - printstatus(); + printstatus(PRINT_ALL); } } @@ -2782,7 +2804,7 @@ void createmon(struct wl_listener *listener, void *data) { add_workspace_by_tag(i, m); } - printstatus(); + printstatus(PRINT_ALL); } void // fix for 0.5 @@ -3238,7 +3260,7 @@ void focusclient(Client *c, int lift) { client_activate_surface(old_keyboard_focus_surface, 0); } } - printstatus(); + printstatus(PRINT_ALL); if (!c) { @@ -3788,7 +3810,7 @@ mapnotify(struct wl_listener *listener, void *data) { // make sure the animation is open type c->is_pending_open_animation = true; resize(c, c->geom, 0); - printstatus(); + printstatus(PRINT_ALL); } void maximizenotify(struct wl_listener *listener, void *data) { @@ -4143,8 +4165,10 @@ void pointerfocus(Client *c, struct wlr_surface *surface, double sx, double sy, wlr_seat_pointer_notify_motion(seat, time, sx, sy); } -void printstatus(void) { - wl_signal_emit(&print_status_manager->print_status, NULL); +// 修改printstatus函数,接受掩码参数 +void printstatus(unsigned int event_mask) { + wl_signal_emit(&print_status_manager->print_status, + (void *)(uintptr_t)event_mask); } void powermgrsetmode(struct wl_listener *listener, void *data) { @@ -4405,7 +4429,7 @@ run(char *startup_cmd) { if (fd_set_nonblock(STDOUT_FILENO) < 0) close(STDOUT_FILENO); - printstatus(); + printstatus(PRINT_ALL); /* At this point the outputs are initialized, choose initial selmon * based on cursor position, and set default cursor image */ @@ -4540,7 +4564,7 @@ setfloating(Client *c, int floating) { arrange(c->mon, false); setborder_color(c); - printstatus(); + printstatus(PRINT_ALL); } void reset_maximizescreen_size(Client *c) { @@ -4880,20 +4904,29 @@ struct mango_print_status_manager *mango_print_status_manager_create() { return manager; } +// 修改信号处理函数,接收掩码参数 void handle_print_status(struct wl_listener *listener, void *data) { struct mango_print_status_manager *manager = wl_container_of(listener, manager, print_status); - // struct wlr_print_status *status = data; + + uint32_t event_mask = (uintptr_t)data; + // 如果传入的是NULL(旧代码)或0,使用默认的所有事件 + if (!event_mask) { + event_mask = PRINT_ALL; + } + Monitor *m = NULL; wl_list_for_each(m, &mons, link) { if (!m->wlr_output->enabled) { continue; } - // Update workspace active states - dwl_ext_workspace_printstatus(m); + // 更新workspace状态(根据掩码决定是否更新) + if (event_mask & PRINT_TAG || event_mask & PRINT_ACTIVE) { + dwl_ext_workspace_printstatus(m); + } - // Update IPC output status - dwl_ipc_output_printstatus(m); + // 更新IPC输出状态(传入掩码) + dwl_ipc_output_printstatus(m, event_mask); } } @@ -5230,7 +5263,7 @@ void tag_client(const Arg *arg, Client *target_client) { } focusclient(target_client, 1); - printstatus(); + printstatus(PRINT_ALL); } void overview(Monitor *m) { grid(m); } @@ -5438,7 +5471,7 @@ void unmapnotify(struct wl_listener *listener, void *data) { } wlr_scene_node_destroy(&c->scene->node); - printstatus(); + printstatus(PRINT_ALL); motionnotify(0, NULL, 0, 0, 0, 0); } @@ -5586,7 +5619,7 @@ void updatetitle(struct wl_listener *listener, void *data) { if (title && c->foreign_toplevel) wlr_foreign_toplevel_handle_v1_set_title(c->foreign_toplevel, title); if (c == focustop(c->mon)) - printstatus(); + printstatus(PRINT_TITLE); } void // 17 fix to 0.5 @@ -5606,7 +5639,7 @@ urgent(struct wl_listener *listener, void *data) { c->isurgent = 1; if (client_surface(c)->mapped) setborder_color(c); - printstatus(); + printstatus(PRINT_ALL); } } @@ -5661,7 +5694,7 @@ toggleseltags: if (changefocus) focusclient(focustop(m), 1); arrange(m, want_animation); - printstatus(); + printstatus(PRINT_ALL); } void view(const Arg *arg, bool want_animation) { @@ -5804,7 +5837,7 @@ void activatex11(struct wl_listener *listener, void *data) { arrange(c->mon, false); } - printstatus(); + printstatus(PRINT_ALL); } void configurex11(struct wl_listener *listener, void *data) { @@ -5876,7 +5909,7 @@ void sethints(struct wl_listener *listener, void *data) { return; c->isurgent = xcb_icccm_wm_hints_get_urgency(c->surface.xwayland->hints); - printstatus(); + printstatus(PRINT_ALL); if (c->isurgent && surface && surface->mapped) setborder_color(c); From b9952f03b53da2e7a64dd966404fd0b431dde1de Mon Sep 17 00:00:00 2001 From: DreamMaoMao <2523610504@qq.com> Date: Tue, 2 Dec 2025 16:57:24 +0800 Subject: [PATCH 48/70] opt: change unsigned int to uint32_t --- mmsg/mmsg.c | 4 +- src/animation/client.h | 40 ++++--- src/animation/common.h | 16 +-- src/animation/layer.h | 38 +++---- src/client/client.h | 16 +-- src/common/util.c | 7 +- src/common/util.h | 4 +- src/config/parse_config.h | 66 ++++++------ src/config/preset.h | 48 ++++----- src/dispatch/bind_define.h | 46 ++++---- src/ext-protocol/dwl-ipc.h | 34 +++--- src/ext-protocol/ext-workspace.h | 12 +-- src/ext-protocol/foreign-toplevel.h | 2 +- src/fetch/client.h | 2 +- src/fetch/common.h | 12 +-- src/fetch/monitor.h | 12 +-- src/layout/arrange.h | 12 +-- src/layout/horizontal.h | 71 ++++++------- src/layout/vertical.h | 42 ++++---- src/mango.c | 159 ++++++++++++++-------------- 20 files changed, 314 insertions(+), 329 deletions(-) diff --git a/mmsg/mmsg.c b/mmsg/mmsg.c index 6f350ed0..2bbe870e 100644 --- a/mmsg/mmsg.c +++ b/mmsg/mmsg.c @@ -86,7 +86,7 @@ static void noop_description(void *data, struct wl_output *wl_output, const char *description) {} // 将 n 转换为 9 位二进制字符串,结果存入 buf(至少长度 10) -void bin_str_9bits(char *buf, unsigned int n) { +void bin_str_9bits(char *buf, uint32_t n) { for (int i = 8; i >= 0; i--) { *buf++ = ((n >> i) & 1) ? '1' : '0'; } @@ -268,7 +268,7 @@ static void dwl_ipc_output_kb_layout(void *data, static void dwl_ipc_output_scalefactor(void *data, struct zdwl_ipc_output_v2 *dwl_ipc_output, - const unsigned int scalefactor) { + const uint32_t scalefactor) { if (!Aflag) return; char *output_name = data; diff --git a/src/animation/client.h b/src/animation/client.h index d26265bb..67f4c10f 100644 --- a/src/animation/client.h +++ b/src/animation/client.h @@ -1,4 +1,4 @@ -void client_actual_size(Client *c, unsigned int *width, unsigned int *height) { +void client_actual_size(Client *c, uint32_t *width, uint32_t *height) { *width = c->animation.current.width - c->bw; *height = c->animation.current.height - c->bw; @@ -183,8 +183,8 @@ void scene_buffer_apply_effect(struct wlr_scene_buffer *buffer, int sx, int sy, if (buffer_data->should_scale) { - unsigned int surface_width = surface->current.width; - unsigned int surface_height = surface->current.height; + uint32_t surface_width = surface->current.width; + uint32_t surface_height = surface->current.height; surface_width = buffer_data->width_scale < 1 ? surface_width @@ -270,7 +270,7 @@ void client_draw_shadow(Client *c) { ? CORNER_LOCATION_NONE : CORNER_LOCATION_ALL; - unsigned int bwoffset = c->bw != 0 && hit_no_border ? c->bw : 0; + uint32_t bwoffset = c->bw != 0 && hit_no_border ? c->bw : 0; uint32_t width, height; client_actual_size(c, &width, &height); @@ -546,7 +546,7 @@ void client_apply_clip(Client *c, float factor) { } // 获取窗口动画实时位置矩形 - unsigned int width, height; + uint32_t width, height; client_actual_size(c, &width, &height); // 计算出除了边框的窗口实际剪切大小 @@ -630,17 +630,16 @@ void fadeout_client_animation_next_tick(Client *c) { int type = c->animation.action = c->animation.action; double factor = find_animation_curve_at(animation_passed, type); - unsigned int width = - c->animation.initial.width + - (c->current.width - c->animation.initial.width) * factor; - unsigned int height = + uint32_t width = c->animation.initial.width + + (c->current.width - c->animation.initial.width) * factor; + uint32_t height = c->animation.initial.height + (c->current.height - c->animation.initial.height) * factor; - unsigned int x = c->animation.initial.x + - (c->current.x - c->animation.initial.x) * factor; - unsigned int y = c->animation.initial.y + - (c->current.y - c->animation.initial.y) * factor; + uint32_t x = c->animation.initial.x + + (c->current.x - c->animation.initial.x) * factor; + uint32_t y = c->animation.initial.y + + (c->current.y - c->animation.initial.y) * factor; wlr_scene_node_set_position(&c->scene->node, x, y); @@ -696,17 +695,16 @@ void client_animation_next_tick(Client *c) { double sx = 0, sy = 0; struct wlr_surface *surface = NULL; - unsigned int width = - c->animation.initial.width + - (c->current.width - c->animation.initial.width) * factor; - unsigned int height = + uint32_t width = c->animation.initial.width + + (c->current.width - c->animation.initial.width) * factor; + uint32_t height = c->animation.initial.height + (c->current.height - c->animation.initial.height) * factor; - unsigned int x = c->animation.initial.x + - (c->current.x - c->animation.initial.x) * factor; - unsigned int y = c->animation.initial.y + - (c->current.y - c->animation.initial.y) * factor; + uint32_t x = c->animation.initial.x + + (c->current.x - c->animation.initial.x) * factor; + uint32_t y = c->animation.initial.y + + (c->current.y - c->animation.initial.y) * factor; wlr_scene_node_set_position(&c->scene->node, x, y); c->animation.current = (struct wlr_box){ diff --git a/src/animation/common.h b/src/animation/common.h index 06ffe1ab..2ff6744a 100644 --- a/src/animation/common.h +++ b/src/animation/common.h @@ -33,33 +33,33 @@ void init_baked_points(void) { baked_points_focus = calloc(BAKED_POINTS_COUNT, sizeof(*baked_points_focus)); - for (unsigned int i = 0; i < BAKED_POINTS_COUNT; i++) { + for (uint32_t i = 0; i < BAKED_POINTS_COUNT; i++) { baked_points_move[i] = calculate_animation_curve_at( (double)i / (BAKED_POINTS_COUNT - 1), MOVE); } - for (unsigned int i = 0; i < BAKED_POINTS_COUNT; i++) { + for (uint32_t i = 0; i < BAKED_POINTS_COUNT; i++) { baked_points_open[i] = calculate_animation_curve_at( (double)i / (BAKED_POINTS_COUNT - 1), OPEN); } - for (unsigned int i = 0; i < BAKED_POINTS_COUNT; i++) { + for (uint32_t i = 0; i < BAKED_POINTS_COUNT; i++) { baked_points_tag[i] = calculate_animation_curve_at( (double)i / (BAKED_POINTS_COUNT - 1), TAG); } - for (unsigned int i = 0; i < BAKED_POINTS_COUNT; i++) { + for (uint32_t i = 0; i < BAKED_POINTS_COUNT; i++) { baked_points_close[i] = calculate_animation_curve_at( (double)i / (BAKED_POINTS_COUNT - 1), CLOSE); } - for (unsigned int i = 0; i < BAKED_POINTS_COUNT; i++) { + for (uint32_t i = 0; i < BAKED_POINTS_COUNT; i++) { baked_points_focus[i] = calculate_animation_curve_at( (double)i / (BAKED_POINTS_COUNT - 1), FOCUS); } } double find_animation_curve_at(double t, int type) { - unsigned int down = 0; - unsigned int up = BAKED_POINTS_COUNT - 1; + uint32_t down = 0; + uint32_t up = BAKED_POINTS_COUNT - 1; - unsigned int middle = (up + down) / 2; + uint32_t middle = (up + down) / 2; struct dvec2 *baked_points; if (type == MOVE) { baked_points = baked_points_move; diff --git a/src/animation/layer.h b/src/animation/layer.h index 48ceb211..e36ddd10 100644 --- a/src/animation/layer.h +++ b/src/animation/layer.h @@ -1,5 +1,4 @@ -void layer_actual_size(LayerSurface *l, unsigned int *width, - unsigned int *height) { +void layer_actual_size(LayerSurface *l, uint32_t *width, uint32_t *height) { struct wlr_box box; if (l->animation.running) { @@ -213,9 +212,8 @@ void layer_scene_buffer_apply_effect(struct wlr_scene_buffer *buffer, int sx, struct wlr_surface *surface = scene_surface->surface; - unsigned int surface_width = - surface->current.width * buffer_data->width_scale; - unsigned int surface_height = + uint32_t surface_width = surface->current.width * buffer_data->width_scale; + uint32_t surface_height = surface->current.height * buffer_data->height_scale; if (surface_height > 0 && surface_width > 0) { @@ -245,17 +243,16 @@ void fadeout_layer_animation_next_tick(LayerSurface *l) { int type = l->animation.action = l->animation.action; double factor = find_animation_curve_at(animation_passed, type); - unsigned int width = - l->animation.initial.width + - (l->current.width - l->animation.initial.width) * factor; - unsigned int height = + uint32_t width = l->animation.initial.width + + (l->current.width - l->animation.initial.width) * factor; + uint32_t height = l->animation.initial.height + (l->current.height - l->animation.initial.height) * factor; - unsigned int x = l->animation.initial.x + - (l->current.x - l->animation.initial.x) * factor; - unsigned int y = l->animation.initial.y + - (l->current.y - l->animation.initial.y) * factor; + uint32_t x = l->animation.initial.x + + (l->current.x - l->animation.initial.x) * factor; + uint32_t y = l->animation.initial.y + + (l->current.y - l->animation.initial.y) * factor; wlr_scene_node_set_position(&l->scene->node, x, y); @@ -310,17 +307,16 @@ void layer_animation_next_tick(LayerSurface *l) { int type = l->animation.action == NONE ? MOVE : l->animation.action; double factor = find_animation_curve_at(animation_passed, type); - unsigned int width = - l->animation.initial.width + - (l->current.width - l->animation.initial.width) * factor; - unsigned int height = + uint32_t width = l->animation.initial.width + + (l->current.width - l->animation.initial.width) * factor; + uint32_t height = l->animation.initial.height + (l->current.height - l->animation.initial.height) * factor; - unsigned int x = l->animation.initial.x + - (l->current.x - l->animation.initial.x) * factor; - unsigned int y = l->animation.initial.y + - (l->current.y - l->animation.initial.y) * factor; + uint32_t x = l->animation.initial.x + + (l->current.x - l->animation.initial.x) * factor; + uint32_t y = l->animation.initial.y + + (l->current.y - l->animation.initial.y) * factor; double opacity = MIN(fadein_begin_opacity + animation_passed * (1.0 - fadein_begin_opacity), diff --git a/src/client/client.h b/src/client/client.h index 06f629de..10ecfdf7 100644 --- a/src/client/client.h +++ b/src/client/client.h @@ -526,16 +526,16 @@ static inline void client_set_size_bound(Client *c) { if (!size_hints) return; - if ((unsigned int)c->geom.width - 2 * c->bw < size_hints->min_width && + if ((uint32_t)c->geom.width - 2 * c->bw < size_hints->min_width && size_hints->min_width > 0) c->geom.width = size_hints->min_width + 2 * c->bw; - if ((unsigned int)c->geom.height - 2 * c->bw < size_hints->min_height && + if ((uint32_t)c->geom.height - 2 * c->bw < size_hints->min_height && size_hints->min_height > 0) c->geom.height = size_hints->min_height + 2 * c->bw; - if ((unsigned int)c->geom.width - 2 * c->bw > size_hints->max_width && + if ((uint32_t)c->geom.width - 2 * c->bw > size_hints->max_width && size_hints->max_width > 0) c->geom.width = size_hints->max_width + 2 * c->bw; - if ((unsigned int)c->geom.height - 2 * c->bw > size_hints->max_height && + if ((uint32_t)c->geom.height - 2 * c->bw > size_hints->max_height && size_hints->max_height > 0) c->geom.height = size_hints->max_height + 2 * c->bw; return; @@ -544,19 +544,19 @@ static inline void client_set_size_bound(Client *c) { toplevel = c->surface.xdg->toplevel; state = toplevel->current; - if ((unsigned int)c->geom.width - 2 * c->bw < state.min_width && + if ((uint32_t)c->geom.width - 2 * c->bw < state.min_width && state.min_width > 0) { c->geom.width = state.min_width + 2 * c->bw; } - if ((unsigned int)c->geom.height - 2 * c->bw < state.min_height && + if ((uint32_t)c->geom.height - 2 * c->bw < state.min_height && state.min_height > 0) { c->geom.height = state.min_height + 2 * c->bw; } - if ((unsigned int)c->geom.width - 2 * c->bw > state.max_width && + if ((uint32_t)c->geom.width - 2 * c->bw > state.max_width && state.max_width > 0) { c->geom.width = state.max_width + 2 * c->bw; } - if ((unsigned int)c->geom.height - 2 * c->bw > state.max_height && + if ((uint32_t)c->geom.height - 2 * c->bw > state.max_height && state.max_height > 0) { c->geom.height = state.max_height + 2 * c->bw; } diff --git a/src/common/util.c b/src/common/util.c index 6eadbc67..79972054 100644 --- a/src/common/util.c +++ b/src/common/util.c @@ -82,14 +82,13 @@ void wl_list_append(struct wl_list *list, struct wl_list *object) { wl_list_insert(list->prev, object); } -unsigned int get_now_in_ms(void) { +uint32_t get_now_in_ms(void) { struct timespec now; clock_gettime(CLOCK_MONOTONIC, &now); return timespec_to_ms(&now); } -unsigned int timespec_to_ms(struct timespec *ts) { - return (unsigned int)ts->tv_sec * 1000 + - (unsigned int)ts->tv_nsec / 1000000; +uint32_t timespec_to_ms(struct timespec *ts) { + return (uint32_t)ts->tv_sec * 1000 + (uint32_t)ts->tv_nsec / 1000000; } diff --git a/src/common/util.h b/src/common/util.h index 3a0f6dae..2718eae8 100644 --- a/src/common/util.h +++ b/src/common/util.h @@ -6,5 +6,5 @@ void *ecalloc(size_t nmemb, size_t size); int fd_set_nonblock(int fd); int regex_match(const char *pattern_mb, const char *str_mb); void wl_list_append(struct wl_list *list, struct wl_list *object); -unsigned int get_now_in_ms(void); -unsigned int timespec_to_ms(struct timespec *ts); \ No newline at end of file +uint32_t get_now_in_ms(void); +uint32_t timespec_to_ms(struct timespec *ts); \ No newline at end of file diff --git a/src/config/parse_config.h b/src/config/parse_config.h index afc9acb8..7c76c5e0 100644 --- a/src/config/parse_config.h +++ b/src/config/parse_config.h @@ -52,7 +52,7 @@ typedef struct { typedef struct { const char *id; const char *title; - unsigned int tags; + uint32_t tags; int isfloating; int isfullscreen; float scroller_proportion; @@ -124,29 +124,29 @@ KeyBinding default_key_bindings[] = {CHVT(1), CHVT(2), CHVT(3), CHVT(4), CHVT(9), CHVT(10), CHVT(11), CHVT(12)}; typedef struct { - unsigned int mod; - unsigned int button; + uint32_t mod; + uint32_t button; int (*func)(const Arg *); Arg arg; } MouseBinding; typedef struct { - unsigned int mod; - unsigned int dir; + uint32_t mod; + uint32_t dir; int (*func)(const Arg *); Arg arg; } AxisBinding; typedef struct { - unsigned int fold; + uint32_t fold; int (*func)(const Arg *); Arg arg; } SwitchBinding; typedef struct { - unsigned int mod; - unsigned int motion; - unsigned int fingers_count; + uint32_t mod; + uint32_t motion; + uint32_t fingers_count; int (*func)(const Arg *); Arg arg; } GestureBinding; @@ -210,7 +210,7 @@ typedef struct { int snap_distance; int enable_floating_snap; int drag_tile_to_tile; - unsigned int swipe_min_threshold; + uint32_t swipe_min_threshold; float focused_opacity; float unfocused_opacity; float *scroller_proportion_preset; @@ -219,21 +219,21 @@ typedef struct { char **circle_layout; int circle_layout_count; - unsigned int new_is_master; + uint32_t new_is_master; float default_mfact; - unsigned int default_nmaster; + uint32_t default_nmaster; int center_master_overspread; int center_when_single_stack; - unsigned int hotarea_size; - unsigned int enable_hotarea; - unsigned int ov_tab_mode; + uint32_t hotarea_size; + uint32_t enable_hotarea; + uint32_t ov_tab_mode; int overviewgappi; int overviewgappo; - unsigned int cursor_hide_timeout; + uint32_t cursor_hide_timeout; - unsigned int axis_bind_apply_timeout; - unsigned int focus_on_activate; + uint32_t axis_bind_apply_timeout; + uint32_t focus_on_activate; int inhibit_regardless_of_visibility; int sloppyfocus; int warpcursor; @@ -241,7 +241,7 @@ typedef struct { /* keyboard */ int repeat_rate; int repeat_delay; - unsigned int numlockon; + uint32_t numlockon; /* Trackpad */ int disable_trackpad; @@ -253,13 +253,13 @@ typedef struct { int disable_while_typing; int left_handed; int middle_button_emulation; - unsigned int accel_profile; + uint32_t accel_profile; double accel_speed; - unsigned int scroll_method; - unsigned int scroll_button; - unsigned int click_method; - unsigned int send_events_mode; - unsigned int button_map; + uint32_t scroll_method; + uint32_t scroll_button; + uint32_t click_method; + uint32_t send_events_mode; + uint32_t button_map; int blur; int blur_layer; @@ -269,18 +269,18 @@ typedef struct { int shadows; int shadow_only_floating; int layer_shadows; - unsigned int shadows_size; + uint32_t shadows_size; float shadows_blur; int shadows_position_x; int shadows_position_y; float shadowscolor[4]; int smartgaps; - unsigned int gappih; - unsigned int gappiv; - unsigned int gappoh; - unsigned int gappov; - unsigned int borderpx; + uint32_t gappih; + uint32_t gappiv; + uint32_t gappoh; + uint32_t gappov; + uint32_t borderpx; float scratchpad_width_ratio; float scratchpad_height_ratio; float rootcolor[4]; @@ -331,7 +331,7 @@ typedef struct { int exec_once_count; char *cursor_theme; - unsigned int cursor_size; + uint32_t cursor_size; int single_scratchpad; int xwayland_persistence; @@ -789,7 +789,7 @@ void convert_hex_to_rgba(float *color, unsigned long int hex) { color[3] = (hex & 0xFF) / 255.0f; } -unsigned int parse_num_type(char *str) { +uint32_t parse_num_type(char *str) { switch (str[0]) { case '-': return NUM_TYPE_MINUS; diff --git a/src/config/preset.h b/src/config/preset.h index 4032a757..ed743a83 100644 --- a/src/config/preset.h +++ b/src/config/preset.h @@ -33,27 +33,27 @@ double animation_curve_close[4] = {0.46, 1.0, 0.29, 0.99}; // 动画曲线 double animation_curve_focus[4] = {0.46, 1.0, 0.29, 0.99}; // 动画曲线 /* appearance */ -unsigned int axis_bind_apply_timeout = 100; // 滚轮绑定动作的触发的时间间隔 -unsigned int focus_on_activate = 1; // 收到窗口激活请求是否自动跳转聚焦 -unsigned int new_is_master = 1; // 新窗口是否插在头部 -double default_mfact = 0.55f; // master 窗口比例 -unsigned int default_nmaster = 1; // 默认master数量 -int center_master_overspread = 0; // 中心master时是否铺满 -int center_when_single_stack = 1; // 单个stack时是否居中 +uint32_t axis_bind_apply_timeout = 100; // 滚轮绑定动作的触发的时间间隔 +uint32_t focus_on_activate = 1; // 收到窗口激活请求是否自动跳转聚焦 +uint32_t new_is_master = 1; // 新窗口是否插在头部 +double default_mfact = 0.55f; // master 窗口比例 +uint32_t default_nmaster = 1; // 默认master数量 +int center_master_overspread = 0; // 中心master时是否铺满 +int center_when_single_stack = 1; // 单个stack时是否居中 /* logging */ int log_level = WLR_ERROR; -unsigned int numlockon = 0; // 是否打开右边小键盘 -unsigned int capslock = 0; // 是否启用快捷键 +uint32_t numlockon = 0; // 是否打开右边小键盘 +uint32_t capslock = 0; // 是否启用快捷键 -unsigned int ov_tab_mode = 0; // alt tab切换模式 -unsigned int hotarea_size = 10; // 热区大小,10x10 -unsigned int enable_hotarea = 1; // 是否启用鼠标热区 -int smartgaps = 0; /* 1 means no outer gap when there is only one window */ -int sloppyfocus = 1; /* focus follows mouse */ -unsigned int gappih = 5; /* horiz inner gap between windows */ -unsigned int gappiv = 5; /* vert inner gap between windows */ -unsigned int gappoh = 10; /* horiz outer gap between windows and screen edge */ -unsigned int gappov = 10; /* vert outer gap between windows and screen edge */ +uint32_t ov_tab_mode = 0; // alt tab切换模式 +uint32_t hotarea_size = 10; // 热区大小,10x10 +uint32_t enable_hotarea = 1; // 是否启用鼠标热区 +int smartgaps = 0; /* 1 means no outer gap when there is only one window */ +int sloppyfocus = 1; /* focus follows mouse */ +uint32_t gappih = 5; /* horiz inner gap between windows */ +uint32_t gappiv = 5; /* vert inner gap between windows */ +uint32_t gappoh = 10; /* horiz outer gap between windows and screen edge */ +uint32_t gappov = 10; /* vert outer gap between windows and screen edge */ float scratchpad_width_ratio = 0.8; float scratchpad_height_ratio = 0.9; @@ -73,15 +73,15 @@ int no_radius_when_single = 0; int snap_distance = 30; int enable_floating_snap = 0; int drag_tile_to_tile = 0; -unsigned int cursor_size = 24; -unsigned int cursor_hide_timeout = 0; +uint32_t cursor_size = 24; +uint32_t cursor_hide_timeout = 0; -unsigned int swipe_min_threshold = 1; +uint32_t swipe_min_threshold = 1; int inhibit_regardless_of_visibility = 0; /* 1 means idle inhibitors will disable idle tracking even if it's surface isn't visible */ -unsigned int borderpx = 4; /* border pixel of windows */ +uint32_t borderpx = 4; /* border pixel of windows */ float rootcolor[] = COLOR(0x323232ff); float bordercolor[] = COLOR(0x444444ff); float focuscolor[] = COLOR(0xc66b25ff); @@ -166,7 +166,7 @@ LIBINPUT_CONFIG_SCROLL_EDGE LIBINPUT_CONFIG_SCROLL_ON_BUTTON_DOWN */ enum libinput_config_scroll_method scroll_method = LIBINPUT_CONFIG_SCROLL_2FG; -unsigned int scroll_button = 274; +uint32_t scroll_button = 274; /* You can choose between: LIBINPUT_CONFIG_CLICK_METHOD_NONE @@ -224,7 +224,7 @@ float blur_params_saturation = 1.2; int shadows = 0; int shadow_only_floating = 1; int layer_shadows = 0; -unsigned int shadows_size = 10; +uint32_t shadows_size = 10; double shadows_blur = 15; int shadows_position_x = 0; int shadows_position_y = 0; diff --git a/src/dispatch/bind_define.h b/src/dispatch/bind_define.h index a782d4f1..1dc29daf 100644 --- a/src/dispatch/bind_define.h +++ b/src/dispatch/bind_define.h @@ -1,6 +1,6 @@ int bind_to_view(const Arg *arg) { - unsigned int target = arg->ui; + uint32_t target = arg->ui; if (view_current_to_back && selmon->pertag->curtag && (target & TAGMASK) == (selmon->tagset[selmon->seltags])) { @@ -130,7 +130,7 @@ int focuslast(const Arg *arg) { Client *c = NULL; Client *tc = NULL; bool begin = false; - unsigned int target = 0; + uint32_t target = 0; wl_list_for_each(c, &fstack, flink) { if (c->iskilling || c->isminimized || c->isunglobal || @@ -531,7 +531,7 @@ int set_proportion(const Arg *arg) { return 0; if (selmon->sel) { - unsigned int max_client_width = + uint32_t max_client_width = selmon->w.width - 2 * scroller_structs - gappih; selmon->sel->scroller_proportion = arg->f; selmon->sel->geom.width = max_client_width * arg->f; @@ -837,9 +837,9 @@ int switch_keyboard_layout(const Arg *arg) { xkb_layout_index_t next = (current + 1) % num_layouts; // 6. 应用新 keymap - unsigned int depressed = keyboard->modifiers.depressed; - unsigned int latched = keyboard->modifiers.latched; - unsigned int locked = keyboard->modifiers.locked; + uint32_t depressed = keyboard->modifiers.depressed; + uint32_t latched = keyboard->modifiers.latched; + uint32_t locked = keyboard->modifiers.locked; wlr_keyboard_set_keymap(keyboard, keyboard->keymap); wlr_keyboard_notify_modifiers(keyboard, depressed, latched, locked, next); @@ -874,7 +874,7 @@ int switch_layout(const Arg *arg) { int jk, ji; char *target_layout_name = NULL; - unsigned int len; + uint32_t len; if (config.circle_layout_count != 0) { for (jk = 0; jk < config.circle_layout_count; jk++) { @@ -959,7 +959,7 @@ int switch_proportion_preset(const Arg *arg) { target_proportion = config.scroller_proportion_preset[0]; } - unsigned int max_client_width = + uint32_t max_client_width = selmon->w.width - 2 * scroller_structs - gappih; selmon->sel->scroller_proportion = target_proportion; selmon->sel->geom.width = max_client_width * target_proportion; @@ -1001,8 +1001,8 @@ int tagmon(const Arg *arg) { if (!m || !m->wlr_output->enabled) return 0; - unsigned int newtags = arg->ui ? arg->ui : arg->i2 ? c->tags : 0; - unsigned int target; + uint32_t newtags = arg->ui ? arg->ui : arg->i2 ? c->tags : 0; + uint32_t target; if (c->mon == m) { view(&(Arg){.ui = newtags}, true); @@ -1242,7 +1242,7 @@ int toggleoverlay(const Arg *arg) { } int toggletag(const Arg *arg) { - unsigned int newtags; + uint32_t newtags; Client *sel = focustop(selmon); if (!sel) return 0; @@ -1265,8 +1265,8 @@ int toggletag(const Arg *arg) { } int toggleview(const Arg *arg) { - unsigned int newtagset; - unsigned int target; + uint32_t newtagset; + uint32_t target; target = arg->ui == 0 ? ~0 & TAGMASK : arg->ui; @@ -1283,7 +1283,7 @@ int toggleview(const Arg *arg) { } int viewtoleft(const Arg *arg) { - unsigned int target = selmon->tagset[selmon->seltags]; + uint32_t target = selmon->tagset[selmon->seltags]; if (selmon->isoverview || selmon->pertag->curtag == 0) { return 0; @@ -1306,7 +1306,7 @@ int viewtoright(const Arg *arg) { if (selmon->isoverview || selmon->pertag->curtag == 0) { return 0; } - unsigned int target = selmon->tagset[selmon->seltags]; + uint32_t target = selmon->tagset[selmon->seltags]; target <<= 1; if (!selmon || (target) == selmon->tagset[selmon->seltags]) @@ -1320,9 +1320,8 @@ int viewtoright(const Arg *arg) { } int viewtoleft_have_client(const Arg *arg) { - unsigned int n; - unsigned int current = - get_tags_first_tag_num(selmon->tagset[selmon->seltags]); + uint32_t n; + uint32_t current = get_tags_first_tag_num(selmon->tagset[selmon->seltags]); bool found = false; if (selmon->isoverview) { @@ -1345,9 +1344,8 @@ int viewtoleft_have_client(const Arg *arg) { } int viewtoright_have_client(const Arg *arg) { - unsigned int n; - unsigned int current = - get_tags_first_tag_num(selmon->tagset[selmon->seltags]); + uint32_t n; + uint32_t current = get_tags_first_tag_num(selmon->tagset[selmon->seltags]); bool found = false; if (selmon->isoverview) { @@ -1384,7 +1382,7 @@ int tagcrossmon(const Arg *arg) { } int comboview(const Arg *arg) { - unsigned int newtags = arg->ui & TAGMASK; + uint32_t newtags = arg->ui & TAGMASK; if (!newtags || !selmon) return 0; @@ -1462,8 +1460,8 @@ int toggleoverview(const Arg *arg) { } selmon->isoverview ^= 1; - unsigned int target; - unsigned int visible_client_number = 0; + uint32_t target; + uint32_t visible_client_number = 0; if (selmon->isoverview) { wl_list_for_each(c, &clients, link) if (c && c->mon == selmon && diff --git a/src/ext-protocol/dwl-ipc.h b/src/ext-protocol/dwl-ipc.h index 1d861b91..649c5f3a 100644 --- a/src/ext-protocol/dwl-ipc.h +++ b/src/ext-protocol/dwl-ipc.h @@ -1,12 +1,11 @@ #include "dwl-ipc-unstable-v2-protocol.h" static void dwl_ipc_manager_bind(struct wl_client *client, void *data, - unsigned int version, unsigned int id); + uint32_t version, uint32_t id); static void dwl_ipc_manager_destroy(struct wl_resource *resource); static void dwl_ipc_manager_get_output(struct wl_client *client, struct wl_resource *resource, - unsigned int id, - struct wl_resource *output); + uint32_t id, struct wl_resource *output); static void dwl_ipc_manager_release(struct wl_client *client, struct wl_resource *resource); static void dwl_ipc_output_destroy(struct wl_resource *resource); @@ -15,15 +14,14 @@ static void dwl_ipc_output_printstatus_to(DwlIpcOutput *ipc_output, uint32_t event_mask); static void dwl_ipc_output_set_client_tags(struct wl_client *client, struct wl_resource *resource, - unsigned int and_tags, - unsigned int xor_tags); + uint32_t and_tags, + uint32_t xor_tags); static void dwl_ipc_output_set_layout(struct wl_client *client, struct wl_resource *resource, - unsigned int index); + uint32_t index); static void dwl_ipc_output_set_tags(struct wl_client *client, struct wl_resource *resource, - unsigned int tagmask, - unsigned int toggle_tagset); + uint32_t tagmask, uint32_t toggle_tagset); static void dwl_ipc_output_quit(struct wl_client *client, struct wl_resource *resource); static void dwl_ipc_output_dispatch(struct wl_client *client, @@ -47,7 +45,7 @@ static struct zdwl_ipc_output_v2_interface dwl_output_implementation = { .set_client_tags = dwl_ipc_output_set_client_tags}; void dwl_ipc_manager_bind(struct wl_client *client, void *data, - unsigned int version, unsigned int id) { + uint32_t version, uint32_t id) { struct wl_resource *manager_resource = wl_resource_create(client, &zdwl_ipc_manager_v2_interface, version, id); if (!manager_resource) { @@ -60,7 +58,7 @@ void dwl_ipc_manager_bind(struct wl_client *client, void *data, zdwl_ipc_manager_v2_send_tags(manager_resource, LENGTH(tags)); - for (unsigned int i = 0; i < LENGTH(layouts); i++) + for (uint32_t i = 0; i < LENGTH(layouts); i++) zdwl_ipc_manager_v2_send_layout(manager_resource, layouts[i].symbol); } @@ -69,7 +67,7 @@ void dwl_ipc_manager_destroy(struct wl_resource *resource) { } void dwl_ipc_manager_get_output(struct wl_client *client, - struct wl_resource *resource, unsigned int id, + struct wl_resource *resource, uint32_t id, struct wl_resource *output) { DwlIpcOutput *ipc_output; struct wlr_output *op = wlr_output_from_resource(output); @@ -292,12 +290,11 @@ void dwl_ipc_output_printstatus_to(DwlIpcOutput *ipc_output, void dwl_ipc_output_set_client_tags(struct wl_client *client, struct wl_resource *resource, - unsigned int and_tags, - unsigned int xor_tags) { + uint32_t and_tags, uint32_t xor_tags) { DwlIpcOutput *ipc_output; Monitor *monitor = NULL; Client *selected_client = NULL; - unsigned int newtags = 0; + uint32_t newtags = 0; ipc_output = wl_resource_get_user_data(resource); if (!ipc_output) @@ -320,8 +317,7 @@ void dwl_ipc_output_set_client_tags(struct wl_client *client, } void dwl_ipc_output_set_layout(struct wl_client *client, - struct wl_resource *resource, - unsigned int index) { + struct wl_resource *resource, uint32_t index) { DwlIpcOutput *ipc_output; Monitor *monitor = NULL; @@ -340,11 +336,11 @@ void dwl_ipc_output_set_layout(struct wl_client *client, } void dwl_ipc_output_set_tags(struct wl_client *client, - struct wl_resource *resource, unsigned int tagmask, - unsigned int toggle_tagset) { + struct wl_resource *resource, uint32_t tagmask, + uint32_t toggle_tagset) { DwlIpcOutput *ipc_output; Monitor *monitor = NULL; - unsigned int newtags = tagmask & TAGMASK; + uint32_t newtags = tagmask & TAGMASK; ipc_output = wl_resource_get_user_data(resource); if (!ipc_output) diff --git a/src/ext-protocol/ext-workspace.h b/src/ext-protocol/ext-workspace.h index 930e6c98..d4e0e514 100644 --- a/src/ext-protocol/ext-workspace.h +++ b/src/ext-protocol/ext-workspace.h @@ -8,7 +8,7 @@ typedef struct Monitor Monitor; struct workspace { struct wl_list link; // Link in global workspaces list - unsigned int tag; // Numeric identifier (1-9, 0=overview) + uint32_t tag; // Numeric identifier (1-9, 0=overview) Monitor *m; // Associated monitor struct wlr_ext_workspace_handle_v1 *ext_workspace; // Protocol object /* Event listeners */ @@ -22,7 +22,7 @@ struct wlr_ext_workspace_manager_v1 *ext_manager; struct wl_list workspaces; void goto_workspace(struct workspace *target) { - unsigned int tag; + uint32_t tag; tag = 1 << (target->tag - 1); if (target->tag == 0) { toggleoverview(&(Arg){.i = -1}); @@ -33,7 +33,7 @@ void goto_workspace(struct workspace *target) { } void toggle_workspace(struct workspace *target) { - unsigned int tag; + uint32_t tag; tag = 1 << (target->tag - 1); if (target->tag == 0) { toggleview(&(Arg){.i = -1}); @@ -69,7 +69,7 @@ static void handle_ext_workspace_deactivate(struct wl_listener *listener, wlr_log(WLR_INFO, "ext deactivating workspace %d", workspace->tag); } -static const char *get_name_from_tag(unsigned int tag) { +static const char *get_name_from_tag(uint32_t tag) { static const char *names[] = {"overview", "1", "2", "3", "4", "5", "6", "7", "8", "9"}; return (tag < sizeof(names) / sizeof(names[0])) ? names[tag] : NULL; @@ -92,7 +92,7 @@ void cleanup_workspaces_by_monitor(Monitor *m) { } } -static void remove_workspace_by_tag(unsigned int tag, Monitor *m) { +static void remove_workspace_by_tag(uint32_t tag, Monitor *m) { struct workspace *workspace, *tmp; wl_list_for_each_safe(workspace, tmp, &workspaces, link) { if (workspace->tag == tag && workspace->m == m) { @@ -127,7 +127,7 @@ static void add_workspace_by_tag(int tag, Monitor *m) { void dwl_ext_workspace_printstatus(Monitor *m) { struct workspace *w; - unsigned int tag_status = 0; + uint32_t tag_status = 0; wl_list_for_each(w, &workspaces, link) { if (w && w->m == m) { diff --git a/src/ext-protocol/foreign-toplevel.h b/src/ext-protocol/foreign-toplevel.h index 0bb649e0..3b819485 100644 --- a/src/ext-protocol/foreign-toplevel.h +++ b/src/ext-protocol/foreign-toplevel.h @@ -4,7 +4,7 @@ static struct wlr_foreign_toplevel_manager_v1 *foreign_toplevel_manager; void handle_foreign_activate_request(struct wl_listener *listener, void *data) { Client *c = wl_container_of(listener, c, foreign_activate_request); - unsigned int target; + uint32_t target; if (c && c->swallowing) return; diff --git a/src/fetch/client.h b/src/fetch/client.h index a9cfed07..ca39ab9e 100644 --- a/src/fetch/client.h +++ b/src/fetch/client.h @@ -70,7 +70,7 @@ setclient_coordinate_center(Client *c, struct wlr_box geom, int offsetx, int len = 0; Monitor *m = c->mon ? c->mon : selmon; - unsigned int cbw = check_hit_no_border(c) ? c->bw : 0; + uint32_t cbw = check_hit_no_border(c) ? c->bw : 0; if (!c->no_force_center) { tempbox.x = m->w.x + (m->w.width - geom.width) / 2; diff --git a/src/fetch/common.h b/src/fetch/common.h index 41dc9944..c86a3fef 100644 --- a/src/fetch/common.h +++ b/src/fetch/common.h @@ -1,5 +1,5 @@ pid_t getparentprocess(pid_t p) { - unsigned int v = 0; + uint32_t v = 0; FILE *f; char buf[256]; @@ -26,7 +26,7 @@ int isdescprocess(pid_t p, pid_t c) { return (int)c; } -char *get_autostart_path(char *autostart_path, unsigned int buf_size) { +char *get_autostart_path(char *autostart_path, uint32_t buf_size) { const char *mangoconfig = getenv("MANGOCONFIG"); if (mangoconfig && mangoconfig[0] != '\0') { @@ -60,10 +60,10 @@ void get_layout_abbr(char *abbr, const char *full_name) { const char *open = strrchr(full_name, '('); const char *close = strrchr(full_name, ')'); if (open && close && close > open) { - unsigned int len = close - open - 1; + uint32_t len = close - open - 1; if (len > 0 && len <= 4) { // 提取并转换为小写 - for (unsigned int j = 0; j < len; j++) { + for (uint32_t j = 0; j < len; j++) { abbr[j] = tolower(open[j + 1]); } abbr[len] = '\0'; @@ -72,8 +72,8 @@ void get_layout_abbr(char *abbr, const char *full_name) { } // 3. 提取前2-3个字母并转换为小写 - unsigned int j = 0; - for (unsigned int i = 0; full_name[i] != '\0' && j < 3; i++) { + uint32_t j = 0; + for (uint32_t i = 0; full_name[i] != '\0' && j < 3; i++) { if (isalpha(full_name[i])) { abbr[j++] = tolower(full_name[i]); } diff --git a/src/fetch/monitor.h b/src/fetch/monitor.h index d55e9ab6..47a5b824 100644 --- a/src/fetch/monitor.h +++ b/src/fetch/monitor.h @@ -26,9 +26,9 @@ bool is_scroller_layout(Monitor *m) { return false; } -unsigned int get_tag_status(unsigned int tag, Monitor *m) { +uint32_t get_tag_status(uint32_t tag, Monitor *m) { Client *c = NULL; - unsigned int status = 0; + uint32_t status = 0; wl_list_for_each(c, &clients, link) { if (c->mon == m && c->tags & 1 << (tag - 1) & TAGMASK) { if (c->isurgent) { @@ -41,8 +41,8 @@ unsigned int get_tag_status(unsigned int tag, Monitor *m) { return status; } -unsigned int get_tags_first_tag_num(unsigned int source_tags) { - unsigned int i, tag; +uint32_t get_tags_first_tag_num(uint32_t source_tags) { + uint32_t i, tag; tag = 0; if (!source_tags) { @@ -63,8 +63,8 @@ unsigned int get_tags_first_tag_num(unsigned int source_tags) { } // 获取tags中最前面的tag的tagmask -unsigned int get_tags_first_tag(unsigned int source_tags) { - unsigned int i, tag; +uint32_t get_tags_first_tag(uint32_t source_tags) { + uint32_t i, tag; tag = 0; if (!source_tags) { diff --git a/src/layout/arrange.h b/src/layout/arrange.h index ba1391e6..3fb25a46 100644 --- a/src/layout/arrange.h +++ b/src/layout/arrange.h @@ -19,7 +19,7 @@ void set_size_per(Monitor *m, Client *c) { } void resize_tile_master_horizontal(Client *grabc, bool isdrag, int offsetx, - int offsety, unsigned int time, int type) { + int offsety, uint32_t time, int type) { Client *tc = NULL; float delta_x, delta_y; Client *next = NULL; @@ -213,7 +213,7 @@ void resize_tile_master_horizontal(Client *grabc, bool isdrag, int offsetx, } void resize_tile_master_vertical(Client *grabc, bool isdrag, int offsetx, - int offsety, unsigned int time, int type) { + int offsety, uint32_t time, int type) { Client *tc = NULL; float delta_x, delta_y; Client *next = NULL; @@ -370,7 +370,7 @@ void resize_tile_master_vertical(Client *grabc, bool isdrag, int offsetx, } void resize_tile_scroller(Client *grabc, bool isdrag, int offsetx, int offsety, - unsigned int time, bool isvertical) { + uint32_t time, bool isvertical) { float delta_x, delta_y; float new_scroller_proportion; @@ -474,7 +474,7 @@ void resize_tile_scroller(Client *grabc, bool isdrag, int offsetx, int offsety, } void resize_tile_client(Client *grabc, bool isdrag, int offsetx, int offsety, - unsigned int time) { + uint32_t time) { if (!grabc || grabc->isfullscreen || grabc->ismaximizescreen) return; @@ -509,8 +509,8 @@ void reset_size_per_mon(Monitor *m, int tile_cilent_num, int stack_num) { Client *c = NULL; int i = 0; - unsigned int stack_index = 0; - unsigned int nmasters = m->pertag->nmasters[m->pertag->curtag]; + uint32_t stack_index = 0; + uint32_t nmasters = m->pertag->nmasters[m->pertag->curtag]; if (m->pertag->ltidxs[m->pertag->curtag]->id != CENTER_TILE) { diff --git a/src/layout/horizontal.h b/src/layout/horizontal.h index 3471fdf7..9a6a5950 100644 --- a/src/layout/horizontal.h +++ b/src/layout/horizontal.h @@ -1,9 +1,9 @@ // 网格布局窗口大小和位置计算 void grid(Monitor *m) { - unsigned int i, n; - unsigned int cx, cy, cw, ch; - unsigned int dx; - unsigned int cols, rows, overcols; + uint32_t i, n; + uint32_t cx, cy, cw, ch; + uint32_t dx; + uint32_t cols, rows, overcols; Client *c = NULL; n = 0; int target_gappo = enablegaps ? m->isoverview ? overviewgappo : gappoh : 0; @@ -121,15 +121,15 @@ void grid(Monitor *m) { } void deck(Monitor *m) { - unsigned int mw, my; + uint32_t 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; + uint32_t cur_gappih = enablegaps ? m->gappih : 0; + uint32_t cur_gappoh = enablegaps ? m->gappoh : 0; + uint32_t cur_gappov = enablegaps ? m->gappov : 0; cur_gappih = smartgaps && m->visible_tiling_clients == 1 ? 0 : cur_gappih; cur_gappoh = smartgaps && m->visible_tiling_clients == 1 ? 0 : cur_gappoh; @@ -192,9 +192,9 @@ void deck(Monitor *m) { void horizontal_scroll_adjust_fullandmax(Client *c, struct wlr_box *target_geom) { Monitor *m = c->mon; - unsigned int cur_gappih = enablegaps ? m->gappih : 0; - unsigned int cur_gappoh = enablegaps ? m->gappoh : 0; - unsigned int cur_gappov = enablegaps ? m->gappov : 0; + uint32_t cur_gappih = enablegaps ? m->gappih : 0; + uint32_t cur_gappoh = enablegaps ? m->gappoh : 0; + uint32_t cur_gappov = enablegaps ? m->gappov : 0; cur_gappih = smartgaps && m->visible_scroll_tiling_clients == 1 ? 0 : cur_gappih; @@ -223,7 +223,7 @@ void horizontal_scroll_adjust_fullandmax(Client *c, // 滚动布局 void scroller(Monitor *m) { - unsigned int i, n, j; + uint32_t i, n, j; float single_proportion = 1.0; Client *c = NULL, *root_client = NULL; @@ -231,9 +231,9 @@ void scroller(Monitor *m) { struct wlr_box target_geom; int focus_client_index = 0; bool need_scroller = false; - unsigned int cur_gappih = enablegaps ? m->gappih : 0; - unsigned int cur_gappoh = enablegaps ? m->gappoh : 0; - unsigned int cur_gappov = enablegaps ? m->gappov : 0; + uint32_t cur_gappih = enablegaps ? m->gappih : 0; + uint32_t cur_gappoh = enablegaps ? m->gappoh : 0; + uint32_t cur_gappov = enablegaps ? m->gappov : 0; cur_gappih = smartgaps && m->visible_scroll_tiling_clients == 1 ? 0 : cur_gappih; @@ -242,8 +242,7 @@ void scroller(Monitor *m) { cur_gappov = smartgaps && m->visible_scroll_tiling_clients == 1 ? 0 : cur_gappov; - unsigned int max_client_width = - m->w.width - 2 * scroller_structs - cur_gappih; + uint32_t max_client_width = m->w.width - 2 * scroller_structs - cur_gappih; n = m->visible_scroll_tiling_clients; @@ -378,7 +377,7 @@ void scroller(Monitor *m) { } void center_tile(Monitor *m) { - unsigned int i, n = 0, h, r, ie = enablegaps, mw, mx, my, oty, ety, tw; + uint32_t i, n = 0, h, r, ie = enablegaps, mw, mx, my, oty, ety, tw; Client *c = NULL; Client *fc = NULL; double mfact = 0; @@ -399,10 +398,10 @@ void center_tile(Monitor *m) { } // 间隙参数处理 - 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; // 外部水平间隙 + uint32_t cur_gappiv = enablegaps ? m->gappiv : 0; // 内部垂直间隙 + uint32_t cur_gappih = enablegaps ? m->gappih : 0; // 内部水平间隙 + uint32_t cur_gappov = enablegaps ? m->gappov : 0; // 外部垂直间隙 + uint32_t cur_gappoh = enablegaps ? m->gappoh : 0; // 外部水平间隙 // 智能间隙处理 cur_gappiv = smartgaps && m->visible_tiling_clients == 1 ? 0 : cur_gappiv; @@ -410,7 +409,7 @@ void center_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; - unsigned int nmasters = m->pertag->nmasters[m->pertag->curtag]; + uint32_t nmasters = m->pertag->nmasters[m->pertag->curtag]; mfact = fc->master_mfact_per > 0.0f ? fc->master_mfact_per : m->pertag->mfacts[m->pertag->curtag]; @@ -489,7 +488,7 @@ void center_tile(Monitor *m) { my += c->geom.height + cur_gappiv * ie; } else { // 堆叠区域窗口 - unsigned int stack_index = i - nmasters; + uint32_t stack_index = i - nmasters; if (n - nmasters == 1) { // 单个堆叠窗口 @@ -587,7 +586,7 @@ void center_tile(Monitor *m) { } void tile(Monitor *m) { - unsigned int i, n = 0, h, r, ie = enablegaps, mw, my, ty; + uint32_t i, n = 0, h, r, ie = enablegaps, mw, my, ty; Client *c = NULL; Client *fc = NULL; double mfact = 0; @@ -601,10 +600,10 @@ void tile(Monitor *m) { if (n == 0) return; - 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; + uint32_t cur_gappiv = enablegaps ? m->gappiv : 0; + uint32_t cur_gappih = enablegaps ? m->gappih : 0; + uint32_t cur_gappov = enablegaps ? m->gappov : 0; + uint32_t 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; @@ -684,7 +683,7 @@ void tile(Monitor *m) { } void right_tile(Monitor *m) { - unsigned int i, n = 0, h, r, ie = enablegaps, mw, my, ty; + uint32_t i, n = 0, h, r, ie = enablegaps, mw, my, ty; Client *c = NULL; Client *fc = NULL; double mfact = 0; @@ -698,10 +697,10 @@ void right_tile(Monitor *m) { if (n == 0) return; - 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; + uint32_t cur_gappiv = enablegaps ? m->gappiv : 0; + uint32_t cur_gappih = enablegaps ? m->gappih : 0; + uint32_t cur_gappov = enablegaps ? m->gappov : 0; + uint32_t 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; @@ -786,8 +785,8 @@ monocle(Monitor *m) { Client *c = NULL; struct wlr_box geom; - unsigned int cur_gappov = enablegaps ? m->gappov : 0; - unsigned int cur_gappoh = enablegaps ? m->gappoh : 0; + uint32_t cur_gappov = enablegaps ? m->gappov : 0; + uint32_t cur_gappoh = enablegaps ? m->gappoh : 0; cur_gappoh = smartgaps && m->visible_tiling_clients == 1 ? 0 : cur_gappoh; cur_gappov = smartgaps && m->visible_tiling_clients == 1 ? 0 : cur_gappov; diff --git a/src/layout/vertical.h b/src/layout/vertical.h index f6aa6b86..5badc72b 100644 --- a/src/layout/vertical.h +++ b/src/layout/vertical.h @@ -1,5 +1,5 @@ void vertical_tile(Monitor *m) { - unsigned int i, n = 0, w, r, ie = enablegaps, mh, mx, tx; + uint32_t i, n = 0, w, r, ie = enablegaps, mh, mx, tx; Client *c = NULL; Client *fc = NULL; double mfact = 0; @@ -13,10 +13,10 @@ void vertical_tile(Monitor *m) { if (n == 0) return; - unsigned int cur_gapih = enablegaps ? m->gappih : 0; - unsigned int cur_gapiv = enablegaps ? m->gappiv : 0; - unsigned int cur_gapoh = enablegaps ? m->gappoh : 0; - unsigned int cur_gapov = enablegaps ? m->gappov : 0; + uint32_t cur_gapih = enablegaps ? m->gappih : 0; + uint32_t cur_gapiv = enablegaps ? m->gappiv : 0; + uint32_t cur_gapoh = enablegaps ? m->gappoh : 0; + uint32_t cur_gapov = enablegaps ? m->gappov : 0; cur_gapih = smartgaps && m->visible_tiling_clients == 1 ? 0 : cur_gapih; cur_gapiv = smartgaps && m->visible_tiling_clients == 1 ? 0 : cur_gapiv; @@ -92,15 +92,15 @@ void vertical_tile(Monitor *m) { } void vertical_deck(Monitor *m) { - unsigned int mh, mx; + uint32_t mh, mx; int i, n = 0; Client *c = NULL; Client *fc = NULL; float mfact; - unsigned int cur_gappiv = enablegaps ? m->gappiv : 0; - unsigned int cur_gappoh = enablegaps ? m->gappoh : 0; - unsigned int cur_gappov = enablegaps ? m->gappov : 0; + uint32_t cur_gappiv = enablegaps ? m->gappiv : 0; + uint32_t cur_gappoh = enablegaps ? m->gappoh : 0; + uint32_t cur_gappov = enablegaps ? m->gappov : 0; cur_gappiv = smartgaps && m->visible_tiling_clients == 1 ? 0 : cur_gappiv; cur_gappoh = smartgaps && m->visible_tiling_clients == 1 ? 0 : cur_gappoh; @@ -157,9 +157,9 @@ void vertical_deck(Monitor *m) { void vertical_scroll_adjust_fullandmax(Client *c, struct wlr_box *target_geom) { Monitor *m = c->mon; - unsigned int cur_gappiv = enablegaps ? m->gappiv : 0; - unsigned int cur_gappov = enablegaps ? m->gappov : 0; - unsigned int cur_gappoh = enablegaps ? m->gappoh : 0; + uint32_t cur_gappiv = enablegaps ? m->gappiv : 0; + uint32_t cur_gappov = enablegaps ? m->gappov : 0; + uint32_t cur_gappoh = enablegaps ? m->gappoh : 0; cur_gappiv = smartgaps && m->visible_scroll_tiling_clients == 1 ? 0 : cur_gappiv; @@ -188,7 +188,7 @@ void vertical_scroll_adjust_fullandmax(Client *c, struct wlr_box *target_geom) { // 竖屏滚动布局 void vertical_scroller(Monitor *m) { - unsigned int i, n, j; + uint32_t i, n, j; float single_proportion = 1.0; Client *c = NULL, *root_client = NULL; @@ -196,9 +196,9 @@ void vertical_scroller(Monitor *m) { struct wlr_box target_geom; int focus_client_index = 0; bool need_scroller = false; - unsigned int cur_gappiv = enablegaps ? m->gappiv : 0; - unsigned int cur_gappov = enablegaps ? m->gappov : 0; - unsigned int cur_gappoh = enablegaps ? m->gappoh : 0; + uint32_t cur_gappiv = enablegaps ? m->gappiv : 0; + uint32_t cur_gappov = enablegaps ? m->gappov : 0; + uint32_t cur_gappoh = enablegaps ? m->gappoh : 0; cur_gappiv = smartgaps && m->visible_scroll_tiling_clients == 1 ? 0 : cur_gappiv; @@ -207,7 +207,7 @@ void vertical_scroller(Monitor *m) { cur_gappoh = smartgaps && m->visible_scroll_tiling_clients == 1 ? 0 : cur_gappoh; - unsigned int max_client_height = + uint32_t max_client_height = m->w.height - 2 * scroller_structs - cur_gappiv; n = m->visible_scroll_tiling_clients; @@ -341,10 +341,10 @@ void vertical_scroller(Monitor *m) { } void vertical_grid(Monitor *m) { - unsigned int i, n; - unsigned int cx, cy, cw, ch; - unsigned int dy; - unsigned int rows, cols, overrows; + uint32_t i, n; + uint32_t cx, cy, cw, ch; + uint32_t dy; + uint32_t rows, cols, overrows; Client *c = NULL; int target_gappo = enablegaps ? m->isoverview ? overviewgappo : gappov : 0; int target_gappi = enablegaps ? m->isoverview ? overviewgappi : gappiv : 0; diff --git a/src/mango.c b/src/mango.c index 1a1ea665..00430b18 100644 --- a/src/mango.c +++ b/src/mango.c @@ -223,16 +223,16 @@ typedef struct { char *v; char *v2; char *v3; - unsigned int ui; - unsigned int ui2; + uint32_t ui; + uint32_t ui2; } Arg; struct mango_print_status_manager { struct wl_signal print_status; }; typedef struct { - unsigned int mod; - unsigned int button; + uint32_t mod; + uint32_t button; int (*func)(const Arg *); const Arg arg; } Button; // 鼠标按键 @@ -243,8 +243,8 @@ typedef struct { } KeyMode; typedef struct { - unsigned int mod; - unsigned int dir; + uint32_t mod; + uint32_t dir; int (*func)(const Arg *); const Arg arg; } Axis; @@ -272,8 +272,8 @@ struct dwl_animation { bool tagouting; bool begin_fade_in; bool tag_from_rule; - unsigned int time_started; - unsigned int duration; + uint32_t time_started; + uint32_t duration; struct wlr_box initial; struct wlr_box current; int action; @@ -284,8 +284,8 @@ struct dwl_opacity_animation { float current_opacity; float target_opacity; float initial_opacity; - unsigned int time_started; - unsigned int duration; + uint32_t time_started; + uint32_t duration; float current_border_color[4]; float target_border_color[4]; float initial_border_color[4]; @@ -302,7 +302,7 @@ typedef struct { struct Client { /* Must keep these three elements in this order */ - unsigned int type; /* XDGShell or X11* */ + uint32_t type; /* XDGShell or X11* */ struct wlr_box geom, pending, float_geom, animainit_geom, overview_backup_geom, current, drag_begin_geom; /* layout-relative, includes border */ @@ -334,10 +334,10 @@ struct Client { struct wl_listener set_hints; struct wl_listener set_geometry; #endif - unsigned int bw; - unsigned int tags, oldtags, mini_restore_tag; + uint32_t bw; + uint32_t tags, oldtags, mini_restore_tag; bool dirty; - unsigned int configure_serial; + uint32_t configure_serial; struct wlr_foreign_toplevel_handle_v1 *foreign_toplevel; int isfloating, isurgent, isfullscreen, isfakefullscreen, need_float_size_reduce, isminimized, isoverlay, isnosizehint, @@ -414,7 +414,7 @@ typedef struct { } DwlIpcOutput; typedef struct { - unsigned int mod; + uint32_t mod; xkb_keysym_t keysym; int (*func)(const Arg *); const Arg arg; @@ -425,8 +425,8 @@ typedef struct { int nsyms; const xkb_keysym_t *keysyms; /* invalid if nsyms == 0 */ - unsigned int mods; /* invalid if nsyms == 0 */ - unsigned int keycode; + uint32_t mods; /* invalid if nsyms == 0 */ + uint32_t keycode; struct wl_event_source *key_repeat_source; struct wl_listener modifiers; @@ -442,7 +442,7 @@ typedef struct { typedef struct { /* Must keep these three elements in this order */ - unsigned int type; /* LayerShell */ + uint32_t type; /* LayerShell */ struct wlr_box geom, current, pending, animainit_geom; Monitor *mon; struct wlr_scene_tree *scene; @@ -473,7 +473,7 @@ typedef struct { const char *symbol; void (*arrange)(Monitor *); const char *name; - unsigned int id; + uint32_t id; } Layout; struct Monitor { @@ -490,8 +490,8 @@ struct Monitor { struct wlr_box w; /* window area, layout-relative */ struct wl_list layers[4]; /* LayerSurface::link */ const Layout *lt; - unsigned int seltags; - unsigned int tagset[2]; + uint32_t seltags; + uint32_t tagset[2]; double mfact; int nmaster; @@ -505,9 +505,9 @@ struct Monitor { int isoverview; int is_in_hotarea; int asleep; - unsigned int visible_clients; - unsigned int visible_tiling_clients; - unsigned int visible_scroll_tiling_clients; + uint32_t visible_clients; + uint32_t visible_tiling_clients; + uint32_t visible_scroll_tiling_clients; bool has_visible_fullscreen_client; struct wlr_scene_optimized_blur *blur; char last_surface_ws_name[256]; @@ -539,7 +539,7 @@ arrange(Monitor *m, static void arrangelayer(Monitor *m, struct wl_list *list, struct wlr_box *usable_area, int exclusive); static void arrangelayers(Monitor *m); -static char *get_autostart_path(char *, unsigned int); // 自启动命令执行 +static char *get_autostart_path(char *, uint32_t); // 自启动命令执行 static void handle_print_status(struct wl_listener *listener, void *data); static void axisnotify(struct wl_listener *listener, void *data); // 滚轮事件处理 @@ -605,21 +605,20 @@ static void gpureset(struct wl_listener *listener, void *data); static int keyrepeat(void *data); static void inputdevice(struct wl_listener *listener, void *data); -static int keybinding(unsigned int state, bool locked, unsigned int mods, - xkb_keysym_t sym, unsigned int keycode); +static int keybinding(uint32_t state, bool locked, uint32_t mods, + xkb_keysym_t sym, uint32_t keycode); static void keypress(struct wl_listener *listener, void *data); static void keypressmod(struct wl_listener *listener, void *data); static bool keypressglobal(struct wlr_surface *last_surface, struct wlr_keyboard *keyboard, - struct wlr_keyboard_key_event *event, - unsigned int mods, xkb_keysym_t keysym, - unsigned int keycode); + struct wlr_keyboard_key_event *event, uint32_t mods, + xkb_keysym_t keysym, uint32_t keycode); static void locksession(struct wl_listener *listener, void *data); static void mapnotify(struct wl_listener *listener, void *data); static void maximizenotify(struct wl_listener *listener, void *data); static void minimizenotify(struct wl_listener *listener, void *data); static void motionabsolute(struct wl_listener *listener, void *data); -static void motionnotify(unsigned int time, struct wlr_input_device *device, +static void motionnotify(uint32_t time, struct wlr_input_device *device, double sx, double sy, double sx_unaccel, double sy_unaccel); static void motionrelative(struct wl_listener *listener, void *data); @@ -633,8 +632,8 @@ static void outputmgrapplyortest(struct wlr_output_configuration_v1 *config, int test); static void outputmgrtest(struct wl_listener *listener, void *data); static void pointerfocus(Client *c, struct wlr_surface *surface, double sx, - double sy, unsigned int time); -static void printstatus(unsigned int event_mask); + double sy, uint32_t time); +static void printstatus(uint32_t event_mask); static void quitsignal(int signo); static void powermgrsetmode(struct wl_listener *listener, void *data); static void rendermon(struct wl_listener *listener, void *data); @@ -651,7 +650,7 @@ static void setmaximizescreen(Client *c, int maximizescreen); static void reset_maximizescreen_size(Client *c); static void setgaps(int oh, int ov, int ih, int iv); -static void setmon(Client *c, Monitor *m, unsigned int newtags, bool focus); +static void setmon(Client *c, Monitor *m, uint32_t newtags, bool focus); static void setpsel(struct wl_listener *listener, void *data); static void setsel(struct wl_listener *listener, void *data); static void setup(void); @@ -682,7 +681,7 @@ static Client *termforwin(Client *w); static void swallow(Client *c, Client *w); static void warp_cursor_to_selmon(Monitor *m); -unsigned int want_restore_fullscreen(Client *target_client); +uint32_t want_restore_fullscreen(Client *target_client); static void overview_restore(Client *c, const Arg *arg); static void overview_backup(Client *c); static int applyrulesgeom(Client *c); @@ -695,7 +694,7 @@ static void tag_client(const Arg *arg, Client *target_client); static struct wlr_box setclient_coordinate_center(Client *c, struct wlr_box geom, int offsetx, int offsety); -static unsigned int get_tags_first_tag(unsigned int tags); +static uint32_t get_tags_first_tag(uint32_t tags); static struct wlr_output_mode * get_nearest_output_mode(struct wlr_output *output, int width, int height, @@ -726,11 +725,11 @@ static bool check_hit_no_border(Client *c); static void reset_keyboard_layout(void); static void client_update_oldmonname_record(Client *c, Monitor *m); static void pending_kill_client(Client *c); -static unsigned int get_tags_first_tag_num(unsigned int source_tags); +static uint32_t get_tags_first_tag_num(uint32_t source_tags); static void set_layer_open_animaiton(LayerSurface *l, struct wlr_box geo); static void init_fadeout_layers(LayerSurface *l); -static void layer_actual_size(LayerSurface *l, unsigned int *width, - unsigned int *height); +static void layer_actual_size(LayerSurface *l, uint32_t *width, + uint32_t *height); static void get_layer_target_geometry(LayerSurface *l, struct wlr_box *target_box); static void scene_buffer_apply_effect(struct wlr_scene_buffer *buffer, int sx, @@ -752,13 +751,13 @@ static Client *get_client_by_id_or_title(const char *arg_id, const char *arg_title); static bool switch_scratchpad_client_state(Client *c); static bool check_trackpad_disabled(struct wlr_pointer *pointer); -static unsigned int get_tag_status(unsigned int tag, Monitor *m); +static uint32_t get_tag_status(uint32_t tag, Monitor *m); static void enable_adaptive_sync(Monitor *m, struct wlr_output_state *state); static Client *get_next_stack_client(Client *c, bool reverse); static void set_float_malposition(Client *tc); static void set_size_per(Monitor *m, Client *c); static void resize_tile_client(Client *grabc, bool isdrag, int offsetx, - int offsety, unsigned int time); + int offsety, uint32_t time); static void refresh_monitors_workspaces_status(Monitor *m); static void init_client_properties(Client *c); static float *get_border_color(Client *c); @@ -773,7 +772,7 @@ static void clear_fullscreen_and_maximized_state(Monitor *m); static const char broken[] = "broken"; static pid_t child_pid = -1; static int locked; -static unsigned int locked_mods = 0; +static uint32_t locked_mods = 0; static void *exclusive_focus; static struct wl_display *dpy; static struct wl_event_loop *event_loop; @@ -824,7 +823,7 @@ static struct wlr_seat *seat; static KeyboardGroup *kb_group; static struct wl_list inputdevices; static struct wl_list keyboard_shortcut_inhibitors; -static unsigned int cursor_mode; +static uint32_t cursor_mode; static Client *grabc; static int grabcx, grabcy; /* client-relative */ static int drag_begin_cursorx, drag_begin_cursory; /* client-relative */ @@ -841,7 +840,7 @@ static int axis_apply_time = 0; static int axis_apply_dir = 0; static int scroller_focus_lock = 0; -static unsigned int swipe_fingers = 0; +static uint32_t swipe_fingers = 0; static double swipe_dx = 0; static double swipe_dy = 0; @@ -871,7 +870,7 @@ static struct { #include "config/preset.h" struct Pertag { - unsigned int curtag, prevtag; /* current and previous tag */ + uint32_t curtag, prevtag; /* current and previous tag */ int nmasters[LENGTH(tags) + 1]; /* number of windows in master area */ float mfacts[LENGTH(tags) + 1]; /* mfacts per tag */ bool no_hide[LENGTH(tags) + 1]; /* no_hide per tag */ @@ -1318,7 +1317,7 @@ void set_float_malposition(Client *tc) { void applyrules(Client *c) { /* rule matching */ const char *appid, *title; - unsigned int i, newtags = 0; + uint32_t i, newtags = 0; const ConfigWinRule *r; Monitor *m = NULL; Client *fc = NULL; @@ -1493,9 +1492,9 @@ void apply_window_snap(Client *c) { int snap_up_mon = 0, snap_down_mon = 0, snap_left_mon = 0, snap_right_mon = 0; - unsigned int cbw = !render_border || c->fake_no_border ? borderpx : 0; - unsigned int tcbw; - unsigned int cx, cy, cw, ch, tcx, tcy, tcw, tch; + uint32_t cbw = !render_border || c->fake_no_border ? borderpx : 0; + uint32_t tcbw; + uint32_t cx, cy, cw, ch, tcx, tcy, tcw, tch; cx = c->geom.x + cbw; cy = c->geom.y + cbw; cw = c->geom.width - 2 * cbw; @@ -1595,7 +1594,7 @@ void focuslayer(LayerSurface *l) { void reset_exclusive_layer(Monitor *m) { LayerSurface *l = NULL; int i; - unsigned int layers_above_shell[] = { + uint32_t layers_above_shell[] = { ZWLR_LAYER_SHELL_V1_LAYER_OVERLAY, ZWLR_LAYER_SHELL_V1_LAYER_TOP, ZWLR_LAYER_SHELL_V1_LAYER_BOTTOM, @@ -1660,10 +1659,10 @@ axisnotify(struct wl_listener *listener, void *data) { * for example when you move the scroll wheel. */ struct wlr_pointer_axis_event *event = data; struct wlr_keyboard *keyboard, *hard_keyboard; - unsigned int mods, hard_mods; + uint32_t mods, hard_mods; AxisBinding *a; int ji; - unsigned int adir; + uint32_t adir; // IDLE_NOTIFY_ACTIVITY; handlecursoractivity(); wlr_idle_notifier_v1_notify_activity(idle_notifier, seat); @@ -1717,11 +1716,11 @@ axisnotify(struct wl_listener *listener, void *data) { int ongesture(struct wlr_pointer_swipe_end_event *event) { struct wlr_keyboard *keyboard, *hard_keyboard; - unsigned int mods, hard_mods; + uint32_t mods, hard_mods; const GestureBinding *g; - unsigned int motion; - unsigned int adx = (int)round(fabs(swipe_dx)); - unsigned int ady = (int)round(fabs(swipe_dy)); + uint32_t motion; + uint32_t adx = (int)round(fabs(swipe_dx)); + uint32_t ady = (int)round(fabs(swipe_dy)); int handled = 0; int ji; @@ -1886,7 +1885,7 @@ void // 鼠标按键事件 buttonpress(struct wl_listener *listener, void *data) { struct wlr_pointer_button_event *event = data; struct wlr_keyboard *hard_keyboard, *keyboard; - unsigned int hard_mods, mods; + uint32_t hard_mods, mods; Client *c = NULL; LayerSurface *l = NULL; struct wlr_surface *surface; @@ -2104,7 +2103,7 @@ void cleanup(void) { void cleanupmon(struct wl_listener *listener, void *data) { Monitor *m = wl_container_of(listener, m, destroy); LayerSurface *l = NULL, *tmp = NULL; - unsigned int i; + uint32_t i; /* m->layers[i] are intentionally not unlinked */ for (i = 0; i < LENGTH(m->layers); i++) { @@ -2518,14 +2517,14 @@ KeyboardGroup *createkeyboardgroup(void) { xkb_mod_index_t mod_index = xkb_keymap_mod_get_index(keymap, XKB_MOD_NAME_NUM); if (mod_index != XKB_MOD_INVALID) - locked_mods |= (unsigned int)1 << mod_index; + locked_mods |= (uint32_t)1 << mod_index; } if (capslock) { xkb_mod_index_t mod_index = xkb_keymap_mod_get_index(keymap, XKB_MOD_NAME_CAPS); if (mod_index != XKB_MOD_INVALID) - locked_mods |= (unsigned int)1 << mod_index; + locked_mods |= (uint32_t)1 << mod_index; } if (locked_mods) @@ -2649,7 +2648,7 @@ void createmon(struct wl_listener *listener, void *data) { * monitor) becomes available. */ struct wlr_output *wlr_output = data; const ConfigMonitorRule *r; - unsigned int i; + uint32_t i; int ji, jk; struct wlr_output_state state; Monitor *m = NULL; @@ -3310,7 +3309,7 @@ void inputdevice(struct wl_listener *listener, void *data) { /* This event is raised by the backend when a new input device becomes * available. */ struct wlr_input_device *device = data; - unsigned int caps; + uint32_t caps; switch (device->type) { case WLR_INPUT_DEVICE_KEYBOARD: @@ -3367,8 +3366,8 @@ bool is_keyboard_shortcut_inhibitor(struct wlr_surface *surface) { } int // 17 -keybinding(unsigned int state, bool locked, unsigned int mods, xkb_keysym_t sym, - unsigned int keycode) { +keybinding(uint32_t state, bool locked, uint32_t mods, xkb_keysym_t sym, + uint32_t keycode) { /* * Here we handle compositor keybindings. This is when the compositor is * processing keys, rather than passing them on to the client for its @@ -3432,10 +3431,10 @@ keybinding(unsigned int state, bool locked, unsigned int mods, xkb_keysym_t sym, bool keypressglobal(struct wlr_surface *last_surface, struct wlr_keyboard *keyboard, - struct wlr_keyboard_key_event *event, unsigned int mods, - xkb_keysym_t keysym, unsigned int keycode) { + struct wlr_keyboard_key_event *event, uint32_t mods, + xkb_keysym_t keysym, uint32_t keycode) { Client *c = NULL, *lastc = focustop(selmon); - unsigned int keycodes[32] = {0}; + uint32_t keycodes[32] = {0}; int reset = false; const char *appid = NULL; const char *title = NULL; @@ -3511,14 +3510,14 @@ void keypress(struct wl_listener *listener, void *data) { #endif /* Translate libinput keycode -> xkbcommon */ - unsigned int keycode = event->keycode + 8; + uint32_t keycode = event->keycode + 8; /* Get a list of keysyms based on the keymap for this keyboard */ const xkb_keysym_t *syms; int nsyms = xkb_state_key_get_syms(group->wlr_group->keyboard.xkb_state, keycode, &syms); int handled = 0; - unsigned int mods = wlr_keyboard_get_modifiers(&group->wlr_group->keyboard); + uint32_t mods = wlr_keyboard_get_modifiers(&group->wlr_group->keyboard); wlr_idle_notifier_v1_notify_activity(idle_notifier, seat); @@ -3915,7 +3914,7 @@ void motionabsolute(struct wl_listener *listener, void *data) { motionnotify(event->time_msec, &event->pointer->base, dx, dy, dx, dy); } -void motionnotify(unsigned int time, struct wlr_input_device *device, double dx, +void motionnotify(uint32_t time, struct wlr_input_device *device, double dx, double dy, double dx_unaccel, double dy_unaccel) { double sx = 0, sy = 0, sx_confined, sy_confined; Client *c = NULL, *w = NULL; @@ -4140,7 +4139,7 @@ void outputmgrtest(struct wl_listener *listener, void *data) { } void pointerfocus(Client *c, struct wlr_surface *surface, double sx, double sy, - unsigned int time) { + uint32_t time) { struct timespec now; if (surface != seat->pointer_state.focused_surface && sloppyfocus && time && @@ -4166,7 +4165,7 @@ void pointerfocus(Client *c, struct wlr_surface *surface, double sx, double sy, } // 修改printstatus函数,接受掩码参数 -void printstatus(unsigned int event_mask) { +void printstatus(uint32_t event_mask) { wl_signal_emit(&print_status_manager->print_status, (void *)(uintptr_t)event_mask); } @@ -4310,7 +4309,7 @@ void setborder_color(Client *c) { void exchange_two_client(Client *c1, Client *c2) { Monitor *tmp_mon = NULL; - unsigned int tmp_tags; + uint32_t tmp_tags; double master_inner_per = 0.0f; double master_mfact_per = 0.0f; double stack_innder_per = 0.0f; @@ -4747,9 +4746,9 @@ void reset_keyboard_layout(void) { } // Apply the new keymap - unsigned int depressed = keyboard->modifiers.depressed; - unsigned int latched = keyboard->modifiers.latched; - unsigned int locked = keyboard->modifiers.locked; + uint32_t depressed = keyboard->modifiers.depressed; + uint32_t latched = keyboard->modifiers.latched; + uint32_t locked = keyboard->modifiers.locked; wlr_keyboard_set_keymap(keyboard, new_keymap); @@ -4784,7 +4783,7 @@ cleanup_context: xkb_context_unref(context); } -void setmon(Client *c, Monitor *m, unsigned int newtags, bool focus) { +void setmon(Client *c, Monitor *m, uint32_t newtags, bool focus) { Monitor *oldmon = c->mon; if (oldmon == m) @@ -4854,7 +4853,7 @@ void setsel(struct wl_listener *listener, void *data) { } void show_hide_client(Client *c) { - unsigned int target = 1; + uint32_t target = 1; set_size_per(c->mon, c); target = get_tags_first_tag(c->oldtags); @@ -5269,7 +5268,7 @@ void tag_client(const Arg *arg, Client *target_client) { void overview(Monitor *m) { grid(m); } // 目标窗口有其他窗口和它同个tag就返回0 -unsigned int want_restore_fullscreen(Client *target_client) { +uint32_t want_restore_fullscreen(Client *target_client) { Client *c = NULL; wl_list_for_each(c, &clients, link) { if (c && c != target_client && c->tags == target_client->tags && @@ -5645,7 +5644,7 @@ urgent(struct wl_listener *listener, void *data) { void view_in_mon(const Arg *arg, bool want_animation, Monitor *m, bool changefocus) { - unsigned int i, tmptag; + uint32_t i, tmptag; if (!m || (arg->ui != (~0 & TAGMASK) && m->isoverview)) { return; From 88e868caf81624a18420697e492c2f8e20368b6e Mon Sep 17 00:00:00 2001 From: DreamMaoMao <2523610504@qq.com> Date: Tue, 2 Dec 2025 18:41:12 +0800 Subject: [PATCH 49/70] opt: simple printstatus signal --- src/mango.c | 26 +++++--------------------- 1 file changed, 5 insertions(+), 21 deletions(-) diff --git a/src/mango.c b/src/mango.c index 00430b18..68d651dd 100644 --- a/src/mango.c +++ b/src/mango.c @@ -226,9 +226,6 @@ typedef struct { uint32_t ui; uint32_t ui2; } Arg; -struct mango_print_status_manager { - struct wl_signal print_status; -}; typedef struct { uint32_t mod; @@ -878,6 +875,8 @@ struct Pertag { *ltidxs[LENGTH(tags) + 1]; /* matrix of tags and layouts indexes */ }; +static struct wl_signal mango_print_status; + static struct wl_listener print_status_listener = {.notify = handle_print_status}; static struct wl_listener cursor_axis = {.notify = axisnotify}; @@ -4166,8 +4165,7 @@ void pointerfocus(Client *c, struct wlr_surface *surface, double sx, double sy, // 修改printstatus函数,接受掩码参数 void printstatus(uint32_t event_mask) { - wl_signal_emit(&print_status_manager->print_status, - (void *)(uintptr_t)event_mask); + wl_signal_emit(&mango_print_status, (void *)(uintptr_t)event_mask); } void powermgrsetmode(struct wl_listener *listener, void *data) { @@ -4891,22 +4889,8 @@ void create_output(struct wlr_backend *backend, void *data) { #endif } -// 创建函数 -struct mango_print_status_manager *mango_print_status_manager_create() { - struct mango_print_status_manager *manager = calloc(1, sizeof(*manager)); - if (!manager) - return NULL; - - // 初始化 print_status 信号,不是 event_signal - wl_signal_init(&manager->print_status); - - return manager; -} - // 修改信号处理函数,接收掩码参数 void handle_print_status(struct wl_listener *listener, void *data) { - struct mango_print_status_manager *manager = - wl_container_of(listener, manager, print_status); uint32_t event_mask = (uintptr_t)data; // 如果传入的是NULL(旧代码)或0,使用默认的所有事件 @@ -5025,8 +5009,8 @@ void setup(void) { wlr_ext_data_control_manager_v1_create(dpy, 1); // 在 setup 函数中 - print_status_manager = mango_print_status_manager_create(); - wl_signal_add(&print_status_manager->print_status, &print_status_listener); + wl_signal_init(&mango_print_status); + wl_signal_add(&mango_print_status, &print_status_listener); /* Initializes the interface used to implement urgency hints */ activation = wlr_xdg_activation_v1_create(dpy); From bfcde37aba4e38c05efbf1d41a316defe1e8716a Mon Sep 17 00:00:00 2001 From: DreamMaoMao <2523610504@qq.com> Date: Wed, 3 Dec 2025 08:18:35 +0800 Subject: [PATCH 50/70] opt: optimize namedscratchpad when swallow --- src/fetch/client.h | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/src/fetch/client.h b/src/fetch/client.h index ca39ab9e..44a15e53 100644 --- a/src/fetch/client.h +++ b/src/fetch/client.h @@ -41,10 +41,21 @@ Client *get_client_by_id_or_title(const char *arg_id, const char *arg_title) { continue; } - if (!(appid = client_get_appid(c))) + if (c->swallowedby) { + appid = client_get_appid(c->swallowedby); + title = client_get_title(c->swallowedby); + } else { + appid = client_get_appid(c); + title = client_get_title(c); + } + + if (!appid) { appid = broken; - if (!(title = client_get_title(c))) + } + + if (!title) { title = broken; + } if (arg_id && strncmp(arg_id, "none", 4) == 0) arg_id = NULL; From 559de3c66b0a3e278dc5ea382e1526dcb9203574 Mon Sep 17 00:00:00 2001 From: DreamMaoMao <2523610504@qq.com> Date: Wed, 3 Dec 2025 08:39:57 +0800 Subject: [PATCH 51/70] feat: support view multi tag in view dispatch --- src/config/parse_config.h | 26 +++++++++++++++++++++++++- 1 file changed, 25 insertions(+), 1 deletion(-) diff --git a/src/config/parse_config.h b/src/config/parse_config.h index 7c76c5e0..ec27e761 100644 --- a/src/config/parse_config.h +++ b/src/config/parse_config.h @@ -988,7 +988,31 @@ FuncType parse_func_name(char *func_name, Arg *arg, char *arg_value, (*arg).i = atoi(arg_value2); } else if (strcmp(func_name, "view") == 0) { func = bind_to_view; - (*arg).ui = 1 << (atoi(arg_value) - 1); + + u_int32_t mask = 0; + char *token; + char *arg_copy = strdup(arg_value); + + if (arg_copy != NULL) { + char *saveptr = NULL; + token = strtok_r(arg_copy, "|", &saveptr); + + while (token != NULL) { + int num = atoi(token); + if (num > 0 && num <= LENGTH(tags)) { + mask |= (1 << (num - 1)); + } + token = strtok_r(NULL, "|", &saveptr); + } + + free(arg_copy); + } + + if (mask) { + (*arg).ui = mask; + } else { + (*arg).ui = atoi(arg_value); + } (*arg).i = atoi(arg_value2); } else if (strcmp(func_name, "viewcrossmon") == 0) { func = viewcrossmon; From 068ec120dec15b6d0e13efb9294b9ffe513122d2 Mon Sep 17 00:00:00 2001 From: DreamMaoMao <2523610504@qq.com> Date: Wed, 3 Dec 2025 09:29:14 +0800 Subject: [PATCH 52/70] fix: curtag overflow when view arg is -1 in view dispatch --- src/mango.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/mango.c b/src/mango.c index 68d651dd..4542b4eb 100644 --- a/src/mango.c +++ b/src/mango.c @@ -5639,9 +5639,9 @@ void view_in_mon(const Arg *arg, bool want_animation, Monitor *m, } if (arg->ui == UINT32_MAX) { - m->pertag->prevtag = m->tagset[m->seltags]; + m->pertag->prevtag = get_tags_first_tag_num(m->tagset[m->seltags]); m->seltags ^= 1; /* toggle sel tagset */ - m->pertag->curtag = m->tagset[m->seltags]; + m->pertag->curtag = get_tags_first_tag_num(m->tagset[m->seltags]); goto toggleseltags; } From a2902a469bc0e7ad16f7a8418e60bdb5578cd046 Mon Sep 17 00:00:00 2001 From: DreamMaoMao <2523610504@qq.com> Date: Wed, 3 Dec 2025 13:46:18 +0800 Subject: [PATCH 53/70] opt: optimize code struct --- src/mango.c | 25 ++++--------------------- 1 file changed, 4 insertions(+), 21 deletions(-) diff --git a/src/mango.c b/src/mango.c index 4542b4eb..f27b9021 100644 --- a/src/mango.c +++ b/src/mango.c @@ -4008,35 +4008,18 @@ void motionnotify(uint32_t time, struct wlr_input_device *device, double dx, if (!surface && !seat->drag && !cursor_hidden) wlr_cursor_set_xcursor(cursor, cursor_mgr, "default"); - if (c && c->mon && !c->animation.running && - (!(c->geom.x + c->geom.width > c->mon->m.x + c->mon->m.width || - c->geom.x < c->mon->m.x || - c->geom.y + c->geom.height > c->mon->m.y + c->mon->m.height || - c->geom.y < c->mon->m.y) || - !ISTILED(c))) { + if (c && c->mon && !c->animation.running && (INSIDEMON(c) || !ISTILED(c))) { scroller_focus_lock = 0; } should_lock = false; - if (!scroller_focus_lock || - !(c && c->mon && - (c->geom.x + c->geom.width > c->mon->m.x + c->mon->m.width || - c->geom.x < c->mon->m.x || - c->geom.y + c->geom.height > c->mon->m.y + c->mon->m.height || - c->geom.y < c->mon->m.y))) { - if (c && c->mon && is_scroller_layout(c->mon) && - (c->geom.x + c->geom.width > c->mon->m.x + c->mon->m.width || - c->geom.x < c->mon->m.x || - c->geom.y + c->geom.height > c->mon->m.y + c->mon->m.height || - c->geom.y < c->mon->m.y)) { + if (!scroller_focus_lock || !(c && c->mon && !INSIDEMON(c))) { + if (c && c->mon && is_scroller_layout(c->mon) && !INSIDEMON(c)) { should_lock = true; } if (!(!edge_scroller_pointer_focus && c && c->mon && - is_scroller_layout(c->mon) && - (c->geom.x < c->mon->m.x || c->geom.y < c->mon->m.y || - c->geom.x + c->geom.width > c->mon->m.x + c->mon->m.width || - c->geom.y + c->geom.height > c->mon->m.y + c->mon->m.height))) + is_scroller_layout(c->mon) && !INSIDEMON(c))) pointerfocus(c, surface, sx, sy, time); if (should_lock && c && c->mon && ISTILED(c) && c == c->mon->sel) { From 1ffdc1ef38c476cdeabc928d71b3343afbcea069 Mon Sep 17 00:00:00 2001 From: DreamMaoMao <2523610504@qq.com> Date: Wed, 3 Dec 2025 16:12:05 +0800 Subject: [PATCH 54/70] feat: support -c option to specified config file --- src/config/parse_config.h | 14 ++++++++++++-- src/fetch/common.h | 7 ++++++- src/mango.c | 5 ++++- 3 files changed, 22 insertions(+), 4 deletions(-) diff --git a/src/config/parse_config.h b/src/config/parse_config.h index ec27e761..45c4993b 100644 --- a/src/config/parse_config.h +++ b/src/config/parse_config.h @@ -1,4 +1,5 @@ #include +#include #include #include #include @@ -2307,7 +2308,14 @@ void parse_config_file(Config *config, const char *file_path) { // Relative path const char *mangoconfig = getenv("MANGOCONFIG"); - if (mangoconfig && mangoconfig[0] != '\0') { + + if (cli_config_path) { + char *config_path = strdup(cli_config_path); + char *config_dir = dirname(config_path); + snprintf(full_path, sizeof(full_path), "%s/%s", config_dir, + file_path + 1); + free(config_path); + } else if (mangoconfig && mangoconfig[0] != '\0') { snprintf(full_path, sizeof(full_path), "%s/%s", mangoconfig, file_path + 1); } else { @@ -3040,7 +3048,9 @@ void parse_config(void) { const char *mangoconfig = getenv("MANGOCONFIG"); // 如果 MANGOCONFIG 环境变量不存在或为空,则使用 HOME 环境变量 - if (!mangoconfig || mangoconfig[0] == '\0') { + if (cli_config_path) { + snprintf(filename, sizeof(filename), "%s", cli_config_path); + } else if (!mangoconfig || mangoconfig[0] == '\0') { // 获取当前用户家目录 const char *homedir = getenv("HOME"); if (!homedir) { diff --git a/src/fetch/common.h b/src/fetch/common.h index c86a3fef..86d85495 100644 --- a/src/fetch/common.h +++ b/src/fetch/common.h @@ -29,7 +29,12 @@ int isdescprocess(pid_t p, pid_t c) { char *get_autostart_path(char *autostart_path, uint32_t buf_size) { const char *mangoconfig = getenv("MANGOCONFIG"); - if (mangoconfig && mangoconfig[0] != '\0') { + if (cli_config_path) { + char *config_path = strdup(cli_config_path); + char *config_dir = dirname(config_path); + snprintf(autostart_path, buf_size, "%s/autostart.sh", config_dir); + free(config_path); + } else if (mangoconfig && mangoconfig[0] != '\0') { snprintf(autostart_path, buf_size, "%s/autostart.sh", mangoconfig); } else { const char *homedir = getenv("HOME"); diff --git a/src/mango.c b/src/mango.c index f27b9021..25e19ca3 100644 --- a/src/mango.c +++ b/src/mango.c @@ -852,6 +852,7 @@ struct dvec2 *baked_points_focus; static struct wl_event_source *hide_source; static bool cursor_hidden = false; static bool tag_combo = false; +static const char *cli_config_path = NULL; static KeyMode keymode = { .mode = {'d', 'e', 'f', 'a', 'u', 'l', 't', '\0'}, .isdefault = true, @@ -5908,13 +5909,15 @@ int main(int argc, char *argv[]) { char *startup_cmd = NULL; int c; - while ((c = getopt(argc, argv, "s:hdv")) != -1) { + while ((c = getopt(argc, argv, "s:c:hdv")) != -1) { if (c == 's') startup_cmd = optarg; else if (c == 'd') log_level = WLR_DEBUG; else if (c == 'v') die("mango " VERSION); + else if (c == 'c') + cli_config_path = optarg; else goto usage; } From 5c314be8c634524517aea8911ba9a84419c2e824 Mon Sep 17 00:00:00 2001 From: DreamMaoMao <2523610504@qq.com> Date: Wed, 3 Dec 2025 16:20:47 +0800 Subject: [PATCH 55/70] break change: remove autostar.sh and MANGOCONFIG env --- src/config/parse_config.h | 14 +------------- src/fetch/common.h | 23 ----------------------- src/mango.c | 6 +----- 3 files changed, 2 insertions(+), 41 deletions(-) diff --git a/src/config/parse_config.h b/src/config/parse_config.h index 45c4993b..6db5d85b 100644 --- a/src/config/parse_config.h +++ b/src/config/parse_config.h @@ -2307,17 +2307,12 @@ void parse_config_file(Config *config, const char *file_path) { if (file_path[0] == '.' && file_path[1] == '/') { // Relative path - const char *mangoconfig = getenv("MANGOCONFIG"); - if (cli_config_path) { char *config_path = strdup(cli_config_path); char *config_dir = dirname(config_path); snprintf(full_path, sizeof(full_path), "%s/%s", config_dir, file_path + 1); free(config_path); - } else if (mangoconfig && mangoconfig[0] != '\0') { - snprintf(full_path, sizeof(full_path), "%s/%s", mangoconfig, - file_path + 1); } else { const char *home = getenv("HOME"); if (!home) { @@ -3044,13 +3039,9 @@ void parse_config(void) { create_config_keymap(); - // 获取 MANGOCONFIG 环境变量 - const char *mangoconfig = getenv("MANGOCONFIG"); - - // 如果 MANGOCONFIG 环境变量不存在或为空,则使用 HOME 环境变量 if (cli_config_path) { snprintf(filename, sizeof(filename), "%s", cli_config_path); - } else if (!mangoconfig || mangoconfig[0] == '\0') { + } else { // 获取当前用户家目录 const char *homedir = getenv("HOME"); if (!homedir) { @@ -3067,9 +3058,6 @@ void parse_config(void) { snprintf(filename, sizeof(filename), "%s/mango/config.conf", SYSCONFDIR); } - } else { - // 使用 MANGOCONFIG 环境变量作为配置文件夹路径 - snprintf(filename, sizeof(filename), "%s/config.conf", mangoconfig); } set_value_default(); diff --git a/src/fetch/common.h b/src/fetch/common.h index 86d85495..c96ee31b 100644 --- a/src/fetch/common.h +++ b/src/fetch/common.h @@ -26,29 +26,6 @@ int isdescprocess(pid_t p, pid_t c) { return (int)c; } -char *get_autostart_path(char *autostart_path, uint32_t buf_size) { - const char *mangoconfig = getenv("MANGOCONFIG"); - - if (cli_config_path) { - char *config_path = strdup(cli_config_path); - char *config_dir = dirname(config_path); - snprintf(autostart_path, buf_size, "%s/autostart.sh", config_dir); - free(config_path); - } else if (mangoconfig && mangoconfig[0] != '\0') { - snprintf(autostart_path, buf_size, "%s/autostart.sh", mangoconfig); - } else { - const char *homedir = getenv("HOME"); - if (!homedir) { - fprintf(stderr, "Error: HOME environment variable not set.\n"); - return NULL; - } - snprintf(autostart_path, buf_size, "%s/.config/mango/autostart.sh", - homedir); - } - - return autostart_path; -} - void get_layout_abbr(char *abbr, const char *full_name) { // 清空输出缓冲区 abbr[0] = '\0'; diff --git a/src/mango.c b/src/mango.c index 25e19ca3..3282759c 100644 --- a/src/mango.c +++ b/src/mango.c @@ -536,7 +536,6 @@ arrange(Monitor *m, static void arrangelayer(Monitor *m, struct wl_list *list, struct wlr_box *usable_area, int exclusive); static void arrangelayers(Monitor *m); -static char *get_autostart_path(char *, uint32_t); // 自启动命令执行 static void handle_print_status(struct wl_listener *listener, void *data); static void axisnotify(struct wl_listener *listener, void *data); // 滚轮事件处理 @@ -4369,7 +4368,6 @@ run(char *startup_cmd) { set_env(); - char autostart_temp_path[1024]; /* Add a Unix socket to the Wayland display. */ const char *socket = wl_display_add_socket_auto(dpy); if (!socket) @@ -4383,9 +4381,7 @@ run(char *startup_cmd) { /* Now that the socket exists and the backend is started, run the * startup command */ - if (!startup_cmd) - startup_cmd = get_autostart_path(autostart_temp_path, - sizeof(autostart_temp_path)); + if (startup_cmd) { int piperw[2]; if (pipe(piperw) < 0) From e965264f3bdd214d619f92d77aa0f9db54a4ff91 Mon Sep 17 00:00:00 2001 From: DreamMaoMao <2523610504@qq.com> Date: Wed, 3 Dec 2025 17:22:19 +0800 Subject: [PATCH 56/70] fix: dont use evenmask --- src/config/parse_config.h | 2 +- src/dispatch/bind_define.h | 16 +-- src/ext-protocol/dwl-ipc.h | 206 ++++++++++++------------------------- src/mango.c | 46 +++------ 4 files changed, 92 insertions(+), 178 deletions(-) diff --git a/src/config/parse_config.h b/src/config/parse_config.h index 6db5d85b..c94bf717 100644 --- a/src/config/parse_config.h +++ b/src/config/parse_config.h @@ -3277,6 +3277,6 @@ void reset_option(void) { int reload_config(const Arg *arg) { parse_config(); reset_option(); - printstatus(PRINT_ALL); + printstatus(); return 0; } diff --git a/src/dispatch/bind_define.h b/src/dispatch/bind_define.h index 1dc29daf..4850889b 100644 --- a/src/dispatch/bind_define.h +++ b/src/dispatch/bind_define.h @@ -503,7 +503,7 @@ int setlayout(const Arg *arg) { selmon->pertag->ltidxs[selmon->pertag->curtag] = &layouts[jk]; clear_fullscreen_and_maximized_state(selmon); arrange(selmon, false); - printstatus(PRINT_ALL); + printstatus(); return 0; } } @@ -517,7 +517,7 @@ int setkeymode(const Arg *arg) { } else { keymode.isdefault = false; } - printstatus(PRINT_KEYMODE); + printstatus(); return 1; } @@ -866,7 +866,7 @@ int switch_keyboard_layout(const Arg *arg) { wlr_seat_keyboard_notify_modifiers(seat, &tkb->modifiers); } - printstatus(PRINT_KB_LAYOUT); + printstatus(); return 0; } @@ -907,7 +907,7 @@ int switch_layout(const Arg *arg) { } clear_fullscreen_and_maximized_state(selmon); arrange(selmon, false); - printstatus(PRINT_ALL); + printstatus(); return 0; } @@ -918,7 +918,7 @@ int switch_layout(const Arg *arg) { jk == LENGTH(layouts) - 1 ? &layouts[0] : &layouts[jk + 1]; clear_fullscreen_and_maximized_state(selmon); arrange(selmon, false); - printstatus(PRINT_ALL); + printstatus(); return 0; } } @@ -1260,7 +1260,7 @@ int toggletag(const Arg *arg) { focusclient(focustop(selmon), 1); arrange(selmon, false); } - printstatus(PRINT_ALL); + printstatus(); return 0; } @@ -1278,7 +1278,7 @@ int toggleview(const Arg *arg) { focusclient(focustop(selmon), 1); arrange(selmon, false); } - printstatus(PRINT_ALL); + printstatus(); return 0; } @@ -1396,7 +1396,7 @@ int comboview(const Arg *arg) { view(&(Arg){.ui = newtags}, false); } - printstatus(PRINT_ALL); + printstatus(); return 0; } diff --git a/src/ext-protocol/dwl-ipc.h b/src/ext-protocol/dwl-ipc.h index 649c5f3a..eda3f49f 100644 --- a/src/ext-protocol/dwl-ipc.h +++ b/src/ext-protocol/dwl-ipc.h @@ -9,9 +9,8 @@ static void dwl_ipc_manager_get_output(struct wl_client *client, static void dwl_ipc_manager_release(struct wl_client *client, struct wl_resource *resource); static void dwl_ipc_output_destroy(struct wl_resource *resource); -static void dwl_ipc_output_printstatus(Monitor *monitor, uint32_t event_mask); -static void dwl_ipc_output_printstatus_to(DwlIpcOutput *ipc_output, - uint32_t event_mask); +static void dwl_ipc_output_printstatus(Monitor *monitor); +static void dwl_ipc_output_printstatus_to(DwlIpcOutput *ipc_output); static void dwl_ipc_output_set_client_tags(struct wl_client *client, struct wl_resource *resource, uint32_t and_tags, @@ -86,7 +85,7 @@ void dwl_ipc_manager_get_output(struct wl_client *client, wl_resource_set_implementation(output_resource, &dwl_output_implementation, ipc_output, dwl_ipc_output_destroy); wl_list_insert(&monitor->dwl_ipc_outputs, &ipc_output->link); - dwl_ipc_output_printstatus_to(ipc_output, PRINT_ALL); + dwl_ipc_output_printstatus_to(ipc_output); } void dwl_ipc_manager_release(struct wl_client *client, @@ -101,15 +100,14 @@ static void dwl_ipc_output_destroy(struct wl_resource *resource) { } // 修改IPC输出函数,接受掩码参数 -void dwl_ipc_output_printstatus(Monitor *monitor, uint32_t event_mask) { +void dwl_ipc_output_printstatus(Monitor *monitor) { DwlIpcOutput *ipc_output; wl_list_for_each(ipc_output, &monitor->dwl_ipc_outputs, link) - dwl_ipc_output_printstatus_to(ipc_output, event_mask); + dwl_ipc_output_printstatus_to(ipc_output); } // 修改主IPC输出函数,根据掩码发送相应事件 -void dwl_ipc_output_printstatus_to(DwlIpcOutput *ipc_output, - uint32_t event_mask) { +void dwl_ipc_output_printstatus_to(DwlIpcOutput *ipc_output) { Monitor *monitor = ipc_output->mon; Client *c = NULL, *focused = NULL; struct wlr_keyboard *keyboard; @@ -117,175 +115,103 @@ void dwl_ipc_output_printstatus_to(DwlIpcOutput *ipc_output, int tagmask, state, numclients, focused_client, tag; const char *title, *appid, *symbol; char kb_layout[32]; + focused = focustop(monitor); + zdwl_ipc_output_v2_send_active(ipc_output->resource, monitor == selmon); - // 只在需要时才获取这些数据 - if (event_mask & (PRINT_ACTIVE | PRINT_TAG | PRINT_TITLE | PRINT_APPID | - PRINT_FULLSCREEN | PRINT_FLOATING | PRINT_X | PRINT_Y | - PRINT_WIDTH | PRINT_HEIGHT)) { - focused = focustop(monitor); - } - - // 发送活动状态 - if (event_mask & PRINT_ACTIVE) { - zdwl_ipc_output_v2_send_active(ipc_output->resource, monitor == selmon); - } - - // 发送标签状态 - if (event_mask & PRINT_TAG) { - for (tag = 0; tag < LENGTH(tags); tag++) { - numclients = state = focused_client = 0; - tagmask = 1 << tag; - if ((tagmask & monitor->tagset[monitor->seltags]) != 0) - state |= ZDWL_IPC_OUTPUT_V2_TAG_STATE_ACTIVE; - - if (focused) { - wl_list_for_each(c, &clients, link) { - if (c->mon != monitor) - continue; - if (!(c->tags & tagmask)) - continue; - if (c == focused) - focused_client = 1; - if (c->isurgent) - state |= ZDWL_IPC_OUTPUT_V2_TAG_STATE_URGENT; - numclients++; - } - } - zdwl_ipc_output_v2_send_tag(ipc_output->resource, tag, state, - numclients, focused_client); + for (tag = 0; tag < LENGTH(tags); tag++) { + numclients = state = focused_client = 0; + tagmask = 1 << tag; + if ((tagmask & monitor->tagset[monitor->seltags]) != 0) + state |= ZDWL_IPC_OUTPUT_V2_TAG_STATE_ACTIVE; + wl_list_for_each(c, &clients, link) { + if (c->mon != monitor) + continue; + if (!(c->tags & tagmask)) + continue; + if (c == focused) + focused_client = 1; + if (c->isurgent) + state |= ZDWL_IPC_OUTPUT_V2_TAG_STATE_URGENT; + numclients++; } + zdwl_ipc_output_v2_send_tag(ipc_output->resource, tag, state, + numclients, focused_client); } - // 只在需要时才获取标题和应用ID - if (event_mask & (PRINT_TITLE | PRINT_APPID)) { - title = focused ? client_get_title(focused) : ""; - appid = focused ? client_get_appid(focused) : ""; + title = focused ? client_get_title(focused) : ""; + appid = focused ? client_get_appid(focused) : ""; + + if (monitor->isoverview) { + symbol = overviewlayout.symbol; + } else { + symbol = monitor->pertag->ltidxs[monitor->pertag->curtag]->symbol; } - // 获取布局符号 - if (event_mask & PRINT_LAYOUT_SYMBOL) { - if (monitor->isoverview) { - symbol = overviewlayout.symbol; - } else { - symbol = monitor->pertag->ltidxs[monitor->pertag->curtag]->symbol; - } - } + keyboard = &kb_group->wlr_group->keyboard; + current = xkb_state_serialize_layout(keyboard->xkb_state, + XKB_STATE_LAYOUT_EFFECTIVE); + get_layout_abbr(kb_layout, + xkb_keymap_layout_get_name(keyboard->keymap, current)); - // 发送布局索引 - if (event_mask & PRINT_LAYOUT) { - zdwl_ipc_output_v2_send_layout( - ipc_output->resource, - monitor->pertag->ltidxs[monitor->pertag->curtag] - layouts); - } - - // 发送标题 - if (event_mask & PRINT_TITLE) { - zdwl_ipc_output_v2_send_title(ipc_output->resource, - title ? title : broken); - } - - // 发送应用ID - if (event_mask & PRINT_APPID) { - zdwl_ipc_output_v2_send_appid(ipc_output->resource, - appid ? appid : broken); - } - - // 发送布局符号 - if (event_mask & PRINT_LAYOUT_SYMBOL) { - zdwl_ipc_output_v2_send_layout_symbol(ipc_output->resource, symbol); - } - - // 发送全屏状态 - if ((event_mask & PRINT_FULLSCREEN) && - wl_resource_get_version(ipc_output->resource) >= - ZDWL_IPC_OUTPUT_V2_FULLSCREEN_SINCE_VERSION) { + zdwl_ipc_output_v2_send_layout( + ipc_output->resource, + monitor->pertag->ltidxs[monitor->pertag->curtag] - layouts); + zdwl_ipc_output_v2_send_title(ipc_output->resource, title ? title : broken); + zdwl_ipc_output_v2_send_appid(ipc_output->resource, appid ? appid : broken); + zdwl_ipc_output_v2_send_layout_symbol(ipc_output->resource, symbol); + if (wl_resource_get_version(ipc_output->resource) >= + ZDWL_IPC_OUTPUT_V2_FULLSCREEN_SINCE_VERSION) { zdwl_ipc_output_v2_send_fullscreen(ipc_output->resource, focused ? focused->isfullscreen : 0); } - - // 发送浮动状态 - if ((event_mask & PRINT_FLOATING) && - wl_resource_get_version(ipc_output->resource) >= - ZDWL_IPC_OUTPUT_V2_FLOATING_SINCE_VERSION) { + if (wl_resource_get_version(ipc_output->resource) >= + ZDWL_IPC_OUTPUT_V2_FLOATING_SINCE_VERSION) { zdwl_ipc_output_v2_send_floating(ipc_output->resource, focused ? focused->isfloating : 0); } - - // 发送X坐标 - if ((event_mask & PRINT_X) && - wl_resource_get_version(ipc_output->resource) >= - ZDWL_IPC_OUTPUT_V2_X_SINCE_VERSION) { + if (wl_resource_get_version(ipc_output->resource) >= + ZDWL_IPC_OUTPUT_V2_X_SINCE_VERSION) { zdwl_ipc_output_v2_send_x(ipc_output->resource, focused ? focused->geom.x : 0); } - - // 发送Y坐标 - if ((event_mask & PRINT_Y) && - wl_resource_get_version(ipc_output->resource) >= - ZDWL_IPC_OUTPUT_V2_Y_SINCE_VERSION) { + if (wl_resource_get_version(ipc_output->resource) >= + ZDWL_IPC_OUTPUT_V2_Y_SINCE_VERSION) { zdwl_ipc_output_v2_send_y(ipc_output->resource, focused ? focused->geom.y : 0); } - - // 发送宽度 - if ((event_mask & PRINT_WIDTH) && - wl_resource_get_version(ipc_output->resource) >= - ZDWL_IPC_OUTPUT_V2_WIDTH_SINCE_VERSION) { + if (wl_resource_get_version(ipc_output->resource) >= + ZDWL_IPC_OUTPUT_V2_WIDTH_SINCE_VERSION) { zdwl_ipc_output_v2_send_width(ipc_output->resource, focused ? focused->geom.width : 0); } - - // 发送高度 - if ((event_mask & PRINT_HEIGHT) && - wl_resource_get_version(ipc_output->resource) >= - ZDWL_IPC_OUTPUT_V2_HEIGHT_SINCE_VERSION) { + if (wl_resource_get_version(ipc_output->resource) >= + ZDWL_IPC_OUTPUT_V2_HEIGHT_SINCE_VERSION) { zdwl_ipc_output_v2_send_height(ipc_output->resource, focused ? focused->geom.height : 0); } - - // 发送最后图层 - if ((event_mask & PRINT_LAST_LAYER) && - wl_resource_get_version(ipc_output->resource) >= - ZDWL_IPC_OUTPUT_V2_LAST_LAYER_SINCE_VERSION) { + if (wl_resource_get_version(ipc_output->resource) >= + ZDWL_IPC_OUTPUT_V2_LAST_LAYER_SINCE_VERSION) { zdwl_ipc_output_v2_send_last_layer(ipc_output->resource, monitor->last_surface_ws_name); } - // 获取键盘布局(只在需要时) - if (event_mask & PRINT_KB_LAYOUT) { - keyboard = &kb_group->wlr_group->keyboard; - current = xkb_state_serialize_layout(keyboard->xkb_state, - XKB_STATE_LAYOUT_EFFECTIVE); - get_layout_abbr(kb_layout, - xkb_keymap_layout_get_name(keyboard->keymap, current)); - } - - // 发送键盘布局 - if ((event_mask & PRINT_KB_LAYOUT) && - wl_resource_get_version(ipc_output->resource) >= - ZDWL_IPC_OUTPUT_V2_KB_LAYOUT_SINCE_VERSION) { + if (wl_resource_get_version(ipc_output->resource) >= + ZDWL_IPC_OUTPUT_V2_KB_LAYOUT_SINCE_VERSION) { zdwl_ipc_output_v2_send_kb_layout(ipc_output->resource, kb_layout); } - // 发送键模式 - if ((event_mask & PRINT_KEYMODE) && - wl_resource_get_version(ipc_output->resource) >= - ZDWL_IPC_OUTPUT_V2_KEYMODE_SINCE_VERSION) { + if (wl_resource_get_version(ipc_output->resource) >= + ZDWL_IPC_OUTPUT_V2_KEYMODE_SINCE_VERSION) { zdwl_ipc_output_v2_send_keymode(ipc_output->resource, keymode.mode); } - // 发送缩放因子 - if ((event_mask & PRINT_SCALEFACTOR) && - wl_resource_get_version(ipc_output->resource) >= - ZDWL_IPC_OUTPUT_V2_SCALEFACTOR_SINCE_VERSION) { + if (wl_resource_get_version(ipc_output->resource) >= + ZDWL_IPC_OUTPUT_V2_SCALEFACTOR_SINCE_VERSION) { zdwl_ipc_output_v2_send_scalefactor(ipc_output->resource, monitor->wlr_output->scale * 100); } - // 发送帧结束标记 - if (event_mask & PRINT_FRAME) { - zdwl_ipc_output_v2_send_frame(ipc_output->resource); - } + zdwl_ipc_output_v2_send_frame(ipc_output->resource); } void dwl_ipc_output_set_client_tags(struct wl_client *client, @@ -313,7 +239,7 @@ void dwl_ipc_output_set_client_tags(struct wl_client *client, if (selmon == monitor) focusclient(focustop(monitor), 1); arrange(selmon, false); - printstatus(PRINT_ALL); + printstatus(); } void dwl_ipc_output_set_layout(struct wl_client *client, @@ -332,7 +258,7 @@ void dwl_ipc_output_set_layout(struct wl_client *client, monitor->pertag->ltidxs[monitor->pertag->curtag] = &layouts[index]; clear_fullscreen_and_maximized_state(monitor); arrange(monitor, false); - printstatus(PRINT_ALL); + printstatus(); } void dwl_ipc_output_set_tags(struct wl_client *client, diff --git a/src/mango.c b/src/mango.c index 3282759c..e051cffe 100644 --- a/src/mango.c +++ b/src/mango.c @@ -629,7 +629,7 @@ static void outputmgrapplyortest(struct wlr_output_configuration_v1 *config, static void outputmgrtest(struct wl_listener *listener, void *data); static void pointerfocus(Client *c, struct wlr_surface *surface, double sx, double sy, uint32_t time); -static void printstatus(uint32_t event_mask); +static void printstatus(void); static void quitsignal(int signo); static void powermgrsetmode(struct wl_listener *listener, void *data); static void rendermon(struct wl_listener *listener, void *data); @@ -2168,7 +2168,7 @@ void closemon(Monitor *m) { } if (selmon) { focusclient(focustop(selmon), 1); - printstatus(PRINT_ALL); + printstatus(); } } @@ -2802,7 +2802,7 @@ void createmon(struct wl_listener *listener, void *data) { add_workspace_by_tag(i, m); } - printstatus(PRINT_ALL); + printstatus(); } void // fix for 0.5 @@ -3258,7 +3258,7 @@ void focusclient(Client *c, int lift) { client_activate_surface(old_keyboard_focus_surface, 0); } } - printstatus(PRINT_ALL); + printstatus(); if (!c) { @@ -3808,7 +3808,7 @@ mapnotify(struct wl_listener *listener, void *data) { // make sure the animation is open type c->is_pending_open_animation = true; resize(c, c->geom, 0); - printstatus(PRINT_ALL); + printstatus(); } void maximizenotify(struct wl_listener *listener, void *data) { @@ -4147,9 +4147,7 @@ void pointerfocus(Client *c, struct wlr_surface *surface, double sx, double sy, } // 修改printstatus函数,接受掩码参数 -void printstatus(uint32_t event_mask) { - wl_signal_emit(&mango_print_status, (void *)(uintptr_t)event_mask); -} +void printstatus(void) { wl_signal_emit(&mango_print_status, NULL); } void powermgrsetmode(struct wl_listener *listener, void *data) { struct wlr_output_power_v1_set_mode_event *event = data; @@ -4406,7 +4404,7 @@ run(char *startup_cmd) { if (fd_set_nonblock(STDOUT_FILENO) < 0) close(STDOUT_FILENO); - printstatus(PRINT_ALL); + printstatus(); /* At this point the outputs are initialized, choose initial selmon * based on cursor position, and set default cursor image */ @@ -4541,7 +4539,7 @@ setfloating(Client *c, int floating) { arrange(c->mon, false); setborder_color(c); - printstatus(PRINT_ALL); + printstatus(); } void reset_maximizescreen_size(Client *c) { @@ -4872,24 +4870,14 @@ void create_output(struct wlr_backend *backend, void *data) { // 修改信号处理函数,接收掩码参数 void handle_print_status(struct wl_listener *listener, void *data) { - uint32_t event_mask = (uintptr_t)data; - // 如果传入的是NULL(旧代码)或0,使用默认的所有事件 - if (!event_mask) { - event_mask = PRINT_ALL; - } - Monitor *m = NULL; wl_list_for_each(m, &mons, link) { if (!m->wlr_output->enabled) { continue; } - // 更新workspace状态(根据掩码决定是否更新) - if (event_mask & PRINT_TAG || event_mask & PRINT_ACTIVE) { - dwl_ext_workspace_printstatus(m); - } + dwl_ext_workspace_printstatus(m); - // 更新IPC输出状态(传入掩码) - dwl_ipc_output_printstatus(m, event_mask); + dwl_ipc_output_printstatus(m); } } @@ -5226,7 +5214,7 @@ void tag_client(const Arg *arg, Client *target_client) { } focusclient(target_client, 1); - printstatus(PRINT_ALL); + printstatus(); } void overview(Monitor *m) { grid(m); } @@ -5434,7 +5422,7 @@ void unmapnotify(struct wl_listener *listener, void *data) { } wlr_scene_node_destroy(&c->scene->node); - printstatus(PRINT_ALL); + printstatus(); motionnotify(0, NULL, 0, 0, 0, 0); } @@ -5582,7 +5570,7 @@ void updatetitle(struct wl_listener *listener, void *data) { if (title && c->foreign_toplevel) wlr_foreign_toplevel_handle_v1_set_title(c->foreign_toplevel, title); if (c == focustop(c->mon)) - printstatus(PRINT_TITLE); + printstatus(); } void // 17 fix to 0.5 @@ -5602,7 +5590,7 @@ urgent(struct wl_listener *listener, void *data) { c->isurgent = 1; if (client_surface(c)->mapped) setborder_color(c); - printstatus(PRINT_ALL); + printstatus(); } } @@ -5657,7 +5645,7 @@ toggleseltags: if (changefocus) focusclient(focustop(m), 1); arrange(m, want_animation); - printstatus(PRINT_ALL); + printstatus(); } void view(const Arg *arg, bool want_animation) { @@ -5800,7 +5788,7 @@ void activatex11(struct wl_listener *listener, void *data) { arrange(c->mon, false); } - printstatus(PRINT_ALL); + printstatus(); } void configurex11(struct wl_listener *listener, void *data) { @@ -5872,7 +5860,7 @@ void sethints(struct wl_listener *listener, void *data) { return; c->isurgent = xcb_icccm_wm_hints_get_urgency(c->surface.xwayland->hints); - printstatus(PRINT_ALL); + printstatus(); if (c->isurgent && surface && surface->mapped) setborder_color(c); From 42771592198992ca48253f50f1012ec723dfe74e Mon Sep 17 00:00:00 2001 From: DreamMaoMao <2523610504@qq.com> Date: Wed, 3 Dec 2025 17:32:53 +0800 Subject: [PATCH 57/70] opt: add some usage message --- src/mango.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/mango.c b/src/mango.c index e051cffe..6c67d70c 100644 --- a/src/mango.c +++ b/src/mango.c @@ -5919,5 +5919,5 @@ int main(int argc, char *argv[]) { return EXIT_SUCCESS; usage: - die("Usage: %s [-v] [-d] [-s startup command]", argv[0]); + die("Usage: %s [-v] [-d] [-c config file] [-s startup command]", argv[0]); } From 02377e2867845e2d450d346253b10b61c2d02f5e Mon Sep 17 00:00:00 2001 From: DreamMaoMao <2523610504@qq.com> Date: Wed, 3 Dec 2025 17:43:19 +0800 Subject: [PATCH 58/70] fix: change u_int32_t to uint32_t --- src/config/parse_config.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/config/parse_config.h b/src/config/parse_config.h index c94bf717..d845e2ab 100644 --- a/src/config/parse_config.h +++ b/src/config/parse_config.h @@ -990,7 +990,7 @@ FuncType parse_func_name(char *func_name, Arg *arg, char *arg_value, } else if (strcmp(func_name, "view") == 0) { func = bind_to_view; - u_int32_t mask = 0; + uint32_t mask = 0; char *token; char *arg_copy = strdup(arg_value); From 2258574e25f4612affdc92621c8aef70e5c134e1 Mon Sep 17 00:00:00 2001 From: DreamMaoMao <2523610504@qq.com> Date: Wed, 3 Dec 2025 18:15:56 +0800 Subject: [PATCH 59/70] bump version to 0.10.7 --- meson.build | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/meson.build b/meson.build index b02e0fd1..460328ef 100644 --- a/meson.build +++ b/meson.build @@ -1,5 +1,5 @@ project('mango', ['c', 'cpp'], - version : '0.10.6', + version : '0.10.7', ) subdir('protocols') From 44c271ee529c33b3312e7ec3dd47e77ced1eb64e Mon Sep 17 00:00:00 2001 From: DreamMaoMao <2523610504@qq.com> Date: Wed, 3 Dec 2025 21:07:45 +0800 Subject: [PATCH 60/70] opt: optimize border color set when change monitor --- src/dispatch/bind_define.h | 6 +----- src/mango.c | 8 ++++++++ 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/src/dispatch/bind_define.h b/src/dispatch/bind_define.h index 4850889b..004147fa 100644 --- a/src/dispatch/bind_define.h +++ b/src/dispatch/bind_define.h @@ -171,7 +171,7 @@ int toggle_trackpad_enable(const Arg *arg) { } int focusmon(const Arg *arg) { - Client *c = NULL, *old_selmon_sel = NULL; + Client *c = NULL; Monitor *m = NULL; if (arg->i != UNDIR) { @@ -192,7 +192,6 @@ int focusmon(const Arg *arg) { if (!m || !m->wlr_output->enabled || m == selmon) return 0; - old_selmon_sel = selmon->sel; selmon = m; if (warpcursor) { warp_cursor_to_selmon(selmon); @@ -205,9 +204,6 @@ int focusmon(const Arg *arg) { } else focusclient(c, 1); - if (old_selmon_sel) { - client_set_unfocused_opacity_animation(old_selmon_sel); - } return 0; } diff --git a/src/mango.c b/src/mango.c index 6c67d70c..47e785a8 100644 --- a/src/mango.c +++ b/src/mango.c @@ -3166,6 +3166,7 @@ void destroykeyboardgroup(struct wl_listener *listener, void *data) { void focusclient(Client *c, int lift) { Client *last_focus_client = NULL; + Monitor *um = NULL; struct wlr_surface *old_keyboard_focus_surface = seat->keyboard_state.focused_surface; @@ -3211,6 +3212,13 @@ void focusclient(Client *c, int lift) { client_set_unfocused_opacity_animation(last_focus_client); } + wl_list_for_each(um, &mons, link) { + if (um->wlr_output->enabled && um != selmon && um->sel && + !um->sel->iskilling) { + client_set_unfocused_opacity_animation(um->sel); + } + } + client_set_focused_opacity_animation(c); // decide whether need to re-arrange From 11b425faad2e9650628ccab8be03bc389a2082f0 Mon Sep 17 00:00:00 2001 From: DreamMaoMao <2523610504@qq.com> Date: Wed, 3 Dec 2025 22:06:10 +0800 Subject: [PATCH 61/70] opt: avoid unnecessary focus animations --- src/mango.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/mango.c b/src/mango.c index 47e785a8..0e52883b 100644 --- a/src/mango.c +++ b/src/mango.c @@ -402,6 +402,7 @@ struct Client { int force_tearing; int allow_shortcuts_inhibit; float scroller_proportion_single; + bool isfocusing; }; typedef struct { @@ -3206,15 +3207,18 @@ void focusclient(Client *c, int lift) { selmon = c->mon; selmon->prevsel = selmon->sel; selmon->sel = c; + c->isfocusing = true; if (last_focus_client && !last_focus_client->iskilling && last_focus_client != c) { + last_focus_client->isfocusing = false; client_set_unfocused_opacity_animation(last_focus_client); } wl_list_for_each(um, &mons, link) { if (um->wlr_output->enabled && um != selmon && um->sel && - !um->sel->iskilling) { + !um->sel->iskilling && um->sel->isfocusing) { + um->sel->isfocusing = false; client_set_unfocused_opacity_animation(um->sel); } } @@ -3663,6 +3667,7 @@ static void iter_xdg_scene_buffers(struct wlr_scene_buffer *buffer, int sx, } void init_client_properties(Client *c) { + c->isfocusing = false; c->ismaximizescreen = 0; c->isfullscreen = 0; c->need_float_size_reduce = 0; From 1b739a1c7e19116b81dcaf275b08d12655dcd66f Mon Sep 17 00:00:00 2001 From: DreamMaoMao <2523610504@qq.com> Date: Wed, 3 Dec 2025 23:19:58 +0800 Subject: [PATCH 62/70] update readme --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index 5701178b..af1d2977 100644 --- a/README.md +++ b/README.md @@ -71,6 +71,8 @@ https://github.com/user-attachments/assets/014c893f-115c-4ae9-8342-f9ae3e9a0df0 - hwdata - seatd - pcre2 +- xorg-xwayland +- libxcb ## Arch Linux The package is in the Arch User Repository and is availble for manual download [here](https://aur.archlinux.org/packages/mangowc-git) or through a AUR helper like yay: From e602605fa4b9c145f7275b1bca149967bdc472de Mon Sep 17 00:00:00 2001 From: DreamMaoMao <2523610504@qq.com> Date: Thu, 4 Dec 2025 09:58:16 +0800 Subject: [PATCH 63/70] opt: optimize focus change when change monitor --- src/dispatch/bind_define.h | 1 + src/mango.c | 17 +++++++++-------- 2 files changed, 10 insertions(+), 8 deletions(-) diff --git a/src/dispatch/bind_define.h b/src/dispatch/bind_define.h index 004147fa..c167915c 100644 --- a/src/dispatch/bind_define.h +++ b/src/dispatch/bind_define.h @@ -201,6 +201,7 @@ int focusmon(const Arg *arg) { selmon->sel = NULL; wlr_seat_pointer_notify_clear_focus(seat); wlr_seat_keyboard_notify_clear_focus(seat); + focusclient(NULL, 0); } else focusclient(c, 1); diff --git a/src/mango.c b/src/mango.c index 0e52883b..8811c849 100644 --- a/src/mango.c +++ b/src/mango.c @@ -3215,14 +3215,6 @@ void focusclient(Client *c, int lift) { client_set_unfocused_opacity_animation(last_focus_client); } - wl_list_for_each(um, &mons, link) { - if (um->wlr_output->enabled && um != selmon && um->sel && - !um->sel->iskilling && um->sel->isfocusing) { - um->sel->isfocusing = false; - client_set_unfocused_opacity_animation(um->sel); - } - } - client_set_focused_opacity_animation(c); // decide whether need to re-arrange @@ -3242,6 +3234,15 @@ void focusclient(Client *c, int lift) { c->isurgent = 0; } + // update other monitor focus disappear + wl_list_for_each(um, &mons, link) { + if (um->wlr_output->enabled && um != selmon && um->sel && + !um->sel->iskilling && um->sel->isfocusing) { + um->sel->isfocusing = false; + client_set_unfocused_opacity_animation(um->sel); + } + } + if (c && !c->iskilling && c->foreign_toplevel) wlr_foreign_toplevel_handle_v1_set_activated(c->foreign_toplevel, true); From 0e59209d2b2911f4d1cc850e7a94cd386e8b4508 Mon Sep 17 00:00:00 2001 From: DreamMaoMao <2523610504@qq.com> Date: Thu, 4 Dec 2025 17:39:13 +0800 Subject: [PATCH 64/70] opt: focusdir use same monitor client first --- src/fetch/client.h | 28 +++++++++++++++++++++++++++- 1 file changed, 27 insertions(+), 1 deletion(-) diff --git a/src/fetch/client.h b/src/fetch/client.h index 44a15e53..7b44344f 100644 --- a/src/fetch/client.h +++ b/src/fetch/client.h @@ -193,7 +193,9 @@ Client *find_client_by_direction(Client *tc, const Arg *arg, bool findfloating, int sel_x = tc->geom.x; int sel_y = tc->geom.y; long long int distance = LLONG_MAX; + long long int same_monitor_distance = LLONG_MAX; Client *tempFocusClients = NULL; + Client *tempSameMonitorFocusClients = NULL; switch (arg->i) { case UP: @@ -224,6 +226,11 @@ Client *find_client_by_direction(Client *tc, const Arg *arg, bool findfloating, distance = tmp_distance; tempFocusClients = tempClients[_i]; } + if (tempClients[_i]->mon == tc->mon && + tmp_distance < same_monitor_distance) { + same_monitor_distance = tmp_distance; + tempSameMonitorFocusClients = tempClients[_i]; + } } } } @@ -256,6 +263,11 @@ Client *find_client_by_direction(Client *tc, const Arg *arg, bool findfloating, distance = tmp_distance; tempFocusClients = tempClients[_i]; } + if (tempClients[_i]->mon == tc->mon && + tmp_distance < same_monitor_distance) { + same_monitor_distance = tmp_distance; + tempSameMonitorFocusClients = tempClients[_i]; + } } } } @@ -288,6 +300,11 @@ Client *find_client_by_direction(Client *tc, const Arg *arg, bool findfloating, distance = tmp_distance; tempFocusClients = tempClients[_i]; } + if (tempClients[_i]->mon == tc->mon && + tmp_distance < same_monitor_distance) { + same_monitor_distance = tmp_distance; + tempSameMonitorFocusClients = tempClients[_i]; + } } } } @@ -320,6 +337,11 @@ Client *find_client_by_direction(Client *tc, const Arg *arg, bool findfloating, distance = tmp_distance; tempFocusClients = tempClients[_i]; } + if (tempClients[_i]->mon == tc->mon && + tmp_distance < same_monitor_distance) { + same_monitor_distance = tmp_distance; + tempSameMonitorFocusClients = tempClients[_i]; + } } } } @@ -327,7 +349,11 @@ Client *find_client_by_direction(Client *tc, const Arg *arg, bool findfloating, } free(tempClients); // 释放内存 - return tempFocusClients; + if(tempSameMonitorFocusClients) { + return tempSameMonitorFocusClients; + } else { + return tempFocusClients; + } } Client *direction_select(const Arg *arg) { From 6086507c5ae355d63273ed4f3714158469b31ea6 Mon Sep 17 00:00:00 2001 From: Owen-sz Date: Sat, 6 Dec 2025 14:50:54 -0600 Subject: [PATCH 65/70] 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 66/70] 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 67/70] 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 68/70] 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 69/70] 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 70/70] 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)) /