How to intercept clipboard operations on Linux Wayland/Mutter/GNOME

I’m looking to send a popup notification whenever an entity is copied/pasted/dragged&dropped. I’ve spent countless hours looking at source code, researching, and testing code modifications to Mutter. I’ve also tried experimenting with gnome-shell extensions and creating a Wayland client to no avail. The system I’m trying to implement this on is a RHEL 9.3 machine running Wayland/Mutter 40.9/gnome-shell 40.0.

My biggest question is where the clipboard operations are actually programmed in the source code. What would be the best course of action for this? I’ve looked at virtually every open-source clipboard manager made by the community and they’re either incompatible with my setup, or I have had no luck in modifying them to fit my purpose. For example, wlroots is required to utilize wl-clipboard’s “watch” option, and that’s not available on Mutter. Pano, a popular clipboard manager, which has a “send notification on copy” setting, is not compatible with gnome-shell 40.

Any help would be appreciated, let me know if you’d like any more information regarding something specific.

What you’re trying to do is intentionally not permitted (since the clipboard often contains sensitive data). You will need to (a) patch mutter, or (b) switch back to X11.

I’m not familiar with the mutter code, but for a starting point, you can look at src/core/meta-clipboard-manager.c and meta-wayland-data-device.c.

So modifying mutter is the only valid work-around? A GNOME extension is out of the question?

I’ve already been experimenting with modifying Mutter and have had no luck. I’ve tried writing system logs from virtually every function related to the clipboard to try to find where it exactly intercepts it, but haven’t had any positive results.

Well AFAIK for copy events, this can already be done in an extension by doing something like the following:

const cb = St.Clipboard.get_default();
const id = global.display.get_selection().connect('owner-changed', () => {
    cb.get_text(St.ClipboardType.CLIPBOARD, (cb, text) => {
        // do something with `text`
    });
});
// make sure to disconnect `id` on extension disable

For others there are no hooks, you might consider checking the Wayland documentation to understand how the data flow works and then try to add a signal to the mutter objects. For an example of how to do it in C, the main interaction where mutter stores the clipboard data is in meta-clipboard-manager.c, which does a similar thing in order to cache a copy of the clipboard data.

I don’t think it is possible without adding another signal emission, for example in meta-wayland-data-offer.c and also in the other backends if you want those to emit notifications as well.