feat(backend): 添加光标支持

This commit is contained in:
2026-06-19 17:12:08 +08:00
parent 090266baa5
commit 7a47f4d44d
7 changed files with 99 additions and 2 deletions

View File

@@ -26,6 +26,7 @@ project(${APP_NAME}
add_executable(${APP_NAME}
${SOURCE_DIR}/backend/output_utils.c
${SOURCE_DIR}/backend/x11/backend.c
${SOURCE_DIR}/backend/x11/cursor.c
${SOURCE_DIR}/backend/x11/event.c
${SOURCE_DIR}/backend/x11/window.c
@@ -76,6 +77,7 @@ find_package(PkgConfig REQUIRED)
pkg_check_modules(deps REQUIRED
xcb
xcb-aux
xcb-cursor
xcb-icccm
xcb-keysyms
xcb-randr

View File

@@ -18,6 +18,7 @@
#include <xcb/xproto.h>
#include "backend/output_utils.h"
#include "backend/x11/cursor.h"
#include "backend/x11/window.h"
#include "base/app.h"
#include "base/array.h"
@@ -184,10 +185,13 @@ backend_t *backend_create(const char *display_name) {
backend->key_symbols = xcb_key_symbols_alloc(conn);
cursor_init(backend);
atoms_init(backend);
create_wm_check_window(backend);
create_no_focus_window(backend);
window_change_cursor(backend, root, ZDWM_CURSOR_NORMAL);
return backend;
}
@@ -204,6 +208,8 @@ void backend_destroy(backend_t *backend) {
xcb_key_symbols_free(backend->key_symbols);
backend->key_symbols = nullptr;
cursor_cleanup(backend);
xcb_disconnect(backend->conn);
backend->conn = nullptr;
free(backend);

51
src/backend/x11/cursor.c Normal file
View File

@@ -0,0 +1,51 @@
#include <stddef.h>
#include <xcb/xcb_cursor.h>
#include <xcb/xproto.h>
#include "base/macros.h"
#include "base/memory.h"
#include "internal.h"
static const char *const cursor_name_map[] = {
[ZDWM_CURSOR_NORMAL] = "left_ptr",
[ZDWM_CURSOR_MOVE] = "fleur",
[ZDWM_CURSOR_RESIZE] = "bottom_right_corner",
};
static xcb_cursor_context_t *get_xcb_cursor_context(backend_t *backend) {
if (backend->cursor_context) return backend->cursor_context;
auto conn = backend->conn;
auto screen = backend->screen;
if (xcb_cursor_context_new(conn, screen, &backend->cursor_context) == 0) {
return backend->cursor_context;
}
return nullptr;
}
void cursor_init(backend_t *backend) {
auto ctx = get_xcb_cursor_context(backend);
if (!ctx) return;
for (size_t i = 0; i < countof(backend->cursors); ++i) {
auto cursor_name = cursor_name_map[i];
backend->cursors[i] = xcb_cursor_load_cursor(ctx, cursor_name);
}
}
void cursor_cleanup(backend_t *backend) {
constexpr size_t count = countof(backend->cursors);
for (size_t i = 0; i < count; ++i) {
xcb_free_cursor(backend->conn, backend->cursors[i]);
}
p_clear(backend->cursors, count);
xcb_cursor_context_free(backend->cursor_context);
backend->cursor_context = nullptr;
}
xcb_cursor_t cursor_get_xcb_cursor(backend_t *backend, cursor_t cursor) {
if (backend->cursor_context == nullptr) return XCB_CURSOR_NONE;
return backend->cursors[cursor];
}

9
src/backend/x11/cursor.h Normal file
View File

@@ -0,0 +1,9 @@
#pragma once
#include <xcb/xproto.h>
#include "internal.h"
void cursor_init(backend_t *backend);
void cursor_cleanup(backend_t *backend);
xcb_cursor_t cursor_get_xcb_cursor(backend_t *backend, cursor_t cursor);

View File

@@ -3,6 +3,7 @@
#include <stddef.h>
#include <stdint.h>
#include <xcb/xcb.h>
#include <xcb/xcb_cursor.h>
#include <xcb/xcb_keysyms.h>
#include <xcb/xproto.h>
@@ -78,7 +79,14 @@ typedef struct window_configure_list_t {
size_t capacity;
} window_configure_list_t;
struct backend_t {
typedef enum cursor_t {
ZDWM_CURSOR_NORMAL,
ZDWM_CURSOR_MOVE,
ZDWM_CURSOR_RESIZE,
ZDWM_CURSOR_COUNT,
} cursor_t;
typedef struct backend_t {
xcb_key_symbols_t *key_symbols;
xcb_connection_t *conn;
xcb_screen_t *screen;
@@ -94,11 +102,14 @@ struct backend_t {
xcb_window_t focus_window;
bool update_focus;
xcb_cursor_t cursors[ZDWM_CURSOR_COUNT];
xcb_cursor_context_t *cursor_context;
window_configure_list_t config_list;
window_list_t unmap;
window_list_t map;
window_list_t kill;
};
} backend_t;
bool populate_window_event(
struct backend_t *backend,

View File

@@ -3,10 +3,12 @@
#include <stddef.h>
#include <stdint.h>
#include <xcb/xcb.h>
#include <xcb/xcb_aux.h>
#include <xcb/xcb_icccm.h>
#include <xcb/xcb_keysyms.h>
#include <xcb/xproto.h>
#include "backend/x11/cursor.h"
#include "base/macros.h"
#include "base/memory.h"
#include "core/backend.h"
@@ -451,3 +453,13 @@ visual_t *window_get_visual(backend_t *backend, bool prefer_alpha) {
return visual;
}
void window_change_cursor(
backend_t *backend,
xcb_window_t window,
cursor_t cursor
) {
auto conn = backend->conn;
xcb_params_cw_t params = {.cursor = cursor_get_xcb_cursor(backend, cursor)};
xcb_aux_change_window_attributes(conn, window, XCB_CW_CURSOR, &params);
}

View File

@@ -118,3 +118,9 @@ typedef struct visual_t {
* @returns 返回的信息使用后记得使用 free 释放
*/
visual_t *window_get_visual(backend_t *backend, bool prefer_alpha);
void window_change_cursor(
backend_t *backend,
xcb_window_t window,
cursor_t cursor
);