@@ -46,6 +46,8 @@ static void may_start_message_win_timer(win_T *wp);
4646static int popup_on_cmdline = FALSE;
4747
4848static void popup_adjust_position (win_T * wp );
49+ static void redraw_under_popup_area (int winrow , int wincol , int height ,
50+ int width , int leftoff );
4951
5052/*
5153 * Get option value for "key", which is "line" or "col".
@@ -3107,6 +3109,14 @@ f_popup_settext(typval_T *argvars, typval_T *rettv UNUSED)
31073109{
31083110 int id ;
31093111 win_T * wp ;
3112+ #ifdef FEAT_PROP_POPUP
3113+ int old_popup_active ;
3114+ #endif
3115+ int old_winrow ;
3116+ int old_wincol ;
3117+ int old_popup_height ;
3118+ int old_popup_width ;
3119+ int old_popup_leftoff ;
31103120
31113121 if (in_vim9script ()
31123122 && (check_for_number_arg (argvars , 0 ) == FAIL
@@ -3118,6 +3128,16 @@ f_popup_settext(typval_T *argvars, typval_T *rettv UNUSED)
31183128 if (wp == NULL )
31193129 return ;
31203130
3131+ #ifdef FEAT_PROP_POPUP
3132+ old_popup_active = (wp -> w_popup_flags & POPF_OPACITY )
3133+ && wp -> w_popup_blend > 0 ;
3134+ #endif
3135+ old_winrow = wp -> w_winrow ;
3136+ old_wincol = wp -> w_wincol ;
3137+ old_popup_height = popup_height (wp );
3138+ old_popup_width = popup_width (wp );
3139+ old_popup_leftoff = wp -> w_popup_leftoff ;
3140+
31213141 if (check_for_string_or_list_arg (argvars , 1 ) == FAIL )
31223142 return ;
31233143
@@ -3132,6 +3152,17 @@ f_popup_settext(typval_T *argvars, typval_T *rettv UNUSED)
31323152 if (must_redraw < UPD_VALID )
31333153 must_redraw = UPD_VALID ;
31343154 popup_adjust_position (wp );
3155+
3156+ #ifdef FEAT_PROP_POPUP
3157+ if (old_popup_active
3158+ && (old_winrow != wp -> w_winrow
3159+ || old_wincol != wp -> w_wincol
3160+ || old_popup_height != popup_height (wp )
3161+ || old_popup_width != popup_width (wp )
3162+ || old_popup_leftoff != wp -> w_popup_leftoff ))
3163+ redraw_under_popup_area (old_winrow , old_wincol ,
3164+ old_popup_height , old_popup_width , old_popup_leftoff );
3165+ #endif
31353166}
31363167
31373168/*
@@ -3316,6 +3347,49 @@ close_all_popups(int force)
33163347 return ;
33173348}
33183349
3350+ /*
3351+ * Force windows under a popup area to redraw.
3352+ */
3353+ static void
3354+ redraw_under_popup_area (int winrow , int wincol , int height , int width , int leftoff )
3355+ {
3356+ int r ;
3357+
3358+ for (r = winrow ; r < winrow + height && r < screen_Rows ; ++ r )
3359+ {
3360+ int c ;
3361+ win_T * prev_twp = NULL ;
3362+
3363+ if (r >= cmdline_row )
3364+ {
3365+ clear_cmdline = TRUE;
3366+ continue ;
3367+ }
3368+
3369+ for (c = wincol ; c < wincol + width - leftoff && c < screen_Columns ; ++ c )
3370+ {
3371+ int line_cp = r ;
3372+ int col_cp = c ;
3373+ win_T * twp ;
3374+
3375+ twp = mouse_find_win (& line_cp , & col_cp , IGNORE_POPUP );
3376+ if (twp != NULL && twp != prev_twp )
3377+ {
3378+ prev_twp = twp ;
3379+ if (line_cp < twp -> w_height )
3380+ {
3381+ linenr_T lnum ;
3382+
3383+ (void )mouse_comp_pos (twp , & line_cp , & col_cp , & lnum , NULL );
3384+ redrawWinline (twp , lnum );
3385+ }
3386+ else if (line_cp == twp -> w_height )
3387+ twp -> w_redr_status = TRUE;
3388+ }
3389+ }
3390+ }
3391+ }
3392+
33193393/*
33203394 * popup_move({id}, {options})
33213395 */
@@ -3329,6 +3403,9 @@ f_popup_move(typval_T *argvars, typval_T *rettv UNUSED)
33293403 int old_wincol ;
33303404 int old_height ;
33313405 int old_width ;
3406+ int old_popup_height ;
3407+ int old_popup_width ;
3408+ int old_popup_leftoff ;
33323409
33333410 if (in_vim9script ()
33343411 && (check_for_number_arg (argvars , 0 ) == FAIL
@@ -3349,6 +3426,9 @@ f_popup_move(typval_T *argvars, typval_T *rettv UNUSED)
33493426 old_wincol = wp -> w_wincol ;
33503427 old_height = wp -> w_height ;
33513428 old_width = wp -> w_width ;
3429+ old_popup_height = popup_height (wp );
3430+ old_popup_width = popup_width (wp );
3431+ old_popup_leftoff = wp -> w_popup_leftoff ;
33523432
33533433 apply_move_options (wp , dict );
33543434
@@ -3367,39 +3447,8 @@ f_popup_move(typval_T *argvars, typval_T *rettv UNUSED)
33673447 redraw_win_later (wp , UPD_NOT_VALID );
33683448
33693449 if ((wp -> w_popup_flags & POPF_OPACITY ) && wp -> w_popup_blend > 0 )
3370- {
3371- int total_h = old_height + popup_top_extra (wp )
3372- + wp -> w_popup_border [2 ] + wp -> w_popup_padding [2 ];
3373- int row ;
3374-
3375- for (row = old_winrow ;
3376- row < old_winrow + total_h && row < screen_Rows ; ++ row )
3377- {
3378- if (row >= cmdline_row )
3379- clear_cmdline = TRUE;
3380- else
3381- {
3382- int line_cp = row ;
3383- int col_cp = old_wincol ;
3384- win_T * twp ;
3385-
3386- twp = mouse_find_win (& line_cp , & col_cp , IGNORE_POPUP );
3387- if (twp != NULL )
3388- {
3389- if (line_cp >= twp -> w_height )
3390- twp -> w_redr_status = TRUE;
3391- else
3392- {
3393- linenr_T lnum ;
3394-
3395- (void )mouse_comp_pos (twp , & line_cp , & col_cp ,
3396- & lnum , NULL );
3397- redrawWinline (twp , lnum );
3398- }
3399- }
3400- }
3401- }
3402- }
3450+ redraw_under_popup_area (old_winrow , old_wincol ,
3451+ old_popup_height , old_popup_width , old_popup_leftoff );
34033452 }
34043453}
34053454
@@ -3415,7 +3464,13 @@ f_popup_setoptions(typval_T *argvars, typval_T *rettv UNUSED)
34153464 linenr_T old_firstline ;
34163465#ifdef FEAT_PROP_POPUP
34173466 int old_blend ;
3467+ int old_popup_active ;
34183468#endif
3469+ int old_winrow ;
3470+ int old_wincol ;
3471+ int old_popup_height ;
3472+ int old_popup_width ;
3473+ int old_popup_leftoff ;
34193474 int old_zindex ;
34203475 int old_popup_flags ;
34213476 char_u * old_scrollbar_highlight ;
@@ -3441,7 +3496,14 @@ f_popup_setoptions(typval_T *argvars, typval_T *rettv UNUSED)
34413496 old_firstline = wp -> w_firstline ;
34423497#ifdef FEAT_PROP_POPUP
34433498 old_blend = wp -> w_popup_blend ;
3499+ old_popup_active = (wp -> w_popup_flags & POPF_OPACITY )
3500+ && wp -> w_popup_blend > 0 ;
34443501#endif
3502+ old_winrow = wp -> w_winrow ;
3503+ old_wincol = wp -> w_wincol ;
3504+ old_popup_height = popup_height (wp );
3505+ old_popup_width = popup_width (wp );
3506+ old_popup_leftoff = wp -> w_popup_leftoff ;
34453507 old_zindex = wp -> w_zindex ;
34463508 old_popup_flags = wp -> w_popup_flags ;
34473509 old_scrollbar_highlight = wp -> w_scrollbar_highlight ;
@@ -3514,6 +3576,17 @@ f_popup_setoptions(typval_T *argvars, typval_T *rettv UNUSED)
35143576 // popup_adjust_position() only sets popup_mask_refresh when the
35153577 // position or size actually changed.
35163578 popup_adjust_position (wp );
3579+
3580+ #ifdef FEAT_PROP_POPUP
3581+ if (old_popup_active
3582+ && (old_winrow != wp -> w_winrow
3583+ || old_wincol != wp -> w_wincol
3584+ || old_popup_height != popup_height (wp )
3585+ || old_popup_width != popup_width (wp )
3586+ || old_popup_leftoff != wp -> w_popup_leftoff ))
3587+ redraw_under_popup_area (old_winrow , old_wincol ,
3588+ old_popup_height , old_popup_width , old_popup_leftoff );
3589+ #endif
35173590}
35183591
35193592/*
@@ -4755,10 +4828,15 @@ draw_opacity_padding_cell(
47554828 && utf_char2cells (ScreenLinesUC [base_off ]) == 2 )
47564829 {
47574830 // The left half still has the wide char on screen.
4758- // Clear it to a space.
4831+ // Clear it to an unblended space: only the right half is
4832+ // covered by the popup background.
47594833 ScreenLines [base_off ] = ' ' ;
47604834 ScreenLinesUC [base_off ] = 0 ;
47614835 ScreenAttrs [base_off ] = saved_screenattrs [base_save_off ];
4836+ popup_set_base_screen_cell (row , base_col ,
4837+ ScreenLines [base_off ],
4838+ ScreenAttrs [base_off ],
4839+ ScreenLinesUC [base_off ]);
47624840 screen_char (base_off , row , base_col );
47634841
47644842 // Draw padding in the right half.
@@ -4778,43 +4856,6 @@ draw_opacity_padding_cell(
47784856 return ;
47794857 }
47804858
4781- // screen_line() already cleared the base cell (popup
4782- // content was a space). Restore the full wide char from
4783- // saved background so it shows through with opacity.
4784- if (base_save_off >= 0
4785- && saved_screenlinesuc != NULL
4786- && saved_screenlinesuc [base_save_off ] != 0
4787- && utf_char2cells (
4788- saved_screenlinesuc [base_save_off ]) == 2 )
4789- {
4790- ScreenLines [base_off ] =
4791- saved_screenlines [base_save_off ];
4792- ScreenLinesUC [base_off ] =
4793- saved_screenlinesuc [base_save_off ];
4794- ScreenLines [off ] = saved_screenlines [save_off ];
4795- ScreenLinesUC [off ] = saved_screenlinesuc [save_off ];
4796- ScreenAttrs [base_off ] =
4797- saved_screenattrs [base_save_off ];
4798- ScreenAttrs [off ] = saved_screenattrs [save_off ];
4799-
4800- int popup_attr_val =
4801- get_win_attr (screen_opacity_popup );
4802- int blend = screen_opacity_popup -> w_popup_blend ;
4803- ScreenAttrs [base_off ] = hl_blend_attr (
4804- ScreenAttrs [base_off ],
4805- popup_attr_val , blend , TRUE);
4806- ScreenAttrs [off ] = ScreenAttrs [base_off ];
4807- popup_set_base_screen_cell (row , base_col ,
4808- ScreenLines [base_off ],
4809- ScreenAttrs [base_off ],
4810- ScreenLinesUC [base_off ]);
4811- popup_set_base_screen_cell (row , col ,
4812- ScreenLines [off ], ScreenAttrs [off ],
4813- ScreenLinesUC [off ]);
4814- screen_char (base_off , row , base_col );
4815- return ;
4816- }
4817-
48184859 // Draw padding in the right half.
48194860 ScreenLines [off ] = ' ' ;
48204861 ScreenAttrs [off ] = saved_screenattrs [save_off ];
0 commit comments