Hyprland icon indicating copy to clipboard operation
Hyprland copied to clipboard

Clipboard synchronization between wayland and xwayland clients broken

Open Ghosthree3 opened this issue 1 year ago • 11 comments

Hyprland Version

System/Version info
Hyprland, built from branch main at commit 2ead1fd22103ce065661555513bace5897083ded  (virtual-keyboard: emit event before finishing keyboard).
Date: Sat May 18 05:07:33 2024
Tag: v0.40.0-111-g2ead1fd2, commits: 4717

flags: (if any)


System Information:
System name: Linux
Node name: milkbar
Release: 6.9.1-arch1-1
Version: #1 SMP PREEMPT_DYNAMIC Fri, 17 May 2024 16:56:38 +0000


GPU information: 
0b:00.0 VGA compatible controller [0300]: Advanced Micro Devices, Inc. [AMD/ATI] Navi 10 [Radeon RX 5600 OEM/5600 XT / 5700/5700 XT] [1002:731f] (rev c1) (prog-if 00 [VGA controller])
0c:00.0 VGA compatible controller [0300]: NVIDIA Corporation TU104 [GeForce RTX 2070 SUPER] [10de:1e84] (rev a1) (prog-if 00 [VGA controller])


os-release: NAME="Arch Linux"
PRETTY_NAME="Arch Linux"
ID=arch
BUILD_ID=rolling
ANSI_COLOR="38;2;23;147;209"
HOME_URL="https://archlinux.org/"
DOCUMENTATION_URL="https://wiki.archlinux.org/"
SUPPORT_URL="https://bbs.archlinux.org/"
BUG_REPORT_URL="https://gitlab.archlinux.org/groups/archlinux/-/issues"
PRIVACY_POLICY_URL="https://terms.archlinux.org/docs/privacy-policy/"
LOGO=archlinux-logo


plugins:

Bug or Regression?

Regression

Description

Trying to copy/paste data between wayland and xwayland clients is broken as of 121d3a7.

121d3a72137d4780602cf245704615f63357ea22 is the first bad commit

An error can be observed from xwayland clients when trying to paste something copied from a wayland client if the xwayland clipboard is empty.

[glfw error 65545]: X11: Failed to convert selection to data from clipboard

But if there exists something on the xwayland clipboard (because of a copy from an existing xwayland client) that will be pasted and no error given. When pasting into a wayland client, the last copy from a wayland client is used (if it still exists), regardless of the existence of a valid xwayland clipboard or not.

There was one time when playing around copying and pasting I managed to crash Hyprland. I think while attempting to close an xwayland window with something on its clipboard, which would hang invisibly.

How to reproduce

Open two windows, one under wayland, one under xwayland, and try to copy paste between them.

I was testing by opening a terminal (kitty) under wayland, then using it to load an x11 copy of itself (kitty -o linux_display_server=x11) and trying to copy paste between them.

First noticed because I was unable to copy paste things from my browser into Discord.

Crash reports, logs, images, videos

No response

Ghosthree3 avatar May 18 '24 01:05 Ghosthree3

Can confirm. I cannot copy/paste between Firefox and electron apps like Discord, Steam, and Obsidian.

System info
Hyprland, built from branch main at commit a8522db683ae260f16f8e7778561d8a54906beb1  (keybinds: fix empty on monitor for new workspaces (6089)).
Date: Wed May 15 13:03:51 2024
Tag: v0.40.0-93-ga8522db6, commits: 4699

flags: (if any)
System name: Linux
Node name: endeavour
Release: 6.9.1-arch1-1
Version: #1 SMP PREEMPT_DYNAMIC Fri, 17 May 2024 16:56:38 +0000

GPU information:
01:00.0 VGA compatible controller [0300]: NVIDIA Corporation AD102 [GeForce RTX 4090] [10de:2684] (rev a1) (prog-if 00 [VGA controller])

os-release:
NAME="EndeavourOS"
PRETTY_NAME="EndeavourOS"
ID="endeavouros"
ID_LIKE="arch"
BUILD_ID="2024.01.25"
ANSI_COLOR="38;2;23;147;209"
HOME_URL="https://endeavouros.com"
DOCUMENTATION_URL="https://discovery.endeavouros.com"
SUPPORT_URL="https://forum.endeavouros.com"
BUG_REPORT_URL="https://forum.endeavouros.com/c/general-system/endeavouros-installation"
PRIVACY_POLICY_URL="https://endeavouros.com/privacy-policy-2"
LOGO="endeavouros"

