Compare commits

...

5 Commits

10 changed files with 119 additions and 84 deletions

View File

@@ -605,15 +605,15 @@ event_bus_publish("network.speed_changed", &speed);
* 与 mini_core_draft 对比 * 与 mini_core_draft 对比
| 特性 | mini_core_draft | 最小核心 + 插件 | | 特性 | mini_core_draft | 最小核心 + 插件 |
|------|-----------------|----------------| |--------------+-----------------+-----------------|
| 核心代码行数 | ~3000行 | ~1500行 | | 核心代码行数 | ~3000行 | ~1500行 |
| 抽象层 | 3-4层 | 1层钩子 | | 抽象层 | 3-4层 | 1层钩子 |
| 扩展方式 | 服务注册 | 插件+钩子 | | 扩展方式 | 服务注册 | 插件+钩子 |
| 学习曲线 | 陡峭 | 平缓 | | 学习曲线 | 陡峭 | 平缓 |
| 性能 | 中等 | 最好 | | 性能 | 中等 | 最好 |
| 可扩展性 | 很高 | 高 | | 可扩展性 | 很高 | 高 |
| 复杂度 | 高 | 低 | | 复杂度 | 高 | 低 |
* 核心代码量估算 * 核心代码量估算

View File

@@ -393,14 +393,14 @@ config.c
## 实现优先级 ## 实现优先级
| 优先级 | 模块 | 说明 | | 优先级 | 模块 | 说明 |
|-------|------|------| |--------|------------------|--------------------------------|
| P0 | config_default.c | 定义默认配置值 | | P0 | config_default.c | 定义默认配置值 |
| P0 | config.c | 主加载逻辑 | | P0 | config.c | 主加载逻辑 |
| P1 | config_xres.c | XResources 支持(已有基础) | | P1 | config_xres.c | XResources 支持(已有基础) |
| P1 | 热重载 | SIGHUP 支持(配合 XResources | | P1 | 热重载 | SIGHUP 支持(配合 XResources |
| P1 | config_lib.c | 动态库加载 | | P1 | config_lib.c | 动态库加载 |
| P2 | config_api.c | API 实现 | | P2 | config_api.c | API 实现 |
**P0**: 核心功能,必须实现 **P0**: 核心功能,必须实现
**P1**: 重要功能,提升用户体验 **P1**: 重要功能,提升用户体验

View File

@@ -796,17 +796,17 @@ static bool route_move_floating_event(wm_runtime_t *runtime,
**输入事件 → 命令映射** **输入事件 → 命令映射**
| 事件类型 | 可能生成的命令 | 条件 | | 事件类型 | 可能生成的命令 | 条件 |
|---------|---------------|------| |-------------------------+-----------------------------------------------------+----------------------------------------------------------|
| KEY_PRESS | 任意命令(通过键盘绑定) | 绑定存在 | | KEY_PRESS | 任意命令(通过键盘绑定) | 绑定存在 |
| POINTER_BUTTON_PRESS | 任意窗口命令 / BEGIN_*_INTERACTION通过鼠标绑定 | 绑定存在 | | POINTER_BUTTON_PRESS | 任意窗口命令 / BEGIN_*_INTERACTION通过鼠标绑定 | 绑定存在 |
| POINTER_ENTER | FOCUS_WINDOW | policy.pointer_enter_focuses_window == true 且窗口已管理 | | POINTER_ENTER | FOCUS_WINDOW | policy.pointer_enter_focuses_window == true 且窗口已管理 |
| WINDOW_MAP_REQUEST | MANAGE_WINDOW | 窗口未管理 | | WINDOW_MAP_REQUEST | MANAGE_WINDOW | 窗口未管理 |
| WINDOW_REMOVE | UNMANAGE_WINDOW | 窗口已管理 | | WINDOW_REMOVE | UNMANAGE_WINDOW | 窗口已管理 |
| WINDOW_ACTIVATE_REQUEST | SWITCH_WORKSPACE + FOCUS_WINDOW / SET_WINDOW_URGENT | source == pager / source != pager | | WINDOW_ACTIVATE_REQUEST | SWITCH_WORKSPACE + FOCUS_WINDOW / SET_WINDOW_URGENT | source == pager / source != pager |
| WINDOW_STATE_REQUEST | SET_FULLSCREEN / SET_MAXIMIZED / SET_MINIMIZED | 窗口已管理 | | WINDOW_STATE_REQUEST | SET_FULLSCREEN / SET_MAXIMIZED / SET_MINIMIZED | 窗口已管理 |
| CONFIGURE_REQUEST | (可能不生成命令) | floating 窗口 | | CONFIGURE_REQUEST | (可能不生成命令) | floating 窗口 |
| POINTER_MOTION | MOVE/RESIZE 命令 | 交互态下 | | POINTER_MOTION | MOVE/RESIZE 命令 | 交互态下 |
补充约定: 补充约定:

View File

@@ -218,7 +218,7 @@ static bool detect_monitor_by_randr(const backend_t *backend,
if (name_reply) { if (name_reply) {
char *name = xcb_get_atom_name_name(name_reply); char *name = xcb_get_atom_name_name(name_reply);
int length = xcb_get_atom_name_name_length(name_reply); int length = xcb_get_atom_name_name_length(name_reply);
output->name = strndup(name, length); output->name = p_strndup(name, length);
p_delete(&name_reply); p_delete(&name_reply);
} }
} }

View File

@@ -68,7 +68,7 @@ static bool handle_map_request(backend_t *backend, event_t *event,
p_clear(event, 1); p_clear(event, 1);
event->type = ZDWM_EVENT_WINDOW_MAP_REQUEST; event->type = ZDWM_EVENT_WINDOW_MAP_REQUEST;
window_map_request_event_t *ev = &event->data.window_map_request; window_map_request_event_t *ev = &event->as.window_map_request;
ev->window = (window_id_t)window; ev->window = (window_id_t)window;
ev->transient_for = window_get_transient_for(backend, window); ev->transient_for = window_get_transient_for(backend, window);
ev->geometry_mode = ZDWM_GEOMETRY_NORMAL; ev->geometry_mode = ZDWM_GEOMETRY_NORMAL;

View File

@@ -176,5 +176,5 @@ typedef struct event_t {
window_activate_request_event_t window_activate_request; window_activate_request_event_t window_activate_request;
window_state_request_event_t window_state_request; window_state_request_event_t window_state_request;
configure_request_event_t configure_request; configure_request_event_t configure_request;
} data; } as;
} event_t; } event_t;

