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 {