NixOS / nixpkgs

Nix Packages collection & NixOS
MIT License
18.38k stars 14.33k forks source link

wrong and not configurable fontpath in `xwayland` used by `gdm` #155044

Open fedeinthemix opened 2 years ago

fedeinthemix commented 2 years ago

Describe the bug

The size and type of fonts displayed by xfig is not correct. At startup it gives the error "Can't load font: 8x13bold, using 6x13" and on the console

Warning: Cannot convert string "-*-times-medium-r-normal--16-*-*-*-*-*-*-*,-*-*-medium-r-normal--16-*-*-*-*-*-*-*,*--16-*" to type FontSet
Warning: Missing charsets in String to FontSet conversion
Warning: Cannot convert string "7x13bold" to type FontStruct
Warning: Missing charsets in String to FontSet conversion

Steps To Reproduce

Steps to reproduce the behavior:

  1. install and launch xfig
  2. insert some text

Notify maintainers

@AndersonTorres

Metadata

[user@system:~]$ nix-shell -p nix-info --run "nix-info -m"
 - system: `"x86_64-linux"`
 - host os: `Linux 5.15.4, NixOS, 21.11 (Porcupine)`
 - multi-user?: `yes`
 - sandbox: `yes`
 - version: `nix-env (Nix) 2.4`
 - nixpkgs: `/nix/var/nix/profiles/per-user/root/channels/nixos`
fedeinthemix commented 2 years ago

For some reason now the fonts are displayed correctly. I now only get warnings

Warning: Missing charsets in String to FontSet conversion
Warning: Missing charsets in String to FontSet conversion

but seems to cause no problems.

fedeinthemix commented 2 years ago

Unfortunately this issue is not solved and seems intermittent. Most of the times xfig doesn't find the fonts and sometimes it does. I've attached a screenshot to show the problem. The upper test next to the arrow is 10pt, the bottom one 30pt. This happens both with PS as well as LaTeX fonts.

xfig-font-problem

fedeinthemix commented 2 years ago

I suspect that the problem has to do with the fact that xfig uses URW fonts distributed with ghostscript. I've tried adding

fonts.enableGhostscriptFonts = true;
fonts.fontconfig.allowType1 = true;

without success. The ghostscript path never showed up in the log of Xorg (displayed with journalctl).

Looking at nixos/modules/services/x11/xserver.nix I see

fontsForXServer =
    config.fonts.fonts ++
    # We don't want these fonts in fonts.conf, because then modern,
    # fontconfig-based applications will get horrible bitmapped
    # Helvetica fonts.  It's better to get a substitution (like Nimbus
    # Sans) than that horror.  But we do need the Adobe fonts for some
    # old non-fontconfig applications.  (Possibly this could be done
    # better using a fontconfig rule.)
    [ pkgs.xorg.fontadobe100dpi
      pkgs.xorg.fontadobe75dpi
    ];

It would probably make sense to make the fonts used by the X server, but not by fontconfig programmable with some new option.

@LunNova, @rnhmjoj I see you recently worked on other font issues. Maybe you could be of help here as well.

fedeinthemix commented 2 years ago

I've figured out the root cause of the problem. Here the steps to check it:

In conclusion the xserver configuration passed trough the display-manager.service is ignored! So the problem is not with xfig, but with the xserver systemd configuration.

fedeinthemix commented 2 years ago

@vcunat appears to be the one who introduced GDM_X_SERVER_EXTRA_ARGS and may be able to comment.

rnhmjoj commented 2 years ago

In conclusion the xserver configuration passed trough the display-manager.service is ignored! So the problem is not with xfig, but with the xserver systemd configuration.

But that's the only configuration file! I don't think the display manager is ignoring it: nothing else would work without it.

You could try using another display manager or startx to test this, but I'm pretty sure this is not the issue.

fedeinthemix commented 2 years ago

gdm is now using wayland by default (and I'm using it). I checked with strace and it appears that Xwayland only reads the xkb configuration file, but is not looking for any other X configuration file.

This post came to the same conclusion https://unix.stackexchange.com/questions/433184/how-can-i-configure-xwayland-to-set-notrapsignals-to-the-correct-value.

fedeinthemix commented 2 years ago

As a workaround I'm adding the font path with xset at the beginning of my user session in GDM with .config/autostart/x-ghostscript-fonts.desktop with content

[Desktop Entry]
Name=X11 Gnostscript Fonts
GenericName=X11 Gnostscript Fonts
Comment=XWayland doesn't honor xorg.conf
Exec=/bin/sh -c "xset fp+ /run/current-system/sw/share/ghostscript/fonts/;xset fp rehash"
Terminal=false
StartupNotify=true
Type=Application
Categories=X11;Legacy;Startup

as suggested in https://lzone.de/blog/The-silent-death-of-.xprofile-in-GNOME-3.22.

I'm not closing the issue as IMHO, with the introduction of Wayland, the xserver infrastructure needs some re-work (unless I'm missing something).

LunNova commented 2 years ago

This looks like an upstream Xwayland issue, it doesn't have a way to configure this or support loading a config file as far as I can see.

I'm not familiar enough with its internals to propose a fix.

