Hi all:
I’m trying to copy data into the clipboard using the Gtk4 API, but something odd happens. I attach my test code.
This code has a function that prints the current clipboard formats, and tries to read the data in any of the following formats: ‘x-special/gnome-copied-files’, ‘text/plain’, ‘text/plain;charset=utf-8’. It does work fine.
Also, I have two GLib.SimpleActions() exported through DBus. Each one received an array of strings, and when received, they try to paste them as a CUT/COPY operation for Nautilus.
The point is that after doing the operation, I call the function that prints the clipboard data and the operation seems to have been carried fine, but if I press the button to read the current clipboard content, it hasn’t changed. Nautilus doesn’t detect the change, neither.
I don’t know if I’m having a problem with closures, or what I am doing wrong, so any help will be appreciated.
The code:
#!/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;
let clipboard = null;
// 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 manageCutCopy(clipboard, action, parameters) {
let content = "";
if (action.name == 'doCut') {
content += 'cut\n';
} else {
content += 'copy\n';
}
let first = true;
for (let file of parameters.recursiveUnpack()) {
if (!first) {
content += '\n';
}
first = false;
content += file;
}
let data = ByteArray.toGBytes(ByteArray.fromString(content));
let provider = Gdk.ContentProvider.new_for_bytes('x-special/gnome-copied-files', data);
let result = clipboard.set_content(provider);
print(`Operacion: ${action.name}; ${provider}; ${clipboard}; resultado: ${result}`);
read_clipboard(clipboard);
}
function read_clipboard(clipboard) {
let formats = clipboard.get_formats().get_mime_types();
for (let format of formats) {
print(`Format: ${format}`);
}
print(`Read: ${clipboard}`);
let content = clipboard.get_content();
clipboard.read_async(['x-special/gnome-copied-files', 'text/plain', 'text/plain;charset=utf-8'], 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);
clipboard = window.get_clipboard();
button.connect('clicked', () => {
read_clipboard(clipboard);
});
let doCopy = new Gio.SimpleAction({
name: 'doCopy',
parameter_type: new GLib.VariantType('as')
});
let doCut = new Gio.SimpleAction({
name: 'doCut',
parameter_type: new GLib.VariantType('as')
});
doCopy.connect('activate', (action, parameters) => {
manageCutCopy(clipboard, action, parameters);
});
doCut.connect('activate', (action, parameters) => {
manageCutCopy(clipboard, action, parameters);
});
let actionGroup = new Gio.SimpleActionGroup();
actionGroup.add_action(doCopy);
actionGroup.add_action(doCut);
let connection = Gio.DBus.session;
let busname = clipboardManagerApp.get_dbus_object_path();
connection.export_action_group(
`${busname}/control`,
actionGroup
);
});
clipboardManagerApp.run(null);
// return value
0;