fix: 修改 wm_set_current_monitor 函数实现避免光标乱跳

- 将 wm_set_current_monitor 改为支持 restore_cursor 参数,按场景决定是
  否恢复光标位置
- 仅在指针位于当前显示器时更新 cursor_position 缓存,减少错误覆盖
This commit is contained in:
2026-03-03 07:18:17 +08:00
parent fb0999df90
commit 4428eb056d
5 changed files with 14 additions and 13 deletions

View File

@@ -65,7 +65,7 @@ void raise_or_run(const user_action_arg_t *arg) {
if (client && client == wm.client_focused) return; if (client && client == wm.client_focused) return;
if (client) { if (client) {
wm_set_current_monitor(client->monitor); wm_set_current_monitor(client->monitor, true);
monitor_select_tag(client->monitor, client->tags); monitor_select_tag(client->monitor, client->tags);
client_stack_raise(client); client_stack_raise(client);
client_focus(client); client_focus(client);

View File

@@ -295,7 +295,7 @@ void client_send_to_monitor(client_t *client, monitor_t *monitor) {
client->tags = monitor->selected_tag->mask; client->tags = monitor->selected_tag->mask;
client_add_to_tag(client, monitor->selected_tag); client_add_to_tag(client, monitor->selected_tag);
wm_set_current_monitor(monitor); wm_set_current_monitor(monitor, true);
monitor_arrange(m); monitor_arrange(m);
monitor_arrange(monitor); monitor_arrange(monitor);
monitor_draw_bar(m); monitor_draw_bar(m);
@@ -607,7 +607,7 @@ void client_apply_rules(client_t *client, const rule_t rules[],
client->tags = t->mask; client->tags = t->mask;
if (r->switch_to_tag) { if (r->switch_to_tag) {
wm_set_current_monitor(m); wm_set_current_monitor(m, true);
m->selected_tag = t; m->selected_tag = t;
logger("++ switch to tag: %u\n", t->index); logger("++ switch to tag: %u\n", t->index);

View File

@@ -34,7 +34,7 @@ static void button_press(xcb_button_press_event_t *ev) {
if (!monitor) return; if (!monitor) return;
wm_set_current_monitor(monitor); wm_set_current_monitor(monitor, false);
if (ev->event_x >= monitor->tag_extent.start && if (ev->event_x >= monitor->tag_extent.start &&
ev->event_x <= monitor->tag_extent.end) { ev->event_x <= monitor->tag_extent.end) {
click_area = click_tag; click_area = click_tag;
@@ -188,7 +188,7 @@ static void client_message(xcb_client_message_event_t *ev) {
switch (ev->data.data32[0]) { switch (ev->data.data32[0]) {
case 2: /* 来自 pager */ case 2: /* 来自 pager */
wm_set_current_monitor(c->monitor); wm_set_current_monitor(c->monitor, true);
monitor_select_tag(c->monitor, t->mask); monitor_select_tag(c->monitor, t->mask);
client_focus(c); client_focus(c);
break; break;

View File

@@ -517,18 +517,18 @@ void wm_restack_clients(void) {
xcb_flush(wm.xcb_conn); xcb_flush(wm.xcb_conn);
} }
void wm_set_current_monitor(monitor_t *monitor) { void wm_set_current_monitor(monitor_t *monitor, bool restore_cursor) {
if (!monitor || wm.current_monitor == monitor) return; if (!monitor || wm.current_monitor == monitor) return;
point_t point = xcursor_query_pointer_position(); point_t point = xcursor_query_pointer_position();
monitor_t *point_monitor = wm_get_monitor_by_point(point); monitor_t *point_monitor = wm_get_monitor_by_point(point);
point_monitor->cursor_position = point; if (point_monitor == wm.current_monitor) {
point_monitor->position_inited = true; point_monitor->cursor_position = point;
point_monitor->position_inited = true;
}
wm.current_monitor = monitor; wm.current_monitor = monitor;
if (point_monitor != monitor) { if (restore_cursor) monitor_restore_cursor_point(monitor);
monitor_restore_cursor_point(monitor);
}
} }
static inline int intersect(area_t area, monitor_t *m) { static inline int intersect(area_t area, monitor_t *m) {
@@ -538,7 +538,8 @@ static inline int intersect(area_t area, monitor_t *m) {
MAX(area.y, m->geometry.y)); MAX(area.y, m->geometry.y));
} }
monitor_t *__attribute__((returns_nonnull)) wm_get_monitor_by_area(area_t area) { monitor_t *__attribute__((returns_nonnull)) wm_get_monitor_by_area(
area_t area) {
if (wm.current_monitor == nullptr) { if (wm.current_monitor == nullptr) {
fatal("wm_get_monitor_by_area: current monitor is nullptr"); fatal("wm_get_monitor_by_area: current monitor is nullptr");
} }

View File

@@ -57,7 +57,7 @@ extern wm_t wm;
void wm_restart(void); void wm_restart(void);
void wm_quit(void); void wm_quit(void);
void wm_restack_clients(void); void wm_restack_clients(void);
void wm_set_current_monitor(monitor_t *monitor); void wm_set_current_monitor(monitor_t *monitor, bool restore_cursor);
monitor_t *__attribute__((returns_nonnull)) wm_get_monitor_by_area(area_t area); monitor_t *__attribute__((returns_nonnull)) wm_get_monitor_by_area(area_t area);
monitor_t *__attribute__((returns_nonnull)) wm_get_monitor_by_point( monitor_t *__attribute__((returns_nonnull)) wm_get_monitor_by_point(
point_t point); point_t point);