aboutsummaryrefslogtreecommitdiffstats
path: root/src/window.c
diff options
context:
space:
mode:
authorMiles Bader2006-01-16 08:37:27 +0000
committerMiles Bader2006-01-16 08:37:27 +0000
commit41882805d6711e32ac0f066119226d84dbdedc13 (patch)
tree44f756cef3fbc4de2f229e93613a1a326da7f55d /src/window.c
parent6a2bd1a5019d2130c87ac5cf17f1322bf614b624 (diff)
parent28f74fdf77eaab2e9daf54e2d5b0b729c5201e4f (diff)
downloademacs-41882805d6711e32ac0f066119226d84dbdedc13.tar.gz
emacs-41882805d6711e32ac0f066119226d84dbdedc13.zip
Revision: miles@gnu.org--gnu-2005/emacs--unicode--0--patch-97
Merge from emacs--cvs-trunk--0 Patches applied: * emacs--cvs-trunk--0 (patch 616-696) - Add lisp/mh-e/.arch-inventory - Update from CVS - Merge from gnus--rel--5.10 - Update from CVS: lisp/smerge-mode.el: Add 'tools' to file keywords. - lisp/gnus/ChangeLog: Remove duplicate entry * gnus--rel--5.10 (patch 147-181) - Update from CVS - Merge from emacs--cvs-trunk--0 - Update from CVS: lisp/mml.el (mml-preview): Doc fix. - Update from CVS: texi/message.texi: Fix default values. - Update from CVS: texi/gnus.texi (RSS): Addition.
Diffstat (limited to 'src/window.c')
-rw-r--r--src/window.c359
1 files changed, 250 insertions, 109 deletions
diff --git a/src/window.c b/src/window.c
index be3ecaa2b0b..e2678a3f3b8 100644
--- a/src/window.c
+++ b/src/window.c
@@ -65,7 +65,7 @@ static int window_min_size P_ ((struct window *, int, int, int *));
65static void size_window P_ ((Lisp_Object, int, int, int)); 65static void size_window P_ ((Lisp_Object, int, int, int));
66static int freeze_window_start P_ ((struct window *, void *)); 66static int freeze_window_start P_ ((struct window *, void *));
67static int window_fixed_size_p P_ ((struct window *, int, int)); 67static int window_fixed_size_p P_ ((struct window *, int, int));
68static void enlarge_window P_ ((Lisp_Object, int, int, int)); 68static void enlarge_window P_ ((Lisp_Object, int, int));
69static Lisp_Object window_list P_ ((void)); 69static Lisp_Object window_list P_ ((void));
70static int add_window_to_list P_ ((struct window *, void *)); 70static int add_window_to_list P_ ((struct window *, void *));
71static int candidate_window_p P_ ((Lisp_Object, Lisp_Object, Lisp_Object, 71static int candidate_window_p P_ ((Lisp_Object, Lisp_Object, Lisp_Object,
@@ -210,6 +210,10 @@ Lisp_Object Vwindow_configuration_change_hook;
210 210
211Lisp_Object Vscroll_preserve_screen_position; 211Lisp_Object Vscroll_preserve_screen_position;
212 212
213/* Incremented by 1 whenever a window is deleted. */
214
215int window_deletion_count;
216
213#if 0 /* This isn't used anywhere. */ 217#if 0 /* This isn't used anywhere. */
214/* Nonzero means we can split a frame even if it is "unsplittable". */ 218/* Nonzero means we can split a frame even if it is "unsplittable". */
215static int inhibit_frame_unsplittable; 219static int inhibit_frame_unsplittable;
@@ -1333,7 +1337,7 @@ delete_window (window)
1333 CHECK_WINDOW (window); 1337 CHECK_WINDOW (window);
1334 p = XWINDOW (window); 1338 p = XWINDOW (window);
1335 1339
1336 /* It's okay to delete an already-deleted window. */ 1340 /* It's a no-op to delete an already-deleted window. */
1337 if (NILP (p->buffer) 1341 if (NILP (p->buffer)
1338 && NILP (p->hchild) 1342 && NILP (p->hchild)
1339 && NILP (p->vchild)) 1343 && NILP (p->vchild))
@@ -1397,6 +1401,9 @@ delete_window (window)
1397 } 1401 }
1398 } 1402 }
1399 1403
1404 /* Now we know we can delete this one. */
1405 window_deletion_count++;
1406
1400 tem = p->buffer; 1407 tem = p->buffer;
1401 /* tem is null for dummy parent windows 1408 /* tem is null for dummy parent windows
1402 (which have inferiors but not any contents themselves) */ 1409 (which have inferiors but not any contents themselves) */
@@ -1962,7 +1969,7 @@ window_loop (type, obj, mini, frames)
1962 GCPRO1 (windows); 1969 GCPRO1 (windows);
1963 best_window = Qnil; 1970 best_window = Qnil;
1964 1971
1965 for (; CONSP (windows); windows = CDR (windows)) 1972 for (; CONSP (windows); windows = XCDR (windows))
1966 { 1973 {
1967 struct window *w; 1974 struct window *w;
1968 1975
@@ -1996,11 +2003,13 @@ window_loop (type, obj, mini, frames)
1996 break; 2003 break;
1997 2004
1998 case GET_LRU_WINDOW: 2005 case GET_LRU_WINDOW:
1999 /* t as arg means consider only full-width windows */ 2006 /* `obj' is an integer encoding a bitvector.
2000 if (!NILP (obj) && !WINDOW_FULL_WIDTH_P (w)) 2007 `obj & 1' means consider only full-width windows.
2001 break; 2008 `obj & 2' means consider also dedicated windows. */
2002 /* Ignore dedicated windows and minibuffers. */ 2009 if (((XINT (obj) & 1) && !WINDOW_FULL_WIDTH_P (w))
2003 if (MINI_WINDOW_P (w) || EQ (w->dedicated, Qt)) 2010 || (!(XINT (obj) & 2) && EQ (w->dedicated, Qt))
2011 /* Minibuffer windows are always ignored. */
2012 || MINI_WINDOW_P (w))
2004 break; 2013 break;
2005 if (NILP (best_window) 2014 if (NILP (best_window)
2006 || (XFASTINT (XWINDOW (best_window)->use_time) 2015 || (XFASTINT (XWINDOW (best_window)->use_time)
@@ -2051,9 +2060,9 @@ window_loop (type, obj, mini, frames)
2051 break; 2060 break;
2052 2061
2053 case GET_LARGEST_WINDOW: 2062 case GET_LARGEST_WINDOW:
2054 { 2063 { /* nil `obj' means to ignore dedicated windows. */
2055 /* Ignore dedicated windows and minibuffers. */ 2064 /* Ignore dedicated windows and minibuffers. */
2056 if (MINI_WINDOW_P (w) || EQ (w->dedicated, Qt)) 2065 if (MINI_WINDOW_P (w) || (NILP (obj) && EQ (w->dedicated, Qt)))
2057 break; 2066 break;
2058 2067
2059 if (NILP (best_window)) 2068 if (NILP (best_window))
@@ -2147,43 +2156,47 @@ check_all_windows ()
2147 window_loop (CHECK_ALL_WINDOWS, Qnil, 1, Qt); 2156 window_loop (CHECK_ALL_WINDOWS, Qnil, 1, Qt);
2148} 2157}
2149 2158
2150DEFUN ("get-lru-window", Fget_lru_window, Sget_lru_window, 0, 1, 0, 2159DEFUN ("get-lru-window", Fget_lru_window, Sget_lru_window, 0, 2, 0,
2151 doc: /* Return the window least recently selected or used for display. 2160 doc: /* Return the window least recently selected or used for display.
2152Return a full-width window if possible. 2161Return a full-width window if possible.
2153A minibuffer window is never a candidate. 2162A minibuffer window is never a candidate.
2154A dedicated window is never a candidate, so if all windows are dedicated, 2163A dedicated window is never a candidate, unless DEDICATED is non-nil,
2155the value is nil. 2164 so if all windows are dedicated, the value is nil.
2156If optional argument FRAME is `visible', search all visible frames. 2165If optional argument FRAME is `visible', search all visible frames.
2157If FRAME is 0, search all visible and iconified frames. 2166If FRAME is 0, search all visible and iconified frames.
2158If FRAME is t, search all frames. 2167If FRAME is t, search all frames.
2159If FRAME is nil, search only the selected frame. 2168If FRAME is nil, search only the selected frame.
2160If FRAME is a frame, search only that frame. */) 2169If FRAME is a frame, search only that frame. */)
2161 (frame) 2170 (frame, dedicated)
2162 Lisp_Object frame; 2171 Lisp_Object frame, dedicated;
2163{ 2172{
2164 register Lisp_Object w; 2173 register Lisp_Object w;
2165 /* First try for a window that is full-width */ 2174 /* First try for a window that is full-width */
2166 w = window_loop (GET_LRU_WINDOW, Qt, 0, frame); 2175 w = window_loop (GET_LRU_WINDOW,
2176 NILP (dedicated) ? make_number (1) : make_number (3),
2177 0, frame);
2167 if (!NILP (w) && !EQ (w, selected_window)) 2178 if (!NILP (w) && !EQ (w, selected_window))
2168 return w; 2179 return w;
2169 /* If none of them, try the rest */ 2180 /* If none of them, try the rest */
2170 return window_loop (GET_LRU_WINDOW, Qnil, 0, frame); 2181 return window_loop (GET_LRU_WINDOW,
2182 NILP (dedicated) ? make_number (0) : make_number (2),
2183 0, frame);
2171} 2184}
2172 2185
2173DEFUN ("get-largest-window", Fget_largest_window, Sget_largest_window, 0, 1, 0, 2186DEFUN ("get-largest-window", Fget_largest_window, Sget_largest_window, 0, 2, 0,
2174 doc: /* Return the largest window in area. 2187 doc: /* Return the largest window in area.
2175A minibuffer window is never a candidate. 2188A minibuffer window is never a candidate.
2176A dedicated window is never a candidate, so if all windows are dedicated, 2189A dedicated window is never a candidate unless DEDICATED is non-nil,
2177the value is nil. 2190 so if all windows are dedicated, the value is nil.
2178If optional argument FRAME is `visible', search all visible frames. 2191If optional argument FRAME is `visible', search all visible frames.
2179If FRAME is 0, search all visible and iconified frames. 2192If FRAME is 0, search all visible and iconified frames.
2180If FRAME is t, search all frames. 2193If FRAME is t, search all frames.
2181If FRAME is nil, search only the selected frame. 2194If FRAME is nil, search only the selected frame.
2182If FRAME is a frame, search only that frame. */) 2195If FRAME is a frame, search only that frame. */)
2183 (frame) 2196 (frame, dedicated)
2184 Lisp_Object frame; 2197 Lisp_Object frame, dedicated;
2185{ 2198{
2186 return window_loop (GET_LARGEST_WINDOW, Qnil, 0, 2199 return window_loop (GET_LARGEST_WINDOW, dedicated, 0,
2187 frame); 2200 frame);
2188} 2201}
2189 2202
@@ -3503,15 +3516,17 @@ displayed. */)
3503 if (FRAME_NO_SPLIT_P (NILP (frames) ? f : last_nonminibuf_frame)) 3516 if (FRAME_NO_SPLIT_P (NILP (frames) ? f : last_nonminibuf_frame))
3504 { 3517 {
3505 /* Try visible frames first. */ 3518 /* Try visible frames first. */
3506 window = Fget_largest_window (Qvisible); 3519 window = Fget_largest_window (Qvisible, Qt);
3507 /* If that didn't work, try iconified frames. */ 3520 /* If that didn't work, try iconified frames. */
3508 if (NILP (window)) 3521 if (NILP (window))
3509 window = Fget_largest_window (make_number (0)); 3522 window = Fget_largest_window (make_number (0), Qt);
3523#if 0 /* Don't try windows on other displays. */
3510 if (NILP (window)) 3524 if (NILP (window))
3511 window = Fget_largest_window (Qt); 3525 window = Fget_largest_window (Qt, Qt);
3526#endif
3512 } 3527 }
3513 else 3528 else
3514 window = Fget_largest_window (frames); 3529 window = Fget_largest_window (frames, Qt);
3515 3530
3516 /* If we got a tall enough full-width window that can be split, 3531 /* If we got a tall enough full-width window that can be split,
3517 split it. */ 3532 split it. */
@@ -3524,7 +3539,7 @@ displayed. */)
3524 { 3539 {
3525 Lisp_Object upper, other; 3540 Lisp_Object upper, other;
3526 3541
3527 window = Fget_lru_window (frames); 3542 window = Fget_lru_window (frames, Qt);
3528 /* If the LRU window is selected, and big enough, 3543 /* If the LRU window is selected, and big enough,
3529 and can be split, split it. */ 3544 and can be split, split it. */
3530 if (!NILP (window) 3545 if (!NILP (window)
@@ -3533,23 +3548,27 @@ displayed. */)
3533 || EQ (XWINDOW (window)->parent, Qnil)) 3548 || EQ (XWINDOW (window)->parent, Qnil))
3534 && window_height (window) >= window_min_height << 1) 3549 && window_height (window) >= window_min_height << 1)
3535 window = Fsplit_window (window, Qnil, Qnil); 3550 window = Fsplit_window (window, Qnil, Qnil);
3551 else
3552 window = Fget_lru_window (frames, Qnil);
3536 /* If Fget_lru_window returned nil, try other approaches. */ 3553 /* If Fget_lru_window returned nil, try other approaches. */
3537 3554
3538 /* Try visible frames first. */ 3555 /* Try visible frames first. */
3539 if (NILP (window)) 3556 if (NILP (window))
3540 window = Fget_buffer_window (buffer, Qvisible); 3557 window = Fget_buffer_window (buffer, Qvisible);
3541 if (NILP (window)) 3558 if (NILP (window))
3542 window = Fget_largest_window (Qvisible); 3559 window = Fget_largest_window (Qvisible, Qnil);
3543 /* If that didn't work, try iconified frames. */ 3560 /* If that didn't work, try iconified frames. */
3544 if (NILP (window)) 3561 if (NILP (window))
3545 window = Fget_buffer_window (buffer, make_number (0)); 3562 window = Fget_buffer_window (buffer, make_number (0));
3546 if (NILP (window)) 3563 if (NILP (window))
3547 window = Fget_largest_window (make_number (0)); 3564 window = Fget_largest_window (make_number (0), Qnil);
3548 /* Try invisible frames. */ 3565
3566#if 0 /* Don't try frames on other displays. */
3549 if (NILP (window)) 3567 if (NILP (window))
3550 window = Fget_buffer_window (buffer, Qt); 3568 window = Fget_buffer_window (buffer, Qt);
3551 if (NILP (window)) 3569 if (NILP (window))
3552 window = Fget_largest_window (Qt); 3570 window = Fget_largest_window (Qt, Qnil);
3571#endif
3553 /* As a last resort, make a new frame. */ 3572 /* As a last resort, make a new frame. */
3554 if (NILP (window)) 3573 if (NILP (window))
3555 window = Fframe_selected_window (call0 (Vpop_up_frame_function)); 3574 window = Fframe_selected_window (call0 (Vpop_up_frame_function));
@@ -3571,12 +3590,12 @@ displayed. */)
3571 + XFASTINT (XWINDOW (window)->total_lines)); 3590 + XFASTINT (XWINDOW (window)->total_lines));
3572 enlarge_window (upper, 3591 enlarge_window (upper,
3573 total / 2 - XFASTINT (XWINDOW (upper)->total_lines), 3592 total / 2 - XFASTINT (XWINDOW (upper)->total_lines),
3574 0, 0); 3593 0);
3575 } 3594 }
3576 } 3595 }
3577 } 3596 }
3578 else 3597 else
3579 window = Fget_lru_window (Qnil); 3598 window = Fget_lru_window (Qnil, Qnil);
3580 3599
3581 Fset_window_buffer (window, buffer, Qnil); 3600 Fset_window_buffer (window, buffer, Qnil);
3582 return display_buffer_1 (window); 3601 return display_buffer_1 (window);
@@ -3648,7 +3667,7 @@ temp_output_buffer_show (buf)
3648#endif 3667#endif
3649 set_buffer_internal (old); 3668 set_buffer_internal (old);
3650 3669
3651 if (!EQ (Vtemp_buffer_show_function, Qnil)) 3670 if (!NILP (Vtemp_buffer_show_function))
3652 call1 (Vtemp_buffer_show_function, buf); 3671 call1 (Vtemp_buffer_show_function, buf);
3653 else 3672 else
3654 { 3673 {
@@ -3862,20 +3881,18 @@ See Info node `(elisp)Splitting Windows' for more details and examples.*/)
3862 return new; 3881 return new;
3863} 3882}
3864 3883
3865DEFUN ("enlarge-window", Fenlarge_window, Senlarge_window, 1, 3, "p", 3884DEFUN ("enlarge-window", Fenlarge_window, Senlarge_window, 1, 2, "p",
3866 doc: /* Make current window ARG lines bigger. 3885 doc: /* Make current window ARG lines bigger.
3867From program, optional second arg non-nil means grow sideways ARG columns. 3886From program, optional second arg non-nil means grow sideways ARG columns.
3868Interactively, if an argument is not given, make the window one line bigger. 3887Interactively, if an argument is not given, make the window one line bigger.
3869 3888If HORIZONTAL is non-nil, enlarge horizontally instead of vertically.
3870Optional third arg PRESERVE-BEFORE, if non-nil, means do not change the size 3889This function can delete windows, even the second window, if they get
3871of the siblings above or to the left of the selected window. Only 3890too small. */)
3872siblings to the right or below are changed. */) 3891 (arg, horizontal)
3873 (arg, side, preserve_before) 3892 Lisp_Object arg, horizontal;
3874 register Lisp_Object arg, side, preserve_before;
3875{ 3893{
3876 CHECK_NUMBER (arg); 3894 CHECK_NUMBER (arg);
3877 enlarge_window (selected_window, XINT (arg), !NILP (side), 3895 enlarge_window (selected_window, XINT (arg), !NILP (horizontal));
3878 !NILP (preserve_before));
3879 3896
3880 if (! NILP (Vwindow_configuration_change_hook)) 3897 if (! NILP (Vwindow_configuration_change_hook))
3881 call1 (Vrun_hooks, Qwindow_configuration_change_hook); 3898 call1 (Vrun_hooks, Qwindow_configuration_change_hook);
@@ -3883,20 +3900,16 @@ siblings to the right or below are changed. */)
3883 return Qnil; 3900 return Qnil;
3884} 3901}
3885 3902
3886DEFUN ("shrink-window", Fshrink_window, Sshrink_window, 1, 3, "p", 3903DEFUN ("shrink-window", Fshrink_window, Sshrink_window, 1, 2, "p",
3887 doc: /* Make current window ARG lines smaller. 3904 doc: /* Make current window ARG lines smaller.
3888From program, optional second arg non-nil means shrink sideways arg columns. 3905From program, optional second arg non-nil means shrink sideways arg columns.
3889Interactively, if an argument is not given, make the window one line smaller. 3906Interactively, if an argument is not given, make the window one line smaller. Only
3890
3891Optional third arg PRESERVE-BEFORE, if non-nil, means do not change the size
3892of the siblings above or to the left of the selected window. Only
3893siblings to the right or below are changed. */) 3907siblings to the right or below are changed. */)
3894 (arg, side, preserve_before) 3908 (arg, side)
3895 register Lisp_Object arg, side, preserve_before; 3909 Lisp_Object arg, side;
3896{ 3910{
3897 CHECK_NUMBER (arg); 3911 CHECK_NUMBER (arg);
3898 enlarge_window (selected_window, -XINT (arg), !NILP (side), 3912 enlarge_window (selected_window, -XINT (arg), !NILP (side));
3899 !NILP (preserve_before));
3900 3913
3901 if (! NILP (Vwindow_configuration_change_hook)) 3914 if (! NILP (Vwindow_configuration_change_hook))
3902 call1 (Vrun_hooks, Qwindow_configuration_change_hook); 3915 call1 (Vrun_hooks, Qwindow_configuration_change_hook);
@@ -3922,40 +3935,40 @@ window_width (window)
3922 3935
3923 3936
3924#define CURBEG(w) \ 3937#define CURBEG(w) \
3925 *(widthflag ? &(XWINDOW (w)->left_col) : &(XWINDOW (w)->top_line)) 3938 *(horiz_flag ? &(XWINDOW (w)->left_col) : &(XWINDOW (w)->top_line))
3926 3939
3927#define CURSIZE(w) \ 3940#define CURSIZE(w) \
3928 *(widthflag ? &(XWINDOW (w)->total_cols) : &(XWINDOW (w)->total_lines)) 3941 *(horiz_flag ? &(XWINDOW (w)->total_cols) : &(XWINDOW (w)->total_lines))
3929 3942
3930 3943
3931/* Enlarge WINDOW by DELTA. WIDTHFLAG non-zero means 3944/* Enlarge WINDOW by DELTA.
3932 increase its width. Siblings of the selected window are resized to 3945 HORIZ_FLAG nonzero means enlarge it horizontally;
3933 fulfill the size request. If they become too small in the process, 3946 zero means do it vertically.
3934 they will be deleted.
3935 3947
3936 If PRESERVE_BEFORE is nonzero, that means don't alter 3948 Siblings of the selected window are resized to fulfill the size
3937 the siblings to the left or above WINDOW. */ 3949 request. If they become too small in the process, they will be
3950 deleted. */
3938 3951
3939static void 3952static void
3940enlarge_window (window, delta, widthflag, preserve_before) 3953enlarge_window (window, delta, horiz_flag)
3941 Lisp_Object window; 3954 Lisp_Object window;
3942 int delta, widthflag, preserve_before; 3955 int delta, horiz_flag;
3943{ 3956{
3944 Lisp_Object parent, next, prev; 3957 Lisp_Object parent, next, prev;
3945 struct window *p; 3958 struct window *p;
3946 Lisp_Object *sizep; 3959 Lisp_Object *sizep;
3947 int maximum; 3960 int maximum;
3948 int (*sizefun) P_ ((Lisp_Object)) 3961 int (*sizefun) P_ ((Lisp_Object))
3949 = widthflag ? window_width : window_height; 3962 = horiz_flag ? window_width : window_height;
3950 void (*setsizefun) P_ ((Lisp_Object, int, int)) 3963 void (*setsizefun) P_ ((Lisp_Object, int, int))
3951 = (widthflag ? set_window_width : set_window_height); 3964 = (horiz_flag ? set_window_width : set_window_height);
3952 3965
3953 /* Check values of window_min_width and window_min_height for 3966 /* Check values of window_min_width and window_min_height for
3954 validity. */ 3967 validity. */
3955 check_min_window_sizes (); 3968 check_min_window_sizes ();
3956 3969
3957 /* Give up if this window cannot be resized. */ 3970 /* Give up if this window cannot be resized. */
3958 if (window_fixed_size_p (XWINDOW (window), widthflag, 1)) 3971 if (window_fixed_size_p (XWINDOW (window), horiz_flag, 1))
3959 error ("Window is not resizable"); 3972 error ("Window is not resizable");
3960 3973
3961 /* Find the parent of the selected window. */ 3974 /* Find the parent of the selected window. */
@@ -3966,12 +3979,12 @@ enlarge_window (window, delta, widthflag, preserve_before)
3966 3979
3967 if (NILP (parent)) 3980 if (NILP (parent))
3968 { 3981 {
3969 if (widthflag) 3982 if (horiz_flag)
3970 error ("No other window to side of this one"); 3983 error ("No other window to side of this one");
3971 break; 3984 break;
3972 } 3985 }
3973 3986
3974 if (widthflag 3987 if (horiz_flag
3975 ? !NILP (XWINDOW (parent)->hchild) 3988 ? !NILP (XWINDOW (parent)->hchild)
3976 : !NILP (XWINDOW (parent)->vchild)) 3989 : !NILP (XWINDOW (parent)->vchild))
3977 break; 3990 break;
@@ -3986,33 +3999,18 @@ enlarge_window (window, delta, widthflag, preserve_before)
3986 3999
3987 /* Compute the maximum size increment this window can have. */ 4000 /* Compute the maximum size increment this window can have. */
3988 4001
3989 if (preserve_before) 4002 maxdelta = (!NILP (parent) ? (*sizefun) (parent) - XINT (*sizep)
3990 { 4003 /* This is a main window followed by a minibuffer. */
3991 if (!NILP (parent)) 4004 : !NILP (p->next) ? ((*sizefun) (p->next)
3992 { 4005 - window_min_size (XWINDOW (p->next),
3993 maxdelta = (*sizefun) (parent) - XINT (*sizep); 4006 horiz_flag, 0, 0))
3994 /* Subtract size of siblings before, since we can't take that. */ 4007 /* This is a minibuffer following a main window. */
3995 maxdelta -= XINT (CURBEG (window)) - XINT (CURBEG (parent)); 4008 : !NILP (p->prev) ? ((*sizefun) (p->prev)
3996 } 4009 - window_min_size (XWINDOW (p->prev),
3997 else 4010 horiz_flag, 0, 0))
3998 maxdelta = (!NILP (p->next) ? ((*sizefun) (p->next) 4011 /* This is a frame with only one window, a minibuffer-only
3999 - window_min_size (XWINDOW (p->next), 4012 or a minibufferless frame. */
4000 widthflag, 0, 0)) 4013 : (delta = 0));
4001 : (delta = 0));
4002 }
4003 else
4004 maxdelta = (!NILP (parent) ? (*sizefun) (parent) - XINT (*sizep)
4005 /* This is a main window followed by a minibuffer. */
4006 : !NILP (p->next) ? ((*sizefun) (p->next)
4007 - window_min_size (XWINDOW (p->next),
4008 widthflag, 0, 0))
4009 /* This is a minibuffer following a main window. */
4010 : !NILP (p->prev) ? ((*sizefun) (p->prev)
4011 - window_min_size (XWINDOW (p->prev),
4012 widthflag, 0, 0))
4013 /* This is a frame with only one window, a minibuffer-only
4014 or a minibufferless frame. */
4015 : (delta = 0));
4016 4014
4017 if (delta > maxdelta) 4015 if (delta > maxdelta)
4018 /* This case traps trying to make the minibuffer 4016 /* This case traps trying to make the minibuffer
@@ -4021,7 +4019,7 @@ enlarge_window (window, delta, widthflag, preserve_before)
4021 delta = maxdelta; 4019 delta = maxdelta;
4022 } 4020 }
4023 4021
4024 if (XINT (*sizep) + delta < window_min_size (XWINDOW (window), widthflag, 0, 0)) 4022 if (XINT (*sizep) + delta < window_min_size (XWINDOW (window), horiz_flag, 0, 0))
4025 { 4023 {
4026 delete_window (window); 4024 delete_window (window);
4027 return; 4025 return;
@@ -4034,11 +4032,10 @@ enlarge_window (window, delta, widthflag, preserve_before)
4034 maximum = 0; 4032 maximum = 0;
4035 for (next = p->next; ! NILP (next); next = XWINDOW (next)->next) 4033 for (next = p->next; ! NILP (next); next = XWINDOW (next)->next)
4036 maximum += (*sizefun) (next) - window_min_size (XWINDOW (next), 4034 maximum += (*sizefun) (next) - window_min_size (XWINDOW (next),
4037 widthflag, 0, 0); 4035 horiz_flag, 0, 0);
4038 if (! preserve_before) 4036 for (prev = p->prev; ! NILP (prev); prev = XWINDOW (prev)->prev)
4039 for (prev = p->prev; ! NILP (prev); prev = XWINDOW (prev)->prev) 4037 maximum += (*sizefun) (prev) - window_min_size (XWINDOW (prev),
4040 maximum += (*sizefun) (prev) - window_min_size (XWINDOW (prev), 4038 horiz_flag, 0, 0);
4041 widthflag, 0, 0);
4042 4039
4043 /* If we can get it all from them without deleting them, do so. */ 4040 /* If we can get it all from them without deleting them, do so. */
4044 if (delta <= maximum) 4041 if (delta <= maximum)
@@ -4054,13 +4051,13 @@ enlarge_window (window, delta, widthflag, preserve_before)
4054 moving away from this window in both directions alternately, 4051 moving away from this window in both directions alternately,
4055 and take as much as we can get without deleting that sibling. */ 4052 and take as much as we can get without deleting that sibling. */
4056 while (delta != 0 4053 while (delta != 0
4057 && (!NILP (next) || (!preserve_before && !NILP (prev)))) 4054 && (!NILP (next) || !NILP (prev)))
4058 { 4055 {
4059 if (! NILP (next)) 4056 if (! NILP (next))
4060 { 4057 {
4061 int this_one = ((*sizefun) (next) 4058 int this_one = ((*sizefun) (next)
4062 - window_min_size (XWINDOW (next), 4059 - window_min_size (XWINDOW (next),
4063 widthflag, 0, &fixed_p)); 4060 horiz_flag, 0, &fixed_p));
4064 if (!fixed_p) 4061 if (!fixed_p)
4065 { 4062 {
4066 if (this_one > delta) 4063 if (this_one > delta)
@@ -4078,11 +4075,11 @@ enlarge_window (window, delta, widthflag, preserve_before)
4078 if (delta == 0) 4075 if (delta == 0)
4079 break; 4076 break;
4080 4077
4081 if (!preserve_before && ! NILP (prev)) 4078 if (! NILP (prev))
4082 { 4079 {
4083 int this_one = ((*sizefun) (prev) 4080 int this_one = ((*sizefun) (prev)
4084 - window_min_size (XWINDOW (prev), 4081 - window_min_size (XWINDOW (prev),
4085 widthflag, 0, &fixed_p)); 4082 horiz_flag, 0, &fixed_p));
4086 if (!fixed_p) 4083 if (!fixed_p)
4087 { 4084 {
4088 if (this_one > delta) 4085 if (this_one > delta)
@@ -4185,10 +4182,10 @@ enlarge_window (window, delta, widthflag, preserve_before)
4185 int n = 1; 4182 int n = 1;
4186 4183
4187 for (s = w->next; !NILP (s); s = XWINDOW (s)->next) 4184 for (s = w->next; !NILP (s); s = XWINDOW (s)->next)
4188 if (!window_fixed_size_p (XWINDOW (s), widthflag, 0)) 4185 if (!window_fixed_size_p (XWINDOW (s), horiz_flag, 0))
4189 ++n; 4186 ++n;
4190 for (s = w->prev; !NILP (s); s = XWINDOW (s)->prev) 4187 for (s = w->prev; !NILP (s); s = XWINDOW (s)->prev)
4191 if (!window_fixed_size_p (XWINDOW (s), widthflag, 0)) 4188 if (!window_fixed_size_p (XWINDOW (s), horiz_flag, 0))
4192 ++n; 4189 ++n;
4193 4190
4194 delta1 = n * delta; 4191 delta1 = n * delta;
@@ -4215,9 +4212,136 @@ enlarge_window (window, delta, widthflag, preserve_before)
4215 adjust_glyphs (XFRAME (WINDOW_FRAME (XWINDOW (window)))); 4212 adjust_glyphs (XFRAME (WINDOW_FRAME (XWINDOW (window))));
4216} 4213}
4217 4214
4215
4216/* Adjust the size of WINDOW by DELTA, moving only its trailing edge.
4217 HORIZ_FLAG nonzero means adjust the width, moving the right edge.
4218 zero means adjust the height, moving the bottom edge.
4219
4220 Following siblings of the selected window are resized to fulfill
4221 the size request. If they become too small in the process, they
4222 are not deleted; instead, we signal an error. */
4223
4224static void
4225adjust_window_trailing_edge (window, delta, horiz_flag)
4226 Lisp_Object window;
4227 int delta, horiz_flag;
4228{
4229 Lisp_Object parent, child;
4230 struct window *p;
4231 Lisp_Object old_config = Fcurrent_window_configuration (Qnil);
4232 int delcount = window_deletion_count;
4233
4234 /* Check values of window_min_width and window_min_height for
4235 validity. */
4236 check_min_window_sizes ();
4237
4238 if (NILP (window))
4239 window = Fselected_window ();
4240
4241 CHECK_WINDOW (window);
4242
4243 /* Give up if this window cannot be resized. */
4244 if (window_fixed_size_p (XWINDOW (window), horiz_flag, 1))
4245 error ("Window is not resizable");
4246
4247 while (1)
4248 {
4249 p = XWINDOW (window);
4250 parent = p->parent;
4251
4252 /* Make sure there is a following window. */
4253 if (NILP (parent)
4254 && (horiz_flag ? 1
4255 : NILP (XWINDOW (window)->next)))
4256 {
4257 Fset_window_configuration (old_config);
4258 error ("No other window following this one");
4259 }
4260
4261 /* Don't make this window too small. */
4262 if (XINT (CURSIZE (window)) + delta
4263 < (horiz_flag ? window_min_width : window_min_height))
4264 {
4265 Fset_window_configuration (old_config);
4266 error ("Cannot adjust window size as specified");
4267 }
4268
4269 /* Clear out some redisplay caches. */
4270 XSETFASTINT (p->last_modified, 0);
4271 XSETFASTINT (p->last_overlay_modified, 0);
4272
4273 /* Adjust this window's edge. */
4274 XSETINT (CURSIZE (window),
4275 XINT (CURSIZE (window)) + delta);
4276
4277 /* If this window has following siblings in the desired dimension,
4278 make them smaller.
4279 (If we reach the top of the tree and can never do this,
4280 we will fail and report an error, above.) */
4281 if (horiz_flag
4282 ? !NILP (XWINDOW (parent)->hchild)
4283 : !NILP (XWINDOW (parent)->vchild))
4284 {
4285 if (!NILP (XWINDOW (window)->next))
4286 {
4287 XSETINT (CURBEG (p->next),
4288 XINT (CURBEG (p->next)) + delta);
4289 size_window (p->next, XINT (CURSIZE (p->next)) - delta,
4290 horiz_flag, 0);
4291 break;
4292 }
4293 }
4294 else
4295 /* Here we have a chain of parallel siblings, in the other dimension.
4296 Change the size of the other siblings. */
4297 for (child = (horiz_flag
4298 ? XWINDOW (parent)->vchild
4299 : XWINDOW (parent)->hchild);
4300 ! NILP (child);
4301 child = XWINDOW (child)->next)
4302 if (! EQ (child, window))
4303 size_window (child, XINT (CURSIZE (child)) + delta,
4304 horiz_flag, 0);
4305
4306 window = parent;
4307 }
4308
4309 /* If we made a window so small it got deleted,
4310 we failed. Report failure. */
4311 if (delcount != window_deletion_count)
4312 {
4313 Fset_window_configuration (old_config);
4314 error ("Cannot adjust window size as specified");
4315 }
4316
4317 /* Adjust glyph matrices. */
4318 adjust_glyphs (XFRAME (WINDOW_FRAME (XWINDOW (window))));
4319}
4320
4218#undef CURBEG 4321#undef CURBEG
4219#undef CURSIZE 4322#undef CURSIZE
4220 4323
4324DEFUN ("adjust-window-trailing-edge", Fadjust_window_trailing_edge,
4325 Sadjust_window_trailing_edge, 3, 3, 0,
4326 doc: /* Adjust the bottom or right edge of WINDOW by DELTA.
4327If HORIZONTAL is non-nil, that means adjust the width, moving the right edge.
4328Otherwise, adjust the height, moving the bottom edge.
4329
4330Following siblings of the selected window are resized to fulfill
4331the size request. If they become too small in the process, they
4332are not deleted; instead, we signal an error. */)
4333 (window, delta, horizontal)
4334 Lisp_Object window, delta, horizontal;
4335{
4336 CHECK_NUMBER (delta);
4337 adjust_window_trailing_edge (window, XINT (delta), !NILP (horizontal));
4338
4339 if (! NILP (Vwindow_configuration_change_hook))
4340 call1 (Vrun_hooks, Qwindow_configuration_change_hook);
4341
4342 return Qnil;
4343}
4344
4221 4345
4222 4346
4223/*********************************************************************** 4347/***********************************************************************
@@ -4452,7 +4576,7 @@ shrink_mini_window (w)
4452 among the other windows. */ 4576 among the other windows. */
4453 Lisp_Object window; 4577 Lisp_Object window;
4454 XSETWINDOW (window, w); 4578 XSETWINDOW (window, w);
4455 enlarge_window (window, 1 - XFASTINT (w->total_lines), 0, 0); 4579 enlarge_window (window, 1 - XFASTINT (w->total_lines), 0);
4456 } 4580 }
4457} 4581}
4458 4582
@@ -5681,7 +5805,23 @@ the return value is nil. Otherwise the value is t. */)
5681 else 5805 else
5682 { 5806 {
5683 if (XBUFFER (new_current_buffer) == current_buffer) 5807 if (XBUFFER (new_current_buffer) == current_buffer)
5684 old_point = PT; 5808 /* The code further down "preserves point" by saving here PT in
5809 old_point and then setting it later back into PT. When the
5810 current-selected-window and the final-selected-window both show
5811 the current buffer, this suffers from the problem that the
5812 current PT is the window-point of the current-selected-window,
5813 while the final PT is the point of the final-selected-window, so
5814 this copy from one PT to the other would end up moving the
5815 window-point of the final-selected-window to the window-point of
5816 the current-selected-window. So we have to be careful which
5817 point of the current-buffer we copy into old_point. */
5818 if (EQ (XWINDOW (data->current_window)->buffer, new_current_buffer)
5819 && WINDOWP (selected_window)
5820 && EQ (XWINDOW (selected_window)->buffer, new_current_buffer)
5821 && !EQ (selected_window, data->current_window))
5822 old_point = XMARKER (XWINDOW (data->current_window)->pointm)->charpos;
5823 else
5824 old_point = PT;
5685 else 5825 else
5686 /* BUF_PT (XBUFFER (new_current_buffer)) gives us the position of 5826 /* BUF_PT (XBUFFER (new_current_buffer)) gives us the position of
5687 point in new_current_buffer as of the last time this buffer was 5827 point in new_current_buffer as of the last time this buffer was
@@ -7098,6 +7238,7 @@ The selected frame is the one whose configuration has changed. */);
7098 defsubr (&Ssplit_window); 7238 defsubr (&Ssplit_window);
7099 defsubr (&Senlarge_window); 7239 defsubr (&Senlarge_window);
7100 defsubr (&Sshrink_window); 7240 defsubr (&Sshrink_window);
7241 defsubr (&Sadjust_window_trailing_edge);
7101 defsubr (&Sscroll_up); 7242 defsubr (&Sscroll_up);
7102 defsubr (&Sscroll_down); 7243 defsubr (&Sscroll_down);
7103 defsubr (&Sscroll_left); 7244 defsubr (&Sscroll_left);