Subject: select-active-regions mouse wheel scroll bug fix

From: David De La Harpe Golden <[email-masked]>
Date: Sun, 15 Nov 2009 14:23:08 +0000

This is dependent on preceding cross-platform clean-up patch (It could 
be recast not to depend I suppose, but that would then necessarily 
involve embedding similar X11isms in mwheel.el to the ones banished by 
the clean-up patch, and be messier looking - the extra abstraction
provided by interprogram-region-function proves useful in the fix)

Didn't spot this for ages as I don't mouse wheel normally (have a gfx 
tablet).  Without this patch, when you have a 'only active region  (i.e. 
shift-cursor or mouse generated) and select-active-regions enabled, when 
you wheel scroll enough to trigger the mark-deactivation path in 
mwheel-scroll, the system selection will end up set to a surprising 
region not corresponding to the last visibly active region, which is 
irritating, especially if you were scrolling somewhere precisely to 
insert somewhere else.

--- emacs-sar-xplat/lisp/mwheel.el	2009-10-10 03:49:47.000000000 +0100
+++ emacs/lisp/mwheel.el	2009-11-15 14:21:52.000000000 +0000
@@ -190,6 +190,14 @@
 	 (buffer (window-buffer curwin))
 	 (opoint (with-current-buffer buffer
 		   (when (eq (car-safe transient-mark-mode) 'only)
+                     ;; temporarily "freeze off" an active region as string if
+                     ;; necessary, to avoid confusingly propagating
+                     ;; region to system if the point is moved by scrolling
+                     ;; causing a deactivation below.
+                     (and interprogram-region-function
+                          (funcall interprogram-region-function
+                                   (buffer-substring-no-properties
+                                    (region-beginning) (region-end)) nil))
 		     (point))))
          (mods
 	  (delq 'click (delq 'double (delq 'triple (event-modifiers event)))))
@@ -228,10 +236,16 @@
       (if curwin (select-window curwin)))
     ;; If there is a temporarily active region, deactivate it iff
     ;; scrolling moves point.
+    ;; Don't propagate deactivating region to system if scrolling moved point,
+    ;; however if scrolling did not move point, set active region back
+    ;; to buffer as we temporarily froze off string above.
     (when opoint
       (with-current-buffer buffer
-	(when (/= opoint (point))
-	  (deactivate-mark)))))
+	(if (/= opoint (point))
+            (let ((interprogram-region-function nil))
+              (deactivate-mark))
+          (and interprogram-region-function
+               (funcall interprogram-region-function buffer nil))))))
   (when (and mouse-wheel-click-event mouse-wheel-inhibit-click-time)
     (if mwheel-inhibit-click-event-timer
 	(cancel-timer mwheel-inhibit-click-event-timer)