Can't read clipboard from Nautilus

Hello:

I’m trying to read the clipboard from Nautilus, using Gtk4 and Javascript, but I’m having trouble to do it. I tried the get_formats() method and it worked, returning all the available mimetypes. But I tried get_contents() but it returns always null.

I tried with read_async() and it seems to work fine when cutting text from a text editor, but it “hangs” when there is something cut or copied from Nautilus, until I do another cut while “hanged”, and then it seems to receive something, but it’s always an empty buffer.

What am I doing wrong?

I attach the GTK4 test code that I did:

#!/usr/bin/env gjs

imports.gi.versions.Gtk = '4.0';
const Gtk = imports.gi.Gtk;
const Gdk = imports.gi.Gdk;
const Gio = imports.gi.Gio;
const GLib = imports.gi.GLib;
const ByteArray = imports.byteArray;
const mainloop = imports.mainloop;

// Use different AppIDs to allow to test it from a command line while the main desktop is also running from the extension
const clipboardManagerApp = new Gtk.Application({application_id: 'com.rastersoft.clipboardManagerApp', flags: Gio.ApplicationFlags.FLAGS_NONE});

clipboardManagerApp.connect('startup', () => {
});

function read_clipboard(clipboard) {
    let formats = clipboard.get_formats().get_mime_types();
    for (let format of formats) {
        print(`Format: ${format}`);
    }
    clipboard.read_async(['x-special/gnome-copied-files', 'text/plain'], 0, null, (source, result) => {
        let datos = source.read_finish(result);
        print(`mime type: ${datos[1]}`);
        datos[0].read_bytes_async(100000, 1, null, (source, result) => {
            let content = source.read_bytes_finish(result);
            source.close(null);
            let ba = ByteArray.toString(ByteArray.fromGBytes(content));
            print(`Data: ${ba}`);
            print("Done");
        });
    })
}

clipboardManagerApp.connect('activate', () => {
    let window = new Gtk.Window();
    let button = new Gtk.Button({label:"push me"});
    window.set_child(button);
    window.show();
    clipboardManagerApp.add_window(window);

    let display = Gdk.Display.get_default();
    let clipboard = display.get_clipboard();
    clipboard.connect('changed', () => {
        print("Clipboard has changed");
        read_clipboard(clipboard);
    });
    button.connect('clicked', () => {
        read_clipboard(clipboard);
    });
});

clipboardManagerApp.run(null);
// return value
0;

EDIT: I also tried with GTK3, but have the same problem. This is the GTK3 test code:

#!/usr/bin/env gjs

imports.gi.versions.Gtk = '3.0';
const Gtk = imports.gi.Gtk;
const Gdk = imports.gi.Gdk;
const Gio = imports.gi.Gio;
const GLib = imports.gi.GLib;

const clipboardManagerApp = new Gtk.Application({application_id: 'com.rastersoft.clipboardTest', flags: Gio.ApplicationFlags.FLAGS_NONE});

clipboardManagerApp.connect('startup', () => {
});

clipboardManagerApp.connect('activate', () => {
    let window = new Gtk.Window();
    let button = new Gtk.Button({label:"push me"});
    window.add(button);
    window.show_all();
    clipboardManagerApp.add_window(window);

    let atom = Gdk.Atom.intern('CLIPBOARD', false);
    let clipboard = Gtk.Clipboard.get(atom);

    button.connect('clicked', () => {
        clipboard.request_targets((clip, atoms) => {
            for (let atom of atoms) {
                clip.request_contents(atom, (clip2, data) => {
                    print(`Atom name: ${atom}`);
                    print(data.get_data());
                    print("");
                });
            }
            print("");
        });
    });
});

clipboardManagerApp.run(null);
// return value
0;

Ok, it seems that part of the problem was in how I was acquiring the clipboard: I replaced

    let display = Gdk.Display.get_default();
    let clipboard = display.get_clipboard();

with

    let clipboard = button.get_clipboard();

and now it does work. But get_content() still returns ‘null’; I have to read from the IStream.

Ok, no… it seems that it can break if I mix Gtk3 and Gtk4 example code.

The GTK 4 test code works fine for me when copying a file from Nautilus.

Format: text/plain
Format: text/plain;charset=utf-8
Format: STRING
Format: TEXT
Format: COMPOUND_TEXT
Format: UTF8_STRING
Format: text/uri-list
Format: x-special/gnome-copied-files
mime type: x-special/gnome-copied-files
Data: copy
file:///home/sonny/Documents/manifest.json
Done

Fedora 35 / wayland

BTW if you just want to read text you can do the following

function read_clipboard(clipboard) {
    let formats = clipboard.get_formats().get_mime_types();
    for (let format of formats) {
        print(`Format: ${format}`);
    }

    print(["local", clipboard.is_local()]);
    clipboard.read_text_async(null, (self, asyncResult) => {
      let result;
      try {
        result = clipboard.read_text_finish(asyncResult);
      } catch (err) {
        printError(err);
        return;
      }
      print(`Data: ${result}`);
      print("Done");
    });
}

Yes, after doing some changes it seems to finally work. But anyway, it seems that there is something fragile. If I find a way of reproducing the bug, I’ll post it here.

About reading the text, is not useful. I need to read x-special/gnome-copied-files.

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.