stylix icon indicating copy to clipboard operation
stylix copied to clipboard

steam: init with adwaita theme

Open brckd opened this issue 1 year ago • 29 comments

This adds the steam module ~~and its adwaitaForSteam.enable option~~, which installs Adwaita for Steam with the Stylix color palette. This is a slightly modifed version of https://github.com/danth/stylix/issues/551#issuecomment-2486272591 and resolves #551. ~~Note that Adwaita for Steam is installed directly on the host system using an activation script.~~ The theme can be applied using the AdwSteamGTK app.

Preview Adwaita for Steam with the Catppuccin Mocha theme applied by Stylix

Adwaita for Steam preview

@reedrw Are you OK with me using most parts of your suggested code here?

brckd avatar Dec 23 '24 22:12 brckd

In case the uncontained nature of the activation script is a problem, I can try to implement the solution suggested in https://github.com/danth/stylix/issues/551#issuecomment-2378167369.

brckd avatar Dec 25 '24 10:12 brckd

Looking into the install script, it seems that the only file directly overwritten is library.css (located at ~/.local/share/Steam/steamui/css/library.css), while the stylesheets and custom colorscheme are copied directly from the source repo into ~/.local/share/Steam/steamui/adwaita. I think it should be possible to do everything besides library.css purely.

Running the install script in stdenv is quite easy, see proof of concept here:

pkgs.stdenv.mkDerivation (self: {
  name = "Adwaita-for-Steam";
  version = "3.1";

  src = pkgs.fetchFromGitHub {
    owner = "tkashkin";
    repo = "Adwaita-for-Steam";
    rev = "v${self.version}";
    sha256 = "sha256-V2Ps4jP7UeoXTY1q7gLbWVQW9WwUzMM6RPYUvNDAJ0I=";
  };

  buildInputs = with pkgs; [
    python3
  ];

  buildPhase = ''
    mkdir -p $out/steamui/css
    touch $out/steamui/css/library.css
    python3 install.py -t $out
  '';
});

I think running the install script in stdenv is a fairly good way to do things, as it will make it easy to customize the install parameters through our home-manager module

reedrw avatar Dec 27 '24 21:12 reedrw

This looks perfect! It's both flexible by using the official CLI and it's isolated by being wrapped in a derivation. I'll try to integrate your solution into the stylix module tomorrow.

brckd avatar Dec 28 '24 03:12 brckd

it seems that the only file directly overwritten is library.css (located at ~/.local/share/Steam/steamui/css/library.css)

Even better, if this file goes missing, steam will just redownload the stock version, so it should be fine to let home-manager link this as well

Edit: nevermind. Steam will redownload library.css if it is a symlink

reedrw avatar Dec 28 '24 06:12 reedrw

Edit: nevermind. Steam will redownload library.css if it is a symlink

Related comment https://github.com/tkashkin/Adwaita-for-Steam/pull/120#issuecomment-1475856572. I wonder if there is any way to circumvent this, like symlinking a read only parent directory to prevent steam from writing to it. Otherwise, the only option to uninstall the theme might be to run a script that removes the library.css whenever the theme is disabled. Judging from https://github.com/tkashkin/Adwaita-for-Steam/pull/120 it seems like overriding the file wasn't required before, but is now.

Edit: Symlinking parent directories seems to leave steam in a startup loop.

brckd avatar Dec 29 '24 00:12 brckd

@reedw I found the reason this version wasn't working! It seems like the css/library.css file is padded to match the filesize of the same file generated by Steam. This isn't the case in the stdenv because the file generated by Steam isn't provided. This is probably also the reason symlinking didn't work, because the symlink itself doesn't match the filesize of the original file. I will try if we can pad the symlink in the same way to circumvent Steam's check.

Edit: This doesn't seem possible because Home Manager can't read local files in pure evaluation.

brckd avatar Dec 30 '24 19:12 brckd

This is probably also the reason symlinking didn't work

Within bootstrap_log.txt (~/.local/share/Steam/logs/bootstrap_log.txt) I see the following line:

BVerifyInstalledFiles: bad symlink ( steamui/css/library.css -> /nix/store/qdi8s371hjx3c32avyygns388aflgyfk-home-manager-files/.local/share/Steam/steamui/css/library.css, expected non-symlink )

