]> git.ipfire.org Git - thirdparty/vim.git/commitdiff
patch 9.2.0332: popup: still opacity rendering issues master v9.2.0332
authorYasuhiro Matsumoto <mattn.jp@gmail.com>
Fri, 10 Apr 2026 17:43:59 +0000 (17:43 +0000)
committerChristian Brabandt <cb@256bit.org>
Fri, 10 Apr 2026 17:43:59 +0000 (17:43 +0000)
Problem:  popup: still opacity rendering issues
Solution: Fix remaining issues, see below
          (Yasuhiro Matsumoto).

This PR fixes the following issues:

- Padding blend hole at wide char boundary: when a padding cell overlaps
  the second half of a wide character, the right half's attr value is
  unreliable. Use the left half's saved attr for blending instead.

- Wide char background split at popup boundary: when a wide character in
  an upper popup straddles the edge of a lower opacity popup, both
  halves got different background colors. Since terminals cannot render
  different left/right background colors for a wide character, detect
  the lower popup with popup_is_over_opacity() and use the non-popup
  side's underlying attr for both halves.

- Wrong blend color with cterm-only highlights under 'termguicolors':
  when a popup highlight has ctermbg but no guibg, bg_rgb is set to
  CTERMCOLOR (not INVALCOLOR). hl_blend_attr() used this value as a real
  RGB color, producing gray instead of the intended color. Use
  COLOR_INVALID() to detect both INVALCOLOR and CTERMCOLOR, and fall back
  to converting the cterm color number to RGB.

closes: #19943

Signed-off-by: Yasuhiro Matsumoto <mattn.jp@gmail.com>
Signed-off-by: Christian Brabandt <cb@256bit.org>
src/highlight.c
src/popupwin.c
src/proto/popupwin.pro
src/screen.c
src/testdir/dumps/Test_popupwin_opacity_wide_1.dump
src/testdir/dumps/Test_popupwin_opacity_wide_2.dump
src/testdir/test_popupwin.vim
src/version.c

index cf5921f4bc600dcdc88719ccf2459fe55ab08b85..73b39e98b2a2810e4f2ba51d27b68ff8aa7582dc 100644 (file)
@@ -3125,6 +3125,32 @@ hl_combine_attr(int char_attr, int prim_attr)
 }
 
 #if defined(FEAT_GUI) || defined(FEAT_TERMGUICOLORS)