rnhmjoj commented 2 years ago

gdm is now using wayland by default

Ah, that's it.

This looks like an upstream Xwayland issue, it doesn't have a way to configure this or support loading a config file as far as I can see.

It can be configured, but only at build time IIRC. If you do this

programs.xwayland.enable = true;
fonts.fontDir.enable = true;

xwayland should be rebuilt with a font path pointing to a directory containing all your fonts.

fedeinthemix commented 2 years ago

I've tried adding

programs.xwayland.enable = true;
fonts.fontDir.enable = true;
fonts.enableGhostscriptFonts = true;
fonts.fontconfig.allowType1 = true;

but the URW fonts provided by ghostscript do not appear in /run/current-system/sw/share/X11/fonts/ and Xwayland don't find them. I've also tried adding

  fonts.fonts = [
    pkgs.ghostscript
  ];

with the same result.

rnhmjoj commented 2 years ago

Ok, the problem is the fontdir module doesn't follow symlinks when collecting the fonts. You should be able to workaround that by adding them as

fonts.fonts = [ "${ghostscript}/share/ghostscript/fonts/" ];
fedeinthemix commented 2 years ago

Unfortunately it still doesn't work.

I also tried adding

programs.xwayland.defaultFontPath = "/run/current-system/sw/share/X11/fonts,${pkgs.ghostscript}/share/ghostscript/fonts";

still without luck. In all cases querying the X server with xset -q always reports that it only knows the "built-ins" font paths (without detailing which ones).

fedeinthemix commented 2 years ago

A couple of clarifications:

Still, the X server doesn't seem aware of the fonts (xset -q only shows "built-ins") and xfig doesn't work correctly.

rnhmjoj commented 2 years ago

programs.xwayland.defaultFontPath = "/run/current-system/sw/share/X11/fonts,${pkgs.ghostscript}/share/ghostscript/fonts";

This is not correct: it should be a single path, not a list of comma-separated paths.

After a more careful check I do see the urw fonts in /run/current-system/sw/share/X11/fonts.

Then maybe Xwayland doesn't support this font format? I'm not sure, you should try reporting this over to the X.org devs.

fedeinthemix commented 2 years ago

When I built xwayland with

  programs.xwayland.enable = true;
  fonts.fontDir.enable = true;
  programs.xwayland.defaultFontPath = "/run/current-system/sw/share/X11/fonts,${pkgs.ghostscript}/share/ghostscript/fonts,built-ins";

I took note of the full path: /nix/store/pqad237vf1fg8b6qs2cmvvybbi331w8s-xwayland-21.1.3.

I then switched to the new configuration and, after launching an X application (xfig) I see a different version of xwayland running

ps -ef | grep wayland
alice       2096    2068  0 18:08 tty2     00:00:00 /nix/store/ajbzq5xrvmr7jpg4g538586nwr0r3gaq-gdm-41.0/libexec/gdm-wayland-session /nix/store/9j32fq7qb043n2bxy5dbmxni1ljz20zw-gnome-session-40.1.1/bin/gnome-session
alice       2795    2139  4 18:08 ?        00:00:00 /nix/store/l56lbrg417vj8nyhmn6xi5dyc8gbsgvi-xwayland-21.1.3/bin/Xwayland :0 -rootless -noreset -accessx -core -auth /run/user/1000/.mutter-Xwaylandauth.9JFIJ1 -listenfd 4 -listenfd 5 -displayfd 6 -listenfd 7
alice       2896    2785  0 18:08 pts/0    00:00:00 grep wayland

How is the wayland used by gdm choosing the xwayland to launch?

fedeinthemix commented 2 years ago

This is not correct: it should be a single path, not a list of comma-separated paths.

You may be right. My reasons for believing that a comma separated list is allowed are two: (i) Fedora is using this syntax https://src.fedoraproject.org/rpms/xorg-x11-server-Xwayland/blob/f34/f/xorg-x11-server-Xwayland.spec and (ii) xwayland shares a lot of code with Xorg and the latter allows them in FontPath specifications. I should check source code.

Let's assume that the syntax is indeed wrong. In any case the build is successful. What I do not understand is why the system doesn't use that build of xwayland but another one (different hash).

Then maybe Xwayland doesn't support this font format? I'm not sure, you should try reporting this over to the X.org devs.

The font format is supported as can be verified by adding the path at runtime with xset fb+ /run/current-system/sw/share/ghostscript/fonts; xset fb rehash (having ghostscript installed). With this all is well and xfig displays text with the right fonts.

rnhmjoj commented 2 years ago

You may be right. My reasons for believing that a comma separated list is allowed are two: (i) Fedora is using this syntax https://src.fedoraproject.org/rpms/xorg-x11-server-Xwayland/blob/f34/f/xorg-x11-server-Xwayland.spec and (ii) xwayland shares a lot of code with Xorg and the latter allows them in FontPath specifications. I should check source code.

No, I think you're right: it's just that the default (result of fonts.fontDir.enable) is a single path but it actually need no be one.

why the system doesn't use that build of xwayland but another one (different hash).

