home-manager icon indicating copy to clipboard operation
home-manager copied to clipboard

bug: services.xscreensaver.settings not functioning

Open altsalt opened this issue 6 months ago • 10 comments

Are you following the right branch?

  • [X] My Nixpkgs and Home Manager versions are in sync

Is there an existing issue for this?

  • [X] I have searched the existing issues

Issue description

While enabling xscreensaver via home-manager works, changing the settings doesn't seem to. I've tried with and without a pre-existing .xscreensaver configuration file.

Not entirely unrelated, and I suppose I may open a separate feature request issue if this one closes...

The main settings make sense to be an attribute set, however, toggling "programs" themselves would probably be unsuitable.

I tend to keep a list of ones I'd like enabled, with some having additional settings. Perhaps this could handle such a case via something like services.xscreensaver.programs which takes a set of names to enable and services.xscreensaver.perProgramSettings.

Maintainer CC

@afreakk @ryc

System information

- system: `"x86_64-linux"`
 - host os: `Linux 6.1.68, NixOS, 23.11 (Tapir), 23.11.2082.d02ffbbe834b`
 - multi-user?: `yes`
 - sandbox: `yes`
 - version: `nix-env (Nix) 2.18.1`
 - channels(root): `"nixos-23.11, nixos-hardware, nixos-unstable"`
 - channels(salt): `"home-manager-23.11.tar.gz"`
 - nixpkgs: `/nix/var/nix/profiles/per-user/root/channels/nixos`

altsalt avatar Dec 21 '23 02:12 altsalt

I've been digging and do see a change in xrdb -all -query after running home-manager switch. That said, the changes don't seem to be applying. I'll try to reboot the system and see if this could be something wrong with the reload function.

Also, I think that I've got the programs syntax worked out, though it is pretty clunky for 250 lines... e.g.:

services.xscreensaver.programs = "abstractile --root \\n\\- anemone --root \\n\\anemotaxis --root \\n\\- GL: antmaze --root \\n\\- apollonian --root \\n\\barcode --root \\n\\slidescreen --root --delay2 100000 --duration 10000 --increment 8 --ibw 3 \\n\\"

altsalt avatar Dec 21 '23 18:12 altsalt

Still not responding after a reboot. I also noticed that in my config I was trying to set the textMode and textURL, but it is unclear if those are supported by the Xresources configuration style. Additionally, they were having an issue of not escaping slashes, and when I removed them from the home-manager config, they were left in Xresources until I ran xrdb -remove. I've also changed between timeout = "0:01:00" and timeout = 1 to no effect.

Unsure what else to try and am going back to the .xscreensaver config style but would love to get this working!

altsalt avatar Dec 21 '23 19:12 altsalt

Thank you for your contribution! I marked this issue as stale due to inactivity. Please be considerate of people watching this issue and receiving notifications before commenting 'I have this issue too'. We welcome additional information that will help resolve this issue. Please read the relevant sections below before commenting.

If you are the original author of the issue

  • If this is resolved, please consider closing it so that the maintainers know not to focus on this.
  • If this might still be an issue, but you are not interested in promoting its resolution, please consider closing it while encouraging others to take over and reopen an issue if they care enough.
  • If you know how to solve the issue, please consider submitting a Pull Request that addresses this issue.
If you are not the original author of the issue

  • If you are also experiencing this issue, please add details of your situation to help with the debugging process.
  • If you know how to solve the issue, please consider submitting a Pull Request that addresses this issue.
Memorandum on closing issues

Don't be afraid to manually close an issue, even if it holds valuable information. Closed issues stay in the system for people to search, read, cross-reference, or even reopen – nothing is lost! Closing obsolete issues is an important way to help maintainers focus their time and effort.

stale[bot] avatar Mar 31 '24 06:03 stale[bot]

This is mostly just a bump to say that I too have run into this. Oddly, I see the resource being set correctly. And it looks like xscreensaver is even reading the contents of ~/.Xresources correctly when I start it up manually, but it still isn't abiding by something as simple as changing the mode:

