Upgrade to GNOME 42 and Switch To Wayland (updated)

Upgrade to GNOME 42 and Switch To Wayland (updated)

我能说我这么多年用 N 卡一直是在跑 X11 么?

今天终于能换 Wayland 了

OS: Arch Linux x86_64

Kernel: 5.17.1-arch1-1

Card: GeForce GTX 1060

Resolution: 3840x2160

DE: GNOME 42.0

WM: Mutter

背景

Wayland 的支持看上去已经较为完善了.

比如近期 Ubuntu 和 Fedora 都会在 4 月份发布的新版本中默认对于 Nvidia 510版本以上的驱动 使用 Wayland:

Ubuntu 22.04 LTS Will Default To Wayland With NVIDIA For v510+ Driver

Fedora Linux 36 changed to Wayland By Default with NVIDIA proprietary Driver

注意: 之所以有"Nvidia 510版本以上的驱动"这个限制, 一是因为 510 之前这个驱动对于 Wayland 支持有问题. 二是因为, 对于其它驱动, 其实 Fedora 早在 Fedora 25 就已经是默认 Wayland 了.

see https://fedoraproject.org/wiki/Changes/WaylandByDefaultOnNVIDIA#Benefit_to_Fedora

Fedora has changed to Wayland by default since Fedora 22, but the NVIDIA proprietary driver has been an exception ever since (either because originally Wayland would be disabled with NVIDIA drivers, or more recently Xorg would be used by default).

另外还有 Fedora 吐槽 NVIDIA 专属驱动: Fedora Project Leader Calls Out NVIDIA Over Their Proprietary Linux Drivers

我们看下 Arch 上面的进度:

2个月前: 有第三方构建了 GNOME unstable

10天前: hitting Arch Linux gnome-unstable repo

5天前: GNOME 42 已经进入 Arch testing 仓库了

2天前: Gnome 42 is here! Check out Extra Repo

事实上我是2天之前得知消息的当天就升级到了 GNOME 42, 同时我的机器都是Nvidia显卡的, 因此同时也切换到了 Wayland.

升级到GNOME 42, 本身没有什么大问题. 主要的问题来自于当前一些应用对于 Wayland 的支持程度(部分需要添加额外的flags), 有一些甚至完全不支持(只能跑在xwayland下面).

本文主要分享一下踩过的坑及一些解决办法.

升级操作

升级本身没有什么特别要注意的. 直接 paru 就好了.

注意安装 wayland 支持

paru -S --needed glfw-wayland xorg-xwayland wayland-utils qt6-wayland qt5-wayland

锁屏解锁问题

注意升级后去 https://extensions.gnome.org/local/ 升级所有能升级的 extensions.

https://extensions.gnome.org/extension/2935/control-blur-effect-on-lock-screen/ 如果安装了这个插件要卸载掉. 会有一定概率导致锁屏后无法登录回原来的会话. 具体的问题是: 锁屏, 然后解锁, 在输入密码框你准备输入密码的时候, GNOME 把所有当前会话启动的进程杀死, 然后 GDM 重启, 退回到登录界面, 这个时候你再进去, 已经跟重启登录没两样了, 进程都被杀死了.

可以启用 gdm debug 看到更详细的过程, 编辑 /etc/gdm/custom.conf 启用 Enable=true:

[debug]
# Uncomment the line below to turn on debugging
Enable=true

重启 gdm 生效.

休眠问题

休眠功能是有问题的. 必须禁用.

检查一下界面展示的配置 ( Settings - Power ) 和 实际的配置是不是一致:

❯ gsettings list-recursively org.gnome.settings-daemon.plugins.power
org.gnome.settings-daemon.plugins.power ambient-enabled true
org.gnome.settings-daemon.plugins.power idle-brightness 30
org.gnome.settings-daemon.plugins.power idle-dim true
org.gnome.settings-daemon.plugins.power power-button-action 'nothing'
org.gnome.settings-daemon.plugins.power power-saver-profile-on-low-battery true
org.gnome.settings-daemon.plugins.power sleep-inactive-ac-timeout 7200
org.gnome.settings-daemon.plugins.power sleep-inactive-ac-type 'nothing'
org.gnome.settings-daemon.plugins.power sleep-inactive-battery-timeout 1200
org.gnome.settings-daemon.plugins.power sleep-inactive-battery-type 'suspend'

