;;; 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
;; 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
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.
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.
(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
(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)))
;; 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)))
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))
(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:
- 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)
(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))
(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)
(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))
(= (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
(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)))
(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))
(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))))))