diff --git a/modules/gtk/meta.nix b/modules/gtk/meta.nix index e1b130a2a..338c00ce0 100644 --- a/modules/gtk/meta.nix +++ b/modules/gtk/meta.nix @@ -1,6 +1,28 @@ { lib, ... }: { name = "GTK"; - homepage = "https://www.gtk.org"; + homepage = "https://gtk.org"; + description = '' + GTK is a widget library used by many applications. + + This module installs three things: + + - A GTK 4 theme based on + [Adwaita](https://gnome.pages.gitlab.gnome.org/libadwaita/), + modified to use your colors. + - A GTK 3 theme based on + [adw-gtk3](https://github.com/lassekongo83/adw-gtk3#readme), + modified to use your colors. + - A settings file listing your fonts. + + Older versions of GTK are not supported. + + Modern GNOME applications must be [patched](./libadwaita.html) to allow + loading custom themes. + + > [!WARNING] + > Theming is [explicitly unsupported](https://stopthemingmy.app) by many + > upstream developers. Please do not bother them with bugs related to this. + ''; maintainers = [ lib.maintainers.danth ]; } diff --git a/modules/gtk/nixos.nix b/modules/gtk/nixos.nix index cb2087169..962f63d6a 100644 --- a/modules/gtk/nixos.nix +++ b/modules/gtk/nixos.nix @@ -1,7 +1,44 @@ -{ mkTarget, ... }: +{ + mkTarget, + pkgs, + lib, + ... +}: mkTarget { - config = { - # Required for Home Manager's GTK settings to work - programs.dconf.enable = true; + options.extraCss = lib.mkOption { + description = '' + Extra code added to `gtk-3.0/gtk.css` and `gtk-4.0/gtk.css`. + ''; + type = lib.types.lines; + default = ""; + example = '' + // Remove rounded corners + window.background { border-radius: 0; } + ''; }; + + config = [ + { + # Required for Home Manager's GTK settings to work + programs.dconf.enable = true; + } + + ( + { cfg, colors }: + { + environment.systemPackages = lib.singleton ( + pkgs.callPackage ./theme.nix { inherit cfg colors; } + ); + + # Under GNOME on Wayland, the XDG Desktop Portal implementation takes + # priority over the settings files in `$XDG_CONFIG_DIRS/etc/xdg` [1], + # reading from this DConf path instead. + # + # [1] https://docs.gtk.org/gtk4/class.Settings.html + programs.dconf.profiles.user.databases = lib.singleton { + settings."org/gnome/desktop/interface".gtk-theme = "Stylix"; + }; + } + ) + ]; } diff --git a/modules/gtk/theme.nix b/modules/gtk/theme.nix new file mode 100644 index 000000000..ae1b99398 --- /dev/null +++ b/modules/gtk/theme.nix @@ -0,0 +1,82 @@ +# This package is currently only used on NixOS. On Home Manager we install the +# adw-gtk3 theme directly, then override it from $XDG_CONFIG_HOME, in a way +# that is not possible at the system level. Such an override avoids the need +# to patch libadwaita, but is not ideal because it doesn't make it clear +# (in settings and log output) that the upstream theme was modified by Stylix. +# The override also doesn't work in Flatpak. + +{ + cfg, + colors, + lib, + adw-gtk3, + linkFarm, + writeText, +}: +let + format = lib.generators.toINI { }; + + settings = writeText "stylix-gtk-settings.ini" (format { + Settings.gtk-theme-name = "Stylix"; + }); + + index = writeText "stylix-gtk-index.theme" (format { + "Desktop Entry" = { + Encoding = "UTF-8"; + Name = "Stylix"; + Type = "X-GNOME-Metatheme"; + }; + X-GNOME-Metatheme.GtkTheme = "Stylix"; + }); + + baseCss = colors { + template = ./gtk.css.mustache; + extension = ".css"; + }; + + css = + path: + writeText "stylix-gtk-${path}" '' + @import url('${adw-gtk3}/share/themes/adw-gtk3/${path}'); + @import url('${baseCss}'); + ${cfg.extraCss} + ''; +in +linkFarm "stylix-gtk" [ + { + name = "etc/xdg/gtk-3.0/settings.ini"; + path = settings; + } + { + name = "etc/xdg/gtk-4.0/settings.ini"; + path = settings; + } + { + name = "share/themes/Stylix/index.theme"; + path = index; + } + { + name = "share/themes/Stylix/gtk-3.0/assets"; + path = "${adw-gtk3}/share/themes/adw-gtk3/gtk-3.0/assets"; + } + { + name = "share/themes/Stylix/gtk-3.0/gtk.css"; + path = css "gtk-3.0/gtk.css"; + } + { + name = "share/themes/Stylix/gtk-3.0/gtk-dark.css"; + path = css "gtk-3.0/gtk-dark.css"; + } + { + name = "share/themes/Stylix/gtk-4.0/assets"; + path = "${adw-gtk3}/share/themes/adw-gtk3/gtk-4.0/assets"; + } + { + name = "share/themes/Stylix/gtk-4.0/gtk.css"; + path = css "gtk-4.0/gtk.css"; + } + { + name = "share/themes/Stylix/gtk-4.0/gtk-dark.css"; + path = css "gtk-4.0/gtk-dark.css"; + } +] diff --git a/modules/libadwaita/load-custom-theme.patch b/modules/libadwaita/load-custom-theme.patch new file mode 100644 index 000000000..a55f429da --- /dev/null +++ b/modules/libadwaita/load-custom-theme.patch @@ -0,0 +1,13 @@ +diff --git a/src/adw-style-manager.c b/src/adw-style-manager.c +index 1119af72..3364061b 100644 +--- a/src/adw-style-manager.c ++++ b/src/adw-style-manager.c +@@ -489,7 +489,7 @@ adw_style_manager_constructed (GObject *object) + self, + G_CONNECT_SWAPPED); + +- if (!adw_is_granite_present () && !g_getenv ("GTK_THEME")) { ++ if (0) { + g_object_set (self->gtk_settings, + "gtk-theme-name", "Adwaita-empty", + NULL); diff --git a/modules/libadwaita/meta.nix b/modules/libadwaita/meta.nix new file mode 100644 index 000000000..0fcf8ebd8 --- /dev/null +++ b/modules/libadwaita/meta.nix @@ -0,0 +1,18 @@ +{ lib, ... }: +{ + name = "Adwaita"; + homepage = "https://gnome.pages.gitlab.gnome.org/libadwaita"; + description = '' + Adwaita is a widget library used by modern GNOME applications. + + It's based on [GTK 4](./gtk.html), but for compatibility reasons, + applications made with it do not allow customization and will always load + the standard Adwaita theme. This module patches the source code to permit + loading other themes. + + > [!WARNING] + > Theming is [explicitly unsupported](https://stopthemingmy.app) by many + > upstream developers. Please do not bother them with bugs related to this. + ''; + maintainers = [ lib.maintainers.danth ]; +} diff --git a/modules/libadwaita/nixos.nix b/modules/libadwaita/nixos.nix new file mode 100644 index 000000000..22a0afa6b --- /dev/null +++ b/modules/libadwaita/nixos.nix @@ -0,0 +1 @@ +{ mkTarget, ... }: mkTarget { } diff --git a/modules/libadwaita/overlay.nix b/modules/libadwaita/overlay.nix new file mode 100644 index 000000000..05a0fb810 --- /dev/null +++ b/modules/libadwaita/overlay.nix @@ -0,0 +1,12 @@ +{ config, lib, ... }: +{ + overlay = + _final: prev: + lib.optionalAttrs + (config.stylix.enable && config.stylix.targets.libadwaita.enable or false) + { + libadwaita = prev.libadwaita.overrideAttrs (oldAttrs: { + patches = (oldAttrs.patches or [ ]) ++ [ ./load-custom-theme.patch ]; + }); + }; +} diff --git a/modules/libadwaita/testbeds/libadwaita.nix b/modules/libadwaita/testbeds/libadwaita.nix new file mode 100644 index 000000000..df622a819 --- /dev/null +++ b/modules/libadwaita/testbeds/libadwaita.nix @@ -0,0 +1,6 @@ +{ + stylix = { + testbed.ui.graphicalEnvironment = "gnome"; + targets.libadwaita.enable = true; + }; +}