diff options
| author | Miles Bader | 2006-01-16 08:37:27 +0000 |
|---|---|---|
| committer | Miles Bader | 2006-01-16 08:37:27 +0000 |
| commit | 41882805d6711e32ac0f066119226d84dbdedc13 (patch) | |
| tree | 44f756cef3fbc4de2f229e93613a1a326da7f55d /src/window.c | |
| parent | 6a2bd1a5019d2130c87ac5cf17f1322bf614b624 (diff) | |
| parent | 28f74fdf77eaab2e9daf54e2d5b0b729c5201e4f (diff) | |
| download | emacs-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.c | 359 |
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 *)); | |||
| 65 | static void size_window P_ ((Lisp_Object, int, int, int)); | 65 | static void size_window P_ ((Lisp_Object, int, int, int)); |
| 66 | static int freeze_window_start P_ ((struct window *, void *)); | 66 | static int freeze_window_start P_ ((struct window *, void *)); |
| 67 | static int window_fixed_size_p P_ ((struct window *, int, int)); | 67 | static int window_fixed_size_p P_ ((struct window *, int, int)); |
| 68 | static void enlarge_window P_ ((Lisp_Object, int, int, int)); | 68 | static void enlarge_window P_ ((Lisp_Object, int, int)); |
| 69 | static Lisp_Object window_list P_ ((void)); | 69 | static Lisp_Object window_list P_ ((void)); |
| 70 | static int add_window_to_list P_ ((struct window *, void *)); | 70 | static int add_window_to_list P_ ((struct window *, void *)); |
| 71 | static int candidate_window_p P_ ((Lisp_Object, Lisp_Object, Lisp_Object, | 71 | static int candidate_window_p P_ ((Lisp_Object, Lisp_Object, Lisp_Object, |
| @@ -210,6 +210,10 @@ Lisp_Object Vwindow_configuration_change_hook; | |||
| 210 | 210 | ||
| 211 | Lisp_Object Vscroll_preserve_screen_position; | 211 | Lisp_Object Vscroll_preserve_screen_position; |
| 212 | 212 | ||
| 213 | /* Incremented by 1 whenever a window is deleted. */ | ||
| 214 | |||
| 215 | int 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". */ |
| 215 | static int inhibit_frame_unsplittable; | 219 | static 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 | ||
| 2150 | DEFUN ("get-lru-window", Fget_lru_window, Sget_lru_window, 0, 1, 0, | 2159 | DEFUN ("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. |
| 2152 | Return a full-width window if possible. | 2161 | Return a full-width window if possible. |
| 2153 | A minibuffer window is never a candidate. | 2162 | A minibuffer window is never a candidate. |
| 2154 | A dedicated window is never a candidate, so if all windows are dedicated, | 2163 | A dedicated window is never a candidate, unless DEDICATED is non-nil, |
| 2155 | the value is nil. | 2164 | so if all windows are dedicated, the value is nil. |
| 2156 | If optional argument FRAME is `visible', search all visible frames. | 2165 | If optional argument FRAME is `visible', search all visible frames. |
| 2157 | If FRAME is 0, search all visible and iconified frames. | 2166 | If FRAME is 0, search all visible and iconified frames. |
| 2158 | If FRAME is t, search all frames. | 2167 | If FRAME is t, search all frames. |
| 2159 | If FRAME is nil, search only the selected frame. | 2168 | If FRAME is nil, search only the selected frame. |
| 2160 | If FRAME is a frame, search only that frame. */) | 2169 | If 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 | ||
| 2173 | DEFUN ("get-largest-window", Fget_largest_window, Sget_largest_window, 0, 1, 0, | 2186 | DEFUN ("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. |
| 2175 | A minibuffer window is never a candidate. | 2188 | A minibuffer window is never a candidate. |
| 2176 | A dedicated window is never a candidate, so if all windows are dedicated, | 2189 | A dedicated window is never a candidate unless DEDICATED is non-nil, |
| 2177 | the value is nil. | 2190 | so if all windows are dedicated, the value is nil. |
| 2178 | If optional argument FRAME is `visible', search all visible frames. | 2191 | If optional argument FRAME is `visible', search all visible frames. |
| 2179 | If FRAME is 0, search all visible and iconified frames. | 2192 | If FRAME is 0, search all visible and iconified frames. |
| 2180 | If FRAME is t, search all frames. | 2193 | If FRAME is t, search all frames. |
| 2181 | If FRAME is nil, search only the selected frame. | 2194 | If FRAME is nil, search only the selected frame. |
| 2182 | If FRAME is a frame, search only that frame. */) | 2195 | If 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 | ||
| 3865 | DEFUN ("enlarge-window", Fenlarge_window, Senlarge_window, 1, 3, "p", | 3884 | DEFUN ("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. |
| 3867 | From program, optional second arg non-nil means grow sideways ARG columns. | 3886 | From program, optional second arg non-nil means grow sideways ARG columns. |
| 3868 | Interactively, if an argument is not given, make the window one line bigger. | 3887 | Interactively, if an argument is not given, make the window one line bigger. |
| 3869 | 3888 | If HORIZONTAL is non-nil, enlarge horizontally instead of vertically. | |
| 3870 | Optional third arg PRESERVE-BEFORE, if non-nil, means do not change the size | 3889 | This function can delete windows, even the second window, if they get |
| 3871 | of the siblings above or to the left of the selected window. Only | 3890 | too small. */) |
| 3872 | siblings 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 | ||
| 3886 | DEFUN ("shrink-window", Fshrink_window, Sshrink_window, 1, 3, "p", | 3903 | DEFUN ("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. |
| 3888 | From program, optional second arg non-nil means shrink sideways arg columns. | 3905 | From program, optional second arg non-nil means shrink sideways arg columns. |
| 3889 | Interactively, if an argument is not given, make the window one line smaller. | 3906 | Interactively, if an argument is not given, make the window one line smaller. Only |
| 3890 | |||
| 3891 | Optional third arg PRESERVE-BEFORE, if non-nil, means do not change the size | ||
| 3892 | of the siblings above or to the left of the selected window. Only | ||
| 3893 | siblings to the right or below are changed. */) | 3907 | siblings 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 | ||
| 3939 | static void | 3952 | static void |
| 3940 | enlarge_window (window, delta, widthflag, preserve_before) | 3953 | enlarge_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 | |||
| 4224 | static void | ||
| 4225 | adjust_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 | ||
| 4324 | DEFUN ("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. | ||
| 4327 | If HORIZONTAL is non-nil, that means adjust the width, moving the right edge. | ||
| 4328 | Otherwise, adjust the height, moving the bottom edge. | ||
| 4329 | |||
| 4330 | Following siblings of the selected window are resized to fulfill | ||
| 4331 | the size request. If they become too small in the process, they | ||
| 4332 | are 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); |