How to make only Darktable uses a custom GTK3?

    (
      let
        gtk3-patched = gtk3.overrideAttrs {
          patches = [
            (pkgs.fetchpatch {
              name = "fix-entry-completion";
              url = "https://gitlab.gnome.org/GNOME/gtk/-/merge_requests/2681.patch";
              hash = "sha256-PAg7jbdKFOSDCqZuyM/DOxsmF8d8LeoJxytaTkHhjpk=";
            })
          ];
        };

      in

      darktable.overrideAttrs (oldAttrs: {
        buildInputs = builtins.filter (x: x != gtk3) oldAttrs.buildInputs ++ [
          gtk3-patched
        ];
      })
    )

With that, it seems that I build darktable with my patched GTK3 but the bug I’m trying to address is still there.

When using quick tag, the “tooltip” only shows on one monitor · Issue #20512 · darktable-org/darktable · GitHub make DT uses the custom GTK3 with some LD env var so it’s a dynamic thingy.

How to do that the Nix way? (flake OK)

Try:

let
  # Intentionally not binding `gtk3` beforehand
  # so that we can use `inherit` without running into
  # infrec.
  gtk3 = pkgs.gtk3.overrideAttrs {
    patches = [
      (pkgs.fetchpatch {
        name = "fix-entry-completion";
        url = "https://gitlab.gnome.org/GNOME/gtk/-/merge_requests/2681.patch";
        hash = "sha256-PAg7jbdKFOSDCqZuyM/DOxsmF8d8LeoJxytaTkHhjpk=";
      })
    ];
  };
in
  darktable.override {
    inherit gtk3;
  }
1 Like

Thanks for your answer!

No luck :frowning: to be sure, it’s in configuration.nix

environment.systemPackages = with pkgs; [
(
      let
        gtk3 = pkgs.gtk3.overrideAttrs {
          patches = [
            (pkgs.fetchpatch {
              name = "fix-entry-completion";
              url = "https://gitlab.gnome.org/GNOME/gtk/-/merge_requests/2681.patch";
              hash = "sha256-PAg7jbdKFOSDCqZuyM/DOxsmF8d8LeoJxytaTkHhjpk=";
            })
          ];
        };

      in

      darktable.override {
        inherit gtk3;
      }     
    )
];

Well, that will definitely apply the patch. Presumably it just doesn’t fix what you think it does.

By the way, using with makes it ambiguous (to human readers) what variable refers to what. I’d suggest either not using it at all or limiting its scope to less complex code.

But didn’t I get 2 versions of gtk3? One we build Darktable against and the other one in the system, which is used dynamically?

Oh!

(
      let
        gtk3 = pkgs.gtk3.overrideAttrs (old: {
          patches = (old.patches or [ ]) ++ [
            (pkgs.fetchpatch {
              name = "fix-entry-completion";
              url = "https://gitlab.gnome.org/GNOME/gtk/-/merge_requests/2681.patch";
              hash = "sha256-PAg7jbdKFOSDCqZuyM/DOxsmF8d8LeoJxytaTkHhjpk=";
            })
          ];
        });

        wrapGAppsHook3 = pkgs.wrapGAppsHook3.override {
          inherit gtk3;
        };
      in
      darktable.override {
        inherit gtk3 wrapGAppsHook3;
      }
    )

That did it!

1 Like

Not how nix packaging works. Nix compiles against libraries in /nix/store to prevent this.

Looks like your issue is in the schemas, though, and the schemas are in fact propagated via an environment variable, which means you need to apply a wrapper, and we did forget to also override the gtk version for it.

1 Like

What are schemas? I’m still learning how all this works :slight_smile:

I’m talking about gsettings schemas. They’re basically some XML that can be accessed via the gtk APIs to specify various inter-application settings in a programmatic way. In fairness, it’s not just the schemas, there are also extensions of the API and all the gobject introspection stuff.

Gtk is quite a complex system, and since it’s not just a C API but an API accessed via many different languages, many of its details aren’t just encoded in classic C library form, which means that a lot of it is exposed via gtk-specific environment variables and settings.

Since all that doesn’t follow standard C build expectations, the standard nixpkgs builder doesn’t capture any of it by default, and that’s why we need the hook that makes a wrapper wrapper; that way nix can properly do its thing of confining an application’s inputs exactly to its closure.

1 Like

Thanks a lot for this thorough explanation!