ding444 avatar May 18 '24 02:05 ding444

I think Varxy mentioned that Copy/Paste will be broken until the xwayland rewrite is completed.

https://github.com/hyprwm/Hyprland/pull/6086

NEUKhoaLe avatar May 18 '24 03:05 NEUKhoaLe

I suppose this can be closed if he wants in that case, since it's a planned issue.

Ghosthree3 avatar May 18 '24 03:05 Ghosthree3

we can keep it to avoid dupes, I'll just link 6086 to this

vaxerski avatar May 18 '24 18:05 vaxerski

Things seem to work for me with XClip? https://github.com/astrand/xclip

Try using this as a workaround for now.

The-Briel-Deal avatar May 19 '24 21:05 The-Briel-Deal

@The-Briel-Deal

Would i have to change the keybindings for copy & paste then aswell? And does XClip work with wayland applications?

RandomLegend avatar May 20 '24 09:05 RandomLegend

Little script I'm using for syncing clipboard as workaround

#!/usr/bin/env sh
# Two-way clipboard syncronization between Wayland and X11.
# Requires: wl-clipboard, xclip, clipnotify.
#
# Usage:
#   clipsync.sh watch - run in background.
#   clipsync.sh kill - kill all background processes.
#   echo -n any | clipsync.sh insert - insert clipboard content fron stdin.
#
# Workaround for issue:
# "Clipboard synchronization between wayland and xwayland clients broken"
# https://github.com/hyprwm/Hyprland/issues/6132

# Updates clipboard content of both Wayland and X11 if current clipboard content differs.
# Usage: echo -e "1\n2" | clipsync insert
insert() {
  # Read all the piped input into variable.
  value=$(cat)
  wValue="$(wl-paste)"
  xValue="$(xclip -o -selection clipboard)"

  notify() {
    notify-send -u low -c clipboard "$1" "$value"
  }
  
  if [ "$value" != "$wValue" ]; then
    notify "Wayland"
    echo -n "$value" | wl-copy
  fi

  if [ "$value" != "$xValue" ]; then
    notify "X11"
    echo -n "$value" | xclip -selection clipboard
  fi
}

watch() {
  # Wayland -> X11
  wl-paste --type text --watch clipsync insert &

  # X11 -> Wayland
  while clipnotify; do
    xclip -o -selection clipboard | clipsync insert
  done &
}

kill() {
  pkill wl-paste
  pkill clipnotify
  pkill xclip
  pkill clipsync
}

"$@"

Elbtalkessel avatar May 23 '24 13:05 Elbtalkessel

I have simply built and am sitting on the commit before the rewrites (4cdddcf) until the xwayland rewrite is merged.

Ghosthree3 avatar May 23 '24 14:05 Ghosthree3

Sorry for the dumb question, but how do I clone the repo b4 the commits?

kaixenberg avatar May 24 '24 03:05 kaixenberg

Sorry for the dumb question, but how do I clone the repo b4 the commits?

git clone --recursive https://github.com/hyprwm/Hyprland
cd Hyprland
git checkout 4cdddcf
git submodule update
make all
sudo make install

When this is resolved and you want to go back to using your regular installation method (I assume AUR -git), just run sudo make uninstall from within the git directory.

Ghosthree3 avatar May 24 '24 07:05 Ghosthree3

@Ghosthree3 Thanks. Had figured it out already by searching the web ;-) . Thanks for the idea nd everyone for this grt project

kaixenberg avatar May 24 '24 08:05 kaixenberg

