Compare commits

...

3 Commits

Author SHA1 Message Date
367d825a58 WIP: 迁移窗口堆叠顺序到新方案 2026-04-01 16:09:29 +08:00
196dab9bb3 事件循环框架 2026-04-01 16:08:01 +08:00
90a25fb120 core: 添加窗口所属层级判定 2026-03-31 18:02:38 +08:00
14 changed files with 161 additions and 16 deletions

View File

@@ -15,13 +15,7 @@
#include "base/log.h"
#include "base/memory.h"
#include "core/types.h"
struct backend_t {
xcb_connection_t *conn;
xcb_screen_t *screen;
int screenp;
bool have_xfixes;
};
#include "internal.h" /* IWYU pragma: keep */
backend_t *backend_create(const char *display_name) {
int screen_num = 0;

74
src/backend/x11/event.c Normal file
View File

@@ -0,0 +1,74 @@
#include <stdio.h>
#include <xcb/xcb.h>
#include <xcb/xcb_event.h>
#include <xcb/xproto.h>
#include "base/memory.h"
#include "core/backend.h"
#include "internal.h" /* IWYU pragma: keep */
static bool handle_map_request(event_t *event,
const xcb_map_request_event_t *xcb_event) {
p_clear(event, 1);
event->type = ZDWM_EVENT_WINDOW_MAP_REQUEST;
/* TODO: */
return true;
}
static bool handle_unmap_notify(event_t *event,
const xcb_unmap_notify_event_t *xcb_event) {
p_clear(event, 1);
event->type = ZDWM_EVENT_WINDOW_REMOVE;
/* TODO: */
return true;
}
static bool handle_destroy_notify(event_t *event,
const xcb_destroy_notify_event_t *xcb_event) {
p_clear(event, 1);
event->type = ZDWM_EVENT_WINDOW_REMOVE;
/* TODO: */
return true;
}
static bool handle_configure_request(
event_t *event, const xcb_configure_request_event_t *xcb_event) {
p_clear(event, 1);
event->type = ZDWM_EVENT_CONFIGURE_REQUEST;
/* TODO: */
return true;
}
bool backend_next_event(backend_t *backend, event_t *event) {
if (!backend || !backend->conn || !event) return false;
for (;;) {
xcb_generic_event_t *raw_event = xcb_wait_for_event(backend->conn);
if (!raw_event) return false;
uint8_t response_type = XCB_EVENT_RESPONSE_TYPE(raw_event);
bool handled = false;
printf("xcb event type: %u\n", response_type);
switch (response_type) {
#define EVENT(type, handler) \
case type: \
handled = handler(event, (void *)raw_event); \
break
EVENT(XCB_MAP_REQUEST, handle_map_request);
EVENT(XCB_UNMAP_NOTIFY, handle_unmap_notify);
EVENT(XCB_DESTROY_NOTIFY, handle_destroy_notify);
EVENT(XCB_CONFIGURE_REQUEST, handle_configure_request);
#undef EVENT
default:
break;
}
p_delete(&raw_event);
if (handled) return true;
}
}

View File

@@ -0,0 +1,12 @@
#pragma once
#include <xcb/xcb.h>
#include "core/backend.h" /* IWYU pragma: keep */
struct backend_t {
xcb_connection_t *conn;
xcb_screen_t *screen;
int screenp;
bool have_xfixes;
};

View File

@@ -2,6 +2,7 @@
#include <stddef.h>
#include "core/event.h"
#include "core/types.h"
typedef struct backend_t backend_t;
@@ -16,3 +17,5 @@ void backend_destroy(backend_t *backend);
backend_detect_t *backend_detect(backend_t *backend);
void backend_detect_destroy(backend_detect_t *detect);
bool backend_next_event(backend_t *backend, event_t *event);

View File

@@ -63,9 +63,10 @@ typedef struct pointer_enter_event_t {
} pointer_enter_event_t;
typedef struct window_map_request_event_t {
window_id_t id;
window_id_t window;
window_props_t props;
window_metadata_t metadata;
window_geometry_mode_t geometry;
} window_map_request_event_t;
typedef enum window_remove_reason_t {
@@ -154,7 +155,6 @@ typedef struct configure_request_event_t {
typedef struct event_t {
event_type_t type;
uint32_t time_ms;
union {
key_press_event_t key_press;
pointer_button_event_t pointer_button_press;

View File

@@ -5,6 +5,7 @@
#include "base/array.h"
#include "base/memory.h"
#include "core/types.h"
#include "core/window.h"
void layer_stack_cleanup(layer_stack_t *layer) {
p_delete(&layer->order);
@@ -86,3 +87,17 @@ bool layer_stack_lower(layer_stack_t *layer, window_id_t window) {
return true;
}
layer_type_t layer_classify(const window_props_t *props) {
for (size_t i = 0; i < props->type_count; ++i) {
window_type_t type = props->types[i];
if (type == ZDWM_WINDOW_TYPE_NOTIFICATION) return ZDWM_WINDOW_LAYER_OVERLAY;
}
for (size_t i = 0; i < props->state_count; ++i) {
window_state_t state = props->states[i];
if (state == ZDWM_WINDOW_STATE_ABOVE) return ZDWM_WINDOW_LAYER_TOP;
}
return ZDWM_WINDOW_LAYER_NORMAL;
}

10
src/core/policy.c Normal file
View File

@@ -0,0 +1,10 @@
#include "core/policy.h"
#include "base/macros.h"
#include "core/state.h"
layer_type_t policy_adjust_window_layer_from_transient(
const state_t *state, window_id_t transient_for, layer_type_t base_layer) {
const window_t *window = state_window_get(state, transient_for);
return MAX(window->layer, base_layer);
}

View File

@@ -4,6 +4,7 @@
#include "base/memory.h"
#include "core/backend.h"
#include "core/event.h"
#include "core/state.h"
#include "core/wm_desc.h"
@@ -90,3 +91,12 @@ void runtime_shutdown(runtime_t *runtime) {
if (runtime->config_module_handle) dlclose(runtime->config_module_handle);
runtime->config_module_handle = nullptr;
}
void runtime_run(runtime_t *runtime) {
for (;;) {
event_t event = {0};
if (!backend_next_event(runtime->backend, &event)) {
break;
}
}
}

View File

@@ -30,3 +30,4 @@ typedef struct runtime_t {
bool runtime_init(runtime_t *runtime, runtime_init_desc_t *desc);
void runtime_init_desc_cleanup(runtime_init_desc_t *desc);
void runtime_shutdown(runtime_t *runtime);
void runtime_run(runtime_t *runtime);

View File

@@ -6,6 +6,7 @@
#include "base/array.h"
#include "base/log.h"
#include "base/memory.h"
#include "core/layer.h"
#include "core/types.h"
#include "core/wm_desc.h"
@@ -69,9 +70,15 @@ void state_cleanup(state_t *state) {
}
state->window_count = 0;
p_delete(&state->windows);
p_delete(&state->stack_order);
state->window_capacity = 0;
for (size_t i = 0; i < ZDWM_WINDOW_LAYER_COUNT; ++i) {
layer_stack_t *layer = &state->stacks[i];
p_delete(&layer->order);
layer->order = 0;
layer->capacity = 0;
}
for (size_t i = 0; i < state->workspace_count; i++) {
workspace_t *workspace = &state->workspaces[i];
p_delete(&workspace->name);
@@ -112,12 +119,15 @@ static void state_workspace_adjust_focused_window(const state_t *state,
state_window_get(state, workspace->focused_window_id);
if (window && window->workspace_id == workspace_id) return;
for (size_t i = state->window_count; i > 0; i--) {
window_id_t window_id = state->stack_order[i - 1];
const window_t *window = state_window_get(state, window_id);
if (window && window->workspace_id == workspace_id) {
workspace->focused_window_id = window_id;
return;
for (size_t i = ZDWM_WINDOW_LAYER_TOP; i >= ZDWM_WINDOW_LAYER_NORMAL; --i) {
const layer_stack_t *layer = &state->stacks[i];
for (size_t i = layer->count; i > 0; --i) {
window_id_t window_id = layer->order[i - 1];
window = state_window_get(state, window_id);
if (window && window->workspace_id == workspace_id) {
workspace->focused_window_id = window_id;
return;
}
}
}

View File

@@ -34,6 +34,8 @@ typedef struct window_props_t {
window_id_t transient_for;
bool override_redirect;
bool skip_taskbar;
bool urgent;
window_type_t *types;
size_t type_count;
@@ -48,3 +50,9 @@ typedef struct window_metadata_t {
const char *class_name;
const char *instance_name;
} window_metadata_t;
typedef struct window_geometry_t {
window_geometry_mode_t mode;
rect_t rect;
bool fixed_size;
} window_geometry_t;

View File

@@ -16,6 +16,12 @@ struct backend_t {
void backend_destroy(backend_t *backend) { free(backend); }
bool backend_next_event(backend_t *backend, event_t *event) {
(void)backend;
(void)event;
return false;
}
static backend_t *test_backend_create(void) {
return calloc(1, sizeof(backend_t));
}

View File

@@ -8,6 +8,7 @@ add_executable(${TEST_APP_NAME}
${SOURCE_DIR}/config/loader.c
${SOURCE_DIR}/config/runtime_config.c
${SOURCE_DIR}/backend/x11/backend.c
${SOURCE_DIR}/backend/x11/event.c
${SOURCE_DIR}/core/layout.c
${SOURCE_DIR}/core/runtime.c
${SOURCE_DIR}/core/state.c

View File

@@ -36,6 +36,7 @@ int main(void) {
runtime_t runtime = {0};
bootstrap(&runtime);
runtime_run(&runtime);
runtime_shutdown(&runtime);
return 0;