Skip to content

wayland: enable ozone via $NIXOS_OZONE_WL#147557

Merged
wmertens merged 1 commit intoNixOS:masterfrom
wmertens:nixos-ozone
Jan 27, 2022
Merged

wayland: enable ozone via $NIXOS_OZONE_WL#147557
wmertens merged 1 commit intoNixOS:masterfrom
wmertens:nixos-ozone

Conversation

@wmertens
Copy link
Contributor

Motivation for this change

Instead of adding separate wayland packages for Electron and Chrome based applications, allow the user to set the environment variable NIXOS_OZONE=y, which adds the necessary flags at runtime, and only on Wayland.

This way, there is no separate wrapper needed and the functionality can be chosen at runtime.

Things done
  • Built on platform(s)
    • x86_64-linux
    • aarch64-linux
    • x86_64-darwin
    • aarch64-darwin
  • For non-Linux: Is sandbox = true set in nix.conf? (See Nix manual)
  • Tested, as applicable:
  • Tested compilation of all packages that depend on this change using nix-shell -p nixpkgs-review --run "nixpkgs-review rev HEAD". Note: all changes have to be committed, also see nixpkgs-review usage
  • [ x Tested basic functionality of all binary files (usually in ./result/bin/)
  • 21.11 Release Notes (or backporting 21.05 Release notes)
    • (Package updates) Added a release notes entry if the change is major or breaking
    • (Module updates) Added a release notes entry if the change is significant
    • (Module addition) Added a release notes entry if adding a new NixOS module
    • (Release notes changes) Ran nixos/doc/manual/md-to-db.sh to update generated release notes
  • Fits CONTRIBUTING.md.

@ofborg ofborg bot added 8.has: clean-up This PR removes packages or removes other cruft 10.rebuild-darwin: 1-10 This PR causes between 1 and 10 packages to rebuild on Darwin. 10.rebuild-linux: 11-100 This PR causes between 11 and 100 packages to rebuild on Linux. labels Nov 27, 2021
@genofire
Copy link
Contributor

do you miss chromium (and ungoogle-chromium)?

@wmertens
Copy link
Contributor Author

do you miss chromium (and ungoogle-chromium)?

Ah, added it now (but did not test)

Btw arch instead reads the flags from a file https://github.com/archlinux/svntogit-community/blob/packages/electron/trunk/electron-launcher.sh

and for chrom* https://wiki.archlinux.org/title/Chromium#Making_flags_persistent

Hmm that's a good idea, we can do that too. It would mean adding a --run to makeWrapper that sources a generic electron-loading script that defines extra flags.

However, instead of putting a single simple env var, users would have to put a complex line in all those config files. We could have a generic fallback config, but still.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we should add aliases for those.

Copy link
Member

@Artturin Artturin Nov 28, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If it hasn't been in a stable release then it doesn't need an alias so check that first

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Well we probably can't avoid it getting released with 21.11 so that will be a stable release.

The alias should just be a wrapper that sets the environment variable, no biggie.

@SuperSamus SuperSamus mentioned this pull request Nov 30, 2021
13 tasks
@TilCreator
Copy link
Contributor

(Coming from #147945)
Does anyone know if there is a way to make Chrom* compatible with Wayland and Xorg at the same time without needing different variants of packages?
For me that would be the preferred solution. 🤔

@wmertens
Copy link
Contributor Author

(Coming from #147945) Does anyone know if there is a way to make Chrom* compatible with Wayland and Xorg at the same time without needing different variants of packages? For me that would be the preferred solution. 🤔

Isn't this PR exactly that?

@TilCreator
Copy link
Contributor

Bad wording on my part, it doesn't require the separate packages anymore, but you still need to do more than to install chrom*. It would be nice to just start chrom* with Wayland support without breaking Xorg support, I currently have no Xorg setup, so that is why I asked that "dumb" question.

@wmertens
Copy link
Contributor Author

@TilCreator ah - what you need to do is ensure that NIXOS_OZONE=y is in your environment. The reason for that is that ozone support is still not 100% so unless you choose it explicitly, we shouldn't force it for everyone.

@TilCreator
Copy link
Contributor

Ah, explicitly enabling it then should be needed. I would prefer this then over #147945

@wmertens
Copy link
Contributor Author

I'm wondering if I should make this slightly more complex, and make all Cr* projects add a --run ${pkgs.cr-support/prepCr.sh} script that adds a bash array of chrome flags and then --flags "${crFlags[@]}" instead of the current one-liner.

It would allow more complex rules but OTOH it's more magic.

@Tungsten842
Copy link
Member

This should also be enabled for discord/discord-ptb/discord-canary.

@wmertens
Copy link
Contributor Author

wmertens commented Dec 6, 2021

added discord and the wrapper scripts for the 2 *-wayland packages

I think this is good to merge and backport to 21.11.


For the wrapping, it would be nice if there was a less error-prone way of providing the makeWrapper arguments. Perhaps a --plugin ${pkgs.electronWrapSupport} flag to makeWrapper that evaluates the given script at build time and lets it add extra configuration to the wrapper declaration. What do you think @abbradar? Note that that does not block this PR, just a thought.

@github-actions github-actions bot added 6.topic: nixos Issues or PRs affecting NixOS modules, or package usability issues specific to NixOS 8.has: changelog This PR adds or changes release notes 8.has: documentation This PR adds or changes documentation labels Dec 6, 2021
@wmertens
Copy link
Contributor Author

wmertens commented Dec 7, 2021

so - anyone opposed to merging this?

@Synthetica9
Copy link
Member

I'm trying to adapt nixosTests.vscodium.wayland to use this, and it somehow dumps core D:

diff --git a/nixos/tests/vscodium.nix b/nixos/tests/vscodium.nix
index 43a0d61c856..f10effe2790 100644
--- a/nixos/tests/vscodium.nix
+++ b/nixos/tests/vscodium.nix
@@ -4,11 +4,17 @@ let
       imports = [ ./common/wayland-cage.nix ];
 
       services.cage.program = ''
-        ${pkgs.vscodium}/bin/codium \
-          --enable-features=UseOzonePlatform \
-          --ozone-platform=wayland
+        ${pkgs.vscodium}/bin/codium
       '';
 
+      environment.variables.NIXOS_OZONE = "y";
+
+      nixpkgs.overlays = [
+        (self: super: {
+          cage = super.cage.override { xwayland = null; };
+        })
+      ];
+
       fonts.fonts = with pkgs; [ dejavu_fonts ];
     };
     xorg = { pkgs, ... }: {
(finished: sending monitor command: screendump /build/tmpfgchet8s/ppm, in 0.01 seconds)
wayland # [   18.254489] systemd[1]: Created slice Slice /system/systemd-coredump.
wayland # [   18.261805] systemd[1]: Started Process Core Dump (PID 945/UID 0).
wayland # [   18.689134] systemd-coredump[946]: Process 927 (codium) of user 1000 dumped core.
wayland # [   18.732325] systemd[1]: [email protected]: Deactivated successfully.
wayland # [   18.849545] systemd-logind[657]: Session c1 logged out. Waiting for processes to exit.
wayland # [   18.865381] systemd[1]: cage-tty1.service: Deactivated successfully.

Any idea what could be going on here?

@wmertens
Copy link
Contributor Author

wmertens commented Dec 7, 2021

@Synthetica9 thanks for checking that! Are you sure the test doesn't just dump core without the change? Could you add a env to the program so we can see what the environment variables are?

I must say I'm mystified how this could cause a coredump, it should be the exact same behavior :-/

@Synthetica9
Copy link
Member

@Synthetica9 thanks for checking that! Are you sure the test doesn't just dump core without the change? Could you add a env to the program so we can see what the environment variables are?

I must say I'm mystified how this could cause a coredump, it should be the exact same behavior :-/

Yep, when I just run it unmodified (or with only the overlay) it works on this PR. I'm also quite flabbergasted on the how and why of this crash tbh

@wmertens
Copy link
Contributor Author

wmertens commented Dec 7, 2021

@Synthetica9 can you change the program to bash -xv ${pkgs.vscodium}/bin/codium? Then we should be able to see what command it ends up executing.

@primeos
Copy link
Member

primeos commented Jan 26, 2022

It might not be worth dropping --enable-features=UseOzonePlatform as some older Electron apps probably won't have this set by default.

Sure, that's a possibility, but then again it'd also be surprising if those Electron apps would still work on modern Wayland compositors. They won't work with wlroots 0.15 (https://bugs.chromium.org/p/chromium/issues/detail?id=1279574), other compositors will follow soon, and for such old Ozone/Wayland revisions there could be additional incompatibilities.

@brandonweeks
Copy link
Contributor

It feels like --ozone-platform-hint will supersede this in the near future?

https://chromium-review.googlesource.com/c/chromium/src/+/3188974

@Enzime
Copy link
Member

Enzime commented Jan 26, 2022

Sure, that's a possibility, but then again it'd also be surprising if those Electron apps would still work on modern Wayland compositors. They won't work with wlroots 0.15 (https://bugs.chromium.org/p/chromium/issues/detail?id=1279574), other compositors will follow soon, and for such old Ozone/Wayland revisions there could be additional incompatibilities.

I just tested VS Code and it requires both flags to render with Wayland natively and it seems to work fine without crashing.

@wmertens wmertens changed the title wayland: enable ozone via $NIXOS_OZONE wayland: enable ozone via $NIXOS_OZONE_WAYLAND Jan 27, 2022
Chrome, Chromium, VSCode, Slack, Signal, Discord, element-desktop,
schildichat.

For the latter two, the feature flag useWayland was removed and a
wrapper script was provided.
@wmertens wmertens changed the title wayland: enable ozone via $NIXOS_OZONE_WAYLAND wayland: enable ozone via $NIXOS_OZONE_WL Jan 27, 2022
@wmertens
Copy link
Contributor Author

Ok I renamed the flag to NIXOS_OZONE_WL=1 to keep it a little shorter.

Good to go?

Copy link
Member

@primeos primeos left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok I renamed the flag to NIXOS_OZONE_WL=1 to keep it a little shorter.

Not sure if that's a good idea but it shouldn't really matter anyway so ¯_(ツ)_/¯

From a quick glance the diff looks ok (I haven't done any testing though).

And this is certainly much better than adding separate -wayland packages :)

@Enzime and thanks for testing if --enable-features=UseOzonePlatform is required. Seems like I was wrong and that change is still too recent.

@wmertens
Copy link
Contributor Author

@primeos there is a test and it passes, so merging. In case of trouble we can still revert :)

@wmertens wmertens merged commit ecd6b28 into NixOS:master Jan 27, 2022
@wmertens wmertens deleted the nixos-ozone branch January 27, 2022 22:46
@primeos
Copy link
Member

primeos commented Jan 27, 2022

@wmertens ok, thanks for your work and seeing this through! :)

@eddyb
Copy link
Contributor

eddyb commented Jan 29, 2022

This doesn't work as intended. This syntax:

--add-flags "\''${NIXOS_OZONE_WL:+\''${WAYLAND_DISPLAY:+--enable-features=UseOzonePlatform --ozone-platform=wayland}}"

checks the variables are set at build time not runtime. You can see this behavior if you run the build manually:

$ cd $(mktemp -d)
$ nix-shell '<nixpkgs>' -A chromium --pure --run 'source $stdenv/setup; out=. sandbox=./sandbox NIXOS_OZONE_WL=1 WAYLAND_DISPLAY=1 genericBuild'

Builder called die: makeWrapper doesn't understand the arg --ozone-platform=wayland

And if those env vars are not set at build time (which they probably never would be), nothing gets appended.

I believe this needs to use the double-escaping used elsewhere:

--add-flags ${escapeShellArg (escapeShellArg commandLineArgs)}

in order to have a chance to work, that is.

EDIT: most of the above is wrong in the general case, it turns out that double-escaping is only needed for chromium because it's just a wrapper package and uses buildCommand does weird stuff idk (see #147557 (comment)).

@wmertens
Copy link
Contributor Author

Odd, I did test it. I'll investigate.

@primeos
Copy link
Member

primeos commented Jan 29, 2022

Oh, right, strange...
Not sure how the current situation looks but now that @eddyb mentions it (thanks!) I remember that I had this problem once too.

Back then I didn't find an elegant solution due to the way wrapProgram is implemented (not sure if that's still the case) and resorted to the following hack for Telegram-Desktop:

