From e77c9861094e4ecdc83b592bd477d036ec8c6b9a Mon Sep 17 00:00:00 2001 From: Zedhugh Chen Date: Fri, 31 Oct 2025 00:36:30 +0800 Subject: [PATCH] =?UTF-8?q?=E6=A3=80=E6=9F=A5=E6=98=AF=E5=90=A6=E6=9C=89?= =?UTF-8?q?=E5=85=B6=E4=BB=96=E7=AA=97=E5=8F=A3=E7=AE=A1=E7=90=86=E5=99=A8?= =?UTF-8?q?=E6=AD=A3=E5=9C=A8=E8=BF=90=E8=A1=8C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/CMakeLists.txt | 3 +++ src/main.c | 33 +++++++++++++++++++++++++++++++++ src/types.h | 8 ++++++++ 3 files changed, 44 insertions(+) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 73cc204..a7ec5ba 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -28,6 +28,9 @@ find_package(PkgConfig REQUIRED) pkg_check_modules(deps REQUIRED glib-2.0 + + xcb + xcb-aux ) target_include_directories(${APP_NAME} SYSTEM diff --git a/src/main.c b/src/main.c index b48901a..18dbf8a 100644 --- a/src/main.c +++ b/src/main.c @@ -5,6 +5,9 @@ #include #include #include +#include +#include +#include #include "backtrace.h" #include "buffer.h" @@ -51,6 +54,34 @@ static void signal_child(int signum) { assert(res == 1); } +static void check_other_wm(void) { + /* connect X server */ + int default_screen; + xcb_connection_t *conn = xcb_connect(NULL, &default_screen); + int xcb_conn_error = xcb_connection_has_error(conn); + if (xcb_conn_error) fatal("cannot open display (error %d)", xcb_conn_error); + + xcb_screen_t *screen = xcb_aux_get_screen(conn, default_screen); + xcb_window_t root = screen->root; + + /* check other window manager running */ + uint32_t mask = XCB_CW_EVENT_MASK; + const xcb_params_cw_t params = { + .event_mask = XCB_EVENT_MASK_SUBSTRUCTURE_REDIRECT, + }; + xcb_void_cookie_t cookie = + xcb_aux_change_window_attributes_checked(conn, root, mask, ¶ms); + if (xcb_request_check(conn, cookie)) { + fatal( + "another window manager is already running (cannot select " + "SubstructureRedirect)"); + } + + global_state.xcb_conn = conn; + global_state.default_screen = default_screen; + global_state.screen = screen; +} + int main(int argc, char *argv[]) { p_clear(&global_state, 1); @@ -73,6 +104,8 @@ int main(int argc, char *argv[]) { sa.sa_flags = SA_NOCLDSTOP | SA_RESTART; sigaction(SIGCHLD, &sa, 0); + check_other_wm(); + if (global_state.loop == NULL) { global_state.loop = g_main_loop_new(NULL, FALSE); g_main_loop_run(global_state.loop); diff --git a/src/types.h b/src/types.h index f0d1975..00e6320 100644 --- a/src/types.h +++ b/src/types.h @@ -1,8 +1,16 @@ #pragma once #include +#include +#include typedef struct global_state_t { bool need_restart; GMainLoop *loop; + + xcb_connection_t *xcb_conn; + xcb_screen_t *screen; + int default_screen; } global_state_t; + +extern global_state_t global_state;