Repository navigation
Releases: soybeanmilka/clipsift
Release list
v0.3.2
修了什么
0.3.1 里,点 × 收进托盘之后,左键点托盘图标(或菜单里的「显示窗口」)叫不回窗口——程序只能从任务管理器杀掉。
根因不是托盘,是窗口藏起来之后帧循环停了:
- eframe 的每一帧都挂在
WindowEvent::RedrawRequested上,而这个事件来自WM_PAINT; - Windows 只给可见窗口派发
WM_PAINT; - 于是
Visible(false)之后 egui 再也没跑过一帧(日志实测:藏起来之后 8 秒 0 帧); - 托盘点击其实收到了,只是堆在队列里没人取——没人跑帧,就没人取。
0.3.1 那个「心跳线程」发的是 request_repaint,对不可见窗口是空转,根本叫不醒。
怎么修的
- 新增
taskbar::force_paint:藏起来时从外部线程SendMessageW(WM_PAINT)同步塞一帧进去。PostMessage(WM_PAINT)和RedrawWindow都试过,对隐藏窗口全是 0 帧,只有SendMessage能叫醒。 - 心跳线程改成事件驱动:每 120ms 只看一眼托盘事件队列空不空(只看不取,不能把事件消耗掉),真有事件才按可见性选路——可见走
request_repaint,藏起来走force_paint。 - 删掉隐藏期间的 1 秒定时重绘:对不可见窗口是纯空转。
副作用是好的:藏起来且没事件时零帧零 CPU,而 0.3.1 是无条件 8 帧/秒。
验证过什么
cargo test64 passed(core 30 / cli 9 / gui 18 / 属性 7);cargo clippy --all-targets -- -D warnings、cargo fmt --check干净。- 真机:debug 版点 × 藏起来 → 日志 3 秒零增长(确认真的没跑帧)→ 用 Win32 往进程的
tray_icon_app窗口发一次左键 → 日志依次出现图标事件 Click、翻译成 [Show]、处理托盘动作 Show,主窗口IsWindowVisible变回 true,帧号继续涨。 - 托盘菜单的「退出」走同一条取事件的路,也能退(原来卡在同一个地方)。
下载
| 平台 | 文件 |
|---|---|
| Windows(安装包,按用户装、不弹 UAC) | ClipSift-setup.exe |
| Windows(免安装 zip) | clipsift-windows-x86_64.zip |
| Linux x86_64 | clipsift-linux-x86_64.tar.gz |
| macOS Apple Silicon | clipsift-macos-aarch64.tar.gz |
装过旧版的直接覆盖安装就行,规则配置会保留。
小提示:Win11 默认把新托盘图标塞进任务栏那个「⌃」溢出面板里,想让它常显,在「任务栏设置 → 其他系统托盘图标」里把 ClipSift 打开。
完整改动:v0.3.1...v0.3.2
v0.3.1
修了什么
点 × 把窗口收进托盘之后,任务栏上会留下一个点不动的按钮:屏幕上没有窗口,
任务栏里却有一个 ClipSift 按钮,点它什么都不会发生。关也关不掉、退也退不出,
只能去任务管理器杀进程。
为什么会这样
有托盘时,程序发的是 Visible(false),winit 把它翻译成 ShowWindow(SW_HIDE)——
只清掉了窗口的 WS_VISIBLE 位。可是窗口既没有被最小化,扩展样式里也还带着
WS_EX_APPWINDOW(普通应用窗口)、没有 WS_EX_TOOLWINDOW(工具窗口)。
Windows 的规则是:只要窗口没最小化又是普通应用窗口,就给它一个任务栏按钮。
于是就有了那个僵尸按钮。
程序唯一的出口本来是托盘菜单里的「退出 ClipSift」,但 Windows 11 默认把新注册的
托盘图标塞进任务栏那个「⌃」溢出面板里——用户根本看不到图标,也就找不到出口。
怎么修的
藏窗口时不再只改可见性,而是把窗口的扩展样式改成工具窗口
(清 WS_EX_APPWINDOW、设 WS_EX_TOOLWINDOW),Windows 就不再分配任务栏按钮。
从托盘唤回窗口时再把样式改回来。
为什么不用 egui/winit 的现成 API:ViewportCommand 里没有 SkipTaskbar 这一项,
winit 0.30 的公开 API 也没有 set_skip_taskbar(它只在内部实现里,走
ITaskbarList::DeleteTab)。运行时切换只能自己拿窗口句柄改。
验证过什么
- 5 个单元测试覆盖样式位运算(藏/唤回各改哪些位、不相干的位不受影响、幂等、
hide→show 往返)。往返测试一开始就抓到一个真 bug:唤回时只清了 APPWINDOW
没清 TOOLWINDOW,藏过一次再唤回,窗口就永远变不回普通窗口。 - 真机跑 debug 构建,点 × 前后用 Win32 查主窗口的 ex style:
点 × 前 vis=true ex=0x00040110(带 APPWINDOW)
点 × 后 vis=false ex=0x00000190(TOOLWINDOW,无 APPWINDOW) - 测试 59 → 64;clippy -D warnings 干净;cargo fmt --check 干净;CI 三平台全绿
已知限制
- 托盘图标在 Win11 上默认可能被收进任务栏的「⌃」溢出面板。
想常显的话:任务栏设置 → 其他系统托盘图标 → 把 ClipSift 设为开。 - 非 Windows 平台没有托盘图标(Linux 要 GTK + libappindicator 一整套依赖,不划算),
点 × 仍然是收进任务栏。
Full Changelog: v0.3.0...v0.3.1
v0.3.0
Windows:双击安装(推荐)
下载 ClipSift-setup.exe 双击,一路下一步就行。
装完直接能用,卸载去「设置 → 应用 → 已安装的应用」找 ClipSift。
- 装到当前用户目录,不需要管理员权限,不弹 UAC
- 安装时可勾选「开机自动启动」「创建桌面快捷方式」
- 卸载干净:程序文件、开始菜单、桌面图标、自启项一起清掉
- 卸载时问一句要不要保留你的规则设置
0.3.0 新增:系统托盘
点 × 不再只是最小化——窗口收进右下角托盘,任务栏上也不留按钮,剪贴板守护继续跑。
- 右键托盘图标:唤回窗口 / 开始守护 / 停止守护 / 立刻净化一次剪贴板 / 退出
- 悬停提示:
ClipSift · 守护中 · 已净化 N 次,跟着界面状态实时更新 - 单击或双击图标都能唤回窗口(Win11 的溢出面板会吃掉单击,所以两个都认)
- 非 Windows 平台、或者托盘建不出来时,自动退回「收进任务栏」的老行为,
界面上会显示「(托盘不可用)」,不会让人找不到程序
托盘图标是专门重绘的 32×32 版本(强调色圆角方块 + 斜放的扫帚 + 三颗被扫走的白点),
缩到 16px 还认得出轮廓——窗口那枚 256 的图标直接塞进去会糊成一团。
实现上值得记的两个坑:
- 心跳线程而不是
request_repaint_after:窗口被Visible(false)藏掉之后,
eframe 会直接跳过排定的重绘帧(Windows 上只有非 0 尺寸的窗口才给发重绘),
表现就是「点托盘图标没反应」。所以另起一个线程每 120ms 调request_repaint——
它走PostMessage那条路,不依赖窗口可见。 - 必须在主线程建托盘:菜单要绑定窗口的消息循环,换线程建出来的菜单点了没反应。
其他方式
| 平台 | 文件 | 说明 |
|---|---|---|
| Windows x64 | clipsift-windows-x86_64.zip |
免安装版,解压即用 |
| Linux x64 | clipsift-linux-x86_64.tar.gz |
命令行 |
| macOS Apple Silicon | clipsift-macos-aarch64.tar.gz |
命令行 |
命令行用法
clipsift watch # 常驻后台,每次复制自动净化
clipsift once # 只净化一次剪贴板
clipsift --list-rules # 看有哪些规则详见 README。
验证过什么
cargo test59 个测试全过(core 30 / cli 9 / gui 13 / 属性测试 7)cargo clippy --all-targets -- -D warnings无警告,cargo fmt --check干净- 三个平台 CI 构建
- 端到端:一万条随机脏文本验证净化幂等(
apply(apply(x)) == apply(x))
v0.2.1
Windows:双击安装(推荐)
下载 ClipSift-setup.exe 双击,一路下一步就行。
装完直接能用,卸载去「设置 → 应用 → 已安装的应用」找 ClipSift。
或者在命令行里:
winget install soybeanmilka.ClipSift- 装到当前用户目录,不需要管理员权限,不弹 UAC
- 安装时可勾选「开机自动启动」「创建桌面快捷方式」
- 卸载干净:程序文件、开始菜单、桌面图标、自启项一起清掉
- 卸载时问一句要不要保留你的规则设置
其他方式
| 平台 | 文件 | 说明 |
|---|---|---|
| Windows x64 | clipsift-windows-x86_64.zip |
免安装版,解压即用 |
| Linux x64 | clipsift-linux-x86_64.tar.gz |
命令行 |
| macOS Apple Silicon | clipsift-macos-aarch64.tar.gz |
命令行 |
命令行用法
clipsift watch # 常驻后台,每次复制自动净化
clipsift once # 只净化一次剪贴板
clipsift --list-rules # 看有哪些规则这个版本验证过什么
从 Release 下载安装包回来,在本机完整跑了一遍:
- 静默安装退出码 0,安装目录、两个 exe、开始菜单、uninstaller 全部落地
clipsift --version报0.2.1- 含 U+200B / U+00A0 / 弯引号的测试文本,净化后可疑字符 0 个
- 静默卸载 1.5 秒完成,程序目录、开始菜单、桌面图标、注册表自启项全清
- 图形卸载:中文界面正常,问「要保留你的规则设置吗」,选「是」后配置文件确实留下
- winget 清单
winget validate通过,SHA256 与这份安装包一致
详见 README。
v0.2.0
从复制粘贴里筛掉隐形字符:零宽空格、伪空格、弯引号、全角字母。
解决飞书 / 网页 / AI 聊天复制代码报 stray '\342'、IndentationError、VLOOKUP 匹配不上的问题。
Windows 用户:省事版
下载 clipsift-windows-x86_64.zip,解压,双击 clipsift-gui.exe —— 完事。
打开就在净化,勾上「开机自启」以后不用管它。
下载
| 平台 | 文件 | 说明 |
|---|---|---|
| Windows x64 | clipsift-windows-x86_64.zip |
含 clipsift-gui.exe(图形界面)和 clipsift.exe(命令行) |
| Linux x64 | clipsift-linux-x86_64.tar.gz |
命令行 |
| macOS Apple Silicon | clipsift-macos-aarch64.tar.gz |
命令行;首次运行可能需 xattr -d com.apple.quarantine clipsift |
命令行用法
clipsift watch # 常驻后台,每次复制自动净化
clipsift once # 只净化一次剪贴板
clipsift --list-rules # 看有哪些规则
clipsift --merge # 把 PDF 那种硬换行还原成段落它治什么
| 场景 | 报错 | 真凶 |
|---|---|---|
| 网页复制 C++ | stray '\342' in program |
U+200B 零宽空格 |
| 飞书复制 Python | IndentationError |
缩进是 NBSP 不是空格 |
| Word 复制代码 | 满屏语法错误 | 全角标点 + 弯引号 |
| Excel 导出 CSV | VLOOKUP 匹配不上 |
单元格尾部有 U+00A0 |
按报错原文查 → 常见报错速查表
飞书场景详解 → 从飞书复制代码为什么老是报错
0.2.0 的改动
- 新增图形界面
clipsift-gui.exe:规则开关、实时预览、守护启停、开机自启、浅深色主题、内嵌中文字体 - 全角字符拆成两档:全角字母数字转半角(默认开),全角标点转半角(默认关,因为中文正文里那些标点本来就是对的)
- 可疑字符按危害排序:隐形字符排最前,其次是会引发语法错的全角运算符
- 关窗口不退出(收进任务栏继续守护),只有点「退出」才真退
- 无控制台弹窗(GUI 子系统编译)
MIT License
ClipSift 0.1.0 — 剪掉复制粘贴里的隐形字符
一句话
从复制粘贴里筛掉隐形字符——零宽空格、伪空格、弯引号、全角字母。
从飞书 / 钉钉文档 / Notion / AI 聊天窗口复制代码,编译报 stray '\342' in program、IndentationError、VLOOKUP 匹配不上?下载它。
安装
| 平台 | 下载 | 说明 |
|---|---|---|
| Windows x64 | clipsift-windows-x86_64.zip |
解压出 clipsift.exe,放进 PATH(如 C:\Users\<你>\.cargo\bin) |
| Linux x64 | clipsift-linux-x86_64.tar.gz |
tar -xzf 后 sudo mv clipsift /usr/local/bin/ |
| macOS Apple Silicon | clipsift-macos-aarch64.tar.gz |
tar -xzf 后 mv clipsift ~/.local/bin/(首次运行可能要 xattr -d com.apple.quarantine clipsift) |
装好后跑一次:
clipsift watch之后每次复制,剪贴板自动净化。单个可执行文件,无任何运行库依赖。
它治什么
| 你遇到的现象 | 真实原因 | ClipSift 怎么处理 |
|---|---|---|
C/C++ 编译报 error: stray '\342' in program |
行里混进了 U+200B 零宽空格 |
直接删掉 |
Python 复制后 IndentationError: unexpected indent |
缩进是 U+00A0 不间断空格 |
归一成 ASCII 空格,宽度不变 |
| 代码里满是语法错误 | 中文弯引号 + 全角标点 | 转成 ASCII |
Excel/ERP 导出的数据 VLOOKUP 匹配不上 |
单元格尾部有 U+00A0 |
归一成普通空格 |
命令行 command not found 但看着一模一样 |
复制了不间断空格当普通空格 | 归一成普通空格 |
| 源码里藏着看不见的指令 | U+E0000 Unicode Tag / bidi 覆盖符 |
删掉 |
边看边用
- 常见报错速查表——按报错原文索引,还解释了 GCC 为什么打八进制、
U+200B的E2 80 8B怎么变成\342 - 从飞书复制代码为什么老是报错
- 中文 README · English
常用命令
clipsift watch # 常驻后台,每次复制自动净化(最常用)
clipsift autostart enable # 开机自动守护,无窗口(免管理员权限)
clipsift once # 只净化当前剪贴板一次
clipsift -f dirty.txt # 净化文件
clipsift inspect < dirty.txt # 先看看脏在哪
clipsift --report < dirty.txt # 净化并给统计
clipsift --list-rules # 看所有规则
clipsift --off fullwidth # 关掉某条规则验证过的
- 41 个测试全绿,其中 7 个属性测试拿一万条随机脏文本验证幂等性
cargo clippy --all-targets -- -D warnings零警告- 文件级两次净化 SHA256 一致
- 剪贴板守护进程实测:复制带
U+200B+U+00A0的文本,2 秒内自动变干净 - 本 Release 的产物是从 GitHub 下载回来重新验证的:Windows exe 实跑净化 + 幂等 + 剪贴板,
Linux 包确认为 ELF 64 位,macOS 包确认为 Mach-O arm64
已知边界
- 剪贴板监听目前只支持 Windows。命令行净化(文件 / stdin)三个平台都能用。
--merge(合并硬回车)不是幂等的,按设计就是一次性变换,只适合把 PDF 正文摊平。默认关闭。- macOS 只有 Apple Silicon(arm64)版本。Intel Mac 请自行
cargo build --release。
许可
MIT

