patch 9.1.1425: tabpanel: there are still some problems with the tabpanel

Problem:  tabpanel: there are still some problems with the tabpanel with
          column handling
Solution: fix the problems and refactor Tabpanel feature (Hirohito
          Higashi).

fixes: #17423
fixes: #17332
closes: #17336

Signed-off-by: Hirohito Higashi <h.east.727@gmail.com>
Signed-off-by: Christian Brabandt <cb@256bit.org>
diff --git a/src/window.c b/src/window.c
index 8543758..f3b23e8 100644
--- a/src/window.c
+++ b/src/window.c
@@ -1385,8 +1385,8 @@
 	// width and column of new window is same as current window
 	if (flags & (WSP_TOP | WSP_BOT))
 	{
-	    wp->w_wincol = 0;
-	    win_new_width(wp, COLUMNS_WITHOUT_TPL());
+	    wp->w_wincol = firstwin->w_wincol;
+	    win_new_width(wp, topframe->fr_width);
 	    wp->w_vsep_width = 0;
 	}
 	else
@@ -2085,8 +2085,8 @@
     if (dir == 0)
 	dir = *p_ead;
     win_equal_rec(next_curwin == NULL ? curwin : next_curwin, current,
-		      topframe, dir, 0, tabline_height(),
-		      (int)COLUMNS_WITHOUT_TPL(), topframe->fr_height);
+		      topframe, dir, firstwin->w_wincol, tabline_height(),
+		      topframe->fr_width, topframe->fr_height);
     if (!is_aucmd_win(next_curwin))
 	win_fix_scroll(TRUE);
 }
@@ -2144,7 +2144,7 @@
 	    // frame.
 	    n = frame_minwidth(topfr, NOWIN);
 	    // add one for the rightmost window, it doesn't have a separator
-	    if (col + width == COLUMNS_WITHOUT_TPL())
+	    if (col + width >= firstwin->w_wincol + topframe->fr_width)
 		extra_sep = 1;
 	    else
 		extra_sep = 0;
@@ -2619,14 +2619,14 @@
     // Since goto_tabpage_tp above did not trigger *Enter autocommands, do
     // that now.
     apply_autocmds(EVENT_TABCLOSED, NULL, NULL, FALSE, curbuf);
-    apply_autocmds(EVENT_WINENTER, NULL, NULL, FALSE, curbuf);
-    apply_autocmds(EVENT_TABENTER, NULL, NULL, FALSE, curbuf);
-    if (old_curbuf != curbuf)
-	apply_autocmds(EVENT_BUFENTER, NULL, NULL, FALSE, curbuf);
 #if defined(FEAT_TABPANEL)
     if (p_stpl > 0)
 	shell_new_columns();
 #endif
+    apply_autocmds(EVENT_WINENTER, NULL, NULL, FALSE, curbuf);
+    apply_autocmds(EVENT_TABENTER, NULL, NULL, FALSE, curbuf);
+    if (old_curbuf != curbuf)
+	apply_autocmds(EVENT_BUFENTER, NULL, NULL, FALSE, curbuf);
     return TRUE;
 }
 
@@ -4596,8 +4596,7 @@
     firstwin->w_height = ROWS_AVAIL;
     firstwin->w_prev_height = ROWS_AVAIL;
     topframe->fr_height = ROWS_AVAIL;
-    firstwin->w_width = COLUMNS_WITHOUT_TPL();
-    topframe->fr_width = COLUMNS_WITHOUT_TPL();
+    firstwin->w_width = topframe->fr_width;
 }
 
 /*
@@ -4696,6 +4695,9 @@
     tabpage_T	*prev_tp = curtab;
     tabpage_T	*newtp;
     int		n;
+#if defined(FEAT_TABPANEL)
+    int prev_columns = COLUMNS_WITHOUT_TPL();
+#endif
 
     if (cmdwin_type != 0)
     {
@@ -4763,7 +4765,22 @@
 #ifdef FEAT_JOB_CHANNEL
 	entering_window(curwin);
 #endif
+#if defined(FEAT_TABPANEL)
+	if (prev_columns != COLUMNS_WITHOUT_TPL())
+	{
+	    tabpage_T *save_curtab = curtab;
 
+	    unuse_tabpage(curtab);
+	    use_tabpage(prev_tp);
+	    shell_new_rows();
+	    shell_new_columns();
+
+	    unuse_tabpage(curtab);
+	    use_tabpage(save_curtab);
+	    shell_new_rows();
+	    shell_new_columns();
+	}
+#endif
 	redraw_all_later(UPD_NOT_VALID);
 	apply_autocmds(EVENT_WINNEW, NULL, NULL, FALSE, curbuf);
 	apply_autocmds(EVENT_WINENTER, NULL, NULL, FALSE, curbuf);
@@ -4971,7 +4988,7 @@
     tp->tp_lastwin = lastwin;
     tp->tp_old_Rows = Rows;
     if (tp->tp_old_Columns != -1)
-	tp->tp_old_Columns = COLUMNS_WITHOUT_TPL();
+	tp->tp_old_Columns = topframe->fr_width;
     firstwin = NULL;
     lastwin = NULL;
     return OK;
@@ -5034,12 +5051,12 @@
 #endif
 		))
 	shell_new_rows();
-    if (curtab->tp_old_Columns != COLUMNS_WITHOUT_TPL())
+    if (curtab->tp_old_Columns != topframe->fr_width)
     {
 	if (starting == 0)
 	{
 	    shell_new_columns();	// update window widths
-	    curtab->tp_old_Columns = COLUMNS_WITHOUT_TPL();
+	    curtab->tp_old_Columns = topframe->fr_width;
 	}
 	else
 	    curtab->tp_old_Columns = -1;  // update window widths later
@@ -5805,7 +5822,7 @@
      */
     if (!hidden)
 	win_append(after, new_wp);
