]> granicus.if.org Git - vim/commitdiff
patch 8.2.3763: when editing the cmdline a callback may cause a scroll up v8.2.3763
authorBram Moolenaar <Bram@vim.org>
Thu, 9 Dec 2021 10:51:05 +0000 (10:51 +0000)
committerBram Moolenaar <Bram@vim.org>
Thu, 9 Dec 2021 10:51:05 +0000 (10:51 +0000)
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)

16 files changed:
src/beval.c
src/channel.c
src/drawscreen.c
src/ex_getln.c
src/job.c
src/popupwin.c
src/proto/drawscreen.pro
src/sound.c
src/terminal.c
src/testdir/dumps/Test_terminal_focus_1.dump
src/testdir/dumps/Test_terminal_focus_2.dump
src/testdir/dumps/Test_terminal_focus_3.dump [new file with mode: 0644]
src/testdir/test_terminal.vim
src/time.c
src/ui.c
src/version.c

index 8e0efb5e2b87db4a7a6dda26ab98c1989114d845..8b7570b57560e402d2df019ff8244c7e0bae1abd 100644 (file)
@@ -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;
index 634312412c7f9b6546861335a57a5e7c599e2584..05e248933bcb07e06d67fb2461637b021262182b 100644 (file)
@@ -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;
index f56ef91f290f5c4cfb4ae56a46c199aa16d34b61..106ae95ca5fed01c745e8b27bd0299a8ec83928b 100644 (file)
@@ -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().
index 2616afc42a67ed5816ccc79520d4203da4d3f589..bffdf657fa70dcd7cc0054c5a226a4f52943aff2 100644 (file)
@@ -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)
 {
index 6ee9f4432e817ef5cc4182e107988a9fbaf73292..7329851aac0a452336b37737766ec1ad9d8b9209 100644 (file)
--- 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;
 }
index 76418275bd9a27dc67333f7e3ca19fd04e592022..266e1134858805ef611c62b79403622d5270fa9f 100644 (file)
@@ -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;
index 528c8b21923ca844c2c1aaec9a33cddae225cb6b..c83501986b56648840806e8c6439ccaeb2974057 100644 (file)
@@ -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);
index e704aed691fd65d48b1598d25d9bd472daabc5a0..2f121eb470c1716a7f2708575d3e2d0867177679 100644 (file)
@@ -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;
index c3ce116443bccae5f2e8f10d548fbc964a0adf2f..7e2f45b4a03c6cc3b7d094d12ccd3d3a9f21d132 100644 (file)
@@ -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);
     }
 }
 
index 96fe303043676b4f28442d0f59fe4a51f1d6b14b..caf67e71afb2f1a48550e3d397903e505cb881ff 100644 (file)
@@ -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| 
index b4e8f4cd2bd2a0bd253443df5189e216be742248..d02c1515f36f9872f55dc46417192e2bdb5e6853 100644 (file)
@@ -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 (file)
index 0000000..8ece5a2
--- /dev/null
@@ -0,0 +1,6 @@
+|~+0#4040ff13#ffffff0| @73
+|~| @73
+|~| @73
+|~| @73
+|:+0#0000000&|x@73
+@6> @68
index 61b14586caa056b36feefc9810915ba3d92cff89..3efc6bbc50cb4f4576359ea7255b444fa0f9f4e9 100644 (file)
@@ -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
index ab12691980b0fbe1722a3bb8b35d705f1170925b..362fd46452e5c31b506e4c859bc4d95a27ed798d 100644 (file)
@@ -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)
index 906d88f299ebdd6d2a81b3670c4eef8a23f65bc0..8cbe49bde417545fe4e6a73ef7db9ed6aa41ebdd 100644 (file)
--- 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)
index a8f2b36a149e9b4e8e74391182a00a88535f4ec4..a14f9a770fc17e6862b0fb706d03536a5c37ab1a 100644 (file)
@@ -753,6 +753,8 @@ static char *(features[]) =
 
 static int included_patches[] =
 {   /* Add new patch number below this line */
+/**/
+    3763,
 /**/
     3762,
 /**/