Mercurial > vim
comparison src/popupmnu.c @ 12566:33a900199c25 v8.0.1161
patch 8.0.1161: popup menu drawing problem when resizing terminal
commit https://github.com/vim/vim/commit/a5e6621aadadf78c7b344e93a4b328788076f14c
Author: Bram Moolenaar <Bram@vim.org>
Date: Fri Sep 29 22:42:33 2017 +0200
patch 8.0.1161: popup menu drawing problem when resizing terminal
Problem: Popup menu drawing problem when resizing terminal.
Solution: Redraw after resizing also when a popup menu is visible. (Ozaki
Kiichi, closes #2110)
author | Christian Brabandt <cb@256bit.org> |
---|---|
date | Fri, 29 Sep 2017 22:45:03 +0200 |
parents | 972ea22c946f |
children | fad36581f788 |
comparison
equal
deleted
inserted
replaced
12565:657abf4f50ba | 12566:33a900199c25 |
---|---|
62 int redo_count = 0; | 62 int redo_count = 0; |
63 #if defined(FEAT_QUICKFIX) | 63 #if defined(FEAT_QUICKFIX) |
64 win_T *pvwin; | 64 win_T *pvwin; |
65 #endif | 65 #endif |
66 | 66 |
67 redo: | 67 do |
68 def_width = PUM_DEF_WIDTH; | 68 { |
69 max_width = 0; | 69 def_width = PUM_DEF_WIDTH; |
70 kind_width = 0; | 70 max_width = 0; |
71 extra_width = 0; | 71 kind_width = 0; |
72 above_row = 0; | 72 extra_width = 0; |
73 below_row = cmdline_row; | 73 above_row = 0; |
74 | 74 below_row = cmdline_row; |
75 /* Pretend the pum is already there to avoid that must_redraw is set when | 75 |
76 * 'cuc' is on. */ | 76 /* Pretend the pum is already there to avoid that must_redraw is set |
77 pum_array = (pumitem_T *)1; | 77 * when 'cuc' is on. */ |
78 validate_cursor_col(); | 78 pum_array = (pumitem_T *)1; |
79 pum_array = NULL; | 79 validate_cursor_col(); |
80 | 80 pum_array = NULL; |
81 row = curwin->w_wrow + W_WINROW(curwin); | 81 |
82 row = curwin->w_wrow + W_WINROW(curwin); | |
82 | 83 |
83 #if defined(FEAT_QUICKFIX) | 84 #if defined(FEAT_QUICKFIX) |
84 FOR_ALL_WINDOWS(pvwin) | 85 FOR_ALL_WINDOWS(pvwin) |
85 if (pvwin->w_p_pvw) | 86 if (pvwin->w_p_pvw) |
86 break; | 87 break; |
87 if (pvwin != NULL) | 88 if (pvwin != NULL) |
88 { | 89 { |
89 if (W_WINROW(pvwin) < W_WINROW(curwin)) | 90 if (W_WINROW(pvwin) < W_WINROW(curwin)) |
90 above_row = W_WINROW(pvwin) + pvwin->w_height; | 91 above_row = W_WINROW(pvwin) + pvwin->w_height; |
91 else if (W_WINROW(pvwin) > W_WINROW(curwin) + curwin->w_height) | 92 else if (W_WINROW(pvwin) > W_WINROW(curwin) + curwin->w_height) |
92 below_row = W_WINROW(pvwin); | 93 below_row = W_WINROW(pvwin); |
93 } | 94 } |
94 #endif | 95 #endif |
95 | 96 |
96 /* | 97 /* |
97 * Figure out the size and position of the pum. | 98 * Figure out the size and position of the pum. |
98 */ | 99 */ |
99 if (size < PUM_DEF_HEIGHT) | 100 if (size < PUM_DEF_HEIGHT) |
100 pum_height = size; | 101 pum_height = size; |
101 else | |
102 pum_height = PUM_DEF_HEIGHT; | |
103 if (p_ph > 0 && pum_height > p_ph) | |
104 pum_height = p_ph; | |
105 | |
106 /* Put the pum below "row" if possible. If there are few lines decide on | |
107 * where there is more room. */ | |
108 if (row + 2 >= below_row - pum_height | |
109 && row - above_row > (below_row - above_row) / 2) | |
110 { | |
111 /* pum above "row" */ | |
112 | |
113 /* Leave two lines of context if possible */ | |
114 if (curwin->w_wrow - curwin->w_cline_row >= 2) | |
115 context_lines = 2; | |
116 else | 102 else |
117 context_lines = curwin->w_wrow - curwin->w_cline_row; | 103 pum_height = PUM_DEF_HEIGHT; |
118 | |
119 if (row >= size + context_lines) | |
120 { | |
121 pum_row = row - size - context_lines; | |
122 pum_height = size; | |
123 } | |
124 else | |
125 { | |
126 pum_row = 0; | |
127 pum_height = row - context_lines; | |
128 } | |
129 if (p_ph > 0 && pum_height > p_ph) | |
130 { | |
131 pum_row += pum_height - p_ph; | |
132 pum_height = p_ph; | |
133 } | |
134 } | |
135 else | |
136 { | |
137 /* pum below "row" */ | |
138 | |
139 /* Leave two lines of context if possible */ | |
140 if (curwin->w_cline_row + curwin->w_cline_height - curwin->w_wrow >= 3) | |
141 context_lines = 3; | |
142 else | |
143 context_lines = curwin->w_cline_row | |
144 + curwin->w_cline_height - curwin->w_wrow; | |
145 | |
146 pum_row = row + context_lines; | |
147 if (size > below_row - pum_row) | |
148 pum_height = below_row - pum_row; | |
149 else | |
150 pum_height = size; | |
151 if (p_ph > 0 && pum_height > p_ph) | 104 if (p_ph > 0 && pum_height > p_ph) |
152 pum_height = p_ph; | 105 pum_height = p_ph; |
153 } | 106 |
154 | 107 /* Put the pum below "row" if possible. If there are few lines decide |
155 /* don't display when we only have room for one line */ | 108 * on where there is more room. */ |
156 if (pum_height < 1 || (pum_height == 1 && size > 1)) | 109 if (row + 2 >= below_row - pum_height |
157 return; | 110 && row - above_row > (below_row - above_row) / 2) |
111 { | |
112 /* pum above "row" */ | |
113 | |
114 /* Leave two lines of context if possible */ | |
115 if (curwin->w_wrow - curwin->w_cline_row >= 2) | |
116 context_lines = 2; | |
117 else | |
118 context_lines = curwin->w_wrow - curwin->w_cline_row; | |
119 | |
120 if (row >= size + context_lines) | |
121 { | |
122 pum_row = row - size - context_lines; | |
123 pum_height = size; | |
124 } | |
125 else | |
126 { | |
127 pum_row = 0; | |
128 pum_height = row - context_lines; | |
129 } | |
130 if (p_ph > 0 && pum_height > p_ph) | |
131 { | |
132 pum_row += pum_height - p_ph; | |
133 pum_height = p_ph; | |
134 } | |
135 } | |
136 else | |
137 { | |
138 /* pum below "row" */ | |
139 | |
140 /* Leave two lines of context if possible */ | |
141 if (curwin->w_cline_row | |
142 + curwin->w_cline_height - curwin->w_wrow >= 3) | |
143 context_lines = 3; | |
144 else | |
145 context_lines = curwin->w_cline_row | |
146 + curwin->w_cline_height - curwin->w_wrow; | |
147 | |
148 pum_row = row + context_lines; | |
149 if (size > below_row - pum_row) | |
150 pum_height = below_row - pum_row; | |
151 else | |
152 pum_height = size; | |
153 if (p_ph > 0 && pum_height > p_ph) | |
154 pum_height = p_ph; | |
155 } | |
156 | |
157 /* don't display when we only have room for one line */ | |
158 if (pum_height < 1 || (pum_height == 1 && size > 1)) | |
159 return; | |
158 | 160 |
159 #if defined(FEAT_QUICKFIX) | 161 #if defined(FEAT_QUICKFIX) |
160 /* If there is a preview window at the above avoid drawing over it. */ | 162 /* If there is a preview window at the above avoid drawing over it. */ |
161 if (pvwin != NULL && pum_row < above_row && pum_height > above_row) | 163 if (pvwin != NULL && pum_row < above_row && pum_height > above_row) |
162 { | 164 { |
163 pum_row += above_row; | 165 pum_row += above_row; |
164 pum_height -= above_row; | 166 pum_height -= above_row; |
165 } | 167 } |
166 #endif | 168 #endif |
167 | 169 |
168 /* Compute the width of the widest match and the widest extra. */ | 170 /* Compute the width of the widest match and the widest extra. */ |
169 for (i = 0; i < size; ++i) | 171 for (i = 0; i < size; ++i) |
170 { | 172 { |
171 w = vim_strsize(array[i].pum_text); | 173 w = vim_strsize(array[i].pum_text); |
172 if (max_width < w) | 174 if (max_width < w) |
173 max_width = w; | 175 max_width = w; |
174 if (array[i].pum_kind != NULL) | 176 if (array[i].pum_kind != NULL) |
175 { | 177 { |
176 w = vim_strsize(array[i].pum_kind) + 1; | 178 w = vim_strsize(array[i].pum_kind) + 1; |
177 if (kind_width < w) | 179 if (kind_width < w) |
178 kind_width = w; | 180 kind_width = w; |
179 } | 181 } |
180 if (array[i].pum_extra != NULL) | 182 if (array[i].pum_extra != NULL) |
181 { | 183 { |
182 w = vim_strsize(array[i].pum_extra) + 1; | 184 w = vim_strsize(array[i].pum_extra) + 1; |
183 if (extra_width < w) | 185 if (extra_width < w) |
184 extra_width = w; | 186 extra_width = w; |
185 } | 187 } |
186 } | 188 } |
187 pum_base_width = max_width; | 189 pum_base_width = max_width; |
188 pum_kind_width = kind_width; | 190 pum_kind_width = kind_width; |
189 | 191 |
190 /* Calculate column */ | 192 /* Calculate column */ |
191 #ifdef FEAT_RIGHTLEFT | |
192 if (curwin->w_p_rl) | |
193 col = curwin->w_wincol + curwin->w_width - curwin->w_wcol - 1; | |
194 else | |
195 #endif | |
196 col = curwin->w_wincol + curwin->w_wcol; | |
197 | |
198 /* if there are more items than room we need a scrollbar */ | |
199 if (pum_height < size) | |
200 { | |
201 pum_scrollbar = 1; | |
202 ++max_width; | |
203 } | |
204 else | |
205 pum_scrollbar = 0; | |
206 | |
207 if (def_width < max_width) | |
208 def_width = max_width; | |
209 | |
210 if (((col < Columns - PUM_DEF_WIDTH || col < Columns - max_width) | |
211 #ifdef FEAT_RIGHTLEFT | |
212 && !curwin->w_p_rl) | |
213 || (curwin->w_p_rl && (col > PUM_DEF_WIDTH || col > max_width) | |
214 #endif | |
215 )) | |
216 { | |
217 /* align pum column with "col" */ | |
218 pum_col = col; | |
219 | |
220 #ifdef FEAT_RIGHTLEFT | 193 #ifdef FEAT_RIGHTLEFT |
221 if (curwin->w_p_rl) | 194 if (curwin->w_p_rl) |
222 pum_width = pum_col - pum_scrollbar + 1; | 195 col = curwin->w_wincol + curwin->w_width - curwin->w_wcol - 1; |
223 else | 196 else |
224 #endif | 197 #endif |
225 pum_width = Columns - pum_col - pum_scrollbar; | 198 col = curwin->w_wincol + curwin->w_wcol; |
226 | 199 |
227 if (pum_width > max_width + kind_width + extra_width + 1 | 200 /* if there are more items than room we need a scrollbar */ |
228 && pum_width > PUM_DEF_WIDTH) | 201 if (pum_height < size) |
229 { | 202 { |
230 pum_width = max_width + kind_width + extra_width + 1; | 203 pum_scrollbar = 1; |
231 if (pum_width < PUM_DEF_WIDTH) | 204 ++max_width; |
232 pum_width = PUM_DEF_WIDTH; | 205 } |
233 } | |
234 } | |
235 else if (Columns < def_width) | |
236 { | |
237 /* not enough room, will use what we have */ | |
238 #ifdef FEAT_RIGHTLEFT | |
239 if (curwin->w_p_rl) | |
240 pum_col = Columns - 1; | |
241 else | 206 else |
242 #endif | 207 pum_scrollbar = 0; |
243 pum_col = 0; | 208 |
244 pum_width = Columns - 1; | 209 if (def_width < max_width) |
245 } | 210 def_width = max_width; |
246 else | 211 |
247 { | 212 if (((col < Columns - PUM_DEF_WIDTH || col < Columns - max_width) |
248 if (max_width > PUM_DEF_WIDTH) | 213 #ifdef FEAT_RIGHTLEFT |
249 max_width = PUM_DEF_WIDTH; /* truncate */ | 214 && !curwin->w_p_rl) |
250 #ifdef FEAT_RIGHTLEFT | 215 || (curwin->w_p_rl && (col > PUM_DEF_WIDTH || col > max_width) |
251 if (curwin->w_p_rl) | 216 #endif |
252 pum_col = max_width - 1; | 217 )) |
218 { | |
219 /* align pum column with "col" */ | |
220 pum_col = col; | |
221 | |
222 #ifdef FEAT_RIGHTLEFT | |
223 if (curwin->w_p_rl) | |
224 pum_width = pum_col - pum_scrollbar + 1; | |
225 else | |
226 #endif | |
227 pum_width = Columns - pum_col - pum_scrollbar; | |
228 | |
229 if (pum_width > max_width + kind_width + extra_width + 1 | |
230 && pum_width > PUM_DEF_WIDTH) | |
231 { | |
232 pum_width = max_width + kind_width + extra_width + 1; | |
233 if (pum_width < PUM_DEF_WIDTH) | |
234 pum_width = PUM_DEF_WIDTH; | |
235 } | |
236 } | |
237 else if (Columns < def_width) | |
238 { | |
239 /* not enough room, will use what we have */ | |
240 #ifdef FEAT_RIGHTLEFT | |
241 if (curwin->w_p_rl) | |
242 pum_col = Columns - 1; | |
243 else | |
244 #endif | |
245 pum_col = 0; | |
246 pum_width = Columns - 1; | |
247 } | |
253 else | 248 else |
254 #endif | 249 { |
255 pum_col = Columns - max_width; | 250 if (max_width > PUM_DEF_WIDTH) |
256 pum_width = max_width - pum_scrollbar; | 251 max_width = PUM_DEF_WIDTH; /* truncate */ |
257 } | 252 #ifdef FEAT_RIGHTLEFT |
258 | 253 if (curwin->w_p_rl) |
259 pum_array = array; | 254 pum_col = max_width - 1; |
260 pum_size = size; | 255 else |
261 | 256 #endif |
262 /* Set selected item and redraw. If the window size changed need to redo | 257 pum_col = Columns - max_width; |
263 * the positioning. Limit this to two times, when there is not much | 258 pum_width = max_width - pum_scrollbar; |
264 * room the window size will keep changing. */ | 259 } |
265 if (pum_set_selected(selected, redo_count) && ++redo_count <= 2) | 260 |
266 goto redo; | 261 pum_array = array; |
262 pum_size = size; | |
263 | |
264 /* Set selected item and redraw. If the window size changed need to | |
265 * redo the positioning. Limit this to two times, when there is not | |
266 * much room the window size will keep changing. */ | |
267 } while (pum_set_selected(selected, redo_count) && ++redo_count <= 2); | |
267 } | 268 } |
268 | 269 |
269 /* | 270 /* |
270 * Redraw the popup menu, using "pum_first" and "pum_selected". | 271 * Redraw the popup menu, using "pum_first" and "pum_selected". |
271 */ | 272 */ |