Mercurial > vim
comparison src/window.c @ 16778:eda4d65f232c v8.1.1391
patch 8.1.1391: no popup window support
commit https://github.com/vim/vim/commit/4d784b21d14fc66e98a2b07f70343cdd4acd62aa
Author: Bram Moolenaar <Bram@vim.org>
Date: Sat May 25 19:51:39 2019 +0200
patch 8.1.1391: no popup window support
Problem: No popup window support.
Solution: Add initial code for popup windows. Add the 'wincolor' option.
author | Bram Moolenaar <Bram@vim.org> |
---|---|
date | Sat, 25 May 2019 20:00:08 +0200 |
parents | 695d9ef00b03 |
children | 491c01280a5d |
comparison
equal
deleted
inserted
replaced
16777:20d51e99dd6a | 16778:eda4d65f232c |
---|---|
1360 | 1360 |
1361 /* copy options from existing window */ | 1361 /* copy options from existing window */ |
1362 win_copy_options(oldp, newp); | 1362 win_copy_options(oldp, newp); |
1363 } | 1363 } |
1364 | 1364 |
1365 static int | |
1366 win_valid_popup(win_T *win) | |
1367 { | |
1368 #ifdef FEAT_TEXT_PROP | |
1369 win_T *wp; | |
1370 | |
1371 for (wp = first_popupwin; wp != NULL; wp = wp->w_next) | |
1372 if (wp == win) | |
1373 return TRUE; | |
1374 for (wp = first_tab_popupwin; wp != NULL; wp = wp->w_next) | |
1375 if (wp == win) | |
1376 return TRUE; | |
1377 #endif | |
1378 return FALSE; | |
1379 } | |
1365 | 1380 |
1366 /* | 1381 /* |
1367 * Check if "win" is a pointer to an existing window in the current tab page. | 1382 * Check if "win" is a pointer to an existing window in the current tab page. |
1368 */ | 1383 */ |
1369 int | 1384 int |
1374 if (win == NULL) | 1389 if (win == NULL) |
1375 return FALSE; | 1390 return FALSE; |
1376 FOR_ALL_WINDOWS(wp) | 1391 FOR_ALL_WINDOWS(wp) |
1377 if (wp == win) | 1392 if (wp == win) |
1378 return TRUE; | 1393 return TRUE; |
1379 return FALSE; | 1394 return win_valid_popup(win); |
1380 } | 1395 } |
1381 | 1396 |
1382 /* | 1397 /* |
1383 * Check if "win" is a pointer to an existing window in any tab page. | 1398 * Check if "win" is a pointer to an existing window in any tab page. |
1384 */ | 1399 */ |
1396 { | 1411 { |
1397 if (wp == win) | 1412 if (wp == win) |
1398 return TRUE; | 1413 return TRUE; |
1399 } | 1414 } |
1400 } | 1415 } |
1401 return FALSE; | 1416 return win_valid_popup(win); |
1402 } | 1417 } |
1403 | 1418 |
1404 /* | 1419 /* |
1405 * Return the number of windows. | 1420 * Return the number of windows. |
1406 */ | 1421 */ |
2291 } | 2306 } |
2292 return FALSE; | 2307 return FALSE; |
2293 } | 2308 } |
2294 | 2309 |
2295 /* | 2310 /* |
2311 * Close the buffer of "win" and unload it if "free_buf" is TRUE. | |
2312 * "abort_if_last" is passed to close_buffer(): abort closing if all other | |
2313 * windows are closed. | |
2314 */ | |
2315 static void | |
2316 win_close_buffer(win_T *win, int free_buf, int abort_if_last) | |
2317 { | |
2318 #ifdef FEAT_SYN_HL | |
2319 // Free independent synblock before the buffer is freed. | |
2320 if (win->w_buffer != NULL) | |
2321 reset_synblock(win); | |
2322 #endif | |
2323 | |
2324 #ifdef FEAT_QUICKFIX | |
2325 // When the quickfix/location list window is closed, unlist the buffer. | |
2326 if (win->w_buffer != NULL && bt_quickfix(win->w_buffer)) | |
2327 win->w_buffer->b_p_bl = FALSE; | |
2328 #endif | |
2329 | |
2330 // Close the link to the buffer. | |
2331 if (win->w_buffer != NULL) | |
2332 { | |
2333 bufref_T bufref; | |
2334 | |
2335 set_bufref(&bufref, curbuf); | |
2336 win->w_closing = TRUE; | |
2337 close_buffer(win, win->w_buffer, free_buf ? DOBUF_UNLOAD : 0, | |
2338 abort_if_last); | |
2339 if (win_valid_any_tab(win)) | |
2340 win->w_closing = FALSE; | |
2341 // Make sure curbuf is valid. It can become invalid if 'bufhidden' is | |
2342 // "wipe". | |
2343 if (!bufref_valid(&bufref)) | |
2344 curbuf = firstbuf; | |
2345 } | |
2346 } | |
2347 | |
2348 /* | |
2296 * Close window "win". Only works for the current tab page. | 2349 * Close window "win". Only works for the current tab page. |
2297 * If "free_buf" is TRUE related buffer may be unloaded. | 2350 * If "free_buf" is TRUE related buffer may be unloaded. |
2298 * | 2351 * |
2299 * Called by :quit, :close, :xit, :wq and findtag(). | 2352 * Called by :quit, :close, :xit, :wq and findtag(). |
2300 * Returns FAIL when the window was not closed. | 2353 * Returns FAIL when the window was not closed. |
2317 } | 2370 } |
2318 | 2371 |
2319 if (win->w_closing || (win->w_buffer != NULL | 2372 if (win->w_closing || (win->w_buffer != NULL |
2320 && win->w_buffer->b_locked > 0)) | 2373 && win->w_buffer->b_locked > 0)) |
2321 return FAIL; /* window is already being closed */ | 2374 return FAIL; /* window is already being closed */ |
2322 if (win == aucmd_win) | 2375 if (win_unlisted(win)) |
2323 { | 2376 { |
2324 emsg(_("E813: Cannot close autocmd window")); | 2377 emsg(_("E813: Cannot close autocmd or popup window")); |
2325 return FAIL; | 2378 return FAIL; |
2326 } | 2379 } |
2327 if ((firstwin == aucmd_win || lastwin == aucmd_win) && one_window()) | 2380 if ((firstwin == aucmd_win || lastwin == aucmd_win) && one_window()) |
2328 { | 2381 { |
2329 emsg(_("E814: Cannot close window, only autocmd window would remain")); | 2382 emsg(_("E814: Cannot close window, only autocmd window would remain")); |
2388 // win_free(). | 2441 // win_free(). |
2389 if (gui.in_use) | 2442 if (gui.in_use) |
2390 out_flush(); | 2443 out_flush(); |
2391 #endif | 2444 #endif |
2392 | 2445 |
2393 #ifdef FEAT_SYN_HL | 2446 win_close_buffer(win, free_buf, TRUE); |
2394 // Free independent synblock before the buffer is freed. | |
2395 if (win->w_buffer != NULL) | |
2396 reset_synblock(win); | |
2397 #endif | |
2398 | |
2399 #ifdef FEAT_QUICKFIX | |
2400 // When the quickfix/location list window is closed, unlist the buffer. | |
2401 if (win->w_buffer != NULL && bt_quickfix(win->w_buffer)) | |
2402 win->w_buffer->b_p_bl = FALSE; | |
2403 #endif | |
2404 | |
2405 /* | |
2406 * Close the link to the buffer. | |
2407 */ | |
2408 if (win->w_buffer != NULL) | |
2409 { | |
2410 bufref_T bufref; | |
2411 | |
2412 set_bufref(&bufref, curbuf); | |
2413 win->w_closing = TRUE; | |
2414 close_buffer(win, win->w_buffer, free_buf ? DOBUF_UNLOAD : 0, TRUE); | |
2415 if (win_valid_any_tab(win)) | |
2416 win->w_closing = FALSE; | |
2417 /* Make sure curbuf is valid. It can become invalid if 'bufhidden' is | |
2418 * "wipe". */ | |
2419 if (!bufref_valid(&bufref)) | |
2420 curbuf = firstbuf; | |
2421 } | |
2422 | 2447 |
2423 if (only_one_window() && win_valid(win) && win->w_buffer == NULL | 2448 if (only_one_window() && win_valid(win) && win->w_buffer == NULL |
2424 && (last_window() || curtab != prev_curtab | 2449 && (last_window() || curtab != prev_curtab |
2425 || close_last_window_tabpage(win, free_buf, prev_curtab))) | 2450 || close_last_window_tabpage(win, free_buf, prev_curtab))) |
2426 { | 2451 { |
2625 if (aucmd_win != NULL) | 2650 if (aucmd_win != NULL) |
2626 { | 2651 { |
2627 (void)win_free_mem(aucmd_win, &dummy, NULL); | 2652 (void)win_free_mem(aucmd_win, &dummy, NULL); |
2628 aucmd_win = NULL; | 2653 aucmd_win = NULL; |
2629 } | 2654 } |
2655 # ifdef FEAT_TEXT_PROP | |
2656 close_all_popups(); | |
2657 # endif | |
2630 | 2658 |
2631 while (firstwin != NULL) | 2659 while (firstwin != NULL) |
2632 (void)win_free_mem(firstwin, &dummy, NULL); | 2660 (void)win_free_mem(firstwin, &dummy, NULL); |
2633 | 2661 |
2634 /* No window should be used after this. Set curwin to NULL to crash | 2662 /* No window should be used after this. Set curwin to NULL to crash |
3456 wp->w_topline = 1; | 3484 wp->w_topline = 1; |
3457 #ifdef FEAT_DIFF | 3485 #ifdef FEAT_DIFF |
3458 wp->w_topfill = 0; | 3486 wp->w_topfill = 0; |
3459 #endif | 3487 #endif |
3460 wp->w_botline = 2; | 3488 wp->w_botline = 2; |
3461 #ifdef FEAT_SYN_HL | 3489 #if defined(FEAT_SYN_HL) || defined(FEAT_SPELL) |
3462 wp->w_s = &wp->w_buffer->b_s; | 3490 wp->w_s = &wp->w_buffer->b_s; |
3463 #endif | 3491 #endif |
3464 } | 3492 } |
3465 | 3493 |
3466 /* | 3494 /* |
3482 | 3510 |
3483 return OK; | 3511 return OK; |
3484 } | 3512 } |
3485 | 3513 |
3486 /* | 3514 /* |
3487 * Init "aucmd_win". This can only be done after the first | 3515 * Allocate and init a window that is not a regular window. |
3488 * window is fully initialized, thus it can't be in win_alloc_first(). | 3516 * This can only be done after the first window is fully initialized, thus it |
3517 * can't be in win_alloc_first(). | |
3518 */ | |
3519 win_T * | |
3520 win_alloc_popup_win(void) | |
3521 { | |
3522 win_T *wp; | |
3523 | |
3524 wp = win_alloc(NULL, TRUE); | |
3525 if (wp != NULL) | |
3526 { | |
3527 // We need to initialize options with something, using the current | |
3528 // window makes most sense. | |
3529 win_init_some(wp, curwin); | |
3530 | |
3531 RESET_BINDING(wp); | |
3532 new_frame(wp); | |
3533 } | |
3534 return wp; | |
3535 } | |
3536 | |
3537 /* | |
3538 * Initialize window "wp" to display buffer "buf". | |
3489 */ | 3539 */ |
3490 void | 3540 void |
3491 win_alloc_aucmd_win(void) | 3541 win_init_popup_win(win_T *wp, buf_T *buf) |
3492 { | 3542 { |
3493 aucmd_win = win_alloc(NULL, TRUE); | 3543 wp->w_buffer = buf; |
3494 if (aucmd_win != NULL) | 3544 ++buf->b_nwindows; |
3495 { | 3545 win_init_empty(wp); // set cursor and topline to safe values |
3496 win_init_some(aucmd_win, curwin); | 3546 |
3497 RESET_BINDING(aucmd_win); | 3547 // Make sure w_localdir and globaldir are NULL to avoid a chdir() in |
3498 new_frame(aucmd_win); | 3548 // win_enter_ext(). |
3499 } | 3549 VIM_CLEAR(wp->w_localdir); |
3500 } | 3550 } |
3501 | 3551 |
3502 /* | 3552 /* |
3503 * Allocate the first window or the first window in a new tab page. | 3553 * Allocate the first window or the first window in a new tab page. |
3504 * When "oldwin" is NULL create an empty buffer for it. | 3554 * When "oldwin" is NULL create an empty buffer for it. |
3617 int idx; | 3667 int idx; |
3618 | 3668 |
3619 # ifdef FEAT_DIFF | 3669 # ifdef FEAT_DIFF |
3620 diff_clear(tp); | 3670 diff_clear(tp); |
3621 # endif | 3671 # endif |
3672 # ifdef FEAT_TEXT_PROP | |
3673 while (tp->tp_first_popupwin != NULL) | |
3674 popup_close(tp->tp_first_popupwin->w_id); | |
3675 #endif | |
3622 for (idx = 0; idx < SNAP_COUNT; ++idx) | 3676 for (idx = 0; idx < SNAP_COUNT; ++idx) |
3623 clear_snapshot(tp, idx); | 3677 clear_snapshot(tp, idx); |
3624 #ifdef FEAT_EVAL | 3678 #ifdef FEAT_EVAL |
3625 vars_clear(&tp->tp_vars->dv_hashtab); /* free all t: variables */ | 3679 vars_clear(&tp->tp_vars->dv_hashtab); /* free all t: variables */ |
3626 hash_init(&tp->tp_vars->dv_hashtab); | 3680 hash_init(&tp->tp_vars->dv_hashtab); |
4780 | 4834 |
4781 #ifdef FEAT_SYN_HL | 4835 #ifdef FEAT_SYN_HL |
4782 vim_free(wp->w_p_cc_cols); | 4836 vim_free(wp->w_p_cc_cols); |
4783 #endif | 4837 #endif |
4784 | 4838 |
4785 if (wp != aucmd_win) | 4839 if (win_valid_any_tab(wp)) |
4786 win_remove(wp, tp); | 4840 win_remove(wp, tp); |
4787 if (autocmd_busy) | 4841 if (autocmd_busy) |
4788 { | 4842 { |
4789 wp->w_next = au_pending_free_win; | 4843 wp->w_next = au_pending_free_win; |
4790 au_pending_free_win = wp; | 4844 au_pending_free_win = wp; |
4791 } | 4845 } |
4792 else | 4846 else |
4793 vim_free(wp); | 4847 vim_free(wp); |
4794 | 4848 |
4795 unblock_autocmds(); | 4849 unblock_autocmds(); |
4850 } | |
4851 | |
4852 /* | |
4853 * Return TRUE if "wp" is not in the list of windows: the autocmd window or a | |
4854 * popup window. | |
4855 */ | |
4856 int | |
4857 win_unlisted(win_T *wp) | |
4858 { | |
4859 return wp == aucmd_win || bt_popup(wp->w_buffer); | |
4860 } | |
4861 | |
4862 /* | |
4863 * Free a popup window. This does not take the window out of the window list | |
4864 * and assumes there is only one toplevel frame, no split. | |
4865 */ | |
4866 void | |
4867 win_free_popup(win_T *win) | |
4868 { | |
4869 win_close_buffer(win, TRUE, FALSE); | |
4870 vim_free(win->w_frame); | |
4871 win_free(win, NULL); | |
4796 } | 4872 } |
4797 | 4873 |
4798 /* | 4874 /* |
4799 * Append window "wp" in the window list after window "after". | 4875 * Append window "wp" in the window list after window "after". |
4800 */ | 4876 */ |
6180 } | 6256 } |
6181 | 6257 |
6182 /* | 6258 /* |
6183 * Return TRUE if there is only one window (in the current tab page), not | 6259 * Return TRUE if there is only one window (in the current tab page), not |
6184 * counting a help or preview window, unless it is the current window. | 6260 * counting a help or preview window, unless it is the current window. |
6185 * Does not count "aucmd_win". | 6261 * Does not count unlisted windows. |
6186 */ | 6262 */ |
6187 int | 6263 int |
6188 only_one_window(void) | 6264 only_one_window(void) |
6189 { | 6265 { |
6190 int count = 0; | 6266 int count = 0; |
6972 tabpage_T *tp; | 7048 tabpage_T *tp; |
6973 | 7049 |
6974 FOR_ALL_TAB_WINDOWS(tp, wp) | 7050 FOR_ALL_TAB_WINDOWS(tp, wp) |
6975 if (wp->w_id == id) | 7051 if (wp->w_id == id) |
6976 return wp; | 7052 return wp; |
7053 #ifdef FEAT_TEXT_PROP | |
7054 // popup windows are in a separate list | |
7055 FOR_ALL_TABPAGES(tp) | |
7056 for (wp = tp->tp_first_popupwin; wp != NULL; wp = wp->w_next) | |
7057 if (wp->w_id == id) | |
7058 return wp; | |
7059 for (wp = first_popupwin; wp != NULL; wp = wp->w_next) | |
7060 if (wp->w_id == id) | |
7061 return wp; | |
7062 #endif | |
6977 | 7063 |
6978 return NULL; | 7064 return NULL; |
6979 } | 7065 } |
6980 | 7066 |
6981 int | 7067 int |