2

I am trying to simply "grab" text from the clipboard and put into a variable. I'm having a lot of trouble doing this. I've tried to use

Gtk.Clipboard.Get(Gdk.Atom.Intern("PRIMARY", true))

The code that I have so far, just returns "Gtk.Clipboard" to TextBox entry1.

Gtk.Clipboard clipboard = Gtk.Clipboard.Get(Gdk.Atom.Intern("PRIMARY", true));
string textClip = clipboard.ToString ();

entry1.Text = textClip;

So I am unable to do anything productive with this.

Luc
  • 5,339
  • 2
  • 48
  • 48
David Davern
  • 263
  • 2
  • 8

2 Answers2

1

Try this piece of code to get text from system clipboard;

Gtk.Clipboard clipboard = Gtk.Clipboard.Get(Gdk.Atom.Intern("CLIPBOARD", false));
var text = clipboard.WaitForText();

For more information mono documentation

ziyasal
  • 549
  • 5
  • 15
  • Thank you, that works! Can you explain to me why var in this case? – David Davern Jan 02 '15 at 11:04
  • The default clipboard corresponds to the "CLIPBOARD" atom; another commonly used clipboard is the "PRIMARY" clipboard, which, in X, traditionally contains the currently selected text. To get the clipboard contents as an arbitrary data chunk, there are also functions to retrieve it as text, Clipboard.RequestText() and Clipboard.WaitForText(). These functions take care of determining which formats are advertised by the clipboard provider, asking for the clipboard in the best available format and converting the results into the UTF-8 encoding. (The standard form for representing strings in Gtk#. – ziyasal Jan 02 '15 at 11:21
  • The `clipboard` variable is null so I get a null pointer on the second line. I don't even know where to start looking, any idea what the issue might be? – Luc Dec 24 '19 at 15:39
0

You could also have used the klipper DBus-interface.
That way, you can avoid a dependency on GTK#.

Here's the code for the Klipper DBus-Interface (a bit large for stackoverflow):
https://pastebin.com/HDsRs5aG

And the abstract class:
https://pastebin.com/939kDvP8

And the actual clipboard-code (requires Tmds.Dbus - for handling DBus)

using System.Threading.Tasks;

namespace TestMe
{
    using NiHaoRS; // TODO: Rename namespaces to TestMe

    public class LinuxClipboard
        : GenericClipboard

    {

        public LinuxClipboard()
        { }


        public static async Task TestClipboard()
        {
            GenericClipboard lc = new LinuxClipboard();
            await lc.SetClipboardContentsAsync("Hello KLIPPY");
            string cc = await lc.GetClipboardContentAsync();
            System.Console.WriteLine(cc);
        } // End Sub TestClipboard 


        public override async Task SetClipboardContentsAsync(string text)
        {
            Tmds.DBus.ObjectPath objectPath = new Tmds.DBus.ObjectPath("/klipper");
            string service = "org.kde.klipper";

            using (Tmds.DBus.Connection connection = new Tmds.DBus.Connection(Tmds.DBus.Address.Session))
            {
                await connection.ConnectAsync();

                Klipper.DBus.IKlipper klipper = connection.CreateProxy<Klipper.DBus.IKlipper>(service, objectPath);
                await klipper.setClipboardContentsAsync(text);
            } // End using connection 

        } // End Task SetClipboardContentsAsync 


        public override async Task<string> GetClipboardContentAsync()
        {
            string clipboardContents = null;

            Tmds.DBus.ObjectPath objectPath = new Tmds.DBus.ObjectPath("/klipper");
            string service = "org.kde.klipper";

            using (Tmds.DBus.Connection connection = new Tmds.DBus.Connection(Tmds.DBus.Address.Session))
            {
                await connection.ConnectAsync();

                Klipper.DBus.IKlipper klipper = connection.CreateProxy<Klipper.DBus.IKlipper>(service, objectPath);

                clipboardContents = await klipper.getClipboardContentsAsync();
            } // End Using connection 

            return clipboardContents;
        } // End Task GetClipboardContentsAsync 


    } // End Class LinuxClipBoardAPI 


} // End Namespace TestMe

AsyncEx is required in the abstract class for synchronizing in the get/set property. AsyncEx not required for the actual clipboard handling, as long as you don't want to utilize the get/set clipboard contents in a synchronous context.

Note: klipper must be running (which it is, if you use KDE).

Stefan Steiger
  • 78,642
  • 66
  • 377
  • 442