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:
@@ -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;
|
||||||
|
@@ -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;
|
||||||
|
@@ -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().
|
||||||
|
@@ -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)
|
||||||
{
|
{
|
||||||
|
@@ -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;
|
||||||
}
|
}
|
||||||
|
@@ -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;
|
||||||
|
@@ -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);
|
||||||
|
@@ -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;
|
||||||
|
@@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -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|
|
||||||
|
@@ -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|
|
||||||
|
6
src/testdir/dumps/Test_terminal_focus_3.dump
Normal file
6
src/testdir/dumps/Test_terminal_focus_3.dump
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
|~+0#4040ff13#ffffff0| @73
|
||||||
|
|~| @73
|
||||||
|
|~| @73
|
||||||
|
|~| @73
|
||||||
|
|:+0#0000000&|x@73
|
||||||
|
@6> @68
|
@@ -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
|
||||||
|
@@ -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)
|
||||||
|
24
src/ui.c
24
src/ui.c
@@ -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)
|
||||||
|
@@ -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,
|
||||||
/**/
|
/**/
|
||||||
|
Reference in New Issue
Block a user