From 25ef44e5f9d44346358c9fe692101c137d5aaa36 Mon Sep 17 00:00:00 2001 From: Zedhugh Chen Date: Sun, 24 Aug 2025 04:04:39 +0800 Subject: [PATCH] =?UTF-8?q?=E5=A4=84=E7=90=86=E7=A7=BB=E5=8A=A8=E9=BC=A0?= =?UTF-8?q?=E6=A0=87=E4=BA=8B=E4=BB=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/include/event-adapter.h | 6 ++++++ src/include/utils.h | 5 +++++ src/main.c | 28 +++++++++++++++++++++++++++- src/utils.c | 19 +++++++++++++++++++ src/xcb/event.c | 12 ++++++++++-- 5 files changed, 67 insertions(+), 3 deletions(-) diff --git a/src/include/event-adapter.h b/src/include/event-adapter.h index e7bf18c..137a37f 100644 --- a/src/include/event-adapter.h +++ b/src/include/event-adapter.h @@ -71,6 +71,12 @@ typedef struct expose_event_t { typedef struct motion_notify_event_t { event_type_t type; + xcb_window_t root; + int32_t root_x; + int32_t root_y; + xcb_window_t window; + int32_t x; + int32_t y; } motion_notify_event_t; typedef struct enter_notify_event_t { diff --git a/src/include/utils.h b/src/include/utils.h index 9145fa5..ca0e84e 100644 --- a/src/include/utils.h +++ b/src/include/utils.h @@ -5,6 +5,8 @@ #include #include +#include "types.h" + #define LENGTH(X) (sizeof(X) / sizeof(X)[0]) #define MIN(a, b) (((a) < (b)) ? (a) : (b)) @@ -40,3 +42,6 @@ uint32_t rgba_to_argb(uint32_t rgba); */ void extract_color_channel(const uint32_t rgba, double *red, double *green, double *blue, double *alpha); + +monitor_t *rect_to_monitor(monitor_t *monitors, int32_t x, int32_t y, + uint32_t width, uint32_t height); diff --git a/src/main.c b/src/main.c index ef255b9..dc7313f 100644 --- a/src/main.c +++ b/src/main.c @@ -39,6 +39,7 @@ static void key_press(key_press_event_t *event); static void configure_request(configure_request_event_t *event); static void map_request(map_request_event_t *event); static void unmap_notify(unmap_notify_event_t *event); +static void motion_notify(motion_notify_event_t *event); static void manage_window(xcb_window_t window); static void unmanage_client(client_t *client); static void update_client_name(client_t *client); @@ -52,6 +53,7 @@ static void arrange(monitor_t *monitor); static void show_hide_client(client_t *client); static void restack(monitor_t *monitor); static void focus(client_t *client); +static void unfocus(client_t *client, bool set_focus); static void apply_monitor_layout(monitor_t *monitor); static client_t *get_client_of_window(xcb_window_t window); static gboolean handle_xcb_event(GIOChannel *channel, GIOCondition condition, @@ -457,6 +459,7 @@ void xcb_event_handler(generic_event_t *event, void *user_data) { EVENT(EVENT_TYPE_CONFIGURE_REQUEST, configure_request); EVENT(EVENT_TYPE_MAP_REQUEST, map_request); EVENT(EVENT_TYPE_UNMAP_NOTIFY, unmap_notify); + EVENT(EVENT_TYPE_MOTION_NOTIFY, motion_notify); #undef EVENT @@ -505,6 +508,19 @@ void unmap_notify(unmap_notify_event_t *event) { } } +void motion_notify(motion_notify_event_t *event) { + if (event->window != get_root_window()) return; + + static monitor_t *mon = NULL; + monitor_t *m = rect_to_monitor(monitors, event->root_x, event->root_y, 1, 1); + if (mon && m != mon) { + unfocus(current_monitor->selected_client, true); + current_monitor = m; + focus(NULL); + } + mon = m; +} + void manage_window(xcb_window_t window) { window_geometry_t *geometry = get_window_geometry(window); client_t *c = ecalloc(1, sizeof(client_t)); @@ -660,12 +676,22 @@ void arrange(monitor_t *monitor) { } } -void restack(monitor_t *monitor) { /* TODO: */ draw_monitor_bar(monitor); } +void restack(monitor_t *monitor) { + draw_monitor_bar(monitor); + /* TODO: */ +} void focus(client_t *client) { /* TODO: */ current_monitor->selected_client = client; draw_all_monitor_bars(); } +void unfocus(client_t *client, bool set_focus) { + if (!client) return; + change_window_border_color(client->window, color_set->border_color.argb); + if (set_focus) { + /* TODO: */ + } +} void show_hide_client(client_t *client) { if (!client) return; diff --git a/src/utils.c b/src/utils.c index 0327859..0e67a4a 100644 --- a/src/utils.c +++ b/src/utils.c @@ -93,3 +93,22 @@ void extract_color_channel(const uint32_t rgba, double *red, double *green, *blue = COLOR_SPLIT(rgba, 8); *alpha = COLOR_SPLIT(rgba, 0); } + +#define INTERSECT(x, y, w, h, m) \ + (MAX(0, MIN((x) + (w), (m)->window_x + (m)->window_width) - \ + MAX((x), (m)->window_x)) * \ + MAX(0, MIN((y) + (h), (m)->window_y + (m)->window_height) - \ + MAX((y), (m)->window_y))) +monitor_t *rect_to_monitor(monitor_t *monitors, int32_t x, int32_t y, + uint32_t width, uint32_t height) { + monitor_t *r = monitors; + int32_t a, area = 0; + for (monitor_t *m = monitors; m; m = m->next) { + if ((a = INTERSECT(x, y, width, height, m)) > area) { + area = a; + r = m; + } + } + + return r; +} diff --git a/src/xcb/event.c b/src/xcb/event.c index 6bc5716..3683943 100644 --- a/src/xcb/event.c +++ b/src/xcb/event.c @@ -73,9 +73,17 @@ static void convert_event(xcb_generic_event_t *xcb_event, case XCB_EXPOSE: event->type = EVENT_TYPE_EXPOSE; break; - case XCB_MOTION_NOTIFY: - event->type = EVENT_TYPE_MOTION_NOTIFY; + case XCB_MOTION_NOTIFY: { + xcb_motion_notify_event_t *ev = (xcb_motion_notify_event_t *)xcb_event; + event->motiion_notify.type = EVENT_TYPE_MOTION_NOTIFY; + event->motiion_notify.root = ev->root; + event->motiion_notify.root_x = ev->root_x; + event->motiion_notify.root_y = ev->root_y; + event->motiion_notify.window = ev->event; + event->motiion_notify.x = ev->event_x; + event->motiion_notify.y = ev->event_y; break; + } case XCB_ENTER_NOTIFY: event->type = EVENT_TYPE_ENTER_NOTIFY; break;