Skip to content

Releases

SnipForge 0.2.1

SnipForge 0.2.1 Pre-release
Pre-release

Choose a tag to compare

@github-actions github-actions released this 07 Nov 07:46

[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 —— 显示和执行用了两套规则。
    现在两处共用同一套回落,浮标显示的永远是真正会执行的那个动作

SnipForge 0.2.0

SnipForge 0.2.0 Pre-release
Pre-release

Choose a tag to compare

@github-actions github-actions released this 04 Nov 14:15

[0.2.0] - 2026-11-03

剪贴板 · 富文本与隐私

对照 TieZ 的剪贴板实现补齐三块:

  • 富文本 HTML 保留(以前挂在 📋 计划里的那条)。采集时读 Windows 的
    HTML Format,粘贴时同时写 CF_UNICODETEXT 和 HTML —— 从网页复制的表格、
    带样式的文字,粘到 Word / 邮件 / 飞书里格式不丢;记事本、终端这类只认纯文本的
    地方照常能粘。去重仍按纯文本 hash:同一段话复制两次不该变成两条历史
  • 隐私遮罩预览:列表里手机号、身份证、银行卡、邮箱自动打码
    (138****8000 / 110101********1234)。只影响显示,选中后写进剪贴板的
    还是原文。面板和主窗口都生效 —— 投屏、录屏、旁边有人的时候不至于把证件号念出来
  • 按来源程序筛选:卡片底部的程序名现在可点,点一下只看那个程序里的复制记录;
    再点一下(或点顶部「来自 xxx ✕」)取消
  • 粘贴为纯文本:面板里 Alt+Enter,丢掉网页带来的字体颜色等样式,
    只把文字塞过去。配合上面的富文本保留,两种场景各取所需

不做的事:WebDAV / MQTT 跨设备同步。这个工具的定位是本地常驻,剪贴板历史里
经常有密码和证件号,不上传比"能同步"重要。

鼠标手势 · 支持画字母

以前只能认方向(←→↑↓ 及其组合)和 S / H 两个形状,画 W、V、B、M
一律落到"未绑定"。原因是形状和方向串共用同一批字符:D 既是"向下划"
又是"字母 D",加一个字母就得跟方向抢名字。

现在按主流工具的做法拆开:

  • 一笔画字母基本都认:A B C D E F G H J K L M N P R S T U V W X Y
    (I 是一条竖线、等于方向串;O 是闭合圆;Q 一笔画不自然)
  • 形状用 @ 前缀,和方向串分处两个命名空间:@W 是字母,DR 是方向。
    用户手写 W 也认(自动补前缀)
  • 形状没绑动作时自动回落方向串:画 Z 会先认成 @Z,没绑就落回 RLR,
    「画 Z 排除当前程序」照常工作,不需要为每个字母补绑定
  • 配置迁移 v4:老绑定里的 S / H 自动改成 @S / @H
  • S 补了两个斜写模板(±10°):点云不抗旋转,以前斜着写 S 认不出
  • 形状识别从主 crate 搬到 snipforge-core,第一次有了真正能跑的测试
    (letters_recognize_themselves:每个字母 6 个抖动/缩放变体必须认回自己)

鼠标手势 · 手感修复

反馈「划起来不流畅、不灵活,和其它手势工具差距极大」。定位到四个实现问题,
全部在轨迹层和默认参数上,与 UI 框架无关:

  • 不再每帧重建 GDI 资源:画笔、画刷、字体改成随窗口缓存,只在分辨率或
    轨迹色变化时重建。以前每帧 CreateFontW 一次,字体面查询就是几毫秒
  • 重绘合并 + 66fps 上限:高刷鼠标每秒上千次位移,以前每次都投递一次重绘,
    消息队列被灌满,表现是轨迹越划越落后于光标
  • 只贴脏区:以前每帧清空并回贴整个虚拟屏(4K 双屏 800 万像素每帧),
    现在只处理「轨迹包围盒 ∪ 浮标包围盒 ∪ 上一帧范围」
  • 灵敏度默认值 30/55 → 16/38:旧值划一小段没反应、短促手势划不出方向。
    配置里两个值都还是旧默认的自动升级(v3 迁移),自己调过的不动
  • 浮标停留 520 → 240ms:连续划两个手势不再互相干扰
  • 轨迹采样加 2px 阈值,去掉一像素一报的抖动点

决策记录

  • 新增 docs/ADR-001-ui-stack.md:评估 Rust + egui 迁移,结论是不迁。
    内存 27 MB 不是瓶颈,且 egui 的立即模式对全屏覆盖层是负优化;
    手势卡顿的根因在 GDI 重绘方式,换框架解决不了。文档里留了重新评估的触发条件

SnipForge 0.1.0

SnipForge 0.1.0 Pre-release
Pre-release

Choose a tag to compare

@github-actions github-actions released this 01 Nov 04:06

[0.1.0] - 2026-11-01

第一个预览版。Windows 10/11 x64。

截图

  • 一个入口:Alt+Q 打开冻结画面,拖拽框选区域、单击选窗口、Ctrl 选整窗、
    Ctrl+A 整屏、S 滚动长截图
  • 滚动长截图按行签名拼接,最高 24000px
  • 取完之后做什么可配:打开编辑器 / 直接复制到剪贴板 / 直接保存 / 钉在屏幕上。
    选「直接复制」完全不弹窗口

标注与美化

  • 矩形、椭圆、箭头、画笔、文字、序号、高亮、马赛克
  • V 切选择工具,点中标注可拖动、Delete 删除,Esc 先退选中再退编辑器
  • 撤销重做、颜色/粗细/字号可调;对象化模型(标注是数据不是像素)
  • 美化:背景、边距、圆角、阴影;水印:文字/平铺/九宫格

取字(OCR)

  • Windows 系统 OCR(需对应语言包);可选 PaddleOCR 引擎,设置页一键下载安装
    (多镜像 + 体积校验 + 离线导入)
  • 识别结果手动触发翻译;点词复制:原图上每个词都是可点区域

剪贴板

  • 文本 / 图片 / 文件 / 颜色四类全收,按 GetClipboardSequenceNumber 变更检测
  • Alt+V 面板:搜索、分类、收藏、来源程序识别;Win+V 可用键盘钩子接管
  • 历史落盘做了节流,连续复制不会反复重写索引

安全

  • 主密码:Argon2id 派生 + AES-256-GCM,加密收藏的密码、图床 token、翻译 key。
    设了主密码后磁盘上没有明文;启动即锁定,可随时「立即锁定」
  • 忘记密码没有后门,唯一出路是「清空保险箱」(两段式确认)
  • 路径穿越防护:图床目录、文件名、保存文件名统一出口校验

图床

  • GitHub、S3 兼容、SM.MS、自定义、本地目录;声明式插件(JSON 描述即可接入新图床)
  • 上传历史、连通性测试、目录浏览

录屏

  • 视频(H.264 MP4)与 GIF 分开录,Ctrl+Alt+R / Ctrl+Alt+G
  • 系统声音(WASAPI loopback,不用装虚拟声卡)+ 麦克风,两路自动混音,
    静音时段按视频时间轴补静音
  • 摄像头画中画:圆角+描边、四角位置、大小比例、水平镜像
  • 恒定帧率、光标合成、点击高亮环、放大镜、暂停续录

其他

  • 图标提取:exe / dll / lnk / APK / IPA → 各尺寸原始图标,可导出 PNG / ICO。
    Android 自适应图标会合成背景+前景
  • 图片工具:格式互转、质量压缩、等比缩放
  • Hosts 编辑:可视化编辑,写入自动提权
  • 鼠标手势:自定义手势绑定到任意功能
  • 检查更新:启动后静默检查一次 GitHub Release,只提示不自动安装。
    API 被限流时自动改用 releases 订阅(不受 60 次/小时配额限制)
  • 联网走系统代理:图床上传、OCR 引擎下载、翻译、检查更新统一读取
    Windows「Internet 选项」的代理设置(Clash / v2rayN 默认就是系统代理),
    也认 HTTPS_PROXY / ALL_PROXY 环境变量

已知限制

  • 只支持 Windows;多显示器不支持跨屏框选
  • 没有代码签名,首次运行 SmartScreen 会拦一下
  • 录屏的摄像头设备不支持热切换,录制后不能剪辑
  • 长截图依赖目标窗口响应合成滚轮事件(部分 Electron 应用和游戏不响应)

产物已重打包(2026-11-01 15:30):设置 → 关于新增「产品主页 / GitHub / 反馈 / 更新日志」入口;
产品主页上线 https://adream2.github.io/SnipForge/。版本号不变,直接覆盖同名产物。