From 079f41ce8aa7c3a5b4fabf3f3235b96ce5b7b3a4 Mon Sep 17 00:00:00 2001 From: Zedhugh Chen Date: Thu, 25 Jun 2026 03:00:30 +0800 Subject: [PATCH] =?UTF-8?q?refactor:=20=E4=BB=8E=20core=20=E4=B8=AD?= =?UTF-8?q?=E6=8A=BD=E5=87=BA=E8=B7=A8=E6=A8=A1=E5=9D=97=E5=A5=91=E7=BA=A6?= =?UTF-8?q?=E5=BB=BA=E7=AB=8B=20interface/common=20=E6=A8=A1=E5=9D=97?= =?UTF-8?q?=E5=88=86=E5=B1=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 引入 interface/(零实现声明层)与 common/(共享 ADT 操作层),把跨模块 契约从 core 实现里抽出来,依赖方向回到单向(base ← interface ← common ← 各实现层)。docs/module-layering.org 记录完整方案与判定标准。 interface/(纯类型与多态接口声明,零 .c): - types.h / event.h / backend.h 从 core 移入 - effect.h 新建(effect_t 从 plan.h 抽出) common/(多实现层共用的自包含操作,.h + .c): - event.{h,c}:event_reset / event_cleanup - listeners.{h,c}:listeners 维护(add / cleanup);notify 留 core - window.{h,c}:window_list + layer_props/metadata cleanup + window_classify_layer - workspace.{h,c}:workspace_desc(从 wm_desc.h 拆出,改真实函数) window 相关整理: - window_layer_type_t 上浮 interface/types.h(common 的 classify 需要) - window_classify_layer 移 common/window - window_info_t 独立成 core/window_info.h(state/command 共享,不寄生) - 删除 wm_desc.h,base/window_list 并入 common/window 全项目 include 路径同步更新 --- CMakeLists.txt | 7 +- docs/module-layering.org | 76 +++++++---- src/backend/output_utils.c | 4 +- src/backend/output_utils.h | 3 +- src/backend/x11/backend.c | 8 +- src/backend/x11/common.c | 2 +- src/backend/x11/common.h | 2 +- src/backend/x11/event.c | 7 +- src/backend/x11/internal.h | 4 +- src/backend/x11/window.c | 2 - src/backend/x11/window.h | 2 +- src/bar/bar.c | 1 - src/bar/bar.h | 2 +- src/bar/binding.c | 2 +- src/bar/binding.h | 2 +- src/bar/windows.c | 2 +- src/bar/windows.h | 2 +- src/bar/workspaces.c | 2 +- src/bar/workspaces.h | 2 +- src/base/window_list.c | 23 ---- src/{core => common}/event.c | 4 +- src/common/event.h | 6 + src/common/listeners.c | 107 +++++++++++++++ src/common/listeners.h | 94 +++++++++++++ src/common/window.c | 55 ++++++++ src/{base/window_list.h => common/window.h} | 7 +- src/common/workspace.c | 46 +++++++ src/common/workspace.h | 21 +++ src/config/defaults.c | 2 +- src/config/runtime_config.c | 7 +- src/config/runtime_config.h | 7 +- src/core/binding.c | 2 +- src/core/binding.h | 2 +- src/core/command.h | 4 +- src/core/layer.c | 2 +- src/core/layer.h | 2 +- src/core/layout.c | 2 +- src/core/layout.h | 2 +- src/core/listeners.c | 103 +------------- src/core/listeners.h | 94 +------------ src/core/plan.c | 3 +- src/core/plan.h | 83 +----------- src/core/policy.c | 8 +- src/core/policy.h | 21 ++- src/core/rules.c | 2 +- src/core/rules.h | 3 +- src/core/state.c | 7 +- src/core/state.h | 7 +- src/core/window.c | 35 +---- src/core/window.h | 68 +--------- src/core/window_info.h | 30 +++++ src/core/wm_desc.h | 91 ------------- src/{core => interface}/backend.h | 6 +- src/interface/effect.h | 95 +++++++++++++ src/{core => interface}/event.h | 6 +- src/{core => interface}/types.h | 142 ++++++++++++-------- src/runtime/runtime.c | 12 +- 57 files changed, 686 insertions(+), 657 deletions(-) delete mode 100644 src/base/window_list.c rename src/{core => common}/event.c (91%) create mode 100644 src/common/event.h create mode 100644 src/common/listeners.c create mode 100644 src/common/listeners.h create mode 100644 src/common/window.c rename src/{base/window_list.h => common/window.h} (57%) create mode 100644 src/common/workspace.c create mode 100644 src/common/workspace.h create mode 100644 src/core/window_info.h delete mode 100644 src/core/wm_desc.h rename src/{core => interface}/backend.h (96%) create mode 100644 src/interface/effect.h rename src/{core => interface}/event.h (96%) rename src/{core => interface}/types.h (61%) diff --git a/CMakeLists.txt b/CMakeLists.txt index ceea343..ae2eb0a 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -42,15 +42,18 @@ add_executable(${APP_NAME} ${SOURCE_DIR}/base/log.c ${SOURCE_DIR}/base/process.c ${SOURCE_DIR}/base/time.c - ${SOURCE_DIR}/base/window_list.c ${SOURCE_DIR}/config/defaults.c ${SOURCE_DIR}/config/loader.c ${SOURCE_DIR}/config/runtime_config.c + ${SOURCE_DIR}/common/event.c + ${SOURCE_DIR}/common/listeners.c + ${SOURCE_DIR}/common/window.c + ${SOURCE_DIR}/common/workspace.c + ${SOURCE_DIR}/core/binding.c ${SOURCE_DIR}/core/command_buffer.c - ${SOURCE_DIR}/core/event.c ${SOURCE_DIR}/core/layer.c ${SOURCE_DIR}/core/layout.c ${SOURCE_DIR}/core/listeners.c diff --git a/docs/module-layering.org b/docs/module-layering.org index ccdd4fa..1431460 100644 --- a/docs/module-layering.org +++ b/docs/module-layering.org @@ -17,11 +17,17 @@ 关键推论:**只需消费"类型"的层,不该被迫背上"操作函数"的依赖**。这是把类型和操作分到两个目录的根本理由。 -* 两个目录的定位 +* 目录的定位 + +先明确三层关系:=base/= 是**项目无关**的通用底层(任何 C 项目都能直接用),=interface/= 和 =common/= 是**项目业务相关**的通用内容。后两者依赖前者(业务依赖基础设施)。 + +** =src/base/= :项目无关的通用底层,零业务依赖 + +放任何 C 项目都能直接用的纯工具(=memory= / =array= / =macros= / =color= / =log= / =time= / =process=)。不依赖 interface/common/任何实现层——它根本不知道 ZDWM 的业务。=interface/= 和 =common/= 都可以依赖它。 ** =src/interface/= :跨模块共享的【声明】,零 .c -只放类型定义、多态接口的函数声明。绝对不放假装、零实现代码。被所有实现层依赖,自身不依赖任何实现层。 +只放类型定义、多态接口的函数声明。绝对不放假装、零实现代码。被所有实现层依赖,自身不依赖任何实现层(可依赖 =base/= 的纯类型)。 ** =src/common/= :被多实现层共用的【操作函数】,.h + .c @@ -32,21 +38,25 @@ * 依赖方向 #+begin_example -interface/ ← 零依赖(纯声明),所有实现层都依赖它 +base/ ← 项目无关的通用底层(任何 C 项目可用),零业务依赖 ↑ -common/ ← 依赖 interface(用类型)+ base/(工具),被需要操作的层依赖 +interface/ ← 零业务依赖(纯类型声明,含 backend 抽象接口);可依赖 base ↑ -core/ runtime/ (依赖 common + interface) -backend/ bar/ (只依赖 interface —— 不碰 common 的操作) +common/ ← 项目业务通用的共享 ADT 操作;依赖 interface + base + ↑ +core/ runtime/ backend/ bar/ ← 实现层,都依赖 common + interface(+ base) #+end_example +注意:没有实现层"只依赖 interface"——所有实现层都用 =common/= 的业务通用操作。interface 的纯净性约束的是 interface *内部*(含 backend 抽象接口不依赖 interface 之外的任何东西),不是约束某个实现层的依赖深度。 + 不变量: -- =interface/= 不依赖任何实现层。 +- =base/= 不依赖任何业务层(interface/common/实现层),是项目无关的纯工具。 +- =interface/=(含 backend 抽象接口)不依赖 =interface/= 之外的任何业务内容;可依赖 =base/= 的纯类型(业务层依赖基础设施,合理)。 - =common/= 只依赖 =interface/= 和 =base/=,不依赖任何实现层。 -- 实现层之间(core/backend/bar/runtime)不直接相互依赖跨模块契约,都经由 =interface/= 或 =common/=。 +- 所有实现层(core/runtime/backend/bar)都依赖 =common/= + =interface/=(+ =base/=);它们之间不直接相互依赖跨模块契约,都经由 =interface/= 或 =common/=。 - 因此 =bar ↔ backend= 这类对等层之间不再有交叉依赖:都通过 =interface/tray.h= 通信。 -* 判定示例:effect / plan / event +* 判定示例:effect / plan / event / listeners 用上面的标准,逐个判定现有跨模块类型: @@ -59,35 +69,45 @@ backend/ bar/ (只依赖 interface —— 不碰 common 的操作) bool backend_apply_effect(backend_t *backend, const effect_t *effects, size_t effect_count); #+end_src -** =plan_t= → common(完整 ADT:类型 + 操作) +** =plan_t= → 留 core(完整 ADT:类型 + 操作) -消费方:只 core(policy 产生、收集 effect)和 runtime(提交后 reset/cleanup)。backend 完全不消费 =plan_t=——runtime 提交时把 plan 拆成 =effect_t= 数组喂给 backend。所以 =plan_t= 非跨模块,类型和操作整个 ADT 都落 =common/plan.h= + =common/plan.c=。 +消费方:只 core(policy 产生、收集 effect)和 runtime(提交后 reset/cleanup)。两者之间是 *runtime→core 的天然单向依赖*(runtime 是桥接层,本就依赖 core 的 policy/state 等)。把 =plan_t= 放 =core/plan.h= + =core/plan.c=,runtime 正向 include 即可,不破坏任何方向——所以它*不必*进 common。 + +这把 common 的门槛精确化:common 是为"对等、无天然依赖"的消费者中立化(见下文 =listeners_t=);若消费者之间已有单向依赖(如 plan 的 core+runtime),共享操作放被依赖方(core)即可,不必上浮 common。 ** =event_t= → interface(类型)+ common(操作) -=event_t= 类型被 backend(产生/填充)和 core/runtime(路由/清理)直接消费 → 类型进 =interface/event.h=。 -但 =event_reset= / =event_cleanup= 这些操作被 backend 和 runtime 共用,而两者对等、不该互相依赖,操作不能归属任一层 → 操作落 =common/event.h= + =common/event.c=。 +=event_t= 类型进 =interface/event.h= 的关键理由:interface 内的 =backend.h= 契约直接 *#include 了 event.h*——=backend_poll_event= / =backend_next_event= 的参数是 =event_t *=,且契约注释讨论 event 的所有权与 =event_cleanup= 语义。一份完整的后端契约要让读者看到 event_t 全貌(字段、联合、生命周期责任),而非甩一个前向声明。所以 event_t 必须在 interface:若放 common,=backend.h= 要么退化为前向声明(契约不完整),要么 interface 反向依赖 common(破坏零依赖)。 -这是"类型和操作分两个目录"的典型:类型跨模块必须在 interface(backend 要产 =event_t=),操作对等共用必须在 common。 +=event_reset= / =event_cleanup= 这些操作被 backend 和 runtime 共用,两者对等、不该互相依赖 → 操作落 =common/event.h= + =common/event.c=。于是 event 是"类型在 interface、操作在 common"的典型。 + +** =listeners_t= → common(类型 + 维护)+ core(notify) + +=listeners_t= 类型被 bar(订阅)、core(发布)、runtime(生命周期)消费,但 **backend 完全不碰它**。判定关键:它的消费者(bar/config/runtime)都*既用类型又用维护操作*(=add_*= / =cleanup=),没有哪个层"只需类型、不需操作"——按核心推论(只有"只需消费类型"的层才迫使类型单独上提 interface),类型不必进 interface。与 =event_t= 的对照就在这里:=event_t= 因被 interface 内的 =backend.h= 契约需要完整定义而必须留 interface;=listeners_t= 则*不被 interface 内任何契约依赖*(=backend.h= 完全不碰它),所以能整个进 common: + +- 类型 =listeners_t= + 维护操作 =add_*= / =cleanup=:自包含容器操作,被 bar/config/runtime 多个对等层共用 → 整个 ADT 进 =common/listeners.{h,c}=。 +- =notify_*=(触发):单消费者(只 core/runtime 发布侧调用),且依赖 core 内部(把 =state_t= 翻译成 =zdwm_window_t= 等 DTO)→ 声明 + 实现都留 =core/listeners=。 + +真正的跨层契约(回调签名 =zdwm_window_added= 等 + DTO)已在 =include/zdwm/listeners.h=(比 interface 更公开的那层),=listeners_t= 只是这些回调的容器,所以它整个待在 common 自洽,不必单独占一个 interface 头。 * 汇总表 -| 东西 | 类型在哪 | 操作在哪 | 判定理由 | -|------------------------------+-------------------------+-------------------------------------+--------------------------------------------------------------------------| -| =effect_t= | =interface/effect.h= | (无,构造归 plan 操作) | 类型跨模块(core 产 + backend 执行),纯数据 | -| =plan_t= | =common/plan.h= | =common/plan.c= | 非跨模块,只 core/runtime 用,整个 ADT 在 common | -| =event_t= | =interface/event.h= | =common/event.h= + =common/event.c= | 类型跨模块;操作对等共用 | -| 后端接口(=backend_t= 等) | =interface/backend.h= | =backend/x11/*.c= | 多态接口:声明在 interface,实现在具体后端 | -| tray 契约(=tray_t= 等) | =interface/tray.h= | =backend/x11/tray.c= | 多态接口:bar 用、backend 实现,声明在 interface 消除 =bar↔backend= 交叉 | -| 通知协议(listeners) | =interface/listeners.h= | =core/listeners.c= | 多态接口:core 发布、bar 订阅,声明在 interface | -| 基础类型(=window_id_t= 等) | =interface/types.h= | (按需) | 所有层共用 | +| 东西 | 类型在哪 | 操作在哪 | 判定理由 | +|------------------------------+-----------------------+-------------------------------------------+--------------------------------------------------------------------------| +| =effect_t= | =interface/effect.h= | (无,构造归 plan 操作) | 类型跨模块(core 产 + backend 执行),纯数据 | +| =plan_t= | =core/plan.h= | =core/plan.c= | 消费者 runtime→core 单向,放 core 不破坏方向,不必 common | +| =event_t= | =interface/event.h= | =common/event.h= + =common/event.c= | 类型跨模块;操作对等共用 | +| 后端接口(=backend_t= 等) | =interface/backend.h= | =backend/x11/*.c= | 多态接口:声明在 interface,实现在具体后端 | +| tray 契约(=tray_t= 等) | =interface/tray.h= | =backend/x11/tray.c= | 多态接口:bar 用、backend 实现,声明在 interface 消除 =bar↔backend= 交叉 | +| 通知协议(listeners) | =common/listeners.h= | =common/listeners.c= + =core/listeners.c= | 消费者 bar↔core 对等,必须 common 中立化;notify 依赖 core 留 core | +| 基础类型(=window_id_t= 等) | =interface/types.h= | (按需) | 所有层共用 | * 多态接口 vs 共享 ADT:.c 归属的不同 =interface/= 里有两类声明,它们的 .c 归属不同,务必区分: -- **多态接口**(=backend.h=、=tray.h=、=listeners.h=):声明一组"由谁来实现"的函数,实现依赖具体实现层(xcb / 未来 wayland)。这类 .c **必须在实现层**(=backend/x11/=、=core/=),不能在 interface——否则 interface 就"知道"了具体实现。 -- **共享 ADT 的操作**(plan、event 的操作):实现自包含、不依赖任何实现层。这类 .c 进 =common/=。 +- **多态接口**(=backend.h=、=tray.h=):声明一组"由谁来实现"的函数,实现依赖具体实现层(xcb / 未来 wayland)。这类 .c **必须在实现层**(=backend/x11/=、=core/=),不能在 interface——否则 interface 就"知道"了具体实现。 +- **共享 ADT 的操作**(event 的操作):实现自包含、不依赖任何实现层。这类 .c 进 =common/=。 换句话说:=interface/= 永远零 .c。多态接口的 .c 在实现层,共享操作的 .c 在 =common/=。 @@ -104,9 +124,9 @@ backend/ bar/ (只依赖 interface —— 不碰 common 的操作) 1. 建 =src/interface/= 和 =src/common/= 目录,加入 CMakeLists。 2. 先迁移"纯类型、零依赖"的声明进 =interface/=:=types.h=、=effect.h=(从 =core/plan.h= 抽出 =effect_t=)、=event.h= 的类型部分。 -3. 多态接口声明迁移:=backend.h=、=listeners.h= 进 =interface/=(=.c= 留原处)。 -4. 共享 ADT 迁移:=plan.h= + =plan.c= 整体进 =common/=;=event.h= 操作部分 + =event.c= 进 =common/=。 -5. 更新全项目 include 路径(="core/plan.h"= → ="common/plan.h"= 等)。 +3. 多态接口声明迁移:=backend.h= 进 =interface/=(=.c= 留原处)。=listeners= 走共享 ADT、不进 interface:=listeners_t= 类型 + =add_*= / =cleanup= 整体进 =common/listeners.{h,c}=,=notify_*= 留 =core/listeners=(详见上方判定示例)。 +4. 共享 ADT 迁移:=event.h= 操作部分 + =event.c= 进 =common/=。(=plan= 留 core:消费者 runtime→core 单向,不必上浮。) +5. 更新全项目 include 路径(="core/types.h"= → ="interface/types.h"= 等)。 6. 每步后编译验证,确保依赖方向单向、无循环。 注意边界:遇到"看起来该进 interface、但其类型依赖还在 core"的情况(如某个 event 子结构引用了 =core/window.h= 的类型),要么把那个被引用的类型也提到 =interface/=,要么承认它暂不进 interface——**进 interface 的前提是它的所有依赖都在 interface**,不能硬塞。 diff --git a/src/backend/output_utils.c b/src/backend/output_utils.c index 75ed42f..06375df 100644 --- a/src/backend/output_utils.c +++ b/src/backend/output_utils.c @@ -4,8 +4,8 @@ #include #include "base/memory.h" -#include "core/backend.h" -#include "core/types.h" +#include "interface/backend.h" +#include "interface/types.h" static inline int32_t right(rect_t a) { return a.x + a.width; } static inline int32_t bottom(rect_t a) { return a.y + a.height; } diff --git a/src/backend/output_utils.h b/src/backend/output_utils.h index 658d6d5..40b6524 100644 --- a/src/backend/output_utils.h +++ b/src/backend/output_utils.h @@ -2,8 +2,7 @@ #include -#include "core/backend.h" -#include "core/types.h" +#include "interface/backend.h" backend_detect_t * output_remove_duplication(const output_info_t *output, const size_t count); diff --git a/src/backend/x11/backend.c b/src/backend/x11/backend.c index 539bb99..d1c11d6 100644 --- a/src/backend/x11/backend.c +++ b/src/backend/x11/backend.c @@ -1,4 +1,4 @@ -#include "core/backend.h" +#include "interface/backend.h" #include #include @@ -25,11 +25,7 @@ #include "base/log.h" #include "base/macros.h" #include "base/memory.h" -#include "base/window_list.h" -#include "core/event.h" -#include "core/plan.h" -#include "core/types.h" -#include "core/window.h" +#include "common/window.h" #include "internal.h" typedef struct atom_item_t { diff --git a/src/backend/x11/common.c b/src/backend/x11/common.c index 293336b..c67cb0f 100644 --- a/src/backend/x11/common.c +++ b/src/backend/x11/common.c @@ -5,7 +5,7 @@ #include #include "base/macros.h" -#include "core/types.h" +#include "interface/types.h" typedef struct modifier_map_t { modifier_bit_t modifier; diff --git a/src/backend/x11/common.h b/src/backend/x11/common.h index 91c9e8a..087b489 100644 --- a/src/backend/x11/common.h +++ b/src/backend/x11/common.h @@ -3,7 +3,7 @@ #include #include -#include "core/types.h" +#include "interface/types.h" modifier_mask_t modifiers_xcb_to_zdwm(uint16_t mask); uint16_t modifiers_zdwm_to_xcb(modifier_mask_t mask); diff --git a/src/backend/x11/event.c b/src/backend/x11/event.c index 43d4eae..3680eb2 100644 --- a/src/backend/x11/event.c +++ b/src/backend/x11/event.c @@ -1,4 +1,4 @@ -#include "core/event.h" +#include "common/event.h" #include #include @@ -12,9 +12,8 @@ #include "backend/x11/common.h" #include "backend/x11/window.h" #include "base/memory.h" -#include "core/backend.h" -#include "core/types.h" -#include "core/window.h" +#include "interface/backend.h" +#include "interface/event.h" #include "internal.h" static window_state_t *derive_window_states( diff --git a/src/backend/x11/internal.h b/src/backend/x11/internal.h index bad8a50..9525258 100644 --- a/src/backend/x11/internal.h +++ b/src/backend/x11/internal.h @@ -7,8 +7,8 @@ #include #include -#include "base/window_list.h" -#include "core/event.h" +#include "common/window.h" +#include "interface/event.h" #define EWMH_ATOMS(X) \ X(_NET_WM_NAME) \ diff --git a/src/backend/x11/window.c b/src/backend/x11/window.c index 20614eb..a6271ad 100644 --- a/src/backend/x11/window.c +++ b/src/backend/x11/window.c @@ -12,8 +12,6 @@ #include "backend/x11/cursor.h" #include "base/macros.h" #include "base/memory.h" -#include "core/backend.h" -#include "core/types.h" #include "internal.h" static char *window_get_text_property( diff --git a/src/backend/x11/window.h b/src/backend/x11/window.h index a9543c6..8f2d035 100644 --- a/src/backend/x11/window.h +++ b/src/backend/x11/window.h @@ -8,7 +8,7 @@ #include #include "base/app.h" -#include "core/backend.h" +#include "interface/backend.h" #include "internal.h" typedef struct atoms_t atoms_t; diff --git a/src/bar/bar.c b/src/bar/bar.c index 5fcc148..87c3c2e 100644 --- a/src/bar/bar.c +++ b/src/bar/bar.c @@ -20,7 +20,6 @@ #include "base/macros.h" #include "base/memory.h" #include "base/time.h" -#include "core/listeners.h" static zdwm_bar_item_t *bar_add_item( zdwm_output_id_t output_id, diff --git a/src/bar/bar.h b/src/bar/bar.h index 3799101..0152383 100644 --- a/src/bar/bar.h +++ b/src/bar/bar.h @@ -10,7 +10,7 @@ #include "bar/text.h" #include "bar/types.h" #include "base/color.h" -#include "core/listeners.h" +#include "common/listeners.h" typedef struct bar_output_t { cairo_t *cr; diff --git a/src/bar/binding.c b/src/bar/binding.c index 874a27a..32c3822 100644 --- a/src/bar/binding.c +++ b/src/bar/binding.c @@ -9,7 +9,7 @@ #include #include "base/memory.h" -#include "core/listeners.h" +#include "common/listeners.h" typedef struct bar_binding_state_t { zdwm_binding_mode_notify_t mode; diff --git a/src/bar/binding.h b/src/bar/binding.h index 2c37f0f..5bfd892 100644 --- a/src/bar/binding.h +++ b/src/bar/binding.h @@ -3,7 +3,7 @@ #include #include -#include "core/listeners.h" +#include "common/listeners.h" typedef struct bar_binding_config_t { bool show_default; diff --git a/src/bar/windows.c b/src/bar/windows.c index d2d9804..488366f 100644 --- a/src/bar/windows.c +++ b/src/bar/windows.c @@ -8,7 +8,7 @@ #include "base/array.h" #include "base/memory.h" -#include "core/listeners.h" +#include "common/listeners.h" typedef struct bar_windows_state_t { zdwm_output_id_t output_id; diff --git a/src/bar/windows.h b/src/bar/windows.h index 58593d5..2ebbc3b 100644 --- a/src/bar/windows.h +++ b/src/bar/windows.h @@ -3,7 +3,7 @@ #include #include -#include "core/listeners.h" +#include "common/listeners.h" typedef struct bar_windows_config_t { uint32_t cell_padding; diff --git a/src/bar/workspaces.c b/src/bar/workspaces.c index ac2fcf1..5895c98 100644 --- a/src/bar/workspaces.c +++ b/src/bar/workspaces.c @@ -10,7 +10,7 @@ #include "base/array.h" #include "base/memory.h" -#include "core/listeners.h" +#include "common/listeners.h" typedef struct bar_workspace_t { zdwm_workspace_t info; diff --git a/src/bar/workspaces.h b/src/bar/workspaces.h index d8957ee..bb9aa24 100644 --- a/src/bar/workspaces.h +++ b/src/bar/workspaces.h @@ -3,7 +3,7 @@ #include #include -#include "core/listeners.h" +#include "common/listeners.h" typedef struct bar_workspace_config_t { uint32_t cell_padding; diff --git a/src/base/window_list.c b/src/base/window_list.c deleted file mode 100644 index a8a30ad..0000000 --- a/src/base/window_list.c +++ /dev/null @@ -1,23 +0,0 @@ -#include "base/window_list.h" - -#include - -#include "base/array.h" -#include "base/memory.h" - -void window_list_push(window_list_t *window_list, zdwm_window_id_t window_id) { - zdwm_window_id_t *window = - array_push(window_list->windows, window_list->count, window_list->capacity); - *window = window_id; -} - -void window_list_reset(window_list_t *window_list) { - p_clear(window_list->windows, window_list->capacity); - window_list->count = 0; -} - -void window_list_cleanup(window_list_t *window_list) { - p_delete(&window_list->windows); - window_list->count = 0; - window_list->capacity = 0; -} diff --git a/src/core/event.c b/src/common/event.c similarity index 91% rename from src/core/event.c rename to src/common/event.c index 693a126..8e96cd6 100644 --- a/src/core/event.c +++ b/src/common/event.c @@ -1,7 +1,7 @@ -#include "core/event.h" +#include "interface/event.h" #include "base/memory.h" -#include "core/window.h" +#include "common/window.h" void event_cleanup(event_t *event) { if (!event || event->type == ZDWM_EVENT_NONE) return; diff --git a/src/common/event.h b/src/common/event.h new file mode 100644 index 0000000..1cee7fd --- /dev/null +++ b/src/common/event.h @@ -0,0 +1,6 @@ +#pragma once + +#include "interface/event.h" + +void event_cleanup(event_t *event); +void event_reset(event_t *event); diff --git a/src/common/listeners.c b/src/common/listeners.c new file mode 100644 index 0000000..a552d2f --- /dev/null +++ b/src/common/listeners.c @@ -0,0 +1,107 @@ +#include "common/listeners.h" + +#include + +#include "base/array.h" +#include "base/memory.h" + +#define ADD_LISTENER(FIELD) \ + auto list = &listeners->FIELD; \ + auto item = array_push(list->items, list->count, list->capacity); \ + item->fn = fn; \ + item->user_data = user_data + +void listeners_add_output_listener( + listeners_t *listeners, + zdwm_current_output_id_listener fn, + void *user_data +) { + ADD_LISTENER(output_listeners); +} + +void listeners_add_initial_workspace_listener( + listeners_t *listeners, + zdwm_initial_workspace_list fn, + void *user_data +) { + ADD_LISTENER(initial_workspace_listeners); +} + +void listeners_add_active_workspace_listener( + listeners_t *listeners, + zdwm_workspace_active_updated fn, + void *user_data +) { + ADD_LISTENER(active_workspace_listeners); +} + +void listeners_add_layout_notify( + listeners_t *listeners, + zdwm_layout_notify fn, + void *user_data +) { + ADD_LISTENER(layout_listeners); +} + +void listeners_add_binding_mode_notify( + listeners_t *listeners, + zdwm_binding_mode_notify fn, + void *user_data +) { + ADD_LISTENER(binding_mode_listeners); +} + +void listeners_add_initial_window_listener( + listeners_t *listeners, + zdwm_initial_window_list fn, + void *user_data +) { + ADD_LISTENER(initial_window_listeners); +} + +void listeners_add_window_added_listener( + listeners_t *listeners, + zdwm_window_added fn, + void *user_data +) { + ADD_LISTENER(window_added_listeners); +} + +void listeners_add_window_updated_listener( + listeners_t *listeners, + zdwm_window_updated fn, + void *user_data +) { + ADD_LISTENER(window_updated_listeners); +} + +void listeners_add_window_removed_listener( + listeners_t *listeners, + zdwm_window_removed fn, + void *user_data +) { + ADD_LISTENER(window_removed_listeners); +} + +#undef ADD_LISTENER + +#define CLEANUP_LIST(FIELD) \ + p_delete(&listeners->FIELD.items); \ + listeners->FIELD.count = 0; \ + listeners->FIELD.capacity = 0 + +void listeners_cleanup(listeners_t *listeners) { + if (!listeners) return; + + CLEANUP_LIST(output_listeners); + CLEANUP_LIST(initial_workspace_listeners); + CLEANUP_LIST(active_workspace_listeners); + CLEANUP_LIST(layout_listeners); + CLEANUP_LIST(binding_mode_listeners); + CLEANUP_LIST(initial_window_listeners); + CLEANUP_LIST(window_added_listeners); + CLEANUP_LIST(window_updated_listeners); + CLEANUP_LIST(window_removed_listeners); +} + +#undef CLEANUP_LIST diff --git a/src/common/listeners.h b/src/common/listeners.h new file mode 100644 index 0000000..0fd98ff --- /dev/null +++ b/src/common/listeners.h @@ -0,0 +1,94 @@ +#pragma once + +#include + +typedef struct binding_table_t binding_table_t; +typedef struct layout_registry_t layout_registry_t; +typedef struct state_t state_t; + +#define ITEM(NAME, FN_TYPE) \ + typedef struct NAME##_listener_item_t { \ + FN_TYPE *fn; \ + void *user_data; \ + } NAME##_listener_item_t + +#define LISTENERS(NAME, FN_TYPE) \ + ITEM(NAME, FN_TYPE); \ + typedef struct NAME##_listeners_t { \ + NAME##_listener_item_t *items; \ + size_t count; \ + size_t capacity; \ + } NAME##_listeners_t + +LISTENERS(output, zdwm_current_output_id_listener); +LISTENERS(initial_workspace_list, zdwm_initial_workspace_list); +LISTENERS(workspace_active, zdwm_workspace_active_updated); +LISTENERS(layout, zdwm_layout_notify); +LISTENERS(binding_mode, zdwm_binding_mode_notify); +LISTENERS(initial_window_list, zdwm_initial_window_list); +LISTENERS(window_added, zdwm_window_added); +LISTENERS(window_updated, zdwm_window_updated); +LISTENERS(window_removed, zdwm_window_removed); + +#undef ITEM +#undef LISTENERS + +typedef struct listeners_t { + output_listeners_t output_listeners; + initial_workspace_list_listeners_t initial_workspace_listeners; + workspace_active_listeners_t active_workspace_listeners; + layout_listeners_t layout_listeners; + binding_mode_listeners_t binding_mode_listeners; + initial_window_list_listeners_t initial_window_listeners; + window_added_listeners_t window_added_listeners; + window_updated_listeners_t window_updated_listeners; + window_removed_listeners_t window_removed_listeners; +} listeners_t; + +void listeners_add_output_listener( + listeners_t *listeners, + zdwm_current_output_id_listener fn, + void *user_data +); +void listeners_add_initial_workspace_listener( + listeners_t *listeners, + zdwm_initial_workspace_list fn, + void *user_data +); +void listeners_add_active_workspace_listener( + listeners_t *listeners, + zdwm_workspace_active_updated fn, + void *user_data +); +void listeners_add_layout_notify( + listeners_t *listeners, + zdwm_layout_notify fn, + void *user_data +); +void listeners_add_binding_mode_notify( + listeners_t *listeners, + zdwm_binding_mode_notify fn, + void *user_data +); +void listeners_add_initial_window_listener( + listeners_t *listeners, + zdwm_initial_window_list fn, + void *user_data +); +void listeners_add_window_added_listener( + listeners_t *listeners, + zdwm_window_added fn, + void *user_data +); +void listeners_add_window_updated_listener( + listeners_t *listeners, + zdwm_window_updated fn, + void *user_data +); +void listeners_add_window_removed_listener( + listeners_t *listeners, + zdwm_window_removed fn, + void *user_data +); + +void listeners_cleanup(listeners_t *listeners); diff --git a/src/common/window.c b/src/common/window.c new file mode 100644 index 0000000..b9bec3d --- /dev/null +++ b/src/common/window.c @@ -0,0 +1,55 @@ +#include "common/window.h" + +#include "base/array.h" +#include "base/memory.h" +#include "interface/types.h" + +window_layer_type_t window_classify_layer(const window_layer_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; +} + +void window_layer_props_cleanup(window_layer_props_t *props) { + if (!props) return; + + p_delete(&props->types); + props->type_count = 0; + p_delete(&props->states); + props->state_count = 0; +} + +void window_metadata_cleanup(window_metadata_t *metadata) { + if (!metadata) return; + + p_delete(&metadata->title); + p_delete(&metadata->app_id); + p_delete(&metadata->role); + p_delete(&metadata->class_name); + p_delete(&metadata->instance_name); +} + +void window_list_push(window_list_t *window_list, zdwm_window_id_t window_id) { + zdwm_window_id_t *window = + array_push(window_list->windows, window_list->count, window_list->capacity); + *window = window_id; +} + +void window_list_reset(window_list_t *window_list) { + p_clear(window_list->windows, window_list->capacity); + window_list->count = 0; +} + +void window_list_cleanup(window_list_t *window_list) { + p_delete(&window_list->windows); + window_list->count = 0; + window_list->capacity = 0; +} diff --git a/src/base/window_list.h b/src/common/window.h similarity index 57% rename from src/base/window_list.h rename to src/common/window.h index 9b57772..22aa235 100644 --- a/src/base/window_list.h +++ b/src/common/window.h @@ -1,7 +1,10 @@ #pragma once -#include -#include +#include "interface/types.h" + +window_layer_type_t window_classify_layer(const window_layer_props_t *props); +void window_layer_props_cleanup(window_layer_props_t *props); +void window_metadata_cleanup(window_metadata_t *metadata); typedef struct window_list_t { zdwm_window_id_t *windows; diff --git a/src/common/workspace.c b/src/common/workspace.c new file mode 100644 index 0000000..12b2ab4 --- /dev/null +++ b/src/common/workspace.c @@ -0,0 +1,46 @@ +#include "common/workspace.h" + +#include "base/memory.h" + +void workspace_desc_cleanup(workspace_desc_t *workspace) { + if (!workspace) return; + + p_delete(&workspace->name); + p_delete(&workspace->layout_ids); + workspace->output_index = 0; + workspace->layout_count = 0; + workspace->initial_layout_id = ZDWM_LAYOUT_ID_INVALID; +} + +void workspace_desc_list_cleanup(workspace_desc_t **list, size_t *count) { + if (!list || !count) return; + + for (size_t i = 0; i < *count; i++) { + workspace_desc_cleanup(&(*list)[i]); + } + + p_delete(list); + *count = 0; +} + +bool workspace_desc_layouts_valid(const workspace_desc_t *workspace) { + if (!workspace || !workspace->layout_count || !workspace->layout_ids) { + return false; + } + + for (size_t i = 0; i < workspace->layout_count; i++) { + if (workspace->layout_ids[i] == workspace->initial_layout_id) return true; + } + + return false; +} + +bool workspace_desc_valid( + const workspace_desc_t *workspace, + size_t output_count +) { + if (!workspace || !workspace->name) return false; + if (workspace->output_index >= output_count) return false; + + return workspace_desc_layouts_valid(workspace); +} diff --git a/src/common/workspace.h b/src/common/workspace.h new file mode 100644 index 0000000..5b2bb07 --- /dev/null +++ b/src/common/workspace.h @@ -0,0 +1,21 @@ +#pragma once + +#include + +#include "interface/types.h" + +typedef struct workspace_desc_t { + size_t output_index; /* 对应 state_init() 中 outputs[] 的索引 */ + const char *name; + const layout_id_t *layout_ids; + size_t layout_count; + layout_id_t initial_layout_id; +} workspace_desc_t; + +void workspace_desc_cleanup(workspace_desc_t *workspace); +void workspace_desc_list_cleanup(workspace_desc_t **list, size_t *count); +bool workspace_desc_layouts_valid(const workspace_desc_t *workspace); +bool workspace_desc_valid( + const workspace_desc_t *workspace, + size_t output_count +); diff --git a/src/config/defaults.c b/src/config/defaults.c index 2bcd5d0..8262e61 100644 --- a/src/config/defaults.c +++ b/src/config/defaults.c @@ -9,7 +9,7 @@ #include "base/log.h" #include "base/macros.h" -#include "core/types.h" +#include "interface/types.h" static constexpr char launcher[] = "rofi -show combi -modes combi -combi-modes window,drun,run,ssh,windowcd"; diff --git a/src/config/runtime_config.c b/src/config/runtime_config.c index a8f1323..07ee989 100644 --- a/src/config/runtime_config.c +++ b/src/config/runtime_config.c @@ -5,18 +5,19 @@ #include #include #include +#include #include "base/array.h" #include "base/color.h" #include "base/memory.h" +#include "common/listeners.h" +#include "common/workspace.h" #include "config/defaults.h" #include "config/loader.h" #include "core/binding.h" #include "core/layout.h" -#include "core/listeners.h" #include "core/rules.h" -#include "core/types.h" -#include "core/wm_desc.h" +#include "interface/types.h" #include "layouts/fair.h" #include "layouts/fullscreen.h" #include "layouts/maximize.h" diff --git a/src/config/runtime_config.h b/src/config/runtime_config.h index d360783..c69d526 100644 --- a/src/config/runtime_config.h +++ b/src/config/runtime_config.h @@ -5,13 +5,12 @@ #include #include -#include "core/backend.h" +#include "common/listeners.h" +#include "common/workspace.h" #include "core/binding.h" #include "core/layout.h" -#include "core/listeners.h" #include "core/rules.h" -#include "core/types.h" -#include "core/wm_desc.h" +#include "interface/backend.h" typedef struct runtime_init_desc_t { backend_t *backend; diff --git a/src/core/binding.c b/src/core/binding.c index d3dd548..34a9e0b 100644 --- a/src/core/binding.c +++ b/src/core/binding.c @@ -12,7 +12,7 @@ #include "base/array.h" #include "base/macros.h" #include "base/memory.h" -#include "core/types.h" +#include "interface/types.h" typedef struct binding_mode_t { zdwm_binding_mode_id_t id; diff --git a/src/core/binding.h b/src/core/binding.h index cfa185f..f3f8152 100644 --- a/src/core/binding.h +++ b/src/core/binding.h @@ -5,7 +5,7 @@ #include #include -#include "core/types.h" +#include "interface/types.h" typedef struct binding_table_t binding_table_t; diff --git a/src/core/command.h b/src/core/command.h index f0e5493..bf946a8 100644 --- a/src/core/command.h +++ b/src/core/command.h @@ -1,7 +1,7 @@ #pragma once -#include "core/types.h" -#include "core/wm_desc.h" +#include "core/window_info.h" +#include "interface/types.h" typedef enum command_type_t { ZDWM_COMMAND_MANAGE_WINDOW, diff --git a/src/core/layer.c b/src/core/layer.c index 56f706e..2888e9f 100644 --- a/src/core/layer.c +++ b/src/core/layer.c @@ -4,7 +4,7 @@ #include "base/array.h" #include "base/memory.h" -#include "core/types.h" +#include "interface/types.h" void layer_stack_cleanup(layer_stack_t *layer) { p_delete(&layer->order); diff --git a/src/core/layer.h b/src/core/layer.h index 66cff99..30b89a0 100644 --- a/src/core/layer.h +++ b/src/core/layer.h @@ -2,7 +2,7 @@ #include -#include "core/types.h" +#include "interface/types.h" typedef struct layer_stack_t { window_id_t *order; diff --git a/src/core/layout.c b/src/core/layout.c index dd0b22c..f1bdc29 100644 --- a/src/core/layout.c +++ b/src/core/layout.c @@ -6,7 +6,7 @@ #include "base/array.h" #include "base/memory.h" -#include "core/types.h" +#include "interface/types.h" void layout_result_cleanup(layout_result_t *result) { p_delete(&result->items); diff --git a/src/core/layout.h b/src/core/layout.h index bb181e6..c8a222b 100644 --- a/src/core/layout.h +++ b/src/core/layout.h @@ -3,7 +3,7 @@ #include #include -#include "core/types.h" +#include "interface/types.h" typedef zdwm_layout_ctx_t layout_ctx_t; typedef zdwm_layout_item_t layout_item_t; diff --git a/src/core/listeners.c b/src/core/listeners.c index 7b85a20..a698a54 100644 --- a/src/core/listeners.c +++ b/src/core/listeners.c @@ -1,112 +1,11 @@ #include "core/listeners.h" -#include "base/array.h" #include "base/memory.h" +#include "common/listeners.h" #include "core/binding.h" #include "core/layout.h" #include "core/state.h" -#define ADD_LISTENER(FIELD) \ - auto list = &listeners->FIELD; \ - auto item = array_push(list->items, list->count, list->capacity); \ - item->fn = fn; \ - item->user_data = user_data - -void listeners_add_output_listener( - listeners_t *listeners, - zdwm_current_output_id_listener fn, - void *user_data -) { - ADD_LISTENER(output_listeners); -} - -void listeners_add_initial_workspace_listener( - listeners_t *listeners, - zdwm_initial_workspace_list fn, - void *user_data -) { - ADD_LISTENER(initial_workspace_listeners); -} - -void listeners_add_active_workspace_listener( - listeners_t *listeners, - zdwm_workspace_active_updated fn, - void *user_data -) { - ADD_LISTENER(active_workspace_listeners); -} - -void listeners_add_layout_notify( - listeners_t *listeners, - zdwm_layout_notify fn, - void *user_data -) { - ADD_LISTENER(layout_listeners); -} - -void listeners_add_binding_mode_notify( - listeners_t *listeners, - zdwm_binding_mode_notify fn, - void *user_data -) { - ADD_LISTENER(binding_mode_listeners); -} - -void listeners_add_initial_window_listener( - listeners_t *listeners, - zdwm_initial_window_list fn, - void *user_data -) { - ADD_LISTENER(initial_window_listeners); -} - -void listeners_add_window_added_listener( - listeners_t *listeners, - zdwm_window_added fn, - void *user_data -) { - ADD_LISTENER(window_added_listeners); -} - -void listeners_add_window_updated_listener( - listeners_t *listeners, - zdwm_window_updated fn, - void *user_data -) { - ADD_LISTENER(window_updated_listeners); -} - -void listeners_add_window_removed_listener( - listeners_t *listeners, - zdwm_window_removed fn, - void *user_data -) { - ADD_LISTENER(window_removed_listeners); -} - -#undef ADD_LISTENER - -#define CLEANUP_LIST(FIELD) \ - p_delete(&listeners->FIELD.items); \ - listeners->FIELD.count = 0; \ - listeners->FIELD.capacity = 0 - -void listeners_cleanup(listeners_t *listeners) { - if (!listeners) return; - - CLEANUP_LIST(output_listeners); - CLEANUP_LIST(initial_workspace_listeners); - CLEANUP_LIST(active_workspace_listeners); - CLEANUP_LIST(layout_listeners); - CLEANUP_LIST(binding_mode_listeners); - CLEANUP_LIST(initial_window_listeners); - CLEANUP_LIST(window_added_listeners); - CLEANUP_LIST(window_updated_listeners); - CLEANUP_LIST(window_removed_listeners); -} - -#undef CLEANUP_LIST - #define FOR_EACH_LISTENER(FIELD, BODY) \ do { \ if (!(listeners)) return; \ diff --git a/src/core/listeners.h b/src/core/listeners.h index d26e1fd..9590112 100644 --- a/src/core/listeners.h +++ b/src/core/listeners.h @@ -3,98 +3,8 @@ #include #include -#include "core/types.h" - -typedef struct binding_table_t binding_table_t; -typedef struct layout_registry_t layout_registry_t; -typedef struct state_t state_t; - -#define ITEM(NAME, FN_TYPE) \ - typedef struct NAME##_listener_item_t { \ - FN_TYPE *fn; \ - void *user_data; \ - } NAME##_listener_item_t - -#define LISTENERS(NAME, FN_TYPE) \ - ITEM(NAME, FN_TYPE); \ - typedef struct NAME##_listeners_t { \ - NAME##_listener_item_t *items; \ - size_t count; \ - size_t capacity; \ - } NAME##_listeners_t - -LISTENERS(output, zdwm_current_output_id_listener); -LISTENERS(initial_workspace_list, zdwm_initial_workspace_list); -LISTENERS(workspace_active, zdwm_workspace_active_updated); -LISTENERS(layout, zdwm_layout_notify); -LISTENERS(binding_mode, zdwm_binding_mode_notify); -LISTENERS(initial_window_list, zdwm_initial_window_list); -LISTENERS(window_added, zdwm_window_added); -LISTENERS(window_updated, zdwm_window_updated); -LISTENERS(window_removed, zdwm_window_removed); - -#undef ITEM -#undef LISTENERS - -typedef struct listeners_t { - output_listeners_t output_listeners; - initial_workspace_list_listeners_t initial_workspace_listeners; - workspace_active_listeners_t active_workspace_listeners; - layout_listeners_t layout_listeners; - binding_mode_listeners_t binding_mode_listeners; - initial_window_list_listeners_t initial_window_listeners; - window_added_listeners_t window_added_listeners; - window_updated_listeners_t window_updated_listeners; - window_removed_listeners_t window_removed_listeners; -} listeners_t; - -void listeners_add_output_listener( - listeners_t *listeners, - zdwm_current_output_id_listener fn, - void *user_data -); -void listeners_add_initial_workspace_listener( - listeners_t *listeners, - zdwm_initial_workspace_list fn, - void *user_data -); -void listeners_add_active_workspace_listener( - listeners_t *listeners, - zdwm_workspace_active_updated fn, - void *user_data -); -void listeners_add_layout_notify( - listeners_t *listeners, - zdwm_layout_notify fn, - void *user_data -); -void listeners_add_binding_mode_notify( - listeners_t *listeners, - zdwm_binding_mode_notify fn, - void *user_data -); -void listeners_add_initial_window_listener( - listeners_t *listeners, - zdwm_initial_window_list fn, - void *user_data -); -void listeners_add_window_added_listener( - listeners_t *listeners, - zdwm_window_added fn, - void *user_data -); -void listeners_add_window_updated_listener( - listeners_t *listeners, - zdwm_window_updated fn, - void *user_data -); -void listeners_add_window_removed_listener( - listeners_t *listeners, - zdwm_window_removed fn, - void *user_data -); - -void listeners_cleanup(listeners_t *listeners); +#include "common/listeners.h" +#include "interface/types.h" /** * @brief 通知当前 output 信息 diff --git a/src/core/plan.c b/src/core/plan.c index 375efff..5496632 100644 --- a/src/core/plan.c +++ b/src/core/plan.c @@ -4,7 +4,8 @@ #include "base/array.h" #include "base/memory.h" -#include "core/types.h" +#include "interface/effect.h" +#include "interface/types.h" static void free_memory_hold_by_effects(effect_t *effects, size_t count) { for (size_t i = 0; i < count; ++i) { diff --git a/src/core/plan.h b/src/core/plan.h index 016e874..6912b23 100644 --- a/src/core/plan.h +++ b/src/core/plan.h @@ -1,89 +1,10 @@ #pragma once #include -#include #include "base/color.h" -#include "core/types.h" - -typedef enum effect_type_t { - ZDWM_EFFECT_MAP_WINDOW = 1, - ZDWM_EFFECT_UNMAP_WINDOW, - ZDWM_EFFECT_FOCUS_WINDOW, - ZDWM_EFFECT_KILL_WINDOW, - ZDWM_EFFECT_WITHDRAW_WINDOW, - ZDWM_EFFECT_START_MOVE_WINDOW, - ZDWM_EFFECT_START_RESIZE_WINDOW, - ZDWM_EFFECT_MINIMIZE_WINDOW, - ZDWM_EFFECT_MAXIMIZE_WINDOW, - ZDWM_EFFECT_FULLSCREEN_WINDOW, - ZDWM_EFFECT_CONFIGURE_WINDOW, - ZDWM_EFFECT_CHANGE_BORDER_COLOR, - ZDWM_EFFECT_CHANGE_WINDOW_LIST, - ZDWM_EFFECT_RESTACK_WINDOWS, - ZDWM_EFFECT_BIND_KEY, - ZDWM_EFFECT_GRAB_BUTTON, - ZDWM_EFFECT_UNGRAB_POINTER, -} effect_type_t; - -typedef struct effect_move_window_t { - window_id_t window; - point_t left_top_point; -} effect_move_window_t; - -typedef struct effect_resize_window_t { - window_id_t window; - int32_t width; - int32_t height; -} effect_resize_window_t; - -typedef struct effect_change_border_color_t { - window_id_t window; - const color_t *color; -} effect_change_border_color_t; - -typedef struct effect_window_list_t { - const window_id_t *windows; - size_t count; -} effect_window_list_t; - -typedef struct effect_bind_key_t { - const key_bind_t *keys; - size_t count; -} effect_bind_key_t; - -typedef struct effect_grab_button_t { - window_id_t window; - const grab_button_t *buttons; - size_t count; -} effect_grab_button_t; - -typedef struct effect_bool_window_t { - window_id_t window; - bool value; -} effect_bool_window_t; - -typedef struct effect_t { - effect_type_t type; - union { - only_window_data_t map; - only_window_data_t unmap; - only_window_data_t focus; - only_window_data_t kill; - only_window_data_t withdraw; - only_window_data_t move; - only_window_data_t resize; - effect_bool_window_t minimize; - effect_bool_window_t maximize; - effect_bool_window_t fullscreen; - configure_data_t configure; - effect_change_border_color_t change_border_color; - effect_window_list_t change_window_list; - effect_window_list_t restack_windows; - effect_bind_key_t bind_key; - effect_grab_button_t grab_button; - } as; -} effect_t; +#include "interface/effect.h" +#include "interface/types.h" typedef struct plan_t { effect_t *effects; diff --git a/src/core/policy.c b/src/core/policy.c index f8589a2..1cfef61 100644 --- a/src/core/policy.c +++ b/src/core/policy.c @@ -10,19 +10,19 @@ #include "base/memory.h" #include "base/process.h" #include "base/time.h" -#include "base/window_list.h" +#include "common/listeners.h" +#include "common/window.h" #include "core/binding.h" #include "core/command.h" #include "core/command_buffer.h" -#include "core/event.h" #include "core/layout.h" #include "core/listeners.h" #include "core/plan.h" #include "core/rules.h" #include "core/state.h" -#include "core/types.h" #include "core/window.h" -#include "core/wm_desc.h" +#include "interface/event.h" +#include "interface/types.h" static void quit(bool restart, command_buffer_t *command_buffer) { command_t quit_command = { diff --git a/src/core/policy.h b/src/core/policy.h index 4d5e381..3bdfbf4 100644 --- a/src/core/policy.h +++ b/src/core/policy.h @@ -3,16 +3,29 @@ #include #include -#include "base/window_list.h" +#include "common/listeners.h" +#include "common/window.h" #include "core/binding.h" #include "core/command_buffer.h" -#include "core/event.h" #include "core/layout.h" -#include "core/listeners.h" #include "core/plan.h" #include "core/rules.h" #include "core/state.h" -#include "core/types.h" +#include "interface/event.h" + +typedef enum window_interaction_mode_t { + ZDWM_WINDOW_INTERACTION_NONE, + ZDWM_WINDOW_INTERACTION_MOVE, + ZDWM_WINDOW_INTERACTION_RESIZE, +} window_interaction_mode_t; + +typedef struct window_interaction_state_t { + window_interaction_mode_t mode; + window_id_t window; + point_t start_coordinate; + rect_t origin_rect; + uint64_t last_change_time; +} window_interaction_state_t; typedef struct policy_bar_t { bool *visible; diff --git a/src/core/rules.c b/src/core/rules.c index 871caeb..b0d587b 100644 --- a/src/core/rules.c +++ b/src/core/rules.c @@ -5,7 +5,7 @@ #include #include "base/memory.h" -#include "core/types.h" +#include "interface/types.h" bool rules_move(rules_t *src, rules_t *dest) { if (!dest || !src) return false; diff --git a/src/core/rules.h b/src/core/rules.h index 456d803..33aab21 100644 --- a/src/core/rules.h +++ b/src/core/rules.h @@ -2,8 +2,7 @@ #include -#include "core/types.h" -#include "core/window.h" +#include "interface/types.h" typedef struct rule_item_t { rule_match_t match; diff --git a/src/core/state.c b/src/core/state.c index 08a6657..4b35469 100644 --- a/src/core/state.c +++ b/src/core/state.c @@ -8,11 +8,12 @@ #include "base/array.h" #include "base/log.h" #include "base/memory.h" -#include "base/window_list.h" +#include "common/window.h" +#include "common/workspace.h" #include "core/layer.h" -#include "core/types.h" #include "core/window.h" -#include "core/wm_desc.h" +#include "core/window_info.h" +#include "interface/types.h" void state_init( state_t *state, diff --git a/src/core/state.h b/src/core/state.h index 7d94442..064e72c 100644 --- a/src/core/state.h +++ b/src/core/state.h @@ -3,11 +3,12 @@ #include #include -#include "base/window_list.h" +#include "common/window.h" +#include "common/workspace.h" #include "core/layer.h" -#include "core/types.h" #include "core/window.h" -#include "core/wm_desc.h" +#include "core/window_info.h" +#include "interface/types.h" typedef struct workspace_t { workspace_id_t id; diff --git a/src/core/window.c b/src/core/window.c index 9862901..d0b4385 100644 --- a/src/core/window.c +++ b/src/core/window.c @@ -1,40 +1,7 @@ #include "core/window.h" #include "base/memory.h" -#include "core/types.h" - -window_layer_type_t window_classify_layer(const window_layer_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; -} - -void window_layer_props_cleanup(window_layer_props_t *props) { - if (!props) return; - - p_delete(&props->types); - props->type_count = 0; - p_delete(&props->states); - props->state_count = 0; -} - -void window_metadata_cleanup(window_metadata_t *metadata) { - if (!metadata) return; - - p_delete(&metadata->title); - p_delete(&metadata->app_id); - p_delete(&metadata->role); - p_delete(&metadata->class_name); - p_delete(&metadata->instance_name); -} +#include "interface/types.h" void window_set_fullscreen(window_t *window, bool fullscreen) { window->fullscreen = fullscreen; diff --git a/src/core/window.h b/src/core/window.h index 4bb22a9..c566541 100644 --- a/src/core/window.h +++ b/src/core/window.h @@ -3,68 +3,7 @@ #include #include -#include "core/types.h" - -/* Internal semantic window types mapped from backend-specific protocols. */ -typedef enum window_type_t { - ZDWM_WINDOW_TYPE_NORMAL = 0, - ZDWM_WINDOW_TYPE_DESKTOP, - ZDWM_WINDOW_TYPE_DOCK, - ZDWM_WINDOW_TYPE_TOOLBAR, - ZDWM_WINDOW_TYPE_DIALOG, - ZDWM_WINDOW_TYPE_UTILITY, - ZDWM_WINDOW_TYPE_SPLASH, - ZDWM_WINDOW_TYPE_MENU, - ZDWM_WINDOW_TYPE_DROPDOWN_MENU, - ZDWM_WINDOW_TYPE_POPUP_MENU, - ZDWM_WINDOW_TYPE_TOOLTIP, - ZDWM_WINDOW_TYPE_COMBO, - ZDWM_WINDOW_TYPE_DND, - ZDWM_WINDOW_TYPE_NOTIFICATION, -} window_type_t; - -/* Internal semantic window states mapped from backend-specific protocols. */ -typedef enum window_state_t { - ZDWM_WINDOW_STATE_ABOVE = 0, - ZDWM_WINDOW_STATE_FULLSCREEN, - ZDWM_WINDOW_STATE_MODAL, - ZDWM_WINDOW_STATE_STICKY, -} window_state_t; - -/* 层级从低到高 */ -typedef enum window_layer_type_t { - ZDWM_WINDOW_LAYER_DESKTOP = 0, - ZDWM_WINDOW_LAYER_NORMAL, - ZDWM_WINDOW_LAYER_TOP, - ZDWM_WINDOW_LAYER_OVERLAY, - ZDWM_WINDOW_LAYER_COUNT, -} window_layer_type_t; - -/* clang-format off */ -typedef enum window_metadata_change_flags_t { - ZDWM_WINDOW_METADATA_CHANGE_TITLE = 1u << 0, - ZDWM_WINDOW_METADATA_CHANGE_APP_ID = 1u << 1, - ZDWM_WINDOW_METADATA_CHANGE_ROLE = 1u << 2, - ZDWM_WINDOW_METADATA_CHANGE_CLASS = 1u << 3, - ZDWM_WINDOW_METADATA_CHANGE_INSTANCE = 1u << 4, -} window_metadata_change_flags_t; -/* clang-format on */ - -typedef struct window_layer_props_t { - window_type_t *types; - size_t type_count; - - window_state_t *states; - size_t state_count; -} window_layer_props_t; - -typedef struct window_metadata_t { - char *title; - char *app_id; - char *role; - char *class_name; - char *instance_name; -} window_metadata_t; +#include "interface/types.h" typedef struct window_t { window_id_t id; @@ -97,11 +36,6 @@ typedef struct window_t { uint32_t border_width; } window_t; -window_layer_type_t window_classify_layer(const window_layer_props_t *props); - -void window_layer_props_cleanup(window_layer_props_t *props); -void window_metadata_cleanup(window_metadata_t *metadata); - void window_set_fullscreen(window_t *window, bool fullscreen); void window_set_maximized(window_t *window, bool maximized); void window_set_minimized(window_t *window, bool minimized); diff --git a/src/core/window_info.h b/src/core/window_info.h new file mode 100644 index 0000000..110d6c6 --- /dev/null +++ b/src/core/window_info.h @@ -0,0 +1,30 @@ +#pragma once + +#include "interface/types.h" + +/* + * 由 backend 提供的窗口基础信息。 + * + * 这些字符串由调用方提供;state 如需长期持有,应自行复制。 + */ +typedef struct window_info_t { + window_id_t id; + window_id_t transient_for; + rect_t frame_rect; + + const char *title; + const char *app_id; + const char *role; + const char *class_name; + const char *instance_name; + + window_layer_type_t layer_type; + bool fullscreen; + bool maximized; + bool minimized; + bool urgent; + bool skip_taskbar; + + zdwm_size_t min_size; + zdwm_size_t max_size; +} window_info_t; diff --git a/src/core/wm_desc.h b/src/core/wm_desc.h deleted file mode 100644 index 0fba79a..0000000 --- a/src/core/wm_desc.h +++ /dev/null @@ -1,91 +0,0 @@ -#pragma once - -#include - -#include "base/memory.h" -#include "core/types.h" -#include "core/window.h" - -/* - * 由 backend 提供的窗口基础信息。 - * - * 这些字符串由调用方提供;state 如需长期持有,应自行复制。 - */ -typedef struct window_info_t { - window_id_t id; - window_id_t transient_for; - rect_t frame_rect; - - const char *title; - const char *app_id; - const char *role; - const char *class_name; - const char *instance_name; - - window_layer_type_t layer_type; - bool fullscreen; - bool maximized; - bool minimized; - bool urgent; - bool skip_taskbar; - - zdwm_size_t min_size; - zdwm_size_t max_size; -} window_info_t; - -typedef struct workspace_desc_t { - size_t output_index; /* 对应 state_init() 中 outputs[] 的索引 */ - const char *name; - const layout_id_t *layout_ids; - size_t layout_count; - layout_id_t initial_layout_id; -} workspace_desc_t; - -static inline void workspace_desc_cleanup(workspace_desc_t *workspace) { - if (!workspace) return; - - p_delete(&workspace->name); - p_delete(&workspace->layout_ids); - workspace->output_index = 0; - workspace->layout_count = 0; - workspace->initial_layout_id = ZDWM_LAYOUT_ID_INVALID; -} - -static inline void -workspace_desc_list_cleanup(workspace_desc_t **list, size_t *count) { - if (!list || !count) return; - - for (size_t i = 0; i < *count; i++) { - workspace_desc_cleanup(&(*list)[i]); - } - - p_delete(list); - *count = 0; -} - -/* - * workspace 描述校验接口。 - * - * 这组接口只校验描述表自身的一致性,不访问 state。 - */ -static inline bool workspace_desc_layouts_valid( - const workspace_desc_t *workspace -) { - if (!workspace || !workspace->layout_count || !workspace->layout_ids) { - return false; - } - - for (size_t i = 0; i < workspace->layout_count; i++) { - if (workspace->layout_ids[i] == workspace->initial_layout_id) return true; - } - - return false; -} - -static inline bool -workspace_desc_valid(const workspace_desc_t *workspace, size_t output_count) { - if (!workspace || !workspace->name) return false; - if (workspace->output_index >= output_count) return false; - - return workspace_desc_layouts_valid(workspace); -} diff --git a/src/core/backend.h b/src/interface/backend.h similarity index 96% rename from src/core/backend.h rename to src/interface/backend.h index ac15d50..164a9cc 100644 --- a/src/core/backend.h +++ b/src/interface/backend.h @@ -3,9 +3,9 @@ #include #include -#include "core/event.h" -#include "core/plan.h" -#include "core/types.h" +#include "interface/effect.h" +#include "interface/event.h" +#include "interface/types.h" typedef struct backend_t backend_t; diff --git a/src/interface/effect.h b/src/interface/effect.h new file mode 100644 index 0000000..54a31c3 --- /dev/null +++ b/src/interface/effect.h @@ -0,0 +1,95 @@ +#pragma once + +#include + +#include "base/color.h" +#include "interface/types.h" + +typedef enum effect_type_t { + ZDWM_EFFECT_MAP_WINDOW = 1, + ZDWM_EFFECT_UNMAP_WINDOW, + ZDWM_EFFECT_FOCUS_WINDOW, + ZDWM_EFFECT_KILL_WINDOW, + ZDWM_EFFECT_WITHDRAW_WINDOW, + ZDWM_EFFECT_START_MOVE_WINDOW, + ZDWM_EFFECT_START_RESIZE_WINDOW, + ZDWM_EFFECT_MINIMIZE_WINDOW, + ZDWM_EFFECT_MAXIMIZE_WINDOW, + ZDWM_EFFECT_FULLSCREEN_WINDOW, + ZDWM_EFFECT_CONFIGURE_WINDOW, + ZDWM_EFFECT_CHANGE_BORDER_COLOR, + ZDWM_EFFECT_CHANGE_WINDOW_LIST, + ZDWM_EFFECT_RESTACK_WINDOWS, + ZDWM_EFFECT_BIND_KEY, + ZDWM_EFFECT_GRAB_BUTTON, + ZDWM_EFFECT_UNGRAB_POINTER, +} effect_type_t; + +typedef struct effect_move_window_t { + window_id_t window; + point_t left_top_point; +} effect_move_window_t; + +typedef struct effect_resize_window_t { + window_id_t window; + int32_t width; + int32_t height; +} effect_resize_window_t; + +typedef struct effect_change_border_color_t { + window_id_t window; + const color_t *color; +} effect_change_border_color_t; + +typedef struct effect_window_list_t { + const window_id_t *windows; + size_t count; +} effect_window_list_t; + +typedef struct key_bind_t { + modifier_mask_t modifiers; + keysym_t keysym; +} key_bind_t; + +typedef struct effect_bind_key_t { + const key_bind_t *keys; + size_t count; +} effect_bind_key_t; + +typedef struct grab_button_t { + modifier_mask_t modifiers; + button_t button; +} grab_button_t; + +typedef struct effect_grab_button_t { + window_id_t window; + const grab_button_t *buttons; + size_t count; +} effect_grab_button_t; + +typedef struct effect_bool_window_t { + window_id_t window; + bool value; +} effect_bool_window_t; + +typedef struct effect_t { + effect_type_t type; + union { + only_window_data_t map; + only_window_data_t unmap; + only_window_data_t focus; + only_window_data_t kill; + only_window_data_t withdraw; + only_window_data_t move; + only_window_data_t resize; + effect_bool_window_t minimize; + effect_bool_window_t maximize; + effect_bool_window_t fullscreen; + configure_data_t configure; + effect_change_border_color_t change_border_color; + effect_window_list_t change_window_list; + effect_window_list_t restack_windows; + effect_bind_key_t bind_key; + effect_grab_button_t grab_button; + } as; +} effect_t; diff --git a/src/core/event.h b/src/interface/event.h similarity index 96% rename from src/core/event.h rename to src/interface/event.h index ecc00a8..2506742 100644 --- a/src/core/event.h +++ b/src/interface/event.h @@ -2,8 +2,7 @@ #include -#include "core/types.h" -#include "core/window.h" +#include "interface/types.h" typedef enum event_type_t { ZDWM_EVENT_NONE, @@ -111,6 +110,3 @@ typedef struct event_t { configure_data_t configure_request; } as; } event_t; - -void event_cleanup(event_t *event); -void event_reset(event_t *event); diff --git a/src/core/types.h b/src/interface/types.h similarity index 61% rename from src/core/types.h rename to src/interface/types.h index 245feed..448c96f 100644 --- a/src/core/types.h +++ b/src/interface/types.h @@ -1,5 +1,6 @@ #pragma once +#include #include #include #include @@ -32,38 +33,14 @@ typedef struct point_t { int32_t y; } point_t; -typedef enum focus_direction_t { - ZDWM_FOCUS_PREV, - ZDWM_FOCUS_NEXT, -} focus_direction_t; +typedef struct zdwm_size_t { + int32_t width; + int32_t height; +} zdwm_size_t; -typedef enum cross_output_policy_t { - ZDWM_CROSS_OUTPUT_KEEP_WORKSPACE, - ZDWM_CROSS_OUTPUT_MOVE_TO_TARGET_WORKSPACE, -} cross_output_policy_t; - -typedef struct key_bind_t { - modifier_mask_t modifiers; - keysym_t keysym; -} key_bind_t; - -typedef struct grab_button_t { - modifier_mask_t modifiers; - button_t button; -} grab_button_t; - -typedef enum window_state_request_type_t { - ZDWM_WINDOW_STATE_REQUEST_FULLSCREEN, - ZDWM_WINDOW_STATE_REQUEST_MAXIMIZED, - ZDWM_WINDOW_STATE_REQUEST_MINIMIZED, - ZDWM_WINDOW_STATE_REQUEST_SKIP_TASKBAR, -} window_state_request_type_t; - -typedef enum window_state_request_action_t { - ZDWM_WINDOW_STATE_ACTION_ADD, - ZDWM_WINDOW_STATE_ACTION_REMOVE, - ZDWM_WINDOW_STATE_ACTION_TOGGLE, -} window_state_request_action_t; +typedef struct only_window_data_t { + window_id_t window; +} only_window_data_t; /* clang-format off */ typedef enum configure_field_t { @@ -89,26 +66,85 @@ typedef struct configure_data_t { uint32_t stack_mode; } configure_data_t; -typedef struct border_config_t { - uint32_t width; - color_t normal_color; - color_t focused_color; -} border_config_t; +/* Internal semantic window types mapped from backend-specific protocols. */ +typedef enum window_type_t { + ZDWM_WINDOW_TYPE_NORMAL = 0, + ZDWM_WINDOW_TYPE_DESKTOP, + ZDWM_WINDOW_TYPE_DOCK, + ZDWM_WINDOW_TYPE_TOOLBAR, + ZDWM_WINDOW_TYPE_DIALOG, + ZDWM_WINDOW_TYPE_UTILITY, + ZDWM_WINDOW_TYPE_SPLASH, + ZDWM_WINDOW_TYPE_MENU, + ZDWM_WINDOW_TYPE_DROPDOWN_MENU, + ZDWM_WINDOW_TYPE_POPUP_MENU, + ZDWM_WINDOW_TYPE_TOOLTIP, + ZDWM_WINDOW_TYPE_COMBO, + ZDWM_WINDOW_TYPE_DND, + ZDWM_WINDOW_TYPE_NOTIFICATION, +} window_type_t; -typedef struct only_window_data_t { - window_id_t window; -} only_window_data_t; +/* Internal semantic window states mapped from backend-specific protocols. */ +typedef enum window_state_t { + ZDWM_WINDOW_STATE_ABOVE = 0, + ZDWM_WINDOW_STATE_FULLSCREEN, + ZDWM_WINDOW_STATE_MODAL, + ZDWM_WINDOW_STATE_STICKY, +} window_state_t; + +typedef enum window_state_request_type_t { + ZDWM_WINDOW_STATE_REQUEST_FULLSCREEN, + ZDWM_WINDOW_STATE_REQUEST_MAXIMIZED, + ZDWM_WINDOW_STATE_REQUEST_MINIMIZED, + ZDWM_WINDOW_STATE_REQUEST_SKIP_TASKBAR, +} window_state_request_type_t; + +typedef enum window_state_request_action_t { + ZDWM_WINDOW_STATE_ACTION_ADD, + ZDWM_WINDOW_STATE_ACTION_REMOVE, + ZDWM_WINDOW_STATE_ACTION_TOGGLE, +} window_state_request_action_t; + +/* 层级从低到高 */ +typedef enum window_layer_type_t { + ZDWM_WINDOW_LAYER_DESKTOP = 0, + ZDWM_WINDOW_LAYER_NORMAL, + ZDWM_WINDOW_LAYER_TOP, + ZDWM_WINDOW_LAYER_OVERLAY, + ZDWM_WINDOW_LAYER_COUNT, +} window_layer_type_t; + +typedef struct window_layer_props_t { + window_type_t *types; + size_t type_count; + + window_state_t *states; + size_t state_count; +} window_layer_props_t; + +/* clang-format off */ +typedef enum window_metadata_change_flags_t { + ZDWM_WINDOW_METADATA_CHANGE_TITLE = 1u << 0, + ZDWM_WINDOW_METADATA_CHANGE_APP_ID = 1u << 1, + ZDWM_WINDOW_METADATA_CHANGE_ROLE = 1u << 2, + ZDWM_WINDOW_METADATA_CHANGE_CLASS = 1u << 3, + ZDWM_WINDOW_METADATA_CHANGE_INSTANCE = 1u << 4, +} window_metadata_change_flags_t; +/* clang-format on */ + +typedef struct window_metadata_t { + char *title; + char *app_id; + char *role; + char *class_name; + char *instance_name; +} window_metadata_t; typedef enum hint_field_t { ZDWM_HINT_FIELD_URGENT, ZDWM_HINT_FIELD_SIZE, } hint_field_t; -typedef struct zdwm_size_t { - int32_t width; - int32_t height; -} zdwm_size_t; - typedef struct hints_data_t { window_id_t window; uint32_t changed_fields; @@ -117,19 +153,11 @@ typedef struct hints_data_t { zdwm_size_t max_size; } hints_data_t; -typedef enum window_interaction_mode_t { - ZDWM_WINDOW_INTERACTION_NONE, - ZDWM_WINDOW_INTERACTION_MOVE, - ZDWM_WINDOW_INTERACTION_RESIZE, -} window_interaction_mode_t; - -typedef struct window_interaction_state_t { - window_interaction_mode_t mode; - window_id_t window; - point_t start_coordinate; - rect_t origin_rect; - uint64_t last_change_time; -} window_interaction_state_t; +typedef struct border_config_t { + uint32_t width; + color_t normal_color; + color_t focused_color; +} border_config_t; static inline bool window_id_invalid(window_id_t window_id) { return window_id == ZDWM_WINDOW_ID_INVALID; diff --git a/src/runtime/runtime.c b/src/runtime/runtime.c index a7a77d1..31b27d4 100644 --- a/src/runtime/runtime.c +++ b/src/runtime/runtime.c @@ -17,21 +17,23 @@ #include "base/log.h" #include "base/macros.h" #include "base/memory.h" -#include "base/window_list.h" +#include "common/event.h" +#include "common/listeners.h" +#include "common/window.h" +#include "common/workspace.h" #include "config/runtime_config.h" -#include "core/backend.h" #include "core/binding.h" #include "core/command_buffer.h" -#include "core/event.h" #include "core/layout.h" #include "core/listeners.h" #include "core/plan.h" #include "core/policy.h" #include "core/rules.h" #include "core/state.h" -#include "core/types.h" #include "core/window.h" -#include "core/wm_desc.h" +#include "interface/backend.h" +#include "interface/event.h" +#include "interface/types.h" typedef struct runtime_t { bool running;