]> git.eshelyaron.com Git - emacs.git/commitdiff
Prevent artist-mode from creating runaway timers (Bug#6130).
authorDaniel Koning <dk@danielkoning.com>
Wed, 21 Jan 2015 08:01:30 +0000 (09:01 +0100)
committerMartin Rudalics <rudalics@gmx.at>
Wed, 21 Jan 2015 08:01:30 +0000 (09:01 +0100)
* 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.

doc/lispref/ChangeLog
doc/lispref/commands.texi
lisp/ChangeLog
lisp/subr.el
lisp/textmodes/artist.el

index 11a6f32718c51a4398dc13fca30aeaa30dfafbf3..52c621c1fa57e5f616ce9117a4d05e9642378e8f 100644 (file)
@@ -1,3 +1,9 @@
+2015-01-21  Daniel Koning  <dk@danielkoning.com>  (tiny change)
+
+       * commands.texi (Drag Events, Motion Events, Event Examples)
+       (Accessing Mouse): Describe actual range of values that mouse
+       position objects can have.
+
 2015-01-20  Eli Zaretskii  <eliz@gnu.org>
 
        * display.texi (Manipulating Buttons): Explain more about the
index a503e3f117b2ba0ba6a629972e470e1a8aa4cb53..5ea1a48b26257c35e5e2c72883d371c33c935d2d 100644 (file)
@@ -1485,8 +1485,10 @@ prefix @samp{drag-}.  For example, dragging the mouse with button 2
 held down generates a @code{drag-mouse-2} event.  The second and third
 elements of the event give the starting and ending position of the
 drag, as mouse position lists (@pxref{Click Events}).  You can access
-the second element of any mouse event in the same way, with no need to
-distinguish drag events from others.
+the second element of any mouse event in the same way.  However, the
+drag event may end outside the boundaries of the frame that was
+initially selected.  In that case, the third element's position list
+contains that frame in place of a window.
 
 The @samp{drag-} prefix follows the modifier key prefixes such as
 @samp{C-} and @samp{M-}.
@@ -1631,7 +1633,10 @@ represented by lists that look like this:
 
 @noindent
 @var{position} is a mouse position list (@pxref{Click Events}),
-specifying the current position of the mouse cursor.
+specifying the current position of the mouse cursor.  As with the
+end-position of a drag event, this position list may represent a
+location outside the boundaries of the initially selected frame, in
+which case the list contains that frame in place of a window.
 
 The special form @code{track-mouse} enables generation of motion
 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:
                    -453816))
 @end smallexample
 
+The frame with input focus might not take up the entire screen, and
+the user might move the mouse outside the scope of the frame. Inside
+the @code{track-mouse} special form, that produces an event like this:
+
+@smallexample
+(mouse-movement (#<frame *ielm* 0x102849a30> nil (563 . 205) 532301936))
+@end smallexample
+
 To handle a SIGUSR1 signal, define an interactive function, and
 bind it to the @code{signal usr1} event sequence:
 
@@ -2010,7 +2023,9 @@ Events}); and @code{nil} otherwise.
 various parts of it:
 
 @defun posn-window position
-Return the window that @var{position} is in.
+Return the window that @var{position} is in.  If @var{position}
+represents a location outside the frame where the event was initiated,
+return that frame instead.
 @end defun
 
 @defun posn-area position