View File

@@ -1,6 +1,7 @@
#include "core/state.h" #include "core/state.h"
#include <stddef.h> #include <stddef.h>
#include <stdint.h>
#include <string.h> #include <string.h>
#include <zdwm/types.h> #include <zdwm/types.h>
@@ -267,6 +268,65 @@ bool state_output_valid(const state_t *state, output_id_t id) {
#endif #endif
} }
void state_cycle_current_output(state_t *state, int delta) {
int64_t count = (int64_t)state->output_count;
int64_t current = (int64_t)state->current_output_index;
int64_t next = (current + (int64_t)delta) % count;
if (next < 0) next += count;
state->current_output_index = (size_t)next;
}
static inline void window_set_geometry_mode(
window_t *window, window_geometry_mode_t geometry_mode) {
window->geometry_mode = geometry_mode;
}
static inline void window_set_floating(window_t *window, bool floating) {
window->floating = floating;
if (floating) window->float_rect = window->frame_rect;
}
static inline void window_set_sticky(window_t *window, bool sticky) {
window->sticky = sticky;
if (sticky) window_set_floating(window, true);
}
static inline void window_set_urgent(window_t *window, bool urgent) {
window->urgent = urgent;
}
static inline void window_set_fixed_size(window_t *window, bool fixed_size) {
window->fixed_size = fixed_size;
if (fixed_size) window_set_floating(window, true);
}
static inline void window_set_float_rect(window_t *window, rect_t rect) {
window->float_rect = rect;
}
static inline void window_set_frame_rect(window_t *window, rect_t rect) {
window->frame_rect = rect;
}
static inline void window_set_title(window_t *window, const char *title) {
p_delete(&window->title);
window->title = p_strdup_nullable(title);
}
static inline void window_set_app_id(window_t *window, const char *app_id) {
p_delete(&window->app_id);
window->app_id = p_strdup_nullable(app_id);
}
static inline void window_set_role(window_t *window, const char *role) {
p_delete(&window->role);
window->role = p_strdup_nullable(role);
}
static inline void window_set_class(window_t *window, const char *class_name) {
p_delete(&window->class_name);
window->class_name = p_strdup_nullable(class_name);
}
static inline void window_set_instance(window_t *window,
const char *instance_name) {
p_delete(&window->instance_name);
window->instance_name = p_strdup_nullable(instance_name);
}
static inline void window_set_skip_taskbar(window_t *window,
bool skip_taskbar) {
window->skip_taskbar = skip_taskbar;
}
const window_t *state_window_add(state_t *state, const window_info_t *info) { const window_t *state_window_add(state_t *state, const window_info_t *info) {
window_id_t id = info->id; window_id_t id = info->id;
window_t *window = (window_t *)state_window_get(state, id); window_t *window = (window_t *)state_window_get(state, id);
@@ -279,19 +339,21 @@ const window_t *state_window_add(state_t *state, const window_info_t *info) {
p_clear(window, 1); p_clear(window, 1);
window->id = id; window->id = id;
window->transient_for = info->transient_for;
window->workspace_id = ZDWM_WORKSPACE_ID_INVALID; window->workspace_id = ZDWM_WORKSPACE_ID_INVALID;
window->layer = info->layer_type;
} }
state_window_set_geometry_mode(state, id, info->geometry_mode); window_set_geometry_mode(window, info->geometry_mode);
state_window_set_urgent(state, id, info->urgent); window_set_urgent(window, info->urgent);
state_window_set_fixed_size(state, id, info->fixed_size); window_set_fixed_size(window, info->fixed_size);
state_window_set_frame_rect(state, id, info->frame_rect); window_set_frame_rect(window, info->frame_rect);
state_window_set_title(state, id, info->title); window_set_title(window, info->title);
state_window_set_app_id(state, id, info->app_id); window_set_app_id(window, info->app_id);
state_window_set_role(state, id, info->role); window_set_role(window, info->role);
state_window_set_class(state, id, info->class_name); window_set_class(window, info->class_name);
state_window_set_instance(state, id, info->instance_name); window_set_instance(window, info->instance_name);
state_window_set_skip_taskbar(state, id, info->skip_taskbar); window_set_skip_taskbar(window, info->skip_taskbar);
return window; return window;
} }
@@ -373,67 +435,49 @@ void state_window_set_workspace(state_t *state, window_id_t window_id,
void state_window_set_geometry_mode(state_t *state, window_id_t window_id, void state_window_set_geometry_mode(state_t *state, window_id_t window_id,
window_geometry_mode_t geometry_mode) { window_geometry_mode_t geometry_mode) {
window_t *window = (window_t *)state_window_get(state, window_id); window_t *window = (window_t *)state_window_get(state, window_id);
if (!window) return; if (window) window_set_geometry_mode(window, geometry_mode);
window->geometry_mode = geometry_mode;
} }
void state_window_set_floating(state_t *state, window_id_t window_id, void state_window_set_floating(state_t *state, window_id_t window_id,
bool floating) { bool floating) {
window_t *window = (window_t *)state_window_get(state, window_id); window_t *window = (window_t *)state_window_get(state, window_id);
if (!window) return; if (window) window_set_floating(window, floating);
window->floating = floating;
} }
void state_window_set_sticky(state_t *state, window_id_t window_id, void state_window_set_sticky(state_t *state, window_id_t window_id,
bool sticky) { bool sticky) {
window_t *window = (window_t *)state_window_get(state, window_id); window_t *window = (window_t *)state_window_get(state, window_id);
if (!window) return; if (window) window_set_sticky(window, sticky);
window->sticky = sticky;
if (window->sticky) state_window_set_floating(state, window_id, true);
} }
void state_window_set_urgent(state_t *state, window_id_t window_id, void state_window_set_urgent(state_t *state, window_id_t window_id,
bool urgent) { bool urgent) {
window_t *window = (window_t *)state_window_get(state, window_id); window_t *window = (window_t *)state_window_get(state, window_id);
if (!window) return; if (window) window_set_urgent(window, urgent);
window->urgent = urgent;
} }
void state_window_set_fixed_size(state_t *state, window_id_t window_id, void state_window_set_fixed_size(state_t *state, window_id_t window_id,
bool fixed_size) { bool fixed_size) {
window_t *window = (window_t *)state_window_get(state, window_id); window_t *window = (window_t *)state_window_get(state, window_id);
if (!window) return; if (window) window_set_fixed_size(window, fixed_size);
window->fixed_size = fixed_size;
if (fixed_size) state_window_set_floating(state, window_id, true);
} }
void state_window_set_skip_taskbar(state_t *state, window_id_t window_id, void state_window_set_skip_taskbar(state_t *state, window_id_t window_id,
bool skip_taskbar) { bool skip_taskbar) {
window_t *window = (window_t *)state_window_get(state, window_id); window_t *window = (window_t *)state_window_get(state, window_id);
if (!window) return; if (window) window_set_skip_taskbar(window, skip_taskbar);
window->skip_taskbar = skip_taskbar;
} }
void state_window_set_float_rect(state_t *state, window_id_t window_id, void state_window_set_float_rect(state_t *state, window_id_t window_id,
rect_t float_rect) { rect_t float_rect) {
window_t *window = (window_t *)state_window_get(state, window_id); window_t *window = (window_t *)state_window_get(state, window_id);
if (!window) return; if (window) window_set_float_rect(window, float_rect);
window->float_rect = float_rect;
} }
void state_window_set_frame_rect(state_t *state, window_id_t window_id, void state_window_set_frame_rect(state_t *state, window_id_t window_id,
rect_t frame_rect) { rect_t frame_rect) {
window_t *window = (window_t *)state_window_get(state, window_id); window_t *window = (window_t *)state_window_get(state, window_id);
if (!window) return; if (window) window_set_frame_rect(window, frame_rect);
window->frame_rect = frame_rect;
} }
bool state_window_take_metadata(state_t *state, window_id_t window_id, bool state_window_take_metadata(state_t *state, window_id_t window_id,
@@ -466,9 +510,7 @@ bool state_window_set_title(state_t *state, window_id_t window_id,
window_t *window = (window_t *)state_window_get(state, window_id); window_t *window = (window_t *)state_window_get(state, window_id);
if (!window) return false; if (!window) return false;
p_delete(&window->title); window_set_title(window, title);
window->title = p_strdup_nullable(title);
return true; return true;
} }
@@ -477,9 +519,7 @@ bool state_window_set_app_id(state_t *state, window_id_t window_id,
window_t *window = (window_t *)state_window_get(state, window_id); window_t *window = (window_t *)state_window_get(state, window_id);
if (!window) return false; if (!window) return false;
p_delete(&window->app_id); window_set_app_id(window, app_id);
window->app_id = p_strdup_nullable(app_id);
return true; return true;
} }
@@ -488,9 +528,7 @@ bool state_window_set_role(state_t *state, window_id_t window_id,
window_t *window = (window_t *)state_window_get(state, window_id); window_t *window = (window_t *)state_window_get(state, window_id);
if (!window) return false; if (!window) return false;
p_delete(&window->role); window_set_role(window, role);
window->role = p_strdup_nullable(role);
return true; return true;
} }
@@ -499,9 +537,7 @@ bool state_window_set_class(state_t *state, window_id_t window_id,
window_t *window = (window_t *)state_window_get(state, window_id); window_t *window = (window_t *)state_window_get(state, window_id);
if (!window) return false; if (!window) return false;
p_delete(&window->class_name); window_set_class(window, class_name);
window->class_name = p_strdup_nullable(class_name);
return true; return true;
} }
@@ -510,9 +546,7 @@ bool state_window_set_instance(state_t *state, window_id_t window_id,
window_t *window = (window_t *)state_window_get(state, window_id); window_t *window = (window_t *)state_window_get(state, window_id);
if (!window) return false; if (!window) return false;
p_delete(&window->instance_name); window_set_instance(window, instance_name);
window->instance_name = p_strdup_nullable(instance_name);
return true; return true;
} }

