Skip to content

Instantly share code, notes, and snippets.

@ben-cohen
Last active November 23, 2022 20:35
Show Gist options
  • Save ben-cohen/9d5f02bcb84c2adbb67523966734d50c to your computer and use it in GitHub Desktop.
Save ben-cohen/9d5f02bcb84c2adbb67523966734d50c to your computer and use it in GitHub Desktop.
Linux/GTK X11 CLIPBOARD and PRIMARY clipboard sync
#!/usr/bin/python3
#
# Keep the X primary selection and the clipboard
# in sync. Polls regularly and, when one changes,
# it's copied to the other.
#
# To the extent possible under law, Alun Jones has waived all copyright and
# related or neighbouring rights to this work. This work is published from:
# United Kingdom.
#
# From https://www.ty-penguin.org.uk/~auj/blog/2019/05/24/clipper/
#
# If you are using XWayland you may need to set the environment variable
# GDK_BACKEND=x11 (otherwise the 'owner-change' signal is never received).
import gi
gi.require_version("Gtk", "3.0")
from gi.repository import Gtk, GLib, Gdk
class Clipper():
cb = []
waiting_for_clipboard = False
def __init__(self):
for board in (Gdk.SELECTION_PRIMARY, Gdk.SELECTION_CLIPBOARD):
cb = Gtk.Clipboard.get(board)
cb.connect('owner-change', self.changed)
self.cb.append(cb)
self.oldtext = None
def changed(self, clipboard, event):
if not self.waiting_for_clipboard:
# Avoid infinite recursion if changed() is called again
self.waiting_for_clipboard = True
ct = clipboard.wait_for_text()
self.waiting_for_clipboard = False
if ct is not None and ct != self.oldtext:
self.oldtext = ct
for cb in self.cb:
if cb != clipboard:
cb.set_text(ct, -1)
def run(self):
Gtk.main()
Clipper().run()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment