]> git.ipfire.org Git - thirdparty/vim.git/commitdiff
patch 9.2.0857: popup: opacity popup over a terminal is not cleared when closed v9.2.0857
authormityu <mityu.mail@gmail.com>
Sun, 26 Jul 2026 14:40:46 +0000 (14:40 +0000)
committerChristian Brabandt <cb@256bit.org>
Sun, 26 Jul 2026 14:40:46 +0000 (14:40 +0000)
Problem:  A semi-transparent (opacity) popup shown over a terminal window
          leaves its old cells on screen when it is closed.
Solution: When a semi-transparent popup is closed, trigger full redraw
          of underlying terminal windows.

fixes:  #20846
closes: #20848

Signed-off-by: mityu <mityu.mail@gmail.com>
Signed-off-by: Christian Brabandt <cb@256bit.org>
src/popupwin.c
src/testdir/dumps/Test_popupwin_opacity_term_close_1.dump [new file with mode: 0644]
src/testdir/dumps/Test_popupwin_opacity_term_close_2.dump [new file with mode: 0644]
src/testdir/test_popupwin.vim
src/version.c

index bbbfa300c68cee07a068ddb08fec405bd1fd9d05..7ef2d766a447d50bee5c71e9489d32985a023fd9 100644 (file)
@@ -117,6 +117,7 @@ static void redraw_under_popup_area(int winrow, int wincol, int height,
        int width, int leftoff);
 static void redraw_overlapped_opacity_popups(int winrow, int wincol,
        int height, int width, int leftoff, int zindex);
+static void redraw_win_under_opacity_popup(win_T *wp);
 #ifdef FEAT_IMAGE_KITTY
 static void popup_image_clear_kitty(win_T *wp);
 #endif
@@ -4641,6 +4642,11 @@ popup_close(int id, int force)
                first_popupwin = wp->w_next;
            else
                prev->w_next = wp->w_next;
+#ifdef FEAT_TERMINAL
+           // If the popup to be closed is opaque, terminal windows under
+           // the popup should trigger a force repaint of their windows.
+           redraw_win_under_opacity_popup(wp);
+#endif
            popup_free(wp);
            return OK;
        }
@@ -4684,6 +4690,11 @@ popup_close_tabpage(tabpage_T *tp, int id, int force)
                *root = wp->w_next;
            else
                prev->w_next = wp->w_next;
+#ifdef FEAT_TERMINAL
+           // If the popup to be closed is opaque, terminal windows under
+           // the popup should trigger a force repaint of their windows.
+           redraw_win_under_opacity_popup(wp);
+#endif
            popup_free(wp);
            return OK;
        }
diff --git a/src/testdir/dumps/Test_popupwin_opacity_term_close_1.dump b/src/testdir/dumps/Test_popupwin_opacity_term_close_1.dump
new file mode 100644 (file)
index 0000000..46714d0
--- /dev/null
@@ -0,0 +1,12 @@
+|v+0&#ffffff0|i|m|>| > @69
+@75
+@75
+@75
+@9|A+0#0000001#ffffff255|B|C| +0#0000000#ffffff0@62
+@75
+@75
+@75
+@75
+@75
+@75
+@75
diff --git a/src/testdir/dumps/Test_popupwin_opacity_term_close_2.dump b/src/testdir/dumps/Test_popupwin_opacity_term_close_2.dump
new file mode 100644 (file)
index 0000000..cba005d
--- /dev/null
@@ -0,0 +1,12 @@
+|v+0&#ffffff0|i|m|>| > @69
+@75
+@75
+@75
+@75
+@75
+@75
+@75
+@75
+@75
+@75
+|:|c|a|l@1| |C|l|o|s|e|I|t|(|)| @59
index 6aed7be3ecc097dca68318d4f1e73289a5eb79c1..a08d50ebe5b7d1149cdc2dd8deca3d4a009d4078 100644 (file)
@@ -5383,6 +5383,50 @@ func Test_popup_opacity_terminal_move_no_leftover()
   exe buf .. 'bwipe!'
 endfunc
 
+func s:do_test_popup_opacity_terminal_close_no_leftover(tabpage)
+  CheckScreendump
+  CheckFeature terminal
+  CheckUnix
+
+  " A semi-transparent popup over a terminal used to leave the old popup
+  " cells behind when it closed.
+  let lines =<< trim END
+    set shell=/bin/sh noruler
+    unlet $PROMPT_COMMAND
+    let $PS1 = 'vim> '
+    terminal ++curwin
+    call popup_create('ABC',
+        \ #{line: 5, col: 10, highlight: 'None', opacity: 30})
+    func CloseIt()
+      let id = popup_list()[0]
+      call popup_close(id)
+    endfunc
+  END
+  call writefile(lines, 'XtestPopupOpacityTermClose', 'D')
+  let buf = RunVimInTerminal('-S XtestPopupOpacityTermClose',
+       \ #{rows: 12, wait_for_ruler: 0})
+  call WaitForAssert({-> assert_match('ABC', term_getline(buf, 5))})
+  call VerifyScreenDump(buf, 'Test_popupwin_opacity_term_close_1', {})
+
+  " Close the popup: the old "ABC" cells must be cleared.
+  call term_sendkeys(buf, "\<C-W>:call CloseIt()\<CR>")
+  call WaitForAssert({-> assert_equal('', term_getline(buf, 5)->trim())})
+  call VerifyScreenDump(buf, 'Test_popupwin_opacity_term_close_2', {})
+
+  " clean up
+  call term_sendkeys(buf, "\<C-W>:qa!\<CR>")
+  call WaitForAssert({-> assert_equal("finished", term_getstatus(buf))})
+  exe buf .. 'bwipe!'
+endfunc
+
+function Test_popup_opacity_global_terminal_close_no_leftover()
+  call s:do_test_popup_opacity_terminal_close_no_leftover(-1)
+endfunction
+
+function Test_popup_opacity_tablocal_terminal_close_no_leftover()
+  call s:do_test_popup_opacity_terminal_close_no_leftover(0)
+endfunction
+
 func Test_popup_opacity_terminal_no_freeze()
   CheckFeature terminal
   CheckUnix
index b289c6800e798ce0960f25449516d6bcf336bd6a..ba72d4ad8bb55535375a80736f52dec60ad7e2e5 100644 (file)
@@ -758,6 +758,8 @@ static char *(features[]) =
 
 static int included_patches[] =
 {   /* Add new patch number below this line */
+/**/
+    857,
 /**/
     856,
 /**/