切换到 KDE Plasma Wayland 后,有时会遇到这样一种现象:每次登录桌面,系统都会自动弹出一个屏幕共享选择窗口,要求选择显示器,并显示类似以下名称:
xdg-desktop-portal-kde
org.freedesktop.impl.portal.desktop.kde
窗口底部还可能出现:
Allow restoring on future sessions
乍看之下,很容易怀疑 KDE Portal、PipeWire 或 Wayland 配置出现了问题。但在这次排查中,真正的问题并不在 KDE,而是一个基于 Electron 的聊天客户端在启动时错误地申请了屏幕捕获权限。
本文记录完整的判断过程、定位方法以及最终解决方案。
一、现象:切换到 Wayland 后,每次开机都要求共享屏幕
系统环境大致如下:
- Linux 桌面系统
- KDE Plasma
- 显示协议由 X11 切换为 Wayland
- 登录桌面后自动启动若干应用
- 每次登录都会出现屏幕共享授权窗口
窗口要求用户选择:
- Laptop screen
- 某个外接显示器
- 某个应用窗口
即使完全没有进行视频会议、录屏或远程桌面操作,这个窗口仍然会自动出现。
这种现象通常说明:
某个登录自启动应用,在启动过程中调用了 Wayland 的屏幕捕获接口。
二、为什么切换到 Wayland 后才出现
X11 和 Wayland 对屏幕内容访问的安全模型完全不同。
X11 的方式
在传统 X11 环境中,桌面应用通常可以直接读取屏幕内容。录屏软件、截图工具、远程桌面和视频会议程序不一定需要经过系统级授权。
这也意味着,理论上任何连接到 X Server 的程序都可能读取其他窗口内容。
Wayland 的方式
Wayland 不允许普通应用随意读取整个屏幕。
应用如果需要:
- 录制屏幕
- 共享屏幕
- 远程控制
- 获取显示器画面
- 创建 WebRTC 屏幕流
通常必须通过以下组件:
应用
↓
xdg-desktop-portal
↓
xdg-desktop-portal-kde
↓
PipeWire
↓
KDE 屏幕共享授权窗口
因此,切换到 Wayland 后首次看到这种窗口,本身并不异常。
异常之处在于:
没有主动进行屏幕共享,但窗口却在每次登录时自动出现。
这说明某个程序在启动时主动发起了 ScreenCast 或 RemoteDesktop 请求。
三、xdg-desktop-portal-kde 不是罪魁祸首
屏幕共享窗口中出现的名称通常包括:
xdg-desktop-portal-kde
以及:
org.freedesktop.impl.portal.desktop.kde
这两个名称分别对应:
- KDE 的 XDG Desktop Portal 后端程序
- 该后端在 D-Bus 上注册的服务名称
它们的作用是:
- 接收应用发出的屏幕共享请求;
- 显示由桌面环境控制的授权窗口;
- 将用户选择的屏幕或窗口通过 PipeWire 提供给申请程序。
因此,Portal 是窗口的显示者,但通常不是请求的发起者。
可以将它理解为操作系统的权限管理器:
门卫负责显示授权窗口,但真正敲门的是其他应用。
所以不应该因为看到 xdg-desktop-portal-kde,就直接禁用或删除它。
禁用 KDE Portal 可能导致以下功能失效:
- Spectacle 截图和录屏
- 浏览器屏幕共享
- 视频会议软件
- OBS Wayland 捕获
- 远程桌面
- Flatpak 文件选择窗口
- 部分沙盒应用的系统集成
正确做法是定位真正的调用者。
四、通过 D-Bus 请求路径查找申请程序
当屏幕共享窗口保持打开时,XDG Portal 通常会创建一个活动请求对象,其路径格式类似:
/org/freedesktop/portal/desktop/request/1_98/webrtc850831072
其中:
1_98
对应 D-Bus 唯一连接名:
:1.98
通过这个连接名,可以进一步查询对应的进程 PID。
自动定位脚本
保持屏幕共享窗口打开,然后在终端中运行:
req="$(
busctl --user tree org.freedesktop.portal.Desktop --no-pager 2>/dev/null |
grep -o '/org/freedesktop/portal/desktop/request/[^[:space:]]*' |
head -n1
)"
if [[ -z "$req" ]]; then
echo "没有找到活动的 Portal 请求。"
echo "请保持屏幕共享窗口打开后重新运行。"
exit 1
fi
caller="${req#*/request/}"
caller="${caller%%/*}"
sender=":${caller//_/.}"
pid="$(
busctl --user call \
org.freedesktop.DBus \
/org/freedesktop/DBus \
org.freedesktop.DBus \
GetConnectionUnixProcessID \
s "$sender" 2>/dev/null |
awk '{print $2}'
)"
echo "Portal 请求路径:$req"
echo "D-Bus 请求者:$sender"
echo "PID:$pid"
echo
echo "程序文件:"
readlink -f "/proc/$pid/exe"
echo
echo "启动命令:"
tr '\0' ' ' < "/proc/$pid/cmdline"
echo
echo
echo "所属 cgroup:"
cat "/proc/$pid/cgroup"
这个脚本完成了四件事:
- 查找活动的 Portal 请求;
- 从请求路径提取 D-Bus 调用者;
- 根据 D-Bus 名称反查 PID;
- 根据 PID 查找可执行文件和完整启动命令。
五、定位结果:Rocket.Chat Desktop
最终获得的信息类似:
Portal 请求路径:
/org/freedesktop/portal/desktop/request/1_98/webrtc850831072
D-Bus 请求者:
:1.98
PID:
1637
程序文件:
/opt/Rocket.Chat/rocketchat-desktop.bin
启动命令:
/opt/Rocket.Chat/rocketchat-desktop.bin
这说明真正发起屏幕共享请求的是:
Rocket.Chat Desktop
而不是:
xdg-desktop-portal-kde
也不是 KDE Plasma、PipeWire 或 Wayland 本身。
六、为什么 cgroup 中显示 Chromium
进程所属 cgroup 可能显示为:
app-org.chromium.Chromium-1637.scope
这可能再次引起误解,让人怀疑 Chromium 浏览器在请求屏幕共享。
但 Rocket.Chat Desktop 是一个 Electron 应用。
Electron 的底层由以下组件组成:
- Chromium
- Node.js
- 桌面应用封装层
因此,Electron 应用在进程、窗口类、沙盒和 systemd scope 中,经常表现出 Chromium 的特征。
类似情况也常见于:
- Discord
- Slack
- Microsoft Teams
- Visual Studio Code
- Obsidian
- Chatbox
- 各类 Electron 聊天客户端
所以:
app-org.chromium.Chromium-xxxx.scope
并不一定代表真正的 Chromium 浏览器。
判断时应优先查看:
readlink -f /proc/PID/exe
以及:
tr '\0' ' ' < /proc/PID/cmdline
这两个位置更能准确反映实际程序。
七、检查已安装版本
确认问题程序后,需要检查当前安装的软件包和版本。
先查询可执行文件属于哪个包:
pacman -Qo /opt/Rocket.Chat/rocketchat-desktop.bin
结果类似:
/opt/Rocket.Chat/rocketchat-desktop.bin is owned by rocketchat-client-bin
可以进一步自动提取包名:
pkg="$(
pacman -Qo /opt/Rocket.Chat/rocketchat-desktop.bin |
awk '{print $5}'
)"
echo "软件包:$pkg"
然后查询版本:
pacman -Qi "$pkg" |
grep -E '^(Name|Version)'
当时的版本为:
Name : rocketchat-client-bin
Version : 4.14.1-1
这是一个 AUR 安装的软件包。
使用以下命令也能看到它:
yay -Qm
不过需要注意:
yay -Qm
只负责列出“非官方仓库软件包”,并不能判断这些软件包是否存在更新。
八、真正的解决方案:升级 Rocket.Chat Desktop
问题最终通过升级 Rocket.Chat Desktop 解决。
可以先检查远程软件包版本:
yay -Si rocketchat-client-bin |
grep -E '^(Name|Version|Out Of Date|Last Modified)'
然后执行更新:
yay -S rocketchat-client-bin
或者在正常进行完整系统升级时执行:
yay -Syu
升级完成后确认版本:
pacman -Qi rocketchat-client-bin |
grep -E '^(Name|Version)'
更新后不需要立即进行专门测试。
等下一次正常登录 Wayland 桌面时观察即可:
- 如果屏幕共享窗口不再出现,说明问题已经解决;
- 如果仍然出现,可以再次使用 D-Bus 方法确认请求者是否仍为 Rocket.Chat;
- 如果请求者已经变化,则说明还有其他自启动应用也在申请屏幕捕获。
九、为什么不建议通过“永久允许”绕过问题
窗口底部的选项:
Allow restoring on future sessions
并不意味着“以后不再显示这个窗口”。
它的作用更接近于:
允许申请程序保存一个恢复令牌,并在未来尝试恢复同一个屏幕共享会话。
是否能够真正无提示恢复,还取决于:
- 应用是否正确保存恢复令牌;
- 应用是否在下一次启动时重新使用令牌;
- Portal 后端是否允许当前恢复模式;
- 桌面环境的安全策略;
- 应用申请的持久化级别。
更重要的是,在不知道哪个程序申请屏幕权限时,不应该轻易授权。
屏幕共享权限意味着程序可能获得:
- 当前显示器的完整内容
- 正在输入的信息
- 浏览器页面
- 聊天内容
- 文件管理器内容
- 终端窗口
- 密码管理器界面
因此,正确处理方式不是盲目勾选“以后恢复”,而是先确认申请者身份。
十、为什么不应该修改 KDE Portal
遇到这种情况时,一些常见但不正确的处理方式包括:
systemctl --user disable xdg-desktop-portal-kde
或者直接删除相关软件包:
sudo pacman -R xdg-desktop-portal-kde
还有人可能尝试删除 Portal 缓存、禁用 PipeWire,甚至回退到 X11。
这些操作都没有解决真正的问题。
本次排查已经证明:
- Portal 正常接收请求;
- KDE 正常显示授权窗口;
- PipeWire 屏幕捕获链路正常;
- Wayland 安全机制正常工作;
- 真正异常的是应用在不恰当的时机申请了屏幕捕获。
换句话说:
授权窗口的出现,反而证明 Wayland 的权限隔离正在正常工作。
如果仍处于 X11 环境,同一个程序可能直接访问屏幕,而不会出现明显提示。
十一、可以顺便检查哪些自启动位置
如果升级后问题仍然存在,可以检查程序是通过什么方式自动启动的。
KDE 自动启动目录
ls -la ~/.config/autostart/
系统级自动启动目录
ls -la /etc/xdg/autostart/
systemd 用户服务
systemctl --user list-unit-files --state=enabled
当前用户图形会话中的应用 scope
systemctl --user list-units --type=scope
查看 Rocket.Chat 相关项目
grep -Ril 'Rocket.Chat\|rocketchat' \
~/.config/autostart \
~/.config/systemd/user \
/etc/xdg/autostart \
2>/dev/null
不过,如果应用本身需要日常使用,通常没有必要直接关闭它的自启动。
升级到修复该问题的版本,比禁止自动启动更合理。
十二、通用排障思路
这次问题可以总结为一个适用于 Wayland 桌面的通用排障流程。
第一步:不要根据窗口标题判断请求者
看到:
xdg-desktop-portal-kde
只能说明 KDE Portal 显示了窗口,不能说明 Portal 自己发起了请求。
第二步:保持授权窗口打开
窗口关闭后,请求对象可能立即消失,导致无法继续追踪。
第三步:查找 Portal 请求路径
busctl --user tree org.freedesktop.portal.Desktop
第四步:从请求路径恢复 D-Bus 名称
例如:
1_98
转换为:
:1.98
第五步:根据 D-Bus 名称反查 PID
busctl --user call \
org.freedesktop.DBus \
/org/freedesktop/DBus \
org.freedesktop.DBus \
GetConnectionUnixProcessID \
s ':1.98'
第六步:检查实际可执行文件
readlink -f /proc/PID/exe
第七步:检查软件版本
pacman -Qo /path/to/executable
pacman -Qi package-name
第八步:优先升级问题应用
不要首先破坏 Wayland、Portal 或 PipeWire 的正常功能。
十三、结论
这次开机自动弹出的屏幕共享窗口,并不是 KDE Wayland 配置错误,而是 Rocket.Chat Desktop 旧版本在启动时错误地发起了 WebRTC 屏幕捕获请求。
完整因果关系如下:
Rocket.Chat Desktop 自动启动
↓
Electron/Chromium 初始化屏幕捕获功能
↓
调用 XDG Desktop Portal ScreenCast 接口
↓
xdg-desktop-portal-kde 接收请求
↓
KDE 显示屏幕共享授权窗口
最终处理方式是:
定位 D-Bus 请求者
↓
确认进程为 Rocket.Chat Desktop
↓
确认已安装版本较旧
↓
通过 AUR 升级 rocketchat-client-bin
这次排查最重要的经验是:
Wayland 下突然出现权限窗口时,不要急着修改桌面环境。先找出真正发起请求的应用,再处理应用本身。
从安全角度看,Wayland 显示授权窗口并不是故障,而是一种保护。真正需要修复的是那个在错误时间申请权限的程序。