清理 xcb 光标

This commit is contained in:
2025-08-16 06:43:44 +08:00
parent 8ac231fb4b
commit 4252604c52
3 changed files with 24 additions and 7 deletions

View File

@@ -103,14 +103,24 @@ static const char *xcursor_font_tostr(uint16_t c) {
return NULL; return NULL;
} }
static xcb_cursor_t cursor_list[LENGTH(xcursor_font)];
xcb_cursor_context_t *cursor_ctx = NULL;
xcb_cursor_t get_xcb_cursor(cursor_t cursor) { xcb_cursor_t get_xcb_cursor(cursor_t cursor) {
xcb_cursor_context_t *ctx = get_xcb_cursor_context(); if (!cursor_ctx) cursor_ctx = get_xcb_cursor_context();
if (!ctx) die("cannot get cursor:"); if (!cursor_ctx) die("cannot get cursor:");
static xcb_cursor_t cursor_list[LENGTH(xcursor_font)];
if (!cursor_list[cursor]) { if (!cursor_list[cursor]) {
const char *name = xcursor_font_tostr(cursor); const char *name = xcursor_font_tostr(cursor);
cursor_list[cursor] = xcb_cursor_load_cursor(ctx, name); cursor_list[cursor] = xcb_cursor_load_cursor(cursor_ctx, name);
} }
return cursor_list[cursor]; return cursor_list[cursor];
} }
void clean_xcb_cursor(void) {
for (int i = 0; i < LENGTH(xcursor_font); i++) {
xcb_cursor_t cursor = cursor_list[i];
if (cursor) xcb_free_cursor(conn, cursor);
}
xcb_cursor_context_free(cursor_ctx);
}

View File

@@ -6,3 +6,4 @@ extern xcb_connection_t *conn;
extern xcb_screen_t *screen; extern xcb_screen_t *screen;
xcb_cursor_t get_xcb_cursor(cursor_t cursor); xcb_cursor_t get_xcb_cursor(cursor_t cursor);
void clean_xcb_cursor(void);

View File

@@ -226,11 +226,13 @@ window_list_t *scan_window_list(void) {
xcb_query_tree_cookie_t cookie = xcb_query_tree(conn, screen->root); xcb_query_tree_cookie_t cookie = xcb_query_tree(conn, screen->root);
xcb_query_tree_reply_t *tree_reply = xcb_query_tree_reply(conn, cookie, NULL); xcb_query_tree_reply_t *tree_reply = xcb_query_tree_reply(conn, cookie, NULL);
if (!tree_reply) return NULL;
xcb_window_t *list = xcb_query_tree_children(tree_reply); xcb_window_t *list = xcb_query_tree_children(tree_reply);
int len = xcb_query_tree_children_length(tree_reply); int len = xcb_query_tree_children_length(tree_reply);
uint32_t count = 0; uint32_t count = 0;
xcb_window_t temp_windoow_array[len]; xcb_window_t temp_window_array[len];
for (int i = 0; i < len; i++) { for (int i = 0; i < len; i++) {
xcb_window_t window = list[i]; xcb_window_t window = list[i];
@@ -238,6 +240,8 @@ window_list_t *scan_window_list(void) {
xcb_get_window_attributes(conn, window); xcb_get_window_attributes(conn, window);
xcb_get_window_attributes_reply_t *attribute_reply = xcb_get_window_attributes_reply_t *attribute_reply =
xcb_get_window_attributes_reply(conn, wa_cookie, NULL); xcb_get_window_attributes_reply(conn, wa_cookie, NULL);
if (!attribute_reply) continue;
uint8_t override_redirect = attribute_reply->override_redirect; uint8_t override_redirect = attribute_reply->override_redirect;
uint8_t map_state = attribute_reply->map_state; uint8_t map_state = attribute_reply->map_state;
free(attribute_reply); free(attribute_reply);
@@ -249,7 +253,7 @@ window_list_t *scan_window_list(void) {
xcb_icccm_get_wm_transient_for_reply(conn, p_cookie, &transient_for, NULL); xcb_icccm_get_wm_transient_for_reply(conn, p_cookie, &transient_for, NULL);
if (transient_for != XCB_NONE) continue; if (transient_for != XCB_NONE) continue;
temp_windoow_array[count] = window; temp_window_array[count] = window;
count++; count++;
} }
free(tree_reply); free(tree_reply);
@@ -257,7 +261,7 @@ window_list_t *scan_window_list(void) {
if (!count) return NULL; if (!count) return NULL;
xcb_window_t *window_list = ecalloc(count, sizeof(xcb_window_t)); xcb_window_t *window_list = ecalloc(count, sizeof(xcb_window_t));
for (uint32_t i = 0; i < count; i++) window_list[i] = temp_windoow_array[i]; for (uint32_t i = 0; i < count; i++) window_list[i] = temp_window_array[i];
window_list_t *r = ecalloc(1, sizeof(window_list_t)); window_list_t *r = ecalloc(1, sizeof(window_list_t));
r->count = count; r->count = count;
@@ -283,6 +287,8 @@ void start_xcb_event_loop(void) {
} }
void clean_xcb(void) { void clean_xcb(void) {
clean_xcb_cursor();
if (wm_check_window != XCB_NONE) { if (wm_check_window != XCB_NONE) {
xcb_destroy_window(conn, wm_check_window); xcb_destroy_window(conn, wm_check_window);
wm_check_window = XCB_NONE; wm_check_window = XCB_NONE;