Repository navigation
SnipForge 0.2.1
Pre-release[0.2.1] - 2026-11-08
变更 · 开机自启改为静默启动(重新打包)
- 注册表 Run 项写入
"…\snipforge.exe" --silent。登录 Windows 后只驻留托盘图标,
不再弹主界面抢焦点;主窗口照常创建,热键、托盘、剪贴板监听全都正常,
点托盘或按热键随时亮出来 - 手动双击 exe 不带该参数,行为不变(照常显示主界面)
- 老版本写入的自启项在下次启动时自动校正成带
--silent的写法,不用手动重开开关 - 静默启动时撞上已有实例直接安静退出,不弹"已经在运行"的对话框
新增 · 开发者工具箱(插件形式)
21 个本地工具,侧边栏「开发工具」进入,手势里也能挂一条。
- 编码转换:Base64(URL-safe / 折行)、URL、Hex、HTML 实体、Unicode 转义、JWT 解析
- 格式化 / 校验:JSON(带行列报错、键排序)、XML、SQL、正则测试(高亮 + 分组明细 + 替换预览)
- 生成 / 计算:UUID、时间戳互转、哈希(MD5/SHA-1/256/384/512)、随机密码、进制转换、Cron 下次触发
- 文本处理:命名风格(camel/snake/kebab…)、去重排序、行级 diff、行处理、字数统计
- 工具目录写在
plugins/devkit.plugin.json,算法在前端注册表src/lib/devkit/。
清单一改,导航和工具列表跟着变;插件页可以整体开关这个工具箱 - MD5 是手写的(Web Crypto 不提供),已和 Node 的
crypto对过 8 组输入;
密码用拒绝采样 + 保证每类字符至少一个;进制转换走 BigInt,超过 2^53 不丢精度
变更 · 手势引擎换 8 方向(破坏性)
- 方向从 4 个扩到 8 个:上下左右 + 四个斜向。位移按 45° 扇区判定,
一个方向走够step才记一个 token - 逗号分隔 token:
D,R= 先下后右,DR= 一条右下斜线 —— 不分开的话
这两种手势会撞成同一个串 - 容错一个 token:转折处多判/少判一个方向是常态,要求逐字相等太脆。
DR,UR和DR,U,UR都能命中 V - 掉头要 1.8 倍距离:上↔下、左↔右这种正相反的方向,防转折点抖动
切出多余 token - 删掉形状识别:点云匹配、模板阈值、
@前缀、自定义笔画全部去掉。
S / H 改用方向串写(S =DL,DR,DL,H =D,R,D),行为从"黑盒猜"
变成"画什么就是什么" - 默认绑定全部重配(配置迁移 v5 会重置,旧绑定在新语义下意思全变了):
四个主方向 +DR/DL两条斜线 + 若干组合 - 录制框改成「画一遍 → 后端翻译成方向串」,和真手势共用同一套判定
变更 · 默认手势定稿(8 方向)
按实际使用习惯重排,配置迁移 v6 会重置绑定:
| 手势 | 动作 | 手势 | 动作 |
|---|---|---|---|
| ↑ | 复制 | ↓ | 粘贴 |
| → | 前进 | ← | 后退 |
| ↓→ | 关闭窗口 | ↓← | 关闭同程序其他窗口 |
| ↗ | 最大化/还原 | ↙ | 最小化 |
| ↖ | Esc | ↘ | Del |
| ←↓→↓← | 搜索选中文字 | ↑→↓← | Ping 选中地址 |
| ↓↑→↓ | 编辑 hosts | ↓→↑← | 贴图 |
| ↓←↑→ | OCR | →↙→ | 排除当前程序 |
| ↙↘↙ | 截图 |
浏览器专用集:↑ 页顶 / ↓ 页底 / ↘↗ 刷新 / ↗↘ 强制刷新 / ↓→ 关标签 /
↑→ 右侧标签 / ↑← 左侧标签 / ↓→↓ 主页。
新增三个动作:
- 关闭同程序其他窗口:枚举同进程、可见、有标题的顶层窗口发
WM_CLOSE,
当前窗口留着。没有标题的多是隐藏辅助窗口,关掉会伤到正在运行的程序 - 搜索选中文字:先
Ctrl+C,180ms 后读剪贴板,开 Bing - Ping 选中地址:
Ctrl+C后只保留域名/IP/端口的合法字符,
直接spawn ping—— 不经过任何 shell,没有命令注入面
修复
- 右键点一下菜单不弹(被"吞"了)。判定的顺序错了:先看方向串再看位移。
手抖 40 多像素时path_to_dir已经能切出一个 token(R/D/…),而单 token
手势是精确匹配的 —— 于是"点一下"变成执行动作,菜单自然不出来。
现在位移 < 48px 一律按单击补发,不看向量算出了什么 - 补发点击加了诊断日志(光标位置 + 光标下的窗口类名 +
SendInput的返回值和
错误码)。以后"补发没生效"能一眼看出是没发出去,还是发到了别的窗口
审计(第二轮)
- 方向解析(
dir8/ RDP / 折线简化)搬进snipforge_core::stroke,
补 8 条单测。这块以前一条测试都没有 —— 而"画 3 段出 5 个 token"
正是这里出过的 bug。现在覆盖:8 个扇区、22.5° 边界、直线单 token、
直角两 token、↙↘↙三段、锯齿抖动仍是一段、相邻同向合并、过短轨迹不出 token step字段已废弃:RDP 之后"几段就是几个 token",本来按"走够多少像素
算一次转向"的step不再参与任何判定。从Snapshot和on_move里删掉,
配置字段保留但注明废弃(删了会让旧配置文件丢字段)gesture_trace去掉没用的step参数(前后端一起改)- 文档对齐现状:
docs/FEATURES.md还在写"画一个 S 截图""@S/@H
形状命名空间""接管右键按下开关""$P 点云匹配"—— 这些都是已经删掉的东西。
整章按 8 方向重写,含默认手势表和三条匹配规则;README.md的
"画一个 S 就截图"一并改掉
审计(手势链路)
一轮完整代码审计,按"会不会在钩子线程里出事"这条线逐层过:
-
handle_event每个 mousemove 都拿配置锁 +clone()一个 String。
这个函数就在钩子线程里同步跑,等于持续分配内存。改为配置变更时写进
AtomicBool+RwLock<String>,热路径只做一次原子读 -
on_move在轨迹点数封顶后每个事件都做全量 RDP。pts到 1500 后长度
不再变,1500 % 6 == 0让重算条件恒成立 —— 越划越卡。改成只有真的压入
新点时才重算 -
match_action每次方向变化都整体 clone 专用手势集(连所有绑定的轨迹点)。
改成按引用索引 -
inject_click在钩子回调里调SendInput。整理成整对发送都在工作线程
里做,回调只负责"决定要补点一下" -
"关闭同程序其他窗口"会把自己也关掉:枚举时没有排除当前窗口,
说是"其他窗口",实际连用户正在用的那个一起WM_CLOSE -
path_to_dir里有两处unwrap()(包围盒)。虽然前面对点数有保护,
但这段跑在钩子线程,panic 会连带整个输入链。改成单次遍历算包围盒 -
on_move的兜底之外,on_down也会处理"上一次抬起丢了"的残留状态,
先把旧轨迹收掉再开新的 -
修正
gesture.rs顶部过时的模块文档(还在描述已删除的点云形状识别、
四个方向)和window.rs里一段粘错位置的注释 -
在浏览器里画
↓↑→↓打开的是主页,而不是编辑 hosts。原因是匹配顺序:
先查浏览器专用集,里面↓→↓(主页)只要"差一个 token"就算命中,
于是把通用集里精确命中的↓↑→↓挡住了。现在改成:- 先比距离,精确匹配永远赢过模糊匹配;距离相同才让专用集优先
(专用集的意义是"在这个程序里覆盖",不是"随便糊一个") - 容错按长度收紧:两段以内只认精确(
↓→是关窗口,↓→→不该命中它);
三段以上才允许差一个 - 只容忍"多画",不容忍"少画":转折处手抖多切一个 token 可以,
但 3 段手势不会去命中 4 段绑定 —— 否则画↓→↓会误触↓↑→↓
- 先比距离,精确匹配永远赢过模糊匹配;距离相同才让专用集优先
-
匹配规则搬到
snipforge_core::pattern。主 crate 的测试 harness 在本机
起不来(STATUS_ENTRYPOINT_NOT_FOUND),所以gesture.rs里的测试从来没跑过,
其中两条断言一直是错的(normalize("D-X,R")和一处编辑距离)。搬进 core 后
36 项单测全绿,这两条也一并修正 -
吞一半按下/抬起会让系统按键状态卡死(这是这一轮所有怪现象的根)。
鼠标钩子吞掉一个事件,系统那颗键的状态就不会跟着变 —— 实测:放行
RButtondown、吞掉RButtonup之后,GetAsyncKeyState(VK_RBUTTON)
会一直返回 DOWN。后果是目标窗口一直以为右键按着:捕获不放、
菜单卡住、左键跟着失灵,得再点一次右键才恢复。
规则:按下和抬起必须成对处理,要么都放行,要么都吞掉 -
桌面右键菜单跳两下。整对吞掉后必须补发一次点击,而补发时按下和抬起
之间的间隔太短(35ms),桌面/任务栏的菜单还没建完,合成的抬起落在了底下
的桌面上,于是又开一次菜单。间隔改成 100ms(接近真人点击),抬起就能落到
已经建好的菜单窗口上 -
松手后手势不结束、轨迹一直跟着鼠标。根因是同时跑了两个实例:
两套钩子互相截事件,一边拿了按下、另一边拿了抬起,前者状态永远不清。
启动时用会话内命名互斥体挡掉第二个实例(弹提示后退出);另外加 20 秒
超时兜底,任何情况下都不会再"永久跟随" -
删掉
swallowDown开关(配置项和界面都去掉):两种模式只有一种是对的,
留个开关只会让人选到错的那个 -
手势只认 S 和 H,其余字母不再内置识别。一笔画的折线本来就是方向串
(↓→既是「向下再向右」,又恰好是字母 L 的写法),全字母参与识别时
每次「下再右」都被判成画字母。更要紧的是RLR(画 Z 形)是「排除当前
程序」的默认绑定,会被@Z吃掉,排除功能直接失效。
现在只有 S / H 参与内置识别;其他字母在「鼠标手势」页画一遍存成自定义
手势即可 —— 只认你加的那一个,不干扰任何方向手势 -
画
↓→时浮标报「未绑定」,但松手却执行了动作。原因:↓→的形状正好
等于字母L的模板(竖下 + 横右),被形状识别抢成@L。执行层有回落
(@L没绑就按方向串DR找),浮标层却只查@L—— 显示和执行用了两套规则。
现在两处共用同一套回落,浮标显示的永远是真正会执行的那个动作