View File

@@ -65,6 +65,7 @@ typedef struct state_t {
output_t *outputs; output_t *outputs;
size_t output_count; size_t output_count;
size_t current_output_index;
window_t *windows; window_t *windows;
size_t window_count; size_t window_count;
@@ -129,6 +130,7 @@ void state_output_set_current_workspace(state_t *state, output_id_t output_id,
workspace_id_t workspace_id); workspace_id_t workspace_id);
size_t state_output_count(const state_t *state); size_t state_output_count(const state_t *state);
bool state_output_valid(const state_t *state, output_id_t id); bool state_output_valid(const state_t *state, output_id_t id);
void state_cycle_current_output(state_t *state, int delta);
/* /*
* state 持有的 window 集合接口 * state 持有的 window 集合接口

View File

@@ -2,8 +2,6 @@
#include <stddef.h> #include <stddef.h>
#include "core/types.h"
/* Internal semantic window types mapped from backend-specific protocols. */ /* Internal semantic window types mapped from backend-specific protocols. */
typedef enum window_type_t { typedef enum window_type_t {
ZDWM_WINDOW_TYPE_NORMAL = 0, ZDWM_WINDOW_TYPE_NORMAL = 0,

View File

@@ -13,6 +13,7 @@
*/ */
typedef struct window_info_t { typedef struct window_info_t {
window_id_t id; window_id_t id;
window_id_t transient_for;
rect_t frame_rect; rect_t frame_rect;
const char *title; const char *title;