Mercurial > vim
comparison src/popupwin.c @ 17863:08f1dd29550e v8.1.1928
patch 8.1.1928: popup windows don't move with the text when making changes
Commit: https://github.com/vim/vim/commit/12034e22dd80cf533ac1c681be521ab299383f63
Author: Bram Moolenaar <Bram@vim.org>
Date: Sun Aug 25 22:25:02 2019 +0200
patch 8.1.1928: popup windows don't move with the text when making changes
Problem: Popup windows don't move with the text when making changes.
Solution: Add the 'textprop" property to the popup window options, position
the popup relative to a text property. (closes #4560)
No tests yet.
author | Bram Moolenaar <Bram@vim.org> |
---|---|
date | Sun, 25 Aug 2019 22:30:03 +0200 |
parents | bdddd215bf09 |
children | f13a5c48320b |
comparison
equal
deleted
inserted
replaced
17862:debebb1dcef1 | 17863:08f1dd29550e |
---|---|
71 n = screen_screencol() + 1 + n; | 71 n = screen_screencol() + 1 + n; |
72 | 72 |
73 if (n < 1) | 73 if (n < 1) |
74 n = 1; | 74 n = 1; |
75 return n; | 75 return n; |
76 } | |
77 | |
78 static void | |
79 get_pos_options(win_T *wp, dict_T *dict) | |
80 { | |
81 char_u *str; | |
82 int nr; | |
83 dictitem_T *di; | |
84 | |
85 nr = popup_options_one(dict, (char_u *)"line"); | |
86 if (nr > 0) | |
87 wp->w_wantline = nr; | |
88 nr = popup_options_one(dict, (char_u *)"col"); | |
89 if (nr > 0) | |
90 wp->w_wantcol = nr; | |
91 | |
92 di = dict_find(dict, (char_u *)"fixed", -1); | |
93 if (di != NULL) | |
94 wp->w_popup_fixed = dict_get_number(dict, (char_u *)"fixed") != 0; | |
95 | |
96 str = dict_get_string(dict, (char_u *)"pos", FALSE); | |
97 if (str != NULL) | |
98 { | |
99 for (nr = 0; | |
100 nr < (int)(sizeof(poppos_entries) / sizeof(poppos_entry_T)); | |
101 ++nr) | |
102 if (STRCMP(str, poppos_entries[nr].pp_name) == 0) | |
103 { | |
104 wp->w_popup_pos = poppos_entries[nr].pp_val; | |
105 nr = -1; | |
106 break; | |
107 } | |
108 if (nr != -1) | |
109 semsg(_(e_invarg2), str); | |
110 } | |
111 } | 76 } |
112 | 77 |
113 static void | 78 static void |
114 set_padding_border(dict_T *dict, int *array, char *name, int max_val) | 79 set_padding_border(dict_T *dict, int *array, char *name, int max_val) |
115 { | 80 { |
254 void | 219 void |
255 popup_start_drag(win_T *wp, int row, int col) | 220 popup_start_drag(win_T *wp, int row, int col) |
256 { | 221 { |
257 drag_start_row = mouse_row; | 222 drag_start_row = mouse_row; |
258 drag_start_col = mouse_col; | 223 drag_start_col = mouse_col; |
259 // TODO: handle using different corner | |
260 if (wp->w_wantline == 0) | 224 if (wp->w_wantline == 0) |
261 drag_start_wantline = wp->w_winrow + 1; | 225 drag_start_wantline = wp->w_winrow + 1; |
262 else | 226 else |
263 drag_start_wantline = wp->w_wantline; | 227 drag_start_wantline = wp->w_wantline; |
264 if (wp->w_wantcol == 0) | 228 if (wp->w_wantcol == 0) |
428 * Shared between popup_create() and f_popup_move(). | 392 * Shared between popup_create() and f_popup_move(). |
429 */ | 393 */ |
430 static void | 394 static void |
431 apply_move_options(win_T *wp, dict_T *d) | 395 apply_move_options(win_T *wp, dict_T *d) |
432 { | 396 { |
433 int nr; | 397 int nr; |
398 char_u *str; | |
399 dictitem_T *di; | |
434 | 400 |
435 if ((nr = dict_get_number(d, (char_u *)"minwidth")) > 0) | 401 if ((nr = dict_get_number(d, (char_u *)"minwidth")) > 0) |
436 wp->w_minwidth = nr; | 402 wp->w_minwidth = nr; |
437 if ((nr = dict_get_number(d, (char_u *)"minheight")) > 0) | 403 if ((nr = dict_get_number(d, (char_u *)"minheight")) > 0) |
438 wp->w_minheight = nr; | 404 wp->w_minheight = nr; |
439 if ((nr = dict_get_number(d, (char_u *)"maxwidth")) > 0) | 405 if ((nr = dict_get_number(d, (char_u *)"maxwidth")) > 0) |
440 wp->w_maxwidth = nr; | 406 wp->w_maxwidth = nr; |
441 if ((nr = dict_get_number(d, (char_u *)"maxheight")) > 0) | 407 if ((nr = dict_get_number(d, (char_u *)"maxheight")) > 0) |
442 wp->w_maxheight = nr; | 408 wp->w_maxheight = nr; |
443 get_pos_options(wp, d); | 409 |
410 nr = popup_options_one(d, (char_u *)"line"); | |
411 if (nr > 0) | |
412 wp->w_wantline = nr; | |
413 nr = popup_options_one(d, (char_u *)"col"); | |
414 if (nr > 0) | |
415 wp->w_wantcol = nr; | |
416 | |
417 di = dict_find(d, (char_u *)"fixed", -1); | |
418 if (di != NULL) | |
419 wp->w_popup_fixed = dict_get_number(d, (char_u *)"fixed") != 0; | |
420 | |
421 str = dict_get_string(d, (char_u *)"pos", FALSE); | |
422 if (str != NULL) | |
423 { | |
424 for (nr = 0; | |
425 nr < (int)(sizeof(poppos_entries) / sizeof(poppos_entry_T)); | |
426 ++nr) | |
427 if (STRCMP(str, poppos_entries[nr].pp_name) == 0) | |
428 { | |
429 wp->w_popup_pos = poppos_entries[nr].pp_val; | |
430 nr = -1; | |
431 break; | |
432 } | |
433 if (nr != -1) | |
434 semsg(_(e_invarg2), str); | |
435 } | |
436 | |
437 str = dict_get_string(d, (char_u *)"textprop", FALSE); | |
438 if (str != NULL) | |
439 { | |
440 wp->w_popup_prop_type = 0; | |
441 if (*str != NUL) | |
442 { | |
443 nr = find_prop_type_id(str, wp->w_buffer); | |
444 if (nr <= 0) | |
445 nr = find_prop_type_id(str, NULL); | |
446 if (nr <= 0) | |
447 semsg(_(e_invarg2), str); | |
448 else | |
449 { | |
450 wp->w_popup_prop_type = nr; | |
451 wp->w_popup_prop_win = curwin; | |
452 | |
453 di = dict_find(d, (char_u *)"textpropwin", -1); | |
454 if (di != NULL) | |
455 { | |
456 wp->w_popup_prop_win = find_win_by_nr_or_id(&di->di_tv); | |
457 if (win_valid(wp->w_popup_prop_win)) | |
458 wp->w_popup_prop_win = curwin; | |
459 } | |
460 } | |
461 } | |
462 } | |
463 | |
464 di = dict_find(d, (char_u *)"textpropid", -1); | |
465 if (di != NULL) | |
466 wp->w_popup_prop_id = dict_get_number(d, (char_u *)"textpropid"); | |
444 } | 467 } |
445 | 468 |
446 static void | 469 static void |
447 handle_moved_argument(win_T *wp, dictitem_T *di, int mousemoved) | 470 handle_moved_argument(win_T *wp, dictitem_T *di, int mousemoved) |
448 { | 471 { |
1013 int org_width = wp->w_width; | 1036 int org_width = wp->w_width; |
1014 int org_height = wp->w_height; | 1037 int org_height = wp->w_height; |
1015 int org_leftcol = wp->w_leftcol; | 1038 int org_leftcol = wp->w_leftcol; |
1016 int org_leftoff = wp->w_popup_leftoff; | 1039 int org_leftoff = wp->w_popup_leftoff; |
1017 int minwidth; | 1040 int minwidth; |
1041 int wantline = wp->w_wantline; // adjusted for textprop | |
1042 int wantcol = wp->w_wantcol; // adjusted for textprop | |
1018 | 1043 |
1019 wp->w_winrow = 0; | 1044 wp->w_winrow = 0; |
1020 wp->w_wincol = 0; | 1045 wp->w_wincol = 0; |
1021 wp->w_leftcol = 0; | 1046 wp->w_leftcol = 0; |
1022 wp->w_popup_leftoff = 0; | 1047 wp->w_popup_leftoff = 0; |
1023 wp->w_popup_rightoff = 0; | 1048 wp->w_popup_rightoff = 0; |
1049 | |
1050 // If no line was specified default to vertical centering. | |
1051 if (wantline == 0) | |
1052 center_vert = TRUE; | |
1053 | |
1054 if (wp->w_popup_prop_type > 0 && win_valid(wp->w_popup_prop_win)) | |
1055 { | |
1056 win_T *prop_win = wp->w_popup_prop_win; | |
1057 textprop_T prop; | |
1058 linenr_T prop_lnum; | |
1059 pos_T pos; | |
1060 int screen_row; | |
1061 int screen_scol; | |
1062 int screen_ccol; | |
1063 int screen_ecol; | |
1064 | |
1065 // Popup window is positioned relative to a text property. | |
1066 if (find_visible_prop(prop_win, | |
1067 wp->w_popup_prop_type, wp->w_popup_prop_id, | |
1068 &prop, &prop_lnum) == FAIL) | |
1069 { | |
1070 // Text property is no longer visible, hide the popup. | |
1071 // Unhiding the popup is done in check_popup_unhidden(). | |
1072 if ((wp->w_popup_flags & POPF_HIDDEN) == 0) | |
1073 { | |
1074 wp->w_popup_flags |= POPF_HIDDEN; | |
1075 --wp->w_buffer->b_nwindows; | |
1076 if (win_valid(wp->w_popup_prop_win)) | |
1077 redraw_win_later(wp->w_popup_prop_win, SOME_VALID); | |
1078 } | |
1079 return; | |
1080 } | |
1081 | |
1082 // Compute the desired position from the position of the text | |
1083 // property. Use "wantline" and "wantcol" as offsets. | |
1084 pos.lnum = prop_lnum; | |
1085 pos.col = prop.tp_col; | |
1086 if (wp->w_popup_pos == POPPOS_TOPLEFT | |
1087 || wp->w_popup_pos == POPPOS_BOTLEFT) | |
1088 pos.col += prop.tp_len - 1; | |
1089 textpos2screenpos(prop_win, &pos, &screen_row, | |
1090 &screen_scol, &screen_ccol, &screen_ecol); | |
1091 | |
1092 if (wp->w_popup_pos == POPPOS_TOPLEFT | |
1093 || wp->w_popup_pos == POPPOS_TOPRIGHT) | |
1094 // below the text | |
1095 wantline = screen_row + wantline + 1; | |
1096 else | |
1097 // above the text | |
1098 wantline = screen_row + wantline - 1; | |
1099 center_vert = FALSE; | |
1100 if (wp->w_popup_pos == POPPOS_TOPLEFT | |
1101 || wp->w_popup_pos == POPPOS_BOTLEFT) | |
1102 // right of the text | |
1103 wantcol = screen_ecol + wantcol; | |
1104 else | |
1105 // left of the text | |
1106 wantcol = screen_scol + wantcol - 1; | |
1107 } | |
1108 | |
1024 if (wp->w_popup_pos == POPPOS_CENTER) | 1109 if (wp->w_popup_pos == POPPOS_CENTER) |
1025 { | 1110 { |
1026 // center after computing the size | 1111 // center after computing the size |
1027 center_vert = TRUE; | 1112 center_vert = TRUE; |
1028 center_hor = TRUE; | 1113 center_hor = TRUE; |
1029 } | 1114 } |
1030 else | 1115 else |
1031 { | 1116 { |
1032 if (wp->w_wantline == 0) | 1117 if (wantline != 0 && (wp->w_popup_pos == POPPOS_TOPLEFT |
1033 center_vert = TRUE; | 1118 || wp->w_popup_pos == POPPOS_TOPRIGHT)) |
1034 else if (wp->w_popup_pos == POPPOS_TOPLEFT | 1119 { |
1035 || wp->w_popup_pos == POPPOS_TOPRIGHT) | 1120 wp->w_winrow = wantline - 1; |
1036 { | |
1037 wp->w_winrow = wp->w_wantline - 1; | |
1038 if (wp->w_winrow >= Rows) | 1121 if (wp->w_winrow >= Rows) |
1039 wp->w_winrow = Rows - 1; | 1122 wp->w_winrow = Rows - 1; |
1040 } | 1123 } |
1041 | 1124 |
1042 if (wp->w_wantcol == 0) | 1125 if (wantcol == 0) |
1043 center_hor = TRUE; | 1126 center_hor = TRUE; |
1044 else if (wp->w_popup_pos == POPPOS_TOPLEFT | 1127 else if (wp->w_popup_pos == POPPOS_TOPLEFT |
1045 || wp->w_popup_pos == POPPOS_BOTLEFT) | 1128 || wp->w_popup_pos == POPPOS_BOTLEFT) |
1046 { | 1129 { |
1047 wp->w_wincol = wp->w_wantcol - 1; | 1130 wp->w_wincol = wantcol - 1; |
1048 if (wp->w_wincol >= Columns - 3) | 1131 if (wp->w_wincol >= Columns - 3) |
1049 wp->w_wincol = Columns - 3; | 1132 wp->w_wincol = Columns - 3; |
1050 } | 1133 } |
1051 } | 1134 } |
1052 | 1135 |
1159 wp->w_wincol = 0; | 1242 wp->w_wincol = 0; |
1160 } | 1243 } |
1161 else if (wp->w_popup_pos == POPPOS_BOTRIGHT | 1244 else if (wp->w_popup_pos == POPPOS_BOTRIGHT |
1162 || wp->w_popup_pos == POPPOS_TOPRIGHT) | 1245 || wp->w_popup_pos == POPPOS_TOPRIGHT) |
1163 { | 1246 { |
1164 int leftoff = wp->w_wantcol - (wp->w_width + extra_width); | 1247 int leftoff = wantcol - (wp->w_width + extra_width); |
1165 | 1248 |
1166 // Right aligned: move to the right if needed. | 1249 // Right aligned: move to the right if needed. |
1167 // No truncation, because that would change the height. | 1250 // No truncation, because that would change the height. |
1168 if (leftoff >= 0) | 1251 if (leftoff >= 0) |
1169 wp->w_wincol = leftoff; | 1252 wp->w_wincol = leftoff; |
1214 wp->w_winrow = 0; | 1297 wp->w_winrow = 0; |
1215 } | 1298 } |
1216 else if (wp->w_popup_pos == POPPOS_BOTRIGHT | 1299 else if (wp->w_popup_pos == POPPOS_BOTRIGHT |
1217 || wp->w_popup_pos == POPPOS_BOTLEFT) | 1300 || wp->w_popup_pos == POPPOS_BOTLEFT) |
1218 { | 1301 { |
1219 if ((wp->w_height + extra_height) <= wp->w_wantline) | 1302 if ((wp->w_height + extra_height) <= wantline) |
1220 // bottom aligned: may move down | 1303 // bottom aligned: may move down |
1221 wp->w_winrow = wp->w_wantline - (wp->w_height + extra_height); | 1304 wp->w_winrow = wantline - (wp->w_height + extra_height); |
1222 else | 1305 else |
1223 // not enough space, make top aligned | 1306 // not enough space, make top aligned |
1224 wp->w_winrow = wp->w_wantline + 1; | 1307 wp->w_winrow = wantline + 1; |
1225 } | 1308 } |
1309 if (wp->w_winrow >= Rows) | |
1310 wp->w_winrow = Rows - 1; | |
1311 else if (wp->w_winrow < 0) | |
1312 wp->w_winrow = 0; | |
1226 | 1313 |
1227 wp->w_popup_last_changedtick = CHANGEDTICK(wp->w_buffer); | 1314 wp->w_popup_last_changedtick = CHANGEDTICK(wp->w_buffer); |
1315 if (win_valid(wp->w_popup_prop_win)) | |
1316 { | |
1317 wp->w_popup_prop_changedtick = | |
1318 CHANGEDTICK(wp->w_popup_prop_win->w_buffer); | |
1319 wp->w_popup_prop_topline = wp->w_popup_prop_win->w_topline; | |
1320 } | |
1228 | 1321 |
1229 // Need to update popup_mask if the position or size changed. | 1322 // Need to update popup_mask if the position or size changed. |
1230 // And redraw windows and statuslines that were behind the popup. | 1323 // And redraw windows and statuslines that were behind the popup. |
1231 if (org_winrow != wp->w_winrow | 1324 if (org_winrow != wp->w_winrow |
1232 || org_wincol != wp->w_wincol | 1325 || org_wincol != wp->w_wincol |
1835 invoke_popup_callback(wp, arg); | 1928 invoke_popup_callback(wp, arg); |
1836 | 1929 |
1837 popup_close(id); | 1930 popup_close(id); |
1838 } | 1931 } |
1839 | 1932 |
1933 static void | |
1934 popup_close_with_retval(win_T *wp, int retval) | |
1935 { | |
1936 typval_T res; | |
1937 | |
1938 res.v_type = VAR_NUMBER; | |
1939 res.vval.v_number = retval; | |
1940 popup_close_and_callback(wp, &res); | |
1941 } | |
1942 | |
1840 /* | 1943 /* |
1841 * Close popup "wp" because of a mouse click. | 1944 * Close popup "wp" because of a mouse click. |
1842 */ | 1945 */ |
1843 void | 1946 void |
1844 popup_close_for_mouse_click(win_T *wp) | 1947 popup_close_for_mouse_click(win_T *wp) |
1845 { | 1948 { |
1846 typval_T res; | 1949 popup_close_with_retval(wp, -2); |
1847 | |
1848 res.v_type = VAR_NUMBER; | |
1849 res.vval.v_number = -2; | |
1850 popup_close_and_callback(wp, &res); | |
1851 } | 1950 } |
1852 | 1951 |
1853 static void | 1952 static void |
1854 check_mouse_moved(win_T *wp, win_T *mouse_wp) | 1953 check_mouse_moved(win_T *wp, win_T *mouse_wp) |
1855 { | 1954 { |
1862 && wp->w_popup_mouse_row != 0 | 1961 && wp->w_popup_mouse_row != 0 |
1863 && (wp->w_popup_mouse_row != mouse_row | 1962 && (wp->w_popup_mouse_row != mouse_row |
1864 || mouse_col < wp->w_popup_mouse_mincol | 1963 || mouse_col < wp->w_popup_mouse_mincol |
1865 || mouse_col > wp->w_popup_mouse_maxcol)) | 1964 || mouse_col > wp->w_popup_mouse_maxcol)) |
1866 { | 1965 { |
1867 typval_T res; | |
1868 | |
1869 res.v_type = VAR_NUMBER; | |
1870 res.vval.v_number = -2; | |
1871 // Careful: this makes "wp" invalid. | 1966 // Careful: this makes "wp" invalid. |
1872 popup_close_and_callback(wp, &res); | 1967 popup_close_with_retval(wp, -2); |
1873 } | 1968 } |
1874 } | 1969 } |
1875 | 1970 |
1876 /* | 1971 /* |
1877 * Called when the mouse moved: may close a popup with "mousemoved". | 1972 * Called when the mouse moved: may close a popup with "mousemoved". |
2456 dict_add_number(dict, "maxwidth", wp->w_maxwidth); | 2551 dict_add_number(dict, "maxwidth", wp->w_maxwidth); |
2457 dict_add_number(dict, "firstline", wp->w_firstline); | 2552 dict_add_number(dict, "firstline", wp->w_firstline); |
2458 dict_add_number(dict, "scrollbar", wp->w_want_scrollbar); | 2553 dict_add_number(dict, "scrollbar", wp->w_want_scrollbar); |
2459 dict_add_number(dict, "zindex", wp->w_zindex); | 2554 dict_add_number(dict, "zindex", wp->w_zindex); |
2460 dict_add_number(dict, "fixed", wp->w_popup_fixed); | 2555 dict_add_number(dict, "fixed", wp->w_popup_fixed); |
2556 if (wp->w_popup_prop_type && win_valid(wp->w_popup_prop_win)) | |
2557 { | |
2558 proptype_T *pt = text_prop_type_by_id( | |
2559 wp->w_popup_prop_win->w_buffer, | |
2560 wp->w_popup_prop_type); | |
2561 | |
2562 if (pt != NULL) | |
2563 dict_add_string(dict, "textprop", pt->pt_name); | |
2564 dict_add_number(dict, "textpropwin", wp->w_popup_prop_win->w_id); | |
2565 dict_add_number(dict, "textpropid", wp->w_popup_prop_id); | |
2566 } | |
2461 dict_add_string(dict, "title", wp->w_popup_title); | 2567 dict_add_string(dict, "title", wp->w_popup_title); |
2462 dict_add_number(dict, "wrap", wp->w_p_wrap); | 2568 dict_add_number(dict, "wrap", wp->w_p_wrap); |
2463 dict_add_number(dict, "drag", (wp->w_popup_flags & POPF_DRAG) != 0); | 2569 dict_add_number(dict, "drag", (wp->w_popup_flags & POPF_DRAG) != 0); |
2464 dict_add_number(dict, "mapping", (wp->w_popup_flags & POPF_MAPPING) != 0); | 2570 dict_add_number(dict, "mapping", |
2571 (wp->w_popup_flags & POPF_MAPPING) != 0); | |
2465 dict_add_number(dict, "resize", (wp->w_popup_flags & POPF_RESIZE) != 0); | 2572 dict_add_number(dict, "resize", (wp->w_popup_flags & POPF_RESIZE) != 0); |
2466 dict_add_number(dict, "cursorline", | 2573 dict_add_number(dict, "cursorline", |
2467 (wp->w_popup_flags & POPF_CURSORLINE) != 0); | 2574 (wp->w_popup_flags & POPF_CURSORLINE) != 0); |
2468 dict_add_string(dict, "highlight", wp->w_p_wcr); | 2575 dict_add_string(dict, "highlight", wp->w_p_wcr); |
2469 if (wp->w_scrollbar_highlight != NULL) | 2576 if (wp->w_scrollbar_highlight != NULL) |
2601 linenr_T old_lnum = wp->w_cursor.lnum; | 2708 linenr_T old_lnum = wp->w_cursor.lnum; |
2602 | 2709 |
2603 // Emergency exit: CTRL-C closes the popup. | 2710 // Emergency exit: CTRL-C closes the popup. |
2604 if (c == Ctrl_C) | 2711 if (c == Ctrl_C) |
2605 { | 2712 { |
2606 rettv.v_type = VAR_NUMBER; | 2713 popup_close_with_retval(wp, -1); |
2607 rettv.vval.v_number = -1; | |
2608 popup_close_and_callback(wp, &rettv); | |
2609 return 1; | 2714 return 1; |
2610 } | 2715 } |
2611 | 2716 |
2612 argv[0].v_type = VAR_NUMBER; | 2717 argv[0].v_type = VAR_NUMBER; |
2613 argv[0].vval.v_number = (varnumber_T)wp->w_id; | 2718 argv[0].vval.v_number = (varnumber_T)wp->w_id; |
2685 */ | 2790 */ |
2686 void | 2791 void |
2687 popup_check_cursor_pos() | 2792 popup_check_cursor_pos() |
2688 { | 2793 { |
2689 win_T *wp; | 2794 win_T *wp; |
2690 typval_T tv; | |
2691 | 2795 |
2692 popup_reset_handled(); | 2796 popup_reset_handled(); |
2693 while ((wp = find_next_popup(TRUE)) != NULL) | 2797 while ((wp = find_next_popup(TRUE)) != NULL) |
2694 if (wp->w_popup_curwin != NULL | 2798 if (wp->w_popup_curwin != NULL |
2695 && (curwin != wp->w_popup_curwin | 2799 && (curwin != wp->w_popup_curwin |
2696 || curwin->w_cursor.lnum != wp->w_popup_lnum | 2800 || curwin->w_cursor.lnum != wp->w_popup_lnum |
2697 || curwin->w_cursor.col < wp->w_popup_mincol | 2801 || curwin->w_cursor.col < wp->w_popup_mincol |
2698 || curwin->w_cursor.col > wp->w_popup_maxcol)) | 2802 || curwin->w_cursor.col > wp->w_popup_maxcol)) |
2699 { | 2803 popup_close_with_retval(wp, -1); |
2700 tv.v_type = VAR_NUMBER; | |
2701 tv.vval.v_number = -1; | |
2702 popup_close_and_callback(wp, &tv); | |
2703 } | |
2704 } | 2804 } |
2705 | 2805 |
2706 /* | 2806 /* |
2707 * Update "w_popup_mask_cells". | 2807 * Update "w_popup_mask_cells". |
2708 */ | 2808 */ |
2820 } | 2920 } |
2821 } | 2921 } |
2822 } | 2922 } |
2823 | 2923 |
2824 /* | 2924 /* |
2925 * Only called when popup window "wp" is hidden: If the window is positioned | |
2926 * next to a text property, and it is now visible, then unhide the popup. | |
2927 * We don't check if visible popups become hidden, that is done in | |
2928 * popup_adjust_position(). | |
2929 * Return TRUE if the popup became unhidden. | |
2930 */ | |
2931 static int | |
2932 check_popup_unhidden(win_T *wp) | |
2933 { | |
2934 if (wp->w_popup_prop_type > 0 && win_valid(wp->w_popup_prop_win)) | |
2935 { | |
2936 textprop_T prop; | |
2937 linenr_T lnum; | |
2938 | |
2939 if (find_visible_prop(wp->w_popup_prop_win, | |
2940 wp->w_popup_prop_type, wp->w_popup_prop_id, | |
2941 &prop, &lnum) == OK) | |
2942 { | |
2943 wp->w_popup_flags &= ~POPF_HIDDEN; | |
2944 ++wp->w_buffer->b_nwindows; | |
2945 wp->w_popup_prop_topline = 0; // force repositioning | |
2946 return TRUE; | |
2947 } | |
2948 } | |
2949 return FALSE; | |
2950 } | |
2951 | |
2952 /* | |
2953 * Return TRUE if popup_adjust_position() needs to be called for "wp". | |
2954 * That is when the buffer in the popup was changed, or the popup is following | |
2955 * a textprop and the referenced buffer was changed. | |
2956 */ | |
2957 static int | |
2958 popup_need_position_adjust(win_T *wp) | |
2959 { | |
2960 if (wp->w_popup_last_changedtick != CHANGEDTICK(wp->w_buffer)) | |
2961 return TRUE; | |
2962 if (win_valid(wp->w_popup_prop_win)) | |
2963 return wp->w_popup_prop_changedtick | |
2964 != CHANGEDTICK(wp->w_popup_prop_win->w_buffer) | |
2965 || wp->w_popup_prop_topline != wp->w_popup_prop_win->w_topline; | |
2966 return FALSE; | |
2967 } | |
2968 | |
2969 /* | |
2825 * Update "popup_mask" if needed. | 2970 * Update "popup_mask" if needed. |
2826 * Also recomputes the popup size and positions. | 2971 * Also recomputes the popup size and positions. |
2827 * Also updates "popup_visible". | 2972 * Also updates "popup_visible". |
2828 * Also marks window lines for redrawing. | 2973 * Also marks window lines for redrawing. |
2829 */ | 2974 */ |
2842 if (popup_mask_tab != curtab || type >= NOT_VALID) | 2987 if (popup_mask_tab != curtab || type >= NOT_VALID) |
2843 { | 2988 { |
2844 popup_mask_refresh = TRUE; | 2989 popup_mask_refresh = TRUE; |
2845 redraw_all_popups = TRUE; | 2990 redraw_all_popups = TRUE; |
2846 } | 2991 } |
2992 | |
2993 // Check if any popup window buffer has changed and if any popup connected | |
2994 // to a text property has become visible. | |
2995 for (wp = first_popupwin; wp != NULL; wp = wp->w_next) | |
2996 if (wp->w_popup_flags & POPF_HIDDEN) | |
2997 popup_mask_refresh |= check_popup_unhidden(wp); | |
2998 else if (popup_need_position_adjust(wp)) | |
2999 popup_mask_refresh = TRUE; | |
3000 for (wp = curtab->tp_first_popupwin; wp != NULL; wp = wp->w_next) | |
3001 if (wp->w_popup_flags & POPF_HIDDEN) | |
3002 popup_mask_refresh |= check_popup_unhidden(wp); | |
3003 else if (popup_need_position_adjust(wp)) | |
3004 popup_mask_refresh = TRUE; | |
3005 | |
2847 if (!popup_mask_refresh) | 3006 if (!popup_mask_refresh) |
2848 { | 3007 return; |
2849 // Check if any popup window buffer has changed. | |
2850 for (wp = first_popupwin; wp != NULL; wp = wp->w_next) | |
2851 if (wp->w_popup_last_changedtick != CHANGEDTICK(wp->w_buffer)) | |
2852 popup_mask_refresh = TRUE; | |
2853 for (wp = curtab->tp_first_popupwin; wp != NULL; wp = wp->w_next) | |
2854 if (wp->w_popup_last_changedtick != CHANGEDTICK(wp->w_buffer)) | |
2855 popup_mask_refresh = TRUE; | |
2856 if (!popup_mask_refresh) | |
2857 return; | |
2858 } | |
2859 | 3008 |
2860 // Need to update the mask, something has changed. | 3009 // Need to update the mask, something has changed. |
2861 popup_mask_refresh = FALSE; | 3010 popup_mask_refresh = FALSE; |
2862 popup_mask_tab = curtab; | 3011 popup_mask_tab = curtab; |
2863 popup_visible = FALSE; | 3012 popup_visible = FALSE; |
2884 int width; | 3033 int width; |
2885 int height; | 3034 int height; |
2886 | 3035 |
2887 popup_visible = TRUE; | 3036 popup_visible = TRUE; |
2888 | 3037 |
2889 // Recompute the position if the text changed. | 3038 // Recompute the position if the text changed. It may make the popup |
2890 if (redraw_all_popups | 3039 // hidden if it's attach to a text property that is no longer visible. |
2891 || wp->w_popup_last_changedtick != CHANGEDTICK(wp->w_buffer)) | 3040 if (redraw_all_popups || popup_need_position_adjust(wp)) |
3041 { | |
2892 popup_adjust_position(wp); | 3042 popup_adjust_position(wp); |
3043 if (wp->w_popup_flags & POPF_HIDDEN) | |
3044 continue; | |
3045 } | |
2893 | 3046 |
2894 width = popup_width(wp); | 3047 width = popup_width(wp); |
2895 height = popup_height(wp); | 3048 height = popup_height(wp); |
2896 popup_update_mask(wp, width, height); | 3049 popup_update_mask(wp, width, height); |
2897 for (line = wp->w_winrow; | 3050 for (line = wp->w_winrow; |
3409 popup_close_preview(void) | 3562 popup_close_preview(void) |
3410 { | 3563 { |
3411 win_T *wp = popup_find_preview_window(); | 3564 win_T *wp = popup_find_preview_window(); |
3412 | 3565 |
3413 if (wp != NULL) | 3566 if (wp != NULL) |
3414 { | 3567 popup_close_with_retval(wp, -1); |
3415 typval_T res; | |
3416 | |
3417 res.v_type = VAR_NUMBER; | |
3418 res.vval.v_number = -1; | |
3419 popup_close_and_callback(wp, &res); | |
3420 } | |
3421 } | 3568 } |
3422 | 3569 |
3423 /* | 3570 /* |
3424 * Hide the info popup. | 3571 * Hide the info popup. |
3425 */ | 3572 */ |
3430 | 3577 |
3431 if (wp != NULL) | 3578 if (wp != NULL) |
3432 popup_hide(wp); | 3579 popup_hide(wp); |
3433 } | 3580 } |
3434 #endif | 3581 #endif |
3582 | |
3583 /* | |
3584 * Close any popup for a text property associated with "win". | |
3585 * Return TRUE if a popup was closed. | |
3586 */ | |
3587 int | |
3588 popup_win_closed(win_T *win) | |
3589 { | |
3590 win_T *wp; | |
3591 | |
3592 for (wp = first_popupwin; wp != NULL; wp = wp->w_next) | |
3593 if (wp->w_popup_prop_win == win) | |
3594 { | |
3595 popup_close_with_retval(wp, -1); | |
3596 return TRUE; | |
3597 } | |
3598 for (wp = curtab->tp_first_popupwin; wp != NULL; wp = wp->w_next) | |
3599 if (wp->w_popup_prop_win == win) | |
3600 { | |
3601 popup_close_with_retval(wp, -1); | |
3602 return TRUE; | |
3603 } | |
3604 return FALSE; | |
3605 } | |
3435 | 3606 |
3436 /* | 3607 /* |
3437 * Set the title of the popup window to the file name. | 3608 * Set the title of the popup window to the file name. |
3438 */ | 3609 */ |
3439 void | 3610 void |