% grep -A2 xscreensaver home/nipsy/richese.nix
  services.xscreensaver.settings = {
    mode = "blank";
  };

% xrdb -query | grep xscreensaver
xscreensaver.mode:      blank

% strace -s 4096 xscreensaver --verbose --no-splash 2>&1 | grep blank
recvmsg(3, {msg_name=NULL, msg_namelen=0, msg_iov=[{iov_base="\1\10\4\0\"\0\0\0\37\0\0\0\0\0\0\0\210\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0Xft.antialias:\t1\nXft.autohint:\t0\nXft.hinting:\t1\nXft.hintstyle:\tslight\nXft.lcdfilter:\tlcddefault\nXft.rgba:\tnone\nxscreensaver.mode:\tblank\n", iov_len=4096}], msg_iovlen=1, msg_controllen=0, msg_flags=0}, 0) = 168

So it's clearly getting fed the correct data seemingly. It's just ignoring it entirely for whatever reason. And based on what I've read, that should only really be happening if xscreensaver itself is finding a .xscreensaver configuration file that's overriding all of this. But I also don't have that in my home directory anywhere and I don't see that the package is providing one globally somehow as part of the package file list anyway.

Hopefully someone can piece together why this is happening.

nipsy avatar Apr 24 '24 17:04 nipsy

I did some more work on this and have found the somewhat confusing following results.

Since options provided through these files support wildcards, I started trying different combinations in a ~/.Xresources file of my own creation. I started with something like:

*fade: false
*mode: blank
*timeout: 1

This worked, but only partially. The fade and mode options actually did apply successfully, but setting the timeout to 1 minute did not work.

From there, I finally landed on:

XScreenSaver.fade: false
XScreenSaver.mode: blank
XScreenSaver.timeout: 1

which again, worked fine for specifying the fade and mode options, but timeout is still ignored as above.

I thought perhaps starting via systemd user service was possibly related, but I stopped the user service and ran it directly from a terminal with xscreensaver --verbose --no-splash, and the behavior was the same. And besides, it IS successfully reading the options even when started by systemd, just not the timeout.

I then tried various capitalizations of timeout, including TimeOut, Timeout, timeOut and timeout, and none of that made any difference, even when simply specifying all of them as wildcards like *timeout: 1.

So at the very minimum here, we obviously need to fix the existing behavior to use XScreenSaver instead of xscreensaver, which will get some of these options actually working for folks. But it would still be nice to know why timeout isn't working and which of the other options which should be configurable by an X resource aren't working as expected. Getting timeout working in general though would be hugely appreciated of course, since it's probably one of the more common options people might want to adjust.

And since this is all related, here's what I'm seeing from the Xserver directly:

% xlsclients -la | grep -B2 XScreenSaver
Window 0x400001:
''  Name:  XScreenSaver Daemon
  Command:  xscreensaver
  Instance/Class:  xscreensaver/XScreenSaver

% xprop -id 0x400001
_SCREENSAVER_ID(STRING) = "21581 (nipsy@ginaz)"
_SCREENSAVER_VERSION(STRING) = "6.08"
WM_COMMAND(STRING) = { "xscreensaver" }
WM_CLASS(STRING) = "xscreensaver", "XScreenSaver"
WM_NAME(STRING) = "XScreenSaver Daemon"

nipsy avatar Apr 27 '24 00:04 nipsy

Thanks for looking into this! I don't use xscreensaver any more so can't help very much but would be happy to accept PRs.

rycee avatar Apr 27 '24 09:04 rycee

I'm pretty sure it's just the following, no?

% diff -urN modules/services/xscreensaver.nix modules/services/xscreensaver.nix.new
--- modules/services/xscreensaver.nix   2024-04-27 03:02:45.688936861 -0700
+++ modules/services/xscreensaver.nix.new       2024-04-27 03:04:52.889248058 -0700
@@ -45,7 +45,7 @@
     home.packages = [ cfg.package ];

     xresources.properties =
