You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

Ubuntu(X11/Wayland)桌面OTP应用窗口防屏幕捕获的编程实现

Ubuntu实时桌面OTP应用屏幕捕获豁免方案指南

我正在Ubuntu上开发一款实时桌面OTP应用,需确保OTP窗口在屏幕共享(Chrome、Zoom、OBS、Discord等)时绝不被捕获,即使用户共享整个屏幕。该应用窗口始终置顶于角落,持续刷新六位验证码。

现代Ubuntu采用PipeWire + xdg-desktop-portal实现屏幕捕获,在X11与Wayland环境下表现不同。我期望找到可靠方法将窗口标记为「屏幕捕获豁免」,同时保持窗口可见、可交互且受窗口管理器正常管理。

以下是针对具体问题的解答:

1. EWMH的_NET_WM_STATE_SKIP_CAPTURE原子在PipeWire/xdg-desktop-portal及主流屏幕共享应用中是否可靠?是否已废弃或依赖 compositor?

_NET_WM_STATE_SKIP_CAPTURE是EWMH标准中专门用于标记窗口不被屏幕捕获的属性,在X11环境下的PipeWire/xdg-desktop-portal实现中是可靠的,Chrome、Zoom、OBS、Discord等主流捕获工具都会尊重这个属性。它并未被废弃,但完全依赖 compositor 的支持——大部分现代X11 compositor(如GNOME Shell、KWin)都兼容,但老旧或小众 compositor 可能存在兼容性问题。需要注意的是,该原子在Wayland环境下完全不适用,因为Wayland不兼容EWMH规范。

2. 在X11环境下,设置override_redirect=true或使用xprop/窗口提示能否可靠排除窗口被捕获?存在哪些UX、焦点或窗口管理器集成方面的权衡?

  • override_redirect=true:确实能让窗口脱离窗口管理器控制,从而不被大多数屏幕捕获工具捕获,但代价极高:
    • UX层面:窗口无法被置顶、最小化、拖拽移动(需自行实现),也不会出现在任务栏或Alt+Tab切换列表中
    • 焦点问题:无法正常获取键盘焦点,无法接收快捷键输入
    • 集成问题:不支持窗口管理器的动画、阴影等系统风格效果,与系统UI脱节
  • xprop设置_NET_WM_STATE_SKIP_CAPTURE:这是更友好的方案,执行命令:
    xprop -f _NET_WM_STATE 32a -set _NET_WM_STATE _NET_WM_STATE_SKIP_CAPTURE
    
    这种方式下窗口仍受窗口管理器正常管理,没有上述权衡,但仅在X11环境生效。

3. 在Wayland环境下,是否有官方portal、DBus API或 compositor 专属提示可标记窗口为私密/敏感?或是因Wayland安全模型,窗口级捕获排除被刻意禁止?

Wayland的安全模型设计上禁止应用直接控制捕获行为,目前没有官方的xdg-desktop-portal API或标准方法标记单个窗口为捕获豁免。部分 compositor 有专属实现,但跨环境不通用:

  • GNOME Shell:可通过第三方扩展实现,但不属于官方支持的API,稳定性无法保障
  • KWin:提供org.kde.kwin.WindowRules DBus接口,可设置窗口的skipCapture规则,但仅适用于KDE环境

核心原因是Wayland的捕获机制基于 compositor 全局或桌面区域选择,应用无法主动排除自己——这是为了防止恶意应用规避监控,但对合法OTP应用造成了限制。

4. 对于GTK/Qt应用,是否存在框架级函数间接影响捕获行为(如窗口类型提示、模态标记、透明层)?

有一些框架级设置可以间接降低被捕获的概率,但并非专门的捕获豁免手段,可靠性不足:

  • GTK
    • 将窗口类型设置为GTK_WINDOW_TYPE_POPUPGTK_WINDOW_TYPE_TOOLTIP,部分捕获工具可能忽略这类临时窗口,但不是所有工具都支持
    • 使用gtk_window_set_skip_taskbar_hint()gtk_window_set_skip_pager_hint(),仅隐藏任务栏显示,不影响捕获
  • Qt
    • 设置窗口标志Qt::PopupQt::ToolTip,同理,部分捕获工具可能跳过,但不可靠
    • 使用QWidget::setWindowOpacity()设置透明,仅为视觉效果,窗口仍会被捕获

这些方法只能作为辅助手段,不能完全依赖来实现捕获豁免。

5. 若跨会话无法实现可靠的编程式排除,Linux下OTP/密码应用的推荐 fallback 方案或安全最佳实践是什么?

推荐的 fallback 方案及安全实践包括:

  • 剪贴板自动清空:复制OTP后,在3-5秒内自动清空剪贴板,避免被恶意应用读取
  • 安全显示限制:禁止选中复制OTP内容,显示时禁用系统截图快捷键(需额外权限)
  • 用户教育:提示用户在屏幕共享前关闭OTP窗口,或使用系统自带的隐私过滤功能(如GNOME屏幕共享的隐私模式)
  • 可选X11模式:允许用户切换到X11会话运行应用,确保捕获豁免机制生效
  • 硬件级替代:引导用户使用YubiKey等硬件密钥生成OTP,完全脱离屏幕显示环节

6. 若上述方案均不可行,如何重新编译xdg-desktop-portal及必要工具以排除我的应用?

如果必须通过修改系统组件实现,步骤如下:

  1. 获取xdg-desktop-portal源码:
    git clone https://gitlab.freedesktop.org/xdg/xdg-desktop-portal.git
    
  2. 修改src/screen-cast.c中的捕获逻辑:在窗口枚举的代码段中,添加对应用窗口类名(WM_CLASS)或PID的检查,匹配则跳过该窗口的捕获
  3. 编译并安装修改后的版本:
    meson build
    ninja -C build
    sudo ninja -C build install
    
  4. 重启xdg-desktop-portal服务:
    systemctl restart --user xdg-desktop-portal
    

注意:这种方式需要用户具备系统编译权限,且系统更新会覆盖修改,仅适合自用或小众场景,不适合分发应用。

内容的提问来源于stack exchange,提问作者Maifee Ul Asad

火山引擎 最新活动