diff options
| author | Daniel Koning | 2015-01-21 09:01:30 +0100 |
|---|---|---|
| committer | Martin Rudalics | 2015-01-21 09:01:30 +0100 |
| commit | 3ea1b31f46f21ecfb089628e63187970fdb58d5a (patch) | |
| tree | f02efdd511dfb3eecb1583bd454912c2bc70abc3 | |
| parent | 4c09e3aef9a366ffebd314d01f666e04bd7798e2 (diff) | |
| download | emacs-3ea1b31f46f21ecfb089628e63187970fdb58d5a.tar.gz emacs-3ea1b31f46f21ecfb089628e63187970fdb58d5a.zip | |
Prevent artist-mode from creating runaway timers (Bug#6130).
* subr.el (posnp): Correct docstring of `posnp'.
(posn-col-row): Make it work with all mouse position objects.
* textmodes/artist.el (artist-mouse-draw-continously): Cancel
timers if an error occurs during continuous drawing. (Bug#6130)
* commands.texi (Drag Events, Motion Events, Event Examples)
(Accessing Mouse): Describe actual range of values that mouse
position objects can have.
| -rw-r--r-- | doc/lispref/ChangeLog | 6 | ||||
| -rw-r--r-- | doc/lispref/commands.texi | 23 | ||||
| -rw-r--r-- | lisp/ChangeLog | 7 | ||||
| -rw-r--r-- | lisp/subr.el | 33 | ||||
| -rw-r--r-- | lisp/textmodes/artist.el | 95 |
5 files changed, 102 insertions, 62 deletions
diff --git a/doc/lispref/ChangeLog b/doc/lispref/ChangeLog index 11a6f32718c..52c621c1fa5 100644 --- a/doc/lispref/ChangeLog +++ b/doc/lispref/ChangeLog | |||
| @@ -1,3 +1,9 @@ | |||
| 1 | 2015-01-21 Daniel Koning <dk@danielkoning.com> (tiny change) | ||
| 2 | |||
| 3 | * commands.texi (Drag Events, Motion Events, Event Examples) | ||
| 4 | (Accessing Mouse): Describe actual range of values that mouse | ||
| 5 | position objects can have. | ||
| 6 | |||
| 1 | 2015-01-20 Eli Zaretskii <eliz@gnu.org> | 7 | 2015-01-20 Eli Zaretskii <eliz@gnu.org> |
| 2 | 8 | ||
| 3 | * display.texi (Manipulating Buttons): Explain more about the | 9 | * display.texi (Manipulating Buttons): Explain more about the |
diff --git a/doc/lispref/commands.texi b/doc/lispref/commands.texi index a503e3f117b..5ea1a48b262 100644 --- a/doc/lispref/commands.texi +++ b/doc/lispref/commands.texi | |||
| @@ -1485,8 +1485,10 @@ prefix @samp{drag-}. For example, dragging the mouse with button 2 | |||
| 1485 | held down generates a @code{drag-mouse-2} event. The second and third | 1485 | held down generates a @code{drag-mouse-2} event. The second and third |
| 1486 | elements of the event give the starting and ending position of the | 1486 | elements of the event give the starting and ending position of the |
| 1487 | drag, as mouse position lists (@pxref{Click Events}). You can access | 1487 | drag, as mouse position lists (@pxref{Click Events}). You can access |
| 1488 | the second element of any mouse event in the same way, with no need to | 1488 | the second element of any mouse event in the same way. However, the |
| 1489 | distinguish drag events from others. | 1489 | drag event may end outside the boundaries of the frame that was |
| 1490 | initially selected. In that case, the third element's position list | ||
| 1491 | contains that frame in place of a window. | ||
| 1490 | 1492 | ||
| 1491 | The @samp{drag-} prefix follows the modifier key prefixes such as | 1493 | The @samp{drag-} prefix follows the modifier key prefixes such as |
| 1492 | @samp{C-} and @samp{M-}. | 1494 | @samp{C-} and @samp{M-}. |
| @@ -1631,7 +1633,10 @@ represented by lists that look like this: | |||
| 1631 | 1633 | ||
| 1632 | @noindent | 1634 | @noindent |
| 1633 | @var{position} is a mouse position list (@pxref{Click Events}), | 1635 | @var{position} is a mouse position list (@pxref{Click Events}), |
| 1634 | specifying the current position of the mouse cursor. | 1636 | specifying the current position of the mouse cursor. As with the |
| 1637 | end-position of a drag event, this position list may represent a | ||
| 1638 | location outside the boundaries of the initially selected frame, in | ||
| 1639 | which case the list contains that frame in place of a window. | ||
| 1635 | 1640 | ||
| 1636 | The special form @code{track-mouse} enables generation of motion | 1641 | The special form @code{track-mouse} enables generation of motion |
| 1637 | events within its body. Outside of @code{track-mouse} forms, Emacs | 1642 | events within its body. Outside of @code{track-mouse} forms, Emacs |
| @@ -1846,6 +1851,14 @@ into another window. That produces a pair of events like these: | |||
| 1846 | -453816)) | 1851 | -453816)) |
| 1847 | @end smallexample | 1852 | @end smallexample |
| 1848 | 1853 | ||
| 1854 | The frame with input focus might not take up the entire screen, and | ||
| 1855 | the user might move the mouse outside the scope of the frame. Inside | ||
| 1856 | the @code{track-mouse} special form, that produces an event like this: | ||
| 1857 | |||
| 1858 | @smallexample | ||
| 1859 | (mouse-movement (#<frame *ielm* 0x102849a30> nil (563 . 205) 532301936)) | ||
| 1860 | @end smallexample | ||
| 1861 | |||
| 1849 | To handle a SIGUSR1 signal, define an interactive function, and | 1862 | To handle a SIGUSR1 signal, define an interactive function, and |
| 1850 | bind it to the @code{signal usr1} event sequence: | 1863 | bind it to the @code{signal usr1} event sequence: |
| 1851 | 1864 | ||
| @@ -2010,7 +2023,9 @@ Events}); and @code{nil} otherwise. | |||
| 2010 | various parts of it: | 2023 | various parts of it: |
| 2011 | 2024 | ||
| 2012 | @defun posn-window position | 2025 | @defun posn-window position |
| 2013 | Return the window that @var{position} is in. | 2026 | Return the window that @var{position} is in. If @var{position} |
| 2027 | represents a location outside the frame where the event was initiated, | ||
| 2028 | return that frame instead. | ||
| 2014 | @end defun | 2029 | @end defun |
| 2015 | 2030 | ||
| 2016 | @defun posn-area position | 2031 | @defun posn-area position |
diff --git a/lisp/ChangeLog b/lisp/ChangeLog index 20efe68bff6..280f6022007 100644 --- a/lisp/ChangeLog +++ b/lisp/ChangeLog | |||
| @@ -1,3 +1,10 @@ | |||
| 1 | 2015-01-21 Daniel Koning <dk@danielkoning.com> (tiny change) | ||
| 2 | |||
| 3 | * subr.el (posnp): Correct docstring of `posnp'. | ||
| 4 | (posn-col-row): Make it work with all mouse position objects. | ||
| 5 | * textmodes/artist.el (artist-mouse-draw-continously): Cancel | ||
| 6 | timers if an error occurs during continuous drawing. (Bug#6130) | ||
| 7 | |||
| 1 | 2015-01-20 Eli Zaretskii <eliz@gnu.org> | 8 | 2015-01-20 Eli Zaretskii <eliz@gnu.org> |
| 2 | 9 | ||
| 3 | * button.el (button-activate, push-button): Doc fix. (Bug#19628) | 10 | * button.el (button-activate, push-button): Doc fix. (Bug#19628) |
diff --git a/lisp/subr.el b/lisp/subr.el index d71de87b42c..a48038fa12b 100644 --- a/lisp/subr.el +++ b/lisp/subr.el | |||
| @@ -1062,7 +1062,12 @@ The return value is a positive integer." | |||
| 1062 | ;;;; Extracting fields of the positions in an event. | 1062 | ;;;; Extracting fields of the positions in an event. |
| 1063 | 1063 | ||
| 1064 | (defun posnp (obj) | 1064 | (defun posnp (obj) |
| 1065 | "Return non-nil if OBJ appears to be a valid `posn' object." | 1065 | "Return non-nil if OBJ appears to be a valid `posn' object specifying a window. |
| 1066 | If OBJ is a valid `posn' object, but specifies a frame rather | ||
| 1067 | than a window, return nil." | ||
| 1068 | ;; FIXME: Correct the behavior of this function so that all valid | ||
| 1069 | ;; `posn' objects are recognized, after updating other code that | ||
| 1070 | ;; depends on its present behavior. | ||
| 1066 | (and (windowp (car-safe obj)) | 1071 | (and (windowp (car-safe obj)) |
| 1067 | (atom (car-safe (setq obj (cdr obj)))) ;AREA-OR-POS. | 1072 | (atom (car-safe (setq obj (cdr obj)))) ;AREA-OR-POS. |
| 1068 | (integerp (car-safe (car-safe (setq obj (cdr obj))))) ;XOFFSET. | 1073 | (integerp (car-safe (car-safe (setq obj (cdr obj))))) ;XOFFSET. |
| @@ -1122,24 +1127,28 @@ For a scroll-bar event, the result column is 0, and the row | |||
| 1122 | corresponds to the vertical position of the click in the scroll bar. | 1127 | corresponds to the vertical position of the click in the scroll bar. |
| 1123 | POSITION should be a list of the form returned by the `event-start' | 1128 | POSITION should be a list of the form returned by the `event-start' |
| 1124 | and `event-end' functions." | 1129 | and `event-end' functions." |
| 1125 | (let* ((pair (posn-x-y position)) | 1130 | (let* ((pair (posn-x-y position)) |
| 1126 | (window (posn-window position)) | 1131 | (frame-or-window (posn-window position)) |
| 1127 | (area (posn-area position))) | 1132 | (frame (if (framep frame-or-window) |
| 1133 | frame-or-window | ||
| 1134 | (window-frame frame-or-window))) | ||
| 1135 | (window (when (windowp frame-or-window) frame-or-window)) | ||
| 1136 | (area (posn-area position))) | ||
| 1128 | (cond | 1137 | (cond |
| 1129 | ((null window) | 1138 | ((null frame-or-window) |
| 1130 | '(0 . 0)) | 1139 | '(0 . 0)) |
| 1131 | ((eq area 'vertical-scroll-bar) | 1140 | ((eq area 'vertical-scroll-bar) |
| 1132 | (cons 0 (scroll-bar-scale pair (1- (window-height window))))) | 1141 | (cons 0 (scroll-bar-scale pair (1- (window-height window))))) |
| 1133 | ((eq area 'horizontal-scroll-bar) | 1142 | ((eq area 'horizontal-scroll-bar) |
| 1134 | (cons (scroll-bar-scale pair (window-width window)) 0)) | 1143 | (cons (scroll-bar-scale pair (window-width window)) 0)) |
| 1135 | (t | 1144 | (t |
| 1136 | (let* ((frame (if (framep window) window (window-frame window))) | 1145 | ;; FIXME: This should take line-spacing properties on |
| 1137 | ;; FIXME: This should take line-spacing properties on | 1146 | ;; newlines into account. |
| 1138 | ;; newlines into account. | 1147 | (let* ((spacing (when (display-graphic-p frame) |
| 1139 | (spacing (when (display-graphic-p frame) | 1148 | (or (with-current-buffer |
| 1140 | (or (with-current-buffer (window-buffer window) | 1149 | (window-buffer (frame-selected-window frame)) |
| 1141 | line-spacing) | 1150 | line-spacing) |
| 1142 | (frame-parameter frame 'line-spacing))))) | 1151 | (frame-parameter frame 'line-spacing))))) |
| 1143 | (cond ((floatp spacing) | 1152 | (cond ((floatp spacing) |
| 1144 | (setq spacing (truncate (* spacing | 1153 | (setq spacing (truncate (* spacing |
| 1145 | (frame-char-height frame))))) | 1154 | (frame-char-height frame))))) |
diff --git a/lisp/textmodes/artist.el b/lisp/textmodes/artist.el index 8a2383c12ff..85d9410868a 100644 --- a/lisp/textmodes/artist.el +++ b/lisp/textmodes/artist.el | |||
| @@ -4963,52 +4963,55 @@ The event, EV, is the mouse event." | |||
| 4963 | (artist-funcall init-fn x1 y1) | 4963 | (artist-funcall init-fn x1 y1) |
| 4964 | (if (not artist-rubber-banding) | 4964 | (if (not artist-rubber-banding) |
| 4965 | (artist-no-rb-set-point1 x1 y1)) | 4965 | (artist-no-rb-set-point1 x1 y1)) |
| 4966 | (track-mouse | 4966 | (unwind-protect |
| 4967 | (while (or (mouse-movement-p ev) | 4967 | (track-mouse |
| 4968 | (member 'down (event-modifiers ev))) | 4968 | (while (or (mouse-movement-p ev) |
| 4969 | (setq ev-start-pos (artist-coord-win-to-buf | 4969 | (member 'down (event-modifiers ev))) |
| 4970 | (posn-col-row (event-start ev)))) | 4970 | (setq ev-start-pos (artist-coord-win-to-buf |
| 4971 | (setq x1 (car ev-start-pos)) | 4971 | (posn-col-row (event-start ev)))) |
| 4972 | (setq y1 (cdr ev-start-pos)) | 4972 | (setq x1 (car ev-start-pos)) |
| 4973 | 4973 | (setq y1 (cdr ev-start-pos)) | |
| 4974 | ;; Cancel previous timer | 4974 | |
| 4975 | (if timer | 4975 | ;; Cancel previous timer |
| 4976 | (cancel-timer timer)) | 4976 | (if timer |
| 4977 | 4977 | (cancel-timer timer)) | |
| 4978 | (if (not (eq initial-win (posn-window (event-start ev)))) | 4978 | |
| 4979 | ;; If we moved outside the window, do nothing | 4979 | (if (not (eq initial-win (posn-window (event-start ev)))) |
| 4980 | nil | 4980 | ;; If we moved outside the window, do nothing |
| 4981 | 4981 | nil | |
| 4982 | ;; Still in same window: | 4982 | |
| 4983 | ;; | 4983 | ;; Still in same window: |
| 4984 | ;; Check if user presses or releases shift key | 4984 | ;; |
| 4985 | (if (artist-shift-has-changed shift-state ev) | 4985 | ;; Check if user presses or releases shift key |
| 4986 | 4986 | (if (artist-shift-has-changed shift-state ev) | |
| 4987 | ;; First check that the draw-how is the same as we | 4987 | |
| 4988 | ;; already have. Otherwise, ignore the changed shift-state. | 4988 | ;; First check that the draw-how is the same as we |
| 4989 | (if (not (eq draw-how | 4989 | ;; already have. Otherwise, ignore the changed shift-state. |
| 4990 | (artist-go-get-draw-how-from-symbol | 4990 | (if (not (eq draw-how |
| 4991 | (if (not shift-state) shifted unshifted)))) | 4991 | (artist-go-get-draw-how-from-symbol |
| 4992 | (message "Cannot switch to shifted operation") | 4992 | (if (not shift-state) shifted unshifted)))) |
| 4993 | 4993 | (message "Cannot switch to shifted operation") | |
| 4994 | ;; progn is "implicit" since this is the else-part | 4994 | |
| 4995 | (setq shift-state (not shift-state)) | 4995 | ;; progn is "implicit" since this is the else-part |
| 4996 | (setq op (if shift-state shifted unshifted)) | 4996 | (setq shift-state (not shift-state)) |
| 4997 | (setq draw-how (artist-go-get-draw-how-from-symbol op)) | 4997 | (setq op (if shift-state shifted unshifted)) |
| 4998 | (setq draw-fn (artist-go-get-draw-fn-from-symbol op)))) | 4998 | (setq draw-how (artist-go-get-draw-how-from-symbol op)) |
| 4999 | 4999 | (setq draw-fn (artist-go-get-draw-fn-from-symbol op)))) | |
| 5000 | ;; Draw the new shape | 5000 | |
| 5001 | (setq shape (artist-funcall draw-fn x1 y1)) | 5001 | ;; Draw the new shape |
| 5002 | (artist-move-to-xy x1 y1) | 5002 | (setq shape (artist-funcall draw-fn x1 y1)) |
| 5003 | 5003 | (artist-move-to-xy x1 y1) | |
| 5004 | ;; Start the timer to call `draw-fn' repeatedly every | 5004 | |
| 5005 | ;; `interval' second | 5005 | ;; Start the timer to call `draw-fn' repeatedly every |
| 5006 | (if (and interval draw-fn) | 5006 | ;; `interval' second |
| 5007 | (setq timer (run-at-time interval interval draw-fn x1 y1)))) | 5007 | (if (and interval draw-fn) |
| 5008 | 5008 | (setq timer (run-at-time interval interval draw-fn x1 y1)))) | |
| 5009 | ;; Read next event | 5009 | |
| 5010 | (setq ev (read-event)))) | 5010 | ;; Read next event |
| 5011 | 5011 | (setq ev (read-event)))) | |
| 5012 | ;; Cleanup: get rid of any active timer. | ||
| 5013 | (if timer | ||
| 5014 | (cancel-timer timer))) | ||
| 5012 | ;; Cancel any timers | 5015 | ;; Cancel any timers |
| 5013 | (if timer | 5016 | (if timer |
| 5014 | (cancel-timer timer)) | 5017 | (cancel-timer timer)) |