From 09ea9d3b066ebd9062d73cb7b7f804907e4d3557 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Wed, 18 Feb 2026 08:50:19 +0000 Subject: [PATCH 1/6] Initial plan From 73995e58281198d2d892c14b45e59e7c6a0402c7 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Wed, 18 Feb 2026 08:54:36 +0000 Subject: [PATCH 2/6] Improve code readability: refactor animation code and translate comments Co-authored-by: squassina <8495707+squassina@users.noreply.github.com> --- src/animation/common.h | 140 ++++++++++++++++++-------------------- src/common/util.h | 2 + src/config/parse_config.h | 12 ++-- src/config/preset.h | 84 ++++++++++++++--------- src/mango.c | 4 +- 5 files changed, 128 insertions(+), 114 deletions(-) diff --git a/src/animation/common.h b/src/animation/common.h index 9f022db2..ea12a3f9 100644 --- a/src/animation/common.h +++ b/src/animation/common.h @@ -1,23 +1,28 @@ +/* Helper function to get animation curve array by type */ +static double *get_animation_curve_by_type(int32_t type) { + switch (type) { + case MOVE: + return animation_curve_move; + case OPEN: + return animation_curve_open; + case TAG: + return animation_curve_tag; + case CLOSE: + return animation_curve_close; + case FOCUS: + return animation_curve_focus; + case OPAFADEIN: + return animation_curve_opafadein; + case OPAFADEOUT: + return animation_curve_opafadeout; + default: + return animation_curve_move; + } +} + struct dvec2 calculate_animation_curve_at(double t, int32_t type) { struct dvec2 point; - double *animation_curve; - if (type == MOVE) { - animation_curve = animation_curve_move; - } else if (type == OPEN) { - animation_curve = animation_curve_open; - } else if (type == TAG) { - animation_curve = animation_curve_tag; - } else if (type == CLOSE) { - animation_curve = animation_curve_close; - } else if (type == FOCUS) { - animation_curve = animation_curve_focus; - } else if (type == OPAFADEIN) { - animation_curve = animation_curve_opafadein; - } else if (type == OPAFADEOUT) { - animation_curve = animation_curve_opafadeout; - } else { - animation_curve = animation_curve_move; - } + double *animation_curve = get_animation_curve_by_type(type); point.x = 3 * t * (1 - t) * (1 - t) * animation_curve[0] + 3 * t * t * (1 - t) * animation_curve[2] + t * t * t; @@ -29,45 +34,51 @@ struct dvec2 calculate_animation_curve_at(double t, int32_t type) { } void init_baked_points(void) { - baked_points_move = calloc(BAKED_POINTS_COUNT, sizeof(*baked_points_move)); - baked_points_open = calloc(BAKED_POINTS_COUNT, sizeof(*baked_points_open)); - baked_points_tag = calloc(BAKED_POINTS_COUNT, sizeof(*baked_points_tag)); - baked_points_close = - calloc(BAKED_POINTS_COUNT, sizeof(*baked_points_close)); - baked_points_focus = - calloc(BAKED_POINTS_COUNT, sizeof(*baked_points_focus)); - baked_points_opafadein = - calloc(BAKED_POINTS_COUNT, sizeof(*baked_points_opafadein)); - baked_points_opafadeout = - calloc(BAKED_POINTS_COUNT, sizeof(*baked_points_opafadeout)); + /* Animation type to baked points mapping */ + struct { + int32_t type; + struct dvec2 **points; + } animation_types[] = { + {MOVE, &baked_points_move}, + {OPEN, &baked_points_open}, + {TAG, &baked_points_tag}, + {CLOSE, &baked_points_close}, + {FOCUS, &baked_points_focus}, + {OPAFADEIN, &baked_points_opafadein}, + {OPAFADEOUT, &baked_points_opafadeout}, + }; - for (int32_t i = 0; i < BAKED_POINTS_COUNT; i++) { - baked_points_move[i] = calculate_animation_curve_at( - (double)i / (BAKED_POINTS_COUNT - 1), MOVE); + /* Allocate and calculate baked points for all animation types */ + for (size_t j = 0; j < sizeof(animation_types) / sizeof(animation_types[0]); + j++) { + *animation_types[j].points = + calloc(BAKED_POINTS_COUNT, sizeof(struct dvec2)); + for (int32_t i = 0; i < BAKED_POINTS_COUNT; i++) { + (*animation_types[j].points)[i] = calculate_animation_curve_at( + (double)i / (BAKED_POINTS_COUNT - 1), animation_types[j].type); + } } - for (int32_t i = 0; i < BAKED_POINTS_COUNT; i++) { - baked_points_open[i] = calculate_animation_curve_at( - (double)i / (BAKED_POINTS_COUNT - 1), OPEN); - } - for (int32_t i = 0; i < BAKED_POINTS_COUNT; i++) { - baked_points_tag[i] = calculate_animation_curve_at( - (double)i / (BAKED_POINTS_COUNT - 1), TAG); - } - for (int32_t i = 0; i < BAKED_POINTS_COUNT; i++) { - baked_points_close[i] = calculate_animation_curve_at( - (double)i / (BAKED_POINTS_COUNT - 1), CLOSE); - } - for (int32_t i = 0; i < BAKED_POINTS_COUNT; i++) { - baked_points_focus[i] = calculate_animation_curve_at( - (double)i / (BAKED_POINTS_COUNT - 1), FOCUS); - } - for (int32_t i = 0; i < BAKED_POINTS_COUNT; i++) { - baked_points_opafadein[i] = calculate_animation_curve_at( - (double)i / (BAKED_POINTS_COUNT - 1), OPAFADEIN); - } - for (int32_t i = 0; i < BAKED_POINTS_COUNT; i++) { - baked_points_opafadeout[i] = calculate_animation_curve_at( - (double)i / (BAKED_POINTS_COUNT - 1), OPAFADEOUT); +} + +/* Helper function to get baked points array by type */ +static struct dvec2 *get_baked_points_by_type(int32_t type) { + switch (type) { + case MOVE: + return baked_points_move; + case OPEN: + return baked_points_open; + case TAG: + return baked_points_tag; + case CLOSE: + return baked_points_close; + case FOCUS: + return baked_points_focus; + case OPAFADEIN: + return baked_points_opafadein; + case OPAFADEOUT: + return baked_points_opafadeout; + default: + return baked_points_move; } } @@ -76,24 +87,7 @@ double find_animation_curve_at(double t, int32_t type) { int32_t up = BAKED_POINTS_COUNT - 1; int32_t middle = (up + down) / 2; - struct dvec2 *baked_points; - if (type == MOVE) { - baked_points = baked_points_move; - } else if (type == OPEN) { - baked_points = baked_points_open; - } else if (type == TAG) { - baked_points = baked_points_tag; - } else if (type == CLOSE) { - baked_points = baked_points_close; - } else if (type == FOCUS) { - baked_points = baked_points_focus; - } else if (type == OPAFADEIN) { - baked_points = baked_points_opafadein; - } else if (type == OPAFADEOUT) { - baked_points = baked_points_opafadeout; - } else { - baked_points = baked_points_move; - } + struct dvec2 *baked_points = get_baked_points_by_type(type); while (up - down != 1) { if (baked_points[middle].x <= t) { diff --git a/src/common/util.h b/src/common/util.h index 8fb60338..b635c36a 100644 --- a/src/common/util.h +++ b/src/common/util.h @@ -4,6 +4,8 @@ void die(const char *fmt, ...); void *ecalloc(size_t nmemb, size_t size); int32_t fd_set_nonblock(int32_t fd); +/* Match string against regex pattern. Both pattern and string are multi-byte + * (mb) UTF-8 encoded. */ int32_t regex_match(const char *pattern_mb, const char *str_mb); void wl_list_append(struct wl_list *list, struct wl_list *object); uint32_t get_now_in_ms(void); diff --git a/src/config/parse_config.h b/src/config/parse_config.h index b7f89d59..6fff4027 100644 --- a/src/config/parse_config.h +++ b/src/config/parse_config.h @@ -8,13 +8,13 @@ #define SYSCONFDIR "/etc" #endif -// 整数版本 - 截断小数部分 +// Integer version - truncates decimal part #define CLAMP_INT(x, min, max) \ ((int32_t)(x) < (int32_t)(min) \ ? (int32_t)(min) \ : ((int32_t)(x) > (int32_t)(max) ? (int32_t)(max) : (int32_t)(x))) -// 浮点数版本 - 保留小数部分 +// Floating point version - preserves decimal part #define CLAMP_FLOAT(x, min, max) \ ((x) < (min) ? (min) : ((x) > (max) ? (max) : (x))) @@ -1485,7 +1485,7 @@ bool parse_option(Config *config, char *key, char *value) { "scroller_proportion_preset format: %s\n", value); free(value_copy); - free(config->scroller_proportion_preset); // 释放已分配的内存 + free(config->scroller_proportion_preset); // 释放已分配的内存 config->scroller_proportion_preset = NULL; // 防止野指针 config->scroller_proportion_preset_count = 0; return false; @@ -3267,9 +3267,9 @@ void set_value_default() { config.axis_bind_apply_timeout = axis_bind_apply_timeout; // 滚轮绑定动作的触发的时间间隔 config.focus_on_activate = - focus_on_activate; // 收到窗口激活请求是否自动跳转聚焦 - config.new_is_master = new_is_master; // 新窗口是否插在头部 - config.default_mfact = default_mfact; // master 窗口比例 + focus_on_activate; // 收到窗口激活请求是否自动跳转聚焦 + config.new_is_master = new_is_master; // 新窗口是否插在头部 + config.default_mfact = default_mfact; // master 窗口比例 config.default_nmaster = default_nmaster; // 默认master数量 config.center_master_overspread = center_master_overspread; // 中心master时是否铺满 diff --git a/src/config/preset.h b/src/config/preset.h index ae4424f9..8522748f 100644 --- a/src/config/preset.h +++ b/src/config/preset.h @@ -4,21 +4,27 @@ /* speedie's mango config */ #define COLOR(hex) \ - {((hex >> 24) & 0xFF) / 255.0f, ((hex >> 16) & 0xFF) / 255.0f, \ - ((hex >> 8) & 0xFF) / 255.0f, (hex & 0xFF) / 255.0f} + { \ + ((hex >> 24) & 0xFF) / 255.0f, ((hex >> 16) & 0xFF) / 255.0f, \ + ((hex >> 8) & 0xFF) / 255.0f, (hex & 0xFF) / 255.0f \ + } -/* animaion */ -char *animation_type_open = "slide"; // 是否启用动画 //slide,zoom -char *animation_type_close = "slide"; // 是否启用动画 //slide,zoom -char *layer_animation_type_open = "slide"; // 是否启用layer动画 //slide,zoom -char *layer_animation_type_close = "slide"; // 是否启用layer动画 //slide,zoom -int32_t animations = 1; // 是否启用动画 -int32_t layer_animations = 0; // 是否启用layer动画 -int32_t tag_animation_direction = HORIZONTAL; // 标签动画方向 +/* animation */ +char *animation_type_open = + "slide"; // Animation type for window open: slide or zoom +char *animation_type_close = + "slide"; // Animation type for window close: slide or zoom +char *layer_animation_type_open = + "slide"; // Animation type for layer open: slide or zoom +char *layer_animation_type_close = + "slide"; // Animation type for layer close: slide or zoom +int32_t animations = 1; // Enable window animations +int32_t layer_animations = 0; // Enable layer animations +int32_t tag_animation_direction = HORIZONTAL; // Tag animation direction int32_t animation_fade_in = 1; // Enable animation fade in int32_t animation_fade_out = 1; // Enable animation fade out -float zoom_initial_ratio = 0.3; // 动画起始窗口比例 -float zoom_end_ratio = 0.8; // 动画结束窗口比例 +float zoom_initial_ratio = 0.3; // Initial window size ratio for zoom animation +float zoom_end_ratio = 0.8; // End window size ratio for zoom animation float fadein_begin_opacity = 0.5; // Begin opac window ratio for animations float fadeout_begin_opacity = 0.5; // Begin opac window ratio for animations uint32_t animation_duration_move = 500; // Animation move speed @@ -26,31 +32,42 @@ uint32_t animation_duration_open = 400; // Animation open speed uint32_t animation_duration_tag = 300; // Animation tag speed uint32_t animation_duration_close = 300; // Animation close speed uint32_t animation_duration_focus = 0; // Animation focus opacity speed -double animation_curve_move[4] = {0.46, 1.0, 0.29, 0.99}; // 动画曲线 -double animation_curve_open[4] = {0.46, 1.0, 0.29, 0.99}; // 动画曲线 -double animation_curve_tag[4] = {0.46, 1.0, 0.29, 0.99}; // 动画曲线 -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}; // 动画曲线 -double animation_curve_opafadein[4] = {0.46, 1.0, 0.29, 0.99}; // 动画曲线 -double animation_curve_opafadeout[4] = {0.5, 0.5, 0.5, 0.5}; // 动画曲线 +double animation_curve_move[4] = {0.46, 1.0, 0.29, + 0.99}; // Animation curve for move +double animation_curve_open[4] = {0.46, 1.0, 0.29, + 0.99}; // Animation curve for open +double animation_curve_tag[4] = {0.46, 1.0, 0.29, + 0.99}; // Animation curve for tag +double animation_curve_close[4] = {0.46, 1.0, 0.29, + 0.99}; // Animation curve for close +double animation_curve_focus[4] = {0.46, 1.0, 0.29, + 0.99}; // Animation curve for focus +double animation_curve_opafadein[4] = { + 0.46, 1.0, 0.29, 0.99}; // Animation curve for opacity fade in +double animation_curve_opafadeout[4] = { + 0.5, 0.5, 0.5, 0.5}; // Animation curve for opacity fade out /* appearance */ -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数量 -int32_t center_master_overspread = 0; // 中心master时是否铺满 -int32_t center_when_single_stack = 1; // 单个stack时是否居中 +uint32_t axis_bind_apply_timeout = + 100; // Timeout interval for mouse wheel binding actions +uint32_t focus_on_activate = + 1; // Auto-focus when receiving window activation request +uint32_t new_is_master = 1; // Insert new windows at the head +double default_mfact = 0.55f; // Master window proportion +uint32_t default_nmaster = 1; // Default number of master windows +int32_t center_master_overspread = + 0; // Whether to fill screen when center master +int32_t center_when_single_stack = + 1; // Whether to center when single stack window /* logging */ int32_t log_level = WLR_ERROR; -uint32_t numlockon = 0; // 是否打开右边小键盘 -uint32_t capslock = 0; // 是否启用快捷键 +uint32_t numlockon = 0; // Enable numlock +uint32_t capslock = 0; // Enable capslock -uint32_t ov_tab_mode = 0; // alt tab切换模式 -uint32_t hotarea_size = 10; // 热区大小,10x10 +uint32_t ov_tab_mode = 0; // Alt-tab switch mode +uint32_t hotarea_size = 10; // Hot corner size in pixels (10x10) uint32_t hotarea_corner = BOTTOM_LEFT; -uint32_t enable_hotarea = 1; // 是否启用鼠标热区 +uint32_t enable_hotarea = 1; // Enable mouse hot corner int32_t smartgaps = 0; /* 1 means no outer gap when there is only one window */ int32_t sloppyfocus = 1; /* focus follows mouse */ uint32_t gappih = 5; /* horiz inner gap between windows */ @@ -95,8 +112,9 @@ float globalcolor[] = COLOR(0xb153a7ff); float overlaycolor[] = COLOR(0x14a57cff); // char *cursor_theme = "Bibata-Modern-Ice"; -int32_t overviewgappi = 5; /* overview时 窗口与边缘 缝隙大小 */ -int32_t overviewgappo = 30; /* overview时 窗口与窗口 缝隙大小 */ +int32_t overviewgappi = + 5; /* Gap size between windows and edges in overview mode */ +int32_t overviewgappo = 30; /* Gap size between windows in overview mode */ /* To conform the xdg-protocol, set the alpha to zero to restore the old * behavior */ diff --git a/src/mango.c b/src/mango.c index 540395ae..e1f3c3a0 100644 --- a/src/mango.c +++ b/src/mango.c @@ -259,7 +259,7 @@ typedef struct { struct wlr_input_device *wlr_device; struct libinput_device *libinput_device; struct wl_listener destroy_listener; // 用于监听设备销毁事件 - void *device_data; // 新增:指向设备特定数据(如 Switch) + void *device_data; // 新增:指向设备特定数据(如 Switch) } InputDevice; typedef struct { @@ -570,7 +570,7 @@ static void pinch_end(struct wl_listener *listener, void *data); static void hold_begin(struct wl_listener *listener, void *data); static void hold_end(struct wl_listener *listener, void *data); static void checkidleinhibitor(struct wlr_surface *exclude); -static void cleanup(void); // 退出清理 +static void cleanup(void); // 退出清理 static void cleanupmon(struct wl_listener *listener, void *data); // 退出清理 static void closemon(Monitor *m); static void cleanuplisteners(void); From c08c9c4fb866c48a54cb6e31d17916405ca4c599 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Wed, 18 Feb 2026 08:56:21 +0000 Subject: [PATCH 3/6] Add macro documentation and translate remaining Chinese comments Co-authored-by: squassina <8495707+squassina@users.noreply.github.com> --- src/animation/layer.h | 20 ++++++++++---------- src/common/util.c | 2 +- src/mango.c | 16 ++++++++++++++++ 3 files changed, 27 insertions(+), 11 deletions(-) diff --git a/src/animation/layer.h b/src/animation/layer.h index 568d52b3..56130956 100644 --- a/src/animation/layer.h +++ b/src/animation/layer.h @@ -27,21 +27,21 @@ void get_layer_target_geometry(LayerSurface *l, struct wlr_box *target_box) { const struct wlr_layer_surface_v1_state *state = &l->layer_surface->current; - // 限制区域 - // waybar一般都是大于0,表示要占用多少区域,所以计算位置也要用全部区域作为基准 - // 如果是-1可能表示独占所有可用空间 - // 如果是0,应该是表示使用exclusive_zone外的可用区域 + // Exclusive zone handling: + // Waybar typically uses > 0, indicating how much area to reserve (use full + // monitor bounds) If -1, may indicate exclusive use of all available space + // If 0, indicates use of available area outside exclusive zones struct wlr_box bounds; if (state->exclusive_zone > 0 || state->exclusive_zone == -1) bounds = l->mon->m; else bounds = l->mon->w; - // 初始化几何位置 + // Initialize geometry struct wlr_box box = {.width = state->desired_width, .height = state->desired_height}; - // 水平方向定位 + // Horizontal positioning const int32_t both_horiz = ZWLR_LAYER_SURFACE_V1_ANCHOR_LEFT | ZWLR_LAYER_SURFACE_V1_ANCHOR_RIGHT; if (box.width == 0) { @@ -56,7 +56,7 @@ void get_layer_target_geometry(LayerSurface *l, struct wlr_box *target_box) { box.x = bounds.x + ((bounds.width - box.width) / 2); } - // 垂直方向定位 + // Vertical positioning const int32_t both_vert = ZWLR_LAYER_SURFACE_V1_ANCHOR_TOP | ZWLR_LAYER_SURFACE_V1_ANCHOR_BOTTOM; if (box.height == 0) { @@ -71,7 +71,7 @@ void get_layer_target_geometry(LayerSurface *l, struct wlr_box *target_box) { box.y = bounds.y + ((bounds.height - box.height) / 2); } - // 应用边距 + // Apply margins if (box.width == 0) { box.x += state->margin.left; box.width = bounds.width - (state->margin.left + state->margin.right); @@ -412,8 +412,8 @@ void init_fadeout_layers(LayerSurface *l) { fadeout_layer->animation_type_close = l->animation_type_close; fadeout_layer->animation_type_open = l->animation_type_open; - // 这里snap节点的坐标设置是使用的相对坐标,不能用绝对坐标 - // 这跟普通node有区别 + // Snapshot node coordinates use relative coordinates, not absolute + // This differs from regular nodes fadeout_layer->animation.initial.x = 0; fadeout_layer->animation.initial.y = 0; diff --git a/src/common/util.c b/src/common/util.c index a15cca7c..59f50455 100644 --- a/src/common/util.c +++ b/src/common/util.c @@ -59,7 +59,7 @@ int32_t regex_match(const char *pattern, const char *str) { } pcre2_code *re = pcre2_compile((PCRE2_SPTR)pattern, PCRE2_ZERO_TERMINATED, - PCRE2_UTF, // 启用 UTF-8 支持 + PCRE2_UTF, // Enable UTF-8 support &errnum, &erroffset, NULL); if (!re) { PCRE2_UCHAR errbuf[256]; diff --git a/src/mango.c b/src/mango.c index e1f3c3a0..f1f1e7f2 100644 --- a/src/mango.c +++ b/src/mango.c @@ -97,31 +97,43 @@ /* macros */ #define MAX(A, B) ((A) > (B) ? (A) : (B)) #define MIN(A, B) ((A) < (B) ? (A) : (B)) +/* Get value if >= 0, otherwise return 0 */ #define GEZERO(A) ((A) >= 0 ? (A) : 0) +/* Remove caps lock modifier from mask */ #define CLEANMASK(mask) (mask & ~WLR_MODIFIER_CAPS) +/* Check if client A is fully inside its monitor bounds */ #define INSIDEMON(A) \ (A->geom.x >= A->mon->m.x && A->geom.y >= A->mon->m.y && \ 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) +/* Check if geometry A is fully inside monitor M bounds */ #define GEOMINSIDEMON(A, M) \ (A->x >= M->m.x && A->y >= M->m.y && \ A->x + A->width <= M->m.x + M->m.width && \ A->y + A->height <= M->m.y + M->m.height) +/* Check if client is in tiled state (not floating, minimized, killing, etc.) */ #define ISTILED(A) \ (A && !(A)->isfloating && !(A)->isminimized && !(A)->iskilling && \ !(A)->ismaximizescreen && !(A)->isfullscreen && !(A)->isunglobal) +/* Check if client is tiled for scroller layout (less restrictive than ISTILED) + */ #define ISSCROLLTILED(A) \ (A && !(A)->isfloating && !(A)->isminimized && !(A)->iskilling && \ !(A)->isunglobal) +/* Check if client C is visible on monitor M (matching tags) */ #define VISIBLEON(C, M) \ ((C) && (M) && (C)->mon == (M) && ((C)->tags & (M)->tagset[(M)->seltags])) #define LENGTH(X) (sizeof X / sizeof X[0]) #define END(A) ((A) + LENGTH(A)) +/* Generate bitmask for all tags */ #define TAGMASK ((1 << LENGTH(tags)) - 1) +/* Register event listener: adds signal handler H to event E with listener L */ #define LISTEN(E, L, H) wl_signal_add((E), ((L)->notify = (H), (L))) +/* Check if client is in any fullscreen-like state */ #define ISFULLSCREEN(A) \ ((A)->isfullscreen || (A)->ismaximizescreen || \ (A)->overview_ismaximizescreenbak || (A)->overview_isfullscreenbak) +/* Register static event listener (allocates listener internally) */ #define LISTEN_STATIC(E, H) \ do { \ struct wl_listener *_l = ecalloc(1, sizeof(*_l)); \ @@ -129,18 +141,22 @@ wl_signal_add((E), _l); \ } while (0) +/* Apply integer property from rule to object if set (>= 0) */ #define APPLY_INT_PROP(obj, rule, prop) \ if (rule->prop >= 0) \ obj->prop = rule->prop +/* Apply float property from rule to object if set (> 0.0) */ #define APPLY_FLOAT_PROP(obj, rule, prop) \ if (rule->prop > 0.0f) \ obj->prop = rule->prop +/* Apply string property from rule to object if set (not NULL) */ #define APPLY_STRING_PROP(obj, rule, prop) \ if (rule->prop != NULL) \ obj->prop = rule->prop +/* Number of pre-calculated animation curve points for performance */ #define BAKED_POINTS_COUNT 256 /* enums */ From 3336d8d8eede5fbf0ca7f9023101006eab963a53 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Wed, 18 Feb 2026 08:58:37 +0000 Subject: [PATCH 4/6] Address code review feedback: improve array formatting and extract size constant Co-authored-by: squassina <8495707+squassina@users.noreply.github.com> --- src/animation/common.h | 5 +++-- src/config/preset.h | 28 ++++++++++++++-------------- 2 files changed, 17 insertions(+), 16 deletions(-) diff --git a/src/animation/common.h b/src/animation/common.h index ea12a3f9..9ff27df4 100644 --- a/src/animation/common.h +++ b/src/animation/common.h @@ -47,10 +47,11 @@ void init_baked_points(void) { {OPAFADEIN, &baked_points_opafadein}, {OPAFADEOUT, &baked_points_opafadeout}, }; + const size_t num_animation_types = + sizeof(animation_types) / sizeof(animation_types[0]); /* Allocate and calculate baked points for all animation types */ - for (size_t j = 0; j < sizeof(animation_types) / sizeof(animation_types[0]); - j++) { + for (size_t j = 0; j < num_animation_types; j++) { *animation_types[j].points = calloc(BAKED_POINTS_COUNT, sizeof(struct dvec2)); for (int32_t i = 0; i < BAKED_POINTS_COUNT; i++) { diff --git a/src/config/preset.h b/src/config/preset.h index 8522748f..353af572 100644 --- a/src/config/preset.h +++ b/src/config/preset.h @@ -32,20 +32,20 @@ uint32_t animation_duration_open = 400; // Animation open speed uint32_t animation_duration_tag = 300; // Animation tag speed uint32_t animation_duration_close = 300; // Animation close speed uint32_t animation_duration_focus = 0; // Animation focus opacity speed -double animation_curve_move[4] = {0.46, 1.0, 0.29, - 0.99}; // Animation curve for move -double animation_curve_open[4] = {0.46, 1.0, 0.29, - 0.99}; // Animation curve for open -double animation_curve_tag[4] = {0.46, 1.0, 0.29, - 0.99}; // Animation curve for tag -double animation_curve_close[4] = {0.46, 1.0, 0.29, - 0.99}; // Animation curve for close -double animation_curve_focus[4] = {0.46, 1.0, 0.29, - 0.99}; // Animation curve for focus -double animation_curve_opafadein[4] = { - 0.46, 1.0, 0.29, 0.99}; // Animation curve for opacity fade in -double animation_curve_opafadeout[4] = { - 0.5, 0.5, 0.5, 0.5}; // Animation curve for opacity fade out +// Animation curve for move +double animation_curve_move[4] = {0.46, 1.0, 0.29, 0.99}; +// Animation curve for open +double animation_curve_open[4] = {0.46, 1.0, 0.29, 0.99}; +// Animation curve for tag +double animation_curve_tag[4] = {0.46, 1.0, 0.29, 0.99}; +// Animation curve for close +double animation_curve_close[4] = {0.46, 1.0, 0.29, 0.99}; +// Animation curve for focus +double animation_curve_focus[4] = {0.46, 1.0, 0.29, 0.99}; +// Animation curve for opacity fade in +double animation_curve_opafadein[4] = {0.46, 1.0, 0.29, 0.99}; +// Animation curve for opacity fade out +double animation_curve_opafadeout[4] = {0.5, 0.5, 0.5, 0.5}; /* appearance */ uint32_t axis_bind_apply_timeout = From ffa83cd0fc4407bb548a2beca9f1e37e2ac0c8ac Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Wed, 18 Feb 2026 09:01:48 +0000 Subject: [PATCH 5/6] Translate remaining Chinese comments in parse_config.h to English Co-authored-by: squassina <8495707+squassina@users.noreply.github.com> --- src/config/parse_config.h | 82 ++++++++++++++++++++------------------- 1 file changed, 42 insertions(+), 40 deletions(-) diff --git a/src/config/parse_config.h b/src/config/parse_config.h index 6fff4027..b96aa8a5 100644 --- a/src/config/parse_config.h +++ b/src/config/parse_config.h @@ -113,7 +113,7 @@ typedef struct { int32_t vrr; // variable refresh rate } ConfigMonitorRule; -// 修改后的宏定义 +// Modified macro definition #define CHVT(n) \ { \ WLR_MODIFIER_CTRL | WLR_MODIFIER_ALT, \ @@ -123,7 +123,7 @@ typedef struct { } \ } -// 默认按键绑定数组 +// Default key bindings array KeyBinding default_key_bindings[] = {CHVT(1), CHVT(2), CHVT(3), CHVT(4), CHVT(5), CHVT(6), CHVT(7), CHVT(8), CHVT(9), CHVT(10), CHVT(11), CHVT(12)}; @@ -170,7 +170,7 @@ typedef struct { } ConfigTagRule; typedef struct { - char *layer_name; // 布局名称 + char *layer_name; // Layout name char *animation_type_open; char *animation_type_close; int32_t noblur; @@ -311,17 +311,17 @@ typedef struct { char autostart[3][256]; - ConfigTagRule *tag_rules; // 动态数组 - int32_t tag_rules_count; // 数量 + ConfigTagRule *tag_rules; // Dynamic array + int32_t tag_rules_count; // Count - ConfigLayerRule *layer_rules; // 动态数组 - int32_t layer_rules_count; // 数量 + ConfigLayerRule *layer_rules; // Dynamic array + int32_t layer_rules_count; // Count ConfigWinRule *window_rules; int32_t window_rules_count; - ConfigMonitorRule *monitor_rules; // 动态数组 - int32_t monitor_rules_count; // 条数 + ConfigMonitorRule *monitor_rules; // Dynamic array + int32_t monitor_rules_count; // Count KeyBinding *key_bindings; int32_t key_bindings_count; @@ -402,7 +402,7 @@ int32_t parse_double_array(const char *input, double *output, char *token; int32_t count = 0; - // 先清空整个数组 + // First clear the entire array memset(output, 0, max_count * sizeof(double)); token = strtok(dup, ","); @@ -418,8 +418,8 @@ int32_t parse_double_array(const char *input, double *output, free(dup); return -1; } - output[count] = val; // 赋值到当前count位置 - count++; // 然后才自增 + output[count] = val; // Assign to current count position + count++; // Then increment token = strtok(NULL, ","); } @@ -427,12 +427,12 @@ int32_t parse_double_array(const char *input, double *output, return count; } -// 清理字符串中的不可见字符(包括 \r, \n, 空格等) +// Clean invisible characters from string (including \r, \n, spaces, etc.) char *sanitize_string(char *str) { - // 去除首部不可见字符 + // Remove leading invisible characters while (*str != '\0' && !isprint((unsigned char)*str)) str++; - // 去除尾部不可见字符 + // Remove trailing invisible characters char *end = str + strlen(str) - 1; while (end > str && !isprint((unsigned char)*end)) end--; @@ -440,17 +440,17 @@ char *sanitize_string(char *str) { return str; } -// 解析bind组合字符串 +// Parse bind combination string void parse_bind_flags(const char *str, KeyBinding *kb) { - // 检查是否以"bind"开头 + // Check if starts with "bind" if (strncmp(str, "bind", 4) != 0) { return; } - const char *suffix = str + 4; // 跳过"bind" + const char *suffix = str + 4; // Skip "bind" - // 遍历后缀字符 + // Iterate through suffix characters for (int32_t i = 0; suffix[i] != '\0'; i++) { switch (suffix[i]) { case 's': @@ -475,7 +475,7 @@ void parse_bind_flags(const char *str, KeyBinding *kb) { } int32_t parse_circle_direction(const char *str) { - // 将输入字符串转换为小写 + // Convert input string to lowercase char lowerStr[10]; int32_t i = 0; while (str[i] && i < 9) { @@ -3276,12 +3276,12 @@ void set_value_default() { config.center_when_single_stack = center_when_single_stack; // 单个stack时是否居中 - config.numlockon = numlockon; // 是否打开右边小键盘 + config.numlockon = numlockon; // Enable numlock - config.ov_tab_mode = ov_tab_mode; // alt tab切换模式 - config.hotarea_size = hotarea_size; // 热区大小,10x10 + config.ov_tab_mode = ov_tab_mode; // Alt-tab switch mode + config.hotarea_size = hotarea_size; // Hot corner size (10x10) config.hotarea_corner = hotarea_corner; - config.enable_hotarea = enable_hotarea; // 是否启用鼠标热区 + config.enable_hotarea = enable_hotarea; // Enable mouse hot corner config.smartgaps = smartgaps; /* 1 means no outer gap when there is only one window */ config.sloppyfocus = sloppyfocus; /* focus follows mouse */ @@ -3328,8 +3328,10 @@ void set_value_default() { */ config.borderpx = borderpx; - config.overviewgappi = overviewgappi; /* overview时 窗口与边缘 缝隙大小 */ - config.overviewgappo = overviewgappo; /* overview时 窗口与窗口 缝隙大小 */ + config.overviewgappi = + overviewgappi; /* Gap size between windows and edges in overview mode */ + config.overviewgappo = + overviewgappo; /* Gap size between windows in overview mode */ config.cursor_hide_timeout = cursor_hide_timeout; config.warpcursor = warpcursor; /* Warp cursor to focused client */ @@ -3406,11 +3408,11 @@ void set_value_default() { } void set_default_key_bindings(Config *config) { - // 计算默认按键绑定的数量 + // Calculate the count of default key bindings size_t default_key_bindings_count = sizeof(default_key_bindings) / sizeof(KeyBinding); - // 重新分配内存以容纳新的默认按键绑定 + // Reallocate memory to hold new default key bindings config->key_bindings = realloc(config->key_bindings, (config->key_bindings_count + default_key_bindings_count) * @@ -3419,7 +3421,7 @@ void set_default_key_bindings(Config *config) { return; } - // 将默认按键绑定复制到配置的按键绑定数组中 + // Copy default key bindings to the config's key bindings array for (size_t i = 0; i < default_key_bindings_count; i++) { config->key_bindings[config->key_bindings_count + i] = default_key_bindings[i]; @@ -3428,7 +3430,7 @@ void set_default_key_bindings(Config *config) { config->key_bindings[config->key_bindings_count + i].islockapply = true; } - // 更新按键绑定的总数 + // Update the total count of key bindings config->key_bindings_count += default_key_bindings_count; } @@ -3438,7 +3440,7 @@ bool parse_config(void) { free_config(); - // 重置config结构体,确保所有指针初始化为NULL + // Reset config struct, ensuring all pointers are initialized to NULL memset(&config, 0, sizeof(config)); memset(&xkb_rules_rules, 0, sizeof(xkb_rules_rules)); memset(&xkb_rules_model, 0, sizeof(xkb_rules_model)); @@ -3446,7 +3448,7 @@ bool parse_config(void) { memset(&xkb_rules_variant, 0, sizeof(xkb_rules_variant)); memset(&xkb_rules_options, 0, sizeof(xkb_rules_options)); - // 初始化动态数组的指针为NULL,避免野指针 + // Initialize dynamic array pointers to NULL to avoid dangling pointers config.window_rules = NULL; config.window_rules_count = 0; config.monitor_rules = NULL; @@ -3481,19 +3483,19 @@ bool parse_config(void) { if (cli_config_path) { snprintf(filename, sizeof(filename), "%s", cli_config_path); } else { - // 获取当前用户家目录 + // Get current user's home directory const char *homedir = getenv("HOME"); if (!homedir) { - // 如果获取失败,则无法继续 + // Cannot continue if retrieval fails return false; } - // 构建日志文件路径 + // Build config file path snprintf(filename, sizeof(filename), "%s/.config/mango/config.conf", homedir); - // 检查文件是否存在 + // Check if file exists if (access(filename, F_OK) != 0) { - // 如果文件不存在,则使用 /etc/mango/config.conf + // If file doesn't exist, use /etc/mango/config.conf snprintf(filename, sizeof(filename), "%s/mango/config.conf", SYSCONFDIR); } @@ -3555,10 +3557,10 @@ void reapply_monitor_rules(void) { mr = &config.monitor_rules[ji]; - // 检查是否匹配的变量 + // Check if variable matches match_rule = true; - // 检查四个标识字段的匹配 + // Check the four identification fields for matching if (mr->name != NULL) { if (!regex_match(mr->name, m->wlr_output->name)) { match_rule = false; @@ -3586,7 +3588,7 @@ void reapply_monitor_rules(void) { } } - // 只有当所有指定的标识都匹配时才应用规则 + // Apply rule only when all specified identifiers match if (match_rule) { mx = mr->x == INT32_MAX ? m->m.x : mr->x; my = mr->y == INT32_MAX ? m->m.y : mr->y; From 3f0c11b0683000d2b18ecdb047285c956f17bad3 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Wed, 18 Feb 2026 09:03:32 +0000 Subject: [PATCH 6/6] Translate final Chinese comments in mango.c and parse_config.h Co-authored-by: squassina <8495707+squassina@users.noreply.github.com> --- src/config/parse_config.h | 23 +++++++++++++---------- src/mango.c | 9 +++++---- 2 files changed, 18 insertions(+), 14 deletions(-) diff --git a/src/config/parse_config.h b/src/config/parse_config.h index b96aa8a5..0d7ded57 100644 --- a/src/config/parse_config.h +++ b/src/config/parse_config.h @@ -1485,8 +1485,9 @@ bool parse_option(Config *config, char *key, char *value) { "scroller_proportion_preset format: %s\n", value); free(value_copy); - free(config->scroller_proportion_preset); // 释放已分配的内存 - config->scroller_proportion_preset = NULL; // 防止野指针 + free(config->scroller_proportion_preset); // Free allocated memory + config->scroller_proportion_preset = + NULL; // Prevent dangling pointer config->scroller_proportion_preset_count = 0; return false; } @@ -3265,16 +3266,18 @@ void set_value_default() { /* appearance */ config.axis_bind_apply_timeout = - axis_bind_apply_timeout; // 滚轮绑定动作的触发的时间间隔 - config.focus_on_activate = - focus_on_activate; // 收到窗口激活请求是否自动跳转聚焦 - config.new_is_master = new_is_master; // 新窗口是否插在头部 - config.default_mfact = default_mfact; // master 窗口比例 - config.default_nmaster = default_nmaster; // 默认master数量 + axis_bind_apply_timeout; // Timeout interval for mouse wheel binding + // actions + config.focus_on_activate = focus_on_activate; // Auto-focus when receiving + // window activation request + config.new_is_master = new_is_master; // Insert new windows at the head + config.default_mfact = default_mfact; // Master window proportion + config.default_nmaster = + default_nmaster; // Default number of master windows config.center_master_overspread = - center_master_overspread; // 中心master时是否铺满 + center_master_overspread; // Whether to fill screen when center master config.center_when_single_stack = - center_when_single_stack; // 单个stack时是否居中 + center_when_single_stack; // Whether to center when single stack window config.numlockon = numlockon; // Enable numlock diff --git a/src/mango.c b/src/mango.c index f1f1e7f2..ae163a75 100644 --- a/src/mango.c +++ b/src/mango.c @@ -274,8 +274,8 @@ typedef struct { struct wl_list link; struct wlr_input_device *wlr_device; struct libinput_device *libinput_device; - struct wl_listener destroy_listener; // 用于监听设备销毁事件 - void *device_data; // 新增:指向设备特定数据(如 Switch) + struct wl_listener destroy_listener; // Listen for device destruction events + void *device_data; // Added: pointer to device-specific data (e.g. Switch) } InputDevice; typedef struct { @@ -586,8 +586,9 @@ static void pinch_end(struct wl_listener *listener, void *data); static void hold_begin(struct wl_listener *listener, void *data); static void hold_end(struct wl_listener *listener, void *data); static void checkidleinhibitor(struct wlr_surface *exclude); -static void cleanup(void); // 退出清理 -static void cleanupmon(struct wl_listener *listener, void *data); // 退出清理 +static void cleanup(void); // Cleanup on exit +static void cleanupmon(struct wl_listener *listener, + void *data); // Monitor cleanup static void closemon(Monitor *m); static void cleanuplisteners(void); static void toggle_hotarea(int32_t x_root, int32_t y_root); // 触发热区