]> code.delx.au - gnu-emacs/blobdiff - lisp/mouse.el
2005-09-14 Chong Yidong <cyd@stupidchicken.com>
[gnu-emacs] / lisp / mouse.el
index edf7575306239313a11fa80e6e8d9df37f1e03f8..3b591694cfeb72ffbd9edfe727842fba49819227 100644 (file)
@@ -1,7 +1,7 @@
 ;;; mouse.el --- window system-independent mouse support
 
-;; Copyright (C) 1993, 94, 95, 1999, 2000, 2001, 2002, 2003, 2004, 2005
-;;   Free Software Foundation, Inc.
+;; Copyright (C) 1993, 1994, 1995, 1999, 2000, 2001, 2002, 2003,
+;;   2004, 2005 Free Software Foundation, Inc.
 
 ;; Maintainer: FSF
 ;; Keywords: hardware, mouse
@@ -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.
 
@@ -142,7 +153,7 @@ PREFIX is the prefix argument (if any) to pass to the command."
 
 (defvar mouse-major-mode-menu-prefix)  ; dynamically bound
 
-(defun mouse-major-mode-menu (event prefix)
+(defun mouse-major-mode-menu (event &optional prefix)
   "Pop up a mode-specific menu of mouse commands.
 Default to the Edit menu if the major mode doesn't define a menu."
   ;; Switch to the window clicked on, because otherwise
@@ -162,8 +173,7 @@ Default to the Edit menu if the major mode doesn't define a menu."
         ;; default to the edit menu.
         (newmap (if ancestor
                     (make-sparse-keymap (concat mode-name " Mode"))
-                  menu-bar-edit-menu))
-        result)
+                  menu-bar-edit-menu)))
     (if ancestor
        ;; Make our menu inherit from the desired keymap which we want
        ;; to display as the menu now.
@@ -527,11 +537,10 @@ resized by dragging their header-line."
         (window (posn-window start))
         (frame (window-frame window))
         (first-window (frame-first-window frame)))
-    (when (or (eq window first-window)
-             (= (nth 1 (window-edges window))
-                (nth 1 (window-edges first-window))))
-      (error "Cannot move header-line at the top of the frame"))
-    (mouse-drag-mode-line-1 start-event nil)))
+    (unless (or (eq window first-window)
+               (= (nth 1 (window-edges window))
+                  (nth 1 (window-edges first-window))))
+      (mouse-drag-mode-line-1 start-event nil))))
 
 \f
 (defun mouse-drag-vertical-line (start-event)
@@ -757,6 +766,7 @@ If the click is in the echo area, display the `*Messages*' buffer."
     (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))
@@ -768,12 +778,15 @@ 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:
 
 - If the character at POS has a non-nil `follow-link' text or
-overlay property, use the value of that property determines what
-to do.
+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
@@ -786,7 +799,7 @@ is a non-nil `mouse-face' property at POS.  Return t in this case.
 
 - 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 value itself.
 
@@ -802,17 +815,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."
-  (let ((action
-        (or (get-char-property pos 'follow-link)
-            (save-excursion
-              (goto-char pos)
-              (key-binding [follow-link] nil t)))))
-    (cond
-     ((eq action 'mouse-face)
-      (and (get-char-property pos 'mouse-face) t))
-     ((functionp action)
-      (funcall action pos))
-     (t action))))
+  (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 action 'mouse-face)
+           (and (get-char-property pos 'mouse-face) t))
+          ((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)
@@ -830,7 +874,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))
@@ -840,7 +887,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)
@@ -970,7 +1017,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
@@ -1808,7 +1855,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))))))