org-page

static site generator

升级gnome 47之后修复gnome-flashback hidpi问题

昨天arch升级gnome 47之后发现我目前正在使用的gnome-flashback-xmonad-nopanel会话的缩放出问题了。现象就是在我的4k显示器下,kitty、emacs、fcitx等应用显示的非常小。 然而切换到gnome-shell会话则没有问题。

于是就翻起了arch关于HiDPI的wiki。下面这段引起了我的兴趣。

GNOME ignores X settings due to its xsettings Plugin in Gnome Settings Daemon, where DPI setting is hard coded. There is blog entry for recompiling Gnome Settings Daemon^{[dead link 2022-09-18 ⓘ]}. In the source documentation there is another way mentioned to set X settings DPI:

You can use the gsettings, just make sure to read previous setting first and merge it. In just simply set it with this command:

$ gsettings set org.gnome.settings-daemon.plugins.xsettings overrides "{'Xft/DPI': <153600>}"

gnome-falshback-xmonad-nopanel 会话和 gnome-shell 会话分别执行命令:

xrdb -query | grep dpi

得到的结果分别为:

Xft.dpi:        96

Xft.dpi:        192

推测很可能是这个 Xft.dpi 参数相关了。

于是尝试使用 X Resources 设置这个参数。以下是 ~/.Xresources 文件的内容:

Xft.dpi:  192
Xft.antialias:  1
Xft.hinting:  1
Xft.hintstyle:  hintfull
Xft.rgba: none
Xcursor.size: 48
Xcursor.theme:  Bibata-Modern-Amber

执行以下命令使之生效:

xrdb -merge ~/.Xresources

果然kitty等应用都恢复了。

经过搜索发现, gnome-shell 会话通过 org.gnome.SettingsDaemon.XSettings.service 服务设置X配置。执行以下命令查看服务运行状态:

systemctl status --user org.gnome.SettingsDaemon.XSettings.service

执行结果如下:

● org.gnome.SettingsDaemon.XSettings.service - GNOME XSettings service
     Loaded: loaded (/usr/lib/systemd/user/org.gnome.SettingsDaemon.XSettings.service; static)
     Active: active (running) since Thu 2024-09-26 09:05:30 CST; 1h 45min ago
 Invocation: 3f08d3cc97164b8fa22d2a0015444682
   Main PID: 34347 (gsd-xsettings)
      Tasks: 5 (limit: 77071)
     Memory: 8.9M (peak: 10.9M)
        CPU: 426ms
     CGroup: /user.slice/user-1000.slice/user@1000.service/session.slice/org.gnome.SettingsDaemon.XSettings.service
             └─34347 /usr/lib/gsd-xsettings

Sep 26 09:05:30 archdesktop systemd[1801]: Starting GNOME XSettings service...
Sep 26 09:05:30 archdesktop gsd-xsettings[34347]: Failed to get current UI scaling factor: GDBus.Error:org.freedesktop.DBus.Error.NameHasNoOwner: Destination does not exist
Sep 26 09:05:30 archdesktop systemd[1801]: Started GNOME XSettings service.

可见其中有一条异常日志, Sep 26 09:05:30 archdesktop gsd-xsettings[34347]: Failed to get current UI scaling factor: GDBus.Error:org.freedesktop.DBus.Error.NameHasNoOwner: Destination does not exist 。 因为 gnome-flashback 会话已经长期没人维护了,这次升级应该破坏了 gnome-flashbackgnome-settings-daemon 的兼容性。

唉!

查看源码 47.0/plugins/xsettings/gsd-xsettings-manager.c?ref_type=tags#L621 如下:

static int
get_window_scale (GsdXSettingsManager *manager)
{
        g_autoptr(GError) error = NULL;
        g_autoptr(GVariant) res = NULL;
        g_autoptr(GVariant) ui_scaling_factor_variant = NULL;
        g_autoptr(GVariantIter) properties = NULL;
        int ui_scaling_factor = 1;

        res = g_dbus_connection_call_sync (manager->dbus_connection,
                                           "org.gnome.Mutter.X11",
                                           "/org/gnome/Mutter/X11",
                                           "org.freedesktop.DBus.Properties",
                                           "Get",
                                           g_variant_new ("(ss)",
                                                          "org.gnome.Mutter.X11",
                                                          "UiScalingFactor"),
                                           NULL,
                                           G_DBUS_CALL_FLAGS_NO_AUTO_START,
                                           -1,
                                           NULL,
                                           &error);
        if (!res) {
                g_warning ("Failed to get current UI scaling factor: %s",
                           error->message);
                return 1;
        }

        g_variant_get (res, "(v)", &ui_scaling_factor_variant);
        g_variant_get (ui_scaling_factor_variant, "i", &ui_scaling_factor);

        return ui_scaling_factor;
}

此段代码试图从DBus中获取当前ui的缩放因子,然而在 gnome-falshback 会失败,直接 return 1 了。 将这段代码转化称 dbus-send 命令,

dbus-send --session --dest=org.gnome.Mutter.X11 \
          --print-reply /org/gnome/Mutter/X11 \
          org.freedesktop.DBus.Properties.Get \
          string:"org.gnome.Mutter.X11" string:"UiScalingFactor"

分别在 gnome-falshbackgnome-shell 会话执行得到以下结果:

Error org.freedesktop.DBus.Error.ServiceUnknown: The name is not activatable

method return time=1727322064.543245 sender=:1.19 -> destination=:1.180 serial=1227 reply_serial=2
   variant       int32 2

这里还可以看看gnome 46的源码 46.0/plugins/xsettings/gsd-xsettings-manager.c?ref_type=tags#L658

反正,我基本上不会去换显示器了,这里直接把出错时候的 return 1 改成 return 2 简单修复下吧。

重新打包安装,解决问题。

PS: 2024-10-09收到了archlinux的gnome-flashback 3.54.0的更新包,看了下官方的NEWS,问题已经解决了。

Version 3.54.0
==============
- Fix use after free in timeout_bubble. (#96)
- Fix polkit crash. (#92)
- Add new D-Bus API for UI scaling.
- Update DisplayConfig D-Bus API.
- Improve screensaver style. (!54)
- Add support for color-scheme setting. (!51, !53)
- Save and restore numlock state. (#62, #93)
- Updated translations.

Comments

comments powered by Disqus