fix(backend): 扫描窗口时按 transient 关系排序并过滤无效窗口

This commit is contained in:
2026-06-23 00:33:03 +08:00
parent b71b66921e
commit f3b1466dac
2 changed files with 34 additions and 10 deletions

View File

@@ -711,19 +711,47 @@ backend_scan_result_t *backend_scan_windows(backend_t *backend) {
auto list = xcb_query_tree_children(reply); auto list = xcb_query_tree_children(reply);
backend_scan_result_t *result = p_new(backend_scan_result_t, 1); auto result = p_new(backend_scan_result_t, 1);
auto sub_result = p_new(backend_scan_result_t, 1);
for (int i = 0; i < length; i++) { for (typeof(length) i = 0; i < length; ++i) {
auto slot = array_push(result->windows, result->count, result->capacity); auto window = list[i];
if (!populate_window_event(backend, list[i], slot)) { auto wa = window_get_attributes(backend, window);
if (!wa) continue;
auto override_redirect = wa->override_redirect;
auto map_state = wa->map_state;
p_delete(&wa);
if (override_redirect) continue;
auto hints = (xcb_icccm_wm_hints_t){0};
auto hints_getted = window_get_wm_hints(backend, window, &hints);
if (!(map_state == XCB_MAP_STATE_VIEWABLE ||
(hints_getted && hints.initial_state == XCB_ICCCM_WM_STATE_ICONIC))) {
continue;
}
auto transient_for = window_get_transient_for(backend, window);
auto r = transient_for == XCB_WINDOW_NONE ? result : sub_result;
auto slot = array_push(r->windows, r->count, r->capacity);
if (!populate_window_event(backend, list[i], slot) ||
slot->override_redirect) {
window_layer_props_cleanup(&slot->props); window_layer_props_cleanup(&slot->props);
window_metadata_cleanup(&slot->metadata); window_metadata_cleanup(&slot->metadata);
result->count--; r->count--;
} }
} }
p_delete(&reply); p_delete(&reply);
for (size_t i = 0; i < sub_result->count; ++i) {
auto slot = array_push(result->windows, result->count, result->capacity);
*slot = sub_result->windows[i];
}
p_clear(sub_result->windows, sub_result->count);
backend_scan_result_destroy(sub_result);
if (result->count == 0) { if (result->count == 0) {
backend_scan_result_destroy(result); backend_scan_result_destroy(result);
result = nullptr; result = nullptr;

View File

@@ -52,10 +52,6 @@ static bool derive_skip_taskbar(
return false; return false;
} }
static bool minimized_from_hints(const xcb_icccm_wm_hints_t *hints) {
return hints->initial_state == XCB_ICCCM_WM_STATE_ICONIC;
}
static bool maximized_from_states( static bool maximized_from_states(
const atoms_t *atoms, const atoms_t *atoms,
const xcb_atom_t *state_atoms, const xcb_atom_t *state_atoms,
@@ -130,7 +126,7 @@ bool populate_window_event(
xcb_icccm_wm_hints_t wm_hints = {0}; xcb_icccm_wm_hints_t wm_hints = {0};
if (window_get_wm_hints(backend, window, &wm_hints)) { if (window_get_wm_hints(backend, window, &wm_hints)) {
ev->urgent = (bool)xcb_icccm_wm_hints_get_urgency(&wm_hints); ev->urgent = (bool)xcb_icccm_wm_hints_get_urgency(&wm_hints);
ev->minimized = minimized_from_hints(&wm_hints); ev->minimized = wm_hints.initial_state == XCB_ICCCM_WM_STATE_ICONIC;
} }
xcb_size_hints_t size_hints = {0}; xcb_size_hints_t size_hints = {0};