--set XDG_RUNTIME_DIR "XDG-RUNTIME-DIR"
sed -i $out/bin/telegram-desktop \
-e "s,'XDG-RUNTIME-DIR',\"\''${XDG_RUNTIME_DIR:-/run/user/\$(id --user)}\","

There's hopefully a better alternative available.

@wmertens
Copy link
Contributor Author

@eddyb are you seeing it not work somewhere? It's working correctly for me with vscode and google-chrome-stable.

@primeos
Copy link
Member

primeos commented Jan 31, 2022

Ah, interesting, I've only tested it with Chromium but e.g. Signal-Desktop works:

$ git rev-parse HEAD
5bb20f9dc70e9ee16e21cc404b6508654931ce41
$ tail -n1 $(nix-build -A chromium)/bin/chromium
gq7rrhd10df-chromium-unwrapped-97.0.4692.99/libexec/chromium/chromium"    "$@"
$ tail -n1 $(nix-build -A signal-desktop)/bin/signal-desktop
exec -a "$0" "/nix/store/k7cjv6sg0pqqrdqlm6abv6vyxw9kgp49-signal-desktop-5.29.1/bin/.signal-desktop-wrapped"  ${NIXOS_OZONE_WL:+${WAYLAND_DISPLAY:+--enable-features=UseOzonePlatform --ozone-platform=wayland}} "$@"

