From 25bd1fa058af52ce1a47b87a6353372196bdb831 Mon Sep 17 00:00:00 2001 From: Zedhugh Chen Date: Tue, 12 Aug 2025 20:46:47 +0800 Subject: [PATCH] =?UTF-8?q?=E5=BC=80=E5=90=AF=20xcb=20=E4=BA=8B=E4=BB=B6?= =?UTF-8?q?=E5=BE=AA=E7=8E=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/include/xcb.h | 1 + src/main.c | 24 ++++++++++++++++++++++++ src/xcb/xcb.c | 17 +++++++++++++++++ 3 files changed, 42 insertions(+) diff --git a/src/include/xcb.h b/src/include/xcb.h index 80b73c1..f788ae8 100644 --- a/src/include/xcb.h +++ b/src/include/xcb.h @@ -5,6 +5,7 @@ #include bool has_other_wm_running(void); +int get_xcb_connection_fd(void); typedef struct monitor_rect_t monitor_rect_t; struct monitor_rect_t { diff --git a/src/main.c b/src/main.c index adf41e3..cb26cac 100644 --- a/src/main.c +++ b/src/main.c @@ -20,6 +20,9 @@ static gboolean update_wallpaper(gpointer user_data); static void set_wallpaper_by_index(uint32_t index); static wallpaper_config_t *parse_wallpaper_config(const char **wallpapers); static void free_wallpaper_config(wallpaper_config_t *wallpaper_config); +static void init_xcb_event_loop(void); +static gboolean handle_xcb_event(GIOChannel *channel, GIOCondition condition, + gpointer userdata); static void cleanup(void); static monitor_t *monitors = NULL; @@ -163,6 +166,25 @@ void free_wallpaper_config(wallpaper_config_t *wallpaper_config) { free(wallpaper_config); } +void init_xcb_event_loop(void) { + GIOChannel *channel = g_io_channel_unix_new(get_xcb_connection_fd()); + g_io_channel_set_encoding(channel, NULL, NULL); + GIOCondition cond = G_IO_IN | G_IO_HUP | G_IO_ERR; + g_io_add_watch(channel, cond, handle_xcb_event, NULL); + g_io_channel_unref(channel); +} + +gboolean handle_xcb_event(GIOChannel *channel, GIOCondition condition, + gpointer userdata) { + if ((condition & G_IO_HUP) || (condition & G_IO_ERR)) { + g_main_loop_quit(loop); + return false; + } + + start_xcb_event_loop(); + return true; +} + void cleanup(void) { clean_xcb(); @@ -200,6 +222,8 @@ int main(int argc, char *argv[]) { free_window_list(window_list); + init_xcb_event_loop(); + loop = g_main_loop_new(NULL, FALSE); g_main_loop_run(loop); diff --git a/src/xcb/xcb.c b/src/xcb/xcb.c index af408ca..8d162ee 100644 --- a/src/xcb/xcb.c +++ b/src/xcb/xcb.c @@ -2,10 +2,12 @@ #include #include +#include #include #include #include #include +#include #include #include #include @@ -47,6 +49,11 @@ bool has_other_wm_running(void) { return false; } +/** + * @brief 获取 xcb 链接对应的文件描述符 + */ +int get_xcb_connection_fd(void) { return xcb_get_file_descriptor(conn); } + /* xinerama 扩展是否激活 */ static bool xinerama_active(void) { const char *name = "XINERAMA"; @@ -263,6 +270,16 @@ void free_window_list(window_list_t *window_list) { free(window_list); } +void start_xcb_event_loop(void) { + xcb_generic_event_t *event = NULL; + while ((event = xcb_poll_for_event(conn)) != NULL) { + uint8_t event_type = XCB_EVENT_RESPONSE_TYPE(event); + const char *label = xcb_event_get_label(event_type); + printf("================== %s ==================\n", label); + free(event); + } +} + void clean_xcb(void) { if (wm_check_window != XCB_NONE) { xcb_destroy_window(conn, wm_check_window);