diff options
| author | Paul Eggert | 2011-06-10 11:19:35 -0700 |
|---|---|---|
| committer | Paul Eggert | 2011-06-10 11:19:35 -0700 |
| commit | e41e9a0e24877b0bc81e08df396f59115f8636da (patch) | |
| tree | c0cf7e2838761b2c26047aeeac6415bb542bf5a0 /src | |
| parent | 6a54b501af0633c909c96de867c805222fde970c (diff) | |
| parent | 529a133c390049085db38e7c8f745d650a2626ee (diff) | |
| download | emacs-e41e9a0e24877b0bc81e08df396f59115f8636da.tar.gz emacs-e41e9a0e24877b0bc81e08df396f59115f8636da.zip | |
Merge from trunk.
Diffstat (limited to 'src')
| -rw-r--r-- | src/ChangeLog | 109 | ||||
| -rw-r--r-- | src/buffer.c | 4 | ||||
| -rw-r--r-- | src/dispnew.c | 27 | ||||
| -rw-r--r-- | src/frame.c | 5 | ||||
| -rw-r--r-- | src/image.c | 2 | ||||
| -rw-r--r-- | src/w32fns.c | 7 | ||||
| -rw-r--r-- | src/window.c | 2850 | ||||
| -rw-r--r-- | src/window.h | 16 | ||||
| -rw-r--r-- | src/xdisp.c | 28 | ||||
| -rw-r--r-- | src/xfns.c | 8 |
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 @@ | |||
| 1 | 2011-06-09 Paul Eggert <eggert@cs.ucla.edu> | 1 | 2011-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 | ||
| 17 | 2011-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 | ||
| 73 | 2011-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 | |||
| 78 | 2011-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 | |||
| 86 | 2011-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 | |||
| 95 | 2011-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 | |||
| 159 | 2011-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 | |||
| 75 | 2011-06-08 Martin Rudalics <rudalics@gmx.at> | 178 | 2011-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 | ||
| 1941 | extern Lisp_Object Qdelete_window; | ||
| 1942 | |||
| 1941 | DEFUN ("bury-buffer", Fbury_buffer, Sbury_buffer, 0, 1, "", | 1943 | DEFUN ("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. |
| 1943 | There it is the least likely candidate for `other-buffer' to return; | 1945 | There 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 | ||
| 53 | Lisp_Object Qwindowp, Qwindow_live_p; | 53 | Lisp_Object Qwindowp, Qwindow_live_p, Qdelete_window; |
| 54 | static Lisp_Object Qwindow_configuration_p, Qrecord_window_buffer; | 54 | static Lisp_Object Qwindow_configuration_p, Qrecord_window_buffer; |
| 55 | static Lisp_Object Qwindow_deletable_p, Qdelete_window, Qdisplay_buffer; | 55 | static Lisp_Object Qwindow_deletable_p, Qdisplay_buffer; |
| 56 | static Lisp_Object Qreplace_buffer_in_windows, Qget_mru_window; | 56 | static Lisp_Object Qreplace_buffer_in_windows, Qget_mru_window; |
| 57 | static Lisp_Object Qresize_root_window, Qresize_root_window_vertically; | 57 | static Lisp_Object Qresize_root_window, Qresize_root_window_vertically; |
| 58 | static Lisp_Object Qscroll_up, Qscroll_down, Qscroll_command; | 58 | static Lisp_Object Qscroll_up, Qscroll_down, Qscroll_command; |
| 59 | static Lisp_Object Qsafe, Qabove, Qbelow; | 59 | static Lisp_Object Qsafe, Qabove, Qbelow; |
| 60 | static Lisp_Object Qauto_buffer_name; | 60 | static Lisp_Object Qauto_buffer_name; |
| 61 | 61 | ||
| 62 | static Lisp_Object Qwindow_size_fixed; | ||
| 63 | |||
| 64 | static int displayed_window_lines (struct window *); | 62 | static int displayed_window_lines (struct window *); |
| 65 | static struct window *decode_window (Lisp_Object); | 63 | static struct window *decode_window (Lisp_Object); |
| 66 | static int count_windows (struct window *); | 64 | static int count_windows (struct window *); |
| @@ -68,13 +66,7 @@ static int get_leaf_windows (struct window *, struct window **, int); | |||
| 68 | static void window_scroll (Lisp_Object, int, int, int); | 66 | static void window_scroll (Lisp_Object, int, int, int); |
| 69 | static void window_scroll_pixel_based (Lisp_Object, int, int, int); | 67 | static void window_scroll_pixel_based (Lisp_Object, int, int, int); |
| 70 | static void window_scroll_line_based (Lisp_Object, int, int, int); | 68 | static void window_scroll_line_based (Lisp_Object, int, int, int); |
| 71 | static int window_min_size_1 (struct window *, int, int); | ||
| 72 | static int window_min_size_2 (struct window *, int, int); | ||
| 73 | static int window_min_size (struct window *, int, int, int, int *); | ||
| 74 | static void size_window (Lisp_Object, int, int, int, int, int); | ||
| 75 | static int freeze_window_start (struct window *, void *); | 69 | static int freeze_window_start (struct window *, void *); |
| 76 | static int window_fixed_size_p (struct window *, int, int); | ||
| 77 | static void enlarge_window (Lisp_Object, int, int); | ||
| 78 | static Lisp_Object window_list (void); | 70 | static Lisp_Object window_list (void); |
| 79 | static int add_window_to_list (struct window *, void *); | 71 | static int add_window_to_list (struct window *, void *); |
| 80 | static int candidate_window_p (Lisp_Object, Lisp_Object, Lisp_Object, | 72 | static 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 *); |
| 92 | static Lisp_Object window_list_1 (Lisp_Object, Lisp_Object, Lisp_Object); | 84 | static Lisp_Object window_list_1 (Lisp_Object, Lisp_Object, Lisp_Object); |
| 85 | static void resize_window_apply (struct window *, int); | ||
| 93 | static Lisp_Object select_window (Lisp_Object, Lisp_Object, int); | 86 | static 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 | ||
| 1805 | static 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. */ |
| 1809 | static void | 1800 | static void |
| 1810 | unshow_buffer (register struct window *w) | 1801 | unshow_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. */ | ||
| 1857 | static void | 1850 | static void |
| 1858 | replace_window (Lisp_Object old, Lisp_Object replacement) | 1851 | replace_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 | ||
| 1906 | and so is its new parent, we should make replacement's | ||
| 1907 | children be children of that parent instead. ***/ | ||
| 1908 | } | 1902 | } |
| 1909 | 1903 | ||
| 1910 | DEFUN ("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 |
| 1912 | WINDOW defaults to the selected window. Return nil. | 1906 | deleted. */ |
| 1913 | Signal 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 | ||
| 1930 | static void | 1908 | static void |
| 1931 | delete_window (register Lisp_Object window) | 1909 | recombine_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. */ | |
| 1979 | Lisp_Object | ||
| 1980 | delete_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 | ||
| 2430 | DEFUN ("window-list-1", Fwindow_list_1, Swindow_list_1, 0, 3, 0, | ||
| 2431 | doc: /* Return a list of all live windows. | ||
| 2432 | WINDOW specifies the first window to list and defaults to the selected | ||
| 2433 | window. | ||
| 2434 | |||
| 2435 | Optional argument MINIBUF nil or omitted means consider the minibuffer | ||
| 2436 | window only if the minibuffer is active. MINIBUF t means consider the | ||
| 2437 | minibuffer window even if the minibuffer is not active. Any other value | ||
| 2438 | means do not consider the minibuffer window even if the minibuffer is | ||
| 2439 | active. | ||
| 2440 | |||
| 2441 | Optional argument ALL-FRAMES nil or omitted means consider all windows | ||
| 2442 | on WINDOW's frame, plus the minibuffer window if specified by the | ||
| 2443 | MINIBUF argument. If the minibuffer counts, consider all windows on all | ||
| 2444 | frames that share that minibuffer too. The following non-nil values of | ||
| 2445 | ALL-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 | |||
| 2456 | Anything else means consider all windows on WINDOW's frame and no | ||
| 2457 | others. | ||
| 2458 | |||
| 2459 | If WINDOW is not on the list of windows returned, some other window will | ||
| 2460 | be 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 | |||
| 2467 | DEFUN ("other-window", Fother_window, Sother_window, 1, 2, "p", | 2280 | DEFUN ("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. |
| 2469 | COUNT specifies the number of windows to skip, starting with the | 2282 | COUNT 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 | ||
| 2363 | DEFUN ("window-list-1", Fwindow_list_1, Swindow_list_1, 0, 3, 0, | ||
| 2364 | doc: /* Return a list of all live windows. | ||
| 2365 | WINDOW specifies the first window to list and defaults to the selected | ||
| 2366 | window. | ||
| 2367 | |||
| 2368 | Optional argument MINIBUF nil or omitted means consider the minibuffer | ||
| 2369 | window only if the minibuffer is active. MINIBUF t means consider the | ||
| 2370 | minibuffer window even if the minibuffer is not active. Any other value | ||
| 2371 | means do not consider the minibuffer window even if the minibuffer is | ||
| 2372 | active. | ||
| 2373 | |||
| 2374 | Optional argument ALL-FRAMES nil or omitted means consider all windows | ||
| 2375 | on WINDOW's frame, plus the minibuffer window if specified by the | ||
| 2376 | MINIBUF argument. If the minibuffer counts, consider all windows on all | ||
| 2377 | frames that share that minibuffer too. The following non-nil values of | ||
| 2378 | ALL-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 | |||
| 2389 | Anything else means consider all windows on WINDOW's frame and no | ||
| 2390 | others. | ||
| 2391 | |||
| 2392 | If WINDOW is not on the list of windows returned, some other window will | ||
| 2393 | be 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 | ||
| 2804 | DEFUN ("delete-other-windows", Fdelete_other_windows, Sdelete_other_windows, | 2646 | Lisp_Object |
| 2805 | 0, 1, "", | 2647 | resize_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 | { |
| 2807 | Only the frame WINDOW is on is affected. | 2649 | return call4 (Qresize_root_window, window, delta, horizontal, ignore); |
| 2808 | This function tries to reduce display jumps by keeping the text | 2650 | } |
| 2651 | |||
| 2652 | |||
| 2653 | DEFUN ("delete-other-windows-internal", Fdelete_other_windows_internal, | ||
| 2654 | Sdelete_other_windows_internal, 0, 2, "", | ||
| 2655 | doc: /* Make WINDOW fill its frame. | ||
| 2656 | Only the frame WINDOW is on is affected. WINDOW may be any window and | ||
| 2657 | defaults to the selected one. | ||
| 2658 | |||
| 2659 | Optional argument ROOT, if non-nil, must specify an internal window | ||
| 2660 | containing WINDOW as a subwindow. If this is the case, replace ROOT by | ||
| 2661 | WINDOW and leave alone any windows not contained in ROOT. | ||
| 2662 | |||
| 2663 | When WINDOW is live try to reduce display jumps by keeping the text | ||
| 2809 | previously visible in WINDOW in the same place on the frame. Doing this | 2664 | previously visible in WINDOW in the same place on the frame. Doing this |
| 2810 | depends on the value of (window-start WINDOW), so if calling this | 2665 | depends on the value of (window-start WINDOW), so if calling this |
| 2811 | function in a program gives strange scrolling, make sure the | 2666 | function in a program gives strange scrolling, make sure the |
| 2812 | window-start value is reasonable when this function is called. */) | 2667 | window-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 | |||
| 2866 | DEFUN ("delete-windows-on", Fdelete_windows_on, Sdelete_windows_on, | 2888 | DEFUN ("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 | |||
| 2978 | static int | ||
| 2979 | window_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 | |||
| 3078 | static int | ||
| 3079 | window_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 | |||
| 3112 | static int | ||
| 3113 | window_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 | |||
| 3187 | static int | ||
| 3188 | window_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. */ | ||
| 3267 | static int * | ||
| 3268 | shrink_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 | |||
| 3404 | static void | ||
| 3405 | size_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 | |||
| 3600 | void | ||
| 3601 | set_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 | |||
| 3614 | void | ||
| 3615 | set_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 | |||
| 3622 | void | ||
| 3623 | change_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 | ||
| 3648 | int window_select_count; | 3027 | int 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 | ||
| 3095 | DEFUN ("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). */ | ||
| 4003 | static void | 3395 | static void |
| 4004 | make_dummy_parent (Lisp_Object window) | 3396 | make_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 | ||
| 4141 | DEFUN ("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) |
| 4143 | WINDOW defaults to selected one and SIZE to half its size. | 3531 | for window W and recursively all subwindows of W. |
| 4144 | If optional third arg HORIZONTAL is non-nil, split side by side and put | ||
| 4145 | SIZE columns in the first of the pair. In that case, SIZE includes that | ||
| 4146 | window's scroll bar, or the divider column to its right. | ||
| 4147 | Interactively, all arguments are nil. | ||
| 4148 | Returns the newly created window (which is the lower or rightmost one). | ||
| 4149 | The upper or leftmost window is the original one, and remains selected | ||
| 4150 | if it was selected before. | ||
| 4151 | 3532 | ||
| 4152 | See 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). */ | ||
| 3536 | int | ||
| 3537 | resize_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. */ | ||
| 3617 | static void | ||
| 3618 | resize_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 | |||
| 4283 | DEFUN ("enlarge-window", Fenlarge_window, Senlarge_window, 1, 2, "p", | ||
| 4284 | doc: /* Make selected window SIZE lines taller. | ||
| 4285 | Interactively, if no argument is given, make the selected window one | ||
| 4286 | line taller. If optional argument HORIZONTAL is non-nil, make selected | ||
| 4287 | window wider by SIZE columns. If SIZE is negative, shrink the window by | ||
| 4288 | -SIZE lines or columns. Return nil. | ||
| 4289 | |||
| 4290 | This function can delete windows if they get too small. The size of | ||
| 4291 | fixed 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 | ||
| 4302 | DEFUN ("shrink-window", Fshrink_window, Sshrink_window, 1, 2, "p", | ||
| 4303 | doc: /* Make selected window SIZE lines smaller. | ||
| 4304 | Interactively, if no argument is given, make the selected window one | ||
| 4305 | line smaller. If optional argument HORIZONTAL is non-nil, make the | ||
| 4306 | window narrower by SIZE columns. If SIZE is negative, enlarge selected | ||
| 4307 | window by -SIZE lines or columns. Return nil. | ||
| 4308 | |||
| 4309 | This function can delete windows if they get too small. The size of | ||
| 4310 | fixed 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; | 3681 | DEFUN ("resize-window-apply", Fresize_window_apply, Sresize_window_apply, 1, 2, 0, |
| 4319 | } | 3682 | doc: /* Apply requested size values for window-tree of FRAME. |
| 3683 | Optional argument HORIZONTAL omitted or nil means apply requested height | ||
| 3684 | values. HORIZONTAL non-nil means apply requested width values. | ||
| 4320 | 3685 | ||
| 4321 | static int | 3686 | This function checks whether the requested values sum up to a valid |
| 4322 | window_height (Lisp_Object window) | 3687 | window layout, recursively assigns the new sizes of all subwindows and |
| 4323 | { | 3688 | calculates 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 | ||
| 4328 | static int | 3690 | Note: This function does not check any of `window-fixed-size-p', |
| 4329 | window_width (Lisp_Object window) | 3691 | `window-min-height' or `window-min-width'. All these checks have to |
| 3692 | be 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 | ||
| 4350 | static void | 3706 | if (!resize_window_check (r, horflag) |
| 4351 | enlarge_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. */ | ||
| 3732 | void | ||
| 3733 | resize_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. */ | 3809 | DEFUN ("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 | } | 3811 | Second argument TOTAL-SIZE specifies the number of lines or columns of the |
| 3812 | new window. In any case TOTAL-SIZE must be a positive integer | ||
| 4616 | 3813 | ||
| 3814 | Third argument SIDE nil (or `below') specifies that the new window shall | ||
| 3815 | be located below WINDOW. SIDE `above' means the new window shall be | ||
| 3816 | located above WINDOW. In both cases TOTAL-SIZE specifies the number of | ||
| 3817 | lines of the new window including space reserved for the mode and/or | ||
| 3818 | header line. | ||
| 4617 | 3819 | ||
| 4618 | /* Adjust the size of WINDOW by DELTA, moving only its trailing edge. | 3820 | SIDE t (or `right') specifies that the new window shall be located on |
| 4619 | HORIZ_FLAG nonzero means adjust the width, moving the right edge. | 3821 | the right side of WINDOW. SIDE `left' means the new window shall be |
| 4620 | zero means adjust the height, moving the bottom edge. | 3822 | located on the left of WINDOW. In both cases TOTAL-SIZE specifies the |
| 3823 | number of columns of the new window including space reserved for fringes | ||
| 3824 | and the scrollbar or a divider column. | ||
| 4621 | 3825 | ||
| 4622 | Following siblings of the selected window are resized to fulfill | 3826 | Fourth argument NORMAL-SIZE specifies the normal size of the new window |
| 4623 | the size request. If they become too small in the process, they | 3827 | according to the SIDE argument. |
| 4624 | are not deleted; instead, we signal an error. */ | ||
| 4625 | 3828 | ||
| 4626 | static void | 3829 | The new total and normal sizes of all involved windows must have been |
| 4627 | adjust_window_trailing_edge (Lisp_Object window, int delta, int horiz_flag) | 3830 | set 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 | |||
| 4754 | DEFUN ("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. | ||
| 4757 | If HORIZONTAL is non-nil, that means adjust the width, moving the right edge. | ||
| 4758 | Otherwise, adjust the height, moving the bottom edge. | ||
| 4759 | 3987 | ||
| 4760 | Following siblings of the selected window are resized to fulfill | 3988 | BLOCK_INPUT; |
| 4761 | the size request. If they become too small in the process, they | 3989 | resize_window_apply (p, horflag); |
| 4762 | are 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 | 4006 | DEFUN ("delete-window-internal", Fdelete_window_internal, Sdelete_window_internal, 1, 1, 0, | |
| 4778 | /*********************************************************************** | 4007 | doc: /* Remove WINDOW from its frame. |
| 4779 | Resizing Mini-Windows | 4008 | WINDOW defaults to the selected window. Return nil. Signal an error |
| 4780 | ***********************************************************************/ | 4009 | when WINDOW is the only window on its frame. */) |
| 4781 | 4010 | (register Lisp_Object window) | |
| 4782 | static void shrink_window_lowest_first (struct window *, int); | ||
| 4783 | |||
| 4784 | enum 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; | |
| 4791 | static 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 | ||
| 4797 | static void | 4018 | w = decode_any_window (window); |
| 4798 | shrink_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 | ||
| 4879 | static int | 4142 | /* If all ended up well, we now promote the mru window. */ |
| 4880 | save_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 | |||
| 4934 | void | 4183 | void |
| 4935 | grow_mini_window (struct window *w, int delta) | 4184 | grow_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 | |||
| 4983 | void | 4214 | void |
| 4984 | shrink_mini_window (struct window *w) | 4215 | shrink_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 | ||
| 4253 | DEFUN ("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. */ |
| 6561 | void | 5843 | void |
| @@ -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 | |||
| 6612 | static int | 5893 | static int |
| 6613 | get_leaf_windows (struct window *w, struct window **flat, int i) | 5894 | get_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 | |||
| 6635 | struct glyph * | 5915 | struct glyph * |
| 6636 | get_phys_cursor_glyph (struct window *w) | 5916 | get_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. | ||
| 7483 | The value is measured in line units. If a window wants a modeline it | ||
| 7484 | is counted as one line. | ||
| 7485 | |||
| 7486 | Emacs honors settings of this variable when enlarging or shrinking | ||
| 7487 | windows 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. | ||
| 7492 | The value is measured in characters and includes any fringes or | ||
| 7493 | the scrollbar. | ||
| 7494 | |||
| 7495 | Emacs honors settings of this variable when enlarging or shrinking | ||
| 7496 | windows 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 | |||
| 7527 | frame to be redrawn only if it is a tty frame. */); | 6782 | frame 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. | ||
| 6787 | If this variable is nil, splitting a window gets the entire screen space | ||
| 6788 | for displaying the new window from the window to split. If this | ||
| 6789 | variable is non-nil, splitting a window may resize all windows in the | ||
| 6790 | same combination. This also allows to split a window that is otherwise | ||
| 6791 | too small or of fixed size. | ||
| 6792 | |||
| 6793 | The value of this variable is also assigned to the split status of the | ||
| 6794 | new window and, provided the old and new window form a new combination, | ||
| 6795 | to the window that was split as well. The split status of a window can | ||
| 6796 | be retrieved with the function `window-splits' and altered by the | ||
| 6797 | function `set-window-splits'. | ||
| 6798 | |||
| 6799 | If the value of the variable `window-nest' is non-nil, the space for the | ||
| 6800 | new window is exclusively taken from the window that shall be split, but | ||
| 6801 | the split status of the window that is split as well as that of the new | ||
| 6802 | window 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. | ||
| 6807 | If this variable is nil, splitting a window will create a new parent | ||
| 6808 | window only if the window has no parent window or the window shall | ||
| 6809 | become a combination orthogonal to the one it it is part of. | ||
| 6810 | |||
| 6811 | If this variable is non-nil, splitting a window always creates a new | ||
| 6812 | parent window. If all splits behave this way, each frame's window tree | ||
| 6813 | is a binary tree and every window but the frame's root window has | ||
| 6814 | exactly one sibling. | ||
| 6815 | |||
| 6816 | The value of this variable is also assigned to the nest status of the | ||
| 6817 | new parent window. The nest status of a window can be retrieved via the | ||
| 6818 | function `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. */); | |||
| 7637 | void | 6927 | void |
| 7638 | keys_of_window (void) | 6928 | keys_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); | |||
| 833 | extern Lisp_Object window_from_coordinates (struct frame *, int, int, | 827 | extern Lisp_Object window_from_coordinates (struct frame *, int, int, |
| 834 | enum window_part *, int); | 828 | enum window_part *, int); |
| 835 | EXFUN (Fwindow_dedicated_p, 1); | 829 | EXFUN (Fwindow_dedicated_p, 1); |
| 836 | extern void set_window_height (Lisp_Object, int, int); | ||
| 837 | extern void set_window_width (Lisp_Object, int, int); | ||
| 838 | extern void change_window_heights (Lisp_Object, int); | ||
| 839 | extern void delete_all_subwindows (Lisp_Object); | 830 | extern void delete_all_subwindows (Lisp_Object); |
| 840 | extern void freeze_window_starts (struct frame *, int); | 831 | extern void freeze_window_starts (struct frame *, int); |
| 841 | extern void grow_mini_window (struct window *, int); | 832 | extern void grow_mini_window (struct window *, int); |
| @@ -918,7 +909,6 @@ EXFUN (Fselected_window, 0); | |||
| 918 | EXFUN (Fframe_root_window, 1); | 909 | EXFUN (Fframe_root_window, 1); |
| 919 | EXFUN (Fframe_first_window, 1); | 910 | EXFUN (Fframe_first_window, 1); |
| 920 | EXFUN (Fset_frame_selected_window, 3); | 911 | EXFUN (Fset_frame_selected_window, 3); |
| 921 | EXFUN (Fdelete_window, 1); | ||
| 922 | EXFUN (Fset_window_configuration, 1); | 912 | EXFUN (Fset_window_configuration, 1); |
| 923 | EXFUN (Fcurrent_window_configuration, 1); | 913 | EXFUN (Fcurrent_window_configuration, 1); |
| 924 | extern int compare_window_configurations (Lisp_Object, Lisp_Object, int); | 914 | extern int compare_window_configurations (Lisp_Object, Lisp_Object, int); |
| @@ -933,5 +923,11 @@ extern void init_window_once (void); | |||
| 933 | extern void init_window (void); | 923 | extern void init_window (void); |
| 934 | extern void syms_of_window (void); | 924 | extern void syms_of_window (void); |
| 935 | extern void keys_of_window (void); | 925 | extern void keys_of_window (void); |
| 926 | extern void resize_frame_windows (struct frame *, int, int); | ||
| 927 | extern int resize_window_check (struct window *, int); | ||
| 928 | extern Lisp_Object delete_deletable_window (Lisp_Object); | ||
| 929 | extern 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 | |||
| 27115 | void | 27115 | void |
| 27116 | init_xdisp (void) | 27116 | init_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 | ||