From 572f348a10826b2207caaf394e9ad2e9ffc6ffa7 Mon Sep 17 00:00:00 2001 From: midchildan Date: Sun, 24 Apr 2022 16:19:56 +0900 Subject: [PATCH] darwin: add support for 'defaults -currentHost' options Closes #2615 --- modules/misc/news.nix | 11 ++ modules/targets/darwin/default.nix | 83 ++----------- .../targets/darwin/user-defaults/default.nix | 112 ++++++++++++++++++ .../opts-allhosts.nix} | 5 +- .../darwin/user-defaults/opts-currenthost.nix | 29 +++++ tests/modules/targets-darwin/default.nix | 1 + .../modules/targets-darwin/user-defaults.nix | 18 +++ 7 files changed, 183 insertions(+), 76 deletions(-) create mode 100644 modules/targets/darwin/user-defaults/default.nix rename modules/targets/darwin/{options.nix => user-defaults/opts-allhosts.nix} (97%) create mode 100644 modules/targets/darwin/user-defaults/opts-currenthost.nix create mode 100644 tests/modules/targets-darwin/user-defaults.nix diff --git a/modules/misc/news.nix b/modules/misc/news.nix index 939917d09..192860bcf 100644 --- a/modules/misc/news.nix +++ b/modules/misc/news.nix @@ -605,6 +605,17 @@ in A new module is available: 'programs.librewolf'. ''; } + + { + time = "2022-07-24T13:17:01+00:00"; + condition = hostPlatform.isDarwin; + message = '' + A new option is available: 'targets.darwin.currentHostDefaults'. + + This exposes macOS preferences that are available through the + 'defaults -currentHost' command. + ''; + } ]; }; } diff --git a/modules/targets/darwin/default.nix b/modules/targets/darwin/default.nix index 4cf295daa..360a3f3d5 100644 --- a/modules/targets/darwin/default.nix +++ b/modules/targets/darwin/default.nix @@ -1,76 +1,13 @@ -{ config, lib, pkgs, ... }: +{ lib, ... }: -with lib; +{ + meta.maintainers = with lib.maintainers; [ midchildan ]; -let - cfg = config.targets.darwin; - - toDefaultsFile = domain: attrs: - pkgs.writeText "${domain}.plist" (lib.generators.toPlist { } attrs); - - toActivationCmd = domain: attrs: - "$DRY_RUN_CMD defaults import ${escapeShellArg domain} ${ - toDefaultsFile domain attrs - }"; - - nonNullDefaults = - mapAttrs (domain: attrs: (filterAttrs (n: v: v != null) attrs)) - cfg.defaults; - writableDefaults = filterAttrs (domain: attrs: attrs != { }) nonNullDefaults; - activationCmds = mapAttrsToList toActivationCmd writableDefaults; -in { - meta.maintainers = [ maintainers.midchildan ]; - - imports = [ ./fonts.nix ./keybindings.nix ./linkapps.nix ./search.nix ]; - - options.targets.darwin.defaults = mkOption { - type = types.submodule ./options.nix; - default = { }; - example = { - "com.apple.desktopservices" = { - DSDontWriteNetworkStores = true; - DSDontWriteUSBStores = true; - }; - }; - description = '' - Set macOS user defaults. Values set to null are - ignored. - - - - Some settings might require a re-login to take effect. - - - ''; - }; - - config = mkIf (activationCmds != [ ]) { - assertions = [ - (hm.assertions.assertPlatform "targets.darwin.defaults" pkgs - platforms.darwin) - ]; - - warnings = let - batteryPercentage = - attrByPath [ "com.apple.menuextra.battery" "ShowPercent" ] null - cfg.defaults; - webkitDevExtras = attrByPath [ - "com.apple.Safari" - "com.apple.Safari.ContentPageGroupIdentifier.WebKit2DeveloperExtrasEnabled" - ] null cfg.defaults; - in optional (batteryPercentage != null) '' - The option 'com.apple.menuextra.battery.ShowPercent' no longer works on - macOS 11 and later. Instead, open System Preferences, go to "Dock & - Menu Bar", select "Battery", and toggle the checkbox labeled "Show - Percentage." - '' ++ optional (webkitDevExtras != null) '' - The option 'com.apple.Safari.com.apple.Safari.ContentPageGroupIdentifier.WebKit2DeveloperExtrasEnabled' - is no longer present in recent versions of Safari. - ''; - - home.activation.setDarwinDefaults = hm.dag.entryAfter [ "writeBoundary" ] '' - $VERBOSE_ECHO "Configuring macOS user defaults" - ${concatStringsSep "\n" activationCmds} - ''; - }; + imports = [ + ./user-defaults + ./fonts.nix + ./keybindings.nix + ./linkapps.nix + ./search.nix + ]; } diff --git a/modules/targets/darwin/user-defaults/default.nix b/modules/targets/darwin/user-defaults/default.nix new file mode 100644 index 000000000..dfb9b61ec --- /dev/null +++ b/modules/targets/darwin/user-defaults/default.nix @@ -0,0 +1,112 @@ +{ config, lib, pkgs, ... }: + +with lib; + +let + cfg = config.targets.darwin; + + mkActivationCmds = isLocal: settings: + let + toDefaultsFile = domain: attrs: + pkgs.writeText "${domain}.plist" (lib.generators.toPlist { } attrs); + + cliFlags = lib.optionalString isLocal "-currentHost"; + + toActivationCmd = domain: attrs: + "$DRY_RUN_CMD defaults ${cliFlags} import ${escapeShellArg domain} ${ + toDefaultsFile domain attrs + }"; + + nonNullDefaults = + mapAttrs (domain: attrs: (filterAttrs (n: v: v != null) attrs)) + settings; + + writableDefaults = + filterAttrs (domain: attrs: attrs != { }) nonNullDefaults; + in mapAttrsToList toActivationCmd writableDefaults; + + defaultsCmds = mkActivationCmds false cfg.defaults; + currentHostDefaultsCmds = mkActivationCmds true cfg.currentHostDefaults; + + activationCmds = defaultsCmds ++ currentHostDefaultsCmds; +in { + meta.maintainers = [ maintainers.midchildan ]; + + options.targets.darwin.defaults = mkOption { + type = types.submodule ./opts-allhosts.nix; + default = { }; + example = { + "com.apple.desktopservices" = { + DSDontWriteNetworkStores = true; + DSDontWriteUSBStores = true; + }; + }; + description = '' + Set macOS user defaults. Values set to null are + ignored. + + + + Some settings might require a re-login to take effect. + + + + + Some settings are only read from + . + + + ''; + }; + + options.targets.darwin.currentHostDefaults = mkOption { + type = types.submodule ./opts-currenthost.nix; + default = { }; + example = { + "com.apple.controlcenter" = { BatteryShowPercentage = true; }; + }; + description = '' + Set macOS user defaults. Unlike , + the preferences will only be applied to the currently logged-in host. This + distinction is important for networked accounts. + + Values set to null are ignored. + + + + Some settings might require a re-login to take effect. + + + ''; + }; + + config = mkIf (activationCmds != [ ]) { + assertions = [ + (hm.assertions.assertPlatform "targets.darwin.defaults" pkgs + platforms.darwin) + ]; + + warnings = let + batteryOptionName = '' + targets.darwin.currentHostDefaults."com.apple.controlcenter".BatteryShowPercentage''; + batteryPercentage = + attrByPath [ "com.apple.menuextra.battery" "ShowPercent" ] null + cfg.defaults; + webkitDevExtras = attrByPath [ + "com.apple.Safari" + "com.apple.Safari.ContentPageGroupIdentifier.WebKit2DeveloperExtrasEnabled" + ] null cfg.defaults; + in optional (batteryPercentage != null) '' + The option 'com.apple.menuextra.battery.ShowPercent' no longer works on + macOS 11 and later. Instead, use '${batteryOptionName}'. + '' ++ optional (webkitDevExtras != null) '' + The option 'com.apple.Safari.com.apple.Safari.ContentPageGroupIdentifier.WebKit2DeveloperExtrasEnabled' + is no longer present in recent versions of Safari. + ''; + + home.activation.setDarwinDefaults = hm.dag.entryAfter [ "writeBoundary" ] '' + $VERBOSE_ECHO "Configuring macOS user defaults" + ${concatStringsSep "\n" activationCmds} + ''; + }; +} diff --git a/modules/targets/darwin/options.nix b/modules/targets/darwin/user-defaults/opts-allhosts.nix similarity index 97% rename from modules/targets/darwin/options.nix rename to modules/targets/darwin/user-defaults/opts-allhosts.nix index 65ce4e011..673997751 100644 --- a/modules/targets/darwin/options.nix +++ b/modules/targets/darwin/user-defaults/opts-allhosts.nix @@ -99,9 +99,8 @@ in { type = types.enum [ "YES" "NO" ]; example = "NO"; description = '' - This option no longer works on macOS 11 and later. Instead, open System - Preferences, go to "Dock & Menu Bar", select "Battery", and toggle - the checkbox labeled "Show Percentage." + This option no longer works on macOS 11 and later. Instead, use + . Whether to show battery percentage in the menu bar. ''; diff --git a/modules/targets/darwin/user-defaults/opts-currenthost.nix b/modules/targets/darwin/user-defaults/opts-currenthost.nix new file mode 100644 index 000000000..129f91487 --- /dev/null +++ b/modules/targets/darwin/user-defaults/opts-currenthost.nix @@ -0,0 +1,29 @@ +{ config, lib, ... }: + +let + mkNullableOption = args: + lib.mkOption (args // { + type = lib.types.nullOr args.type; + default = null; + }); + + mkNullableEnableOption = name: + lib.mkOption { + type = with lib.types; nullOr bool; + default = null; + example = true; + description = "Whether to enable ${name}."; + }; +in { + freeformType = with lib.types; attrsOf (attrsOf anything); + + options = { + "com.apple.controlcenter".BatteryShowPercentage = mkNullableOption { + type = lib.types.bool; + example = true; + description = '' + Whether to show battery percentage in the menu bar. + ''; + }; + }; +} diff --git a/tests/modules/targets-darwin/default.nix b/tests/modules/targets-darwin/default.nix index 10e4111f7..e0cf9be56 100644 --- a/tests/modules/targets-darwin/default.nix +++ b/tests/modules/targets-darwin/default.nix @@ -2,4 +2,5 @@ # Disabled for now due to conflicting behavior with nix-darwin. See # https://github.com/nix-community/home-manager/issues/1341#issuecomment-687286866 #targets-darwin = ./darwin.nix; + user-defaults = ./user-defaults.nix; } diff --git a/tests/modules/targets-darwin/user-defaults.nix b/tests/modules/targets-darwin/user-defaults.nix new file mode 100644 index 000000000..26e0656e8 --- /dev/null +++ b/tests/modules/targets-darwin/user-defaults.nix @@ -0,0 +1,18 @@ +{ lib, ... }: + +{ + config = { + targets.darwin = { + defaults."com.apple.desktopservices".DSDontWriteNetworkStores = true; + currentHostDefaults."com.apple.controlcenter".BatteryShowPercentage = + true; + }; + + nmt.script = '' + assertFileRegex activate \ + "defaults import 'com.apple.desktopservices' /nix/store/[a-z0-9]\\{32\\}-com\\.apple\\.desktopservices\\.plist" + assertFileRegex activate \ + "defaults -currentHost import 'com.apple.controlcenter' /nix/store/[a-z0-9]\\{32\\}-com\\.apple\\.controlcenter\\.plist" + ''; + }; +}