diff options
| author | Martin Rudalics | 2008-05-01 10:17:47 +0000 |
|---|---|---|
| committer | Martin Rudalics | 2008-05-01 10:17:47 +0000 |
| commit | 047aaeb9fd1e673ec473a20199430e8797df5e61 (patch) | |
| tree | fc93d07238493f8ea8ac59598432d03ad9e204a6 /src/window.c | |
| parent | 92f774f36eca32759f97381e8502444aefb59940 (diff) | |
| download | emacs-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.c | 441 |
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)); | |||
| 65 | static void window_scroll P_ ((Lisp_Object, int, int, int)); | 65 | static void window_scroll P_ ((Lisp_Object, int, int, int)); |
| 66 | static void window_scroll_pixel_based P_ ((Lisp_Object, int, int, int)); | 66 | static void window_scroll_pixel_based P_ ((Lisp_Object, int, int, int)); |
| 67 | static void window_scroll_line_based P_ ((Lisp_Object, int, int, int)); | 67 | static void window_scroll_line_based P_ ((Lisp_Object, int, int, int)); |
| 68 | static int window_min_size_1 P_ ((struct window *, int)); | 68 | static int window_min_size_1 P_ ((struct window *, int, int)); |
| 69 | static int window_min_size_2 P_ ((struct window *, int)); | 69 | static int window_min_size_2 P_ ((struct window *, int, int)); |
| 70 | static int window_min_size P_ ((struct window *, int, int, int *)); | 70 | static int window_min_size P_ ((struct window *, int, int, int, int *)); |
| 71 | static void size_window P_ ((Lisp_Object, int, int, int, int, int)); | 71 | static void size_window P_ ((Lisp_Object, int, int, int, int, int)); |
| 72 | static int freeze_window_start P_ ((struct window *, void *)); | 72 | static int freeze_window_start P_ ((struct window *, void *)); |
| 73 | static int window_fixed_size_p P_ ((struct window *, int, int)); | 73 | static 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 | ||
| 2556 | static void | 2557 | #define WINDOW_TOTAL_SIZE(w, wp) \ |
| 2557 | check_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 | ||
| 2696 | static int | 2693 | static int |
| 2697 | window_min_size_2 (w, width_p) | 2694 | window_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 | ||
| 2727 | static int | 2729 | static int |
| 2728 | window_min_size_1 (w, width_p) | 2730 | window_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 | ||
| 2802 | static int | 2806 | static int |
| 2803 | window_min_size (w, width_p, ignore_fixed_p, fixed) | 2807 | window_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. */ | ||
| 2882 | static int * | 2889 | static int * |
| 2883 | shrink_windows (total, size, nchildren, shrinkable, | 2890 | shrink_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 | ||
| 3021 | static void | 3033 | static void |
| 3022 | size_window (window, size, width_p, nodelete_p, first_only, last_only) | 3034 | size_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 | ||
| 3242 | void | 3227 | void |
| 3243 | set_window_height (window, height, nodelete) | 3228 | set_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 | ||
| 3257 | void | 3244 | void |
| 3258 | set_window_width (window, width, nodelete) | 3245 | set_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 | ||
| 4288 | static void | 4272 | static 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. |
| 7615 | The value is in line units. */); | 7581 | The value is measured in line units. If a window wants a modeline it |
| 7582 | is counted as one line. | ||
| 7583 | |||
| 7584 | Emacs honors settings of this variable when enlarging or shrinking | ||
| 7585 | windows 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. |
| 7590 | The value is measured in characters and includes any fringes or | ||
| 7591 | the scrollbar. | ||
| 7592 | |||
| 7593 | Emacs honors settings of this variable when enlarging or shrinking | ||
| 7594 | windows 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", |