Giter VIP home page Giter VIP logo

golang-design / clipboard Goto Github PK

View Code? Open in Web Editor NEW
570.0 8.0 62.0 844 KB

๐Ÿ“‹ cross-platform clipboard package that supports accessing text and image in Go (macOS/Linux/Windows/Android/iOS)

Home Page: https://golang.design/x/clipboard

License: MIT License

Go 75.70% C 18.55% Makefile 0.67% Objective-C 3.78% Dockerfile 0.74% Shell 0.56%
go golang clipboard clipboard-library linux macos x11 nspasteboard windows android

clipboard's People

Contributors

52funny avatar bw31642 avatar changkun avatar geekgasm avatar hrntknr avatar microo8 avatar nocd5 avatar pluveto avatar quackduck avatar webdev-support avatar y-yagi avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

clipboard's Issues

Don't panic when headless

I've just added you're excellent package to my project and it works great on my arm mac.
When I try to run my docker compose based tests it fails to compile:

clipboard_linux.c:15:10: fatal error: X11/Xlib.h: No such file or directory
   15 | #include <X11/Xlib.h>
        |          ^~~~~~~~~~~~
 compilation terminated.

Makes sense - containers don't have X. I've tried disabling CGO and got in run time:

 panic: clipboard: cannot use when CGO_ENABLED=0

It's clear the package can't do anything on a system with no clipboard, but IMHO it should be able to compile and return an error on all calls, leaving it to the calling program to handle. Like in my program's, where I want to use an environment variable as the clipboard storage so I can run and validate clipboard related tests.

PNG data overwritten on Windows

I'd like to be able to hit "Print Screen" on my keyboard and paste the images into a Steam chat, but as it stands that doesn't work because the screenshots created by Windows are too big in terms of filesize.

I wrote a simple program using this library that uses pngquant to optimize the image data in the clipboard and then replace the clipboard with it, but it doesn't work.

Here's the important code:

imageChannel := clipboard.Watch(context.Background(), clipboard.FmtImage)

copiedImage := <-imageChannel
fmt.Println("detected that an image was copied, compressing image...")

compressedImage, err := pngquant.CompressBytes(copiedImage, "1")

fmt.Println("original image size in bytes:", len(copiedImage))
fmt.Println("compressed image size in bytes:", len(compressedImage))

if err != nil {
	panic(err)
}

fmt.Println("reading clipboard...")
fmt.Println(len(clipboard.Read(clipboard.FmtImage)))

fmt.Println("replacing clipboard...")
clipboard.Write(clipboard.FmtImage, compressedImage)

fmt.Println("reading clipboard...")
fmt.Println(len(clipboard.Read(clipboard.FmtImage)))

and here's the output I see:

detected that an image was copied, compressing image...
original image size in bytes: 1947271
compressed image size in bytes: 1696311
reading clipboard...
1947271
replacing clipboard...
reading clipboard...
3881712

As you can see, the compression does work, but when I write that to the clipboard it's replaced with something much larger, often around 2x the original size(!)

It'd be great if the original bytes could be written to the clipboard without being re-encoded (on Windows)

Feature Request: Support to read and write raw content (without any formatting) from and into clipboards

Hey

First of all thanks a ton for this project. I have been experimenting with the project for a week now. I have a requirement for an internal project where I have to detect the content type of the clipboard as file or text and take an action based on that.

I tried the clipboard package and when I try to copy a folder or a file (agnostic of any format) , the Read function gives only the text path of the folder. Hence I am unable to differentiate if the copied content is just the text file path or the actual file itself.

My request pertains to providing an additional method to directly read the raw content from the clipboard (hex format / any other suitable binary format) , than forcing it to be formatted to a Text or Image (which is the case as on date) in which case it loses context of the content; and a direct write of raw content to the clipboard.

