From 35ea56c96a85e8ecc3c97210a2006e6b3694b062 Mon Sep 17 00:00:00 2001 From: Martin Rudalics Date: Mon, 6 Aug 2007 06:44:31 +0000 Subject: [PATCH] (window_min_size_2): New function. (window_min_size_1, size_window, Fdisplay_buffer) (Fsplit_window, adjust_window_trailing_edge): Use it to avoid windows without mode- or header-lines when window-min-height is too small. (size_window): Reset nodelete_p after testing it, following an earlier note by Kim F. Storm. (display_buffer): Do not set split_height_threshold to twice the value of window_min_height to avoid changing the value of a customizable variable. Rather explicitly check whether the height of the window that shall be splitted is at least as large as split_height_threshold. (Fwindow_full_width_p): New defun. (syms_of_window): Defsubr it. (Fdisplay_buffer): Use NILP. (Fset_window_scroll_bars): Likewise. --- src/window.c | 117 ++++++++++++++++++++++++++++++--------------------- 1 file changed, 70 insertions(+), 47 deletions(-) diff --git a/src/window.c b/src/window.c index e6fe32ea506..6fe78166ba1 100644 --- a/src/window.c +++ b/src/window.c @@ -62,6 +62,7 @@ static void window_scroll P_ ((Lisp_Object, int, int, int)); static void window_scroll_pixel_based P_ ((Lisp_Object, int, int, int)); static void window_scroll_line_based P_ ((Lisp_Object, int, int, int)); static int window_min_size_1 P_ ((struct window *, int)); +static int window_min_size_2 P_ ((struct window *, int)); static int window_min_size P_ ((struct window *, int, int, int *)); static void size_window P_ ((Lisp_Object, int, int, int, int, int)); static int freeze_window_start P_ ((struct window *, void *)); @@ -556,6 +557,15 @@ use (let ((edges (window-edges))) (- (nth 2 edges) (nth 0 edges))). */) return make_number (window_box_text_cols (decode_any_window (window))); } +DEFUN ("window-full-width-p", Fwindow_full_width_p, Swindow_full_width_p, 0, 1, 0, + doc: /* Return t if WINDOW is as wide as its frame. +WINDOW defaults to the selected window. */) + (window) + Lisp_Object window; +{ + return WINDOW_FULL_WIDTH_P (decode_any_window (window)) ? Qt : Qnil; +} + DEFUN ("window-hscroll", Fwindow_hscroll, Swindow_hscroll, 0, 1, 0, doc: /* Return the number of columns by which WINDOW is scrolled from left margin. WINDOW defaults to the selected window. */) @@ -2553,7 +2563,6 @@ check_frame_size (frame, rows, cols) *cols = MIN_SAFE_WINDOW_WIDTH; } - /* Value is non-zero if window W is fixed-size. WIDTH_P non-zero means check if W's width can be changed, otherwise check W's height. CHECK_SIBLINGS_P non-zero means check resizablity of WINDOW's @@ -2655,6 +2664,33 @@ window_fixed_size_p (w, width_p, check_siblings_p) return fixed_p; } +/* Return the minimum size for leaf window W. WIDTH_P non-zero means + take into account fringes and the scrollbar of W. WIDTH_P zero + means take into account mode-line and header-line of W. Return 1 + for the minibuffer. */ + +static int +window_min_size_2 (w, width_p) + struct window *w; + int width_p; +{ + int size; + + if (width_p) + size = max (window_min_width, + (MIN_SAFE_WINDOW_WIDTH + + WINDOW_FRINGE_COLS (w) + + WINDOW_SCROLL_BAR_COLS (w))); + else if (MINI_WINDOW_P (w)) + size = 1; + else + size = max (window_min_height, + (MIN_SAFE_WINDOW_HEIGHT + + (WINDOW_WANTS_MODELINE_P (w) ? 1 : 0) + + (WINDOW_WANTS_HEADER_LINE_P (w) ? 1 : 0 ))); + + return size; +} /* Return the minimum size of window W, not taking fixed-width windows into account. WIDTH_P non-zero means return the minimum width, @@ -2724,22 +2760,7 @@ window_min_size_1 (w, width_p) } } else - { - if (width_p) - size = max (window_min_width, - (MIN_SAFE_WINDOW_WIDTH - + WINDOW_FRINGE_COLS (w) - + WINDOW_SCROLL_BAR_COLS (w))); - else - { - if (MINI_WINDOW_P (w) - || (!WINDOW_WANTS_MODELINE_P (w) - && !WINDOW_WANTS_HEADER_LINE_P (w))) - size = 1; - else - size = window_min_height; - } - } + size = window_min_size_2 (w, width_p); return size; } @@ -2981,11 +3002,6 @@ size_window (window, size, width_p, nodelete_p, first_only, last_only) Lisp_Object child, *forward, *sideward; int old_size, min_size, safe_min_size; - /* We test nodelete_p != 2 and nodelete_p != 1 below, so it - seems like it's too soon to do this here. ++KFS. */ - if (nodelete_p == 2) - nodelete_p = 0; - check_min_window_sizes (); size = max (0, size); @@ -2996,22 +3012,23 @@ size_window (window, size, width_p, nodelete_p, first_only, last_only) { old_size = WINDOW_TOTAL_COLS (w); min_size = window_min_width; - /* Ensure that there is room for the scroll bar and fringes! - We may reduce display margins though. */ - safe_min_size = (MIN_SAFE_WINDOW_WIDTH - + WINDOW_FRINGE_COLS (w) - + WINDOW_SCROLL_BAR_COLS (w)); + safe_min_size = window_min_size_2 (w, 1); } else { old_size = XINT (w->total_lines); min_size = window_min_height; - safe_min_size = MIN_SAFE_WINDOW_HEIGHT; + safe_min_size = window_min_size_2 (w, 0); } if (old_size < min_size && nodelete_p != 2) w->too_small_ok = Qt; + /* Move the following test here since otherwise the + preceding test doesn't make sense. martin. */ + if (nodelete_p == 2) + nodelete_p = 0; + /* Maybe delete WINDOW if it's too small. */ if (nodelete_p != 1 && !NILP (w->parent)) { @@ -3708,9 +3725,6 @@ displayed. */) frames = Qnil; if (FRAME_MINIBUF_ONLY_P (f)) XSETFRAME (frames, last_nonminibuf_frame); - /* Don't try to create a window if we would get an error. */ - if (split_height_threshold < window_min_height << 1) - split_height_threshold = window_min_height << 1; /* Note that both Fget_largest_window and Fget_lru_window ignore minibuffers and dedicated windows. @@ -3733,25 +3747,30 @@ displayed. */) else window = Fget_largest_window (frames, Qt); - /* If we got a tall enough full-width window that can be split, - split it. */ + /* If the largest window is tall enough, full-width, and either eligible + for splitting or the only window, split it. */ if (!NILP (window) && ! FRAME_NO_SPLIT_P (XFRAME (XWINDOW (window)->frame)) - && window_height (window) >= split_height_threshold - && WINDOW_FULL_WIDTH_P (XWINDOW (window))) + && WINDOW_FULL_WIDTH_P (XWINDOW (window)) + && (window_height (window) >= split_height_threshold + || (NILP (XWINDOW (window)->parent))) + && (window_height (window) + >= (2 * window_min_size_2 (XWINDOW (window), 0)))) window = Fsplit_window (window, Qnil, Qnil); else { Lisp_Object upper, lower, other; window = Fget_lru_window (frames, Qt); - /* If the LRU window is selected, and big enough, - and can be split, split it. */ + /* If the LRU window is tall enough, and either eligible for splitting + and selected or the only window, split it. */ if (!NILP (window) && ! FRAME_NO_SPLIT_P (XFRAME (XWINDOW (window)->frame)) - && (EQ (window, selected_window) - || EQ (XWINDOW (window)->parent, Qnil)) - && window_height (window) >= window_min_height << 1) + && ((EQ (window, selected_window) + && window_height (window) >= split_height_threshold) + || (NILP (XWINDOW (window)->parent))) + && (window_height (window) + >= (2 * window_min_size_2 (XWINDOW (window), 0)))) window = Fsplit_window (window, Qnil, Qnil); else window = Fget_lru_window (frames, Qnil); @@ -4000,9 +4019,11 @@ See Info node `(elisp)Splitting Windows' for more details and examples.*/) if (NILP (horflag)) { - if (size_int < window_min_height) + int window_safe_height = window_min_size_2 (o, 0); + + if (size_int < window_safe_height) error ("Window height %d too small (after splitting)", size_int); - if (size_int + window_min_height > XFASTINT (o->total_lines)) + if (size_int + window_safe_height > XFASTINT (o->total_lines)) error ("Window height %d too small (after splitting)", XFASTINT (o->total_lines) - size_int); if (NILP (o->parent) @@ -4015,10 +4036,11 @@ See Info node `(elisp)Splitting Windows' for more details and examples.*/) } else { - if (size_int < window_min_width) + int window_safe_width = window_min_size_2 (o, 1); + + if (size_int < window_safe_width) error ("Window width %d too small (after splitting)", size_int); - - if (size_int + window_min_width > XFASTINT (o->total_cols)) + if (size_int + window_safe_width > XFASTINT (o->total_cols)) error ("Window width %d too small (after splitting)", XFASTINT (o->total_cols) - size_int); if (NILP (o->parent) @@ -4499,7 +4521,7 @@ adjust_window_trailing_edge (window, delta, horiz_flag) /* Don't make this window too small. */ if (XINT (CURSIZE (window)) + delta - < (horiz_flag ? window_min_width : window_min_height)) + < window_min_size_2 (XWINDOW (window), horiz_flag)) { Fset_window_configuration (old_config); error ("Cannot adjust window size as specified"); @@ -6897,7 +6919,7 @@ Fourth parameter HORIZONTAL-TYPE is currently unused. */) vertical_type = Qnil; } - if (!(EQ (vertical_type, Qnil) + if (!(NILP (vertical_type) || EQ (vertical_type, Qleft) || EQ (vertical_type, Qright) || EQ (vertical_type, Qt))) @@ -7502,6 +7524,7 @@ The selected frame is the one whose configuration has changed. */); defsubr (&Swindow_buffer); defsubr (&Swindow_height); defsubr (&Swindow_width); + defsubr (&Swindow_full_width_p); defsubr (&Swindow_hscroll); defsubr (&Sset_window_hscroll); defsubr (&Swindow_redisplay_end_trigger); -- 2.39.2