So I assume Steam is not happy with it being a symlink whatsoever

reedrw avatar Dec 31 '24 18:12 reedrw

The only solution I can imagine is to run a specified version of steam to replicate the local configuration and then run the script in the same container.

brckd avatar Jan 01 '25 02:01 brckd

Any way we can conveniently patch Steam or wrap it:

wrapProgram $out/bin/steam \
  --please-work /nix/store/<HASH>-home-manager-files/.local/share/Steam/steamui/css/library.css

trueNAHO avatar Jan 01 '25 18:01 trueNAHO

I'm not familiar with wrapProgram, so what I'm about to say may turn out completely wrong, but I think any attempt automating the generation of Steam's default theme will fail. AFAIK the theme is generated when the Steam GUI first starts up during the Updating Steam dialogue. Since the Steam binary lacks any CLI capabilities, it's impossible to reproducibly control this progress. The dialogue usually takes quite long as well. which would make automating it very inefficient. We would probably have to start Steam and listen for when the theme file is created to stop the application again.

brckd avatar Jan 01 '25 22:01 brckd

I just found this useful information.

Every time you start Steam, it checks the integrity of every file and re-downloads files that have been changed. To prevent this, add the -noverifyfiles and -norepairfiles flags to your steam shortcut

~~Sadly this was the only documentation I found on Steam's CLI capabilities so far.~~ But I was able to confirm that running steam -noverifyfiles -norepairfiles with a non-padded library.css file worked. This solution would successfully install and display the custom theme, but it will miss CSS declaration for components not covered by the custom theme, making the app less usable.

Edit: There is some useful information on Steam's CLI in https://developer.valvesoftware.com/wiki/Command_line_options#Steam

brckd avatar Jan 01 '25 23:01 brckd

I'm not familiar with wrapProgram, so what I'm about to say may turn out completely wrong, but I think any attempt automating the generation of Steam's default theme will fail. AFAIK the theme is generated when the Steam GUI first starts up during the Updating Steam dialogue. Since the Steam binary lacks any CLI capabilities, it's impossible to reproducibly control this progress. The dialogue usually takes quite long as well. which would make automating it very inefficient. We would probably have to start Steam and listen for when the theme file is created to stop the application again.

Forget what I said, SteamCMD seems to be "updating Steam" the same way the GUI does. It even downloads the required theme files. This solves most of the problems I was pointing to. I only have to see if this works without logging in too.

Edit: Derivations don't have access to the internet so this doesn't work.

brckd avatar Jan 01 '25 23:01 brckd

Edit: Derivations don't have access to the internet so this doesn't work.

What I meant by this is that SteamCMD, which is used to generate the library.css required by the theme, requires internet access to fetch its files. This is usually not possible in derivations, but as https://discourse.nixos.org/t/how-do-i-access-internet-inside-nix-build/7671/5 suggests, we could use a fixed-output derivation. But this only works if the returned files always matches the same hash. Sounds like a plan, right?

brckd avatar Jan 04 '25 15:01 brckd

But this only works if the returned files always matches the same hash.

If we fetch an unpinned version, like the latest version, instead of a pinned version, this solution will inevitably break in the future.

Seems like Steam itself is the problem...

Sounds like a plan, right?

@danth, do you know how we could resolve this issue?

trueNAHO avatar Jan 04 '25 16:01 trueNAHO

As it requires internet access, and we don't have a fixed hash, I think the best we can do is run SteamCMD as part of the activation script. This would have to be done in a temporary directory, with sufficient isolation etc. to avoid modifying the real installation. Then once we know the correct file size, pad the generated file and copy it into the real installation.

(This probably shouldn't be enabled by default, as it's quite hacky and slow.)

danth avatar Jan 19 '25 12:01 danth

What is the status of this PR?

trueNAHO avatar Mar 10 '25 15:03 trueNAHO

I kept it working as is, because I use it in my own config, but I'd add isolation and disable the module by default as Daniel suggested.

brckd avatar Mar 10 '25 18:03 brckd

Finally, Adwaita for Steam using just symlinks! Steam startup with Adwaita theme

brckd avatar Mar 11 '25 20:03 brckd

It's been a long way, but in the end I just had to put two and two together.

The big problem I always faced was that Steam would override symlinks. However:

