aboutsummaryrefslogtreecommitdiffstats
path: root/src/window.c
diff options
context:
space:
mode:
authorMartin Rudalics2008-05-01 10:17:47 +0000
committerMartin Rudalics2008-05-01 10:17:47 +0000
commit047aaeb9fd1e673ec473a20199430e8797df5e61 (patch)
treefc93d07238493f8ea8ac59598432d03ad9e204a6 /src/window.c
parent92f774f36eca32759f97381e8502444aefb59940 (diff)
downloademacs-047aaeb9fd1e673ec473a20199430e8797df5e61.tar.gz
emacs-047aaeb9fd1e673ec473a20199430e8797df5e61.zip
(make_window): Initialize resize_proportionally.
(enlarge_window): Temporarily set resize_proportionally to make sure that shrink_windows does scale the window proportionally. (shrink_windows): When window has resize_proportionally set try to shrink it proportionally by stealing from other windows. (struct saved_window, Fset_window_configuration) (compare_window_configurations): Handle resize_proportionally. (WINDOW_TOTAL_SIZE): New macro. (window_min_size, shrink_windows, size_window): Use it. (check_min_window_sizes): Removed. Invalid values of window-min-height|width are handled by window_min_size_2 now. (size_window, Fsplit_window, enlarge_window) (adjust_window_trailing_edge, grow_mini_window): Don't call check_min_window_sizes. (window_min_size_2, window_min_size_1, window_min_size): New argument safe_p for retrieving "safe" minimum sizes. (Fdisplay_buffer, Fsplit_window, enlarge_window): (adjust_window_trailing_edge, grow_mini_window): Adjust arguments of window_min_size... functions. (shrink_windows): Argument min_size removed. New argument safe_p allows shrinking windows to their safe minimum sizes. Calculate minimum size and decide whether a window shall be deleted for each window individually. (size_window): When nodelete_p equals 2, tell shrink_windows to delete windows only if their new minimum size is no more safe. (shrink_window_lowest_first): Call window_min_size_1 to make sure to preserve modeline of bottom-most window when resizing the minibuffer. (Fset_window_configuration, Fcurrent_window_configuration) (compare_window_configurations): Do not handle window-min-height|width any more. (syms_of_window): Clarify window-min-height|width doc-strings.
Diffstat (limited to 'src/window.c')
-rw-r--r--src/window.c441
1 files changed, 208 insertions, 233 deletions
diff --git a/src/window.c b/src/window.c
index 77940d250a6..f93cb6a366e 100644
--- a/src/window.c
+++ b/src/window.c
@@ -65,9 +65,9 @@ static int get_leaf_windows P_ ((struct window *, struct window **, int));
65static void window_scroll P_ ((Lisp_Object, int, int, int)); 65static void window_scroll P_ ((Lisp_Object, int, int, int));
66static void window_scroll_pixel_based P_ ((Lisp_Object, int, int, int)); 66static void window_scroll_pixel_based P_ ((Lisp_Object, int, int, int));
67static void window_scroll_line_based P_ ((Lisp_Object, int, int, int)); 67static void window_scroll_line_based P_ ((Lisp_Object, int, int, int));
68static int window_min_size_1 P_ ((struct window *, int)); 68static int window_min_size_1 P_ ((struct window *, int, int));
69static int window_min_size_2 P_ ((struct window *, int)); 69static int window_min_size_2 P_ ((struct window *, int, int));
70static int window_min_size P_ ((struct window *, int, int, int *)); 70static int window_min_size P_ ((struct window *, int, int, int, int *));
71static void size_window P_ ((Lisp_Object, int, int, int, int, int)); 71static void size_window P_ ((Lisp_Object, int, int, int, int, int));
72static int freeze_window_start P_ ((struct window *, void *)); 72static int freeze_window_start P_ ((struct window *, void *));
73static int window_fixed_size_p P_ ((struct window *, int, int)); 73static int window_fixed_size_p P_ ((struct window *, int, int));
@@ -299,6 +299,7 @@ make_window ()
299 p->fringes_outside_margins = Qnil; 299 p->fringes_outside_margins = Qnil;
300 p->scroll_bar_width = Qnil; 300 p->scroll_bar_width = Qnil;
301 p->vertical_scroll_bar_type = Qt; 301 p->vertical_scroll_bar_type = Qt;
302 p->resize_proportionally = Qnil;
302 303
303 Vwindow_list = Qnil; 304 Vwindow_list = Qnil;
304 return val; 305 return val;
@@ -2550,18 +2551,11 @@ replace_buffer_in_all_windows (buffer)
2550#define MIN_SAFE_WINDOW_WIDTH (2) 2551#define MIN_SAFE_WINDOW_WIDTH (2)
2551#define MIN_SAFE_WINDOW_HEIGHT (1) 2552#define MIN_SAFE_WINDOW_HEIGHT (1)
2552 2553
2553/* Make sure that window_min_height and window_min_width are 2554/* For wp non-zero the total number of columns of window w. Otherwise
2554 not too small; if they are, set them to safe minima. */ 2555 the total number of lines of w. */
2555 2556
2556static void 2557#define WINDOW_TOTAL_SIZE(w, wp) \
2557check_min_window_sizes () 2558 (wp ? WINDOW_TOTAL_COLS (w) : WINDOW_TOTAL_LINES (w))
2558{
2559 /* Smaller values might permit a crash. */
2560 if (window_min_width < MIN_SAFE_WINDOW_WIDTH)
2561 window_min_width = MIN_SAFE_WINDOW_WIDTH;
2562 if (window_min_height < MIN_SAFE_WINDOW_HEIGHT)
2563 window_min_height = MIN_SAFE_WINDOW_HEIGHT;
2564}
2565 2559
2566/* If *ROWS or *COLS are too small a size for FRAME, set them to the 2560/* If *ROWS or *COLS are too small a size for FRAME, set them to the
2567 minimum allowable size. */ 2561 minimum allowable size. */
@@ -2608,7 +2602,7 @@ window_fixed_size_p (w, width_p, check_siblings_p)
2608 2602
2609 if (width_p) 2603 if (width_p)
2610 { 2604 {
2611 /* A horiz. combination is fixed-width if all of if its 2605 /* A horizontal combination is fixed-width if all of if its
2612 children are. */ 2606 children are. */
2613 while (c && window_fixed_size_p (c, width_p, 0)) 2607 while (c && window_fixed_size_p (c, width_p, 0))
2614 c = WINDOWP (c->next) ? XWINDOW (c->next) : NULL; 2608 c = WINDOWP (c->next) ? XWINDOW (c->next) : NULL;
@@ -2616,7 +2610,7 @@ window_fixed_size_p (w, width_p, check_siblings_p)
2616 } 2610 }
2617 else 2611 else
2618 { 2612 {
2619 /* A horiz. combination is fixed-height if one of if its 2613 /* A horizontal combination is fixed-height if one of if its
2620 children is. */ 2614 children is. */
2621 while (c && !window_fixed_size_p (c, width_p, 0)) 2615 while (c && !window_fixed_size_p (c, width_p, 0))
2622 c = WINDOWP (c->next) ? XWINDOW (c->next) : NULL; 2616 c = WINDOWP (c->next) ? XWINDOW (c->next) : NULL;
@@ -2629,7 +2623,7 @@ window_fixed_size_p (w, width_p, check_siblings_p)
2629 2623
2630 if (width_p) 2624 if (width_p)
2631 { 2625 {
2632 /* A vert. combination is fixed-width if one of if its 2626 /* A vertical combination is fixed-width if one of if its
2633 children is. */ 2627 children is. */
2634 while (c && !window_fixed_size_p (c, width_p, 0)) 2628 while (c && !window_fixed_size_p (c, width_p, 0))
2635 c = WINDOWP (c->next) ? XWINDOW (c->next) : NULL; 2629 c = WINDOWP (c->next) ? XWINDOW (c->next) : NULL;
@@ -2637,7 +2631,7 @@ window_fixed_size_p (w, width_p, check_siblings_p)
2637 } 2631 }
2638 else 2632 else
2639 { 2633 {
2640 /* A vert. combination is fixed-height if all of if its 2634 /* A vertical combination is fixed-height if all of if its
2641 children are. */ 2635 children are. */
2642 while (c && window_fixed_size_p (c, width_p, 0)) 2636 while (c && window_fixed_size_p (c, width_p, 0))
2643 c = WINDOWP (c->next) ? XWINDOW (c->next) : NULL; 2637 c = WINDOWP (c->next) ? XWINDOW (c->next) : NULL;
@@ -2689,120 +2683,130 @@ window_fixed_size_p (w, width_p, check_siblings_p)
2689 return fixed_p; 2683 return fixed_p;
2690} 2684}
2691 2685
2692/* Return the minimum size for leaf window W. WIDTH_P non-zero means 2686/* Return minimum size of leaf window W. WIDTH_P non-zero means return
2693 take into account fringes and the scrollbar of W. WIDTH_P zero means 2687 the minimum width of W, WIDTH_P zero means return the minimum height
2694 take into account mode-line of W. Return 1 for the minibuffer. */ 2688 of W. SAFE_P non-zero means ignore window-min-height|width but just
2689 return values that won't crash Emacs and don't hide components like
2690 fringes, scrollbars, or modelines. If WIDTH_P is zero and W is the
2691 minibuffer window, always return 1. */
2695 2692
2696static int 2693static int
2697window_min_size_2 (w, width_p) 2694window_min_size_2 (w, width_p, safe_p)
2698 struct window *w; 2695 struct window *w;
2699 int width_p; 2696 int width_p, safe_p;
2700{ 2697{
2701 int size; 2698 /* We should consider buffer-local values of window_min_height and
2702 2699 window_min_width here. */
2703 if (width_p) 2700 if (width_p)
2704 size = max (window_min_width, 2701 {
2705 (MIN_SAFE_WINDOW_WIDTH 2702 int safe_size = (MIN_SAFE_WINDOW_WIDTH
2706 + WINDOW_FRINGE_COLS (w) 2703 + WINDOW_FRINGE_COLS (w)
2707 + WINDOW_SCROLL_BAR_COLS (w))); 2704 + WINDOW_SCROLL_BAR_COLS (w));
2705
2706 return safe_p ? safe_size : max (window_min_width, safe_size);
2707 }
2708 else if (MINI_WINDOW_P (w)) 2708 else if (MINI_WINDOW_P (w))
2709 size = 1; 2709 return 1;
2710 else 2710 else
2711 size = max (window_min_height, 2711 {
2712 (MIN_SAFE_WINDOW_HEIGHT 2712 int safe_size = (MIN_SAFE_WINDOW_HEIGHT
2713 /* Don't count the header-line here. It would break 2713 + ((BUFFERP (w->buffer)
2714 splitting a window with a header-line when the new 2714 && !NILP (XBUFFER (w->buffer)->mode_line_format))
2715 window shall have a height of two (calculator does 2715 ? 1 : 0));
2716 that). */
2717 + (WINDOW_WANTS_MODELINE_P (w) ? 1 : 0)));
2718 2716
2719 return size; 2717 return safe_p ? safe_size : max (window_min_height, safe_size);
2718 }
2720} 2719}
2721 2720
2722/* Return the minimum size of window W, not taking fixed-width windows 2721/* Return minimum size of window W, not taking fixed-width windows into
2723 into account. WIDTH_P non-zero means return the minimum width, 2722 account. WIDTH_P non-zero means return the minimum width, otherwise
2724 otherwise return the minimum height. If W is a combination window, 2723 return the minimum height. SAFE_P non-zero means ignore
2725 compute the minimum size from the minimum sizes of W's children. */ 2724 window-min-height|width but just return values that won't crash Emacs
2725 and don't hide components like fringes, scrollbars, or modelines. If
2726 W is a combination window, compute the minimum size from the minimum
2727 sizes of W's children. */
2726 2728
2727static int 2729static int
2728window_min_size_1 (w, width_p) 2730window_min_size_1 (w, width_p, safe_p)
2729 struct window *w; 2731 struct window *w;
2730 int width_p; 2732 int width_p, safe_p;
2731{ 2733{
2732 struct window *c; 2734 struct window *c;
2733 int size; 2735 int size;
2734 2736
2735 if (!NILP (w->hchild)) 2737 if (!NILP (w->hchild))
2736 { 2738 {
2739 /* W is a horizontal combination. */
2737 c = XWINDOW (w->hchild); 2740 c = XWINDOW (w->hchild);
2738 size = 0; 2741 size = 0;
2739 2742
2740 if (width_p) 2743 if (width_p)
2741 { 2744 {
2742 /* The min width of a horizontal combination is 2745 /* The minimum width of a horizontal combination is the sum of
2743 the sum of the min widths of its children. */ 2746 the minimum widths of its children. */
2744 while (c) 2747 while (c)
2745 { 2748 {
2746 size += window_min_size_1 (c, width_p); 2749 size += window_min_size_1 (c, 1, safe_p);
2747 c = WINDOWP (c->next) ? XWINDOW (c->next) : NULL; 2750 c = WINDOWP (c->next) ? XWINDOW (c->next) : NULL;
2748 } 2751 }
2749 } 2752 }
2750 else 2753 else
2751 { 2754 {
2752 /* The min height a horizontal combination equals 2755 /* The minimum height of a horizontal combination is the
2753 the maximum of all min height of its children. */ 2756 maximum of the minimum heights of its children. */
2754 while (c) 2757 while (c)
2755 { 2758 {
2756 int min_size = window_min_size_1 (c, width_p); 2759 size = max (window_min_size_1 (c, 0, safe_p), size);
2757 size = max (min_size, size);
2758 c = WINDOWP (c->next) ? XWINDOW (c->next) : NULL; 2760 c = WINDOWP (c->next) ? XWINDOW (c->next) : NULL;
2759 } 2761 }
2760 } 2762 }
2761 } 2763 }
2762 else if (!NILP (w->vchild)) 2764 else if (!NILP (w->vchild))
2763 { 2765 {
2766 /* W is a vertical combination. */
2764 c = XWINDOW (w->vchild); 2767 c = XWINDOW (w->vchild);
2765 size = 0; 2768 size = 0;
2766 2769
2767 if (width_p) 2770 if (width_p)
2768 { 2771 {
2769 /* The min width of a vertical combination is 2772 /* The minimum width of a vertical combination is the maximum
2770 the maximum of the min widths of its children. */ 2773 of the minimum widths of its children. */
2771 while (c) 2774 while (c)
2772 { 2775 {
2773 int min_size = window_min_size_1 (c, width_p); 2776 size = max (window_min_size_1 (c, 1, safe_p), size);
2774 size = max (min_size, size);
2775 c = WINDOWP (c->next) ? XWINDOW (c->next) : NULL; 2777 c = WINDOWP (c->next) ? XWINDOW (c->next) : NULL;
2776 } 2778 }
2777 } 2779 }
2778 else 2780 else
2779 { 2781 {
2780 /* The min height of a vertical combination equals 2782 /* The minimum height of a vertical combination is the sum of
2781 the sum of the min height of its children. */ 2783 the minimum height of its children. */
2782 while (c) 2784 while (c)
2783 { 2785 {
2784 size += window_min_size_1 (c, width_p); 2786 size += window_min_size_1 (c, 0, safe_p);
2785 c = WINDOWP (c->next) ? XWINDOW (c->next) : NULL; 2787 c = WINDOWP (c->next) ? XWINDOW (c->next) : NULL;
2786 } 2788 }
2787 } 2789 }
2788 } 2790 }
2789 else 2791 else
2790 size = window_min_size_2 (w, width_p); 2792 /* W is a leaf window. */
2793 size = window_min_size_2 (w, width_p, safe_p);
2791 2794
2792 return size; 2795 return size;
2793} 2796}
2794 2797
2795
2796/* Return the minimum size of window W, taking fixed-size windows into 2798/* Return the minimum size of window W, taking fixed-size windows into
2797 account. WIDTH_P non-zero means return the minimum width, 2799 account. WIDTH_P non-zero means return the minimum width, otherwise
2798 otherwise return the minimum height. IGNORE_FIXED_P non-zero means 2800 return the minimum height. SAFE_P non-zero means ignore
2799 ignore if W is fixed-size. Set *FIXED to 1 if W is fixed-size 2801 window-min-height|width but just return values that won't crash Emacs
2800 unless FIXED is null. */ 2802 and don't hide components like fringes, scrollbars, or modelines.
2803 IGNORE_FIXED_P non-zero means ignore if W is fixed-size. Set *FIXED
2804 to 1 if W is fixed-size unless FIXED is null. */
2801 2805
2802static int 2806static int
2803window_min_size (w, width_p, ignore_fixed_p, fixed) 2807window_min_size (w, width_p, safe_p, ignore_fixed_p, fixed)
2804 struct window *w; 2808 struct window *w;
2805 int width_p, ignore_fixed_p, *fixed; 2809 int width_p, safe_p, ignore_fixed_p, *fixed;
2806{ 2810{
2807 int size, fixed_p; 2811 int size, fixed_p;
2808 2812
@@ -2815,9 +2819,9 @@ window_min_size (w, width_p, ignore_fixed_p, fixed)
2815 *fixed = fixed_p; 2819 *fixed = fixed_p;
2816 2820
2817 if (fixed_p) 2821 if (fixed_p)
2818 size = width_p ? XFASTINT (w->total_cols) : XFASTINT (w->total_lines); 2822 size = WINDOW_TOTAL_SIZE (w, width_p);
2819 else 2823 else
2820 size = window_min_size_1 (w, width_p); 2824 size = window_min_size_1 (w, width_p, safe_p);
2821 2825
2822 return size; 2826 return size;
2823} 2827}
@@ -2859,35 +2863,38 @@ adjust_window_margins (w)
2859 return 1; 2863 return 1;
2860} 2864}
2861 2865
2862/* Calculate new sizes for windows in the list FORWARD when the window size 2866/* Calculate new sizes for windows in the list FORWARD when their
2863 goes from TOTAL to SIZE. TOTAL must be greater than SIZE. 2867 compound size goes from TOTAL to SIZE. TOTAL must be greater than
2864 The number of windows in FORWARD is NCHILDREN, and the number that 2868 SIZE. The number of windows in FORWARD is NCHILDREN, and the number
2865 can shrink is SHRINKABLE. 2869 that can shrink is SHRINKABLE. Fixed-size windows may be shrunk if
2866 The minimum size a window can have is MIN_SIZE. 2870 and only if RESIZE_FIXED_P is non-zero. WIDTH_P non-zero means
2867 If we are shrinking fixed windows, RESIZE_FIXED_P is non-zero. 2871 shrink columns, otherwise shrink lines.
2868 If we are shrinking columns, WIDTH_P is non-zero, otherwise we are
2869 shrinking rows.
2870 2872
2871 This function returns an allocated array of new sizes that the caller 2873 SAFE_P zero means windows may be sized down to window-min-height
2872 must free. The size -1 means the window is fixed and RESIZE_FIXED_P 2874 lines (window-min-window columns for WIDTH_P non-zero). SAFE_P
2873 is zero. Array index 0 refers to the first window in FORWARD, 1 to 2875 non-zero means windows may be sized down to their minimum safe sizes
2874 the second, and so on. 2876 taking into account the space needed to display modelines, fringes,
2877 and scrollbars.
2875 2878
2876 This function tries to keep windows at least at the minimum size 2879 This function returns an allocated array of new sizes that the caller
2877 and resize other windows before it resizes any window to zero (i.e. 2880 must free. A size -1 means the window is fixed and RESIZE_FIXED_P is
2878 delete that window). 2881 zero. A size zero means the window shall be deleted. Array index 0
2879 2882 refers to the first window in FORWARD, 1 to the second, and so on.
2880 Windows are resized proportional to their size, so bigger windows 2883
2881 shrink more than smaller windows. */ 2884 This function resizes windows proportionally to their size. It also
2885 tries to preserve smaller windows by resizing larger windows before
2886 resizing any window to zero. If resize_proportionally is non-nil for
2887 a specific window, it will attempt to strictly resize that window
2888 proportionally, even at the expense of deleting smaller windows. */
2882static int * 2889static int *
2883shrink_windows (total, size, nchildren, shrinkable, 2890shrink_windows (total, size, nchildren, shrinkable, resize_fixed_p,
2884 min_size, resize_fixed_p, forward, width_p) 2891 forward, width_p, safe_p)
2885 int total, size, nchildren, shrinkable, min_size; 2892 int total, size, nchildren, shrinkable;
2886 int resize_fixed_p, width_p; 2893 int resize_fixed_p, width_p, safe_p;
2887 Lisp_Object forward; 2894 Lisp_Object forward;
2888{ 2895{
2889 int available_resize = 0; 2896 int available_resize = 0;
2890 int *new_sizes; 2897 int *new_sizes, *min_sizes;
2891 struct window *c; 2898 struct window *c;
2892 Lisp_Object child; 2899 Lisp_Object child;
2893 int smallest = total; 2900 int smallest = total;
@@ -2896,21 +2903,24 @@ shrink_windows (total, size, nchildren, shrinkable,
2896 int i; 2903 int i;
2897 2904
2898 new_sizes = xmalloc (sizeof (*new_sizes) * nchildren); 2905 new_sizes = xmalloc (sizeof (*new_sizes) * nchildren);
2906 min_sizes = xmalloc (sizeof (*min_sizes) * nchildren);
2899 2907
2900 for (i = 0, child = forward; !NILP (child); child = c->next, ++i) 2908 for (i = 0, child = forward; !NILP (child); child = c->next, ++i)
2901 { 2909 {
2902 int child_size; 2910 int child_size;
2903 2911
2904 c = XWINDOW (child); 2912 c = XWINDOW (child);
2905 child_size = width_p ? XINT (c->total_cols) : XINT (c->total_lines); 2913 child_size = WINDOW_TOTAL_SIZE (c, width_p);
2906 2914
2907 if (! resize_fixed_p && window_fixed_size_p (c, width_p, 0)) 2915 if (!resize_fixed_p && window_fixed_size_p (c, width_p, 0))
2908 new_sizes[i] = -1; 2916 new_sizes[i] = -1;
2909 else 2917 else
2910 { 2918 {
2911 new_sizes[i] = child_size; 2919 new_sizes[i] = child_size;
2912 if (child_size > min_size) 2920 min_sizes[i] = window_min_size_1 (c, width_p, safe_p);
2913 available_resize += child_size - min_size; 2921 if (child_size > min_sizes[i]
2922 && NILP (c->resize_proportionally))
2923 available_resize += child_size - min_sizes[i];
2914 } 2924 }
2915 } 2925 }
2916 /* We might need to shrink some windows to zero. Find the smallest 2926 /* We might need to shrink some windows to zero. Find the smallest
@@ -2927,8 +2937,8 @@ shrink_windows (total, size, nchildren, shrinkable,
2927 { 2937 {
2928 /* Resize this window down to zero. */ 2938 /* Resize this window down to zero. */
2929 new_sizes[i] = 0; 2939 new_sizes[i] = 0;
2930 if (smallest > min_size) 2940 if (smallest > min_sizes[i])
2931 available_resize -= smallest - min_size; 2941 available_resize -= smallest - min_sizes[i];
2932 available_resize += smallest; 2942 available_resize += smallest;
2933 --shrinkable; 2943 --shrinkable;
2934 total_removed += smallest; 2944 total_removed += smallest;
@@ -2946,11 +2956,12 @@ shrink_windows (total, size, nchildren, shrinkable,
2946 proportional to its size. */ 2956 proportional to its size. */
2947 for (i = 0; i < nchildren; ++i) 2957 for (i = 0; i < nchildren; ++i)
2948 { 2958 {
2949 if (new_sizes[i] > min_size) 2959 if (new_sizes[i] > min_sizes[i])
2950 { 2960 {
2951 int to_shrink = total_shrink*new_sizes[i]/total; 2961 int to_shrink = total_shrink * new_sizes[i] / total;
2952 if (new_sizes[i] - to_shrink < min_size) 2962
2953 to_shrink = new_sizes[i] - min_size; 2963 if (new_sizes[i] - to_shrink < min_sizes[i])
2964 to_shrink = new_sizes[i] - min_sizes[i];
2954 new_sizes[i] -= to_shrink; 2965 new_sizes[i] -= to_shrink;
2955 total_removed += to_shrink; 2966 total_removed += to_shrink;
2956 } 2967 }
@@ -2971,7 +2982,7 @@ shrink_windows (total, size, nchildren, shrinkable,
2971 } 2982 }
2972 2983
2973 for (i = 0; i < nchildren; ++i) 2984 for (i = 0; i < nchildren; ++i)
2974 if (new_sizes[i] > min_size) 2985 if (new_sizes[i] > min_sizes[i])
2975 { 2986 {
2976 --new_sizes[i]; 2987 --new_sizes[i];
2977 ++total_removed; 2988 ++total_removed;
@@ -2981,7 +2992,6 @@ shrink_windows (total, size, nchildren, shrinkable,
2981 break; 2992 break;
2982 } 2993 }
2983 2994
2984
2985 /* Special case, only one window left. */ 2995 /* Special case, only one window left. */
2986 if (nonzero_sizes == 1) 2996 if (nonzero_sizes == 1)
2987 break; 2997 break;
@@ -3001,22 +3011,24 @@ shrink_windows (total, size, nchildren, shrinkable,
3001 } 3011 }
3002 } 3012 }
3003 3013
3014 xfree (min_sizes);
3015
3004 return new_sizes; 3016 return new_sizes;
3005} 3017}
3006 3018
3007/* Set WINDOW's height or width to SIZE. WIDTH_P non-zero means set 3019/* Set WINDOW's height or width to SIZE. WIDTH_P non-zero means set
3008 WINDOW's width. Resize WINDOW's children, if any, so that they 3020 WINDOW's width. Resize WINDOW's children, if any, so that they keep
3009 keep their proportionate size relative to WINDOW. 3021 their proportionate size relative to WINDOW.
3010 3022
3011 If FIRST_ONLY is 1, change only the first of WINDOW's children when 3023 If FIRST_ONLY is 1, change only the first of WINDOW's children when
3012 they are in series. If LAST_ONLY is 1, change only the last of 3024 they are in series. If LAST_ONLY is 1, change only the last of
3013 WINDOW's children when they are in series. 3025 WINDOW's children when they are in series.
3014 3026
3015 Propagate WINDOW's top or left edge position to children. Delete 3027 Propagate WINDOW's top or left edge position to children. Delete
3016 windows that become too small unless NODELETE_P is non-zero. 3028 windows that become too small unless NODELETE_P is 1. When
3017 3029 NODELETE_P equals 2 do not honor settings for window-min-height and
3018 If NODELETE_P is 2, that means we do delete windows that are 3030 window-min-width when resizing windows but use safe defaults instead.
3019 too small, even if they were too small before! */ 3031 This should give better behavior when resizing frames. */
3020 3032
3021static void 3033static void
3022size_window (window, size, width_p, nodelete_p, first_only, last_only) 3034size_window (window, size, width_p, nodelete_p, first_only, last_only)
@@ -3027,47 +3039,16 @@ size_window (window, size, width_p, nodelete_p, first_only, last_only)
3027 struct window *w = XWINDOW (window); 3039 struct window *w = XWINDOW (window);
3028 struct window *c; 3040 struct window *c;
3029 Lisp_Object child, *forward, *sideward; 3041 Lisp_Object child, *forward, *sideward;
3030 int old_size, min_size, safe_min_size; 3042 int old_size = WINDOW_TOTAL_SIZE (w, width_p);
3031 3043
3032 check_min_window_sizes ();
3033 size = max (0, size); 3044 size = max (0, size);
3034 3045
3035 /* If the window has been "too small" at one point, 3046 /* Delete WINDOW if it's too small. */
3036 don't delete it for being "too small" in the future. 3047 if (nodelete_p != 1 && !NILP (w->parent)
3037 Preserve it as long as that is at all possible. */ 3048 && size < window_min_size_1 (w, width_p, nodelete_p == 2))
3038 if (width_p)
3039 {
3040 old_size = WINDOW_TOTAL_COLS (w);
3041 min_size = window_min_width;
3042 safe_min_size = window_min_size_2 (w, 1);
3043 }
3044 else
3045 { 3049 {
3046 old_size = XINT (w->total_lines); 3050 delete_window (window);
3047 min_size = window_min_height; 3051 return;
3048 safe_min_size = window_min_size_2 (w, 0);
3049 }
3050
3051 if (old_size < min_size && nodelete_p != 2)
3052 w->too_small_ok = Qt;
3053
3054 /* Move the following test here since otherwise the
3055 preceding test doesn't make sense. martin. */
3056 if (nodelete_p == 2)
3057 nodelete_p = 0;
3058
3059 /* Maybe delete WINDOW if it's too small. */
3060 if (nodelete_p != 1 && !NILP (w->parent))
3061 {
3062 if (!MINI_WINDOW_P (w) && !NILP (w->too_small_ok))
3063 min_size = width_p ? MIN_SAFE_WINDOW_WIDTH : MIN_SAFE_WINDOW_HEIGHT;
3064 if (min_size < safe_min_size)
3065 min_size = safe_min_size;
3066 if (size < min_size)
3067 {
3068 delete_window (window);
3069 return;
3070 }
3071 } 3052 }
3072 3053
3073 /* Set redisplay hints. */ 3054 /* Set redisplay hints. */
@@ -3117,9 +3098,8 @@ size_window (window, size, width_p, nodelete_p, first_only, last_only)
3117 last_child = child; 3098 last_child = child;
3118 } 3099 }
3119 3100
3120 child_size = XINT (width_p ? c->total_cols : c->total_lines); 3101 child_size = WINDOW_TOTAL_SIZE (c, width_p);
3121 size_window (last_child, 3102 size_window (last_child, size - old_size + child_size,
3122 size - old_size + child_size,
3123 width_p, nodelete_p, first_only, last_only); 3103 width_p, nodelete_p, first_only, last_only);
3124 } 3104 }
3125 else if (!NILP (*forward) && first_only) 3105 else if (!NILP (*forward) && first_only)
@@ -3135,9 +3115,8 @@ size_window (window, size, width_p, nodelete_p, first_only, last_only)
3135 else 3115 else
3136 c->top_line = w->top_line; 3116 c->top_line = w->top_line;
3137 3117
3138 child_size = XINT (width_p ? c->total_cols : c->total_lines); 3118 child_size = WINDOW_TOTAL_SIZE (c, width_p);
3139 size_window (child, 3119 size_window (child, size - old_size + child_size,
3140 size - old_size + child_size,
3141 width_p, nodelete_p, first_only, last_only); 3120 width_p, nodelete_p, first_only, last_only);
3142 } 3121 }
3143 else if (!NILP (*forward)) 3122 else if (!NILP (*forward))
@@ -3155,7 +3134,7 @@ size_window (window, size, width_p, nodelete_p, first_only, last_only)
3155 int child_size; 3134 int child_size;
3156 3135
3157 c = XWINDOW (child); 3136 c = XWINDOW (child);
3158 child_size = width_p ? XINT (c->total_cols) : XINT (c->total_lines); 3137 child_size = WINDOW_TOTAL_SIZE (c, width_p);
3159 total += child_size; 3138 total += child_size;
3160 3139
3161 if (window_fixed_size_p (c, width_p, 0)) 3140 if (window_fixed_size_p (c, width_p, 0))
@@ -3174,8 +3153,9 @@ size_window (window, size, width_p, nodelete_p, first_only, last_only)
3174 value of extra takes care of rounding errors. */ 3153 value of extra takes care of rounding errors. */
3175 n = resize_fixed_p ? nchildren : nchildren - nfixed; 3154 n = resize_fixed_p ? nchildren : nchildren - nfixed;
3176 if (size < total && n > 1) 3155 if (size < total && n > 1)
3177 new_sizes = shrink_windows (total, size, nchildren, n, min_size, 3156 new_sizes = shrink_windows (total, size, nchildren, n,
3178 resize_fixed_p, *forward, width_p); 3157 resize_fixed_p, *forward, width_p,
3158 nodelete_p == 2);
3179 else 3159 else
3180 { 3160 {
3181 each = (size - total) / n; 3161 each = (size - total) / n;
@@ -3190,7 +3170,7 @@ size_window (window, size, width_p, nodelete_p, first_only, last_only)
3190 int new_size, old_size; 3170 int new_size, old_size;
3191 3171
3192 c = XWINDOW (child); 3172 c = XWINDOW (child);
3193 old_size = width_p ? XFASTINT (c->total_cols) : XFASTINT (c->total_lines); 3173 old_size = WINDOW_TOTAL_SIZE (c, width_p);
3194 new_size = old_size; 3174 new_size = old_size;
3195 3175
3196 /* The top or left edge position of this child equals the 3176 /* The top or left edge position of this child equals the
@@ -3207,7 +3187,7 @@ size_window (window, size, width_p, nodelete_p, first_only, last_only)
3207 extra = 0; 3187 extra = 0;
3208 } 3188 }
3209 3189
3210 /* Set new height. Note that size_window also propagates 3190 /* Set new size. Note that size_window also propagates
3211 edge positions to children, so it's not a no-op if we 3191 edge positions to children, so it's not a no-op if we
3212 didn't change the child's size. */ 3192 didn't change the child's size. */
3213 size_window (child, new_size, width_p, 1, first_only, last_only); 3193 size_window (child, new_size, width_p, 1, first_only, last_only);
@@ -3223,21 +3203,26 @@ size_window (window, size, width_p, nodelete_p, first_only, last_only)
3223 xassert (size == last_pos - first_pos); 3203 xassert (size == last_pos - first_pos);
3224 3204
3225 /* Now delete any children that became too small. */ 3205 /* Now delete any children that became too small. */
3226 if (!nodelete_p) 3206 if (nodelete_p != 1)
3227 for (child = *forward; !NILP (child); child = c->next) 3207 for (child = *forward; !NILP (child); child = c->next)
3228 { 3208 {
3229 int child_size; 3209 int child_size;
3210
3230 c = XWINDOW (child); 3211 c = XWINDOW (child);
3231 child_size = width_p ? XINT (c->total_cols) : XINT (c->total_lines); 3212 child_size = WINDOW_TOTAL_SIZE (c, width_p);
3232 size_window (child, child_size, width_p, 2, first_only, last_only); 3213 size_window (child, child_size, width_p, nodelete_p,
3214 first_only, last_only);
3233 } 3215 }
3234 } 3216 }
3235} 3217}
3236 3218
3237/* Set WINDOW's height to HEIGHT, and recursively change the height of 3219/* Set WINDOW's height to HEIGHT, and recursively change the height of
3238 WINDOW's children. NODELETE non-zero means don't delete windows 3220 WINDOW's children. NODELETE zero means windows that have become
3239 that become too small in the process. (The caller should check 3221 smaller than window-min-height in the process may be deleted.
3240 later and do so if appropriate.) */ 3222 NODELETE 1 means never delete windows that become too small in the
3223 process. (The caller should check later and do so if appropriate.)
3224 NODELETE 2 means delete only windows that have become too small to be
3225 displayed correctly. */
3241 3226
3242void 3227void
3243set_window_height (window, height, nodelete) 3228set_window_height (window, height, nodelete)
@@ -3248,11 +3233,13 @@ set_window_height (window, height, nodelete)
3248 size_window (window, height, 0, nodelete, 0, 0); 3233 size_window (window, height, 0, nodelete, 0, 0);
3249} 3234}
3250 3235
3251
3252/* Set WINDOW's width to WIDTH, and recursively change the width of 3236/* Set WINDOW's width to WIDTH, and recursively change the width of
3253 WINDOW's children. NODELETE non-zero means don't delete windows 3237 WINDOW's children. NODELETE zero means windows that have become
3254 that become too small in the process. (The caller should check 3238 smaller than window-min-width in the process may be deleted.
3255 later and do so if appropriate.) */ 3239 NODELETE 1 means never delete windows that become too small in the
3240 process. (The caller should check later and do so if appropriate.)
3241 NODELETE 2 means delete only windows that have become too small to be
3242 displayed correctly. */
3256 3243
3257void 3244void
3258set_window_width (window, width, nodelete) 3245set_window_width (window, width, nodelete)
@@ -3359,7 +3346,7 @@ run_window_configuration_change_hook (struct frame *f)
3359 } 3346 }
3360 } 3347 }
3361 } 3348 }
3362 3349
3363 run_funs (global_wcch); 3350 run_funs (global_wcch);
3364 unbind_to (count, Qnil); 3351 unbind_to (count, Qnil);
3365} 3352}
@@ -3863,7 +3850,7 @@ displayed. */)
3863 && (window_height (window) >= split_height_threshold 3850 && (window_height (window) >= split_height_threshold
3864 || (NILP (XWINDOW (window)->parent))) 3851 || (NILP (XWINDOW (window)->parent)))
3865 && (window_height (window) 3852 && (window_height (window)
3866 >= (2 * window_min_size_2 (XWINDOW (window), 0)))) 3853 >= (2 * window_min_size_2 (XWINDOW (window), 0, 0))))
3867 window = Fsplit_window (window, Qnil, Qnil); 3854 window = Fsplit_window (window, Qnil, Qnil);
3868 else 3855 else
3869 { 3856 {
@@ -3878,7 +3865,7 @@ displayed. */)
3878 && window_height (window) >= split_height_threshold) 3865 && window_height (window) >= split_height_threshold)
3879 || (NILP (XWINDOW (window)->parent))) 3866 || (NILP (XWINDOW (window)->parent)))
3880 && (window_height (window) 3867 && (window_height (window)
3881 >= (2 * window_min_size_2 (XWINDOW (window), 0)))) 3868 >= (2 * window_min_size_2 (XWINDOW (window), 0, 0))))
3882 window = Fsplit_window (window, Qnil, Qnil); 3869 window = Fsplit_window (window, Qnil, Qnil);
3883 else 3870 else
3884 window = Fget_lru_window (frames, Qnil); 3871 window = Fget_lru_window (frames, Qnil);
@@ -4124,12 +4111,10 @@ See Info node `(elisp)Splitting Windows' for more details and examples.*/)
4124 else if (window_fixed_size_p (o, !NILP (horflag), 0)) 4111 else if (window_fixed_size_p (o, !NILP (horflag), 0))
4125 error ("Attempt to split fixed-size window"); 4112 error ("Attempt to split fixed-size window");
4126 4113
4127 check_min_window_sizes ();
4128
4129 if (NILP (horflag)) 4114 if (NILP (horflag))
4130 { 4115 {
4131 int window_safe_height = window_min_size_2 (o, 0); 4116 int window_safe_height = window_min_size_2 (o, 0, 0);
4132 4117
4133 if (size_int < window_safe_height) 4118 if (size_int < window_safe_height)
4134 error ("Window height %d too small (after splitting)", size_int); 4119 error ("Window height %d too small (after splitting)", size_int);
4135 if (size_int + window_safe_height > XFASTINT (o->total_lines)) 4120 if (size_int + window_safe_height > XFASTINT (o->total_lines))
@@ -4145,8 +4130,8 @@ See Info node `(elisp)Splitting Windows' for more details and examples.*/)
4145 } 4130 }
4146 else 4131 else
4147 { 4132 {
4148 int window_safe_width = window_min_size_2 (o, 1); 4133 int window_safe_width = window_min_size_2 (o, 1, 0);
4149 4134
4150 if (size_int < window_safe_width) 4135 if (size_int < window_safe_width)
4151 error ("Window width %d too small (after splitting)", size_int); 4136 error ("Window width %d too small (after splitting)", size_int);
4152 if (size_int + window_safe_width > XFASTINT (o->total_cols)) 4137 if (size_int + window_safe_width > XFASTINT (o->total_cols))
@@ -4277,12 +4262,11 @@ window_width (window)
4277 *(horiz_flag ? &(XWINDOW (w)->total_cols) : &(XWINDOW (w)->total_lines)) 4262 *(horiz_flag ? &(XWINDOW (w)->total_cols) : &(XWINDOW (w)->total_lines))
4278 4263
4279 4264
4280/* Enlarge WINDOW by DELTA. 4265/* Enlarge WINDOW by DELTA. HORIZ_FLAG nonzero means enlarge it
4281 HORIZ_FLAG nonzero means enlarge it horizontally; 4266 horizontally; zero means do it vertically.
4282 zero means do it vertically.
4283 4267
4284 Siblings of the selected window are resized to fulfill the size 4268 Siblings of the selected window are resized to fulfill the size
4285 request. If they become too small in the process, they will be 4269 request. If they become too small in the process, they may be
4286 deleted. */ 4270 deleted. */
4287 4271
4288static void 4272static void
@@ -4299,10 +4283,6 @@ enlarge_window (window, delta, horiz_flag)
4299 void (*setsizefun) P_ ((Lisp_Object, int, int)) 4283 void (*setsizefun) P_ ((Lisp_Object, int, int))
4300 = (horiz_flag ? set_window_width : set_window_height); 4284 = (horiz_flag ? set_window_width : set_window_height);
4301 4285
4302 /* Check values of window_min_width and window_min_height for
4303 validity. */
4304 check_min_window_sizes ();
4305
4306 /* Give up if this window cannot be resized. */ 4286 /* Give up if this window cannot be resized. */
4307 if (window_fixed_size_p (XWINDOW (window), horiz_flag, 1)) 4287 if (window_fixed_size_p (XWINDOW (window), horiz_flag, 1))
4308 error ("Window is not resizable"); 4288 error ("Window is not resizable");
@@ -4339,11 +4319,11 @@ enlarge_window (window, delta, horiz_flag)
4339 /* This is a main window followed by a minibuffer. */ 4319 /* This is a main window followed by a minibuffer. */
4340 : !NILP (p->next) ? ((*sizefun) (p->next) 4320 : !NILP (p->next) ? ((*sizefun) (p->next)
4341 - window_min_size (XWINDOW (p->next), 4321 - window_min_size (XWINDOW (p->next),
4342 horiz_flag, 0, 0)) 4322 horiz_flag, 0, 0, 0))
4343 /* This is a minibuffer following a main window. */ 4323 /* This is a minibuffer following a main window. */
4344 : !NILP (p->prev) ? ((*sizefun) (p->prev) 4324 : !NILP (p->prev) ? ((*sizefun) (p->prev)
4345 - window_min_size (XWINDOW (p->prev), 4325 - window_min_size (XWINDOW (p->prev),
4346 horiz_flag, 0, 0)) 4326 horiz_flag, 0, 0, 0))
4347 /* This is a frame with only one window, a minibuffer-only 4327 /* This is a frame with only one window, a minibuffer-only
4348 or a minibufferless frame. */ 4328 or a minibufferless frame. */
4349 : (delta = 0)); 4329 : (delta = 0));
@@ -4355,7 +4335,8 @@ enlarge_window (window, delta, horiz_flag)
4355 delta = maxdelta; 4335 delta = maxdelta;
4356 } 4336 }
4357 4337
4358 if (XINT (*sizep) + delta < window_min_size (XWINDOW (window), horiz_flag, 0, 0)) 4338 if (XINT (*sizep) + delta < window_min_size (XWINDOW (window),
4339 horiz_flag, 0, 0, 0))
4359 { 4340 {
4360 delete_window (window); 4341 delete_window (window);
4361 return; 4342 return;
@@ -4368,10 +4349,10 @@ enlarge_window (window, delta, horiz_flag)
4368 maximum = 0; 4349 maximum = 0;
4369 for (next = p->next; WINDOWP (next); next = XWINDOW (next)->next) 4350 for (next = p->next; WINDOWP (next); next = XWINDOW (next)->next)
4370 maximum += (*sizefun) (next) - window_min_size (XWINDOW (next), 4351 maximum += (*sizefun) (next) - window_min_size (XWINDOW (next),
4371 horiz_flag, 0, 0); 4352 horiz_flag, 0, 0, 0);
4372 for (prev = p->prev; WINDOWP (prev); prev = XWINDOW (prev)->prev) 4353 for (prev = p->prev; WINDOWP (prev); prev = XWINDOW (prev)->prev)
4373 maximum += (*sizefun) (prev) - window_min_size (XWINDOW (prev), 4354 maximum += (*sizefun) (prev) - window_min_size (XWINDOW (prev),
4374 horiz_flag, 0, 0); 4355 horiz_flag, 0, 0, 0);
4375 4356
4376 /* If we can get it all from them without deleting them, do so. */ 4357 /* If we can get it all from them without deleting them, do so. */
4377 if (delta <= maximum) 4358 if (delta <= maximum)
@@ -4392,8 +4373,8 @@ enlarge_window (window, delta, horiz_flag)
4392 if (! NILP (next)) 4373 if (! NILP (next))
4393 { 4374 {
4394 int this_one = ((*sizefun) (next) 4375 int this_one = ((*sizefun) (next)
4395 - window_min_size (XWINDOW (next), 4376 - window_min_size (XWINDOW (next), horiz_flag,
4396 horiz_flag, 0, &fixed_p)); 4377 0, 0, &fixed_p));
4397 if (!fixed_p) 4378 if (!fixed_p)
4398 { 4379 {
4399 if (this_one > delta) 4380 if (this_one > delta)
@@ -4414,8 +4395,8 @@ enlarge_window (window, delta, horiz_flag)
4414 if (! NILP (prev)) 4395 if (! NILP (prev))
4415 { 4396 {
4416 int this_one = ((*sizefun) (prev) 4397 int this_one = ((*sizefun) (prev)
4417 - window_min_size (XWINDOW (prev), 4398 - window_min_size (XWINDOW (prev), horiz_flag,
4418 horiz_flag, 0, &fixed_p)); 4399 0, 0, &fixed_p));
4419 if (!fixed_p) 4400 if (!fixed_p)
4420 { 4401 {
4421 if (this_one > delta) 4402 if (this_one > delta)
@@ -4474,7 +4455,7 @@ enlarge_window (window, delta, horiz_flag)
4474 4455
4475 /* Delete any siblings that come after WINDOW. 4456 /* Delete any siblings that come after WINDOW.
4476 Note that if START is not WINDOW, then WINDOW still 4457 Note that if START is not WINDOW, then WINDOW still
4477 Fhas siblings, so WINDOW has not yet replaced its parent. */ 4458 has siblings, so WINDOW has not yet replaced its parent. */
4478 tem = start; 4459 tem = start;
4479 while (! EQ (tem, window)) 4460 while (! EQ (tem, window))
4480 { 4461 {
@@ -4511,7 +4492,11 @@ enlarge_window (window, delta, horiz_flag)
4511 4492
4512 The number of children n equals the number of resizable 4493 The number of children n equals the number of resizable
4513 children of this window + 1 because we know window itself 4494 children of this window + 1 because we know window itself
4514 is resizable (otherwise we would have signalled an error). */ 4495 is resizable (otherwise we would have signalled an error).
4496
4497 This reasoning is not correct when other windows become too
4498 small and shrink_windows refuses to delete them. Below we
4499 use resize_proportionally to work around this problem. */
4515 4500
4516 struct window *w = XWINDOW (window); 4501 struct window *w = XWINDOW (window);
4517 Lisp_Object s; 4502 Lisp_Object s;
@@ -4532,12 +4517,17 @@ enlarge_window (window, delta, horiz_flag)
4532 (*setsizefun) (window, XINT (*sizep) + delta1, 0); 4517 (*setsizefun) (window, XINT (*sizep) + delta1, 0);
4533 4518
4534 /* Squeeze out delta1 lines or columns from our parent, 4519 /* Squeeze out delta1 lines or columns from our parent,
4535 shriking this window and siblings proportionately. 4520 shrinking this window and siblings proportionately. This
4536 This brings parent back to correct size. 4521 brings parent back to correct size. Delta1 was calculated
4537 Delta1 was calculated so this makes this window the desired size, 4522 so this makes this window the desired size, taking it all
4538 taking it all out of the siblings. */ 4523 out of the siblings.
4524
4525 Temporarily set resize_proportionally to Qt to assure that,
4526 if necessary, shrink_windows deletes smaller windows rather
4527 than shrink this window. */
4528 w->resize_proportionally = Qt;
4539 (*setsizefun) (parent, opht, 0); 4529 (*setsizefun) (parent, opht, 0);
4540 4530 w->resize_proportionally = Qnil;
4541 } 4531 }
4542 } 4532 }
4543 4533
@@ -4567,10 +4557,6 @@ adjust_window_trailing_edge (window, delta, horiz_flag)
4567 Lisp_Object old_config = Fcurrent_window_configuration (Qnil); 4557 Lisp_Object old_config = Fcurrent_window_configuration (Qnil);
4568 int delcount = window_deletion_count; 4558 int delcount = window_deletion_count;
4569 4559
4570 /* Check values of window_min_width and window_min_height for
4571 validity. */
4572 check_min_window_sizes ();
4573
4574 CHECK_WINDOW (window); 4560 CHECK_WINDOW (window);
4575 4561
4576 /* Give up if this window cannot be resized. */ 4562 /* Give up if this window cannot be resized. */
@@ -4625,7 +4611,7 @@ adjust_window_trailing_edge (window, delta, horiz_flag)
4625 4611
4626 /* Don't make this window too small. */ 4612 /* Don't make this window too small. */
4627 if (XINT (CURSIZE (window)) + delta 4613 if (XINT (CURSIZE (window)) + delta
4628 < window_min_size_2 (XWINDOW (window), horiz_flag)) 4614 < window_min_size_2 (XWINDOW (window), horiz_flag, 0))
4629 { 4615 {
4630 Fset_window_configuration (old_config); 4616 Fset_window_configuration (old_config);
4631 error ("Cannot adjust window size as specified"); 4617 error ("Cannot adjust window size as specified");
@@ -4778,13 +4764,13 @@ shrink_window_lowest_first (w, height)
4778 for (child = w->vchild; WINDOWP (child); child = XWINDOW (child)->next) 4764 for (child = w->vchild; WINDOWP (child); child = XWINDOW (child)->next)
4779 last_child = child; 4765 last_child = child;
4780 4766
4781 /* Assign new heights. We leave only MIN_SAFE_WINDOW_HEIGHT. */ 4767 /* Size children down to their safe heights. */
4782 for (child = last_child; delta && !NILP (child); child = c->prev) 4768 for (child = last_child; delta && !NILP (child); child = c->prev)
4783 { 4769 {
4784 int this_one; 4770 int this_one;
4785 4771
4786 c = XWINDOW (child); 4772 c = XWINDOW (child);
4787 this_one = XFASTINT (c->total_lines) - MIN_SAFE_WINDOW_HEIGHT; 4773 this_one = XFASTINT (c->total_lines) - window_min_size_1 (c, 0, 1);
4788 4774
4789 if (this_one > delta) 4775 if (this_one > delta)
4790 this_one = delta; 4776 this_one = delta;
@@ -4887,16 +4873,12 @@ grow_mini_window (w, delta)
4887 xassert (MINI_WINDOW_P (w)); 4873 xassert (MINI_WINDOW_P (w));
4888 xassert (delta >= 0); 4874 xassert (delta >= 0);
4889 4875
4890 /* Check values of window_min_width and window_min_height for
4891 validity. */
4892 check_min_window_sizes ();
4893
4894 /* Compute how much we can enlarge the mini-window without deleting 4876 /* Compute how much we can enlarge the mini-window without deleting
4895 other windows. */ 4877 other windows. */
4896 root = XWINDOW (FRAME_ROOT_WINDOW (f)); 4878 root = XWINDOW (FRAME_ROOT_WINDOW (f));
4897 if (delta) 4879 if (delta)
4898 { 4880 {
4899 int min_height = window_min_size (root, 0, 0, 0); 4881 int min_height = window_min_size (root, 0, 0, 0, 0);
4900 if (XFASTINT (root->total_lines) - delta < min_height) 4882 if (XFASTINT (root->total_lines) - delta < min_height)
4901 /* Note that the root window may already be smaller than 4883 /* Note that the root window may already be smaller than
4902 min_height. */ 4884 min_height. */
@@ -6141,9 +6123,6 @@ struct save_window_data
6141 6123
6142 int frame_cols, frame_lines, frame_menu_bar_lines; 6124 int frame_cols, frame_lines, frame_menu_bar_lines;
6143 int frame_tool_bar_lines; 6125 int frame_tool_bar_lines;
6144 /* Record the values of window-min-width and window-min-height
6145 so that window sizes remain consistent with them. */
6146 int min_width, min_height;
6147 }; 6126 };
6148 6127
6149/* This is saved as a Lisp_Vector */ 6128/* This is saved as a Lisp_Vector */
@@ -6164,7 +6143,7 @@ struct saved_window
6164 Lisp_Object left_margin_cols, right_margin_cols; 6143 Lisp_Object left_margin_cols, right_margin_cols;
6165 Lisp_Object left_fringe_width, right_fringe_width, fringes_outside_margins; 6144 Lisp_Object left_fringe_width, right_fringe_width, fringes_outside_margins;
6166 Lisp_Object scroll_bar_width, vertical_scroll_bar_type; 6145 Lisp_Object scroll_bar_width, vertical_scroll_bar_type;
6167 Lisp_Object dedicated; 6146 Lisp_Object dedicated, resize_proportionally;
6168}; 6147};
6169 6148
6170#define SAVED_WINDOW_N(swv,n) \ 6149#define SAVED_WINDOW_N(swv,n) \
@@ -6327,11 +6306,6 @@ the return value is nil. Otherwise the value is t. */)
6327 * sizeof (struct window *)); 6306 * sizeof (struct window *));
6328 n_leaf_windows = get_leaf_windows (root_window, leaf_windows, 0); 6307 n_leaf_windows = get_leaf_windows (root_window, leaf_windows, 0);
6329 6308
6330 /* Temporarily avoid any problems with windows that are smaller
6331 than they are supposed to be. */
6332 window_min_height = 1;
6333 window_min_width = 1;
6334
6335 /* Kludge Alert! 6309 /* Kludge Alert!
6336 Mark all windows now on frame as "deleted". 6310 Mark all windows now on frame as "deleted".
6337 Restoring the new configuration "undeletes" any that are in it. 6311 Restoring the new configuration "undeletes" any that are in it.
@@ -6398,6 +6372,7 @@ the return value is nil. Otherwise the value is t. */)
6398 w->scroll_bar_width = p->scroll_bar_width; 6372 w->scroll_bar_width = p->scroll_bar_width;
6399 w->vertical_scroll_bar_type = p->vertical_scroll_bar_type; 6373 w->vertical_scroll_bar_type = p->vertical_scroll_bar_type;
6400 w->dedicated = p->dedicated; 6374 w->dedicated = p->dedicated;
6375 w->resize_proportionally = p->resize_proportionally;
6401 XSETFASTINT (w->last_modified, 0); 6376 XSETFASTINT (w->last_modified, 0);
6402 XSETFASTINT (w->last_overlay_modified, 0); 6377 XSETFASTINT (w->last_overlay_modified, 0);
6403 6378
@@ -6527,10 +6502,6 @@ the return value is nil. Otherwise the value is t. */)
6527 if (!NILP (new_current_buffer)) 6502 if (!NILP (new_current_buffer))
6528 Fset_buffer (new_current_buffer); 6503 Fset_buffer (new_current_buffer);
6529 6504
6530 /* Restore the minimum heights recorded in the configuration. */
6531 window_min_height = data->min_height;
6532 window_min_width = data->min_width;
6533
6534 Vminibuf_scroll_window = data->minibuf_scroll_window; 6505 Vminibuf_scroll_window = data->minibuf_scroll_window;
6535 minibuf_selected_window = data->minibuf_selected_window; 6506 minibuf_selected_window = data->minibuf_selected_window;
6536 6507
@@ -6666,6 +6637,7 @@ save_window_save (window, vector, i)
6666 p->scroll_bar_width = w->scroll_bar_width; 6637 p->scroll_bar_width = w->scroll_bar_width;
6667 p->vertical_scroll_bar_type = w->vertical_scroll_bar_type; 6638 p->vertical_scroll_bar_type = w->vertical_scroll_bar_type;
6668 p->dedicated = w->dedicated; 6639 p->dedicated = w->dedicated;
6640 p->resize_proportionally = w->resize_proportionally;
6669 if (!NILP (w->buffer)) 6641 if (!NILP (w->buffer))
6670 { 6642 {
6671 /* Save w's value of point in the window configuration. 6643 /* Save w's value of point in the window configuration.
@@ -6753,8 +6725,6 @@ redirection (see `redirect-frame-focus'). */)
6753 data->minibuf_selected_window = minibuf_level > 0 ? minibuf_selected_window : Qnil; 6725 data->minibuf_selected_window = minibuf_level > 0 ? minibuf_selected_window : Qnil;
6754 data->root_window = FRAME_ROOT_WINDOW (f); 6726 data->root_window = FRAME_ROOT_WINDOW (f);
6755 data->focus_frame = FRAME_FOCUS_FRAME (f); 6727 data->focus_frame = FRAME_FOCUS_FRAME (f);
6756 data->min_height = window_min_height;
6757 data->min_width = window_min_width;
6758 tem = Fmake_vector (make_number (n_windows), Qnil); 6728 tem = Fmake_vector (make_number (n_windows), Qnil);
6759 data->saved_windows = tem; 6729 data->saved_windows = tem;
6760 for (i = 0; i < n_windows; i++) 6730 for (i = 0; i < n_windows; i++)
@@ -7287,10 +7257,6 @@ compare_window_configurations (c1, c2, ignore_positions)
7287 if everything else compares equal. */ 7257 if everything else compares equal. */
7288 if (! EQ (d1->focus_frame, d2->focus_frame)) 7258 if (! EQ (d1->focus_frame, d2->focus_frame))
7289 return 0; 7259 return 0;
7290 if (d1->min_width != d2->min_width)
7291 return 0;
7292 if (d1->min_height != d2->min_height)
7293 return 0;
7294 7260
7295 /* Verify that the two confis have the same number of windows. */ 7261 /* Verify that the two confis have the same number of windows. */
7296 if (sw1->size != sw2->size) 7262 if (sw1->size != sw2->size)
@@ -7611,12 +7577,21 @@ if splitting is not eligible. */);
7611 Vsplit_window_preferred_function = Qnil; 7577 Vsplit_window_preferred_function = Qnil;
7612 7578
7613 DEFVAR_INT ("window-min-height", &window_min_height, 7579 DEFVAR_INT ("window-min-height", &window_min_height,
7614 doc: /* *Delete any window less than this tall (including its mode line). 7580 doc: /* Allow deleting windows less than this tall.
7615The value is in line units. */); 7581The value is measured in line units. If a window wants a modeline it
7582is counted as one line.
7583
7584Emacs honors settings of this variable when enlarging or shrinking
7585windows vertically. A value less than 1 is invalid. */);
7616 window_min_height = 4; 7586 window_min_height = 4;
7617 7587
7618 DEFVAR_INT ("window-min-width", &window_min_width, 7588 DEFVAR_INT ("window-min-width", &window_min_width,
7619 doc: /* *Delete any window less than this wide (measured in characters). */); 7589 doc: /* Allow deleting windows less than this wide.
7590The value is measured in characters and includes any fringes or
7591the scrollbar.
7592
7593Emacs honors settings of this variable when enlarging or shrinking
7594windows horizontally. A value less than 2 is invalid. */);
7620 window_min_width = 10; 7595 window_min_width = 10;
7621 7596
7622 DEFVAR_LISP ("scroll-preserve-screen-position", 7597 DEFVAR_LISP ("scroll-preserve-screen-position",