{ lib, config, pkgs, ... }: let enabledExtensions = [] ++ lib.optional config.gnome.extensions.dash-to-dock.enable pkgs.gnomeExtensions.dash-to-dock ++ lib.optional config.gnome.extensions.dash-to-panel.enable pkgs.gnomeExtensions.dash-to-panel; extensions = config.gnome.extraExtensions ++ enabledExtensions; in { options.gnome = { extraWindowControls = lib.mkEnableOption "Should we add back in the minimize and maximize window controls?"; clockFormat = lib.mkOption { type = lib.types.enum [ "12h" "24h" ]; default = "24h"; }; colorScheme = lib.mkOption { type = lib.types.enum [ "default" "prefer-dark" "prefer-light" ]; default = "default"; }; accentColor = lib.mkOption { type = lib.types.enum [ "blue" "teal" "green" "yellow" "orange" "red" "pink" "purple" "slate" ]; default = "blue"; }; extraExtensions = lib.mkOption { type = lib.types.listOf lib.types.package; default = []; description = "The set of extensions to install and enable in the user environment."; }; hotkeys = lib.mkOption { type = lib.types.attrsOf (lib.types.submodule ({name, ...}: { options = { key = lib.mkOption { type = lib.types.strMatching "[a-zA-Z0-9-]+"; default = builtins.replaceStrings [" " "/" "_"] ["-" "-" "-"] name; }; name = lib.mkOption { type = lib.types.str; default = name; }; binding = lib.mkOption { type = lib.types.str; }; command = lib.mkOption { type = lib.types.str; }; }; })); default = {}; }; displayScaling = lib.mkOption { type = lib.types.nullOr (lib.types.enum [100 125 150 175 200]); default = null; description = "Display scaling percentage for GNOME"; }; experimentalFeatures = lib.mkOption { type = lib.types.submodule { options = { scaleMonitorFramebuffer = lib.mkEnableOption "scale-monitor-framebuffer experimental feature"; }; }; default = {}; description = "GNOME experimental features to enable"; }; nightLight = lib.mkOption { type = lib.types.submodule { options = { enable = lib.mkEnableOption "night light (blue light filter)"; automatic = lib.mkOption { type = lib.types.bool; default = true; description = "Whether to automatically schedule night light based on sunset/sunrise"; }; fromTime = lib.mkOption { type = lib.types.float; default = 20.0; description = "Start time for night light in 24-hour format (e.g., 20.0 for 8:00 PM)"; }; toTime = lib.mkOption { type = lib.types.float; default = 6.0; description = "End time for night light in 24-hour format (e.g., 6.0 for 6:00 AM)"; }; temperature = lib.mkOption { type = lib.types.int; default = 4000; description = "Color temperature for night light (1000-10000K, lower is warmer)"; }; }; }; default = {}; description = "Night light configuration"; }; extensions = { dash-to-dock = { enable = lib.mkEnableOption "Dash to Dock extension"; options = lib.mkOption { type = lib.types.nullOr lib.types.attrs; default = null; description = "Dash to Dock configuration options. If null, no custom configuration will be applied."; }; }; dash-to-panel = { enable = lib.mkEnableOption "Dash to Panel extension"; options = lib.mkOption { type = lib.types.nullOr lib.types.attrs; default = null; description = "Dash to Panel configuration options. If null, no custom configuration will be applied."; }; }; }; }; config = { home.packages = extensions; dconf = { settings = lib.mkMerge [ { "org/gnome/shell" = { disable-user-extensions = false; # enables user extensions enabled-extensions = builtins.map (extension: extension.extensionUuid) extensions; }; "org/gnome/desktop/wm/preferences".button-layout = lib.mkIf config.gnome.extraWindowControls ":minimize,maximize,close"; "org/gnome/desktop/interface".color-scheme = config.gnome.colorScheme; "org/gnome/desktop/interface".accent-color = config.gnome.accentColor; "org/gnome/desktop/interface".clock-format = config.gnome.clockFormat; "org/gnome/desktop/interface".text-scaling-factor = lib.mkIf (config.gnome.displayScaling != null) (config.gnome.displayScaling / 100.0); "org/gnome/mutter".experimental-features = lib.mkIf (builtins.any (x: x) (builtins.attrValues config.gnome.experimentalFeatures)) ( lib.optional config.gnome.experimentalFeatures.scaleMonitorFramebuffer "scale-monitor-framebuffer" ); } # Night light configuration (lib.mkIf config.gnome.nightLight.enable { "org/gnome/settings-daemon/plugins/color" = { night-light-enabled = true; night-light-schedule-automatic = config.gnome.nightLight.automatic; night-light-schedule-from = lib.mkIf (!config.gnome.nightLight.automatic) config.gnome.nightLight.fromTime; night-light-schedule-to = lib.mkIf (!config.gnome.nightLight.automatic) config.gnome.nightLight.toTime; night-light-temperature = config.gnome.nightLight.temperature; }; }) ( lib.mkMerge ( builtins.map (value: let entry = "org/gnome/settings-daemon/plugins/media-keys/custom-keybindings/${value.key}"; in { ${entry} = { binding = value.binding; command = value.command; name = value.name; }; "org/gnome/settings-daemon/plugins/media-keys" = { custom-keybindings = [ "/${entry}/" ]; }; }) ( lib.attrsets.mapAttrsToList (_: value: value) config.gnome.hotkeys ) ) ) # Extension configurations (lib.mkIf (config.gnome.extensions.dash-to-dock.enable && config.gnome.extensions.dash-to-dock.options != null) { "org/gnome/shell/extensions/dash-to-dock" = config.gnome.extensions.dash-to-dock.options; }) (lib.mkIf (config.gnome.extensions.dash-to-panel.enable && config.gnome.extensions.dash-to-panel.options != null) { "org/gnome/shell/extensions/dash-to-panel" = config.gnome.extensions.dash-to-panel.options; }) ]; }; }; }