I was able to confirm that running steam -noverifyfiles -norepairfiles with a non-padded library.css file worked.

To automate this, I have overridden the Steam package on NixOS to always run with -noverifyfiles.

https://github.com/danth/stylix/blob/a33b6fe6f16da1042da8f36bf2fd9a5c665993da/modules/steam/nixos.nix#L20-L22

Now I had to make sure the original Steam theme is backed up before it's overridden.

https://github.com/danth/stylix/blob/a33b6fe6f16da1042da8f36bf2fd9a5c665993da/modules/steam/hm.nix#L44-L45

This is the only script that has to run locally. The --no-clobber flag makes it so an existing backup won't be overridden.

Everything else was just about symlinking the correct files.

https://github.com/danth/stylix/blob/a33b6fe6f16da1042da8f36bf2fd9a5c665993da/modules/steam/hm.nix#L52-L58

brckd avatar Mar 11 '25 20:03 brckd

@reedrw Are you OK with me using most parts of your suggested code here?

Ideally, their contribution should be acknowledged by specifying their Git credentials with a Co-authored-by: tag in the commit body.

Don't forget to also do this when eventually merging, because a substantial amount of the module is still their work:

Co-authored-by: Reed <[email protected]>

brckd avatar Mar 11 '25 20:03 brckd

It's been a long way, but in the end I just had to put two and two together.

Amazing job! I didn't think it was possible. The theme itself is now at v3.7 compared to 3.1 when this PR was drafted, Probably worth it to do a quick version bump. Very happy to see a cleaner solution here!

edit: nevermind. looks like the theme is added as a flake input

reedrw avatar Mar 11 '25 22:03 reedrw

Well, one problem with this approach is that this doesn't work if Steam hasn't downloaded its config files before. That's also likely why the app in the testbed fails.

brckd avatar Mar 12 '25 06:03 brckd

Well, one problem with this approach is that this doesn't work if Steam hasn't downloaded its config files before. That's also likely why the app in the testbed fails.

Since this issue seems impossible to resolve, I'd suggest going the route of #1147 where we configure the Adwaita for Steam app and the user has to run it manually.

brckd avatar Jul 03 '25 12:07 brckd

I confirmed that this works! image

For some reason the AdwSteamGTK app isn't styled, but that shouldn't be too important.

image

brckd avatar Jul 05 '25 21:07 brckd

Steam doesn't seem to work on aarch64 (or darwin) so I'll only enable the testbed on x86_64-linux

brckd avatar Oct 15 '25 11:10 brckd

I'm clueless

          error: attribute 'system' missing
              at /nix/store/lqz3v37glkq85ssyl1rv195d1h8ax0vc-source/modules/steam/testbeds/steam.nix:10:14:
                   9|   stylix.testbed = {
                  10|     enable = pkgs.system == "x86_64-linux";
                    |              ^
                  11|     ui.application = {
              Did you mean one of mystem, systemc, systemd, syntex or systemfd?

brckd avatar Oct 15 '25 13:10 brckd

The docs fail to build right after the nix daemon crashes. https://github.com/nix-community/stylix/actions/runs/18564175224/job/52920599560?pr=696#step:6:642

brckd avatar Oct 16 '25 17:10 brckd

I've been using code based on some of this PR for a while now and it's worked perfectly! I'm unsure if it's within scope of this module/stylix as a whole, but I did add an extra check for people who use a modified dconf button layout (such as myself). https://github.com/skiletro/erebus/blob/2f5ecc3e6cf8315a70a2368356eaef15eae9c352/modules/nixos/steam.nix#L14

skiletro avatar Nov 08 '25 15:11 skiletro

I'm unsure if it's within scope of this module/stylix as a whole, but I did add an extra check for people who use a modified dconf button layout (such as myself). https://github.com/skiletro/erebus/blob/2f5ecc3e6cf8315a70a2368356eaef15eae9c352/modules/nixos/steam.nix#L14

Considering

https://github.com/nix-community/stylix/blob/b68e8220689a6f0393204b07be1bc14bb973a0ed/modules/eog/hm.nix#L9-L12

already declares dconf settings, what about declaring the "correct" window controls:

dconf.settings."org/gnome/desktop/wm/preferences".button-layout = "close,minimize,maximize:";

trueNAHO avatar Nov 16 '25 19:11 trueNAHO