BOB CHEN

NEW POST  ·  2026-07-14

INPUT
TRAP

LOG FILE / SAVE 007

Snipaste 在 KDE Wayland 上翻车:一个全屏窗口按住了整个桌面

我用 Snipaste 很久了。喜欢它的理由很简单:常驻后台,快捷键一按,截图界面立刻出来。没有启动过程,也不用先想该开哪个模式。这套操作已经成了习惯,所以换到 KDE 以后,我还是把 Snipaste 装了回来。

KDE 自带的 Spectacle 不是不能用,功能也够。只是从按下快捷键到真正开始截,总觉得比 Snipaste 慢半拍。可能差距没有多大,但手已经被惯坏了。

这次翻车也很突然。本来只是在修 Firefox 粘贴图片的问题,按了几次截图快捷键,桌面先多出五张一模一样的整屏截图。紧接着 KDE 进入一种很奇怪的半死状态:画面还在,鼠标指针也能动,但窗口拖不了,点击没反应,MetaAlt + Tab 全部失效。

从外面看就像 Plasma 或 KWin 崩了。最后查出来,它俩没崩。Snipaste 留了一个透明的全屏截图窗口,安安静静盖在最上面,把所有输入都吃了。

我的环境是 Debian 13、KDE Plasma 6 Wayland,Snipaste 2.11.3 用 AppImage 运行。桌面还是通过 Sunshine 串流的,这让后面的抢救过程又多绕了一个大弯。

先是桌面多了五张图

五张图在不到 0.2 秒内生成,尺寸、大小完全相同。跑一下哈希,五份结果也是同一个:

检查五张截图是否相同SHELL
sha256sum ~/桌面/Snipaste_2026-07-14_13-15-27*.png
五张图的哈希一致OUTPUT
e77dd74e...  Snipaste_2026-07-14_13-15-27.png
e77dd74e...  Snipaste_2026-07-14_13-15-27_0.png
e77dd74e...  Snipaste_2026-07-14_13-15-27_1.png
e77dd74e...  Snipaste_2026-07-14_13-15-27_2.png
e77dd74e...  Snipaste_2026-07-14_13-15-27_3.png

我一开始怀疑是 SyncClipboard。前面刚动过 Firefox 图片剪贴板的处理,怎么看都像是“修好一个,又修坏一个”。继续对日志以后,才看到同一个 snip -o clipboard 命令约每 40 毫秒触发一次。

第一次触发进入截图界面,后面几次连发被它当成“快速保存整屏”,于是桌面上整整齐齐落了五张图。SyncClipboard 当时没有对应事件,这口锅确实不归它。

桌面没崩,是选区窗口没退

更大的问题不是五张图,而是截图界面没有正常退掉。

当时的现象很有迷惑性:画面能持续输出,鼠标和键盘设备也没有断,指针甚至能正常移动。只有点击、拖窗和全局快捷键全部没反应。这个组合不像桌面进程挂了,更像有个全屏窗口正在独占输入。

Snipaste 跑在 XWayland 下,可以直接看窗口树:

查找 Snipaste 顶层窗口SHELL
DISPLAY=:0 xwininfo -root -tree | rg -i 'Snipaste|Snipper'

结果里躺着这个玩意:

覆盖整个屏幕的选区窗口OUTPUT
0x1800010 "Snipper - Snipaste":
  ("Snipaste" "Snipaste") 1920x1080+0+0

显示器正好也是 1920×1080。这不是“小窗口卡住”,而是 Snipaste 的选区窗口完整盖住了桌面。KWin 还在合成,Plasma 也还活着,只是我的每一次点击和按键都先撞到它身上。

所以严格来说,Snipaste 没把 KDE 进程搞崩。只是这个全屏窗口没退,桌面看起来还活着,实际上什么都操作不了。体感和崩了也差不多。

Ctrl + Alt + F1 以后,为什么切不回桌面

在没找到这个全屏窗口之前,我按了 Ctrl + Alt + F1,想进 TTY 救桌面。串流画面确实切到了命令行,接下来却怎么都回不去。

最省事的处理当然是重启,或者注销 KDE 会话。但那时 Codex 和 Claude Code 都还在干活,我不想为了一个截图窗口把两个正在跑的任务一起干掉,也不想赌重新登录以后现场还能不能接上。

桌面操作不了,Moonlight 又只剩一个终端画面。我只好拿手机 SSH 连回这台机器,继续查进程、切 VT、重启 Sunshine。一个截图工具留下的全屏窗口,最后靠手机远程修电脑,多少有点绕。

我先以为只是 KDE 所在的功能键没找对,于是从 F2F3 一路试。试到 Ctrl + Alt + F4 时还出了个很蠢的插曲:这套组合键是从 Windows 的 Moonlight 客户端发出去的,Windows 先认出了里面的 Alt + F4,直接把 Moonlight 关了。重新连接,画面仍然是命令行。等于桌面没救回来,串流客户端先没了。

后面确认 KDE 会话一直在 tty2,Plasma 和 KWin 也都活着。无论按 Ctrl + Alt + F2,还是执行下面这条命令,系统都显示已经成功切回图形会话:

切回 KDE 所在的虚拟终端SHELL
sudo chvt 2

但 Sunshine 仍在输出 tty1 的终端画面。问题不在“切换命令没生效”,而在显卡的控制权没有交回来。

