I want to express my gratitude for developing this package! It has been incredibly helpful in many aspects of my work, and I truly appreciate the time and effort you've invested in it. However, I have noticed some performance issues and unexpected behavior when using it in a Linux Wayland session desktop environment.
I noticed that each write operation starts a coroutine that then enters a C function
go func() { // serve as a daemon until the ownership is terminated.
runtime.LockOSThread()
defer runtime.UnlockOSThread()
cs := C.CString(s)
defer C.free(unsafe.Pointer(cs))
h := cgo.NewHandle(start)
var ok C.int
if len(buf) == 0 {
ok = C.clipboard_write(cs, nil, 0, C.uintptr_t(h))
} else {
ok = C.clipboard_write(cs, (*C.uchar)(unsafe.Pointer(&(buf[0]))), C.size_t(len(buf)), C.uintptr_t(h))
}
if ok != C.int(0) {
fmt.Fprintf(os.Stderr, "write failed with status: %d\n", int(ok))
}
done <- struct{}{}
close(done)
}()
Within the C function clipboard_write, it appears to enter a loop that seems unable to exit (at least, I haven't found an exit condition so far).
// clipboard_write writes the given buf of size n as type typ.
// if start is provided, the value of start will be changed to 1 to indicate
// if the write is availiable for reading.
int clipboard_write(char *typ, unsigned char *buf, size_t n, uintptr_t handle) {
// ......
XEvent event;
XSelectionRequestEvent* xsr;
int notified = 0;
for (;;) { // loop forever
if (notified == 0) {
syncStatus(handle, 1); // notify Go side
notified = 1;
}
(*P_XNextEvent)(d, &event);
switch (event.type) {
case SelectionClear:
(*P_XCloseDisplay)(d);
return 0;
case SelectionNotify:
break;
case SelectionRequest:
// ......
if ((R & 2) == 0) (*P_XSendEvent)(d, ev.requestor, 0, 0, (XEvent *)&ev);
break;
}
}
}
I am concerned that repeatedly calling write in this way could lead to performance issues over time. If there’s no performance impact, could you kindly explain why? I would love to understand the mechanics better and learn from your insights.
--
Doesn't Work as Expected on Linux Wayland-session DE
I'm encountering an issue with clipboard operations in a Wayland session on Linux. Here’s a summary of the problem:
// Initialization...
<-clipboard.Write(f, []byte("123456")) // This hangs indefinitely until I manually send a Control-C signal.
//go func() { <-changed }()
return nil
However, this approach doesn’t work as expected—the clipboard doesn’t receive the data successfully. I suspect this is because the Goroutine handling the Write operation doesn't complete before the program exits.
This works, but introducing an arbitrary sleep is not ideal.
Expected Behavior:
I expected that, after successfully writing to the clipboard, the channel would receive a signal or value indicating completion. This way, I could avoid any delay-based workarounds.
Would you be able to clarify if there’s a preferred way to ensure the Write operation completes before the program exits? Or is there an internal mechanism for confirming successful writes that I might have missed?
First of all
I want to express my gratitude for developing this package! It has been incredibly helpful in many aspects of my work, and I truly appreciate the time and effort you've invested in it. However, I have noticed some performance issues and unexpected behavior when using it in a Linux Wayland session desktop environment.
Environment
Performance issues
I noticed that each write operation starts a coroutine that then enters a C function
Within the C function clipboard_write, it appears to enter a loop that seems unable to exit (at least, I haven't found an exit condition so far).
I am concerned that repeatedly calling write in this way could lead to performance issues over time. If there’s no performance impact, could you kindly explain why? I would love to understand the mechanics better and learn from your insights.
--
Doesn't Work as Expected on Linux Wayland-session DE
I'm encountering an issue with clipboard operations in a Wayland session on Linux. Here’s a summary of the problem:
To troubleshoot, I modified the code as follows:
However, this approach doesn’t work as expected—the clipboard doesn’t receive the data successfully. I suspect this is because the Goroutine handling the
Write
operation doesn't complete before the program exits.To verify, I added a short delay after
Write
:This works, but introducing an arbitrary sleep is not ideal.
Expected Behavior:
I expected that, after successfully writing to the clipboard, the channel would receive a signal or value indicating completion. This way, I could avoid any delay-based workarounds.
Would you be able to clarify if there’s a preferred way to ensure the
Write
operation completes before the program exits? Or is there an internal mechanism for confirming successful writes that I might have missed?