diff options
| author | Stefan Monnier | 2014-12-17 21:03:30 -0500 |
|---|---|---|
| committer | Stefan Monnier | 2014-12-17 21:03:30 -0500 |
| commit | 9e77c1b7bcfd0807be7fe67daf73c2320e864309 (patch) | |
| tree | 0614f71857da0f47422502b6d9c71b3f50546342 | |
| parent | ec10ba2792eef613caf47fff83e869d4bc177616 (diff) | |
| download | emacs-9e77c1b7bcfd0807be7fe67daf73c2320e864309.tar.gz emacs-9e77c1b7bcfd0807be7fe67daf73c2320e864309.zip | |
* src/keyboard.c (input_was_pending): New var.
(read_char): Use it to make sure we only skip redisplay when we can't
keep up with the repeat rate.
| -rw-r--r-- | src/ChangeLog | 6 | ||||
| -rw-r--r-- | src/keyboard.c | 53 |
2 files changed, 58 insertions, 1 deletions
diff --git a/src/ChangeLog b/src/ChangeLog index 01653de22ed..16e99aec99a 100644 --- a/src/ChangeLog +++ b/src/ChangeLog | |||
| @@ -1,3 +1,9 @@ | |||
| 1 | 2014-12-18 Stefan Monnier <monnier@iro.umontreal.ca> | ||
| 2 | |||
| 3 | * keyboard.c (input_was_pending): New var. | ||
| 4 | (read_char): Use it to make sure we only skip redisplay when we can't | ||
| 5 | keep up with the repeat rate. | ||
| 6 | |||
| 1 | 2014-12-17 Stefan Monnier <monnier@iro.umontreal.ca> | 7 | 2014-12-17 Stefan Monnier <monnier@iro.umontreal.ca> |
| 2 | 8 | ||
| 3 | * keyboard.c (swallow_events): Don't redisplay if there's input pending. | 9 | * keyboard.c (swallow_events): Don't redisplay if there's input pending. |
diff --git a/src/keyboard.c b/src/keyboard.c index 9e12f590c57..d76a8fcb783 100644 --- a/src/keyboard.c +++ b/src/keyboard.c | |||
| @@ -273,6 +273,54 @@ static FILE *dribble; | |||
| 273 | /* True if input is available. */ | 273 | /* True if input is available. */ |
| 274 | bool input_pending; | 274 | bool input_pending; |
| 275 | 275 | ||
| 276 | /* True if more input was available last time we read an event. | ||
| 277 | |||
| 278 | Since redisplay can take a significant amount of time and is not | ||
| 279 | indispensible to perform the user's commands, when input arrives | ||
| 280 | "too fast", Emacs skips redisplay. More specifically, if the next | ||
| 281 | command has already been input when we finish the previous command, | ||
| 282 | we skip the intermediate redisplay. | ||
| 283 | |||
| 284 | This is useful to try and make sure Emacs keeps up with fast input | ||
| 285 | rates, such as auto-repeating keys. But in some cases, this proves | ||
| 286 | too conservative: we may end up disabling redisplay for the whole | ||
| 287 | duration of a key repetition, even though we could afford to | ||
| 288 | redisplay every once in a while. | ||
| 289 | |||
| 290 | So we "sample" the input_pending flag before running a command and | ||
| 291 | use *that* value after running the command to decide whether to | ||
| 292 | skip redisplay or not. This way, we only skip redisplay if we | ||
| 293 | really can't keep up with the repeat rate. | ||
| 294 | |||
| 295 | This only makes a difference if the next input arrives while running the | ||
| 296 | command, which is very unlikely if the command is executed quickly. | ||
| 297 | IOW this tends to avoid skipping redisplay after a long running command | ||
| 298 | (which is a case where skipping redisplay is not very useful since the | ||
| 299 | redisplay time is small compared to the time it took to run the command). | ||
| 300 | |||
| 301 | A typical use case is when scrolling. Scrolling time can be split into: | ||
| 302 | - Time to do jit-lock on the newly displayed portion of buffer. | ||
| 303 | - Time to run the actual scroll command. | ||
| 304 | - Time to perform the redisplay. | ||
| 305 | Jit-lock can happen either during the command or during the redisplay. | ||
| 306 | In the most painful cases, the jit-lock time is the one that dominates. | ||
| 307 | Also jit-lock can be tweaked (via jit-lock-defer) to delay its job, at the | ||
| 308 | cost of temporary inaccuracy in display and scrolling. | ||
| 309 | So without input_was_pending, what typically happens is the following: | ||
| 310 | - when the command starts, there's no pending input (yet). | ||
| 311 | - the scroll command triggers jit-lock. | ||
| 312 | - during the long jit-lock time the next input arrives. | ||
| 313 | - at the end of the command, we check input_pending and hence decide to | ||
| 314 | skip redisplay. | ||
| 315 | - we read the next input and start over. | ||
| 316 | End result: all the hard work of jit-locking is "wasted" since redisplay | ||
| 317 | doesn't actually happens (at least not before the input rate slows down). | ||
| 318 | With input_was_pending redisplay is still skipped if Emacs can't keep up | ||
| 319 | with the input rate, but if it can keep up just enough that there's no | ||
| 320 | input_pending when we begin the command, then redisplay is not skipped | ||
| 321 | which results in better feedback to the user. */ | ||
| 322 | static bool input_was_pending; | ||
| 323 | |||
| 276 | /* Circular buffer for pre-read keyboard input. */ | 324 | /* Circular buffer for pre-read keyboard input. */ |
| 277 | 325 | ||
| 278 | static struct input_event kbd_buffer[KBD_BUFFER_SIZE]; | 326 | static struct input_event kbd_buffer[KBD_BUFFER_SIZE]; |
| @@ -2585,8 +2633,10 @@ read_char (int commandflag, Lisp_Object map, | |||
| 2585 | swallow_events (false); /* May clear input_pending. */ | 2633 | swallow_events (false); /* May clear input_pending. */ |
| 2586 | 2634 | ||
| 2587 | /* Redisplay if no pending input. */ | 2635 | /* Redisplay if no pending input. */ |
| 2588 | while (!input_pending) | 2636 | while (!(input_pending |
| 2637 | && (input_was_pending || !redisplay_dont_pause))) | ||
| 2589 | { | 2638 | { |
| 2639 | input_was_pending = input_pending; | ||
| 2590 | if (help_echo_showing_p && !EQ (selected_window, minibuf_window)) | 2640 | if (help_echo_showing_p && !EQ (selected_window, minibuf_window)) |
| 2591 | redisplay_preserve_echo_area (5); | 2641 | redisplay_preserve_echo_area (5); |
| 2592 | else | 2642 | else |
| @@ -3255,6 +3305,7 @@ read_char (int commandflag, Lisp_Object map, | |||
| 3255 | 3305 | ||
| 3256 | exit: | 3306 | exit: |
| 3257 | RESUME_POLLING; | 3307 | RESUME_POLLING; |
| 3308 | input_was_pending = input_pending; | ||
| 3258 | RETURN_UNGCPRO (c); | 3309 | RETURN_UNGCPRO (c); |
| 3259 | } | 3310 | } |
| 3260 | 3311 | ||