gui: one shared dbus session bus for the gui session (#1906)
This commit is contained in:
parent
14ae7367cd
commit
baa5ce3e1a
2 changed files with 62 additions and 5 deletions
|
|
@ -270,6 +270,19 @@ connects to the compositor at `127.0.0.1:<vnc_port>`.
|
|||
wayland client sharing the `/run/gui/wayland-0` socket). Wayland
|
||||
clients in the agent's config (e.g. bitburner electron) must run as the
|
||||
same user with `XDG_RUNTIME_DIR=/run/gui`.
|
||||
- **One shared D-Bus session bus (`gui-dbus.service`)**: a single
|
||||
persistent `dbus-daemon --session` bound at `/run/gui/bus`, run as the
|
||||
agent user, ordered `before weston.service` (it shares the same
|
||||
`RuntimeDirectory=gui`, creating the dir first). Chromium/electron via
|
||||
ozone refuse to map an `xdg_toplevel` without a reachable session bus
|
||||
("Failed to connect to the bus" → binds `xdg_wm_base` then destroys it
|
||||
= invisible window even though CDP works). The fix is **not** to wrap
|
||||
each client in its own `dbus-run-session` (a private throwaway bus per
|
||||
process — that's a *separate* session, defeating the one-session
|
||||
model); it's this one shared bus, whose address is exported as
|
||||
`DBUS_SESSION_BUS_ADDRESS=unix:path=/run/gui/bus` via
|
||||
`systemd.globalEnvironment` so weston, the harness and every GUI client
|
||||
inherit it.
|
||||
- **Fixed Wayland socket name (`--socket=wayland-0`)**: weston is
|
||||
launched with `--socket=wayland-0` so the socket path is
|
||||
deterministic. `harness-base.nix` exports `WAYLAND_DISPLAY=wayland-0`
|
||||
|
|
|
|||
|
|
@ -55,9 +55,11 @@ in
|
|||
`Type = "simple"` so a misconfigured weston degrades to a restart
|
||||
loop instead of blocking `nixos-container update`.
|
||||
|
||||
Weston and the wayland client run as the agent's own non-root
|
||||
user (`hyperhive.user.name`), sharing one user session with a
|
||||
fixed `XDG_RUNTIME_DIR=/run/gui`.
|
||||
Weston, the wayland client and the agent harness run as the
|
||||
agent's own non-root user (`hyperhive.user.name`), sharing one
|
||||
session: a fixed `XDG_RUNTIME_DIR=/run/gui`, one wayland display,
|
||||
and one D-Bus session bus at `/run/gui/bus` (gui-dbus.service),
|
||||
so GUI clients need no private `dbus-run-session`.
|
||||
'';
|
||||
};
|
||||
|
||||
|
|
@ -100,9 +102,48 @@ in
|
|||
session sufficient pam_permit.so
|
||||
'';
|
||||
|
||||
# One shared D-Bus *session* bus for the whole GUI session, bound at
|
||||
# /run/gui/bus and owned by the agent user. Wayland GUI clients
|
||||
# (chromium / electron via ozone) refuse to map a toplevel without a
|
||||
# reachable session bus ("Failed to connect to the bus" -> binds
|
||||
# xdg_wm_base then destroys it = invisible window, though CDP still
|
||||
# works). Running ONE persistent bus here -- instead of each client
|
||||
# wrapping itself in `dbus-run-session` (a private throwaway bus per
|
||||
# process) -- keeps weston, the agent harness and the GUI client in a
|
||||
# single session: one user, one XDG_RUNTIME_DIR, one wayland display,
|
||||
# one bus. The address is exported via globalEnvironment below so
|
||||
# every unit in the container inherits it.
|
||||
systemd.services.gui-dbus = {
|
||||
description = "Shared D-Bus session bus for the GUI session";
|
||||
wantedBy = [ "multi-user.target" ];
|
||||
before = [ "weston.service" ];
|
||||
serviceConfig = {
|
||||
Type = "simple";
|
||||
User = userName;
|
||||
Group = userName;
|
||||
# Share /run/gui with weston; ordered `before` weston so this
|
||||
# creates + chowns the dir first. Preserve across restarts so
|
||||
# weston + clients don't lose the dir holding their sockets.
|
||||
RuntimeDirectory = "gui";
|
||||
RuntimeDirectoryMode = "0700";
|
||||
RuntimeDirectoryPreserve = "yes";
|
||||
Environment = "XDG_RUNTIME_DIR=/run/gui";
|
||||
# dbus-daemon unlinks a stale path socket before binding, so a
|
||||
# restart re-binds /run/gui/bus cleanly.
|
||||
ExecStart = "${pkgs.dbus}/bin/dbus-daemon --session --nofork --nopidfile --address=unix:path=/run/gui/bus";
|
||||
SyslogIdentifier = "gui-dbus";
|
||||
Restart = "on-failure";
|
||||
RestartSec = "2s";
|
||||
};
|
||||
};
|
||||
|
||||
systemd.services.weston = {
|
||||
description = "Weston Wayland compositor (VNC backend)";
|
||||
after = [ "network.target" ];
|
||||
after = [
|
||||
"network.target"
|
||||
"gui-dbus.service"
|
||||
];
|
||||
wants = [ "gui-dbus.service" ];
|
||||
wantedBy = [ "multi-user.target" ];
|
||||
serviceConfig = {
|
||||
Type = "simple";
|
||||
|
|
@ -155,10 +196,13 @@ in
|
|||
# to systemd service units. Without these vars a service starting
|
||||
# a Wayland client would either fail to connect (libwayland falls
|
||||
# back to a headless display) or open a second compositor — VNC
|
||||
# shows a blank desktop.
|
||||
# shows a blank desktop. DBUS_SESSION_BUS_ADDRESS points every unit
|
||||
# at the one shared session bus (gui-dbus.service above) so GUI
|
||||
# clients use it instead of spawning a private `dbus-run-session`.
|
||||
systemd.globalEnvironment = {
|
||||
WAYLAND_DISPLAY = "wayland-0";
|
||||
XDG_RUNTIME_DIR = "/run/gui";
|
||||
DBUS_SESSION_BUS_ADDRESS = "unix:path=/run/gui/bus";
|
||||
};
|
||||
|
||||
# weston on the agent's interactive PATH so claude can run Wayland
|
||||
|
|
|
|||
Loading…
Reference in a new issue