Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
343 changes: 52 additions & 291 deletions modules/misc/gtk.nix
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@

let
inherit (lib)
literalExpression
mkEnableOption
mkIf
mkOption
optionalAttrs
types
;

Expand All @@ -13,313 +13,74 @@ let
cfg3 = config.gtk.gtk3;
cfg4 = config.gtk.gtk4;

toGtk3Ini = lib.generators.toINI {
mkKeyValue =
key: value:
let
value' = if lib.isBool value then lib.boolToString value else toString value;
in
"${lib.escape [ "=" ] key}=${value'}";
};

formatGtk2Option =
n: v:
let
v' =
if lib.isBool v then
lib.boolToString lib.value
else if lib.isString v then
''"${v}"''
else
toString v;
in
"${lib.escape [ "=" ] n} = ${v'}";

themeType = types.submodule {
options = {
package = mkOption {
type = types.nullOr types.package;
default = null;
example = literalExpression "pkgs.gnome.gnome-themes-extra";
description = ''
Package providing the theme. This package will be installed
to your profile. If `null` then the theme
is assumed to already be available in your profile.
gtkLib = import ./gtk/lib.nix { inherit lib; };

For the theme to apply to GTK 4, this option is mandatory.
'';
};

name = mkOption {
type = types.str;
example = "Adwaita";
description = "The name of the theme within the package.";
};
};
themeType = gtkLib.mkThemeType {
typeName = "theme";
packageExample = "pkgs.gnome.gnome-themes-extra";
};

iconThemeType = types.submodule {
options = {
package = mkOption {
type = types.nullOr types.package;
default = null;
example = literalExpression "pkgs.adwaita-icon-theme";
description = ''
Package providing the icon theme. This package will be installed
to your profile. If `null` then the theme
is assumed to already be available in your profile.
'';
};

name = mkOption {
type = types.str;
example = "Adwaita";
description = "The name of the icon theme within the package.";
};
};
iconThemeType = gtkLib.mkThemeType {
typeName = "icon theme";
packageExample = "pkgs.adwaita-icon-theme";
};

cursorThemeType = types.submodule {
options = {
package = mkOption {
type = types.nullOr types.package;
default = null;
example = literalExpression "pkgs.vanilla-dmz";
description = ''
Package providing the cursor theme. This package will be installed
to your profile. If `null` then the theme
is assumed to already be available in your profile.
'';
};

name = mkOption {
type = types.str;
example = "Vanilla-DMZ";
description = "The name of the cursor theme within the package.";
};

size = mkOption {
type = types.nullOr types.int;
default = null;
example = 16;
description = ''
The size of the cursor.
'';
};
};
cursorThemeType = gtkLib.mkThemeType {
typeName = "cursor theme";
hasSize = true;
packageExample = "pkgs.vanilla-dmz";
nameExample = "Vanilla-DMZ";
};

in

{
meta.maintainers = [ lib.maintainers.rycee ];
meta.maintainers = with lib.maintainers; [
khaneliman
rycee
];

imports = [
(lib.mkRemovedOptionModule [ "gtk" "gtk3" "waylandSupport" ] ''
This options is not longer needed and can be removed.
'')
./gtk/gtk2.nix
./gtk/gtk3.nix
./gtk/gtk4.nix
];

options = {
gtk = {
enable = lib.mkEnableOption "GTK 2/3 configuration";

font = mkOption {
type = types.nullOr lib.hm.types.fontType;
default = null;
description = ''
The font to use in GTK+ 2/3 applications.
'';
};

cursorTheme = mkOption {
type = types.nullOr cursorThemeType;
default = null;
description = "The cursor theme to use.";
};

iconTheme = mkOption {
type = types.nullOr iconThemeType;
default = null;
description = "The icon theme to use.";
};

theme = mkOption {
type = types.nullOr themeType;
default = null;
description = "The GTK+2/3 theme to use.";
};

gtk2 = {
extraConfig = mkOption {
type = types.lines;
default = "";
example = "gtk-can-change-accels = 1";
description = ''
Extra configuration lines to add verbatim to
{file}`~/.gtkrc-2.0`.
'';
};

configLocation = mkOption {
type = types.path;
default = "${config.home.homeDirectory}/.gtkrc-2.0";
defaultText = literalExpression ''"''${config.home.homeDirectory}/.gtkrc-2.0"'';
example = literalExpression ''"''${config.xdg.configHome}/gtk-2.0/gtkrc"'';
description = ''
The location to put the GTK configuration file.
'';
};
options.gtk = {
enable = mkEnableOption "GTK theming and configuration";

force = lib.mkEnableOption "GTK 2 config force overwrite without creating a backup";
};

gtk3 = {
bookmarks = mkOption {
type = types.listOf types.str;
default = [ ];
example = [ "file:///home/jane/Documents" ];
description = "Bookmarks in the sidebar of the GTK file browser";
};

extraConfig = mkOption {
type =
with types;
attrsOf (oneOf [
bool
int
str
]);
default = { };
example = {
gtk-cursor-blink = false;
gtk-recent-files-limit = 20;
};
description = ''
Extra configuration options to add to
{file}`$XDG_CONFIG_HOME/gtk-3.0/settings.ini`.
'';
};
# Global settings that act as defaults for version-specific settings
font = mkOption {
type = types.nullOr lib.hm.types.fontType;
default = null;
description = "Default font for all GTK versions.";
};

extraCss = mkOption {
type = types.lines;
default = "";
description = ''
Extra configuration lines to add verbatim to
{file}`$XDG_CONFIG_HOME/gtk-3.0/gtk.css`.
'';
};
};
theme = mkOption {
type = types.nullOr themeType;
default = null;
description = "Default theme for all GTK versions.";
};

gtk4 = {
extraConfig = mkOption {
type = with types; attrsOf (either bool (either int str));
default = { };
example = {
gtk-cursor-blink = false;
gtk-recent-files-limit = 20;
};
description = ''
Extra configuration options to add to
{file}`$XDG_CONFIG_HOME/gtk-4.0/settings.ini`.
'';
};
iconTheme = mkOption {
type = types.nullOr iconThemeType;
default = null;
description = "Default icon theme for all GTK versions.";
};

extraCss = mkOption {
type = types.lines;
default = "";
description = ''
Extra configuration lines to add verbatim to
{file}`$XDG_CONFIG_HOME/gtk-4.0/gtk.css`.
'';
};
};
cursorTheme = mkOption {
type = types.nullOr cursorThemeType;
default = null;
description = "Default cursor theme for all GTK versions.";
};
};

config = lib.mkIf cfg.enable (
let
gtkIni =
optionalAttrs (cfg.font != null) {
gtk-font-name =
let
fontSize = if cfg.font.size != null then cfg.font.size else 10;
in
"${cfg.font.name} ${toString fontSize}";
}
// 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;
}
// optionalAttrs (cfg.cursorTheme != null && cfg.cursorTheme.size != null) {
gtk-cursor-theme-size = cfg.cursorTheme.size;
};

gtk4Css =
lib.optionalString (cfg.theme != null && cfg.theme.package != null) ''
/**
* GTK 4 reads the theme configured by gtk-theme-name, but ignores it.
* It does however respect user CSS, so import the theme from here.
**/
@import url("file://${cfg.theme.package}/share/themes/${cfg.theme.name}/gtk-4.0/gtk.css");
''
+ cfg4.extraCss;

dconfIni =
optionalAttrs (cfg.font != null) {
font-name =
let
fontSize = if cfg.font.size != null then cfg.font.size else 10;
in
"${cfg.font.name} ${toString fontSize}";
}
// optionalAttrs (cfg.theme != null) { gtk-theme = cfg.theme.name; }
// optionalAttrs (cfg.iconTheme != null) {
icon-theme = cfg.iconTheme.name;
}
// optionalAttrs (cfg.cursorTheme != null) {
cursor-theme = cfg.cursorTheme.name;
}
// optionalAttrs (cfg.cursorTheme != null && cfg.cursorTheme.size != null) {
cursor-size = cfg.cursorTheme.size;
};

optionalPackage = opt: lib.optional (opt != null && opt.package != null) opt.package;
in
{
home.packages = lib.concatMap optionalPackage [
cfg.font
cfg.theme
cfg.iconTheme
cfg.cursorTheme
];

home.file.${cfg2.configLocation} = {
text =
lib.concatMapStrings (l: l + "\n") (lib.mapAttrsToList formatGtk2Option gtkIni)
+ cfg2.extraConfig
+ "\n";

inherit (cfg2) force;
};

home.sessionVariables.GTK2_RC_FILES = cfg2.configLocation;

xdg.configFile."gtk-3.0/settings.ini".text = toGtk3Ini { Settings = gtkIni // cfg3.extraConfig; };

xdg.configFile."gtk-3.0/gtk.css" = lib.mkIf (cfg3.extraCss != "") { text = cfg3.extraCss; };

xdg.configFile."gtk-3.0/bookmarks" = lib.mkIf (cfg3.bookmarks != [ ]) {
text = lib.concatMapStrings (l: l + "\n") cfg3.bookmarks;
};

xdg.configFile."gtk-4.0/settings.ini".text = toGtk3Ini { Settings = gtkIni // cfg4.extraConfig; };

xdg.configFile."gtk-4.0/gtk.css" = lib.mkIf (gtk4Css != "") { text = gtk4Css; };

dconf.settings."org/gnome/desktop/interface" = dconfIni;
}
);
config = mkIf cfg.enable {
# Collect packages from all GTK versions
home.packages = gtkLib.collectGtkPackages [
cfg2
cfg3
cfg4
];
};
}
Loading