Uhm, the programs.xwayland module is simply adding that build to environment.systemPackages. It may be gdm or something has a hardcoded path to xwayland instead of looking a the PATH.

rnhmjoj commented 2 years ago

Indeed: https://github.com/nixos/nixpkgs/blob/master/pkgs/desktops/gnome/core/gdm/fix-paths.patch. Wow, this is pretty stupid.

The only way to override it without rebuilding a whole lot of packages is system.replaceRuntimeDependencies, but it's far from ideal.

fedeinthemix commented 2 years ago

The used xwayland binary uses the following built-in font paths:

/nix/store/vikpqndvdgn7p4bgcrb45jcnfsaycjqh-font-util-1.3.1/share/fonts/X11/misc
/nix/store/vikpqndvdgn7p4bgcrb45jcnfsaycjqh-font-util-1.3.1/share/fonts/X11/TTF
/nix/store/vikpqndvdgn7p4bgcrb45jcnfsaycjqh-font-util-1.3.1/share/fonts/X11/OTF
/nix/store/vikpqndvdgn7p4bgcrb45jcnfsaycjqh-font-util-1.3.1/share/fonts/X11/Type1
/nix/store/vikpqndvdgn7p4bgcrb45jcnfsaycjqh-font-util-1.3.1/share/fonts/X11/100dpi
/nix/store/vikpqndvdgn7p4bgcrb45jcnfsaycjqh-font-util-1.3.1/share/fonts/X11/75dpi

but those directories do not exist!

What do you think of specifying /run/current-system/sw/share/X11/fonts,built-ins instead of "" as the default font path in pkgs/servers/x11/xorg/xwayland.nix

...
, defaultFontPath ? "" }:
...

This way if we set fonts.fontDir.enable = true at least it points to a sensible location without having to rebuild many derivations.

rnhmjoj commented 2 years ago

I'm not too keen on adding NixOS-specific changes to a cross-platform package. If possible, I'd rather add a small patch to read the path from an environment variable or similar mechanism.

fedeinthemix commented 2 years ago

Yeah, it's not optimal. At the moment I can't dig into that code base to prepare a patch. For the moment I'll stick with the workaround that I described earlier.

I would like to ask a couple of questions to improve my NixOS understanding: Is it correct that the intended purpose of programs.xwayland.package (and in general the programs.xxx.package) is to replace the xwayland attribute on NixOS systems? Assuming this is true, what is preventing the fix point xwayland attribute to propagate down to the gdm package? In other words, why is this not happening?

rnhmjoj commented 2 years ago

Is it correct that the intended purpose of programs.xwayland.package (and in general the programs.xxx.package) is to replace the xwayland attribute on NixOS systems?

No, the module is not overriding the pkgs.xwayland attribute. This could be done with an overlay, but it's not recommended because it will cause many packages to be rebuilt.

The new package is simply being added to environment.systemPackages, which is a list of derivations to be symlinked into the system profile. So, when typing xwayland, the patched xwayland will start, but gdm keeps starting the original one because it has a hardcoded reference to it.

fedeinthemix commented 2 years ago

OK. Thanks for all your help!

fedeinthemix commented 2 years ago

Let Gnome maintainers know about this issue @bobby285271 @dasj19 @maxeaubrey

RamKromberg commented 11 months ago

A few caveats:

  1. home-manager's sway package uses pkgs.xwayland so the package generated by fontDir and programs.xwayland.enable isn't being used by the user profile breaking the fix here.
  2. The issue extends beyond just xfig and adobe's base-14 fonts. It also affects ddd (ancient gdb frontend), xfontsel and xlsfonts with access to any fonts beyond the built-ins xwayland is compiled against by default. That is, anything (so old that is) looking for server-side X11 fonts (rather than going via fontconfig) under sway will only have access to the built-ins xwayland provides.
  3. xset's "built-ins" is specific to xset and isn't compatible with the xwayland compilation flag. That is, setting fontDir to defaultFontPath = "/run/current-system/sw/share/X11/fonts,built-ins"; will compile Xwayland with `/run/current-system/sw/share/X11/fonts,built-ins' to override the existing built-ins with a hardcoded string in the binary (used a hex editor to verify) rather than expand the "built-ins". Since I only have the binary available under root I haven't tested it, but I'm guessing it will either crash or silently/vocally fail to resolve the path.
  4. xset fp+ /run/current-system/sw/share/X11/fonts returns an error for me. I suspect it's a permission issue but I'm unsure, in true X tradition, the error doesn't say.
  5. i3 under home-manager isn't affected since it's running under xorg.

Overall, I've personally been unable to get anything in xwayland accessing server-side fonts using the above settings with home-manager.

fedeinthemix commented 2 months ago

I'm still getting an error trying to use fonts.fontDir.enable = true;.

$ xset fp+ /run/current-system/sw/share/X11/fonts/
xset:  bad font path element (#3), possible causes are:
    Directory does not exist or has wrong permissions
    Directory missing fonts.dir
    Incorrect font server address or syntax

If I copy the content of that directory to a directory in my home it works. The symlinks may trigger a different interpretation of the directory content, see Xorg manual.

In any case it looks like Xwayland font path can be configured through an argument. See Xwayland -help.