Files
liyepan 580abbcadf feat: VoiletXterm - Qt5 terminal workspace for SSH, Telnet and serial
Terminal core (src/core, QtCore only, headless testable):
- VT100/xterm parser: CSI/OSC/DCS, SGR 256/truecolor, scroll regions,
  insert/delete, DEC special graphics, alternate screen
- cell grid with 5000 line scrollback, CJK wide chars, combining marks
- xterm 256 color palette

Terminal widget (src/term):
- QPainter renderer with run batching, wide char clipping, cursor blink
- mouse selection (char/word/line), auto copy, middle click paste
- full key encoding: arrows + DECCKM, F1-F12, modifiers, ctrl/alt
- IME support via inputMethodEvent

Transports (src/session):
- SSH through the system OpenSSH client on a forkpty pseudo terminal,
  so agent, ProxyJump, known_hosts and 2FA keep working
- Telnet with IAC negotiation (NAWS, ECHO, SGA)
- Serial via QSerialPort

UI (src/ui):
- tabbed main window, session dialog with saved profiles
- dark violet theme, CLI targets (user@host:port, telnet://, serial:)

Tests:
- tests/test_core: escape sequence and layout assertions
- tests/test_widget: offscreen render checks and key encoding
2026-10-23 17:38:16 +08:00

98 lines
4.2 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# VoiletXterm
> 轻量的 SSH / Telnet / 串口终端工作台。Qt 5 + qmake,终端内核全部自研。
![screenshot](docs/screenshot.png)
MobaXterm 很好用,但只跑 Windows、源码闭源。VoiletXterm 只做三件事——**SSH、Telnet、串口**——用一套自己写的 VT100/xterm 内核把它们塞进同一个窗口,三平台共用一套 C++ 代码。
## 特性
**终端内核(自研,不依赖任何终端控件)**
- VT100/xterm 转义序列:CSI / OSC / DCS、SGR 256 色与真彩色、滚动区、插入/删除行列、DEC 特殊字符集
- 备用屏:`vim`、`htop`、`less` 正常工作;5000 行回滚
- CJK 宽字符、组合字符、彩色 emoji、粗体/斜体/下划线/删除线/反色
- 鼠标选区(单击拖动 / 双击选词 / 三击选行)、中键粘贴、自动复制
- 完整键位编码:方向键(含 DECCKM)、F1–F12、Home/End、`Ctrl+字母`、`Alt` 前缀、xterm 修饰符
- 中文输入法走 `inputMethodEvent`,候选窗跟随光标
**三种连接**
| 类型 | 实现 | 说明 |
| --- | --- | --- |
| SSH | 系统 `ssh` 跑在伪终端(pty)上 | `~/.ssh/config`、密钥、agent、`ProxyJump`、known_hosts、二次验证全部照常生效 |
| Telnet | 内置 IAC 协商 | 自动回 `WILL/DO`,支持 NAWS 窗口尺寸随窗口变化 |
| 串口 | QSerialPort | 波特率 / 数据位 / 校验 / 停止位 / 流控 / 本地回显 |
**界面**
- 多标签会话,标签标题跟随远端 `OSC 0/2` 标题
- 会话保存与复用(QSettings 持久化),新建/编辑/删除
- 命令行直达:`voiletxterm user@host:22` / `telnet://host:port` / `serial:/dev/ttyUSB0@115200`
- 深色紫罗兰主题,Ctrl+滚轮缩放字号
## 构建
需要 Qt 5.15(Widgets / Network / SerialPort 三个模块)。
```bash
export PATH=/path/to/Qt/5.15.2/gcc_64/bin:$PATH
mkdir -p build && cd build
qmake ../VoiletXterm.pro
make -j$(nproc)
./voiletxterm
```
串口需要读写权限,通常把用户加进 `dialout` 组:`sudo usermod -aG dialout $USER`。
## 使用
```bash
voiletxterm # 打开会话窗口
voiletxterm root@10.0.0.5:2222 # 直接 SSH
voiletxterm telnet://192.168.1.1 # 直接 Telnet
voiletxterm serial:/dev/ttyUSB0@115200
```
| 快捷键 | 作用 |
| --- | --- |
| `Ctrl+N` | 新建 SSH 会话 |
| `Ctrl+W` | 关闭当前标签 |
| `Ctrl+Shift+C` / `Ctrl+Shift+V` | 复制 / 粘贴 |
| `Ctrl++` / `Ctrl+-` / `Ctrl+0` | 放大 / 缩小 / 重置字号 |
## 结构
```
src/core/ Screen、Cell、VtParser、字符宽度、调色板 ← 只依赖 QtCore,可无头测试
src/term/ TerminalWidget(QPainter 渲染)、主题
src/session/ Transport 抽象、PtyProcess、SSH/Telnet/串口实现
src/ui/ MainWindow、SessionDialog、会话存储、样式
tests/ test_core(转义序列)、test_widget(离屏渲染 + 键位编码)
```
终端内核和界面完全解耦:`src/core` 只依赖 QtCore,测试可以直接跑在无显示环境里。
## 设计取舍
**为什么 SSH 用系统 `ssh` 而不是内嵌协议库?**
SSH 客户端最难的不是握手,而是把密钥、agent、跳板、known_hosts、二次验证这些琐事处理对。系统 OpenSSH 已经替我们做了二十年。VoiletXterm 用 `forkpty` 起一个 `ssh`,窗口尺寸通过 `TIOCSWINSZ` 同步,密码提示、主机指纹确认直接显示在终端里——所见即系统 ssh 的所见。
代价是依赖系统的 `ssh`(Linux/macOS 自带),以及无法做程序化的密码保管。
**为什么不用 qtermwidget?**
它是 GPL-2.0,一旦引入整个项目就得按 GPL 发布;而且 Konsole 血统的 QPainter 路径限制了性能上限。自研内核约 2000 行,MIT 无约束,问题也能自己修。
**宽字符对齐**
默认字体优先选半角/全角宽度严格 1:2 的字体(Sarasa Mono SC、文泉驿等宽正黑),这样 `中` 正好占两格;找不到再退回 DejaVu Sans Mono。
## 已知限制
- 只在 Linux 上验证过;`forkpty` 是 POSIX 接口,Windows 需要换成 ConPTY 才能编译
- 没有 SFTP 文件面板、没有 X11 转发、没有 RDP(MobaXterm 的那部分不在当前范围)
- 没有标签内搜索、没有分屏
- SSH 密码登录在终端里交互,不经过独立密码框
## 许可
MIT