+
+# ifdef FEAT_TERMGUICOLORS
+/*
+ * Convert a cterm color number (1-16) to an RGB value.
+ * Used as a fallback when 'termguicolors' is set but only cterm colors are
+ * specified (no guifg/guibg).
+ * Returns INVALCOLOR if the color number is out of range.
+ */
+    static guicolor_T
+cterm_color_to_rgb(int color_nr)
+{
+    // ANSI color order: Black, Red, Green, Yellow, Blue, Magenta,
+    // Cyan, White, then bright variants.
+    static const guicolor_T cterm_color_16[16] = {
+       0x000000, 0xc00000, 0x008000, 0x808000,
+       0x0000c0, 0xc000c0, 0x004080, 0xc0c0c0,
+       0x808080, 0xff8080, 0x00ff00, 0xffff00,
+       0x6060ff, 0xff40ff, 0x00ffff, 0xffffff
+    };
+
+    if (color_nr < 1 || color_nr > 16)
+       return INVALCOLOR;
+    return cterm_color_16[color_nr - 1];
+}
+# endif
+
 /*
  * Blend two RGB colors based on blend value (0-100).
  * blend: 0=use popup color, 100=use background color
@@ -3273,32 +3299,47 @@ hl_blend_attr(int char_attr, int popup_attr, int blend, int blend_fg UNUSED)
                if (popup_aep->ae_u.cterm.bg_color > 0)
                    new_en.ae_u.cterm.bg_color = popup_aep->ae_u.cterm.bg_color;
 #ifdef FEAT_TERMGUICOLORS
-               // Blend RGB colors for termguicolors mode
-               if (blend_fg)
+               // Blend RGB colors for termguicolors mode.
+               // Fall back to cterm color converted to RGB when
+               // gui color is not set.
                {
-                   // blend_fg=TRUE: fade underlying text toward popup bg.
-                   if (popup_aep->ae_u.cterm.bg_rgb != INVALCOLOR)
+                   guicolor_T popup_bg = popup_aep->ae_u.cterm.bg_rgb;
+                   guicolor_T popup_fg = popup_aep->ae_u.cterm.fg_rgb;
+
+                   if (COLOR_INVALID(popup_bg)
+                                   && popup_aep->ae_u.cterm.bg_color > 0)
+                       popup_bg = cterm_color_to_rgb(
+                                       popup_aep->ae_u.cterm.bg_color);
+                   if (COLOR_INVALID(popup_fg)
+                                   && popup_aep->ae_u.cterm.fg_color > 0)
+                       popup_fg = cterm_color_to_rgb(
+                                       popup_aep->ae_u.cterm.fg_color);
+
+                   if (blend_fg)
                    {
-                       int base_fg = 0xFFFFFF;
-                       if (char_aep != NULL
-                               && char_aep->ae_u.cterm.fg_rgb != INVALCOLOR)
-                           base_fg = char_aep->ae_u.cterm.fg_rgb;
-                       new_en.ae_u.cterm.fg_rgb = blend_colors(
-                               base_fg, popup_aep->ae_u.cterm.bg_rgb, blend);
+                       // blend_fg=TRUE: fade underlying text toward popup bg.
+                       if (popup_bg != INVALCOLOR)
+                       {
+                           int base_fg = 0xFFFFFF;
+                           if (char_aep != NULL
+                                   && char_aep->ae_u.cterm.fg_rgb != INVALCOLOR)
+                               base_fg = char_aep->ae_u.cterm.fg_rgb;
+                           new_en.ae_u.cterm.fg_rgb = blend_colors(
+                                   base_fg, popup_bg, blend);
+                       }
+                   }
+                   else if (popup_fg != INVALCOLOR)
+                       // blend_fg=FALSE: use popup foreground
+                       new_en.ae_u.cterm.fg_rgb = popup_fg;
+                   if (popup_bg != INVALCOLOR)
+                   {
+                       // Blend popup bg toward underlying bg
+                       guicolor_T underlying_bg = INVALCOLOR;
+                       if (char_aep != NULL)
+                           underlying_bg = char_aep->ae_u.cterm.bg_rgb;
+                       new_en.ae_u.cterm.bg_rgb = blend_colors(
+                               popup_bg, underlying_bg, blend);
                    }
-               }
-               else if (popup_aep->ae_u.cterm.fg_rgb != INVALCOLOR)
-                   // blend_fg=FALSE: use popup foreground
-                   new_en.ae_u.cterm.fg_rgb = popup_aep->ae_u.cterm.fg_rgb;
-               if (popup_aep->ae_u.cterm.bg_rgb != INVALCOLOR)
-               {
-                   // Blend popup bg toward underlying bg
-                   guicolor_T underlying_bg = INVALCOLOR;
-                   if (char_aep != NULL)
-                       underlying_bg = char_aep->ae_u.cterm.bg_rgb;
-                   new_en.ae_u.cterm.bg_rgb = blend_colors(
-                           popup_aep->ae_u.cterm.bg_rgb,
-                           underlying_bg, blend);
                }
 #endif
            }
index d5fdbb8d26604ffd4a0931bb88e5d1c2b37a9dc0..bdf53cdc4fc8ead8e0bd2c361d9d1b5467ec2b2b 100644 (file)
@@ -4438,6 +4438,37 @@ popup_is_under_opacity(int row, int col)
     return opacity_zindex[row * opacity_zindex_cols + col] > screen_zindex;
 }
 
+/*
+ * Return TRUE if cell (row, col) is covered by a lower-zindex opacity popup.
+ */
+    int
+popup_is_over_opacity(int row, int col)
+{
+    win_T *wp;
+
+    FOR_ALL_POPUPWINS(wp)
+       if ((wp->w_popup_flags & POPF_OPACITY)
+               && wp->w_popup_blend > 0
+               && !(wp->w_popup_flags & POPF_HIDDEN)
+               && wp->w_zindex < screen_zindex
+               && row >= wp->w_winrow
+               && row < wp->w_winrow + popup_height(wp)
+               && col >= wp->w_wincol
+               && col < wp->w_wincol + popup_width(wp))
+           return TRUE;
+    FOR_ALL_POPUPWINS_IN_TAB(curtab, wp)
+       if ((wp->w_popup_flags & POPF_OPACITY)
+               && wp->w_popup_blend > 0
+               && !(wp->w_popup_flags & POPF_HIDDEN)
+               && wp->w_zindex < screen_zindex
+               && row >= wp->w_winrow
+               && row < wp->w_winrow + popup_height(wp)
+               && col >= wp->w_wincol
+               && col < wp->w_wincol + popup_width(wp))
+           return TRUE;
+    return FALSE;
+}
+
 /*
  * Return TRUE if any cell in row "row" from "start_col" to "end_col"
  * (exclusive) is covered by a higher-zindex opacity popup.
@@ -4840,8 +4871,10 @@ draw_opacity_padding_cell(
                        screen_char(base_off, row, base_col);
 
                        // Draw padding in the right half.
+                       // Use left half's attr since the right half of a
+                       // wide char may have an unreliable attr value.
                        ScreenLines[off] = ' ';
-                       ScreenAttrs[off] = saved_screenattrs[save_off];
+                       ScreenAttrs[off] = saved_screenattrs[base_save_off];
                        if (enc_utf8)
                            ScreenLinesUC[off] = 0;
                        int popup_attr_val =
@@ -4855,10 +4888,53 @@ draw_opacity_padding_cell(
                        screen_char(off, row, col);
                        return;
                    }
+                   // The content drawing cleared the left half to a
+                   // space (wide char didn't fit at content edge),
+                   // but the saved data has a wide char.  Restore it
+                   // spanning both the content cell and padding cell.
+                   if (base_save_off >= 0
+                           && saved_screenlinesuc[base_save_off] != 0
+                           && utf_char2cells(
+                               saved_screenlinesuc[base_save_off]) == 2
+                           && ScreenLines[base_off] == ' '
+                           && ScreenLinesUC[base_off] == 0)
+                   {
+                       int popup_attr_val =
+                                   get_win_attr(screen_opacity_popup);
+                       int blend =
+                                   screen_opacity_popup->w_popup_blend;
+
+                       ScreenLines[base_off] =
+                                   saved_screenlines[base_save_off];
+                       ScreenLinesUC[base_off] =
+                                   saved_screenlinesuc[base_save_off];
+                       ScreenAttrs[base_off] =
+                                   saved_screenattrs[base_save_off];
+                       ScreenAttrs[base_off] = hl_blend_attr(
+                                   ScreenAttrs[base_off],
+                                   popup_attr_val, blend, TRUE);
+
+                       ScreenLines[off] = 0;
+                       ScreenLinesUC[off] = 0;
+                       ScreenAttrs[off] = ScreenAttrs[base_off];
+
+                       popup_set_base_screen_cell(row, base_col,
+                                   ScreenLines[base_off],
+                                   ScreenAttrs[base_off],
+                                   ScreenLinesUC[base_off]);
+                       popup_set_base_screen_cell(row, col,
+                                   ScreenLines[off],
+                                   ScreenAttrs[off],
+                                   ScreenLinesUC[off]);
+                       screen_char(base_off, row, base_col);
+                       return;
+                   }
 
                    // Draw padding in the right half.
+                   // Use left half's attr since the right half of a
+                   // wide char may have an unreliable attr value.
                    ScreenLines[off] = ' ';
-                   ScreenAttrs[off] = saved_screenattrs[save_off];
+                   ScreenAttrs[off] = saved_screenattrs[base_save_off];
                    if (enc_utf8 && ScreenLinesUC != NULL)
                        ScreenLinesUC[off] = 0;
                    int popup_attr_val = get_win_attr(screen_opacity_popup);
index d6ac2b72a0e68ebec166d26124a72ce68d37cff4..14e4a6fd29c341a97098303b10df9bcc3fdb4d80 100644 (file)
@@ -53,6 +53,7 @@ int popup_do_filter(int c);
 int popup_no_mapping(void);
 void popup_check_cursor_pos(void);
 int popup_is_under_opacity(int row, int col);
+int popup_is_over_opacity(int row, int col);
 int popup_is_under_opacity_range(int row, int start_col, int end_col);
 void may_update_popup_mask(int type);
 void may_update_popup_position(void);
index 311735d82111499944e4a7abb4f3f4c4ff33dc62..f667e6eb24209d14c6d27e5ed17f756543c201e4 100644 (file)
@@ -945,27 +945,36 @@ skip_opacity:
 
                popup_get_base_screen_cell(row, col + coloff,
                                                NULL, &underlying_attr, NULL);
-               ScreenAttrs[off_to] = hl_blend_attr(underlying_attr,
-                                               combined, blend, FALSE);
 
-               // For double-wide characters, the second cell may have a
-               // different underlying attr (e.g. at popup boundary),
-               // so blend it independently.
+               // For double-wide characters, a terminal cannot render
+               // different background colors for the left and right
+               // halves.  When one half is over a lower opacity popup
+               // and the other is not, use the non-popup side's
+               // underlying attr for both to avoid color leaking.
                if (char_cells == 2)
                {
                    int underlying_attr2 = 0;
+                   int scol1 = col + coloff;
+                   int over1 = popup_is_over_opacity(row, scol1);
+                   int over2 = popup_is_over_opacity(row, scol1 + 1);
 
-                   popup_get_base_screen_cell(row, col + coloff + 1,
+                   popup_get_base_screen_cell(row, scol1 + 1,
                                                NULL, &underlying_attr2, NULL);
+                   if (over1 != over2)
+                   {
+                       // One half is over a lower popup, the other is
+                       // not.  Use the non-popup side for both.
+                       if (over1)
+                           underlying_attr = underlying_attr2;
+                       else
+                           underlying_attr2 = underlying_attr;
+                   }
                    ScreenAttrs[off_to + 1] = hl_blend_attr(
                                        underlying_attr2, combined, blend,
                                        FALSE);
-                   if (blend == 100)
-                       resolve_wide_char_opacity_attrs(row,
-                               col + coloff, col + coloff + 1,
-                               &ScreenAttrs[off_to],
-                               &ScreenAttrs[off_to + 1]);
                }
+               ScreenAttrs[off_to] = hl_blend_attr(underlying_attr,
+                                               combined, blend, FALSE);
            }
            else
 #endif
@@ -2330,11 +2339,28 @@ screen_char(unsigned off, int row, int col)
     // output the final blended result.
     // Also suppress if this is a wide character whose second cell
     // is under an opacity popup.
-    if (popup_is_under_opacity(row, col)
-           || (enc_utf8 && ScreenLinesUC[off] != 0
+    if (popup_is_under_opacity(row, col))
+    {
+       // If this is a wide character whose left half is under an opacity
+       // popup but right half is not, clear the right half so the old
+       // blended value doesn't remain as a ghost after popup_move().
+       if (enc_utf8 && ScreenLinesUC[off] != 0
                && utf_char2cells(ScreenLinesUC[off]) == 2
                && col + 1 < screen_Columns
-               && popup_is_under_opacity(row, col + 1)))
+               && !popup_is_under_opacity(row, col + 1))
+       {
+           int off2 = off + 1;
+           ScreenLines[off2] = ' ';
+           ScreenLinesUC[off2] = 0;
+           screen_char(off2, row, col + 1);
+       }
+       screen_cur_col = 9999;
+       return;
+    }
+    if (enc_utf8 && ScreenLinesUC[off] != 0
+           && utf_char2cells(ScreenLinesUC[off]) == 2
+           && col + 1 < screen_Columns
+           && popup_is_under_opacity(row, col + 1))
     {
        screen_cur_col = 9999;
        return;
index be464f7721ae5b040d0195870e2e0449d5f050ad..875430044bd9d66cca0c7f7c48d6d6bb2de296b2 100644 (file)
@@ -1,13 +1,13 @@
->い*0&#ffffff0|え|ー@15|い|!+&| |1| @3
-|い*&|え|ー@15|い|!+&| |2| @3
-|い*&|え|ー@15|い|!+&| |3| @3
-|い*&|え*0#ffffff16#e000002|ー@6| +&| +0#0000000#ffffff0|ー*&@7|い|!+&| |4| @3
-|い*&| +0#ffffff16#e000002|カ*&|ラ|フ|ル|な| +&|ー*&@1| +&| +0#0000000#ffffff0|ー*&@7|い|!+&| |5| @3
-|い*&| +0#ffffff16#e000002|ポ*&|ッ|プ|ア|ッ|プ|で|─+&|╮| +0#0000000#ffffff0|ー*&@7|い|!+&| |6| @3
-|い*&| +0#ffffff16#e000002|最*&|上|川| +&|ぼ*&|赤|い|な|│+&| +0#0000000#ffffff0|ー*&@7|い|!+&| |7| @3
-|い*&| +0#ffffff16#e000002|│|あ*&|い|う|え|お|ー@1|│+&| +0#0000000#ffffff0|ー*&@7|い|!+&| |8| @3
-|い*&| +&|│+0#ffffff16#0000e05|ー*&@6|│+&| +0#0000000#ffffff0|ー*&@7|い|!+&| |9| @3
-|い*&| +&|╰+0#ffffff16#0000e05|─@13|╯| +0#0000000#ffffff0|ー*&@7|い|!+&| |1|0| @2
+>い*0&#ffffff0|え*0#e08080255#600000255|ー@6| +&| +0#0000000#ffffff0|ー*&@7|い|!+&| |1| @3
+|い*&| +0#e08080255#600000255|カ*0#ffffff255&|ラ|フ|ル|な| +0#e08080255&|ー*&@1| +&| +0#0000000#ffffff0|ー*&@7|い|!+&| |2| @3
+|い*&| +0#e08080255#600000255|ポ*0#ffffff255#600030255|ッ|プ|ア|ッ|プ|で|─+0#e08080255&|╮| +0#0000000#ffffff0|ー*&@7|い|!+&| |3| @3
+|い*&| +0#e08080255#600000255|最*0#ffffff255#600030255|上|川| +0#e08080255&|ぼ*&|赤|い|な|│+&| +0#0000000#ffffff0|ー*&@7|い|!+&| |4| @3
+|い*&| +0#e08080255#600000255|│+0&#600030255|あ*&|い|う|え|お|ー*0#a04070255&@1|│+0#e08080255&| +0#0000000#ffffff0|ー*&@7|い|!+&| |5| @3
+|い*&| +&|│+0#ffffff255#000060255|ー*0#8080e0255&@6|│+0#ffffff255&| +0#0000000#ffffff0|ー*&@7|い|!+&| |6| @3
+|い*&| +&|╰+0#ffffff255#000060255|─@13|╯| +0#0000000#ffffff0|ー*&@7|い|!+&| |7| @3
+|い*&|え|ー@15|い|!+&| |8| @3
+|い*&|え|ー@15|い|!+&| |9| @3
+|い*&|え|ー@15|い|!+&| |1|0| @2
 |い*&|え|ー@15|い|!+&| |1@1| @2
 |い*&|え|ー@15|い|!+&| |1|2| @2
 |い*&|え|ー@15|い|!+&| |1|3| @2
index a6ffdb11de5ac46f01852d4af9d7fc4630652c23..df2e6c09b8976bf17f4030ce01410fb770f64254 100644 (file)
@@ -1,15 +1,15 @@
 >い*0&#ffffff0|え|ー@15|い|!+&| |1| @3
 |い*&|え|ー@15|い|!+&| |2| @3
-|い*&|え|ー@15|い|!+&| |3| @3
-|い*&|え|ー@15|い|!+&| |4| @3
-|い*&|え|ー@15|い|!+&| |5| @3
-|ã\81\84*&| +&|â\95­+0#ffffff16#0000e05|â\94\80@13|â\95®| +0#0000000#ffffff0|ã\83¼*&@7|い|!+&| |6| @3
-|ã\81\84*&| +&|â\94\82+0#ffffff16#0000e05|ã\81\82*&|ã\82\81\82\93\81¼|赤|ã\81\84\81ª|â\94\82+&| +0#0000000#ffffff0|ã\83¼*&@7|い|!+&| |7| @3
-|い*&| +&|│+0#ffffff16#0000e05|あ*&|い|う|え|お| +&| +0&#e000002|ー*&|│+&| |ー*&@5|ー*0#0000000#ffffff0@1|い|!+&| |8| @3
-|い*&| +&|│+0#ffffff16#0000e05|ー*&@4| +&| +0&#e000002|カ*&|ラ|フ|ル|な|ー@1| +&@1|ー*0#0000000#ffffff0@1|い|!+&| |9| @3
-|い*&| +&|╰+0#ffffff16#0000e05|─@10|─+0&#e000002|ポ*&|ッ|プ|ア|ッ|プ|で| +&@1|ー*0#0000000#ffffff0@1|い|!+&| |1|0| @2
-|い*&|え|ー@4| +&| +0#ffffff16#e000002|最*&|上|川|ー@3| +&@1|ー*0#0000000#ffffff0@1|い|!+&| |1@1| @2
-|い*&|え|ー@4| +&| +0#ffffff16#e000002|ー*&@7|ー*0#0000000#ffffff0@1|い|!+&| |1|2| @2
+|い*&| +&|╭+0#ffffff255#000060255|─@13|╮| +0#0000000#ffffff0|ー*&@7|い|!+&| |3| @3
+|い*&| +&|│+0#ffffff255#000060255|あ*&|め|ん|ぼ|赤|い|な|│+&| +0#0000000#ffffff0|ー*&@7|い|!+&| |4| @3
+|い*&| +&|│+0#ffffff255#000060255|あ*&|い|う|え|お|ー*0#8080e0255&@1|│+0#ffffff255&| +0#0000000#ffffff0|ー*&@7|い|!+&| |5| @3
+|ã\81\84*&| +&|â\94\82+0#ffffff255#000060255|ã\83¼*0#8080e0255&@4| +&| +0#a04070255#600030255|ã\83¼*&|â\94\82+0#e08080255&| +0&#600000255|ã\83¼*&@5|ã\83¼*0#0000000#ffffff0@1|い|!+&| |6| @3
+|ã\81\84*&| +&|â\95°+0#ffffff255#000060255|â\94\80@10|â\94\80+0#e08080255#600030255|ã\82«*0#ffffff255&|ã\83©*0&#600000255|ã\83\95\83«|ã\81ª|ã\83¼*0#e08080255&@2|ã\83¼*0#0000000#ffffff0@1|い|!+&| |7| @3
+|い*&|え|ー@4| +&| +0#e08080255#600000255|ポ*0#ffffff255&|ッ|プ|ア|ッ|プ|で|ー*0#e08080255&|ー*0#0000000#ffffff0@1|い|!+&| |8| @3
+|い*&|え|ー@4| +&| +0#e08080255#600000255|最*0#ffffff255&|上|川|ー*0#e08080255&@4|ー*0#0000000#ffffff0@1|い|!+&| |9| @3
+|い*&|え|ー@4| +&| +0#e08080255#600000255|ー*&@7|ー*0#0000000#ffffff0@1|い|!+&| |1|0| @2
+|い*&|え|ー@15|い|!+&| |1@1| @2
+|い*&|え|ー@15|い|!+&| |1|2| @2
 |い*&|え|ー@15|い|!+&| |1|3| @2
 |い*&|え|ー@15|い|!+&| |1|4| @2
 |:| @25|1|,|1| @10|T|o|p| 
index 023d8906764a00d75c6117d32687b3584e8b1df7..a134acabd90070152d4f642cd4b91acae2d96389 100644 (file)
@@ -4932,6 +4932,7 @@ func Test_popup_opacity_wide_char_overlap()
   " higher-zindex popup are properly blended (no holes or missing chars).
   let lines =<< trim END
     set encoding=utf-8
+    set termguicolors
     for i in range(1, 20)
       call setline(i, 'いえーーーーーーーーーーーーーーーーい! ' .. i)
     endfor
@@ -4939,7 +4940,7 @@ func Test_popup_opacity_wide_char_overlap()
     hi MyPopup2 ctermbg=darkred ctermfg=white
     let g:p1 = popup_create(['あめんぼ赤いな','あいうえお'], #{
         \ opacity: 50,
-        \ line: 6,
+        \ line: 3,
         \ col: 4,
         \ border: [],
         \ borderchars: ['─','│','─','│','╭','╮','╯','╰'],
@@ -4950,7 +4951,7 @@ func Test_popup_opacity_wide_char_overlap()
         \})
     let g:p2 = popup_create(['カラフルな','ポップアップで','最上川'], #{
         \ opacity: 50,
-        \ line: 4,
+        \ line: 1,
         \ col: 3,
         \ minwidth: 15,
         \ minheight: 3,
@@ -4963,9 +4964,9 @@ func Test_popup_opacity_wide_char_overlap()
   let buf = RunVimInTerminal('-S XtestPopupOpacityWide', #{rows: 15, cols: 45})
   call VerifyScreenDump(buf, 'Test_popupwin_opacity_wide_1', {})
 
-  " Move popups far apart so they don't overlap.
-  " Tests right edge of popup where wide chars span content/padding boundary.
-  call term_sendkeys(buf, ":call popup_move(g:p2, #{line: 14, col: 16})\<CR>")
+  " Move p2 so it partially overlaps with p1 at a different position.
+  " Tests wide chars at the overlap boundary of two opacity popups.
+  call term_sendkeys(buf, ":call popup_move(g:p2, #{line: 6, col: 16})\<CR>")
   call TermWait(buf)
   call term_sendkeys(buf, ":\<CR>")
   call VerifyScreenDump(buf, 'Test_popupwin_opacity_wide_2', {})
index ccffba42d0c02ea621792b5ae0efee78f37ae239..e2dbe11e88f571f783bacdbcff0ca6dd102f1076 100644 (file)
@@ -734,6 +734,8 @@ static char *(features[]) =
 
 static int included_patches[] =
 {   /* Add new patch number below this line */
+/**/
+    332,
 /**/
     331,
 /**/