aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/ChangeLog9
-rw-r--r--src/window.c371
2 files changed, 156 insertions, 224 deletions
diff --git a/src/ChangeLog b/src/ChangeLog
index 46926778345..e638728a655 100644
--- a/src/ChangeLog
+++ b/src/ChangeLog
@@ -1,3 +1,12 @@
12011-06-11 Martin Rudalics <rudalics@gmx.at>
2
3 * window.c (delete_deletable_window): Re-add.
4 (Fset_window_configuration): Rewrite to handle dead buffers and
5 consequently deletable windows.
6 (window_tree, Fwindow_tree): Remove. Supply functionality in
7 window.el.
8 (compare_window_configurations): Simplify code.
9
12011-06-11 Andreas Schwab <schwab@linux-m68k.org> 102011-06-11 Andreas Schwab <schwab@linux-m68k.org>
2 11
3 * image.c (imagemagick_load_image): Fix type mismatch. 12 * image.c (imagemagick_load_image): Fix type mismatch.
diff --git a/src/window.c b/src/window.c
index 959c1c31aa2..ae5798c7ebc 100644
--- a/src/window.c
+++ b/src/window.c
@@ -1974,6 +1974,14 @@ recombine_windows (Lisp_Object window)
1974 } 1974 }
1975 } 1975 }
1976} 1976}
1977
1978/* If WINDOW can be deleted, delete it. */
1979static Lisp_Object
1980delete_deletable_window (Lisp_Object window)
1981{
1982 if (!NILP (call1 (Qwindow_deletable_p, window)))
1983 call1 (Qdelete_window, window);
1984}
1977 1985
1978/*********************************************************************** 1986/***********************************************************************
1979 Window List 1987 Window List
@@ -5388,6 +5396,7 @@ the return value is nil. Otherwise the value is t. */)
5388 struct Lisp_Vector *saved_windows; 5396 struct Lisp_Vector *saved_windows;
5389 Lisp_Object new_current_buffer; 5397 Lisp_Object new_current_buffer;
5390 Lisp_Object frame; 5398 Lisp_Object frame;
5399 Lisp_Object auto_buffer_name;
5391 FRAME_PTR f; 5400 FRAME_PTR f;
5392 EMACS_INT old_point = -1; 5401 EMACS_INT old_point = -1;
5393 5402
@@ -5443,6 +5452,8 @@ the return value is nil. Otherwise the value is t. */)
5443 However, there is other stuff we should still try to do below. */ 5452 However, there is other stuff we should still try to do below. */
5444 if (FRAME_LIVE_P (f)) 5453 if (FRAME_LIVE_P (f))
5445 { 5454 {
5455 Lisp_Object window;
5456 Lisp_Object dead_windows = Qnil;
5446 register struct window *w; 5457 register struct window *w;
5447 register struct saved_window *p; 5458 register struct saved_window *p;
5448 struct window *root_window; 5459 struct window *root_window;
@@ -5519,7 +5530,8 @@ the return value is nil. Otherwise the value is t. */)
5519 for (k = 0; k < saved_windows->header.size; k++) 5530 for (k = 0; k < saved_windows->header.size; k++)
5520 { 5531 {
5521 p = SAVED_WINDOW_N (saved_windows, k); 5532 p = SAVED_WINDOW_N (saved_windows, k);
5522 w = XWINDOW (p->window); 5533 window = p->window;
5534 w = XWINDOW (window);
5523 w->next = Qnil; 5535 w->next = Qnil;
5524 5536
5525 if (!NILP (p->parent)) 5537 if (!NILP (p->parent))
@@ -5582,55 +5594,70 @@ the return value is nil. Otherwise the value is t. */)
5582 5594
5583 /* Reinstall the saved buffer and pointers into it. */ 5595 /* Reinstall the saved buffer and pointers into it. */
5584 if (NILP (p->buffer)) 5596 if (NILP (p->buffer))
5597 /* An internal window. */
5585 w->buffer = p->buffer; 5598 w->buffer = p->buffer;
5599 else if (!NILP (BVAR (XBUFFER (p->buffer), name)))
5600 /* If saved buffer is alive, install it. */
5601 {
5602 w->buffer = p->buffer;
5603 w->start_at_line_beg = p->start_at_line_beg;
5604 set_marker_restricted (w->start, p->start, w->buffer);
5605 set_marker_restricted (w->pointm, p->pointm, w->buffer);
5606 Fset_marker (BVAR (XBUFFER (w->buffer), mark),
5607 p->mark, w->buffer);
5608
5609 /* As documented in Fcurrent_window_configuration, don't
5610 restore the location of point in the buffer which was
5611 current when the window configuration was recorded. */
5612 if (!EQ (p->buffer, new_current_buffer)
5613 && XBUFFER (p->buffer) == current_buffer)
5614 Fgoto_char (w->pointm);
5615 }
5616 else if (!NILP (w->buffer) && !NILP (BVAR (XBUFFER (w->buffer), name)))
5617 /* Keep window's old buffer; make sure the markers are
5618 real. */
5619 {
5620 /* Set window markers at start of visible range. */
5621 if (XMARKER (w->start)->buffer == 0)
5622 set_marker_restricted (w->start, make_number (0),
5623 w->buffer);
5624 if (XMARKER (w->pointm)->buffer == 0)
5625 set_marker_restricted_both (w->pointm, w->buffer,
5626 BUF_PT (XBUFFER (w->buffer)),
5627 BUF_PT_BYTE (XBUFFER (w->buffer)));
5628 w->start_at_line_beg = Qt;
5629 }
5630 else if (STRINGP (auto_buffer_name =
5631 Fwindow_parameter (window, Qauto_buffer_name))
5632 && SCHARS (auto_buffer_name) != 0
5633 && !NILP (w->buffer = Fget_buffer_create (auto_buffer_name)))
5634 {
5635 set_marker_restricted (w->start, make_number (0), w->buffer);
5636 set_marker_restricted (w->pointm, make_number (0), w->buffer);
5637 w->start_at_line_beg = Qt;
5638 }
5586 else 5639 else
5640 /* Window has no live buffer, get one. */
5587 { 5641 {
5588 if (!NILP (BVAR (XBUFFER (p->buffer), name))) 5642 /* Get the buffer via other_buffer_safely in order to
5589 /* If saved buffer is alive, install it. */ 5643 avoid showing an unimportant buffer and, if necessary, to
5590 { 5644 recreate *scratch* in the course (part of Juanma's bs-show
5591 w->buffer = p->buffer; 5645 scenario from March 2011). */
5592 w->start_at_line_beg = p->start_at_line_beg; 5646 w->buffer = other_buffer_safely (Fcurrent_buffer ());
5593 set_marker_restricted (w->start, p->start, w->buffer); 5647 /* This will set the markers to beginning of visible
5594 set_marker_restricted (w->pointm, p->pointm, w->buffer); 5648 range. */
5595 Fset_marker (BVAR (XBUFFER (w->buffer), mark), 5649 set_marker_restricted (w->start, make_number (0), w->buffer);
5596 p->mark, w->buffer); 5650 set_marker_restricted (w->pointm, make_number (0), w->buffer);
5597 5651 w->start_at_line_beg = Qt;
5598 /* As documented in Fcurrent_window_configuration, don't 5652 if (!NILP (w->dedicated))
5599 restore the location of point in the buffer which was 5653 /* Record this window as dead. */
5600 current when the window configuration was recorded. */ 5654 dead_windows = Fcons (window, dead_windows);
5601 if (!EQ (p->buffer, new_current_buffer) 5655 /* Make sure window is no more dedicated. */
5602 && XBUFFER (p->buffer) == current_buffer) 5656 w->dedicated = Qnil;
5603 Fgoto_char (w->pointm);
5604 }
5605 else if (NILP (w->buffer) || NILP (BVAR (XBUFFER (w->buffer), name)))
5606 /* Else unless window has a live buffer, get one. */
5607 {
5608 w->buffer = Fcdr (Fcar (Vbuffer_alist));
5609 /* This will set the markers to beginning of visible
5610 range. */
5611 set_marker_restricted (w->start, make_number (0), w->buffer);
5612 set_marker_restricted (w->pointm, make_number (0),w->buffer);
5613 w->start_at_line_beg = Qt;
5614 }
5615 else
5616 /* Keeping window's old buffer; make sure the markers
5617 are real. */
5618 {
5619 /* Set window markers at start of visible range. */
5620 if (XMARKER (w->start)->buffer == 0)
5621 set_marker_restricted (w->start, make_number (0),
5622 w->buffer);
5623 if (XMARKER (w->pointm)->buffer == 0)
5624 set_marker_restricted_both (w->pointm, w->buffer,
5625 BUF_PT (XBUFFER (w->buffer)),
5626 BUF_PT_BYTE (XBUFFER (w->buffer)));
5627 w->start_at_line_beg = Qt;
5628 }
5629 } 5657 }
5630 } 5658 }
5631 5659
5632 FRAME_ROOT_WINDOW (f) = data->root_window; 5660 FRAME_ROOT_WINDOW (f) = data->root_window;
5633
5634 /* Arrange *not* to restore point in the buffer that was 5661 /* Arrange *not* to restore point in the buffer that was
5635 current when the window configuration was saved. */ 5662 current when the window configuration was saved. */
5636 if (EQ (XWINDOW (data->current_window)->buffer, new_current_buffer)) 5663 if (EQ (XWINDOW (data->current_window)->buffer, new_current_buffer))
@@ -5638,10 +5665,10 @@ the return value is nil. Otherwise the value is t. */)
5638 make_number (old_point), 5665 make_number (old_point),
5639 XWINDOW (data->current_window)->buffer); 5666 XWINDOW (data->current_window)->buffer);
5640 5667
5641 /* In the following call to `select-window, prevent "swapping 5668 /* In the following call to `select-window', prevent "swapping out
5642 out point" in the old selected window using the buffer that 5669 point" in the old selected window using the buffer that has
5643 has been restored into it. We already swapped out that point 5670 been restored into it. We already swapped out that point from
5644 from that window's old buffer. */ 5671 that window's old buffer. */
5645 select_window (data->current_window, Qnil, 1); 5672 select_window (data->current_window, Qnil, 1);
5646 BVAR (XBUFFER (XWINDOW (selected_window)->buffer), last_selected_window) 5673 BVAR (XBUFFER (XWINDOW (selected_window)->buffer), last_selected_window)
5647 = selected_window; 5674 = selected_window;
@@ -5682,9 +5709,16 @@ the return value is nil. Otherwise the value is t. */)
5682 } 5709 }
5683 5710
5684 adjust_glyphs (f); 5711 adjust_glyphs (f);
5685
5686 UNBLOCK_INPUT; 5712 UNBLOCK_INPUT;
5687 5713
5714 /* Scan dead buffer windows. */
5715 for (; CONSP (dead_windows); dead_windows = XCDR (dead_windows))
5716 {
5717 window = XCAR (dead_windows);
5718 if (WINDOW_LIVE_P (window) && !EQ (window, FRAME_ROOT_WINDOW (f)))
5719 delete_deletable_window (window);
5720 }
5721
5688 /* Fselect_window will have made f the selected frame, so we 5722 /* Fselect_window will have made f the selected frame, so we
5689 reselect the proper frame here. Fhandle_switch_frame will change the 5723 reselect the proper frame here. Fhandle_switch_frame will change the
5690 selected window too, but that doesn't make the call to 5724 selected window too, but that doesn't make the call to
@@ -5930,82 +5964,6 @@ redirection (see `redirect-frame-focus'). */)
5930 XSETWINDOW_CONFIGURATION (tem, data); 5964 XSETWINDOW_CONFIGURATION (tem, data);
5931 return (tem); 5965 return (tem);
5932} 5966}
5933
5934
5935/***********************************************************************
5936 Window Split Tree
5937 ***********************************************************************/
5938
5939static Lisp_Object
5940window_tree (struct window *w)
5941{
5942 Lisp_Object tail = Qnil;
5943 Lisp_Object result = Qnil;
5944
5945 while (w)
5946 {
5947 Lisp_Object wn;
5948
5949 XSETWINDOW (wn, w);
5950 if (!NILP (w->hchild))
5951 wn = Fcons (Qnil, Fcons (Fwindow_edges (wn),
5952 window_tree (XWINDOW (w->hchild))));
5953 else if (!NILP (w->vchild))
5954 wn = Fcons (Qt, Fcons (Fwindow_edges (wn),
5955 window_tree (XWINDOW (w->vchild))));
5956
5957 if (NILP (result))
5958 {
5959 result = tail = Fcons (wn, Qnil);
5960 }
5961 else
5962 {
5963 XSETCDR (tail, Fcons (wn, Qnil));
5964 tail = XCDR (tail);
5965 }
5966
5967 w = NILP (w->next) ? 0 : XWINDOW (w->next);
5968 }
5969
5970 return result;
5971}
5972
5973
5974
5975DEFUN ("window-tree", Fwindow_tree, Swindow_tree,
5976 0, 1, 0,
5977 doc: /* Return the window tree for frame FRAME.
5978
5979The return value is a list of the form (ROOT MINI), where ROOT
5980represents the window tree of the frame's root window, and MINI
5981is the frame's minibuffer window.
5982
5983If the root window is not split, ROOT is the root window itself.
5984Otherwise, ROOT is a list (DIR EDGES W1 W2 ...) where DIR is nil for a
5985horizontal split, and t for a vertical split, EDGES gives the combined
5986size and position of the subwindows in the split, and the rest of the
5987elements are the subwindows in the split. Each of the subwindows may
5988again be a window or a list representing a window split, and so on.
5989EDGES is a list \(LEFT TOP RIGHT BOTTOM) as returned by `window-edges'.
5990
5991If FRAME is nil or omitted, return information on the currently
5992selected frame. */)
5993 (Lisp_Object frame)
5994{
5995 FRAME_PTR f;
5996
5997 if (NILP (frame))
5998 frame = selected_frame;
5999
6000 CHECK_FRAME (frame);
6001 f = XFRAME (frame);
6002
6003 if (!FRAME_LIVE_P (f))
6004 return Qnil;
6005
6006 return window_tree (XWINDOW (FRAME_ROOT_WINDOW (f)));
6007}
6008
6009 5967
6010/*********************************************************************** 5968/***********************************************************************
6011 Marginal Areas 5969 Marginal Areas
@@ -6365,116 +6323,82 @@ freeze_window_starts (struct frame *f, int freeze_p)
6365 Initialization 6323 Initialization
6366 ***********************************************************************/ 6324 ***********************************************************************/
6367 6325
6368/* Return 1 if window configurations C1 and C2 6326/* Return 1 if window configurations CONFIGURATION1 and CONFIGURATION2
6369 describe the same state of affairs. This is used by Fequal. */ 6327 describe the same state of affairs. This is used by Fequal.
6328
6329 ignore_positions non-zero means ignore non-matching scroll positions
6330 and the like.
6331
6332 This ignores a couple of things like the dedicatedness status of
6333 window, splits, nest and the like. This might have to be fixed. */
6370 6334
6371int 6335int
6372compare_window_configurations (Lisp_Object c1, Lisp_Object c2, int ignore_positions) 6336compare_window_configurations (Lisp_Object configuration1, Lisp_Object configuration2, int ignore_positions)
6373{ 6337{
6374 register struct save_window_data *d1, *d2; 6338 register struct save_window_data *d1, *d2;
6375 struct Lisp_Vector *sw1, *sw2; 6339 struct Lisp_Vector *sws1, *sws2;
6376 int i; 6340 int i;
6377 6341
6378 CHECK_WINDOW_CONFIGURATION (c1); 6342 CHECK_WINDOW_CONFIGURATION (configuration1);
6379 CHECK_WINDOW_CONFIGURATION (c2); 6343 CHECK_WINDOW_CONFIGURATION (configuration2);
6380 6344
6381 d1 = (struct save_window_data *) XVECTOR (c1); 6345 d1 = (struct save_window_data *) XVECTOR (configuration1);
6382 d2 = (struct save_window_data *) XVECTOR (c2); 6346 d2 = (struct save_window_data *) XVECTOR (configuration2);
6383 sw1 = XVECTOR (d1->saved_windows); 6347 sws1 = XVECTOR (d1->saved_windows);
6384 sw2 = XVECTOR (d2->saved_windows); 6348 sws2 = XVECTOR (d2->saved_windows);
6385 6349
6386 if (d1->frame_cols != d2->frame_cols) 6350 /* Frame settings must match. */
6387 return 0; 6351 if (d1->frame_cols != d2->frame_cols
6388 if (d1->frame_lines != d2->frame_lines) 6352 || d1->frame_lines != d2->frame_lines
6389 return 0; 6353 || d1->frame_menu_bar_lines != d2->frame_menu_bar_lines
6390 if (d1->frame_menu_bar_lines != d2->frame_menu_bar_lines) 6354 || !EQ (d1->selected_frame, d2->selected_frame)
6391 return 0; 6355 || !EQ (d1->current_buffer, d2->current_buffer)
6392 if (! EQ (d1->selected_frame, d2->selected_frame)) 6356 || (!ignore_positions
6393 return 0; 6357 && (!EQ (d1->minibuf_scroll_window, d2->minibuf_scroll_window)
6394 /* Don't compare the current_window field directly. 6358 || !EQ (d1->minibuf_selected_window, d2->minibuf_selected_window)))
6395 Instead see w1_is_current and w2_is_current, below. */ 6359 || !EQ (d1->focus_frame, d2->focus_frame)
6396 if (! EQ (d1->current_buffer, d2->current_buffer)) 6360 /* Verify that the two configurations have the same number of windows. */
6397 return 0; 6361 || sws1->header.size != sws2->header.size)
6398 if (! ignore_positions)
6399 {
6400 if (! EQ (d1->minibuf_scroll_window, d2->minibuf_scroll_window))
6401 return 0;
6402 if (! EQ (d1->minibuf_selected_window, d2->minibuf_selected_window))
6403 return 0;
6404 }
6405 /* Don't compare the root_window field.
6406 We don't require the two configurations
6407 to use the same window object,
6408 and the two root windows must be equivalent
6409 if everything else compares equal. */
6410 if (! EQ (d1->focus_frame, d2->focus_frame))
6411 return 0; 6362 return 0;
6412 6363
6413 /* Verify that the two confis have the same number of windows. */ 6364 for (i = 0; i < sws1->header.size; i++)
6414 if (sw1->header.size != sw2->header.size)
6415 return 0;
6416
6417 for (i = 0; i < sw1->header.size; i++)
6418 { 6365 {
6419 struct saved_window *p1, *p2; 6366 struct saved_window *sw1, *sw2;
6420 int w1_is_current, w2_is_current; 6367 int w1_is_current, w2_is_current;
6421 6368
6422 p1 = SAVED_WINDOW_N (sw1, i); 6369 sw1 = SAVED_WINDOW_N (sws1, i);
6423 p2 = SAVED_WINDOW_N (sw2, i); 6370 sw2 = SAVED_WINDOW_N (sws2, i);
6424 6371
6425 /* Verify that the current windows in the two 6372 if (
6426 configurations correspond to each other. */ 6373 /* The "current" windows in the two configurations must
6427 w1_is_current = EQ (d1->current_window, p1->window); 6374 correspond to each other. */
6428 w2_is_current = EQ (d2->current_window, p2->window); 6375 EQ (d1->current_window, sw1->window)
6429 6376 != EQ (d2->current_window, sw2->window)
6430 if (w1_is_current != w2_is_current) 6377 /* Windows' buffers must match. */
6431 return 0; 6378 || !EQ (sw1->buffer, sw2->buffer)
6432 6379 || !EQ (sw1->left_col, sw2->left_col)
6433 /* Verify that the corresponding windows do match. */ 6380 || !EQ (sw1->top_line, sw2->top_line)
6434 if (! EQ (p1->buffer, p2->buffer)) 6381 || !EQ (sw1->total_cols, sw2->total_cols)
6435 return 0; 6382 || !EQ (sw1->total_lines, sw2->total_lines)
6436 if (! EQ (p1->left_col, p2->left_col)) 6383 || !EQ (sw1->display_table, sw2->display_table)
6437 return 0; 6384 /* The next two disjuncts check the window structure for
6438 if (! EQ (p1->top_line, p2->top_line)) 6385 equality. */
6439 return 0; 6386 || !EQ (sw1->parent, sw2->parent)
6440 if (! EQ (p1->total_cols, p2->total_cols)) 6387 || !EQ (sw1->prev, sw2->prev)
6441 return 0; 6388 || (!ignore_positions
6442 if (! EQ (p1->total_lines, p2->total_lines)) 6389 && (!EQ (sw1->hscroll, sw2->hscroll)
6443 return 0; 6390 || !EQ (sw1->min_hscroll, sw2->min_hscroll)
6444 if (! EQ (p1->display_table, p2->display_table)) 6391 || !EQ (sw1->start_at_line_beg, sw2->start_at_line_beg)
6445 return 0; 6392 || NILP (Fequal (sw1->start, sw2->start))
6446 if (! EQ (p1->parent, p2->parent)) 6393 || NILP (Fequal (sw1->pointm, sw2->pointm))
6447 return 0; 6394 || NILP (Fequal (sw1->mark, sw2->mark))))
6448 if (! EQ (p1->prev, p2->prev)) 6395 || !EQ (sw1->left_margin_cols, sw2->left_margin_cols)
6449 return 0; 6396 || !EQ (sw1->right_margin_cols, sw2->right_margin_cols)
6450 if (! ignore_positions) 6397 || !EQ (sw1->left_fringe_width, sw2->left_fringe_width)
6451 { 6398 || !EQ (sw1->right_fringe_width, sw2->right_fringe_width)
6452 if (! EQ (p1->hscroll, p2->hscroll)) 6399 || !EQ (sw1->fringes_outside_margins, sw2->fringes_outside_margins)
6453 return 0; 6400 || !EQ (sw1->scroll_bar_width, sw2->scroll_bar_width)
6454 if (!EQ (p1->min_hscroll, p2->min_hscroll)) 6401 || !EQ (sw1->vertical_scroll_bar_type, sw2->vertical_scroll_bar_type))
6455 return 0;
6456 if (! EQ (p1->start_at_line_beg, p2->start_at_line_beg))
6457 return 0;
6458 if (NILP (Fequal (p1->start, p2->start)))
6459 return 0;
6460 if (NILP (Fequal (p1->pointm, p2->pointm)))
6461 return 0;
6462 if (NILP (Fequal (p1->mark, p2->mark)))
6463 return 0;
6464 }
6465 if (! EQ (p1->left_margin_cols, p2->left_margin_cols))
6466 return 0;
6467 if (! EQ (p1->right_margin_cols, p2->right_margin_cols))
6468 return 0;
6469 if (! EQ (p1->left_fringe_width, p2->left_fringe_width))
6470 return 0;
6471 if (! EQ (p1->right_fringe_width, p2->right_fringe_width))
6472 return 0;
6473 if (! EQ (p1->fringes_outside_margins, p2->fringes_outside_margins))
6474 return 0;
6475 if (! EQ (p1->scroll_bar_width, p2->scroll_bar_width))
6476 return 0;
6477 if (! EQ (p1->vertical_scroll_bar_type, p2->vertical_scroll_bar_type))
6478 return 0; 6402 return 0;
6479 } 6403 }
6480 6404
@@ -6768,7 +6692,6 @@ function `window-nest' and altered by the function `set-window-nest'. */);
6768 defsubr (&Swindow_configuration_frame); 6692 defsubr (&Swindow_configuration_frame);
6769 defsubr (&Sset_window_configuration); 6693 defsubr (&Sset_window_configuration);
6770 defsubr (&Scurrent_window_configuration); 6694 defsubr (&Scurrent_window_configuration);
6771 defsubr (&Swindow_tree);
6772 defsubr (&Sset_window_margins); 6695 defsubr (&Sset_window_margins);
6773 defsubr (&Swindow_margins); 6696 defsubr (&Swindow_margins);
6774 defsubr (&Sset_window_fringes); 6697 defsubr (&Sset_window_fringes);