feat(core+backend/X11): 实现窗口状态变更(最大化/最小化/全屏)

This commit is contained in:
2026-04-28 03:45:40 +08:00
parent d602b0111e
commit a393308704
8 changed files with 263 additions and 31 deletions

View File

@@ -502,6 +502,33 @@ static void backend_merge_effects(
XCB_ICCCM_WM_STATE_WITHDRAWN
);
break;
case ZDWM_EFFECT_MINIMIZE_WINDOW: {
auto window = e->as.minimize.window;
xcb_icccm_wm_state_t state = XCB_ICCCM_WM_STATE_NORMAL;
if (e->as.minimize.value) state = XCB_ICCCM_WM_STATE_ICONIC;
window_set_icccm_wm_state(backend->conn, window, state);
} break;
case ZDWM_EFFECT_MAXIMIZE_WINDOW: {
auto window = e->as.maximize.window;
if (e->as.maximize.value) {
xcb_atom_t max_atoms[] = {
backend->atoms._NET_WM_STATE_MAXIMIZED_HORZ,
backend->atoms._NET_WM_STATE_MAXIMIZED_VERT
};
window_set_net_wm_state(backend, window, countof(max_atoms), max_atoms);
} else {
window_set_net_wm_state(backend, window, 0, nullptr);
}
} break;
case ZDWM_EFFECT_FULLSCREEN_WINDOW: {
auto window = e->as.fullscreen.window;
if (e->as.fullscreen.value) {
auto fullscreen_atom = backend->atoms._NET_WM_STATE_FULLSCREEN;
window_set_net_wm_state(backend, window, 1, &fullscreen_atom);
} else {
window_set_net_wm_state(backend, window, 0, nullptr);
}
} break;
case ZDWM_EFFECT_MOVE_WINDOW: {
window_configure_t *cfg =
find_or_push_configure(configs, e->as.move.window);

View File

@@ -340,6 +340,24 @@ void window_set_icccm_wm_state(
xcb_icccm_set_wm_hints(conn, window, &hints);
}
void window_set_net_wm_state(
backend_t *backend,
xcb_window_t window,
size_t count,
xcb_atom_t *atoms
) {
xcb_change_property(
backend->conn,
XCB_PROP_MODE_REPLACE,
window,
backend->atoms._NET_WM_STATE,
XCB_ATOM_ATOM,
32,
count,
atoms
);
}
void window_list_push(window_list_t *window_list, xcb_window_t window) {
xcb_window_t *win =
array_push(window_list->windows, window_list->count, window_list->capacity);

View File

@@ -3,6 +3,7 @@
#include <stdbool.h>
#include <stddef.h>
#include <string.h>
#include <xcb/xcb.h>
#include <xcb/xcb_icccm.h>
#include <xcb/xproto.h>
@@ -89,6 +90,12 @@ void window_set_icccm_wm_state(
xcb_window_t window,
xcb_icccm_wm_state_t state
);
void window_set_net_wm_state(
backend_t *backend,
xcb_window_t window,
size_t count,
xcb_atom_t *atoms
);
void window_list_push(window_list_t *window_list, xcb_window_t window);
void window_list_reset(window_list_t *window_list);