Mercurial > emacs
changeset 67156:33af3a25cca6
(adjust_window_trailing_edge): New function.
(Fadjust_window_trailing_edge): New function.
(syms_of_window): defsubr it.
(window_deletion_count): New variable.
(delete_window): Update window_deletion_count.
author | Richard M. Stallman <rms@gnu.org> |
---|---|
date | Sun, 27 Nov 2005 19:16:28 +0000 |
parents | 30968a553175 |
children | 657155c4b77b |
files | src/window.c |
diffstat | 1 files changed, 136 insertions(+), 1 deletions(-) [+] |
line wrap: on
line diff
--- a/src/window.c Sun Nov 27 17:02:13 2005 +0000 +++ b/src/window.c Sun Nov 27 19:16:28 2005 +0000 @@ -210,6 +210,10 @@ Lisp_Object Vscroll_preserve_screen_position; +/* Incremented by 1 whenever a window is deleted. */ + +int window_deletion_count; + #if 0 /* This isn't used anywhere. */ /* Nonzero means we can split a frame even if it is "unsplittable". */ static int inhibit_frame_unsplittable; @@ -1333,7 +1337,7 @@ CHECK_WINDOW (window); p = XWINDOW (window); - /* It's okay to delete an already-deleted window. */ + /* It's a no-op to delete an already-deleted window. */ if (NILP (p->buffer) && NILP (p->hchild) && NILP (p->vchild)) @@ -1397,6 +1401,9 @@ } } + /* Now we know we can delete this one. */ + window_deletion_count++; + tem = p->buffer; /* tem is null for dummy parent windows (which have inferiors but not any contents themselves) */ @@ -4231,9 +4238,136 @@ adjust_glyphs (XFRAME (WINDOW_FRAME (XWINDOW (window)))); } + +/* Adjust the size of WINDOW by DELTA, moving only its trailing edge. + HORIZ_FLAG nonzero means adjust the width, moving the right edge. + zero means adjust the height, moving the bottom edge. + + Following siblings of the selected window are resized to fulfill + the size request. If they become too small in the process, they + are not deleted; instead, we signal an error. */ + +static void +adjust_window_trailing_edge (window, delta, horiz_flag) + Lisp_Object window; + int delta, horiz_flag; +{ + Lisp_Object parent, child; + struct window *p; + Lisp_Object old_config = Fcurrent_window_configuration (Qnil); + int delcount = window_deletion_count; + + /* Check values of window_min_width and window_min_height for + validity. */ + check_min_window_sizes (); + + if (NILP (window)) + window = Fselected_window (); + + CHECK_WINDOW (window); + + /* Give up if this window cannot be resized. */ + if (window_fixed_size_p (XWINDOW (window), horiz_flag, 1)) + error ("Window is not resizable"); + + while (1) + { + p = XWINDOW (window); + parent = p->parent; + + /* Make sure there is a following window. */ + if (NILP (parent) + && (horiz_flag ? 1 + : NILP (XWINDOW (window)->next))) + { + Fset_window_configuration (old_config); + error ("No other window following this one"); + } + + /* Don't make this window too small. */ + if (XINT (CURSIZE (window)) + delta + < (horiz_flag ? window_min_width : window_min_height)) + { + Fset_window_configuration (old_config); + error ("Cannot adjust window size as specified"); + } + + /* Clear out some redisplay caches. */ + XSETFASTINT (p->last_modified, 0); + XSETFASTINT (p->last_overlay_modified, 0); + + /* Adjust this window's edge. */ + XSETINT (CURSIZE (window), + XINT (CURSIZE (window)) + delta); + + /* If this window has following siblings in the desired dimension, + make them smaller. + (If we reach the top of the tree and can never do this, + we will fail and report an error, above.) */ + if (horiz_flag + ? !NILP (XWINDOW (parent)->hchild) + : !NILP (XWINDOW (parent)->vchild)) + { + if (!NILP (XWINDOW (window)->next)) + { + XSETINT (CURBEG (p->next), + XINT (CURBEG (p->next)) + delta); + size_window (p->next, XINT (CURSIZE (p->next)) - delta, + horiz_flag, 0); + break; + } + } + else + /* Here we have a chain of parallel siblings, in the other dimension. + Change the size of the other siblings. */ + for (child = (horiz_flag + ? XWINDOW (parent)->vchild + : XWINDOW (parent)->hchild); + ! NILP (child); + child = XWINDOW (child)->next) + if (! EQ (child, window)) + size_window (child, XINT (CURSIZE (child)) + delta, + horiz_flag, 0); + + window = parent; + } + + /* If we made a window so small it got deleted, + we failed. Report failure. */ + if (delcount != window_deletion_count) + { + Fset_window_configuration (old_config); + error ("Cannot adjust window size as specified"); + } + + /* Adjust glyph matrices. */ + adjust_glyphs (XFRAME (WINDOW_FRAME (XWINDOW (window)))); +} + #undef CURBEG #undef CURSIZE +DEFUN ("adjust-window-trailing-edge", Fadjust_window_trailing_edge, + Sadjust_window_trailing_edge, 3, 3, 0, + doc: /* Adjust the bottom or right edge of WINDOW by DELTA. +If HORIZ_FLAG is t, that means adjust the width, moving the right edge. +Otherwise, adjust the height, moving the bottom edge. + +Following siblings of the selected window are resized to fulfill +the size request. If they become too small in the process, they +are not deleted; instead, we signal an error. */) + (window, delta, horizontal) + Lisp_Object window, delta, horizontal; +{ + CHECK_NUMBER (delta); + adjust_window_trailing_edge (window, XINT (delta), !NILP (horizontal)); + + if (! NILP (Vwindow_configuration_change_hook)) + call1 (Vrun_hooks, Qwindow_configuration_change_hook); + + return Qnil; +} + /*********************************************************************** @@ -7114,6 +7248,7 @@ defsubr (&Ssplit_window); defsubr (&Senlarge_window); defsubr (&Sshrink_window); + defsubr (&Sadjust_window_trailing_edge); defsubr (&Sscroll_up); defsubr (&Sscroll_down); defsubr (&Sscroll_left);