diff options
| author | Juri Linkov | 2019-11-24 00:22:46 +0200 |
|---|---|---|
| committer | Juri Linkov | 2019-11-24 00:22:46 +0200 |
| commit | 4b5d04be44af36cb2faccd368de063cf376282ca (patch) | |
| tree | 587358591551d040473728b2b5344b8e0a37c472 | |
| parent | 8934762bb37273e6606097de92dcc2556456acd2 (diff) | |
| download | emacs-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/NEWS | 5 | ||||
| -rw-r--r-- | lisp/emacs-lisp/timer.el | 44 | ||||
| -rw-r--r-- | lisp/image.el | 30 |
3 files changed, 67 insertions, 12 deletions
| @@ -2796,6 +2796,11 @@ doing computations on a decoded time structure), 'make-decoded-time' | |||
| 2796 | filled out), and 'encoded-time-set-defaults' (which fills in nil | 2796 | filled out), and 'encoded-time-set-defaults' (which fills in nil |
| 2797 | elements as if it's midnight January 1st, 1970) have been added. | 2797 | elements as if it's midnight January 1st, 1970) have been added. |
| 2798 | 2798 | ||
| 2799 | ** New macros 'debounce' and 'debounce-reduce' postpone function call | ||
| 2800 | until after specified time have elapsed since the last time it was invoked. | ||
| 2801 | This improves performance of processing events occurring rapidly | ||
| 2802 | in 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'." | |||
| 488 | If the user does not answer after SECONDS seconds, return DEFAULT-VALUE." | 488 | If 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. | ||
| 494 | Postpone FUNCTION call until after SECS seconds have elapsed since the | ||
| 495 | last time it was invoked. On consecutive calls within the interval of | ||
| 496 | SECS seconds, cancel all previous calls that occur rapidly in quick succession, | ||
| 497 | and 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. | ||
| 511 | Postpone FUNCTION call until after SECS seconds have elapsed since the | ||
| 512 | last time it was invoked. On consecutive calls within the interval of | ||
| 513 | SECS seconds, cancel all previous calls that occur rapidly in quick succession, | ||
| 514 | and execute only the last call. This improves performance of event processing. | ||
| 515 | |||
| 516 | STATE-FUNCTION can be used to accumulate the state on consecutive calls | ||
| 517 | starting with the value of INITIAL-STATE, and then execute the last call | ||
| 518 | with 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." | |||
| 1017 | If N is 3, then the image size will be increased by 30%. The | 1017 | If N is 3, then the image size will be increased by 30%. The |
| 1018 | default is 20%." | 1018 | default 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. |
| 1026 | If N is 3, then the image size will be decreased by 30%. The | 1027 | If N is 3, then the image size will be decreased by 30%. The |
| 1027 | default is 20%." | 1028 | default 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) |