aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorRichard M. Stallman2005-11-27 19:16:28 +0000
committerRichard M. Stallman2005-11-27 19:16:28 +0000
commit0d384044c48a4e5d6aa12d51c7b3165433225e85 (patch)
tree348a15310dc60f7a47d3f75e18384d7109e892a5 /src
parenta9f72e5feaad5267d098258af7bd5f5bbc1db3d1 (diff)
downloademacs-0d384044c48a4e5d6aa12d51c7b3165433225e85.tar.gz
emacs-0d384044c48a4e5d6aa12d51c7b3165433225e85.zip
(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.
Diffstat (limited to 'src')
-rw-r--r--src/window.c137
1 files changed, 136 insertions, 1 deletions
diff --git a/src/window.c b/src/window.c
index cb6767c5c94..2e2f6427b5f 100644
--- a/src/window.c
+++ b/src/window.c
@@ -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) */
@@ -4231,9 +4238,136 @@ enlarge_window (window, delta, horiz_flag, preserve_before)
4231 adjust_glyphs (XFRAME (WINDOW_FRAME (XWINDOW (window)))); 4238 adjust_glyphs (XFRAME (WINDOW_FRAME (XWINDOW (window))));
4232} 4239}
4233 4240
4241
4242/* Adjust the size of WINDOW by DELTA, moving only its trailing edge.
4243 HORIZ_FLAG nonzero means adjust the width, moving the right edge.
4244 zero means adjust the height, moving the bottom edge.
4245
4246 Following siblings of the selected window are resized to fulfill
4247 the size request. If they become too small in the process, they
4248 are not deleted; instead, we signal an error. */
4249
4250static void
4251adjust_window_trailing_edge (window, delta, horiz_flag)
4252 Lisp_Object window;
4253 int delta, horiz_flag;
4254{
4255 Lisp_Object parent, child;
4256 struct window *p;
4257 Lisp_Object old_config = Fcurrent_window_configuration (Qnil);
4258 int delcount = window_deletion_count;
4259
4260 /* Check values of window_min_width and window_min_height for
4261 validity. */
4262 check_min_window_sizes ();
4263
4264 if (NILP (window))
4265 window = Fselected_window ();
4266
4267 CHECK_WINDOW (window);
4268
4269 /* Give up if this window cannot be resized. */
4270 if (window_fixed_size_p (XWINDOW (window), horiz_flag, 1))
4271 error ("Window is not resizable");
4272
4273 while (1)
4274 {
4275 p = XWINDOW (window);
4276 parent = p->parent;
4277
4278 /* Make sure there is a following window. */
4279 if (NILP (parent)
4280 && (horiz_flag ? 1
4281 : NILP (XWINDOW (window)->next)))
4282 {
4283 Fset_window_configuration (old_config);
4284 error ("No other window following this one");
4285 }
4286
4287 /* Don't make this window too small. */
4288 if (XINT (CURSIZE (window)) + delta
4289 < (horiz_flag ? window_min_width : window_min_height))
4290 {
4291 Fset_window_configuration (old_config);
4292 error ("Cannot adjust window size as specified");
4293 }
4294
4295 /* Clear out some redisplay caches. */
4296 XSETFASTINT (p->last_modified, 0);
4297 XSETFASTINT (p->last_overlay_modified, 0);
4298
4299 /* Adjust this window's edge. */
4300 XSETINT (CURSIZE (window),
4301 XINT (CURSIZE (window)) + delta);
4302
4303 /* If this window has following siblings in the desired dimension,
4304 make them smaller.
4305 (If we reach the top of the tree and can never do this,
4306 we will fail and report an error, above.) */
4307 if (horiz_flag
4308 ? !NILP (XWINDOW (parent)->hchild)
4309 : !NILP (XWINDOW (parent)->vchild))
4310 {
4311 if (!NILP (XWINDOW (window)->next))
4312 {
4313 XSETINT (CURBEG (p->next),
4314 XINT (CURBEG (p->next)) + delta);
4315 size_window (p->next, XINT (CURSIZE (p->next)) - delta,
4316 horiz_flag, 0);
4317 break;
4318 }
4319 }
4320 else
4321 /* Here we have a chain of parallel siblings, in the other dimension.
4322 Change the size of the other siblings. */
4323 for (child = (horiz_flag
4324 ? XWINDOW (parent)->vchild
4325 : XWINDOW (parent)->hchild);
4326 ! NILP (child);
4327 child = XWINDOW (child)->next)
4328 if (! EQ (child, window))
4329 size_window (child, XINT (CURSIZE (child)) + delta,
4330 horiz_flag, 0);
4331
4332 window = parent;
4333 }
4334
4335 /* If we made a window so small it got deleted,
4336 we failed. Report failure. */
4337 if (delcount != window_deletion_count)
4338 {
4339 Fset_window_configuration (old_config);
4340 error ("Cannot adjust window size as specified");
4341 }
4342
4343 /* Adjust glyph matrices. */
4344 adjust_glyphs (XFRAME (WINDOW_FRAME (XWINDOW (window))));
4345}
4346
4234#undef CURBEG 4347#undef CURBEG
4235#undef CURSIZE 4348#undef CURSIZE
4236 4349
4350DEFUN ("adjust-window-trailing-edge", Fadjust_window_trailing_edge,
4351 Sadjust_window_trailing_edge, 3, 3, 0,
4352 doc: /* Adjust the bottom or right edge of WINDOW by DELTA.
4353If HORIZ_FLAG is t, that means adjust the width, moving the right edge.
4354Otherwise, adjust the height, moving the bottom edge.
4355
4356Following siblings of the selected window are resized to fulfill
4357the size request. If they become too small in the process, they
4358are not deleted; instead, we signal an error. */)
4359 (window, delta, horizontal)
4360 Lisp_Object window, delta, horizontal;
4361{
4362 CHECK_NUMBER (delta);
4363 adjust_window_trailing_edge (window, XINT (delta), !NILP (horizontal));
4364
4365 if (! NILP (Vwindow_configuration_change_hook))
4366 call1 (Vrun_hooks, Qwindow_configuration_change_hook);
4367
4368 return Qnil;
4369}
4370
4237 4371
4238 4372
4239/*********************************************************************** 4373/***********************************************************************
@@ -7114,6 +7248,7 @@ The selected frame is the one whose configuration has changed. */);
7114 defsubr (&Ssplit_window); 7248 defsubr (&Ssplit_window);
7115 defsubr (&Senlarge_window); 7249 defsubr (&Senlarge_window);
7116 defsubr (&Sshrink_window); 7250 defsubr (&Sshrink_window);
7251 defsubr (&Sadjust_window_trailing_edge);
7117 defsubr (&Sscroll_up); 7252 defsubr (&Sscroll_up);
7118 defsubr (&Sscroll_down); 7253 defsubr (&Sscroll_down);
7119 defsubr (&Sscroll_left); 7254 defsubr (&Sscroll_left);