From 9d615463f419d2ee28cd811a05c6500c3a3575c7 Mon Sep 17 00:00:00 2001 From: Lea Anthony Date: Mon, 2 Oct 2023 20:47:04 +1100 Subject: [PATCH] [linux] support clipboard --- v3/pkg/application/clipboard.go | 6 +++-- v3/pkg/application/clipboard_linux.go | 36 +++++++++++++++++++++------ v3/pkg/application/linux_cgo.go | 2 +- v3/pkg/application/mainthread.go | 12 +++++++++ 4 files changed, 45 insertions(+), 11 deletions(-) diff --git a/v3/pkg/application/clipboard.go b/v3/pkg/application/clipboard.go index 8a651e430..f21b597e2 100644 --- a/v3/pkg/application/clipboard.go +++ b/v3/pkg/application/clipboard.go @@ -16,9 +16,11 @@ func newClipboard() *Clipboard { } func (c *Clipboard) SetText(text string) bool { - return c.impl.setText(text) + return InvokeSyncWithResult(func() bool { + return c.impl.setText(text) + }) } func (c *Clipboard) Text() (string, bool) { - return c.impl.text() + return InvokeSyncWithResultAndOther(c.impl.text) } diff --git a/v3/pkg/application/clipboard_linux.go b/v3/pkg/application/clipboard_linux.go index ef7b25607..2ecdbfa80 100644 --- a/v3/pkg/application/clipboard_linux.go +++ b/v3/pkg/application/clipboard_linux.go @@ -2,8 +2,29 @@ package application +/* +#cgo linux pkg-config: gtk+-3.0 webkit2gtk-4.0 + +#include "gtk/gtk.h" +#include "webkit2/webkit2.h" + +static gchar* getClipboardText() { + GtkClipboard *clip = gtk_clipboard_get(GDK_SELECTION_CLIPBOARD); + return gtk_clipboard_wait_for_text(clip); +} + +static void setClipboardText(gchar* text) { + GtkClipboard *clip = gtk_clipboard_get(GDK_SELECTION_CLIPBOARD); + gtk_clipboard_set_text(clip, text, -1); + + clip = gtk_clipboard_get(GDK_SELECTION_PRIMARY); + gtk_clipboard_set_text(clip, text, -1); +} +*/ +import "C" import ( "sync" + "unsafe" ) var clipboardLock sync.RWMutex @@ -13,19 +34,18 @@ type linuxClipboard struct{} func (m linuxClipboard) setText(text string) bool { clipboardLock.Lock() defer clipboardLock.Unlock() - // cText := C.CString(text) - // success := C.setClipboardText(cText) - // C.free(unsafe.Pointer(cText)) - success := false - return bool(success) + cText := C.CString(text) + C.setClipboardText(cText) + C.free(unsafe.Pointer(cText)) + return true } func (m linuxClipboard) text() (string, bool) { clipboardLock.RLock() defer clipboardLock.RUnlock() - // clipboardText := C.getClipboardText() - // result := C.GoString(clipboardText) - return "", false + clipboardText := C.getClipboardText() + result := C.GoString(clipboardText) + return result, true } func newClipboardImpl() *linuxClipboard { diff --git a/v3/pkg/application/linux_cgo.go b/v3/pkg/application/linux_cgo.go index 97b66fdcf..dce953ccf 100644 --- a/v3/pkg/application/linux_cgo.go +++ b/v3/pkg/application/linux_cgo.go @@ -119,7 +119,7 @@ static void* gtkFileChooserDialogNew(char* title, GtkWindow* window, GtkFileChoo GTK_RESPONSE_CANCEL, acceptLabel, GTK_RESPONSE_ACCEPT, - 0); + NULL); } typedef struct Screen { diff --git a/v3/pkg/application/mainthread.go b/v3/pkg/application/mainthread.go index d7b0af371..b76663aa2 100644 --- a/v3/pkg/application/mainthread.go +++ b/v3/pkg/application/mainthread.go @@ -67,6 +67,18 @@ func InvokeSyncWithResultAndError[T any](fn func() (T, error)) (res T, err error return res, err } +func InvokeSyncWithResultAndOther[T any, U any](fn func() (T, U)) (res T, other U) { + var wg sync.WaitGroup + wg.Add(1) + globalApplication.dispatchOnMainThread(func() { + defer processPanicHandlerRecover() + res, other = fn() + wg.Done() + }) + wg.Wait() + return res, other +} + func InvokeAsync(fn func()) { globalApplication.dispatchOnMainThread(func() { defer processPanicHandlerRecover()