From 4d3595669c32e8bd88f62bdeb2b129aa3886d58f Mon Sep 17 00:00:00 2001 From: DreamMaoMao <2523610504@qq.com> Date: Wed, 24 Sep 2025 19:35:12 +0800 Subject: [PATCH] feat: add option scratchpad_cross_monitor --- src/animation/client.h | 4 ++++ src/config/parse_config.h | 5 ++++ src/config/preset.h | 1 + src/dispatch/bind_define.h | 2 +- src/fetch/client.h | 2 +- src/mango.c | 48 +++++++++++++++++++++++++++++++++----- 6 files changed, 54 insertions(+), 8 deletions(-) diff --git a/src/animation/client.h b/src/animation/client.h index cb56b11..07a8875 100644 --- a/src/animation/client.h +++ b/src/animation/client.h @@ -1012,6 +1012,10 @@ void resize(Client *c, struct wlr_box geo, int interact) { c->animainit_geom = c->geom; } + if (c->isminied) { + c->animainit_geom = c->geom; + } + // 开始应用动画设置 client_set_pending_state(c); diff --git a/src/config/parse_config.h b/src/config/parse_config.h index fb6e523..4cec516 100644 --- a/src/config/parse_config.h +++ b/src/config/parse_config.h @@ -174,6 +174,7 @@ typedef struct { int edge_scroller_pointer_focus; int focus_cross_monitor; int exchange_cross_monitor; + int scratchpad_cross_monitor; int focus_cross_tag; int view_current_to_back; int no_border_when_single; @@ -980,6 +981,8 @@ void parse_config_line(Config *config, const char *line) { config->focus_cross_monitor = atoi(value); } else if (strcmp(key, "exchange_cross_monitor") == 0) { config->exchange_cross_monitor = atoi(value); + } else if (strcmp(key, "scratchpad_cross_monitor") == 0) { + config->scratchpad_cross_monitor = atoi(value); } else if (strcmp(key, "focus_cross_tag") == 0) { config->focus_cross_tag = atoi(value); } else if (strcmp(key, "view_current_to_back") == 0) { @@ -2363,6 +2366,7 @@ void override_config(void) { warpcursor = CLAMP_INT(config.warpcursor, 0, 1); focus_cross_monitor = CLAMP_INT(config.focus_cross_monitor, 0, 1); exchange_cross_monitor = CLAMP_INT(config.exchange_cross_monitor, 0, 1); + scratchpad_cross_monitor = CLAMP_INT(config.scratchpad_cross_monitor, 0, 1); focus_cross_tag = CLAMP_INT(config.focus_cross_tag, 0, 1); view_current_to_back = CLAMP_INT(config.view_current_to_back, 0, 1); enable_floating_snap = CLAMP_INT(config.enable_floating_snap, 0, 1); @@ -2513,6 +2517,7 @@ void set_value_default() { config.edge_scroller_pointer_focus = edge_scroller_pointer_focus; config.focus_cross_monitor = focus_cross_monitor; config.exchange_cross_monitor = exchange_cross_monitor; + config.scratchpad_cross_monitor = scratchpad_cross_monitor; config.focus_cross_tag = focus_cross_tag; config.view_current_to_back = view_current_to_back; config.single_scratchpad = single_scratchpad; diff --git a/src/config/preset.h b/src/config/preset.h index be046d2..e5f360f 100644 --- a/src/config/preset.h +++ b/src/config/preset.h @@ -62,6 +62,7 @@ int scroller_prefer_center = 0; int focus_cross_monitor = 0; int focus_cross_tag = 0; int exchange_cross_monitor = 0; +int scratchpad_cross_monitor = 0; int view_current_to_back = 1; int no_border_when_single = 0; int no_radius_when_single = 0; diff --git a/src/dispatch/bind_define.h b/src/dispatch/bind_define.h index a0dd479..102e4f3 100644 --- a/src/dispatch/bind_define.h +++ b/src/dispatch/bind_define.h @@ -1045,7 +1045,7 @@ void toggle_scratchpad(const Arg *arg) { return; wl_list_for_each_safe(c, tmp, &clients, link) { - if (c->mon != selmon) { + if (!scratchpad_cross_monitor && c->mon != selmon) { continue; } diff --git a/src/fetch/client.h b/src/fetch/client.h index 4ecd93c..5b30d17 100644 --- a/src/fetch/client.h +++ b/src/fetch/client.h @@ -37,7 +37,7 @@ Client *get_client_by_id_or_title(const char *arg_id, const char *arg_title) { const char *appid, *title; Client *c = NULL; wl_list_for_each(c, &clients, link) { - if (c->mon != selmon) { + if (!scratchpad_cross_monitor && c->mon != selmon) { continue; } diff --git a/src/mango.c b/src/mango.c index fc20192..5697ba3 100644 --- a/src/mango.c +++ b/src/mango.c @@ -926,7 +926,7 @@ void show_scratchpad(Client *c) { resize(c, c->geom, 0); } - c->oldtags = selmon->tagset[selmon->seltags]; + c->oldtags = c->mon->tagset[c->mon->seltags]; wl_list_remove(&c->link); // 从原来位置移除 wl_list_insert(clients.prev->next, &c->link); // 插入开头 show_hide_client(c); @@ -975,6 +975,35 @@ void swallow(Client *c, Client *w) { } bool switch_scratchpad_client_state(Client *c) { + + if (scratchpad_cross_monitor && selmon && c->mon != selmon && + c->is_in_scratchpad) { + // 保存原始monitor用于尺寸计算 + Monitor *oldmon = c->mon; + + c->mon = selmon; + reset_foreign_tolevel(c); + client_update_oldmonname_record(c, selmon); + + // 根据新monitor调整窗口尺寸 + c->float_geom.width = + (int)(c->float_geom.width * c->mon->w.width / oldmon->w.width); + c->float_geom.height = + (int)(c->float_geom.height * c->mon->w.height / oldmon->w.height); + + c->float_geom = setclient_coordinate_center(c, c->float_geom, 0, 0); + + // 只有显示状态的scratchpad才需要聚焦和返回true + if (c->is_scratchpad_show) { + c->tags = get_tags_first_tag(selmon->tagset[selmon->seltags]); + resize(c, c->float_geom, 0); + focusclient(c, true); + return true; + } else { + resize(c, c->float_geom, 0); + } + } + if (c->is_in_scratchpad && c->is_scratchpad_show && (selmon->tagset[selmon->seltags] & c->tags) == 0) { unsigned int target = @@ -996,9 +1025,11 @@ bool switch_scratchpad_client_state(Client *c) { void apply_named_scratchpad(Client *target_client) { Client *c = NULL; wl_list_for_each(c, &clients, link) { - if (c->mon != selmon) { + + if (!scratchpad_cross_monitor && c->mon != selmon) { continue; } + if (single_scratchpad && c->is_in_scratchpad && c->is_scratchpad_show && c != target_client) { set_minimized(c); @@ -3517,10 +3548,14 @@ mapnotify(struct wl_listener *listener, void *data) { at_client = center_tiled_select(selmon); } - at_client->link.next->prev = &c->link; - c->link.prev = &at_client->link; - c->link.next = at_client->link.next; - at_client->link.next = &c->link; + if (at_client) { + at_client->link.next->prev = &c->link; + c->link.prev = &at_client->link; + c->link.next = at_client->link.next; + at_client->link.next = &c->link; + } else { + wl_list_insert(clients.prev, &c->link); // 尾部入栈 + } } else wl_list_insert(clients.prev, &c->link); // 尾部入栈 wl_list_insert(&fstack, &c->flink); @@ -4552,6 +4587,7 @@ void setsel(struct wl_listener *listener, void *data) { } void show_hide_client(Client *c) { + unsigned int target = get_tags_first_tag(c->oldtags); tag_client(&(Arg){.ui = target}, c); // c->tags = c->oldtags;