if (di != NULL)
{
nr = dict_get_number(dict, "opacity");
- if (nr > 0 && nr <= 100)
+ if (nr > 0 && nr < 100)
{
- // opacity: 0-100, where 0=transparent, 100=opaque
+ // opacity: 1-99, partially transparent
// Convert to blend (0=opaque, 100=transparent)
wp->w_popup_flags |= POPF_OPACITY;
wp->w_popup_blend = 100 - nr;
}
+ else if (nr == 100)
+ {
+ // Fully opaque, same as no opacity set.
+ wp->w_popup_flags &= ~POPF_OPACITY;
+ wp->w_popup_blend = 0;
+ }
else
{
wp->w_popup_flags &= ~POPF_OPACITY;
wp->w_valid &= ~VALID_BOTLINE;
}
- popup_mask_refresh = TRUE;
+ if (create)
+ popup_mask_refresh = TRUE;
popup_highlight_curline(wp);
return OK;
return;
popup_set_buffer_text(wp->w_buffer, argvars[1]);
- redraw_win_later(wp, UPD_NOT_VALID);
+
+ // Redraw the popup window without triggering a full screen redraw.
+ // Using redraw_win_later() with UPD_NOT_VALID would set the global
+ // must_redraw, causing may_update_popup_mask() to refresh the mask and
+ // redraw windows behind the popup, resulting in flickering.
+ wp->w_redr_type = UPD_NOT_VALID;
+ wp->w_lines_valid = 0;
+ if (must_redraw < UPD_VALID)
+ must_redraw = UPD_VALID;
popup_adjust_position(wp);
}
char_u *old_thumb_highlight;
char_u *old_border_highlight[4];
int need_redraw = FALSE;
+ int need_reposition = FALSE;
int i;
if (in_vim9script()
(void)apply_options(wp, dict, FALSE);
+ // Keep "firstline" sticky across popup_setoptions(): when it is set, any
+ // property update should reapply it and restore the displayed top line.
+ if (wp->w_firstline > 0
+ && wp->w_firstline <= wp->w_buffer->b_ml.ml_line_count)
+ wp->w_topline = wp->w_firstline;
+
// Check if visual options changed and redraw if needed
if (old_firstline != wp->w_firstline)
need_redraw = TRUE;
if (old_zindex != wp->w_zindex)
+ {
need_redraw = TRUE;
+ need_reposition = TRUE;
+ }
if (old_popup_flags != wp->w_popup_flags)
+ {
need_redraw = TRUE;
+ need_reposition = TRUE;
+ }
if (old_scrollbar_highlight != wp->w_scrollbar_highlight)
need_redraw = TRUE;
if (old_thumb_highlight != wp->w_thumb_highlight)
break;
}
- if (need_redraw)
+ if (need_reposition)
+ {
redraw_win_later(wp, UPD_NOT_VALID);
+ popup_mask_refresh = TRUE;
+ }
+ else if (need_redraw)
+ {
+ // Only content changed (e.g. firstline, highlight): redraw the
+ // popup window without updating the popup mask or triggering a
+ // full screen redraw. This avoids flickering of windows behind
+ // the popup.
+ wp->w_redr_type = UPD_NOT_VALID;
+ wp->w_lines_valid = 0;
+ if (must_redraw < UPD_VALID)
+ must_redraw = UPD_VALID;
+ }
+
#ifdef FEAT_PROP_POPUP
// Force redraw if opacity value changed
if (old_blend != wp->w_popup_blend)
redraw_win_later(wp, UPD_NOT_VALID);
// Also redraw windows below the popup
redraw_all_later(UPD_NOT_VALID);
+ popup_mask_refresh = TRUE;
}
#endif
+
+ // Always recalculate popup position/size: other options like border,
+ // close, padding may have changed without affecting w_popup_flags.
+ // popup_adjust_position() only sets popup_mask_refresh when the
+ // position or size actually changed.
popup_adjust_position(wp);
}