summaryrefslogtreecommitdiff
path: root/lisp/emacs-lisp
diff options
context:
space:
mode:
authorJuri Linkov <juri@linkov.net>2019-11-24 00:22:46 +0200
committerJuri Linkov <juri@linkov.net>2019-11-24 00:22:46 +0200
commit4b5d04be44af36cb2faccd368de063cf376282ca (patch)
tree587358591551d040473728b2b5344b8e0a37c472 /lisp/emacs-lisp
parent8934762bb37273e6606097de92dcc2556456acd2 (diff)
downloademacs-4b5d04be44af36cb2faccd368de063cf376282ca.tar.gz
emacs-4b5d04be44af36cb2faccd368de063cf376282ca.tar.bz2
emacs-4b5d04be44af36cb2faccd368de063cf376282ca.zip
Use new macro debounce-reduce to make mouse scaling of images more responsive
* lisp/emacs-lisp/timer.el (debounce, debounce-reduce): New macros. * lisp/image.el (image-increase-size, image-decrease-size): Use funcall to call image--change-size-function. (image--change-size-function): Move code from defun of image--change-size to defvar that has the value of lambda returned from debounce-reduce. (Bug#38187)
Diffstat (limited to 'lisp/emacs-lisp')
-rw-r--r--lisp/emacs-lisp/timer.el44
1 files changed, 44 insertions, 0 deletions
diff --git a/lisp/emacs-lisp/timer.el b/lisp/emacs-lisp/timer.el
index 561cc70078f..5fdf9a426a7 100644
--- a/lisp/emacs-lisp/timer.el
+++ b/lisp/emacs-lisp/timer.el
@@ -488,6 +488,50 @@ The argument should be a value previously returned by `with-timeout-suspend'."
If the user does not answer after SECONDS seconds, return DEFAULT-VALUE."
(with-timeout (seconds default-value)
(y-or-n-p prompt)))
+
+(defmacro debounce (secs function)
+ "Call FUNCTION after SECS seconds have elapsed.
+Postpone FUNCTION call until after SECS seconds have elapsed since the
+last time it was invoked. On consecutive calls within the interval of
+SECS seconds, cancel all previous calls that occur rapidly in quick succession,
+and execute only the last call. This improves performance of event processing."
+ (declare (indent 1) (debug t))
+ (let ((timer-sym (make-symbol "timer")))
+ `(let (,timer-sym)
+ (lambda (&rest args)
+ (when (timerp ,timer-sym)
+ (cancel-timer ,timer-sym))
+ (setq ,timer-sym
+ (run-with-timer
+ ,secs nil (lambda ()
+ (apply ,function args))))))))
+
+(defmacro debounce-reduce (secs initial-state state-function function)
+ "Call FUNCTION after SECS seconds have elapsed.
+Postpone FUNCTION call until after SECS seconds have elapsed since the
+last time it was invoked. On consecutive calls within the interval of
+SECS seconds, cancel all previous calls that occur rapidly in quick succession,
+and execute only the last call. This improves performance of event processing.
+
+STATE-FUNCTION can be used to accumulate the state on consecutive calls
+starting with the value of INITIAL-STATE, and then execute the last call
+with the collected state value."
+ (declare (indent 1) (debug t))
+ (let ((timer-sym (make-symbol "timer"))
+ (state-sym (make-symbol "state")))
+ `(let (,timer-sym (,state-sym ,initial-state))
+ (lambda (&rest args)
+ (setq ,state-sym (apply ,state-function ,state-sym args))
+ (when (timerp ,timer-sym)
+ (cancel-timer ,timer-sym))
+ (setq ,timer-sym
+ (run-with-timer
+ ,secs nil (lambda ()
+ (apply ,function (if (listp ,state-sym)
+ ,state-sym
+ (list ,state-sym)))
+ (setq ,state-sym ,initial-state))))))))
+
(defconst timer-duration-words
(list (cons "microsec" 0.000001)