From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.org!not-for-mail From: Daniel Koning Newsgroups: gmane.emacs.bugs Subject: bug#6130: 23.1; artist-mode spray-can malfunction Date: Tue, 20 Jan 2015 18:26:27 -0600 Message-ID: References: <8dd014e7478827e94e3a8fe5b2b948e0@lysator.liu.se> <54BA6A0A.4080408@gmx.at> <54BB8375.9000506@gmx.at> NNTP-Posting-Host: plane.gmane.org Mime-Version: 1.0 Content-Type: multipart/mixed; boundary="=-=-=" X-Trace: ger.gmane.org 1421800038 15226 80.91.229.3 (21 Jan 2015 00:27:18 GMT) X-Complaints-To: usenet@ger.gmane.org NNTP-Posting-Date: Wed, 21 Jan 2015 00:27:18 +0000 (UTC) Cc: 6130@debbugs.gnu.org, busk To: martin rudalics Original-X-From: bug-gnu-emacs-bounces+geb-bug-gnu-emacs=m.gmane.org@gnu.org Wed Jan 21 01:27:13 2015 Return-path: Envelope-to: geb-bug-gnu-emacs@m.gmane.org Original-Received: from lists.gnu.org ([208.118.235.17]) by plane.gmane.org with esmtp (Exim 4.69) (envelope-from ) id 1YDj8Z-0006bP-Cb for geb-bug-gnu-emacs@m.gmane.org; Wed, 21 Jan 2015 01:27:11 +0100 Original-Received: from localhost ([::1]:46111 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1YDj8Y-00032k-F0 for geb-bug-gnu-emacs@m.gmane.org; Tue, 20 Jan 2015 19:27:10 -0500 Original-Received: from eggs.gnu.org ([2001:4830:134:3::10]:60613) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1YDj8U-00032d-8f for bug-gnu-emacs@gnu.org; Tue, 20 Jan 2015 19:27:08 -0500 Original-Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1YDj8Q-0007JK-5E for bug-gnu-emacs@gnu.org; Tue, 20 Jan 2015 19:27:06 -0500 Original-Received: from debbugs.gnu.org ([140.186.70.43]:60727) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1YDj8Q-0007JG-11 for bug-gnu-emacs@gnu.org; Tue, 20 Jan 2015 19:27:02 -0500 Original-Received: from Debian-debbugs by debbugs.gnu.org with local (Exim 4.80) (envelope-from ) id 1YDj8P-00057Y-KA for bug-gnu-emacs@gnu.org; Tue, 20 Jan 2015 19:27:01 -0500 X-Loop: help-debbugs@gnu.org Resent-From: Daniel Koning Original-Sender: "Debbugs-submit" Resent-CC: bug-gnu-emacs@gnu.org Resent-Date: Wed, 21 Jan 2015 00:27:01 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: followup 6130 X-GNU-PR-Package: emacs X-GNU-PR-Keywords: Original-Received: via spool by 6130-submit@debbugs.gnu.org id=B6130.142180000619661 (code B ref 6130); Wed, 21 Jan 2015 00:27:01 +0000 Original-Received: (at 6130) by debbugs.gnu.org; 21 Jan 2015 00:26:46 +0000 Original-Received: from localhost ([127.0.0.1]:51186 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.80) (envelope-from ) id 1YDj89-000572-HV for submit@debbugs.gnu.org; Tue, 20 Jan 2015 19:26:46 -0500 Original-Received: from sender1.zohomail.com ([74.201.84.155]:29200) by debbugs.gnu.org with esmtp (Exim 4.80) (envelope-from ) id 1YDj85-00056s-Rh for 6130@debbugs.gnu.org; Tue, 20 Jan 2015 19:26:43 -0500 Original-Received: from cornelius (99-181-53-37.lightspeed.rcsntx.sbcglobal.net [99.181.53.37]) by mx.zohomail.com with SMTPS id 1421799989004554.9554962858034; Tue, 20 Jan 2015 16:26:29 -0800 (PST) In-Reply-To: <54BB8375.9000506@gmx.at> (martin rudalics's message of "Sun, 18 Jan 2015 10:57:09 +0100") User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/25.0.50 (darwin) X-Zoho-Virus-Status: 1 X-ZohoMailClient: External X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.15 Precedence: list X-detected-operating-system: by eggs.gnu.org: GNU/Linux 3.x X-Received-From: 140.186.70.43 X-BeenThere: bug-gnu-emacs@gnu.org List-Id: "Bug reports for GNU Emacs, the Swiss army knife of text editors" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: bug-gnu-emacs-bounces+geb-bug-gnu-emacs=m.gmane.org@gnu.org Original-Sender: bug-gnu-emacs-bounces+geb-bug-gnu-emacs=m.gmane.org@gnu.org Xref: news.gmane.org gmane.emacs.bugs:98529 Archived-At: --=-=-= Content-Type: text/plain martin rudalics writes: >> I added a line to check for frames. > > No - this might be dangerous for now. Suppose we have callers that > relied on `posnp' to return nil in that case. They would all of sudden > have to deal with the fact that they get a frame now, so more or less we > could reintroduce the problem you try to fix presently. Please take > this out for the moment but state in the doc-string that `posnp' returns > nil if the first element of OBJ is a frame. Later on we can change this > as you did and see what happens. Okay, but I think this should be a reasonably high priority for the maintainers of this part of the lisp tree. Aren't there likely to be quite a few undiscovered bugs, some perhaps quite destructive, that result from following the behavior as it was documented, just as there are (presumably) places where new bugs would manifest if `posnp' were brought in line with its advertised behavior? In any case, I've appended a FIXME comment in addition to revising the docstring. I added the log entry to the highest-level ChangeLog file, since I edited files in lisp/ and doc/ (even though the doc/ changes were only in reference to functionality implemented under lisp/). Is that right? Daniel --=-=-= Content-Type: text/x-patch Content-Disposition: inline; filename=artist.patch Content-Description: Fix for #6130 diff --git a/ChangeLog b/ChangeLog index 309b04f..53d7bb4 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,14 @@ +2015-01-20 Daniel Koning + + Prevent artist-mode from creating runaway timers. + * lisp/textmodes/artist.el: Cancel timers if an error occurs + during continuous drawing. + * lisp/subr.el: Make `posn-col-row' work with all mouse position + objects. Correct docstring of `posnp'. + * doc/lispref/commands.texi: Describe actual range of values that + mouse position objects can have. + Fixes: bug#6130 + 2015-01-16 Paul Eggert Give up on -Wsuggest-attribute=const diff --git a/doc/lispref/commands.texi b/doc/lispref/commands.texi index 36c7445..6fdc8e2 100644 --- a/doc/lispref/commands.texi +++ b/doc/lispref/commands.texi @@ -1489,8 +1489,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-}. @@ -1635,7 +1637,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 @@ -1850,6 +1855,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 (# 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: @@ -2014,7 +2027,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 diff --git a/lisp/subr.el b/lisp/subr.el index 0534585..b37d17f 100644 --- a/lisp/subr.el +++ b/lisp/subr.el @@ -1082,7 +1082,10 @@ 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 that specifies 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. @@ -1142,24 +1145,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))))) diff --git a/lisp/textmodes/artist.el b/lisp/textmodes/artist.el index 8a2383c..85d9410 100644 --- a/lisp/textmodes/artist.el +++ b/lisp/textmodes/artist.el @@ -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)) --=-=-=--