实现 wm_scan_clients 函数

This commit is contained in:
2026-01-25 15:57:19 +08:00
parent ef37f28fa5
commit 47d578ca71
4 changed files with 103 additions and 8 deletions

View File

@@ -2,7 +2,6 @@
#include <glib.h>
#include <stdint.h>
#include <string.h>
#include <xcb/xcb.h>
#include <xcb/xcb_event.h>
#include <xcb/xcb_keysyms.h>
@@ -107,10 +106,8 @@ static void key_press(xcb_key_press_event_t *ev) {
}
static void map_request(xcb_map_request_event_t *ev) {
xcb_get_window_attributes_cookie_t wa_cookie =
xcb_get_window_attributes_unchecked(wm.xcb_conn, ev->window);
xcb_get_window_attributes_reply_t *wa_reply =
xcb_get_window_attributes_reply(wm.xcb_conn, wa_cookie, nullptr);
xwindow_get_attributes_reply(ev->window);
if (!wa_reply) return;
if (wa_reply->override_redirect) {
@@ -120,10 +117,8 @@ static void map_request(xcb_map_request_event_t *ev) {
client_t *c = client_get_by_window(ev->window);
if (!c) {
xcb_get_geometry_cookie_t geo_cookie =
xcb_get_geometry(wm.xcb_conn, ev->window);
xcb_get_geometry_reply_t *geo_reply =
xcb_get_geometry_reply(wm.xcb_conn, geo_cookie, nullptr);
xwindow_get_geometry_reply(ev->window);
if (!geo_reply) {
p_delete(&wa_reply);
return;

View File

@@ -243,7 +243,67 @@ void wm_detect_monitor(void) {
wm.current_monitor = monitor;
}
void wm_scan_clients(void) {}
typedef struct window_list_t {
xcb_window_t *normal_list;
xcb_window_t *transient_list;
uint32_t normal_count;
uint32_t transient_count;
} window_list_t;
void wm_scan_clients(void) {
xcb_query_tree_cookie_t cookie = xcb_query_tree(wm.xcb_conn, wm.screen->root);
xcb_query_tree_reply_t *tree_reply =
xcb_query_tree_reply(wm.xcb_conn, cookie, nullptr);
if (!tree_reply) return;
xcb_window_t *list = xcb_query_tree_children(tree_reply);
int len = xcb_query_tree_children_length(tree_reply);
if (!len) {
p_delete(&tree_reply);
return;
}
xcb_get_window_attributes_reply_t *wa_reply = nullptr;
xcb_get_geometry_reply_t *geo_reply = nullptr;
for (int i = 0; i < len; i++) {
xcb_window_t window = list[i];
wa_reply = xwindow_get_attributes_reply(window);
if (!wa_reply) continue;
uint8_t override_redirect = wa_reply->override_redirect;
uint8_t map_state = wa_reply->map_state;
p_delete(&wa_reply);
if (override_redirect || xwindow_get_transient_for(window)) continue;
geo_reply = xwindow_get_geometry_reply(window);
if (!geo_reply) continue;
if (map_state == XCB_MAP_STATE_VIEWABLE ||
xwindow_get_state(window) == XCB_ICCCM_WM_STATE_ICONIC) {
client_manage(window, geo_reply);
}
p_delete(&geo_reply);
}
for (int i = 0; i < len; i++) {
xcb_window_t window = list[i];
wa_reply = xwindow_get_attributes_reply(window);
if (!wa_reply) continue;
uint8_t map_state = wa_reply->map_state;
p_delete(&wa_reply);
geo_reply = xwindow_get_geometry_reply(window);
if (!geo_reply) continue;
if (xwindow_get_transient_for(window) &&
(map_state == XCB_MAP_STATE_VIEWABLE ||
xwindow_get_state(window) == XCB_ICCCM_WM_STATE_ICONIC)) {
client_manage(window, geo_reply);
}
p_delete(&geo_reply);
}
p_delete(&tree_reply);
}
void wm_clean(void) {
text_clean_pango_layout();
@@ -483,6 +543,7 @@ int main(int argc, char *argv[]) {
wm_detect_monitor();
wm_setup();
setup_event_loop();
wm_scan_clients();
debug_show_monitor_list();

View File

@@ -205,3 +205,37 @@ void xwindow_get_text_property(xcb_window_t window, xcb_atom_t property,
p_delete(&reply);
}
xcb_window_t xwindow_get_transient_for(xcb_window_t window) {
xcb_connection_t *conn = wm.xcb_conn;
xcb_window_t t_window = XCB_WINDOW_NONE;
xcb_get_property_cookie_t cookie =
xcb_icccm_get_wm_transient_for(conn, window);
xcb_icccm_get_wm_transient_for_reply(conn, cookie, &t_window, nullptr);
return t_window;
}
/**
* @brief 获取窗口的状态
* @param window 目标窗口
* @returns 成功返回 xcb_icccm_wm_state_t 枚举类型,失败返回 -1
*/
int32_t xwindow_get_state(xcb_window_t window) {
xcb_connection_t *conn = wm.xcb_conn;
xcb_icccm_wm_hints_t hints;
xcb_get_property_cookie_t cookie = xcb_icccm_get_wm_hints(conn, window);
if (!xcb_icccm_get_wm_hints_reply(conn, cookie, &hints, nullptr)) return -1;
return hints.initial_state;
}
xcb_get_geometry_reply_t *xwindow_get_geometry_reply(xcb_window_t window) {
xcb_get_geometry_cookie_t cookie = xcb_get_geometry(wm.xcb_conn, window);
return xcb_get_geometry_reply(wm.xcb_conn, cookie, nullptr);
}
xcb_get_window_attributes_reply_t *xwindow_get_attributes_reply(
xcb_window_t window) {
xcb_get_window_attributes_cookie_t wa_cookie =
xcb_get_window_attributes(wm.xcb_conn, window);
return xcb_get_window_attributes_reply(wm.xcb_conn, wa_cookie, nullptr);
}

View File

@@ -20,6 +20,11 @@ bool xwindow_send_event(xcb_window_t window, xcb_atom_t atom);
void xwindow_focus(xcb_window_t window);
void xwindow_get_text_property(xcb_window_t window, xcb_atom_t property,
char **out);
xcb_window_t xwindow_get_transient_for(xcb_window_t window);
int32_t xwindow_get_state(xcb_window_t window);
xcb_get_geometry_reply_t *xwindow_get_geometry_reply(xcb_window_t window);
xcb_get_window_attributes_reply_t *xwindow_get_attributes_reply(
xcb_window_t window);
#define xwindow_set_name_static(window, name) \
xcb_icccm_set_wm_name(wm.xcb_conn, window, XCB_ATOM_STRING, 8, \