middleware: VNC generator add disable_wayland + restart_gdm options for GNOME

Ubuntu 22.04 defaults to WaylandEnable=true in /etc/gdm3/custom.conf.
Wayland + x11vnc has known issues (keyboard remap, clipboard, gnome-shell
crashes on X events). Add two options: disable_wayland (write
WaylandEnable=false to gdm3/custom.conf on GNOME installs, guarded when no
gdm3 exists) and restart_gdm (immediately restart gdm vs apply on reboot).
This commit is contained in:
cnbug
2026-08-06 14:05:05 +08:00
parent b9bd50c869
commit 6f4d071bf3
+52
View File
@@ -59,6 +59,14 @@ class VNCSrv(Generator):
"对 VNC 连接无影响,只影响原生 X11 客户端直连能力。"),
Field("use_xvfb", "使用 Xvfb (无显卡)", "checkbox", default="yes",
help="Headless 服务器必须启用 — VNC 通过 Xvfb 渲染,无需物理显卡。"),
Field("disable_wayland", "禁用 GDM Wayland (强制 X11)", "checkbox", default="yes",
help="强烈建议启用 — Ubuntu 22.04 默认用 Wayland + GDM,但 Wayland 下 x11vnc "
"会出现键盘映射异常、剪贴板双向不通、gnome-shell 偶发闪退等问题。"
"此选项写 /etc/gdm3/custom.conf 把 WaylandEnable 设为 false,所有 GDM session "
"(包括物理登录和锁屏)都强制走 X11。注意:在有活动的物理桌面登录时会断开一次。"),
Field("restart_gdm", "立即重启 GDM 应用 Wayland 更改", "checkbox", default="no",
help="yes = 立刻 systemctl restart gdm 让 Wayland 禁用生效(会断开当前物理会话);"
"no = 仅改配置,下次重启后生效。生产机器建议 no,自己本地实验可以 yes。"),
]
# ---- per-DE helpers (chosen at render time) ----
@@ -134,6 +142,8 @@ class VNCSrv(Generator):
nolisten_unix = bool_str(p.get("nolisten_unix", True))
nolisten_tcp_local = bool_str(p.get("nolisten_tcp_local"))
use_xvfb = bool_str(p.get("use_xvfb", True))
disable_wayland = bool_str(p.get("disable_wayland", True))
restart_gdm = bool_str(p.get("restart_gdm"))
if de not in self.DE_PACKAGES:
raise ValueError(f"Unknown desktop_env: {de}. Choose one of: {', '.join(self.DE_PACKAGES)}")
@@ -184,6 +194,48 @@ class VNCSrv(Generator):
' gnome-tweaks')
out.append(install)
# GDM Wayland disable — only relevant for GNOME on a machine that
# has a physical GDM (i.e. ubuntu-desktop-01, not a headless server).
# Ubuntu 22.04 defaults to WaylandEnable=true in /etc/gdm3/custom.conf.
# Wayland + x11vnc has known issues: keyboard remapping gets
# confused, clipboard isn't bidirectional, gnome-shell occasionally
# crashes on X client events. Forcing X11 makes the VNC session
# behave like a normal X11 desktop.
if de == "gnome" and disable_wayland:
out.append('log "Disabling GDM Wayland (forcing X11 session)..."')
# custom.conf may not exist on a server (no gdm3 installed) — guard
out.append('if [ -d /etc/gdm3 ] && [ -f /etc/gdm3/custom.conf ] || [ ! -f /etc/gdm3/custom.conf ]; then')
out.append(' mkdir -p /etc/gdm3')
out.append(' if [ -f /etc/gdm3/custom.conf ]; then')
# Replace any existing WaylandEnable line, else add under [daemon]
out.append(' if grep -q "^[[:space:]]*WaylandEnable" /etc/gdm3/custom.conf; then')
out.append(' sed -i "s/^[[:space:]]*WaylandEnable.*/WaylandEnable=false/" /etc/gdm3/custom.conf')
out.append(' else')
out.append(' sed -i "/^[[:space:]]*\\[daemon\\]/a WaylandEnable=false" /etc/gdm3/custom.conf')
out.append(' fi')
out.append(' else')
# No custom.conf yet — write a minimal one
out.append(' cat > /etc/gdm3/custom.conf <<GDM_EOF')
out.append('[daemon]')
out.append('WaylandEnable=false')
out.append('')
out.append('[security]')
out.append('')
out.append('[xdmcp]')
out.append('')
out.append('[chooser]')
out.append('')
out.append('[debug]')
out.append('GDM_EOF')
out.append(' fi')
out.append(' log " /etc/gdm3/custom.conf now has WaylandEnable=false"')
out.append('fi')
if restart_gdm:
out.append('log "Restarting GDM to apply Wayland=false (will briefly disconnect any physical session)..."')
out.append('systemctl restart gdm 2>&1 | head -5 || warn "gdm restart failed (no gdm installed?)"')
else:
out.append('log "Wayland disabled in custom.conf; will take effect after next gdm restart or reboot."')
out.append('log "Preparing VNC directory..."')
out.append(f'USER_HOME="$(getent passwd {quote(user)} | cut -d: -f6 || echo /root)"')
# If getent returned /root for a non-root user, the account is in a