Can't read clipboard from Nautilus (original) (raw)
December 20, 2021, 11:59pm 1
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;
Rastersoft (Rastersoft ) December 21, 2021, 9:38pm 2
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.
Rastersoft (Rastersoft ) December 21, 2021, 9:43pm 3
Ok, no… it seems that it can break if I mix Gtk3 and Gtk4 example code.
sonny (Sonny Piers) December 22, 2021, 9:59am 4
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
sonny (Sonny Piers) December 22, 2021, 10:08am 5
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");
});
}
Rastersoft (Rastersoft ) December 23, 2021, 5:24pm 6
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.
system (system) Closed January 22, 2022, 5:25pm 7
This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.