重点关注 power-button-action 'nothing'sleep-inactive-ac-type 'nothing', 由于我是台式机, 因此不需要关注 sleep-inactive-battery-type

可以通过 systemd 彻底禁用休眠:

编辑 /etc/systemd/sleep.conf 配置:

[Sleep]
AllowSuspend=no
AllowHibernation=no
AllowSuspendThenHibernate=no

这样以后, 再也不用担心在关机按钮那里误点 Suspend 或 Hibernate 了 (同时休眠相关的选项会从 Settings - Power 界面消失):

花屏的图我这里也放一个吧:

切换到 Wayland

  1. 确认当前的Nvidia显卡驱动版本已经大于 510
❯ paru -Qi nvidia | rg Version
Version         : 510.60.02-11
  1. 确认当前N卡驱动模块已经启用 KMS

KMS 默认是禁用的 (1 = enable, 0 = disable (default)) :

modinfo nvidia_drm | rg mode
depends:        nvidia-modeset
parm:           modeset:Enable atomic kernel modesetting (1 = enable, 0 = disable (default)) (bool)

我们检查下内核参数: cat /proc/cmdline , 如果没有 nvidia-drm.modeset=1 则要加上.

编辑 /etc/default/grub 加上即可, 如:

GRUB_CMDLINE_LINUX_DEFAULT="loglevel=3 noquiet nvidia-drm.modeset=1"

然后重新生成一下 grub2 配置:

sudo grub-mkconfig -o /boot/grub/grub.cfg

重启后检查 cmdline 确认 OK:

cat /proc/cmdline    
BOOT_IMAGE=/vmlinuz-linux root=/dev/mapper/archlinux-root rw loglevel=3 noquiet nvidia-drm.modeset=1

其实也不用检查 cmdline, 重启后在 GDM 登录界面, 点击用户名, 别急着输入密码, 此时会看到右下角有一个齿轮图标,点击可以发现, 默认的 session 是 GNOME (这个其实就是wayland session), 然后剩下的依次是GNOME Classic, GNOME Classic on Xorg, GNOME on Xorg. 出现这些就表示 GDM 已经检测到 Wayland 支持了.

放张图 (使用 GNOME 42 自带的 screenshot 截图的: 右击窗口标题栏, 选择take screenshot):

如果不能切 Wayland 的, 可以尝试强制禁用 gdm udev 规则:

sudo ln -s /dev/null /etc/udev/rules.d/61-gdm.rules

Troubleshooting

没错, 这里到了最麻烦的部分了. 首先我们安装一下 Xorg 的一个小工具 paru -S xorg-xlsclients

这个工具的作用是 "List client applications running on a display"

因此, 凡是被 xlsclients 识别出是客户端的, 我们就知道这个程序是跑在 X11 兼容模式 (xwayland), 而不是跑在 Wayland 协议下.

flameshot

flameshot 当前是基于 qt5 编译的, qt5 当前对于 Wayland 的支持已经较好. 但是由于我之前是 X11 的桌面, 因此这里遇到了麻烦, flameshot 无法截图. 解决办法是安装 xdg-desktop-portal :

paru -S xdg-desktop-portal xdg-desktop-portal-gnome

如果我们观察 flameshot 的 dbus 调用:

dbus-monitor --session sender=org.flameshot.Flameshot

我们会发现它截图的时候实际上是调用的 org.freedesktop.portal.Screenshot 接口 (正是由 xdg-desktop-portal 提供):

method call time=1649470142.114187 sender=:1.281 -> destination=org.freedesktop.portal.Desktop serial=27 path=/org/freedesktop/portal/desktop; interface=org.freedesktop.DBus.Introspectable; member=Introspect
method call time=1649470142.114449 sender=:1.281 -> destination=org.freedesktop.DBus serial=28 path=/org/freedesktop/DBus; interface=org.freedesktop.DBus; member=AddMatch
   string "type='signal',sender='org.freedesktop.portal.Desktop',path='/org/freedesktop/portal/desktop/request/1_281/90f9e60a9e1f4e1bb80ec889f15e855f',interface='org.freedesktop.portal.Request',member='Response'"
