emacs-devel
[Top][All Lists]
Advanced

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

Re: select-active-regions


From: David De La Harpe Golden
Subject: Re: select-active-regions
Date: Sat, 18 Jul 2009 19:45:54 +0100
User-agent: Mozilla-Thunderbird 2.0.0.22 (X11/20090701)

Eli Zaretskii wrote:

(x-set-selection 'PRIMARY value)
;should just stash value somewhere

What would be the purpose of stashing the value ``somewhere''?

The purpose is to emulate internally to emacs a primary selection facility otherwise missing from the platform in question. w32 emacs looks to have been treating the primary selection that way for the past 13 years or so.
http://cvs.savannah.gnu.org/viewvc/emacs/lisp/w32-fns.el?revision=1.14&root=emacs&view=markup

On recent w32 it might now be possible to use an accessibility API (at least with sufficient privileges) to record selections in some other applications, which might allow a closer to complete emulation of at least incoming primary, though it might be tricksy to actually implement and not especially worth it.

The
NEWS entry says:

    *** If `select-active-regions' is t, setting the mark automatically
    makes the new region into the primary selection (for interaction with
    other window applications).


Uh-huh. Note how it also says "makes the new region into the primary selection" ?

How can Emacs interact with other applications, if we just stash the
value in some internal variable?


Not all platforms have a primary selection as an OS-level entity in the first place, they only have a clipboard (well, the amiga actually had hundreds of distinct clipboards, but I'm not sure amiga support is worth worrying about even though AROS now exists), so emacs just has to interact with them via means other than a primary selection. But mixing up primary and clipboard within x-set-selection/x-get-selection/x-selection-owner-p is wrong not
to mention phenomenally confusing.

Waht's more, I suspect it also Just Won't Work Anyway, because on w32 AFAIK you set the system clipboard, on x11 you acquire the clipboard selection and applications ask you for the clipboard contents. Perhaps just regard select-active-regions as a feature aimed mostly at X11 users...

If you do want select-active-regions to be able to affect the clipboard, a relatively sane way to do it would be to introduce customization variables:

x-select-active-regions-enable-clipboard x-select-active-regions-enable-primary

by analogy with x-select-enable-primary and x-select-enable-clipboard,
that would allow customization of which selections to actually affect during select-active-regions. Note that x-select-enable-primary and x-select-enable-clipboard would be completely UNsuitable for reuse there, if you don't see why you probably haven't quite understood the issue.

See attached (illstrative) patch.




Index: lisp/simple.el
===================================================================
RCS file: /sources/emacs/emacs/lisp/simple.el,v
retrieving revision 1.995
diff -U 8 -r1.995 simple.el
--- lisp/simple.el      18 Jul 2009 04:37:56 -0000      1.995
+++ lisp/simple.el      18 Jul 2009 18:43:58 -0000
@@ -3468,35 +3468,55 @@
 
 If you are using this in an editing command, you are most likely making
 a mistake; see the documentation of `set-mark'."
   (if (or force (not transient-mark-mode) mark-active mark-even-if-inactive)
       (marker-position (mark-marker))
     (signal 'mark-inactive nil)))
 
 (defcustom select-active-regions nil
-  "If non-nil, an active region automatically becomes the window selection."
+  "If non-nil, an active region automatically becomes the window selection.
+Which selections are actually affected is determined by the
+`x-select-active-regions-enable-primary' and
+`x-select-active-regions-enable-clipboard' variables -
+if unbound or nil, that selection will be unaffected.
+may be poorly supported on windowing systems other than X11
+due to basic windowing system architectural differences."
   :type 'boolean
   :group 'killing
   :version "23.1")
 
+(defsubst select-active-regions--start ()
+  (and (bound-and-true-p x-select-active-regions-enable-primary)
+       (x-set-selection 'PRIMARY (current-buffer)))
+  (and (bound-and-true-p x-select-active-regions-enable-clipboard)
+       (x-set-selection 'CLIPBOARD (current-buffer))))
+
+(defsubst select-active-regions--end ()
+  (and (bound-and-true-p x-select-active-regions-enable-primary)
+       (x-selection-owner-p 'PRIMARY)
+       (x-set-selection 'PRIMARY (buffer-substring-no-properties
+                                 (region-beginning) (region-end))))
+  (and (bound-and-true-p x-select-active-regions-enable-clipboard)
+       (x-selection-owner-p 'CLIPBOARD)
+       (x-set-selection 'CLIPBOARD (buffer-substring-no-properties
+                                   (region-beginning) (region-end)))))
+
 ;; Many places set mark-active directly, and several of them failed to also
 ;; run deactivate-mark-hook.  This shorthand should simplify.
 (defsubst deactivate-mark (&optional force)
   "Deactivate the mark by setting `mark-active' to nil.
 Unless FORCE is non-nil, this function does nothing if Transient
 Mark mode is disabled.
 This function also runs `deactivate-mark-hook'."
   (when (or transient-mark-mode force)
     ;; Copy the latest region into the primary selection, if desired.
     (and select-active-regions
         mark-active
-        (x-selection-owner-p 'PRIMARY)
-        (x-set-selection 'PRIMARY (buffer-substring-no-properties
-                                   (region-beginning) (region-end))))
+        (select-active-regions--end))
     (if (and (null force)
             (or (eq transient-mark-mode 'lambda)
                 (and (eq (car-safe transient-mark-mode) 'only)
                      (null (cdr transient-mark-mode)))))
        ;; When deactivating a temporary region, don't change
        ;; `mark-active' or run `deactivate-mark-hook'.
        (setq transient-mark-mode nil)
       (if (eq (car-safe transient-mark-mode) 'only)
@@ -3506,17 +3526,17 @@
 
 (defun activate-mark ()
   "Activate the mark."
   (when (mark t)
     (setq mark-active t)
     (unless transient-mark-mode
       (setq transient-mark-mode 'lambda))
     (when select-active-regions
-      (x-set-selection 'PRIMARY (current-buffer)))))
+      (select-active-regions--start))))
 
 (defun set-mark (pos)
   "Set this buffer's mark to POS.  Don't use this function!
 That is to say, don't use this function unless you want
 the user to see that the mark has moved, and you want the previous
 mark position to be lost.
 
 Normally, when a new mark is set, the old one should go on the stack.
@@ -3530,17 +3550,17 @@
 
    (let ((beg (point))) (forward-line 1) (delete-region beg (point)))."
 
   (if pos
       (progn
        (setq mark-active t)
        (run-hooks 'activate-mark-hook)
        (when select-active-regions
-         (x-set-selection 'PRIMARY (current-buffer)))
+         (select-active-regions--start))
        (set-marker (mark-marker) pos (current-buffer)))
     ;; Normally we never clear mark-active except in Transient Mark mode.
     ;; But when we actually clear out the mark value too, we must
     ;; clear mark-active in any mode.
     (deactivate-mark t)
     (set-marker (mark-marker) nil)))
 
 (defcustom use-empty-active-region nil
Index: lisp/term/x-win.el
===================================================================
RCS file: /sources/emacs/emacs/lisp/term/x-win.el,v
retrieving revision 1.240
diff -U 8 -r1.240 x-win.el
--- lisp/term/x-win.el  19 Mar 2009 00:56:52 -0000      1.240
+++ lisp/term/x-win.el  18 Jul 2009 18:43:58 -0000
@@ -1243,16 +1243,26 @@
   :type 'boolean
   :group 'killing)
 
 (defcustom x-select-enable-primary t
   "Non-nil means cutting and pasting uses the primary selection."
   :type 'boolean
   :group 'killing)
 
+(defcustom x-select-active-regions-enable-clipboard nil
+  "Non-nil means `select-active-regions' uses the clipboard"
+  :type 'boolean
+  :group 'killing)
+
+(defcustom x-select-active-regions-enable-primary t
+  "Non-nil means `select-active-regions' uses the primary selection."
+  :type 'boolean
+  :group 'killing)
+
 (defun x-select-text (text &optional push)
   "Make TEXT, a string, the primary X selection.
 Also, set the value of X cut buffer 0, for backward compatibility
 with older X applications.
 address@hidden says it's not desirable to put kills
 in the clipboard."
   ;; With multi-tty, this function may be called from a tty frame.
   (when (eq (framep (selected-frame)) 'x)

reply via email to

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