Slackadays/Clipboard

Suggestion: Enable Pasting into X11/Wayland session after copying from terminal on Linux

PlexSheep opened this issue ยท 55 comments

This project does all copy pasting one would want, but is restricted to the terminal. It would be a useful addition to be able to copy to the system clipboard and paste the systems clipboard using cb.

This is actually already WIP, but X11 is such a crusty old legacy API that it could be a couple releases before we get anything like this, so stay tuned.

Thats great news :). How is it with Wayland?

Wayland currently has nothing yet, as I'm finishing up a couple more features before I can get X11 working. (Check the changes-updates channel in Discord)

Hubro commented

Doesn't seem to work with Wayland at all, actually. When I copy anything from a terminal or the browser, cb show shows nothing. If I copy something using cb, for example echo foo | cb copy then it isn't added to my clipboard (I can't paste it into the e.g. the browser.)

@Hubro as the Owner stated:

Wayland currently has nothing yet

Hubro commented

@PlexSheep The context of this ticket is specifically pasting from clipboard. Since I saw references to Wayland in the source code, I had assumed everything else (like copying) worked with Wayland. I wrote the comment to clarify.

Fair enough.

Writing to the Windows clipboard has been added in 652e890

Reading from the Windows clipboard has been added in ce4c204

X11 read support has been added in 98d260f ๐Ÿ‘€ @PlexSheep

Thats great! next update will really be worth it.

macOS read support has been added in f4ac182 (you can also check https://github.com/Slackadays/Clipboard/wiki/GUI-Clipboard-Compat)

Full X11 support (copy and paste) is now available in 0.2.1 ๐Ÿ™‚

Hi, I'm the maintainer of the clipboard AUR packages.

Since v0.2.1 came out, there's now 4 different prebuilt binaries (no GUI, X11, Wayland and X11+Wayland) and I'm wondering which one the clipboard-bin AUR package should provide since there's no way for the PKGBUILD to determine whether the end-user has no GUI or is using X11/Wayland.

Does the X11+Wayland binary works for both but also for no GUI?
If so, is there any reason to provide the other binaries (since this one alone could cover all scenarios)?

Thanks in advance :)

X11+Wayland works for both, but because that build is linked against the X11 and Wayland libraries, if the user doesn't have both libraries installed, then the X11+Wayland version won't even start up. Perhaps you could check if the user has libx11 or libwayland installed to see if it would work?

X11+Wayland works for both, but because that build is linked against the X11 and Wayland libraries, if the user doesn't have both libraries installed, then the X11+Wayland version won't even start up. Perhaps you could check if the user has libx11 or libwayland installed to see if it would work?

If not sure I can elegantly check for installed packages on the end-user machines and decide which binary to install according to it via the PKGBUILD unfortunately. Isn't that something that can be managed by the program/binary directly (e.g. "if libx11 is installed, then [...])?

In the current state, I guess the three options we have as far as the AUR is concerned are:
1 - Create 3 new AUR packages associated with each binary (in addition of the current clipboard-bin package): clipboard-x11-bin, clipboard-wayland-bin, clipboard-x11_wayland-bin
2 - Either delete the clipboard-bin package and/or advice people to preferably use the clipboard/clipboard-git packages which will build clipboard directly on the end-user machine with the correct features according to their configuration (right?).
3 - Make x11 and wayland dependencies for the clipboard-bin packages and install the x11+wayland binary everytime.

Option 1 is obviously more work from a maintenance side and makes things more complex. But if this cannot be handled by the program/binary itself, that would probably be the only way to package the multiple versions correctly.
Option 2 is a bit more "radical" and only works because the package will be built on the end-user machine directly thanks to the AUR, which wouldn't be the case on official repo for instance (tell me if this need clearer explanations).
While it looks like the easiest solution, I'd like to avoid option 3 because it is not very elegant in my opinion...

Hopefully this can be handled by a single binary. Otherwise we'll have to choose one of the above options I guess.
What do you think?

Unfortunately, this can't be handled by the program/binary, because the library requirement happens before any code runs. So even if there was logic to handle this, it could never run because Linux insists on loading all the necessary libraries before doing anything. See this link: https://stackoverflow.com/questions/15951672/loading-linux-libraries-at-runtime

I think that the best solution is to make libx11 and libwayland dependencies because they don't have to do anything other than be present. If there is no X11 or Wayland compositor available (only the libraries), then Clipboard should still work because the errors are hidden unless you enable Debug Mode.

Unfortunately, this can't be handled by the program/binary, because the library requirement happens before any code runs. So even if there was logic to handle this, it could never run because Linux insists on loading all the necessary libraries before doing anything. See this link: https://stackoverflow.com/questions/15951672/loading-linux-libraries-at-runtime

Alright then

I think that the best solution is to make libx11 and libwayland dependencies because they don't have to do anything other than be present. If there is no X11 or Wayland compositor available (only the libraries), then Clipboard should still work because the errors are hidden unless you enable Debug Mode.

I initially wanted to avoid that since it didn't felt right forcing users with no GUI to install both X11 and Wayland. But if it's just the libraries, that should be fine indeed :)