does anyone know how to pin the commit for nix flake inputs? i tried this (with submodules=1 based on #5891)

    hyprland = {
      url = "git+https://github.com/hyprwm/Hyprland/?ref=refs/heads/main&rev=4cdddcfe466cb21db81af0ac39e51cc15f574da9&submodules=1";
    };

but it fails

error: RPC failed; curl 92 HTTP/2 stream 5 was not closed cleanly: CANCEL (err 8)
error: 4933 bytes of body are still expected
fetch-pack: unexpected disconnect while reading sideband packet
fatal: early EOF
fatal: fetch-pack: invalid index-pack output
fatal: clone of 'https://github.com/wolfpld/tracy' into submodule path '/tmp/nix-111478-0/subprojects/tracy' failed
Failed to clone 'subprojects/tracy'. Retry scheduled
error: RPC failed; curl 92 HTTP/2 stream 5 was not closed cleanly: CANCEL (err 8)
error: 1877 bytes of body are still expected
fetch-pack: unexpected disconnect while reading sideband packet
fatal: early EOF
fatal: fetch-pack: invalid index-pack output
fatal: clone of 'https://github.com/canihavesomecoffee/udis86' into submodule path '/tmp/nix-111478-0/subprojects/udis86' failed
Failed to clone 'subprojects/udis86'. Retry scheduled
error: 85 bytes of body are still expected
fetch-pack: unexpected disconnect while reading sideband packet
fatal: early EOF
fatal: fetch-pack: invalid index-pack output
fatal: clone of 'https://github.com/wolfpld/tracy' into submodule path '/tmp/nix-111478-0/subprojects/tracy' failed
Failed to clone 'subprojects/tracy' a second time, aborting

UPDATE: here's what worked for me

    hyprland = {
      type = "git";
      url = "https://github.com/hyprwm/Hyprland";
      submodules = true;
      rev = "4cdddcfe466cb21db81af0ac39e51cc15f574da9";
    };

it was able to build (with some errors which, i believe, is due to submodules = true)

error: RPC failed; curl 92 HTTP/2 stream 5 was not closed cleanly: CANCEL (err 8)
error: 2422 bytes of body are still expected
fetch-pack: unexpected disconnect while reading sideband packet
fatal: early EOF
fatal: fetch-pack: invalid index-pack output
fatal: clone of 'https://github.com/hyprwm/wlroots-hyprland' into submodule path '/tmp/nix-143604-0/subprojects/wlroots-hyprland' failed
Failed to clone 'subprojects/wlroots-hyprland'. Retry scheduled
warning: updating lock file '/home/jfvillablanca/nixos-dot/flake.lock':
• Updated input 'hyprland':
    'git+https://github.com/hyprwm/Hyprland/?ref=refs/heads/main&rev=4cdddcfe466cb21db81af0ac39e51cc15f574da9' (2024-05-14)
  → 'git+https://github.com/hyprwm/Hyprland?ref=refs/heads/main&rev=4cdddcfe466cb21db81af0ac39e51cc15f574da9' (2024-05-14)

jfvillablanca avatar May 27 '24 13:05 jfvillablanca

@jfvillablanca that looks like an unreliable internet connection. git clone is not resilient to connection resets.

error: RPC failed; curl 92 HTTP/2 stream 5 was not closed cleanly: CANCEL (err 8) error: 4933 bytes of body are still expected fetch-pack: unexpected disconnect while reading sideband packet fatal: early EOF

navidmafi avatar Jun 08 '24 17:06 navidmafi

I'm not precisely an expert here, but just in case this is useful for somebody:

As a researcher, when I need further compatibility with MS Office, I use WPS Office and this issue was bothering me for quite a while. I found the forked script and I modified it a little bit so it's completely functional (I'm not sure why I was getting lots of new line characters when copy-pasting with the original):

https://gist.github.com/andriandreo/cc48e2d67c389919e18c54429d768c1f

andriandreo avatar Jun 11 '24 07:06 andriandreo

The issue is closed, but as far as I can tell the issue is still there in 0.41.0. Should I open a new issue?

Tristan971 avatar Jun 11 '24 22:06 Tristan971

there already is an issue open #6247 concerning a specific subset of xwayland applications

Agent00Ming avatar Jun 11 '24 22:06 Agent00Ming

This is happening to me since v0.41.0 ._.

Nama avatar Jun 12 '24 14:06 Nama

Commits to master on hyprland-git haven't helped in my case, but I'll tell you what HAS helped.

A slightly modified version of @Elbtalkessel 's little sync script.