-      mapAttrs' (n: nameValuePair "xscreensaver.${n}") cfg.settings;
+      mapAttrs' (n: nameValuePair "XScreenSaver.${n}") cfg.settings;

     systemd.user.services.xscreensaver = {
       Unit = {

nipsy avatar Apr 27 '24 10:04 nipsy

Okay, after spending even more time looking through the source code, I finally pieced together that with the way the xscreensaver daemon is written now, it only ever looks for settings which might affect its own startup in the app-defaults directory in the file XScreenSaver or in the user's home directory in .xscreensaver, but never through the heavier Xrm* function path X11 provides (the RESOURCE_MANAGER property into which xrdb loads our ~/.Xresources basically).

Since I felt like I was losing my mind at this point, I reached out to the original author, Jamie Zawinski, directly to confirm my understanding of this code path, and he confirmed my suspicions:

Correct, the version 6 xscreensaver daemon does not use Xrm. It only reads 7 fields, so it just reads those directly from .xscreensaver, falling back to the app-defaults file or the compile-time defaults.

Version 5 and earlier used Xrm.

Version 6 xscreensaver-gfx and the various hacks *do* use Xrm.

All of which explains why there are so many examples out there where this seemingly all worked as it clearly did in the past for folks and why specifying some options via ~/.Xresources are applied, but others are ignored entirely.

I'm not even sure at this point if there's a clean way to handle any of this. Setting the options directly in ~/.xscreensaver is probably easier at this point rather than trying to go the traditional X resource route. But doing that via home-manager probably isn't tenable necessarily anymore because that would then be a read-only symlink I believe, and you'd still want people to be able to fire up xscreensaver-demo to mess with settings potentially, which will attempt to completely rewrite that file the first time you make a change, and presumably fail miserably at that point with the read-only file.

I'm open to any suggestions though for folks who might have more experience with how situations like this might be handled.

nipsy avatar Apr 28 '24 23:04 nipsy

This issue has been mentioned on NixOS Discourse. There might be relevant details there:

https://discourse.nixos.org/t/potential-limitation-in-handling-user-configuration-via-home-manager-or-otherwise/44379/1

nixos-discourse avatar Apr 29 '24 04:04 nixos-discourse

As mentioned in the linked discourse, home.activation was recommended here as a potential workaround, which works just as much as I need it to:

  home.activation.xscreensaver = lib.hm.dag.entryAfter ["writeBoundary"] ''
    conf=$HOME/.xscreensaver

    if grep -q '^fade:'$'\t' $conf; then
      run sed -i -e 's/^fade:\t.*$/fade:\t\tFalse/' $conf
    else
      run echo -e 'fade:\t\tFalse' >> $conf
    fi

    if grep -q '^mode:'$'\t' $conf; then
      run sed -i -e 's/^mode:\t.*$/mode:\t\trandom/' $conf
    else
      run echo -e 'mode:\t\trandom' >> $conf
    fi

    if grep -q '^splash:'$'\t' $conf; then
      run sed -i -e 's/^splash:\t.*$/splash:\t\tFalse/' $conf
    else
      run echo -e 'splash:\t\tFalse' >> $conf
    fi

    if grep -q '^timeout:'$'\t' $conf; then
      run sed -i -e 's/^timeout:\t.*$/timeout:\t0:10:00/' $conf
    else
      run echo -e 'timeout:\t0:10:00' >> $conf
    fi

    if /run/current-system/sw/bin/systemctl --user --quiet is-active xscreensaver.service; then
      /run/current-system/sw/bin/systemctl --user restart xscreensaver.service
    fi
  '';

Maybe not ideal and kind of ugly, but it captures everything I want it to capture functionality wise, including restarting the user service and modifying any existing options in place if need be or creating everything from scratch otherwise.

This is probably about as solved as this is going to get.

nipsy avatar Apr 29 '24 08:04 nipsy