Looks like it works via $gappsWrapperArgs:

diff --git a/pkgs/applications/networking/browsers/google-chrome/default.nix b/pkgs/applications/networking/browsers/google-chrome/default.nix
index e93ea8ca66d..b0fc87a1801 100644
--- a/pkgs/applications/networking/browsers/google-chrome/default.nix
+++ b/pkgs/applications/networking/browsers/google-chrome/default.nix
@@ -142,8 +142,9 @@ in stdenv.mkDerivation {
     makeWrapper "$out/share/google/$appname/google-$appname" "$exe" \
       --prefix LD_LIBRARY_PATH : "$rpath" \
       --prefix PATH            : "$binpath" \
-      --prefix XDG_DATA_DIRS   : "$XDG_ICON_DIRS:$GSETTINGS_SCHEMAS_PATH:${addOpenGLRunpath.driverLink}/share" \
-      --add-flags ${escapeShellArg commandLineArgs}
+      --prefix XDG_DATA_DIRS   : "$XDG_ICON_DIRS:$GSETTINGS_SCHEMAS_PATH" \
+      --add-flags ${escapeShellArg commandLineArgs} \
+      --add-flags "\''${NIXOS_OZONE_WL:+\''${WAYLAND_DISPLAY:+--enable-features=UseOzonePlatform --ozone-platform=wayland}}"

     for elf in $out/share/google/$appname/{chrome,chrome-sandbox,${crashpadHandlerBinary},nacl_helper}; do
       patchelf --set-rpath $rpath $elf
diff --git a/pkgs/applications/networking/instant-messengers/signal-desktop/default.nix b/pkgs/applications/networking/instant-messengers/signal-desktop/default.nix
index f1bcd101279..22440d71805 100644
--- a/pkgs/applications/networking/instant-messengers/signal-desktop/default.nix
+++ b/pkgs/applications/networking/instant-messengers/signal-desktop/default.nix
@@ -123,6 +123,7 @@ in stdenv.mkDerivation rec {
     gappsWrapperArgs+=(
       --prefix LD_LIBRARY_PATH : "${lib.makeLibraryPath [ stdenv.cc.cc ] }"
       ${customLanguageWrapperArgs}
+      --add-flags "\''${NIXOS_OZONE_WL:+\''${WAYLAND_DISPLAY:+--enable-features=UseOzonePlatform --ozone-platform=wayland}}"
     )

     # Fix the desktop link

Seems like I also missed that you've dropped ${addOpenGLRunpath.driverLink}/share for google-chrome. That needs to be reverted. Edit: I've opened #157554.

@eddyb
Copy link
Contributor

eddyb commented Jan 31, 2022

@eddyb are you seeing it not work somewhere? It's working correctly for me with vscode and google-chrome-stable.

I was testing with the chromium package - since it seemed like the same line got copy-pasted everywhere, I didn't expect it to work anywhere, but maybe the context is subtly different?

EDIT: okay, yeah, rereading the comment above, gappsWrapperArgs+=( is very likely giving you one extra level of escapeShellArg to make it work. Ideally this would always be added to a Nix "wrapper args" variable instead of directly inline.

Copy link
Contributor

@eddyb eddyb left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks like 6/8 are likely broken (left comments), only Signal and VSCode (the main ones mentioned being tested) seem to be correct.

EDIT: I was wrong, see #147557 (comment)

Comment on lines 82 to +83
"''${gappsWrapperArgs[@]}" \
--add-flags "\''${NIXOS_OZONE_WL:+\''${WAYLAND_DISPLAY:+--enable-features=UseOzonePlatform --ozone-platform=wayland}}" \

This comment was marked as off-topic.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unfortunately wrapGAppsHook is AFAIK (and I lack knowledge in that area) only intended for GNOME applications (does a lot more). But I think it's often also used for GTK applications in general so that's probably why it's used for some Electron apps. It'd probably be a good idea to investigate if it's usage is appropriate for Chromium/Electron or not and use a consistent approach - but that deserves a dedicated issue.

Anyway, the implementation, for reference:

wrapProgram "$program" "${gappsWrapperArgs[@]}" "$@"

Comment on lines 185 to +187
eval makeWrapper "${browserBinary}" "$out/bin/chromium" \
--add-flags ${escapeShellArg (escapeShellArg commandLineArgs)}
--add-flags ${escapeShellArg (escapeShellArg commandLineArgs)} \
--add-flags "\''${NIXOS_OZONE_WL:+\''${WAYLAND_DISPLAY:+--enable-features=UseOzonePlatform --ozone-platform=wayland}}"

This comment was marked as off-topic.

Copy link
Member

@primeos primeos Jan 31, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We shouldn't use commandLineArgs itself as that isn't extendable (we could only set a default which is probably not how it should be - also has some advantages though) but we could use the same escapeShellArg based approach.

Comment on lines 142 to +147
makeWrapper "$out/share/google/$appname/google-$appname" "$exe" \
--prefix LD_LIBRARY_PATH : "$rpath" \
--prefix PATH : "$binpath" \
--prefix XDG_DATA_DIRS : "$XDG_ICON_DIRS:$GSETTINGS_SCHEMAS_PATH:${addOpenGLRunpath.driverLink}/share" \
--add-flags ${escapeShellArg commandLineArgs}
--prefix XDG_DATA_DIRS : "$XDG_ICON_DIRS:$GSETTINGS_SCHEMAS_PATH" \
--add-flags ${escapeShellArg commandLineArgs} \
--add-flags "\''${NIXOS_OZONE_WL:+\''${WAYLAND_DISPLAY:+--enable-features=UseOzonePlatform --ozone-platform=wayland}}"

This comment was marked as off-topic.

Copy link
Contributor

@eddyb eddyb Jan 31, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This one is weird, and I guess it might explain why it's not broken (IIUC one of the comments).
It only seems to need escapeShellArg once for commandLineArgs instead of twice, is there a second escaping elsewhere?

The only difference I can see is this is in installPhase but chromium is in buildCommand? (EDIT: it was eval)

@eddyb
Copy link
Contributor

eddyb commented Jan 31, 2022

@wmertens Ugh, sorry for all the noise, it might just be chromium. In #147557 (comment) I noticed something I had missed before, and went back to check, and chromium is the only one that uses buildCommand, which could explain why it needs double-escaping.

(Frankly the entire buildCommand could probably be wrapped in a single escapeShellArg to make it equivalent to installPhase in other packages)

EDIT: wait, it's doing eval makeWrapper while other scripts are doing makeWrapper?
Is it not buildCommand vs installCommand but rather an unnecessary(?) eval??

@eddyb
Copy link
Contributor

eddyb commented Jan 31, 2022

@primeos Regarding reusing commandLineArgs, I was mostly just imagining something like this:

let commandLineArgs =
  "${commandLineArgs} \${NIXOS_OZONE_WL:+\${WAYLAND_DISPLAY:+--enable-features=UseOzonePlatform --ozone-platform=wayland}}";

(i.e. not changing commandLineArgs at its origin, but creating a longer string locally)

(not sure about the escaping syntax, but at least if it was always done in Nix, it should be possible to remain consistent and avoid weird shell escaping syntax)

@wmertens
Copy link
Contributor Author

wmertens commented Feb 2, 2022

@eddyb good catch on the eval! I removed it and things seem to work fine in #157835

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

6.topic: nixos Issues or PRs affecting NixOS modules, or package usability issues specific to NixOS 8.has: changelog This PR adds or changes release notes 8.has: clean-up This PR removes packages or removes other cruft 8.has: documentation This PR adds or changes documentation 10.rebuild-darwin: 1-10 This PR causes between 1 and 10 packages to rebuild on Darwin. 10.rebuild-linux: 11-100 This PR causes between 11 and 100 packages to rebuild on Linux.

Projects

None yet

Development

Successfully merging this pull request may close these issues.