-    new_wp->w_wincol = 0;
+    new_wp->w_wincol = TPL_LCOL(NULL);
     new_wp->w_width = COLUMNS_WITHOUT_TPL();
 
     // position the display and the cursor at the top of the file.
@@ -6164,8 +6181,8 @@
     if (h < frame_minheight(topframe, NULL))
 	h = frame_minheight(topframe, NULL);
 
-    // First try setting the heights of windows with 'winfixheight'.  If
-    // that doesn't result in the right height, forget about that option.
+    // 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, FALSE);
     if (!frame_check_height(topframe, h))
 	frame_new_height(topframe, h, FALSE, FALSE, FALSE);
@@ -6177,6 +6194,10 @@
     if (!skip_win_fix_scroll)
 	win_fix_scroll(TRUE);
 
+    redraw_tabline = TRUE;
+#if defined(FEAT_TABPANEL)
+    redraw_tabpanel = TRUE;
+#endif
 #if 0
     // Disabled: don't want making the screen smaller make a window larger.
     if (p_ea)
@@ -6193,13 +6214,23 @@
     if (firstwin == NULL)	// not initialized yet
 	return;
 
+    int w = COLUMNS_WITHOUT_TPL();
+
     // First try setting the widths of windows with 'winfixwidth'.  If that
     // doesn't result in the right width, forget about that option.
-    frame_new_width(topframe, COLUMNS_WITHOUT_TPL(), FALSE, TRUE);
-    if (!frame_check_width(topframe, COLUMNS_WITHOUT_TPL()))
-	frame_new_width(topframe, COLUMNS_WITHOUT_TPL(), FALSE, FALSE);
+    frame_new_width(topframe, w, FALSE, TRUE);
+    if (!frame_check_width(topframe, w))
+	frame_new_width(topframe, w, FALSE, FALSE);
 
     (void)win_comp_pos();		// recompute w_winrow and w_wincol
+
+    if (!skip_win_fix_scroll)
+	win_fix_scroll(TRUE);
+
+    redraw_tabline = TRUE;
+#if defined(FEAT_TABPANEL)
+    redraw_tabpanel = TRUE;
+#endif
 #if 0
     // Disabled: don't want making the screen smaller make a window larger.
     if (p_ea)
@@ -6269,7 +6300,7 @@
 win_comp_pos(void)
 {
     int		row = tabline_height();
-    int		col = 0;
+    int		col = TPL_LCOL(NULL);
 
     frame_comp_pos(topframe, &row, &col);
     return row;
@@ -6439,7 +6470,7 @@
 		if (frp != curfrp)
 		    room -= frame_minheight(frp, NULL);
 	    }
-	    if (curfrp->fr_width != COLUMNS_WITHOUT_TPL())
+	    if (curfrp->fr_width != topframe->fr_width)
 		room_cmdline = 0;
 	    else
 	    {
@@ -6452,7 +6483,7 @@
 
 	    if (height <= room + room_cmdline)
 		break;
-	    if (run == 2 || curfrp->fr_width == COLUMNS_WITHOUT_TPL())
+	    if (run == 2 || curfrp->fr_width == topframe->fr_width)
 	    {
 		height = room + room_cmdline;
 		break;
@@ -6757,7 +6788,7 @@
     // loop until there is a 'winminheight' that is possible
     while (p_wmw > 0)
     {
-	room = Columns;
+	room = topframe->fr_width;
 	needed = frame_minwidth(topframe, NULL);
 	if (room >= needed)
 	    break;
@@ -7347,7 +7378,7 @@
 
     // Find bottom frame with width of screen.
     frame_T *frp = lastwin->w_frame;
-    while (frp->fr_width != COLUMNS_WITHOUT_TPL() && frp->fr_parent != NULL)
+    while (frp->fr_width != topframe->fr_width && frp->fr_parent != NULL)
 	frp = frp->fr_parent;
 
     // Avoid changing the height of a window with 'winfixheight' set.
@@ -7667,7 +7698,7 @@
 	    if (wp->w_save_cursor.w_topline_corr == wp->w_topline
 				  && wp->w_save_cursor.w_topline_save != 0)
 		wp->w_topline = wp->w_save_cursor.w_topline_save;
-	   if (wp->w_save_cursor.w_topline_save > wp->w_buffer->b_ml.ml_line_count)
+	    if (wp->w_save_cursor.w_topline_save > wp->w_buffer->b_ml.ml_line_count)
 		wp->w_valid &= ~VALID_TOPLINE;
 	}
 }