index 20efe68bff65d429984b975bb07180030ec57fd2..280f602200709fe221867884e610a789ef6ba077 100644 (file)
@@ -1,3 +1,10 @@
+2015-01-21  Daniel Koning  <dk@danielkoning.com>  (tiny change)
+
+       * 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)
+
 2015-01-20  Eli Zaretskii  <eliz@gnu.org>
 
        * button.el (button-activate, push-button): Doc fix.  (Bug#19628)
index d71de87b42cfb24b761dc34fefc41733a6521587..a48038fa12b17bc7f60ee6edde38ae0980b839b8 100644 (file)
@@ -1062,7 +1062,12 @@ The return value is a positive integer."
 ;;;; Extracting fields of the positions in an event.
 
 (defun posnp (obj)
-  "Return non-nil if OBJ appears to be a valid `posn' object."
+  "Return non-nil if OBJ appears to be a valid `posn' object specifying a window.
+If OBJ is a valid `posn' object, but specifies a frame rather
+than a window, return nil."
+  ;; FIXME: Correct the behavior of this function so that all valid
+  ;; `posn' objects are recognized, after updating other code that
+  ;; depends on its present behavior.
   (and (windowp (car-safe obj))
        (atom (car-safe (setq obj (cdr obj))))                ;AREA-OR-POS.
        (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
 corresponds to the vertical position of the click in the scroll bar.
 POSITION should be a list of the form returned by the `event-start'
 and `event-end' functions."
-  (let* ((pair   (posn-x-y position))
-        (window (posn-window position))
-        (area   (posn-area position)))
+  (let* ((pair            (posn-x-y position))
+         (frame-or-window (posn-window position))
+         (frame           (if (framep frame-or-window)
+                              frame-or-window
+                            (window-frame frame-or-window)))
+         (window          (when (windowp frame-or-window) frame-or-window))
+         (area            (posn-area position)))
     (cond
-     ((null window)
+     ((null frame-or-window)
       '(0 . 0))
      ((eq area 'vertical-scroll-bar)
       (cons 0 (scroll-bar-scale pair (1- (window-height window)))))
      ((eq area 'horizontal-scroll-bar)
       (cons (scroll-bar-scale pair (window-width window)) 0))
      (t
-      (let* ((frame (if (framep window) window (window-frame window)))
-            ;; FIXME: This should take line-spacing properties on
-            ;; newlines into account.
-            (spacing (when (display-graphic-p frame)
-                       (or (with-current-buffer (window-buffer window)
-                             line-spacing)
-                           (frame-parameter frame 'line-spacing)))))
+      ;; FIXME: This should take line-spacing properties on
+      ;; newlines into account.
+      (let* ((spacing (when (display-graphic-p frame)
+                        (or (with-current-buffer
+                                (window-buffer (frame-selected-window frame))
+                              line-spacing)
+                            (frame-parameter frame 'line-spacing)))))
        (cond ((floatp spacing)
               (setq spacing (truncate (* spacing
                                          (frame-char-height frame)))))
index 8a2383c12ffbcd6e83dc822594d8214209c1b6a9..85d9410868a31272d7cf135b430dce8ddfbffc96 100644 (file)
@@ -4963,52 +4963,55 @@ The event, EV, is the mouse event."
     (artist-funcall init-fn x1 y1)
     (if (not artist-rubber-banding)
        (artist-no-rb-set-point1 x1 y1))
-    (track-mouse
-      (while (or (mouse-movement-p ev)
-                (member 'down (event-modifiers ev)))
-       (setq ev-start-pos (artist-coord-win-to-buf
-                           (posn-col-row (event-start ev))))
-       (setq x1 (car ev-start-pos))
-       (setq y1 (cdr ev-start-pos))
-
-       ;; Cancel previous timer
-       (if timer
-           (cancel-timer timer))
-
-       (if (not (eq initial-win (posn-window (event-start ev))))
-           ;; If we moved outside the window, do nothing
-           nil
-
-         ;; Still in same window:
-         ;;
-         ;; Check if user presses or releases shift key
-         (if (artist-shift-has-changed shift-state ev)
-
-             ;; First check that the draw-how is the same as we
-             ;; already have. Otherwise, ignore the changed shift-state.
-             (if (not (eq draw-how
-                          (artist-go-get-draw-how-from-symbol
-                           (if (not shift-state) shifted unshifted))))
-                 (message "Cannot switch to shifted operation")
-
-               ;; progn is "implicit" since this is the else-part
-               (setq shift-state (not shift-state))
-               (setq op          (if shift-state shifted unshifted))
-               (setq draw-how    (artist-go-get-draw-how-from-symbol op))
-               (setq draw-fn     (artist-go-get-draw-fn-from-symbol op))))
-
-         ;; Draw the new shape
-         (setq shape (artist-funcall draw-fn x1 y1))
-         (artist-move-to-xy x1 y1)
-
-         ;; Start the timer to call `draw-fn' repeatedly every
-         ;; `interval' second
-         (if (and interval draw-fn)
-             (setq timer (run-at-time interval interval draw-fn x1 y1))))
-
-       ;; Read next event
-       (setq ev (read-event))))
-
+    (unwind-protect
+        (track-mouse
+          (while (or (mouse-movement-p ev)
+                     (member 'down (event-modifiers ev)))
+            (setq ev-start-pos (artist-coord-win-to-buf
+                                (posn-col-row (event-start ev))))
+            (setq x1 (car ev-start-pos))
+            (setq y1 (cdr ev-start-pos))
+
+            ;; Cancel previous timer
+            (if timer
+                (cancel-timer timer))
+
+            (if (not (eq initial-win (posn-window (event-start ev))))
+                ;; If we moved outside the window, do nothing
+                nil
+
+              ;; Still in same window:
+              ;;
+              ;; Check if user presses or releases shift key
+              (if (artist-shift-has-changed shift-state ev)
+
+                  ;; First check that the draw-how is the same as we
+                  ;; already have. Otherwise, ignore the changed shift-state.
+                  (if (not (eq draw-how
+                               (artist-go-get-draw-how-from-symbol
+                                (if (not shift-state) shifted unshifted))))
+                      (message "Cannot switch to shifted operation")
+
+                    ;; progn is "implicit" since this is the else-part
+                    (setq shift-state (not shift-state))
+                    (setq op          (if shift-state shifted unshifted))
+                    (setq draw-how    (artist-go-get-draw-how-from-symbol op))
+                    (setq draw-fn     (artist-go-get-draw-fn-from-symbol op))))
+
+              ;; Draw the new shape
+              (setq shape (artist-funcall draw-fn x1 y1))
+              (artist-move-to-xy x1 y1)
+
+              ;; Start the timer to call `draw-fn' repeatedly every
+              ;; `interval' second
+              (if (and interval draw-fn)
+                  (setq timer (run-at-time interval interval draw-fn x1 y1))))
+
+            ;; Read next event
+            (setq ev (read-event))))
+      ;; Cleanup: get rid of any active timer.
+      (if timer
+          (cancel-timer timer)))
     ;; Cancel any timers
     (if timer
        (cancel-timer timer))