aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJuri Linkov2019-11-24 00:22:46 +0200
committerJuri Linkov2019-11-24 00:22:46 +0200
commit4b5d04be44af36cb2faccd368de063cf376282ca (patch)
tree587358591551d040473728b2b5344b8e0a37c472
parent8934762bb37273e6606097de92dcc2556456acd2 (diff)
downloademacs-4b5d04be44af36cb2faccd368de063cf376282ca.tar.gz
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)
-rw-r--r--etc/NEWS5
-rw-r--r--lisp/emacs-lisp/timer.el44
-rw-r--r--lisp/image.el30
3 files changed, 67 insertions, 12 deletions
diff --git a/etc/NEWS b/etc/NEWS
index 3bf4c81014b..819637b79fc 100644
--- a/etc/NEWS
+++ b/etc/NEWS
@@ -2796,6 +2796,11 @@ doing computations on a decoded time structure), 'make-decoded-time'
2796filled out), and 'encoded-time-set-defaults' (which fills in nil 2796filled out), and 'encoded-time-set-defaults' (which fills in nil
2797elements as if it's midnight January 1st, 1970) have been added. 2797elements as if it's midnight January 1st, 1970) have been added.
2798 2798
2799** New macros 'debounce' and 'debounce-reduce' postpone function call
2800until after specified time have elapsed since the last time it was invoked.
2801This improves performance of processing events occurring rapidly
2802in quick succession.
2803
2799** 'define-minor-mode' automatically documents the meaning of ARG. 2804** 'define-minor-mode' automatically documents the meaning of ARG.
2800 2805
2801+++ 2806+++
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'."
488If the user does not answer after SECONDS seconds, return DEFAULT-VALUE." 488If the user does not answer after SECONDS seconds, return DEFAULT-VALUE."
489 (with-timeout (seconds default-value) 489 (with-timeout (seconds default-value)
490 (y-or-n-p prompt))) 490 (y-or-n-p prompt)))
491
492(defmacro debounce (secs function)
493 "Call FUNCTION after SECS seconds have elapsed.
494Postpone FUNCTION call until after SECS seconds have elapsed since the
495last time it was invoked. On consecutive calls within the interval of
496SECS seconds, cancel all previous calls that occur rapidly in quick succession,
497and execute only the last call. This improves performance of event processing."
498 (declare (indent 1) (debug t))
499 (let ((timer-sym (make-symbol "timer")))
500 `(let (,timer-sym)
501 (lambda (&rest args)
502 (when (timerp ,timer-sym)
503 (cancel-timer ,timer-sym))
504 (setq ,timer-sym
505 (run-with-timer
506 ,secs nil (lambda ()
507 (apply ,function args))))))))
508
509(defmacro debounce-reduce (secs initial-state state-function function)
510 "Call FUNCTION after SECS seconds have elapsed.
511Postpone FUNCTION call until after SECS seconds have elapsed since the
512last time it was invoked. On consecutive calls within the interval of
513SECS seconds, cancel all previous calls that occur rapidly in quick succession,
514and execute only the last call. This improves performance of event processing.
515
516STATE-FUNCTION can be used to accumulate the state on consecutive calls
517starting with the value of INITIAL-STATE, and then execute the last call
518with the collected state value."
519 (declare (indent 1) (debug t))
520 (let ((timer-sym (make-symbol "timer"))
521 (state-sym (make-symbol "state")))
522 `(let (,timer-sym (,state-sym ,initial-state))
523 (lambda (&rest args)
524 (setq ,state-sym (apply ,state-function ,state-sym args))
525 (when (timerp ,timer-sym)
526 (cancel-timer ,timer-sym))
527 (setq ,timer-sym
528 (run-with-timer
529 ,secs nil (lambda ()
530 (apply ,function (if (listp ,state-sym)
531 ,state-sym
532 (list ,state-sym)))
533 (setq ,state-sym ,initial-state))))))))
534
491 535
492(defconst timer-duration-words 536(defconst timer-duration-words
493 (list (cons "microsec" 0.000001) 537 (list (cons "microsec" 0.000001)
diff --git a/lisp/image.el b/lisp/image.el
index 6e19f17fd25..c4304782327 100644
--- a/lisp/image.el
+++ b/lisp/image.el
@@ -1017,18 +1017,20 @@ has no effect."
1017If N is 3, then the image size will be increased by 30%. The 1017If N is 3, then the image size will be increased by 30%. The
1018default is 20%." 1018default is 20%."
1019 (interactive "P") 1019 (interactive "P")
1020 (image--change-size (if n 1020 (funcall image--change-size-function
1021 (1+ (/ (prefix-numeric-value n) 10.0)) 1021 (if n
1022 1.2))) 1022 (1+ (/ (prefix-numeric-value n) 10.0))
1023 1.2)))
1023 1024
1024(defun image-decrease-size (&optional n) 1025(defun image-decrease-size (&optional n)
1025 "Decrease the image size by a factor of N. 1026 "Decrease the image size by a factor of N.
1026If N is 3, then the image size will be decreased by 30%. The 1027If N is 3, then the image size will be decreased by 30%. The
1027default is 20%." 1028default is 20%."
1028 (interactive "P") 1029 (interactive "P")
1029 (image--change-size (if n 1030 (funcall image--change-size-function
1030 (- 1 (/ (prefix-numeric-value n) 10.0)) 1031 (if n
1031 0.8))) 1032 (- 1 (/ (prefix-numeric-value n) 10.0))
1033 0.8)))
1032 1034
1033(defun image-mouse-increase-size (&optional event) 1035(defun image-mouse-increase-size (&optional event)
1034 "Increase the image size using the mouse." 1036 "Increase the image size using the mouse."
@@ -1063,12 +1065,16 @@ default is 20%."
1063 (plist-put (cdr image) :type 'imagemagick)) 1065 (plist-put (cdr image) :type 'imagemagick))
1064 image)) 1066 image))
1065 1067
1066(defun image--change-size (factor) 1068(defvar image--change-size-function
1067 (let* ((image (image--get-imagemagick-and-warn)) 1069 (debounce-reduce 0.3 1
1068 (new-image (image--image-without-parameters image)) 1070 (lambda (state factor)
1069 (scale (image--current-scaling image new-image))) 1071 (* state factor))
1070 (setcdr image (cdr new-image)) 1072 (lambda (factor)
1071 (plist-put (cdr image) :scale (* scale factor)))) 1073 (let* ((image (image--get-imagemagick-and-warn))
1074 (new-image (image--image-without-parameters image))
1075 (scale (image--current-scaling image new-image)))
1076 (setcdr image (cdr new-image))
1077 (plist-put (cdr image) :scale (* scale factor))))))
1072 1078
1073(defun image--image-without-parameters (image) 1079(defun image--image-without-parameters (image)
1074 (cons (pop image) 1080 (cons (pop image)