fix(desktop): file dialog on the GTK backend, one portal config
useNautilus = false assigns FileChooser to gtk and drops the nautilus D-Bus registration; the GTK3 dialog then follows the same settings.ini as thunar. The deployed niri-portals.conf is gone: /etc/xdg-desktop-portal/ ranks below /etc/xdg/, where programs.niri writes the same file. Its one extra key, Inhibit=none, moves to desktop.nix.
This commit is contained in:
1 parent
3007656b0f
commit
d26faa091d
3 files changed
+98
-5
No files matched your search
@@ -1,5 +1,61 @@
|
||||
# Decisions
|
||||
|
||||
## 2026-09-25 – One portal config, and the file dialog on the GTK backend
|
||||
|
||||
- **Who**: Dominik, ClaudeCode
|
||||
- **Why**: Firefox's save dialog was drawn in a style that belongs to nothing
|
||||
else on the system — Adwaita buttons and colours — while thunar, the file
|
||||
manager, was themed. Two causes, one behind the other.
|
||||
|
||||
The dialog is not Firefox's own: under Wayland it is requested through
|
||||
`org.freedesktop.impl.portal.FileChooser`, and that interface was unassigned,
|
||||
so the `default=gnome;gtk` line handed it to `xdg-desktop-portal-gnome`. That
|
||||
backend delegates to nautilus, which nixpkgs' niri module registers with D-Bus
|
||||
although the binary is on no `PATH`. Nautilus is GTK4 and libadwaita, and
|
||||
libadwaita draws its own style without reading `gtk-theme-name` from
|
||||
`settings.ini` — so no amount of theming in `modules/theme.nix` could have
|
||||
reached it.
|
||||
|
||||
Behind that: the portal assignment was written in two places. `desktop.nix`
|
||||
deployed moonarch's `niri-portals.conf` to `/etc/xdg-desktop-portal/`, and
|
||||
`programs.niri` had NixOS write its own from `xdg.portal.config.niri` to
|
||||
`/etc/xdg/xdg-desktop-portal/`. `portals.conf(5)` searches every directory in
|
||||
`$XDG_CONFIG_DIRS` — `/etc/xdg` among them — before the build-time sysconfdir
|
||||
`/etc`, so the module's file outranked the deployed one and the file this
|
||||
repo maintained decided nothing. Both carried the same four keys; moonarch's
|
||||
stated a fifth, `Inhibit=none;`, whose effect from the lower-ranked file was
|
||||
never established.
|
||||
- **Tradeoffs**: (1) **Installing nautilus** would have made the dialog a
|
||||
deliberate choice rather than an accident, but it stays unthemeable for the
|
||||
reason above, and it is a second file manager next to thunar. (2) **Keeping
|
||||
moonarch's file as the source** and generating `xdg.portal.config.niri` from
|
||||
it would hold the two distros together, at the price of parsing an ini file
|
||||
in Nix — more code than the assignment itself, for five keys of which four
|
||||
already match what the module sets. (3) **Leaving the deployed copy in place**
|
||||
and only fixing the dialog was rejected: it would have left a file in the tree
|
||||
that looks like the place to change the portal assignment and is not.
|
||||
- **How**: The `environment.etc` entry for `niri-portals.conf` is gone, and with
|
||||
it the `etc` binding in the `let` block, which had no other reader. The whole
|
||||
assignment now comes from `xdg.portal.config.niri`: four keys from
|
||||
`programs.niri`, `FileChooser = "gtk"` from setting
|
||||
`programs.niri.useNautilus = false`, and
|
||||
`org.freedesktop.impl.portal.Inhibit = "none"` restated in `desktop.nix` with
|
||||
moonarch's reasoning carried over in the comment. The option rather than a
|
||||
config key for the file chooser: only the option also drops the nautilus D-Bus
|
||||
registration, and setting the key in both places would collide.
|
||||
|
||||
Verified on the thinkpad host: the generated
|
||||
`/etc/xdg/xdg-desktop-portal/niri-portals.conf` carries all six lines, no
|
||||
second portal config is deployed anywhere, nautilus is out of
|
||||
`services.dbus.packages`, and the system builds.
|
||||
|
||||
`xdg-desktop-portal-gtk` builds the dialog with GTK3 and reads
|
||||
`/etc/xdg/gtk-3.0/settings.ini`, the same file thunar follows. Screencasting
|
||||
keeps the gnome backend: niri serves `org.gnome.Mutter.ScreenCast` itself and
|
||||
that backend is the only caller, which is why it stays in `extraPortals`.
|
||||
Assigning the file chooser to gtk is also what the niri wiki recommends for a
|
||||
setup without nautilus.
|
||||
|
||||
## 2026-09-24 – One topic per module, split out of desktop.nix
|
||||
|
||||
- **Who**: Dominik, ClaudeCode
|
||||
|
||||
@@ -280,6 +280,7 @@ NixOS module owns the destination:
|
||||
| `gtklock/config.ini` | generated, not copied: background and module paths are store paths. Deployed to `/etc/xdg`, which gtklock reads — no `$HOME` seed |
|
||||
| `stasis/stasis.rune` | copied unchanged and seeded into `$HOME`; its four action lines name `moonarch-lock`, which `moonarch-scripts` installs |
|
||||
| `waypaper/config.ini` | wallpaper path, rewritten and seeded into `$HOME` |
|
||||
| `xdg-desktop-portal/niri-portals.conf` | not deployed at all: `programs.niri` writes the same file from `xdg.portal.config.niri` to `/etc/xdg`, which `portals.conf(5)` ranks above the `/etc` copy. The one key moonarch states beyond the module's four is set in `desktop.nix` |
|
||||
| fontconfig defaults | `/etc/fonts/conf.d` is owned by the NixOS module |
|
||||
|
||||
`kanshi/config` is not deployed and kanshi is not installed: niri configures its
|
||||
|
||||
+41
-5
@@ -5,8 +5,6 @@
|
||||
|
||||
let
|
||||
xdg = "${moonarchSrc}/defaults/xdg";
|
||||
etc = "${moonarchSrc}/defaults/etc";
|
||||
|
||||
# waypaper calls `swww`/`swww-daemon`, but the maintained successor ships as
|
||||
# `awww`. The symlinks keep the shared config working unchanged.
|
||||
swww-compat = pkgs.runCommand "swww-compat" { } ''
|
||||
@@ -70,9 +68,13 @@ in
|
||||
# No stasis entry: /etc/stasis/ is only its fallback for a missing user
|
||||
# config, and the seed below means there never is one.
|
||||
|
||||
# Configs that live outside defaults/xdg/ in moonarch as well.
|
||||
"xdg-desktop-portal/niri-portals.conf".source =
|
||||
"${etc}/xdg-desktop-portal/niri-portals.conf";
|
||||
# No xdg-desktop-portal entry: moonarch's niri-portals.conf would be
|
||||
# deployed to /etc/xdg-desktop-portal/, and portals.conf(5) searches that
|
||||
# path — the build-time sysconfdir — only after every directory in
|
||||
# $XDG_CONFIG_DIRS. /etc/xdg is one of those, and it is where NixOS writes
|
||||
# the same file from xdg.portal.config.niri, which programs.niri defines.
|
||||
# The deployed copy would rank below it and decide nothing. What it carries
|
||||
# is set under Portals below instead.
|
||||
};
|
||||
|
||||
# --- Compositor ---
|
||||
@@ -97,10 +99,44 @@ in
|
||||
];
|
||||
|
||||
# --- Portals ---
|
||||
#
|
||||
# The whole assignment lives here, in the one file NixOS writes. programs.niri
|
||||
# defines xdg.portal.config.niri with default=gnome;gtk and Access,
|
||||
# FileChooser, Notification and Secret — the same four moonarch's
|
||||
# niri-portals.conf carries, which is why that file is not deployed; see the
|
||||
# note in environment.etc above. Only what moonarch states beyond them is
|
||||
# restated below.
|
||||
xdg.portal = {
|
||||
enable = true;
|
||||
extraPortals = with pkgs; [ xdg-desktop-portal-gnome xdg-desktop-portal-gtk ];
|
||||
|
||||
# Carried over from moonarch's file verbatim, its reasoning included:
|
||||
# xdg-desktop-portal-gtk reports the Inhibit interface as success even
|
||||
# though nothing implements it under niri, which makes Firefox skip the
|
||||
# native Wayland idle-inhibit. With no backend the browser falls back to
|
||||
# zwp_idle_inhibit, which niri honors, so windowed video keeps the screen
|
||||
# awake. programs.niri leaves this interface unassigned, so stating it here
|
||||
# does not collide with the module's definition.
|
||||
config.niri."org.freedesktop.impl.portal.Inhibit" = "none";
|
||||
};
|
||||
|
||||
# The file dialog every portal client opens — Firefox's save dialog among
|
||||
# them. The option defaults to true, which registers nautilus with D-Bus and
|
||||
# leaves org.freedesktop.impl.portal.FileChooser unassigned, so the
|
||||
# default=gnome;gtk line hands it to xdg-desktop-portal-gnome and the dialog
|
||||
# is nautilus' own: GTK4 and libadwaita, which draw their own style and never
|
||||
# read gtk-theme-name out of settings.ini. That is why the dialog came up in
|
||||
# Adwaita while thunar, a GTK3 program reading /etc/xdg/gtk-3.0/settings.ini,
|
||||
# was themed.
|
||||
#
|
||||
# Off, the module assigns the interface to gtk and drops the nautilus D-Bus
|
||||
# registration; xdg-desktop-portal-gtk then builds the dialog with GTK3 from
|
||||
# that same settings.ini. It is set through the option rather than through
|
||||
# config.niri above because only the option covers the D-Bus half — and
|
||||
# setting the key in both places would collide. Screencasting is unaffected:
|
||||
# niri serves org.gnome.Mutter.ScreenCast itself and only the gnome backend
|
||||
# calls it, which is why that one stays in extraPortals.
|
||||
programs.niri.useNautilus = false;
|
||||
environment.systemPackages = with pkgs; [
|
||||
# XDG plumbing, before anything that calls into it. xdg-terminal-exec
|
||||
# resolves a caller to whichever TerminalEmulator entry the XDG data
|
||||
|
||||
Reference in new issue
Block a user