]> code.delx.au - gnu-emacs/blobdiff - lisp/mouse.el
Fix previous change.
[gnu-emacs] / lisp / mouse.el
index 63e0f6c9d913dd1c6d9c62edefec3a8332b2dba2..4fd81ced99802556d7dc668082ce6952540b07a5 100644 (file)
@@ -1,6 +1,6 @@
 ;;; mouse.el --- window system-independent mouse support
 
-;; Copyright (C) 1993, 94, 95, 1999, 2000, 2001, 2002, 2003, 2004
+;; Copyright (C) 1993, 94, 95, 1999, 2000, 2001, 2002, 2003, 2004, 2005
 ;;   Free Software Foundation, Inc.
 
 ;; Maintainer: FSF
@@ -20,8 +20,8 @@
 
 ;; You should have received a copy of the GNU General Public License
 ;; along with GNU Emacs; see the file COPYING.  If not, write to the
-;; Free Software Foundation, Inc., 59 Temple Place - Suite 330,
-;; Boston, MA 02111-1307, USA.
+;; Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+;; Boston, MA 02110-1301, USA.
 
 ;;; Commentary:
 
 (defcustom mouse-drag-copy-region t
   "*If non-nil, mouse drag copies region to kill-ring."
   :type 'boolean
-  :version "21.4"
+  :version "22.1"
   :group 'mouse)
 
-(defcustom mouse-1-click-follows-link 350
+(defcustom mouse-1-click-follows-link 450
   "Non-nil means that clicking Mouse-1 on a link follows the link.
 
 With the default setting, an ordinary Mouse-1 click on a link
@@ -64,7 +64,7 @@ or perform the normal Mouse-1 action (typically set point).
 The absolute numeric value specifices the maximum duration of a
 \"short click\" in milliseconds.  A positive value means that a
 short click follows the link, and a longer click performs the
-normal action.  A negative value gives the opposite behaviour.
+normal action.  A negative value gives the opposite behavior.
 
 If value is `double', a double click follows the link.
 
@@ -75,13 +75,24 @@ Note that dragging the mouse never follows the link.
 This feature only works in modes that specifically identify
 clickable text as links, so it may not work with some external
 packages.  See `mouse-on-link-p' for details."
-  :version "21.4"
+  :version "22.1"
   :type '(choice (const :tag "Disabled" nil)
                 (const :tag "Double click" double)
                  (number :tag "Single click time limit" :value 350)
                  (other :tag "Single click" t))
   :group 'mouse)
 
+(defcustom mouse-1-click-in-non-selected-windows t
+  "*If non-nil, a Mouse-1 click also follows links in non-selected windows.
+
+If nil, a Mouse-1 click on a link in a non-selected window performs
+the normal mouse-1 binding, typically selects the window and sets
+point at the click position."
+  :type 'boolean
+  :version "22.1"
+  :group 'mouse)
+
+
 \f
 ;; Provide a mode-specific menu on a mouse button.
 
@@ -397,7 +408,6 @@ MODE-LINE-P non-nil means dragging a mode line; nil means a header line."
         (start-nwindows (count-windows t))
         (old-selected-window (selected-window))
         (minibuffer (frame-parameter nil 'minibuffer))
-        (mouse-autoselect-window nil)
         should-enlarge-minibuffer event mouse y top bot edges wconfig growth)
     (track-mouse
       (progn
@@ -435,7 +445,7 @@ MODE-LINE-P non-nil means dragging a mode line; nil means a header line."
          (cond ((integerp event)
                 (setq done t))
 
-               ((eq (car event) 'switch-frame)
+               ((memq (car event) '(switch-frame select-window))
                 nil)
 
                ((not (memq (car event) '(mouse-movement scroll-bar-movement)))
@@ -582,7 +592,7 @@ resized by dragging their header-line."
          ;;     unknown event.
          (cond ((integerp event)
                 (setq done t))
-               ((eq (car event) 'switch-frame)
+               ((memq (car event) '(switch-frame select-window))
                 nil)
                ((not (memq (car event)
                            '(mouse-movement scroll-bar-movement)))
@@ -754,11 +764,11 @@ remains active.  Otherwise, it remains until the next input event.
 
 If the click is in the echo area, display the `*Messages*' buffer."
   (interactive "e")
-  (let ((w (posn-window (event-start start-event)))
-       (mouse-autoselect-window nil))
-    (if (not (or (not (window-minibuffer-p w))
-                (minibuffer-window-active-p w)))
+  (let ((w (posn-window (event-start start-event))))
+    (if (and (window-minibuffer-p w)
+            (not (minibuffer-window-active-p w)))
        (save-excursion
+         ;; Swallow the up-event.
          (read-event)
          (set-buffer "*Messages*")
          (goto-char (point-max))
@@ -770,24 +780,30 @@ If the click is in the echo area, display the `*Messages*' buffer."
 
 (defun mouse-on-link-p (pos)
   "Return non-nil if POS is on a link in the current buffer.
+POS must be a buffer position in the current buffer or an mouse
+event location in the selected window, see `event-start'.
+However, if `mouse-1-click-in-non-selected-windows' is non-nil,
+POS may be a mouse event location in any window.
 
 A clickable link is identified by one of the following methods:
 
-1) If the character at POS has a non-nil `follow-link' text or
-overlay property, the value of that property is returned.
+- If the character at POS has a non-nil `follow-link' text or
+overlay property, the value of that property determines what to do.
+
+- If there is a local key-binding or a keybinding at position POS
+for the `follow-link' event, the binding of that event determines
+what to do.
 
-2) If there is a local key-binding or a keybinding at position
-POS for the `follow-link' event, the binding of that event
-determines whether POS is inside a link:
+The resulting value determine whether POS is inside a link:
 
-- If the binding is `mouse-face', POS is inside a link if there
+- If the value is `mouse-face', POS is inside a link if there
 is a non-nil `mouse-face' property at POS.  Return t in this case.
 
-- If the binding is a function, FUNC, POS is inside a link if
+- If the value is a function, FUNC, POS is inside a link if
 the call \(FUNC POS) returns non-nil.  Return the return value
-from that call.
+from that call.  Arg is \(posn-point POS) if POS is a mouse event,
 
-- Otherwise, return the binding of the `follow-link' binding.
+- Otherwise, return the value itself.
 
 The return value is interpreted as follows:
 
@@ -801,16 +817,48 @@ click is the local or global binding of that event.
 
 - Otherwise, the mouse-1 event is translated into a mouse-2 event
 at the same position."
-  (or (get-char-property pos 'follow-link)
-      (save-excursion
-       (goto-char pos)
-       (let ((b (key-binding [follow-link] nil t)))
+  (let ((w (and (consp pos) (posn-window pos))))
+    (if (consp pos)
+       (setq pos (and (or mouse-1-click-in-non-selected-windows
+                          (eq (selected-window) w))
+                      (posn-point pos))))
+    (when pos
+      (with-current-buffer (window-buffer w)
+       (let ((action
+              (or (get-char-property pos 'follow-link)
+                  (save-excursion
+                    (goto-char pos)
+                    (key-binding [follow-link] nil t)))))
          (cond
-          ((eq b 'mouse-face)
+          ((eq action 'mouse-face)
            (and (get-char-property pos 'mouse-face) t))
-          ((functionp b)
-           (funcall b pos))
-          (t b))))))
+          ((functionp action)
+           (funcall action pos))
+          (t action)))))))
+
+(defun mouse-fixup-help-message (msg)
+  "Fix help message MSG for `mouse-1-click-follows-link'."
+  (let (mp pos)
+    (if (and mouse-1-click-follows-link
+            (stringp msg)
+            (save-match-data
+              (string-match "^mouse-2" msg))
+            (setq mp (mouse-pixel-position))
+            (consp (setq pos (cdr mp)))
+            (car pos) (>= (car pos) 0)
+            (cdr pos) (>= (cdr pos) 0)
+            (setq pos (posn-at-x-y (car pos) (cdr pos) (car mp)))
+            (windowp (posn-window pos)))
+       (with-current-buffer (window-buffer (posn-window pos))
+         (if (mouse-on-link-p pos)
+             (setq msg (concat
+                   (cond
+                    ((eq mouse-1-click-follows-link 'double) "double-")
+                    ((and (integerp mouse-1-click-follows-link)
+                          (< mouse-1-click-follows-link 0)) "Long ")
+                    (t ""))
+                   "mouse-1" (substring msg 7)))))))
+  msg)
 
 (defun mouse-drag-region-1 (start-event)
   (mouse-minibuffer-check start-event)
@@ -828,7 +876,10 @@ at the same position."
                     (nth 3 bounds)
                   ;; Don't count the mode line.
                   (1- (nth 3 bounds))))
-        on-link remap-double-click
+        (on-link (and mouse-1-click-follows-link
+                      (or mouse-1-click-in-non-selected-windows
+                          (eq start-window (selected-window)))))
+        remap-double-click
         (click-count (1- (event-click-count start-event))))
     (setq mouse-selection-click-count click-count)
     (setq mouse-selection-click-count-buffer (current-buffer))
@@ -838,7 +889,7 @@ at the same position."
     (if (< (point) start-point)
        (goto-char start-point))
     (setq start-point (point))
-    (setq on-link (and mouse-1-click-follows-link
+    (setq on-link (and on-link
                       (mouse-on-link-p start-point)))
     (setq remap-double-click (and on-link
                                  (eq mouse-1-click-follows-link 'double)
@@ -858,8 +909,8 @@ at the same position."
        (while (progn
                 (setq event (read-event))
                 (or (mouse-movement-p event)
-                    (eq (car-safe event) 'switch-frame)))
-         (if (eq (car-safe event) 'switch-frame)
+                    (memq (car-safe event) '(switch-frame select-window))))
+         (if (memq (car-safe event) '(switch-frame select-window))
              nil
            (setq end (event-end event)
                  end-point (posn-point end))
@@ -968,7 +1019,7 @@ at the same position."
                             (= (window-start start-window)
                                start-window-start)))
                (if (and on-link
-                        (not end-point)
+                        (or (not end-point) (= end-point start-point))
                         (consp event)
                         (or remap-double-click
                             (and
@@ -1153,6 +1204,7 @@ If MODE is 2 then do the same for lines."
       (move-overlay mouse-drag-overlay (point) (mark t)))
     (catch 'mouse-show-mark
       ;; In this loop, execute scroll bar and switch-frame events.
+      ;; Should we similarly handle `select-window' events?  --Stef
       ;; Also ignore down-events that are undefined.
       (while (progn (setq event (read-event))
                    (setq events (append events (list event)))
@@ -1476,9 +1528,9 @@ The function returns a non-nil value if it creates a secondary selection."
          (while (progn
                   (setq event (read-event))
                   (or (mouse-movement-p event)
-                      (eq (car-safe event) 'switch-frame)))
+                      (memq (car-safe event) '(switch-frame select-window))))
 
-           (if (eq (car-safe event) 'switch-frame)
+           (if (memq (car-safe event) '(switch-frame select-window))
                nil
              (setq end (event-end event)
                    end-point (posn-point end))
@@ -1805,7 +1857,7 @@ and selects that window."
                            (string< (buffer-name elt1) (buffer-name elt2))))))
     (setq tail buffers)
     (while tail
-      (or (eq ?\ (aref (buffer-name (car tail)) 0))
+      (or (eq ?\s (aref (buffer-name (car tail)) 0))
          (setq maxlen
                (max maxlen
                     (length (buffer-name (car tail))))))