Mercurial > vim
comparison src/gui.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 | 6f1c7e9a6393 |
children | ad8b2c109b22 |
comparison
equal
deleted
inserted
replaced
15652:e987698f1397 | 15653:59a1ff689b4d |
---|---|
2894 /* | 2894 /* |
2895 * Returns OK if a character was found to be available within the given time, | 2895 * Returns OK if a character was found to be available within the given time, |
2896 * or FAIL otherwise. | 2896 * or FAIL otherwise. |
2897 */ | 2897 */ |
2898 static int | 2898 static int |
2899 gui_wait_for_chars_or_timer(long wtime) | 2899 gui_wait_for_chars_or_timer( |
2900 long wtime, | |
2901 int *interrupted UNUSED, | |
2902 int ignore_input UNUSED) | |
2900 { | 2903 { |
2901 #ifdef FEAT_TIMERS | 2904 #ifdef FEAT_TIMERS |
2902 return ui_wait_for_chars_or_timer(wtime, gui_wait_for_chars_3, NULL, 0); | 2905 return ui_wait_for_chars_or_timer(wtime, gui_wait_for_chars_3, |
2906 interrupted, ignore_input); | |
2903 #else | 2907 #else |
2904 return gui_mch_wait_for_chars(wtime); | 2908 return gui_mch_wait_for_chars(wtime); |
2905 #endif | 2909 #endif |
2906 } | 2910 } |
2907 | 2911 |
2908 /* | 2912 /* |
2909 * The main GUI input routine. Waits for a character from the keyboard. | 2913 * The main GUI input routine. Waits for a character from the keyboard. |
2914 * "wtime" == -1 Wait forever. | |
2915 * "wtime" == 0 Don't wait. | |
2916 * "wtime" > 0 Wait wtime milliseconds for a character. | |
2917 * | |
2918 * Returns the number of characters read or zero when timed out or interrupted. | |
2919 * "buf" may be NULL, in which case a non-zero number is returned if characters | |
2920 * are available. | |
2921 */ | |
2922 static int | |
2923 gui_wait_for_chars_buf( | |
2924 char_u *buf, | |
2925 int maxlen, | |
2926 long wtime, // don't use "time", MIPS cannot handle it | |
2927 int tb_change_cnt) | |
2928 { | |
2929 int retval; | |
2930 | |
2931 #ifdef FEAT_MENU | |
2932 // If we're going to wait a bit, update the menus and mouse shape for the | |
2933 // current State. | |
2934 if (wtime != 0) | |
2935 gui_update_menus(0); | |
2936 #endif | |
2937 | |
2938 gui_mch_update(); | |
2939 if (input_available()) // Got char, return immediately | |
2940 { | |
2941 if (buf != NULL && !typebuf_changed(tb_change_cnt)) | |
2942 return read_from_input_buf(buf, (long)maxlen); | |
2943 return 0; | |
2944 } | |
2945 if (wtime == 0) // Don't wait for char | |
2946 return FAIL; | |
2947 | |
2948 // Before waiting, flush any output to the screen. | |
2949 gui_mch_flush(); | |
2950 | |
2951 // Blink while waiting for a character. | |
2952 gui_mch_start_blink(); | |
2953 | |
2954 // Common function to loop until "wtime" is met, while handling timers and | |
2955 // other callbacks. | |
2956 retval = inchar_loop(buf, maxlen, wtime, tb_change_cnt, | |
2957 gui_wait_for_chars_or_timer, NULL); | |
2958 | |
2959 gui_mch_stop_blink(TRUE); | |
2960 | |
2961 return retval; | |
2962 } | |
2963 | |
2964 /* | |
2965 * Wait for a character from the keyboard without actually reading it. | |
2966 * Also deals with timers. | |
2910 * wtime == -1 Wait forever. | 2967 * wtime == -1 Wait forever. |
2911 * wtime == 0 Don't wait. | 2968 * wtime == 0 Don't wait. |
2912 * wtime > 0 Wait wtime milliseconds for a character. | 2969 * wtime > 0 Wait wtime milliseconds for a character. |
2913 * Returns OK if a character was found to be available within the given time, | 2970 * Returns OK if a character was found to be available within the given time, |
2914 * or FAIL otherwise. | 2971 * or FAIL otherwise. |
2915 */ | 2972 */ |
2916 int | 2973 int |
2917 gui_wait_for_chars(long wtime, int tb_change_cnt) | 2974 gui_wait_for_chars(long wtime, int tb_change_cnt) |
2918 { | 2975 { |
2919 int retval; | 2976 return gui_wait_for_chars_buf(NULL, 0, wtime, tb_change_cnt); |
2920 #if defined(ELAPSED_FUNC) | |
2921 elapsed_T start_tv; | |
2922 #endif | |
2923 | |
2924 #ifdef FEAT_MENU | |
2925 /* | |
2926 * If we're going to wait a bit, update the menus and mouse shape for the | |
2927 * current State. | |
2928 */ | |
2929 if (wtime != 0) | |
2930 gui_update_menus(0); | |
2931 #endif | |
2932 | |
2933 gui_mch_update(); | |
2934 if (input_available()) /* Got char, return immediately */ | |
2935 return OK; | |
2936 if (wtime == 0) /* Don't wait for char */ | |
2937 return FAIL; | |
2938 | |
2939 /* Before waiting, flush any output to the screen. */ | |
2940 gui_mch_flush(); | |
2941 | |
2942 if (wtime > 0) | |
2943 { | |
2944 /* Blink when waiting for a character. Probably only does something | |
2945 * for showmatch() */ | |
2946 gui_mch_start_blink(); | |
2947 retval = gui_wait_for_chars_or_timer(wtime); | |
2948 gui_mch_stop_blink(TRUE); | |
2949 return retval; | |
2950 } | |
2951 | |
2952 #if defined(ELAPSED_FUNC) | |
2953 ELAPSED_INIT(start_tv); | |
2954 #endif | |
2955 | |
2956 /* | |
2957 * While we are waiting indefinitely for a character, blink the cursor. | |
2958 */ | |
2959 gui_mch_start_blink(); | |
2960 | |
2961 retval = FAIL; | |
2962 /* | |
2963 * We may want to trigger the CursorHold event. First wait for | |
2964 * 'updatetime' and if nothing is typed within that time, and feedkeys() | |
2965 * wasn't used, put the K_CURSORHOLD key in the input buffer. | |
2966 */ | |
2967 if (gui_wait_for_chars_or_timer(p_ut) == OK) | |
2968 retval = OK; | |
2969 else if (trigger_cursorhold() | |
2970 #if defined(ELAPSED_FUNC) | |
2971 && ELAPSED_FUNC(start_tv) >= p_ut | |
2972 #endif | |
2973 && typebuf.tb_change_cnt == tb_change_cnt) | |
2974 { | |
2975 char_u buf[3]; | |
2976 | |
2977 /* Put K_CURSORHOLD in the input buffer. */ | |
2978 buf[0] = CSI; | |
2979 buf[1] = KS_EXTRA; | |
2980 buf[2] = (int)KE_CURSORHOLD; | |
2981 add_to_input_buf(buf, 3); | |
2982 | |
2983 retval = OK; | |
2984 } | |
2985 | |
2986 if (retval == FAIL && typebuf.tb_change_cnt == tb_change_cnt) | |
2987 { | |
2988 /* Blocking wait. */ | |
2989 before_blocking(); | |
2990 retval = gui_wait_for_chars_or_timer(-1L); | |
2991 } | |
2992 | |
2993 gui_mch_stop_blink(TRUE); | |
2994 return retval; | |
2995 } | 2977 } |
2996 | 2978 |
2997 /* | 2979 /* |
2998 * Equivalent of mch_inchar() for the GUI. | 2980 * Equivalent of mch_inchar() for the GUI. |
2999 */ | 2981 */ |
3002 char_u *buf, | 2984 char_u *buf, |
3003 int maxlen, | 2985 int maxlen, |
3004 long wtime, /* milli seconds */ | 2986 long wtime, /* milli seconds */ |
3005 int tb_change_cnt) | 2987 int tb_change_cnt) |
3006 { | 2988 { |
3007 if (gui_wait_for_chars(wtime, tb_change_cnt) | 2989 return gui_wait_for_chars_buf(buf, maxlen, wtime, tb_change_cnt); |
3008 && !typebuf_changed(tb_change_cnt)) | |
3009 return read_from_input_buf(buf, (long)maxlen); | |
3010 return 0; | |
3011 } | 2990 } |
3012 | 2991 |
3013 /* | 2992 /* |
3014 * Fill p[4] with mouse coordinates encoded for check_termcode(). | 2993 * Fill p[4] with mouse coordinates encoded for check_termcode(). |
3015 */ | 2994 */ |