Mercurial > emacs
changeset 25792:80e84cb91f1e
(window_min_size): Add parameter ignore_fixed_p.
(change_window_height): Call window_min_size with new parameter.
(shrink_window_lowest_first, save_restore_orig_size,
grow_mini_window, shrink_mini_window): New.
(make_window, replace_window): Initialize orig_top and
orig_height.
(enlarge_window): Renamed from change_window_height. Make it
static.
(Fdisplay_buffer, Fenlage_window, Fshrink_window): Call
enlarge_window instead of change_window_height.
author | Gerd Moellmann <gerd@gnu.org> |
---|---|
date | Thu, 23 Sep 1999 11:58:37 +0000 |
parents | 6413bcf4ea32 |
children | 2bbee3534773 |
files | src/window.c |
diffstat | 1 files changed, 218 insertions(+), 22 deletions(-) [+] |
line wrap: on
line diff
--- a/src/window.c Thu Sep 23 11:58:34 1999 +0000 +++ b/src/window.c Thu Sep 23 11:58:37 1999 +0000 @@ -54,12 +54,13 @@ static void window_scroll_pixel_based P_ ((Lisp_Object, int, int, int)); static void window_scroll_line_based P_ ((Lisp_Object, int, int, int)); static int window_min_size_1 P_ ((struct window *, int)); -static int window_min_size P_ ((struct window *, int, int *)); -static int window_fixed_size_p P_ ((struct window *, int, int)); +static int window_min_size P_ ((struct window *, int, int, int *)); static void size_window P_ ((Lisp_Object, int, int, int)); static void foreach_window_1 P_ ((struct window *, void (*fn) (), int, int, int, int)); static void freeze_window_start P_ ((struct window *, int)); +static int window_fixed_size_p P_ ((struct window *, int, int)); +static void enlarge_window P_ ((int, int)); /* This is the window in which the terminal's cursor should @@ -210,6 +211,7 @@ XSETFASTINT (p->height, 0); XSETFASTINT (p->width, 0); XSETFASTINT (p->hscroll, 0); + p->orig_top = p->orig_height = Qnil; p->start = Fmake_marker (); p->pointm = Fmake_marker (); XSETFASTINT (p->use_time, 0); @@ -923,6 +925,7 @@ XSETFASTINT (p->window_end_pos, 0); p->window_end_valid = Qnil; p->frozen_window_start_p = 0; + p->orig_top = p->orig_height = Qnil; p->next = tem = o->next; if (!NILP (tem)) @@ -2104,17 +2107,22 @@ /* Return the minimum size of window W, taking fixed-size windows into account. WIDTH_P non-zero means return the minimum width, - otherwise return the minimum height. Set *FIXED to 1 if W is - fixed-size unless FIXED is null. */ + otherwise return the minimum height. IGNORE_FIXED_P non-zero means + ignore if W is fixed-size. Set *FIXED to 1 if W is fixed-size + unless FIXED is null. */ static int -window_min_size (w, width_p, fixed) +window_min_size (w, width_p, ignore_fixed_p, fixed) struct window *w; - int width_p, *fixed; + int width_p, ignore_fixed_p, *fixed; { int size, fixed_p; - fixed_p = window_fixed_size_p (w, width_p, 1); + if (ignore_fixed_p) + fixed_p = 0; + else + fixed_p = window_fixed_size_p (w, width_p, 1); + if (fixed) *fixed = fixed_p; @@ -2122,7 +2130,7 @@ size = width_p ? XFASTINT (w->width) : XFASTINT (w->height); else size = window_min_size_1 (w, width_p); - + return size; } @@ -2785,9 +2793,9 @@ old_selected_window = selected_window; selected_window = upper; - change_window_height ((total / 2 - - XFASTINT (XWINDOW (upper)->height)), - 0); + enlarge_window ((total / 2 + - XFASTINT (XWINDOW (upper)->height)), + 0); selected_window = old_selected_window; } } @@ -3022,7 +3030,7 @@ register Lisp_Object arg, side; { CHECK_NUMBER (arg, 0); - change_window_height (XINT (arg), !NILP (side)); + enlarge_window (XINT (arg), !NILP (side)); if (! NILP (Vwindow_configuration_change_hook)) call1 (Vrun_hooks, Qwindow_configuration_change_hook); @@ -3037,7 +3045,7 @@ register Lisp_Object arg, side; { CHECK_NUMBER (arg, 0); - change_window_height (-XINT (arg), !NILP (side)); + enlarge_window (-XINT (arg), !NILP (side)); if (! NILP (Vwindow_configuration_change_hook)) call1 (Vrun_hooks, Qwindow_configuration_change_hook); @@ -3074,8 +3082,8 @@ fullfil the size request. If they become too small in the process, they will be deleted. */ -void -change_window_height (delta, widthflag) +static void +enlarge_window (delta, widthflag) int delta, widthflag; { Lisp_Object parent, window, next, prev; @@ -3124,10 +3132,10 @@ maxdelta = (!NILP (parent) ? (*sizefun) (parent) - *sizep : !NILP (p->next) ? ((*sizefun) (p->next) - window_min_size (XWINDOW (p->next), - widthflag, 0)) + widthflag, 0, 0)) : !NILP (p->prev) ? ((*sizefun) (p->prev) - window_min_size (XWINDOW (p->prev), - widthflag, 0)) + widthflag, 0, 0)) /* This is a frame with only one window, a minibuffer-only or a minibufferless frame. */ : (delta = 0)); @@ -3139,7 +3147,7 @@ delta = maxdelta; } - if (*sizep + delta < window_min_size (XWINDOW (window), widthflag, 0)) + if (*sizep + delta < window_min_size (XWINDOW (window), widthflag, 0, 0)) { delete_window (window); return; @@ -3152,10 +3160,10 @@ maximum = 0; for (next = p->next; ! NILP (next); next = XWINDOW (next)->next) maximum += (*sizefun) (next) - window_min_size (XWINDOW (next), - widthflag, 0); + widthflag, 0, 0); for (prev = p->prev; ! NILP (prev); prev = XWINDOW (prev)->prev) maximum += (*sizefun) (prev) - window_min_size (XWINDOW (prev), - widthflag, 0); + widthflag, 0, 0); /* If we can get it all from them, do so. */ if (delta <= maximum) @@ -3176,7 +3184,7 @@ { int this_one = ((*sizefun) (next) - window_min_size (XWINDOW (next), - widthflag, &fixed_p)); + widthflag, 0, &fixed_p)); if (!fixed_p) { if (this_one > delta) @@ -3198,7 +3206,7 @@ { int this_one = ((*sizefun) (prev) - window_min_size (XWINDOW (prev), - widthflag, &fixed_p)); + widthflag, 0, &fixed_p)); if (!fixed_p) { if (this_one > delta) @@ -3309,6 +3317,194 @@ #undef CURSIZE + +/*********************************************************************** + Resizing Mini-Windows + ***********************************************************************/ + +static void shrink_window_lowest_first P_ ((struct window *, int)); +static void save_restore_orig_size P_ ((struct window *, int)); + + +/* Shrink windows rooted in window W to HEIGHT. Take the space needed + from lowest windows first. */ + +static void +shrink_window_lowest_first (w, height) + struct window *w; + int height; +{ + struct window *c; + Lisp_Object child; + int old_height; + + xassert (!MINI_WINDOW_P (w)); + + /* Set redisplay hints. */ + XSETFASTINT (w->last_modified, 0); + XSETFASTINT (w->last_overlay_modified, 0); + windows_or_buffers_changed++; + FRAME_WINDOW_SIZES_CHANGED (XFRAME (WINDOW_FRAME (w))) = 1; + + old_height = XFASTINT (w->height); + XSETFASTINT (w->height, height); + + if (!NILP (w->hchild)) + { + for (child = w->hchild; !NILP (child); child = c->next) + { + c = XWINDOW (child); + c->top = w->top; + shrink_window_lowest_first (c, height); + } + } + else if (!NILP (w->vchild)) + { + Lisp_Object last_child; + int delta = old_height - height; + int last_top; + + /* Find the last child. We are taking space from lowest windows + first, so we iterate over children from the last child + backwards. */ + for (child = w->vchild; !NILP (child); child = XWINDOW (child)->next) + last_child = child; + + /* Assign new heights. We leave only MIN_SAFE_WINDOW_HEIGHT. */ + for (child = last_child; delta && !NILP (child); child = c->prev) + { + int this_one; + + c = XWINDOW (child); + this_one = XFASTINT (c->height) - MIN_SAFE_WINDOW_HEIGHT; + + if (this_one > delta) + this_one = delta; + + shrink_window_lowest_first (c, XFASTINT (c->height) - this_one); + delta -= this_one; + } + + /* Compute new positions. */ + last_top = w->top; + for (child = w->vchild; !NILP (child); child = c->next) + { + c = XWINDOW (child); + c->top = make_number (last_top); + shrink_window_lowest_first (c, XFASTINT (c->height)); + last_top += XFASTINT (c->height); + } + } +} + + +/* Save or restore positions and sizes in the window tree rooted at W. + SAVE_P non-zero means save top position and height in orig_top and + orig_height members of the window structure. Otherwise, restore top + and height from orig_top and orig_height. */ + +static void +save_restore_orig_size (w, save_p) + struct window *w; + int save_p; +{ + while (w) + { + if (!NILP (w->hchild)) + save_restore_orig_size (XWINDOW (w->hchild), save_p); + else if (!NILP (w->vchild)) + save_restore_orig_size (XWINDOW (w->vchild), save_p); + + if (save_p) + { + w->orig_top = w->top; + w->orig_height = w->height; + } + else + { + xassert (INTEGERP (w->orig_top) && INTEGERP (w->orig_height)); + w->top = w->orig_top; + w->height = w->orig_height; + w->orig_height = w->orig_top = Qnil; + } + + XSETFASTINT (w->last_modified, 0); + XSETFASTINT (w->last_overlay_modified, 0); + w = NILP (w->next) ? NULL : XWINDOW (w->next); + } +} + + +/* Grow mini-window W by DELTA lines, DELTA >= 0, or as much as we can + without deleting other windows. */ + +void +grow_mini_window (w, delta) + struct window *w; + int delta; +{ + struct frame *f = XFRAME (w->frame); + struct window *root; + + xassert (MINI_WINDOW_P (w)); + xassert (delta >= 0); + + /* Check values of window_min_width and window_min_height for + validity. */ + check_min_window_sizes (); + + /* Compute how much we can enlarge the mini-window without deleting + other windows. */ + root = XWINDOW (FRAME_ROOT_WINDOW (f)); + if (delta) + { + int min_height = window_min_size (root, 0, 0, 0); + if (XFASTINT (root->height) - delta < min_height) + delta = XFASTINT (root->height) - min_height; + } + + if (delta) + { + /* Save original window sizes and positions, if not already done. */ + if (NILP (root->orig_top)) + save_restore_orig_size (root, 1); + + /* Shrink other windows. */ + shrink_window_lowest_first (root, XFASTINT (root->height) - delta); + + /* Grow the mini-window. */ + w->top = make_number (XFASTINT (root->top) + XFASTINT (root)->height); + w->height = make_number (XFASTINT (w->height) + delta); + XSETFASTINT (w->last_modified, 0); + XSETFASTINT (w->last_overlay_modified, 0); + + adjust_glyphs (f); + } +} + + +/* Shrink mini-window W back to its original size before the first + call to grow_mini_window. Resize other windows on the same frame + back to their original size. */ + +void +shrink_mini_window (w) + struct window *w; +{ + struct frame *f = XFRAME (w->frame); + struct window *root = XWINDOW (FRAME_ROOT_WINDOW (f)); + + if (!NILP (root->orig_height)) + { + save_restore_orig_size (root, 0); + adjust_glyphs (f); + FRAME_WINDOW_SIZES_CHANGED (f) = 1; + windows_or_buffers_changed = 1; + } +} + + + /* Mark window cursors off for all windows in the window tree rooted at W by setting their phys_cursor_on_p flag to zero. Called from xterm.c, e.g. when a frame is cleared and thereby all cursors on