gist: https://gist.github.com/armenr/81b77587c1dda1d00d1c1c9541dcda94

I took the liberty of adding:

  • Minor modifications/fixes to prevent the script from throwing errors like: Error: target STRING not available
  • Minor modification/fix with the kill command --> renamed to stop
  • Option(s) to run with-notifications or without-notifications
  • For hyprland users, it also checks for cliphist and syncs cliphist too
  • help function, because why not?

Script below:

#!/usr/bin/env sh
#
# Two-way clipboard syncronization between Wayland and X11, with cliphy support!
# !! Recommended use: Drop this file off @ /usr/local/bin/clipsync && make it executable
# Requires: wl-clipboard, xclip, clipnotify.
# Modified from: https://github.com/hyprwm/Hyprland/issues/6132#issuecomment-2127153823
#
# Usage:
#   clipsync watch [with-notifications|without-notifications] - run in background.
#   clipsync stop - kill all background processes.
#   echo -n any | clipsync insert [with-notifications|without-notifications] - insert clipboard content from stdin.
#   clipsync help - display help information.
#
# Workaround for issue:
# "Clipboard synchronization between wayland and xwayland clients broken"
# https://github.com/hyprwm/Hyprland/issues/6132
#
# Also pertains to:
# https://github.com/hyprwm/Hyprland/issues/6247
# https://github.com/hyprwm/Hyprland/issues/6443
# https://github.com/hyprwm/Hyprland/issues/6148

# Updates clipboard content of both Wayland and X11 if current clipboard content differs.
# Usage: echo -e "1\n2" | clipsync insert [with-notifications|without-notifications]
insert() {
  # Read all the piped input into variable.
  value=$(cat)
  wValue=$(wl-paste -n 2>/dev/null || echo "")
  xValue=$(xclip -o -selection clipboard 2>/dev/null || echo "")

  notify() {
    if [ "$1" != "without-notifications" ]; then
      notify-send -u low -c clipboard "$2" "$value"
    fi
  }

  if [ "$value" != "$wValue" ]; then
    notify "$1" "Wayland"
    echo -n "$value" | wl-copy
    # Add to cliphist if it's installed
    if command -v cliphist >/dev/null 2>&1; then
      echo -n "$value" | cliphist store
    fi
  fi

  if [ "$value" != "$xValue" ]; then
    notify "$1" "X11"
    echo -n "$value" | xclip -selection clipboard
    # Add to cliphist if it's installed
    if command -v cliphist >/dev/null 2>&1; then
      echo -n "$value" | cliphist store
    fi
  fi
}

# Watch for clipboard changes and synchronize between Wayland and X11
# Usage: clipsync watch [with-notifications|without-notifications]
watch() {
  # Add a small delay to ensure clipboard services are initialized
  sleep 1

  notification_mode=${1:-with-notifications}

  # Wayland -> X11
  wl-paste --type text --watch bash -c "clipsync insert $notification_mode" &

  # X11 -> Wayland
  while clipnotify; do
    xclip -o -selection clipboard 2>/dev/null | clipsync insert "$notification_mode"
  done &
}

# Kill all background processes related to clipsync
stop_clipsync() {
  pkill -f "wl-paste --type text --watch"
  pkill clipnotify
  pkill -f "xclip -selection clipboard"
  pkill -f "clipsync insert"
}

help() {
  cat << EOF
clipsync - Two-way clipboard synchronization between Wayland and X11, with cliphist support

Usage:
  clipsync watch [with-notifications|without-notifications]
    Run clipboard synchronization in the background.
    Options:
      with-notifications (default): Show desktop notifications for clipboard changes.
      without-notifications: Operate silently without notifications.

  clipsync stop
    Stop all background processes related to clipsync.

  echo -n "text" | clipsync insert [with-notifications|without-notifications]
    Insert clipboard content from stdin.
    Notification options work the same as in the watch command.

  clipsync help
    Display this help information.

Requirements: wl-clipboard, xclip, clipnotify
Optional: cliphist (for Hyprland users)
EOF
}