This will also help others to write their own implementation of formatting until the support for their requested format ( such as the issue here - #17) is added to the main library.

Segmentation violation using the gclip tool on Fedora

I have been using clipboard to build a small personal application as a replacement for xclip. The first time I built and tested the application, it threw this error:

fatal error: unexpected signal during runtime execution
[signal SIGSEGV: segmentation violation code=0x1 addr=0x0 pc=0x0]

runtime stack:
runtime.throw({0x4bc05d?, 0x1?})
        /usr/local/go/src/runtime/panic.go:992 +0x71
runtime.sigpanic()
        /usr/local/go/src/runtime/signal_unix.go:802 +0x3a9

goroutine 1 [syscall, locked to thread]:
runtime.cgocall(0x4996f0, 0xc00006fde8)
        /usr/local/go/src/runtime/cgocall.go:157 +0x5c fp=0xc00006fdc0 sp=0xc00006fd88 pc=0x40521c
golang.design/x/clipboard._Cfunc_clipboard_test()
        _cgo_gotypes.go:93 +0x48 fp=0xc00006fde8 sp=0xc00006fdc0 pc=0x498028
golang.design/x/clipboard.initialize()
        /home/$USER/.go/pkg/mod/golang.design/x/[email protected]/clipboard_linux.go:60 +0x1d fp=0xc00006fe30 sp=0xc00006fde8 pc=0x49829d
golang.design/x/clipboard.Init(...)
        /home/$USER/.go/pkg/mod/golang.design/x/[email protected]/clipboard.go:102
main.init.0()
        /home/$USER/.go/pkg/mod/golang.design/x/[email protected]/cmd/gclip/main.go:47 +0x1a fp=0xc00006fe50 sp=0xc00006fe30 pc=0x49903a
runtime.doInit(0x546a00)
        /usr/local/go/src/runtime/proc.go:6222 +0x126 fp=0xc00006ff80 sp=0xc00006fe50 pc=0x4429e6
runtime.main()
        /usr/local/go/src/runtime/proc.go:233 +0x1d3 fp=0xc00006ffe0 sp=0xc00006ff80 pc=0x435a93
runtime.goexit()
        /usr/local/go/src/runtime/asm_amd64.s:1571 +0x1 fp=0xc00006ffe8 sp=0xc00006ffe0 pc=0x45ebc1

I thought it was an issue with my code, but the gclip reference tool throws the same error, so I must assume that the issue lies with the clipboard library. My /etc/os-release file (unsure if this helps):

VERSION="35 (KDE Plasma)"
ID=fedora
VERSION_ID=35
VERSION_CODENAME=""
PLATFORM_ID="platform:f35"
PRETTY_NAME="Fedora Linux 35 (KDE Plasma)"
ANSI_COLOR="0;38;2;60;110;180"
LOGO=fedora-logo-icon
CPE_NAME="cpe:/o:fedoraproject:fedora:35"
HOME_URL="https://fedoraproject.org/"
DOCUMENTATION_URL="https://docs.fedoraproject.org/en-US/fedora/f35/system-administrators-guide/"
SUPPORT_URL="https://ask.fedoraproject.org/"
BUG_REPORT_URL="https://bugzilla.redhat.com/"
REDHAT_BUGZILLA_PRODUCT="Fedora"
REDHAT_BUGZILLA_PRODUCT_VERSION=35
REDHAT_SUPPORT_PRODUCT="Fedora"
REDHAT_SUPPORT_PRODUCT_VERSION=35
PRIVACY_POLICY_URL="https://fedoraproject.org/wiki/Legal:PrivacyPolicy"
VARIANT="KDE Plasma"
VARIANT_ID=kde```

Wayland support?

Hey quick question. Are there plans to support wayland in the future?
Thank you for you time :)

Improve setup message

If the clipboard package is used in a cloud server environment, it may still not be possible to use the package on Linux. This is because x11 requires a frame buffer for GUI features.

This message:

panic(`cannot use this package, failed to initialize x11 display, maybe try install:
apt install -y libx11-dev

Suggests to install libx11-dev may not be helpful, change to the following might be helpful:

failed to initialize the x11 display, and the clipboard will not work properly. Install the following
dependency may help:
 
	apt install -y libx11-dev

If the clipboard package is in an environment without a frame buffer, such as a cloud server, it may also
necessary to install xvfb:

	apt install -y xvfb

and initialize a virtual frame buffer:

	Xvfb :99 -screen 0 1024x768x24 > /dev/null 2>&1 &
 	export DISPLAY=:99.0

If we don't write this in the package panic message, we may document this in the README.md

Issue discovered by @qcrao

Android support

I've tested for Linux and it works perfectly. But for Android not working at all. Not tested with iOS. Any plans for supporting those?

ld: error: duplicate symbol: when using with Fyne Android

I tried to remove the clipboard it's working fine.

logs

$ fyne-cross android
[i] Target: android/multiple
[i] Cleaning target directories...
[โœ“] "dist" dir cleaned: C:\Users\ntsd\Desktop\git\ntsd\cross-clipboard\fyne-cross\dist\android
[โœ“] "temp" dir cleaned: C:\Users\ntsd\Desktop\git\ntsd\cross-clipboard\fyne-cross\tmp\android
[โœ“] "bin" dir cleaned: C:\Users\ntsd\Desktop\git\ntsd\cross-clipboard\fyne-cross\bin\android
[i] Checking for go.mod: C:\Users\ntsd\Desktop\git\ntsd\cross-clipboard\go.mod
[โœ“] go.mod found
[i] Packaging app...
go build -buildmode=c-shared -o /tmp/gomobile-work-1926614866/lib/armeabi-v7a/libcross-clipboard.so github.com/ntsd/cross-clipboard failed: exit status 2
# fyne.io/fyne/v2/internal/driver/mobile
android.c:50:9: warning: returning 'const char *' from a function with result type 'char *' discards qualifiers [-Wincompatible-pointer-types-discards-qualifiers]
android.c:67:48: warning: incompatible integer to pointer conversion passing 'uintptr_t' (aka 'unsigned int') to parameter of type 'jobject' (aka 'void *') [-Wint-conversion]     
android.c:71:55: warning: incompatible integer to pointer conversion passing 'uintptr_t' (aka 'unsigned int') to parameter of type 'jobject' (aka 'void *') [-Wint-conversion]     
android.c:122:48: warning: incompatible integer to pointer conversion passing 'uintptr_t' (aka 'unsigned int') to parameter of type 'jobject' (aka 'void *') [-Wint-conversion]    
android.c:125:48: warning: incompatible integer to pointer conversion passing 'uintptr_t' (aka 'unsigned int') to parameter of type 'jobject' (aka 'void *') [-Wint-conversion]    
android.c:181:50: warning: passing 'char *' to parameter of type 'jbyte *' (aka 'signed char *') converts between pointers to integer types with different sign [-Wpointer-sign]   
android.c:191:48: warning: passing 'char *' to parameter of type 'const jbyte *' (aka 'const signed char *') converts between pointers to integer types with different sign [-Wpointer-sign]
# fyne.io/fyne/v2/app
app_mobile_and.c:46:48: warning: incompatible integer to pointer conversion passing 'uintptr_t' (aka 'unsigned int') to parameter of type 'jobject' (aka 'void *') [-Wint-conversion]
app_mobile_and.c:49:48: warning: incompatible integer to pointer conversion passing 'uintptr_t' (aka 'unsigned int') to parameter of type 'jobject' (aka 'void *') [-Wint-conversion]
app_mobile_and.c:85:30: warning: incompatible integer to pointer conversion passing 'uintptr_t' (aka 'unsigned int') to parameter of type 'jobject' (aka 'void *') [-Wint-conversion]
app_mobile_and.c:98:33: warning: incompatible pointer to integer conversion passing 'JNIEnv *' (aka 'const struct JNINativeInterface **') to parameter of type 'uintptr_t' (aka 'unsigned int') [-Wint-conversion]
app_mobile_and.c:42:36: note: passing argument to parameter 'jni_env' here
# github.com/ntsd/cross-clipboard
/usr/local/go/pkg/tool/linux_amd64/link: running /usr/local/android_sdk/ndk-bundle/toolchains/llvm/prebuilt/linux-x86_64/bin/armv7a-linux-androideabi16-clang failed: exit status 1
ld: error: duplicate symbol: callMain
>>> defined at _cgo_export.c:44
>>>            /tmp/go-link-655786190/000020.o:(callMain)
>>> defined at _cgo_export.c:44
>>>            /tmp/go-link-655786190/000039.o:(.text+0x50)

ld: error: duplicate symbol: onConfigurationChanged
>>> defined at _cgo_export.c:334
>>>            /tmp/go-link-655786190/000020.o:(onConfigurationChanged)
>>> defined at _cgo_export.c:317
>>>            /tmp/go-link-655786190/000039.o:(.text+0x4D4)

ld: error: duplicate symbol: onContentRectChanged
>>> defined at _cgo_export.c:298
>>>            /tmp/go-link-655786190/000020.o:(onContentRectChanged)
>>> defined at _cgo_export.c:298
>>>            /tmp/go-link-655786190/000039.o:(.text+0x484)

ld: error: duplicate symbol: onCreate
>>> defined at _cgo_export.c:150
>>>            /tmp/go-link-655786190/000020.o:(onCreate)
>>> defined at _cgo_export.c:150
>>>            /tmp/go-link-655786190/000039.o:(.text+0x214)

ld: error: duplicate symbol: onDestroy
>>> defined at _cgo_export.c:167
>>>            /tmp/go-link-655786190/000020.o:(onDestroy)
>>> defined at _cgo_export.c:167
>>>            /tmp/go-link-655786190/000039.o:(.text+0x25C)

ld: error: duplicate symbol: onInputQueueCreated
>>> defined at _cgo_export.c:260
>>>            /tmp/go-link-655786190/000020.o:(onInputQueueCreated)
>>> defined at _cgo_export.c:260
>>>            /tmp/go-link-655786190/000039.o:(.text+0x3E4)

ld: error: duplicate symbol: onInputQueueDestroyed
>>> defined at _cgo_export.c:279
>>>            /tmp/go-link-655786190/000020.o:(onInputQueueDestroyed)
>>> defined at _cgo_export.c:279
>>>            /tmp/go-link-655786190/000039.o:(.text+0x434)

ld: error: duplicate symbol: onLowMemory
>>> defined at _cgo_export.c:351
>>>            /tmp/go-link-655786190/000020.o:(onLowMemory)
>>> defined at _cgo_export.c:334
>>>            /tmp/go-link-655786190/000039.o:(.text+0x51C)

ld: error: duplicate symbol: onNativeWindowCreated
>>> defined at _cgo_export.c:203
>>>            /tmp/go-link-655786190/000020.o:(onNativeWindowCreated)
>>> defined at _cgo_export.c:203
>>>            /tmp/go-link-655786190/000039.o:(.text+0x2F4)

ld: error: duplicate symbol: onNativeWindowDestroyed
>>> defined at _cgo_export.c:241
>>>            /tmp/go-link-655786190/000020.o:(onNativeWindowDestroyed)
>>> defined at _cgo_export.c:241
>>>            /tmp/go-link-655786190/000039.o:(.text+0x394)

ld: error: duplicate symbol: onNativeWindowRedrawNeeded
>>> defined at _cgo_export.c:222
>>>            /tmp/go-link-655786190/000020.o:(onNativeWindowRedrawNeeded)
>>> defined at _cgo_export.c:222
>>>            /tmp/go-link-655786190/000039.o:(.text+0x344)

ld: error: duplicate symbol: onPause
>>> defined at _cgo_export.c:116
>>>            /tmp/go-link-655786190/000020.o:(onPause)
>>> defined at _cgo_export.c:116
>>>            /tmp/go-link-655786190/000039.o:(.text+0x184)

ld: error: duplicate symbol: onResume
>>> defined at _cgo_export.c:78
>>>            /tmp/go-link-655786190/000020.o:(onResume)
>>> defined at _cgo_export.c:78
>>>            /tmp/go-link-655786190/000039.o:(.text+0xE0)

ld: error: duplicate symbol: onSaveInstanceState
>>> defined at _cgo_export.c:95
>>>            /tmp/go-link-655786190/000020.o:(onSaveInstanceState)
>>> defined at _cgo_export.c:95
>>>            /tmp/go-link-655786190/000039.o:(.text+0x128)

ld: error: duplicate symbol: onStart
>>> defined at _cgo_export.c:61
>>>            /tmp/go-link-655786190/000020.o:(onStart)
>>> defined at _cgo_export.c:61
>>>            /tmp/go-link-655786190/000039.o:(.text+0x98)

ld: error: duplicate symbol: onStop
>>> defined at _cgo_export.c:133
>>>            /tmp/go-link-655786190/000020.o:(onStop)
>>> defined at _cgo_export.c:133
>>>            /tmp/go-link-655786190/000039.o:(.text+0x1CC)

ld: error: duplicate symbol: onWindowFocusChanged
>>> defined at _cgo_export.c:184
>>>            /tmp/go-link-655786190/000020.o:(onWindowFocusChanged)
>>> defined at _cgo_export.c:184
>>>            /tmp/go-link-655786190/000039.o:(.text+0x2A4)

ld: error: duplicate symbol: setCurrentContext
>>> defined at _cgo_export.c:25
>>>            /tmp/go-link-655786190/000020.o:(setCurrentContext)
>>> defined at _cgo_export.c:25
>>>            /tmp/go-link-655786190/000039.o:(.text+0x0)

ld: error: duplicate symbol: ANativeActivity_onCreate
>>> defined at android.c:76
>>>            /tmp/go-link-655786190/000023.o:(ANativeActivity_onCreate)
>>> defined at android.c:72
>>>            /tmp/go-link-655786190/000041.o:(.text+0x40)

ld: error: duplicate symbol: JNI_OnLoad
>>> defined at android.c:57
>>>            /tmp/go-link-655786190/000023.o:(JNI_OnLoad)
>>> defined at android.c:53
>>>            /tmp/go-link-655786190/000041.o:(.text+0x0)

ld: error: too many errors emitted, stopping now (use -error-limit=0 to see all errors)
clang: error: linker command failed with exit code 1 (use -v to see invocation)


[โœ—] could not package the Fyne app: could not package the Fyne app: exit status 1

Go version: 1.18
Clipboard version: 0.6.2
Fyne version: 2.1.4
NDK version: 21.4.7075529, 23.1.7779620

The shortcut key Ctrl+C cannot be detected when copying images.

The platform I am using is Win11, and the go version is 1.20. When I use the shortcut keys Ctrl+C to copy images to the clipboard, the "golang. design/x/clipboard" library cannot detect clipboard changes.

package main

import (
	"context"
	"encoding/base64"
	"golang.design/x/clipboard"
	"log"
)

func main() {
	watchLocalClipboard(context.Background())
}

func watchLocalClipboard(ctx context.Context) {
	err := clipboard.Init()
	if err != nil {
		panic(err)
	}
	textCh := clipboard.Watch(ctx, clipboard.FmtText)
	imagCh := clipboard.Watch(ctx, clipboard.FmtImage)
	for {
		select {
		case <-ctx.Done():
			return
		case textData, ok := <-textCh:
			if !ok {
				return
			}
			log.Println(string(textData))
			log.Println("------------>text")
		case imageData, ok := <-imagCh:
			if !ok {
				return
			}
			//log.Println(imageData)
			// ๅฐ†ๅ›พ็‰‡ๆ•ฐๆฎ็ผ–็ ไธบ Base64 ๅญ—็ฌฆไธฒ
			base64String := base64.StdEncoding.EncodeToString(imageData)
			log.Println(base64String)
			//clipboard.Write(clipboard.FmtText, []byte(base64String))
			log.Println("------------>img")
		}
	}
}

Build fails with "error: implicit declaration of function 'nanosleep'"

On attempt to cross-compile a program with clipboard in dependencies from windows to linux amd64:

Set GOOS=linux
Set GOARCH=amd64
Set CGO_ENABLED=1

go build main.go

Gives:

# runtime/cgo
gcc_libinit.c: In function '_cgo_try_pthread_create':
gcc_libinit.c:110:17: error: implicit declaration of function 'nanosleep' [-Werror=implicit-function-declaration]
  110 |                 nanosleep(&ts, nil);
      |                 ^~~~~~~~~
cc1.exe: all warnings being treated as errors

GCC 12.1.0, gcc -v output:

Built by Equation Solution <http://www.Equation.com>.
Using built-in specs.
COLLECT_GCC=gcc
COLLECT_LTO_WRAPPER=c:/users/user/gcc/bin/../libexec/gcc/x86_64-w64-mingw32/12.1.0/lto-wrapper.exe
Target: x86_64-w64-mingw32
Configured with: ../gcc-12.1.0/configure --host=x86_64-w64-mingw32 --build=x86_64-unknown-linux-gnu --target=x86_64-w64-mingw32 --prefix=/home/gfortran/gcc-home/binary/mingw32/native/x86_64/gcc/12.1.0 --with-sysroot=/home/gfortran/gcc-home/binary/mingw32/cross/x86_64/gcc/12-20220403 --with-gcc --with-gnu-ld --with-gnu-as --with-ld64=no --with-gmp=/home/gfortran/gcc-home/binary/mingw32/native/x86_64/gmp --with-mpfr=/home/gfortran/gcc-home/binary/mingw32/native/x86_64/mpfr --with-mpc=/home/gfortran/gcc-home/binary/mingw32/native/x86_64/mpc --with-cloog=/home/gfortran/gcc-home/binary/mingw32/native/x86_64/cloog --with-libiconv-prefix=/home/gfortran/gcc-home/binary/mingw32/native/x86_64/libiconv --with-diagnostics-color=auto --enable-cloog-backend=isl --enable-targets=i686-w64-mingw32,x86_64-w64-mingw32 --enable-lto --enable-languages=c,c++,fortran --enable-threads=win32 --enable-static --enable-shared=lto-plugin --enable-plugins --enable-ld=yes --enable-libquadmath --enable-libquadmath-support --enable-libgomp --disable-checking --disable-nls --disable-tls --disable-win32-registry : (reconfigured) ../gcc-12.1.0/configure --host=x86_64-w64-mingw32 --build=x86_64-unknown-linux-gnu --target=x86_64-w64-mingw32 --prefix=/home/gfortran/gcc-home/binary/mingw32/native/x86_64/gcc/12.1.0 --with-sysroot=/home/gfortran/gcc-home/binary/mingw32/cross/x86_64/gcc/12-20220403 --with-gcc --with-gnu-ld --with-gnu-as --with-ld64=no --with-gmp=/home/gfortran/gcc-home/binary/mingw32/native/x86_64/gmp --with-mpfr=/home/gfortran/gcc-home/binary/mingw32/native/x86_64/mpfr --with-mpc=/home/gfortran/gcc-home/binary/mingw32/native/x86_64/mpc --with-cloog=/home/gfortran/gcc-home/binary/mingw32/native/x86_64/cloog --with-libiconv-prefix=/home/gfortran/gcc-home/binary/mingw32/native/x86_64/libiconv --with-diagnostics-color=auto --enable-cloog-backend=isl --enable-targets=i686-w64-mingw32,x86_64-w64-mingw32 --enable-lto --enable-languages=c,c++,fortran --enable-threads=win32 --enable-static --enable-shared=lto-plugin --enable-plugins --enable-ld=yes --enable-libquadmath --enable-libquadmath-support --enable-libgomp --disable-checking --disable-nls --disable-tls --disable-win32-registry
Thread model: win32
Supported LTO compression algorithms: zlib
gcc version 12.1.0 (GCC)

Backward compatibility for Go 1.16

Newbie here.
When I ran commands below:

$ go version
go version go1.16.8 linux/amd64
$ go mod init main
$ touch main.go
$ go get -u golang.design/x/clipboard                                                                                                                                     โœ˜ 1 
//go:build comment without // +build comment
$ go run main                                                                                                                                                             โœ˜ 1 
main.go:4:8: no required module provides package golang.design/x/clipboard; to add it:
        go get golang.design/x/clipboard
$ go get golang.design/x/clipboard                                                                                                                                        โœ˜ 1 
//go:build comment without // +build comment

I got //go:build comment without // +build comment, but the go.mod file never changed.
So how could I install golang-design/clipboard?

main.go

package main

import "fmt"
import "golang.design/x/clipboard"

func main(){
	fmt.Println("hi")
}

bug: Image Write Doesn't Seem to Work on Linux and Windows (Ubuntu 20.04)

My computer:

  • OS: Ubuntu 20.04, 5.15.0-56-generic
  • Arch: amd64
  • Display manager: X11

Sample 1

If I take a screenshot, and run the following code, I can no longer access the screenshot.

The code below simply reads the image, and write it back after 10 seconds.

func main() {
	err := clipboard.Init()
	checkErr(err)

	imgBuf := clipboard.Read(clipboard.FmtImage)
	fmt.Println(len(imgBuf))
	time.Sleep(10 * time.Second)
	clipboard.Write(clipboard.FmtImage, imgBuf)
}

Sample 2

I tried to use a base64 image string for testing. The code writes the image and read it back then compare with the source.

stdout outputs "true" in the end (on ubuntu), but I can't paste the image out. It seems like the image is written to somewhere not recognized by the OS.

This sample works on MacOS and Windows (Windows outputs false in the end but image can be pasted, seems like there were some transformation applied.)

func main() {
	sampleBase64Img := "iVBORw0KGgoAAAANSUhEUgAAABcAAAAXCAYAAADgKtSgAAAABHNCSVQICAgIfAhkiAAAABl0RVh0U29mdHdhcmUAZ25vbWUtc2NyZWVuc2hvdO8Dvz4AAAAtdEVYdENyZWF0aW9uIFRpbWUAVHVlIDEzIERlYyAyMDIyIDA0OjM5OjI1IFBNIEVTVH9UhTgAAAIhSURBVEiJrZQxaBNhFMd/d7leYprGWEMkldIONta4xFAHqWiEYMHBpRktCkWHUoJOcexsF8EO6iA4KE4O0jgIgk6iUrDadrKobW3TJhgSm6S5kPscUhQbcvkS+qbHvXe/7//e979TwuGwYE8c6Du691HDmJqI/80TicR/NVWa0kZYwAV9wW1OHqobbH/gJ6Ip7t/5xqPrWcKe1g+xXIsQgK1K4EyGu1PrXB0wUfYHrvLqQT+Tjw+yVADFXWQ8vsGoX34Ca+WGxvxbH/FpL58KoHYWuXElR4+kfCm37Kx4mE46MAQ4j+e43C+nXh2PTBILRQm4dIs2hbX3bj5XAbXCULAipUr9svULvXuI8+FLHLM3ntfM63zPAQj8vgo2GfiHpWe8XF5H6AMM+lyN3SAUSkatatcl1wIm+XyKklBw6M6WrNYUrmsOHA4nuiLYKRdp/3usD+1a5GYtEwVyRWt4q1Nps3NPd1OD3/lq407VpNNRO7psyP3vtPXsilSjerhMwA2g8HNTw0LGv3d0zzAjp8cY6fdb2EsQPJdnUAXMDj4udGDKwGOnztKr51hOpRqoEXhDaW5HDWwKbC96eLEqt31tczXJ/I9FMpX6q+zqKXDxQpaxSAmvDcx8JzNP3GxKWkp7/XWhQclkOLbBrVCNVMm4uDdzhNktec9ozRrMos67N908THaxXJLmNoMrzD3vZXTLTtpoDSoFT6/Z26Puxh8ZKK5kzvJifAAAAABJRU5ErkJggg=="
	sampleImgBuf, _ := base64.StdEncoding.DecodeString(sampleBase64Img)
	clipboard.Write(clipboard.FmtImage, sampleImgBuf)
	time.Sleep(time.Second)
	imgRead := clipboard.Read(clipboard.FmtImage)
	decodedImgRead := base64.StdEncoding.EncodeToString(imgRead)
	fmt.Println(decodedImgRead == sampleBase64Img)
}

Does not completely work on Linux

Hi again, I'm testing the library with my Arch Linux+KDE Plasma installation (with X11).
It seems that the image that I put in clipboard works only on some application (ie. GIMP), but not in others (ie. Xournal++).

I also tried another solution using xclip and it works fine on both (maybe this information can be useful for you).

build time warnings under macOS 12.1

go build outputs warnings, but clipboard.Read works:

ld: warning: object file (/var/folders/9g/pvy9xv2s2s1grjl7x55dw3hr0000gn/T/go-link-3048299529/000003.o) was built for newer macOS version (12.0) than being linked (11.3)
ld: warning: object file (/var/folders/9g/pvy9xv2s2s1grjl7x55dw3hr0000gn/T/go-link-3048299529/000004.o) was built for newer macOS version (12.0) than being linked (11.3)
ld: warning: object file (/var/folders/9g/pvy9xv2s2s1grjl7x55dw3hr0000gn/T/go-link-3048299529/000005.o) was built for newer macOS version (12.0) than being linked (11.3)
ld: warning: object file (/var/folders/9g/pvy9xv2s2s1grjl7x55dw3hr0000gn/T/go-link-3048299529/000006.o) was built for newer macOS version (12.0) than being linked (11.3)
ld: warning: object file (/var/folders/9g/pvy9xv2s2s1grjl7x55dw3hr0000gn/T/go-link-3048299529/000007.o) was built for newer macOS version (12.0) than being linked (11.3)
ld: warning: object file (/var/folders/9g/pvy9xv2s2s1grjl7x55dw3hr0000gn/T/go-link-3048299529/000008.o) was built for newer macOS version (12.0) than being linked (11.3)
ld: warning: object file (/var/folders/9g/pvy9xv2s2s1grjl7x55dw3hr0000gn/T/go-link-3048299529/000009.o) was built for newer macOS version (12.0) than being linked (11.3)
ld: warning: object file (/var/folders/9g/pvy9xv2s2s1grjl7x55dw3hr0000gn/T/go-link-3048299529/000010.o) was built for newer macOS version (12.0) than being linked (11.3)
ld: warning: object file (/var/folders/9g/pvy9xv2s2s1grjl7x55dw3hr0000gn/T/go-link-3048299529/000011.o) was built for newer macOS version (12.0) than being linked (11.3)

my go env:

GO111MODULE=""
GOARCH="amd64"
GOBIN=""
GOCACHE="/Users/georgexsh/Library/Caches/go-build"
GOENV="/Users/georgexsh/Library/Application Support/go/env"
GOEXE=""
GOEXPERIMENT=""
GOFLAGS=""
GOHOSTARCH="amd64"
GOHOSTOS="darwin"
GOINSECURE=""
GOMODCACHE="/Users/georgexsh/go/pkg/mod"
GONOPROXY=""
GONOSUMDB=""
GOOS="darwin"
GOPATH="/Users/georgexsh/go"
GOPRIVATE=""
GOPROXY="https://proxy.golang.org,direct"
GOROOT="/usr/local/Cellar/go/1.17.5/libexec"
GOSUMDB="sum.golang.org"
GOTMPDIR=""
GOTOOLDIR="/usr/local/Cellar/go/1.17.5/libexec/pkg/tool/darwin_amd64"
GOVCS=""
GOVERSION="go1.17.5"
GCCGO="gccgo"
AR="ar"
CC="clang"
CXX="clang++"
CGO_ENABLED="1"
GOMOD="/Users/georgexsh/workspace/wasteland/alfred-timestamp/go.mod"
CGO_CFLAGS="-g -O2"
CGO_CPPFLAGS=""
CGO_CXXFLAGS="-g -O2"
CGO_FFLAGS="-g -O2"
CGO_LDFLAGS="-g -O2"
PKG_CONFIG="pkg-config"
GOGCCFLAGS="-fPIC -arch x86_64 -m64 -pthread -fno-caret-diagnostics -Qunused-arguments -fmessage-length=0 -fdebug-prefix-map=/var/folders/9g/pvy9xv2s2s1grjl7x55dw3hr0000gn/T/go-build4136004347=/tmp/go-build -gno-record-gcc-switches -fno-common"

Using clipboard trough ssh

I have a TUI application, which could potencially run trough ssh.
It's a rss reader with sixel images: https://sr.ht/~ghost08/photon
There are keybindings to copy the rss item's link, or the item's image, for which I use the golang-design/clipboard library.

But when I run it trough ssh it just panics this:

panic: Failed to initialize the X11 display, and the clipboard package
will not work properly. Install the following dependency may help:

	apt install -y libx11-dev

If the clipboard package is in an environment without a frame buffer,
such as a cloud server, it may also be necessary to install xvfb:

	apt install -y xvfb

and initialize a virtual frame buffer:

	Xvfb :99 -screen 0 1024x768x24 > /dev/null 2>&1 &
	export DISPLAY=:99.0

Then this package should be ready to use.


goroutine 1 [running]:
golang.design/x/clipboard.init.0()
	golang.design/x/[email protected]/clipboard_linux.go:65 +0x4b

Is there a way to ignore the missing display and don't panic?
I know that trough ssh clipboard will not work, but that's ok.

suggestion: making `Write` blocking instead of returning a channel

Thank you for such a great library!

The current Write returns a channel

func Write(t Format, buf []byte) <-chan struct{}

but an example in the comments doesn't use this channel. Is this intended? So I was a little confused whether the channel should be used or not.

In order to avoid confusion, wouldn't it better to change Write blocking and let users decide whether they wait for returning or not? They could use their own channels if they wanted to use Write as non-blocking. This suggestion would simplify the API and consistent with Read, which is already blocking.

What do you think? Thanks,

Warn and panic when CGO_ENABLED is set to 0

I'm not sure which library caused the problem. I wrote a demo to verify, it said

   โจฏ release failed after 0.53s error=failed to build for darwin_arm64: exit status 2: # golang.design/x/clipboard
../../../go/pkg/mod/golang.design/x/[email protected]/clipboard.go:90:14: undefined: read
../../../go/pkg/mod/golang.design/x/[email protected]/clipboard.go:110:18: undefined: write
../../../go/pkg/mod/golang.design/x/[email protected]/clipboard.go:125:9: undefined: watch

demo

Any ideas?

Exit directly after copying

if :

clipboard.Write(clipboard.FmtText, []byte("hello world"))
exit()

or

clipboard.Write(clipboard.FmtImage, content)
exit()

there will be nothing in clipboard
else:

<-clipboard.Write(clipboard.FmtText, []byte(imagePath))

clipboard is ok,but program is blocked untill something new is copied into clipboad .


ubuntu20.04

Copy GIF into clipboard failed(MacOS)

I am using a M1 Macbook Pro, I download a GIF image from Giphy site, then copy it to MacOS clipboard.
BUT Ooops, they transfer into a static image.

I am sure that copy it from Finder it works well.

Add *BSD support

Hi,

when building on recent FreeBSD 14.0 and OpenBSD 7.3 (amd64):

$ go install golang.design/x/clipboard/cmd/gclip@latest
# golang.design/x/clipboard
.go/pkg/mod/golang.design/x/[email protected]/clipboard.go:107:15: undefined: initialize
.go/pkg/mod/golang.design/x/[email protected]/clipboard.go:118:14: undefined: read
.go/pkg/mod/golang.design/x/[email protected]/clipboard.go:138:18: undefined: write
.go/pkg/mod/golang.design/x/[email protected]/clipboard.go:153:9: undefined: watch

I figure this is due to *BSDs not being explicitly supported, but perhaps there's a way to build clipboard anyways, especially since BSDs share a lot with Linux, including the X system.

Allow Custom Format

Currently, we only support UTF-8 text and PNG-encoded image data. However, there are much more formats than that.

Let's support registering custom format and handlers so that this package can help any other unregistered format. API design could be:

package clipboard

type Format int

// Add this.
func Register[T any](format clipboard.Format, read func([]byte) (T, error), write func() []byte) error { ... }

func Read(format clipboard.Format) []byte
func Write(format clipboard.Format, data []byte)
func Watch(format clipboard.Format) <-chan struct{}

Limit number of read requests by other applications

Hey @changkun,

Thank you for your great work.
I am wondering how hard it would be to implement the equivalent of the -l, -loops switch of xclip (X11ย tool on Linux) in your package.
The goal would be to allow only a limited number of Read operations on the clipboard before the content gets flushed. I am currently relying on piping to xclip to do that but Iย think it is not very clean and I'd like to opt for a full C/Go approach.

Cheers,

Windows 32-bit system will get stuck when executing.

The compilation parameters are as follows:
$env:GOARCH="amd64";
$env:GOOS="windows";
$env:GOARCH="386"; # 32
#$env:GOARCH="amd64"; # 64

and the program will be stucked at line 324 in the file clipborad_windows.go:

println("test in read 2")
// try again until open clipboard successed
   // will stuck here
for {
	r, _, _ = openClipboard.Call()
	if r == 0 {
		continue
	}
	break
}
    //  the following code will not be executed.
println("test in read 3")

Image read may block on Windows 10

when copy text can get text content;
but copy image, Read blocking

package main

import (
	"fmt"
	"golang.design/x/clipboard"
)

func main()  {

	fmt.Println(clipboard.Read(clipboard.FmtImage))
}

Windows: Write an image encoded to PNG after being loaded as JPEG messes up the image

package main

import (
	"bytes"
	"image"
	"image/png"
	"os"

	"golang.design/x/clipboard"

	_ "image/jpeg"
)

func main() {
	if err := clipboard.Init(); err != nil {
		panic(err)
	}

	// open some jpeg file
	fh, err := os.Open("image.jpg")
	if err != nil {
		panic(fh)
	}
	defer fh.Close()

	// decode the jpeg
	img, _, err := image.Decode(fh)
	if err != nil {
		panic(err)
	}

	// re-encode it to png
	var buf bytes.Buffer
	if err := png.Encode(&buf, img); err != nil {
		panic(err)
	}

	// image copied to clipboard is totally messed up
	clipboard.Write(clipboard.FmtImage, buf.Bytes())

	// image saved to file is good
	wfh, err := os.Create("image.png")
	if err != nil {
		panic(err)
	}
	defer wfh.Close()

	wfh.Write(buf.Bytes())
}

When executing this on windows, the PNG on disk is good, but the one on clipboard is bad

Source JPEG
508118

Here is the resulting PNG in clipboard
image

Build Error in Ubuntu 20.04 LTS with Unity as X-Window

Got the following error on Ubuntu:

# golang.design/x/clipboard
../../go/pkg/mod/golang.design/x/[email protected]/clipboard_linux.go:18:10: fatal error: X11/Xlib.h: No such file or directory
   18 | #include <X11/Xlib.h>
      |          ^~~~~~~~~~~~
compilation terminated.

Ref:

โฏ uname -a
Linux ubuntu 5.13.0-35-generic #40~20.04.1-Ubuntu SMP Mon Mar 7 09:18:32 UTC 2022 x86_64 x86_64 x86_64 GNU/Linux

Crashing on wayland

Hey,
I was trying to copy bytes to my clipboard using this library using

clipboard.Write(clipboard.FmtText, []byte(id))

But it immediately crashes, with this error:

โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
       โ”‚ File: err.log
โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
   1   โ”‚ X Error of failed request:  BadWindow (invalid Window parameter)
   2   โ”‚   Major opcode of failed request:  18 (X_ChangeProperty)
   3   โ”‚   Resource id in failed request:  0x20000b
   4   โ”‚   Serial number of failed request:  16
   5   โ”‚   Current serial number in output stream:  18
   6   โ”‚ exit status 1

I tried it again in a Xorg session, and it works as intended.

Also I run hyprland on wayland and gnome on xorg (both of them on arch).

I can take up this issue if you point me in the right direction.

Doesn't work with some target application on Windows 10

Hi, congratulations for your library, it is very useful and especially it's written in pure Go.
I have no problems at all while running on Linux, but when it comes to Windows problems magically appear (as always).
Basically, I am putting an image received from the network into the clipboard, but on Windows I get a broken clipboard, which makes impossible to copy-paste anything until I stop the application.
Using the clipboard history on Windows 10 I can partially see the image sent, but anyway all is gone.
The image I am sending is PNG encoded at the source, then send to my application which takes the image bytes received in a multipart HTTP form and puts it into the clipboard.

Thanks for help.

UPDATE:
I tried the demo tool gclip and it is able to save to a file the clipboard content, while ctrl+v (or gui equivalent) simply doesn't work as I said before. Once the file is saved, the clipboard begins to work again and I'm able to paste again.

Hangs / slow on Linux

Image from file_example_PNG_500kB.png

โžœ  ~ go install golang.design/x/clipboard/cmd/gclip@latest
โžœ  ~ gclip -copy -f ~/Downloads/file_example_PNG_500kB.png 

Takes 10-30 seconds to copy it to clipboard

โžœ  ~ cat /etc/os-release                     
PRETTY_NAME="Ubuntu 22.04.3 LTS"
NAME="Ubuntu"
VERSION_ID="22.04"
VERSION="22.04.3 LTS (Jammy Jellyfish)"
VERSION_CODENAME=jammy
ID=ubuntu
ID_LIKE=debian
HOME_URL="https://www.ubuntu.com/"
SUPPORT_URL="https://help.ubuntu.com/"
BUG_REPORT_URL="https://bugs.launchpad.net/ubuntu/"
PRIVACY_POLICY_URL="https://www.ubuntu.com/legal/terms-and-policies/privacy-policy"
UBUNTU_CODENAME=jammy

โžœ  ~ echo $XDG_SESSION_TYPE
wayland

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.