summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBram Moolenaar <Bram@vim.org>2021-12-09 10:51:05 +0000
committerBram Moolenaar <Bram@vim.org>2021-12-09 10:51:05 +0000
commite50507126f532a0b0ae65e201a6372b7ea5b0ccd (patch)
tree91e6c7e0409133dfd761059f03055320e3659cdc
parent56150da6879a96db1c84c7ec4ceedeb84969f606 (diff)
patch 8.2.3763: when editing the cmdline a callback may cause a scroll upv8.2.3763
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)
-rw-r--r--src/beval.c2
-rw-r--r--src/channel.c4
-rw-r--r--src/drawscreen.c11
-rw-r--r--src/ex_getln.c4
-rw-r--r--src/job.c2
-rw-r--r--src/popupwin.c2
-rw-r--r--src/proto/drawscreen.pro2
-rw-r--r--src/sound.c4
-rw-r--r--src/terminal.c2
-rw-r--r--src/testdir/dumps/Test_terminal_focus_1.dump4
-rw-r--r--src/testdir/dumps/Test_terminal_focus_2.dump4
-rw-r--r--src/testdir/dumps/Test_terminal_focus_3.dump6
-rw-r--r--src/testdir/test_terminal.vim12
-rw-r--r--src/time.c2
-rw-r--r--src/ui.c24
-rw-r--r--src/version.c2
16 files changed, 45 insertions, 42 deletions
diff --git a/src/beval.c b/src/beval.c
index 8e0efb5e2b..8b7570b575 100644
--- a/src/beval.c
+++ b/src/beval.c
@@ -308,7 +308,7 @@ general_beval_cb(BalloonEval *beval, int state UNUSED)
// The 'balloonexpr' evaluation may show something on the screen
// that requires a screen update.
if (must_redraw)
- redraw_after_callback(FALSE);
+ redraw_after_callback(FALSE, FALSE);
recursive = FALSE;
return;
diff --git a/src/channel.c b/src/channel.c
index 634312412c..05e248933b 100644
--- a/src/channel.c
+++ b/src/channel.c
@@ -3205,7 +3205,7 @@ channel_close(channel_T *channel, int invoke_close_cb)
if (channel_need_redraw)
{
channel_need_redraw = FALSE;
- redraw_after_callback(TRUE);
+ redraw_after_callback(TRUE, FALSE);
}
if (!channel->ch_drop_never)
@@ -4687,7 +4687,7 @@ channel_parse_messages(void)
if (channel_need_redraw)
{
channel_need_redraw = FALSE;
- redraw_after_callback(TRUE);
+ redraw_after_callback(TRUE, FALSE);
}
--safe_to_invoke_callback;
diff --git a/src/drawscreen.c b/src/drawscreen.c
index f56ef91f29..106ae95ca5 100644
--- a/src/drawscreen.c
+++ b/src/drawscreen.c
@@ -3019,14 +3019,19 @@ redraw_asap(int type)
* it belongs. If highlighting was changed a redraw is needed.
* If "call_update_screen" is FALSE don't call update_screen() when at the
* command line.
+ * If "redraw_message" is TRUE.
*/
void
-redraw_after_callback(int call_update_screen)
+redraw_after_callback(int call_update_screen, int do_message)
{
++redrawing_for_callback;
- if (State == HITRETURN || State == ASKMORE)
- ; // do nothing
+ if (State == HITRETURN || State == ASKMORE || State == SETWSIZE
+ || State == EXTERNCMD || State == CONFIRM || exmode_active)
+ {
+ if (do_message)
+ repeat_message();
+ }
else if (State & CMDLINE)
{
// Don't redraw when in prompt_for_number().
diff --git a/src/ex_getln.c b/src/ex_getln.c
index 2616afc42a..bffdf657fa 100644
--- a/src/ex_getln.c
+++ b/src/ex_getln.c
@@ -3730,6 +3730,10 @@ redrawcmdline(void)
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
redrawcmdline_ex(int do_compute_cmdrow)
{
diff --git a/src/job.c b/src/job.c
index 6ee9f4432e..7329851aac 100644
--- a/src/job.c
+++ b/src/job.c
@@ -1260,7 +1260,7 @@ job_check_ended(void)
if (channel_need_redraw)
{
channel_need_redraw = FALSE;
- redraw_after_callback(TRUE);
+ redraw_after_callback(TRUE, FALSE);
}
return did_end;
}
diff --git a/src/popupwin.c b/src/popupwin.c
index 76418275bd..266e113485 100644
--- a/src/popupwin.c
+++ b/src/popupwin.c
@@ -3357,7 +3357,7 @@ popup_do_filter(int c)
// Reset got_int to avoid a function used in the statusline aborts.
got_int = FALSE;
- redraw_after_callback(FALSE);
+ redraw_after_callback(FALSE, FALSE);
got_int |= save_got_int;
}
recursive = FALSE;
diff --git a/src/proto/drawscreen.pro b/src/proto/drawscreen.pro
index 528c8b2192..c83501986b 100644
--- a/src/proto/drawscreen.pro
+++ b/src/proto/drawscreen.pro
@@ -8,7 +8,7 @@ void update_curbuf(int type);
void update_debug_sign(buf_T *buf, linenr_T lnum);
void updateWindow(win_T *wp);
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_win_later(win_T *wp, int type);
void redraw_later_clear(void);
diff --git a/src/sound.c b/src/sound.c
index e704aed691..2f121eb470 100644
--- a/src/sound.c
+++ b/src/sound.c
@@ -173,7 +173,7 @@ invoke_sound_callback(void)
delete_sound_callback(scb->scb_callback);
vim_free(scb);
}
- redraw_after_callback(TRUE);
+ redraw_after_callback(TRUE, FALSE);
}
static void
@@ -327,7 +327,7 @@ sound_wndproc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
clear_tv(&rettv);
delete_sound_callback(p);
- redraw_after_callback(TRUE);
+ redraw_after_callback(TRUE, FALSE);
}
break;
diff --git a/src/terminal.c b/src/terminal.c
index c3ce116443..7e2f45b4a0 100644
--- a/src/terminal.c
+++ b/src/terminal.c
@@ -1258,7 +1258,7 @@ write_to_term(buf_T *buffer, char_u *msg, channel_T *channel)
update_cursor(curbuf->b_term, TRUE);
}
else
- redraw_after_callback(TRUE);
+ redraw_after_callback(TRUE, FALSE);
}
}
diff --git a/src/testdir/dumps/Test_terminal_focus_1.dump b/src/testdir/dumps/Test_terminal_focus_1.dump
index 96fe303043..caf67e71af 100644
--- a/src/testdir/dumps/Test_terminal_focus_1.dump
+++ b/src/testdir/dumps/Test_terminal_focus_1.dump
@@ -1,6 +1,6 @@
-> +0&#ffffff0@74
+>I+0&#ffffff0| |a|m| |l|o|s|t| @65
|~+0#4040ff13&| @73
|~| @73
|~| @73
|~| @73
-|I+0#0000000&| |a|m| |l|o|s|t| @65
+| +0#0000000&@56|0|,|0|-|1| @8|A|l@1|
diff --git a/src/testdir/dumps/Test_terminal_focus_2.dump b/src/testdir/dumps/Test_terminal_focus_2.dump
index b4e8f4cd2b..d02c1515f3 100644
--- a/src/testdir/dumps/Test_terminal_focus_2.dump
+++ b/src/testdir/dumps/Test_terminal_focus_2.dump
@@ -1,6 +1,6 @@
-> +0&#ffffff0@74
+>I+0&#ffffff0| |a|m| |b|a|c|k| @65
|~+0#4040ff13&| @73
|~| @73
|~| @73
|~| @73
-|I+0#0000000&| |a|m| |b|a|c|k| @65
+| +0#0000000&@56|0|,|0|-|1| @8|A|l@1|
diff --git a/src/testdir/dumps/Test_terminal_focus_3.dump b/src/testdir/dumps/Test_terminal_focus_3.dump
new file mode 100644
index 0000000000..8ece5a2cf3
--- /dev/null
+++ b/src/testdir/dumps/Test_terminal_focus_3.dump
@@ -0,0 +1,6 @@
+|~+0#4040ff13#ffffff0| @73
+|~| @73
+|~| @73
+|~| @73
+|:+0#0000000&|x@73
+@6> @68
diff --git a/src/testdir/test_terminal.vim b/src/testdir/test_terminal.vim
index 61b14586ca..3efc6bbc50 100644
--- a/src/testdir/test_terminal.vim
+++ b/src/testdir/test_terminal.vim
@@ -1135,8 +1135,8 @@ func Test_terminal_focus_events()
let lines =<< trim END
set term=xterm ttymouse=xterm2
- au FocusLost * echo 'I am lost'
- au FocusGained * echo 'I am back'
+ au FocusLost * call setline(1, 'I am lost') | set nomod
+ au FocusGained * call setline(1, 'I am back') | set nomod
" FIXME: sometimes this job hangs, exit after a couple of seconds
call timer_start(2000, {id -> execute('qall')})
END
@@ -1152,6 +1152,14 @@ func Test_terminal_focus_events()
call TermWait(buf)
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 delete('XtermFocus')
let &term = save_term
diff --git a/src/time.c b/src/time.c
index ab12691980..362fd46452 100644
--- a/src/time.c
+++ b/src/time.c
@@ -595,7 +595,7 @@ check_due_timer(void)
}
if (did_one)
- redraw_after_callback(need_update_screen);
+ redraw_after_callback(need_update_screen, FALSE);
#ifdef FEAT_BEVAL_TERM
if (bevalexpr_due_set)
diff --git a/src/ui.c b/src/ui.c
index 906d88f299..8cbe49bde4 100644
--- a/src/ui.c
+++ b/src/ui.c
@@ -1156,29 +1156,7 @@ ui_focus_change(
: EVENT_FOCUSLOST, NULL, NULL, FALSE, curbuf);
if (need_redraw)
- {
- // 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
- }
+ redraw_after_callback(TRUE, TRUE);
// File may have been changed from 'readonly' to 'noreadonly'
if (need_maketitle)
diff --git a/src/version.c b/src/version.c
index a8f2b36a14..a14f9a770f 100644
--- a/src/version.c
+++ b/src/version.c
@@ -754,6 +754,8 @@ static char *(features[]) =
static int included_patches[] =
{ /* Add new patch number below this line */
/**/
+ 3763,
+/**/
3762,
/**/
3761,