case "$1" in
  watch)
    watch "$2"
    ;;
  stop)
    stop_clipsync
    ;;
  insert)
    insert "$2"
    ;;
  help)
    help
    ;;
  *)
    echo "Usage: $0 {watch [with-notifications|without-notifications]|stop|insert [with-notifications|without-notifications]|help}"
    echo "Run '$0 help' for more information."
    exit 1
    ;;
esac

...And now, 1Password is usable again 🚀

armenr avatar Sep 07 '24 10:09 armenr

Fix doesn't work for me

vadim-su avatar Oct 07 '24 10:10 vadim-su

In my case I needed the clipboard to sync between my VMWare Workstation guest (Ubuntu 24.04, KDE 5, Wayland) and host (Ubuntu 22.04, Gnome, X11). It worked only with some programs. For example, it didn't work when copy-pasting from or to the terminal.

I tried @armenr 's script.

It helped in having text copied on the host sync over to the guest, but not the other way around.

To enable the sync from the guest to the host as well, I amended this:

echo -n "$value" | xclip -selection clipboard

To this:

echo -n "$value" | xclip -selection clipboard
echo -n "$value" | xclip -selection primary
echo -n "$value" | xclip -selection secondary

Based on my experimentation only the secondary type is needed for syncing to the host, but I added primary as well for good measure.

obeobe avatar Nov 18 '24 17:11 obeobe

For those, who still encounter this issue.

I've noticed with clipnotify, that sometimes copying do work, but rarely and unreliably.

So I've come up with simple (stupid) brute force solution - force xwayldand windows to copy selection to clipboard, until it's synced. The script tries to do it 5 times max, just in case. In my testing works on first or second try.

I've bound the following script to non-consuming CTRL+C, so it will still work as usual for non xwayland apps.

if [[ $(hyprctl activewindow -j | jq -r ".xwayland") == true ]]; then
    while [[ "$(xclip -o -selection primary 2>/dev/null)" != "$(xclip -o -selection clipboard 2>/dev/null)" ]]; do
        sleep 0.05 && xclip -o -sel prim | xclip -sel clip
        ((c++)) && ((c==5)) && break
    done
fi

My (relevant) config, your mileage may vary with different clip management:

exec-once = wl-clip-persist --clipboard regular
exec-once = cliphist wipe
exec-once = wl-paste --watch cliphist store
exec-once = wl-paste --type image --watch cliphist store
bindn = CTRL, C, exec, xwayland-force-copy

dron1885 avatar Dec 11 '24 11:12 dron1885

EDIT: I basically just recreated this in python with better control flow and MIME type awareness instead. https://github.com/alexankitty/clipsync

I ended up tweaking the existing code because it had a habit of copying inconsistently. I reversed the check to determine the source, and then check if it needs updating. I also exit early if the inbound is empty to prevent some situations with the clipboard clearing itself. Then for users with cliphist I added a failsafe in the event that both clipboards appear to be in sync but the clipboard history has not been updated to allow it to update. I'm sure there are more things that need to be fixed, but the script seems to be stable in my limited testing.

#!/usr/bin/env sh
#
# Two-way clipboard syncronization between Wayland and X11, with cliphy support!
# !! Recommended use: Drop this file off @ /usr/local/bin/clipsync && make it executable
# Requires: wl-clipboard, xclip, clipnotify.
# Modified from: https://github.com/hyprwm/Hyprland/issues/6132#issuecomment-2127153823
#
# Usage:
#   clipsync watch [with-notifications|without-notifications] - run in background.
#   clipsync stop - kill all background processes.
#   echo -n any | clipsync insert [with-notifications|without-notifications] - insert clipboard content from stdin.
#   clipsync help - display help information.
#
# Workaround for issue:
# "Clipboard synchronization between wayland and xwayland clients broken"
# https://github.com/hyprwm/Hyprland/issues/6132
#
# Also pertains to:
# https://github.com/hyprwm/Hyprland/issues/6247
# https://github.com/hyprwm/Hyprland/issues/6443
# https://github.com/hyprwm/Hyprland/issues/6148

