aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorMartin Rudalics2011-06-10 08:55:18 +0200
committerMartin Rudalics2011-06-10 08:55:18 +0200
commit562dd5e9532d75d18843a37a1e42a1f4398d4823 (patch)
tree7798ae13567bdc16a2bee08c0184e5d5b21fd50b /src
parentb229f37d43081a2d960467ead3c5eed6a5764680 (diff)
downloademacs-562dd5e9532d75d18843a37a1e42a1f4398d4823.tar.gz
emacs-562dd5e9532d75d18843a37a1e42a1f4398d4823.zip
Move window resize code from window.c to window.el.
* window.c: Remove declarations of Qwindow_size_fixed, window_min_size_1, window_min_size_2, window_min_size, size_window, window_fixed_size_p, enlarge_window, delete_window. Remove static from declaration of Qdelete_window, it's temporarily needed by Fbury_buffer. (replace_window): Don't assign orig_top_line and orig_total_lines. (Fdelete_window, delete_window): Remove. Window deletion is handled by window.el. (window_loop): Remove DELETE_OTHER_WINDOWS case. Replace Fdelete_window calls with calls to Qdelete_window. (Fdelete_other_windows): Remove. Deleting other windows is handled by window.el. (window_fixed_size_p): Remove. Fixed-sizeness of windows is handled in window.el. (window_min_size_2, window_min_size_1, window_min_size): Remove. Window minimum sizes are handled in window.el. (shrink_windows, size_window, set_window_height) (set_window_width, change_window_heights, window_height) (window_width, CURBEG, CURSIZE, enlarge_window) (adjust_window_trailing_edge, Fadjust_window_trailing_edge) (Fenlarge_window, Fshrink_window): Remove. Window resizing is handled in window.el. (make_dummy_parent): Rename to make_parent_window and give it a second argument horflag. (make_window): Don't set resize_proportionally any more. (Fsplit_window): Remove. Windows are split in window.el. (save_restore_action, save_restore_orig_size) (shrink_window_lowest_first, save_restore_orig_size): Remove. Resize mini windows in window.el. (grow_mini_window, shrink_mini_window): Implement by calling Qresize_root_window_vertically, resize_window_check and resize_window_apply. (saved_window, Fset_window_configuration, save_window_save): Do not handle orig_top_line, orig_total_lines, and resize_proportionally. (window_min_height, window_min_width): Move to window.el. (keys_of_window): Move bindings for delete-other-windows, split-window, delete-window and enlarge-window to window.el. * buffer.c: Temporarily extern Qdelete_window. (Fbury_buffer): Temporarily call Qdelete_window instead of Fdelete_window (Fbury_buffer will move to window.el soon). * frame.c (set_menu_bar_lines_1): Remove code handling orig_top_line and orig_total_lines. * dispnew.c (adjust_frame_glyphs_initially): Don't use set_window_height but set heights directly. (change_frame_size_1): Use resize_frame_windows. * xdisp.c (init_xdisp): Don't use set_window_height but set heights directly. * xfns.c (x_set_menu_bar_lines, x_set_tool_bar_lines): Use resize_frame_windows instead of change_window_heights and run run_window_configuration_change_hook. * w32fns.c (x_set_tool_bar_lines): Use resize_frame_windows instead of change_window_heights and run run_window_configuration_change_hook. * window.el (window-min-height, window-min-width): Move here from window.c. Add defcustoms and rewrite doc-strings. (resize-mini-window, resize-window): New functions. (adjust-window-trailing-edge, enlarge-window, shrink-window): Move here from window.c. (maximize-window, minimize-window): New functions. (delete-window, delete-other-windows, split-window): Move here from window.c. (window-split-min-size): New function. (split-window-keep-point): Mention split-window-above-each-other instead of split-window-vertically. (split-window-above-each-other, split-window-vertically): Rename split-window-vertically to split-window-above-each-other and provide defalias for old definition. (split-window-side-by-side, split-window-horizontally): Rename split-window-horizontally to split-window-side-by-side and provide defalias for the old definition. (ctl-x-map): Move bindings for delete-window, delete-other-windows and enlarge-window here from window.c. Replace bindings for split-window-vertically and split-window-horizontally by bindings for split-window-above-each-other and split-window-side-by-side. * cus-start.el (all): Remove entries for window-min-height and window-min-width. Add entries for window-splits and window-nest.
Diffstat (limited to 'src')
-rw-r--r--src/ChangeLog64
-rw-r--r--src/buffer.c4
-rw-r--r--src/dispnew.c27
-rw-r--r--src/frame.c5
-rw-r--r--src/w32fns.c7
-rw-r--r--src/window.c1953
-rw-r--r--src/xdisp.c28
-rw-r--r--src/xfns.c8
8 files changed, 161 insertions, 1935 deletions
diff --git a/src/ChangeLog b/src/ChangeLog
index 01c102c3bc0..1643be47a1a 100644
--- a/src/ChangeLog
+++ b/src/ChangeLog
@@ -1,3 +1,67 @@
12011-06-10 Martin Rudalics <rudalics@gmx.at>
2
3 * window.c: Remove declarations of Qwindow_size_fixed,
4 window_min_size_1, window_min_size_2, window_min_size,
5 size_window, window_fixed_size_p, enlarge_window, delete_window.
6 Remove static from declaration of Qdelete_window, it's
7 temporarily needed by Fbury_buffer.
8 (replace_window): Don't assign orig_top_line and
9 orig_total_lines.
10 (Fdelete_window, delete_window): Remove. Window deletion is
11 handled by window.el.
12 (window_loop): Remove DELETE_OTHER_WINDOWS case. Replace
13 Fdelete_window calls with calls to Qdelete_window.
14 (Fdelete_other_windows): Remove. Deleting other windows is
15 handled by window.el.
16 (window_fixed_size_p): Remove. Fixed-sizeness of windows is
17 handled in window.el.
18 (window_min_size_2, window_min_size_1, window_min_size): Remove.
19 Window minimum sizes are handled in window.el.
20 (shrink_windows, size_window, set_window_height)
21 (set_window_width, change_window_heights, window_height)
22 (window_width, CURBEG, CURSIZE, enlarge_window)
23 (adjust_window_trailing_edge, Fadjust_window_trailing_edge)
24 (Fenlarge_window, Fshrink_window): Remove. Window resizing is
25 handled in window.el.
26 (make_dummy_parent): Rename to make_parent_window and give it a
27 second argument horflag.
28 (make_window): Don't set resize_proportionally any more.
29 (Fsplit_window): Remove. Windows are split in window.el.
30 (save_restore_action, save_restore_orig_size)
31 (shrink_window_lowest_first, save_restore_orig_size): Remove.
32 Resize mini windows in window.el.
33 (grow_mini_window, shrink_mini_window): Implement by calling
34 Qresize_root_window_vertically, resize_window_check and
35 resize_window_apply.
36 (saved_window, Fset_window_configuration, save_window_save): Do
37 not handle orig_top_line, orig_total_lines, and
38 resize_proportionally.
39 (window_min_height, window_min_width): Move to window.el.
40 (keys_of_window): Move bindings for delete-other-windows,
41 split-window, delete-window and enlarge-window to window.el.
42
43 * buffer.c: Temporarily extern Qdelete_window.
44 (Fbury_buffer): Temporarily call Qdelete_window instead of
45 Fdelete_window (Fbury_buffer will move to window.el soon).
46
47 * frame.c (set_menu_bar_lines_1): Remove code handling
48 orig_top_line and orig_total_lines.
49
50 * dispnew.c (adjust_frame_glyphs_initially): Don't use
51 set_window_height but set heights directly.
52 (change_frame_size_1): Use resize_frame_windows.
53
54 * xdisp.c (init_xdisp): Don't use set_window_height but set
55 heights directly.
56
57 * xfns.c (x_set_menu_bar_lines, x_set_tool_bar_lines): Use
58 resize_frame_windows instead of change_window_heights and run
59 run_window_configuration_change_hook.
60
61 * w32fns.c (x_set_tool_bar_lines): Use resize_frame_windows
62 instead of change_window_heights and run
63 run_window_configuration_change_hook.
64
12011-06-09 Martin Rudalics <rudalics@gmx.at> 652011-06-09 Martin Rudalics <rudalics@gmx.at>
2 66
3 * window.c (replace_window): Rename second argument REPLACEMENT to 67 * window.c (replace_window): Rename second argument REPLACEMENT to
diff --git a/src/buffer.c b/src/buffer.c
index e9ff8f492ba..0862de9baf7 100644
--- a/src/buffer.c
+++ b/src/buffer.c
@@ -1938,6 +1938,8 @@ DEFUN ("barf-if-buffer-read-only", Fbarf_if_buffer_read_only,
1938 return Qnil; 1938 return Qnil;
1939} 1939}
1940 1940
1941extern Lisp_Object Qdelete_window;
1942
1941DEFUN ("bury-buffer", Fbury_buffer, Sbury_buffer, 0, 1, "", 1943DEFUN ("bury-buffer", Fbury_buffer, Sbury_buffer, 0, 1, "",
1942 doc: /* Put BUFFER-OR-NAME at the end of the list of all buffers. 1944 doc: /* Put BUFFER-OR-NAME at the end of the list of all buffers.
1943There it is the least likely candidate for `other-buffer' to return; 1945There it is the least likely candidate for `other-buffer' to return;
@@ -1969,7 +1971,7 @@ its frame, iconify that frame. */)
1969 else if (NILP (XWINDOW (selected_window)->parent)) 1971 else if (NILP (XWINDOW (selected_window)->parent))
1970 Ficonify_frame (Fwindow_frame (selected_window)); 1972 Ficonify_frame (Fwindow_frame (selected_window));
1971 else 1973 else
1972 Fdelete_window (selected_window); 1974 call1 (Qdelete_window, selected_window);
1973 } 1975 }
1974 } 1976 }
1975 else 1977 else
diff --git a/src/dispnew.c b/src/dispnew.c
index 501dc4ffd80..2dffc0dce25 100644
--- a/src/dispnew.c
+++ b/src/dispnew.c
@@ -1933,13 +1933,13 @@ adjust_frame_glyphs_initially (void)
1933 1933
1934 /* Do it for the root window. */ 1934 /* Do it for the root window. */
1935 XSETFASTINT (root->top_line, top_margin); 1935 XSETFASTINT (root->top_line, top_margin);
1936 XSETFASTINT (root->total_lines, frame_lines - 1 - top_margin);
1936 XSETFASTINT (root->total_cols, frame_cols); 1937 XSETFASTINT (root->total_cols, frame_cols);
1937 set_window_height (sf->root_window, frame_lines - 1 - top_margin, 0);
1938 1938
1939 /* Do it for the mini-buffer window. */ 1939 /* Do it for the mini-buffer window. */
1940 XSETFASTINT (mini->top_line, frame_lines - 1); 1940 XSETFASTINT (mini->top_line, frame_lines - 1);
1941 XSETFASTINT (mini->total_lines, 1);
1941 XSETFASTINT (mini->total_cols, frame_cols); 1942 XSETFASTINT (mini->total_cols, frame_cols);
1942 set_window_height (root->next, 1, 0);
1943 1943
1944 adjust_frame_glyphs (sf); 1944 adjust_frame_glyphs (sf);
1945 glyphs_initialized_initially_p = 1; 1945 glyphs_initialized_initially_p = 1;
@@ -5715,24 +5715,7 @@ change_frame_size_1 (register struct frame *f, int newheight, int newwidth, int
5715 5715
5716 if (newheight != FRAME_LINES (f)) 5716 if (newheight != FRAME_LINES (f))
5717 { 5717 {
5718 if (FRAME_HAS_MINIBUF_P (f) && !FRAME_MINIBUF_ONLY_P (f)) 5718 resize_frame_windows (f, newheight, 0);
5719 {
5720 /* Frame has both root and mini-buffer. */
5721 XSETFASTINT (XWINDOW (FRAME_ROOT_WINDOW (f))->top_line,
5722 FRAME_TOP_MARGIN (f));
5723 set_window_height (FRAME_ROOT_WINDOW (f),
5724 (newheight
5725 - 1
5726 - FRAME_TOP_MARGIN (f)),
5727 2);
5728 XSETFASTINT (XWINDOW (FRAME_MINIBUF_WINDOW (f))->top_line,
5729 newheight - 1);
5730 set_window_height (FRAME_MINIBUF_WINDOW (f), 1, 0);
5731 }
5732 else
5733 /* Frame has just one top-level window. */
5734 set_window_height (FRAME_ROOT_WINDOW (f),
5735 newheight - FRAME_TOP_MARGIN (f), 2);
5736 5719
5737 /* MSDOS frames cannot PRETEND, as they change frame size by 5720 /* MSDOS frames cannot PRETEND, as they change frame size by
5738 manipulating video hardware. */ 5721 manipulating video hardware. */
@@ -5742,9 +5725,7 @@ change_frame_size_1 (register struct frame *f, int newheight, int newwidth, int
5742 5725
5743 if (new_frame_total_cols != FRAME_TOTAL_COLS (f)) 5726 if (new_frame_total_cols != FRAME_TOTAL_COLS (f))
5744 { 5727 {
5745 set_window_width (FRAME_ROOT_WINDOW (f), new_frame_total_cols, 2); 5728 resize_frame_windows (f, new_frame_total_cols, 1);
5746 if (FRAME_HAS_MINIBUF_P (f))
5747 set_window_width (FRAME_MINIBUF_WINDOW (f), new_frame_total_cols, 0);
5748 5729
5749 /* MSDOS frames cannot PRETEND, as they change frame size by 5730 /* MSDOS frames cannot PRETEND, as they change frame size by
5750 manipulating video hardware. */ 5731 manipulating video hardware. */
diff --git a/src/frame.c b/src/frame.c
index 71881265b44..6baf2d0e671 100644
--- a/src/frame.c
+++ b/src/frame.c
@@ -135,11 +135,6 @@ set_menu_bar_lines_1 (Lisp_Object window, int n)
135 XSETFASTINT (w->top_line, XFASTINT (w->top_line) + n); 135 XSETFASTINT (w->top_line, XFASTINT (w->top_line) + n);
136 XSETFASTINT (w->total_lines, XFASTINT (w->total_lines) - n); 136 XSETFASTINT (w->total_lines, XFASTINT (w->total_lines) - n);
137 137
138 if (INTEGERP (w->orig_top_line))
139 XSETFASTINT (w->orig_top_line, XFASTINT (w->orig_top_line) + n);
140 if (INTEGERP (w->orig_total_lines))
141 XSETFASTINT (w->orig_total_lines, XFASTINT (w->orig_total_lines) - n);
142
143 /* Handle just the top child in a vertical split. */ 138 /* Handle just the top child in a vertical split. */
144 if (!NILP (w->vchild)) 139 if (!NILP (w->vchild))
145 set_menu_bar_lines_1 (w->vchild, n); 140 set_menu_bar_lines_1 (w->vchild, n);
diff --git a/src/w32fns.c b/src/w32fns.c
index bdf9dce9411..823dbe3567e 100644
--- a/src/w32fns.c
+++ b/src/w32fns.c
@@ -1596,7 +1596,7 @@ x_set_tool_bar_lines (struct frame *f, Lisp_Object value, Lisp_Object oldval)
1596 } 1596 }
1597 1597
1598 FRAME_TOOL_BAR_LINES (f) = nlines; 1598 FRAME_TOOL_BAR_LINES (f) = nlines;
1599 change_window_heights (root_window, delta); 1599 resize_frame_windows (f, FRAME_LINES (f), 0);
1600 adjust_glyphs (f); 1600 adjust_glyphs (f);
1601 1601
1602 /* We also have to make sure that the internal border at the top of 1602 /* We also have to make sure that the internal border at the top of
@@ -1631,6 +1631,9 @@ x_set_tool_bar_lines (struct frame *f, Lisp_Object value, Lisp_Object oldval)
1631 if (WINDOWP (f->tool_bar_window)) 1631 if (WINDOWP (f->tool_bar_window))
1632 clear_glyph_matrix (XWINDOW (f->tool_bar_window)->current_matrix); 1632 clear_glyph_matrix (XWINDOW (f->tool_bar_window)->current_matrix);
1633 } 1633 }
1634
1635 run_window_configuration_change_hook (f);
1636
1634} 1637}
1635 1638
1636 1639
@@ -5822,8 +5825,6 @@ Value is t if tooltip was open, nil otherwise. */)
5822 UNGCPRO; 5825 UNGCPRO;
5823 return unbind_to (count, deleted); 5826 return unbind_to (count, deleted);
5824} 5827}
5825
5826
5827 5828
5828/*********************************************************************** 5829/***********************************************************************
5829 File selection dialog 5830 File selection dialog
diff --git a/src/window.c b/src/window.c
index dd8cdab77a4..3ee220e1d27 100644
--- a/src/window.c
+++ b/src/window.c
@@ -50,17 +50,15 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
50#include "nsterm.h" 50#include "nsterm.h"
51#endif 51#endif
52 52
53Lisp_Object Qwindowp, Qwindow_live_p; 53Lisp_Object Qwindowp, Qwindow_live_p, Qdelete_window;
54static Lisp_Object Qwindow_configuration_p, Qrecord_window_buffer; 54static Lisp_Object Qwindow_configuration_p, Qrecord_window_buffer;
55static Lisp_Object Qwindow_deletable_p, Qdelete_window, Qdisplay_buffer; 55static Lisp_Object Qwindow_deletable_p, Qdisplay_buffer;
56static Lisp_Object Qreplace_buffer_in_windows, Qget_mru_window; 56static Lisp_Object Qreplace_buffer_in_windows, Qget_mru_window;
57static Lisp_Object Qresize_root_window, Qresize_root_window_vertically; 57static Lisp_Object Qresize_root_window, Qresize_root_window_vertically;
58static Lisp_Object Qscroll_up, Qscroll_down, Qscroll_command; 58static Lisp_Object Qscroll_up, Qscroll_down, Qscroll_command;
59static Lisp_Object Qsafe, Qabove, Qbelow; 59static Lisp_Object Qsafe, Qabove, Qbelow;
60static Lisp_Object Qauto_buffer_name; 60static Lisp_Object Qauto_buffer_name;
61 61
62static Lisp_Object Qwindow_size_fixed;
63
64static int displayed_window_lines (struct window *); 62static int displayed_window_lines (struct window *);
65static struct window *decode_window (Lisp_Object); 63static struct window *decode_window (Lisp_Object);
66static int count_windows (struct window *); 64static int count_windows (struct window *);
@@ -68,13 +66,7 @@ static int get_leaf_windows (struct window *, struct window **, int);
68static void window_scroll (Lisp_Object, int, int, int); 66static void window_scroll (Lisp_Object, int, int, int);
69static void window_scroll_pixel_based (Lisp_Object, int, int, int); 67static void window_scroll_pixel_based (Lisp_Object, int, int, int);
70static void window_scroll_line_based (Lisp_Object, int, int, int); 68static void window_scroll_line_based (Lisp_Object, int, int, int);
71static int window_min_size_1 (struct window *, int, int);
72static int window_min_size_2 (struct window *, int, int);
73static int window_min_size (struct window *, int, int, int, int *);
74static void size_window (Lisp_Object, int, int, int, int, int);
75static int freeze_window_start (struct window *, void *); 69static int freeze_window_start (struct window *, void *);
76static int window_fixed_size_p (struct window *, int, int);
77static void enlarge_window (Lisp_Object, int, int);
78static Lisp_Object window_list (void); 70static Lisp_Object window_list (void);
79static int add_window_to_list (struct window *, void *); 71static int add_window_to_list (struct window *, void *);
80static int candidate_window_p (Lisp_Object, Lisp_Object, Lisp_Object, 72static int candidate_window_p (Lisp_Object, Lisp_Object, Lisp_Object,
@@ -1803,9 +1795,7 @@ DEFUN ("set-window-display-table", Fset_window_display_table, Sset_window_displa
1803 return table; 1795 return table;
1804} 1796}
1805 1797
1806static void delete_window (Lisp_Object); 1798/* Record info on buffer window W is displaying
1807
1808/* Record info on buffer window w is displaying
1809 when it is about to cease to display that buffer. */ 1799 when it is about to cease to display that buffer. */
1810static void 1800static void
1811unshow_buffer (register struct window *w) 1801unshow_buffer (register struct window *w)
@@ -1891,7 +1881,6 @@ replace_window (Lisp_Object old, Lisp_Object new, int setflag)
1891 XSETFASTINT (n->window_end_pos, 0); 1881 XSETFASTINT (n->window_end_pos, 0);
1892 n->window_end_valid = Qnil; 1882 n->window_end_valid = Qnil;
1893 n->frozen_window_start_p = 0; 1883 n->frozen_window_start_p = 0;
1894 n->orig_top_line = n->orig_total_lines = Qnil;
1895 } 1884 }
1896 1885
1897 n->next = tem = o->next; 1886 n->next = tem = o->next;
@@ -1994,232 +1983,6 @@ delete_deletable_window (Lisp_Object window)
1994 call1 (Qdelete_window, window); 1983 call1 (Qdelete_window, window);
1995} 1984}
1996 1985
1997DEFUN ("delete-window", Fdelete_window, Sdelete_window, 0, 1, "",
1998 doc: /* Remove WINDOW from its frame.
1999WINDOW defaults to the selected window. Return nil.
2000Signal an error when WINDOW is the only window on its frame. */)
2001 (register Lisp_Object window)
2002{
2003 struct frame *f;
2004 if (NILP (window))
2005 window = selected_window;
2006 else
2007 CHECK_LIVE_WINDOW (window);
2008
2009 f = XFRAME (WINDOW_FRAME (XWINDOW (window)));
2010 delete_window (window);
2011
2012 run_window_configuration_change_hook (f);
2013
2014 return Qnil;
2015}
2016
2017static void
2018delete_window (register Lisp_Object window)
2019{
2020 register Lisp_Object tem, parent, sib;
2021 register struct window *p;
2022 register struct window *par;
2023 struct frame *f;
2024
2025 /* Because this function is called by other C code on non-leaf
2026 windows, the CHECK_LIVE_WINDOW macro would choke inappropriately,
2027 so we can't decode_window here. */
2028 CHECK_WINDOW (window);
2029 p = XWINDOW (window);
2030
2031 /* It's a no-op to delete an already-deleted window. */
2032 if (NILP (p->buffer)
2033 && NILP (p->hchild)
2034 && NILP (p->vchild))
2035 return;
2036
2037 parent = p->parent;
2038 if (NILP (parent))
2039 error ("Attempt to delete minibuffer or sole ordinary window");
2040 par = XWINDOW (parent);
2041
2042 windows_or_buffers_changed++;
2043 Vwindow_list = Qnil;
2044 f = XFRAME (WINDOW_FRAME (p));
2045 FRAME_WINDOW_SIZES_CHANGED (f) = 1;
2046
2047 /* Are we trying to delete any frame's selected window? */
2048 {
2049 Lisp_Object swindow, pwindow;
2050
2051 /* See if the frame's selected window is either WINDOW
2052 or any subwindow of it, by finding all that window's parents
2053 and comparing each one with WINDOW. */
2054 swindow = FRAME_SELECTED_WINDOW (f);
2055
2056 while (1)
2057 {
2058 pwindow = swindow;
2059 while (!NILP (pwindow))
2060 {
2061 if (EQ (window, pwindow))
2062 break;
2063 pwindow = XWINDOW (pwindow)->parent;
2064 }
2065
2066 /* If the window being deleted is not a parent of SWINDOW,
2067 then SWINDOW is ok as the new selected window. */
2068 if (!EQ (window, pwindow))
2069 break;
2070 /* Otherwise, try another window for SWINDOW. */
2071 swindow = Fnext_window (swindow, Qlambda, Qnil);
2072
2073 /* If we get back to the frame's selected window,
2074 it means there was no acceptable alternative,
2075 so we cannot delete. */
2076 if (EQ (swindow, FRAME_SELECTED_WINDOW (f)))
2077 error ("Cannot delete window");
2078 }
2079
2080 /* If we need to change SWINDOW, do it. */
2081 if (! EQ (swindow, FRAME_SELECTED_WINDOW (f)))
2082 {
2083 /* If we're about to delete the selected window on the
2084 selected frame, then we should use Fselect_window to select
2085 the new window. On the other hand, if we're about to
2086 delete the selected window on any other frame, we shouldn't do
2087 anything but set the frame's selected_window slot. */
2088 if (EQ (FRAME_SELECTED_WINDOW (f), selected_window))
2089 Fselect_window (swindow, Qnil);
2090 else
2091 FRAME_SELECTED_WINDOW (f) = swindow;
2092 }
2093 }
2094
2095 /* Now we know we can delete this one. */
2096 window_deletion_count++;
2097
2098 tem = p->buffer;
2099 /* tem is null for dummy parent windows
2100 (which have inferiors but not any contents themselves) */
2101 if (!NILP (tem))
2102 {
2103 unshow_buffer (p);
2104 unchain_marker (XMARKER (p->pointm));
2105 unchain_marker (XMARKER (p->start));
2106 }
2107
2108 /* Free window glyph matrices. It is sure that they are allocated
2109 again when ADJUST_GLYPHS is called. Block input so that expose
2110 events and other events that access glyph matrices are not
2111 processed while we are changing them. */
2112 BLOCK_INPUT;
2113 free_window_matrices (XWINDOW (FRAME_ROOT_WINDOW (f)));
2114
2115 tem = p->next;
2116 if (!NILP (tem))
2117 XWINDOW (tem)->prev = p->prev;
2118
2119 tem = p->prev;
2120 if (!NILP (tem))
2121 XWINDOW (tem)->next = p->next;
2122
2123 if (EQ (window, par->hchild))
2124 par->hchild = p->next;
2125 if (EQ (window, par->vchild))
2126 par->vchild = p->next;
2127
2128 /* Find one of our siblings to give our space to. */
2129 sib = p->prev;
2130 if (NILP (sib))
2131 {
2132 /* If p gives its space to its next sibling, that sibling needs
2133 to have its top/left side pulled back to where p's is.
2134 set_window_{height,width} will re-position the sibling's
2135 children. */
2136 sib = p->next;
2137 XWINDOW (sib)->top_line = p->top_line;
2138 XWINDOW (sib)->left_col = p->left_col;
2139 }
2140
2141 /* Stretch that sibling. */
2142 if (!NILP (par->vchild))
2143 set_window_height (sib,
2144 XFASTINT (XWINDOW (sib)->total_lines) + XFASTINT (p->total_lines),
2145 1);
2146 if (!NILP (par->hchild))
2147 set_window_width (sib,
2148 XFASTINT (XWINDOW (sib)->total_cols) + XFASTINT (p->total_cols),
2149 1);
2150
2151 /* If parent now has only one child,
2152 put the child into the parent's place. */
2153 tem = par->hchild;
2154 if (NILP (tem))
2155 tem = par->vchild;
2156 if (NILP (XWINDOW (tem)->next)) {
2157 replace_window (parent, tem, 1);
2158 par = XWINDOW (tem);
2159 }
2160
2161 /* Since we may be deleting combination windows, we must make sure that
2162 not only p but all its children have been marked as deleted. */
2163 if (! NILP (p->hchild))
2164 delete_all_subwindows (p->hchild);
2165 else if (! NILP (p->vchild))
2166 delete_all_subwindows (p->vchild);
2167
2168 /* Mark this window as deleted. */
2169 p->buffer = p->hchild = p->vchild = Qnil;
2170
2171 if (! NILP (par->parent))
2172 par = XWINDOW (par->parent);
2173
2174 /* Check if we have a v/hchild with a v/hchild. In that case remove
2175 one of them. */
2176
2177 if (! NILP (par->vchild) && ! NILP (XWINDOW (par->vchild)->vchild))
2178 {
2179 p = XWINDOW (par->vchild);
2180 par->vchild = p->vchild;
2181 tem = p->vchild;
2182 }
2183 else if (! NILP (par->hchild) && ! NILP (XWINDOW (par->hchild)->hchild))
2184 {
2185 p = XWINDOW (par->hchild);
2186 par->hchild = p->hchild;
2187 tem = p->hchild;
2188 }
2189 else
2190 p = 0;
2191
2192 if (p)
2193 {
2194 while (! NILP (tem)) {
2195 XWINDOW (tem)->parent = p->parent;
2196 if (NILP (XWINDOW (tem)->next))
2197 break;
2198 tem = XWINDOW (tem)->next;
2199 }
2200 if (! NILP (tem)) {
2201 /* The next of the v/hchild we are removing is now the next of the
2202 last child for the v/hchild:
2203 Before v/hchild -> v/hchild -> next1 -> next2
2204 |
2205 -> next3
2206 After: v/hchild -> next1 -> next2 -> next3
2207 */
2208 XWINDOW (tem)->next = p->next;
2209 if (! NILP (p->next))
2210 XWINDOW (p->next)->prev = tem;
2211 }
2212 p->next = p->prev = p->vchild = p->hchild = p->buffer = Qnil;
2213 }
2214
2215
2216 /* Adjust glyph matrices. */
2217 adjust_glyphs (f);
2218 UNBLOCK_INPUT;
2219}
2220
2221
2222
2223/*********************************************************************** 1986/***********************************************************************
2224 Window List 1987 Window List
2225 ***********************************************************************/ 1988 ***********************************************************************/
@@ -2645,7 +2408,6 @@ enum window_loop
2645{ 2408{
2646 WINDOW_LOOP_UNUSED, 2409 WINDOW_LOOP_UNUSED,
2647 GET_BUFFER_WINDOW, /* Arg is buffer */ 2410 GET_BUFFER_WINDOW, /* Arg is buffer */
2648 DELETE_OTHER_WINDOWS, /* Arg is window not to delete */
2649 DELETE_BUFFER_WINDOWS, /* Arg is buffer */ 2411 DELETE_BUFFER_WINDOWS, /* Arg is buffer */
2650 UNSHOW_BUFFER, /* Arg is buffer */ 2412 UNSHOW_BUFFER, /* Arg is buffer */
2651 REDISPLAY_BUFFER_WINDOWS, /* Arg is buffer */ 2413 REDISPLAY_BUFFER_WINDOWS, /* Arg is buffer */
@@ -2729,11 +2491,6 @@ window_loop (enum window_loop type, Lisp_Object obj, int mini, Lisp_Object frame
2729 } 2491 }
2730 break; 2492 break;
2731 2493
2732 case DELETE_OTHER_WINDOWS:
2733 if (!EQ (window, obj))
2734 Fdelete_window (window);
2735 break;
2736
2737 case DELETE_BUFFER_WINDOWS: 2494 case DELETE_BUFFER_WINDOWS:
2738 if (EQ (w->buffer, obj)) 2495 if (EQ (w->buffer, obj))
2739 { 2496 {
@@ -2769,7 +2526,7 @@ window_loop (enum window_loop type, Lisp_Object obj, int mini, Lisp_Object frame
2769 Fset_buffer (w->buffer); 2526 Fset_buffer (w->buffer);
2770 } 2527 }
2771 else 2528 else
2772 Fdelete_window (window); 2529 call1 (Qdelete_window, window);
2773 } 2530 }
2774 break; 2531 break;
2775 2532
@@ -2804,7 +2561,7 @@ window_loop (enum window_loop type, Lisp_Object obj, int mini, Lisp_Object frame
2804 XSETWINDOW (window_to_delete, w); 2561 XSETWINDOW (window_to_delete, w);
2805 /* If this window is dedicated and not the only window 2562 /* If this window is dedicated and not the only window
2806 in its frame, then kill it. */ 2563 in its frame, then kill it. */
2807 Fdelete_window (window_to_delete); 2564 call1 (Qdelete_window, window_to_delete);
2808 } 2565 }
2809 else 2566 else
2810 { 2567 {
@@ -3128,68 +2885,6 @@ window-start value is reasonable when this function is called. */)
3128} 2885}
3129 2886
3130 2887
3131DEFUN ("delete-other-windows", Fdelete_other_windows, Sdelete_other_windows,
3132 0, 1, "",
3133 doc: /* Make WINDOW (or the selected window) fill its frame.
3134Only the frame WINDOW is on is affected.
3135This function tries to reduce display jumps by keeping the text
3136previously visible in WINDOW in the same place on the frame. Doing this
3137depends on the value of (window-start WINDOW), so if calling this
3138function in a program gives strange scrolling, make sure the
3139window-start value is reasonable when this function is called. */)
3140 (Lisp_Object window)
3141{
3142 struct window *w;
3143 EMACS_INT startpos;
3144 int top, new_top;
3145
3146 if (NILP (window))
3147 window = selected_window;
3148 else
3149 CHECK_LIVE_WINDOW (window);
3150 w = XWINDOW (window);
3151
3152 startpos = marker_position (w->start);
3153 top = WINDOW_TOP_EDGE_LINE (w) - FRAME_TOP_MARGIN (XFRAME (WINDOW_FRAME (w)));
3154
3155 if (MINI_WINDOW_P (w) && top > 0)
3156 error ("Can't expand minibuffer to full frame");
3157
3158 window_loop (DELETE_OTHER_WINDOWS, window, 0, WINDOW_FRAME (w));
3159
3160 /* Try to minimize scrolling, by setting the window start to the point
3161 will cause the text at the old window start to be at the same place
3162 on the frame. But don't try to do this if the window start is
3163 outside the visible portion (as might happen when the display is
3164 not current, due to typeahead). */
3165 new_top = WINDOW_TOP_EDGE_LINE (w) - FRAME_TOP_MARGIN (XFRAME (WINDOW_FRAME (w)));
3166 if (new_top != top
3167 && startpos >= BUF_BEGV (XBUFFER (w->buffer))
3168 && startpos <= BUF_ZV (XBUFFER (w->buffer)))
3169 {
3170 struct position pos;
3171 struct buffer *obuf = current_buffer;
3172
3173 Fset_buffer (w->buffer);
3174 /* This computation used to temporarily move point, but that can
3175 have unwanted side effects due to text properties. */
3176 pos = *vmotion (startpos, -top, w);
3177
3178 set_marker_both (w->start, w->buffer, pos.bufpos, pos.bytepos);
3179 w->window_end_valid = Qnil;
3180 w->start_at_line_beg = ((pos.bytepos == BEGV_BYTE
3181 || FETCH_BYTE (pos.bytepos - 1) == '\n') ? Qt
3182 : Qnil);
3183 /* We need to do this, so that the window-scroll-functions
3184 get called. */
3185 w->optional_new_start = Qt;
3186
3187 set_buffer_internal (obuf);
3188 }
3189
3190 return Qnil;
3191}
3192
3193DEFUN ("delete-windows-on", Fdelete_windows_on, Sdelete_windows_on, 2888DEFUN ("delete-windows-on", Fdelete_windows_on, Sdelete_windows_on,
3194 0, 2, "bDelete windows on (buffer): ", 2889 0, 2, "bDelete windows on (buffer): ",
3195 doc: /* Delete all windows showing BUFFER-OR-NAME. 2890 doc: /* Delete all windows showing BUFFER-OR-NAME.
@@ -3271,8 +2966,6 @@ replace_buffer_in_all_windows (Lisp_Object buffer)
3271 window_loop (UNSHOW_BUFFER, buffer, 1, frame); 2966 window_loop (UNSHOW_BUFFER, buffer, 1, frame);
3272} 2967}
3273 2968
3274/* Set the height of WINDOW and all its inferiors. */
3275
3276/* If *ROWS or *COLS are too small a size for FRAME, set them to the 2969/* If *ROWS or *COLS are too small a size for FRAME, set them to the
3277 minimum allowable size. */ 2970 minimum allowable size. */
3278 2971
@@ -3296,243 +2989,6 @@ check_frame_size (FRAME_PTR frame, int *rows, int *cols)
3296 *cols = MIN_SAFE_WINDOW_WIDTH; 2989 *cols = MIN_SAFE_WINDOW_WIDTH;
3297} 2990}
3298 2991
3299/* Value is non-zero if window W is fixed-size. WIDTH_P non-zero means
3300 check if W's width can be changed, otherwise check W's height.
3301 CHECK_SIBLINGS_P non-zero means check resizablity of WINDOW's
3302 siblings, too. If none of the siblings is resizable, WINDOW isn't
3303 either. */
3304
3305static int
3306window_fixed_size_p (struct window *w, int width_p, int check_siblings_p)
3307{
3308 int fixed_p;
3309 struct window *c;
3310
3311 if (!NILP (w->hchild))
3312 {
3313 c = XWINDOW (w->hchild);
3314
3315 if (width_p)
3316 {
3317 /* A horizontal combination is fixed-width if all of if its
3318 children are. */
3319 while (c && window_fixed_size_p (c, width_p, 0))
3320 c = WINDOWP (c->next) ? XWINDOW (c->next) : NULL;
3321 fixed_p = c == NULL;
3322 }
3323 else
3324 {
3325 /* A horizontal combination is fixed-height if one of if its
3326 children is. */
3327 while (c && !window_fixed_size_p (c, width_p, 0))
3328 c = WINDOWP (c->next) ? XWINDOW (c->next) : NULL;
3329 fixed_p = c != NULL;
3330 }
3331 }
3332 else if (!NILP (w->vchild))
3333 {
3334 c = XWINDOW (w->vchild);
3335
3336 if (width_p)
3337 {
3338 /* A vertical combination is fixed-width if one of if its
3339 children is. */
3340 while (c && !window_fixed_size_p (c, width_p, 0))
3341 c = WINDOWP (c->next) ? XWINDOW (c->next) : NULL;
3342 fixed_p = c != NULL;
3343 }
3344 else
3345 {
3346 /* A vertical combination is fixed-height if all of if its
3347 children are. */
3348 while (c && window_fixed_size_p (c, width_p, 0))
3349 c = WINDOWP (c->next) ? XWINDOW (c->next) : NULL;
3350 fixed_p = c == NULL;
3351 }
3352 }
3353 else if (BUFFERP (w->buffer))
3354 {
3355 struct buffer *old = current_buffer;
3356 Lisp_Object val;
3357
3358 current_buffer = XBUFFER (w->buffer);
3359 val = find_symbol_value (Qwindow_size_fixed);
3360 current_buffer = old;
3361
3362 fixed_p = 0;
3363 if (!EQ (val, Qunbound))
3364 {
3365 fixed_p = !NILP (val);
3366
3367 if (fixed_p
3368 && ((EQ (val, Qheight) && width_p)
3369 || (EQ (val, Qwidth) && !width_p)))
3370 fixed_p = 0;
3371 }
3372
3373 /* Can't tell if this one is resizable without looking at
3374 siblings. If all siblings are fixed-size this one is too. */
3375 if (!fixed_p && check_siblings_p && WINDOWP (w->parent))
3376 {
3377 Lisp_Object child;
3378
3379 for (child = w->prev; WINDOWP (child); child = XWINDOW (child)->prev)
3380 if (!window_fixed_size_p (XWINDOW (child), width_p, 0))
3381 break;
3382
3383 if (NILP (child))
3384 for (child = w->next; WINDOWP (child); child = XWINDOW (child)->next)
3385 if (!window_fixed_size_p (XWINDOW (child), width_p, 0))
3386 break;
3387
3388 if (NILP (child))
3389 fixed_p = 1;
3390 }
3391 }
3392 else
3393 fixed_p = 1;
3394
3395 return fixed_p;
3396}
3397
3398/* Return minimum size of leaf window W. WIDTH_P non-zero means return
3399 the minimum width of W, WIDTH_P zero means return the minimum height
3400 of W. SAFE_P non-zero means ignore window-min-height|width but just
3401 return values that won't crash Emacs and don't hide components like
3402 fringes, scrollbars, or modelines. If WIDTH_P is zero and W is the
3403 minibuffer window, always return 1. */
3404
3405static int
3406window_min_size_2 (struct window *w, int width_p, int safe_p)
3407{
3408 /* We should consider buffer-local values of window_min_height and
3409 window_min_width here. */
3410 if (width_p)
3411 {
3412 int safe_size = (MIN_SAFE_WINDOW_WIDTH
3413 + WINDOW_FRINGE_COLS (w)
3414 + WINDOW_SCROLL_BAR_COLS (w));
3415
3416 return safe_p ? safe_size : max (window_min_width, safe_size);
3417 }
3418 else if (MINI_WINDOW_P (w))
3419 return 1;
3420 else
3421 {
3422 int safe_size = (MIN_SAFE_WINDOW_HEIGHT
3423 + ((BUFFERP (w->buffer)
3424 && !NILP (BVAR (XBUFFER (w->buffer), mode_line_format)))
3425 ? 1 : 0));
3426
3427 return safe_p ? safe_size : max (window_min_height, safe_size);
3428 }
3429}
3430
3431/* Return minimum size of window W, not taking fixed-width windows into
3432 account. WIDTH_P non-zero means return the minimum width, otherwise
3433 return the minimum height. SAFE_P non-zero means ignore
3434 window-min-height|width but just return values that won't crash Emacs
3435 and don't hide components like fringes, scrollbars, or modelines. If
3436 W is a combination window, compute the minimum size from the minimum
3437 sizes of W's children. */
3438
3439static int
3440window_min_size_1 (struct window *w, int width_p, int safe_p)
3441{
3442 struct window *c;
3443 int size;
3444
3445 if (!NILP (w->hchild))
3446 {
3447 /* W is a horizontal combination. */
3448 c = XWINDOW (w->hchild);
3449 size = 0;
3450
3451 if (width_p)
3452 {
3453 /* The minimum width of a horizontal combination is the sum of
3454 the minimum widths of its children. */
3455 while (c)
3456 {
3457 size += window_min_size_1 (c, 1, safe_p);
3458 c = WINDOWP (c->next) ? XWINDOW (c->next) : NULL;
3459 }
3460 }
3461 else
3462 {
3463 /* The minimum height of a horizontal combination is the
3464 maximum of the minimum heights of its children. */
3465 while (c)
3466 {
3467 size = max (window_min_size_1 (c, 0, safe_p), size);
3468 c = WINDOWP (c->next) ? XWINDOW (c->next) : NULL;
3469 }
3470 }
3471 }
3472 else if (!NILP (w->vchild))
3473 {
3474 /* W is a vertical combination. */
3475 c = XWINDOW (w->vchild);
3476 size = 0;
3477
3478 if (width_p)
3479 {
3480 /* The minimum width of a vertical combination is the maximum
3481 of the minimum widths of its children. */
3482 while (c)
3483 {
3484 size = max (window_min_size_1 (c, 1, safe_p), size);
3485 c = WINDOWP (c->next) ? XWINDOW (c->next) : NULL;
3486 }
3487 }
3488 else
3489 {
3490 /* The minimum height of a vertical combination is the sum of
3491 the minimum height of its children. */
3492 while (c)
3493 {
3494 size += window_min_size_1 (c, 0, safe_p);
3495 c = WINDOWP (c->next) ? XWINDOW (c->next) : NULL;
3496 }
3497 }
3498 }
3499 else
3500 /* W is a leaf window. */
3501 size = window_min_size_2 (w, width_p, safe_p);
3502
3503 return size;
3504}
3505
3506/* Return the minimum size of window W, taking fixed-size windows into
3507 account. WIDTH_P non-zero means return the minimum width, otherwise
3508 return the minimum height. SAFE_P non-zero means ignore
3509 window-min-height|width but just return values that won't crash Emacs
3510 and don't hide components like fringes, scrollbars, or modelines.
3511 IGNORE_FIXED_P non-zero means ignore if W is fixed-size. Set *FIXED
3512 to 1 if W is fixed-size unless FIXED is null. */
3513
3514static int
3515window_min_size (struct window *w, int width_p, int safe_p, int ignore_fixed_p, int *fixed)
3516{
3517 int size, fixed_p;
3518
3519 if (ignore_fixed_p)
3520 fixed_p = 0;
3521 else
3522 fixed_p = window_fixed_size_p (w, width_p, 1);
3523
3524 if (fixed)
3525 *fixed = fixed_p;
3526
3527 if (fixed_p)
3528 size = WINDOW_TOTAL_SIZE (w, width_p);
3529 else
3530 size = window_min_size_1 (w, width_p, safe_p);
3531
3532 return size;
3533}
3534
3535
3536/* Adjust the margins of window W if text area is too small. 2992/* Adjust the margins of window W if text area is too small.
3537 Return 1 if window width is ok after adjustment; 0 if window 2993 Return 1 if window width is ok after adjustment; 0 if window
3538 is still too narrow. */ 2994 is still too narrow. */
@@ -3567,410 +3023,6 @@ adjust_window_margins (struct window *w)
3567 w->left_margin_cols = make_number (margin_cols); 3023 w->left_margin_cols = make_number (margin_cols);
3568 return 1; 3024 return 1;
3569} 3025}
3570
3571/* Calculate new sizes for windows in the list FORWARD when their
3572 compound size goes from TOTAL to SIZE. TOTAL must be greater than
3573 SIZE. The number of windows in FORWARD is NCHILDREN, and the number
3574 that can shrink is SHRINKABLE. Fixed-size windows may be shrunk if
3575 and only if RESIZE_FIXED_P is non-zero. WIDTH_P non-zero means
3576 shrink columns, otherwise shrink lines.
3577
3578 SAFE_P zero means windows may be sized down to window-min-height
3579 lines (window-min-window columns for WIDTH_P non-zero). SAFE_P
3580 non-zero means windows may be sized down to their minimum safe sizes
3581 taking into account the space needed to display modelines, fringes,
3582 and scrollbars.
3583
3584 This function returns an allocated array of new sizes that the caller
3585 must free. A size -1 means the window is fixed and RESIZE_FIXED_P is
3586 zero. A size zero means the window shall be deleted. Array index 0
3587 refers to the first window in FORWARD, 1 to the second, and so on.
3588
3589 This function resizes windows proportionally to their size. It also
3590 tries to preserve smaller windows by resizing larger windows before
3591 resizing any window to zero. If resize_proportionally is non-nil for
3592 a specific window, it will attempt to strictly resize that window
3593 proportionally, even at the expense of deleting smaller windows. */
3594static int *
3595shrink_windows (int total, int size, int nchildren, int shrinkable,
3596 int resize_fixed_p, Lisp_Object forward, int width_p, int safe_p)
3597{
3598 int available_resize = 0;
3599 int *new_sizes, *min_sizes;
3600 struct window *c;
3601 Lisp_Object child;
3602 int smallest = total;
3603 int total_removed = 0;
3604 int total_shrink = total - size;
3605 int i;
3606
3607 new_sizes = xmalloc (sizeof (*new_sizes) * nchildren);
3608 min_sizes = xmalloc (sizeof (*min_sizes) * nchildren);
3609
3610 for (i = 0, child = forward; !NILP (child); child = c->next, ++i)
3611 {
3612 int child_size;
3613
3614 c = XWINDOW (child);
3615 child_size = WINDOW_TOTAL_SIZE (c, width_p);
3616
3617 if (!resize_fixed_p && window_fixed_size_p (c, width_p, 0))
3618 new_sizes[i] = -1;
3619 else
3620 {
3621 new_sizes[i] = child_size;
3622 min_sizes[i] = window_min_size_1 (c, width_p, safe_p);
3623 if (child_size > min_sizes[i]
3624 && NILP (c->resize_proportionally))
3625 available_resize += child_size - min_sizes[i];
3626 }
3627 }
3628 /* We might need to shrink some windows to zero. Find the smallest
3629 windows and set them to 0 until we can fulfil the new size. */
3630
3631 while (shrinkable > 1 && size + available_resize < total)
3632 {
3633 for (i = 0; i < nchildren; ++i)
3634 if (new_sizes[i] > 0 && smallest > new_sizes[i])
3635 smallest = new_sizes[i];
3636
3637 for (i = 0; i < nchildren; ++i)
3638 if (new_sizes[i] == smallest)
3639 {
3640 /* Resize this window down to zero. */
3641 new_sizes[i] = 0;
3642 if (smallest > min_sizes[i])
3643 available_resize -= smallest - min_sizes[i];
3644 available_resize += smallest;
3645 --shrinkable;
3646 total_removed += smallest;
3647
3648 /* We don't know what the smallest is now. */
3649 smallest = total;
3650
3651 /* Out of for, just remove one window at the time and
3652 check again if we have enough space. */
3653 break;
3654 }
3655 }
3656
3657 /* Now, calculate the new sizes. Try to shrink each window
3658 proportional to its size. */
3659 for (i = 0; i < nchildren; ++i)
3660 {
3661 if (new_sizes[i] > min_sizes[i])
3662 {
3663 int to_shrink = total_shrink * new_sizes[i] / total;
3664
3665 if (new_sizes[i] - to_shrink < min_sizes[i])
3666 to_shrink = new_sizes[i] - min_sizes[i];
3667 new_sizes[i] -= to_shrink;
3668 total_removed += to_shrink;
3669 }
3670 }
3671
3672 /* Any reminder due to rounding, we just subtract from windows
3673 that are left and still can be shrunk. */
3674 while (total_shrink > total_removed)
3675 {
3676 int nonzero_sizes = 0;
3677
3678 for (i = 0; i < nchildren; ++i)
3679 if (new_sizes[i] > 0)
3680 ++nonzero_sizes;
3681
3682 for (i = 0; i < nchildren; ++i)
3683 if (new_sizes[i] > min_sizes[i])
3684 {
3685 --new_sizes[i];
3686 ++total_removed;
3687
3688 /* Out of for, just shrink one window at the time and
3689 check again if we have enough space. */
3690 break;
3691 }
3692
3693 /* Special case, only one window left. */
3694 if (nonzero_sizes == 1)
3695 break;
3696 }
3697
3698 /* Any surplus due to rounding, we add to windows that are left. */
3699 while (total_shrink < total_removed)
3700 {
3701 for (i = 0; i < nchildren; ++i)
3702 {
3703 if (new_sizes[i] != 0 && total_shrink < total_removed)
3704 {
3705 ++new_sizes[i];
3706 --total_removed;
3707 break;
3708 }
3709 }
3710 }
3711
3712 xfree (min_sizes);
3713
3714 return new_sizes;
3715}
3716
3717/* Set WINDOW's height or width to SIZE. WIDTH_P non-zero means set
3718 WINDOW's width. Resize WINDOW's children, if any, so that they keep
3719 their proportionate size relative to WINDOW.
3720
3721 If FIRST_ONLY is 1, change only the first of WINDOW's children when
3722 they are in series. If LAST_ONLY is 1, change only the last of
3723 WINDOW's children when they are in series.
3724
3725 Propagate WINDOW's top or left edge position to children. Delete
3726 windows that become too small unless NODELETE_P is 1. When
3727 NODELETE_P equals 2 do not honor settings for window-min-height and
3728 window-min-width when resizing windows but use safe defaults instead.
3729 This should give better behavior when resizing frames. */
3730
3731static void
3732size_window (Lisp_Object window, int size, int width_p, int nodelete_p, int first_only, int last_only)
3733{
3734 struct window *w = XWINDOW (window);
3735 struct window *c;
3736 Lisp_Object child, *forward, *sideward;
3737 int old_size = WINDOW_TOTAL_SIZE (w, width_p);
3738
3739 size = max (0, size);
3740
3741 /* Delete WINDOW if it's too small. */
3742 if (nodelete_p != 1 && !NILP (w->parent)
3743 && size < window_min_size_1 (w, width_p, nodelete_p == 2))
3744 {
3745 delete_window (window);
3746 return;
3747 }
3748
3749 /* Set redisplay hints. */
3750 w->last_modified = make_number (0);
3751 w->last_overlay_modified = make_number (0);
3752 windows_or_buffers_changed++;
3753 FRAME_WINDOW_SIZES_CHANGED (XFRAME (w->frame)) = 1;
3754
3755 if (width_p)
3756 {
3757 sideward = &w->vchild;
3758 forward = &w->hchild;
3759 w->total_cols = make_number (size);
3760 adjust_window_margins (w);
3761 }
3762 else
3763 {
3764 sideward = &w->hchild;
3765 forward = &w->vchild;
3766 w->total_lines = make_number (size);
3767 w->orig_total_lines = Qnil;
3768 }
3769
3770 if (!NILP (*sideward))
3771 {
3772 /* We have a chain of parallel siblings whose size should all change. */
3773 for (child = *sideward; !NILP (child); child = c->next)
3774 {
3775 c = XWINDOW (child);
3776 if (width_p)
3777 c->left_col = w->left_col;
3778 else
3779 c->top_line = w->top_line;
3780 size_window (child, size, width_p, nodelete_p,
3781 first_only, last_only);
3782 }
3783 }
3784 else if (!NILP (*forward) && last_only)
3785 {
3786 /* Change the last in a series of siblings. */
3787 Lisp_Object last_child;
3788 int child_size;
3789
3790 child = *forward;
3791 do
3792 {
3793 c = XWINDOW (child);
3794 last_child = child;
3795 child = c->next;
3796 }
3797 while (!NILP (child));
3798
3799 child_size = WINDOW_TOTAL_SIZE (c, width_p);
3800 size_window (last_child, size - old_size + child_size,
3801 width_p, nodelete_p, first_only, last_only);
3802 }
3803 else if (!NILP (*forward) && first_only)
3804 {
3805 /* Change the first in a series of siblings. */
3806 int child_size;
3807
3808 child = *forward;
3809 c = XWINDOW (child);
3810
3811 if (width_p)
3812 c->left_col = w->left_col;
3813 else
3814 c->top_line = w->top_line;
3815
3816 child_size = WINDOW_TOTAL_SIZE (c, width_p);
3817 size_window (child, size - old_size + child_size,
3818 width_p, nodelete_p, first_only, last_only);
3819 }
3820 else if (!NILP (*forward))
3821 {
3822 int fixed_size, each IF_LINT (= 0), extra IF_LINT (= 0), n;
3823 int resize_fixed_p, nfixed;
3824 int last_pos, first_pos, nchildren, total;
3825 int *new_sizes = NULL;
3826
3827 /* Determine the fixed-size portion of this window, and the
3828 number of child windows. */
3829 fixed_size = nchildren = nfixed = total = 0;
3830 for (child = *forward; !NILP (child); child = c->next, ++nchildren)
3831 {
3832 int child_size;
3833
3834 c = XWINDOW (child);
3835 child_size = WINDOW_TOTAL_SIZE (c, width_p);
3836 total += child_size;
3837
3838 if (window_fixed_size_p (c, width_p, 0))
3839 {
3840 fixed_size += child_size;
3841 ++nfixed;
3842 }
3843 }
3844
3845 /* If the new size is smaller than fixed_size, or if there
3846 aren't any resizable windows, allow resizing fixed-size
3847 windows. */
3848 resize_fixed_p = nfixed == nchildren || size < fixed_size;
3849
3850 /* Compute how many lines/columns to add/remove to each child. The
3851 value of extra takes care of rounding errors. */
3852 n = resize_fixed_p ? nchildren : nchildren - nfixed;
3853 if (size < total && n > 1)
3854 new_sizes = shrink_windows (total, size, nchildren, n,
3855 resize_fixed_p, *forward, width_p,
3856 nodelete_p == 2);
3857 else
3858 {
3859 each = (size - total) / n;
3860 extra = (size - total) - n * each;
3861 }
3862
3863 /* Compute new children heights and edge positions. */
3864 first_pos = width_p ? XINT (w->left_col) : XINT (w->top_line);
3865 last_pos = first_pos;
3866 for (n = 0, child = *forward; !NILP (child); child = c->next, ++n)
3867 {
3868 int new_child_size, old_child_size;
3869
3870 c = XWINDOW (child);
3871 old_child_size = WINDOW_TOTAL_SIZE (c, width_p);
3872 new_child_size = old_child_size;
3873
3874 /* The top or left edge position of this child equals the
3875 bottom or right edge of its predecessor. */
3876 if (width_p)
3877 c->left_col = make_number (last_pos);
3878 else
3879 c->top_line = make_number (last_pos);
3880
3881 /* If this child can be resized, do it. */
3882 if (resize_fixed_p || !window_fixed_size_p (c, width_p, 0))
3883 {
3884 new_child_size =
3885 new_sizes ? new_sizes[n] : old_child_size + each + extra;
3886 extra = 0;
3887 }
3888
3889 /* Set new size. Note that size_window also propagates
3890 edge positions to children, so it's not a no-op if we
3891 didn't change the child's size. */
3892 size_window (child, new_child_size, width_p, 1,
3893 first_only, last_only);
3894
3895 /* Remember the bottom/right edge position of this child; it
3896 will be used to set the top/left edge of the next child. */
3897 last_pos += new_child_size;
3898 }
3899
3900 xfree (new_sizes);
3901
3902 /* We should have covered the parent exactly with child windows. */
3903 xassert (size == last_pos - first_pos);
3904
3905 /* Now delete any children that became too small. */
3906 if (nodelete_p != 1)
3907 for (child = *forward; !NILP (child); child = c->next)
3908 {
3909 int child_size;
3910
3911 c = XWINDOW (child);
3912 child_size = WINDOW_TOTAL_SIZE (c, width_p);
3913 size_window (child, child_size, width_p, nodelete_p,
3914 first_only, last_only);
3915 }
3916 }
3917}
3918
3919/* Set WINDOW's height to HEIGHT, and recursively change the height of
3920 WINDOW's children. NODELETE zero means windows that have become
3921 smaller than window-min-height in the process may be deleted.
3922 NODELETE 1 means never delete windows that become too small in the
3923 process. (The caller should check later and do so if appropriate.)
3924 NODELETE 2 means delete only windows that have become too small to be
3925 displayed correctly. */
3926
3927void
3928set_window_height (Lisp_Object window, int height, int nodelete)
3929{
3930 size_window (window, height, 0, nodelete, 0, 0);
3931}
3932
3933/* Set WINDOW's width to WIDTH, and recursively change the width of
3934 WINDOW's children. NODELETE zero means windows that have become
3935 smaller than window-min-width in the process may be deleted.
3936 NODELETE 1 means never delete windows that become too small in the
3937 process. (The caller should check later and do so if appropriate.)
3938 NODELETE 2 means delete only windows that have become too small to be
3939 displayed correctly. */
3940
3941void
3942set_window_width (Lisp_Object window, int width, int nodelete)
3943{
3944 size_window (window, width, 1, nodelete, 0, 0);
3945}
3946
3947/* Change window heights in windows rooted in WINDOW by N lines. */
3948
3949void
3950change_window_heights (Lisp_Object window, int n)
3951{
3952 struct window *w = XWINDOW (window);
3953
3954 XSETFASTINT (w->top_line, XFASTINT (w->top_line) + n);
3955 XSETFASTINT (w->total_lines, XFASTINT (w->total_lines) - n);
3956
3957 if (INTEGERP (w->orig_top_line))
3958 XSETFASTINT (w->orig_top_line, XFASTINT (w->orig_top_line) + n);
3959 if (INTEGERP (w->orig_total_lines))
3960 XSETFASTINT (w->orig_total_lines, XFASTINT (w->orig_total_lines) - n);
3961
3962 /* Handle just the top child in a vertical split. */
3963 if (!NILP (w->vchild))
3964 change_window_heights (w->vchild, n);
3965
3966 /* Adjust all children in a horizontal split. */
3967 for (window = w->hchild; !NILP (window); window = w->next)
3968 {
3969 w = XWINDOW (window);
3970 change_window_heights (window, n);
3971 }
3972}
3973
3974 3026
3975int window_select_count; 3027int window_select_count;
3976 3028
@@ -4337,43 +3389,6 @@ DEFUN ("internal-temp-output-buffer-show",
4337 return Qnil; 3389 return Qnil;
4338} 3390}
4339 3391
4340static void
4341make_dummy_parent (Lisp_Object window)
4342{
4343 Lisp_Object new;
4344 register struct window *o, *p;
4345 int i;
4346
4347 o = XWINDOW (window);
4348 p = allocate_window ();
4349 for (i = 0; i < VECSIZE (struct window); ++i)
4350 ((struct Lisp_Vector *) p)->contents[i]
4351 = ((struct Lisp_Vector *)o)->contents[i];
4352 XSETWINDOW (new, p);
4353
4354 ++sequence_number;
4355 XSETFASTINT (p->sequence_number, sequence_number);
4356 XSETFASTINT (p->clone_number, sequence_number);
4357
4358 /* Put new into window structure in place of window */
4359 replace_window (window, new, 1);
4360
4361 o->next = Qnil;
4362 o->prev = Qnil;
4363 o->vchild = Qnil;
4364 o->hchild = Qnil;
4365 o->parent = new;
4366
4367 p->start = Qnil;
4368 p->pointm = Qnil;
4369 p->buffer = Qnil;
4370
4371 p->splits = Qnil;
4372 p->nest = Qnil;
4373 p->window_parameters = Qnil;
4374
4375}
4376
4377/* Make new window, have it replace WINDOW in window-tree, and make 3392/* Make new window, have it replace WINDOW in window-tree, and make
4378 WINDOW its only vertical child (HORFLAG 1 means make WINDOW its only 3393 WINDOW its only vertical child (HORFLAG 1 means make WINDOW its only
4379 horizontal child). */ 3394 horizontal child). */
@@ -4470,7 +3485,6 @@ make_window (void)
4470 w->pseudo_window_p = 0; 3485 w->pseudo_window_p = 0;
4471 w->frozen_window_start_p = 0; 3486 w->frozen_window_start_p = 0;
4472 w->vscroll = 0; 3487 w->vscroll = 0;
4473 w->resize_proportionally = Qnil;
4474 /* Reset window_list. */ 3488 /* Reset window_list. */
4475 Vwindow_list = Qnil; 3489 Vwindow_list = Qnil;
4476 /* Return window. */ 3490 /* Return window. */
@@ -5159,147 +4173,81 @@ when WINDOW is the only window on its frame. */)
5159 4173
5160 return Qnil; 4174 return Qnil;
5161} 4175}
4176
4177/***********************************************************************
4178 Resizing Mini-Windows
4179 ***********************************************************************/
5162 4180
5163DEFUN ("split-window", Fsplit_window, Ssplit_window, 0, 3, "", 4181/* Grow mini-window W by DELTA lines, DELTA >= 0, or as much as we
5164 doc: /* Split WINDOW, putting SIZE lines in the first of the pair. 4182 can. */
5165WINDOW defaults to selected one and SIZE to half its size. 4183void
5166If optional third arg HORIZONTAL is non-nil, split side by side and put 4184grow_mini_window (struct window *w, int delta)
5167SIZE columns in the first of the pair. In that case, SIZE includes that
5168window's scroll bar, or the divider column to its right.
5169Interactively, all arguments are nil.
5170Returns the newly created window (which is the lower or rightmost one).
5171The upper or leftmost window is the original one, and remains selected
5172if it was selected before.
5173
5174See Info node `(elisp)Splitting Windows' for more details and examples. */)
5175 (Lisp_Object window, Lisp_Object size, Lisp_Object horizontal)
5176{ 4185{
5177 register Lisp_Object new; 4186 struct frame *f = XFRAME (w->frame);
5178 register struct window *o, *p; 4187 struct window *r;
5179 FRAME_PTR fo; 4188 Lisp_Object root, value;
5180 register int size_int;
5181
5182 if (NILP (window))
5183 window = selected_window;
5184 else
5185 CHECK_LIVE_WINDOW (window);
5186 4189
5187 o = XWINDOW (window); 4190 xassert (MINI_WINDOW_P (w));
5188 fo = XFRAME (WINDOW_FRAME (o)); 4191 xassert (delta >= 0);
5189 4192
5190 if (NILP (size)) 4193 root = FRAME_ROOT_WINDOW (f);
5191 { 4194 r = XWINDOW (root);
5192 if (!NILP (horizontal)) 4195 value = call2 (Qresize_root_window_vertically, root, make_number (- delta));
5193 /* Calculate the size of the left-hand window, by dividing 4196 if (INTEGERP (value) && resize_window_check (r, 0))
5194 the usable space in columns by two.
5195 We round up, since the left-hand window may include
5196 a dividing line, while the right-hand may not. */
5197 size_int = (XFASTINT (o->total_cols) + 1) >> 1;
5198 else
5199 size_int = XFASTINT (o->total_lines) >> 1;
5200 }
5201 else
5202 { 4197 {
5203 CHECK_NUMBER (size); 4198 BLOCK_INPUT;
5204 size_int = XINT (size); 4199 resize_window_apply (r, 0);
5205 }
5206
5207 if (MINI_WINDOW_P (o))
5208 error ("Attempt to split minibuffer window");
5209 else if (window_fixed_size_p (o, !NILP (horizontal), 0))
5210 error ("Attempt to split fixed-size window");
5211 4200
5212 if (NILP (horizontal)) 4201 /* Grow the mini-window. */
5213 { 4202 XSETFASTINT (w->top_line, XFASTINT (r->top_line) + XFASTINT (r->total_lines));
5214 int window_safe_height = window_min_size_2 (o, 0, 0); 4203 XSETFASTINT (w->total_lines, XFASTINT (w->total_lines) - XINT (value));
4204 XSETFASTINT (w->last_modified, 0);
4205 XSETFASTINT (w->last_overlay_modified, 0);
5215 4206
5216 if (size_int < window_safe_height) 4207 adjust_glyphs (f);
5217 error ("Window height %d too small (after splitting)", size_int); 4208 UNBLOCK_INPUT;
5218 if (size_int + window_safe_height > XFASTINT (o->total_lines))
5219 error ("Window height %d too small (after splitting)",
5220 (int) (XFASTINT (o->total_lines) - size_int));
5221 if (NILP (o->parent)
5222 || NILP (XWINDOW (o->parent)->vchild))
5223 {
5224 make_dummy_parent (window);
5225 new = o->parent;
5226 XWINDOW (new)->vchild = window;
5227 }
5228 } 4209 }
5229 else 4210}
5230 {
5231 int window_safe_width = window_min_size_2 (o, 1, 0);
5232 4211
5233 if (size_int < window_safe_width)
5234 error ("Window width %d too small (after splitting)", size_int);
5235 if (size_int + window_safe_width > XFASTINT (o->total_cols))
5236 error ("Window width %d too small (after splitting)",
5237 (int) (XFASTINT (o->total_cols) - size_int));
5238 if (NILP (o->parent)
5239 || NILP (XWINDOW (o->parent)->hchild))
5240 {
5241 make_dummy_parent (window);
5242 new = o->parent;
5243 XWINDOW (new)->hchild = window;
5244 }
5245 }
5246 4212
5247 /* Now we know that window's parent is a vertical combination 4213/* Shrink mini-window W. */
5248 if we are dividing vertically, or a horizontal combination 4214void
5249 if we are making side-by-side windows */ 4215shrink_mini_window (struct window *w)
4216{
4217 struct frame *f = XFRAME (w->frame);
4218 struct window *r;
4219 Lisp_Object root, value;
4220 EMACS_INT size;
5250 4221
5251 windows_or_buffers_changed++; 4222 xassert (MINI_WINDOW_P (w));
5252 FRAME_WINDOW_SIZES_CHANGED (fo) = 1; 4223
5253 new = make_window (); 4224 size = XINT (w->total_lines);
5254 p = XWINDOW (new); 4225 if (size > 1)
5255
5256 p->frame = o->frame;
5257 p->next = o->next;
5258 if (!NILP (p->next))
5259 XWINDOW (p->next)->prev = new;
5260 p->prev = window;
5261 o->next = new;
5262 p->parent = o->parent;
5263 p->buffer = Qt;
5264 p->window_end_valid = Qnil;
5265 memset (&p->last_cursor, 0, sizeof p->last_cursor);
5266
5267 /* Duplicate special geometry settings. */
5268
5269 p->left_margin_cols = o->left_margin_cols;
5270 p->right_margin_cols = o->right_margin_cols;
5271 p->left_fringe_width = o->left_fringe_width;
5272 p->right_fringe_width = o->right_fringe_width;
5273 p->fringes_outside_margins = o->fringes_outside_margins;
5274 p->scroll_bar_width = o->scroll_bar_width;
5275 p->vertical_scroll_bar_type = o->vertical_scroll_bar_type;
5276
5277 /* Apportion the available frame space among the two new windows */
5278
5279 if (!NILP (horizontal))
5280 {
5281 p->total_lines = o->total_lines;
5282 p->top_line = o->top_line;
5283 XSETFASTINT (p->total_cols, XFASTINT (o->total_cols) - size_int);
5284 XSETFASTINT (o->total_cols, size_int);
5285 XSETFASTINT (p->left_col, XFASTINT (o->left_col) + size_int);
5286 adjust_window_margins (p);
5287 adjust_window_margins (o);
5288 }
5289 else
5290 { 4226 {
5291 p->left_col = o->left_col; 4227 root = FRAME_ROOT_WINDOW (f);
5292 p->total_cols = o->total_cols; 4228 r = XWINDOW (root);
5293 XSETFASTINT (p->total_lines, XFASTINT (o->total_lines) - size_int); 4229 value = call2 (Qresize_root_window_vertically,
5294 XSETFASTINT (o->total_lines, size_int); 4230 root, make_number (size - 1));
5295 XSETFASTINT (p->top_line, XFASTINT (o->top_line) + size_int); 4231 if (INTEGERP (value) && resize_window_check (r, 0))
5296 } 4232 {
4233 BLOCK_INPUT;
4234 resize_window_apply (r, 0);
5297 4235
5298 /* Adjust glyph matrices. */ 4236 /* Shrink the mini-window. */
5299 adjust_glyphs (fo); 4237 XSETFASTINT (w->top_line, XFASTINT (r->top_line) + XFASTINT (r->total_lines));
4238 XSETFASTINT (w->total_lines, 1);
5300 4239
5301 Fset_window_buffer (new, o->buffer, Qt); 4240 XSETFASTINT (w->last_modified, 0);
5302 return new; 4241 XSETFASTINT (w->last_overlay_modified, 0);
4242
4243 adjust_glyphs (f);
4244 UNBLOCK_INPUT;
4245 }
4246 /* If the above failed for whatever strange reason we must make a
4247 one window frame here. The same routine will be needed when
4248 shrinking the frame (and probably when making the initial
4249 *scratch* window). For the moment leave things as they are. */
4250 }
5303} 4251}
5304 4252
5305DEFUN ("resize-mini-window-internal", Fresize_mini_window_internal, Sresize_mini_window_internal, 1, 1, 0, 4253DEFUN ("resize-mini-window-internal", Fresize_mini_window_internal, Sresize_mini_window_internal, 1, 1, 0,
@@ -5342,730 +4290,6 @@ DEFUN ("resize-mini-window-internal", Fresize_mini_window_internal, Sresize_mini
5342 else error ("Failed to resize minibuffer window"); 4290 else error ("Failed to resize minibuffer window");
5343} 4291}
5344 4292
5345DEFUN ("enlarge-window", Fenlarge_window, Senlarge_window, 1, 2, "p",
5346 doc: /* Make selected window SIZE lines taller.
5347Interactively, if no argument is given, make the selected window one
5348line taller. If optional argument HORIZONTAL is non-nil, make selected
5349window wider by SIZE columns. If SIZE is negative, shrink the window by
5350-SIZE lines or columns. Return nil.
5351
5352This function can delete windows if they get too small. The size of
5353fixed size windows is not altered by this function. */)
5354 (Lisp_Object size, Lisp_Object horizontal)
5355{
5356 CHECK_NUMBER (size);
5357 enlarge_window (selected_window, XINT (size), !NILP (horizontal));
5358
5359 run_window_configuration_change_hook (SELECTED_FRAME ());
5360
5361 return Qnil;
5362}
5363
5364DEFUN ("shrink-window", Fshrink_window, Sshrink_window, 1, 2, "p",
5365 doc: /* Make selected window SIZE lines smaller.
5366Interactively, if no argument is given, make the selected window one
5367line smaller. If optional argument HORIZONTAL is non-nil, make the
5368window narrower by SIZE columns. If SIZE is negative, enlarge selected
5369window by -SIZE lines or columns. Return nil.
5370
5371This function can delete windows if they get too small. The size of
5372fixed size windows is not altered by this function. */)
5373 (Lisp_Object size, Lisp_Object horizontal)
5374{
5375 CHECK_NUMBER (size);
5376 enlarge_window (selected_window, -XINT (size), !NILP (horizontal));
5377
5378 run_window_configuration_change_hook (SELECTED_FRAME ());
5379
5380 return Qnil;
5381}
5382
5383static int
5384window_height (Lisp_Object window)
5385{
5386 register struct window *p = XWINDOW (window);
5387 return WINDOW_TOTAL_LINES (p);
5388}
5389
5390static int
5391window_width (Lisp_Object window)
5392{
5393 register struct window *p = XWINDOW (window);
5394 return WINDOW_TOTAL_COLS (p);
5395}
5396
5397
5398#define CURBEG(w) \
5399 *(horiz_flag ? &(XWINDOW (w)->left_col) : &(XWINDOW (w)->top_line))
5400
5401#define CURSIZE(w) \
5402 *(horiz_flag ? &(XWINDOW (w)->total_cols) : &(XWINDOW (w)->total_lines))
5403
5404
5405/* Enlarge WINDOW by DELTA. HORIZ_FLAG nonzero means enlarge it
5406 horizontally; zero means do it vertically.
5407
5408 Siblings of the selected window are resized to fulfill the size
5409 request. If they become too small in the process, they may be
5410 deleted. */
5411
5412static void
5413enlarge_window (Lisp_Object window, int delta, int horiz_flag)
5414{
5415 Lisp_Object parent, next, prev;
5416 struct window *p;
5417 Lisp_Object *sizep;
5418 int maximum;
5419 int (*sizefun) (Lisp_Object)
5420 = horiz_flag ? window_width : window_height;
5421 void (*setsizefun) (Lisp_Object, int, int)
5422 = (horiz_flag ? set_window_width : set_window_height);
5423
5424 /* Give up if this window cannot be resized. */
5425 if (window_fixed_size_p (XWINDOW (window), horiz_flag, 1))
5426 error ("Window is not resizable");
5427
5428 /* Find the parent of the selected window. */
5429 while (1)
5430 {
5431 p = XWINDOW (window);
5432 parent = p->parent;
5433
5434 if (NILP (parent))
5435 {
5436 if (horiz_flag)
5437 error ("No other window to side of this one");
5438 break;
5439 }
5440
5441 if (horiz_flag
5442 ? !NILP (XWINDOW (parent)->hchild)
5443 : !NILP (XWINDOW (parent)->vchild))
5444 break;
5445
5446 window = parent;
5447 }
5448
5449 sizep = &CURSIZE (window);
5450
5451 {
5452 register int maxdelta;
5453
5454 /* Compute the maximum size increment this window can have. */
5455
5456 maxdelta = (!NILP (parent) ? (*sizefun) (parent) - XINT (*sizep)
5457 /* This is a main window followed by a minibuffer. */
5458 : !NILP (p->next) ? ((*sizefun) (p->next)
5459 - window_min_size (XWINDOW (p->next),
5460 horiz_flag, 0, 0, 0))
5461 /* This is a minibuffer following a main window. */
5462 : !NILP (p->prev) ? ((*sizefun) (p->prev)
5463 - window_min_size (XWINDOW (p->prev),
5464 horiz_flag, 0, 0, 0))
5465 /* This is a frame with only one window, a minibuffer-only
5466 or a minibufferless frame. */
5467 : (delta = 0));
5468
5469 if (delta > maxdelta)
5470 /* This case traps trying to make the minibuffer
5471 the full frame, or make the only window aside from the
5472 minibuffer the full frame. */
5473 delta = maxdelta;
5474 }
5475
5476 if (XINT (*sizep) + delta < window_min_size (XWINDOW (window),
5477 horiz_flag, 0, 0, 0))
5478 {
5479 delete_window (window);
5480 return;
5481 }
5482
5483 if (delta == 0)
5484 return;
5485
5486 /* Find the total we can get from other siblings without deleting them. */
5487 maximum = 0;
5488 for (next = p->next; WINDOWP (next); next = XWINDOW (next)->next)
5489 maximum += (*sizefun) (next) - window_min_size (XWINDOW (next),
5490 horiz_flag, 0, 0, 0);
5491 for (prev = p->prev; WINDOWP (prev); prev = XWINDOW (prev)->prev)
5492 maximum += (*sizefun) (prev) - window_min_size (XWINDOW (prev),
5493 horiz_flag, 0, 0, 0);
5494
5495 /* If we can get it all from them without deleting them, do so. */
5496 if (delta <= maximum)
5497 {
5498 Lisp_Object first_unaffected;
5499 Lisp_Object first_affected;
5500 int fixed_p;
5501
5502 next = p->next;
5503 prev = p->prev;
5504 first_affected = window;
5505 /* Look at one sibling at a time,
5506 moving away from this window in both directions alternately,
5507 and take as much as we can get without deleting that sibling. */
5508 while (delta != 0
5509 && (!NILP (next) || !NILP (prev)))
5510 {
5511 if (! NILP (next))
5512 {
5513 int this_one = ((*sizefun) (next)
5514 - window_min_size (XWINDOW (next), horiz_flag,
5515 0, 0, &fixed_p));
5516 if (!fixed_p)
5517 {
5518 if (this_one > delta)
5519 this_one = delta;
5520
5521 (*setsizefun) (next, (*sizefun) (next) - this_one, 0);
5522 (*setsizefun) (window, XINT (*sizep) + this_one, 0);
5523
5524 delta -= this_one;
5525 }
5526
5527 next = XWINDOW (next)->next;
5528 }
5529
5530 if (delta == 0)
5531 break;
5532
5533 if (! NILP (prev))
5534 {
5535 int this_one = ((*sizefun) (prev)
5536 - window_min_size (XWINDOW (prev), horiz_flag,
5537 0, 0, &fixed_p));
5538 if (!fixed_p)
5539 {
5540 if (this_one > delta)
5541 this_one = delta;
5542
5543 first_affected = prev;
5544
5545 (*setsizefun) (prev, (*sizefun) (prev) - this_one, 0);
5546 (*setsizefun) (window, XINT (*sizep) + this_one, 0);
5547
5548 delta -= this_one;
5549 }
5550
5551 prev = XWINDOW (prev)->prev;
5552 }
5553 }
5554
5555 xassert (delta == 0);
5556
5557 /* Now recalculate the edge positions of all the windows affected,
5558 based on the new sizes. */
5559 first_unaffected = next;
5560 prev = first_affected;
5561 for (next = XWINDOW (prev)->next; ! EQ (next, first_unaffected);
5562 prev = next, next = XWINDOW (next)->next)
5563 {
5564 XSETINT (CURBEG (next), XINT (CURBEG (prev)) + (*sizefun) (prev));
5565 /* This does not change size of NEXT,
5566 but it propagates the new top edge to its children */
5567 (*setsizefun) (next, (*sizefun) (next), 0);
5568 }
5569 }
5570 else
5571 {
5572 register int delta1;
5573 register int opht = (*sizefun) (parent);
5574
5575 if (opht <= XINT (*sizep) + delta)
5576 {
5577 /* If trying to grow this window to or beyond size of the parent,
5578 just delete all the sibling windows. */
5579 Lisp_Object start, tem;
5580
5581 start = XWINDOW (parent)->vchild;
5582 if (NILP (start))
5583 start = XWINDOW (parent)->hchild;
5584
5585 /* Delete any siblings that come after WINDOW. */
5586 tem = XWINDOW (window)->next;
5587 while (! NILP (tem))
5588 {
5589 Lisp_Object next1 = XWINDOW (tem)->next;
5590 delete_window (tem);
5591 tem = next1;
5592 }
5593
5594 /* Delete any siblings that come after WINDOW.
5595 Note that if START is not WINDOW, then WINDOW still
5596 has siblings, so WINDOW has not yet replaced its parent. */
5597 tem = start;
5598 while (! EQ (tem, window))
5599 {
5600 Lisp_Object next1 = XWINDOW (tem)->next;
5601 delete_window (tem);
5602 tem = next1;
5603 }
5604 }
5605 else
5606 {
5607 /* Otherwise, make delta1 just right so that if we add
5608 delta1 lines to this window and to the parent, and then
5609 shrink the parent back to its original size, the new
5610 proportional size of this window will increase by delta.
5611
5612 The function size_window will compute the new height h'
5613 of the window from delta1 as:
5614
5615 e = delta1/n
5616 x = delta1 - delta1/n * n for the 1st resizable child
5617 h' = h + e + x
5618
5619 where n is the number of children that can be resized.
5620 We can ignore x by choosing a delta1 that is a multiple of
5621 n. We want the height of this window to come out as
5622
5623 h' = h + delta
5624
5625 So, delta1 must be
5626
5627 h + e = h + delta
5628 delta1/n = delta
5629 delta1 = n * delta.
5630
5631 The number of children n equals the number of resizable
5632 children of this window + 1 because we know window itself
5633 is resizable (otherwise we would have signaled an error).
5634
5635 This reasoning is not correct when other windows become too
5636 small and shrink_windows refuses to delete them. Below we
5637 use resize_proportionally to work around this problem. */
5638
5639 struct window *w = XWINDOW (window);
5640 Lisp_Object s;
5641 int n = 1;
5642
5643 for (s = w->next; WINDOWP (s); s = XWINDOW (s)->next)
5644 if (!window_fixed_size_p (XWINDOW (s), horiz_flag, 0))
5645 ++n;
5646 for (s = w->prev; WINDOWP (s); s = XWINDOW (s)->prev)
5647 if (!window_fixed_size_p (XWINDOW (s), horiz_flag, 0))
5648 ++n;
5649
5650 delta1 = n * delta;
5651
5652 /* Add delta1 lines or columns to this window, and to the parent,
5653 keeping things consistent while not affecting siblings. */
5654 XSETINT (CURSIZE (parent), opht + delta1);
5655 (*setsizefun) (window, XINT (*sizep) + delta1, 0);
5656
5657 /* Squeeze out delta1 lines or columns from our parent,
5658 shrinking this window and siblings proportionately. This
5659 brings parent back to correct size. Delta1 was calculated
5660 so this makes this window the desired size, taking it all
5661 out of the siblings.
5662
5663 Temporarily set resize_proportionally to Qt to assure that,
5664 if necessary, shrink_windows deletes smaller windows rather
5665 than shrink this window. */
5666 w->resize_proportionally = Qt;
5667 (*setsizefun) (parent, opht, 0);
5668 w->resize_proportionally = Qnil;
5669 }
5670 }
5671
5672 XSETFASTINT (p->last_modified, 0);
5673 XSETFASTINT (p->last_overlay_modified, 0);
5674
5675 /* Adjust glyph matrices. */
5676 adjust_glyphs (XFRAME (WINDOW_FRAME (XWINDOW (window))));
5677}
5678
5679
5680/* Adjust the size of WINDOW by DELTA, moving only its trailing edge.
5681 HORIZ_FLAG nonzero means adjust the width, moving the right edge.
5682 zero means adjust the height, moving the bottom edge.
5683
5684 Following siblings of the selected window are resized to fulfill
5685 the size request. If they become too small in the process, they
5686 are not deleted; instead, we signal an error. */
5687
5688static void
5689adjust_window_trailing_edge (Lisp_Object window, int delta, int horiz_flag)
5690{
5691 Lisp_Object parent, child;
5692 struct window *p;
5693 Lisp_Object old_config = Fcurrent_window_configuration (Qnil);
5694 int delcount = window_deletion_count;
5695
5696 CHECK_WINDOW (window);
5697
5698 /* Give up if this window cannot be resized. */
5699 if (window_fixed_size_p (XWINDOW (window), horiz_flag, 1))
5700 error ("Window is not resizable");
5701
5702 while (1)
5703 {
5704 Lisp_Object first_parallel = Qnil;
5705
5706 if (NILP (window))
5707 {
5708 /* This happens if WINDOW on the previous iteration was
5709 at top level of the window tree. */
5710 Fset_window_configuration (old_config);
5711 error ("Specified window edge is fixed");
5712 }
5713
5714 p = XWINDOW (window);
5715 parent = p->parent;
5716
5717 /* See if this level has windows in parallel in the specified
5718 direction. If so, set FIRST_PARALLEL to the first one. */
5719 if (horiz_flag)
5720 {
5721 if (! NILP (parent) && !NILP (XWINDOW (parent)->vchild))
5722 first_parallel = XWINDOW (parent)->vchild;
5723 else if (NILP (parent) && !NILP (p->next))
5724 {
5725 /* Handle the vertical chain of main window and minibuffer
5726 which has no parent. */
5727 first_parallel = window;
5728 while (! NILP (XWINDOW (first_parallel)->prev))
5729 first_parallel = XWINDOW (first_parallel)->prev;
5730 }
5731 }
5732 else
5733 {
5734 if (! NILP (parent) && !NILP (XWINDOW (parent)->hchild))
5735 first_parallel = XWINDOW (parent)->hchild;
5736 }
5737
5738 /* If this level's succession is in the desired dimension,
5739 and this window is the last one, and there is no higher level,
5740 its trailing edge is fixed. */
5741 if (NILP (XWINDOW (window)->next) && NILP (first_parallel)
5742 && NILP (parent))
5743 {
5744 Fset_window_configuration (old_config);
5745 error ("Specified window edge is fixed");
5746 }
5747
5748 /* Don't make this window too small. */
5749 if (XINT (CURSIZE (window)) + delta
5750 < window_min_size_2 (XWINDOW (window), horiz_flag, 0))
5751 {
5752 Fset_window_configuration (old_config);
5753 error ("Cannot adjust window size as specified");
5754 }
5755
5756 /* Clear out some redisplay caches. */
5757 XSETFASTINT (p->last_modified, 0);
5758 XSETFASTINT (p->last_overlay_modified, 0);
5759
5760 /* Adjust this window's edge. */
5761 XSETINT (CURSIZE (window),
5762 XINT (CURSIZE (window)) + delta);
5763
5764 /* If this window has following siblings in the desired dimension,
5765 make them smaller, and exit the loop.
5766
5767 (If we reach the top of the tree and can never do this,
5768 we will fail and report an error, above.) */
5769 if (NILP (first_parallel))
5770 {
5771 if (!NILP (p->next))
5772 {
5773 /* This may happen for the minibuffer. In that case
5774 the window_deletion_count check below does not work. */
5775 if (XINT (CURSIZE (p->next)) - delta <= 0)
5776 {
5777 Fset_window_configuration (old_config);
5778 error ("Cannot adjust window size as specified");
5779 }
5780
5781 XSETINT (CURBEG (p->next),
5782 XINT (CURBEG (p->next)) + delta);
5783 size_window (p->next, XINT (CURSIZE (p->next)) - delta,
5784 horiz_flag, 0, 1, 0);
5785 break;
5786 }
5787 }
5788 else
5789 /* Here we have a chain of parallel siblings, in the other dimension.
5790 Change the size of the other siblings. */
5791 for (child = first_parallel;
5792 ! NILP (child);
5793 child = XWINDOW (child)->next)
5794 if (! EQ (child, window))
5795 size_window (child, XINT (CURSIZE (child)) + delta,
5796 horiz_flag, 0, 0, 1);
5797
5798 window = parent;
5799 }
5800
5801 /* If we made a window so small it got deleted,
5802 we failed. Report failure. */
5803 if (delcount != window_deletion_count)
5804 {
5805 Fset_window_configuration (old_config);
5806 error ("Cannot adjust window size as specified");
5807 }
5808
5809 /* Adjust glyph matrices. */
5810 adjust_glyphs (XFRAME (WINDOW_FRAME (XWINDOW (window))));
5811}
5812
5813#undef CURBEG
5814#undef CURSIZE
5815
5816DEFUN ("adjust-window-trailing-edge", Fadjust_window_trailing_edge,
5817 Sadjust_window_trailing_edge, 3, 3, 0,
5818 doc: /* Adjust the bottom or right edge of WINDOW by DELTA.
5819If HORIZONTAL is non-nil, that means adjust the width, moving the right edge.
5820Otherwise, adjust the height, moving the bottom edge.
5821
5822Following siblings of the selected window are resized to fulfill
5823the size request. If they become too small in the process, they
5824are not deleted; instead, we signal an error. */)
5825 (Lisp_Object window, Lisp_Object delta, Lisp_Object horizontal)
5826{
5827 CHECK_NUMBER (delta);
5828 if (NILP (window))
5829 window = selected_window;
5830 adjust_window_trailing_edge (window, XINT (delta), !NILP (horizontal));
5831
5832 run_window_configuration_change_hook
5833 (XFRAME (WINDOW_FRAME (XWINDOW (window))));
5834
5835 return Qnil;
5836}
5837
5838
5839
5840/***********************************************************************
5841 Resizing Mini-Windows
5842 ***********************************************************************/
5843
5844static void shrink_window_lowest_first (struct window *, int);
5845
5846enum save_restore_action
5847{
5848 CHECK_ORIG_SIZES,
5849 SAVE_ORIG_SIZES,
5850 RESTORE_ORIG_SIZES
5851};
5852
5853static int save_restore_orig_size (struct window *,
5854 enum save_restore_action);
5855
5856/* Shrink windows rooted in window W to HEIGHT. Take the space needed
5857 from lowest windows first. */
5858
5859static void
5860shrink_window_lowest_first (struct window *w, int height)
5861{
5862 struct window *c;
5863 Lisp_Object child;
5864 int old_height;
5865
5866 xassert (!MINI_WINDOW_P (w));
5867
5868 /* Set redisplay hints. */
5869 XSETFASTINT (w->last_modified, 0);
5870 XSETFASTINT (w->last_overlay_modified, 0);
5871 windows_or_buffers_changed++;
5872 FRAME_WINDOW_SIZES_CHANGED (XFRAME (WINDOW_FRAME (w))) = 1;
5873
5874 old_height = XFASTINT (w->total_lines);
5875 XSETFASTINT (w->total_lines, height);
5876
5877 if (!NILP (w->hchild))
5878 {
5879 for (child = w->hchild; !NILP (child); child = c->next)
5880 {
5881 c = XWINDOW (child);
5882 c->top_line = w->top_line;
5883 shrink_window_lowest_first (c, height);
5884 }
5885 }
5886 else if (!NILP (w->vchild))
5887 {
5888 Lisp_Object last_child;
5889 int delta = old_height - height;
5890 int last_top;
5891
5892 last_child = Qnil;
5893
5894 /* Find the last child. We are taking space from lowest windows
5895 first, so we iterate over children from the last child
5896 backwards. */
5897 for (child = w->vchild; WINDOWP (child); child = XWINDOW (child)->next)
5898 last_child = child;
5899
5900 /* Size children down to their safe heights. */
5901 for (child = last_child; delta && !NILP (child); child = c->prev)
5902 {
5903 int this_one;
5904
5905 c = XWINDOW (child);
5906 this_one = XFASTINT (c->total_lines) - window_min_size_1 (c, 0, 1);
5907
5908 if (this_one > delta)
5909 this_one = delta;
5910
5911 shrink_window_lowest_first (c, XFASTINT (c->total_lines) - this_one);
5912 delta -= this_one;
5913 }
5914
5915 /* Compute new positions. */
5916 last_top = XINT (w->top_line);
5917 for (child = w->vchild; !NILP (child); child = c->next)
5918 {
5919 c = XWINDOW (child);
5920 c->top_line = make_number (last_top);
5921 shrink_window_lowest_first (c, XFASTINT (c->total_lines));
5922 last_top += XFASTINT (c->total_lines);
5923 }
5924 }
5925}
5926
5927
5928/* Save, restore, or check positions and sizes in the window tree
5929 rooted at W. ACTION says what to do.
5930
5931 If ACTION is CHECK_ORIG_SIZES, check if orig_top_line and
5932 orig_total_lines members are valid for all windows in the window
5933 tree. Value is non-zero if they are valid.
5934
5935 If ACTION is SAVE_ORIG_SIZES, save members top and height in
5936 orig_top_line and orig_total_lines for all windows in the tree.
5937
5938 If ACTION is RESTORE_ORIG_SIZES, restore top and height from values
5939 stored in orig_top_line and orig_total_lines for all windows. */
5940
5941static int
5942save_restore_orig_size (struct window *w, enum save_restore_action action)
5943{
5944 int success_p = 1;
5945
5946 while (w)
5947 {
5948 if (!NILP (w->hchild))
5949 {
5950 if (!save_restore_orig_size (XWINDOW (w->hchild), action))
5951 success_p = 0;
5952 }
5953 else if (!NILP (w->vchild))
5954 {
5955 if (!save_restore_orig_size (XWINDOW (w->vchild), action))
5956 success_p = 0;
5957 }
5958
5959 switch (action)
5960 {
5961 case CHECK_ORIG_SIZES:
5962 if (!INTEGERP (w->orig_top_line) || !INTEGERP (w->orig_total_lines))
5963 return 0;
5964 break;
5965
5966 case SAVE_ORIG_SIZES:
5967 w->orig_top_line = w->top_line;
5968 w->orig_total_lines = w->total_lines;
5969 XSETFASTINT (w->last_modified, 0);
5970 XSETFASTINT (w->last_overlay_modified, 0);
5971 break;
5972
5973 case RESTORE_ORIG_SIZES:
5974 xassert (INTEGERP (w->orig_top_line) && INTEGERP (w->orig_total_lines));
5975 w->top_line = w->orig_top_line;
5976 w->total_lines = w->orig_total_lines;
5977 w->orig_total_lines = w->orig_top_line = Qnil;
5978 XSETFASTINT (w->last_modified, 0);
5979 XSETFASTINT (w->last_overlay_modified, 0);
5980 break;
5981
5982 default:
5983 abort ();
5984 }
5985
5986 w = NILP (w->next) ? NULL : XWINDOW (w->next);
5987 }
5988
5989 return success_p;
5990}
5991
5992
5993/* Grow mini-window W by DELTA lines, DELTA >= 0, or as much as we can
5994 without deleting other windows. */
5995
5996void
5997grow_mini_window (struct window *w, int delta)
5998{
5999 struct frame *f = XFRAME (w->frame);
6000 struct window *root;
6001
6002 xassert (MINI_WINDOW_P (w));
6003 /* Commenting out the following assertion goes against the stated interface
6004 of the function, but it currently does not seem to do anything useful.
6005 See discussion of this issue in the thread for bug#4534.
6006 xassert (delta >= 0); */
6007
6008 /* Compute how much we can enlarge the mini-window without deleting
6009 other windows. */
6010 root = XWINDOW (FRAME_ROOT_WINDOW (f));
6011 if (delta > 0)
6012 {
6013 int min_height = window_min_size (root, 0, 0, 0, 0);
6014 if (XFASTINT (root->total_lines) - delta < min_height)
6015 /* Note that the root window may already be smaller than
6016 min_height. */
6017 delta = max (0, XFASTINT (root->total_lines) - min_height);
6018 }
6019
6020 if (delta)
6021 {
6022 /* Save original window sizes and positions, if not already done. */
6023 if (!save_restore_orig_size (root, CHECK_ORIG_SIZES))
6024 save_restore_orig_size (root, SAVE_ORIG_SIZES);
6025
6026 /* Shrink other windows. */
6027 shrink_window_lowest_first (root, XFASTINT (root->total_lines) - delta);
6028
6029 /* Grow the mini-window. */
6030 w->top_line = make_number (XFASTINT (root->top_line) + XFASTINT (root->total_lines));
6031 w->total_lines = make_number (XFASTINT (w->total_lines) + delta);
6032 XSETFASTINT (w->last_modified, 0);
6033 XSETFASTINT (w->last_overlay_modified, 0);
6034
6035 adjust_glyphs (f);
6036 }
6037}
6038
6039
6040/* Shrink mini-window W. If there is recorded info about window sizes
6041 before a call to grow_mini_window, restore recorded window sizes.
6042 Otherwise, if the mini-window is higher than 1 line, resize it to 1
6043 line. */
6044
6045void
6046shrink_mini_window (struct window *w)
6047{
6048 struct frame *f = XFRAME (w->frame);
6049 struct window *root = XWINDOW (FRAME_ROOT_WINDOW (f));
6050
6051 if (save_restore_orig_size (root, CHECK_ORIG_SIZES))
6052 {
6053 save_restore_orig_size (root, RESTORE_ORIG_SIZES);
6054 adjust_glyphs (f);
6055 FRAME_WINDOW_SIZES_CHANGED (f) = 1;
6056 windows_or_buffers_changed = 1;
6057 }
6058 else if (XFASTINT (w->total_lines) > 1)
6059 {
6060 /* Distribute the additional lines of the mini-window
6061 among the other windows. */
6062 Lisp_Object window;
6063 XSETWINDOW (window, w);
6064 enlarge_window (window, 1 - XFASTINT (w->total_lines), 0);
6065 }
6066}
6067
6068
6069 4293
6070/* Mark window cursors off for all windows in the window tree rooted 4294/* Mark window cursors off for all windows in the window tree rooted
6071 at W by setting their phys_cursor_on_p flag to zero. Called from 4295 at W by setting their phys_cursor_on_p flag to zero. Called from
@@ -7252,11 +5476,9 @@ struct saved_window
7252 Lisp_Object parent, prev; 5476 Lisp_Object parent, prev;
7253 Lisp_Object start_at_line_beg; 5477 Lisp_Object start_at_line_beg;
7254 Lisp_Object display_table; 5478 Lisp_Object display_table;
7255 Lisp_Object orig_top_line, orig_total_lines;
7256 Lisp_Object left_margin_cols, right_margin_cols; 5479 Lisp_Object left_margin_cols, right_margin_cols;
7257 Lisp_Object left_fringe_width, right_fringe_width, fringes_outside_margins; 5480 Lisp_Object left_fringe_width, right_fringe_width, fringes_outside_margins;
7258 Lisp_Object scroll_bar_width, vertical_scroll_bar_type; 5481 Lisp_Object scroll_bar_width, vertical_scroll_bar_type, dedicated;
7259 Lisp_Object dedicated, resize_proportionally;
7260 Lisp_Object splits, nest, window_parameters; 5482 Lisp_Object splits, nest, window_parameters;
7261}; 5483};
7262 5484
@@ -7476,8 +5698,6 @@ the return value is nil. Otherwise the value is t. */)
7476 w->hscroll = p->hscroll; 5698 w->hscroll = p->hscroll;
7477 w->min_hscroll = p->min_hscroll; 5699 w->min_hscroll = p->min_hscroll;
7478 w->display_table = p->display_table; 5700 w->display_table = p->display_table;
7479 w->orig_top_line = p->orig_top_line;
7480 w->orig_total_lines = p->orig_total_lines;
7481 w->left_margin_cols = p->left_margin_cols; 5701 w->left_margin_cols = p->left_margin_cols;
7482 w->right_margin_cols = p->right_margin_cols; 5702 w->right_margin_cols = p->right_margin_cols;
7483 w->left_fringe_width = p->left_fringe_width; 5703 w->left_fringe_width = p->left_fringe_width;
@@ -7489,7 +5709,6 @@ the return value is nil. Otherwise the value is t. */)
7489 w->splits = p->splits; 5709 w->splits = p->splits;
7490 w->nest = p->nest; 5710 w->nest = p->nest;
7491 w->window_parameters = p->window_parameters; 5711 w->window_parameters = p->window_parameters;
7492 w->resize_proportionally = p->resize_proportionally;
7493 XSETFASTINT (w->last_modified, 0); 5712 XSETFASTINT (w->last_modified, 0);
7494 XSETFASTINT (w->last_overlay_modified, 0); 5713 XSETFASTINT (w->last_overlay_modified, 0);
7495 5714
@@ -7618,6 +5837,7 @@ the return value is nil. Otherwise the value is t. */)
7618 return (FRAME_LIVE_P (f) ? Qt : Qnil); 5837 return (FRAME_LIVE_P (f) ? Qt : Qnil);
7619} 5838}
7620 5839
5840
7621/* Delete all subwindows reachable via the next, vchild, and hchild 5841/* Delete all subwindows reachable via the next, vchild, and hchild
7622 slots of WINDOW. */ 5842 slots of WINDOW. */
7623void 5843void
@@ -7670,7 +5890,6 @@ count_windows (register struct window *window)
7670 5890
7671/* Fill vector FLAT with leaf windows under W, starting at index I. 5891/* Fill vector FLAT with leaf windows under W, starting at index I.
7672 Value is last index + 1. */ 5892 Value is last index + 1. */
7673
7674static int 5893static int
7675get_leaf_windows (struct window *w, struct window **flat, int i) 5894get_leaf_windows (struct window *w, struct window **flat, int i)
7676{ 5895{
@@ -7693,7 +5912,6 @@ get_leaf_windows (struct window *w, struct window **flat, int i)
7693/* Return a pointer to the glyph W's physical cursor is on. Value is 5912/* Return a pointer to the glyph W's physical cursor is on. Value is
7694 null if W's current matrix is invalid, so that no meaningfull glyph 5913 null if W's current matrix is invalid, so that no meaningfull glyph
7695 can be returned. */ 5914 can be returned. */
7696
7697struct glyph * 5915struct glyph *
7698get_phys_cursor_glyph (struct window *w) 5916get_phys_cursor_glyph (struct window *w)
7699{ 5917{
@@ -7738,8 +5956,6 @@ save_window_save (Lisp_Object window, struct Lisp_Vector *vector, int i)
7738 p->hscroll = w->hscroll; 5956 p->hscroll = w->hscroll;
7739 p->min_hscroll = w->min_hscroll; 5957 p->min_hscroll = w->min_hscroll;
7740 p->display_table = w->display_table; 5958 p->display_table = w->display_table;
7741 p->orig_top_line = w->orig_top_line;
7742 p->orig_total_lines = w->orig_total_lines;
7743 p->left_margin_cols = w->left_margin_cols; 5959 p->left_margin_cols = w->left_margin_cols;
7744 p->right_margin_cols = w->right_margin_cols; 5960 p->right_margin_cols = w->right_margin_cols;
7745 p->left_fringe_width = w->left_fringe_width; 5961 p->left_fringe_width = w->left_fringe_width;
@@ -7750,7 +5966,6 @@ save_window_save (Lisp_Object window, struct Lisp_Vector *vector, int i)
7750 p->dedicated = w->dedicated; 5966 p->dedicated = w->dedicated;
7751 p->splits = w->splits; 5967 p->splits = w->splits;
7752 p->nest = w->nest; 5968 p->nest = w->nest;
7753 p->resize_proportionally = w->resize_proportionally;
7754 p->window_parameters = w->window_parameters; 5969 p->window_parameters = w->window_parameters;
7755 if (!NILP (w->buffer)) 5970 if (!NILP (w->buffer))
7756 { 5971 {
@@ -8444,10 +6659,6 @@ syms_of_window (void)
8444 Fput (Qscroll_up, Qscroll_command, Qt); 6659 Fput (Qscroll_up, Qscroll_command, Qt);
8445 Fput (Qscroll_down, Qscroll_command, Qt); 6660 Fput (Qscroll_down, Qscroll_command, Qt);
8446 6661
8447 Qwindow_size_fixed = intern_c_string ("window-size-fixed");
8448 staticpro (&Qwindow_size_fixed);
8449 Fset (Qwindow_size_fixed, Qnil);
8450
8451 staticpro (&Qwindow_configuration_change_hook); 6662 staticpro (&Qwindow_configuration_change_hook);
8452 Qwindow_configuration_change_hook 6663 Qwindow_configuration_change_hook
8453 = intern_c_string ("window-configuration-change-hook"); 6664 = intern_c_string ("window-configuration-change-hook");
@@ -8540,24 +6751,6 @@ is displayed in the `mode-line' face. */);
8540 doc: /* *Number of lines of continuity when scrolling by screenfuls. */); 6751 doc: /* *Number of lines of continuity when scrolling by screenfuls. */);
8541 next_screen_context_lines = 2; 6752 next_screen_context_lines = 2;
8542 6753
8543 DEFVAR_INT ("window-min-height", window_min_height,
8544 doc: /* Allow deleting windows less than this tall.
8545The value is measured in line units. If a window wants a modeline it
8546is counted as one line.
8547
8548Emacs honors settings of this variable when enlarging or shrinking
8549windows vertically. A value less than 1 is invalid. */);
8550 window_min_height = 4;
8551
8552 DEFVAR_INT ("window-min-width", window_min_width,
8553 doc: /* Allow deleting windows less than this wide.
8554The value is measured in characters and includes any fringes or
8555the scrollbar.
8556
8557Emacs honors settings of this variable when enlarging or shrinking
8558windows horizontally. A value less than 2 is invalid. */);
8559 window_min_width = 10;
8560
8561 DEFVAR_LISP ("scroll-preserve-screen-position", 6754 DEFVAR_LISP ("scroll-preserve-screen-position",
8562 Vscroll_preserve_screen_position, 6755 Vscroll_preserve_screen_position,
8563 doc: /* *Controls if scroll commands move point to keep its screen position unchanged. 6756 doc: /* *Controls if scroll commands move point to keep its screen position unchanged.
@@ -8684,10 +6877,8 @@ function `window-nest' and altered by the function `set-window-nest'. */);
8684 defsubr (&Sprevious_window); 6877 defsubr (&Sprevious_window);
8685 defsubr (&Sother_window); 6878 defsubr (&Sother_window);
8686 defsubr (&Sget_buffer_window); 6879 defsubr (&Sget_buffer_window);
8687 defsubr (&Sdelete_other_windows);
8688 defsubr (&Sdelete_windows_on); 6880 defsubr (&Sdelete_windows_on);
8689 defsubr (&Sreplace_buffer_in_windows); 6881 defsubr (&Sreplace_buffer_in_windows);
8690 defsubr (&Sdelete_window);
8691 defsubr (&Sdelete_other_windows_internal); 6882 defsubr (&Sdelete_other_windows_internal);
8692 defsubr (&Sdelete_window_internal); 6883 defsubr (&Sdelete_window_internal);
8693 defsubr (&Sresize_mini_window_internal); 6884 defsubr (&Sresize_mini_window_internal);
@@ -8697,11 +6888,7 @@ function `window-nest' and altered by the function `set-window-nest'. */);
8697 defsubr (&Sselect_window); 6888 defsubr (&Sselect_window);
8698 defsubr (&Sforce_window_update); 6889 defsubr (&Sforce_window_update);
8699 defsubr (&Stemp_output_buffer_show); 6890 defsubr (&Stemp_output_buffer_show);
8700 defsubr (&Ssplit_window);
8701 defsubr (&Ssplit_window_internal); 6891 defsubr (&Ssplit_window_internal);
8702 defsubr (&Senlarge_window);
8703 defsubr (&Sshrink_window);
8704 defsubr (&Sadjust_window_trailing_edge);
8705 defsubr (&Sscroll_up); 6892 defsubr (&Sscroll_up);
8706 defsubr (&Sscroll_down); 6893 defsubr (&Sscroll_down);
8707 defsubr (&Sscroll_left); 6894 defsubr (&Sscroll_left);
@@ -8740,11 +6927,7 @@ function `window-nest' and altered by the function `set-window-nest'. */);
8740void 6927void
8741keys_of_window (void) 6928keys_of_window (void)
8742{ 6929{
8743 initial_define_key (control_x_map, '1', "delete-other-windows");
8744 initial_define_key (control_x_map, '2', "split-window");
8745 initial_define_key (control_x_map, '0', "delete-window");
8746 initial_define_key (control_x_map, 'o', "other-window"); 6930 initial_define_key (control_x_map, 'o', "other-window");
8747 initial_define_key (control_x_map, '^', "enlarge-window");
8748 initial_define_key (control_x_map, '<', "scroll-left"); 6931 initial_define_key (control_x_map, '<', "scroll-left");
8749 initial_define_key (control_x_map, '>', "scroll-right"); 6932 initial_define_key (control_x_map, '>', "scroll-right");
8750 6933
diff --git a/src/xdisp.c b/src/xdisp.c
index 02467c7bedd..65f6ddd3889 100644
--- a/src/xdisp.c
+++ b/src/xdisp.c
@@ -27115,31 +27115,27 @@ Its value should be an ASCII acronym string, `hex-code', `empty-box', or
27115void 27115void
27116init_xdisp (void) 27116init_xdisp (void)
27117{ 27117{
27118 Lisp_Object root_window;
27119 struct window *mini_w;
27120
27121 current_header_line_height = current_mode_line_height = -1; 27118 current_header_line_height = current_mode_line_height = -1;
27122 27119
27123 CHARPOS (this_line_start_pos) = 0; 27120 CHARPOS (this_line_start_pos) = 0;
27124 27121
27125 mini_w = XWINDOW (minibuf_window);
27126 root_window = FRAME_ROOT_WINDOW (XFRAME (WINDOW_FRAME (mini_w)));
27127 echo_area_window = minibuf_window;
27128
27129 if (!noninteractive) 27122 if (!noninteractive)
27130 { 27123 {
27131 struct frame *f = XFRAME (WINDOW_FRAME (XWINDOW (root_window))); 27124 struct window *m = XWINDOW (minibuf_window);
27125 Lisp_Object frame = m->frame;
27126 struct frame *f = XFRAME (frame);
27127 Lisp_Object root = FRAME_ROOT_WINDOW (f);
27128 struct window *r = XWINDOW (root);
27132 int i; 27129 int i;
27133 27130
27134 XWINDOW (root_window)->top_line = make_number (FRAME_TOP_MARGIN (f)); 27131 echo_area_window = minibuf_window;
27135 set_window_height (root_window,
27136 FRAME_LINES (f) - 1 - FRAME_TOP_MARGIN (f),
27137 0);
27138 mini_w->top_line = make_number (FRAME_LINES (f) - 1);
27139 set_window_height (minibuf_window, 1, 0);
27140 27132
27141 XWINDOW (root_window)->total_cols = make_number (FRAME_COLS (f)); 27133 XSETFASTINT (r->top_line, FRAME_TOP_MARGIN (f));
27142 mini_w->total_cols = make_number (FRAME_COLS (f)); 27134 XSETFASTINT (r->total_lines, FRAME_LINES (f) - 1 - FRAME_TOP_MARGIN (f));
27135 XSETFASTINT (r->total_cols, FRAME_COLS (f));
27136 XSETFASTINT (m->top_line, FRAME_LINES (f) - 1);
27137 XSETFASTINT (m->total_lines, 1);
27138 XSETFASTINT (m->total_cols, FRAME_COLS (f));
27143 27139
27144 scratch_glyph_row.glyphs[TEXT_AREA] = scratch_glyphs; 27140 scratch_glyph_row.glyphs[TEXT_AREA] = scratch_glyphs;
27145 scratch_glyph_row.glyphs[TEXT_AREA + 1] 27141 scratch_glyph_row.glyphs[TEXT_AREA + 1]
diff --git a/src/xfns.c b/src/xfns.c
index c307cc345e3..3d74ead330a 100644
--- a/src/xfns.c
+++ b/src/xfns.c
@@ -1227,7 +1227,7 @@ x_set_menu_bar_lines (struct frame *f, Lisp_Object value, Lisp_Object oldval)
1227 } 1227 }
1228#else /* not USE_X_TOOLKIT && not USE_GTK */ 1228#else /* not USE_X_TOOLKIT && not USE_GTK */
1229 FRAME_MENU_BAR_LINES (f) = nlines; 1229 FRAME_MENU_BAR_LINES (f) = nlines;
1230 change_window_heights (f->root_window, nlines - olines); 1230 resize_frame_windows (f, FRAME_LINES (f), 0);
1231 1231
1232 /* If the menu bar height gets changed, the internal border below 1232 /* If the menu bar height gets changed, the internal border below
1233 the top margin has to be cleared. Also, if the menu bar gets 1233 the top margin has to be cleared. Also, if the menu bar gets
@@ -1266,6 +1266,7 @@ x_set_menu_bar_lines (struct frame *f, Lisp_Object value, Lisp_Object oldval)
1266 } 1266 }
1267#endif /* not USE_X_TOOLKIT && not USE_GTK */ 1267#endif /* not USE_X_TOOLKIT && not USE_GTK */
1268 adjust_glyphs (f); 1268 adjust_glyphs (f);
1269 run_window_configuration_change_hook (f);
1269} 1270}
1270 1271
1271 1272
@@ -1326,7 +1327,7 @@ x_set_tool_bar_lines (struct frame *f, Lisp_Object value, Lisp_Object oldval)
1326 } 1327 }
1327 1328
1328 FRAME_TOOL_BAR_LINES (f) = nlines; 1329 FRAME_TOOL_BAR_LINES (f) = nlines;
1329 change_window_heights (root_window, delta); 1330 resize_frame_windows (f, FRAME_LINES (f), 0);
1330 adjust_glyphs (f); 1331 adjust_glyphs (f);
1331 1332
1332 /* We also have to make sure that the internal border at the top of 1333 /* We also have to make sure that the internal border at the top of
@@ -1362,6 +1363,9 @@ x_set_tool_bar_lines (struct frame *f, Lisp_Object value, Lisp_Object oldval)
1362 if (WINDOWP (f->tool_bar_window)) 1363 if (WINDOWP (f->tool_bar_window))
1363 clear_glyph_matrix (XWINDOW (f->tool_bar_window)->current_matrix); 1364 clear_glyph_matrix (XWINDOW (f->tool_bar_window)->current_matrix);
1364 } 1365 }
1366
1367 run_window_configuration_change_hook (f);
1368
1365} 1369}
1366 1370
1367 1371