diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index 55d5239ac558..952cf8275763 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -77,6 +77,8 @@ /modules/programs/git.nix @rycee +/modules/programs/gnome-shell.nix @tadfisher + /modules/programs/gnome-terminal.nix @rycee /modules/programs/go.nix @rvolosatovs diff --git a/modules/misc/news.nix b/modules/misc/news.nix index a94fa6c0e250..9c7730f48b41 100644 --- a/modules/misc/news.nix +++ b/modules/misc/news.nix @@ -2084,6 +2084,14 @@ in A new module is available: 'programs.mangohud'. ''; } + + { + time = "2021-06-13T21:40:02+00:00"; + condition = hostPlatform.isLinux; + message = '' + A new module is available: 'programs.gnome-shell'. + ''; + } ]; }; } diff --git a/modules/modules.nix b/modules/modules.nix index 0e9c4327b85e..1720c30ac926 100644 --- a/modules/modules.nix +++ b/modules/modules.nix @@ -74,6 +74,7 @@ let (loadModule ./programs/getmail.nix { condition = hostPlatform.isLinux; }) (loadModule ./programs/gh.nix { }) (loadModule ./programs/git.nix { }) + (loadModule ./programs/gnome-shell.nix { condition = hostPlatform.isLinux; }) (loadModule ./programs/gnome-terminal.nix { }) (loadModule ./programs/go.nix { }) (loadModule ./programs/gpg.nix { }) diff --git a/modules/programs/gnome-shell.nix b/modules/programs/gnome-shell.nix new file mode 100644 index 000000000000..9d8ed9add822 --- /dev/null +++ b/modules/programs/gnome-shell.nix @@ -0,0 +1,114 @@ +{ config, lib, pkgs, ... }: + +with lib; +let + cfg = config.programs.gnome-shell; + + extensionOpts = { config, ... }: { + options = { + id = mkOption { + type = types.str; + example = "user-theme@gnome-shell-extensions.gcampax.github.com"; + description = '' + ID of the gnome-shell extension. If not provided, it + will be obtained from package.uuid. + ''; + }; + + package = mkOption { + type = types.package; + example = "pkgs.gnome3.gnome-shell-extensions"; + description = '' + Package providing a gnome-shell extension in + $out/share/gnome-shell/extensions/''${id}. + ''; + }; + }; + + config = mkIf (hasAttr "uuid" config.package) { + id = mkDefault config.package.uuid; + }; + }; + + themeOpts = { + options = { + name = mkOption { + type = types.str; + example = "Plata-Noir"; + description = '' + Name of the gnome-shell theme. + ''; + }; + package = mkOption { + type = types.nullOr types.package; + default = null; + example = literalExample "pkgs.plata-theme"; + description = '' + Package providing a gnome-shell theme in + $out/share/themes/''${name}/gnome-shell. + ''; + }; + }; + }; + +in { + meta.maintainers = [ maintainers.tadfisher ]; + + options.programs.gnome-shell = { + enable = mkEnableOption "gnome-shell customization"; + + extensions = mkOption { + type = types.listOf (types.submodule extensionOpts); + default = [ ]; + example = literalExample '' + [ + { package = pkgs.gnomeExtensions.dash-to-panel; } + { + id = "user-theme@gnome-shell-extensions.gcampax.github.com"; + package = pkgs.gnome3.gnome-shell-extensions; + } + ] + ''; + description = '' + List of gnome-shell extensions. + ''; + }; + + theme = mkOption { + type = types.nullOr (types.submodule themeOpts); + default = null; + example = literalExample '' + { + name = "Plata-Noir"; + package = [ pkgs.plata-theme ]; + } + ''; + description = '' + Theme to use for gnome-shell. + ''; + }; + }; + + config = mkIf cfg.enable (mkMerge [ + (mkIf (cfg.extensions != [ ]) { + dconf.settings."org/gnome/shell" = { + disable-user-extensions = false; + enabled-extensions = catAttrs "id" cfg.extensions; + }; + + home.packages = catAttrs "package" cfg.extensions; + }) + + (mkIf (cfg.theme != null) { + dconf.settings."org/gnome/shell/extensions/user-theme".name = + cfg.theme.name; + + programs.gnome-shell.extensions = [{ + id = "user-theme@gnome-shell-extensions.gcampax.github.com"; + package = pkgs.gnome3.gnome-shell-extensions; + }]; + + home.packages = [ cfg.theme.package ]; + }) + ]); +} diff --git a/tests/default.nix b/tests/default.nix index 4ec787280bbc..7b6ce7a94174 100644 --- a/tests/default.nix +++ b/tests/default.nix @@ -100,6 +100,7 @@ import nmt { ./modules/programs/firefox ./modules/programs/foot ./modules/programs/getmail + ./modules/programs/gnome-shell ./modules/programs/i3status-rust ./modules/programs/mangohud ./modules/programs/ncmpcpp-linux diff --git a/tests/modules/programs/gnome-shell/default.nix b/tests/modules/programs/gnome-shell/default.nix new file mode 100644 index 000000000000..58e4598f8e26 --- /dev/null +++ b/tests/modules/programs/gnome-shell/default.nix @@ -0,0 +1 @@ +{ gnome-shell = ./gnome-shell.nix; } diff --git a/tests/modules/programs/gnome-shell/gnome-shell.nix b/tests/modules/programs/gnome-shell/gnome-shell.nix new file mode 100644 index 000000000000..f29b2db17260 --- /dev/null +++ b/tests/modules/programs/gnome-shell/gnome-shell.nix @@ -0,0 +1,91 @@ +{ config, lib, pkgs, ... }: + +with lib; + +let + dummy-gnome-shell-extensions = pkgs.runCommand "dummy-package" { } '' + mkdir -p $out/share/gnome-shell/extensions/dummy-package + touch $out/share/gnome-shell/extensions/dummy-package/test + ''; + + test-extension = pkgs.runCommand "test-extension" { } '' + mkdir -p $out/share/gnome-shell/extensions/test-extension + touch $out/share/gnome-shell/extensions/test-extension/test + ''; + + test-extension-uuid = + pkgs.runCommand "test-extension-uuid" { uuid = "test-extension-uuid"; } '' + mkdir -p $out/share/gnome-shell/extensions/test-extension-uuid + touch $out/share/gnome-shell/extensions/test-extension-uuid/test + ''; + + test-theme = pkgs.runCommand "test-theme" { } '' + mkdir -p $out/share/themes/Test/gnome-shell + touch $out/share/themes/Test/gnome-shell/test + ''; + + expectedEnabledExtensions = [ + "user-theme@gnome-shell-extensions.gcampax.github.com" + "test-extension" + "test-extension-uuid" + ]; + + actualEnabledExtensions = + catAttrs "value" config.dconf.settings."org/gnome/shell".enabled-extensions; + +in { + nixpkgs.overlays = [ + (self: super: { + gnome3 = super.gnome3.overrideScope' (gself: gsuper: { + gnome-shell-extensions = dummy-gnome-shell-extensions; + }); + }) + ]; + + programs.gnome-shell.enable = true; + + programs.gnome-shell.extensions = [ + { + id = "test-extension"; + package = test-extension; + } + { package = test-extension-uuid; } + ]; + + programs.gnome-shell.theme = { + name = "Test"; + package = test-theme; + }; + + assertions = [ + { + assertion = + config.dconf.settings."org/gnome/shell".disable-user-extensions + == false; + message = "Expected disable-user-extensions to be false."; + } + { + assertion = + all (e: elem e actualEnabledExtensions) expectedEnabledExtensions; + message = '' + Expected enabled-extensions to contain all of: + ${toString expectedEnabledExtensions} + But it was: + ${toString actualEnabledExtensions} + ''; + } + { + assertion = + config.dconf.settings."org/gnome/shell/extensions/user-theme".name + == "Test"; + message = "Expected extensions/user-theme/name to be 'Test'."; + } + ]; + + nmt.script = '' + assertFileExists home-path/share/gnome-shell/extensions/dummy-package/test + assertFileExists home-path/share/gnome-shell/extensions/test-extension/test + assertFileExists home-path/share/gnome-shell/extensions/test-extension-uuid/test + assertFileExists home-path/share/themes/Test/gnome-shell/test + ''; +}