about summary refs log tree commit diff
diff options
context:
space:
mode:
authorSören Tempel <soeren+git@soeren-tempel.net>2021-06-03 21:06:32 +0200
committerSören Tempel <soeren+git@soeren-tempel.net>2021-06-03 21:06:32 +0200
commit88f8ea5ef711e15f8cf12365cfc344bc14fdfd07 (patch)
tree8b8bfd4ea539f618321c978cee4394e7cff74d98
parent7327f400bf233e0008041312355e42e667ad13db (diff)
Prevent Gtk from clearing the primary selection
This is a horrible workaround for https://gitlab.gnome.org/GNOME/gtk/-/issues/317
-rw-r--r--saneterm/termview.py20
1 files changed, 20 insertions, 0 deletions
diff --git a/saneterm/termview.py b/saneterm/termview.py
index 27c9103..759c5b2 100644
--- a/saneterm/termview.py
+++ b/saneterm/termview.py
@@ -1,4 +1,5 @@
 from gi.repository import Gtk
+from gi.repository import Gdk
 from gi.repository import GObject
 
 from . import completion
@@ -12,6 +13,7 @@ class LimitTextBuffer(Gtk.TextBuffer):
 
     def __init__(self, limit):
         Gtk.TextBuffer.__init__(self)
+        self._clipboard = Gtk.Clipboard.get(Gdk.SELECTION_PRIMARY)
 
         if limit == -1:
             return # unlimited
@@ -19,6 +21,24 @@ class LimitTextBuffer(Gtk.TextBuffer):
         self.limit = limit
         self.connect_after("insert-text", self.__insert_text)
 
+    def do_mark_set(self, loc, mark):
+        # Gtk only partially adheres to the freedesktop.org clipboard
+        # specification. If text is selected, this text is copied to the
+        # primary clipboard. However, if the user unselects the text by
+        # clicking somewhere else the clipboard is cleared. This has
+        # been a known bug in Gtk for over 12 years. The code here is a
+        # dirty workaround for this bug.
+        #
+        # See https://gitlab.gnome.org/GNOME/gtk/-/issues/317
+
+        selection = self.get_selection_bounds()
+        if selection:
+            start, end = selection
+            text = self.get_text(start, end, True)
+            self._clipboard.set_text(text, -1)
+        else:
+            Gtk.TextBuffer.do_mark_set(self, loc, mark)
+
     def __insert_text(self, buffer, loc, text, len):
         lines = buffer.get_line_count()
         diff = lines - self.limit