method call time=1649470142.114597 sender=:1.281 -> destination=org.freedesktop.portal.Desktop serial=29 path=/org/freedesktop/portal/desktop; interface=org.freedesktop.portal.Screenshot; member=Screenshot
   string ""
   array \[
      dict entry(
         string "handle_token"
         variant             string "90f9e60a9e1f4e1bb80ec889f15e855f"
      )
      dict entry(
         string "interactive"
         variant             boolean false
      )
   ]

另一方面是, 其实 flameshot 包的依赖里面已经说明了这一点, 但是由于我新非新装, 因此不会太容易看到这个提示:

xdg-desktop-portal: for wayland support, you will need the implementation for your wayland desktop environment

Optional Deps   : gnome-shell-extension-appindicator: for system tray icon 
                  if you are using Gnome
                  grim: for wlroots wayland support
                  xdg-desktop-portal: for wayland support, you will need 
                  the implementation for your wayland desktop environment
                  [installed]
Required By     : None
Optional For    : None
Conflicts With  : None

在 Arch 文档有提到另外一点, 不过我貌似没有遇到这个问题:

Flameshot does not use currently visible windows You may encounter this issue if you have installed xf86-video-intel.

Simply remove the xf86-video-intel package and make sure there is no dangling X11 configuration for the package under /etc/X11/xorg.conf.d/.

Then reboot the system.

This was discussed in an issue on the Flameshot Github repository: https://github.com/flameshot-org/flameshot/issues/1677.

好了, 截图的功能能用了, 但是还有另外一个蛋疼的问题: "to take screenshot I need to click "Share" EVERY time"

即每次 flameshot 截屏, 会弹出一个 xdg portal 的界面, 你要点击这个 "Share" 按钮, 才会继续进入 flameshot 的截图和标注界面. (实际上是把整个屏幕先完全截取, 保存在 ~/Pictures/Screenshot.png 文件, 然后 flameshot 应该是拿这个文件在操作. 如果此时不在 flameshot 做接下来的操作, 那么这个文件会残留在这个位置, 否则, 这个中间文件会被删除)

flameshot 有人提出了这个问题: https://github.com/flameshot-org/flameshot/issues/2186

但是其实这个问题, flameshot 这边无能为力. xdg-desktop-portal 需要改进.

另外提一下, GNOME 自带的 gnome-screenshot 似乎有"特权", 可以不需要通过 xdg-desktop-portal 来截屏. 但是 flameshot 无法调用这种 private 接口.

Slack

Slack 当前只能跑在 XWayland 模式. 由于它用的 electron 版本太老了. 像下面这样添加 --enable-features=UseOzonePlatform --ozone-platform=wayland 参数是无法成功启动的:

env LIBVA_DRIVER_NAME="" /usr/bin/slack -s --enable-features=UseOzonePlatform --ozone-platform=wayland

XWayland 模式下的 Slack 有什么问题? 嗯, 问题就是, 输入中文的时候会卡顿. 这一点似乎在所有基于 electron 的 Linux 应用上面都有所表现. 比如 vs code 也有这个问题.

有个 aur 包, slack-electron , 测试了下貌似对于解决中文输入问题没有什么帮助.

结论: 先 XWayland 将就着用着吧, 或者直接使用 slack web 版.

2022-04-13 更新: 受到这个评论 https://github.com/swaywm/sway/issues/2508#issuecomment-438185459 的启发:

on slack the freezing seems to get better when you disable (or enable) hardware acceleration.

老灯发现 禁用 HwAcceleration 后, 打字什么的都流畅多了, 界面也不卡顿了.

可以直接在 Slack prefs 配置的高级选项里禁用hw acc, 或者, 直接修改配置文件 ~/.config/Slack/local-settings.json 增加:

"useHwAcceleration":false

Discord

Discord 同样是跑在 XWayland 下, 但是我测试的时候发现, 一定要设置 LIBVA_DRIVER_NAME (猜测跟我安装了 libva Intel 硬件加速相关库有关)

当前 Intel 12 代 CPU 集显的硬件加速在 Linux 下面还不支持. 因此我这里用的是 vdpau driver.

env LIBVA_DRIVER_NAME=vdpau /usr/bin/discord 可以成功启动. 我们需要覆盖一下 discord.desktop 文件:

cp -v /usr/share/applications/discord.desktop ~/.local/share/applications/
sed -i 's|Exec=/usr/bin/discord|Exec=env LIBVA_DRIVER_NAME=vdpau /usr/bin/discord|g' ~/.local/share/applications/discord.desktop

Chrome, Chromium 和 Microsoft Edge

Chrome, Chromium 和 Microsoft Edge 可以跑在原生 Wayland 下面, 只是需要添加 flags.

对于 Chromium , 编辑 ~/.config/chromium-flags.conf 增加:

--enable-features=UseOzonePlatform
--ozone-platform=wayland
--gtk-version=4

对于 Chrome, 这个文件是 ~/.config/chrome-flags.conf, 对于 Microsoft Edge, 这个文件是 ~/.config/microsoft-edge-stable-flags.conf

注意这里老灯还多添加了一个 --gtk-version=4, 这个主要是为了修复 Wayland 下面的输入法支持问题, 要不然无法输入中文.

另外提一句, 你怎么知道这个文件的位置的? 除了看文档, 更靠谱的是, 通过其启动shell脚本判断:

❯ rg 'flags.conf' /usr/bin/microsoft-edge-stable
2:# Launches MS Edge with flags specified in $XDG_CONFIG_HOME/microsoft-edge-beta-flags.conf
11:if [ -r "${XDG_CONFIG_HOME}/microsoft-edge-stable-flags.conf" ]; then
12:  EDGE_USER_FLAGS="$(cat "$XDG_CONFIG_HOME/microsoft-edge-stable-flags.conf")"


❯ rg 'flags.conf' /usr/bin/google-chrome-stable 
6:if [[ -f $XDG_CONFIG_HOME/chrome-flags.conf ]]; then
7:   CHROME_USER_FLAGS="$(cat $XDG_CONFIG_HOME/chrome-flags.conf)"

Ulauncher

Ulauncher 的全局热键不再生效. 解决办法参考 https://github.com/Ulauncher/Ulauncher/wiki/Hotkey-In-Wayland

Fedora and Ubuntu (since 17.04) start Wayland session by default. Ulauncher in Wayland does not receive hotkey events when triggered from some windows (like terminal or OS Settings).

Please follow these steps to fix that:

Install package wmctrl (needed to activate app focus) Open Ulauncher Preferences and set Hotkey to something you'll never use Open Settings > Keyboard (may be named "Keyboard Shortcuts"), then scroll down to Customize Shortcuts > Custom Shortcuts > + In Command enter ulauncher-toggle, set name and shortcut, then click Add

官方这个文档已经把步骤描述得挺详细了, 这里我就不再说了. 最重要的是你要在 Ulauncher Preferences 设置 Hotkey 为一个超级复杂的组合键, 并且确保你在日常使用中 100% 都不会触发这个按键.

因为这个热键实际从 GNOME 的 custom shortcut 那里设置了. 并且触发启动的命令是 ulauncher-toggle

我们看下这个 ulauncher-toggle (位置 /usr/bin/ulauncher-toggle ) 做了啥.

#!/bin/sh

dbus-send \
    --session \
    --print-reply \
    --dest=net.launchpad.ulauncher \
    /net/launchpad/ulauncher \
    net.launchpad.ulauncher.toggle_window

# dbus-send is asynchronous and sometimes it takes a bit of time for Ulauncher window to be presented
sleep 0.03

wmctrl -a "Ulauncher - Application Launcher"

它首先给 ulauncher 的 dbus 接口发送了一个显示隐藏窗口的命令 (net.launchpad.ulauncher.toggle_window). 同时, 由于 dbus-send 是异步执行的, 因此实际上脚本不知道 ulauncher 的操作是否已经完成. 不过通常显示一个窗口不算是耗时操作, 因此它这里拍脑袋设定了一个值, 这个值的响应时间对于人操作来说不会有明显的delay, 同时也满足大部分情况下的结果.

最后, 它需要调用 wmctrl 激活这个窗口, 并获取焦点. 看上去是个 tricks, 不过至少能工作了.

visual-studio-code

vs code 当前只能跑在 XWayland 模式, 并且跟 Slack 一样有中文输入卡顿问题.

当前主分支已经修复 Wayland 支持问题, 预计 1.67 会发布.

