aboutsummaryrefslogtreecommitdiffstats
path: root/lisp
diff options
context:
space:
mode:
authorJuri Linkov2019-11-24 00:22:46 +0200
committerJuri Linkov2019-11-24 00:22:46 +0200
commit4b5d04be44af36cb2faccd368de063cf376282ca (patch)
tree587358591551d040473728b2b5344b8e0a37c472 /lisp
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)
Diffstat (limited to 'lisp')
-rw-r--r--lisp/emacs-lisp/timer.el44
-rw-r--r--lisp/image.el30
2 files changed, 62 insertions, 12 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'."
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)