检查是否有其他窗口管理器正在运行
This commit is contained in:
@@ -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
|
||||||
|
|||||||
33
src/main.c
33
src/main.c
@@ -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, ¶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[]) {
|
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);
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
Reference in New Issue
Block a user