mirror of
https://github.com/vim/vim.git
synced 2026-05-28 00:21:37 +02:00
patch 9.2.0080: popup: a few redrawing problems
Problem: Popup windows leave ghost images when moved. Visual options
do not trigger a redraw when updated via popup_setoptions().
An empty borderhighlight list fails to clear existing
highlights.
Solution: Modify f_popup_move() in src/popupwin.c to save the old
position before moving and force a redraw. Enhance
f_popup_setoptions() to trigger a redraw when
visual-affecting options change. Modify
apply_general_options() to explicitly clear border
highlights when an empty list is provided
(Yasuhiro Matsumoto).
closes: #19297
Signed-off-by: Yasuhiro Matsumoto <mattn.jp@gmail.com>
Signed-off-by: Christian Brabandt <cb@256bit.org>
This commit is contained in:
committed by
Christian Brabandt
parent
b901fa9a6a
commit
cded5e2205
+8
-1
@@ -97,6 +97,9 @@ update_screen(int type_arg)
|
|||||||
#endif
|
#endif
|
||||||
int no_update = FALSE;
|
int no_update = FALSE;
|
||||||
int save_pum_will_redraw = pum_will_redraw;
|
int save_pum_will_redraw = pum_will_redraw;
|
||||||
|
#ifdef FEAT_PROP_POPUP
|
||||||
|
int did_redraw_window = FALSE;
|
||||||
|
#endif
|
||||||
|
|
||||||
// Don't do anything if the screen structures are (not yet) valid.
|
// Don't do anything if the screen structures are (not yet) valid.
|
||||||
if (!screen_valid(TRUE))
|
if (!screen_valid(TRUE))
|
||||||
@@ -319,6 +322,9 @@ update_screen(int type_arg)
|
|||||||
if (wp->w_redr_type != 0)
|
if (wp->w_redr_type != 0)
|
||||||
{
|
{
|
||||||
cursor_off();
|
cursor_off();
|
||||||
|
#ifdef FEAT_PROP_POPUP
|
||||||
|
did_redraw_window = TRUE;
|
||||||
|
#endif
|
||||||
#ifdef FEAT_GUI
|
#ifdef FEAT_GUI
|
||||||
if (!did_one)
|
if (!did_one)
|
||||||
{
|
{
|
||||||
@@ -363,7 +369,8 @@ update_screen(int type_arg)
|
|||||||
|
|
||||||
#ifdef FEAT_PROP_POPUP
|
#ifdef FEAT_PROP_POPUP
|
||||||
// Display popup windows on top of the windows and command line.
|
// Display popup windows on top of the windows and command line.
|
||||||
update_popups(win_update);
|
if (did_redraw_window || popup_need_redraw())
|
||||||
|
update_popups(win_update);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef FEAT_TERMINAL
|
#ifdef FEAT_TERMINAL
|
||||||
|
|||||||
+12
-8
@@ -3167,14 +3167,15 @@ hl_blend_attr(int char_attr, int popup_attr, int blend, int blend_fg UNUSED)
|
|||||||
{
|
{
|
||||||
if (blend_fg)
|
if (blend_fg)
|
||||||
{
|
{
|
||||||
// blend_fg=TRUE: blend bg text fg from popup bg color to white
|
// blend_fg=TRUE: fade underlying text toward popup bg.
|
||||||
// At blend=0: fg becomes popup bg (blue, invisible - opaque popup)
|
|
||||||
// At blend=100: fg is white (visible - transparent popup)
|
|
||||||
// Always use white (0xFFFFFF) as the target color for consistency
|
|
||||||
if (popup_aep->ae_u.gui.bg_color != INVALCOLOR)
|
if (popup_aep->ae_u.gui.bg_color != INVALCOLOR)
|
||||||
{
|
{
|
||||||
|
int base_fg = 0xFFFFFF;
|
||||||
|
if (char_aep != NULL
|
||||||
|
&& char_aep->ae_u.gui.fg_color != INVALCOLOR)
|
||||||
|
base_fg = char_aep->ae_u.gui.fg_color;
|
||||||
new_en.ae_u.gui.fg_color = blend_colors(
|
new_en.ae_u.gui.fg_color = blend_colors(
|
||||||
popup_aep->ae_u.gui.bg_color, 0xFFFFFF, blend);
|
base_fg, popup_aep->ae_u.gui.bg_color, blend);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (popup_aep->ae_u.gui.fg_color != INVALCOLOR)
|
else if (popup_aep->ae_u.gui.fg_color != INVALCOLOR)
|
||||||
@@ -3230,12 +3231,15 @@ hl_blend_attr(int char_attr, int popup_attr, int blend, int blend_fg UNUSED)
|
|||||||
// Blend RGB colors for termguicolors mode
|
// Blend RGB colors for termguicolors mode
|
||||||
if (blend_fg)
|
if (blend_fg)
|
||||||
{
|
{
|
||||||
// blend_fg=TRUE: blend bg text fg from popup bg color to white
|
// blend_fg=TRUE: fade underlying text toward popup bg.
|
||||||
// Always use white (0xFFFFFF) as the target color for consistency
|
|
||||||
if (popup_aep->ae_u.cterm.bg_rgb != INVALCOLOR)
|
if (popup_aep->ae_u.cterm.bg_rgb != 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(
|
new_en.ae_u.cterm.fg_rgb = blend_colors(
|
||||||
popup_aep->ae_u.cterm.bg_rgb, 0xFFFFFF, blend);
|
base_fg, popup_aep->ae_u.cterm.bg_rgb, blend);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (popup_aep->ae_u.cterm.fg_rgb != INVALCOLOR)
|
else if (popup_aep->ae_u.cterm.fg_rgb != INVALCOLOR)
|
||||||
|
|||||||
+418
-17
@@ -852,23 +852,36 @@ apply_general_options(win_T *wp, dict_T *dict)
|
|||||||
int i;
|
int i;
|
||||||
|
|
||||||
CHECK_LIST_MATERIALIZE(list);
|
CHECK_LIST_MATERIALIZE(list);
|
||||||
for (i = 0, li = list->lv_first; i < 4 && i < list->lv_len;
|
wp->w_border_highlight_isset = TRUE;
|
||||||
++i, li = li->li_next)
|
// Clear all highlights if list is empty
|
||||||
|
if (list->lv_len == 0)
|
||||||
{
|
{
|
||||||
str = tv_get_string(&li->li_tv);
|
for (i = 0; i < 4; ++i)
|
||||||
if (*str != NUL)
|
|
||||||
{
|
{
|
||||||
vim_free(wp->w_border_highlight[i]);
|
vim_free(wp->w_border_highlight[i]);
|
||||||
wp->w_border_highlight[i] = vim_strsave(str);
|
wp->w_border_highlight[i] = NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (list->lv_len == 1 && wp->w_border_highlight[0] != NULL)
|
else
|
||||||
for (i = 1; i < 4; ++i)
|
{
|
||||||
|
for (i = 0, li = list->lv_first; i < 4 && i < list->lv_len;
|
||||||
|
++i, li = li->li_next)
|
||||||
{
|
{
|
||||||
vim_free(wp->w_border_highlight[i]);
|
str = tv_get_string(&li->li_tv);
|
||||||
wp->w_border_highlight[i] =
|
if (*str != NUL)
|
||||||
vim_strsave(wp->w_border_highlight[0]);
|
{
|
||||||
|
vim_free(wp->w_border_highlight[i]);
|
||||||
|
wp->w_border_highlight[i] = vim_strsave(str);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
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]);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2180,6 +2193,23 @@ popup_redraw_all(void)
|
|||||||
wp->w_redr_type = UPD_NOT_VALID;
|
wp->w_redr_type = UPD_NOT_VALID;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Return TRUE if any visible popup window needs a redraw.
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
popup_need_redraw(void)
|
||||||
|
{
|
||||||
|
win_T *wp;
|
||||||
|
|
||||||
|
FOR_ALL_POPUPWINS(wp)
|
||||||
|
if ((wp->w_popup_flags & POPF_HIDDEN) == 0 && wp->w_redr_type != 0)
|
||||||
|
return TRUE;
|
||||||
|
FOR_ALL_POPUPWINS_IN_TAB(curtab, wp)
|
||||||
|
if ((wp->w_popup_flags & POPF_HIDDEN) == 0 && wp->w_redr_type != 0)
|
||||||
|
return TRUE;
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Set the color for a notification window.
|
* Set the color for a notification window.
|
||||||
*/
|
*/
|
||||||
@@ -3238,6 +3268,10 @@ f_popup_move(typval_T *argvars, typval_T *rettv UNUSED)
|
|||||||
dict_T *dict;
|
dict_T *dict;
|
||||||
int id;
|
int id;
|
||||||
win_T *wp;
|
win_T *wp;
|
||||||
|
int old_winrow;
|
||||||
|
int old_wincol;
|
||||||
|
int old_height;
|
||||||
|
int old_width;
|
||||||
|
|
||||||
if (in_vim9script()
|
if (in_vim9script()
|
||||||
&& (check_for_number_arg(argvars, 0) == FAIL
|
&& (check_for_number_arg(argvars, 0) == FAIL
|
||||||
@@ -3253,11 +3287,22 @@ f_popup_move(typval_T *argvars, typval_T *rettv UNUSED)
|
|||||||
return;
|
return;
|
||||||
dict = argvars[1].vval.v_dict;
|
dict = argvars[1].vval.v_dict;
|
||||||
|
|
||||||
|
// Save old position for redrawing
|
||||||
|
old_winrow = wp->w_winrow;
|
||||||
|
old_wincol = wp->w_wincol;
|
||||||
|
old_height = wp->w_height;
|
||||||
|
old_width = wp->w_width;
|
||||||
|
|
||||||
apply_move_options(wp, dict);
|
apply_move_options(wp, dict);
|
||||||
|
|
||||||
if (wp->w_winrow + wp->w_height >= cmdline_row)
|
if (wp->w_winrow + wp->w_height >= cmdline_row)
|
||||||
clear_cmdline = TRUE;
|
clear_cmdline = TRUE;
|
||||||
popup_adjust_position(wp);
|
popup_adjust_position(wp);
|
||||||
|
|
||||||
|
// Redraw the old position to clear ghost images
|
||||||
|
if (old_winrow != wp->w_winrow || old_wincol != wp->w_wincol
|
||||||
|
|| old_height != wp->w_height || old_width != wp->w_width)
|
||||||
|
redraw_all_later(UPD_NOT_VALID);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -3273,6 +3318,13 @@ f_popup_setoptions(typval_T *argvars, typval_T *rettv UNUSED)
|
|||||||
#ifdef FEAT_PROP_POPUP
|
#ifdef FEAT_PROP_POPUP
|
||||||
int old_blend;
|
int old_blend;
|
||||||
#endif
|
#endif
|
||||||
|
int old_zindex;
|
||||||
|
int old_popup_flags;
|
||||||
|
char_u *old_scrollbar_highlight;
|
||||||
|
char_u *old_thumb_highlight;
|
||||||
|
char_u *old_border_highlight[4];
|
||||||
|
int need_redraw = FALSE;
|
||||||
|
int i;
|
||||||
|
|
||||||
if (in_vim9script()
|
if (in_vim9script()
|
||||||
&& (check_for_number_arg(argvars, 0) == FAIL
|
&& (check_for_number_arg(argvars, 0) == FAIL
|
||||||
@@ -3291,10 +3343,34 @@ f_popup_setoptions(typval_T *argvars, typval_T *rettv UNUSED)
|
|||||||
#ifdef FEAT_PROP_POPUP
|
#ifdef FEAT_PROP_POPUP
|
||||||
old_blend = wp->w_popup_blend;
|
old_blend = wp->w_popup_blend;
|
||||||
#endif
|
#endif
|
||||||
|
old_zindex = wp->w_zindex;
|
||||||
|
old_popup_flags = wp->w_popup_flags;
|
||||||
|
old_scrollbar_highlight = wp->w_scrollbar_highlight;
|
||||||
|
old_thumb_highlight = wp->w_thumb_highlight;
|
||||||
|
for (i = 0; i < 4; i++)
|
||||||
|
old_border_highlight[i] = wp->w_border_highlight[i];
|
||||||
|
|
||||||
(void)apply_options(wp, dict, FALSE);
|
(void)apply_options(wp, dict, FALSE);
|
||||||
|
|
||||||
|
// Check if visual options changed and redraw if needed
|
||||||
if (old_firstline != wp->w_firstline)
|
if (old_firstline != wp->w_firstline)
|
||||||
|
need_redraw = TRUE;
|
||||||
|
if (old_zindex != wp->w_zindex)
|
||||||
|
need_redraw = TRUE;
|
||||||
|
if (old_popup_flags != wp->w_popup_flags)
|
||||||
|
need_redraw = TRUE;
|
||||||
|
if (old_scrollbar_highlight != wp->w_scrollbar_highlight)
|
||||||
|
need_redraw = TRUE;
|
||||||
|
if (old_thumb_highlight != wp->w_thumb_highlight)
|
||||||
|
need_redraw = TRUE;
|
||||||
|
for (i = 0; i < 4; i++)
|
||||||
|
if (old_border_highlight[i] != wp->w_border_highlight[i])
|
||||||
|
{
|
||||||
|
need_redraw = TRUE;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (need_redraw)
|
||||||
redraw_win_later(wp, UPD_NOT_VALID);
|
redraw_win_later(wp, UPD_NOT_VALID);
|
||||||
#ifdef FEAT_PROP_POPUP
|
#ifdef FEAT_PROP_POPUP
|
||||||
// Force redraw if opacity value changed
|
// Force redraw if opacity value changed
|
||||||
@@ -3432,7 +3508,9 @@ get_borderhighlight(dict_T *dict, win_T *wp)
|
|||||||
for (i = 0; i < 4; ++i)
|
for (i = 0; i < 4; ++i)
|
||||||
if (wp->w_border_highlight[i] != NULL)
|
if (wp->w_border_highlight[i] != NULL)
|
||||||
break;
|
break;
|
||||||
if (i == 4)
|
// Only include "borderhighlight" if it was explicitly set (even if empty)
|
||||||
|
// or if at least one highlight is set.
|
||||||
|
if (i == 4 && !wp->w_border_highlight_isset)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
list = list_alloc();
|
list = list_alloc();
|
||||||
@@ -3440,6 +3518,9 @@ get_borderhighlight(dict_T *dict, win_T *wp)
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
dict_add_list(dict, "borderhighlight", list);
|
dict_add_list(dict, "borderhighlight", list);
|
||||||
|
// When all highlights are NULL (cleared to empty list), return empty list.
|
||||||
|
if (i == 4)
|
||||||
|
return;
|
||||||
for (i = 0; i < 4; ++i)
|
for (i = 0; i < 4; ++i)
|
||||||
list_append_string(list, wp->w_border_highlight[i], -1);
|
list_append_string(list, wp->w_border_highlight[i], -1);
|
||||||
}
|
}
|
||||||
@@ -4240,11 +4321,68 @@ may_update_popup_position(void)
|
|||||||
popup_adjust_position(curwin);
|
popup_adjust_position(curwin);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef FEAT_PROP_POPUP
|
||||||
|
static schar_T *base_screenlines = NULL;
|
||||||
|
static int *base_screenattrs = NULL;
|
||||||
|
static u8char_T *base_screenlinesuc = NULL;
|
||||||
|
static int base_screen_rows = 0;
|
||||||
|
static int base_screen_cols = 0;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Get the base screen cell saved before drawing opacity popups.
|
||||||
|
* Returns TRUE if the cell is available.
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
popup_get_base_screen_cell(int row, int col, schar_T *linep, int *attrp,
|
||||||
|
u8char_T *ucp)
|
||||||
|
{
|
||||||
|
if (base_screenlines == NULL || base_screenattrs == NULL)
|
||||||
|
return FALSE;
|
||||||
|
if (row < 0 || col < 0 || row >= base_screen_rows
|
||||||
|
|| col >= base_screen_cols)
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
int off = row * base_screen_cols + col;
|
||||||
|
if (linep != NULL)
|
||||||
|
*linep = base_screenlines[off];
|
||||||
|
if (attrp != NULL)
|
||||||
|
*attrp = base_screenattrs[off];
|
||||||
|
if (ucp != NULL)
|
||||||
|
{
|
||||||
|
if (enc_utf8 && base_screenlinesuc != NULL)
|
||||||
|
*ucp = base_screenlinesuc[off];
|
||||||
|
else
|
||||||
|
*ucp = 0;
|
||||||
|
}
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Set the base screen cell saved before drawing opacity popups.
|
||||||
|
* Used to update the snapshot after blending a layer.
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
popup_set_base_screen_cell(int row, int col, schar_T line, int attr, u8char_T uc)
|
||||||
|
{
|
||||||
|
if (base_screenlines == NULL || base_screenattrs == NULL)
|
||||||
|
return;
|
||||||
|
if (row < 0 || col < 0 || row >= base_screen_rows
|
||||||
|
|| col >= base_screen_cols)
|
||||||
|
return;
|
||||||
|
|
||||||
|
int off = row * base_screen_cols + col;
|
||||||
|
base_screenlines[off] = line;
|
||||||
|
base_screenattrs[off] = attr;
|
||||||
|
if (enc_utf8 && base_screenlinesuc != NULL)
|
||||||
|
base_screenlinesuc[off] = uc;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Draw a single padding cell with opacity blending.
|
* Draw a single padding cell with opacity blending.
|
||||||
* Restores background from saved data and blends with popup attribute.
|
* Restores background from saved data and blends with popup attribute.
|
||||||
*/
|
*/
|
||||||
static void
|
static void
|
||||||
draw_opacity_padding_cell(
|
draw_opacity_padding_cell(
|
||||||
int row,
|
int row,
|
||||||
int col,
|
int col,
|
||||||
@@ -4254,7 +4392,9 @@ draw_opacity_padding_cell(
|
|||||||
int save_start_row,
|
int save_start_row,
|
||||||
int save_start_col,
|
int save_start_col,
|
||||||
int save_rows,
|
int save_rows,
|
||||||
int save_cols)
|
int save_cols,
|
||||||
|
int pad_start_col,
|
||||||
|
int pad_end_col)
|
||||||
{
|
{
|
||||||
int off = LineOffset[row] + col;
|
int off = LineOffset[row] + col;
|
||||||
int r = row - save_start_row;
|
int r = row - save_start_row;
|
||||||
@@ -4263,14 +4403,165 @@ draw_opacity_padding_cell(
|
|||||||
if (r >= 0 && r < save_rows && c >= 0 && c < save_cols)
|
if (r >= 0 && r < save_rows && c >= 0 && c < save_cols)
|
||||||
{
|
{
|
||||||
int save_off = r * save_cols + c;
|
int save_off = r * save_cols + c;
|
||||||
|
// If this is the second cell of a wide background character, blend
|
||||||
|
// the wide character instead of overwriting it.
|
||||||
|
if (enc_utf8 && saved_screenlinesuc != NULL)
|
||||||
|
{
|
||||||
|
int base_col = col - 1;
|
||||||
|
int base_off = off - 1;
|
||||||
|
int base_save_off = save_off - 1;
|
||||||
|
int wide_prev = FALSE;
|
||||||
|
|
||||||
|
// Prefer current screen state for detecting a wide char, since the
|
||||||
|
// saved data may not contain a reliable right-half marker.
|
||||||
|
if (base_off >= 0 && ScreenLines != NULL)
|
||||||
|
{
|
||||||
|
if (ScreenLinesUC != NULL
|
||||||
|
&& ScreenLinesUC[base_off] != 0
|
||||||
|
&& utf_char2cells(ScreenLinesUC[base_off]) == 2
|
||||||
|
&& ScreenLines[off] == 0)
|
||||||
|
wide_prev = TRUE;
|
||||||
|
}
|
||||||
|
if (!wide_prev && save_off > 0)
|
||||||
|
{
|
||||||
|
if (saved_screenlinesuc[save_off - 1] != 0
|
||||||
|
&& utf_char2cells(saved_screenlinesuc[save_off - 1]) == 2
|
||||||
|
&& saved_screenlines[save_off] == 0)
|
||||||
|
wide_prev = TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (wide_prev && base_col >= 0)
|
||||||
|
{
|
||||||
|
// If the wide character starts outside the padding area, do not
|
||||||
|
// overwrite it. Use the base screen cell if available.
|
||||||
|
if (base_col < pad_start_col)
|
||||||
|
{
|
||||||
|
if (ScreenLinesUC != NULL
|
||||||
|
&& ScreenLinesUC[base_off] != 0
|
||||||
|
&& utf_char2cells(ScreenLinesUC[base_off]) == 2)
|
||||||
|
{
|
||||||
|
// The left half still has the wide char on screen.
|
||||||
|
// Clear it to a space.
|
||||||
|
ScreenLines[base_off] = ' ';
|
||||||
|
ScreenLinesUC[base_off] = 0;
|
||||||
|
ScreenAttrs[base_off] = saved_screenattrs[base_save_off];
|
||||||
|
screen_char(base_off, row, base_col);
|
||||||
|
|
||||||
|
// Draw padding in the right half.
|
||||||
|
ScreenLines[off] = ' ';
|
||||||
|
ScreenAttrs[off] = saved_screenattrs[save_off];
|
||||||
|
if (enc_utf8)
|
||||||
|
ScreenLinesUC[off] = 0;
|
||||||
|
int popup_attr_val =
|
||||||
|
get_wcr_attr(screen_opacity_popup);
|
||||||
|
int blend = screen_opacity_popup->w_popup_blend;
|
||||||
|
ScreenAttrs[off] = hl_blend_attr(ScreenAttrs[off],
|
||||||
|
popup_attr_val, blend, TRUE);
|
||||||
|
popup_set_base_screen_cell(row, col,
|
||||||
|
ScreenLines[off], ScreenAttrs[off],
|
||||||
|
ScreenLinesUC[off]);
|
||||||
|
screen_char(off, row, col);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// screen_line() already cleared the base cell (popup
|
||||||
|
// content was a space). Restore the full wide char from
|
||||||
|
// saved background so it shows through with opacity.
|
||||||
|
if (base_save_off >= 0
|
||||||
|
&& saved_screenlinesuc != NULL
|
||||||
|
&& saved_screenlinesuc[base_save_off] != 0
|
||||||
|
&& utf_char2cells(
|
||||||
|
saved_screenlinesuc[base_save_off]) == 2)
|
||||||
|
{
|
||||||
|
ScreenLines[base_off] =
|
||||||
|
saved_screenlines[base_save_off];
|
||||||
|
ScreenLinesUC[base_off] =
|
||||||
|
saved_screenlinesuc[base_save_off];
|
||||||
|
ScreenLines[off] = saved_screenlines[save_off];
|
||||||
|
ScreenLinesUC[off] = saved_screenlinesuc[save_off];
|
||||||
|
ScreenAttrs[base_off] =
|
||||||
|
saved_screenattrs[base_save_off];
|
||||||
|
ScreenAttrs[off] = saved_screenattrs[save_off];
|
||||||
|
|
||||||
|
int popup_attr_val =
|
||||||
|
get_wcr_attr(screen_opacity_popup);
|
||||||
|
int blend = screen_opacity_popup->w_popup_blend;
|
||||||
|
ScreenAttrs[base_off] = hl_blend_attr(
|
||||||
|
ScreenAttrs[base_off],
|
||||||
|
popup_attr_val, blend, TRUE);
|
||||||
|
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.
|
||||||
|
ScreenLines[off] = ' ';
|
||||||
|
ScreenAttrs[off] = saved_screenattrs[save_off];
|
||||||
|
if (enc_utf8 && ScreenLinesUC != NULL)
|
||||||
|
ScreenLinesUC[off] = 0;
|
||||||
|
int popup_attr_val = get_wcr_attr(screen_opacity_popup);
|
||||||
|
int blend = screen_opacity_popup->w_popup_blend;
|
||||||
|
ScreenAttrs[off] = hl_blend_attr(ScreenAttrs[off],
|
||||||
|
popup_attr_val, blend, TRUE);
|
||||||
|
popup_set_base_screen_cell(row, col, ScreenLines[off],
|
||||||
|
ScreenAttrs[off], ScreenLinesUC[off]);
|
||||||
|
screen_char(off, row, col);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Base cell is inside the saved area, redraw the wide char.
|
||||||
|
if (save_off > 0)
|
||||||
|
{
|
||||||
|
ScreenLines[base_off] = saved_screenlines[base_save_off];
|
||||||
|
ScreenAttrs[base_off] = saved_screenattrs[base_save_off];
|
||||||
|
ScreenLines[off] = saved_screenlines[save_off];
|
||||||
|
ScreenAttrs[off] = saved_screenattrs[save_off];
|
||||||
|
ScreenLinesUC[base_off] = saved_screenlinesuc[base_save_off];
|
||||||
|
ScreenLinesUC[off] = saved_screenlinesuc[save_off];
|
||||||
|
|
||||||
|
int popup_attr_val = get_wcr_attr(screen_opacity_popup);
|
||||||
|
int blend = screen_opacity_popup->w_popup_blend;
|
||||||
|
ScreenAttrs[base_off] = hl_blend_attr(ScreenAttrs[base_off],
|
||||||
|
popup_attr_val, blend, TRUE);
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
ScreenLines[off] = saved_screenlines[save_off];
|
ScreenLines[off] = saved_screenlines[save_off];
|
||||||
ScreenAttrs[off] = saved_screenattrs[save_off];
|
ScreenAttrs[off] = saved_screenattrs[save_off];
|
||||||
if (enc_utf8 && saved_screenlinesuc != NULL)
|
if (enc_utf8 && saved_screenlinesuc != NULL)
|
||||||
ScreenLinesUC[off] = saved_screenlinesuc[save_off];
|
ScreenLinesUC[off] = saved_screenlinesuc[save_off];
|
||||||
|
|
||||||
|
// If the saved character is wide and would extend past the padding
|
||||||
|
// area into the content area, replace with a space to avoid
|
||||||
|
// corrupting the content.
|
||||||
|
if (enc_utf8 && ScreenLinesUC[off] != 0
|
||||||
|
&& utf_char2cells(ScreenLinesUC[off]) == 2
|
||||||
|
&& col + 1 >= pad_end_col)
|
||||||
|
{
|
||||||
|
ScreenLines[off] = ' ';
|
||||||
|
ScreenLinesUC[off] = 0;
|
||||||
|
}
|
||||||
|
|
||||||
int popup_attr_val = get_wcr_attr(screen_opacity_popup);
|
int popup_attr_val = get_wcr_attr(screen_opacity_popup);
|
||||||
int blend = screen_opacity_popup->w_popup_blend;
|
int blend = screen_opacity_popup->w_popup_blend;
|
||||||
ScreenAttrs[off] = hl_blend_attr(ScreenAttrs[off],
|
ScreenAttrs[off] = hl_blend_attr(ScreenAttrs[off],
|
||||||
popup_attr_val, blend, TRUE);
|
popup_attr_val, blend, TRUE);
|
||||||
|
popup_set_base_screen_cell(row, col, ScreenLines[off],
|
||||||
|
ScreenAttrs[off], ScreenLinesUC[off]);
|
||||||
screen_char(off, row, col);
|
screen_char(off, row, col);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -4278,7 +4569,7 @@ draw_opacity_padding_cell(
|
|||||||
/*
|
/*
|
||||||
* Fill a rectangular padding area with opacity blending.
|
* Fill a rectangular padding area with opacity blending.
|
||||||
*/
|
*/
|
||||||
static void
|
static void
|
||||||
fill_opacity_padding(
|
fill_opacity_padding(
|
||||||
int start_row,
|
int start_row,
|
||||||
int end_row,
|
int end_row,
|
||||||
@@ -4296,7 +4587,8 @@ fill_opacity_padding(
|
|||||||
for (int pad_col = start_col; pad_col < end_col; pad_col++)
|
for (int pad_col = start_col; pad_col < end_col; pad_col++)
|
||||||
draw_opacity_padding_cell(pad_row, pad_col,
|
draw_opacity_padding_cell(pad_row, pad_col,
|
||||||
saved_screenlines, saved_screenattrs, saved_screenlinesuc,
|
saved_screenlines, saved_screenattrs, saved_screenlinesuc,
|
||||||
save_start_row, save_start_col, save_rows, save_cols);
|
save_start_row, save_start_col, save_rows, save_cols,
|
||||||
|
start_col, end_col);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -4333,6 +4625,25 @@ update_popups(void (*win_update)(win_T *wp))
|
|||||||
// so that the window with a higher zindex is drawn later, thus goes on
|
// so that the window with a higher zindex is drawn later, thus goes on
|
||||||
// top.
|
// top.
|
||||||
popup_reset_handled(POPUP_HANDLED_5);
|
popup_reset_handled(POPUP_HANDLED_5);
|
||||||
|
#ifdef FEAT_PROP_POPUP
|
||||||
|
if (base_screenlines != NULL)
|
||||||
|
{
|
||||||
|
vim_free(base_screenlines);
|
||||||
|
base_screenlines = NULL;
|
||||||
|
}
|
||||||
|
if (base_screenattrs != NULL)
|
||||||
|
{
|
||||||
|
vim_free(base_screenattrs);
|
||||||
|
base_screenattrs = NULL;
|
||||||
|
}
|
||||||
|
if (base_screenlinesuc != NULL)
|
||||||
|
{
|
||||||
|
vim_free(base_screenlinesuc);
|
||||||
|
base_screenlinesuc = NULL;
|
||||||
|
}
|
||||||
|
base_screen_rows = 0;
|
||||||
|
base_screen_cols = 0;
|
||||||
|
#endif
|
||||||
while ((wp = find_next_popup(TRUE, POPUP_HANDLED_5)) != NULL)
|
while ((wp = find_next_popup(TRUE, POPUP_HANDLED_5)) != NULL)
|
||||||
{
|
{
|
||||||
int title_len = 0;
|
int title_len = 0;
|
||||||
@@ -4350,6 +4661,54 @@ update_popups(void (*win_update)(win_T *wp))
|
|||||||
else
|
else
|
||||||
screen_opacity_popup = NULL;
|
screen_opacity_popup = NULL;
|
||||||
|
|
||||||
|
#ifdef FEAT_PROP_POPUP
|
||||||
|
if (screen_opacity_popup != NULL)
|
||||||
|
{
|
||||||
|
if (base_screenlines != NULL)
|
||||||
|
{
|
||||||
|
vim_free(base_screenlines);
|
||||||
|
base_screenlines = NULL;
|
||||||
|
}
|
||||||
|
if (base_screenattrs != NULL)
|
||||||
|
{
|
||||||
|
vim_free(base_screenattrs);
|
||||||
|
base_screenattrs = NULL;
|
||||||
|
}
|
||||||
|
if (base_screenlinesuc != NULL)
|
||||||
|
{
|
||||||
|
vim_free(base_screenlinesuc);
|
||||||
|
base_screenlinesuc = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
base_screen_rows = screen_Rows;
|
||||||
|
base_screen_cols = screen_Columns;
|
||||||
|
base_screenlines = ALLOC_MULT(schar_T,
|
||||||
|
base_screen_rows * base_screen_cols);
|
||||||
|
base_screenattrs = ALLOC_MULT(int,
|
||||||
|
base_screen_rows * base_screen_cols);
|
||||||
|
if (enc_utf8)
|
||||||
|
base_screenlinesuc = ALLOC_MULT(u8char_T,
|
||||||
|
base_screen_rows * base_screen_cols);
|
||||||
|
|
||||||
|
if (base_screenlines != NULL && base_screenattrs != NULL)
|
||||||
|
{
|
||||||
|
for (int r = 0; r < base_screen_rows; r++)
|
||||||
|
{
|
||||||
|
int off = LineOffset[r];
|
||||||
|
int base_off = r * base_screen_cols;
|
||||||
|
for (int c = 0; c < base_screen_cols; c++)
|
||||||
|
{
|
||||||
|
base_screenlines[base_off + c] = ScreenLines[off + c];
|
||||||
|
base_screenattrs[base_off + c] = ScreenAttrs[off + c];
|
||||||
|
if (enc_utf8 && base_screenlinesuc != NULL)
|
||||||
|
base_screenlinesuc[base_off + c] =
|
||||||
|
ScreenLinesUC[off + c];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
// Save background ScreenLines for padding opacity.
|
// Save background ScreenLines for padding opacity.
|
||||||
// We need to save it before win_update() overwrites it.
|
// We need to save it before win_update() overwrites it.
|
||||||
schar_T *saved_screenlines = NULL;
|
schar_T *saved_screenlines = NULL;
|
||||||
@@ -4370,6 +4729,14 @@ update_popups(void (*win_update)(win_T *wp))
|
|||||||
save_rows = wp->w_popup_padding[0] + wp->w_height + wp->w_popup_padding[2];
|
save_rows = wp->w_popup_padding[0] + wp->w_height + wp->w_popup_padding[2];
|
||||||
save_cols = wp->w_popup_padding[3] + wp->w_width + wp->w_popup_padding[1];
|
save_cols = wp->w_popup_padding[3] + wp->w_width + wp->w_popup_padding[1];
|
||||||
|
|
||||||
|
// Include one column to the left to handle wide chars that overlap
|
||||||
|
// the padding boundary.
|
||||||
|
if (save_start_col > 0)
|
||||||
|
{
|
||||||
|
--save_start_col;
|
||||||
|
++save_cols;
|
||||||
|
}
|
||||||
|
|
||||||
// Allocate buffers
|
// Allocate buffers
|
||||||
saved_screenlines = ALLOC_MULT(schar_T, save_rows * save_cols);
|
saved_screenlines = ALLOC_MULT(schar_T, save_rows * save_cols);
|
||||||
saved_screenattrs = ALLOC_MULT(int, save_rows * save_cols);
|
saved_screenattrs = ALLOC_MULT(int, save_rows * save_cols);
|
||||||
@@ -4686,8 +5053,16 @@ update_popups(void (*win_update)(win_T *wp))
|
|||||||
col = 0;
|
col = 0;
|
||||||
}
|
}
|
||||||
if (pad_left > 0)
|
if (pad_left > 0)
|
||||||
screen_fill(row, row + 1, col, col + pad_left,
|
{
|
||||||
|
if (screen_opacity_popup != NULL && saved_screenlines != NULL)
|
||||||
|
fill_opacity_padding(row, row + 1, col, col + pad_left,
|
||||||
|
saved_screenlines, saved_screenattrs,
|
||||||
|
saved_screenlinesuc, save_start_row,
|
||||||
|
save_start_col, save_rows, save_cols);
|
||||||
|
else
|
||||||
|
screen_fill(row, row + 1, col, col + pad_left,
|
||||||
' ', ' ', popup_attr);
|
' ', ' ', popup_attr);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
// scrollbar
|
// scrollbar
|
||||||
if (wp->w_has_scrollbar)
|
if (wp->w_has_scrollbar)
|
||||||
@@ -4717,7 +5092,13 @@ update_popups(void (*win_update)(win_T *wp))
|
|||||||
+ wp->w_popup_padding[3] + wp->w_width + wp->w_leftcol;
|
+ wp->w_popup_padding[3] + wp->w_width + wp->w_leftcol;
|
||||||
int pad_col_end = pad_col_start + wp->w_popup_padding[1];
|
int pad_col_end = pad_col_start + wp->w_popup_padding[1];
|
||||||
|
|
||||||
screen_fill(row, row + 1, pad_col_start, pad_col_end,
|
if (screen_opacity_popup != NULL && saved_screenlines != NULL)
|
||||||
|
fill_opacity_padding(row, row + 1, pad_col_start, pad_col_end,
|
||||||
|
saved_screenlines, saved_screenattrs,
|
||||||
|
saved_screenlinesuc, save_start_row, save_start_col,
|
||||||
|
save_rows, save_cols);
|
||||||
|
else
|
||||||
|
screen_fill(row, row + 1, pad_col_start, pad_col_end,
|
||||||
' ', ' ', popup_attr);
|
' ', ' ', popup_attr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -4805,6 +5186,26 @@ update_popups(void (*win_update)(win_T *wp))
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef FEAT_PROP_POPUP
|
||||||
|
if (base_screenlines != NULL)
|
||||||
|
{
|
||||||
|
vim_free(base_screenlines);
|
||||||
|
base_screenlines = NULL;
|
||||||
|
}
|
||||||
|
if (base_screenattrs != NULL)
|
||||||
|
{
|
||||||
|
vim_free(base_screenattrs);
|
||||||
|
base_screenattrs = NULL;
|
||||||
|
}
|
||||||
|
if (base_screenlinesuc != NULL)
|
||||||
|
{
|
||||||
|
vim_free(base_screenlinesuc);
|
||||||
|
base_screenlinesuc = NULL;
|
||||||
|
}
|
||||||
|
base_screen_rows = 0;
|
||||||
|
base_screen_cols = 0;
|
||||||
|
#endif
|
||||||
|
|
||||||
#if defined(FEAT_SEARCH_EXTRA)
|
#if defined(FEAT_SEARCH_EXTRA)
|
||||||
// In case win_update() called start_search_hl().
|
// In case win_update() called start_search_hl().
|
||||||
end_search_hl();
|
end_search_hl();
|
||||||
|
|||||||
@@ -16,6 +16,7 @@ int parse_completepopup(win_T *wp);
|
|||||||
void popup_set_wantpos_cursor(win_T *wp, int width, dict_T *d);
|
void popup_set_wantpos_cursor(win_T *wp, int width, dict_T *d);
|
||||||
void popup_set_wantpos_rowcol(win_T *wp, int row, int col);
|
void popup_set_wantpos_rowcol(win_T *wp, int row, int col);
|
||||||
void popup_redraw_all(void);
|
void popup_redraw_all(void);
|
||||||
|
int popup_need_redraw(void);
|
||||||
void f_popup_clear(typval_T *argvars, typval_T *rettv);
|
void f_popup_clear(typval_T *argvars, typval_T *rettv);
|
||||||
void f_popup_create(typval_T *argvars, typval_T *rettv);
|
void f_popup_create(typval_T *argvars, typval_T *rettv);
|
||||||
void f_popup_atcursor(typval_T *argvars, typval_T *rettv);
|
void f_popup_atcursor(typval_T *argvars, typval_T *rettv);
|
||||||
@@ -53,6 +54,8 @@ int popup_no_mapping(void);
|
|||||||
void popup_check_cursor_pos(void);
|
void popup_check_cursor_pos(void);
|
||||||
void may_update_popup_mask(int type);
|
void may_update_popup_mask(int type);
|
||||||
void may_update_popup_position(void);
|
void may_update_popup_position(void);
|
||||||
|
int popup_get_base_screen_cell(int row, int col, schar_T *linep, int *attrp, u8char_T *ucp);
|
||||||
|
void popup_set_base_screen_cell(int row, int col, schar_T line, int attr, u8char_T uc);
|
||||||
void update_popups(void (*win_update)(win_T *wp));
|
void update_popups(void (*win_update)(win_T *wp));
|
||||||
int set_ref_in_popups(int copyID);
|
int set_ref_in_popups(int copyID);
|
||||||
int popup_is_popup(win_T *wp);
|
int popup_is_popup(win_T *wp);
|
||||||
|
|||||||
+47
-2
@@ -627,6 +627,7 @@ screen_line(
|
|||||||
&& ScreenLines[off_from] == ' '
|
&& ScreenLines[off_from] == ' '
|
||||||
&& (!enc_utf8 || ScreenLinesUC[off_from] == 0)
|
&& (!enc_utf8 || ScreenLinesUC[off_from] == 0)
|
||||||
&& ScreenLines[off_to] == 0
|
&& ScreenLines[off_to] == 0
|
||||||
|
&& (!enc_utf8 || ScreenLinesUC[off_to] == 0)
|
||||||
&& off_to > 0
|
&& off_to > 0
|
||||||
&& enc_utf8 && ScreenLinesUC[off_to - 1] != 0
|
&& enc_utf8 && ScreenLinesUC[off_to - 1] != 0
|
||||||
&& utf_char2cells(ScreenLinesUC[off_to - 1]) == 2)
|
&& utf_char2cells(ScreenLinesUC[off_to - 1]) == 2)
|
||||||
@@ -639,7 +640,8 @@ screen_line(
|
|||||||
&& (flags & SLF_POPUP)
|
&& (flags & SLF_POPUP)
|
||||||
&& ScreenLines[off_from] == ' '
|
&& ScreenLines[off_from] == ' '
|
||||||
&& (!enc_utf8 || ScreenLinesUC[off_from] == 0)
|
&& (!enc_utf8 || ScreenLinesUC[off_from] == 0)
|
||||||
&& ScreenLines[off_to] != 0)
|
&& (ScreenLines[off_to] != 0
|
||||||
|
|| (enc_utf8 && ScreenLinesUC[off_to] != 0)))
|
||||||
{
|
{
|
||||||
int bg_char_cells = 1;
|
int bg_char_cells = 1;
|
||||||
if (enc_utf8 && ScreenLinesUC[off_to] != 0)
|
if (enc_utf8 && ScreenLinesUC[off_to] != 0)
|
||||||
@@ -652,8 +654,23 @@ screen_line(
|
|||||||
{
|
{
|
||||||
if (col + 1 >= endcol || off_from + 1 >= max_off_from
|
if (col + 1 >= endcol || off_from + 1 >= max_off_from
|
||||||
|| off_to + 1 >= max_off_to)
|
|| off_to + 1 >= max_off_to)
|
||||||
// At the edge of the screen, skip wide char.
|
{
|
||||||
|
// Wide char doesn't fit at the edge. Replace with a
|
||||||
|
// blended space so opacity is still applied.
|
||||||
|
int char_attr = ScreenAttrs[off_from];
|
||||||
|
int popup_attr = get_wcr_attr(screen_opacity_popup);
|
||||||
|
int combined = hl_combine_attr(popup_attr, char_attr);
|
||||||
|
int blend = screen_opacity_popup->w_popup_blend;
|
||||||
|
ScreenLines[off_to] = ' ';
|
||||||
|
if (enc_utf8)
|
||||||
|
ScreenLinesUC[off_to] = 0;
|
||||||
|
ScreenAttrs[off_to] = hl_blend_attr(ScreenAttrs[off_to],
|
||||||
|
combined, blend, TRUE);
|
||||||
|
screen_char(off_to, row, col + coloff);
|
||||||
|
opacity_blank = TRUE;
|
||||||
|
redraw_this = FALSE;
|
||||||
goto skip_opacity;
|
goto skip_opacity;
|
||||||
|
}
|
||||||
int next_off_from = off_from + 1;
|
int next_off_from = off_from + 1;
|
||||||
if (!(ScreenLines[next_off_from] == ' '
|
if (!(ScreenLines[next_off_from] == ' '
|
||||||
&& (!enc_utf8 || ScreenLinesUC[next_off_from] == 0)))
|
&& (!enc_utf8 || ScreenLinesUC[next_off_from] == 0)))
|
||||||
@@ -681,6 +698,30 @@ screen_line(
|
|||||||
ScreenAttrs[off_to + 1] = ScreenAttrs[off_to];
|
ScreenAttrs[off_to + 1] = ScreenAttrs[off_to];
|
||||||
redraw_this = FALSE;
|
redraw_this = FALSE;
|
||||||
}
|
}
|
||||||
|
// When a popup space overlaps the second half of a destroyed wide
|
||||||
|
// character (e.g., the first half was overwritten by popup content),
|
||||||
|
// the underlying cell has ScreenLines == 0 and no valid wide char
|
||||||
|
// at the previous cell. Apply opacity blending so that the cell
|
||||||
|
// matches surrounding opacity-blended cells instead of appearing
|
||||||
|
// as a solid-colored gap.
|
||||||
|
else if (screen_opacity_popup != NULL
|
||||||
|
&& (flags & SLF_POPUP)
|
||||||
|
&& ScreenLines[off_from] == ' '
|
||||||
|
&& (!enc_utf8 || ScreenLinesUC[off_from] == 0)
|
||||||
|
&& ScreenLines[off_to] == 0
|
||||||
|
&& (!enc_utf8 || ScreenLinesUC[off_to] == 0))
|
||||||
|
{
|
||||||
|
int char_attr = ScreenAttrs[off_from];
|
||||||
|
int popup_attr = get_wcr_attr(screen_opacity_popup);
|
||||||
|
int combined = hl_combine_attr(popup_attr, char_attr);
|
||||||
|
int blend = screen_opacity_popup->w_popup_blend;
|
||||||
|
ScreenLines[off_to] = ' ';
|
||||||
|
ScreenAttrs[off_to] = hl_blend_attr(ScreenAttrs[off_to],
|
||||||
|
combined, blend, TRUE);
|
||||||
|
screen_char(off_to, row, col + coloff);
|
||||||
|
opacity_blank = TRUE;
|
||||||
|
redraw_this = FALSE;
|
||||||
|
}
|
||||||
skip_opacity:
|
skip_opacity:
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -784,7 +825,11 @@ skip_opacity:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (char_cells == 2)
|
if (char_cells == 2)
|
||||||
|
{
|
||||||
ScreenLines[off_to + 1] = ScreenLines[off_from + 1];
|
ScreenLines[off_to + 1] = ScreenLines[off_from + 1];
|
||||||
|
if (enc_utf8)
|
||||||
|
ScreenLinesUC[off_to + 1] = 0;
|
||||||
|
}
|
||||||
|
|
||||||
#if defined(FEAT_GUI) || defined(UNIX)
|
#if defined(FEAT_GUI) || defined(UNIX)
|
||||||
// The bold trick makes a single column of pixels appear in the
|
// The bold trick makes a single column of pixels appear in the
|
||||||
|
|||||||
@@ -4085,6 +4085,7 @@ struct window_S
|
|||||||
int w_popup_padding[4]; // popup padding top/right/bot/left
|
int w_popup_padding[4]; // popup padding top/right/bot/left
|
||||||
int w_popup_border[4]; // popup border top/right/bot/left
|
int w_popup_border[4]; // popup border top/right/bot/left
|
||||||
char_u *w_border_highlight[4]; // popup border highlight
|
char_u *w_border_highlight[4]; // popup border highlight
|
||||||
|
int w_border_highlight_isset; // borderhighlight was explicitly set
|
||||||
int w_border_char[8]; // popup border characters
|
int w_border_char[8]; // popup border characters
|
||||||
int w_popup_shadow; // popup shadow (right and bottom edges)
|
int w_popup_shadow; // popup shadow (right and bottom edges)
|
||||||
|
|
||||||
|
|||||||
@@ -10,4 +10,4 @@
|
|||||||
|1|2|3|4|5|6|7|8|9|1|0|1@2|2|1|3|1|4|1|5|1|6|1|7|1|8|1|9|2|0|2|1|2@2|3|2|4|2|5|2|6|2|7|2|8|2|9|3|0|3|1|3|2|3@2|4|3|5|3|6|3|7|3|8|3|9|4|0|4|1|4|2
|
|1|2|3|4|5|6|7|8|9|1|0|1@2|2|1|3|1|4|1|5|1|6|1|7|1|8|1|9|2|0|2|1|2@2|3|2|4|2|5|2|6|2|7|2|8|2|9|3|0|3|1|3|2|3@2|4|3|5|3|6|3|7|3|8|3|9|4|0|4|1|4|2
|
||||||
| +0&#e0e0e08@11|1+0&#ffffff0@1|2|1|3|1|4|1|5|1|6|1|7|1|8|1|9|2|0|2|1|2@2|3|2|4|2|5|2|6|═+0#0000001#ffd7ff255@13|X|4+0#0000000#ffffff0|3|5|3|6|3|7|3|8|3|9|4|0|4|1|4|2
|
| +0&#e0e0e08@11|1+0&#ffffff0@1|2|1|3|1|4|1|5|1|6|1|7|1|8|1|9|2|0|2|1|2@2|3|2|4|2|5|2|6|═+0#0000001#ffd7ff255@13|X|4+0#0000000#ffffff0|3|5|3|6|3|7|3|8|3|9|4|0|4|1|4|2
|
||||||
|o+0&#e0e0e08|m|e| |t|e|x|t| @3|1+0&#ffffff0@1|2|1|3|1|4|1|5|1|6|1|7|1|8|1|9|2|0|2|1|2@2|3|2|4|2|5|║+0#0000001#ffd7ff255| @4|2+0#0000000#ffffff0|9|3| +0#0000001#ffd7ff255@6|║|4+0#0000000#ffffff0|3|5|3|6|3|7|3|8|3|9|4|0|4|1|4|2
|
|o+0&#e0e0e08|m|e| |t|e|x|t| @3|1+0&#ffffff0@1|2|1|3|1|4|1|5|1|6|1|7|1|8|1|9|2|0|2|1|2@2|3|2|4|2|5|║+0#0000001#ffd7ff255| @4|2+0#0000000#ffffff0|9|3| +0#0000001#ffd7ff255@6|║|4+0#0000000#ffffff0|3|5|3|6|3|7|3|8|3|9|4|0|4|1|4|2
|
||||||
|n+0&#e0e0e08|o|t|h|e|r| |l|i|n|e| | +0&#ffffff0@28|║+0#0000001#ffd7ff255| |j|u|s|t| |o|n|e| |l|i|n|e| |║|,+0#0000000#ffffff0|1| @10|T|o|p|
|
|:| |t+0&#e0e0e08|h| +0&#ffffff0@2|l+0&#e0e0e08|i|n|e| | +0&#ffffff0@28|║+0#0000001#ffd7ff255| |j|u|s|t| +0#0000000#ffffff0@2|e+0#0000001#ffd7ff255| |l|i|n|e| |║|,+0#0000000#ffffff0|1| @10|T|o|p|
|
||||||
|
|||||||
@@ -0,0 +1,15 @@
|
|||||||
|
>い*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
|
||||||
|
|い*&|え|ー@15|い|!+&| |1@1| @2
|
||||||
|
|い*&|え|ー@15|い|!+&| |1|2| @2
|
||||||
|
|い*&|え|ー@15|い|!+&| |1|3| @2
|
||||||
|
|い*&|え|ー@15|い|!+&| |1|4| @2
|
||||||
|
@27|1|,|1| @10|T|o|p|
|
||||||
@@ -0,0 +1,15 @@
|
|||||||
|
>い*0&#ffffff0|え|ー@15|い|!+&| |1| @3
|
||||||
|
|い*&|え|ー@15|い|!+&| |2| @3
|
||||||
|
|い*&|え|ー@15|い|!+&| |3| @3
|
||||||
|
|い*&|え|ー@15|い|!+&| |4| @3
|
||||||
|
|い*&|え|ー@15|い|!+&| |5| @3
|
||||||
|
|い*&| +&|╭+0#ffffff16#0000e05|─@13|╮| +0#0000000#ffffff0|ー*&@7|い|!+&| |6| @3
|
||||||
|
|い*&| +&|│+0#ffffff16#0000e05|あ*&|め|ん|ぼ|赤|い|な|│+&| +0#0000000#ffffff0|ー*&@7|い|!+&| |7| @3
|
||||||
|
|い*&| +&|│+0#ffffff16#0000e05|あ*&|い|う|え|お| +&| +0&#e000002|ー*&|│+&| |ー*&@5|ー*0#0000000#ffffff0@1|い|!+&| |8| @3
|
||||||
|
|い*&| +&|│+0#ffffff16#0000e05|ー*&@4| +&| +0&#e000002|カ*&|ラ|フ|ル|な|ー@2|ー*0#0000000#ffffff0@1|い|!+&| |9| @3
|
||||||
|
|い*&| +&|╰+0#ffffff16#0000e05|─@10|─+0&#e000002|ポ*&|ッ|プ|ア|ッ|プ|で|ー|ー*0#0000000#ffffff0@1|い|!+&| |1|0| @2
|
||||||
|
|い*&|え|ー@4| +&| +0#ffffff16#e000002|最*&|上|川|ー@4|ー*0#0000000#ffffff0@1|い|!+&| |1@1| @2
|
||||||
|
|い*&|え|ー@4| +&| +0#ffffff16#e000002|ー*&@7|ー*0#0000000#ffffff0@1|い|!+&| |1|2| @2
|
||||||
|
|い*&|え|ー@15|い|!+&| |1|3| @2
|
||||||
|
|い*&|え|ー@15|い|!+&| |1|4| @2
|
||||||
|
|:| @25|1|,|1| @10|T|o|p|
|
||||||
@@ -176,6 +176,11 @@ func Test_popup_with_border_and_padding()
|
|||||||
call popup_setoptions(winid, options)
|
call popup_setoptions(winid, options)
|
||||||
call assert_equal(options, popup_getoptions(winid))
|
call assert_equal(options, popup_getoptions(winid))
|
||||||
|
|
||||||
|
" Check that borderhighlight can be cleared with empty list
|
||||||
|
call popup_setoptions(winid, #{borderhighlight: []})
|
||||||
|
let options_cleared = popup_getoptions(winid)
|
||||||
|
call assert_equal([], options_cleared.borderhighlight)
|
||||||
|
|
||||||
" Check that range() doesn't crash
|
" Check that range() doesn't crash
|
||||||
call popup_setoptions(winid, #{
|
call popup_setoptions(winid, #{
|
||||||
\ padding: range(1, 4),
|
\ padding: range(1, 4),
|
||||||
@@ -4845,4 +4850,53 @@ func Test_popup_getwininfo_tabnr()
|
|||||||
tabonly
|
tabonly
|
||||||
endfunc
|
endfunc
|
||||||
|
|
||||||
|
func Test_popup_opacity_wide_char_overlap()
|
||||||
|
CheckScreendump
|
||||||
|
|
||||||
|
" Two overlapping popups with opacity over wide-character background.
|
||||||
|
" Verifies that wide characters at the content/padding boundary of the
|
||||||
|
" higher-zindex popup are properly blended (no holes or missing chars).
|
||||||
|
let lines =<< trim END
|
||||||
|
set encoding=utf-8
|
||||||
|
for i in range(1, 20)
|
||||||
|
call setline(i, 'いえーーーーーーーーーーーーーーーーい! ' .. i)
|
||||||
|
endfor
|
||||||
|
hi MyPopup1 ctermbg=darkblue ctermfg=white
|
||||||
|
hi MyPopup2 ctermbg=darkred ctermfg=white
|
||||||
|
let g:p1 = popup_create(['あめんぼ赤いな','あいうえお'], #{
|
||||||
|
\ opacity: 50,
|
||||||
|
\ line: 6,
|
||||||
|
\ col: 4,
|
||||||
|
\ border: [],
|
||||||
|
\ borderchars: ['─','│','─','│','╭','╮','╯','╰'],
|
||||||
|
\ minwidth: 14,
|
||||||
|
\ minheight: 3,
|
||||||
|
\ highlight: 'MyPopup1',
|
||||||
|
\ zindex: 1,
|
||||||
|
\})
|
||||||
|
let g:p2 = popup_create(['カラフルな','ポップアップで','最上川'], #{
|
||||||
|
\ opacity: 50,
|
||||||
|
\ line: 4,
|
||||||
|
\ col: 3,
|
||||||
|
\ minwidth: 15,
|
||||||
|
\ minheight: 3,
|
||||||
|
\ padding: [1,1,1,1],
|
||||||
|
\ highlight: 'MyPopup2',
|
||||||
|
\ zindex: 2,
|
||||||
|
\})
|
||||||
|
END
|
||||||
|
call writefile(lines, 'XtestPopupOpacityWide', 'D')
|
||||||
|
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>")
|
||||||
|
call TermWait(buf)
|
||||||
|
call term_sendkeys(buf, ":\<CR>")
|
||||||
|
call VerifyScreenDump(buf, 'Test_popupwin_opacity_wide_2', {})
|
||||||
|
|
||||||
|
call StopVimInTerminal(buf)
|
||||||
|
endfunc
|
||||||
|
|
||||||
" vim: shiftwidth=2 sts=2
|
" vim: shiftwidth=2 sts=2
|
||||||
|
|||||||
@@ -734,6 +734,8 @@ static char *(features[]) =
|
|||||||
|
|
||||||
static int included_patches[] =
|
static int included_patches[] =
|
||||||
{ /* Add new patch number below this line */
|
{ /* Add new patch number below this line */
|
||||||
|
/**/
|
||||||
|
80,
|
||||||
/**/
|
/**/
|
||||||
79,
|
79,
|
||||||
/**/
|
/**/
|
||||||
|
|||||||
Reference in New Issue
Block a user