# Updates clipboard content of both Wayland and X11 if current clipboard content differs.
# Usage: echo -e "1\n2" | clipsync insert [with-notifications|without-notifications]
insert() {
  # Read all the piped input into variable.
  value=$(cat)
  wValue=$(wl-paste -n 2>/dev/null || echo "")
  xValue=$(xclip -o -selection clipboard 2>/dev/null || echo "")

  notify() {
    if [ "$1" != "without-notifications" ]; then
      notify-send -u low -c clipboard "$2" "$value"
    fi
  }

  # discard if empty
  if [ -z "$value" ]; then
    exit
  fi

  if command -v cliphist >/dev/null 2>&1; then
    clipHistLast=$(cliphist list | head -1 | cliphist decode)
    if [ "$value" != "$clipHistLast" ]; then
      notify "$1" "Failsafe Copy"
      echo -n "$value" | wl-copy
      echo -n "$value" | cliphist store
    fi
  fi


  if [ "$value" == "$wValue" ]; then
    if [ "$value" != "$xValue" ]; then
      notify "$1" "Wayland"
      echo -n "$value" | xclip -selection clipboard
      # Add to cliphist if it's installed
      if command -v cliphist >/dev/null 2>&1; then
        echo -n "$value" | cliphist store
      fi
      exit
    fi
  fi

  if [ "$value" == "$xValue" ]; then
    if [ "$value" != "$wValue" ]; then
      notify "$1" "X11"
      echo -n "$value" | wl-copy
      # Add to cliphist if it's installed
      if command -v cliphist >/dev/null 2>&1; then
        echo -n "$value" | cliphist store
      fi
      exit
    fi
  fi
}

# Watch for clipboard changes and synchronize between Wayland and X11
# Usage: clipsync watch [with-notifications|without-notifications]
watch() {
  # Add a small delay to ensure clipboard services are initialized
  sleep 1

  notification_mode=${1:-with-notifications}

  # Wayland -> X11
  wl-paste --type text --watch bash -c "clipsync insert $notification_mode" &

  # X11 -> Wayland
  while clipnotify; do
    xclip -o -selection clipboard 2>/dev/null | clipsync insert "$notification_mode"
  done &
}

# Kill all background processes related to clipsync
stop_clipsync() {
  pkill -f "wl-paste --type text --watch"
  pkill clipnotify
  pkill -f "xclip -selection clipboard"
  pkill -f "clipsync insert"
}

help() {
  cat << EOF
clipsync - Two-way clipboard synchronization between Wayland and X11, with cliphist support

Usage:
  clipsync watch [with-notifications|without-notifications]
    Run clipboard synchronization in the background.
    Options:
      with-notifications (default): Show desktop notifications for clipboard changes.
      without-notifications: Operate silently without notifications.

  clipsync stop
    Stop all background processes related to clipsync.

  echo -n "text" | clipsync insert [with-notifications|without-notifications]
    Insert clipboard content from stdin.
    Notification options work the same as in the watch command.

  clipsync help
    Display this help information.

Requirements: wl-clipboard, xclip, clipnotify
Optional: cliphist (for Hyprland users)
EOF
}

case "$1" in
  watch)
    watch "$2"
    ;;
  stop)
    stop_clipsync
    ;;
  insert)
    insert "$2"
    ;;
  help)
    help
    ;;
  *)
    echo "Usage: $0 {watch [with-notifications|without-notifications]|stop|insert [with-notifications|without-notifications]|help}"
    echo "Run '$0 help' for more information."
    exit 1
    ;;
esac

alexankitty avatar Jan 16 '25 07:01 alexankitty

not sure why this was closed seems like people still having issues...

codevski avatar Jan 24 '25 08:01 codevski

None of the solutions suited me completely, so I wrote my own synchronization in python. It requires xclip, wl-clipboard and clipnotify to work.

https://github.com/arabianq/wl-x11-clipsync

arabianq avatar Jan 30 '25 14:01 arabianq

None of the solutions suited me completely, so I wrote my own synchronization in python. It requires xclip, wl-clipboard and clipnotify to work.

https://github.com/arabianq/wl-x11-clipsync

prefect! please note this require python version bigger than 3.9

JunYang-tes avatar Feb 27 '25 09:02 JunYang-tes

Is there still not an official solution from Hyprland? :c

eisterman avatar Mar 30 '25 19:03 eisterman

Issue still seems to persist, making it very hard to use in a productive environment...

worksasintended avatar Apr 08 '25 09:04 worksasintended