diff --git a/nixos/doc/manual/configuration/x-windows.xml b/nixos/doc/manual/configuration/x-windows.xml
index 06dd7c8bfb94..e0207b5f2ae8 100644
--- a/nixos/doc/manual/configuration/x-windows.xml
+++ b/nixos/doc/manual/configuration/x-windows.xml
@@ -160,6 +160,38 @@
package into your system environment. It should work for all Qt 5 library
versions.
+
+ With help of
+
+ and
+
+ modules you can declaratively set system-wide themes settings.
+
+ gtk.enable = true;
+ gtk.theme = {
+ name = "Adwaita-dark";
+ package = pkgs.gnome-themes-extra;
+ };
+ gtk.iconTheme = {
+ name = "Adwaita";
+ package = pkgs.gnome3.adwaita-icon-theme;
+ };
+ qt.enable = true;
+ qt.platformTheme = "gtk3";
+ qt.style = {
+ name = "adwaita-dark";
+ package = pkgs.adwaita-qt;
+ };
+
+
Custom XKB layouts
diff --git a/nixos/modules/config/gtk/gtk.nix b/nixos/modules/config/gtk/gtk.nix
new file mode 100644
index 000000000000..22f1e5d74835
--- /dev/null
+++ b/nixos/modules/config/gtk/gtk.nix
@@ -0,0 +1,160 @@
+{ config, lib, pkgs, ... }:
+
+with lib;
+
+let
+ cfg = config.gtk;
+ gtk2 = cfg.enable && cfg.gtk2;
+
+ toGtk2File = key: value:
+ let
+ value' =
+ if isBool value then (if value then "true" else "false")
+ else if isString value then "\"${value}\""
+ else toString value;
+ in
+ "${key} = ${value'}";
+ toGtk3File = generators.toINI {
+ mkKeyValue = key: value:
+ let
+ value' =
+ if isBool value then (if value then "true" else "false")
+ else toString value;
+ in
+ "${key}=${value'}";
+ };
+
+ settings =
+ optionalAttrs (cfg.font != null)
+ { gtk-font-name = cfg.font.name; }
+ //
+ optionalAttrs (cfg.theme != null)
+ { gtk-theme-name = cfg.theme.name; }
+ //
+ optionalAttrs (cfg.iconTheme != null)
+ { gtk-icon-theme-name = cfg.iconTheme.name; }
+ //
+ optionalAttrs (cfg.cursorTheme != null)
+ { gtk-cursor-theme-name = cfg.cursorTheme.name; };
+
+ fontType = types.submodule {
+ options = {
+ package = mkOption {
+ internal = true;
+ type = types.nullOr types.package;
+ default = null;
+ };
+ name = mkOption {
+ internal = true;
+ type = types.str;
+ };
+ };
+ };
+ themeType = types.submodule {
+ options = {
+ package = mkOption {
+ internal = true;
+ type = types.nullOr types.package;
+ default = null;
+ };
+ name = mkOption {
+ internal = true;
+ type = types.str;
+ };
+ };
+ };
+
+ optionalPackage = opt:
+ optional (opt != null && opt.package != null) opt.package;
+in
+{
+ options = {
+ gtk = {
+ enable = mkEnableOption "Gtk theming configuration";
+
+ gtk2 = mkOption {
+ type = types.bool;
+ default = true;
+ description = ''
+ Whether to enable theming for obsolete GTK2 engine.
+ '';
+ };
+
+ font = mkOption {
+ type = types.nullOr fontType;
+ default = null;
+ example = literalExample ''
+ {
+ name = "Cantarell 11";
+ package = pkgs.cantarell-fonts;
+ };
+ '';
+ description = ''
+ The font to use in GTK+ applications.
+ '';
+ };
+
+ iconTheme = mkOption {
+ type = types.nullOr themeType;
+ default = null;
+ example = literalExample ''
+ {
+ name = "Adwaita";
+ package = pkgs.gnome3.adwaita-icon-theme;
+ };
+ '';
+ description = "The icon theme to use.";
+ };
+
+ cursorTheme = mkOption {
+ type = types.nullOr themeType;
+ default = null;
+ example = literalExample ''
+ {
+ name = "Adwaita";
+ package = pkgs.gnome3.adwaita-icon-theme;
+ };
+ '';
+ description = "The cursor theme to use.";
+ };
+
+ theme = mkOption {
+ type = types.nullOr themeType;
+ default = null;
+ example = literalExample ''
+ {
+ name = "Adwaita";
+ package = pkgs.gnome-themes-extra;
+ };
+ '';
+ description = "The GTK+ theme to use.";
+ };
+ };
+ };
+
+ config = mkMerge [
+
+ (mkIf gtk2 {
+ environment.etc."xdg/gtk-2.0/gtkrc".text =
+ concatStringsSep "\n" (
+ mapAttrsToList toGtk2File settings
+ );
+ })
+
+ (mkIf cfg.enable {
+ environment.systemPackages =
+ optionalPackage cfg.font
+ ++ optionalPackage cfg.theme
+ ++ optionalPackage cfg.iconTheme
+ ++ optionalPackage cfg.cursorTheme;
+
+ environment.etc."xdg/gtk-3.0/settings.ini".text =
+ toGtk3File { Settings = settings; };
+
+ # TODO: support Wayland/XSettings
+ # once https://github.com/NixOS/nixpkgs/issues/54150 is fixed
+ })
+ ];
+
+ meta.maintainers = [ maintainers.gnidorah ];
+}
diff --git a/nixos/modules/config/qt.nix b/nixos/modules/config/qt.nix
new file mode 100644
index 000000000000..87d07ccfb342
--- /dev/null
+++ b/nixos/modules/config/qt.nix
@@ -0,0 +1,259 @@
+{ config, lib, pkgs, ... }:
+
+with lib;
+
+let
+
+ cfg = config.qt;
+
+ toQtIni = generators.toINI {
+ mkKeyValue = key: value:
+ let
+ value' =
+ if isBool value then (if value then "true" else "false")
+ else toString value;
+ in
+ "${key}=${value'}";
+ };
+
+ general =
+ optionalAttrs (cfg.font != null)
+ {
+ font = cfg.font.name;
+ menuFont = cfg.font.name;
+ toolBarFont = cfg.font.name;
+ }
+ //
+ optionalAttrs (cfg.style != null)
+ { widgetStyle = cfg.style.name; };
+ icons =
+ optionalAttrs (cfg.iconTheme != null)
+ { Theme = cfg.iconTheme.name; };
+
+ qt =
+ optionalAttrs (cfg.font != null)
+ { font = ''"${cfg.font.name}"''; }
+ //
+ { style = "GTK+"; };
+
+ fontType = types.submodule {
+ options = {
+ package = mkOption {
+ internal = true;
+ type = types.nullOr types.package;
+ default = null;
+ };
+ name = mkOption {
+ internal = true;
+ type = types.str;
+ };
+ };
+ };
+ themeType = types.submodule {
+ options = {
+ package = mkOption {
+ internal = true;
+ type = types.nullOr types.package;
+ default = null;
+ };
+ name = mkOption {
+ internal = true;
+ type = types.str;
+ };
+ };
+ };
+
+ optionalPackage = opt:
+ optional (opt != null && opt.package != null) opt.package;
+
+ platforms = {
+ gtk2 = rec {
+ description = ''
+
+ gtk2
+ Use GTK2 theme with
+ qtstyleplugins
+
+
+ '';
+ styles = [ "cleanlooks" "gtk2" "cde" "motif" "plastique" ];
+
+ assertions = [
+ {
+ assertion = cfg.style != null && any (name: name == cfg.style.name) styles;
+ message = "`qt5.style.name` is not one of [ ${toString styles} ].";
+ }
+ {
+ assertion = cfg.font == null && cfg.iconTheme == null;
+ message = "`qt.font` and `qt.iconTheme` are only supported by kde platform.";
+ }
+ ];
+ environment.variables.QT_QPA_PLATFORMTHEME = "gtk2";
+ environment.variables.QT_STYLE_OVERRIDE = cfg.style.name;
+ environment.systemPackages = [ pkgs.libsForQt5.qtstyleplugins ];
+ };
+ qgnomeplatform = {
+ description = ''
+
+ qgnomeplatform
+ Use GNOME theme with
+ qgnomeplatform
+
+
+ '';
+
+ assertions = [
+ {
+ assertion = cfg.font == null && cfg.iconTheme == null;
+ message = "`qt.font` and `qt.iconTheme` are only supported by kde platform.";
+ }
+ ];
+ environment.variables.QT_QPA_PLATFORMTHEME = "qgnomeplatform";
+ # TODO: make this optional once https://github.com/NixOS/nixpkgs/issues/54150 is fixed
+ # qgnomeplatform reads theme and other settings from dconf db
+ environment.variables.QT_STYLE_OVERRIDE = cfg.style.name;
+ environment.variables.XDG_DATA_DIRS = [ "${pkgs.gsettings-desktop-schemas}/share/gsettings-schemas/${pkgs.gsettings-desktop-schemas.name}" ];
+ environment.systemPackages = [ pkgs.qgnomeplatform ];
+ };
+ gtk3 = {
+ description = ''
+
+ gtk3
+ Use GNOME theme with
+ gtk3
+
+
+ '';
+
+ assertions = [
+ {
+ assertion = cfg.style != null;
+ message = "`qt5.platformTheme` gtk3 requires `qt5.style` to be set.";
+ }
+ {
+ assertion = cfg.font == null && cfg.iconTheme == null;
+ message = "`qt.font` and `qt.iconTheme` are only supported by kde platform.";
+ }
+ ];
+ environment.variables.QT_QPA_PLATFORMTHEME = "gtk3";
+ environment.variables.QT_STYLE_OVERRIDE = cfg.style.name;
+ };
+ kde = {
+ description = ''
+
+ kde
+ Use Qt theme with
+ qkdetheme
+
+
+ '';
+
+ environment.variables.XDG_CURRENT_DESKTOP = mkForce "KDE";
+ environment.variables.KDE_SESSION_VERSION = "5";
+ environment.etc."xdg/kdeglobals".text =
+ toQtIni {
+ General = general;
+ Icons = icons;
+ };
+ };
+ };
+in
+
+{
+
+ imports = [
+ (mkRenamedOptionModule [ "qt5" "style" ] [ "qt" "style" ])
+ (mkRenamedOptionModule [ "qt5" "enable" ] [ "qt" "enable" ])
+ (mkRenamedOptionModule [ "qt5" "platformTheme" ] [ "qt" "platformTheme" ])
+ (mkRenamedOptionModule [ "qt5" "font" ] [ "qt" "font" ])
+ (mkRenamedOptionModule [ "qt5" "iconTheme" ] [ "qt" "iconTheme" ])
+ ];
+
+ options = {
+ qt = {
+
+ enable = mkEnableOption "Qt theming configuration";
+
+ qt4 = mkOption {
+ type = types.bool;
+ default = true;
+ description = ''
+ Whether to enable theming for obsolete Qt4 engine.
+ '';
+ };
+
+ platformTheme = mkOption {
+ type = types.enum (attrNames platforms);
+ example = head (attrNames platforms);
+ description = ''
+ Selects the platform theme to use for Qt applications.
+ The options are
+
+ ${concatStrings (mapAttrsToList (name: value: value.description) platforms)}
+
+ '';
+ };
+
+ font = mkOption {
+ type = types.nullOr fontType;
+ default = null;
+ example = literalExample ''
+ {
+ name = "Noto Sans,10,-1,5,50,0,0,0,0,0,Regular";
+ package = pkgs.noto-fonts;
+ }
+ '';
+ description = ''
+ The font to use in Qt applications.
+ '';
+ };
+
+ iconTheme = mkOption {
+ type = types.nullOr themeType;
+ default = null;
+ example = literalExample ''
+ {
+ name = "breeze";
+ package = pkgs.breeze-icons;
+ }
+ '';
+ description = "The icon theme to use.";
+ };
+
+ style = mkOption {
+ type = types.nullOr themeType;
+ default = null;
+ example = literalExample ''
+ {
+ name = "Breeze";
+ package = pkgs.breeze-qt5;
+ };
+ '';
+ description = "The Qt style to use.";
+ };
+
+ };
+ };
+
+ config = mkIf cfg.enable {
+
+ assertions = attrByPath [ cfg.platformTheme "assertions" ] [] platforms;
+
+ environment.variables = attrByPath [ cfg.platformTheme "environment" "variables" ] {} platforms;
+
+ environment.etc = attrByPath [ cfg.platformTheme "environment" "etc" ] {} platforms // {
+ "xdg/Trolltech.conf".text =
+ toQtIni {
+ Qt = qt;
+ };
+ };
+
+ environment.systemPackages = attrByPath [ cfg.platformTheme "environment" "systemPackages" ] [] platforms
+ ++ optionalPackage cfg.font
+ ++ optionalPackage cfg.style
+ ++ optionalPackage cfg.iconTheme;
+
+ };
+
+ meta.maintainers = with maintainers; [ worldofpeace gnidorah ];
+}
diff --git a/nixos/modules/config/qt5.nix b/nixos/modules/config/qt5.nix
deleted file mode 100644
index d9dec74f1552..000000000000
--- a/nixos/modules/config/qt5.nix
+++ /dev/null
@@ -1,102 +0,0 @@
-{ config, lib, pkgs, ... }:
-
-with lib;
-
-let
-
- cfg = config.qt5;
-
- isQGnome = cfg.platformTheme == "gnome" && cfg.style == "adwaita";
- isQtStyle = cfg.platformTheme == "gtk2" && cfg.style != "adwaita";
-
- packages = if isQGnome then [ pkgs.qgnomeplatform pkgs.adwaita-qt ]
- else if isQtStyle then [ pkgs.libsForQt5.qtstyleplugins ]
- else throw "`qt5.platformTheme` ${cfg.platformTheme} and `qt5.style` ${cfg.style} are not compatible.";
-
-in
-
-{
-
- options = {
- qt5 = {
-
- enable = mkEnableOption "Qt5 theming configuration";
-
- platformTheme = mkOption {
- type = types.enum [
- "gtk2"
- "gnome"
- ];
- example = "gnome";
- relatedPackages = [
- "qgnomeplatform"
- ["libsForQt5" "qtstyleplugins"]
- ];
- description = ''
- Selects the platform theme to use for Qt5 applications.
- The options are
-
-
- gtk
- Use GTK theme with
- qtstyleplugins
-
-
-
- gnome
- Use GNOME theme with
- qgnomeplatform
-
-
-
- '';
- };
-
- style = mkOption {
- type = types.enum [
- "adwaita"
- "cleanlooks"
- "gtk2"
- "motif"
- "plastique"
- ];
- example = "adwaita";
- relatedPackages = [
- "adwaita-qt"
- ["libsForQt5" "qtstyleplugins"]
- ];
- description = ''
- Selects the style to use for Qt5 applications.
- The options are
-
-
- adwaita
- Use Adwaita Qt style with
- adwaita
-
-
-
- cleanlooks
- gtk2
- motif
- plastique
- Use styles from
- qtstyleplugins
-
-
-
- '';
- };
- };
- };
-
- config = mkIf cfg.enable {
-
- environment.variables.QT_QPA_PLATFORMTHEME = cfg.platformTheme;
-
- environment.variables.QT_STYLE_OVERRIDE = cfg.style;
-
- environment.systemPackages = packages;
-
- };
-}
diff --git a/nixos/modules/module-list.nix b/nixos/modules/module-list.nix
index 6734929b9d4e..db655f6dc857 100644
--- a/nixos/modules/module-list.nix
+++ b/nixos/modules/module-list.nix
@@ -13,6 +13,7 @@
./config/appstream.nix
./config/console.nix
./config/xdg/sounds.nix
+ ./config/gtk/gtk.nix
./config/gtk/gtk-icon-cache.nix
./config/gnu.nix
./config/i18n.nix
@@ -26,7 +27,7 @@
./config/nsswitch.nix
./config/power-management.nix
./config/pulseaudio.nix
- ./config/qt5.nix
+ ./config/qt.nix
./config/resolvconf.nix
./config/shells-environment.nix
./config/swap.nix
diff --git a/nixos/modules/services/x11/desktop-managers/pantheon.nix b/nixos/modules/services/x11/desktop-managers/pantheon.nix
index b46a2d189ef9..5b3fea845964 100644
--- a/nixos/modules/services/x11/desktop-managers/pantheon.nix
+++ b/nixos/modules/services/x11/desktop-managers/pantheon.nix
@@ -242,9 +242,9 @@ in
programs.zsh.vteIntegration = mkDefault true;
# Harmonize Qt5 applications under Pantheon
- qt5.enable = true;
- qt5.platformTheme = "gnome";
- qt5.style = "adwaita";
+ qt.enable = true;
+ qt.platformTheme = "qgnomeplatform";
+ qt.style.name = "adwaita";
# Default Fonts
fonts.fonts = with pkgs; [