diff options
author | Josh Rahm <joshuarahm@gmail.com> | 2025-02-05 23:09:29 +0000 |
---|---|---|
committer | Josh Rahm <joshuarahm@gmail.com> | 2025-02-05 23:09:29 +0000 |
commit | d5f194ce780c95821a855aca3c19426576d28ae0 (patch) | |
tree | d45f461b19f9118ad2bb1f440a7a08973ad18832 /src/nvim/window.c | |
parent | c5d770d311841ea5230426cc4c868e8db27300a8 (diff) | |
parent | 44740e561fc93afe3ebecfd3618bda2d2abeafb0 (diff) | |
download | rneovim-d5f194ce780c95821a855aca3c19426576d28ae0.tar.gz rneovim-d5f194ce780c95821a855aca3c19426576d28ae0.tar.bz2 rneovim-d5f194ce780c95821a855aca3c19426576d28ae0.zip |
Diffstat (limited to 'src/nvim/window.c')
-rw-r--r-- | src/nvim/window.c | 358 |
1 files changed, 164 insertions, 194 deletions
diff --git a/src/nvim/window.c b/src/nvim/window.c index c3f3e075f1..fa2bfec138 100644 --- a/src/nvim/window.c +++ b/src/nvim/window.c @@ -1,9 +1,7 @@ #include <assert.h> -#include <ctype.h> #include <inttypes.h> #include <limits.h> #include <stdbool.h> -#include <stdio.h> #include <stdlib.h> #include <string.h> @@ -52,7 +50,6 @@ #include "nvim/mark.h" #include "nvim/mark_defs.h" #include "nvim/match.h" -#include "nvim/mbyte.h" #include "nvim/memory.h" #include "nvim/message.h" #include "nvim/mouse.h" @@ -186,13 +183,13 @@ win_T *swbuf_goto_win_with_buf(buf_T *buf) // If 'switchbuf' contains "useopen": jump to first window in the current // tab page containing "buf" if one exists. - if (swb_flags & SWB_USEOPEN) { + if (swb_flags & kOptSwbFlagUseopen) { wp = buf_jump_open_win(buf); } // If 'switchbuf' contains "usetab": jump to first window in any tab page // containing "buf" if one exists. - if (wp == NULL && (swb_flags & SWB_USETAB)) { + if (wp == NULL && (swb_flags & kOptSwbFlagUsetab)) { wp = buf_jump_open_tab(buf); } @@ -583,7 +580,7 @@ wingotofile: // If 'switchbuf' is set to 'useopen' or 'usetab' and the // file is already opened in a window, then jump to it. win_T *wp = NULL; - if ((swb_flags & (SWB_USEOPEN | SWB_USETAB)) + if ((swb_flags & (kOptSwbFlagUseopen | kOptSwbFlagUsetab)) && cmdmod.cmod_tab == 0) { wp = swbuf_goto_win_with_buf(buflist_findname_exp(ptr)); } @@ -746,40 +743,28 @@ void win_set_buf(win_T *win, buf_T *buf, Error *err) RedrawingDisabled++; switchwin_T switchwin; - if (switch_win_noblock(&switchwin, win, tab, true) == FAIL) { - api_set_error(err, - kErrorTypeException, - "Failed to switch to window %d", - win->handle); - goto cleanup; - } - - try_start(); - - const int save_acd = p_acd; - if (!switchwin.sw_same_win) { - // Temporarily disable 'autochdir' when setting buffer in another window. - p_acd = false; - } - int result = do_buffer(DOBUF_GOTO, DOBUF_FIRST, FORWARD, buf->b_fnum, 0); + TRY_WRAP(err, { + int win_result = switch_win_noblock(&switchwin, win, tab, true); + if (win_result != FAIL) { + const int save_acd = p_acd; + if (!switchwin.sw_same_win) { + // Temporarily disable 'autochdir' when setting buffer in another window. + p_acd = false; + } - if (!switchwin.sw_same_win) { - p_acd = save_acd; - } + do_buffer(DOBUF_GOTO, DOBUF_FIRST, FORWARD, buf->b_fnum, 0); - if (!try_end(err) && result == FAIL) { - api_set_error(err, - kErrorTypeException, - "Failed to set buffer %d", - buf->handle); - } + if (!switchwin.sw_same_win) { + p_acd = save_acd; + } + } + }); // If window is not current, state logic will not validate its cursor. So do it now. // Still needed if do_buffer returns FAIL (e.g: autocmds abort script after buffer was set). validate_cursor(curwin); -cleanup: restore_win_noblock(&switchwin, true); RedrawingDisabled--; } @@ -850,9 +835,19 @@ void ui_ext_win_position(win_T *wp, bool validate) col += tcol - 1; } } + } else if (c.relative == kFloatRelativeLaststatus) { + row += Rows - (int)p_ch - last_stl_height(false); + } else if (c.relative == kFloatRelativeTabline) { + row += tabline_height(); } + bool resort = wp->w_grid_alloc.comp_index != 0 + && wp->w_grid_alloc.zindex != wp->w_config.zindex; + bool raise = resort && wp->w_grid_alloc.zindex < wp->w_config.zindex; wp->w_grid_alloc.zindex = wp->w_config.zindex; + if (resort) { + ui_comp_layers_adjust(wp->w_grid_alloc.comp_index, raise); + } if (ui_has(kUIMultigrid)) { String anchor = cstr_as_string(float_anchor_str[c.anchor]); if (!c.hide) { @@ -1075,6 +1070,7 @@ win_T *win_split_ins(int size, int flags, win_T *new_wp, int dir, frame_T *to_fl return NULL; } need_status = STATUS_HEIGHT; + win_float_anchor_laststatus(); } bool do_equal = false; @@ -1471,7 +1467,7 @@ win_T *win_split_ins(int size, int flags, win_T *new_wp, int dir, frame_T *to_fl frame_add_statusline(curfrp); } } - frame_new_height(curfrp, new_fr_height, flags & WSP_TOP, false); + frame_new_height(curfrp, new_fr_height, flags & WSP_TOP, false, false); } else { win_new_height(oldwin, oldwin_height - (new_size + STATUS_HEIGHT)); } @@ -2145,7 +2141,7 @@ static void win_equal_rec(win_T *next_curwin, bool current, frame_T *topfr, int || topfr->fr_width != width || topfr->fr_win->w_wincol != col) { topfr->fr_win->w_winrow = row; - frame_new_height(topfr, height, false, false); + frame_new_height(topfr, height, false, false, false); topfr->fr_win->w_wincol = col; frame_new_width(topfr, width, false, false); redraw_all_later(UPD_NOT_VALID); @@ -3163,7 +3159,7 @@ win_T *winframe_remove(win_T *win, int *dirp, tabpage_T *tp, frame_T **unflat_al if (*dirp == 'v') { frame_new_height(altfr, altfr->fr_height + frp_close->fr_height, - altfr == frp_close->fr_next, false); + altfr == frp_close->fr_next, false, false); } else { assert(*dirp == 'h'); frame_new_width(altfr, altfr->fr_width + frp_close->fr_width, @@ -3365,7 +3361,7 @@ void winframe_restore(win_T *wp, int dir, frame_T *unflat_altfr) // adjusts window sizes to fit restored statuslines/separators, if needed. if (dir == 'v') { frame_new_height(unflat_altfr, unflat_altfr->fr_height - frp->fr_height, - unflat_altfr == frp->fr_next, false); + unflat_altfr == frp->fr_next, false, false); } else if (dir == 'h') { frame_new_width(unflat_altfr, unflat_altfr->fr_width - frp->fr_width, unflat_altfr == frp->fr_next, false); @@ -3448,13 +3444,13 @@ static frame_T *win_altframe(win_T *win, tabpage_T *tp) static tabpage_T *alt_tabpage(void) { // Use the last accessed tab page, if possible. - if ((tcl_flags & TCL_USELAST) && valid_tabpage(lastused_tabpage)) { + if ((tcl_flags & kOptTclFlagUselast) && valid_tabpage(lastused_tabpage)) { return lastused_tabpage; } // Use the next tab page, if possible. bool forward = curtab->tp_next != NULL - && ((tcl_flags & TCL_LEFT) == 0 || curtab == first_tabpage); + && ((tcl_flags & kOptTclFlagLeft) == 0 || curtab == first_tabpage); tabpage_T *tp; if (forward) { @@ -3508,15 +3504,31 @@ static bool is_bottom_win(win_T *wp) } return true; } + +// 'cmdheight' value explicitly set by the user: window commands are allowed to +// resize the topframe to values higher than this minimum, but not lower. +static OptInt min_set_ch = 1; + /// Set a new height for a frame. Recursively sets the height for contained /// frames and windows. Caller must take care of positions. /// /// @param topfirst resize topmost contained frame first. /// @param wfh obey 'winfixheight' when there is a choice; /// may cause the height not to be set. -void frame_new_height(frame_T *topfrp, int height, bool topfirst, bool wfh) +/// @param set_ch set 'cmdheight' to resize topframe. +void frame_new_height(frame_T *topfrp, int height, bool topfirst, bool wfh, bool set_ch) FUNC_ATTR_NONNULL_ALL { + if (topfrp->fr_parent == NULL && set_ch) { + // topframe: update the command line height, with side effects. + OptInt new_ch = MAX(min_set_ch, p_ch + topfrp->fr_height - height); + if (new_ch != p_ch) { + const OptInt save_ch = min_set_ch; + set_option_value(kOptCmdheight, NUMBER_OPTVAL(new_ch), 0); + min_set_ch = save_ch; + } + height = (int)MIN(ROWS_AVAIL, height); + } if (topfrp->fr_win != NULL) { // Simple case: just one window. win_T *wp = topfrp->fr_win; @@ -3529,7 +3541,7 @@ void frame_new_height(frame_T *topfrp, int height, bool topfirst, bool wfh) do { // All frames in this row get the same new height. FOR_ALL_FRAMES(frp, topfrp->fr_child) { - frame_new_height(frp, height, topfirst, wfh); + frame_new_height(frp, height, topfirst, wfh, set_ch); if (frp->fr_height > height) { // Could not fit the windows, make the whole row higher. height = frp->fr_height; @@ -3571,10 +3583,9 @@ void frame_new_height(frame_T *topfrp, int height, bool topfirst, bool wfh) int h = frame_minheight(frp, NULL); if (frp->fr_height + extra_lines < h) { extra_lines += frp->fr_height - h; - frame_new_height(frp, h, topfirst, wfh); + frame_new_height(frp, h, topfirst, wfh, set_ch); } else { - frame_new_height(frp, frp->fr_height + extra_lines, - topfirst, wfh); + frame_new_height(frp, frp->fr_height + extra_lines, topfirst, wfh, set_ch); break; } if (topfirst) { @@ -3593,7 +3604,7 @@ void frame_new_height(frame_T *topfrp, int height, bool topfirst, bool wfh) } } else if (extra_lines > 0) { // increase height of bottom or top frame - frame_new_height(frp, frp->fr_height + extra_lines, topfirst, wfh); + frame_new_height(frp, frp->fr_height + extra_lines, topfirst, wfh, set_ch); } } topfrp->fr_height = height; @@ -4010,6 +4021,10 @@ void unuse_tabpage(tabpage_T *tp) tp->tp_curwin = curwin; } +// When switching tabpage, handle other side-effects in command_height(), but +// avoid setting frame sizes which are still correct. +static bool command_frame_height = true; + /// Set the relevant pointers to use tab page "tp". May want to call /// unuse_tabpage() first. void use_tabpage(tabpage_T *tp) @@ -4411,6 +4426,16 @@ static void enter_tabpage(tabpage_T *tp, buf_T *old_curbuf, bool trigger_enter_a use_tabpage(tp); + if (p_ch != curtab->tp_ch_used) { + // Use the stored value of p_ch, so that it can be different for each tab page. + // Handle other side-effects but avoid setting frame sizes, which are still correct. + OptInt new_ch = curtab->tp_ch_used; + curtab->tp_ch_used = p_ch; + command_frame_height = false; + set_option_value(kOptCmdheight, NUMBER_OPTVAL(new_ch), 0); + command_frame_height = true; + } + if (old_curtab != curtab) { tabpage_check_windows(old_curtab); } @@ -4424,27 +4449,9 @@ static void enter_tabpage(tabpage_T *tp, buf_T *old_curbuf, bool trigger_enter_a prevwin = next_prevwin; last_status(false); // status line may appear or disappear - const int row = win_comp_pos(); // recompute w_winrow for all windows + win_comp_pos(); // recompute w_winrow for all windows diff_need_scrollbind = true; - // Use the stored value of p_ch, so that it can be different for each tab page. - if (p_ch != curtab->tp_ch_used) { - clear_cmdline = true; - if (msg_grid.chars && p_ch < curtab->tp_ch_used) { - // TODO(bfredl): a bit expensive, should be enough to invalidate the - // region between the old and the new p_ch. - grid_invalidate(&msg_grid); - } - } - p_ch = curtab->tp_ch_used; - - // When cmdheight is changed in a tab page with '<C-w>-', cmdline_row is - // changed but p_ch and tp_ch_used are not changed. Thus we also need to - // check cmdline_row. - if (row < cmdline_row && cmdline_row <= Rows - p_ch) { - clear_cmdline = true; - } - // If there was a click in a window, it won't be usable for a following // drag. reset_dragwin(); @@ -5169,8 +5176,8 @@ win_T *win_alloc(win_T *after, bool hidden) return new_wp; } -// Free one wininfo_T. -void free_wininfo(wininfo_T *wip, buf_T *bp) +// Free one WinInfo. +void free_wininfo(WinInfo *wip, buf_T *bp) { if (wip->wi_optset) { clear_winopt(&wip->wi_opt); @@ -5235,30 +5242,27 @@ void win_free(win_T *wp, tabpage_T *tp) // Remove the window from the b_wininfo lists, it may happen that the // freed memory is re-used for another window. FOR_ALL_BUFFERS(buf) { - for (wininfo_T *wip = buf->b_wininfo; wip != NULL; wip = wip->wi_next) { + WinInfo *wip_wp = NULL; + size_t pos_wip = kv_size(buf->b_wininfo); + size_t pos_null = kv_size(buf->b_wininfo); + for (size_t i = 0; i < kv_size(buf->b_wininfo); i++) { + WinInfo *wip = kv_A(buf->b_wininfo, i); if (wip->wi_win == wp) { - wininfo_T *wip2; - - // If there already is an entry with "wi_win" set to NULL it - // must be removed, it would never be used. - // Skip "wip" itself, otherwise Coverity complains. - for (wip2 = buf->b_wininfo; wip2 != NULL; wip2 = wip2->wi_next) { - // `wip2 != wip` to satisfy Coverity. #14884 - if (wip2 != wip && wip2->wi_win == NULL) { - if (wip2->wi_next != NULL) { - wip2->wi_next->wi_prev = wip2->wi_prev; - } - if (wip2->wi_prev == NULL) { - buf->b_wininfo = wip2->wi_next; - } else { - wip2->wi_prev->wi_next = wip2->wi_next; - } - free_wininfo(wip2, buf); - break; - } - } + wip_wp = wip; + pos_wip = i; + } else if (wip->wi_win == NULL) { + pos_null = i; + } + } - wip->wi_win = NULL; + if (wip_wp) { + wip_wp->wi_win = NULL; + // If there already is an entry with "wi_win" set to NULL, only + // the first entry with NULL will ever be used, delete the other one. + if (pos_null < kv_size(buf->b_wininfo)) { + size_t pos_delete = MAX(pos_null, pos_wip); + free_wininfo(kv_A(buf->b_wininfo, pos_delete), buf); + kv_shift(buf->b_wininfo, pos_delete, 1); } } } @@ -5422,9 +5426,9 @@ void win_new_screen_rows(void) // First try setting the heights of windows with 'winfixheight'. If // that doesn't result in the right height, forget about that option. - frame_new_height(topframe, h, false, true); + frame_new_height(topframe, h, false, true, false); if (!frame_check_height(topframe, h)) { - frame_new_height(topframe, h, false, false); + frame_new_height(topframe, h, false, false, false); } win_comp_pos(); // recompute w_winrow and w_wincol @@ -5859,22 +5863,7 @@ void win_setheight_win(int height, win_T *win) frame_setheight(win->w_frame, height + win->w_hsep_height + win->w_status_height); // recompute the window positions - int row = win_comp_pos(); - - // If there is extra space created between the last window and the command - // line, clear it. - if (full_screen && msg_scrolled == 0 && row < cmdline_row) { - grid_clear(&default_grid, row, cmdline_row, 0, Columns, 0); - if (msg_grid.chars) { - clear_cmdline = true; - } - } - cmdline_row = row; - p_ch = MAX(Rows - cmdline_row, 0); - curtab->tp_ch_used = p_ch; - msg_row = row; - msg_col = 0; - + win_comp_pos(); win_fix_scroll(true); redraw_all_later(UPD_NOT_VALID); @@ -5902,14 +5891,8 @@ static void frame_setheight(frame_T *curfrp, int height) if (curfrp->fr_parent == NULL) { // topframe: can only change the command line height - if (height > ROWS_AVAIL) { - // If height is greater than the available space, try to create space for - // the frame by reducing 'cmdheight' if possible, while making sure - // `cmdheight` doesn't go below 1 if it wasn't set to 0 explicitly. - height = (int)MIN(ROWS_AVAIL + p_ch - !p_ch_was_zero, height); - } if (height > 0) { - frame_new_height(curfrp, height, false, false); + frame_new_height(curfrp, height, false, false, true); } } else if (curfrp->fr_parent->fr_layout == FR_ROW) { // Row of frames: Also need to resize frames left and right of this @@ -5988,7 +5971,7 @@ static void frame_setheight(frame_T *curfrp, int height) } // set the current frame to the new height - frame_new_height(curfrp, height, false, false); + frame_new_height(curfrp, height, false, false, true); // First take lines from the frames after the current frame. If // that is not enough, takes lines from frames above the current @@ -6010,15 +5993,15 @@ static void frame_setheight(frame_T *curfrp, int height) room_reserved = frp->fr_height - take; } take -= frp->fr_height - room_reserved; - frame_new_height(frp, room_reserved, false, false); + frame_new_height(frp, room_reserved, false, false, true); room_reserved = 0; } } else { if (frp->fr_height - take < h) { take -= frp->fr_height - h; - frame_new_height(frp, h, false, false); + frame_new_height(frp, h, false, false, true); } else { - frame_new_height(frp, frp->fr_height - take, false, false); + frame_new_height(frp, frp->fr_height - take, false, false, true); take = 0; } } @@ -6189,7 +6172,7 @@ const char *did_set_winminheight(optset_T *args FUNC_ATTR_UNUSED) // loop until there is a 'winminheight' that is possible while (p_wmh > 0) { const int room = Rows - (int)p_ch; - const int needed = min_rows(); + const int needed = min_rows_for_all_tabpages(); if (room >= needed) { break; } @@ -6276,7 +6259,7 @@ void win_drag_status_line(win_T *dragwin, int offset) room = Rows - cmdline_row; if (curfr->fr_next != NULL) { room -= (int)p_ch + global_stl_height(); - } else if (!p_ch_was_zero) { + } else if (min_set_ch > 0) { room--; } room = MAX(room, 0); @@ -6296,7 +6279,7 @@ void win_drag_status_line(win_T *dragwin, int offset) // Grow frame fr by "offset" lines. // Doesn't happen when dragging the last status line up. if (fr != NULL) { - frame_new_height(fr, fr->fr_height + offset, up, false); + frame_new_height(fr, fr->fr_height + offset, up, false, true); } if (up) { @@ -6309,9 +6292,9 @@ void win_drag_status_line(win_T *dragwin, int offset) int n = frame_minheight(fr, NULL); if (fr->fr_height - offset <= n) { offset -= fr->fr_height - n; - frame_new_height(fr, n, !up, false); + frame_new_height(fr, n, !up, false, true); } else { - frame_new_height(fr, fr->fr_height - offset, !up, false); + frame_new_height(fr, fr->fr_height - offset, !up, false, true); break; } if (up) { @@ -6320,15 +6303,7 @@ void win_drag_status_line(win_T *dragwin, int offset) fr = fr->fr_next; } } - int row = win_comp_pos(); - grid_clear(&default_grid, row, cmdline_row, 0, Columns, 0); - if (msg_grid.chars) { - clear_cmdline = true; - } - cmdline_row = row; - p_ch = MAX(Rows - cmdline_row, p_ch_was_zero ? 0 : 1); - curtab->tp_ch_used = p_ch; - + win_comp_pos(); win_fix_scroll(true); redraw_all_later(UPD_SOME_VALID); @@ -6390,7 +6365,7 @@ void win_drag_vsep_line(win_T *dragwin, int offset) fr = curfr; // put fr at window that grows } - // If not enough room thn move as far as we can + // If not enough room then move as far as we can offset = MIN(offset, room); // No room at all, quit. @@ -6765,21 +6740,6 @@ void command_height(void) { int old_p_ch = (int)curtab->tp_ch_used; - // Use the value of p_ch that we remembered. This is needed for when the - // GUI starts up, we can't be sure in what order things happen. And when - // p_ch was changed in another tab page. - curtab->tp_ch_used = p_ch; - - // Update cmdline_row to what it should be: just below the last window. - cmdline_row = topframe->fr_height + tabline_height() + global_stl_height(); - - // If cmdline_row is smaller than what it is supposed to be for 'cmdheight' - // then set old_p_ch to what it would be, so that the windows get resized - // properly for the new value. - if (cmdline_row < Rows - p_ch) { - old_p_ch = Rows - cmdline_row; - } - // Find bottom frame with width of screen. frame_T *frp = lastwin_nofloating()->w_frame; while (frp->fr_width != Columns && frp->fr_parent != NULL) { @@ -6787,60 +6747,53 @@ void command_height(void) } // Avoid changing the height of a window with 'winfixheight' set. - while (frp->fr_prev != NULL && frp->fr_layout == FR_LEAF - && frp->fr_win->w_p_wfh) { + while (frp->fr_prev != NULL && frp->fr_layout == FR_LEAF && frp->fr_win->w_p_wfh) { frp = frp->fr_prev; } - if (starting != NO_SCREEN) { - cmdline_row = Rows - (int)p_ch; - - if (p_ch > old_p_ch) { // p_ch got bigger - while (p_ch > old_p_ch) { - if (frp == NULL) { - emsg(_(e_noroom)); - p_ch = old_p_ch; - curtab->tp_ch_used = p_ch; - cmdline_row = Rows - (int)p_ch; - break; - } - int h = frp->fr_height - frame_minheight(frp, NULL); - h = MIN(h, (int)p_ch - old_p_ch); - old_p_ch += h; - frame_add_height(frp, -h); - frp = frp->fr_prev; - } - - // Recompute window positions. - win_comp_pos(); - - if (!need_wait_return) { - // clear the lines added to cmdline - if (full_screen) { - grid_clear(&default_grid, cmdline_row, Rows, 0, Columns, 0); - } - msg_row = cmdline_row; - } - redraw_cmdline = true; - return; + while (p_ch > old_p_ch && command_frame_height) { + if (frp == NULL) { + emsg(_(e_noroom)); + p_ch = old_p_ch; + break; } - - msg_row = MAX(msg_row, cmdline_row); - redraw_cmdline = true; + int h = MIN((int)(p_ch - old_p_ch), frp->fr_height - frame_minheight(frp, NULL)); + frame_add_height(frp, -h); + old_p_ch += h; + frp = frp->fr_prev; + } + if (p_ch < old_p_ch && command_frame_height && frp != NULL) { + frame_add_height(frp, (int)(old_p_ch - p_ch)); } - frame_add_height(frp, (int)(old_p_ch - p_ch)); // Recompute window positions. - if (frp != lastwin->w_frame) { - win_comp_pos(); + win_comp_pos(); + cmdline_row = Rows - (int)p_ch; + redraw_cmdline = true; + + // Clear the cmdheight area. + if (msg_scrolled == 0 && full_screen) { + ScreenGrid *grid = &default_grid; + if (!ui_has(kUIMessages)) { + msg_grid_validate(); + grid = &msg_grid_adj; + } + grid_clear(grid, cmdline_row, Rows, 0, Columns, 0); + msg_row = cmdline_row; } + + // Use the value of p_ch that we remembered. This is needed for when the + // GUI starts up, we can't be sure in what order things happen. And when + // p_ch was changed in another tab page. + curtab->tp_ch_used = p_ch; + min_set_ch = p_ch; } // Resize frame "frp" to be "n" lines higher (negative for less high). // Also resize the frames it is contained in. static void frame_add_height(frame_T *frp, int n) { - frame_new_height(frp, frp->fr_height + n, false, false); + frame_new_height(frp, frp->fr_height + n, false, false, false); while (true) { frp = frp->fr_parent; if (frp == NULL) { @@ -6858,6 +6811,7 @@ void last_status(bool morewin) { // Don't make a difference between horizontal or vertical split. last_status_rec(topframe, last_stl_height(morewin) > 0, global_stl_height() > 0); + win_float_anchor_laststatus(); } // Remove status line from window, replacing it with a horizontal separator if needed. @@ -6910,7 +6864,7 @@ static bool resize_frame_for_status(frame_T *fr) emsg(_(e_noroom)); return false; } else if (fp != fr) { - frame_new_height(fp, fp->fr_height - 1, false, false); + frame_new_height(fp, fp->fr_height - 1, false, false, false); frame_fix_height(wp); win_comp_pos(); } else { @@ -6931,7 +6885,7 @@ static bool resize_frame_for_winbar(frame_T *fr) emsg(_(e_noroom)); return false; } - frame_new_height(fp, fp->fr_height - 1, false, false); + frame_new_height(fp, fp->fr_height - 1, false, false, false); win_new_height(wp, wp->w_height + 1); frame_fix_height(wp); win_comp_pos(); @@ -7065,8 +7019,24 @@ int last_stl_height(bool morewin) } /// Return the minimal number of rows that is needed on the screen to display -/// the current number of windows. -int min_rows(void) +/// the current number of windows for the given tab page. +int min_rows(tabpage_T *tp) FUNC_ATTR_NONNULL_ALL +{ + if (firstwin == NULL) { // not initialized yet + return MIN_LINES; + } + + int total = frame_minheight(tp->tp_topframe, NULL); + total += tabline_height() + global_stl_height(); + if ((tp == curtab ? p_ch : tp->tp_ch_used) > 0) { + total++; // count the room for the command line + } + return total; +} + +/// Return the minimal number of rows that is needed on the screen to display +/// the current number of windows for all tab pages. +int min_rows_for_all_tabpages(void) { if (firstwin == NULL) { // not initialized yet return MIN_LINES; @@ -7075,12 +7045,12 @@ int min_rows(void) int total = 0; FOR_ALL_TABS(tp) { int n = frame_minheight(tp->tp_topframe, NULL); + if ((tp == curtab ? p_ch : tp->tp_ch_used) > 0) { + n++; // count the room for the command line + } total = MAX(total, n); } total += tabline_height() + global_stl_height(); - if (p_ch > 0) { - total += 1; // count the room for the command line - } return total; } @@ -7304,7 +7274,7 @@ static win_T *restore_snapshot_rec(frame_T *sn, frame_T *fr) fr->fr_height = sn->fr_height; fr->fr_width = sn->fr_width; if (fr->fr_layout == FR_LEAF) { - frame_new_height(fr, fr->fr_height, false, false); + frame_new_height(fr, fr->fr_height, false, false, false); frame_new_width(fr, fr->fr_width, false, false); wp = sn->fr_win; } |