KDE Wayland 下,KWin 需要持有 DRM master 才能把桌面画面提交给显卡。切到 tty1 时,图形会话暂停,KWin 会暂时放开设备;Sunshine 又正好直接打开 /dev/dri/card0 做 KMS 采集,于是它成了新的 DRM master。再切回 tty2 时,logind 已经把 KDE 会话标记为 active,KWin 却拿不回显卡,原子提交一直报权限不足。

当时查到的状态大致是这样:

DRM 客户端状态OUTPUT
KDE session: active, tty2
sunshine:     master=y
kwin_wayland: master=n

所以桌面进程从头到尾都没退出,真正卡住的是最后一步:KWin 已经醒了,但它画的 framebuffer 没法重新挂到显示平面上。Sunshine 继续采集显卡里残留的 fbcon,Moonlight 看到的自然一直是命令行。

手机 SSH 里最后跑的是这组命令:

不注销 KDE,重新交接 DRM masterSHELL
systemctl --user stop app-dev.lizardbyte.app.Sunshine.service
sudo chvt 1
sleep 3
sudo chvt 2
systemctl --user start app-dev.lizardbyte.app.Sunshine.service

关键不是单独执行一次 chvt 2,而是先停掉 Sunshine,再完整走一遍 tty1 → tty2。KWin 重新拿到 DRM master 以后,才启动 Sunshine。串流画面终于回到 KDE,窗口却依然拖不了,这才确认原来的输入问题一直都在,来源还是 Snipaste 的全屏选区窗口。

这一段必须分清:Snipaste 导致的是输入被全屏窗口拦截;Sunshine 抢 DRM master,是我切 TTY 自救时触发的第二场事故。两个问题叠在一起,才显得像整个桌面彻底炸了。

后来我又试了一次 Ctrl + Alt + F3,同样切不回来。靠命令抢救一次可以,次次拿手机 SSH 修就没意思了。最后把 Sunshine 的抓屏方式改成了 KWin ScreenCast:

~/.config/sunshine/sunshine.confINI
# 使用 KWin ScreenCast
capture = kwin

重启 Sunshine 后,抓屏链路变成 KWin ScreenCast → PipeWire → Sunshine。Sunshine 不再直接接管 DRM master,从其他 TTY 按 Ctrl + Alt + F2 返回时,KWin 可以正常恢复桌面和串流。

但这不算完美解决。切到 tty3 以后,Moonlight 不会显示终端,只会停在 KDE 的最后一帧,因为 KWin ScreenCast 只能抓到 KWin 合成的桌面。按 Ctrl + Alt + F2 回来,画面会继续更新。它只是用“看不到 TTY”换来了“能正常回桌面”。

真想两边都要,还得 Sunshine 自己改进 KMS 抓屏:需要在切换 VT 时正确释放和重新交接 DRM master,让 Moonlight 既能看到 Linux TTY,又不挡着 KWin 恢复显示。这不是改一行配置就能补好的,还是得等 Sunshine 做出努力。

关掉全屏窗口,桌面当场复活

窗口 ID 已经找到了,直接结束创建它的 Snipaste 进程:

关闭卡住的全屏选区窗口SHELL
DISPLAY=:0 xkill -id 0x1800010

再查一次窗口树,Snipper - Snipaste 已经消失。拖窗、点击、MetaAlt + Tab 也立刻恢复。KWin 的活动效果里只剩正常的 blurcontrast,没有残留截图抓取。

这算是最小损失的处理,没有重启 KWin,没有注销 Plasma,也没有关掉桌面上其他程序。

AppImage 和 KDE 会话恢复留下的尾巴

我把 Snipaste 文件扔进回收站以后,后台还活着一个 AppImage 启动器。系统里留下的桌面入口指向了这个位置:

Snipaste 自动生成的桌面入口INI
Exec="/tmp/.mount_SnipasqNTSmH/usr/bin/Snipaste"

KDE 的会话恢复里还有另一条同类记录:

~/.config/ksmserverrcINI
program1=/tmp/.mount_Snipas8pecG5/usr/bin/Snipaste

/tmp/.mount_Snipas... 是 AppImage 每次运行时创建的临时挂载目录,后面的随机串会变。这个机制本身很正常,AppImage 就是这样把程序挂载起来再运行。问题是桌面入口和 KDE 会话恢复记住了里面的可执行文件,而不是原来的 AppImage。注销或重启以后,这条路径自然就失效了。

这部分更像 AppImage、XWayland 和 KDE 会话恢复碰到一起后的兼容问题,没必要全算在 Snipaste 头上。最后我还是把 AppImage、残留进程、自动启动项和菜单入口清掉了,先换回 Spectacle。

以后在 KDE Wayland 下再碰到“指针能动,但所有窗口都点不了”,先别急着重启桌面。查一下顶层窗口有没有截图工具留下的全屏覆盖层:

排查截图工具的全屏覆盖层SHELL
DISPLAY=:0 xwininfo -root -tree \
  | rg -i 'Snipaste|Snipper|Screenshot|Spectacle'

这次看着像 KDE 崩了,其实是两个问题叠在一起:Snipaste 的选区窗口盖住桌面,切 TTY 自救时又撞上 Sunshine 的 KMS 抓屏问题。

这篇也不是什么标准解决方案,只是把当天的折腾和踩到的坑记下来。目前 Snipaste 换成了 Spectacle,Sunshine 暂时用 capture = kwin 绕开 DRM master 冲突。以后软件更新了,结果可能又不一样。

不过说到底也只是一个截图工具。能用就用,不能用拉倒。