aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorPaul Eggert2011-06-10 11:19:35 -0700
committerPaul Eggert2011-06-10 11:19:35 -0700
commite41e9a0e24877b0bc81e08df396f59115f8636da (patch)
treec0cf7e2838761b2c26047aeeac6415bb542bf5a0 /src
parent6a54b501af0633c909c96de867c805222fde970c (diff)
parent529a133c390049085db38e7c8f745d650a2626ee (diff)
downloademacs-e41e9a0e24877b0bc81e08df396f59115f8636da.tar.gz
emacs-e41e9a0e24877b0bc81e08df396f59115f8636da.zip
Merge from trunk.
Diffstat (limited to 'src')
-rw-r--r--src/ChangeLog109
-rw-r--r--src/buffer.c4
-rw-r--r--src/dispnew.c27
-rw-r--r--src/frame.c5
-rw-r--r--src/image.c2
-rw-r--r--src/w32fns.c7
-rw-r--r--src/window.c2850
-rw-r--r--src/window.h16
-rw-r--r--src/xdisp.c28
-rw-r--r--src/xfns.c8
10 files changed, 1210 insertions, 1846 deletions
diff --git a/src/ChangeLog b/src/ChangeLog
index 1222c04d091..fa9ed02614a 100644
--- a/src/ChangeLog
+++ b/src/ChangeLog
@@ -1,4 +1,4 @@
12011-06-09 Paul Eggert <eggert@cs.ucla.edu> 12011-06-10 Paul Eggert <eggert@cs.ucla.edu>
2 2
3 * xmenu.c (dialog_selection_callback) [!USE_GTK]: Cast to intptr_t, 3 * xmenu.c (dialog_selection_callback) [!USE_GTK]: Cast to intptr_t,
4 not to EMACS_INT, to avoid GCC warning. 4 not to EMACS_INT, to avoid GCC warning.
@@ -14,8 +14,6 @@
14 14
15 * data.c (Qcompiled_function): Now static. 15 * data.c (Qcompiled_function): Now static.
16 16
172011-06-08 Paul Eggert <eggert@cs.ucla.edu>
18
19 * window.c (window_body_lines): Now static. 17 * window.c (window_body_lines): Now static.
20 18
21 * image.c (gif_load): Rename local to avoid shadowing. 19 * image.c (gif_load): Rename local to avoid shadowing.
@@ -72,6 +70,111 @@
72 70
73 * alloc.c (Fmake_string): Check for out-of-range init. 71 * alloc.c (Fmake_string): Check for out-of-range init.
74 72
732011-06-10 Chong Yidong <cyd@stupidchicken.com>
74
75 * image.c (gif_load): Fix omitted cast error introduced by
76 2011-06-06 change.
77
782011-06-10 Martin Rudalics <rudalics@gmx.at>
79
80 * window.h (resize_proportionally, orig_total_lines)
81 (orig_top_line): Remove from window structure.
82 (set_window_height, set_window_width, change_window_heights)
83 (Fdelete_window): Remove prototypes.
84 (resize_frame_windows): Remove duplicate declaration.
85
862011-06-10 Eli Zaretskii <eliz@gnu.org>
87
88 * window.h (resize_frame_windows, resize_window_check)
89 (delete_deletable_window, resize_root_window)
90 (resize_frame_windows): Declare prototypes.
91
92 * window.c (resize_window_apply): Make definition be "static" to
93 match the prototype.
94
952011-06-10 Martin Rudalics <rudalics@gmx.at>
96
97 * window.c: Remove declarations of Qwindow_size_fixed,
98 window_min_size_1, window_min_size_2, window_min_size,
99 size_window, window_fixed_size_p, enlarge_window, delete_window.
100 Remove static from declaration of Qdelete_window, it's
101 temporarily needed by Fbury_buffer.
102 (replace_window): Don't assign orig_top_line and
103 orig_total_lines.
104 (Fdelete_window, delete_window): Remove. Window deletion is
105 handled by window.el.
106 (window_loop): Remove DELETE_OTHER_WINDOWS case. Replace
107 Fdelete_window calls with calls to Qdelete_window.
108 (Fdelete_other_windows): Remove. Deleting other windows is
109 handled by window.el.
110 (window_fixed_size_p): Remove. Fixed-sizeness of windows is
111 handled in window.el.
112 (window_min_size_2, window_min_size_1, window_min_size): Remove.
113 Window minimum sizes are handled in window.el.
114 (shrink_windows, size_window, set_window_height)
115 (set_window_width, change_window_heights, window_height)
116 (window_width, CURBEG, CURSIZE, enlarge_window)
117 (adjust_window_trailing_edge, Fadjust_window_trailing_edge)
118 (Fenlarge_window, Fshrink_window): Remove. Window resizing is
119 handled in window.el.
120 (make_dummy_parent): Rename to make_parent_window and give it a
121 second argument horflag.
122 (make_window): Don't set resize_proportionally any more.
123 (Fsplit_window): Remove. Windows are split in window.el.
124 (save_restore_action, save_restore_orig_size)
125 (shrink_window_lowest_first, save_restore_orig_size): Remove.
126 Resize mini windows in window.el.
127 (grow_mini_window, shrink_mini_window): Implement by calling
128 Qresize_root_window_vertically, resize_window_check and
129 resize_window_apply.
130 (saved_window, Fset_window_configuration, save_window_save): Do
131 not handle orig_top_line, orig_total_lines, and
132 resize_proportionally.
133 (window_min_height, window_min_width): Move to window.el.
134 (keys_of_window): Move bindings for delete-other-windows,
135 split-window, delete-window and enlarge-window to window.el.
136
137 * buffer.c: Temporarily extern Qdelete_window.
138 (Fbury_buffer): Temporarily call Qdelete_window instead of
139 Fdelete_window (Fbury_buffer will move to window.el soon).
140
141 * frame.c (set_menu_bar_lines_1): Remove code handling
142 orig_top_line and orig_total_lines.
143
144 * dispnew.c (adjust_frame_glyphs_initially): Don't use
145 set_window_height but set heights directly.
146 (change_frame_size_1): Use resize_frame_windows.
147
148 * xdisp.c (init_xdisp): Don't use set_window_height but set
149 heights directly.
150
151 * xfns.c (x_set_menu_bar_lines, x_set_tool_bar_lines): Use
152 resize_frame_windows instead of change_window_heights and run
153 run_window_configuration_change_hook.
154
155 * w32fns.c (x_set_tool_bar_lines): Use resize_frame_windows
156 instead of change_window_heights and run
157 run_window_configuration_change_hook.
158
1592011-06-09 Martin Rudalics <rudalics@gmx.at>
160
161 * window.c (replace_window): Rename second argument REPLACEMENT to
162 NEW. New third argument SETFLAG. Rewrite.
163 (delete_window, make_dummy_parent): Call replace_window with
164 third argument 1.
165 (window_list_1): Move down in code.
166 (run_window_configuration_change_hook): Move set_buffer part
167 before select_frame_norecord part in order to unwind correctly.
168 Rename count1 to count.
169 (recombine_windows, delete_deletable_window, resize_root_window)
170 (Fdelete_other_windows_internal)
171 (Frun_window_configuration_change_hook, make_parent_window)
172 (resize_window_check, resize_window_apply, Fresize_window_apply)
173 (resize_frame_windows, Fsplit_window_internal)
174 (Fdelete_window_internal, Fresize_mini_window_internal): New
175 functions.
176 (syms_of_window): New variables Vwindow_splits and Vwindow_nest.
177
752011-06-08 Martin Rudalics <rudalics@gmx.at> 1782011-06-08 Martin Rudalics <rudalics@gmx.at>
76 179
77 * window.h (window): Add some new members to window structure - 180 * window.h (window): Add some new members to window structure -
diff --git a/src/buffer.c b/src/buffer.c
index 8fdd094a20d..0c4cdb544a5 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/image.c b/src/image.c
index 31b3f01c17d..7d15a4725c5 100644
--- a/src/image.c
+++ b/src/image.c
@@ -7238,7 +7238,7 @@ gif_load (struct frame *f, struct image *img)
7238 /* From gif89a spec: 1 = "keep in place", 2 = "restore 7238 /* From gif89a spec: 1 = "keep in place", 2 = "restore
7239 to background". Treat any other value like 2. */ 7239 to background". Treat any other value like 2. */
7240 disposal = (extblock->Bytes[0] >> 2) & 7; 7240 disposal = (extblock->Bytes[0] >> 2) & 7;
7241 transparency_color_index = extblock->Bytes[3]; 7241 transparency_color_index = (unsigned char) extblock->Bytes[3];
7242 break; 7242 break;
7243 } 7243 }
7244 } 7244 }
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 493972c7545..31a25286bcc 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,
@@ -90,6 +82,7 @@ static int foreach_window_1 (struct window *,
90 int (* fn) (struct window *, void *), 82 int (* fn) (struct window *, void *),
91 void *); 83 void *);
92static Lisp_Object window_list_1 (Lisp_Object, Lisp_Object, Lisp_Object); 84static Lisp_Object window_list_1 (Lisp_Object, Lisp_Object, Lisp_Object);
85static void resize_window_apply (struct window *, int);
93static Lisp_Object select_window (Lisp_Object, Lisp_Object, int); 86static Lisp_Object select_window (Lisp_Object, Lisp_Object, int);
94 87
95/* This is the window in which the terminal's cursor should 88/* This is the window in which the terminal's cursor should
@@ -1802,9 +1795,7 @@ DEFUN ("set-window-display-table", Fset_window_display_table, Sset_window_displa
1802 return table; 1795 return table;
1803} 1796}
1804 1797
1805static void delete_window (Lisp_Object); 1798/* Record info on buffer window W is displaying
1806
1807/* Record info on buffer window w is displaying
1808 when it is about to cease to display that buffer. */ 1799 when it is about to cease to display that buffer. */
1809static void 1800static void
1810unshow_buffer (register struct window *w) 1801unshow_buffer (register struct window *w)
@@ -1853,285 +1844,144 @@ unshow_buffer (register struct window *w)
1853 BVAR (b, last_selected_window) = Qnil; 1844 BVAR (b, last_selected_window) = Qnil;
1854} 1845}
1855 1846
1856/* Put replacement into the window structure in place of old. */ 1847/* Put NEW into the window structure in place of OLD. SETFLAG zero
1848 means change window structure only. Otherwise store geometry and
1849 other settings as well. */
1857static void 1850static void
1858replace_window (Lisp_Object old, Lisp_Object replacement) 1851replace_window (Lisp_Object old, Lisp_Object new, int setflag)
1859{ 1852{
1860 register Lisp_Object tem; 1853 register Lisp_Object tem;
1861 register struct window *o = XWINDOW (old), *p = XWINDOW (replacement); 1854 register struct window *o = XWINDOW (old), *n = XWINDOW (new);
1862
1863 /* If OLD is its frame's root_window, then replacement is the new
1864 root_window for that frame. */
1865 1855
1856 /* If OLD is its frame's root window, then NEW is the new
1857 root window for that frame. */
1866 if (EQ (old, FRAME_ROOT_WINDOW (XFRAME (o->frame)))) 1858 if (EQ (old, FRAME_ROOT_WINDOW (XFRAME (o->frame))))
1867 FRAME_ROOT_WINDOW (XFRAME (o->frame)) = replacement; 1859 FRAME_ROOT_WINDOW (XFRAME (o->frame)) = new;
1868 1860
1869 p->left_col = o->left_col; 1861 if (setflag)
1870 p->top_line = o->top_line; 1862 {
1871 p->total_cols = o->total_cols; 1863 n->left_col = o->left_col;
1872 p->total_lines = o->total_lines; 1864 n->top_line = o->top_line;
1873 p->desired_matrix = p->current_matrix = 0; 1865 n->total_cols = o->total_cols;
1874 p->vscroll = 0; 1866 n->total_lines = o->total_lines;
1875 memset (&p->cursor, 0, sizeof (p->cursor)); 1867 n->normal_cols = o->normal_cols;
1876 memset (&p->last_cursor, 0, sizeof (p->last_cursor)); 1868 o->normal_cols = make_float (1.0);
1877 memset (&p->phys_cursor, 0, sizeof (p->phys_cursor)); 1869 n->normal_lines = o->normal_lines;
1878 p->phys_cursor_type = -1; 1870 o->normal_lines = make_float (1.0);
1879 p->phys_cursor_width = -1; 1871 n->desired_matrix = n->current_matrix = 0;
1880 p->must_be_updated_p = 0; 1872 n->vscroll = 0;
1881 p->pseudo_window_p = 0; 1873 memset (&n->cursor, 0, sizeof (n->cursor));
1882 XSETFASTINT (p->window_end_vpos, 0); 1874 memset (&n->last_cursor, 0, sizeof (n->last_cursor));
1883 XSETFASTINT (p->window_end_pos, 0); 1875 memset (&n->phys_cursor, 0, sizeof (n->phys_cursor));
1884 p->window_end_valid = Qnil; 1876 n->phys_cursor_type = -1;
1885 p->frozen_window_start_p = 0; 1877 n->phys_cursor_width = -1;
1886 p->orig_top_line = p->orig_total_lines = Qnil; 1878 n->must_be_updated_p = 0;
1887 1879 n->pseudo_window_p = 0;
1888 p->next = tem = o->next; 1880 XSETFASTINT (n->window_end_vpos, 0);
1881 XSETFASTINT (n->window_end_pos, 0);
1882 n->window_end_valid = Qnil;
1883 n->frozen_window_start_p = 0;
1884 }
1885
1886 n->next = tem = o->next;
1889 if (!NILP (tem)) 1887 if (!NILP (tem))
1890 XWINDOW (tem)->prev = replacement; 1888 XWINDOW (tem)->prev = new;
1891 1889
1892 p->prev = tem = o->prev; 1890 n->prev = tem = o->prev;
1893 if (!NILP (tem)) 1891 if (!NILP (tem))
1894 XWINDOW (tem)->next = replacement; 1892 XWINDOW (tem)->next = new;
1895 1893
1896 p->parent = tem = o->parent; 1894 n->parent = tem = o->parent;
1897 if (!NILP (tem)) 1895 if (!NILP (tem))
1898 { 1896 {
1899 if (EQ (XWINDOW (tem)->vchild, old)) 1897 if (EQ (XWINDOW (tem)->vchild, old))
1900 XWINDOW (tem)->vchild = replacement; 1898 XWINDOW (tem)->vchild = new;
1901 if (EQ (XWINDOW (tem)->hchild, old)) 1899 if (EQ (XWINDOW (tem)->hchild, old))
1902 XWINDOW (tem)->hchild = replacement; 1900 XWINDOW (tem)->hchild = new;
1903 } 1901 }
1904
1905/*** Here, if replacement is a vertical combination
1906and so is its new parent, we should make replacement's
1907children be children of that parent instead. ***/
1908} 1902}
1909 1903
1910DEFUN ("delete-window", Fdelete_window, Sdelete_window, 0, 1, "", 1904/* If window WINDOW and its parent window are iso-combined, merge
1911 doc: /* Remove WINDOW from its frame. 1905 WINDOW's children into those of its parent window and mark WINDOW as
1912WINDOW defaults to the selected window. Return nil. 1906 deleted. */
1913Signal an error when WINDOW is the only window on its frame. */)
1914 (register Lisp_Object window)
1915{
1916 struct frame *f;
1917 if (NILP (window))
1918 window = selected_window;
1919 else
1920 CHECK_LIVE_WINDOW (window);
1921
1922 f = XFRAME (WINDOW_FRAME (XWINDOW (window)));
1923 delete_window (window);
1924
1925 run_window_configuration_change_hook (f);
1926
1927 return Qnil;
1928}
1929 1907
1930static void 1908static void
1931delete_window (register Lisp_Object window) 1909recombine_windows (Lisp_Object window)
1932{ 1910{
1933 register Lisp_Object tem, parent, sib; 1911 struct window *w, *p, *c;
1934 register struct window *p; 1912 Lisp_Object parent, child;
1935 register struct window *par; 1913 int horflag;
1936 struct frame *f;
1937
1938 /* Because this function is called by other C code on non-leaf
1939 windows, the CHECK_LIVE_WINDOW macro would choke inappropriately,
1940 so we can't decode_window here. */
1941 CHECK_WINDOW (window);
1942 p = XWINDOW (window);
1943
1944 /* It's a no-op to delete an already-deleted window. */
1945 if (NILP (p->buffer)
1946 && NILP (p->hchild)
1947 && NILP (p->vchild))
1948 return;
1949
1950 parent = p->parent;
1951 if (NILP (parent))
1952 error ("Attempt to delete minibuffer or sole ordinary window");
1953 par = XWINDOW (parent);
1954
1955 windows_or_buffers_changed++;
1956 Vwindow_list = Qnil;
1957 f = XFRAME (WINDOW_FRAME (p));
1958 FRAME_WINDOW_SIZES_CHANGED (f) = 1;
1959
1960 /* Are we trying to delete any frame's selected window? */
1961 {
1962 Lisp_Object swindow, pwindow;
1963
1964 /* See if the frame's selected window is either WINDOW
1965 or any subwindow of it, by finding all that window's parents
1966 and comparing each one with WINDOW. */
1967 swindow = FRAME_SELECTED_WINDOW (f);
1968
1969 while (1)
1970 {
1971 pwindow = swindow;
1972 while (!NILP (pwindow))
1973 {
1974 if (EQ (window, pwindow))
1975 break;
1976 pwindow = XWINDOW (pwindow)->parent;
1977 }
1978
1979 /* If the window being deleted is not a parent of SWINDOW,
1980 then SWINDOW is ok as the new selected window. */
1981 if (!EQ (window, pwindow))
1982 break;
1983 /* Otherwise, try another window for SWINDOW. */
1984 swindow = Fnext_window (swindow, Qlambda, Qnil);
1985
1986 /* If we get back to the frame's selected window,
1987 it means there was no acceptable alternative,
1988 so we cannot delete. */
1989 if (EQ (swindow, FRAME_SELECTED_WINDOW (f)))
1990 error ("Cannot delete window");
1991 }
1992
1993 /* If we need to change SWINDOW, do it. */
1994 if (! EQ (swindow, FRAME_SELECTED_WINDOW (f)))
1995 {
1996 /* If we're about to delete the selected window on the
1997 selected frame, then we should use Fselect_window to select
1998 the new window. On the other hand, if we're about to
1999 delete the selected window on any other frame, we shouldn't do
2000 anything but set the frame's selected_window slot. */
2001 if (EQ (FRAME_SELECTED_WINDOW (f), selected_window))
2002 Fselect_window (swindow, Qnil);
2003 else
2004 FRAME_SELECTED_WINDOW (f) = swindow;
2005 }
2006 }
2007
2008 /* Now we know we can delete this one. */
2009 window_deletion_count++;
2010
2011 tem = p->buffer;
2012 /* tem is null for dummy parent windows
2013 (which have inferiors but not any contents themselves) */
2014 if (!NILP (tem))
2015 {
2016 unshow_buffer (p);
2017 unchain_marker (XMARKER (p->pointm));
2018 unchain_marker (XMARKER (p->start));
2019 }
2020
2021 /* Free window glyph matrices. It is sure that they are allocated
2022 again when ADJUST_GLYPHS is called. Block input so that expose
2023 events and other events that access glyph matrices are not
2024 processed while we are changing them. */
2025 BLOCK_INPUT;
2026 free_window_matrices (XWINDOW (FRAME_ROOT_WINDOW (f)));
2027
2028 tem = p->next;
2029 if (!NILP (tem))
2030 XWINDOW (tem)->prev = p->prev;
2031 1914
2032 tem = p->prev; 1915 w = XWINDOW (window);
2033 if (!NILP (tem)) 1916 parent = w->parent;
2034 XWINDOW (tem)->next = p->next; 1917 if (!NILP (parent) && NILP (w->nest))
2035 1918 {
2036 if (EQ (window, par->hchild)) 1919 p = XWINDOW (parent);
2037 par->hchild = p->next; 1920 if (((!NILP (p->vchild) && !NILP (w->vchild))
2038 if (EQ (window, par->vchild)) 1921 || (!NILP (p->hchild) && !NILP (w->hchild))))
2039 par->vchild = p->next; 1922 /* WINDOW and PARENT are both either a vertical or a horizontal
2040 1923 combination. */
2041 /* Find one of our siblings to give our space to. */ 1924 {
2042 sib = p->prev; 1925 horflag = NILP (w->vchild);
2043 if (NILP (sib)) 1926 child = horflag ? w->hchild : w->vchild;
2044 { 1927 c = XWINDOW (child);
2045 /* If p gives its space to its next sibling, that sibling needs
2046 to have its top/left side pulled back to where p's is.
2047 set_window_{height,width} will re-position the sibling's
2048 children. */
2049 sib = p->next;
2050 XWINDOW (sib)->top_line = p->top_line;
2051 XWINDOW (sib)->left_col = p->left_col;
2052 }
2053
2054 /* Stretch that sibling. */
2055 if (!NILP (par->vchild))
2056 set_window_height (sib,
2057 XFASTINT (XWINDOW (sib)->total_lines) + XFASTINT (p->total_lines),
2058 1);
2059 if (!NILP (par->hchild))
2060 set_window_width (sib,
2061 XFASTINT (XWINDOW (sib)->total_cols) + XFASTINT (p->total_cols),
2062 1);
2063
2064 /* If parent now has only one child,
2065 put the child into the parent's place. */
2066 tem = par->hchild;
2067 if (NILP (tem))
2068 tem = par->vchild;
2069 if (NILP (XWINDOW (tem)->next)) {
2070 replace_window (parent, tem);
2071 par = XWINDOW (tem);
2072 }
2073 1928
2074 /* Since we may be deleting combination windows, we must make sure that 1929 /* Splice WINDOW's children into its parent's children and
2075 not only p but all its children have been marked as deleted. */ 1930 assign new normal sizes. */
2076 if (! NILP (p->hchild)) 1931 if (NILP (w->prev))
2077 delete_all_subwindows (p->hchild); 1932 if (horflag)
2078 else if (! NILP (p->vchild)) 1933 p->hchild = child;
2079 delete_all_subwindows (p->vchild); 1934 else
1935 p->vchild = child;
1936 else
1937 {
1938 c->prev = w->prev;
1939 XWINDOW (w->prev)->next = child;
1940 }
2080 1941
2081 /* Mark this window as deleted. */ 1942 while (c)
2082 p->buffer = p->hchild = p->vchild = Qnil; 1943 {
1944 c->parent = parent;
2083 1945
2084 if (! NILP (par->parent)) 1946 if (horflag)
2085 par = XWINDOW (par->parent); 1947 c->normal_cols
1948 = make_float (XFLOATINT (c->total_cols)
1949 / XFLOATINT (p->total_cols));
1950 else
1951 c->normal_lines
1952 = make_float (XFLOATINT (c->total_lines)
1953 / XFLOATINT (p->total_lines));
2086 1954
2087 /* Check if we have a v/hchild with a v/hchild. In that case remove 1955 if (NILP (c->next))
2088 one of them. */ 1956 {
1957 if (!NILP (w->next))
1958 {
1959 c->next = w->next;
1960 XWINDOW (c->next)->prev = child;
1961 }
2089 1962
2090 if (! NILP (par->vchild) && ! NILP (XWINDOW (par->vchild)->vchild)) 1963 c = 0;
2091 { 1964 }
2092 p = XWINDOW (par->vchild); 1965 else
2093 par->vchild = p->vchild; 1966 {
2094 tem = p->vchild; 1967 child = c->next;
2095 } 1968 c = XWINDOW (child);
2096 else if (! NILP (par->hchild) && ! NILP (XWINDOW (par->hchild)->hchild)) 1969 }
2097 { 1970 }
2098 p = XWINDOW (par->hchild);
2099 par->hchild = p->hchild;
2100 tem = p->hchild;
2101 }
2102 else
2103 p = 0;
2104 1971
2105 if (p) 1972 /* WINDOW can be deleted now. */
2106 { 1973 w->vchild = w->hchild = Qnil;
2107 while (! NILP (tem)) { 1974 }
2108 XWINDOW (tem)->parent = p->parent;
2109 if (NILP (XWINDOW (tem)->next))
2110 break;
2111 tem = XWINDOW (tem)->next;
2112 }
2113 if (! NILP (tem)) {
2114 /* The next of the v/hchild we are removing is now the next of the
2115 last child for the v/hchild:
2116 Before v/hchild -> v/hchild -> next1 -> next2
2117 |
2118 -> next3
2119 After: v/hchild -> next1 -> next2 -> next3
2120 */
2121 XWINDOW (tem)->next = p->next;
2122 if (! NILP (p->next))
2123 XWINDOW (p->next)->prev = tem;
2124 }
2125 p->next = p->prev = p->vchild = p->hchild = p->buffer = Qnil;
2126 } 1975 }
2127
2128
2129 /* Adjust glyph matrices. */
2130 adjust_glyphs (f);
2131 UNBLOCK_INPUT;
2132} 1976}
2133 1977
2134 1978/* If WINDOW can be deleted, delete it. */
1979Lisp_Object
1980delete_deletable_window (Lisp_Object window)
1981{
1982 if (!NILP (call1 (Qwindow_deletable_p, window)))
1983 call1 (Qdelete_window, window);
1984}
2135 1985
2136/*********************************************************************** 1986/***********************************************************************
2137 Window List 1987 Window List
@@ -2427,43 +2277,6 @@ reverse order. */)
2427} 2277}
2428 2278
2429 2279
2430DEFUN ("window-list-1", Fwindow_list_1, Swindow_list_1, 0, 3, 0,
2431 doc: /* Return a list of all live windows.
2432WINDOW specifies the first window to list and defaults to the selected
2433window.
2434
2435Optional argument MINIBUF nil or omitted means consider the minibuffer
2436window only if the minibuffer is active. MINIBUF t means consider the
2437minibuffer window even if the minibuffer is not active. Any other value
2438means do not consider the minibuffer window even if the minibuffer is
2439active.
2440
2441Optional argument ALL-FRAMES nil or omitted means consider all windows
2442on WINDOW's frame, plus the minibuffer window if specified by the
2443MINIBUF argument. If the minibuffer counts, consider all windows on all
2444frames that share that minibuffer too. The following non-nil values of
2445ALL-FRAMES have special meanings:
2446
2447- t means consider all windows on all existing frames.
2448
2449- `visible' means consider all windows on all visible frames.
2450
2451- 0 (the number zero) means consider all windows on all visible and
2452 iconified frames.
2453
2454- A frame means consider all windows on that frame only.
2455
2456Anything else means consider all windows on WINDOW's frame and no
2457others.
2458
2459If WINDOW is not on the list of windows returned, some other window will
2460be listed first but no error is signalled. */)
2461 (Lisp_Object window, Lisp_Object minibuf, Lisp_Object all_frames)
2462{
2463 return window_list_1 (window, minibuf, all_frames);
2464}
2465
2466
2467DEFUN ("other-window", Fother_window, Sother_window, 1, 2, "p", 2280DEFUN ("other-window", Fother_window, Sother_window, 1, 2, "p",
2468 doc: /* Select another window in cyclic ordering of windows. 2281 doc: /* Select another window in cyclic ordering of windows.
2469COUNT specifies the number of windows to skip, starting with the 2282COUNT specifies the number of windows to skip, starting with the
@@ -2547,6 +2360,41 @@ MINIBUF neither nil nor t means never include the minibuffer window. */)
2547} 2360}
2548 2361
2549 2362
2363DEFUN ("window-list-1", Fwindow_list_1, Swindow_list_1, 0, 3, 0,
2364 doc: /* Return a list of all live windows.
2365WINDOW specifies the first window to list and defaults to the selected
2366window.
2367
2368Optional argument MINIBUF nil or omitted means consider the minibuffer
2369window only if the minibuffer is active. MINIBUF t means consider the
2370minibuffer window even if the minibuffer is not active. Any other value
2371means do not consider the minibuffer window even if the minibuffer is
2372active.
2373
2374Optional argument ALL-FRAMES nil or omitted means consider all windows
2375on WINDOW's frame, plus the minibuffer window if specified by the
2376MINIBUF argument. If the minibuffer counts, consider all windows on all
2377frames that share that minibuffer too. The following non-nil values of
2378ALL-FRAMES have special meanings:
2379
2380- t means consider all windows on all existing frames.
2381
2382- `visible' means consider all windows on all visible frames.
2383
2384- 0 (the number zero) means consider all windows on all visible and
2385 iconified frames.
2386
2387- A frame means consider all windows on that frame only.
2388
2389Anything else means consider all windows on WINDOW's frame and no
2390others.
2391
2392If WINDOW is not on the list of windows returned, some other window will
2393be listed first but no error is signalled. */)
2394 (Lisp_Object window, Lisp_Object minibuf, Lisp_Object all_frames)
2395{
2396 return window_list_1 (window, minibuf, all_frames);
2397}
2550 2398
2551/* Look at all windows, performing an operation specified by TYPE 2399/* Look at all windows, performing an operation specified by TYPE
2552 with argument OBJ. 2400 with argument OBJ.
@@ -2560,7 +2408,6 @@ enum window_loop
2560{ 2408{
2561 WINDOW_LOOP_UNUSED, 2409 WINDOW_LOOP_UNUSED,
2562 GET_BUFFER_WINDOW, /* Arg is buffer */ 2410 GET_BUFFER_WINDOW, /* Arg is buffer */
2563 DELETE_OTHER_WINDOWS, /* Arg is window not to delete */
2564 DELETE_BUFFER_WINDOWS, /* Arg is buffer */ 2411 DELETE_BUFFER_WINDOWS, /* Arg is buffer */
2565 UNSHOW_BUFFER, /* Arg is buffer */ 2412 UNSHOW_BUFFER, /* Arg is buffer */
2566 REDISPLAY_BUFFER_WINDOWS, /* Arg is buffer */ 2413 REDISPLAY_BUFFER_WINDOWS, /* Arg is buffer */
@@ -2644,11 +2491,6 @@ window_loop (enum window_loop type, Lisp_Object obj, int mini, Lisp_Object frame
2644 } 2491 }
2645 break; 2492 break;
2646 2493
2647 case DELETE_OTHER_WINDOWS:
2648 if (!EQ (window, obj))
2649 Fdelete_window (window);
2650 break;
2651
2652 case DELETE_BUFFER_WINDOWS: 2494 case DELETE_BUFFER_WINDOWS:
2653 if (EQ (w->buffer, obj)) 2495 if (EQ (w->buffer, obj))
2654 { 2496 {
@@ -2684,7 +2526,7 @@ window_loop (enum window_loop type, Lisp_Object obj, int mini, Lisp_Object frame
2684 Fset_buffer (w->buffer); 2526 Fset_buffer (w->buffer);
2685 } 2527 }
2686 else 2528 else
2687 Fdelete_window (window); 2529 call1 (Qdelete_window, window);
2688 } 2530 }
2689 break; 2531 break;
2690 2532
@@ -2719,7 +2561,7 @@ window_loop (enum window_loop type, Lisp_Object obj, int mini, Lisp_Object frame
2719 XSETWINDOW (window_to_delete, w); 2561 XSETWINDOW (window_to_delete, w);
2720 /* If this window is dedicated and not the only window 2562 /* If this window is dedicated and not the only window
2721 in its frame, then kill it. */ 2563 in its frame, then kill it. */
2722 Fdelete_window (window_to_delete); 2564 call1 (Qdelete_window, window_to_delete);
2723 } 2565 }
2724 else 2566 else
2725 { 2567 {
@@ -2801,68 +2643,248 @@ selected frame and no others. */)
2801 return Qnil; 2643 return Qnil;
2802} 2644}
2803 2645
2804DEFUN ("delete-other-windows", Fdelete_other_windows, Sdelete_other_windows, 2646Lisp_Object
2805 0, 1, "", 2647resize_root_window (Lisp_Object window, Lisp_Object delta, Lisp_Object horizontal, Lisp_Object ignore)
2806 doc: /* Make WINDOW (or the selected window) fill its frame. 2648{
2807Only the frame WINDOW is on is affected. 2649 return call4 (Qresize_root_window, window, delta, horizontal, ignore);
2808This function tries to reduce display jumps by keeping the text 2650}
2651
2652
2653DEFUN ("delete-other-windows-internal", Fdelete_other_windows_internal,
2654 Sdelete_other_windows_internal, 0, 2, "",
2655 doc: /* Make WINDOW fill its frame.
2656Only the frame WINDOW is on is affected. WINDOW may be any window and
2657defaults to the selected one.
2658
2659Optional argument ROOT, if non-nil, must specify an internal window
2660containing WINDOW as a subwindow. If this is the case, replace ROOT by
2661WINDOW and leave alone any windows not contained in ROOT.
2662
2663When WINDOW is live try to reduce display jumps by keeping the text
2809previously visible in WINDOW in the same place on the frame. Doing this 2664previously visible in WINDOW in the same place on the frame. Doing this
2810depends on the value of (window-start WINDOW), so if calling this 2665depends on the value of (window-start WINDOW), so if calling this
2811function in a program gives strange scrolling, make sure the 2666function in a program gives strange scrolling, make sure the
2812window-start value is reasonable when this function is called. */) 2667window-start value is reasonable when this function is called. */)
2813 (Lisp_Object window) 2668 (Lisp_Object window, Lisp_Object root)
2814{ 2669{
2815 struct window *w; 2670 struct window *w, *r, *s;
2671 struct frame *f;
2672 Lisp_Object sibling, pwindow, swindow, delta;
2816 EMACS_INT startpos; 2673 EMACS_INT startpos;
2817 int top, new_top; 2674 int top, new_top, resize_failed;
2818 2675
2819 if (NILP (window)) 2676 w = decode_any_window (window);
2820 window = selected_window; 2677 XSETWINDOW (window, w);
2821 else 2678 f = XFRAME (w->frame);
2822 CHECK_LIVE_WINDOW (window);
2823 w = XWINDOW (window);
2824 2679
2825 startpos = marker_position (w->start); 2680 if (NILP (root))
2826 top = WINDOW_TOP_EDGE_LINE (w) - FRAME_TOP_MARGIN (XFRAME (WINDOW_FRAME (w))); 2681 /* ROOT is the frame's root window. */
2682 {
2683 root = FRAME_ROOT_WINDOW (f);
2684 r = XWINDOW (root);
2685 }
2686 else
2687 /* ROOT must be an ancestor of WINDOW. */
2688 {
2689 r = decode_any_window (root);
2690 pwindow = XWINDOW (window)->parent;
2691 while (!NILP (pwindow))
2692 if (EQ (pwindow, root))
2693 break;
2694 else
2695 pwindow = XWINDOW (pwindow)->parent;
2696 if (!EQ (pwindow, root))
2697 error ("Specified root is not an ancestor of specified window");
2698 }
2827 2699
2828 if (MINI_WINDOW_P (w) && top > 0) 2700 if (EQ (window, root))
2701 /* A noop. */
2702 return Qnil;
2703 /* I don't understand the "top > 0" part below. If we deal with a
2704 standalone minibuffer it would have been caught by the preceding
2705 test. */
2706 else if (MINI_WINDOW_P (w)) /* && top > 0) */
2829 error ("Can't expand minibuffer to full frame"); 2707 error ("Can't expand minibuffer to full frame");
2830 2708
2831 window_loop (DELETE_OTHER_WINDOWS, window, 0, WINDOW_FRAME (w)); 2709 if (!NILP (w->buffer))
2710 {
2711 startpos = marker_position (w->start);
2712 top = WINDOW_TOP_EDGE_LINE (w)
2713 - FRAME_TOP_MARGIN (XFRAME (WINDOW_FRAME (w)));
2714 /* Make sure WINDOW is the frame's selected window. */
2715 if (!EQ (window, FRAME_SELECTED_WINDOW (f)))
2716 {
2717 if (EQ (selected_frame, w->frame))
2718 Fselect_window (window, Qnil);
2719 else
2720 FRAME_SELECTED_WINDOW (f) = window;
2721 }
2722 }
2723 else
2724 {
2725 /* See if the frame's selected window is a subwindow of WINDOW, by
2726 finding all the selected window's parents and comparing each
2727 one with WINDOW. If it isn't we need a new selected window for
2728 this frame. */
2729 swindow = FRAME_SELECTED_WINDOW (f);
2730 while (1)
2731 {
2732 pwindow = swindow;
2733 while (!NILP (pwindow) && !EQ (window, pwindow))
2734 pwindow = XWINDOW (pwindow)->parent;
2735
2736 if (EQ (window, pwindow))
2737 /* If WINDOW is an ancestor of SWINDOW, then SWINDOW is ok
2738 as the new selected window. */
2739 break;
2740 else
2741 /* Else try the previous window of SWINDOW. */
2742 swindow = Fprevious_window (swindow, Qlambda, Qnil);
2743 }
2832 2744
2833 /* Try to minimize scrolling, by setting the window start to the point 2745 if (!EQ (swindow, FRAME_SELECTED_WINDOW (f)))
2834 will cause the text at the old window start to be at the same place 2746 {
2835 on the frame. But don't try to do this if the window start is 2747 if (EQ (selected_frame, w->frame))
2836 outside the visible portion (as might happen when the display is 2748 Fselect_window (swindow, Qnil);
2837 not current, due to typeahead). */ 2749 else
2838 new_top = WINDOW_TOP_EDGE_LINE (w) - FRAME_TOP_MARGIN (XFRAME (WINDOW_FRAME (w))); 2750 FRAME_SELECTED_WINDOW (f) = swindow;
2839 if (new_top != top 2751 }
2840 && startpos >= BUF_BEGV (XBUFFER (w->buffer)) 2752 }
2841 && startpos <= BUF_ZV (XBUFFER (w->buffer))) 2753
2754 BLOCK_INPUT;
2755 free_window_matrices (r);
2756
2757 windows_or_buffers_changed++;
2758 Vwindow_list = Qnil;
2759 FRAME_WINDOW_SIZES_CHANGED (f) = 1;
2760
2761 if (NILP (w->buffer))
2842 { 2762 {
2843 struct position pos; 2763 resize_failed = 0;
2844 struct buffer *obuf = current_buffer; 2764 /* Resize subwindows vertically. */
2765 XSETINT (delta, XINT (r->total_lines) - XINT (w->total_lines));
2766 w->top_line = r->top_line;
2767 resize_root_window (window, delta, Qnil, Qnil);
2768 if (resize_window_check (w, 0))
2769 resize_window_apply (w, 0);
2770 else
2771 {
2772 resize_root_window (window, delta, Qnil, Qt);
2773 if (resize_window_check (w, 0))
2774 resize_window_apply (w, 0);
2775 else
2776 resize_failed = 1;
2777 }
2845 2778
2846 Fset_buffer (w->buffer); 2779 /* Resize subwindows horizontally. */
2847 /* This computation used to temporarily move point, but that can 2780 if (!resize_failed)
2848 have unwanted side effects due to text properties. */ 2781 {
2849 pos = *vmotion (startpos, -top, w); 2782 w->left_col = r->left_col;
2783 XSETINT (delta, XINT (r->total_cols) - XINT (w->total_cols));
2784 w->left_col = r->left_col;
2785 resize_root_window (window, delta, Qt, Qnil);
2786 if (resize_window_check (w, 1))
2787 resize_window_apply (w, 1);
2788 else
2789 {
2790 resize_root_window (window, delta, Qt, Qt);
2791 if (resize_window_check (w, 1))
2792 resize_window_apply (w, 1);
2793 else
2794 resize_failed = 1;
2795 }
2796 }
2850 2797
2851 set_marker_both (w->start, w->buffer, pos.bufpos, pos.bytepos); 2798 if (resize_failed)
2852 w->window_end_valid = Qnil; 2799 /* Play safe, if we still can ... */
2853 w->start_at_line_beg = ((pos.bytepos == BEGV_BYTE 2800 {
2854 || FETCH_BYTE (pos.bytepos - 1) == '\n') ? Qt 2801 window = swindow;
2855 : Qnil); 2802 w = XWINDOW (window);
2856 /* We need to do this, so that the window-scroll-functions 2803 }
2857 get called. */ 2804 }
2858 w->optional_new_start = Qt;
2859 2805
2860 set_buffer_internal (obuf); 2806 /* Cleanly unlink WINDOW from window-tree. */
2807 if (!NILP (w->prev))
2808 /* Get SIBLING above (on the left of) WINDOW. */
2809 {
2810 sibling = w->prev;
2811 s = XWINDOW (sibling);
2812 s->next = w->next;
2813 if (!NILP (s->next))
2814 XWINDOW (s->next)->prev = sibling;
2815 }
2816 else
2817 /* Get SIBLING below (on the right of) WINDOW. */
2818 {
2819 sibling = w->next;
2820 s = XWINDOW (sibling);
2821 s->prev = Qnil;
2822 if (!NILP (XWINDOW (w->parent)->vchild))
2823 XWINDOW (w->parent)->vchild = sibling;
2824 else
2825 XWINDOW (w->parent)->hchild = sibling;
2826 }
2827
2828 /* Delete ROOT and all subwindows of ROOT. */
2829 if (!NILP (r->vchild))
2830 {
2831 delete_all_subwindows (r->vchild);
2832 r->vchild = Qnil;
2833 }
2834 else if (!NILP (r->hchild))
2835 {
2836 delete_all_subwindows (r->hchild);
2837 r->hchild = Qnil;
2861 } 2838 }
2862 2839
2840 replace_window (root, window, 1);
2841
2842 /* Reset WINDOW's splits status. */
2843 w->splits = Qnil;
2844
2845 /* This must become SWINDOW anyway ....... */
2846 if (!NILP (w->buffer) && !resize_failed)
2847 {
2848 /* Try to minimize scrolling, by setting the window start to the
2849 point will cause the text at the old window start to be at the
2850 same place on the frame. But don't try to do this if the
2851 window start is outside the visible portion (as might happen
2852 when the display is not current, due to typeahead). */
2853 new_top = WINDOW_TOP_EDGE_LINE (w) - FRAME_TOP_MARGIN (XFRAME (WINDOW_FRAME (w)));
2854 if (new_top != top
2855 && startpos >= BUF_BEGV (XBUFFER (w->buffer))
2856 && startpos <= BUF_ZV (XBUFFER (w->buffer)))
2857 {
2858 struct position pos;
2859 struct buffer *obuf = current_buffer;
2860
2861 Fset_buffer (w->buffer);
2862 /* This computation used to temporarily move point, but that
2863 can have unwanted side effects due to text properties. */
2864 pos = *vmotion (startpos, -top, w);
2865
2866 set_marker_both (w->start, w->buffer, pos.bufpos, pos.bytepos);
2867 w->window_end_valid = Qnil;
2868 w->start_at_line_beg = ((pos.bytepos == BEGV_BYTE
2869 || FETCH_BYTE (pos.bytepos - 1) == '\n') ? Qt
2870 : Qnil);
2871 /* We need to do this, so that the window-scroll-functions
2872 get called. */
2873 w->optional_new_start = Qt;
2874
2875 set_buffer_internal (obuf);
2876 }
2877 }
2878
2879 adjust_glyphs (f);
2880 UNBLOCK_INPUT;
2881
2882 run_window_configuration_change_hook (f);
2883
2863 return Qnil; 2884 return Qnil;
2864} 2885}
2865 2886
2887
2866DEFUN ("delete-windows-on", Fdelete_windows_on, Sdelete_windows_on, 2888DEFUN ("delete-windows-on", Fdelete_windows_on, Sdelete_windows_on,
2867 0, 2, "bDelete windows on (buffer): ", 2889 0, 2, "bDelete windows on (buffer): ",
2868 doc: /* Delete all windows showing BUFFER-OR-NAME. 2890 doc: /* Delete all windows showing BUFFER-OR-NAME.
@@ -2944,8 +2966,6 @@ replace_buffer_in_all_windows (Lisp_Object buffer)
2944 window_loop (UNSHOW_BUFFER, buffer, 1, frame); 2966 window_loop (UNSHOW_BUFFER, buffer, 1, frame);
2945} 2967}
2946 2968
2947/* Set the height of WINDOW and all its inferiors. */
2948
2949/* 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
2950 minimum allowable size. */ 2970 minimum allowable size. */
2951 2971
@@ -2969,243 +2989,6 @@ check_frame_size (FRAME_PTR frame, int *rows, int *cols)
2969 *cols = MIN_SAFE_WINDOW_WIDTH; 2989 *cols = MIN_SAFE_WINDOW_WIDTH;
2970} 2990}
2971 2991
2972/* Value is non-zero if window W is fixed-size. WIDTH_P non-zero means
2973 check if W's width can be changed, otherwise check W's height.
2974 CHECK_SIBLINGS_P non-zero means check resizablity of WINDOW's
2975 siblings, too. If none of the siblings is resizable, WINDOW isn't
2976 either. */
2977
2978static int
2979window_fixed_size_p (struct window *w, int width_p, int check_siblings_p)
2980{
2981 int fixed_p;
2982 struct window *c;
2983
2984 if (!NILP (w->hchild))
2985 {
2986 c = XWINDOW (w->hchild);
2987
2988 if (width_p)
2989 {
2990 /* A horizontal combination is fixed-width if all of if its
2991 children are. */
2992 while (c && window_fixed_size_p (c, width_p, 0))
2993 c = WINDOWP (c->next) ? XWINDOW (c->next) : NULL;
2994 fixed_p = c == NULL;
2995 }
2996 else
2997 {
2998 /* A horizontal combination is fixed-height if one of if its
2999 children is. */
3000 while (c && !window_fixed_size_p (c, width_p, 0))
3001 c = WINDOWP (c->next) ? XWINDOW (c->next) : NULL;
3002 fixed_p = c != NULL;
3003 }
3004 }
3005 else if (!NILP (w->vchild))
3006 {
3007 c = XWINDOW (w->vchild);
3008
3009 if (width_p)
3010 {
3011 /* A vertical combination is fixed-width if one of if its
3012 children is. */
3013 while (c && !window_fixed_size_p (c, width_p, 0))
3014 c = WINDOWP (c->next) ? XWINDOW (c->next) : NULL;
3015 fixed_p = c != NULL;
3016 }
3017 else
3018 {
3019 /* A vertical combination is fixed-height if all of if its
3020 children are. */
3021 while (c && window_fixed_size_p (c, width_p, 0))
3022 c = WINDOWP (c->next) ? XWINDOW (c->next) : NULL;
3023 fixed_p = c == NULL;
3024 }
3025 }
3026 else if (BUFFERP (w->buffer))
3027 {
3028 struct buffer *old = current_buffer;
3029 Lisp_Object val;
3030
3031 current_buffer = XBUFFER (w->buffer);
3032 val = find_symbol_value (Qwindow_size_fixed);
3033 current_buffer = old;
3034
3035 fixed_p = 0;
3036 if (!EQ (val, Qunbound))
3037 {
3038 fixed_p = !NILP (val);
3039
3040 if (fixed_p
3041 && ((EQ (val, Qheight) && width_p)
3042 || (EQ (val, Qwidth) && !width_p)))
3043 fixed_p = 0;
3044 }
3045
3046 /* Can't tell if this one is resizable without looking at
3047 siblings. If all siblings are fixed-size this one is too. */
3048 if (!fixed_p && check_siblings_p && WINDOWP (w->parent))
3049 {
3050 Lisp_Object child;
3051
3052 for (child = w->prev; WINDOWP (child); child = XWINDOW (child)->prev)
3053 if (!window_fixed_size_p (XWINDOW (child), width_p, 0))
3054 break;
3055
3056 if (NILP (child))
3057 for (child = w->next; WINDOWP (child); child = XWINDOW (child)->next)
3058 if (!window_fixed_size_p (XWINDOW (child), width_p, 0))
3059 break;
3060
3061 if (NILP (child))
3062 fixed_p = 1;
3063 }
3064 }
3065 else
3066 fixed_p = 1;
3067
3068 return fixed_p;
3069}
3070
3071/* Return minimum size of leaf window W. WIDTH_P non-zero means return
3072 the minimum width of W, WIDTH_P zero means return the minimum height
3073 of W. SAFE_P non-zero means ignore window-min-height|width but just
3074 return values that won't crash Emacs and don't hide components like
3075 fringes, scrollbars, or modelines. If WIDTH_P is zero and W is the
3076 minibuffer window, always return 1. */
3077
3078static int
3079window_min_size_2 (struct window *w, int width_p, int safe_p)
3080{
3081 /* We should consider buffer-local values of window_min_height and
3082 window_min_width here. */
3083 if (width_p)
3084 {
3085 int safe_size = (MIN_SAFE_WINDOW_WIDTH
3086 + WINDOW_FRINGE_COLS (w)
3087 + WINDOW_SCROLL_BAR_COLS (w));
3088
3089 return safe_p ? safe_size : max (window_min_width, safe_size);
3090 }
3091 else if (MINI_WINDOW_P (w))
3092 return 1;
3093 else
3094 {
3095 int safe_size = (MIN_SAFE_WINDOW_HEIGHT
3096 + ((BUFFERP (w->buffer)
3097 && !NILP (BVAR (XBUFFER (w->buffer), mode_line_format)))
3098 ? 1 : 0));
3099
3100 return safe_p ? safe_size : max (window_min_height, safe_size);
3101 }
3102}
3103
3104/* Return minimum size of window W, not taking fixed-width windows into
3105 account. WIDTH_P non-zero means return the minimum width, otherwise
3106 return the minimum height. SAFE_P non-zero means ignore
3107 window-min-height|width but just return values that won't crash Emacs
3108 and don't hide components like fringes, scrollbars, or modelines. If
3109 W is a combination window, compute the minimum size from the minimum
3110 sizes of W's children. */
3111
3112static int
3113window_min_size_1 (struct window *w, int width_p, int safe_p)
3114{
3115 struct window *c;
3116 int size;
3117
3118 if (!NILP (w->hchild))
3119 {
3120 /* W is a horizontal combination. */
3121 c = XWINDOW (w->hchild);
3122 size = 0;
3123
3124 if (width_p)
3125 {
3126 /* The minimum width of a horizontal combination is the sum of
3127 the minimum widths of its children. */
3128 while (c)
3129 {
3130 size += window_min_size_1 (c, 1, safe_p);
3131 c = WINDOWP (c->next) ? XWINDOW (c->next) : NULL;
3132 }
3133 }
3134 else
3135 {
3136 /* The minimum height of a horizontal combination is the
3137 maximum of the minimum heights of its children. */
3138 while (c)
3139 {
3140 size = max (window_min_size_1 (c, 0, safe_p), size);
3141 c = WINDOWP (c->next) ? XWINDOW (c->next) : NULL;
3142 }
3143 }
3144 }
3145 else if (!NILP (w->vchild))
3146 {
3147 /* W is a vertical combination. */
3148 c = XWINDOW (w->vchild);
3149 size = 0;
3150
3151 if (width_p)
3152 {
3153 /* The minimum width of a vertical combination is the maximum
3154 of the minimum widths of its children. */
3155 while (c)
3156 {
3157 size = max (window_min_size_1 (c, 1, safe_p), size);
3158 c = WINDOWP (c->next) ? XWINDOW (c->next) : NULL;
3159 }
3160 }
3161 else
3162 {
3163 /* The minimum height of a vertical combination is the sum of
3164 the minimum height of its children. */
3165 while (c)
3166 {
3167 size += window_min_size_1 (c, 0, safe_p);
3168 c = WINDOWP (c->next) ? XWINDOW (c->next) : NULL;
3169 }
3170 }
3171 }
3172 else
3173 /* W is a leaf window. */
3174 size = window_min_size_2 (w, width_p, safe_p);
3175
3176 return size;
3177}
3178
3179/* Return the minimum size of window W, taking fixed-size windows into
3180 account. WIDTH_P non-zero means return the minimum width, otherwise
3181 return the minimum height. SAFE_P non-zero means ignore
3182 window-min-height|width but just return values that won't crash Emacs
3183 and don't hide components like fringes, scrollbars, or modelines.
3184 IGNORE_FIXED_P non-zero means ignore if W is fixed-size. Set *FIXED
3185 to 1 if W is fixed-size unless FIXED is null. */
3186
3187static int
3188window_min_size (struct window *w, int width_p, int safe_p, int ignore_fixed_p, int *fixed)
3189{
3190 int size, fixed_p;
3191
3192 if (ignore_fixed_p)
3193 fixed_p = 0;
3194 else
3195 fixed_p = window_fixed_size_p (w, width_p, 1);
3196
3197 if (fixed)
3198 *fixed = fixed_p;
3199
3200 if (fixed_p)
3201 size = WINDOW_TOTAL_SIZE (w, width_p);
3202 else
3203 size = window_min_size_1 (w, width_p, safe_p);
3204
3205 return size;
3206}
3207
3208
3209/* 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.
3210 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
3211 is still too narrow. */ 2994 is still too narrow. */
@@ -3240,410 +3023,6 @@ adjust_window_margins (struct window *w)
3240 w->left_margin_cols = make_number (margin_cols); 3023 w->left_margin_cols = make_number (margin_cols);
3241 return 1; 3024 return 1;
3242} 3025}
3243
3244/* Calculate new sizes for windows in the list FORWARD when their
3245 compound size goes from TOTAL to SIZE. TOTAL must be greater than
3246 SIZE. The number of windows in FORWARD is NCHILDREN, and the number
3247 that can shrink is SHRINKABLE. Fixed-size windows may be shrunk if
3248 and only if RESIZE_FIXED_P is non-zero. WIDTH_P non-zero means
3249 shrink columns, otherwise shrink lines.
3250
3251 SAFE_P zero means windows may be sized down to window-min-height
3252 lines (window-min-window columns for WIDTH_P non-zero). SAFE_P
3253 non-zero means windows may be sized down to their minimum safe sizes
3254 taking into account the space needed to display modelines, fringes,
3255 and scrollbars.
3256
3257 This function returns an allocated array of new sizes that the caller
3258 must free. A size -1 means the window is fixed and RESIZE_FIXED_P is
3259 zero. A size zero means the window shall be deleted. Array index 0
3260 refers to the first window in FORWARD, 1 to the second, and so on.
3261
3262 This function resizes windows proportionally to their size. It also
3263 tries to preserve smaller windows by resizing larger windows before
3264 resizing any window to zero. If resize_proportionally is non-nil for
3265 a specific window, it will attempt to strictly resize that window
3266 proportionally, even at the expense of deleting smaller windows. */
3267static int *
3268shrink_windows (int total, int size, int nchildren, int shrinkable,
3269 int resize_fixed_p, Lisp_Object forward, int width_p, int safe_p)
3270{
3271 int available_resize = 0;
3272 int *new_sizes, *min_sizes;
3273 struct window *c;
3274 Lisp_Object child;
3275 int smallest = total;
3276 int total_removed = 0;
3277 int total_shrink = total - size;
3278 int i;
3279
3280 new_sizes = xmalloc (sizeof (*new_sizes) * nchildren);
3281 min_sizes = xmalloc (sizeof (*min_sizes) * nchildren);
3282
3283 for (i = 0, child = forward; !NILP (child); child = c->next, ++i)
3284 {
3285 int child_size;
3286
3287 c = XWINDOW (child);
3288 child_size = WINDOW_TOTAL_SIZE (c, width_p);
3289
3290 if (!resize_fixed_p && window_fixed_size_p (c, width_p, 0))
3291 new_sizes[i] = -1;
3292 else
3293 {
3294 new_sizes[i] = child_size;
3295 min_sizes[i] = window_min_size_1 (c, width_p, safe_p);
3296 if (child_size > min_sizes[i]
3297 && NILP (c->resize_proportionally))
3298 available_resize += child_size - min_sizes[i];
3299 }
3300 }
3301 /* We might need to shrink some windows to zero. Find the smallest
3302 windows and set them to 0 until we can fulfil the new size. */
3303
3304 while (shrinkable > 1 && size + available_resize < total)
3305 {
3306 for (i = 0; i < nchildren; ++i)
3307 if (new_sizes[i] > 0 && smallest > new_sizes[i])
3308 smallest = new_sizes[i];
3309
3310 for (i = 0; i < nchildren; ++i)
3311 if (new_sizes[i] == smallest)
3312 {
3313 /* Resize this window down to zero. */
3314 new_sizes[i] = 0;
3315 if (smallest > min_sizes[i])
3316 available_resize -= smallest - min_sizes[i];
3317 available_resize += smallest;
3318 --shrinkable;
3319 total_removed += smallest;
3320
3321 /* We don't know what the smallest is now. */
3322 smallest = total;
3323
3324 /* Out of for, just remove one window at the time and
3325 check again if we have enough space. */
3326 break;
3327 }
3328 }
3329
3330 /* Now, calculate the new sizes. Try to shrink each window
3331 proportional to its size. */
3332 for (i = 0; i < nchildren; ++i)
3333 {
3334 if (new_sizes[i] > min_sizes[i])
3335 {
3336 int to_shrink = total_shrink * new_sizes[i] / total;
3337
3338 if (new_sizes[i] - to_shrink < min_sizes[i])
3339 to_shrink = new_sizes[i] - min_sizes[i];
3340 new_sizes[i] -= to_shrink;
3341 total_removed += to_shrink;
3342 }
3343 }
3344
3345 /* Any reminder due to rounding, we just subtract from windows
3346 that are left and still can be shrunk. */
3347 while (total_shrink > total_removed)
3348 {
3349 int nonzero_sizes = 0;
3350
3351 for (i = 0; i < nchildren; ++i)
3352 if (new_sizes[i] > 0)
3353 ++nonzero_sizes;
3354
3355 for (i = 0; i < nchildren; ++i)
3356 if (new_sizes[i] > min_sizes[i])
3357 {
3358 --new_sizes[i];
3359 ++total_removed;
3360
3361 /* Out of for, just shrink one window at the time and
3362 check again if we have enough space. */
3363 break;
3364 }
3365
3366 /* Special case, only one window left. */
3367 if (nonzero_sizes == 1)
3368 break;
3369 }
3370
3371 /* Any surplus due to rounding, we add to windows that are left. */
3372 while (total_shrink < total_removed)
3373 {
3374 for (i = 0; i < nchildren; ++i)
3375 {
3376 if (new_sizes[i] != 0 && total_shrink < total_removed)
3377 {
3378 ++new_sizes[i];
3379 --total_removed;
3380 break;
3381 }
3382 }
3383 }
3384
3385 xfree (min_sizes);
3386
3387 return new_sizes;
3388}
3389
3390/* Set WINDOW's height or width to SIZE. WIDTH_P non-zero means set
3391 WINDOW's width. Resize WINDOW's children, if any, so that they keep
3392 their proportionate size relative to WINDOW.
3393
3394 If FIRST_ONLY is 1, change only the first of WINDOW's children when
3395 they are in series. If LAST_ONLY is 1, change only the last of
3396 WINDOW's children when they are in series.
3397
3398 Propagate WINDOW's top or left edge position to children. Delete
3399 windows that become too small unless NODELETE_P is 1. When
3400 NODELETE_P equals 2 do not honor settings for window-min-height and
3401 window-min-width when resizing windows but use safe defaults instead.
3402 This should give better behavior when resizing frames. */
3403
3404static void
3405size_window (Lisp_Object window, int size, int width_p, int nodelete_p, int first_only, int last_only)
3406{
3407 struct window *w = XWINDOW (window);
3408 struct window *c;
3409 Lisp_Object child, *forward, *sideward;
3410 int old_size = WINDOW_TOTAL_SIZE (w, width_p);
3411
3412 size = max (0, size);
3413
3414 /* Delete WINDOW if it's too small. */
3415 if (nodelete_p != 1 && !NILP (w->parent)
3416 && size < window_min_size_1 (w, width_p, nodelete_p == 2))
3417 {
3418 delete_window (window);
3419 return;
3420 }
3421
3422 /* Set redisplay hints. */
3423 w->last_modified = make_number (0);
3424 w->last_overlay_modified = make_number (0);
3425 windows_or_buffers_changed++;
3426 FRAME_WINDOW_SIZES_CHANGED (XFRAME (w->frame)) = 1;
3427
3428 if (width_p)
3429 {
3430 sideward = &w->vchild;
3431 forward = &w->hchild;
3432 w->total_cols = make_number (size);
3433 adjust_window_margins (w);
3434 }
3435 else
3436 {
3437 sideward = &w->hchild;
3438 forward = &w->vchild;
3439 w->total_lines = make_number (size);
3440 w->orig_total_lines = Qnil;
3441 }
3442
3443 if (!NILP (*sideward))
3444 {
3445 /* We have a chain of parallel siblings whose size should all change. */
3446 for (child = *sideward; !NILP (child); child = c->next)
3447 {
3448 c = XWINDOW (child);
3449 if (width_p)
3450 c->left_col = w->left_col;
3451 else
3452 c->top_line = w->top_line;
3453 size_window (child, size, width_p, nodelete_p,
3454 first_only, last_only);
3455 }
3456 }
3457 else if (!NILP (*forward) && last_only)
3458 {
3459 /* Change the last in a series of siblings. */
3460 Lisp_Object last_child;
3461 int child_size;
3462
3463 child = *forward;
3464 do
3465 {
3466 c = XWINDOW (child);
3467 last_child = child;
3468 child = c->next;
3469 }
3470 while (!NILP (child));
3471
3472 child_size = WINDOW_TOTAL_SIZE (c, width_p);
3473 size_window (last_child, size - old_size + child_size,
3474 width_p, nodelete_p, first_only, last_only);
3475 }
3476 else if (!NILP (*forward) && first_only)
3477 {
3478 /* Change the first in a series of siblings. */
3479 int child_size;
3480
3481 child = *forward;
3482 c = XWINDOW (child);
3483
3484 if (width_p)
3485 c->left_col = w->left_col;
3486 else
3487 c->top_line = w->top_line;
3488
3489 child_size = WINDOW_TOTAL_SIZE (c, width_p);
3490 size_window (child, size - old_size + child_size,
3491 width_p, nodelete_p, first_only, last_only);
3492 }
3493 else if (!NILP (*forward))
3494 {
3495 int fixed_size, each IF_LINT (= 0), extra IF_LINT (= 0), n;
3496 int resize_fixed_p, nfixed;
3497 int last_pos, first_pos, nchildren, total;
3498 int *new_sizes = NULL;
3499
3500 /* Determine the fixed-size portion of this window, and the
3501 number of child windows. */
3502 fixed_size = nchildren = nfixed = total = 0;
3503 for (child = *forward; !NILP (child); child = c->next, ++nchildren)
3504 {
3505 int child_size;
3506
3507 c = XWINDOW (child);
3508 child_size = WINDOW_TOTAL_SIZE (c, width_p);
3509 total += child_size;
3510
3511 if (window_fixed_size_p (c, width_p, 0))
3512 {
3513 fixed_size += child_size;
3514 ++nfixed;
3515 }
3516 }
3517
3518 /* If the new size is smaller than fixed_size, or if there
3519 aren't any resizable windows, allow resizing fixed-size
3520 windows. */
3521 resize_fixed_p = nfixed == nchildren || size < fixed_size;
3522
3523 /* Compute how many lines/columns to add/remove to each child. The
3524 value of extra takes care of rounding errors. */
3525 n = resize_fixed_p ? nchildren : nchildren - nfixed;
3526 if (size < total && n > 1)
3527 new_sizes = shrink_windows (total, size, nchildren, n,
3528 resize_fixed_p, *forward, width_p,
3529 nodelete_p == 2);
3530 else
3531 {
3532 each = (size - total) / n;
3533 extra = (size - total) - n * each;
3534 }
3535
3536 /* Compute new children heights and edge positions. */
3537 first_pos = width_p ? XINT (w->left_col) : XINT (w->top_line);
3538 last_pos = first_pos;
3539 for (n = 0, child = *forward; !NILP (child); child = c->next, ++n)
3540 {
3541 int new_child_size, old_child_size;
3542
3543 c = XWINDOW (child);
3544 old_child_size = WINDOW_TOTAL_SIZE (c, width_p);
3545 new_child_size = old_child_size;
3546
3547 /* The top or left edge position of this child equals the
3548 bottom or right edge of its predecessor. */
3549 if (width_p)
3550 c->left_col = make_number (last_pos);
3551 else
3552 c->top_line = make_number (last_pos);
3553
3554 /* If this child can be resized, do it. */
3555 if (resize_fixed_p || !window_fixed_size_p (c, width_p, 0))
3556 {
3557 new_child_size =
3558 new_sizes ? new_sizes[n] : old_child_size + each + extra;
3559 extra = 0;
3560 }
3561
3562 /* Set new size. Note that size_window also propagates
3563 edge positions to children, so it's not a no-op if we
3564 didn't change the child's size. */
3565 size_window (child, new_child_size, width_p, 1,
3566 first_only, last_only);
3567
3568 /* Remember the bottom/right edge position of this child; it
3569 will be used to set the top/left edge of the next child. */
3570 last_pos += new_child_size;
3571 }
3572
3573 xfree (new_sizes);
3574
3575 /* We should have covered the parent exactly with child windows. */
3576 xassert (size == last_pos - first_pos);
3577
3578 /* Now delete any children that became too small. */
3579 if (nodelete_p != 1)
3580 for (child = *forward; !NILP (child); child = c->next)
3581 {
3582 int child_size;
3583
3584 c = XWINDOW (child);
3585 child_size = WINDOW_TOTAL_SIZE (c, width_p);
3586 size_window (child, child_size, width_p, nodelete_p,
3587 first_only, last_only);
3588 }
3589 }
3590}
3591
3592/* Set WINDOW's height to HEIGHT, and recursively change the height of
3593 WINDOW's children. NODELETE zero means windows that have become
3594 smaller than window-min-height in the process may be deleted.
3595 NODELETE 1 means never delete windows that become too small in the
3596 process. (The caller should check later and do so if appropriate.)
3597 NODELETE 2 means delete only windows that have become too small to be
3598 displayed correctly. */
3599
3600void
3601set_window_height (Lisp_Object window, int height, int nodelete)
3602{
3603 size_window (window, height, 0, nodelete, 0, 0);
3604}
3605
3606/* Set WINDOW's width to WIDTH, and recursively change the width of
3607 WINDOW's children. NODELETE zero means windows that have become
3608 smaller than window-min-width in the process may be deleted.
3609 NODELETE 1 means never delete windows that become too small in the
3610 process. (The caller should check later and do so if appropriate.)
3611 NODELETE 2 means delete only windows that have become too small to be
3612 displayed correctly. */
3613
3614void
3615set_window_width (Lisp_Object window, int width, int nodelete)
3616{
3617 size_window (window, width, 1, nodelete, 0, 0);
3618}
3619
3620/* Change window heights in windows rooted in WINDOW by N lines. */
3621
3622void
3623change_window_heights (Lisp_Object window, int n)
3624{
3625 struct window *w = XWINDOW (window);
3626
3627 XSETFASTINT (w->top_line, XFASTINT (w->top_line) + n);
3628 XSETFASTINT (w->total_lines, XFASTINT (w->total_lines) - n);
3629
3630 if (INTEGERP (w->orig_top_line))
3631 XSETFASTINT (w->orig_top_line, XFASTINT (w->orig_top_line) + n);
3632 if (INTEGERP (w->orig_total_lines))
3633 XSETFASTINT (w->orig_total_lines, XFASTINT (w->orig_total_lines) - n);
3634
3635 /* Handle just the top child in a vertical split. */
3636 if (!NILP (w->vchild))
3637 change_window_heights (w->vchild, n);
3638
3639 /* Adjust all children in a horizontal split. */
3640 for (window = w->hchild; !NILP (window); window = w->next)
3641 {
3642 w = XWINDOW (window);
3643 change_window_heights (window, n);
3644 }
3645}
3646
3647 3026
3648int window_select_count; 3027int window_select_count;
3649 3028
@@ -3676,12 +3055,6 @@ run_window_configuration_change_hook (struct frame *f)
3676 if (NILP (Vrun_hooks)) 3055 if (NILP (Vrun_hooks))
3677 return; 3056 return;
3678 3057
3679 if (SELECTED_FRAME () != f)
3680 {
3681 record_unwind_protect (select_frame_norecord, Fselected_frame ());
3682 Fselect_frame (frame, Qt);
3683 }
3684
3685 /* Use the right buffer. Matters when running the local hooks. */ 3058 /* Use the right buffer. Matters when running the local hooks. */
3686 if (current_buffer != XBUFFER (Fwindow_buffer (Qnil))) 3059 if (current_buffer != XBUFFER (Fwindow_buffer (Qnil)))
3687 { 3060 {
@@ -3689,6 +3062,12 @@ run_window_configuration_change_hook (struct frame *f)
3689 Fset_buffer (Fwindow_buffer (Qnil)); 3062 Fset_buffer (Fwindow_buffer (Qnil));
3690 } 3063 }
3691 3064
3065 if (SELECTED_FRAME () != f)
3066 {
3067 record_unwind_protect (select_frame_norecord, Fselected_frame ());
3068 select_frame_norecord (frame);
3069 }
3070
3692 /* Look for buffer-local values. */ 3071 /* Look for buffer-local values. */
3693 { 3072 {
3694 Lisp_Object windows = Fwindow_list (frame, Qlambda, Qnil); 3073 Lisp_Object windows = Fwindow_list (frame, Qlambda, Qnil);
@@ -3699,12 +3078,12 @@ run_window_configuration_change_hook (struct frame *f)
3699 if (!NILP (Flocal_variable_p (Qwindow_configuration_change_hook, 3078 if (!NILP (Flocal_variable_p (Qwindow_configuration_change_hook,
3700 buffer))) 3079 buffer)))
3701 { 3080 {
3702 int count1 = SPECPDL_INDEX (); 3081 int count = SPECPDL_INDEX ();
3703 record_unwind_protect (select_window_norecord, Fselected_window ()); 3082 record_unwind_protect (select_window_norecord, Fselected_window ());
3704 select_window_norecord (window); 3083 select_window_norecord (window);
3705 run_funs (Fbuffer_local_value (Qwindow_configuration_change_hook, 3084 run_funs (Fbuffer_local_value (Qwindow_configuration_change_hook,
3706 buffer)); 3085 buffer));
3707 unbind_to (count1, Qnil); 3086 unbind_to (count, Qnil);
3708 } 3087 }
3709 } 3088 }
3710 } 3089 }
@@ -3713,6 +3092,16 @@ run_window_configuration_change_hook (struct frame *f)
3713 unbind_to (count, Qnil); 3092 unbind_to (count, Qnil);
3714} 3093}
3715 3094
3095DEFUN ("run-window-configuration-change-hook", Frun_window_configuration_change_hook,
3096 Srun_window_configuration_change_hook, 1, 1, 0,
3097 doc: /* Run `window-configuration-change-hook' for FRAME. */)
3098 (Lisp_Object frame)
3099{
3100 CHECK_LIVE_FRAME (frame);
3101 run_window_configuration_change_hook (XFRAME (frame));
3102 return Qnil;
3103}
3104
3716/* Make WINDOW display BUFFER as its contents. RUN_HOOKS_P non-zero 3105/* Make WINDOW display BUFFER as its contents. RUN_HOOKS_P non-zero
3717 means it's allowed to run hooks. See make_frame for a case where 3106 means it's allowed to run hooks. See make_frame for a case where
3718 it's not allowed. KEEP_MARGINS_P non-zero means that the current 3107 it's not allowed. KEEP_MARGINS_P non-zero means that the current
@@ -4000,10 +3389,13 @@ DEFUN ("internal-temp-output-buffer-show",
4000 return Qnil; 3389 return Qnil;
4001} 3390}
4002 3391
3392/* Make new window, have it replace WINDOW in window-tree, and make
3393 WINDOW its only vertical child (HORFLAG 1 means make WINDOW its only
3394 horizontal child). */
4003static void 3395static void
4004make_dummy_parent (Lisp_Object window) 3396make_parent_window (Lisp_Object window, int horflag)
4005{ 3397{
4006 Lisp_Object new; 3398 Lisp_Object parent;
4007 register struct window *o, *p; 3399 register struct window *o, *p;
4008 int i; 3400 int i;
4009 3401
@@ -4011,30 +3403,27 @@ make_dummy_parent (Lisp_Object window)
4011 p = allocate_window (); 3403 p = allocate_window ();
4012 for (i = 0; i < VECSIZE (struct window); ++i) 3404 for (i = 0; i < VECSIZE (struct window); ++i)
4013 ((struct Lisp_Vector *) p)->contents[i] 3405 ((struct Lisp_Vector *) p)->contents[i]
4014 = ((struct Lisp_Vector *)o)->contents[i]; 3406 = ((struct Lisp_Vector *) o)->contents[i];
4015 XSETWINDOW (new, p); 3407 XSETWINDOW (parent, p);
4016 3408
4017 ++sequence_number; 3409 ++sequence_number;
4018 XSETFASTINT (p->sequence_number, sequence_number); 3410 XSETFASTINT (p->sequence_number, sequence_number);
4019 XSETFASTINT (p->clone_number, sequence_number); 3411 XSETFASTINT (p->clone_number, sequence_number);
4020 3412
4021 /* Put new into window structure in place of window */ 3413 replace_window (window, parent, 1);
4022 replace_window (window, new);
4023 3414
4024 o->next = Qnil; 3415 o->next = Qnil;
4025 o->prev = Qnil; 3416 o->prev = Qnil;
4026 o->vchild = Qnil; 3417 o->parent = parent;
4027 o->hchild = Qnil;
4028 o->parent = new;
4029 3418
3419 p->hchild = horflag ? window : Qnil;
3420 p->vchild = horflag ? Qnil : window;
4030 p->start = Qnil; 3421 p->start = Qnil;
4031 p->pointm = Qnil; 3422 p->pointm = Qnil;
4032 p->buffer = Qnil; 3423 p->buffer = Qnil;
4033
4034 p->splits = Qnil; 3424 p->splits = Qnil;
4035 p->nest = Qnil; 3425 p->nest = Qnil;
4036 p->window_parameters = Qnil; 3426 p->window_parameters = Qnil;
4037
4038} 3427}
4039 3428
4040/* Make new window from scratch. */ 3429/* Make new window from scratch. */
@@ -4096,7 +3485,6 @@ make_window (void)
4096 w->pseudo_window_p = 0; 3485 w->pseudo_window_p = 0;
4097 w->frozen_window_start_p = 0; 3486 w->frozen_window_start_p = 0;
4098 w->vscroll = 0; 3487 w->vscroll = 0;
4099 w->resize_proportionally = Qnil;
4100 /* Reset window_list. */ 3488 /* Reset window_list. */
4101 Vwindow_list = Qnil; 3489 Vwindow_list = Qnil;
4102 /* Return window. */ 3490 /* Return window. */
@@ -4138,872 +3526,770 @@ Note: This function does not operate on any subwindows of WINDOW. */)
4138 return w->new_normal; 3526 return w->new_normal;
4139} 3527}
4140 3528
4141DEFUN ("split-window", Fsplit_window, Ssplit_window, 0, 3, "", 3529/* Return 1 if setting w->total_lines (w->total_cols if HORFLAG is
4142 doc: /* Split WINDOW, putting SIZE lines in the first of the pair. 3530 non-zero) to w->new_total would result in correct heights (widths)
4143WINDOW defaults to selected one and SIZE to half its size. 3531 for window W and recursively all subwindows of W.
4144If optional third arg HORIZONTAL is non-nil, split side by side and put
4145SIZE columns in the first of the pair. In that case, SIZE includes that
4146window's scroll bar, or the divider column to its right.
4147Interactively, all arguments are nil.
4148Returns the newly created window (which is the lower or rightmost one).
4149The upper or leftmost window is the original one, and remains selected
4150if it was selected before.
4151 3532
4152See Info node `(elisp)Splitting Windows' for more details and examples. */) 3533 Note: This function does not check any of `window-fixed-size-p',
4153 (Lisp_Object window, Lisp_Object size, Lisp_Object horizontal) 3534 `window-min-height' or `window-min-width'. It does check that window
3535 sizes do not drop below one line (two columns). */
3536int
3537resize_window_check (struct window *w, int horflag)
4154{ 3538{
4155 register Lisp_Object new; 3539 struct window *c;
4156 register struct window *o, *p;
4157 FRAME_PTR fo;
4158 register int size_int;
4159
4160 if (NILP (window))
4161 window = selected_window;
4162 else
4163 CHECK_LIVE_WINDOW (window);
4164
4165 o = XWINDOW (window);
4166 fo = XFRAME (WINDOW_FRAME (o));
4167 3540
4168 if (NILP (size)) 3541 if (!NILP (w->vchild))
3542 /* W is a vertical combination. */
4169 { 3543 {
4170 if (!NILP (horizontal)) 3544 c = XWINDOW (w->vchild);
4171 /* Calculate the size of the left-hand window, by dividing 3545 if (horflag)
4172 the usable space in columns by two. 3546 /* All subwindows of W must have the same width as W. */
4173 We round up, since the left-hand window may include 3547 {
4174 a dividing line, while the right-hand may not. */ 3548 while (c)
4175 size_int = (XFASTINT (o->total_cols) + 1) >> 1; 3549 {
3550 if ((XINT (c->new_total) != XINT (w->new_total))
3551 || !resize_window_check (c, horflag))
3552 return 0;
3553 c = NILP (c->next) ? 0 : XWINDOW (c->next);
3554 }
3555 return 1;
3556 }
4176 else 3557 else
4177 size_int = XFASTINT (o->total_lines) >> 1; 3558 /* The sum of the heights of the subwindows of W must equal W's
3559 height. */
3560 {
3561 int sum_of_sizes = 0;
3562 while (c)
3563 {
3564 if (!resize_window_check (c, horflag))
3565 return 0;
3566 sum_of_sizes = sum_of_sizes + XINT (c->new_total);
3567 c = NILP (c->next) ? 0 : XWINDOW (c->next);
3568 }
3569 return (sum_of_sizes == XINT (w->new_total));
3570 }
4178 } 3571 }
4179 else 3572 else if (!NILP (w->hchild))
3573 /* W is a horizontal combination. */
4180 { 3574 {
4181 CHECK_NUMBER (size); 3575 c = XWINDOW (w->hchild);
4182 size_int = XINT (size); 3576 if (horflag)
3577 /* The sum of the widths of the subwindows of W must equal W's
3578 width. */
3579 {
3580 int sum_of_sizes = 0;
3581 while (c)
3582 {
3583 if (!resize_window_check (c, horflag))
3584 return 0;
3585 sum_of_sizes = sum_of_sizes + XINT (c->new_total);
3586 c = NILP (c->next) ? 0 : XWINDOW (c->next);
3587 }
3588 return (sum_of_sizes == XINT (w->new_total));
3589 }
3590 else
3591 /* All subwindows of W must have the same height as W. */
3592 {
3593 while (c)
3594 {
3595 if ((XINT (c->new_total) != XINT (w->new_total))
3596 || !resize_window_check (c, horflag))
3597 return 0;
3598 c = NILP (c->next) ? 0 : XWINDOW (c->next);
3599 }
3600 return 1;
3601 }
4183 } 3602 }
3603 else
3604 /* A leaf window. Make sure it's not too small. The following
3605 hardcodes the values of `window-safe-min-width' (2) and
3606 `window-safe-min-height' (1) which are defined in window.el. */
3607 return XINT (w->new_total) >= (horflag ? 2 : 1);
3608}
4184 3609
4185 if (MINI_WINDOW_P (o)) 3610/* Set w->total_lines (w->total_cols if HORIZONTAL is non-zero) to
4186 error ("Attempt to split minibuffer window"); 3611 w->new_total for window W and recursively all subwindows of W. Also
4187 else if (window_fixed_size_p (o, !NILP (horizontal), 0)) 3612 calculate and assign the new vertical (horizontal) start positions of
4188 error ("Attempt to split fixed-size window"); 3613 each of these windows.
4189 3614
4190 if (NILP (horizontal)) 3615 This function does not perform any error checks. Make sure you have
3616 run resize_window_check on W before applying this function. */
3617static void
3618resize_window_apply (struct window *w, int horflag)
3619{
3620 struct window *c, *p;
3621 int pos;
3622
3623 /* Note: Assigning new_normal requires that the new total size of the
3624 parent window has been set *before*. */
3625 if (horflag)
4191 { 3626 {
4192 int window_safe_height = window_min_size_2 (o, 0, 0); 3627 w->total_cols = w->new_total;
3628 if (NUMBERP (w->new_normal))
3629 w->normal_cols = w->new_normal;
4193 3630
4194 if (size_int < window_safe_height) 3631 pos = XINT (w->left_col);
4195 error ("Window height %d too small (after splitting)", size_int);
4196 if (size_int + window_safe_height > XFASTINT (o->total_lines))
4197 error ("Window height %d too small (after splitting)",
4198 (int) (XFASTINT (o->total_lines) - size_int));
4199 if (NILP (o->parent)
4200 || NILP (XWINDOW (o->parent)->vchild))
4201 {
4202 make_dummy_parent (window);
4203 new = o->parent;
4204 XWINDOW (new)->vchild = window;
4205 }
4206 } 3632 }
4207 else 3633 else
4208 { 3634 {
4209 int window_safe_width = window_min_size_2 (o, 1, 0); 3635 w->total_lines = w->new_total;
3636 if (NUMBERP (w->new_normal))
3637 w->normal_lines = w->new_normal;
4210 3638
4211 if (size_int < window_safe_width) 3639 pos = XINT (w->top_line);
4212 error ("Window width %d too small (after splitting)", size_int);
4213 if (size_int + window_safe_width > XFASTINT (o->total_cols))
4214 error ("Window width %d too small (after splitting)",
4215 (int) (XFASTINT (o->total_cols) - size_int));
4216 if (NILP (o->parent)
4217 || NILP (XWINDOW (o->parent)->hchild))
4218 {
4219 make_dummy_parent (window);
4220 new = o->parent;
4221 XWINDOW (new)->hchild = window;
4222 }
4223 } 3640 }
4224 3641
4225 /* Now we know that window's parent is a vertical combination 3642 if (!NILP (w->vchild))
4226 if we are dividing vertically, or a horizontal combination 3643 /* W is a vertical combination. */
4227 if we are making side-by-side windows */ 3644 {
4228 3645 c = XWINDOW (w->vchild);
4229 windows_or_buffers_changed++; 3646 while (c)
4230 FRAME_WINDOW_SIZES_CHANGED (fo) = 1; 3647 {
4231 new = make_window (); 3648 if (horflag)
4232 p = XWINDOW (new); 3649 XSETFASTINT (c->left_col, pos);
4233 3650 else
4234 p->frame = o->frame; 3651 XSETFASTINT (c->top_line, pos);
4235 p->next = o->next; 3652 resize_window_apply (c, horflag);
4236 if (!NILP (p->next)) 3653 if (!horflag)
4237 XWINDOW (p->next)->prev = new; 3654 pos = pos + XINT (c->total_lines);
4238 p->prev = window; 3655 c = NILP (c->next) ? 0 : XWINDOW (c->next);
4239 o->next = new; 3656 }
4240 p->parent = o->parent;
4241 p->buffer = Qt;
4242 p->window_end_valid = Qnil;
4243 memset (&p->last_cursor, 0, sizeof p->last_cursor);
4244
4245 /* Duplicate special geometry settings. */
4246
4247 p->left_margin_cols = o->left_margin_cols;
4248 p->right_margin_cols = o->right_margin_cols;
4249 p->left_fringe_width = o->left_fringe_width;
4250 p->right_fringe_width = o->right_fringe_width;
4251 p->fringes_outside_margins = o->fringes_outside_margins;
4252 p->scroll_bar_width = o->scroll_bar_width;
4253 p->vertical_scroll_bar_type = o->vertical_scroll_bar_type;
4254
4255 /* Apportion the available frame space among the two new windows */
4256
4257 if (!NILP (horizontal))
4258 {
4259 p->total_lines = o->total_lines;
4260 p->top_line = o->top_line;
4261 XSETFASTINT (p->total_cols, XFASTINT (o->total_cols) - size_int);
4262 XSETFASTINT (o->total_cols, size_int);
4263 XSETFASTINT (p->left_col, XFASTINT (o->left_col) + size_int);
4264 adjust_window_margins (p);
4265 adjust_window_margins (o);
4266 } 3657 }
4267 else 3658 else if (!NILP (w->hchild))
3659 /* W is a horizontal combination. */
4268 { 3660 {
4269 p->left_col = o->left_col; 3661 c = XWINDOW (w->hchild);
4270 p->total_cols = o->total_cols; 3662 while (c)
4271 XSETFASTINT (p->total_lines, XFASTINT (o->total_lines) - size_int); 3663 {
4272 XSETFASTINT (o->total_lines, size_int); 3664 if (horflag)
4273 XSETFASTINT (p->top_line, XFASTINT (o->top_line) + size_int); 3665 XSETFASTINT (c->left_col, pos);
3666 else
3667 XSETFASTINT (c->top_line, pos);
3668 resize_window_apply (c, horflag);
3669 if (horflag)
3670 pos = pos + XINT (c->total_cols);
3671 c = NILP (c->next) ? 0 : XWINDOW (c->next);
3672 }
4274 } 3673 }
4275 3674
4276 /* Adjust glyph matrices. */ 3675 /* Clear out some redisplay caches. */
4277 adjust_glyphs (fo); 3676 XSETFASTINT (w->last_modified, 0);
4278 3677 XSETFASTINT (w->last_overlay_modified, 0);
4279 Fset_window_buffer (new, o->buffer, Qt);
4280 return new;
4281}
4282
4283DEFUN ("enlarge-window", Fenlarge_window, Senlarge_window, 1, 2, "p",
4284 doc: /* Make selected window SIZE lines taller.
4285Interactively, if no argument is given, make the selected window one
4286line taller. If optional argument HORIZONTAL is non-nil, make selected
4287window wider by SIZE columns. If SIZE is negative, shrink the window by
4288-SIZE lines or columns. Return nil.
4289
4290This function can delete windows if they get too small. The size of
4291fixed size windows is not altered by this function. */)
4292 (Lisp_Object size, Lisp_Object horizontal)
4293{
4294 CHECK_NUMBER (size);
4295 enlarge_window (selected_window, XINT (size), !NILP (horizontal));
4296
4297 run_window_configuration_change_hook (SELECTED_FRAME ());
4298
4299 return Qnil;
4300} 3678}
4301 3679
4302DEFUN ("shrink-window", Fshrink_window, Sshrink_window, 1, 2, "p",
4303 doc: /* Make selected window SIZE lines smaller.
4304Interactively, if no argument is given, make the selected window one
4305line smaller. If optional argument HORIZONTAL is non-nil, make the
4306window narrower by SIZE columns. If SIZE is negative, enlarge selected
4307window by -SIZE lines or columns. Return nil.
4308
4309This function can delete windows if they get too small. The size of
4310fixed size windows is not altered by this function. */)
4311 (Lisp_Object size, Lisp_Object horizontal)
4312{
4313 CHECK_NUMBER (size);
4314 enlarge_window (selected_window, -XINT (size), !NILP (horizontal));
4315
4316 run_window_configuration_change_hook (SELECTED_FRAME ());
4317 3680
4318 return Qnil; 3681DEFUN ("resize-window-apply", Fresize_window_apply, Sresize_window_apply, 1, 2, 0,
4319} 3682 doc: /* Apply requested size values for window-tree of FRAME.
3683Optional argument HORIZONTAL omitted or nil means apply requested height
3684values. HORIZONTAL non-nil means apply requested width values.
4320 3685
4321static int 3686This function checks whether the requested values sum up to a valid
4322window_height (Lisp_Object window) 3687window layout, recursively assigns the new sizes of all subwindows and
4323{ 3688calculates and assigns the new start positions of these windows.
4324 register struct window *p = XWINDOW (window);
4325 return WINDOW_TOTAL_LINES (p);
4326}
4327 3689
4328static int 3690Note: This function does not check any of `window-fixed-size-p',
4329window_width (Lisp_Object window) 3691`window-min-height' or `window-min-width'. All these checks have to
3692be applied on the Elisp level. */)
3693 (Lisp_Object frame, Lisp_Object horizontal)
4330{ 3694{
4331 register struct window *p = XWINDOW (window); 3695 struct frame *f;
4332 return WINDOW_TOTAL_COLS (p); 3696 struct window *r;
4333} 3697 int horflag = !NILP (horizontal);
4334
4335
4336#define CURBEG(w) \
4337 *(horiz_flag ? &(XWINDOW (w)->left_col) : &(XWINDOW (w)->top_line))
4338
4339#define CURSIZE(w) \
4340 *(horiz_flag ? &(XWINDOW (w)->total_cols) : &(XWINDOW (w)->total_lines))
4341
4342 3698
4343/* Enlarge WINDOW by DELTA. HORIZ_FLAG nonzero means enlarge it 3699 if (NILP (frame))
4344 horizontally; zero means do it vertically. 3700 frame = selected_frame;
3701 CHECK_LIVE_FRAME (frame);
4345 3702
4346 Siblings of the selected window are resized to fulfill the size 3703 f = XFRAME (frame);
4347 request. If they become too small in the process, they may be 3704 r = XWINDOW (FRAME_ROOT_WINDOW (f));
4348 deleted. */
4349 3705
4350static void 3706 if (!resize_window_check (r, horflag)
4351enlarge_window (Lisp_Object window, int delta, int horiz_flag) 3707 || ! EQ (r->new_total, (horflag ? r->total_cols : r->total_lines)))
4352{ 3708 return Qnil;
4353 Lisp_Object parent, next, prev;
4354 struct window *p;
4355 Lisp_Object *sizep;
4356 int maximum;
4357 int (*sizefun) (Lisp_Object)
4358 = horiz_flag ? window_width : window_height;
4359 void (*setsizefun) (Lisp_Object, int, int)
4360 = (horiz_flag ? set_window_width : set_window_height);
4361 3709
4362 /* Give up if this window cannot be resized. */ 3710 BLOCK_INPUT;
4363 if (window_fixed_size_p (XWINDOW (window), horiz_flag, 1)) 3711 resize_window_apply (r, horflag);
4364 error ("Window is not resizable");
4365 3712
4366 /* Find the parent of the selected window. */ 3713 windows_or_buffers_changed++;
4367 while (1) 3714 FRAME_WINDOW_SIZES_CHANGED (f) = 1;
4368 {
4369 p = XWINDOW (window);
4370 parent = p->parent;
4371 3715
4372 if (NILP (parent)) 3716 adjust_glyphs (f);
4373 { 3717 UNBLOCK_INPUT;
4374 if (horiz_flag)
4375 error ("No other window to side of this one");
4376 break;
4377 }
4378 3718
4379 if (horiz_flag 3719 run_window_configuration_change_hook (f);
4380 ? !NILP (XWINDOW (parent)->hchild)
4381 : !NILP (XWINDOW (parent)->vchild))
4382 break;
4383 3720
4384 window = parent; 3721 return Qt;
4385 } 3722}
4386 3723
4387 sizep = &CURSIZE (window);
4388 3724
4389 { 3725/* Resize frame F's windows when number of lines of F is set to SIZE.
4390 register int maxdelta; 3726 HORFLAG 1 means resize windows when number of columns of F is set to
4391 3727 SIZE.
4392 /* Compute the maximum size increment this window can have. */
4393
4394 maxdelta = (!NILP (parent) ? (*sizefun) (parent) - XINT (*sizep)
4395 /* This is a main window followed by a minibuffer. */
4396 : !NILP (p->next) ? ((*sizefun) (p->next)
4397 - window_min_size (XWINDOW (p->next),
4398 horiz_flag, 0, 0, 0))
4399 /* This is a minibuffer following a main window. */
4400 : !NILP (p->prev) ? ((*sizefun) (p->prev)
4401 - window_min_size (XWINDOW (p->prev),
4402 horiz_flag, 0, 0, 0))
4403 /* This is a frame with only one window, a minibuffer-only
4404 or a minibufferless frame. */
4405 : (delta = 0));
4406
4407 if (delta > maxdelta)
4408 /* This case traps trying to make the minibuffer
4409 the full frame, or make the only window aside from the
4410 minibuffer the full frame. */
4411 delta = maxdelta;
4412 }
4413 3728
4414 if (XINT (*sizep) + delta < window_min_size (XWINDOW (window), 3729 This function can delete all windows but the selected one in order to
4415 horiz_flag, 0, 0, 0)) 3730 satisfy the request. The result will be meaningful if and only if
3731 F's windows have meaningful sizes when you call this. */
3732void
3733resize_frame_windows (struct frame *f, int size, int horflag)
3734{
3735 Lisp_Object root = f->root_window;
3736 struct window *r = XWINDOW (root);
3737 Lisp_Object mini = f->minibuffer_window;
3738 struct window *m;
3739 /* new_size is the new size of the frame's root window. */
3740 int new_size = (horflag
3741 ? size
3742 : (size
3743 - FRAME_TOP_MARGIN (f)
3744 - ((FRAME_HAS_MINIBUF_P (f) && !FRAME_MINIBUF_ONLY_P (f))
3745 ? 1 : 0)));
3746
3747 XSETFASTINT (r->top_line, FRAME_TOP_MARGIN (f));
3748 if (NILP (r->vchild) && NILP (r->hchild))
3749 /* For a leaf root window just set the size. */
3750 if (horflag)
3751 XSETFASTINT (r->total_cols, new_size);
3752 else
3753 XSETFASTINT (r->total_lines, new_size);
3754 else
4416 { 3755 {
4417 delete_window (window); 3756 /* old_size is the old size of the frame's root window. */
4418 return; 3757 int old_size = XFASTINT (horflag ? r->total_cols : r->total_lines);
4419 } 3758 Lisp_Object delta;
4420
4421 if (delta == 0)
4422 return;
4423 3759
4424 /* Find the total we can get from other siblings without deleting them. */ 3760 XSETINT (delta, new_size - old_size);
4425 maximum = 0; 3761 /* Try a "normal" resize first. */
4426 for (next = p->next; WINDOWP (next); next = XWINDOW (next)->next) 3762 resize_root_window (root, delta, horflag ? Qt : Qnil, Qnil);
4427 maximum += (*sizefun) (next) - window_min_size (XWINDOW (next), 3763 if (resize_window_check (r, horflag) && new_size == XINT (r->new_total))
4428 horiz_flag, 0, 0, 0); 3764 resize_window_apply (r, horflag);
4429 for (prev = p->prev; WINDOWP (prev); prev = XWINDOW (prev)->prev) 3765 else
4430 maximum += (*sizefun) (prev) - window_min_size (XWINDOW (prev),
4431 horiz_flag, 0, 0, 0);
4432
4433 /* If we can get it all from them without deleting them, do so. */
4434 if (delta <= maximum)
4435 {
4436 Lisp_Object first_unaffected;
4437 Lisp_Object first_affected;
4438 int fixed_p;
4439
4440 next = p->next;
4441 prev = p->prev;
4442 first_affected = window;
4443 /* Look at one sibling at a time,
4444 moving away from this window in both directions alternately,
4445 and take as much as we can get without deleting that sibling. */
4446 while (delta != 0
4447 && (!NILP (next) || !NILP (prev)))
4448 { 3766 {
4449 if (! NILP (next)) 3767 /* Try with "reasonable" minimum sizes next. */
4450 { 3768 resize_root_window (root, delta, horflag ? Qt : Qnil, Qt);
4451 int this_one = ((*sizefun) (next) 3769 if (resize_window_check (r, horflag)
4452 - window_min_size (XWINDOW (next), horiz_flag, 3770 && new_size == XINT (r->new_total))
4453 0, 0, &fixed_p)); 3771 resize_window_apply (r, horflag);
4454 if (!fixed_p) 3772 else
4455 {
4456 if (this_one > delta)
4457 this_one = delta;
4458
4459 (*setsizefun) (next, (*sizefun) (next) - this_one, 0);
4460 (*setsizefun) (window, XINT (*sizep) + this_one, 0);
4461
4462 delta -= this_one;
4463 }
4464
4465 next = XWINDOW (next)->next;
4466 }
4467
4468 if (delta == 0)
4469 break;
4470
4471 if (! NILP (prev))
4472 { 3773 {
4473 int this_one = ((*sizefun) (prev) 3774 /* Finally, try with "safe" minimum sizes. */
4474 - window_min_size (XWINDOW (prev), horiz_flag, 3775 resize_root_window (root, delta, horflag ? Qt : Qnil, Qsafe);
4475 0, 0, &fixed_p)); 3776 if (resize_window_check (r, horflag)
4476 if (!fixed_p) 3777 && new_size == XINT (r->new_total))
3778 resize_window_apply (r, horflag);
3779 else
4477 { 3780 {
4478 if (this_one > delta) 3781 /* We lost. Delete all windows but the frame's
4479 this_one = delta; 3782 selected one. */
4480 3783 root = f->selected_window;
4481 first_affected = prev; 3784 Fdelete_other_windows_internal (root, Qnil);
4482 3785 if (horflag)
4483 (*setsizefun) (prev, (*sizefun) (prev) - this_one, 0); 3786 XSETFASTINT (XWINDOW (root)->total_cols, new_size);
4484 (*setsizefun) (window, XINT (*sizep) + this_one, 0); 3787 else
4485 3788 XSETFASTINT (XWINDOW (root)->total_lines, new_size);
4486 delta -= this_one;
4487 } 3789 }
4488
4489 prev = XWINDOW (prev)->prev;
4490 } 3790 }
4491 } 3791 }
4492
4493 xassert (delta == 0);
4494
4495 /* Now recalculate the edge positions of all the windows affected,
4496 based on the new sizes. */
4497 first_unaffected = next;
4498 prev = first_affected;
4499 for (next = XWINDOW (prev)->next; ! EQ (next, first_unaffected);
4500 prev = next, next = XWINDOW (next)->next)
4501 {
4502 XSETINT (CURBEG (next), XINT (CURBEG (prev)) + (*sizefun) (prev));
4503 /* This does not change size of NEXT,
4504 but it propagates the new top edge to its children */
4505 (*setsizefun) (next, (*sizefun) (next), 0);
4506 }
4507 } 3792 }
4508 else
4509 {
4510 register int delta1;
4511 register int opht = (*sizefun) (parent);
4512
4513 if (opht <= XINT (*sizep) + delta)
4514 {
4515 /* If trying to grow this window to or beyond size of the parent,
4516 just delete all the sibling windows. */
4517 Lisp_Object start, tem;
4518
4519 start = XWINDOW (parent)->vchild;
4520 if (NILP (start))
4521 start = XWINDOW (parent)->hchild;
4522 3793
4523 /* Delete any siblings that come after WINDOW. */ 3794 if (FRAME_HAS_MINIBUF_P (f) && !FRAME_MINIBUF_ONLY_P (f))
4524 tem = XWINDOW (window)->next; 3795 {
4525 while (! NILP (tem)) 3796 m = XWINDOW (mini);
4526 { 3797 if (horflag)
4527 Lisp_Object next1 = XWINDOW (tem)->next; 3798 XSETFASTINT (m->total_cols, size);
4528 delete_window (tem);
4529 tem = next1;
4530 }
4531
4532 /* Delete any siblings that come after WINDOW.
4533 Note that if START is not WINDOW, then WINDOW still
4534 has siblings, so WINDOW has not yet replaced its parent. */
4535 tem = start;
4536 while (! EQ (tem, window))
4537 {
4538 Lisp_Object next1 = XWINDOW (tem)->next;
4539 delete_window (tem);
4540 tem = next1;
4541 }
4542 }
4543 else 3799 else
4544 { 3800 {
4545 /* Otherwise, make delta1 just right so that if we add 3801 /* Are we sure we always want 1 line here? */
4546 delta1 lines to this window and to the parent, and then 3802 XSETFASTINT (m->total_lines, 1);
4547 shrink the parent back to its original size, the new 3803 XSETFASTINT (m->top_line, XINT (r->top_line) + XINT (r->total_lines));
4548 proportional size of this window will increase by delta.
4549
4550 The function size_window will compute the new height h'
4551 of the window from delta1 as:
4552
4553 e = delta1/n
4554 x = delta1 - delta1/n * n for the 1st resizable child
4555 h' = h + e + x
4556
4557 where n is the number of children that can be resized.
4558 We can ignore x by choosing a delta1 that is a multiple of
4559 n. We want the height of this window to come out as
4560
4561 h' = h + delta
4562
4563 So, delta1 must be
4564
4565 h + e = h + delta
4566 delta1/n = delta
4567 delta1 = n * delta.
4568
4569 The number of children n equals the number of resizable
4570 children of this window + 1 because we know window itself
4571 is resizable (otherwise we would have signaled an error).
4572
4573 This reasoning is not correct when other windows become too
4574 small and shrink_windows refuses to delete them. Below we
4575 use resize_proportionally to work around this problem. */
4576
4577 struct window *w = XWINDOW (window);
4578 Lisp_Object s;
4579 int n = 1;
4580
4581 for (s = w->next; WINDOWP (s); s = XWINDOW (s)->next)
4582 if (!window_fixed_size_p (XWINDOW (s), horiz_flag, 0))
4583 ++n;
4584 for (s = w->prev; WINDOWP (s); s = XWINDOW (s)->prev)
4585 if (!window_fixed_size_p (XWINDOW (s), horiz_flag, 0))
4586 ++n;
4587
4588 delta1 = n * delta;
4589
4590 /* Add delta1 lines or columns to this window, and to the parent,
4591 keeping things consistent while not affecting siblings. */
4592 XSETINT (CURSIZE (parent), opht + delta1);
4593 (*setsizefun) (window, XINT (*sizep) + delta1, 0);
4594
4595 /* Squeeze out delta1 lines or columns from our parent,
4596 shrinking this window and siblings proportionately. This
4597 brings parent back to correct size. Delta1 was calculated
4598 so this makes this window the desired size, taking it all
4599 out of the siblings.
4600
4601 Temporarily set resize_proportionally to Qt to assure that,
4602 if necessary, shrink_windows deletes smaller windows rather
4603 than shrink this window. */
4604 w->resize_proportionally = Qt;
4605 (*setsizefun) (parent, opht, 0);
4606 w->resize_proportionally = Qnil;
4607 } 3804 }
4608 } 3805 }
3806}
4609 3807
4610 XSETFASTINT (p->last_modified, 0);
4611 XSETFASTINT (p->last_overlay_modified, 0);
4612 3808
4613 /* Adjust glyph matrices. */ 3809DEFUN ("split-window-internal", Fsplit_window_internal, Ssplit_window_internal, 4, 4, 0,
4614 adjust_glyphs (XFRAME (WINDOW_FRAME (XWINDOW (window)))); 3810 doc: /* Split window OLD.
4615} 3811Second argument TOTAL-SIZE specifies the number of lines or columns of the
3812new window. In any case TOTAL-SIZE must be a positive integer
4616 3813
3814Third argument SIDE nil (or `below') specifies that the new window shall
3815be located below WINDOW. SIDE `above' means the new window shall be
3816located above WINDOW. In both cases TOTAL-SIZE specifies the number of
3817lines of the new window including space reserved for the mode and/or
3818header line.
4617 3819
4618/* Adjust the size of WINDOW by DELTA, moving only its trailing edge. 3820SIDE t (or `right') specifies that the new window shall be located on
4619 HORIZ_FLAG nonzero means adjust the width, moving the right edge. 3821the right side of WINDOW. SIDE `left' means the new window shall be
4620 zero means adjust the height, moving the bottom edge. 3822located on the left of WINDOW. In both cases TOTAL-SIZE specifies the
3823number of columns of the new window including space reserved for fringes
3824and the scrollbar or a divider column.
4621 3825
4622 Following siblings of the selected window are resized to fulfill 3826Fourth argument NORMAL-SIZE specifies the normal size of the new window
4623 the size request. If they become too small in the process, they 3827according to the SIDE argument.
4624 are not deleted; instead, we signal an error. */
4625 3828
4626static void 3829The new total and normal sizes of all involved windows must have been
4627adjust_window_trailing_edge (Lisp_Object window, int delta, int horiz_flag) 3830set correctly. See the code of `split-window' for how this is done. */)
3831 (Lisp_Object old, Lisp_Object total_size, Lisp_Object side, Lisp_Object normal_size)
4628{ 3832{
4629 Lisp_Object parent, child; 3833 /* OLD (*o) is the window we have to split. (*p) is either OLD's
4630 struct window *p; 3834 parent window or an internal window we have to install as OLD's new
4631 Lisp_Object old_config = Fcurrent_window_configuration (Qnil); 3835 parent. REFERENCE (*r) must denote a live window, or is set to OLD
4632 int delcount = window_deletion_count; 3836 provided OLD is a leaf window, or to the frame's selected window.
4633 3837 NEW (*n) is the new window created with some parameters taken from
4634 CHECK_WINDOW (window); 3838 REFERENCE (*r). */
3839 register Lisp_Object new, frame, reference;
3840 register struct window *o, *p, *n, *r;
3841 struct frame *f;
3842 int horflag
3843 /* HORFLAG is 1 when we split side-by-side, 0 otherwise. */
3844 = EQ (side, Qt) || EQ (side, Qleft) || EQ (side, Qright);
3845 int do_nest = 0;
3846
3847 CHECK_WINDOW (old);
3848 o = XWINDOW (old);
3849 frame = WINDOW_FRAME (o);
3850 f = XFRAME (frame);
4635 3851
4636 /* Give up if this window cannot be resized. */ 3852 CHECK_NUMBER (total_size);
4637 if (window_fixed_size_p (XWINDOW (window), horiz_flag, 1)) 3853
4638 error ("Window is not resizable"); 3854 /* Set do_nest to 1 if we have to make a new parent window. We do
3855 that if either `window-nest' is non-nil, or OLD has no parent, or
3856 OLD is ortho-combined. */
3857 do_nest =
3858 !NILP (Vwindow_nest)
3859 || NILP (o->parent)
3860 || NILP (horflag
3861 ? (XWINDOW (o->parent)->hchild)
3862 : (XWINDOW (o->parent)->vchild));
3863
3864 /* We need a live reference window to initialize some parameters. */
3865 if (WINDOW_LIVE_P (old))
3866 /* OLD is live, use it as reference window. */
3867 reference = old;
3868 else
3869 /* Use the frame's selected window as reference window. */
3870 reference = FRAME_SELECTED_WINDOW (f);
3871 r = XWINDOW (reference);
4639 3872
4640 while (1) 3873 /* The following bugs are caught by `split-window'. */
3874 if (MINI_WINDOW_P (o))
3875 error ("Attempt to split minibuffer window");
3876 else if (XINT (total_size) < (horflag ? 2 : 1))
3877 error ("Size of new window too small (after split)");
3878 else if (!do_nest && !NILP (Vwindow_splits))
3879 /* `window-splits' non-nil means try to resize OLD's siblings
3880 proportionally. */
3881 {
3882 p = XWINDOW (o->parent);
3883 /* Temporarily pretend we split the parent window. */
3884 XSETINT (p->new_total,
3885 XINT (horflag ? p->total_cols : p->total_lines)
3886 - XINT (total_size));
3887 if (!resize_window_check (p, horflag))
3888 error ("Window sizes don't fit");
3889 else
3890 /* Undo the temporary pretension. */
3891 p->new_total = horflag ? p->total_cols : p->total_lines;
3892 }
3893 else
4641 { 3894 {
4642 Lisp_Object first_parallel = Qnil; 3895 if (!resize_window_check (o, horflag))
4643 3896 error ("Resizing old window failed");
4644 if (NILP (window)) 3897 else if (XINT (total_size) + XINT (o->new_total)
4645 { 3898 != XINT (horflag ? o->total_cols : o->total_lines))
4646 /* This happens if WINDOW on the previous iteration was 3899 error ("Sum of sizes of old and new window don't fit");
4647 at top level of the window tree. */ 3900 }
4648 Fset_window_configuration (old_config); 3901
4649 error ("Specified window edge is fixed"); 3902 /* This is our point of no return. */
4650 } 3903 if (do_nest)
3904 {
3905 /* Save the old value of o->normal_cols/lines. It gets corrupted
3906 by make_parent_window and we need it below for assigning it to
3907 p->new_normal. */
3908 Lisp_Object new_normal = horflag ? o->normal_cols : o->normal_lines;
3909
3910 make_parent_window (old, horflag);
3911 p = XWINDOW (o->parent);
3912 /* Store value of `window-nest' in new parent's nest slot. */
3913 p->nest = Vwindow_nest;
3914 /* Have PARENT inherit splits slot value from OLD. */
3915 p->splits = o->splits;
3916 /* Store value of `window-splits' in OLD's splits slot. */
3917 o->splits = Vwindow_splits;
3918 /* These get applied below. */
3919 p->new_total = horflag ? o->total_cols : o->total_lines;
3920 p->new_normal = new_normal;
3921 }
3922 else
3923 p = XWINDOW (o->parent);
4651 3924
4652 p = XWINDOW (window); 3925 windows_or_buffers_changed++;
4653 parent = p->parent; 3926 FRAME_WINDOW_SIZES_CHANGED (f) = 1;
3927 new = make_window ();
3928 n = XWINDOW (new);
3929 n->frame = frame;
3930 n->parent = o->parent;
3931 n->vchild = n->hchild = Qnil;
4654 3932
4655 /* See if this level has windows in parallel in the specified 3933 if (EQ (side, Qabove) || EQ (side, Qleft))
4656 direction. If so, set FIRST_PARALLEL to the first one. */ 3934 {
4657 if (horiz_flag) 3935 n->prev = o->prev;
4658 { 3936 if (NILP (n->prev))
4659 if (! NILP (parent) && !NILP (XWINDOW (parent)->vchild)) 3937 if (horflag)
4660 first_parallel = XWINDOW (parent)->vchild; 3938 p->hchild = new;
4661 else if (NILP (parent) && !NILP (p->next)) 3939 else
4662 { 3940 p->vchild = new;
4663 /* Handle the vertical chain of main window and minibuffer
4664 which has no parent. */
4665 first_parallel = window;
4666 while (! NILP (XWINDOW (first_parallel)->prev))
4667 first_parallel = XWINDOW (first_parallel)->prev;
4668 }
4669 }
4670 else 3941 else
4671 { 3942 XWINDOW (n->prev)->next = new;
4672 if (! NILP (parent) && !NILP (XWINDOW (parent)->hchild)) 3943 n->next = old;
4673 first_parallel = XWINDOW (parent)->hchild; 3944 o->prev = new;
4674 } 3945 }
4675 3946 else
4676 /* If this level's succession is in the desired dimension, 3947 {
4677 and this window is the last one, and there is no higher level, 3948 n->next = o->next;
4678 its trailing edge is fixed. */ 3949 if (!NILP (n->next))
4679 if (NILP (XWINDOW (window)->next) && NILP (first_parallel) 3950 XWINDOW (n->next)->prev = new;
4680 && NILP (parent)) 3951 n->prev = old;
4681 { 3952 o->next = new;
4682 Fset_window_configuration (old_config); 3953 }
4683 error ("Specified window edge is fixed");
4684 }
4685
4686 /* Don't make this window too small. */
4687 if (XINT (CURSIZE (window)) + delta
4688 < window_min_size_2 (XWINDOW (window), horiz_flag, 0))
4689 {
4690 Fset_window_configuration (old_config);
4691 error ("Cannot adjust window size as specified");
4692 }
4693 3954
4694 /* Clear out some redisplay caches. */ 3955 n->buffer = Qt;
4695 XSETFASTINT (p->last_modified, 0); 3956 n->window_end_valid = Qnil;
4696 XSETFASTINT (p->last_overlay_modified, 0); 3957 memset (&n->last_cursor, 0, sizeof n->last_cursor);
4697 3958
4698 /* Adjust this window's edge. */ 3959 /* Get special geometry settings from reference window. */
4699 XSETINT (CURSIZE (window), 3960 n->left_margin_cols = r->left_margin_cols;
4700 XINT (CURSIZE (window)) + delta); 3961 n->right_margin_cols = r->right_margin_cols;
3962 n->left_fringe_width = r->left_fringe_width;
3963 n->right_fringe_width = r->right_fringe_width;
3964 n->fringes_outside_margins = r->fringes_outside_margins;
3965 n->scroll_bar_width = r->scroll_bar_width;
3966 n->vertical_scroll_bar_type = r->vertical_scroll_bar_type;
4701 3967
4702 /* If this window has following siblings in the desired dimension, 3968 /* Store `window-splits' in NEW's splits slot. */
4703 make them smaller, and exit the loop. 3969 n->splits = Vwindow_splits;
4704 3970
4705 (If we reach the top of the tree and can never do this, 3971 /* Directly assign orthogonal coordinates and sizes. */
4706 we will fail and report an error, above.) */ 3972 if (horflag)
4707 if (NILP (first_parallel)) 3973 {
4708 { 3974 n->top_line = o->top_line;
4709 if (!NILP (p->next)) 3975 n->total_lines = o->total_lines;
4710 {
4711 /* This may happen for the minibuffer. In that case
4712 the window_deletion_count check below does not work. */
4713 if (XINT (CURSIZE (p->next)) - delta <= 0)
4714 {
4715 Fset_window_configuration (old_config);
4716 error ("Cannot adjust window size as specified");
4717 }
4718
4719 XSETINT (CURBEG (p->next),
4720 XINT (CURBEG (p->next)) + delta);
4721 size_window (p->next, XINT (CURSIZE (p->next)) - delta,
4722 horiz_flag, 0, 1, 0);
4723 break;
4724 }
4725 }
4726 else
4727 /* Here we have a chain of parallel siblings, in the other dimension.
4728 Change the size of the other siblings. */
4729 for (child = first_parallel;
4730 ! NILP (child);
4731 child = XWINDOW (child)->next)
4732 if (! EQ (child, window))
4733 size_window (child, XINT (CURSIZE (child)) + delta,
4734 horiz_flag, 0, 0, 1);
4735
4736 window = parent;
4737 } 3976 }
4738 3977 else
4739 /* If we made a window so small it got deleted,
4740 we failed. Report failure. */
4741 if (delcount != window_deletion_count)
4742 { 3978 {
4743 Fset_window_configuration (old_config); 3979 n->left_col = o->left_col;
4744 error ("Cannot adjust window size as specified"); 3980 n->total_cols = o->total_cols;
4745 } 3981 }
4746 3982
4747 /* Adjust glyph matrices. */ 3983 /* Iso-coordinates and sizes are assigned by resize_window_apply,
4748 adjust_glyphs (XFRAME (WINDOW_FRAME (XWINDOW (window)))); 3984 get them ready here. */
4749} 3985 n->new_total = total_size;
4750 3986 n->new_normal = normal_size;
4751#undef CURBEG
4752#undef CURSIZE
4753
4754DEFUN ("adjust-window-trailing-edge", Fadjust_window_trailing_edge,
4755 Sadjust_window_trailing_edge, 3, 3, 0,
4756 doc: /* Adjust the bottom or right edge of WINDOW by DELTA.
4757If HORIZONTAL is non-nil, that means adjust the width, moving the right edge.
4758Otherwise, adjust the height, moving the bottom edge.
4759 3987
4760Following siblings of the selected window are resized to fulfill 3988 BLOCK_INPUT;
4761the size request. If they become too small in the process, they 3989 resize_window_apply (p, horflag);
4762are not deleted; instead, we signal an error. */) 3990 adjust_glyphs (f);
4763 (Lisp_Object window, Lisp_Object delta, Lisp_Object horizontal) 3991 /* Set buffer of NEW to buffer of reference window. Don't run
4764{ 3992 any hooks. */
4765 CHECK_NUMBER (delta); 3993 set_window_buffer (new, r->buffer, 0, 1);
4766 if (NILP (window)) 3994 UNBLOCK_INPUT;
4767 window = selected_window;
4768 adjust_window_trailing_edge (window, XINT (delta), !NILP (horizontal));
4769
4770 run_window_configuration_change_hook
4771 (XFRAME (WINDOW_FRAME (XWINDOW (window))));
4772 3995
4773 return Qnil; 3996 /* Maybe we should run the scroll functions in Elisp (which already
3997 runs the configuration change hook). */
3998 if (! NILP (Vwindow_scroll_functions))
3999 run_hook_with_args_2 (Qwindow_scroll_functions, new,
4000 Fmarker_position (n->start));
4001 /* Return NEW. */
4002 return new;
4774} 4003}
4775 4004
4776 4005
4777 4006DEFUN ("delete-window-internal", Fdelete_window_internal, Sdelete_window_internal, 1, 1, 0,
4778/*********************************************************************** 4007 doc: /* Remove WINDOW from its frame.
4779 Resizing Mini-Windows 4008WINDOW defaults to the selected window. Return nil. Signal an error
4780 ***********************************************************************/ 4009when WINDOW is the only window on its frame. */)
4781 4010 (register Lisp_Object window)
4782static void shrink_window_lowest_first (struct window *, int);
4783
4784enum save_restore_action
4785{ 4011{
4786 CHECK_ORIG_SIZES, 4012 register Lisp_Object parent, sibling, frame, root;
4787 SAVE_ORIG_SIZES, 4013 struct window *w, *p, *s, *r;
4788 RESTORE_ORIG_SIZES 4014 struct frame *f;
4789}; 4015 int horflag;
4790 4016 int before_sibling = 0;
4791static int save_restore_orig_size (struct window *,
4792 enum save_restore_action);
4793
4794/* Shrink windows rooted in window W to HEIGHT. Take the space needed
4795 from lowest windows first. */
4796 4017
4797static void 4018 w = decode_any_window (window);
4798shrink_window_lowest_first (struct window *w, int height) 4019 XSETWINDOW (window, w);
4799{ 4020 if (NILP (w->buffer) && NILP (w->hchild) && NILP (w->vchild))
4800 struct window *c; 4021 /* It's a no-op to delete an already deleted window. */
4801 Lisp_Object child; 4022 return Qnil;
4802 int old_height;
4803 4023
4804 xassert (!MINI_WINDOW_P (w)); 4024 parent = w->parent;
4025 if (NILP (parent))
4026 /* Never delete a minibuffer or frame root window. */
4027 error ("Attempt to delete minibuffer or sole ordinary window");
4028 else if (NILP (w->prev) && NILP (w->next))
4029 /* Rather bow out here, this case should be handled on the Elisp
4030 level. */
4031 error ("Attempt to delete sole window of parent");
4805 4032
4806 /* Set redisplay hints. */ 4033 p = XWINDOW (parent);
4807 XSETFASTINT (w->last_modified, 0); 4034 horflag = NILP (p->vchild);
4808 XSETFASTINT (w->last_overlay_modified, 0);
4809 windows_or_buffers_changed++;
4810 FRAME_WINDOW_SIZES_CHANGED (XFRAME (WINDOW_FRAME (w))) = 1;
4811 4035
4812 old_height = XFASTINT (w->total_lines); 4036 frame = WINDOW_FRAME (w);
4813 XSETFASTINT (w->total_lines, height); 4037 f = XFRAME (frame);
4814 4038
4815 if (!NILP (w->hchild)) 4039 root = FRAME_ROOT_WINDOW (f);
4040 r = XWINDOW (root);
4041
4042 /* Unlink WINDOW from window tree. */
4043 if (NILP (w->prev))
4044 /* Get SIBLING below (on the right of) WINDOW. */
4045 {
4046 /* before_sibling 1 means WINDOW is the first child of its
4047 parent and thus before the sibling. */
4048 before_sibling = 1;
4049 sibling = w->next;
4050 s = XWINDOW (sibling);
4051 s->prev = Qnil;
4052 if (horflag)
4053 p->hchild = sibling;
4054 else
4055 p->vchild = sibling;
4056 }
4057 else
4058 /* Get SIBLING above (on the left of) WINDOW. */
4816 { 4059 {
4817 for (child = w->hchild; !NILP (child); child = c->next) 4060 sibling = w->prev;
4818 { 4061 s = XWINDOW (sibling);
4819 c = XWINDOW (child); 4062 s->next = w->next;
4820 c->top_line = w->top_line; 4063 if (!NILP (s->next))
4821 shrink_window_lowest_first (c, height); 4064 XWINDOW (s->next)->prev = sibling;
4822 }
4823 } 4065 }
4824 else if (!NILP (w->vchild)) 4066
4067 if (resize_window_check (r, horflag)
4068 && EQ (r->new_total, (horflag ? r->total_cols : r->total_lines)))
4069 /* We can delete WINDOW now. */
4825 { 4070 {
4826 Lisp_Object last_child; 4071 /* Block input. */
4827 int delta = old_height - height; 4072 BLOCK_INPUT;
4828 int last_top; 4073 resize_window_apply (p, horflag);
4829 4074
4830 last_child = Qnil; 4075 windows_or_buffers_changed++;
4076 Vwindow_list = Qnil;
4077 FRAME_WINDOW_SIZES_CHANGED (f) = 1;
4831 4078
4832 /* Find the last child. We are taking space from lowest windows 4079 w->next = Qnil; /* Don't delete w->next too. */
4833 first, so we iterate over children from the last child 4080 free_window_matrices (w);
4834 backwards. */
4835 for (child = w->vchild; WINDOWP (child); child = XWINDOW (child)->next)
4836 last_child = child;
4837 4081
4838 /* Size children down to their safe heights. */ 4082 if (!NILP (w->vchild))
4839 for (child = last_child; delta && !NILP (child); child = c->prev)
4840 { 4083 {
4841 int this_one; 4084 delete_all_subwindows (w->vchild);
4842 4085 w->vchild = Qnil;
4843 c = XWINDOW (child);
4844 this_one = XFASTINT (c->total_lines) - window_min_size_1 (c, 0, 1);
4845
4846 if (this_one > delta)
4847 this_one = delta;
4848
4849 shrink_window_lowest_first (c, XFASTINT (c->total_lines) - this_one);
4850 delta -= this_one;
4851 } 4086 }
4852 4087 else if (!NILP (w->hchild))
4853 /* Compute new positions. */
4854 last_top = XINT (w->top_line);
4855 for (child = w->vchild; !NILP (child); child = c->next)
4856 { 4088 {
4857 c = XWINDOW (child); 4089 delete_all_subwindows (w->hchild);
4858 c->top_line = make_number (last_top); 4090 w->hchild = Qnil;
4859 shrink_window_lowest_first (c, XFASTINT (c->total_lines)); 4091 }
4860 last_top += XFASTINT (c->total_lines); 4092 else if (!NILP (w->buffer))
4093 {
4094 unshow_buffer (w);
4095 unchain_marker (XMARKER (w->pointm));
4096 unchain_marker (XMARKER (w->start));
4097 w->buffer = Qnil;
4861 } 4098 }
4862 }
4863}
4864 4099
4100 if (NILP (s->prev) && NILP (s->next))
4101 /* A matrjoshka where SIBLING has become the only child of
4102 PARENT. */
4103 {
4104 /* Put SIBLING into PARENT's place. */
4105 replace_window (parent, sibling, 0);
4106 /* Have SIBLING inherit the following three slot values from
4107 PARENT (the nest slot is not inherited). */
4108 s->normal_cols = p->normal_cols;
4109 s->normal_lines = p->normal_lines;
4110 s->splits = p->splits;
4111 /* Mark PARENT as deleted. */
4112 p->vchild = p->hchild = Qnil;
4113 /* Try to merge SIBLING into its new parent. */
4114 recombine_windows (sibling);
4115 }
4865 4116
4866/* Save, restore, or check positions and sizes in the window tree 4117 adjust_glyphs (f);
4867 rooted at W. ACTION says what to do.
4868 4118
4869 If ACTION is CHECK_ORIG_SIZES, check if orig_top_line and 4119 if (!WINDOW_LIVE_P (FRAME_SELECTED_WINDOW (f)))
4870 orig_total_lines members are valid for all windows in the window 4120 /* We deleted the frame's selected window. */
4871 tree. Value is non-zero if they are valid. 4121 {
4122 /* Use the frame's first window as fallback ... */
4123 Lisp_Object new_selected_window = Fframe_first_window (frame);
4124 /* ... but preferably use its most recently used window. */
4125 Lisp_Object mru_window;
4126
4127 /* `get-mru-window' might fail for some reason so play it safe
4128 - promote the first window _without recording it_ first. */
4129 if (EQ (FRAME_SELECTED_WINDOW (f), selected_window))
4130 Fselect_window (new_selected_window, Qt);
4131 else
4132 FRAME_SELECTED_WINDOW (f) = new_selected_window;
4872 4133
4873 If ACTION is SAVE_ORIG_SIZES, save members top and height in 4134 UNBLOCK_INPUT;
4874 orig_top_line and orig_total_lines for all windows in the tree.
4875 4135
4876 If ACTION is RESTORE_ORIG_SIZES, restore top and height from values 4136 /* Now look whether `get-mru-window' gets us something. */
4877 stored in orig_top_line and orig_total_lines for all windows. */ 4137 mru_window = call1 (Qget_mru_window, frame);
4138 if (WINDOW_LIVE_P (mru_window)
4139 && EQ (XWINDOW (mru_window)->frame, frame))
4140 new_selected_window = mru_window;
4878 4141
4879static int 4142 /* If all ended up well, we now promote the mru window. */
4880save_restore_orig_size (struct window *w, enum save_restore_action action) 4143 if (EQ (FRAME_SELECTED_WINDOW (f), selected_window))
4881{ 4144 Fselect_window (new_selected_window, Qnil);
4882 int success_p = 1; 4145 else
4146 FRAME_SELECTED_WINDOW (f) = new_selected_window;
4147 }
4148 else
4149 UNBLOCK_INPUT;
4883 4150
4884 while (w) 4151 /* Must be run by the caller:
4152 run_window_configuration_change_hook (f); */
4153 }
4154 else
4155 /* We failed: Relink WINDOW into window tree. */
4885 { 4156 {
4886 if (!NILP (w->hchild)) 4157 if (before_sibling)
4887 {
4888 if (!save_restore_orig_size (XWINDOW (w->hchild), action))
4889 success_p = 0;
4890 }
4891 else if (!NILP (w->vchild))
4892 { 4158 {
4893 if (!save_restore_orig_size (XWINDOW (w->vchild), action)) 4159 s->prev = window;
4894 success_p = 0; 4160 if (horflag)
4161 p->hchild = window;
4162 else
4163 p->vchild = window;
4895 } 4164 }
4896 4165 else
4897 switch (action)
4898 { 4166 {
4899 case CHECK_ORIG_SIZES: 4167 s->next = window;
4900 if (!INTEGERP (w->orig_top_line) || !INTEGERP (w->orig_total_lines)) 4168 if (!NILP (w->next))
4901 return 0; 4169 XWINDOW (w->next)->prev = window;
4902 break;
4903
4904 case SAVE_ORIG_SIZES:
4905 w->orig_top_line = w->top_line;
4906 w->orig_total_lines = w->total_lines;
4907 XSETFASTINT (w->last_modified, 0);
4908 XSETFASTINT (w->last_overlay_modified, 0);
4909 break;
4910
4911 case RESTORE_ORIG_SIZES:
4912 xassert (INTEGERP (w->orig_top_line) && INTEGERP (w->orig_total_lines));
4913 w->top_line = w->orig_top_line;
4914 w->total_lines = w->orig_total_lines;
4915 w->orig_total_lines = w->orig_top_line = Qnil;
4916 XSETFASTINT (w->last_modified, 0);
4917 XSETFASTINT (w->last_overlay_modified, 0);
4918 break;
4919
4920 default:
4921 abort ();
4922 } 4170 }
4923 4171 error ("Deletion failed");
4924 w = NILP (w->next) ? NULL : XWINDOW (w->next);
4925 } 4172 }
4926 4173
4927 return success_p; 4174 return Qnil;
4928} 4175}
4176
4177/***********************************************************************
4178 Resizing Mini-Windows
4179 ***********************************************************************/
4929 4180
4930 4181/* Grow mini-window W by DELTA lines, DELTA >= 0, or as much as we
4931/* Grow mini-window W by DELTA lines, DELTA >= 0, or as much as we can 4182 can. */
4932 without deleting other windows. */
4933
4934void 4183void
4935grow_mini_window (struct window *w, int delta) 4184grow_mini_window (struct window *w, int delta)
4936{ 4185{
4937 struct frame *f = XFRAME (w->frame); 4186 struct frame *f = XFRAME (w->frame);
4938 struct window *root; 4187 struct window *r;
4188 Lisp_Object root, value;
4939 4189
4940 xassert (MINI_WINDOW_P (w)); 4190 xassert (MINI_WINDOW_P (w));
4941 /* Commenting out the following assertion goes against the stated interface 4191 xassert (delta >= 0);
4942 of the function, but it currently does not seem to do anything useful.
4943 See discussion of this issue in the thread for bug#4534.
4944 xassert (delta >= 0); */
4945 4192
4946 /* Compute how much we can enlarge the mini-window without deleting 4193 root = FRAME_ROOT_WINDOW (f);
4947 other windows. */ 4194 r = XWINDOW (root);
4948 root = XWINDOW (FRAME_ROOT_WINDOW (f)); 4195 value = call2 (Qresize_root_window_vertically, root, make_number (- delta));
4949 if (delta > 0) 4196 if (INTEGERP (value) && resize_window_check (r, 0))
4950 { 4197 {
4951 int min_height = window_min_size (root, 0, 0, 0, 0); 4198 BLOCK_INPUT;
4952 if (XFASTINT (root->total_lines) - delta < min_height) 4199 resize_window_apply (r, 0);
4953 /* Note that the root window may already be smaller than
4954 min_height. */
4955 delta = max (0, XFASTINT (root->total_lines) - min_height);
4956 }
4957
4958 if (delta)
4959 {
4960 /* Save original window sizes and positions, if not already done. */
4961 if (!save_restore_orig_size (root, CHECK_ORIG_SIZES))
4962 save_restore_orig_size (root, SAVE_ORIG_SIZES);
4963
4964 /* Shrink other windows. */
4965 shrink_window_lowest_first (root, XFASTINT (root->total_lines) - delta);
4966 4200
4967 /* Grow the mini-window. */ 4201 /* Grow the mini-window. */
4968 w->top_line = make_number (XFASTINT (root->top_line) + XFASTINT (root->total_lines)); 4202 XSETFASTINT (w->top_line, XFASTINT (r->top_line) + XFASTINT (r->total_lines));
4969 w->total_lines = make_number (XFASTINT (w->total_lines) + delta); 4203 XSETFASTINT (w->total_lines, XFASTINT (w->total_lines) - XINT (value));
4970 XSETFASTINT (w->last_modified, 0); 4204 XSETFASTINT (w->last_modified, 0);
4971 XSETFASTINT (w->last_overlay_modified, 0); 4205 XSETFASTINT (w->last_overlay_modified, 0);
4972 4206
4973 adjust_glyphs (f); 4207 adjust_glyphs (f);
4208 UNBLOCK_INPUT;
4974 } 4209 }
4975} 4210}
4976 4211
4977 4212
4978/* Shrink mini-window W. If there is recorded info about window sizes 4213/* Shrink mini-window W. */
4979 before a call to grow_mini_window, restore recorded window sizes.
4980 Otherwise, if the mini-window is higher than 1 line, resize it to 1
4981 line. */
4982
4983void 4214void
4984shrink_mini_window (struct window *w) 4215shrink_mini_window (struct window *w)
4985{ 4216{
4986 struct frame *f = XFRAME (w->frame); 4217 struct frame *f = XFRAME (w->frame);
4987 struct window *root = XWINDOW (FRAME_ROOT_WINDOW (f)); 4218 struct window *r;
4219 Lisp_Object root, value;
4220 EMACS_INT size;
4988 4221
4989 if (save_restore_orig_size (root, CHECK_ORIG_SIZES)) 4222 xassert (MINI_WINDOW_P (w));
4990 { 4223
4991 save_restore_orig_size (root, RESTORE_ORIG_SIZES); 4224 size = XINT (w->total_lines);
4992 adjust_glyphs (f); 4225 if (size > 1)
4993 FRAME_WINDOW_SIZES_CHANGED (f) = 1;
4994 windows_or_buffers_changed = 1;
4995 }
4996 else if (XFASTINT (w->total_lines) > 1)
4997 { 4226 {
4998 /* Distribute the additional lines of the mini-window 4227 root = FRAME_ROOT_WINDOW (f);
4999 among the other windows. */ 4228 r = XWINDOW (root);
5000 Lisp_Object window; 4229 value = call2 (Qresize_root_window_vertically,
5001 XSETWINDOW (window, w); 4230 root, make_number (size - 1));
5002 enlarge_window (window, 1 - XFASTINT (w->total_lines), 0); 4231 if (INTEGERP (value) && resize_window_check (r, 0))
4232 {
4233 BLOCK_INPUT;
4234 resize_window_apply (r, 0);
4235
4236 /* Shrink the mini-window. */
4237 XSETFASTINT (w->top_line, XFASTINT (r->top_line) + XFASTINT (r->total_lines));
4238 XSETFASTINT (w->total_lines, 1);
4239
4240 XSETFASTINT (w->last_modified, 0);
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. */
5003 } 4250 }
5004} 4251}
5005 4252
4253DEFUN ("resize-mini-window-internal", Fresize_mini_window_internal, Sresize_mini_window_internal, 1, 1, 0,
4254 doc: /* Resize minibuffer window WINDOW. */)
4255 (Lisp_Object window)
4256{
4257 struct window *w = XWINDOW (window);
4258 struct window *r;
4259 struct frame *f;
4260 int height;
5006 4261
4262 CHECK_WINDOW (window);
4263 f = XFRAME (w->frame);
4264
4265 if (!EQ (FRAME_MINIBUF_WINDOW (XFRAME (w->frame)), window))
4266 error ("Not a valid minibuffer window");
4267 else if (FRAME_MINIBUF_ONLY_P (f))
4268 error ("Cannot resize a minibuffer-only frame");
4269
4270 r = XWINDOW (FRAME_ROOT_WINDOW (f));
4271 height = XINT (r->total_lines) + XINT (w->total_lines);
4272 if (resize_window_check (r, 0)
4273 && XINT (w->new_total) > 0
4274 && height == XINT (r->new_total) + XINT (w->new_total))
4275 {
4276 BLOCK_INPUT;
4277 resize_window_apply (r, 0);
4278
4279 w->total_lines = w->new_total;
4280 XSETFASTINT (w->top_line, XINT (r->top_line) + XINT (r->total_lines));
4281
4282 windows_or_buffers_changed++;
4283 FRAME_WINDOW_SIZES_CHANGED (f) = 1;
4284 adjust_glyphs (f);
4285 UNBLOCK_INPUT;
4286
4287 run_window_configuration_change_hook (f);
4288 return Qt;
4289 }
4290 else error ("Failed to resize minibuffer window");
4291}
4292
5007 4293
5008/* 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
5009 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
@@ -6190,11 +5476,9 @@ struct saved_window
6190 Lisp_Object parent, prev; 5476 Lisp_Object parent, prev;
6191 Lisp_Object start_at_line_beg; 5477 Lisp_Object start_at_line_beg;
6192 Lisp_Object display_table; 5478 Lisp_Object display_table;
6193 Lisp_Object orig_top_line, orig_total_lines;
6194 Lisp_Object left_margin_cols, right_margin_cols; 5479 Lisp_Object left_margin_cols, right_margin_cols;
6195 Lisp_Object left_fringe_width, right_fringe_width, fringes_outside_margins; 5480 Lisp_Object left_fringe_width, right_fringe_width, fringes_outside_margins;
6196 Lisp_Object scroll_bar_width, vertical_scroll_bar_type; 5481 Lisp_Object scroll_bar_width, vertical_scroll_bar_type, dedicated;
6197 Lisp_Object dedicated, resize_proportionally;
6198 Lisp_Object splits, nest, window_parameters; 5482 Lisp_Object splits, nest, window_parameters;
6199}; 5483};
6200 5484
@@ -6414,8 +5698,6 @@ the return value is nil. Otherwise the value is t. */)
6414 w->hscroll = p->hscroll; 5698 w->hscroll = p->hscroll;
6415 w->min_hscroll = p->min_hscroll; 5699 w->min_hscroll = p->min_hscroll;
6416 w->display_table = p->display_table; 5700 w->display_table = p->display_table;
6417 w->orig_top_line = p->orig_top_line;
6418 w->orig_total_lines = p->orig_total_lines;
6419 w->left_margin_cols = p->left_margin_cols; 5701 w->left_margin_cols = p->left_margin_cols;
6420 w->right_margin_cols = p->right_margin_cols; 5702 w->right_margin_cols = p->right_margin_cols;
6421 w->left_fringe_width = p->left_fringe_width; 5703 w->left_fringe_width = p->left_fringe_width;
@@ -6427,7 +5709,6 @@ the return value is nil. Otherwise the value is t. */)
6427 w->splits = p->splits; 5709 w->splits = p->splits;
6428 w->nest = p->nest; 5710 w->nest = p->nest;
6429 w->window_parameters = p->window_parameters; 5711 w->window_parameters = p->window_parameters;
6430 w->resize_proportionally = p->resize_proportionally;
6431 XSETFASTINT (w->last_modified, 0); 5712 XSETFASTINT (w->last_modified, 0);
6432 XSETFASTINT (w->last_overlay_modified, 0); 5713 XSETFASTINT (w->last_overlay_modified, 0);
6433 5714
@@ -6556,6 +5837,7 @@ the return value is nil. Otherwise the value is t. */)
6556 return (FRAME_LIVE_P (f) ? Qt : Qnil); 5837 return (FRAME_LIVE_P (f) ? Qt : Qnil);
6557} 5838}
6558 5839
5840
6559/* Delete all subwindows reachable via the next, vchild, and hchild 5841/* Delete all subwindows reachable via the next, vchild, and hchild
6560 slots of WINDOW. */ 5842 slots of WINDOW. */
6561void 5843void
@@ -6608,7 +5890,6 @@ count_windows (register struct window *window)
6608 5890
6609/* 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.
6610 Value is last index + 1. */ 5892 Value is last index + 1. */
6611
6612static int 5893static int
6613get_leaf_windows (struct window *w, struct window **flat, int i) 5894get_leaf_windows (struct window *w, struct window **flat, int i)
6614{ 5895{
@@ -6631,7 +5912,6 @@ get_leaf_windows (struct window *w, struct window **flat, int i)
6631/* 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
6632 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
6633 can be returned. */ 5914 can be returned. */
6634
6635struct glyph * 5915struct glyph *
6636get_phys_cursor_glyph (struct window *w) 5916get_phys_cursor_glyph (struct window *w)
6637{ 5917{
@@ -6676,8 +5956,6 @@ save_window_save (Lisp_Object window, struct Lisp_Vector *vector, int i)
6676 p->hscroll = w->hscroll; 5956 p->hscroll = w->hscroll;
6677 p->min_hscroll = w->min_hscroll; 5957 p->min_hscroll = w->min_hscroll;
6678 p->display_table = w->display_table; 5958 p->display_table = w->display_table;
6679 p->orig_top_line = w->orig_top_line;
6680 p->orig_total_lines = w->orig_total_lines;
6681 p->left_margin_cols = w->left_margin_cols; 5959 p->left_margin_cols = w->left_margin_cols;
6682 p->right_margin_cols = w->right_margin_cols; 5960 p->right_margin_cols = w->right_margin_cols;
6683 p->left_fringe_width = w->left_fringe_width; 5961 p->left_fringe_width = w->left_fringe_width;
@@ -6688,7 +5966,6 @@ save_window_save (Lisp_Object window, struct Lisp_Vector *vector, int i)
6688 p->dedicated = w->dedicated; 5966 p->dedicated = w->dedicated;
6689 p->splits = w->splits; 5967 p->splits = w->splits;
6690 p->nest = w->nest; 5968 p->nest = w->nest;
6691 p->resize_proportionally = w->resize_proportionally;
6692 p->window_parameters = w->window_parameters; 5969 p->window_parameters = w->window_parameters;
6693 if (!NILP (w->buffer)) 5970 if (!NILP (w->buffer))
6694 { 5971 {
@@ -7382,10 +6659,6 @@ syms_of_window (void)
7382 Fput (Qscroll_up, Qscroll_command, Qt); 6659 Fput (Qscroll_up, Qscroll_command, Qt);
7383 Fput (Qscroll_down, Qscroll_command, Qt); 6660 Fput (Qscroll_down, Qscroll_command, Qt);
7384 6661
7385 Qwindow_size_fixed = intern_c_string ("window-size-fixed");
7386 staticpro (&Qwindow_size_fixed);
7387 Fset (Qwindow_size_fixed, Qnil);
7388
7389 staticpro (&Qwindow_configuration_change_hook); 6662 staticpro (&Qwindow_configuration_change_hook);
7390 Qwindow_configuration_change_hook 6663 Qwindow_configuration_change_hook
7391 = intern_c_string ("window-configuration-change-hook"); 6664 = intern_c_string ("window-configuration-change-hook");
@@ -7478,24 +6751,6 @@ is displayed in the `mode-line' face. */);
7478 doc: /* *Number of lines of continuity when scrolling by screenfuls. */); 6751 doc: /* *Number of lines of continuity when scrolling by screenfuls. */);
7479 next_screen_context_lines = 2; 6752 next_screen_context_lines = 2;
7480 6753
7481 DEFVAR_INT ("window-min-height", window_min_height,
7482 doc: /* Allow deleting windows less than this tall.
7483The value is measured in line units. If a window wants a modeline it
7484is counted as one line.
7485
7486Emacs honors settings of this variable when enlarging or shrinking
7487windows vertically. A value less than 1 is invalid. */);
7488 window_min_height = 4;
7489
7490 DEFVAR_INT ("window-min-width", window_min_width,
7491 doc: /* Allow deleting windows less than this wide.
7492The value is measured in characters and includes any fringes or
7493the scrollbar.
7494
7495Emacs honors settings of this variable when enlarging or shrinking
7496windows horizontally. A value less than 2 is invalid. */);
7497 window_min_width = 10;
7498
7499 DEFVAR_LISP ("scroll-preserve-screen-position", 6754 DEFVAR_LISP ("scroll-preserve-screen-position",
7500 Vscroll_preserve_screen_position, 6755 Vscroll_preserve_screen_position,
7501 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.
@@ -7527,6 +6782,41 @@ will redraw the entire frame; the special value `tty' causes the
7527frame to be redrawn only if it is a tty frame. */); 6782frame to be redrawn only if it is a tty frame. */);
7528 Vrecenter_redisplay = Qtty; 6783 Vrecenter_redisplay = Qtty;
7529 6784
6785 DEFVAR_LISP ("window-splits", Vwindow_splits,
6786 doc: /* Non-nil means splitting windows is handled specially.
6787If this variable is nil, splitting a window gets the entire screen space
6788for displaying the new window from the window to split. If this
6789variable is non-nil, splitting a window may resize all windows in the
6790same combination. This also allows to split a window that is otherwise
6791too small or of fixed size.
6792
6793The value of this variable is also assigned to the split status of the
6794new window and, provided the old and new window form a new combination,
6795to the window that was split as well. The split status of a window can
6796be retrieved with the function `window-splits' and altered by the
6797function `set-window-splits'.
6798
6799If the value of the variable `window-nest' is non-nil, the space for the
6800new window is exclusively taken from the window that shall be split, but
6801the split status of the window that is split as well as that of the new
6802window are still set to the value of this variable. */);
6803 Vwindow_splits = Qnil;
6804
6805 DEFVAR_LISP ("window-nest", Vwindow_nest,
6806 doc: /* Non-nil means splitting a window makes a new parent window.
6807If this variable is nil, splitting a window will create a new parent
6808window only if the window has no parent window or the window shall
6809become a combination orthogonal to the one it it is part of.
6810
6811If this variable is non-nil, splitting a window always creates a new
6812parent window. If all splits behave this way, each frame's window tree
6813is a binary tree and every window but the frame's root window has
6814exactly one sibling.
6815
6816The value of this variable is also assigned to the nest status of the
6817new parent window. The nest status of a window can be retrieved via the
6818function `window-nest' and altered by the function `set-window-nest'. */);
6819 Vwindow_nest = Qnil;
7530 6820
7531 defsubr (&Sselected_window); 6821 defsubr (&Sselected_window);
7532 defsubr (&Sminibuffer_window); 6822 defsubr (&Sminibuffer_window);
@@ -7560,6 +6850,7 @@ frame to be redrawn only if it is a tty frame. */);
7560 defsubr (&Swindow_new_normal); 6850 defsubr (&Swindow_new_normal);
7561 defsubr (&Sset_window_new_total); 6851 defsubr (&Sset_window_new_total);
7562 defsubr (&Sset_window_new_normal); 6852 defsubr (&Sset_window_new_normal);
6853 defsubr (&Sresize_window_apply);
7563 defsubr (&Swindow_body_size); 6854 defsubr (&Swindow_body_size);
7564 defsubr (&Swindow_hscroll); 6855 defsubr (&Swindow_hscroll);
7565 defsubr (&Sset_window_hscroll); 6856 defsubr (&Sset_window_hscroll);
@@ -7586,19 +6877,18 @@ frame to be redrawn only if it is a tty frame. */);
7586 defsubr (&Sprevious_window); 6877 defsubr (&Sprevious_window);
7587 defsubr (&Sother_window); 6878 defsubr (&Sother_window);
7588 defsubr (&Sget_buffer_window); 6879 defsubr (&Sget_buffer_window);
7589 defsubr (&Sdelete_other_windows);
7590 defsubr (&Sdelete_windows_on); 6880 defsubr (&Sdelete_windows_on);
7591 defsubr (&Sreplace_buffer_in_windows); 6881 defsubr (&Sreplace_buffer_in_windows);
7592 defsubr (&Sdelete_window); 6882 defsubr (&Sdelete_other_windows_internal);
6883 defsubr (&Sdelete_window_internal);
6884 defsubr (&Sresize_mini_window_internal);
7593 defsubr (&Sset_window_buffer); 6885 defsubr (&Sset_window_buffer);
7594 defsubr (&Sset_window_clone_number); 6886 defsubr (&Sset_window_clone_number);
6887 defsubr (&Srun_window_configuration_change_hook);
7595 defsubr (&Sselect_window); 6888 defsubr (&Sselect_window);
7596 defsubr (&Sforce_window_update); 6889 defsubr (&Sforce_window_update);
7597 defsubr (&Stemp_output_buffer_show); 6890 defsubr (&Stemp_output_buffer_show);
7598 defsubr (&Ssplit_window); 6891 defsubr (&Ssplit_window_internal);
7599 defsubr (&Senlarge_window);
7600 defsubr (&Sshrink_window);
7601 defsubr (&Sadjust_window_trailing_edge);
7602 defsubr (&Sscroll_up); 6892 defsubr (&Sscroll_up);
7603 defsubr (&Sscroll_down); 6893 defsubr (&Sscroll_down);
7604 defsubr (&Sscroll_left); 6894 defsubr (&Sscroll_left);
@@ -7637,11 +6927,7 @@ frame to be redrawn only if it is a tty frame. */);
7637void 6927void
7638keys_of_window (void) 6928keys_of_window (void)
7639{ 6929{
7640 initial_define_key (control_x_map, '1', "delete-other-windows");
7641 initial_define_key (control_x_map, '2', "split-window");
7642 initial_define_key (control_x_map, '0', "delete-window");
7643 initial_define_key (control_x_map, 'o', "other-window"); 6930 initial_define_key (control_x_map, 'o', "other-window");
7644 initial_define_key (control_x_map, '^', "enlarge-window");
7645 initial_define_key (control_x_map, '<', "scroll-left"); 6931 initial_define_key (control_x_map, '<', "scroll-left");
7646 initial_define_key (control_x_map, '>', "scroll-right"); 6932 initial_define_key (control_x_map, '>', "scroll-right");
7647 6933
diff --git a/src/window.h b/src/window.h
index c33179de9ba..236464775d3 100644
--- a/src/window.h
+++ b/src/window.h
@@ -261,12 +261,6 @@ struct window
261 /* If redisplay in this window goes beyond this buffer position, 261 /* If redisplay in this window goes beyond this buffer position,
262 must run the redisplay-end-trigger-hook. */ 262 must run the redisplay-end-trigger-hook. */
263 Lisp_Object redisplay_end_trigger; 263 Lisp_Object redisplay_end_trigger;
264 /* Non-nil means resizing windows will attempt to resize this window
265 proportionally. */
266 Lisp_Object resize_proportionally;
267
268 /* Original window height and top before mini-window was enlarged. */
269 Lisp_Object orig_total_lines, orig_top_line;
270 264
271 /* Non-nil means deleting or resizing this window distributes 265 /* Non-nil means deleting or resizing this window distributes
272 space among all windows in the same combination. */ 266 space among all windows in the same combination. */
@@ -833,9 +827,6 @@ extern Lisp_Object make_window (void);
833extern Lisp_Object window_from_coordinates (struct frame *, int, int, 827extern Lisp_Object window_from_coordinates (struct frame *, int, int,
834 enum window_part *, int); 828 enum window_part *, int);
835EXFUN (Fwindow_dedicated_p, 1); 829EXFUN (Fwindow_dedicated_p, 1);
836extern void set_window_height (Lisp_Object, int, int);
837extern void set_window_width (Lisp_Object, int, int);
838extern void change_window_heights (Lisp_Object, int);
839extern void delete_all_subwindows (Lisp_Object); 830extern void delete_all_subwindows (Lisp_Object);
840extern void freeze_window_starts (struct frame *, int); 831extern void freeze_window_starts (struct frame *, int);
841extern void grow_mini_window (struct window *, int); 832extern void grow_mini_window (struct window *, int);
@@ -918,7 +909,6 @@ EXFUN (Fselected_window, 0);
918EXFUN (Fframe_root_window, 1); 909EXFUN (Fframe_root_window, 1);
919EXFUN (Fframe_first_window, 1); 910EXFUN (Fframe_first_window, 1);
920EXFUN (Fset_frame_selected_window, 3); 911EXFUN (Fset_frame_selected_window, 3);
921EXFUN (Fdelete_window, 1);
922EXFUN (Fset_window_configuration, 1); 912EXFUN (Fset_window_configuration, 1);
923EXFUN (Fcurrent_window_configuration, 1); 913EXFUN (Fcurrent_window_configuration, 1);
924extern int compare_window_configurations (Lisp_Object, Lisp_Object, int); 914extern int compare_window_configurations (Lisp_Object, Lisp_Object, int);
@@ -933,5 +923,11 @@ extern void init_window_once (void);
933extern void init_window (void); 923extern void init_window (void);
934extern void syms_of_window (void); 924extern void syms_of_window (void);
935extern void keys_of_window (void); 925extern void keys_of_window (void);
926extern void resize_frame_windows (struct frame *, int, int);
927extern int resize_window_check (struct window *, int);
928extern Lisp_Object delete_deletable_window (Lisp_Object);
929extern Lisp_Object resize_root_window (Lisp_Object, Lisp_Object, Lisp_Object,
930 Lisp_Object);
931
936 932
937#endif /* not WINDOW_H_INCLUDED */ 933#endif /* not WINDOW_H_INCLUDED */
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 25fa05c0a6e..8417db7d6e5 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