]> git.ipfire.org Git - thirdparty/vim.git/commitdiff
patch 9.2.0599: popup: title set with popup_setoptions() is not shown v9.2.0599
authorHirohito Higashi <h.east.727@gmail.com>
Fri, 5 Jun 2026 11:51:39 +0000 (11:51 +0000)
committerChristian Brabandt <cb@256bit.org>
Fri, 5 Jun 2026 11:51:39 +0000 (11:51 +0000)
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) <noreply@anthropic.com>
Signed-off-by: Hirohito Higashi <h.east.727@gmail.com>
Signed-off-by: Christian Brabandt <cb@256bit.org>
src/popupwin.c
src/testdir/dumps/Test_popupwin_setoptions_title_1.dump [new file with mode: 0644]
src/testdir/dumps/Test_popupwin_setoptions_title_2.dump [new file with mode: 0644]
src/testdir/test_popupwin.vim
src/version.c

index 87ea44de501a30fd2fd10f428fff4f8682738cb3..cae19b908d9fdf2b5ddfffa1c66944a92ec43c58 100644 (file)
@@ -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 (file)
index 0000000..67e2e6c
--- /dev/null
@@ -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 (file)
index 0000000..939ea7a
--- /dev/null
@@ -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| 
index 11e431246a0b83620feac59636517ebf90b229dc..077c08f618e4c6a298946757483a6d4869ec258b 100644 (file)
@@ -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
index 25903a8edef264a2488df634061f9cd69abd25b7..669a5cf0334829abef503a4a8f7a8fedd9583b91 100644 (file)
@@ -729,6 +729,8 @@ static char *(features[]) =
 
 static int included_patches[] =
 {   /* Add new patch number below this line */
+/**/
+    599,
 /**/
     598,
 /**/