How to get the contents of the user's clipboard in GDK 4

I want to get the clipboard content, there are 2 buttons, one puts the word gintro in the buffer, the second prints the contents of the buffer to the console.
If I first click paste and then print buffer, then everything works well. But if I press print right after starting the program, it turns out that the buffer content is empty( content = nil ) despite the fact that the clipboard is not empty(I can ctrl v something).

Im getting clipboard from window. As far as I understand, this is just an easier way than getting the Display first and then the Clipboard, since when I get the Clipboard from the Window, it’s the same as getting the Clipboard of the Display on which the Window is displayed. So I don’t understand why the Clipboard is initially empty.

P.S. this is Nim language with GitHub - StefanSalewski/gintro: High level GObject-Introspection based GTK3/GTK4 bindings for Nim language

# nim c -r clipboard.nim

import gintro/[gdk4, gtk4, gobject, gio]
import std/with


proc copy_text(self: Button, clb: Clipboard) =
  assert clb != nil

  var value: Value
  discard init(value, g_string_get_type())
  value.setString("gintro")
  clb.set(value)
  value.unset()

  

proc paste_text(self: Button, clb: Clipboard) =
  assert clb != nil

  var value: Value
  discard init(value, g_string_get_type())

  let content = clb.getContent 
  if content == nil: 
    echo "content is null"
    return

  if not content.getValue(value):
    echo "no value"



  echo value.getString()
  value.unset()


proc appActivate(app: Application) =

  let
    window = newApplicationWindow(app)
    box = newBox(Orientation.horizontal, 0)
    btnPaste = newButton("print buffer to console")
    btnCopy = newButton("paste 'gintro' in to the buffer")
    clb = window.getClipboard()
  with box:
    append btnCopy
    append btnPaste


  btnCopy.connect("clicked", copy_text, clb)  
  btnPaste.connect("clicked", paste_text, clb)  


  with window:
    title = "GTK4 Clipboard example"
    defaultSize = (200, 200)
    child = box
    show

proc main =
  let app = newApplication("org.gtk.example")
  connect(app, "activate", appActivate)
  discard run(app)

main()


Your text is not very clear, and a video is in most cases a poor substitute for a well written text.

When I understand you correctly it is a timing problem, when you try to access the clipboard content very fast? Or is it a problem that the content in not permanent for multiple runs of your program?

Generally your programs seems to work.

[EDIT]

I try to follow your video, but what confuses me is that I read “> c -r clipboard.nim”. Where is the nim command? Should be obviously “nim c -r clipboard.nim”. How has the “nim” vanished?

[EDIT2]

OK, carefully watching your issue seems to be that the content is gone when you restart your program. Well I assume not a Nim issue, so a GTK expert may know the answer. Personally I am not surprised – you create a new window and got the clipboard from that window, so I am not surprised that it is empty.

Well I assume not a Nim issue

Yes, thats why its not a issue on your repo hehe.

video is in most cases a poor substitute for a well written text

I think its always better for GUI issues to put a demo(not sure that everybody will compile nim code to check).

carefully watching your issue seems to be that the content is gone when you restart your program

No, the problem is that I cant get user clipboard content, like the global one.
So I can ctrl v something, but when run program it says content of clipboard is nil.
I added a description that getting a Window Clipboard is just an easier way to get a Clipboard from Display.

From Clipboards: GDK 4 Reference Manual

To get a GdkClipboard object, use gdk_display_get_clipboard() or gdk_display_get_primary_clipboard()

Maybe that is what you need?

[EDIT]

No, I think it is more complicated. See

Data transfer in GTK4 – GTK Development Blog and

Clipboards: GDK 4 Reference Manual

If the clipboard is empty or its contents are not owned by the current process, NULL will be returned.

So you may get NULL for global content.

I guess the async functions may fix that, so we have to create the Nim macro for that :frowning:

[EDIT 2]

It seems that gintro currently supports 150 async functions totally, but luckily only two are from gtk4 and about 10 from gdk4. Most may be from gstreamer and glib/gio, which we may ignore for now. So we may manually create a few Nim macros which generates code to call the async functions, in a similar way as we did for the idleAdd() macro.

1 Like