From a34cde4e76ea1368a72a71bf5ffd99bc0faf7f8b Mon Sep 17 00:00:00 2001 From: DreamMaoMao <2523610504@qq.com> Date: Sat, 14 Jun 2025 12:12:36 +0800 Subject: [PATCH 01/27] fix: bw will reset by a wrong way --- 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 5860fe9..25c5db8 100644 --- a/src/config/parse_config.h +++ b/src/config/parse_config.h @@ -2244,7 +2244,7 @@ void reload_config(const Arg *arg) { // reset border width when config change wl_list_for_each(c, &clients, link) { if (c && !c->iskilling) { - if (c->bw) { + if (c->bw && !c->isnoborder) { c->bw = borderpx; } } From ab95c110d9800f4b124c306fdeae25588f766783 Mon Sep 17 00:00:00 2001 From: DreamMaoMao <2523610504@qq.com> Date: Sat, 14 Jun 2025 11:59:43 +0800 Subject: [PATCH 02/27] opt: x11 app miss last frame scale --- src/maomao.c | 5 ----- 1 file changed, 5 deletions(-) diff --git a/src/maomao.c b/src/maomao.c index 5328260..b4c3769 100644 --- a/src/maomao.c +++ b/src/maomao.c @@ -5121,11 +5121,6 @@ void buffer_set_effect(Client *c, animationScale data) { data.should_scale = false; } - if (client_is_x11(c) && c->current.height >= c->animation.current.height && - c->current.width >= c->animation.current.width) { - data.should_scale = false; - } - if (c == grabc) data.should_scale = false; From 1bbf6adbc98287e24ca48952d551fd4c905c1a48 Mon Sep 17 00:00:00 2001 From: DreamMaoMao <2523610504@qq.com> Date: Sat, 14 Jun 2025 15:59:41 +0800 Subject: [PATCH 03/27] feat: focusmon dispatch support mon name --- src/config/parse_config.h | 3 +++ src/maomao.c | 15 ++++++++++++++- 2 files changed, 17 insertions(+), 1 deletion(-) diff --git a/src/config/parse_config.h b/src/config/parse_config.h index 25c5db8..e6c123b 100644 --- a/src/config/parse_config.h +++ b/src/config/parse_config.h @@ -686,6 +686,9 @@ FuncType parse_func_name(char *func_name, Arg *arg, char *arg_value, } else if (strcmp(func_name, "focusmon") == 0) { func = focusmon; (*arg).i = parse_direction(arg_value); + if((*arg).i == UNDIR) { + (*arg).v = strdup(arg_value); + } } else if (strcmp(func_name, "tagmon") == 0) { func = tagmon; (*arg).i = parse_direction(arg_value); diff --git a/src/maomao.c b/src/maomao.c index b4c3769..9d3f08f 100644 --- a/src/maomao.c +++ b/src/maomao.c @@ -4061,11 +4061,24 @@ void focusclient(Client *c, int lift) { void focusmon(const Arg *arg) { Client *c; + Monitor *m = NULL; int i = 0, nmons = wl_list_length(&mons); - if (nmons) { + if (nmons && arg->i != UNDIR) { do /* don't switch to disabled mons */ selmon = dirtomon(arg->i); while (!selmon->wlr_output->enabled && i++ < nmons); + } else if(arg->v) { + wl_list_for_each(m, &mons, link) { + if (!m->wlr_output->enabled) { + continue; + } + if(regex_match(arg->v, m->wlr_output->name)) { + selmon = m; + break; + } + } + } else { + return; } warp_cursor_to_selmon(selmon); c = focustop(selmon); From e0c3101c0c08e549f03e83a5ae7a38f245a93813 Mon Sep 17 00:00:00 2001 From: DreamMaoMao <2523610504@qq.com> Date: Sat, 14 Jun 2025 19:52:10 +0800 Subject: [PATCH 04/27] fix: error clip width height --- src/maomao.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/maomao.c b/src/maomao.c index 9d3f08f..3c0705a 100644 --- a/src/maomao.c +++ b/src/maomao.c @@ -1221,7 +1221,7 @@ struct uvec2 clip_to_hide(Client *c, struct wlr_box *clip_box) { clip_box->width = clip_box->width - (c->animation.current.x + c->animation.current.width - - c->mon->m.x - c->mon->m.width) + + c->mon->m.x - c->mon->m.width) - c->bw; } @@ -1235,7 +1235,7 @@ struct uvec2 clip_to_hide(Client *c, struct wlr_box *clip_box) { clip_box->height = clip_box->height - (c->animation.current.y + c->animation.current.height - - c->mon->m.y - c->mon->m.height) + + c->mon->m.y - c->mon->m.height) - c->bw; } } From ed2595d9ad8bc0744803d0ffbe119fbb4fc3aeda Mon Sep 17 00:00:00 2001 From: DreamMaoMao <2523610504@qq.com> Date: Sat, 14 Jun 2025 20:41:26 +0800 Subject: [PATCH 05/27] opt: optimzie border offset caculate --- src/maomao.c | 183 ++++++++++++++++++++++++++++----------------------- 1 file changed, 101 insertions(+), 82 deletions(-) diff --git a/src/maomao.c b/src/maomao.c index 3c0705a..097fe13 100644 --- a/src/maomao.c +++ b/src/maomao.c @@ -1105,96 +1105,115 @@ bool check_hit_no_border(Client *c) { return hit_no_border; } -void apply_border(Client *c, struct wlr_box clip_box, int offsetx, - int offsety) { - bool hit_no_border = false; +void apply_border(Client *c, struct wlr_box clip_box, int offsetx, int offsety) { + if (c->iskilling || !client_surface(c)->mapped) + return; - if (c->iskilling || !client_surface(c)->mapped) - return; + bool hit_no_border = check_hit_no_border(c); - if (clip_box.width > c->animation.current.width) { - clip_box.width = c->animation.current.width; - } + // Handle no-border cases + if (hit_no_border && smartgaps) { + c->bw = 0; + c->fake_no_border = true; + } else if (hit_no_border && !smartgaps) { + for (int i = 0; i < 4; i++) + set_rect_size(c->border[i], 0, 0); + wlr_scene_node_set_position(&c->scene_surface->node, c->bw, c->bw); + c->fake_no_border = true; + return; + } else if (!c->isfullscreen && VISIBLEON(c, c->mon)) { + c->bw = c->isnoborder ? 0 : borderpx; + c->fake_no_border = false; + } - if (clip_box.height > c->animation.current.height) { - clip_box.height = c->animation.current.height; - } + struct wlr_box geom = c->animation.current; + int bw = c->bw; - hit_no_border = check_hit_no_border(c); + // Calculate how much the window is outside the monitor + // These values will be positive when window is outside the monitor + int outside_left = GEZERO(c->mon->m.x - c->animation.current.x); + int outside_top = GEZERO(c->mon->m.y - c->animation.current.y); + int outside_right = GEZERO((c->animation.current.x + c->animation.current.width) - + (c->mon->m.x + c->mon->m.width)); + int outside_bottom = GEZERO((c->animation.current.y + c->animation.current.height) - + (c->mon->m.y + c->mon->m.height)); - if (hit_no_border && smartgaps) { - c->bw = 0; - c->fake_no_border = true; - } else if (hit_no_border && !smartgaps) { - set_rect_size(c->border[0], 0, 0); - set_rect_size(c->border[1], 0, 0); - set_rect_size(c->border[2], 0, 0); - set_rect_size(c->border[3], 0, 0); - wlr_scene_node_set_position(&c->scene_surface->node, c->bw, c->bw); - c->fake_no_border = true; - return; - } else if (!c->isfullscreen && VISIBLEON(c, c->mon)) { - c->bw = c->isnoborder ? 0 : borderpx; - c->fake_no_border = false; - } + // Initialize border dimensions + int top_width = geom.width; + int top_height = bw; + int bottom_width = geom.width; + int bottom_height = bw; + int left_width = bw; + int left_height = geom.height - 2 * bw; + int right_width = bw; + int right_height = geom.height - 2 * bw; - wlr_scene_node_set_position(&c->scene_surface->node, c->bw, c->bw); - set_rect_size(c->border[0], clip_box.width, c->bw); - set_rect_size(c->border[1], clip_box.width, c->bw); - set_rect_size(c->border[2], c->bw, clip_box.height - 2 * c->bw); - set_rect_size(c->border[3], c->bw, clip_box.height - 2 * c->bw); - wlr_scene_node_set_position(&c->border[0]->node, 0, 0); - wlr_scene_node_set_position(&c->border[2]->node, 0, c->bw); - wlr_scene_node_set_position(&c->border[1]->node, 0, - clip_box.height - c->bw); - wlr_scene_node_set_position(&c->border[3]->node, clip_box.width - c->bw, - c->bw); + // Initialize border positions + int top_x = 0; + int top_y = 0; + int bottom_x = 0; + int bottom_y = geom.height - bottom_height; + int left_x = 0; + int left_y = bw; + int right_x = geom.width - right_width; + int right_y = bw; + + // Adjust borders when window is outside monitor + if (ISTILED(c) || c->animation.tagining || c->animation.tagouted || c->animation.tagouting) { + // Top border - reduce height when window goes above monitor + if (outside_top > 0) { + top_height = GEZERO(bw - outside_top); + top_y = top_y + outside_top; + left_height = left_height - outside_top; + right_height = right_height - outside_top; + left_y = left_y + outside_top; + right_y = right_y + outside_top; + } + + // Bottom border - reduce height when window goes below monitor + if (outside_bottom > 0) { + bottom_height = GEZERO(bw - outside_bottom); + left_height = left_height - outside_bottom; + right_height = right_height - outside_bottom; + } + + // Left border - reduce width when window goes left of monitor + if (outside_left > 0) { + left_width = GEZERO(bw - outside_left); + left_x = left_x + outside_left; + top_width = top_width - outside_left; + bottom_width = bottom_width - outside_left; + top_x = top_x + outside_left; + bottom_x = bottom_x + outside_left; + } + + // Right border - reduce width when window goes right of monitor + if (outside_right > 0) { + right_width = GEZERO(bw - outside_right); + top_width = top_width - outside_right; + bottom_width = bottom_width - outside_right; + } + + } + + // Position the surface within the borders + wlr_scene_node_set_position(&c->scene_surface->node, + bw, + bw); + + // Set border sizes + set_rect_size(c->border[0], top_width, top_height); // Top + set_rect_size(c->border[1], bottom_width, bottom_height); // Bottom + set_rect_size(c->border[2], left_width, left_height); // Left + set_rect_size(c->border[3], right_width, right_height); // Right + + // Position borders with offsets + wlr_scene_node_set_position(&c->border[0]->node, top_x, top_y ); + wlr_scene_node_set_position(&c->border[1]->node, bottom_x, bottom_y); + wlr_scene_node_set_position(&c->border[2]->node, left_x , left_y); + wlr_scene_node_set_position(&c->border[3]->node, right_x, right_y); - if (ISTILED(c) || c->animation.tagining || c->animation.tagouted || - c->animation.tagouting) { - if (c->animation.current.x < c->mon->m.x) { - set_rect_size(c->border[2], GEZERO(c->bw - offsetx), - clip_box.height - 2 * c->bw); - } else if (c->animation.current.x + c->animation.current.width > - c->mon->m.x + c->mon->m.width) { - set_rect_size(c->border[3], - GEZERO(c->bw - GEZERO(c->animation.current.x + - c->animation.current.width - - c->mon->m.x - c->mon->m.width)), - clip_box.height - 2 * c->bw); - set_rect_size(c->border[0], clip_box.width + c->bw, - GEZERO(c->bw - offsety)); - set_rect_size( - c->border[1], clip_box.width + c->bw, - GEZERO(c->bw - GEZERO(c->animation.current.y + - c->animation.current.height - - c->mon->m.y - c->mon->m.height))); - } else if (c->animation.current.y < c->mon->m.y) { - set_rect_size(c->border[0], clip_box.width, - GEZERO(c->bw - offsety)); - } else if (c->animation.current.y + c->animation.current.height > - c->mon->m.y + c->mon->m.height) { - set_rect_size( - c->border[1], clip_box.width, - GEZERO(c->bw - GEZERO(c->animation.current.y + - c->animation.current.height - - c->mon->m.y - c->mon->m.height))); - set_rect_size(c->border[2], GEZERO(c->bw - offsetx), - clip_box.height - c->bw); - set_rect_size(c->border[3], - GEZERO(c->bw - GEZERO(c->animation.current.x + - c->animation.current.width - - c->mon->m.x - c->mon->m.width)), - clip_box.height - c->bw); - } - } - wlr_scene_node_set_position(&c->border[0]->node, offsetx, offsety); - wlr_scene_node_set_position(&c->border[2]->node, offsetx, c->bw + offsety); - wlr_scene_node_set_position(&c->border[1]->node, offsetx, - clip_box.height - c->bw + offsety); - wlr_scene_node_set_position( - &c->border[3]->node, clip_box.width - c->bw + offsetx, c->bw + offsety); } struct uvec2 clip_to_hide(Client *c, struct wlr_box *clip_box) { From 1a2865796f09687ed9fa0398c1f3ec09e29440ac Mon Sep 17 00:00:00 2001 From: DreamMaoMao <2523610504@qq.com> Date: Sat, 14 Jun 2025 20:50:29 +0800 Subject: [PATCH 06/27] fix: ainmaiton clip offset --- src/maomao.c | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/src/maomao.c b/src/maomao.c index 097fe13..ee696f5 100644 --- a/src/maomao.c +++ b/src/maomao.c @@ -1076,9 +1076,9 @@ void client_animation_next_tick(Client *c) { } void client_actual_size(Client *c, uint32_t *width, uint32_t *height) { - *width = c->animation.current.width; + *width = c->animation.current.width - c->bw; - *height = c->animation.current.height; + *height = c->animation.current.height - c->bw; } void set_rect_size(struct wlr_scene_rect *rect, int width, int height) { @@ -1240,8 +1240,7 @@ struct uvec2 clip_to_hide(Client *c, struct wlr_box *clip_box) { clip_box->width = clip_box->width - (c->animation.current.x + c->animation.current.width - - c->mon->m.x - c->mon->m.width) - - c->bw; + c->mon->m.x - c->mon->m.width); } if (c->animation.current.y < c->mon->m.y) { @@ -1254,8 +1253,7 @@ struct uvec2 clip_to_hide(Client *c, struct wlr_box *clip_box) { clip_box->height = clip_box->height - (c->animation.current.y + c->animation.current.height - - c->mon->m.y - c->mon->m.height) - - c->bw; + c->mon->m.y - c->mon->m.height); } } @@ -1333,8 +1331,8 @@ void client_apply_clip(Client *c) { wlr_scene_subsurface_tree_set_clip(&c->scene_surface->node, &clip_box); scale_data.should_scale = true; - scale_data.width = clip_box.width - 2 * c->bw; - scale_data.height = clip_box.height - 2 * c->bw; + scale_data.width = clip_box.width - c->bw; + scale_data.height = clip_box.height - c->bw; scale_data.width_scale = (float)scale_data.width / (geometry.width - offset.x); scale_data.height_scale = From 247463a1dd29886092dbc1f5e6975b622b1d912e Mon Sep 17 00:00:00 2001 From: DreamMaoMao <2523610504@qq.com> Date: Sat, 14 Jun 2025 21:44:56 +0800 Subject: [PATCH 07/27] opt: optimize code struct --- src/maomao.c | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/src/maomao.c b/src/maomao.c index ee696f5..82284d6 100644 --- a/src/maomao.c +++ b/src/maomao.c @@ -631,8 +631,7 @@ static struct wlr_box setclient_coordinate_center(Client *c, static unsigned int get_tags_first_tag(unsigned int tags); static void client_commit(Client *c); -static void apply_border(Client *c, struct wlr_box clip_box, int offsetx, - int offsety); +static void apply_border(Client *c); static void client_set_opacity(Client *c, double opacity); static void init_baked_points(void); static void scene_buffer_apply_opacity(struct wlr_scene_buffer *buffer, int sx, @@ -1105,7 +1104,7 @@ bool check_hit_no_border(Client *c) { return hit_no_border; } -void apply_border(Client *c, struct wlr_box clip_box, int offsetx, int offsety) { +void apply_border(Client *c) { if (c->iskilling || !client_surface(c)->mapped) return; @@ -1295,7 +1294,7 @@ void client_apply_clip(Client *c) { c->geom; client_get_clip(c, &clip_box); offset = clip_to_hide(c, &clip_box); - apply_border(c, clip_box, offset.x, offset.y); + apply_border(c); if (clip_box.width <= 0 || clip_box.height <= 0) return; @@ -1323,7 +1322,7 @@ void client_apply_clip(Client *c) { } offset = clip_to_hide(c, &clip_box); - apply_border(c, clip_box, offset.x, offset.y); + apply_border(c); if (clip_box.width <= 0 || clip_box.height <= 0) return; @@ -5467,13 +5466,13 @@ void resize(Client *c, struct wlr_box geo, int interact) { c->configure_serial = client_set_size(c, c->geom.width - 2 * c->bw, c->geom.height - 2 * c->bw); - if (c == grabc) { + if (!animations || c == grabc) { c->animation.running = false; c->need_output_flush = false; c->animainit_geom = c->current = c->pending = c->animation.current = c->geom; wlr_scene_node_set_position(&c->scene->node, c->geom.x, c->geom.y); - apply_border(c, c->geom, 0, 0); + apply_border(c); client_get_clip(c, &clip); wlr_scene_subsurface_tree_set_clip(&c->scene_surface->node, &clip); return; From 20d132de3f48103bca9e2e862fbcbd436c3defe5 Mon Sep 17 00:00:00 2001 From: DreamMaoMao <2523610504@qq.com> Date: Sat, 14 Jun 2025 21:45:06 +0800 Subject: [PATCH 08/27] format code --- src/config/parse_config.h | 2 +- src/maomao.c | 175 +++++++++++++++++++------------------- 2 files changed, 87 insertions(+), 90 deletions(-) diff --git a/src/config/parse_config.h b/src/config/parse_config.h index e6c123b..e817f48 100644 --- a/src/config/parse_config.h +++ b/src/config/parse_config.h @@ -686,7 +686,7 @@ FuncType parse_func_name(char *func_name, Arg *arg, char *arg_value, } else if (strcmp(func_name, "focusmon") == 0) { func = focusmon; (*arg).i = parse_direction(arg_value); - if((*arg).i == UNDIR) { + if ((*arg).i == UNDIR) { (*arg).v = strdup(arg_value); } } else if (strcmp(func_name, "tagmon") == 0) { diff --git a/src/maomao.c b/src/maomao.c index 82284d6..b719aaa 100644 --- a/src/maomao.c +++ b/src/maomao.c @@ -1105,114 +1105,112 @@ bool check_hit_no_border(Client *c) { } void apply_border(Client *c) { - if (c->iskilling || !client_surface(c)->mapped) - return; + if (c->iskilling || !client_surface(c)->mapped) + return; - bool hit_no_border = check_hit_no_border(c); + bool hit_no_border = check_hit_no_border(c); - // Handle no-border cases - if (hit_no_border && smartgaps) { - c->bw = 0; - c->fake_no_border = true; - } else if (hit_no_border && !smartgaps) { - for (int i = 0; i < 4; i++) - set_rect_size(c->border[i], 0, 0); - wlr_scene_node_set_position(&c->scene_surface->node, c->bw, c->bw); - c->fake_no_border = true; - return; - } else if (!c->isfullscreen && VISIBLEON(c, c->mon)) { - c->bw = c->isnoborder ? 0 : borderpx; - c->fake_no_border = false; - } + // Handle no-border cases + if (hit_no_border && smartgaps) { + c->bw = 0; + c->fake_no_border = true; + } else if (hit_no_border && !smartgaps) { + for (int i = 0; i < 4; i++) + set_rect_size(c->border[i], 0, 0); + wlr_scene_node_set_position(&c->scene_surface->node, c->bw, c->bw); + c->fake_no_border = true; + return; + } else if (!c->isfullscreen && VISIBLEON(c, c->mon)) { + c->bw = c->isnoborder ? 0 : borderpx; + c->fake_no_border = false; + } - struct wlr_box geom = c->animation.current; - int bw = c->bw; + struct wlr_box geom = c->animation.current; + int bw = c->bw; - // Calculate how much the window is outside the monitor - // These values will be positive when window is outside the monitor - int outside_left = GEZERO(c->mon->m.x - c->animation.current.x); - int outside_top = GEZERO(c->mon->m.y - c->animation.current.y); - int outside_right = GEZERO((c->animation.current.x + c->animation.current.width) - - (c->mon->m.x + c->mon->m.width)); - int outside_bottom = GEZERO((c->animation.current.y + c->animation.current.height) - - (c->mon->m.y + c->mon->m.height)); + // Calculate how much the window is outside the monitor + // These values will be positive when window is outside the monitor + int outside_left = GEZERO(c->mon->m.x - c->animation.current.x); + int outside_top = GEZERO(c->mon->m.y - c->animation.current.y); + int outside_right = + GEZERO((c->animation.current.x + c->animation.current.width) - + (c->mon->m.x + c->mon->m.width)); + int outside_bottom = + GEZERO((c->animation.current.y + c->animation.current.height) - + (c->mon->m.y + c->mon->m.height)); - // Initialize border dimensions - int top_width = geom.width; - int top_height = bw; - int bottom_width = geom.width; - int bottom_height = bw; - int left_width = bw; - int left_height = geom.height - 2 * bw; - int right_width = bw; - int right_height = geom.height - 2 * bw; + // Initialize border dimensions + int top_width = geom.width; + int top_height = bw; + int bottom_width = geom.width; + int bottom_height = bw; + int left_width = bw; + int left_height = geom.height - 2 * bw; + int right_width = bw; + int right_height = geom.height - 2 * bw; - // Initialize border positions - int top_x = 0; - int top_y = 0; - int bottom_x = 0; - int bottom_y = geom.height - bottom_height; - int left_x = 0; - int left_y = bw; - int right_x = geom.width - right_width; - int right_y = bw; + // Initialize border positions + int top_x = 0; + int top_y = 0; + int bottom_x = 0; + int bottom_y = geom.height - bottom_height; + int left_x = 0; + int left_y = bw; + int right_x = geom.width - right_width; + int right_y = bw; - // Adjust borders when window is outside monitor - if (ISTILED(c) || c->animation.tagining || c->animation.tagouted || c->animation.tagouting) { - // Top border - reduce height when window goes above monitor - if (outside_top > 0) { - top_height = GEZERO(bw - outside_top); - top_y = top_y + outside_top; + // Adjust borders when window is outside monitor + if (ISTILED(c) || c->animation.tagining || c->animation.tagouted || + c->animation.tagouting) { + // Top border - reduce height when window goes above monitor + if (outside_top > 0) { + top_height = GEZERO(bw - outside_top); + top_y = top_y + outside_top; left_height = left_height - outside_top; right_height = right_height - outside_top; left_y = left_y + outside_top; right_y = right_y + outside_top; - } + } - // Bottom border - reduce height when window goes below monitor - if (outside_bottom > 0) { - bottom_height = GEZERO(bw - outside_bottom); + // Bottom border - reduce height when window goes below monitor + if (outside_bottom > 0) { + bottom_height = GEZERO(bw - outside_bottom); left_height = left_height - outside_bottom; right_height = right_height - outside_bottom; - } + } - // Left border - reduce width when window goes left of monitor - if (outside_left > 0) { - left_width = GEZERO(bw - outside_left); - left_x = left_x + outside_left; + // Left border - reduce width when window goes left of monitor + if (outside_left > 0) { + left_width = GEZERO(bw - outside_left); + left_x = left_x + outside_left; top_width = top_width - outside_left; bottom_width = bottom_width - outside_left; top_x = top_x + outside_left; bottom_x = bottom_x + outside_left; - } + } - // Right border - reduce width when window goes right of monitor - if (outside_right > 0) { - right_width = GEZERO(bw - outside_right); + // Right border - reduce width when window goes right of monitor + if (outside_right > 0) { + right_width = GEZERO(bw - outside_right); top_width = top_width - outside_right; bottom_width = bottom_width - outside_right; - } + } + } - } - - // Position the surface within the borders - wlr_scene_node_set_position(&c->scene_surface->node, - bw, - bw); - - // Set border sizes - set_rect_size(c->border[0], top_width, top_height); // Top - set_rect_size(c->border[1], bottom_width, bottom_height); // Bottom - set_rect_size(c->border[2], left_width, left_height); // Left - set_rect_size(c->border[3], right_width, right_height); // Right - - // Position borders with offsets - wlr_scene_node_set_position(&c->border[0]->node, top_x, top_y ); - wlr_scene_node_set_position(&c->border[1]->node, bottom_x, bottom_y); - wlr_scene_node_set_position(&c->border[2]->node, left_x , left_y); - wlr_scene_node_set_position(&c->border[3]->node, right_x, right_y); + // Position the surface within the borders + wlr_scene_node_set_position(&c->scene_surface->node, bw, bw); + // Set border sizes + set_rect_size(c->border[0], top_width, top_height); // Top + set_rect_size(c->border[1], bottom_width, bottom_height); // Bottom + set_rect_size(c->border[2], left_width, left_height); // Left + set_rect_size(c->border[3], right_width, right_height); // Right + // Position borders with offsets + wlr_scene_node_set_position(&c->border[0]->node, top_x, top_y); + wlr_scene_node_set_position(&c->border[1]->node, bottom_x, bottom_y); + wlr_scene_node_set_position(&c->border[2]->node, left_x, left_y); + wlr_scene_node_set_position(&c->border[3]->node, right_x, right_y); } struct uvec2 clip_to_hide(Client *c, struct wlr_box *clip_box) { @@ -1236,10 +1234,9 @@ struct uvec2 clip_to_hide(Client *c, struct wlr_box *clip_box) { clip_box->width = clip_box->width - offsetx; } else if (c->animation.current.x + c->animation.current.width > c->mon->m.x + c->mon->m.width) { - clip_box->width = - clip_box->width - - (c->animation.current.x + c->animation.current.width - - c->mon->m.x - c->mon->m.width); + clip_box->width = clip_box->width - (c->animation.current.x + + c->animation.current.width - + c->mon->m.x - c->mon->m.width); } if (c->animation.current.y < c->mon->m.y) { @@ -4083,12 +4080,12 @@ void focusmon(const Arg *arg) { do /* don't switch to disabled mons */ selmon = dirtomon(arg->i); while (!selmon->wlr_output->enabled && i++ < nmons); - } else if(arg->v) { + } else if (arg->v) { wl_list_for_each(m, &mons, link) { if (!m->wlr_output->enabled) { continue; } - if(regex_match(arg->v, m->wlr_output->name)) { + if (regex_match(arg->v, m->wlr_output->name)) { selmon = m; break; } From b97222b6b09af3a9788826de26f170bbfaef6ff3 Mon Sep 17 00:00:00 2001 From: DreamMaoMao <2523610504@qq.com> Date: Sun, 15 Jun 2025 11:12:47 +0800 Subject: [PATCH 09/27] feat:add arg to keep tag when tagmon --- src/config/parse_config.h | 1 + src/maomao.c | 3 ++- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/src/config/parse_config.h b/src/config/parse_config.h index e817f48..66a73eb 100644 --- a/src/config/parse_config.h +++ b/src/config/parse_config.h @@ -692,6 +692,7 @@ FuncType parse_func_name(char *func_name, Arg *arg, char *arg_value, } else if (strcmp(func_name, "tagmon") == 0) { func = tagmon; (*arg).i = parse_direction(arg_value); + (*arg).ui = atoi(arg_value2); } else if (strcmp(func_name, "incgaps") == 0) { func = incgaps; (*arg).i = atoi(arg_value); diff --git a/src/maomao.c b/src/maomao.c index b719aaa..54122e7 100644 --- a/src/maomao.c +++ b/src/maomao.c @@ -6702,13 +6702,14 @@ void tagsilent(const Arg *arg) { void tagmon(const Arg *arg) { Client *c = focustop(selmon); + unsigned int newtags = arg->ui ? c->tags : 0; Monitor *m; if (c) { if (c == selmon->sel) { selmon->sel = NULL; } m = dirtomon(arg->i); - setmon(c, m, 0, true); + setmon(c, m, newtags, true); reset_foreign_tolevel(c); // 重新计算居中的坐标 if (c->isfloating) { From 71359a8dbb2df79546f36283ba35dd3e3005162f Mon Sep 17 00:00:00 2001 From: DreamMaoMao <2523610504@qq.com> Date: Sun, 15 Jun 2025 09:39:34 +0800 Subject: [PATCH 10/27] feat: record and restore to old mon when mon reconnect --- src/maomao.c | 74 ++++++++++++++++++++++++++++++++++------------------ 1 file changed, 49 insertions(+), 25 deletions(-) diff --git a/src/maomao.c b/src/maomao.c index b719aaa..7392fda 100644 --- a/src/maomao.c +++ b/src/maomao.c @@ -286,6 +286,7 @@ struct Client { int nofadeout; int no_force_center; int isunglobal; + char oldmonname[128]; }; typedef struct { @@ -650,6 +651,7 @@ static void handlecursoractivity(void); static int hidecursor(void *data); static bool check_hit_no_border(Client *c); static void reset_keyboard_layout(void); +static void client_update_oldmonname_record(Client *c, Monitor *m); #include "data/static_keymap.h" #include "dispatch/dispatch.h" @@ -1084,6 +1086,18 @@ void set_rect_size(struct wlr_scene_rect *rect, int width, int height) { wlr_scene_rect_set_size(rect, GEZERO(width), GEZERO(height)); } +void client_change_mon(Client *c, Monitor *m) { + setmon(c, m, c->tags, true); + reset_foreign_tolevel(c); + if (c->isfloating) { + c->oldgeom = c->geom = setclient_coordinate_center(c, c->geom, 0, 0); + } + if (VISIBLEON(c, m) && c->isfloating) { + wlr_scene_node_set_enabled(&c->scene->node, true); + client_set_suspended(c, false); + } +} + bool check_hit_no_border(Client *c) { int i; bool hit_no_border = false; @@ -1785,12 +1799,13 @@ setclient_coordinate_center(Client *c, struct wlr_box geom, int offsetx, struct wlr_box tempbox; int offset = 0; int len = 0; + Monitor *m = c->mon ? c->mon : selmon; unsigned int cbw = check_hit_no_border(c) ? c->bw : 0; if (!c->no_force_center) { - tempbox.x = selmon->w.x + (selmon->w.width - geom.width) / 2; - tempbox.y = selmon->w.y + (selmon->w.height - geom.height) / 2; + tempbox.x = m->w.x + (m->w.width - geom.width) / 2; + tempbox.y = m->w.y + (m->w.height - geom.height) / 2; } else { tempbox.x = geom.x; tempbox.y = geom.y; @@ -1800,29 +1815,29 @@ setclient_coordinate_center(Client *c, struct wlr_box geom, int offsetx, tempbox.height = geom.height; if (offsetx != 0) { - len = selmon->w.width / 2; + len = m->w.width / 2; offset = len * (offsetx / 100.0); tempbox.x += offset; // 限制窗口在屏幕内 - if (tempbox.x < selmon->m.x) { - tempbox.x = selmon->m.x - cbw; + if (tempbox.x < m->m.x) { + tempbox.x = m->m.x - cbw; } - if (tempbox.x + tempbox.width > selmon->m.x + selmon->m.width) { - tempbox.x = selmon->m.x + selmon->m.width - tempbox.width + cbw; + if (tempbox.x + tempbox.width > m->m.x + m->m.width) { + tempbox.x = m->m.x + m->m.width - tempbox.width + cbw; } } if (offsety != 0) { - len = selmon->w.height; + len = m->w.height; offset = len * (offsety / 100.0); tempbox.y += offset; // 限制窗口在屏幕内 - if (tempbox.y < selmon->m.y) { - tempbox.y = selmon->m.y - cbw; + if (tempbox.y < m->m.y) { + tempbox.y = m->m.y - cbw; } - if (tempbox.y + tempbox.height > selmon->m.y + selmon->m.height) { - tempbox.y = selmon->m.y + selmon->m.height - tempbox.height + cbw; + if (tempbox.y + tempbox.height > m->m.y + m->m.height) { + tempbox.y = m->m.y + m->m.height - tempbox.height + cbw; } } @@ -2813,6 +2828,7 @@ buttonpress(struct wl_listener *listener, void *data) { selmon->sel = NULL; } selmon = xytomon(cursor->x, cursor->y); + client_update_oldmonname_record(grabc, selmon); setmon(grabc, selmon, 0, true); reset_foreign_tolevel(grabc); selmon->prevsel = selmon->sel; @@ -2992,21 +3008,16 @@ void closemon(Monitor *m) { } wl_list_for_each(c, &clients, link) { - if (c->isfloating && c->geom.x > m->m.width) - resize(c, - (struct wlr_box){.x = c->geom.x - m->w.width, - .y = c->geom.y, - .width = c->geom.width, - .height = c->geom.height}, - 0); if (c->mon == m) { + if (selmon == NULL) { remove_foreign_topleve(c); c->mon = NULL; } else { - setmon(c, selmon, c->tags, true); - reset_foreign_tolevel(c); + client_change_mon(c, selmon); } + + client_update_oldmonname_record(c, m); } } if (selmon) { @@ -6700,6 +6711,14 @@ void tagsilent(const Arg *arg) { arrange(target_client->mon, false); } +void client_update_oldmonname_record(Client *c, Monitor *m) { + if (!c || c->iskilling || !client_surface(c)->mapped || c->mon == m) + return; + memset(c->oldmonname, 0, sizeof(c->oldmonname)); + strncpy(c->oldmonname, m->wlr_output->name, sizeof(c->oldmonname) - 1); + c->oldmonname[sizeof(c->oldmonname) - 1] = '\0'; +} + void tagmon(const Arg *arg) { Client *c = focustop(selmon); Monitor *m; @@ -6708,6 +6727,7 @@ void tagmon(const Arg *arg) { selmon->sel = NULL; } m = dirtomon(arg->i); + client_update_oldmonname_record(c, m); setmon(c, m, 0, true); reset_foreign_tolevel(c); // 重新计算居中的坐标 @@ -7288,16 +7308,20 @@ void updatemons(struct wl_listener *listener, void *data) { config_head->state.x = m->m.x; config_head->state.y = m->m.y; - if (!selmon) { - selmon = m; + selmon = m; + + wl_list_for_each(c, &clients, link) { + if (c->mon && c->mon != m && client_surface(c)->mapped && + strcmp(c->oldmonname, m->wlr_output->name) == 0) { + client_change_mon(c, m); + } } } if (selmon && selmon->wlr_output->enabled) { wl_list_for_each(c, &clients, link) { if (!c->mon && client_surface(c)->mapped) { - setmon(c, selmon, c->tags, true); - reset_foreign_tolevel(c); + client_change_mon(c, selmon); } } focusclient(focustop(selmon), 1); From 3ed80345dc91dafeb5209c85b6c131919b77afd5 Mon Sep 17 00:00:00 2001 From: DreamMaoMao <2523610504@qq.com> Date: Sun, 15 Jun 2025 12:54:08 +0800 Subject: [PATCH 11/27] opt: if tagmon target not is current tag, view to target tag --- src/maomao.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/maomao.c b/src/maomao.c index 11f2787..6b2a98d 100644 --- a/src/maomao.c +++ b/src/maomao.c @@ -6723,6 +6723,7 @@ void tagmon(const Arg *arg) { Client *c = focustop(selmon); unsigned int newtags = arg->ui ? c->tags : 0; Monitor *m; + unsigned int target; if (c) { if (c == selmon->sel) { selmon->sel = NULL; @@ -6741,11 +6742,15 @@ void tagmon(const Arg *arg) { (int)(c->geom.height * c->mon->w.height / selmon->w.height); selmon = c->mon; c->geom = setclient_coordinate_center(c, c->geom, 0, 0); + target = get_tags_first_tag(c->tags); + view(&(Arg){.ui = target}, true); focusclient(c, 1); c->oldgeom = c->geom; resize(c, c->geom, 1); } else { selmon = c->mon; + target = get_tags_first_tag(c->tags); + view(&(Arg){.ui = target}, true); focusclient(c, 1); arrange(selmon, false); } From 22665c8952c76da9a9cc69e3374351c9630af719 Mon Sep 17 00:00:00 2001 From: DreamMaoMao <2523610504@qq.com> Date: Sun, 15 Jun 2025 13:00:34 +0800 Subject: [PATCH 12/27] opt: support dirtomon in up and down dir --- src/maomao.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/maomao.c b/src/maomao.c index 6b2a98d..8bcb1b3 100644 --- a/src/maomao.c +++ b/src/maomao.c @@ -3742,7 +3742,9 @@ Monitor *dirtomon(enum wlr_direction dir) { selmon->m.x, selmon->m.y))) return next->data; if ((next = wlr_output_layout_farthest_output( - output_layout, dir ^ (WLR_DIRECTION_LEFT | WLR_DIRECTION_RIGHT), + output_layout, + dir ^ (WLR_DIRECTION_LEFT | WLR_DIRECTION_RIGHT | + WLR_DIRECTION_UP | WLR_DIRECTION_DOWN), selmon->wlr_output, selmon->m.x, selmon->m.y))) return next->data; return selmon; From b8703d10b77137df34ee00ae26849c36f0b6b5e6 Mon Sep 17 00:00:00 2001 From: DreamMaoMao <2523610504@qq.com> Date: Sun, 15 Jun 2025 13:16:36 +0800 Subject: [PATCH 13/27] opt: update mon not change selmon if the selmon not null --- src/maomao.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/maomao.c b/src/maomao.c index 8bcb1b3..ae6e1f5 100644 --- a/src/maomao.c +++ b/src/maomao.c @@ -7318,7 +7318,8 @@ void updatemons(struct wl_listener *listener, void *data) { config_head->state.x = m->m.x; config_head->state.y = m->m.y; - selmon = m; + if (!selmon) + selmon = m; wl_list_for_each(c, &clients, link) { if (c->mon && c->mon != m && client_surface(c)->mapped && From 6a484e6129f67896df6d61322763637c22c8b00b Mon Sep 17 00:00:00 2001 From: DreamMaoMao <2523610504@qq.com> Date: Sun, 15 Jun 2025 14:22:14 +0800 Subject: [PATCH 14/27] fix: avoid to tagmon null client --- src/maomao.c | 68 +++++++++++++++++++++++++++------------------------- 1 file changed, 35 insertions(+), 33 deletions(-) diff --git a/src/maomao.c b/src/maomao.c index ae6e1f5..5bb4dfd 100644 --- a/src/maomao.c +++ b/src/maomao.c @@ -6722,42 +6722,44 @@ void client_update_oldmonname_record(Client *c, Monitor *m) { } void tagmon(const Arg *arg) { - Client *c = focustop(selmon); - unsigned int newtags = arg->ui ? c->tags : 0; Monitor *m; + Client *c = focustop(selmon); + + if (!c) + return; + + unsigned int newtags = arg->ui ? c->tags : 0; unsigned int target; - if (c) { - if (c == selmon->sel) { - selmon->sel = NULL; - } - m = dirtomon(arg->i); - - setmon(c, m, newtags, true); - client_update_oldmonname_record(c, m); - - reset_foreign_tolevel(c); - // 重新计算居中的坐标 - if (c->isfloating) { - c->geom.width = - (int)(c->geom.width * c->mon->w.width / selmon->w.width); - c->geom.height = - (int)(c->geom.height * c->mon->w.height / selmon->w.height); - selmon = c->mon; - c->geom = setclient_coordinate_center(c, c->geom, 0, 0); - target = get_tags_first_tag(c->tags); - view(&(Arg){.ui = target}, true); - focusclient(c, 1); - c->oldgeom = c->geom; - resize(c, c->geom, 1); - } else { - selmon = c->mon; - target = get_tags_first_tag(c->tags); - view(&(Arg){.ui = target}, true); - focusclient(c, 1); - arrange(selmon, false); - } - warp_cursor_to_selmon(c->mon); + if (c == selmon->sel) { + selmon->sel = NULL; } + m = dirtomon(arg->i); + + setmon(c, m, newtags, true); + client_update_oldmonname_record(c, m); + + reset_foreign_tolevel(c); + // 重新计算居中的坐标 + if (c->isfloating) { + c->geom.width = + (int)(c->geom.width * c->mon->w.width / selmon->w.width); + c->geom.height = + (int)(c->geom.height * c->mon->w.height / selmon->w.height); + selmon = c->mon; + c->geom = setclient_coordinate_center(c, c->geom, 0, 0); + target = get_tags_first_tag(c->tags); + view(&(Arg){.ui = target}, true); + focusclient(c, 1); + c->oldgeom = c->geom; + resize(c, c->geom, 1); + } else { + selmon = c->mon; + target = get_tags_first_tag(c->tags); + view(&(Arg){.ui = target}, true); + focusclient(c, 1); + arrange(selmon, false); + } + warp_cursor_to_selmon(c->mon); } void overview(Monitor *m) { grid(m); } From ea12f4bb4d7b02cba6bc57b7ac97ba04318a3dce Mon Sep 17 00:00:00 2001 From: DreamMaoMao <2523610504@qq.com> Date: Sun, 15 Jun 2025 14:48:47 +0800 Subject: [PATCH 15/27] fix: error index of layout --- src/maomao.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/maomao.c b/src/maomao.c index 5bb4dfd..347511e 100644 --- a/src/maomao.c +++ b/src/maomao.c @@ -4883,7 +4883,7 @@ void motionnotify(uint32_t time, struct wlr_input_device *device, double dx, (c->geom.x + c->geom.width > c->mon->m.x + c->mon->m.width || c->geom.x < c->mon->m.x))) { if (c && c->mon && - strcmp(c->mon->pertag->ltidxs[selmon->pertag->curtag]->name, + strcmp(c->mon->pertag->ltidxs[c->mon->pertag->curtag]->name, "scroller") == 0 && (c->geom.x + c->geom.width > c->mon->m.x + c->mon->m.width || c->geom.x < c->mon->m.x)) { From 4f78c0651582af45471e00e87bfa55c65885f5c9 Mon Sep 17 00:00:00 2001 From: DreamMaoMao <2523610504@qq.com> Date: Sun, 15 Jun 2025 15:28:14 +0800 Subject: [PATCH 16/27] opt: floating window position auto adjust the output layout update --- src/maomao.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/src/maomao.c b/src/maomao.c index 347511e..e993a5e 100644 --- a/src/maomao.c +++ b/src/maomao.c @@ -7254,6 +7254,7 @@ void updatemons(struct wl_listener *listener, void *data) { Client *c; struct wlr_output_configuration_head_v1 *config_head; Monitor *m; + int offset_x = 0, offset_y = 0, oldx, oldy; /* First remove from the layout the disabled monitors */ wl_list_for_each(m, &mons, link) { @@ -7290,9 +7291,13 @@ void updatemons(struct wl_listener *listener, void *data) { config_head = wlr_output_configuration_head_v1_create(config, m->wlr_output); + oldx = m->m.x; + oldy = m->m.y; /* Get the effective monitor geometry to use for surfaces */ wlr_output_layout_get_box(output_layout, m->wlr_output, &m->m); m->w = m->m; + offset_x = m->m.x - oldx; + offset_y = m->m.y - oldy; wlr_scene_output_set_position(m->scene_output, m->m.x, m->m.y); // wlr_scene_node_set_position(&m->fullscreen_bg->node, m->m.x, m->m.y); @@ -7324,6 +7329,13 @@ void updatemons(struct wl_listener *listener, void *data) { selmon = m; wl_list_for_each(c, &clients, link) { + if (c->isfloating && c->mon == m) { + c->geom.x += offset_x; + c->geom.y += offset_y; + c->oldgeom = c->geom; + resize(c, c->geom, 0); + } + if (c->mon && c->mon != m && client_surface(c)->mapped && strcmp(c->oldmonname, m->wlr_output->name) == 0) { client_change_mon(c, m); From ba763332fcb9e372cd6392152e71f43998cc7bc8 Mon Sep 17 00:00:00 2001 From: DreamMaoMao <2523610504@qq.com> Date: Sun, 15 Jun 2025 15:55:18 +0800 Subject: [PATCH 17/27] feat: add dispatch focuslast --- src/config/parse_config.h | 2 ++ src/dispatch/dispatch.h | 3 ++- src/maomao.c | 25 +++++++++++++++++++++++++ 3 files changed, 29 insertions(+), 1 deletion(-) diff --git a/src/config/parse_config.h b/src/config/parse_config.h index 66a73eb..9ab68cf 100644 --- a/src/config/parse_config.h +++ b/src/config/parse_config.h @@ -660,6 +660,8 @@ FuncType parse_func_name(char *func_name, Arg *arg, char *arg_value, func = tagtoright; } else if (strcmp(func_name, "killclient") == 0) { func = killclient; + } else if (strcmp(func_name, "focuslast") == 0) { + func = focuslast; } else if (strcmp(func_name, "setlayout") == 0) { func = setlayout; (*arg).v = strdup(arg_value); diff --git a/src/dispatch/dispatch.h b/src/dispatch/dispatch.h index 5632feb..452908b 100644 --- a/src/dispatch/dispatch.h +++ b/src/dispatch/dispatch.h @@ -57,4 +57,5 @@ void resizewin(const Arg *arg); void toggle_named_scratchpad(const Arg *arg); void toggle_render_border(const Arg *arg); void create_virtual_output(const Arg *arg); -void destroy_all_virtual_output(const Arg *arg); \ No newline at end of file +void destroy_all_virtual_output(const Arg *arg); +void focuslast(const Arg *arg); \ No newline at end of file diff --git a/src/maomao.c b/src/maomao.c index e993a5e..0b4f62d 100644 --- a/src/maomao.c +++ b/src/maomao.c @@ -4549,6 +4549,31 @@ void pending_kill_client(Client *c) { client_send_close(c); } +void focuslast(const Arg *arg) { + + Client *c, *prev = NULL; + wl_list_for_each(c, &fstack, flink) { + if (c->iskilling || c->isminied || c->isunglobal) + continue; + if (c) + break; + } + + struct wl_list *prev_node = c->flink.next; + prev = wl_container_of(prev_node, prev, flink); + + unsigned int target; + if (prev) { + if (prev->mon != selmon) { + selmon = prev->mon; + warp_cursor_to_selmon(selmon); + } + target = get_tags_first_tag(prev->tags); + view(&(Arg){.ui = target}, true); + focusclient(prev, 1); + } +} + void killclient(const Arg *arg) { Client *c; c = selmon->sel; From 5f688d6e6ce144986fef22a76a8509a8945d60a3 Mon Sep 17 00:00:00 2001 From: DreamMaoMao <2523610504@qq.com> Date: Sun, 15 Jun 2025 18:14:05 +0800 Subject: [PATCH 18/27] opt: optimize floating window auto ajust monitor position change --- src/maomao.c | 42 +++++++++++++++++++++++++----------------- 1 file changed, 25 insertions(+), 17 deletions(-) diff --git a/src/maomao.c b/src/maomao.c index 0b4f62d..573cbc9 100644 --- a/src/maomao.c +++ b/src/maomao.c @@ -7279,7 +7279,7 @@ void updatemons(struct wl_listener *listener, void *data) { Client *c; struct wlr_output_configuration_head_v1 *config_head; Monitor *m; - int offset_x = 0, offset_y = 0, oldx, oldy; + int mon_pos_offsetx, mon_pos_offsety, oldx, oldy; /* First remove from the layout the disabled monitors */ wl_list_for_each(m, &mons, link) { @@ -7321,8 +7321,30 @@ void updatemons(struct wl_listener *listener, void *data) { /* Get the effective monitor geometry to use for surfaces */ wlr_output_layout_get_box(output_layout, m->wlr_output, &m->m); m->w = m->m; - offset_x = m->m.x - oldx; - offset_y = m->m.y - oldy; + mon_pos_offsetx = m->m.x - oldx; + mon_pos_offsety = m->m.y - oldy; + + wl_list_for_each(c, &clients, link) { + // floating window position auto adjust the change of monitor + // position + if (c->isfloating && c->mon == m) { + c->geom.x += mon_pos_offsetx; + c->geom.y += mon_pos_offsety; + c->oldgeom = c->geom; + resize(c, c->geom, 1); + } + + // restore window to old monitor + if (c->mon && c->mon != m && client_surface(c)->mapped && + strcmp(c->oldmonname, m->wlr_output->name) == 0) { + client_change_mon(c, m); + } + } + + /* + must put it under the floating window position adjustment, + Otherwise, incorrect floating window calculations will occur here. + */ wlr_scene_output_set_position(m->scene_output, m->m.x, m->m.y); // wlr_scene_node_set_position(&m->fullscreen_bg->node, m->m.x, m->m.y); @@ -7352,20 +7374,6 @@ void updatemons(struct wl_listener *listener, void *data) { if (!selmon) selmon = m; - - wl_list_for_each(c, &clients, link) { - if (c->isfloating && c->mon == m) { - c->geom.x += offset_x; - c->geom.y += offset_y; - c->oldgeom = c->geom; - resize(c, c->geom, 0); - } - - if (c->mon && c->mon != m && client_surface(c)->mapped && - strcmp(c->oldmonname, m->wlr_output->name) == 0) { - client_change_mon(c, m); - } - } } if (selmon && selmon->wlr_output->enabled) { From 6b2ef05dcfb62f65c5150f9bca6da78b0268ae96 Mon Sep 17 00:00:00 2001 From: DreamMaoMao <2523610504@qq.com> Date: Sun, 15 Jun 2025 21:51:29 +0800 Subject: [PATCH 19/27] fix: scratchpad window can't enable when toggle by change tag --- src/maomao.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/maomao.c b/src/maomao.c index 573cbc9..d16ded2 100644 --- a/src/maomao.c +++ b/src/maomao.c @@ -1617,6 +1617,7 @@ void swallow(Client *c, Client *w) { bool switch_scratchpad_client_state(Client *c) { if (c->is_in_scratchpad && c->is_scratchpad_show && (selmon->tagset[selmon->seltags] & c->tags) == 0) { + c->is_clip_to_hide = false; unsigned int target = get_tags_first_tag(selmon->tagset[selmon->seltags]); tag_client(&(Arg){.ui = target}, c); From ee44bc148fc2d2bc5a1432e133a043690cd68436 Mon Sep 17 00:00:00 2001 From: DreamMaoMao <2523610504@qq.com> Date: Mon, 16 Jun 2025 13:41:25 +0800 Subject: [PATCH 20/27] opt: disable clip to hide if it is a visible floating window when change monitor --- src/maomao.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/maomao.c b/src/maomao.c index d16ded2..9c0548d 100644 --- a/src/maomao.c +++ b/src/maomao.c @@ -1093,8 +1093,7 @@ void client_change_mon(Client *c, Monitor *m) { c->oldgeom = c->geom = setclient_coordinate_center(c, c->geom, 0, 0); } if (VISIBLEON(c, m) && c->isfloating) { - wlr_scene_node_set_enabled(&c->scene->node, true); - client_set_suspended(c, false); + c->is_clip_to_hide = false; } } From 74bc8e9022165738c6cef15fda4edb412dd01542 Mon Sep 17 00:00:00 2001 From: DreamMaoMao <2523610504@qq.com> Date: Mon, 16 Jun 2025 22:05:01 +0800 Subject: [PATCH 21/27] protocol: enable wlr_ext_data_control_v1 --- src/maomao.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/maomao.c b/src/maomao.c index 9c0548d..deb5a24 100644 --- a/src/maomao.c +++ b/src/maomao.c @@ -31,6 +31,7 @@ #include #include #include +#include #include #include #include @@ -6453,6 +6454,7 @@ void setup(void) { wlr_presentation_create(dpy, backend, 2); wlr_subcompositor_create(dpy); wlr_alpha_modifier_v1_create(dpy); + wlr_ext_data_control_manager_v1_create(dpy, 1); /* Initializes the interface used to implement urgency hints */ activation = wlr_xdg_activation_v1_create(dpy); From d5fc8e3d7d0bb9bc967c26335549ab66def0aff7 Mon Sep 17 00:00:00 2001 From: DreamMaoMao <2523610504@qq.com> Date: Tue, 17 Jun 2025 09:39:56 +0800 Subject: [PATCH 22/27] opt: should set visible in arrange if win is not tile win even if the win has is_clip_to_hide enable, but if the win not a tile style, it should be set visible --- src/maomao.c | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/src/maomao.c b/src/maomao.c index deb5a24..626187d 100644 --- a/src/maomao.c +++ b/src/maomao.c @@ -1093,9 +1093,6 @@ void client_change_mon(Client *c, Monitor *m) { if (c->isfloating) { c->oldgeom = c->geom = setclient_coordinate_center(c, c->geom, 0, 0); } - if (VISIBLEON(c, m) && c->isfloating) { - c->is_clip_to_hide = false; - } } bool check_hit_no_border(Client *c) { @@ -1490,7 +1487,6 @@ void show_scratchpad(Client *c) { resize(c, c->geom, 0); } c->oldtags = selmon->tagset[selmon->seltags]; - c->is_clip_to_hide = false; wl_list_remove(&c->link); // 从原来位置移除 wl_list_insert(clients.prev->next, &c->link); // 插入开头 show_hide_client(c); @@ -1617,7 +1613,6 @@ void swallow(Client *c, Client *w) { bool switch_scratchpad_client_state(Client *c) { if (c->is_in_scratchpad && c->is_scratchpad_show && (selmon->tagset[selmon->seltags] & c->tags) == 0) { - c->is_clip_to_hide = false; unsigned int target = get_tags_first_tag(selmon->tagset[selmon->seltags]); tag_client(&(Arg){.ui = target}, c); @@ -2053,9 +2048,10 @@ arrange(Monitor *m, bool want_animation) { m->visible_clients++; } - if (!c->is_clip_to_hide || + if (!c->is_clip_to_hide || !ISTILED(c) || strcmp(c->mon->pertag->ltidxs[c->mon->pertag->curtag]->name, "scroller") != 0) { + c->is_clip_to_hide = false; wlr_scene_node_set_enabled(&c->scene->node, true); } client_set_suspended(c, false); @@ -7190,7 +7186,8 @@ void unmapnotify(struct wl_listener *listener, void *data) { Monitor *m; c->iskilling = 1; - if (animations && !c->isminied && (!c->mon || VISIBLEON(c, c->mon))) + if (animations && !c->is_clip_to_hide && !c->isminied && + (!c->mon || VISIBLEON(c, c->mon))) init_fadeout_client(c); if (c->swallowedby) { From eeed7939aa5ac14a25e84c94653592efa84d924b Mon Sep 17 00:00:00 2001 From: DreamMaoMao <2523610504@qq.com> Date: Tue, 17 Jun 2025 11:30:10 +0800 Subject: [PATCH 23/27] opt: Unify the accuracy of unsigned int --- src/maomao.c | 192 +++++++++++++++++++++++++++------------------------ 1 file changed, 100 insertions(+), 92 deletions(-) diff --git a/src/maomao.c b/src/maomao.c index 626187d..034925e 100644 --- a/src/maomao.c +++ b/src/maomao.c @@ -187,9 +187,9 @@ struct dwl_animation { bool tagouting; bool begin_fade_in; bool from_rule; - uint32_t total_frames; - uint32_t passed_frames; - uint32_t duration; + unsigned int total_frames; + unsigned int passed_frames; + unsigned int duration; struct wlr_box initial; struct wlr_box current; int action; @@ -242,7 +242,7 @@ struct Client { unsigned int bw; unsigned int tags, oldtags, mini_restore_tag; bool dirty; - uint32_t configure_serial; + unsigned int configure_serial; struct wlr_foreign_toplevel_handle_v1 *foreign_toplevel; int isfloating, isurgent, isfullscreen, isfakefullscreen, need_float_size_reduce, isminied, isoverlay; @@ -297,7 +297,7 @@ typedef struct { } DwlIpcOutput; typedef struct { - uint32_t mod; + unsigned int mod; xkb_keysym_t keysym; void (*func)(const Arg *); const Arg arg; @@ -308,8 +308,8 @@ typedef struct { int nsyms; const xkb_keysym_t *keysyms; /* invalid if nsyms == 0 */ - uint32_t mods; /* invalid if nsyms == 0 */ - uint32_t keycode; + unsigned int mods; /* invalid if nsyms == 0 */ + unsigned int keycode; struct wl_event_source *key_repeat_source; struct wl_listener modifiers; @@ -323,7 +323,7 @@ typedef struct { int nsyms; const xkb_keysym_t *keysyms; /* invalid if nsyms == 0 */ - uint32_t mods; /* invalid if nsyms == 0 */ + unsigned int mods; /* invalid if nsyms == 0 */ struct wl_event_source *key_repeat_source; struct wl_listener modifiers; @@ -370,7 +370,7 @@ struct Monitor { struct wl_list layers[4]; /* LayerSurface::link */ const Layout *lt; unsigned int seltags; - uint32_t tagset[2]; + unsigned int tagset[2]; double mfact; int nmaster; @@ -438,7 +438,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 *, size_t); // 自启动命令执行 +static char *get_autostart_path(char *, unsigned int); // 自启动命令执行 static void axisnotify(struct wl_listener *listener, void *data); // 滚轮事件处理 static void buttonpress(struct wl_listener *listener, @@ -490,11 +490,12 @@ static void destroykeyboardgroup(struct wl_listener *listener, void *data); static Monitor *dirtomon(enum wlr_direction dir); static void setcursorshape(struct wl_listener *listener, void *data); static void dwl_ipc_manager_bind(struct wl_client *client, void *data, - uint32_t version, uint32_t id); + unsigned int version, unsigned int 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, - uint32_t id, struct wl_resource *output); + unsigned int 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); @@ -502,14 +503,15 @@ 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, - uint32_t xor_tags); + unsigned int and_tags, + unsigned int xor_tags); static void dwl_ipc_output_set_layout(struct wl_client *client, struct wl_resource *resource, - uint32_t index); + unsigned int index); static void dwl_ipc_output_set_tags(struct wl_client *client, struct wl_resource *resource, - uint32_t tagmask, uint32_t toggle_tagset); + unsigned int tagmask, + unsigned int 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, @@ -529,20 +531,22 @@ 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(uint32_t mods, xkb_keysym_t sym, uint32_t keycode); +static int keybinding(unsigned int mods, xkb_keysym_t sym, + unsigned int 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, uint32_t mods, - xkb_keysym_t keysym, uint32_t keycode); + struct wlr_keyboard_key_event *event, + unsigned int mods, xkb_keysym_t keysym, + unsigned int 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 monocle(Monitor *m); static void motionabsolute(struct wl_listener *listener, void *data); -static void motionnotify(uint32_t time, struct wlr_input_device *device, +static void motionnotify(unsigned int 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); @@ -556,7 +560,7 @@ 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, uint32_t time); + double sy, unsigned int time); static void printstatus(void); static void quitsignal(int signo); static void powermgrsetmode(struct wl_listener *listener, void *data); @@ -661,7 +665,7 @@ static void client_update_oldmonname_record(Client *c, Monitor *m); static const char broken[] = "broken"; static pid_t child_pid = -1; static int locked; -static uint32_t locked_mods = 0; +static unsigned int locked_mods = 0; static void *exclusive_focus; static struct wl_display *dpy; static struct wl_event_loop *event_loop; @@ -722,7 +726,7 @@ static int axis_apply_time = 0; static int axis_apply_dir = 0; static int scroller_focus_lock = 0; -static uint32_t swipe_fingers = 0; +static unsigned int swipe_fingers = 0; static double swipe_dx = 0; static double swipe_dy = 0; @@ -846,29 +850,29 @@ void init_baked_points(void) { baked_points_close = calloc(BAKED_POINTS_COUNT, sizeof(*baked_points_close)); - for (size_t i = 0; i < BAKED_POINTS_COUNT; i++) { + for (unsigned int i = 0; i < BAKED_POINTS_COUNT; i++) { baked_points_move[i] = calculate_animation_curve_at( (double)i / (BAKED_POINTS_COUNT - 1), MOVE); } - for (size_t i = 0; i < BAKED_POINTS_COUNT; i++) { + for (unsigned int i = 0; i < BAKED_POINTS_COUNT; i++) { baked_points_open[i] = calculate_animation_curve_at( (double)i / (BAKED_POINTS_COUNT - 1), OPEN); } - for (size_t i = 0; i < BAKED_POINTS_COUNT; i++) { + for (unsigned int i = 0; i < BAKED_POINTS_COUNT; i++) { baked_points_tag[i] = calculate_animation_curve_at( (double)i / (BAKED_POINTS_COUNT - 1), TAG); } - for (size_t i = 0; i < BAKED_POINTS_COUNT; i++) { + for (unsigned int i = 0; i < BAKED_POINTS_COUNT; i++) { baked_points_close[i] = calculate_animation_curve_at( (double)i / (BAKED_POINTS_COUNT - 1), CLOSE); } } double find_animation_curve_at(double t, int type) { - size_t down = 0; - size_t up = BAKED_POINTS_COUNT - 1; + unsigned int down = 0; + unsigned int up = BAKED_POINTS_COUNT - 1; - size_t middle = (up + down) / 2; + unsigned int middle = (up + down) / 2; struct vec2 *baked_points; if (type == MOVE) { baked_points = baked_points_move; @@ -950,16 +954,17 @@ void fadeout_client_animation_next_tick(Client *c) { (double)c->animation.passed_frames / c->animation.total_frames; int type = c->animation.action = c->animation.action; double factor = find_animation_curve_at(animation_passed, type); - uint32_t width = c->animation.initial.width + - (c->current.width - c->animation.initial.width) * factor; - uint32_t height = + unsigned int width = + c->animation.initial.width + + (c->current.width - c->animation.initial.width) * factor; + unsigned int height = c->animation.initial.height + (c->current.height - c->animation.initial.height) * 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; + 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; wlr_scene_node_set_position(&c->scene->node, x, y); @@ -1013,16 +1018,17 @@ void client_animation_next_tick(Client *c) { double sx = 0, sy = 0; struct wlr_surface *surface = NULL; - uint32_t width = c->animation.initial.width + - (c->current.width - c->animation.initial.width) * factor; - uint32_t height = + unsigned int width = + c->animation.initial.width + + (c->current.width - c->animation.initial.width) * factor; + unsigned int height = c->animation.initial.height + (c->current.height - c->animation.initial.height) * 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; + 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; wlr_scene_node_set_position(&c->scene->node, x, y); c->animation.current = (struct wlr_box){ @@ -1077,7 +1083,7 @@ void client_animation_next_tick(Client *c) { } } -void client_actual_size(Client *c, uint32_t *width, uint32_t *height) { +void client_actual_size(Client *c, unsigned int *width, unsigned int *height) { *width = c->animation.current.width - c->bw; *height = c->animation.current.height - c->bw; @@ -1312,7 +1318,7 @@ void client_apply_clip(Client *c) { return; } - uint32_t width, height; + unsigned int width, height; client_actual_size(c, &width, &height); struct wlr_box geometry; @@ -1882,7 +1888,7 @@ void // 17 applyrules(Client *c) { /* rule matching */ const char *appid, *title; - uint32_t i, newtags = 0; + unsigned int i, newtags = 0; int ji; const ConfigWinRule *r; Monitor *mon = selmon, *m; @@ -2497,7 +2503,7 @@ void arrangelayers(Monitor *m) { int i; struct wlr_box usable_area = m->m; LayerSurface *l; - uint32_t layers_above_shell[] = { + unsigned int layers_above_shell[] = { ZWLR_LAYER_SHELL_V1_LAYER_OVERLAY, ZWLR_LAYER_SHELL_V1_LAYER_TOP, }; @@ -2535,7 +2541,7 @@ void arrangelayers(Monitor *m) { } } -char *get_autostart_path(char *autostart_path, size_t buf_size) { +char *get_autostart_path(char *autostart_path, unsigned int buf_size) { const char *maomaoconfig = getenv("MAOMAOCONFIG"); if (maomaoconfig && maomaoconfig[0] != '\0') { @@ -2560,7 +2566,7 @@ 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; - uint32_t mods; + unsigned int mods; AxisBinding *a; int ji; unsigned int adir; @@ -2609,7 +2615,7 @@ axisnotify(struct wl_listener *listener, void *data) { int ongesture(struct wlr_pointer_swipe_end_event *event) { struct wlr_keyboard *keyboard; - uint32_t mods; + unsigned int mods; const GestureBinding *g; unsigned int motion; unsigned int adx = (int)round(fabs(swipe_dx)); @@ -2755,7 +2761,7 @@ void // 鼠标按键事件 buttonpress(struct wl_listener *listener, void *data) { struct wlr_pointer_button_event *event = data; struct wlr_keyboard *keyboard; - uint32_t mods; + unsigned int mods; Client *c; LayerSurface *l; struct wlr_surface *surface; @@ -2965,7 +2971,7 @@ cleanupkeyboard(struct wl_listener *listener, void *data) { void cleanupmon(struct wl_listener *listener, void *data) { Monitor *m = wl_container_of(listener, m, destroy); LayerSurface *l, *tmp; - size_t i; + unsigned int i; /* m->layers[i] are intentionally not unlinked */ for (i = 0; i < LENGTH(m->layers); i++) { @@ -3155,7 +3161,7 @@ void commitnotify(struct wl_listener *listener, void *data) { if (client_is_unmanaged(c)) return; - uint32_t serial = c->surface.xdg->current.configure_serial; + unsigned int serial = c->surface.xdg->current.configure_serial; if (!c->dirty || serial < c->configure_serial) return; @@ -3261,14 +3267,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 |= (uint32_t)1 << mod_index; + locked_mods |= (unsigned int)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 |= (uint32_t)1 << mod_index; + locked_mods |= (unsigned int)1 << mod_index; } if (locked_mods) @@ -3358,7 +3364,7 @@ void createmon(struct wl_listener *listener, void *data) { * monitor) becomes available. */ struct wlr_output *wlr_output = data; const ConfigMonitorRule *r; - size_t i; + unsigned int i; int ji, jk; struct wlr_output_state state; Monitor *m; @@ -3748,7 +3754,7 @@ Monitor *dirtomon(enum wlr_direction dir) { } void dwl_ipc_manager_bind(struct wl_client *client, void *data, - uint32_t version, uint32_t id) { + unsigned int version, unsigned int id) { struct wl_resource *manager_resource = wl_resource_create(client, &zdwl_ipc_manager_v2_interface, version, id); if (!manager_resource) { @@ -3770,7 +3776,7 @@ void dwl_ipc_manager_destroy(struct wl_resource *resource) { } void dwl_ipc_manager_get_output(struct wl_client *client, - struct wl_resource *resource, uint32_t id, + struct wl_resource *resource, unsigned int id, struct wl_resource *output) { DwlIpcOutput *ipc_output; struct wlr_output *op = wlr_output_from_resource(output); @@ -3882,7 +3888,8 @@ void dwl_ipc_output_printstatus_to(DwlIpcOutput *ipc_output) { void dwl_ipc_output_set_client_tags(struct wl_client *client, struct wl_resource *resource, - uint32_t and_tags, uint32_t xor_tags) { + unsigned int and_tags, + unsigned int xor_tags) { DwlIpcOutput *ipc_output; Monitor *monitor; Client *selected_client; @@ -3909,7 +3916,8 @@ 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, uint32_t index) { + struct wl_resource *resource, + unsigned int index) { DwlIpcOutput *ipc_output; Monitor *monitor; @@ -3927,8 +3935,8 @@ void dwl_ipc_output_set_layout(struct wl_client *client, } void dwl_ipc_output_set_tags(struct wl_client *client, - struct wl_resource *resource, uint32_t tagmask, - uint32_t toggle_tagset) { + struct wl_resource *resource, unsigned int tagmask, + unsigned int toggle_tagset) { DwlIpcOutput *ipc_output; Monitor *monitor; unsigned int newtags = tagmask & TAGMASK; @@ -4214,7 +4222,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; - uint32_t caps; + unsigned int caps; switch (device->type) { case WLR_INPUT_DEVICE_KEYBOARD: @@ -4255,7 +4263,7 @@ int keyrepeat(void *data) { } int // 17 -keybinding(uint32_t mods, xkb_keysym_t sym, uint32_t keycode) { +keybinding(unsigned int mods, xkb_keysym_t sym, unsigned int keycode) { /* * Here we handle compositor keybindings. This is when the compositor is * processing keys, rather than passing them on to the client for its own @@ -4284,10 +4292,10 @@ keybinding(uint32_t mods, xkb_keysym_t sym, uint32_t keycode) { bool keypressglobal(struct wlr_surface *last_surface, struct wlr_keyboard *keyboard, - struct wlr_keyboard_key_event *event, uint32_t mods, - xkb_keysym_t keysym, uint32_t keycode) { + struct wlr_keyboard_key_event *event, unsigned int mods, + xkb_keysym_t keysym, unsigned int keycode) { Client *c = NULL, *lastc = focustop(selmon); - uint32_t keycodes[32] = {0}; + unsigned int keycodes[32] = {0}; int reset = false; const char *appid = NULL; const char *title = NULL; @@ -4359,14 +4367,14 @@ void keypress(struct wl_listener *listener, void *data) { #endif /* Translate libinput keycode -> xkbcommon */ - uint32_t keycode = event->keycode + 8; + unsigned int 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; - uint32_t mods = wlr_keyboard_get_modifiers(&group->wlr_group->keyboard); + unsigned int mods = wlr_keyboard_get_modifiers(&group->wlr_group->keyboard); wlr_idle_notifier_v1_notify_activity(idle_notifier, seat); @@ -4804,7 +4812,7 @@ void motionabsolute(struct wl_listener *listener, void *data) { motionnotify(event->time_msec, &event->pointer->base, dx, dy, dx, dy); } -void motionnotify(uint32_t time, struct wlr_input_device *device, double dx, +void motionnotify(unsigned int 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; @@ -5037,7 +5045,7 @@ void outputmgrtest(struct wl_listener *listener, void *data) { } void pointerfocus(Client *c, struct wlr_surface *surface, double sx, double sy, - uint32_t time) { + unsigned int time) { struct timespec now; if (surface != seat->pointer_state.focused_surface && sloppyfocus && time && @@ -5130,8 +5138,8 @@ void scene_buffer_apply_effect(struct wlr_scene_buffer *buffer, int sx, int sy, if (scale_data->should_scale) { - uint32_t surface_width = surface->current.width; - uint32_t surface_height = surface->current.height; + unsigned int surface_width = surface->current.width; + unsigned int surface_height = surface->current.height; surface_width = scale_data->width_scale < 1 ? surface_width @@ -5829,12 +5837,12 @@ char *get_layout_abbr(const char *full_name) { const char *open = strrchr(full_name, '('); const char *close = strrchr(full_name, ')'); if (open && close && close > open) { - size_t len = close - open - 1; + unsigned int len = close - open - 1; if (len > 0 && len <= 4) { char *abbr = malloc(len + 1); if (abbr) { // 提取并转换为小写 - for (size_t j = 0; j < len; j++) { + for (unsigned int j = 0; j < len; j++) { abbr[j] = tolower(open[j + 1]); } abbr[len] = '\0'; @@ -5846,8 +5854,8 @@ char *get_layout_abbr(const char *full_name) { // 3. 提取前2-3个字母并转换为小写 char *abbr = malloc(4); if (abbr) { - size_t j = 0; - for (size_t i = 0; full_name[i] != '\0' && j < 3; i++) { + unsigned int j = 0; + for (unsigned int i = 0; full_name[i] != '\0' && j < 3; i++) { if (isalpha(full_name[i])) { abbr[j++] = tolower(full_name[i]); } @@ -5930,9 +5938,9 @@ void reset_keyboard_layout(void) { } // Apply the same keymap (this will reset the layout state) - uint32_t depressed = keyboard->modifiers.depressed; - uint32_t latched = keyboard->modifiers.latched; - uint32_t locked = keyboard->modifiers.locked; + unsigned int depressed = keyboard->modifiers.depressed; + unsigned int latched = keyboard->modifiers.latched; + unsigned int locked = keyboard->modifiers.locked; wlr_keyboard_set_keymap(keyboard, new_keymap); @@ -6006,7 +6014,7 @@ void switch_keyboard_layout(const Arg *arg) { char *layout_buf = (char *)rules.layout; // 假设这是可修改的 // 清空原有内容(安全方式) - size_t layout_buf_size = strlen(layout_buf) + 1; + unsigned int layout_buf_size = strlen(layout_buf) + 1; memset(layout_buf, 0, layout_buf_size); // 构建新的布局字符串 @@ -6042,9 +6050,9 @@ void switch_keyboard_layout(const Arg *arg) { } // 6. 应用新 keymap - uint32_t depressed = keyboard->modifiers.depressed; - uint32_t latched = keyboard->modifiers.latched; - uint32_t locked = keyboard->modifiers.locked; + unsigned int depressed = keyboard->modifiers.depressed; + unsigned int latched = keyboard->modifiers.latched; + unsigned int locked = keyboard->modifiers.locked; wlr_keyboard_set_keymap(keyboard, new_keymap); wlr_keyboard_notify_modifiers(keyboard, depressed, latched, locked, 0); @@ -6071,7 +6079,7 @@ void switch_layout(const Arg *arg) { int jk, ji; char *target_layout_name = NULL; - size_t len; + unsigned int len; if (config.circle_layout_count != 0) { for (jk = 0; jk < config.circle_layout_count; jk++) { @@ -6151,7 +6159,7 @@ void setsmfact(const Arg *arg) { arrange(selmon, false); } -void setmon(Client *c, Monitor *m, uint32_t newtags, bool focus) { +void setmon(Client *c, Monitor *m, unsigned int newtags, bool focus) { Monitor *oldmon = c->mon; if (oldmon == m) @@ -7436,7 +7444,7 @@ urgent(struct wl_listener *listener, void *data) { void bind_to_view(const Arg *arg) { view(arg, true); } void view_in_mon(const Arg *arg, bool want_animation, Monitor *m) { - size_t i, tmptag; + unsigned int i, tmptag; if (!m || (arg->ui != ~0 && m->isoverview)) { return; @@ -7481,7 +7489,7 @@ void view(const Arg *arg, bool want_animation) { } void viewtoleft(const Arg *arg) { - size_t tmptag; + unsigned int tmptag; unsigned int target = selmon->tagset[selmon->seltags]; if (selmon->isoverview || selmon->pertag->curtag == 0) { @@ -7513,7 +7521,7 @@ void viewtoleft(const Arg *arg) { } void viewtoright_have_client(const Arg *arg) { - size_t tmptag; + unsigned int tmptag; Client *c; unsigned int found = 0; unsigned int n = 1; @@ -7567,7 +7575,7 @@ void viewtoright(const Arg *arg) { if (selmon->isoverview || selmon->pertag->curtag == 0) { return; } - size_t tmptag; + unsigned int tmptag; unsigned int target = selmon->tagset[selmon->seltags]; target <<= 1; @@ -7593,7 +7601,7 @@ void viewtoright(const Arg *arg) { } void viewtoleft_have_client(const Arg *arg) { - size_t tmptag; + unsigned int tmptag; Client *c; unsigned int found = 0; unsigned int n = 1; From f202a16abe5bd0c79d698ad6090009c624330c60 Mon Sep 17 00:00:00 2001 From: DreamMaoMao <2523610504@qq.com> Date: Tue, 17 Jun 2025 15:45:17 +0800 Subject: [PATCH 24/27] feat: add option to disable syncobj for nvidia --- src/config/parse_config.h | 5 +++++ src/config/preset_config.h | 1 + src/maomao.c | 2 +- 3 files changed, 7 insertions(+), 1 deletion(-) diff --git a/src/config/parse_config.h b/src/config/parse_config.h index 9ab68cf..cbc9def 100644 --- a/src/config/parse_config.h +++ b/src/config/parse_config.h @@ -241,6 +241,7 @@ typedef struct { int single_scratchpad; int xwayland_persistence; + int syncobj_enable; struct xkb_rule_names xkb_rules; } Config; @@ -876,6 +877,8 @@ void parse_config_line(Config *config, const char *line) { config->single_scratchpad = atoi(value); } else if (strcmp(key, "xwayland_persistence") == 0) { config->xwayland_persistence = atoi(value); + } else if (strcmp(key, "syncobj_enable") == 0) { + config->syncobj_enable = atoi(value); } else if (strcmp(key, "no_border_when_single") == 0) { config->no_border_when_single = atoi(value); } else if (strcmp(key, "snap_distance") == 0) { @@ -1969,6 +1972,7 @@ void override_config(void) { // 杂项设置 xwayland_persistence = CLAMP_INT(config.xwayland_persistence, 0, 1); + syncobj_enable = CLAMP_INT(config.syncobj_enable, 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); @@ -2091,6 +2095,7 @@ void set_value_default() { config.focus_cross_tag = focus_cross_tag; config.single_scratchpad = single_scratchpad; config.xwayland_persistence = xwayland_persistence; + config.syncobj_enable = syncobj_enable; config.no_border_when_single = no_border_when_single; config.snap_distance = snap_distance; config.drag_tile_to_tile = drag_tile_to_tile; diff --git a/src/config/preset_config.h b/src/config/preset_config.h index dab4400..8132b30 100644 --- a/src/config/preset_config.h +++ b/src/config/preset_config.h @@ -87,6 +87,7 @@ float fullscreen_bg[] = {0.1, 0.1, 0.1, 1.0}; int warpcursor = 1; /* Warp cursor to focused client */ int xwayland_persistence = 1; /* xwayland persistence */ +int syncobj_enable = 0; /* layout(s) */ Layout overviewlayout = {"󰃇", overview, "overview"}; diff --git a/src/maomao.c b/src/maomao.c index 034925e..6ff854d 100644 --- a/src/maomao.c +++ b/src/maomao.c @@ -6430,7 +6430,7 @@ void setup(void) { scene, wlr_linux_dmabuf_v1_create_with_renderer(dpy, 5, drw)); } - if ((drm_fd = wlr_renderer_get_drm_fd(drw)) >= 0 && + if (syncobj_enable && (drm_fd = wlr_renderer_get_drm_fd(drw)) >= 0 && drw->features.timeline && backend->features.timeline) wlr_linux_drm_syncobj_manager_v1_create(dpy, 1, drm_fd); From 6c99eeaeb35eb966eb6c924ae93af82ee6557ed4 Mon Sep 17 00:00:00 2001 From: Yappaholic Date: Tue, 17 Jun 2025 22:46:26 +0300 Subject: [PATCH 25/27] refactor: format nix code with alejandra and optimize src path --- flake.nix | 75 +++++++++++++++++++------------------- nix/default.nix | 84 ++++++++++++++++++++++--------------------- nix/hm-modules.nix | 33 +++++++++-------- nix/nixos-modules.nix | 26 +++++++------- 4 files changed, 109 insertions(+), 109 deletions(-) diff --git a/flake.nix b/flake.nix index de3d217..2581d89 100644 --- a/flake.nix +++ b/flake.nix @@ -13,14 +13,13 @@ }; }; - outputs = - { - self, - flake-parts, - treefmt-nix, - ... - }@inputs: - flake-parts.lib.mkFlake { inherit inputs; } { + outputs = { + self, + flake-parts, + treefmt-nix, + ... + } @ inputs: + flake-parts.lib.mkFlake {inherit inputs;} { imports = [ inputs.flake-parts.flakeModules.easyOverlay ]; @@ -30,37 +29,35 @@ nixosModules.maomaowm = import ./nix/nixos-modules.nix self; }; - perSystem = - { - config, - pkgs, - ... - }: - let - inherit (pkgs) - callPackage - ; - maomaowm = callPackage ./nix { - inherit (inputs.nixpkgs-wayland.packages.${pkgs.system}) wlroots; - inherit (inputs.mmsg.packages.${pkgs.system}) mmsg; - }; - shellOverride = old: { - nativeBuildInputs = old.nativeBuildInputs ++ [ ]; - buildInputs = old.buildInputs ++ [ ]; - }; - treefmtEval = treefmt-nix.lib.evalModule pkgs ./treefmt.nix; - in - { - packages.default = maomaowm; - overlayAttrs = { - inherit (config.packages) maomaowm; - }; - packages = { - inherit maomaowm; - }; - devShells.default = maomaowm.overrideAttrs shellOverride; - formatter = treefmtEval.config.build.wrapper; + perSystem = { + config, + pkgs, + ... + }: let + inherit + (pkgs) + callPackage + ; + maomaowm = callPackage ./nix { + inherit (inputs.nixpkgs-wayland.packages.${pkgs.system}) wlroots; + inherit (inputs.mmsg.packages.${pkgs.system}) mmsg; }; - systems = [ "x86_64-linux" ]; + shellOverride = old: { + nativeBuildInputs = old.nativeBuildInputs ++ []; + buildInputs = old.buildInputs ++ []; + }; + treefmtEval = treefmt-nix.lib.evalModule pkgs ./treefmt.nix; + in { + packages.default = maomaowm; + overlayAttrs = { + inherit (config.packages) maomaowm; + }; + packages = { + inherit maomaowm; + }; + devShells.default = maomaowm.overrideAttrs shellOverride; + formatter = treefmtEval.config.build.wrapper; + }; + systems = ["x86_64-linux"]; }; } diff --git a/nix/default.nix b/nix/default.nix index 8f8bd10..205379d 100644 --- a/nix/default.nix +++ b/nix/default.nix @@ -18,51 +18,53 @@ ninja, wlroots, mmsg, -}: -let +}: let pname = "maomaowm"; in -stdenv.mkDerivation { - inherit pname; - version = "nightly"; + stdenv.mkDerivation { + inherit pname; + version = "nightly"; - src = ../.; + src = builtins.path { + path = ../.; + name = "source"; + }; - nativeBuildInputs = [ - meson - ninja - pkg-config - wayland-scanner - ]; - - buildInputs = - [ - libinput - libxcb - libxkbcommon - pcre2 - pixman - wayland - wayland-protocols - wlroots - ] - ++ lib.optionals enableXWayland [ - libX11 - xcbutilwm - xwayland + nativeBuildInputs = [ + meson + ninja + pkg-config + wayland-scanner ]; - passthru = { - providedSessions = [ "maomao" ]; - inherit mmsg; - }; + buildInputs = + [ + libinput + libxcb + libxkbcommon + pcre2 + pixman + wayland + wayland-protocols + wlroots + ] + ++ lib.optionals enableXWayland [ + libX11 + xcbutilwm + xwayland + ]; - meta = { - mainProgram = "maomao"; - description = "A streamlined but feature-rich Wayland compositor"; - homepage = "https://github.com/DreamMaoMao/maomaowm"; - license = lib.licenses.mit; - maintainers = with lib.maintainers; [ ]; - platforms = lib.platforms.unix; - }; -} + passthru = { + providedSessions = ["maomao"]; + inherit mmsg; + }; + + meta = { + mainProgram = "maomao"; + description = "A streamlined but feature-rich Wayland compositor"; + homepage = "https://github.com/DreamMaoMao/maomaowm"; + license = lib.licenses.mit; + maintainers = []; + platforms = lib.platforms.unix; + }; + } diff --git a/nix/hm-modules.nix b/nix/hm-modules.nix index 0b6f37e..83533f5 100644 --- a/nix/hm-modules.nix +++ b/nix/hm-modules.nix @@ -1,11 +1,9 @@ -self: -{ +self: { lib, config, pkgs, ... -}: -let +}: let inherit (self.packages.${pkgs.system}) maomaowm; cfg = config.wayland.windowManager.maomaowm; variables = lib.concatStringsSep " " cfg.systemd.variables; @@ -15,8 +13,7 @@ let ${lib.optionalString cfg.systemd.enable systemdActivation} ${cfg.autostart_sh} ''; -in -{ +in { options = { wayland.windowManager.maomaowm = with lib; { enable = mkOption { @@ -53,7 +50,7 @@ in "XCURSOR_THEME" "XCURSOR_SIZE" ]; - example = [ "--all" ]; + example = ["--all"]; description = '' Environment variables imported into the systemd and D-Bus user environment. ''; @@ -95,23 +92,23 @@ in }; config = lib.mkIf cfg.enable { - home.packages = [ maomaowm ]; + home.packages = [maomaowm]; home.activation = lib.optionalAttrs (cfg.autostart_sh != "") { - createMaomaoScript = lib.hm.dag.entryAfter [ "clearMaomaoConfig" ] '' + createMaomaoScript = lib.hm.dag.entryAfter ["clearMaomaoConfig"] '' cat ${autostart_sh} > $HOME/.config/maomao/autostart.sh chmod +x $HOME/.config/maomao/autostart.sh ''; } // lib.optionalAttrs (cfg.settings != "") { - createMaomaoConfig = lib.hm.dag.entryAfter [ "clearMaomaoConfig" ] '' + createMaomaoConfig = lib.hm.dag.entryAfter ["clearMaomaoConfig"] '' cat > $HOME/.config/maomao/config.conf < Date: Wed, 18 Jun 2025 07:44:39 +0800 Subject: [PATCH 26/27] github: add workflow action --- .github/workflows/lock.yml | 31 +++++++++++++++++++++++++++++++ .github/workflows/stale.yml | 26 ++++++++++++++++++++++++++ 2 files changed, 57 insertions(+) create mode 100644 .github/workflows/lock.yml create mode 100644 .github/workflows/stale.yml diff --git a/.github/workflows/lock.yml b/.github/workflows/lock.yml new file mode 100644 index 0000000..ad1080a --- /dev/null +++ b/.github/workflows/lock.yml @@ -0,0 +1,31 @@ +name: Lock Threads + +on: + schedule: + - cron: "30 12 * * *" + workflow_dispatch: + +concurrency: + group: lock + +jobs: + lock: + runs-on: ubuntu-latest + permissions: + issues: write + pull-requests: write + discussions: write + steps: + - uses: dessant/lock-threads@v5 + with: + issue-inactive-days: "30" + issue-comment: > + I'm going to lock this issue because it has been closed for _30 days_. ⏳ + + This helps our maintainers find and focus on the active issues. + If you have found a problem that seems similar to this, please file a new + issue and complete the issue template so we can capture all the details + necessary to investigate further. + pr-inactive-days: "30" + discussion-inactive-days: "30" + process-only: "issues,prs,discussions" diff --git a/.github/workflows/stale.yml b/.github/workflows/stale.yml new file mode 100644 index 0000000..37d6c59 --- /dev/null +++ b/.github/workflows/stale.yml @@ -0,0 +1,26 @@ +name: Close manually marked stale issues +on: + schedule: + - cron: "30 12 * * *" # 每天 UTC 12:30 运行 + +jobs: + close-issues: + runs-on: ubuntu-latest + permissions: + issues: write + pull-requests: write + steps: + - uses: actions/stale@v9 + with: + # 禁用自动标记 stale(仅手动标记的 issue 会被处理) + days-before-issue-stale: -1 + # 手动标记后,14 天后关闭 + days-before-issue-close: 14 + # 使用的标签(必须和你手动添加的标签一致) + stale-issue-label: "stale" + # 关闭时的提示信息 + close-issue-message: "This issue was closed because it was marked as stale and had no activity for 14 days." + # 禁用 PR 处理 + days-before-pr-stale: -1 + days-before-pr-close: -1 + repo-token: ${{ secrets.GITHUB_TOKEN }} From fb8a76f51ebd2de17a0ef2aa7e77a70e40dfcbd3 Mon Sep 17 00:00:00 2001 From: DreamMaoMao <2523610504@qq.com> Date: Wed, 18 Jun 2025 07:53:34 +0800 Subject: [PATCH 27/27] github: update workflow --- .github/workflows/stale.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/stale.yml b/.github/workflows/stale.yml index 37d6c59..84b1f04 100644 --- a/.github/workflows/stale.yml +++ b/.github/workflows/stale.yml @@ -18,6 +18,8 @@ jobs: days-before-issue-close: 14 # 使用的标签(必须和你手动添加的标签一致) stale-issue-label: "stale" + # 自动关闭时自动加上的标签 + close-issue-label: "automatic-closing" # 关闭时的提示信息 close-issue-message: "This issue was closed because it was marked as stale and had no activity for 14 days." # 禁用 PR 处理