comparison src/popupwin.c @ 17235:2a97167854fc v8.1.1617

patch 8.1.1617: no test for popup window with mask and position fixed commit https://github.com/vim/vim/commit/d529ba58dc7566833546e4beb5c4c50d8b78816a Author: Bram Moolenaar <Bram@vim.org> Date: Tue Jul 2 23:13:53 2019 +0200 patch 8.1.1617: no test for popup window with mask and position fixed Problem: No test for popup window with mask and position fixed. Solution: Add a couple of screenshots. Fix deteced problems.
author Bram Moolenaar <Bram@vim.org>
date Tue, 02 Jul 2019 23:15:06 +0200
parents e9ebf3f27af6
children 3ada3d207b33
comparison
equal deleted inserted replaced
17234:7f61c9065eea 17235:2a97167854fc
698 } 698 }
699 } 699 }
700 } 700 }
701 701
702 /* 702 /*
703 * Return the height of popup window "wp", including border and padding.
704 */
705 int
706 popup_height(win_T *wp)
707 {
708 return wp->w_height
709 + wp->w_popup_padding[0] + wp->w_popup_border[0]
710 + wp->w_popup_padding[2] + wp->w_popup_border[2];
711 }
712
713 /*
714 * Return the width of popup window "wp", including border and padding.
715 */
716 int
717 popup_width(win_T *wp)
718 {
719 return wp->w_width
720 + wp->w_popup_padding[3] + wp->w_popup_border[3]
721 + wp->w_popup_padding[1] + wp->w_popup_border[1]
722 + wp->w_has_scrollbar;
723 }
724
725 /*
726 * Get the padding plus border at the top, adjusted to 1 if there is a title. 703 * Get the padding plus border at the top, adjusted to 1 if there is a title.
727 */ 704 */
728 static int 705 static int
729 popup_top_extra(win_T *wp) 706 popup_top_extra(win_T *wp)
730 { 707 {
734 return 1; 711 return 1;
735 return extra; 712 return extra;
736 } 713 }
737 714
738 /* 715 /*
716 * Return the height of popup window "wp", including border and padding.
717 */
718 int
719 popup_height(win_T *wp)
720 {
721 return wp->w_height
722 + popup_top_extra(wp)
723 + wp->w_popup_padding[2] + wp->w_popup_border[2];
724 }
725
726 /*
727 * Return the width of popup window "wp", including border, padding and
728 * scrollbar.
729 */
730 int
731 popup_width(win_T *wp)
732 {
733 return wp->w_width + wp->w_leftcol
734 + wp->w_popup_padding[3] + wp->w_popup_border[3]
735 + wp->w_popup_padding[1] + wp->w_popup_border[1]
736 + wp->w_has_scrollbar
737 + wp->w_popup_rightoff;
738 }
739
740 /*
739 * Adjust the position and size of the popup to fit on the screen. 741 * Adjust the position and size of the popup to fit on the screen.
740 */ 742 */
741 void 743 void
742 popup_adjust_position(win_T *wp) 744 popup_adjust_position(win_T *wp)
743 { 745 {
744 linenr_T lnum; 746 linenr_T lnum;
745 int wrapped = 0; 747 int wrapped = 0;
746 int maxwidth; 748 int maxwidth;
749 int maxspace;
747 int center_vert = FALSE; 750 int center_vert = FALSE;
748 int center_hor = FALSE; 751 int center_hor = FALSE;
749 int allow_adjust_left = !wp->w_popup_fixed; 752 int allow_adjust_left = !wp->w_popup_fixed;
750 int top_extra = popup_top_extra(wp); 753 int top_extra = popup_top_extra(wp);
751 int right_extra = wp->w_popup_border[1] + wp->w_popup_padding[1]; 754 int right_extra = wp->w_popup_border[1] + wp->w_popup_padding[1];
756 int org_winrow = wp->w_winrow; 759 int org_winrow = wp->w_winrow;
757 int org_wincol = wp->w_wincol; 760 int org_wincol = wp->w_wincol;
758 int org_width = wp->w_width; 761 int org_width = wp->w_width;
759 int org_height = wp->w_height; 762 int org_height = wp->w_height;
760 int org_leftcol = wp->w_leftcol; 763 int org_leftcol = wp->w_leftcol;
764 int org_leftoff = wp->w_popup_leftoff;
761 int minwidth; 765 int minwidth;
762 766
763 wp->w_winrow = 0; 767 wp->w_winrow = 0;
764 wp->w_wincol = 0; 768 wp->w_wincol = 0;
765 wp->w_leftcol = 0; 769 wp->w_leftcol = 0;
770 wp->w_popup_leftoff = 0;
771 wp->w_popup_rightoff = 0;
766 if (wp->w_popup_pos == POPPOS_CENTER) 772 if (wp->w_popup_pos == POPPOS_CENTER)
767 { 773 {
768 // center after computing the size 774 // center after computing the size
769 center_vert = TRUE; 775 center_vert = TRUE;
770 center_hor = TRUE; 776 center_hor = TRUE;
793 } 799 }
794 800
795 // When centering or right aligned, use maximum width. 801 // When centering or right aligned, use maximum width.
796 // When left aligned use the space available, but shift to the left when we 802 // When left aligned use the space available, but shift to the left when we
797 // hit the right of the screen. 803 // hit the right of the screen.
798 maxwidth = Columns - wp->w_wincol - left_extra; 804 maxspace = Columns - wp->w_wincol - left_extra;
805 maxwidth = maxspace;
799 if (wp->w_maxwidth > 0 && maxwidth > wp->w_maxwidth) 806 if (wp->w_maxwidth > 0 && maxwidth > wp->w_maxwidth)
800 { 807 {
801 allow_adjust_left = FALSE; 808 allow_adjust_left = FALSE;
802 maxwidth = wp->w_maxwidth; 809 maxwidth = wp->w_maxwidth;
803 } 810 }
866 } 873 }
867 874
868 if (minwidth > 0 && wp->w_width < minwidth) 875 if (minwidth > 0 && wp->w_width < minwidth)
869 wp->w_width = minwidth; 876 wp->w_width = minwidth;
870 if (wp->w_width > maxwidth) 877 if (wp->w_width > maxwidth)
878 {
879 if (wp->w_width > maxspace)
880 // some columns cut off on the right
881 wp->w_popup_rightoff = wp->w_width - maxspace;
871 wp->w_width = maxwidth; 882 wp->w_width = maxwidth;
883 }
872 if (center_hor) 884 if (center_hor)
873 { 885 {
874 wp->w_wincol = (Columns - wp->w_width - extra_width) / 2; 886 wp->w_wincol = (Columns - wp->w_width - extra_width) / 2;
875 if (wp->w_wincol < 0) 887 if (wp->w_wincol < 0)
876 wp->w_wincol = 0; 888 wp->w_wincol = 0;
885 if (leftoff >= 0) 897 if (leftoff >= 0)
886 wp->w_wincol = leftoff; 898 wp->w_wincol = leftoff;
887 else if (wp->w_popup_fixed) 899 else if (wp->w_popup_fixed)
888 { 900 {
889 // "col" specifies the right edge, but popup doesn't fit, skip some 901 // "col" specifies the right edge, but popup doesn't fit, skip some
890 // columns when displaying the window. 902 // columns when displaying the window, minus left border and
891 wp->w_leftcol = -leftoff; 903 // padding.
892 wp->w_width += leftoff; 904 if (-leftoff > left_extra)
905 wp->w_leftcol = -leftoff - left_extra;
906 wp->w_width -= wp->w_leftcol;
907 wp->w_popup_leftoff = -leftoff;
893 if (wp->w_width < 0) 908 if (wp->w_width < 0)
894 wp->w_width = 0; 909 wp->w_width = 0;
895 } 910 }
896 } 911 }
897 912
926 // Need to update popup_mask if the position or size changed. 941 // Need to update popup_mask if the position or size changed.
927 // And redraw windows that were behind the popup. 942 // And redraw windows that were behind the popup.
928 if (org_winrow != wp->w_winrow 943 if (org_winrow != wp->w_winrow
929 || org_wincol != wp->w_wincol 944 || org_wincol != wp->w_wincol
930 || org_leftcol != wp->w_leftcol 945 || org_leftcol != wp->w_leftcol
946 || org_leftoff != wp->w_popup_leftoff
931 || org_width != wp->w_width 947 || org_width != wp->w_width
932 || org_height != wp->w_height) 948 || org_height != wp->w_height)
933 { 949 {
934 redraw_all_later(VALID); 950 redraw_all_later(VALID);
935 popup_mask_refresh = TRUE; 951 popup_mask_refresh = TRUE;
2064 * "col" and "line" are screen coordinates. 2080 * "col" and "line" are screen coordinates.
2065 */ 2081 */
2066 static int 2082 static int
2067 popup_masked(win_T *wp, int screencol, int screenline) 2083 popup_masked(win_T *wp, int screencol, int screenline)
2068 { 2084 {
2069 int col = screencol - wp->w_wincol + 1 + wp->w_leftcol; 2085 int col = screencol - wp->w_wincol + 1 + wp->w_popup_leftoff;
2070 int line = screenline - wp->w_winrow + 1; 2086 int line = screenline - wp->w_winrow + 1;
2071 listitem_T *lio, *li; 2087 listitem_T *lio, *li;
2072 int width, height; 2088 int width, height;
2073 2089
2074 if (wp->w_popup_mask == NULL) 2090 if (wp->w_popup_mask == NULL)
2143 linee = tv_get_number(&li->li_tv); 2159 linee = tv_get_number(&li->li_tv);
2144 if (linee < 0) 2160 if (linee < 0)
2145 linee = height + linee + 1; 2161 linee = height + linee + 1;
2146 2162
2147 --cols; 2163 --cols;
2148 cols -= wp->w_leftcol; 2164 cols -= wp->w_popup_leftoff;
2149 if (cols < 0) 2165 if (cols < 0)
2150 cols = 0; 2166 cols = 0;
2151 cole -= wp->w_leftcol; 2167 cole -= wp->w_popup_leftoff;
2152 --lines; 2168 --lines;
2153 if (lines < 0) 2169 if (lines < 0)
2154 lines = 0; 2170 lines = 0;
2155 for (line = lines; line < linee && line < screen_Rows; ++line) 2171 for (line = lines; line < linee && line < screen_Rows; ++line)
2156 for (col = cols; col < cole && col < screen_Columns; ++col) 2172 for (col = cols; col < cole && col < screen_Columns; ++col)
2213 // so that the window with a higher zindex overwrites the value in 2229 // so that the window with a higher zindex overwrites the value in
2214 // popup_mask. 2230 // popup_mask.
2215 popup_reset_handled(); 2231 popup_reset_handled();
2216 while ((wp = find_next_popup(TRUE)) != NULL) 2232 while ((wp = find_next_popup(TRUE)) != NULL)
2217 { 2233 {
2218 int height = popup_height(wp); 2234 int height;
2219 int width = popup_width(wp); 2235 int width;
2220 2236
2221 popup_visible = TRUE; 2237 popup_visible = TRUE;
2222 2238
2223 // Recompute the position if the text changed. 2239 // Recompute the position if the text changed.
2224 if (redraw_all 2240 if (redraw_all
2225 || wp->w_popup_last_changedtick != CHANGEDTICK(wp->w_buffer)) 2241 || wp->w_popup_last_changedtick != CHANGEDTICK(wp->w_buffer))
2226 popup_adjust_position(wp); 2242 popup_adjust_position(wp);
2227 2243
2244 height = popup_height(wp);
2245 width = popup_width(wp) - wp->w_popup_leftoff;
2228 for (line = wp->w_winrow; 2246 for (line = wp->w_winrow;
2229 line < wp->w_winrow + height && line < screen_Rows; ++line) 2247 line < wp->w_winrow + height && line < screen_Rows; ++line)
2230 for (col = wp->w_wincol; 2248 for (col = wp->w_wincol;
2231 col < wp->w_wincol + width && col < screen_Columns; ++col) 2249 col < wp->w_wincol + width && col < screen_Columns; ++col)
2232 if (!popup_masked(wp, col, line)) 2250 if (!popup_masked(wp, col, line))
2308 void 2326 void
2309 update_popups(void (*win_update)(win_T *wp)) 2327 update_popups(void (*win_update)(win_T *wp))
2310 { 2328 {
2311 win_T *wp; 2329 win_T *wp;
2312 int top_off; 2330 int top_off;
2313 int left_off; 2331 int left_extra;
2314 int total_width; 2332 int total_width;
2315 int total_height; 2333 int total_height;
2316 int top_padding; 2334 int top_padding;
2317 int popup_attr; 2335 int popup_attr;
2318 int border_attr[4]; 2336 int border_attr[4];
2319 int border_char[8]; 2337 int border_char[8];
2320 char_u buf[MB_MAXBYTES]; 2338 char_u buf[MB_MAXBYTES];
2321 int row; 2339 int row;
2340 int padcol = 0;
2341 int padwidth = 0;
2322 int i; 2342 int i;
2323 int sb_thumb_top = 0; 2343 int sb_thumb_top = 0;
2324 int sb_thumb_height = 0; 2344 int sb_thumb_height = 0;
2325 int attr_scroll = 0; 2345 int attr_scroll = 0;
2326 int attr_thumb = 0; 2346 int attr_thumb = 0;
2340 update_popup_transparent(wp, 1); 2360 update_popup_transparent(wp, 1);
2341 2361
2342 // adjust w_winrow and w_wincol for border and padding, since 2362 // adjust w_winrow and w_wincol for border and padding, since
2343 // win_update() doesn't handle them. 2363 // win_update() doesn't handle them.
2344 top_off = popup_top_extra(wp); 2364 top_off = popup_top_extra(wp);
2345 left_off = wp->w_popup_padding[3] + wp->w_popup_border[3]; 2365 left_extra = wp->w_popup_padding[3] + wp->w_popup_border[3]
2366 - wp->w_popup_leftoff;
2367 if (wp->w_wincol + left_extra < 0)
2368 left_extra = -wp->w_wincol;
2346 wp->w_winrow += top_off; 2369 wp->w_winrow += top_off;
2347 wp->w_wincol += left_off; 2370 wp->w_wincol += left_extra;
2348 2371
2349 // Draw the popup text, unless it's off screen. 2372 // Draw the popup text, unless it's off screen.
2350 if (wp->w_winrow < screen_Rows && wp->w_wincol < screen_Columns) 2373 if (wp->w_winrow < screen_Rows && wp->w_wincol < screen_Columns)
2351 win_update(wp); 2374 win_update(wp);
2352 2375
2353 wp->w_winrow -= top_off; 2376 wp->w_winrow -= top_off;
2354 wp->w_wincol -= left_off; 2377 wp->w_wincol -= left_extra;
2355 2378
2356 total_width = wp->w_popup_border[3] + wp->w_popup_padding[3] 2379 total_width = popup_width(wp);
2357 + wp->w_width + wp->w_popup_padding[1] + wp->w_popup_border[1] 2380 total_height = popup_height(wp);
2358 + wp->w_has_scrollbar;
2359 total_height = popup_top_extra(wp)
2360 + wp->w_height + wp->w_popup_padding[2] + wp->w_popup_border[2];
2361 popup_attr = get_wcr_attr(wp); 2381 popup_attr = get_wcr_attr(wp);
2362 2382
2363 // We can only use these line drawing characters when 'encoding' is 2383 // We can only use these line drawing characters when 'encoding' is
2364 // "utf-8" and 'ambiwidth' is "single". 2384 // "utf-8" and 'ambiwidth' is "single".
2365 if (enc_utf8 && *p_ambw == 's') 2385 if (enc_utf8 && *p_ambw == 's')
2407 } 2427 }
2408 } 2428 }
2409 else if (wp->w_popup_padding[0] == 0 && popup_top_extra(wp) > 0) 2429 else if (wp->w_popup_padding[0] == 0 && popup_top_extra(wp) > 0)
2410 top_padding = 1; 2430 top_padding = 1;
2411 2431
2432 if (top_padding > 0 || wp->w_popup_padding[2] > 0)
2433 {
2434 padcol = wp->w_wincol - wp->w_popup_leftoff + wp->w_popup_border[3];
2435 padwidth = wp->w_wincol + total_width - wp->w_popup_border[1]
2436 - wp->w_has_scrollbar;
2437 if (padcol < 0)
2438 {
2439 padwidth += padcol;
2440 padcol = 0;
2441 }
2442 }
2412 if (top_padding > 0) 2443 if (top_padding > 0)
2413 { 2444 {
2414 // top padding 2445 // top padding
2415 row = wp->w_winrow + wp->w_popup_border[0]; 2446 row = wp->w_winrow + wp->w_popup_border[0];
2416 screen_fill(row, row + top_padding, 2447 screen_fill(row, row + top_padding, padcol, padwidth,
2417 wp->w_wincol + wp->w_popup_border[3],
2418 wp->w_wincol + total_width - wp->w_popup_border[1]
2419 - wp->w_has_scrollbar,
2420 ' ', ' ', popup_attr); 2448 ' ', ' ', popup_attr);
2421 } 2449 }
2422 2450
2423 // Title goes on top of border or padding. 2451 // Title goes on top of border or padding.
2424 if (wp->w_popup_title != NULL) 2452 if (wp->w_popup_title != NULL)
2448 } 2476 }
2449 2477
2450 for (i = wp->w_popup_border[0]; 2478 for (i = wp->w_popup_border[0];
2451 i < total_height - wp->w_popup_border[2]; ++i) 2479 i < total_height - wp->w_popup_border[2]; ++i)
2452 { 2480 {
2481 int pad_left;
2482 int col = wp->w_wincol - wp->w_popup_leftoff;
2483 // left and right padding only needed next to the body
2484 int do_padding =
2485 i >= wp->w_popup_border[0] + wp->w_popup_padding[0]
2486 && i < total_height - wp->w_popup_border[2]
2487 - wp->w_popup_padding[2];
2488
2453 row = wp->w_winrow + i; 2489 row = wp->w_winrow + i;
2454 2490
2455 // left border 2491 // left border
2456 if (wp->w_popup_border[3] > 0) 2492 if (wp->w_popup_border[3] > 0 && col >= 0)
2457 { 2493 {
2458 buf[mb_char2bytes(border_char[3], buf)] = NUL; 2494 buf[mb_char2bytes(border_char[3], buf)] = NUL;
2459 screen_puts(buf, row, wp->w_wincol, border_attr[3]); 2495 screen_puts(buf, row, col, border_attr[3]);
2460 } 2496 }
2461 // left padding 2497 if (do_padding && wp->w_popup_padding[3] > 0)
2462 if (wp->w_popup_padding[3] > 0) 2498 {
2463 screen_puts(get_spaces(wp->w_popup_padding[3]), row, 2499 // left padding
2464 wp->w_wincol + wp->w_popup_border[3], popup_attr); 2500 col += wp->w_popup_border[3];
2501 pad_left = wp->w_popup_padding[3];
2502 if (col < 0)
2503 {
2504 pad_left += col;
2505 col = 0;
2506 }
2507 if (pad_left > 0)
2508 screen_puts(get_spaces(pad_left), row, col, popup_attr);
2509 }
2465 // scrollbar 2510 // scrollbar
2466 if (wp->w_has_scrollbar) 2511 if (wp->w_has_scrollbar)
2467 { 2512 {
2468 int line = i - top_off; 2513 int line = i - top_off;
2469 int scroll_col = wp->w_wincol + total_width - 1 2514 int scroll_col = wp->w_wincol + total_width - 1
2483 buf[mb_char2bytes(border_char[1], buf)] = NUL; 2528 buf[mb_char2bytes(border_char[1], buf)] = NUL;
2484 screen_puts(buf, row, 2529 screen_puts(buf, row,
2485 wp->w_wincol + total_width - 1, border_attr[1]); 2530 wp->w_wincol + total_width - 1, border_attr[1]);
2486 } 2531 }
2487 // right padding 2532 // right padding
2488 if (wp->w_popup_padding[1] > 0) 2533 if (do_padding && wp->w_popup_padding[1] > 0)
2489 screen_puts(get_spaces(wp->w_popup_padding[1]), row, 2534 screen_puts(get_spaces(wp->w_popup_padding[1]), row,
2490 wp->w_wincol + wp->w_popup_border[3] 2535 wp->w_wincol - wp->w_popup_leftoff
2491 + wp->w_popup_padding[3] + wp->w_width, popup_attr); 2536 + wp->w_popup_border[3]
2537 + wp->w_popup_padding[3] + wp->w_width + wp->w_leftcol,
2538 popup_attr);
2492 } 2539 }
2493 2540
2494 if (wp->w_popup_padding[2] > 0) 2541 if (wp->w_popup_padding[2] > 0)
2495 { 2542 {
2496 // bottom padding 2543 // bottom padding
2497 row = wp->w_winrow + wp->w_popup_border[0] 2544 row = wp->w_winrow + wp->w_popup_border[0]
2498 + wp->w_popup_padding[0] + wp->w_height; 2545 + wp->w_popup_padding[0] + wp->w_height;
2499 screen_fill(row, row + wp->w_popup_padding[2], 2546 screen_fill(row, row + wp->w_popup_padding[2],
2500 wp->w_wincol + wp->w_popup_border[3], 2547 padcol, padwidth, ' ', ' ', popup_attr);
2501 wp->w_wincol + total_width - wp->w_popup_border[1],
2502 ' ', ' ', popup_attr);
2503 } 2548 }
2504 2549
2505 if (wp->w_popup_border[2] > 0) 2550 if (wp->w_popup_border[2] > 0)
2506 { 2551 {
2507 // bottom border 2552 // bottom border