1
0
forked from aniani/vim

patch 8.2.3763: when editing the cmdline a callback may cause a scroll up

Problem:    When editing the command line a FocusLost callback may cause the
            screen to scroll up.
Solution:   Do not redraw at the last line but at the same place where the
            command line was before. (closes #9295)
This commit is contained in:
Bram Moolenaar
2021-12-09 10:51:05 +00:00
parent 56150da687
commit e50507126f
16 changed files with 45 additions and 42 deletions

View File

@@ -308,7 +308,7 @@ general_beval_cb(BalloonEval *beval, int state UNUSED)
// The 'balloonexpr' evaluation may show something on the screen // The 'balloonexpr' evaluation may show something on the screen
// that requires a screen update. // that requires a screen update.
if (must_redraw) if (must_redraw)
redraw_after_callback(FALSE); redraw_after_callback(FALSE, FALSE);
recursive = FALSE; recursive = FALSE;
return; return;

View File

@@ -3205,7 +3205,7 @@ channel_close(channel_T *channel, int invoke_close_cb)
if (channel_need_redraw) if (channel_need_redraw)
{ {
channel_need_redraw = FALSE; channel_need_redraw = FALSE;
redraw_after_callback(TRUE); redraw_after_callback(TRUE, FALSE);
} }
if (!channel->ch_drop_never) if (!channel->ch_drop_never)
@@ -4687,7 +4687,7 @@ channel_parse_messages(void)
if (channel_need_redraw) if (channel_need_redraw)
{ {
channel_need_redraw = FALSE; channel_need_redraw = FALSE;
redraw_after_callback(TRUE); redraw_after_callback(TRUE, FALSE);
} }
--safe_to_invoke_callback; --safe_to_invoke_callback;

View File

@@ -3019,14 +3019,19 @@ redraw_asap(int type)
* it belongs. If highlighting was changed a redraw is needed. * it belongs. If highlighting was changed a redraw is needed.
* If "call_update_screen" is FALSE don't call update_screen() when at the * If "call_update_screen" is FALSE don't call update_screen() when at the
* command line. * command line.
* If "redraw_message" is TRUE.
*/ */
void void
redraw_after_callback(int call_update_screen) redraw_after_callback(int call_update_screen, int do_message)
{ {
++redrawing_for_callback; ++redrawing_for_callback;
if (State == HITRETURN || State == ASKMORE) if (State == HITRETURN || State == ASKMORE || State == SETWSIZE
; // do nothing || State == EXTERNCMD || State == CONFIRM || exmode_active)
{
if (do_message)
repeat_message();
}
else if (State & CMDLINE) else if (State & CMDLINE)
{ {
// Don't redraw when in prompt_for_number(). // Don't redraw when in prompt_for_number().

View File

@@ -3730,6 +3730,10 @@ redrawcmdline(void)
redrawcmdline_ex(TRUE); redrawcmdline_ex(TRUE);
} }
/*
* When "do_compute_cmdrow" is TRUE the command line is redrawn at the bottom.
* If FALSE cmdline_row is used, which should redraw in the same place.
*/
void void
redrawcmdline_ex(int do_compute_cmdrow) redrawcmdline_ex(int do_compute_cmdrow)
{ {

View File

@@ -1260,7 +1260,7 @@ job_check_ended(void)
if (channel_need_redraw) if (channel_need_redraw)
{ {
channel_need_redraw = FALSE; channel_need_redraw = FALSE;
redraw_after_callback(TRUE); redraw_after_callback(TRUE, FALSE);
} }
return did_end; return did_end;
} }

View File

@@ -3357,7 +3357,7 @@ popup_do_filter(int c)
// Reset got_int to avoid a function used in the statusline aborts. // Reset got_int to avoid a function used in the statusline aborts.
got_int = FALSE; got_int = FALSE;
redraw_after_callback(FALSE); redraw_after_callback(FALSE, FALSE);
got_int |= save_got_int; got_int |= save_got_int;
} }
recursive = FALSE; recursive = FALSE;

View File

@@ -8,7 +8,7 @@ void update_curbuf(int type);
void update_debug_sign(buf_T *buf, linenr_T lnum); void update_debug_sign(buf_T *buf, linenr_T lnum);
void updateWindow(win_T *wp); void updateWindow(win_T *wp);
int redraw_asap(int type); int redraw_asap(int type);
void redraw_after_callback(int call_update_screen); void redraw_after_callback(int call_update_screen, int do_message);
void redraw_later(int type); void redraw_later(int type);
void redraw_win_later(win_T *wp, int type); void redraw_win_later(win_T *wp, int type);
void redraw_later_clear(void); void redraw_later_clear(void);

View File

@@ -173,7 +173,7 @@ invoke_sound_callback(void)
delete_sound_callback(scb->scb_callback); delete_sound_callback(scb->scb_callback);
vim_free(scb); vim_free(scb);
} }
redraw_after_callback(TRUE); redraw_after_callback(TRUE, FALSE);
} }
static void static void
@@ -327,7 +327,7 @@ sound_wndproc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
clear_tv(&rettv); clear_tv(&rettv);
delete_sound_callback(p); delete_sound_callback(p);
redraw_after_callback(TRUE); redraw_after_callback(TRUE, FALSE);
} }
break; break;