https://github.com/microsoft/vscode/commit/648b352b480c51d2a62092230348b54a1c830ec9

主要就是升级 electron到17.3.1

VSCodium 是跟随ms vscode 版本的, 因此不能解决问题.

ms 的 insider 版试了下, 窗口显示都有问题. 放弃.

反正平常也只用它当编辑器使用, 主力还是 Neovim 和 Jetbrains 全家桶.

2022-04-12 补充更新: vscode 卡顿解决

参考 https://code.visualstudio.com/updates/v1_40#_disable-gpu-acceleration

编辑 ~/.config/code-flags.conf 加上一行:

--disable-gpu

Jetbrains全家桶

目前 java 还没有 Wayland 原生方案, 因此 Jetbrains 全家桶 是跑在 XWayland 下面, 经测试 fcitx 和 ibus rime 均可正常输入中文.

smplayer

smplayer 无法正常在Wayland 下工作. 虽然官方有特别给出说明: https://blog.smplayer.info/how-to-fix-the-video-problem-on-wayland/

  1. flatpak 版本安装后直接跑不起来, 一运行就崩了.
  2. Select a different video output in Preferences -> General -> Video, 切换成各各种方式都无法正常工作.

其中, 硬解 选择 vdpau, Preferences -> General -> Video 选择 drm 可以播放, 但是 mpv 的窗口跑飞了 ("the video being on a separate window"), 其它组合都是 "a black window or a crash when trying to play a video"

mpv 本身播放正常. 只是 mpv 有些问题, 比如无法在 ui 层面选择 外挂字幕等.

不过这里有一个解决办法: https://github.com/darsain/uosc

github 上面的安装方法写得并不详细, 我后续会单独写文章分享, 详细说一下.

结论: 视频播放器暂时只能用 GNOME 自带的 Video 播放器顶一下 或者 用 mpv + uosc (推荐)

其它应用

Kitty 中文输入正常, 自然 Neovim 中文输入正常.

feishu 只能跑在 XWayland 模式, 中文输入正常. 目前无法拖动传文件. 无法使用它内置的截屏功能(当然,我从来就用). 基本上算不太影响使用吧.

jetbrains-toolbox 也是跑在 XWayland 模式, 目前看来使用上没啥影响.

LibreOffice Wayland and HiDPI To work around issues with scaling UI elements in Wayland on HiDPI screens, use the gtk3 VCL UI interface. https://wiki.archlinux.org/title/LibreOffice#Wayland_and_HiDPI 这一点在 GNOME 42 下会默认检测用 gtk3, 因此默认就 OK

Refs

https://fedoraproject.org/wiki/Changes/WaylandByDefaultOnNVIDIA

https://wiki.archlinux.org/title/NVIDIA#DRM_kernel_mode_setting

https://wiki.archlinux.org/title/GDM#Wayland_and_the_proprietary_NVIDIA_driver

https://wiki.archlinux.org/title/Wayland#Display_managers

https://wiki.archlinux.org/title/GNOME#GNOME_applications_in_Wayland

https://fedoraproject.org/wiki/How_to_debug_Wayland_problems

https://cubethethird.wordpress.com/2017/06/07/mixed-feelings-about-wayland-on-gnome/

https://access.redhat.com/documentation/en-us/red_hat_enterprise_linux/8/html/using_the_desktop_environment_in_rhel_8/customizing-gnome-desktop-features_using-the-desktop-environment-in-rhel-8#changing-behavior-when-pressing-the-powerbutton_customizing-gnome-desktop-features

https://www.reddit.com/r/Slack/comments/obgrac/slow_and_sluggish_typing_on_linux/

https://github.com/microsoft/vscode/issues/109176#event-6364443456

https://github.com/microsoft/vscode/commit/648b352b480c51d2a62092230348b54a1c830ec9

https://a-wing.top/linux/2022/01/03/translate_wayland.html

https://github.com/flameshot-org/flameshot/issues/2186

Are we Wayland yet? https://arewewaylandyet.com/

https://wiki.archlinux.org/title/Flameshot#Flameshot_does_not_use_currently_visible_windows

https://github.com/fcitx/fcitx5/issues/263

https://www.fosskers.ca/en/blog/wayland