最近几天在 archbox 上折腾 Sway/niri/Hyprland 三桌面环境,核心诉求很明确:每次进入桌面自动修改 X11 相关配置,覆盖 Sway/niri/Hyprland。目标是让 GTK 逻辑主题尺寸、gsettings、Xresources、光标、Electron flags 等在一套脚本里统一同步,避免每个桌面各自为政。
问题背景
之前每个桌面环境各自维护自己的 X11 配置,存在几个痛点:
- Sway 下 XCURSOR_SIZE=24 覆盖 Chromium/Electron XSETTINGS/Xresources 48,导致 Feishin 等应用指针偏小
- 不同桌面切换时会继承上一桌面的值(如 Hyprland 的 wayland 环境传到 Sway)
- 各应用包装器各自设置环境变量,互相覆盖,难以追踪
- GTK 主题尺寸、gsettings、Xresources 分散在多处,修改要跑多处
统一脚本方案
sync-desktop-x11
2026-10-05 新增 ~/.local/bin/sync-desktop-x11,GTK 逻辑主题尺寸、gsettings、共享 ~/.Xresources、environment.d/cursor.conf、desktop-session/x11.env 与 current.json、Chrome/Code/Electron flags、DBus/systemd 激活环境统一同步,锁与原子写入保留无关设置。
删除 envvars.conf 重复 XCURSOR/Electron 定义(原与 cursor.conf 冲突)。
各桌面调用方式:
- Sway:
sync-xcursor.py在确认 server/尺寸后调用统一脚本,当前 macOS 逻辑 24/X11 高清 48、x11+1.25 - niri:
session.kdl startup调用同一脚本,macOS 24/24,wayland 无 Sway 强制比例 - Hypr:custom execs startup 同脚本,Bibata 24/24,并由脚本
hyprctl setcursor
两者旧独立 xrdb 加载被替代。每桌面明确 Electron 提示,避免继承上一桌面值:Sway 启动器 x11,niri/Hypr 环境 wayland。
sway-x11 优先读统一 current.json,检查 desktop 匹配,其他桌面已知 app 包装器透传系统入口。
cursor-bridge(会话级 X11 指针适配)
2026-10-05 新增 ~/.config/desktop-session/cursor-bridge/bridge.c,通过 LD_PRELOAD 拦截成功的 XOpenDisplay/xcb_connect/auth_info 连接,仅 Sway 且 DISPLAY 匹配时从 desktop-session/x11.env 更新当前进程主题/物理尺寸。
- 原生 Wayland 仍 24
- 64/32 库
~/.local/lib/desktop-cursor/{lib,lib32}/cursor-bridge.so - sway-intel 登录导出含字面
$LIB的 LD_PRELOAD - sync-desktop-x11 同步 DBus/systemd 激活环境,Hypr/niri 清除自己的桥接路径
实际 libX11 测试 Sway 24→48,niri 24 不变,GTK 原生 Wayland 24,32 位加载成功,实际 Feishin 日志 macOS 48;视觉反馈尚待用户确认。完整继承须重登录 Sway,不终止用户桌面。
动态普通客户端覆盖,沙箱/静态/自绘/清环境/混合 backend 例外,不保证所有软件。Steam 容器尚未验证。旧应用包装器保留。
配置切换隔离测试
配置切换隔离测试 Sway→Hypr→niri→Sway 通过,niri validate、Lua 语法检查通过;当前真实 Sway xrdb 48、激活逻辑 24、x11 提示核验通过,未切换当前桌面,Hypr/niri 真实再登录尚待确认。
逻辑 24 不全局改 48;X11 高清尺寸单独保存,忽略配置/自绘/沙箱程序仍可例外,非保证所有未来程序零例外。已有进程需重开,共享文件并行多图形会话未隔离。
备份 ~/.local/state/desktop-session/backups-before-unified/ 含 manifest;详笔记 ~/workspace/markdown/Sway-分数缩放与高清指针笔记.md 第 13 节为最新共享配置规则。
Sway Intel 核显独立会话
2026-10-05 最新状态:用户坚持 Intel Sway 内屏输出 scale 1.25。Chrome (force scale) 单独 desktop 参数试验无效,用户明确要求删除,~/.local/share/applications/google-chrome-force-scale.desktop 已删除。
当前真实 Sway 会话独立 DISPLAY=
satellite 0.8.3 启动成功,X11 提供 1920x1080 物理像素、xrdb Xft.dpi 120;临时 Chrome 独立测试 profile 使用--ozone-platform=x11 --force-device-scale-factor=1.25,另 GTK3/X11 测试。用户明确反馈两个都明显清晰了。
已正式接入 Intel 会话:~/.local/bin/sway-intel 必须 export WLR_BACKENDS=drm,libinput,清除继承 WAYLAND_DISPLAY/WAYLAND_SOCKET 后选择空闲 DISPLAY,再启动 sway --config ~/.config/sway/config-intel;overlay 包含主配置、xwayland disabled、启动 start-xwayland-satellite.sh。
重要:先前登录回归根因是在自动后端选择时预设 DISPLAY 导致误选 X11;显式 DRM 修正必须保留,独立测试不能冒充物理登录验证。
Waybar 稳定性修复
2026-10-05 再次排障:16
Waybar 364905 SIGSEGV core,libgdk3 偏移 0x54648,反汇编及 GTK3.24.52 源码对应_gdk_wayland_cursor_get_buffer 内访问 wl_cursor_image,r15=0x28000000142a 失效,位于 cursor scale 处理路径,符合指针图像释放后仍使用;尚未证明精确触发条件。
修复:config1/2 交互模块 cursor:false 通过 AModule 配置存在性禁用默认 HAND2/ARROW 切换(0.15.0 虽记录 unknown cursor option 但禁用生效);开启 reload_style_on_change,wallpaper.py 取消 SIGUSR2 全量重载;desktop-session.write 相同内容跳过写入,避免重复 GTK 设置通知。
Sway exec 统一 launch_waybar.sh 2,服务 ~/.config/systemd/user/sway-waybar@.service 原生 Wayland、UnsetEnvironment=LD_PRELOAD、Restart=always 2 秒且 30 秒最多 5 次、ExecCondition 检查 Sway socket,会话退出停止重试。
这是绕开 GTK 旧指针/重载风险及恢复机制,不声称 GTK 库内部错误已根治。
经验总结
- 桌面切换时环境隔离是关键:每个桌面明确自己的 X11/Wayland 标识,避免继承上一桌面值
- LD_PRELOAD 桥接比逐应用包装更可靠:cursor-bridge 方案比给每个 Electron 应用写 wrapper 更省心
- 改配置先备份:
~/.local/state/desktop-session/backups-before-*保留路径和 verification.py,出问题可快速回退 - 语法校验不能省:niri validate、Lua/shell/Python 语法检查都通过才敢真机测试
- 服务管理优于 exec 直接启动:systemd user service 的 Restart/ExecCondition 比裸 exec 更可靠,还能自动恢复
这套配置目前在实际 Sway 会话中运行稳定,X11 高清指针在 Feishin/Chrome/Electron 应用下均正常。niri/Hyprland 的真实再登录验证还在进行中。