comparison src/autocmd.c @ 22838:80bd5de5dcab v8.2.1966

patch 8.2.1966: popup becomes current window after closing a terminal window Commit: https://github.com/vim/vim/commit/cbcd9cbd77acc8cc97c0d44683d96c01d3dd0fa7 Author: Bram Moolenaar <Bram@vim.org> Date: Sat Nov 7 16:58:59 2020 +0100 patch 8.2.1966: popup becomes current window after closing a terminal window Problem: Popup becomes current window after closing a terminal window. Solution: When restoring the window after executing autocommands, check that the window ID is still the same. (Naruhiko Nishino, closes #7272)
author Bram Moolenaar <Bram@vim.org>
date Sat, 07 Nov 2020 17:00:05 +0100
parents fba5ccf33794
children a916fca16d4b
comparison
equal deleted inserted replaced
22837:a1e5d99414e8 22838:80bd5de5dcab
1431 if (win == NULL && aucmd_win_used) 1431 if (win == NULL && aucmd_win_used)
1432 // Strange recursive autocommand, fall back to using the current 1432 // Strange recursive autocommand, fall back to using the current
1433 // window. Expect a few side effects... 1433 // window. Expect a few side effects...
1434 win = curwin; 1434 win = curwin;
1435 1435
1436 aco->save_curwin = curwin; 1436 aco->save_curwin_id = curwin->w_id;
1437 aco->save_curbuf = curbuf; 1437 aco->save_curbuf = curbuf;
1438 aco->save_prevwin = prevwin; 1438 aco->save_prevwin_id = prevwin == NULL ? 0 : prevwin->w_id;
1439 if (win != NULL) 1439 if (win != NULL)
1440 { 1440 {
1441 // There is a window for "buf" in the current tab page, make it the 1441 // There is a window for "buf" in the current tab page, make it the
1442 // curwin. This is preferred, it has the least side effects (esp. if 1442 // curwin. This is preferred, it has the least side effects (esp. if
1443 // "buf" is curbuf). 1443 // "buf" is curbuf).
1479 #endif 1479 #endif
1480 unblock_autocmds(); 1480 unblock_autocmds();
1481 curwin = aucmd_win; 1481 curwin = aucmd_win;
1482 } 1482 }
1483 curbuf = buf; 1483 curbuf = buf;
1484 aco->new_curwin = curwin; 1484 aco->new_curwin_id = curwin->w_id;
1485 set_bufref(&aco->new_curbuf, curbuf); 1485 set_bufref(&aco->new_curbuf, curbuf);
1486 } 1486 }
1487 1487
1488 /* 1488 /*
1489 * Cleanup after executing autocommands for a (hidden) buffer. 1489 * Cleanup after executing autocommands for a (hidden) buffer.
1491 */ 1491 */
1492 void 1492 void
1493 aucmd_restbuf( 1493 aucmd_restbuf(
1494 aco_save_T *aco) // structure holding saved values 1494 aco_save_T *aco) // structure holding saved values
1495 { 1495 {
1496 int dummy; 1496 int dummy;
1497 win_T *save_curwin;
1497 1498
1498 if (aco->use_aucmd_win) 1499 if (aco->use_aucmd_win)
1499 { 1500 {
1500 --curbuf->b_nwindows; 1501 --curbuf->b_nwindows;
1501 // Find "aucmd_win", it can't be closed, but it may be in another tab 1502 // Find "aucmd_win", it can't be closed, but it may be in another tab
1531 1532
1532 restore_snapshot(SNAP_AUCMD_IDX, FALSE); 1533 restore_snapshot(SNAP_AUCMD_IDX, FALSE);
1533 (void)win_comp_pos(); // recompute window positions 1534 (void)win_comp_pos(); // recompute window positions
1534 unblock_autocmds(); 1535 unblock_autocmds();
1535 1536
1536 if (win_valid(aco->save_curwin)) 1537 save_curwin = win_find_by_id(aco->save_curwin_id);
1537 curwin = aco->save_curwin; 1538 if (save_curwin != NULL)
1539 curwin = save_curwin;
1538 else 1540 else
1539 // Hmm, original window disappeared. Just use the first one. 1541 // Hmm, original window disappeared. Just use the first one.
1540 curwin = firstwin; 1542 curwin = firstwin;
1541 curbuf = curwin->w_buffer; 1543 curbuf = curwin->w_buffer;
1542 #ifdef FEAT_JOB_CHANNEL 1544 #ifdef FEAT_JOB_CHANNEL
1543 // May need to restore insert mode for a prompt buffer. 1545 // May need to restore insert mode for a prompt buffer.
1544 entering_window(curwin); 1546 entering_window(curwin);
1545 #endif 1547 #endif
1546 1548 prevwin = win_find_by_id(aco->save_prevwin_id);
1547 if (win_valid(aco->save_prevwin))
1548 prevwin = aco->save_prevwin;
1549 #ifdef FEAT_EVAL 1549 #ifdef FEAT_EVAL
1550 vars_clear(&aucmd_win->w_vars->dv_hashtab); // free all w: variables 1550 vars_clear(&aucmd_win->w_vars->dv_hashtab); // free all w: variables
1551 hash_init(&aucmd_win->w_vars->dv_hashtab); // re-use the hashtab 1551 hash_init(&aucmd_win->w_vars->dv_hashtab); // re-use the hashtab
1552 #endif 1552 #endif
1553 vim_free(globaldir); 1553 vim_free(globaldir);
1569 gui_may_update_scrollbars(); 1569 gui_may_update_scrollbars();
1570 #endif 1570 #endif
1571 } 1571 }
1572 else 1572 else
1573 { 1573 {
1574 // restore curwin 1574 // Restore curwin. Use the window ID, a window may have been closed
1575 if (win_valid(aco->save_curwin)) 1575 // and the memory re-used for another one.
1576 save_curwin = win_find_by_id(aco->save_curwin_id);
1577 if (save_curwin != NULL)
1576 { 1578 {
1577 // Restore the buffer which was previously edited by curwin, if 1579 // Restore the buffer which was previously edited by curwin, if
1578 // it was changed, we are still the same window and the buffer is 1580 // it was changed, we are still the same window and the buffer is
1579 // valid. 1581 // valid.
1580 if (curwin == aco->new_curwin 1582 if (curwin->w_id == aco->new_curwin_id
1581 && curbuf != aco->new_curbuf.br_buf 1583 && curbuf != aco->new_curbuf.br_buf
1582 && bufref_valid(&aco->new_curbuf) 1584 && bufref_valid(&aco->new_curbuf)
1583 && aco->new_curbuf.br_buf->b_ml.ml_mfp != NULL) 1585 && aco->new_curbuf.br_buf->b_ml.ml_mfp != NULL)
1584 { 1586 {
1585 # if defined(FEAT_SYN_HL) || defined(FEAT_SPELL) 1587 # if defined(FEAT_SYN_HL) || defined(FEAT_SPELL)
1590 curbuf = aco->new_curbuf.br_buf; 1592 curbuf = aco->new_curbuf.br_buf;
1591 curwin->w_buffer = curbuf; 1593 curwin->w_buffer = curbuf;
1592 ++curbuf->b_nwindows; 1594 ++curbuf->b_nwindows;
1593 } 1595 }
1594 1596
1595 curwin = aco->save_curwin; 1597 curwin = save_curwin;
1596 curbuf = curwin->w_buffer; 1598 curbuf = curwin->w_buffer;
1597 if (win_valid(aco->save_prevwin)) 1599 prevwin = win_find_by_id(aco->save_prevwin_id);
1598 prevwin = aco->save_prevwin;
1599 // In case the autocommand moves the cursor to a position that 1600 // In case the autocommand moves the cursor to a position that
1600 // does not exist in curbuf. 1601 // does not exist in curbuf.
1601 check_cursor(); 1602 check_cursor();
1602 } 1603 }
1603 } 1604 }