Could we remove the hard requirement for libx11 and libwayland from the ELF header and try to load them at runtime with dlopen? If they fail, we assume that the system doesn't have that UI system installed and skip the code path.

It looks like that Stackoverflow post never claimed that you couldn't use dlopen to use shared libraries, just that it won't work if the filename is different from what you specify. If you can get it working, we could make a 0.2.1 Hotfix version to solve this problem once and for all.

Could we remove the hard requirement for libx11 and libwayland from the ELF header and try to load them at runtime with dlopen? If they fail, we assume that the system doesn't have that UI system installed and skip the code path.

๐Ÿ‘ That would allow me to make libx11 and libwayland optional dependencies which feels better honestly.
This way, people using the clipboard or clipboard-git packages will automatically get X11 and/or Wayland support (depending if their system has libx11 and/or libwayland installed) and as far as prebuilt binaries are concerned, you can provide only one that should work in any case.

Looks like dlopen doesn't relocate symbols for objects that have already been loaded, so we have two options:

  1. Remove libx11 and libwayland as compile dependencies entirely, use dlsym to load all of their functions/variables dynamically at runtime (e.g. display = dlsym(HANDLE_X11, 'XOpenDisplay')('DisplayName')
  2. Move the part of Clipboard that talks to X11 into a separate object (e.g. libclipboard-x11.so), ship that with the Linux executable and try to load it from the main clipboard executable (if libx11 isn't installed on the system it'll fail since that's a hard dependency on libclibpard-x11.so's ELF header). Do the same for Wayland, leading to three objects total (main executable, x11 code, wayland code).

Option 1 lets us keep all code into a single CMake target and therefore into a single standalone file for distribution, but it would make programming much more error-prone, since there'd be no compile-time checks to ensure you're calling a function correctly at all. We'd also have to duplicate everything that is lost at compilation on our side (macro definitions, structure definitions, etc).

I'm more partial to option 2. It would require us to split Clipboard into three CMake targets and distribute it as three files, but it makes it much easier to maintain/fix the code in the future. We could mitigate the issue of having to distribute it as three files by embedding the x11 and wayland libraries into the main executable and extracting them to /tmp at runtime, which would be transparent to the user.

I like the second option as well, because the first would seem better, but like you said we lose a lot of error checking and need more boilerplate. Hopefully it's possible to implement the second elegantly. Considering how we already have temporary folders to use, unpacking and loading should be easy, but embedding the files could be difficult because C's embed only made it into the latest C standard and won't be coming officially to C++ for years.

Would that change anything from a manual installation point of view?
If so, that's not a problem. It's just to know if have to adapt the PKGBUILD accordingly.

As long as we could condense the steps for building the libraries into the cmake --build . step, it should be no different because I believe CMake allows you to create multiple compile targets.

embedding the files could be difficult because C's embed only made it into the latest C standard and won't be coming officially to C++ for years.

We can start by shipping three files for Linux, as a minimum viable product. If that works as expected, we can start thinking about embedding and whatnot, but that's a late-stage optimization.

@Antiz96 X11 and Wayland are now optional as of #40

@Davipb Nice! Thanks a lot.
I updated the packages accordingly, making libx11 and wayland optional dependencies.

One last thing though. I noticed that the building logs still report lines related to X11/Wayland support.
For instance, on a "no GUI" system:

[...]
-- Could NOT find X11 (missing: X11_X11_INCLUDE_PATH X11_X11_LIB)
-- Building without X11 support
-- Found PkgConfig: /usr/bin/pkg-config (found version "1.8.0")
-- Checking for module 'wayland-client'
--   Package 'wayland-client', required by 'virtual:world', not found
-- Building without Wayland support
[...]

Is this intended? Maybe I understood things wrongly or I'm missing something but I thought that clipboard would always build with X11 and Wayland support out of the box as of now; but the associated code snippets would only execute if libx11 and/or libwayland are detected at runtime (if that makes sense).

EDIT: Forget it... It's only the provided prebuilt binary that has X11/Wayland support out of the box, right?
My bad, I messed things up in my brain for some reason ๐Ÿ˜†
Anyway, we should be all set now. Thanks once again for your actions!

EDIT: Forget it... It's only the provided prebuilt binary that has X11/Wayland support out of the box, right?

I know you already figured it out, but just to make it explicit to anyone else reading: to build Clipboard fully you still need X11/Wayland installed, but they're no longer required to run Clipboard. Building the project without X11 will cause libclipboardx11.so to not be generated, which means that the executable you built won't support X11 even on systems that do have it installed (the same goes for Wayland).

@Antiz96 What are the requirements to put Clipboard onto the main Arch repo other than having one package for binaries? If there have to be certain features, then maybe we could work on those.

@Antiz96 What are the requirements to put Clipboard onto the main Arch repo other than having one package for binaries? If there have to be certain features, then maybe we could work on those.

@Slackadays I think clipboard now respects every requirements from a packaging stand point. However, it will need to get some popularity on the AUR before being eligible to be moved to official Arch repo. See https://wiki.archlinux.org/title/AUR_Trusted_User_guidelines#Rules_for_packages_entering_the_[community]_repository

This Thread sounds like good progress, but still after installing it again (Fedora 37 using curl -sSL https://github.com/Slackadays/Clipboard/raw/main/src/install.sh | bash with X11, aswell as Arch installed from AUR) nothing is shown to be in the cb (cli) when i put something in my X11 clipboard.

(Clipboard 0.2.1r2)

When can we expect this feature to be in a release? Again thank you all for your great work :)

Also I just noticed that cb help lists a CLIPBOARD_NOGU flag, that can disable GUI integration, which sounds like X11 or Wayland to me, but that doesn't work for me even with the Flag not set. Am I missing something here?

@PlexSheep Would you mind manually compiling Clipboard as a Debug build? This will reveal everything with X11, and then we'll have more details to work with.

Okay I will try compiling it myself.

I just compiled it myself and copying and pasting from X11 clipboard to the cb program works fine. cb help says it's the same version I got before, but X11 pasting didn't work with that.

Anyways, this issues seems to be resolved now.

Wayland support still isn't ready yet, so I don't know if this issue should be closed

Is it a known thing that installation like the README says with curl -sSL https://github.com/Slackadays/Clipboard/raw/main/src/install.sh | bash doesn't enable the X11 clipboard? Even through it's supposedly the same version?

I can reopen the issue until wayland support is in a release aswell.

It should enable X11 support, but the X11 libraries may be different from what it expects or it could be some other issue. We can rule out the first one by adding LD_DEBUG=libs to the beginning, like LD_DEBUG=libs cb to see what libraries Clipboard is trying to load. Try this command with the version you installed with the script

This looks like an issue with the install script: it copies the executable to /usr/bin and the libraries to /usr/lib but never changes the executable's rpath to point to /usr/lib like it's done when CMake installs it. We might need to use patchelf --set-rpath /usr/lib/ clipboard in the install script.

$ LD_DEBUG=libs cb &> /tmp/a.txt
writes

      3432:	find library=libstdc++.so.6 [0]; searching
      3432:	 search path=/usr/bin/glibc-hwcaps/x86-64-v3:/usr/bin/glibc-hwcaps/x86-64-v2:/usr/bin/tls/haswell/x86_64:/usr/bin/tls/haswell:/usr/bin/tls/x86_64:/usr/bin/tls:/usr/bin/haswell/x86_64:/usr/bin/haswell:/usr/bin/x86_64:/usr/bin:glibc-hwcaps/x86-64-v3:glibc-hwcaps/x86-64-v2:tls/haswell/x86_64:tls/haswell:tls/x86_64:tls:haswell/x86_64:haswell:x86_64:		(RUNPATH from file cb)
      3432:	  trying file=/usr/bin/glibc-hwcaps/x86-64-v3/libstdc++.so.6
      3432:	  trying file=/usr/bin/glibc-hwcaps/x86-64-v2/libstdc++.so.6
      3432:	  trying file=/usr/bin/tls/haswell/x86_64/libstdc++.so.6
      3432:	  trying file=/usr/bin/tls/haswell/libstdc++.so.6
      3432:	  trying file=/usr/bin/tls/x86_64/libstdc++.so.6
      3432:	  trying file=/usr/bin/tls/libstdc++.so.6
      3432:	  trying file=/usr/bin/haswell/x86_64/libstdc++.so.6
      3432:	  trying file=/usr/bin/haswell/libstdc++.so.6
      3432:	  trying file=/usr/bin/x86_64/libstdc++.so.6
      3432:	  trying file=/usr/bin/libstdc++.so.6
      3432:	  trying file=glibc-hwcaps/x86-64-v3/libstdc++.so.6
      3432:	  trying file=glibc-hwcaps/x86-64-v2/libstdc++.so.6
      3432:	  trying file=tls/haswell/x86_64/libstdc++.so.6
      3432:	  trying file=tls/haswell/libstdc++.so.6
      3432:	  trying file=tls/x86_64/libstdc++.so.6
      3432:	  trying file=tls/libstdc++.so.6
      3432:	  trying file=haswell/x86_64/libstdc++.so.6
      3432:	  trying file=haswell/libstdc++.so.6
      3432:	  trying file=x86_64/libstdc++.so.6
      3432:	  trying file=libstdc++.so.6
      3432:	 search cache=/etc/ld.so.cache
      3432:	  trying file=/lib64/libstdc++.so.6
      3432:	
      3432:	find library=libgcc_s.so.1 [0]; searching
      3432:	 search path=/usr/bin:glibc-hwcaps/x86-64-v3:glibc-hwcaps/x86-64-v2:tls/haswell/x86_64:tls/haswell:tls/x86_64:tls:haswell/x86_64:haswell:x86_64:		(RUNPATH from file cb)
      3432:	  trying file=/usr/bin/libgcc_s.so.1
      3432:	  trying file=glibc-hwcaps/x86-64-v3/libgcc_s.so.1
      3432:	  trying file=glibc-hwcaps/x86-64-v2/libgcc_s.so.1
      3432:	  trying file=tls/haswell/x86_64/libgcc_s.so.1
      3432:	  trying file=tls/haswell/libgcc_s.so.1
      3432:	  trying file=tls/x86_64/libgcc_s.so.1
      3432:	  trying file=tls/libgcc_s.so.1
      3432:	  trying file=haswell/x86_64/libgcc_s.so.1
      3432:	  trying file=haswell/libgcc_s.so.1
      3432:	  trying file=x86_64/libgcc_s.so.1
      3432:	  trying file=libgcc_s.so.1
      3432:	 search cache=/etc/ld.so.cache
      3432:	  trying file=/lib64/libgcc_s.so.1
      3432:	
      3432:	find library=libc.so.6 [0]; searching
      3432:	 search path=/usr/bin:glibc-hwcaps/x86-64-v3:glibc-hwcaps/x86-64-v2:tls/haswell/x86_64:tls/haswell:tls/x86_64:tls:haswell/x86_64:haswell:x86_64:		(RUNPATH from file cb)
      3432:	  trying file=/usr/bin/libc.so.6
      3432:	  trying file=glibc-hwcaps/x86-64-v3/libc.so.6
      3432:	  trying file=glibc-hwcaps/x86-64-v2/libc.so.6
      3432:	  trying file=tls/haswell/x86_64/libc.so.6
      3432:	  trying file=tls/haswell/libc.so.6
      3432:	  trying file=tls/x86_64/libc.so.6
      3432:	  trying file=tls/libc.so.6
      3432:	  trying file=haswell/x86_64/libc.so.6
      3432:	  trying file=haswell/libc.so.6
      3432:	  trying file=x86_64/libc.so.6
      3432:	  trying file=libc.so.6
      3432:	 search cache=/etc/ld.so.cache
      3432:	  trying file=/lib64/libc.so.6
      3432:	
      3432:	find library=libm.so.6 [0]; searching
      3432:	 search cache=/etc/ld.so.cache
      3432:	  trying file=/lib64/libm.so.6
      3432:	
      3432:	
      3432:	calling init: /lib64/ld-linux-x86-64.so.2
      3432:	
      3432:	
      3432:	calling init: /lib64/libc.so.6
      3432:	
      3432:	
      3432:	calling init: /lib64/libm.so.6
      3432:	
      3432:	
      3432:	calling init: /lib64/libgcc_s.so.1
      3432:	
      3432:	
      3432:	calling init: /lib64/libstdc++.so.6
      3432:	
      3432:	
      3432:	initialize program: cb
      3432:	
      3432:	
      3432:	transferring control: cb
      3432:	
      3432:	find library=libclipboardx11.so [0]; searching
      3432:	 search path=/usr/bin:glibc-hwcaps/x86-64-v3:glibc-hwcaps/x86-64-v2:tls/haswell/x86_64:tls/haswell:tls/x86_64:tls:haswell/x86_64:haswell:x86_64:		(RUNPATH from file cb)
      3432:	  trying file=/usr/bin/libclipboardx11.so
      3432:	  trying file=glibc-hwcaps/x86-64-v3/libclipboardx11.so
      3432:	  trying file=glibc-hwcaps/x86-64-v2/libclipboardx11.so
      3432:	  trying file=tls/haswell/x86_64/libclipboardx11.so
      3432:	  trying file=tls/haswell/libclipboardx11.so
      3432:	  trying file=tls/x86_64/libclipboardx11.so
      3432:	  trying file=tls/libclipboardx11.so
      3432:	  trying file=haswell/x86_64/libclipboardx11.so
      3432:	  trying file=haswell/libclipboardx11.so
      3432:	  trying file=x86_64/libclipboardx11.so
      3432:	  trying file=libclipboardx11.so
      3432:	 search cache=/etc/ld.so.cache
      3432:	 search path=/lib64/glibc-hwcaps/x86-64-v3:/lib64/glibc-hwcaps/x86-64-v2:/lib64/tls/haswell/x86_64:/lib64/tls/haswell:/lib64/tls/x86_64:/lib64/tls:/lib64/haswell/x86_64:/lib64/haswell:/lib64/x86_64:/lib64:/usr/lib64/glibc-hwcaps/x86-64-v3:/usr/lib64/glibc-hwcaps/x86-64-v2:/usr/lib64/tls/haswell/x86_64:/usr/lib64/tls/haswell:/usr/lib64/tls/x86_64:/usr/lib64/tls:/usr/lib64/haswell/x86_64:/usr/lib64/haswell:/usr/lib64/x86_64:/usr/lib64		(system search path)
      3432:	  trying file=/lib64/glibc-hwcaps/x86-64-v3/libclipboardx11.so
      3432:	  trying file=/lib64/glibc-hwcaps/x86-64-v2/libclipboardx11.so
      3432:	  trying file=/lib64/tls/haswell/x86_64/libclipboardx11.so
      3432:	  trying file=/lib64/tls/haswell/libclipboardx11.so
      3432:	  trying file=/lib64/tls/x86_64/libclipboardx11.so
      3432:	  trying file=/lib64/tls/libclipboardx11.so
      3432:	  trying file=/lib64/haswell/x86_64/libclipboardx11.so
      3432:	  trying file=/lib64/haswell/libclipboardx11.so
      3432:	  trying file=/lib64/x86_64/libclipboardx11.so
      3432:	  trying file=/lib64/libclipboardx11.so
      3432:	  trying file=/usr/lib64/glibc-hwcaps/x86-64-v3/libclipboardx11.so
      3432:	  trying file=/usr/lib64/glibc-hwcaps/x86-64-v2/libclipboardx11.so
      3432:	  trying file=/usr/lib64/tls/haswell/x86_64/libclipboardx11.so
      3432:	  trying file=/usr/lib64/tls/haswell/libclipboardx11.so
      3432:	  trying file=/usr/lib64/tls/x86_64/libclipboardx11.so
      3432:	  trying file=/usr/lib64/tls/libclipboardx11.so
      3432:	  trying file=/usr/lib64/haswell/x86_64/libclipboardx11.so
      3432:	  trying file=/usr/lib64/haswell/libclipboardx11.so
      3432:	  trying file=/usr/lib64/x86_64/libclipboardx11.so
      3432:	  trying file=/usr/lib64/libclipboardx11.so
      3432:	
      3432:	find library=libclipboardwayland.so [0]; searching
      3432:	 search path=/usr/bin:glibc-hwcaps/x86-64-v3:glibc-hwcaps/x86-64-v2:tls/haswell/x86_64:tls/haswell:tls/x86_64:tls:haswell/x86_64:haswell:x86_64:		(RUNPATH from file cb)
      3432:	  trying file=/usr/bin/libclipboardwayland.so
      3432:	  trying file=glibc-hwcaps/x86-64-v3/libclipboardwayland.so
      3432:	  trying file=glibc-hwcaps/x86-64-v2/libclipboardwayland.so
      3432:	  trying file=tls/haswell/x86_64/libclipboardwayland.so
      3432:	  trying file=tls/haswell/libclipboardwayland.so
      3432:	  trying file=tls/x86_64/libclipboardwayland.so
      3432:	  trying file=tls/libclipboardwayland.so
      3432:	  trying file=haswell/x86_64/libclipboardwayland.so
      3432:	  trying file=haswell/libclipboardwayland.so
      3432:	  trying file=x86_64/libclipboardwayland.so
      3432:	  trying file=libclipboardwayland.so
      3432:	 search cache=/etc/ld.so.cache
      3432:	 search path=/lib64:/usr/lib64		(system search path)
      3432:	  trying file=/lib64/libclipboardwayland.so
      3432:	  trying file=/usr/lib64/libclipboardwayland.so
      3432:	
      3432:	
      3432:	calling fini: cb [0]
      3432:	
      3432:	
      3432:	calling fini: /lib64/libstdc++.so.6 [0]
      3432:	
      3432:	
      3432:	calling fini: /lib64/libgcc_s.so.1 [0]
      3432:	
      3432:	
      3432:	calling fini: /lib64/libm.so.6 [0]
      3432:	

(I reinstalled the curl version, copy/paste to/from X11 doesn't work with this one)

Looks like Clipboard actually is searching the "right" path, but not the one the libs are installed to, because Fedora is a special case. The simplest fix would be simply to add /usr/bin to the search path both for building and installing in CMake.

The debug logs for the clipboardx11 lib seem to be the same as the ones i get on my arch linux install. Why did the clipboard work when i compiled it myself using the standard cmake commands? If I understand this correctly, I don't have to add anything to any cmake configs.

Just added the install prefix path to my local build, and even though it will search $ORIGIN first for libraries, it will now fall back to searching the install prefix path.

     48478:	transferring control: ./clipboard
     48478:	
     48478:	find library=libclipboardx11.so [0]; searching
     48478:	 search path=/home/jackson/Clipboard/build		(RUNPATH from file ./clipboard)
     48478:	  trying file=/home/jackson/Clipboard/build/libclipboardx11.so
     48478:	
     48478:	find library=libX11.so.6 [0]; searching
     48478:	 search cache=/etc/ld.so.cache
     48478:	  trying file=/lib/x86_64-linux-gnu/libX11.so.6

Dynamic section at offset 0x16a10 contains 30 entries:
  Tag        Type                         Name/Value
 0x0000000000000001 (NEEDED)             Shared library: [libstdc++.so.6]
 0x0000000000000001 (NEEDED)             Shared library: [libgcc_s.so.1]
 0x0000000000000001 (NEEDED)             Shared library: [libc.so.6]
 0x000000000000001d (RUNPATH)            Library runpath: [$ORIGIN:/usr/lib:]
 0x000000000000000c (INIT)               0x4000
 0x000000000000000d (FINI)               0xe654
 0x0000000000000019 (INIT_ARRAY)         0x177e8
 0x000000000000001b (INIT_ARRAYSZ)       16 (bytes)```

The debug logs for the clipboardx11 lib seem to be the same as the ones i get on my arch linux install. Why did the clipboard work when i compiled it myself using the standard cmake commands? If I understand this correctly, I don't have to add anything to any cmake configs.

Do BOTH logs mention "opening an X11 connection"?

Why did the clipboard work when i compiled it myself using the standard cmake commands?

When you do cmake --install, CMake overwrites the executable's rpath to point to wherever it copied the libclipboardx11.so, so it finds and opens that library, which lets it connect to X11. The pre-built binaries used by the install script only have $ORIGIN as their rpath, so this doesn't work as expected since /usr/lib isn't in the system-wide library search path (only /usr/lib64)

The debug logs for the clipboardx11 lib seem to be the same as the ones i get on my arch linux install. Why did the clipboard work when i compiled it myself using the standard cmake commands? If I understand this correctly, I don't have to add anything to any cmake configs.

Do BOTH logs mention "opening an X11 connection"?

I think none do, which makes sense, as none of these versions work. Only the one I compiled on my local machine does.

@PlexSheep The latest build should have a fix, so would you mind trying the install script again?

I will try right now, give me a second

This new cb version works for me on Fedora 37.

      7728:	find library=libstdc++.so.6 [0]; searching
      7728:	 search path=/usr/bin/glibc-hwcaps/x86-64-v3:/usr/bin/glibc-hwcaps/x86-64-v2:/usr/bin/tls/haswell/x86_64:/usr/bin/tls/haswell:/usr/bin/tls/x86_64:/usr/bin/tls:/usr/bin/haswell/x86_64:/usr/bin/haswell:/usr/bin/x86_64:/usr/bin:/usr/lib/glibc-hwcaps/x86-64-v3:/usr/lib/glibc-hwcaps/x86-64-v2:/usr/lib/tls/haswell/x86_64:/usr/lib/tls/haswell:/usr/lib/tls/x86_64:/usr/lib/tls:/usr/lib/haswell/x86_64:/usr/lib/haswell:/usr/lib/x86_64:/usr/lib:glibc-hwcaps/x86-64-v3:glibc-hwcaps/x86-64-v2:tls/haswell/x86_64:tls/haswell:tls/x86_64:tls:haswell/x86_64:haswell:x86_64:		(RUNPATH from file cb)
      7728:	  trying file=/usr/bin/glibc-hwcaps/x86-64-v3/libstdc++.so.6
      7728:	  trying file=/usr/bin/glibc-hwcaps/x86-64-v2/libstdc++.so.6
      7728:	  trying file=/usr/bin/tls/haswell/x86_64/libstdc++.so.6
      7728:	  trying file=/usr/bin/tls/haswell/libstdc++.so.6
      7728:	  trying file=/usr/bin/tls/x86_64/libstdc++.so.6
      7728:	  trying file=/usr/bin/tls/libstdc++.so.6
      7728:	  trying file=/usr/bin/haswell/x86_64/libstdc++.so.6
      7728:	  trying file=/usr/bin/haswell/libstdc++.so.6
      7728:	  trying file=/usr/bin/x86_64/libstdc++.so.6
      7728:	  trying file=/usr/bin/libstdc++.so.6
      7728:	  trying file=/usr/lib/glibc-hwcaps/x86-64-v3/libstdc++.so.6
      7728:	  trying file=/usr/lib/glibc-hwcaps/x86-64-v2/libstdc++.so.6
      7728:	  trying file=/usr/lib/tls/haswell/x86_64/libstdc++.so.6
      7728:	  trying file=/usr/lib/tls/haswell/libstdc++.so.6
      7728:	  trying file=/usr/lib/tls/x86_64/libstdc++.so.6
      7728:	  trying file=/usr/lib/tls/libstdc++.so.6
      7728:	  trying file=/usr/lib/haswell/x86_64/libstdc++.so.6
      7728:	  trying file=/usr/lib/haswell/libstdc++.so.6
      7728:	  trying file=/usr/lib/x86_64/libstdc++.so.6
      7728:	  trying file=/usr/lib/libstdc++.so.6
      7728:	  trying file=glibc-hwcaps/x86-64-v3/libstdc++.so.6
      7728:	  trying file=glibc-hwcaps/x86-64-v2/libstdc++.so.6
      7728:	  trying file=tls/haswell/x86_64/libstdc++.so.6
      7728:	  trying file=tls/haswell/libstdc++.so.6
      7728:	  trying file=tls/x86_64/libstdc++.so.6
      7728:	  trying file=tls/libstdc++.so.6
      7728:	  trying file=haswell/x86_64/libstdc++.so.6
      7728:	  trying file=haswell/libstdc++.so.6
      7728:	  trying file=x86_64/libstdc++.so.6
      7728:	  trying file=libstdc++.so.6
      7728:	 search cache=/etc/ld.so.cache
      7728:	  trying file=/lib64/libstdc++.so.6
      7728:	
      7728:	find library=libgcc_s.so.1 [0]; searching
      7728:	 search path=/usr/bin:/usr/lib:glibc-hwcaps/x86-64-v3:glibc-hwcaps/x86-64-v2:tls/haswell/x86_64:tls/haswell:tls/x86_64:tls:haswell/x86_64:haswell:x86_64:		(RUNPATH from file cb)
      7728:	  trying file=/usr/bin/libgcc_s.so.1
      7728:	  trying file=/usr/lib/libgcc_s.so.1
      7728:	  trying file=glibc-hwcaps/x86-64-v3/libgcc_s.so.1
      7728:	  trying file=glibc-hwcaps/x86-64-v2/libgcc_s.so.1
      7728:	  trying file=tls/haswell/x86_64/libgcc_s.so.1
      7728:	  trying file=tls/haswell/libgcc_s.so.1
      7728:	  trying file=tls/x86_64/libgcc_s.so.1
      7728:	  trying file=tls/libgcc_s.so.1
      7728:	  trying file=haswell/x86_64/libgcc_s.so.1
      7728:	  trying file=haswell/libgcc_s.so.1
      7728:	  trying file=x86_64/libgcc_s.so.1
      7728:	  trying file=libgcc_s.so.1
      7728:	 search cache=/etc/ld.so.cache
      7728:	  trying file=/lib64/libgcc_s.so.1
      7728:	
      7728:	find library=libc.so.6 [0]; searching
      7728:	 search path=/usr/bin:/usr/lib:glibc-hwcaps/x86-64-v3:glibc-hwcaps/x86-64-v2:tls/haswell/x86_64:tls/haswell:tls/x86_64:tls:haswell/x86_64:haswell:x86_64:		(RUNPATH from file cb)
      7728:	  trying file=/usr/bin/libc.so.6
      7728:	  trying file=/usr/lib/libc.so.6
      7728:	  trying file=glibc-hwcaps/x86-64-v3/libc.so.6
      7728:	  trying file=glibc-hwcaps/x86-64-v2/libc.so.6
      7728:	  trying file=tls/haswell/x86_64/libc.so.6
      7728:	  trying file=tls/haswell/libc.so.6
      7728:	  trying file=tls/x86_64/libc.so.6
      7728:	  trying file=tls/libc.so.6
      7728:	  trying file=haswell/x86_64/libc.so.6
      7728:	  trying file=haswell/libc.so.6
      7728:	  trying file=x86_64/libc.so.6
      7728:	  trying file=libc.so.6
      7728:	 search cache=/etc/ld.so.cache
      7728:	  trying file=/lib64/libc.so.6
      7728:	
      7728:	find library=libm.so.6 [0]; searching
      7728:	 search cache=/etc/ld.so.cache
      7728:	  trying file=/lib64/libm.so.6
      7728:	
      7728:	
      7728:	calling init: /lib64/ld-linux-x86-64.so.2
      7728:	
      7728:	
      7728:	calling init: /lib64/libc.so.6
      7728:	
      7728:	
      7728:	calling init: /lib64/libm.so.6
      7728:	
      7728:	
      7728:	calling init: /lib64/libgcc_s.so.1
      7728:	
      7728:	
      7728:	calling init: /lib64/libstdc++.so.6
      7728:	
      7728:	
      7728:	initialize program: cb
      7728:	
      7728:	
      7728:	transferring control: cb
      7728:	
      7728:	find library=libclipboardx11.so [0]; searching
      7728:	 search path=/usr/bin:/usr/lib:glibc-hwcaps/x86-64-v3:glibc-hwcaps/x86-64-v2:tls/haswell/x86_64:tls/haswell:tls/x86_64:tls:haswell/x86_64:haswell:x86_64:		(RUNPATH from file cb)
      7728:	  trying file=/usr/bin/libclipboardx11.so
      7728:	  trying file=/usr/lib/libclipboardx11.so
      7728:	
      7728:	find library=libX11.so.6 [0]; searching
      7728:	 search cache=/etc/ld.so.cache
      7728:	  trying file=/lib64/libX11.so.6
      7728:	
      7728:	find library=libxcb.so.1 [0]; searching
      7728:	 search cache=/etc/ld.so.cache
      7728:	  trying file=/lib64/libxcb.so.1
      7728:	
      7728:	find library=libXau.so.6 [0]; searching
      7728:	 search cache=/etc/ld.so.cache
      7728:	  trying file=/lib64/libXau.so.6
      7728:	
      7728:	
      7728:	calling init: /lib64/libXau.so.6
      7728:	
      7728:	
      7728:	calling init: /lib64/libxcb.so.1
      7728:	
      7728:	
      7728:	calling init: /lib64/libX11.so.6
      7728:	
      7728:	
      7728:	calling init: /usr/lib/libclipboardx11.so
      7728:	
      7728:	find library=libclipboardwayland.so [0]; searching
      7728:	 search path=/usr/bin:/usr/lib:glibc-hwcaps/x86-64-v3:glibc-hwcaps/x86-64-v2:tls/haswell/x86_64:tls/haswell:tls/x86_64:tls:haswell/x86_64:haswell:x86_64:		(RUNPATH from file cb)
      7728:	  trying file=/usr/bin/libclipboardwayland.so
      7728:	  trying file=/usr/lib/libclipboardwayland.so
      7728:	
      7728:	
      7728:	calling init: /usr/lib/libclipboardwayland.so
      7728:	
      7728:	
      7728:	calling fini: cb [0]
      7728:	
      7728:	
      7728:	calling fini: /usr/lib/libclipboardx11.so [0]
      7728:	
      7728:	
      7728:	calling fini: /lib64/libstdc++.so.6 [0]
      7728:	
      7728:	
      7728:	calling fini: /lib64/libgcc_s.so.1 [0]
      7728:	
      7728:	
      7728:	calling fini: /lib64/libm.so.6 [0]
      7728:	
      7728:	
      7728:	calling fini: /lib64/libX11.so.6 [0]
      7728:	
      7728:	
      7728:	calling fini: /lib64/libxcb.so.1 [0]
      7728:	
      7728:	
      7728:	calling fini: /lib64/libXau.so.6 [0]
      7728:	
      7728:	
      7728:	calling fini: /usr/lib/libclipboardwayland.so [0]
      7728:	

In fact, i copied these logs using the project. Not entirely sure what you did, but that fixed it.

@PlexSheep @Hubro It's time to put this issue to rest, as complete Wayland support has been added as of c89b72e. However, the next release may not come for a couple days to allow time for simplification/bug fixing.

Hubro commented

@Slackadays I just tested out clipboard for Wayland, and there's possibly a bug. Whenever I copy something (for example echo foo | cb) a window pops up for maybe 0.1 seconds. This probably wouldn't be so disruptive if I wasn't using Sway (a tiling window manager) and the new window causes every other window to get squished and jump around. The same happens when I run cb show or cb paste.

@Hubro This is actually a feature of Wayland, although not a very nice one. Wayland only lets programs access the clipboard if they have a window with focus in order to improve security. This means that to access the Wayland clipboard, CB has to make a dummy window and give it focus just to get access. That window has a size and height of 1 pixel so it normally isn't visible. However, since sway will want to display everything in tiles, it picks up on that dummy window and causes the problem you see.

So, to fix this, you'll either need to disable tiling, get sway to add a rule to not display 1x1 windows, or get Wayland to change the protocol to let CB not use a dummy window.

Edit: I would say that little things like this are why Wayland is still considered half-baked, considering how this issue doesn't exist anywhere else.

Hubro commented

@Slackadays That's odd, wl-clipboard does this without opening any windows. I've been using wl-copy and wl-paste for months. You could check how they do it ๐Ÿ™‚

@Davipb Any thoughts on this?

While it's technically possible to create a wl_data_device and get clipboard data from it without an active window from a pure reading of the specs, GNOME on Ubuntu 22.04 (the system I used to test the Wayland implementation) will only actually make data available on the device when one of your windows gains focus. Searching online, this seems to be a common behavior across many desktop managers, probably for X11 compatibility.

In fact, wl-clipboard does open a window when getting data from wl_data_device, you can see it here: wl-paste.c:486 (needs_popup_surface is set in the INIT macro, which is set to 1 (true) for wl_data_device; popup_surface_init opens a window).

So there's two possibilities:

wl-clipboard is using a non-standard data device that doesn't require a focused window to get/set the clipboard data.

wl_data_device is the standard device specified in the Wayland specs and supported by all implementations, but systems often have their own implementation-specific devices with different semantics or options. wl-clipboard seems to support gtk_primary_selection_device, zwp_primary_selection_device_v1, and zwlr_data_control_device_v1.

wl-clipboard is opening the window in a way that causes Sway to not show it.

In fact that's already what happens for CB on GNOME: the opened window isn't visible even for a fraction of a second (I tested that when implementing the code). Maybe the way we open the window is enough for it to not show in GNOME but not enough for Sway.