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 */