patch 9.2.0599: popup: title set with popup_setoptions() is not shown

Commit: 
https://github.com/vim/vim/commit/949caf9e914d94309026f4899e0aaaf9e341a0d2
Author: Hirohito Higashi <[email protected]>
Date:   Fri Jun 5 11:51:39 2026 +0000

    patch 9.2.0599: popup: title set with popup_setoptions() is not shown
    
    Problem:  When only the title is changed with popup_setoptions(), the
              popup is not redrawn until another event happens, so the new
              title does not appear right away.
    Solution: Redraw the popup when the title changes.  Also allocate the new
              title and border highlights before freeing the old ones, so the
              current value is not lost on allocation failure.
    
    fixes:  #20426
    closes: #20430
    
    Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
    Signed-off-by: Hirohito Higashi <[email protected]>
    Signed-off-by: Christian Brabandt <[email protected]>

diff --git a/src/popupwin.c b/src/popupwin.c
index 87ea44de5..cae19b908 100644
--- a/src/popupwin.c
+++ b/src/popupwin.c
@@ -55,6 +55,7 @@ typedef struct {
     int                blend;
     int                flags;
     int                zindex;
+    char_u     *title;
     char_u     *scrollbar_highlight;
     char_u     *thumb_highlight;
     char_u     *border_highlight[4];
@@ -808,8 +809,13 @@ apply_general_options(win_T *wp, dict_T *dict)
     str = dict_get_string(dict, "title", FALSE);
     if (str != NULL)
     {
-       vim_free(wp->w_popup_title);
-       wp->w_popup_title = vim_strsave(str);
+       char_u  *title = vim_strsave(str);
+
+       if (title != NULL)
+       {
+           vim_free(wp->w_popup_title);
+           wp->w_popup_title = title;
+       }
     }
 
     nr = dict_get_bool(dict, "wrap", -1);
@@ -975,16 +981,25 @@ apply_general_options(win_T *wp, dict_T *dict)
                    str = tv_get_string(&li->li_tv);
                    if (*str != NUL)
                    {
-                       vim_free(wp->w_border_highlight[i]);
-                       wp->w_border_highlight[i] = vim_strsave(str);
+                       char_u  *hl = vim_strsave(str);
+
+                       if (hl != NULL)
+                       {
+                           vim_free(wp->w_border_highlight[i]);
+                           wp->w_border_highlight[i] = hl;
+                       }
                    }
                }
                if (list->lv_len == 1 && wp->w_border_highlight[0] != NULL)
                    for (i = 1; i < 4; ++i)
                    {
-                       vim_free(wp->w_border_highlight[i]);
-                       wp->w_border_highlight[i] =
-                                       vim_strsave(wp->w_border_highlight[0]);
+                       char_u  *hl = vim_strsave(wp->w_border_highlight[0]);
+
+                       if (hl != NULL)
+                       {
+                           vim_free(wp->w_border_highlight[i]);
+                           wp->w_border_highlight[i] = hl;
+                       }
                    }
            }
        }
@@ -4007,6 +4022,7 @@ popup_save_style(win_T *wp, popup_style_snapshot_T *style)
     style->blend = wp->w_popup_blend;
     style->flags = wp->w_popup_flags;
     style->zindex = wp->w_zindex;
+    style->title = wp->w_popup_title;
     style->scrollbar_highlight = wp->w_scrollbar_highlight;
     style->thumb_highlight = wp->w_thumb_highlight;
     for (i = 0; i < 4; i++)
@@ -4023,6 +4039,7 @@ popup_style_changed(win_T *wp, popup_style_snapshot_T 
*style)
 
     if (style->firstline != wp->w_firstline
            || style->flags != wp->w_popup_flags
+           || style->title != wp->w_popup_title
            || style->scrollbar_highlight != wp->w_scrollbar_highlight
            || style->thumb_highlight != wp->w_thumb_highlight)
        return true;
