Logo
Overview

mangowc 体验

kinntaku kinntaku
June 24, 2026
2 min read

前言

随着 wlroots 0.20 版本的发布, xdg-desktop-portal-wlr 终于拥有了原生的窗口共享协议 ext-image-capture-source-v1, 不用再使用 slurp 选择区域了, 新协议的效果是类似 xdg-desktop-portal-gnome 的真正窗口共享, 哪怕窗口不在屏幕内部或者被其他窗口所遮挡或者半透明依旧可以完整捕获, 但是在实际体验中依旧发现了一些问题, 此文章的目的就是记录配置 mangowc 时遇到的一些问题以及解决方案.

软件安装

由于 mangowc 的主线以及 release 线并没有合并 wlroots 0.20 的代码, 所以需要使用 wl-only 这个 branch 的代码, 对应 aur 中 mangowm-wlonly-git 包

Terminal window
paru -S mangowm-wlonly-git
sudo pacman -S xdg-desktop-portal xdg-desktop-portal-wlr xdg-desktop-portal-gtk

窗口共享

配置 mangowc 的 portal 配置

创建 ~/.config/xdg-desktop-portal/mango-portals.conf 文件, 写入

Terminal window
[preferred]
default=wlr;gtk
org.freedesktop.impl.portal.FileChooser=gtk
org.freedesktop.impl.portal.ScreenCast=wlr

新的 ext-image-capture-source-v1 协议选择窗口需要弹出一个菜单, 这个菜单可以使用支持 dmenu 协议的软件承载, 我这里使用的是 fuzzel

创建 ~/.config/xdg-desktop-portal-wlr/config 文件并写入

Terminal window
[screencast]
chooser_type=dmenu
chooser_cmd=fuzzel --dmenu --prompt="Select window/screen to share: "

由于此协议还在测试中, 目前不确定是 wayland 的问题还是 nvidia 驱动的问题, 笔记本设备在使用 obs 并添加了一个窗口捕获源的情况下, 直接进行挂起 suepend 操作后再唤醒后会导致 dbus 总线错误, 导致添加的捕获源失效, 重启 obs 也不好使, 并且会导致其他使用此协议捕获窗口的软件也会黑屏, 所以需要使用 systemd 创建 hook 重启必要服务

创建 /etc/systemd/system/restart-portals-after-suspend.service 文件, 写入

Terminal window
[Unit]
Description=Restart XDG Desktop Portals
After=suspend.target hybrid-sleep.target hibernate.target
[Service]
Type=oneshot
ExecStart=/usr/bin/systemctl --machine=你的用户名@.host --user restart xdg-desktop-portal.service xdg-desktop-portal-wlr.service pipewire wireplumber
[Install]
WantedBy=suspend.target hybrid-sleep.target hibernate.target

注意将 你的用户名 替换成你自己的用户名

注意, 由于需要使用 hiberate 的 hook, 所以必须使用系统级的 systemd 服务, 无法使用用户级别的 systemd 调用 hiberate 的 hook

启动服务

Terminal window
sudo systemctl start --now restart-portals-after-suspend

xwayland 相关

mangowc 同时支持 原版 xorg-xwayland 以及 xwayland-satellite, 本测试在意兼容性所以使用原版 xorg-xwayland

目前存在的问题是笔记本设备在使用 nvidia 独显输出的 dp 接口连接显示器的时候在外置显示器开启使用 xwayland 的软件后并保留软件在渲染区域内直接进行 suspend 在唤醒后会导致软件崩溃或者卡死, 目前测试可复现的软件有 wechat-bin 以及 wps-office (怎么总是你俩)

解决方法如下

由于问题触发条件如下

  • 外接屏幕是 n 卡输出

  • 软件运行在外接屏幕上

  • 软件在外接屏幕渲染区域内 (就是能在屏幕上看见, 在外接显示器其他工作区的软件不会被触发)

  • 软件使用 xwayland (其实只有 wechat 和 wps 会这样)

所以我们只需要一个 hook 在休眠前关闭外接显示器, 在恢复后再打开就可以了, wlroots 系列的合成器会自动帮我们完成窗口的转移与恢复的过程, 既关闭显示器后软件移动到内置显示器, 再打开后自动移动到外部显示器上

这里使用 swayidlde , 也可以直接使用 systemd 服务

修改 mango 配置文件的 swayide 启动为

Terminal window
exec-once=swayidle -w before-sleep "wlr-randr --output DP-4 --off; swaylock -f" after-resume "sleep 2 && wlr-randr --output DP-4 --on"

其他问题

  1. mango 和 tty 之间相互切换的时候有概率遇到 dma 错误导致 mango崩溃

    • 100% 触发情况:

      当 login manager 和 内核日志输入所在的 tty 不同, 切换到内核日志输出的 tty

      所以使用 tuigreet 将 login manager 和 greeter 页面分离的用户建议直接换 regreet 或者直接关掉内核日志输出

    • 概率触发情况

      开启 obs 并选择 dp 输出显示器捕获的情况下, 切换到其他 tty 再切回 mango

概率触发情况解决方案:

启用 nvidia 相关休眠服务

Terminal window
sudo systemctl enable --now nvidia-hibernate.service
sudo systemctl enable --now nvidia-resume.service
sudo systemctl enable --now nvidia-suspend.service
sudo systemctl enable --now nvidia-suspend-then-hibernate.service
sudo systemctl enable --now nvidia-persistenced.service

添加内核参数

Terminal window
nvidia_drm.modeset=1 NVreg_PreserveVideoMemoryAllocations=1

重新生成引导(以limine为例)

Terminal window
limine update
  1. 使用 wlr-randr 关闭所有显示器的情况下会导致 mango 崩溃

解决办法: 启动回话的时候就利用 mango 自带的功能开启一个虚拟显示器

Terminal window
exec-once=mmsg dispatch create_virtual_output
  1. 腾讯会议无法共享屏幕
  • 修改打包方式(不一定有用, 可选):

    bwrap 封装脚本中移除 —unshare-pid

    原理: 这导致最新版腾讯会议在 Wayland 下通过 PipeWire 和 xdg-desktop-portal 申请投屏时,主机的 portal 守护进程由于 PID 命名空间隔离无法反查客户端凭证,进而导致点击“共享屏幕”按钮没有任何反应。

  • 打 patch, 参考

    wemeet-screenshare-patch

n 卡视频黑屏:

为腾讯会议单独设置 __EGL_VENDOR_LIBRARY_FILENAMES=/usr/share/glvnd/egl_vendor.d/50_mesa.json 环境变量(不要全局设置该变量!)