Closed timzaak closed 2 months ago
wezterm 相较于 xterm.js 解决的问题有:
run_message_loop
。
Linux x11 基于 xcb rust bindings,wayland 基于 Smithay/client-toolkit(wayland-client rust 封装)。
macOS 基于 cocoa rust bindings。
Windows 基于 winapi rust bindings。
还有诸如 toast, pty,粘贴板 等兼容性封装。基于 ANSI/DEC 字符流 绘图的有:
https://github.com/crossterm-rs/crossterm 抹平 cmd 、unix terminal 差异。 https://github.com/ratatui-org/ratatui 在命令行上绘制UI,提供UI组件封装。
alacritty 也是 Rust 实现 video terminals。不过没搞插件,更纯粹。
渲染除了pty output 渲染外,还有交互渲染,例如程序模态框、搜索、光标。这里只研究针对 pty output 的渲染。 变动触发入口:pty.reader().read,
布局变动处理函数:impl
变动先触发 Grid 数据变化,再发出渲染请求(request_redraw
)。
针对 Grid 构建 RenderableContent, 并依据 damagedTracker 确认全量渲染还是部份渲染。
剩下的就是常规GPU渲染操作了:
最开始研究 wezterm, 看看是如何做 SSH 渲染的,但 Rust 代码看的麻烦,且渲染外的功能过多,于是找了 typescript实现的 xterm.js 来看,它提供 Dom Render,Canvas Render,WebGPU Render[WIP],相互比对着看,会更容易找规律,也不需要应对 Rust 的编程繁琐性。
xterm.js 的关键文件有: Keyboard.ts 将输入转译成 ASCII 控制码, 从而适配 SSH字符流的交互。 EscapeSequenceParser.ts 解析ssh 传递过来的 ANSI/DEC 字符流,并转换到UI表达数据结构。 CanvasRenderer.ts 解构了 video terminals 的渲染图层:文字(背景、前景)、选中、光标、链接。
关于文字排版布局再复杂的样例,可以参考 facebook/Lexical 富文本编辑器的设计思路。它有 Dom Render 实现 以及 iOS TextKit Render实现。