diff --git a/src/xcb/xcb.c b/src/xcb/xcb.c index b6a26b5..3504a7d 100644 --- a/src/xcb/xcb.c +++ b/src/xcb/xcb.c @@ -1,7 +1,10 @@ #include "xcb.h" +#include #include +#include #include +#include #include #include #include @@ -24,6 +27,7 @@ bool has_other_wm_running(void) { const xcb_setup_t *setup = xcb_get_setup(conn); xcb_screen_iterator_t iter = xcb_setup_roots_iterator(setup); screen = iter.data; + printf("screen number: %d\n", iter.rem); uint32_t mask = XCB_CW_EVENT_MASK; xcb_params_cw_t params = { .event_mask = XCB_EVENT_MASK_LEAVE_WINDOW | XCB_EVENT_MASK_ENTER_WINDOW | @@ -42,15 +46,30 @@ bool has_other_wm_running(void) { return false; } -/** - * 使用 xinerama 扩展探测每个屏幕的配置信息 - * - * @TODO: 后续考虑兼容无 xinerama 扩展或扩展未启用的情况 - * 当前仅需函数在自己环境下能正常工作即可,先不考虑其他环境 - * - * @note: 返回值使用完后记得释放其内存 - */ -monitor_rect_t *detect_monitor_rect(void) { +/* xinerama 扩展是否激活 */ +static bool xinerama_active(void) { + const char *name = "XINERAMA"; + xcb_query_extension_cookie_t xinerama_cookie = + xcb_query_extension(conn, strlen(name), name); + xcb_query_extension_reply_t *xinerama_reply = + xcb_query_extension_reply(conn, xinerama_cookie, NULL); + + /* 扩展不存在 */ + if (!xinerama_reply || !xinerama_reply->present) { + free(xinerama_reply); + return false; + } + + xcb_xinerama_is_active_cookie_t active_cookie = xcb_xinerama_is_active(conn); + xcb_xinerama_is_active_reply_t *active_reply = + xcb_xinerama_is_active_reply(conn, active_cookie, NULL); + bool active = active_reply && active_reply->state; + free(xinerama_reply); + free(active_reply); + return active; +} + +static monitor_rect_t *detect_monitor_rect_by_xinerama(void) { monitor_rect_t *list, *prev; xcb_xinerama_query_screens_cookie_t cookie = xcb_xinerama_query_screens(conn); xcb_xinerama_query_screens_reply_t *reply = @@ -83,6 +102,25 @@ monitor_rect_t *detect_monitor_rect(void) { return list; } +/** + * 探测屏幕信息 + * @note: 返回值使用完后记得释放其内存 + */ +monitor_rect_t *detect_monitor_rect(void) { + if (xinerama_active()) { + return detect_monitor_rect_by_xinerama(); + } + + if (!screen) return NULL; + + monitor_rect_t *rect = ecalloc(1, sizeof(monitor_rect_t)); + rect->x = 0; + rect->y = 0; + rect->width = screen->width_in_pixels; + rect->height = screen->height_in_pixels; + return rect; +} + static xcb_ewmh_connection_t *ewmh = NULL; static void init_ewmh_extension(void) { if (ewmh) return;