I want to patch GTK3 to disable Client Side Decoration, as of now I’ve found 2 solutions for non-nix systems. The first one is gtk3-nocsd, which LD_Preloads an so file. The second one is gtk3-classic, which patches GTK itself
Are there any way to implement both of them in nixos (eg. gtk3-classic for native apps via gtk patching, and gtk3-nocsd when you can’t patch the GTK apps like with flatpak)?
I found a rejected pull request in regards to gtk3-nocsd gtk3-nocsd: init at 3.0.1 by Abbie5 · Pull Request #70030 · NixOS/nixpkgs · GitHub
I also found a package request for gtk3-classic that hasn’t went anywhere Package request: gtk3-classic · Issue #334803 · NixOS/nixpkgs · GitHub
Someone mentioned about getting it working here but I haven’t managed to get it to patch or build
Thanks in advance
“Someone” saw your post and is happy to report they are still using gtk3-classic (as a “graft” overlay). This works by building gtk3 with gtk3-classic patches and “grafting” them (essentially replacing the gtk3 library reference) in applicable packages. This keeps the building to a minimum (i.e. only gtk3 not the packages that use gtk3).
I’ll try to rip out the applicable parts from my configuration:
The gtk3-classic build and “graft” mechanism (in file gtk3-classic.nix)
{ pkgs, lib, ... }:
let
# This is a straight copy from upstream (which deprecated this function), as
# I don't see another way of doing this
readPathsFromFile = (rootPath: file:
let
lines = lib.splitString "\n" (builtins.readFile file);
removeComments = lib.filter (line: line != "" && !(lib.hasPrefix "#" line));
relativePaths = removeComments lines;
absolutePaths = map (path: rootPath + "/${path}") relativePaths;
in
absolutePaths);
# GTK3-classic
gtk3-classic = pkgs.gtk3.overrideAttrs (old: {
patches = old.patches ++ (let
classic = pkgs.fetchFromGitHub {
owner = "lah7";
repo = "gtk3-classic";
rev = old.version;
sha256 = "sha256-85F8iLyWdBKMfyXYpyHXFYlvptCEQ6FDQ9YXnKSlgKU=";
};
quiltSeries = name: src: readPathsFromFile (builtins.path {
path = src;
name = (name + "-patches");
filter = (path: type:
(type == "regular") &&
(lib.hasSuffix ".patch" path)
);
}) (src + "/series");
in
(quiltSeries "gtk3-classic" classic)
);
});
in
pkg: let
graft = (p: pkgs.replaceDependency {
drv = p;
oldDependency = pkgs.gtk3;
newDependency = gtk3-classic;
});
in
# Add override methods to make graft/replaceDependency act more like a
# package derivation
((graft pkg) // {
override = (o: graft (pkg.override o));
overrideDerivation = (od: graft (pkg.overrideDerivation od));
})
A set of GUI packages that use gtk3 (in your (home-manager) configuration.nix):
let
guiApps = {
terminal = {
scope = "xfce";
name = "xfce4-terminal";
toolkit = "gtk3";
};
web-browser = {
name = "firefox";
toolkit = "gtk3";
};
};
in {
# config = { #pkgs.enable ... etc };
};
The actual overlay graft (in your (home-manager) configuration.nix)
config = {
nixpkgs = {
overlays = [
# Graft GTK3-classic onto GTK3 applications
(self: super:
let
graft = import ./gtk3-classic.nix {
pkgs = super;
lib = super.lib;
};
gtk3Apps = builtins.filter (app:
((app.toolkit or "") == "gtk3")
) (builtins.attrValues guiApps);
gtk3Scopes = super.lib.unique (
builtins.catAttrs "scope" gtk3Apps
);
gtk3Graft = builtins.listToAttrs (builtins.map (app: {
name = app.name;
value = (graft super.${app.name});
}) (builtins.filter (app:
(!(app ? scope))
) gtk3Apps));
gtk3GraftScoped = scope: (
builtins.listToAttrs (builtins.map (app: {
name = app.name;
# Need to use parent scope ('super' vs. 'ssuper') for graft
# to keep from building a new derivation
value = (graft super.${app.scope}.${app.name});
}) (builtins.filter (app:
((app.scope or "") == scope)
) gtk3Apps))
);
in builtins.listToAttrs (builtins.map (scope: {
name = scope;
value = let
overrideScope = super.${scope}.overrideScope;
in
overrideScope (sself: ssuper: gtk3GraftScoped scope);
}) gtk3Scopes) // (gtk3Graft)
)
];
};
# other pkg.enable ... etc
};
I don’t use gtk3-nocsd so can’t say about that one, but I’m sure if its just another set of patches you could modify the above to tack it on.
Thanks,
simplejack
Thank you very much, I will try this as soon as I have some free time, probably this weekend. Marking this as solution for now and I’ll try to get nocsd working too in case someone stumbles on this thread
So just making sure, does every software need the toolkit = "gtk3";
, or will it work on every gtk3 application as long as I have the first and third code?