diff --git a/src/testdir/dumps/Test_popupwin_setoptions_title_1.dump 
b/src/testdir/dumps/Test_popupwin_setoptions_title_1.dump
new file mode 100644
index 000000000..67e2e6c4f
--- /dev/null
+++ b/src/testdir/dumps/Test_popupwin_setoptions_title_1.dump
@@ -0,0 +1,10 @@
+> +0&#ffffff0@74
+|~+0#4040ff13&| @73
+|~| @73
+|~| @31|╔+0#0000001#ffd7ff255|t|i|t|l|e|-|1|╗| +0#4040ff13#ffffff0@32
+|~| @31|║+0#0000001#ffd7ff255|h|e|l@1|o| @1|║| +0#4040ff13#ffffff0@32
+|~| @31|╚+0#0000001#ffd7ff255|═@6|╝| +0#4040ff13#ffffff0@32
+|~| @73
+|~| @73
+|~| @73
+| +0#0000000&@56|0|,|0|-|1| @8|A|l@1| 
diff --git a/src/testdir/dumps/Test_popupwin_setoptions_title_2.dump 
b/src/testdir/dumps/Test_popupwin_setoptions_title_2.dump
new file mode 100644
index 000000000..939ea7a29
--- /dev/null
+++ b/src/testdir/dumps/Test_popupwin_setoptions_title_2.dump
@@ -0,0 +1,10 @@
+> +0&#ffffff0@74
+|~+0#4040ff13&| @73
+|~| @73
+|~| @31|╔+0#0000001#ffd7ff255|t|i|t|l|e|-|2|╗| +0#4040ff13#ffffff0@32
+|~| @31|║+0#0000001#ffd7ff255|h|e|l@1|o| @1|║| +0#4040ff13#ffffff0@32
+|~| @31|╚+0#0000001#ffd7ff255|═@6|╝| +0#4040ff13#ffffff0@32
+|~| @73
+|~| @73
+|~| @73
+|:+0#0000000&|c|a|l@1| |p|o|p|u|p|_|s|e|t|o|p|t|i|o|n|s|(|g|:|i|d|,| 
|#|{|t|i|t|l|e|:| |'|t|i|t|l|e|-|2|'|}|)| @7|0|,|0|-|1| @8|A|l@1| 
diff --git a/src/testdir/test_popupwin.vim b/src/testdir/test_popupwin.vim
index 11e431246..077c08f61 100644
--- a/src/testdir/test_popupwin.vim
+++ b/src/testdir/test_popupwin.vim
@@ -1753,6 +1753,27 @@ func Test_popup_set_firstline()
   call StopVimInTerminal(buf)
 endfunc
 
+func Test_popup_setoptions_title_redraw()
+  CheckScreendump
+
+  " Changing the title with popup_setoptions() must redraw the popup right
+  " away, without waiting for a later event such as a cursor movement.
+  let lines =<< trim END
+      let g:id = popup_create('hello', #{title: 'title-1', border: []})
+      redraw
+  END
+  call writefile(lines, 'XtestPopupTitleRedraw', 'D')
+  let buf = RunVimInTerminal('-S XtestPopupTitleRedraw', #{rows: 10})
+
+  call VerifyScreenDump(buf, 'Test_popupwin_setoptions_title_1', {})
+
+  " No other event happens between popup_setoptions() and the dump.
+  call term_sendkeys(buf, ":call popup_setoptions(g:id, #{title: 
'title-2'})\<CR>")
+  call VerifyScreenDump(buf, 'Test_popupwin_setoptions_title_2', {})
+
+  call StopVimInTerminal(buf)
+endfunc
+
 " this tests that we don't get stuck with an error in "win_execute()"
 func Test_popup_filter_win_execute_error()
   CheckScreendump
diff --git a/src/version.c b/src/version.c
index 25903a8ed..669a5cf03 100644
--- a/src/version.c
+++ b/src/version.c
@@ -729,6 +729,8 @@ static char *(features[]) =
 
 static int included_patches[] =
 {   /* Add new patch number below this line */
+/**/
+    599,
 /**/
     598,
 /**/

-- 
-- 
You received this message from the "vim_dev" maillist.
Do not top-post! Type your reply below the text you are replying to.
For more information, visit http://www.vim.org/maillist.php

--- 
You received this message because you are subscribed to the Google Groups 
"vim_dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To view this discussion visit 
https://groups.google.com/d/msgid/vim_dev/E1wVYbR-0079YW-Kq%40256bit.org.

Raspunde prin e-mail lui