View File

@@ -1258,7 +1258,7 @@ write_to_term(buf_T *buffer, char_u *msg, channel_T *channel)
update_cursor(curbuf->b_term, TRUE); update_cursor(curbuf->b_term, TRUE);
} }
else else
redraw_after_callback(TRUE); redraw_after_callback(TRUE, FALSE);
} }
} }

View File

@@ -1,6 +1,6 @@
> +0&#ffffff0@74 >I+0&#ffffff0| |a|m| |l|o|s|t| @65
|~+0#4040ff13&| @73 |~+0#4040ff13&| @73
|~| @73 |~| @73
|~| @73 |~| @73
|~| @73 |~| @73
|I+0#0000000&| |a|m| |l|o|s|t| @65 | +0#0000000&@56|0|,|0|-|1| @8|A|l@1|

View File

@@ -1,6 +1,6 @@
> +0&#ffffff0@74 >I+0&#ffffff0| |a|m| |b|a|c|k| @65
|~+0#4040ff13&| @73 |~+0#4040ff13&| @73
|~| @73 |~| @73
|~| @73 |~| @73
|~| @73 |~| @73
|I+0#0000000&| |a|m| |b|a|c|k| @65 | +0#0000000&@56|0|,|0|-|1| @8|A|l@1|

View File

@@ -0,0 +1,6 @@
|~+0#4040ff13#ffffff0| @73
|~| @73
|~| @73
|~| @73
|:+0#0000000&|x@73
@6> @68

View File

@@ -1135,8 +1135,8 @@ func Test_terminal_focus_events()
let lines =<< trim END let lines =<< trim END
set term=xterm ttymouse=xterm2 set term=xterm ttymouse=xterm2
au FocusLost * echo 'I am lost' au FocusLost * call setline(1, 'I am lost') | set nomod
au FocusGained * echo 'I am back' au FocusGained * call setline(1, 'I am back') | set nomod
" FIXME: sometimes this job hangs, exit after a couple of seconds " FIXME: sometimes this job hangs, exit after a couple of seconds
call timer_start(2000, {id -> execute('qall')}) call timer_start(2000, {id -> execute('qall')})
END END
@@ -1152,6 +1152,14 @@ func Test_terminal_focus_events()
call TermWait(buf) call TermWait(buf)
call VerifyScreenDump(buf, 'Test_terminal_focus_2', {}) call VerifyScreenDump(buf, 'Test_terminal_focus_2', {})
" check that a command line being edited is redrawn in place
call term_sendkeys(buf, ":" .. repeat('x', 80))
call TermWait(buf)
call feedkeys("\<Esc>[O", "Lx!")
call TermWait(buf)
call VerifyScreenDump(buf, 'Test_terminal_focus_3', {})
call term_sendkeys(buf, "\<Esc>")
call StopVimInTerminal(buf) call StopVimInTerminal(buf)
call delete('XtermFocus') call delete('XtermFocus')
let &term = save_term let &term = save_term

View File

@@ -595,7 +595,7 @@ check_due_timer(void)
} }
if (did_one) if (did_one)
redraw_after_callback(need_update_screen); redraw_after_callback(need_update_screen, FALSE);
#ifdef FEAT_BEVAL_TERM #ifdef FEAT_BEVAL_TERM
if (bevalexpr_due_set) if (bevalexpr_due_set)

View File

@@ -1156,29 +1156,7 @@ ui_focus_change(
: EVENT_FOCUSLOST, NULL, NULL, FALSE, curbuf); : EVENT_FOCUSLOST, NULL, NULL, FALSE, curbuf);
if (need_redraw) if (need_redraw)
{ redraw_after_callback(TRUE, TRUE);
// Something was executed, make sure the cursor is put back where it
// belongs.
need_wait_return = FALSE;
if (State & CMDLINE)
redrawcmdline();
else if (State == HITRETURN || State == SETWSIZE || State == ASKMORE
|| State == EXTERNCMD || State == CONFIRM || exmode_active)
repeat_message();
else if ((State & NORMAL) || (State & INSERT))
{
if (must_redraw != 0)
update_screen(0);
setcursor();
}
cursor_on(); // redrawing may have switched it off
out_flush_cursor(FALSE, TRUE);
# ifdef FEAT_GUI
if (gui.in_use)
gui_update_scrollbars(FALSE);
# endif
}
// File may have been changed from 'readonly' to 'noreadonly' // File may have been changed from 'readonly' to 'noreadonly'
if (need_maketitle) if (need_maketitle)

View File

@@ -753,6 +753,8 @@ static char *(features[]) =
static int included_patches[] = static int included_patches[] =
{ /* Add new patch number below this line */ { /* Add new patch number below this line */
/**/
3763,
/**/ /**/
3762, 3762,
/**/ /**/