Architecturally speaking, what is the "correct" way to have other desktops configure middle-click-paste behavior on GTK-apps?

This is more me wondering architecturally speaking than anything else.

Based on the discussion around middle-click paste (that sadly got too heated to the point it needed closing) I realized that such settings seem odd to me on a toolkit-based level.

Say you’re a user on KDE that installed a gtk app directly or a flatpak of a gtk app. You already configured in your KDE settings (I assume they have a config for that since they have a config for everything) that you want to disable middle-click paste (or want to enable it).
How do you as a DE communicate to the app that it should enable/disable this feature?

If I am understanding the current situation right, then currently GTK apps need to check a toolkit-level setting for GTK. So i.e. KDE devs would need to implement that a user changing this value also syncs that value into a corresponding GTK setting in some config file somewhere.
Unless I’m missing anything, wouldn’t that run into scaling issues as with that approach sooner or later every toolkit comes around with their own toolkit specific settings that now need to be all kept in sync based on what the user does in your DE’s config-GUI?

As somebody that is just a webdev and a gnome user and has no idea of how desktop development works - Is there a standard of “desktop-settings” or something where this could belong to so there’s a central point of truth for that setting?

Back in the X11 days, this would have been an XSETTINGS key.

These days, the settings desktop portal has taken its place, though not every setting has been moved to a shared namespace. Portal backends can expose more settings—for instance, the GNOME portal backend exposes various keys under the org.gnome.* namespace, and I’m sure the KDE portal does the same for KDE settings.

You can open a discussion on the xdg-desktop-portal project if you want to add a key under the org.freedesktop.* namespace, and bridge a setting that exists in different environments.

1 Like

Ahhh check, so basically the org.freedesktop namespace could be used for “settings across toolkits” that all toolkits can listen to. And if need be, syncing those values between namespaces could also be implemented in the portal to keep them consistent. Out of curiosity, are there some shared-settings such as that already?

You mention bridging a setting from the freekdestop namespace to org.gnome.*, how does that look like?
Would this mean implementing for the “set this setting to X” procedure that it should write the new value to both org.gnome.* and org.freedesktop.* ?
Or would this mean implementing for the “read this setting” procedure that it should read both the value from org.gnome.* and org.freekdesktop.* and in case of conflicting values (since anything can happen) determine which has higher “priority”?

In the latter case, what is a sort of convention for deciding such priority, if such a thing exists?

You’re supposed to read the org.freedesktop setting because that’s what’s standardized. The org.gnome namespace is internal to GNOME stuff and really is only used as a fallback on systems that predate the standardization of a given org.freedesktop setting. Or for settings where we simply haven’t made a standardized org.freedesktop setting yet.

org.gnome and org.freedesktop settings may disagree. Let me give an example using a made up setting. Let’s say you’re running a GNOME app on KDE. You want to use the Turbo Encabulation feature in KDE so you turn it on. KDE does what’s required of it and sets org.freedesktop.turbo-encabulation = true. If you happen to also have GNOME installed on this system (or more accurately, xdg-desktop-portal-gtk) then org.gnome.turbo-encabulation will also exist as a setting. However org.gnome.turbo-encabulation = false! KDE doesn’t bother to change the GNOME setting (why would it?), and so the GNOME setting remains off. If an app uses this setting, it’ll incorrectly be ignoring the preferences of the running desktop environment.

This is all to say: apps should use the org.freedesktop setting as much as possible. Everything else exists as a fallback if apps want to use it. Not all apps do, and those apps will simply ignore non-standardized system settings. And that’s a valid approach!

Regarding syncing: this is kinda how it happens to work in GNOME.

The org.gnome settings are actually just a direct export of a relevant subset of the gsettings settings store of the host system. gsettings is the way GNOME stores settings natively. Then there’s additional code that also uses gsettings, but then it programmatically generates the appropriate values for the org.freedesktop settings that get advertised to apps.

However, it doesn’t always work like this. As a concrete example: KDE calculates (or at least used to) the correct value for org.freedesktop.appearance.color-scheme by reading the Qt theme’s window background color, converting it to greyscale, and then deciding if that is light enough to be considered 'light' or 'dark'

Opened up a discussion about this in the xdg repo as suggested and got a really interesting reply. KDE’s solution seemingly is - as a Desktop - to deny you access to the primary selection if it is disabled in the settings.
That in turn seems like a fairly simple and scalable approach:

  • It means the DE - which is the one that cares about controlling this - also is the one that directly controls the feature itself, rather than going through toolkits or the like
  • This will work for any app regardless of how it is made since it lacks the info to provide this feature in the first place

Does that approach have its own problems for gnome based on i.e. how gnome is structured, or does it have other drawbacks that I don’t see?

It’s perfectly possible to adopt this solution for GNOME—but GTK has a fallback in place, as explained in the original topic, which would still need a setting in order to be disabled.

1 Like

Ohhh I missed that one, likely because I didn’t understand it at the time and caught on now, thanks for pointing that out!

So for middle-click-pasting from App A to App B, the KDE solution works.

But for any app made by GTK you can still middle-click-paste a solution from App A to some input in App A and for that you need a setting, which is a bit more of a special case but imo it still makes sense to have for all other toolkits that have similar fallbacks if they have them.

For an implementation it’d make sense to do both, right? Deny primary buffer to apps so that those that don’t respect the setting still mostly comply with it, and have the setting itself so that those that do also can have the correct behavior internally.

Another question that came to me - Why have such a fallback that potentially allows superseding the config a user has already made in the first place?

At first glance such a fallback mostly looks like a footgun because if the app-developer forgets to check, then suddenly the user can middle-click-paste despite the user disabling it. Is there critical usefulness to such a fallback that I am missing?

This kind of questions are better answered by looking at the Git log of the GTK project.

The short answer is: the behaviour of the primary selection under X11 is “implementation defined”, and since X11 always has selections, a selection named PRIMARY is always available to clients. Since Windows and macOS do not have a PRIMARY selection, the implementation has always been limited to an application’s own process. This was also the case for the Wayland backend, when it was introduced in GTK3. After the primary-selection protocol was introduced, the fallback was left in place because any non-core Wayland protocol is optional. The fallback is also not touched when the GTK setting is disabled, so it’s really exercised by people using a Wayland compositor without support for the primary-selection protocol and that did not disable the setting inside their GTK configuration source.

If the next question is “why have a fallback on macOS/Windows in the first place”, then the answer is: because you don’t want to have platform specific checks inside GTK to skip the primary selection buffer copy and paste. Once again: this stuff was introduced in GTK before Wayland, it’s always available on X11, and there was no setting to toggle it. We also had API that needed to do something when called by toolkit, library, and application code. Once again: on X11 there’s no compositor involved, and the PRIMARY selection is always available on client request because the X11 stack does not do anything with it.

The gtk-enable-primary-paste setting setting was added in GTK 3.4, as a stepping stone towards making this behaviour optional, and ideally disabled by default—see bug 665193 from 2011. Unfortunately, it was given a reprieve, and when GTK4 was released in 2020, the setting was left enabled by default. The fallback remained in place because a) very few people actually use the primary selection fallback on Windows and/or macOS (especially because it can only work within the same process) and b) the people that disable primary paste through the GNOME setting don’t ever see the fallback inside GTK.

1 Like