Skip to content
Open
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
24 changes: 23 additions & 1 deletion modules/gtk/meta.nix
Original file line number Diff line number Diff line change
@@ -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 ];
}
45 changes: 41 additions & 4 deletions modules/gtk/nixos.nix
Original file line number Diff line number Diff line change
@@ -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";
};
}
)
];
}
82 changes: 82 additions & 0 deletions modules/gtk/theme.nix
Original file line number Diff line number Diff line change
@@ -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";
}
]
Comment on lines +45 to +82
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What about parametrizing on the GTK version to deduplicate:

Suggested change
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";
}
]
linkFarm "stylix-gtk" (
lib.singleton {
name = "share/themes/Stylix/index.theme";
path = index;
}
++
lib.concatMap
(version: [
{
name = "etc/xdg/gtk-${version}/settings.ini";
path = settings;
}
{
name = "share/themes/Stylix/gtk-${version}/assets";
path = "${adw-gtk3}/share/themes/adw-gtk3/gtk-${version}/assets";
}
{
name = "share/themes/Stylix/gtk-${version}/gtk.css";
path = css "${version}/gtk.css";
}
{
name = "share/themes/Stylix/gtk-${version}/gtk-dark.css";
path = css "${version}/gtk-dark.css";
}
])
[
"3.0"
"4.0"
]
)

This could be further deduplicated but would probably not be worth it due to over-engineering.

13 changes: 13 additions & 0 deletions modules/libadwaita/load-custom-theme.patch
Original file line number Diff line number Diff line change
@@ -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);
18 changes: 18 additions & 0 deletions modules/libadwaita/meta.nix
Original file line number Diff line number Diff line change
@@ -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 ];
}
1 change: 1 addition & 0 deletions modules/libadwaita/nixos.nix
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{ mkTarget, ... }: mkTarget { }
12 changes: 12 additions & 0 deletions modules/libadwaita/overlay.nix
Comment thread
danth marked this conversation as resolved.
Original file line number Diff line number Diff line change
@@ -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 ];
});
};
}
6 changes: 6 additions & 0 deletions modules/libadwaita/testbeds/libadwaita.nix
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
stylix = {
testbed.ui.graphicalEnvironment = "gnome";
targets.libadwaita.enable = true;
};
}