Skip to content

架构

webview 是三层结构,每层职责清晰、可独立理解。

┌─────────────────────────────────────────────────────────┐
│ App(管理层,单例,UI 线程 COM STA)                      │
│  ├── 窗口注册表(weak_ptr)+ MRU + 分组                   │
│  ├── Worker 线程池(Bridge executor)                     │
│  ├── message-only HWND(Tray / 快捷键)                   │
│  ├── taskbar (ITaskbarList3) + 持久化 KV                  │
│  └── Tray / Menu / Display / dialog / shell              │
├─────────────────────────────────────────────────────────┤
│ Window(窗口层,enable_shared_from_this)                 │
│  ├── Win32 HWND + WebView2 controller                    │
│  ├── EventBus<WindowEvent / PageEvent>                   │
│  ├── 几何 / 状态 / 图标 / DevTools / 多屏                 │
│  └── Bridge(RPC)                                        │
├─────────────────────────────────────────────────────────┤
│ Bridge(通信层)                                          │
│  ├── envelope 编解码 + args tuple 拆解 + invoke 类型擦除  │
│  ├── send(即发即忘)/ call<T>(同步嵌套泵)              │
│  └── reentrancy 检测                                      │
└─────────────────────────────────────────────────────────┘

App — 管理层

App::instance() 单例,跑在 UI 线程(COM STA)。职责:

  • 窗口注册表:所有活窗口 weak_ptr + MRU 激活历史 + 分组树
  • 线程池:Bridge executor,长任务丢后台,避免阻塞 UI
  • 系统集成:Tray、Menu、Display、dialog、shell、clipboard
  • taskbar:ITaskbarList3 进度/角标/缩略图
  • 持久化:窗口状态 KV
  • 生命周期run() 消息循环、quit()on(AppEvent)

典型生命周期:

cpp
auto& app = App::instance();     // 进程唯一
app.requestSingleInstanceLock(); // 单实例
auto win = app.createWindow(...);
// ... 注册 RPC / 事件 ...
return app.run();                // 进消息循环,到 quit 退出

Window — 窗口层

std::shared_ptr<Window>,封装一个 Win32 HWND + WebView2 controller。每个窗口自带:

  • Bridge:该窗口专属的 RPC 通道
  • EventBus:WindowEvent(Resize/Move/Close/...)+ PageEvent(DidLoad/TitleChanged/...)
  • 几何 / 状态控制:bounds、min/max、aspect、透明、置顶
  • 多屏:monitor、moveToDisplay
  • DevTools:open/close/executeJavaScript

窗口由 App 创建并登记,close 后从注册表移除。

Bridge — 通信层

JS 与 C++ 之间的 JSON-RPC 风格通道。每个 Window 持有一个 Bridge。

  • envelope:固定 JSON 信封(id / channel / args / result / error)
  • invoke 类型擦除on(name, fn) 把任意可调用包成 Handler,参数从 JSON 反序列化
  • call<T>:同步调用,嵌套消息泵等待 JS Promise resolve,带超时与重入死锁检测
  • send:即发即忘,不等返回

数据流见 RPC 通信

线程模型

线程干什么
UI 线程(主)COM STA、消息循环、所有 HWND / WebView2 操作、EventBus 派发
Worker 线程池Bridge executor 跑 RPC 槽里的耗时任务

线程安全

EventBus 仅 UI 线程安全。跨线程触发事件用 App 提供的投递接口,勿直接碰 EventBus。Bridge 槽函数默认在 executor 线程跑,访问窗口 API 时注意回到 UI 线程。

目录结构

include/webview/
  app.hpp         App 单例
  window.hpp      Window:控制/几何/事件/Bridge
  window_tem.hpp  WindowTem 糖衣基类
  bridge.hpp      RPC:on / call / send
  menu.hpp        Win32 弹出菜单
  tray.hpp        系统托盘
  compression.hpp 资源压缩枚举
  archive.hpp     .7z 解压
  value.hpp       json 别名 + trait
  detail/         envelope / args / invoke / events / mru / pump / strings / js_runtime
src/              实现
tests/            doctest 单测
docs/guide/       本文档站(VitePress)
docs/superpowers/ 设计 spec + 实现计划

下一步