Mercurial > vim
comparison src/os_unix.c @ 15653:59a1ff689b4d v8.1.0834
patch 8.1.0834: GUI may wait too long before dealing with messages
commit https://github.com/vim/vim/commit/e40b9d47bf8f8f716d3ef5a95c8ecbbdc0a501f9
Author: Bram Moolenaar <Bram@vim.org>
Date: Sun Jan 27 16:55:47 2019 +0100
patch 8.1.0834: GUI may wait too long before dealing with messages
Problem: GUI may wait too long before dealing with messages. Returning
early may cause a mapping to time out.
Solution: Use the waiting loop from Unix also for the GUI.
(closes #3817, closes #3824)
author | Bram Moolenaar <Bram@vim.org> |
---|---|
date | Sun, 27 Jan 2019 17:00:07 +0100 |
parents | d4a6d575e910 |
children | 287104a1d51e |
comparison
equal
deleted
inserted
replaced
15652:e987698f1397 | 15653:59a1ff689b4d |
---|---|
354 if (p_wd) /* Unix is too fast, slow down a bit more */ | 354 if (p_wd) /* Unix is too fast, slow down a bit more */ |
355 RealWaitForChar(read_cmd_fd, p_wd, NULL, NULL); | 355 RealWaitForChar(read_cmd_fd, p_wd, NULL, NULL); |
356 } | 356 } |
357 | 357 |
358 /* | 358 /* |
359 * Function passed to inchar_loop() to handle window resizing. | |
360 * If "check_only" is TRUE: Return whether there was a resize. | |
361 * If "check_only" is FALSE: Deal with the window resized. | |
362 */ | |
363 static int | |
364 resize_func(int check_only) | |
365 { | |
366 if (check_only) | |
367 return do_resize; | |
368 while (do_resize) | |
369 handle_resize(); | |
370 return FALSE; | |
371 } | |
372 | |
373 /* | |
359 * mch_inchar(): low level input function. | 374 * mch_inchar(): low level input function. |
360 * Get a characters from the keyboard. | 375 * Get a characters from the keyboard. |
361 * Return the number of characters that are available. | 376 * Return the number of characters that are available. |
362 * If wtime == 0 do not wait for characters. | 377 * If wtime == 0 do not wait for characters. |
363 * If wtime == n wait a short time for characters. | 378 * If wtime == n wait a short time for characters. |
368 char_u *buf, | 383 char_u *buf, |
369 int maxlen, | 384 int maxlen, |
370 long wtime, /* don't use "time", MIPS cannot handle it */ | 385 long wtime, /* don't use "time", MIPS cannot handle it */ |
371 int tb_change_cnt) | 386 int tb_change_cnt) |
372 { | 387 { |
373 int len; | 388 return inchar_loop(buf, maxlen, wtime, tb_change_cnt, |
374 int interrupted = FALSE; | 389 WaitForChar, resize_func); |
375 int did_start_blocking = FALSE; | |
376 long wait_time; | |
377 long elapsed_time = 0; | |
378 #ifdef ELAPSED_FUNC | |
379 elapsed_T start_tv; | |
380 | |
381 ELAPSED_INIT(start_tv); | |
382 #endif | |
383 | |
384 /* repeat until we got a character or waited long enough */ | |
385 for (;;) | |
386 { | |
387 /* Check if window changed size while we were busy, perhaps the ":set | |
388 * columns=99" command was used. */ | |
389 while (do_resize) | |
390 handle_resize(); | |
391 | |
392 #ifdef MESSAGE_QUEUE | |
393 // Only process messages when waiting. | |
394 if (wtime != 0) | |
395 { | |
396 parse_queued_messages(); | |
397 // If input was put directly in typeahead buffer bail out here. | |
398 if (typebuf_changed(tb_change_cnt)) | |
399 return 0; | |
400 } | |
401 #endif | |
402 if (wtime < 0 && did_start_blocking) | |
403 /* blocking and already waited for p_ut */ | |
404 wait_time = -1; | |
405 else | |
406 { | |
407 if (wtime >= 0) | |
408 wait_time = wtime; | |
409 else | |
410 /* going to block after p_ut */ | |
411 wait_time = p_ut; | |
412 #ifdef ELAPSED_FUNC | |
413 elapsed_time = ELAPSED_FUNC(start_tv); | |
414 #endif | |
415 wait_time -= elapsed_time; | |
416 if (wait_time < 0) | |
417 { | |
418 if (wtime >= 0) | |
419 /* no character available within "wtime" */ | |
420 return 0; | |
421 | |
422 else | |
423 { | |
424 /* no character available within 'updatetime' */ | |
425 did_start_blocking = TRUE; | |
426 if (trigger_cursorhold() && maxlen >= 3 | |
427 && !typebuf_changed(tb_change_cnt)) | |
428 { | |
429 buf[0] = K_SPECIAL; | |
430 buf[1] = KS_EXTRA; | |
431 buf[2] = (int)KE_CURSORHOLD; | |
432 return 3; | |
433 } | |
434 /* | |
435 * If there is no character available within 'updatetime' | |
436 * seconds flush all the swap files to disk. | |
437 * Also done when interrupted by SIGWINCH. | |
438 */ | |
439 before_blocking(); | |
440 continue; | |
441 } | |
442 } | |
443 } | |
444 | |
445 #ifdef FEAT_JOB_CHANNEL | |
446 /* Checking if a job ended requires polling. Do this every 100 msec. */ | |
447 if (has_pending_job() && (wait_time < 0 || wait_time > 100L)) | |
448 wait_time = 100L; | |
449 /* If there is readahead then parse_queued_messages() timed out and we | |
450 * should call it again soon. */ | |
451 if ((wait_time < 0 || wait_time > 100L) && channel_any_readahead()) | |
452 wait_time = 10L; | |
453 #endif | |
454 #ifdef FEAT_BEVAL_GUI | |
455 if (p_beval && wait_time > 100L) | |
456 /* The 'balloonexpr' may indirectly invoke a callback while waiting | |
457 * for a character, need to check often. */ | |
458 wait_time = 100L; | |
459 #endif | |
460 | |
461 /* | |
462 * We want to be interrupted by the winch signal | |
463 * or by an event on the monitored file descriptors. | |
464 */ | |
465 if (WaitForChar(wait_time, &interrupted, FALSE)) | |
466 { | |
467 /* If input was put directly in typeahead buffer bail out here. */ | |
468 if (typebuf_changed(tb_change_cnt)) | |
469 return 0; | |
470 | |
471 /* | |
472 * For some terminals we only get one character at a time. | |
473 * We want the get all available characters, so we could keep on | |
474 * trying until none is available | |
475 * For some other terminals this is quite slow, that's why we don't | |
476 * do it. | |
477 */ | |
478 len = read_from_input_buf(buf, (long)maxlen); | |
479 if (len > 0) | |
480 return len; | |
481 continue; | |
482 } | |
483 | |
484 /* no character available */ | |
485 #ifndef ELAPSED_FUNC | |
486 /* estimate the elapsed time */ | |
487 elapsed_time += wait_time; | |
488 #endif | |
489 | |
490 if (do_resize /* interrupted by SIGWINCH signal */ | |
491 #ifdef FEAT_CLIENTSERVER | |
492 || server_waiting() | |
493 #endif | |
494 #ifdef MESSAGE_QUEUE | |
495 || interrupted | |
496 #endif | |
497 || wait_time > 0 | |
498 || (wtime < 0 && !did_start_blocking)) | |
499 continue; | |
500 | |
501 /* no character available or interrupted */ | |
502 break; | |
503 } | |
504 return 0; | |
505 } | 390 } |
506 | 391 |
507 static void | 392 static void |
508 handle_resize(void) | 393 handle_resize(void) |
509 { | 394 { |