检查是否有其他窗口管理器正在运行

This commit is contained in:
2025-10-31 00:36:30 +08:00
parent 0ed798c113
commit e77c986109
3 changed files with 44 additions and 0 deletions

View File

@@ -28,6 +28,9 @@ find_package(PkgConfig REQUIRED)
pkg_check_modules(deps REQUIRED pkg_check_modules(deps REQUIRED
glib-2.0 glib-2.0
xcb
xcb-aux
) )
target_include_directories(${APP_NAME} SYSTEM target_include_directories(${APP_NAME} SYSTEM

View File

@@ -5,6 +5,9 @@
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include <unistd.h> #include <unistd.h>
#include <xcb/xcb.h>
#include <xcb/xcb_aux.h>
#include <xcb/xproto.h>
#include "backtrace.h" #include "backtrace.h"
#include "buffer.h" #include "buffer.h"
@@ -51,6 +54,34 @@ static void signal_child(int signum) {
assert(res == 1); 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, &params);
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[]) { int main(int argc, char *argv[]) {
p_clear(&global_state, 1); p_clear(&global_state, 1);
@@ -73,6 +104,8 @@ int main(int argc, char *argv[]) {
sa.sa_flags = SA_NOCLDSTOP | SA_RESTART; sa.sa_flags = SA_NOCLDSTOP | SA_RESTART;
sigaction(SIGCHLD, &sa, 0); sigaction(SIGCHLD, &sa, 0);
check_other_wm();
if (global_state.loop == NULL) { if (global_state.loop == NULL) {
global_state.loop = g_main_loop_new(NULL, FALSE); global_state.loop = g_main_loop_new(NULL, FALSE);
g_main_loop_run(global_state.loop); g_main_loop_run(global_state.loop);

View File

@@ -1,8 +1,16 @@
#pragma once #pragma once
#include <glib.h> #include <glib.h>
#include <xcb/xcb.h>
#include <xcb/xproto.h>
typedef struct global_state_t { typedef struct global_state_t {
bool need_restart; bool need_restart;
GMainLoop *loop; GMainLoop *loop;
xcb_connection_t *xcb_conn;
xcb_screen_t *screen;
int default_screen;
} global_state_t; } global_state_t;
extern global_state_t global_state;