Search code examples
clipboardx11gtk3

How to store text on the system clipboard after application has quit using GTK3?


I am trying to update the system clipboard from a GTK application. Here is a simplified program:

#include <gtk/gtk.h>

void callback(GtkClipboard *clipboard, const gchar *text, gpointer data) {
    printf( "In callback: text = '%s'\n", text);
}

int main() {
    gtk_init(NULL, NULL); 
    GdkScreen *screen = gdk_screen_get_default();
    GdkDisplay *display = gdk_display_get_default();
    GtkClipboard *clipboard = gtk_clipboard_get_for_display(
        display, GDK_SELECTION_PRIMARY );
    gtk_clipboard_set_text( clipboard, "Hello world", -1);
    gtk_clipboard_request_text( clipboard, callback, NULL );
    if( gdk_display_supports_clipboard_persistence(display) ) {
        printf( "Supports clipboard persistence.\n");
        gtk_clipboard_store(clipboard);
    }
}

The output (after compiling the above program on my Ubuntu 19.10 laptop):

In callback: text = 'Hello world'

Note that the text: Supports clipboard persistence. is not shown, so apparently the display does not support updating the system clipboard (?). However, I can easily update it with the xclip command. Why is it not possible to do it from GTK?


Solution

  • GDK_SELECTION_PRIMARY -> is used to get the currently-selected object or text GDK_SELECTION_CLIPBOARD -> is used perform operations like Cut/copy/paste (https://developer.gnome.org/gtk3/stable/gtk3-Clipboards.html#gtk-clipboard-get-for-display)

    and to store a text the application has to remain in the main loop long enough to let the clipboard manager copy the text.

    #include <gtk/gtk.h>
    
    void callback(GtkClipboard *clipboard, const gchar *text, gpointer data) {
      printf("In callback: text = '%s'\n", text);
    }
    
    int main() {
      gtk_init(NULL, NULL);
      GdkScreen *screen = gdk_screen_get_default();
      GdkDisplay *display = gdk_display_get_default();
      GtkClipboard *clipboard =
          gtk_clipboard_get_for_display(display, GDK_SELECTION_CLIPBOARD);
      gtk_clipboard_set_text(clipboard, "Hello world", -1);
      gtk_clipboard_request_text(clipboard, callback, NULL);
      if (gdk_display_supports_clipboard_persistence(display)) {
        printf("Supports clipboard persistence.\n");
        gtk_clipboard_store(clipboard);
      }
    
      g_timeout_add(100, gtk_main_quit, NULL);
      gtk_main();
    }
    

    according to the doc(https://developer.gnome.org/gdk3/stable/GdkDisplay.html#gdk-display-supports-clipboard-persistence) clipboard_persistance will only check for a running clipboard daemon. I am guessing that there are some changes made in this area as I was not able to find any running clipboard-daemon in me machine (they might have integrated it into the window manager)

    (https://wiki.ubuntu.com/ClipboardPersistence) -> this doc explains the problems with clipboard persistence and ways to fix it.

    if you install "clipit"(clipboard manager) and try to copy the text without waiting in the main loop for few milliseconds your output will be "Clipboard is null, recovering"

    xclip would have mostly stayed online for a few milliseconds to allow coppying of the text.