{ ... }: {
  flake.nixosModules.desktopGui =
    { config, lib, pkgs, self, inputs, options, ... }:
    let
      pi5Greeter = self.lib.pi5NiriKdl;
      cfg = config.chiasson.desktop;
      guiEnabled = cfg.hyprland.enable || cfg.niri.enable || cfg.plasma.enable;
      hmAvailable = lib.hasAttrByPath [ "home-manager" "sharedModules" ] options;
      dm = cfg.displayManager;
      variant = dm.variant or "sddm";
      useGreeter = variant == "dankgreeter";
      sddmTheme =
        if dm.sddm.theme.package == null then
          "breeze"
        else
          "${dm.sddm.theme.package}/share/sddm/themes/${dm.sddm.theme.id}";
      effectiveDefaultSession =
        if cfg.defaultSession != null then
          cfg.defaultSession
        else if cfg.hyprland.enable then
          "hyprland"
        else if cfg.niri.enable then
          "niri"
        else
          "plasma";
      greeterCompositor =
        if effectiveDefaultSession == "niri" then
          "niri"
        else if effectiveDefaultSession == "hyprland" then
          "hyprland"
        else
          "niri";
      enabledUsers = config.chiasson.users.enabled or [ ];
      greeterConfigHome =
        if dm.greeter.configHome != null then
          dm.greeter.configHome
        else if enabledUsers != [ ] then
          "/home/${builtins.head enabledUsers}"
        else
          null;
    in
    {
      # Unconditional imports only — conditional imports that peek at `config` recurse during merge.
      imports = [
        inputs.dms.nixosModules.greeter
      ];

      config = lib.mkMerge [
        (lib.mkIf guiEnabled {
          services.xserver.enable = true;

          # Chromium/Electron (Edge, Vesktop, etc.) only add native Wayland + IME flags when this is
          # set; nixpkgs wrappers gate on NIXOS_OZONE_WL and WAYLAND_DISPLAY. Helps PipeWire/desktop
          # portal screen capture on wlroots-like sessions. Harmless on X11 (flags stay off).
          environment.sessionVariables.NIXOS_OZONE_WL = lib.mkDefault "1";

          xdg.portal.enable = true;
          xdg.portal.extraPortals =
            [ pkgs.xdg-desktop-portal-gtk ]
            ++ lib.optionals cfg.plasma.enable [ pkgs.kdePackages.xdg-desktop-portal-kde ];

          # Backlight control: `brightnessctl` + its udev rule (auto-loaded from the package's
          # `lib/udev/rules.d`). The rule grants the `video` group write access to
          # `/sys/class/backlight/*/brightness`; the user catalog adds desktop users to `video`.
          # The Hyprland defaults already bind XF86MonBrightness* to brightnessctl, and the Niri
          # base config does the same — this guarantees the binary is actually present.
          environment.systemPackages = [ pkgs.brightnessctl ];
          services.udev.packages = [ pkgs.brightnessctl ];
        })
        (lib.mkIf (guiEnabled && !useGreeter) {
          services.displayManager.sddm = {
            enable = true;
            wayland.enable = dm.sddm.wayland.enable;
            theme = sddmTheme;
            inherit (dm.sddm) enableHidpi settings;
            extraPackages = lib.optionals (dm.sddm.theme.package != null) (
              with pkgs.kdePackages; [
                qtdeclarative
                qtsvg
              ]
            );
          };
          services.displayManager.defaultSession = effectiveDefaultSession;
        })
        (lib.mkIf (guiEnabled && useGreeter) {
          assertions = [
            {
              assertion = greeterConfigHome != null;
              message = "DankGreeter needs chiasson.desktop.displayManager.greeter.configHome or a non-empty chiasson.users.enabled list.";
            }
          ];

          services.displayManager.defaultSession = effectiveDefaultSession;

          programs.dank-material-shell.greeter = {
            enable = true;
            compositor = {
              name = greeterCompositor;
            }
            // lib.optionalAttrs (cfg.niri.raspberryPi5DrmWorkaround && greeterCompositor == "niri") {
              customConfig = lib.mkDefault pi5Greeter.dankGreeterCompositorConfig;
            };
            configHome = greeterConfigHome;
          };
        })
        (lib.mkIf (cfg.defaultPackages.enabled && guiEnabled) {
          environment.systemPackages = cfg.defaultPackages.packages;
        })
        (lib.mkIf (cfg.extraPackages != [ ] && guiEnabled) {
          environment.systemPackages = cfg.extraPackages;
        })
        (lib.mkIf (guiEnabled && cfg.keyring.enable) {
          services.gnome.gnome-keyring.enable = true;
          security.pam.services.login.enableGnomeKeyring = true;
          services.xserver.updateDbusEnvironment = lib.mkDefault true;
          # Electron apps (Element, Slack, etc.) use libsecret via keytar; without it they report
          # "unsupported keyring" even if gnome-keyring is enabled.
          environment.systemPackages = [ pkgs.libsecret ];
        })
        (lib.mkIf (guiEnabled && cfg.keyring.enable && !useGreeter) {
          security.pam.services.sddm.enableGnomeKeyring = true;
        })
        (lib.mkIf (guiEnabled && cfg.keyring.enable && useGreeter) {
          security.pam.services.greetd.enableGnomeKeyring = true;
        })
        (lib.mkIf (guiEnabled && cfg.keyring.enable && hmAvailable) {
          "home-manager".sharedModules = [
            ({ lib, pkgs, ... }: {
              services.gnome-keyring = {
                enable = lib.mkDefault true;
                components = [ "secrets" ];
              };
              home.packages = [
                pkgs.gcr
                pkgs.libsecret
              ];
            })
          ];
        })
      ];
    };
}
