diff --git a/hosts/common/programs/sane-open.nix b/hosts/common/programs/sane-open.nix index ea9c860e..d31ffe71 100644 --- a/hosts/common/programs/sane-open.nix +++ b/hosts/common/programs/sane-open.nix @@ -8,7 +8,7 @@ sandbox.extraHomePaths = [ ".local/share/applications" ]; - sandbox.extraRuntimePaths = [ "sway" ]; + sandbox.extraRuntimePaths = [ "sway" ]; #< calls `swaymsg` to query rotation and see if there's room for a keyboard suggestedPrograms = [ "gdbus" "xdg-utils" diff --git a/hosts/common/programs/sway/default.nix b/hosts/common/programs/sway/default.nix index de64f314..65194d79 100644 --- a/hosts/common/programs/sway/default.nix +++ b/hosts/common/programs/sway/default.nix @@ -26,47 +26,59 @@ let ]; passthru.sway-unwrapped = configuredSway; }; - swayPackage = wrapSway ( - pkgs.waylandPkgs.sway-unwrapped.override { - wlroots = (pkgs.waylandPkgs.wlroots.override { - # wlroots seems to launch Xwayland itself, and i can't easily just do that myself externally. - # so in order for the Xwayland it launches to be sandboxed, i need to patch the sandboxed version in here. - xwayland = config.sane.programs.xwayland.package; - }).overrideAttrs (upstream: { - # 2023/09/08: fix so clicking a notification can activate the corresponding window. - # - test: run dino, receive a message while tabbed away, click the desktop notification. - # - if sway activates the dino window (i.e. colors the workspace and tab), then all good - # - do all of this with only a touchscreen (e.g. on mobile phone) -- NOT a mouse/pointer - # 2023/12/17: this patch is still necessary - ## what this patch does: - # - allows any wayland window to request activation, at any time. - # - traditionally, wayland only allows windows to request activation if - # the client requesting to transfer control has some connection to a recent user interaction. - # - e.g. the active window may transfer control to any window - # - a window which was very recently active may transfer control to itself - ## alternative (longer-term) solutions: - # - fix this class of bug in gtk: - # - - # - N.B.: this linked PR doesn't actually fix it - # - add xdg_activation_v1 support to SwayNC (my notification daemon): - # - - # - mako notification daemon supports activation, can use as a reference - # - all of ~30 LoC, looks straight-forward - # - however, it's not clear that gtk4 (or dino) actually support this mode of activation. - # - i.e. my experience with dino is the same using mako as with SwayNC - postPatch = (upstream.postPatch or "") + '' - substituteInPlace types/wlr_xdg_activation_v1.c \ - --replace-fail 'if (token->seat != NULL)' 'if (false && token->seat != NULL)' - ''; - }); + wlroots = (pkgs.waylandPkgs.wlroots.override { + # wlroots seems to launch Xwayland itself, and i can't easily just do that myself externally. + # so in order for the Xwayland it launches to be sandboxed, i need to patch the sandboxed version in here. + xwayland = config.sane.programs.xwayland.package; + }).overrideAttrs (upstream: { + # 2023/09/08: fix so clicking a notification can activate the corresponding window. + # - test: run dino, receive a message while tabbed away, click the desktop notification. + # - if sway activates the dino window (i.e. colors the workspace and tab), then all good + # - do all of this with only a touchscreen (e.g. on mobile phone) -- NOT a mouse/pointer + # 2023/12/17: this patch is still necessary + ## what this patch does: + # - allows any wayland window to request activation, at any time. + # - traditionally, wayland only allows windows to request activation if + # the client requesting to transfer control has some connection to a recent user interaction. + # - e.g. the active window may transfer control to any window + # - a window which was very recently active may transfer control to itself + ## alternative (longer-term) solutions: + # - fix this class of bug in gtk: + # - + # - N.B.: this linked PR doesn't actually fix it + # - add xdg_activation_v1 support to SwayNC (my notification daemon): + # - + # - mako notification daemon supports activation, can use as a reference + # - all of ~30 LoC, looks straight-forward + # - however, it's not clear that gtk4 (or dino) actually support this mode of activation. + # - i.e. my experience with dino is the same using mako as with SwayNC + postPatch = (upstream.postPatch or "") + '' + substituteInPlace types/wlr_xdg_activation_v1.c \ + --replace-fail 'if (token->seat != NULL)' 'if (false && token->seat != NULL)' + ''; + }); + swayPackage = wrapSway ( + (pkgs.waylandPkgs.sway-unwrapped.override { + inherit wlroots; # about xwayland: # - required by many electron apps, though some electron apps support NIXOS_OZONE_WL=1 for native wayland. # - when xwayland is enabled, KOreader incorrectly chooses the X11 backend # -> slower; blurrier # - xwayland uses a small amount of memory (like 30MiB, IIRC?) enableXWayland = config.sane.programs.xwayland.enabled; - } + }).overrideAttrs (upstream: { + # fix to create SWAYSOCK and WAYLAND_DISPLAY directly in a sandboxable subdirectory: + # i can't simply move it after creation i think because that would + # be an unsupported cross-device `mv`? + postPatch = (upstream.postPatch or "") + '' + substituteInPlace sway/ipc-server.c --replace-fail \ + '"%s/sway-ipc.%u.%i.sock", dir, getuid(), getpid())' \ + '"%s/sway/sway-ipc.sock", dir)' + substituteInPlace sway/server.c --replace-fail \ + '"wayland-%u"' '"wl/wayland-%u"' + ''; + }) ); in { @@ -177,7 +189,7 @@ in sandbox.whitelistDri = true; sandbox.whitelistX = true; # sway invokes xwayland itself sandbox.whitelistWayland = true; - sandbox.extraRuntimePaths = [ "/" ]; # TODO: should need just "sway". but even if i sandbox EVERY entry under run individually, it fails! + sandbox.extraRuntimePaths = [ "sway" ]; sandbox.extraPaths = [ # "/dev/input" "/run/seatd.sock" #< required if not using `logind` systemd login manager @@ -222,7 +234,7 @@ in env.DISPLAY = ":0"; # docs: # N.B.: gtk apps support absolute paths for this; webkit apps (e.g. geary) support only relative paths (relative to $XDG_RUNTIME_DIR) - env.WAYLAND_DISPLAY = "wayland/wayland-1"; + env.WAYLAND_DISPLAY = "wl/wayland-1"; services.sway = { description = "sway: tiling wayland desktop environment"; diff --git a/modules/programs/default.nix b/modules/programs/default.nix index 539db11c..ac8a64c3 100644 --- a/modules/programs/default.nix +++ b/modules/programs/default.nix @@ -464,7 +464,7 @@ let sandbox.extraRuntimePaths = lib.optionals config.sandbox.whitelistAudio [ "pipewire" "pulse" ] # this includes pipewire/pipewire-0-manager: is that ok? ++ lib.optionals (builtins.elem "user" config.sandbox.whitelistDbus) [ "bus" ] - ++ lib.optionals config.sandbox.whitelistWayland [ "wayland" ] # app can still communicate with wayland server w/o this, if it has net access + ++ lib.optionals config.sandbox.whitelistWayland [ "wl" ] # app can still communicate with wayland server w/o this, if it has net access ++ lib.optionals config.sandbox.whitelistS6 [ "s6" ] # TODO: this allows re-writing the services themselves: don't allow that! ; sandbox.extraHomePaths = let