[Top][All Lists]

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

X Selection handling

From: Thomas DeWeese
Subject: X Selection handling
Date: Sat, 16 Mar 2002 11:56:58 -0500

This bug report will be sent to the Free Software Foundation,
 not to your local site managers!!
Please write in English, because the Emacs maintainers do not have
translators to read other languages for them.

In GNU Emacs 20.7.1 (powerpc-apple-darwin, X toolkit)
 of Tue Oct  2 2001 on localhost
configured using `configure powerpc-apple-darwin --prefix=/sw --with-x --with-x-toolkit=lucid --x- libraries=/sw/src/emacs-20.7-5/emacs-20.7/xlibs '--infodir=${prefix}/share/info' '--mandir=${prefix}/share/man' '--libexecdir=${prefix}/lib''

Please describe exactly what actions triggered the bug
and the precise symptoms of the bug:

Once Emacs sets the selection it usually never sees another application's

I see this complained about all the time, the main issue seems to be
that as long as the CLIPBOARD or PRIMARY selections have been set (at
least once - ussually by emacs it's self) emacs will essentially never
again check the X-cut buffer.  The attached diff shows my solution to
this (remember what the last selection was for each of the various
selection options and if any of them have changed return that one).

--- /sw/share/emacs/20.7/lisp/term/x-win.el     Wed Dec 16 01:36:08 1998
+++ /Users/tdeweese/emacs/x-win.el      Sat Mar 16 11:46:36 2002
@@ -552,7 +552,9 @@
 ;;; We keep track of the last text selected here, so we can check the
 ;;; current selection against it, and avoid passing back our own text
 ;;; from x-cut-buffer-or-selection-value.
-(defvar x-last-selected-text nil)
+(defvar x-last-selected-text-clipboard nil)
+(defvar x-last-selected-text-primary   nil)
+(defvar x-last-selected-text-cut       nil)

;;; It is said that overlarge strings are slow to put into the cut buffer.
 ;;; Note this value is overridden below.
@@ -571,13 +573,18 @@
 (defun x-select-text (text &optional push)
   ;; Don't send the cut buffer too much text.
   ;; It becomes slow, and if really big it causes errors.
-  (if (< (length text) x-cut-buffer-max)
-      (x-set-cut-buffer text push)
-    (x-set-cut-buffer "" push))
+  (cond ((>= (length text) x-cut-buffer-max)
+        (x-set-cut-buffer "" push)
+        (setq x-last-selected-text-cut ""))
+       (t
+        (x-set-cut-buffer text push)
+        (setq x-last-selected-text-cut text)))
   (x-set-selection 'PRIMARY text)
-  (if x-select-enable-clipboard
-      (x-set-selection 'CLIPBOARD text))
-  (setq x-last-selected-text text))
+  (setq x-last-selected-text-primary text)
+  (when x-select-enable-clipboard
+      (x-set-selection 'CLIPBOARD text)
+      (setq x-last-selected-text-clipboard text))
+  )

 ;;; Return the value of the current X selection.
 ;;; Consult the selection, then the cut buffer.  Treat empty strings
@@ -586,41 +593,67 @@
 ;;; it returns nil the second time.  This is so that a single
 ;;; selection won't be added to the kill ring over and over.
 (defun x-cut-buffer-or-selection-value ()
-  (let (text)
+  (let (clip-text primary-text cut-text)
     (when x-select-enable-clipboard
-      (if (null text)
+      (if (null clip-text)
          (condition-case c
-             (setq text (x-get-selection 'CLIPBOARD 'COMPOUND_TEXT))
+ (setq clip-text (x-get-selection 'CLIPBOARD 'COMPOUND_TEXT))
            (error nil)))
-      (if (null text)
+      (if (null clip-text)
          (condition-case c
-             (setq text (x-get-selection 'CLIPBOARD 'STRING))
+             (setq clip-text (x-get-selection 'CLIPBOARD 'STRING))
            (error nil)))
-      (if (string= text "") (setq text nil)))
+      (if (string= clip-text "") (setq clip-text nil)))

     ;; Don't die if x-get-selection signals an error.
-    (if (null text)
+    (if (null primary-text)
        (condition-case c
-           (setq text (x-get-selection 'PRIMARY 'COMPOUND_TEXT))
+           (setq primary-text (x-get-selection 'PRIMARY 'COMPOUND_TEXT))
          (error nil)))
-    (if (null text)
+    (if (null primary-text)
        (condition-case c
-           (setq text (x-get-selection 'PRIMARY 'STRING))
+           (setq primary-text (x-get-selection 'PRIMARY 'STRING))
          (error nil)))
-    (if (string= text "") (setq text nil))
+    (if (string= primary-text "") (setq primary-text nil))

-    (or text (setq text (x-get-cut-buffer 0)))
-    (if (string= text "") (setq text nil))
+    (or cut-text (setq cut-text (x-get-cut-buffer 0)))
+    (if (string= cut-text "") (setq cut-text nil))

-    (cond
-     ((not text) nil)
-     ((eq text x-last-selected-text) nil)
-     ((string= text x-last-selected-text)
- ;; Record the newer string, so subsequent calls can use the `eq' test.
-      (setq x-last-selected-text text)
-      nil)
-     (t
-      (setq x-last-selected-text text)))))
+    (setq clip-text
+         (cond;; check clipboard
+          ((not clip-text) nil)
+          ((eq      clip-text x-last-selected-text-clipboard) nil)
+          ((string= clip-text x-last-selected-text-clipboard)
+           ;; Record the newer string,
+           ;; so subsequent calls can use the `eq' test.
+           (setq x-last-selected-text-clipboard clip-text)
+           nil)
+          (t
+           (setq x-last-selected-text-clipboard clip-text))))
+     (setq primary-text
+          (cond;; check primary selection
+           ((not primary-text) nil)
+           ((eq      primary-text x-last-selected-text-primary) nil)
+           ((string= primary-text x-last-selected-text-primary)
+            ;; Record the newer string,
+            ;; so subsequent calls can use the `eq' test.
+            (setq x-last-selected-text-primary primary-text)
+            nil)
+           (t
+            (setq x-last-selected-text-primary primary-text))))
+     (setq cut-text
+          (cond;; check primary selection
+           ((not cut-text) nil)
+           ((eq      cut-text x-last-selected-text-cut) nil)
+           ((string= cut-text x-last-selected-text-cut)
+            ;; Record the newer string,
+            ;; so subsequent calls can use the `eq' test.
+            (setq x-last-selected-text-cut cut-text)
+            nil)
+           (t
+            (setq x-last-selected-text-cut cut-text))))
+     (or clip-text primary-text cut-text)
+     ))

 ;;; Do the actual X Windows setup here; the above code just defines

Recent input:
tab C-g M-x d i f f - backspace backspace backspace
backspace backspace C-g M-x s u b backspace backspace
backspace e m a c s - s u backspace backspace b u tab
backspace backspace backspace backspace backspace backspace
backspace backspace s u b backspace backspace backspace
C-g M-? a b u g SPC r e p o r t return M-? a b u g
return C-x o C-s s u b m i t - b u g C-s C-s C-s C-s
C-a M-x r e p o r t - e s backspace m tab return

Recent messages:
Note: file is write protected
Making completion list...
Quit [3 times]
Loading apropos...
Loading apropos...done
No apropos matches for `bug report'
Type C-x 1 to remove help window.  M-C-v to scroll the help.
Mark saved where search started
Loading emacsbug...
Loading emacsbug...done

reply via email to

[Prev in Thread] Current Thread [Next in Thread]