diff --git a/src/config/parse_config.h b/src/config/parse_config.h index a90e337..3020485 100644 --- a/src/config/parse_config.h +++ b/src/config/parse_config.h @@ -205,6 +205,7 @@ typedef struct { int32_t scroller_ignore_proportion_single; int32_t scroller_focus_center; int32_t scroller_prefer_center; + int32_t stacker_loop; int32_t edge_scroller_pointer_focus; int32_t focus_cross_monitor; int32_t exchange_cross_monitor; @@ -1241,6 +1242,8 @@ void parse_option(Config *config, char *key, char *value) { config->scroller_focus_center = atoi(value); } else if (strcmp(key, "scroller_prefer_center") == 0) { config->scroller_prefer_center = atoi(value); + } else if (strcmp(key, "stacker_loop") == 0) { + config->stacker_loop = atoi(value); } else if (strcmp(key, "edge_scroller_pointer_focus") == 0) { config->edge_scroller_pointer_focus = atoi(value); } else if (strcmp(key, "focus_cross_monitor") == 0) { diff --git a/src/config/preset.h b/src/config/preset.h index 6f3cd89..2955eba 100644 --- a/src/config/preset.h +++ b/src/config/preset.h @@ -65,6 +65,7 @@ float scroller_default_proportion_single = 1.0; int32_t scroller_ignore_proportion_single = 0; int32_t scroller_focus_center = 0; int32_t scroller_prefer_center = 0; +int32_t stacker_loop = 1; int32_t focus_cross_monitor = 0; int32_t focus_cross_tag = 0; int32_t exchange_cross_monitor = 0; diff --git a/src/dispatch/bind_define.h b/src/dispatch/bind_define.h index 21cdfea..694d610 100644 --- a/src/dispatch/bind_define.h +++ b/src/dispatch/bind_define.h @@ -426,6 +426,12 @@ int32_t resizewin(const Arg *arg) { return 0; if (ISTILED(c)) { + Client *target_client = c; + if (is_scroller_layout(c->mon) && (c->prev_in_stack || c->next_in_stack)) { + while (target_client->prev_in_stack) { + target_client = target_client->prev_in_stack; + } + } switch (arg->ui) { case NUM_TYPE_MINUS: offsetx = -arg->i; @@ -449,7 +455,7 @@ int32_t resizewin(const Arg *arg) { offsety = arg->i2; break; } - resize_tile_client(c, false, offsetx, offsety, 0); + resize_tile_client(target_client, false, offsetx, offsety, 0); return 0; } @@ -1617,6 +1623,20 @@ int32_t stack_with_left(const Arg *arg) { if (!c || c->isfloating || !is_scroller_layout(selmon)) return 0; + if (!config.stacker_loop) { + Client *first_tiled = NULL; + Client *iter_c = NULL; + wl_list_for_each(iter_c, &clients, link) { + if (ISTILED(iter_c) && VISIBLEON(iter_c, selmon)) { + first_tiled = iter_c; + break; + } + } + if (c == first_tiled) { + return 0; // It's the first client and loop is disabled, so do nothing. + } + } + Client *left_c = get_next_stack_client(c, true); if (!left_c) return 0; diff --git a/src/mango.c b/src/mango.c index 57e4326..5a06e3a 100644 --- a/src/mango.c +++ b/src/mango.c @@ -3638,7 +3638,27 @@ void keypressmod(struct wl_listener *listener, void *data) { } void pending_kill_client(Client *c) { - // c->iskilling = 1; //不可以提前标记已经杀掉,因为有些客户端可能拒绝 + if (!c || c->iskilling) + return; + + // If the client is in a stack, remove it from the stack + if (c->prev_in_stack || c->next_in_stack) { + if (c->prev_in_stack) { + c->prev_in_stack->next_in_stack = c->next_in_stack; + } + if (c->next_in_stack) { + c->next_in_stack->prev_in_stack = c->prev_in_stack; + if (!c->prev_in_stack) { // c was the head of the stack + // The next client becomes the new head, so we need to ensure it's treated as such. + // This is implicitly handled by setting its prev_in_stack to NULL. + } + } + c->prev_in_stack = NULL; + c->next_in_stack = NULL; + arrange(c->mon, false, false); + } + + c->iskilling = 1; client_send_close(c); }