From ced78b004f1c47872218941d0c7012a35d496cc3 Mon Sep 17 00:00:00 2001 From: Zedhugh Chen Date: Tue, 13 Jan 2026 12:29:49 +0800 Subject: [PATCH] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E8=AE=B0=E5=BD=95=E5=92=8C?= =?UTF-8?q?=E6=81=A2=E5=A4=8D=E5=85=89=E6=A0=87=E5=9C=A8=E6=AF=8F=E4=B8=AA?= =?UTF-8?q?=20monitor=20=E4=B8=AD=E7=9A=84=E4=BD=8D=E7=BD=AE=E5=8A=9F?= =?UTF-8?q?=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/base.h | 4 ++++ src/monitor.c | 18 ++++++++++++++++++ src/monitor.h | 2 ++ src/types.h | 3 +++ src/wm.c | 10 ++++++++++ src/wm.h | 2 ++ src/xcursor.c | 18 ++++++++++++++++++ src/xcursor.h | 4 ++++ 8 files changed, 61 insertions(+) diff --git a/src/base.h b/src/base.h index a748914..df4c294 100644 --- a/src/base.h +++ b/src/base.h @@ -11,3 +11,7 @@ typedef struct extent_in_bar_t { int16_t start; int16_t end; } extent_in_bar_t; + +typedef struct point_t { + int16_t x, y; +} point_t; diff --git a/src/monitor.c b/src/monitor.c index fa7bd26..a93e3f0 100644 --- a/src/monitor.c +++ b/src/monitor.c @@ -285,3 +285,21 @@ void monitor_arrange(monitor_t *monitor) { } xcb_flush(wm.xcb_conn); } + +void monitor_save_cursor_point(monitor_t *monitor) { + monitor->cursor_position = xcursor_query_pointer_position(); + monitor->position_inited = true; +} + +void monitor_restore_cursor_point(monitor_t *monitor) { + if (monitor->position_inited) { + xcursor_set_pointer_position(monitor->cursor_position); + return; + } + + point_t point = xcursor_query_pointer_position(); + monitor_t *m = wm_get_monitor_by_point(point); + monitor->cursor_position.x = point.x - m->geometry.x + monitor->geometry.x; + monitor->cursor_position.y = point.y - m->geometry.y + monitor->geometry.y; + monitor->position_inited = true; +} diff --git a/src/monitor.h b/src/monitor.h index 756725d..067ef95 100644 --- a/src/monitor.h +++ b/src/monitor.h @@ -12,3 +12,5 @@ void monitor_clean(monitor_t *monitor); void monitor_init_bar(monitor_t *monitor); void monitor_draw_bar(monitor_t *monitor); void monitor_arrange(monitor_t *monitor); +void monitor_save_cursor_point(monitor_t *monitor); +void monitor_restore_cursor_point(monitor_t *monitor); diff --git a/src/types.h b/src/types.h index e45e8cf..1a5bfe8 100644 --- a/src/types.h +++ b/src/types.h @@ -61,6 +61,9 @@ struct monitor_t { extent_in_bar_t layout_symbol_extent; xcb_window_t bar_window; + + point_t cursor_position; + bool position_inited; }; struct tag_t { diff --git a/src/wm.c b/src/wm.c index 9bd7401..cd1d572 100644 --- a/src/wm.c +++ b/src/wm.c @@ -409,6 +409,16 @@ void wm_restack_clients(void) { xcb_flush(wm.xcb_conn); } +monitor_t *wm_get_monitor_by_point(point_t point) { + for (monitor_t *m = wm.monitor_list; m; m = m->next) { + if (m->geometry.x <= point.x && + point.x < m->geometry.x + m->geometry.width) { + return m; + } + } + return wm.monitor_list; +} + static void debug_show_monitor_list(void) { logger("\n========================== monitors ==========================\n"); for (monitor_t *m = wm.monitor_list; m; m = m->next) { diff --git a/src/wm.h b/src/wm.h index cbef2be..dfe8d76 100644 --- a/src/wm.h +++ b/src/wm.h @@ -5,6 +5,7 @@ #include #include +#include "base.h" #include "types.h" typedef struct wm_t { @@ -52,3 +53,4 @@ extern wm_t wm; void wm_restart(void); void wm_quit(void); void wm_restack_clients(void); +monitor_t *wm_get_monitor_by_point(point_t point); diff --git a/src/xcursor.c b/src/xcursor.c index 74b4f61..92e006b 100644 --- a/src/xcursor.c +++ b/src/xcursor.c @@ -2,7 +2,9 @@ #include #include +#include +#include "base.h" #include "utils.h" #include "wm.h" @@ -126,3 +128,19 @@ void xcursor_clean(void) { } if (cursor_ctx) xcb_cursor_context_free(cursor_ctx); } + +point_t xcursor_query_pointer_position(void) { + xcb_query_pointer_cookie_t cookie = + xcb_query_pointer(wm.xcb_conn, wm.screen->root); + xcb_query_pointer_reply_t *reply = + xcb_query_pointer_reply(wm.xcb_conn, cookie, nullptr); + point_t pos = {.x = reply->root_x, .y = reply->root_y}; + p_delete(&reply); + return pos; +} + +void xcursor_set_pointer_position(point_t point) { + xcb_window_t window = XCB_WINDOW_NONE; + xcb_window_t root = wm.screen->root; + xcb_warp_pointer(wm.xcb_conn, window, root, 0, 0, 1, 1, point.x, point.y); +} diff --git a/src/xcursor.h b/src/xcursor.h index a03aedb..a39c238 100644 --- a/src/xcursor.h +++ b/src/xcursor.h @@ -3,6 +3,8 @@ #include #include +#include "base.h" + typedef enum cursor_t { cursor_normal = XC_left_ptr, cursor_resize = XC_bottom_right_corner, @@ -11,3 +13,5 @@ typedef enum cursor_t { xcb_cursor_t xcursor_get_xcb_cursor(cursor_t cursor); void xcursor_clean(void); +point_t xcursor_query_pointer_position(void); +void xcursor_set_pointer_position(point_t point);