diff options
| -rw-r--r-- | src/window.c | 105 |
1 files changed, 79 insertions, 26 deletions
diff --git a/src/window.c b/src/window.c index 8d6e24de2c5..65c33093ebe 100644 --- a/src/window.c +++ b/src/window.c | |||
| @@ -29,7 +29,7 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ | |||
| 29 | #include "disptab.h" | 29 | #include "disptab.h" |
| 30 | #include "keyboard.h" | 30 | #include "keyboard.h" |
| 31 | 31 | ||
| 32 | Lisp_Object Qwindowp; | 32 | Lisp_Object Qwindowp, Qlive_window_p; |
| 33 | 33 | ||
| 34 | Lisp_Object Fnext_window (), Fdelete_window (), Fselect_window (); | 34 | Lisp_Object Fnext_window (), Fdelete_window (), Fselect_window (); |
| 35 | Lisp_Object Fset_window_buffer (), Fsplit_window (), Frecenter (); | 35 | Lisp_Object Fset_window_buffer (), Fsplit_window (), Frecenter (); |
| @@ -105,6 +105,16 @@ DEFUN ("windowp", Fwindowp, Swindowp, 1, 1, 0, | |||
| 105 | return XTYPE (obj) == Lisp_Window ? Qt : Qnil; | 105 | return XTYPE (obj) == Lisp_Window ? Qt : Qnil; |
| 106 | } | 106 | } |
| 107 | 107 | ||
| 108 | DEFUN ("live-window-p", Flive_window_p, Slive_window_p, 1, 1, 0, | ||
| 109 | "Returns t if OBJ is a window which is currently visible.") | ||
| 110 | (obj) | ||
| 111 | Lisp_Object obj; | ||
| 112 | { | ||
| 113 | return ((XTYPE (obj) == Lisp_Window | ||
| 114 | && ! NILP (XWINDOW (obj)->buffer)) | ||
| 115 | ? Qt : Qnil); | ||
| 116 | } | ||
| 117 | |||
| 108 | Lisp_Object | 118 | Lisp_Object |
| 109 | make_window () | 119 | make_window () |
| 110 | { | 120 | { |
| @@ -158,7 +168,7 @@ used by that frame.") | |||
| 158 | return FRAME_MINIBUF_WINDOW (XFRAME (frame)); | 168 | return FRAME_MINIBUF_WINDOW (XFRAME (frame)); |
| 159 | } | 169 | } |
| 160 | 170 | ||
| 161 | DEFUN ("window-minibuffer-p", Fwindow_minibuffer_p, Swindow_minibuffer_p, 1, 1, 0, | 171 | DEFUN ("window-minibuffer-p", Fwindow_minibuffer_p, Swindow_minibuffer_p, 0, 1, 0, |
| 162 | "Returns non-nil if WINDOW is a minibuffer window.") | 172 | "Returns non-nil if WINDOW is a minibuffer window.") |
| 163 | (window) | 173 | (window) |
| 164 | Lisp_Object window; | 174 | Lisp_Object window; |
| @@ -190,11 +200,7 @@ POS defaults to point; WINDOW, to the selected window.") | |||
| 190 | posint = XINT (pos); | 200 | posint = XINT (pos); |
| 191 | } | 201 | } |
| 192 | 202 | ||
| 193 | if (NILP (window)) | 203 | w = decode_window (window); |
| 194 | window = selected_window; | ||
| 195 | else | ||
| 196 | CHECK_WINDOW (window, 1); | ||
| 197 | w = XWINDOW (window); | ||
| 198 | top = marker_position (w->start); | 204 | top = marker_position (w->start); |
| 199 | 205 | ||
| 200 | if (posint < top) | 206 | if (posint < top) |
| @@ -235,7 +241,7 @@ decode_window (window) | |||
| 235 | if (NILP (window)) | 241 | if (NILP (window)) |
| 236 | return XWINDOW (selected_window); | 242 | return XWINDOW (selected_window); |
| 237 | 243 | ||
| 238 | CHECK_WINDOW (window, 0); | 244 | CHECK_LIVE_WINDOW (window, 0); |
| 239 | return XWINDOW (window); | 245 | return XWINDOW (window); |
| 240 | } | 246 | } |
| 241 | 247 | ||
| @@ -370,7 +376,7 @@ If they are on the border between WINDOW and its right sibling,\n\ | |||
| 370 | { | 376 | { |
| 371 | int x, y; | 377 | int x, y; |
| 372 | 378 | ||
| 373 | CHECK_WINDOW (window, 0); | 379 | CHECK_LIVE_WINDOW (window, 0); |
| 374 | CHECK_CONS (coordinates, 1); | 380 | CHECK_CONS (coordinates, 1); |
| 375 | x = XINT (Fcar (coordinates)); | 381 | x = XINT (Fcar (coordinates)); |
| 376 | y = XINT (Fcdr (coordinates)); | 382 | y = XINT (Fcdr (coordinates)); |
| @@ -682,12 +688,21 @@ DEFUN ("delete-window", Fdelete_window, Sdelete_window, 0, 1, "", | |||
| 682 | register struct window *p; | 688 | register struct window *p; |
| 683 | register struct window *par; | 689 | register struct window *par; |
| 684 | 690 | ||
| 691 | /* Because this function is called by other C code on non-leaf | ||
| 692 | windows, the CHECK_LIVE_WINDOW macro would choke inappropriately, | ||
| 693 | so we can't decode_window here. */ | ||
| 685 | if (NILP (window)) | 694 | if (NILP (window)) |
| 686 | window = selected_window; | 695 | window = selected_window; |
| 687 | else | 696 | else |
| 688 | CHECK_WINDOW (window, 0); | 697 | CHECK_WINDOW (window, 0); |
| 689 | |||
| 690 | p = XWINDOW (window); | 698 | p = XWINDOW (window); |
| 699 | |||
| 700 | /* It's okay to delete an already-deleted window. */ | ||
| 701 | if (NILP (p->buffer) | ||
| 702 | && NILP (p->hchild) | ||
| 703 | && NILP (p->vchild)) | ||
| 704 | return Qnil; | ||
| 705 | |||
| 691 | parent = p->parent; | 706 | parent = p->parent; |
| 692 | if (NILP (parent)) | 707 | if (NILP (parent)) |
| 693 | error ("Attempt to delete minibuffer or sole ordinary window"); | 708 | error ("Attempt to delete minibuffer or sole ordinary window"); |
| @@ -695,8 +710,25 @@ DEFUN ("delete-window", Fdelete_window, Sdelete_window, 0, 1, "", | |||
| 695 | 710 | ||
| 696 | windows_or_buffers_changed++; | 711 | windows_or_buffers_changed++; |
| 697 | 712 | ||
| 698 | if (EQ (window, selected_window)) | 713 | /* Are we trying to delete any frame's selected window? */ |
| 699 | Fselect_window (Fnext_window (window, Qnil, Qnil)); | 714 | { |
| 715 | Lisp_Object frame = WINDOW_FRAME (XWINDOW (window)); | ||
| 716 | |||
| 717 | if (EQ (window, FRAME_SELECTED_WINDOW (XFRAME (frame)))) | ||
| 718 | { | ||
| 719 | Lisp_Object alternative = Fnext_window (window, Qlambda, Qnil); | ||
| 720 | |||
| 721 | /* If we're about to delete the selected window on the | ||
| 722 | selected frame, then we should use Fselect_window to select | ||
| 723 | the new window. On the other hand, if we're about to | ||
| 724 | delete the selected window on any other frame, we shouldn't do | ||
| 725 | anything but set the frame's selected_window slot. */ | ||
| 726 | if (EQ (window, selected_window)) | ||
| 727 | Fselect_window (alternative); | ||
| 728 | else | ||
| 729 | FRAME_SELECTED_WINDOW (XFRAME (frame)) = alternative; | ||
| 730 | } | ||
| 731 | } | ||
| 700 | 732 | ||
| 701 | tem = p->buffer; | 733 | tem = p->buffer; |
| 702 | /* tem is null for dummy parent windows | 734 | /* tem is null for dummy parent windows |
| @@ -706,7 +738,6 @@ DEFUN ("delete-window", Fdelete_window, Sdelete_window, 0, 1, "", | |||
| 706 | unshow_buffer (p); | 738 | unshow_buffer (p); |
| 707 | unchain_marker (p->pointm); | 739 | unchain_marker (p->pointm); |
| 708 | unchain_marker (p->start); | 740 | unchain_marker (p->start); |
| 709 | p->buffer = Qnil; | ||
| 710 | } | 741 | } |
| 711 | 742 | ||
| 712 | tem = p->next; | 743 | tem = p->next; |
| @@ -747,12 +778,22 @@ DEFUN ("delete-window", Fdelete_window, Sdelete_window, 0, 1, "", | |||
| 747 | 778 | ||
| 748 | /* If parent now has only one child, | 779 | /* If parent now has only one child, |
| 749 | put the child into the parent's place. */ | 780 | put the child into the parent's place. */ |
| 750 | |||
| 751 | tem = par->hchild; | 781 | tem = par->hchild; |
| 752 | if (NILP (tem)) | 782 | if (NILP (tem)) |
| 753 | tem = par->vchild; | 783 | tem = par->vchild; |
| 754 | if (NILP (XWINDOW (tem)->next)) | 784 | if (NILP (XWINDOW (tem)->next)) |
| 755 | replace_window (parent, tem); | 785 | replace_window (parent, tem); |
| 786 | |||
| 787 | /* Since we may be deleting combination windows, we must make sure that | ||
| 788 | not only p but all its children have been marked as deleted. */ | ||
| 789 | if (! NILP (p->hchild)) | ||
| 790 | delete_all_subwindows (XWINDOW (p->hchild)); | ||
| 791 | else if (! NILP (p->vchild)) | ||
| 792 | delete_all_subwindows (XWINDOW (p->vchild)); | ||
| 793 | |||
| 794 | /* Mark this window as deleted. */ | ||
| 795 | p->buffer = p->hchild = p->vchild = Qnil; | ||
| 796 | |||
| 756 | return Qnil; | 797 | return Qnil; |
| 757 | } | 798 | } |
| 758 | 799 | ||
| @@ -786,7 +827,7 @@ above. If neither nil nor t, restrict to WINDOW's frame.") | |||
| 786 | if (NILP (window)) | 827 | if (NILP (window)) |
| 787 | window = selected_window; | 828 | window = selected_window; |
| 788 | else | 829 | else |
| 789 | CHECK_WINDOW (window, 0); | 830 | CHECK_LIVE_WINDOW (window, 0); |
| 790 | 831 | ||
| 791 | start_window = window; | 832 | start_window = window; |
| 792 | 833 | ||
| @@ -883,7 +924,7 @@ above. If neither nil nor t, restrict to WINDOW's frame.") | |||
| 883 | if (NILP (window)) | 924 | if (NILP (window)) |
| 884 | window = selected_window; | 925 | window = selected_window; |
| 885 | else | 926 | else |
| 886 | CHECK_WINDOW (window, 0); | 927 | CHECK_LIVE_WINDOW (window, 0); |
| 887 | 928 | ||
| 888 | start_window = window; | 929 | start_window = window; |
| 889 | 930 | ||
| @@ -1170,7 +1211,7 @@ window_loop (type, obj, mini, frames) | |||
| 1170 | 1211 | ||
| 1171 | return best_window; | 1212 | return best_window; |
| 1172 | } | 1213 | } |
| 1173 | 1214 | ||
| 1174 | DEFUN ("get-lru-window", Fget_lru_window, Sget_lru_window, 0, 1, 0, | 1215 | DEFUN ("get-lru-window", Fget_lru_window, Sget_lru_window, 0, 1, 0, |
| 1175 | "Return the window least recently selected or used for display.\n\ | 1216 | "Return the window least recently selected or used for display.\n\ |
| 1176 | If optional argument FRAMES is t, search all frames. If FRAME is a\n\ | 1217 | If optional argument FRAMES is t, search all frames. If FRAME is a\n\ |
| @@ -1227,7 +1268,7 @@ Only the frame WINDOW is on is affected.") | |||
| 1227 | if (NILP (window)) | 1268 | if (NILP (window)) |
| 1228 | window = selected_window; | 1269 | window = selected_window; |
| 1229 | else | 1270 | else |
| 1230 | CHECK_WINDOW (window, 0); | 1271 | CHECK_LIVE_WINDOW (window, 0); |
| 1231 | 1272 | ||
| 1232 | w = XWINDOW (window); | 1273 | w = XWINDOW (window); |
| 1233 | top = XFASTINT (w->top); | 1274 | top = XFASTINT (w->top); |
| @@ -1296,10 +1337,10 @@ check_min_window_sizes () | |||
| 1296 | 1337 | ||
| 1297 | /* If *ROWS or *COLS are too small a size for FRAME, set them to the | 1338 | /* If *ROWS or *COLS are too small a size for FRAME, set them to the |
| 1298 | minimum allowable size. */ | 1339 | minimum allowable size. */ |
| 1299 | extern void | 1340 | void |
| 1300 | check_frame_size (frame, rows, cols) | 1341 | check_frame_size (frame, rows, cols) |
| 1301 | FRAME_PTR frame; | 1342 | FRAME_PTR frame; |
| 1302 | int *rows, *cols; | 1343 | int *rows, *cols; |
| 1303 | { | 1344 | { |
| 1304 | /* For height, we have to see whether the frame has a minibuffer, and | 1345 | /* For height, we have to see whether the frame has a minibuffer, and |
| 1305 | whether it wants a mode line. */ | 1346 | whether it wants a mode line. */ |
| @@ -1497,7 +1538,7 @@ before each command.") | |||
| 1497 | register struct window *w; | 1538 | register struct window *w; |
| 1498 | register struct window *ow = XWINDOW (selected_window); | 1539 | register struct window *ow = XWINDOW (selected_window); |
| 1499 | 1540 | ||
| 1500 | CHECK_WINDOW (window, 0); | 1541 | CHECK_LIVE_WINDOW (window, 0); |
| 1501 | 1542 | ||
| 1502 | w = XWINDOW (window); | 1543 | w = XWINDOW (window); |
| 1503 | 1544 | ||
| @@ -1706,7 +1747,7 @@ and put SIZE columns in the first of the pair.") | |||
| 1706 | if (NILP (window)) | 1747 | if (NILP (window)) |
| 1707 | window = selected_window; | 1748 | window = selected_window; |
| 1708 | else | 1749 | else |
| 1709 | CHECK_WINDOW (window, 0); | 1750 | CHECK_LIVE_WINDOW (window, 0); |
| 1710 | 1751 | ||
| 1711 | o = XWINDOW (window); | 1752 | o = XWINDOW (window); |
| 1712 | 1753 | ||
| @@ -2143,7 +2184,7 @@ showing that buffer, popping the buffer up if necessary.") | |||
| 2143 | else | 2184 | else |
| 2144 | /* Nothing specified; pick a neighboring window. */ | 2185 | /* Nothing specified; pick a neighboring window. */ |
| 2145 | window = Fnext_window (selected_window, Qnil, Qt); | 2186 | window = Fnext_window (selected_window, Qnil, Qt); |
| 2146 | CHECK_WINDOW (window, 0); | 2187 | CHECK_LIVE_WINDOW (window, 0); |
| 2147 | 2188 | ||
| 2148 | if (EQ (window, selected_window)) | 2189 | if (EQ (window, selected_window)) |
| 2149 | error ("There is no other window"); | 2190 | error ("There is no other window"); |
| @@ -2540,14 +2581,22 @@ static void | |||
| 2540 | delete_all_subwindows (w) | 2581 | delete_all_subwindows (w) |
| 2541 | register struct window *w; | 2582 | register struct window *w; |
| 2542 | { | 2583 | { |
| 2543 | w->height = w->buffer; /* See Fset_window_configuration for excuse. */ | ||
| 2544 | w->buffer = Qnil; | ||
| 2545 | if (!NILP (w->next)) | 2584 | if (!NILP (w->next)) |
| 2546 | delete_all_subwindows (XWINDOW (w->next)); | 2585 | delete_all_subwindows (XWINDOW (w->next)); |
| 2547 | if (!NILP (w->vchild)) | 2586 | if (!NILP (w->vchild)) |
| 2548 | delete_all_subwindows (XWINDOW (w->vchild)); | 2587 | delete_all_subwindows (XWINDOW (w->vchild)); |
| 2549 | if (!NILP (w->hchild)) | 2588 | if (!NILP (w->hchild)) |
| 2550 | delete_all_subwindows (XWINDOW (w->hchild)); | 2589 | delete_all_subwindows (XWINDOW (w->hchild)); |
| 2590 | |||
| 2591 | w->height = w->buffer; /* See Fset_window_configuration for excuse. */ | ||
| 2592 | |||
| 2593 | /* We set all three of these fields to nil, to make sure that we can | ||
| 2594 | distinguish this dead window from any live window. Live leaf | ||
| 2595 | windows will have buffer set, and combination windows will have | ||
| 2596 | vchild or hchild set. */ | ||
| 2597 | w->buffer = Qnil; | ||
| 2598 | w->vchild = Qnil; | ||
| 2599 | w->hchild = Qnil; | ||
| 2551 | } | 2600 | } |
| 2552 | 2601 | ||
| 2553 | static int | 2602 | static int |
| @@ -2754,6 +2803,9 @@ syms_of_window () | |||
| 2754 | Qwindowp = intern ("windowp"); | 2803 | Qwindowp = intern ("windowp"); |
| 2755 | staticpro (&Qwindowp); | 2804 | staticpro (&Qwindowp); |
| 2756 | 2805 | ||
| 2806 | Qlive_window_p = intern ("live-window-p"); | ||
| 2807 | staticpro (&Qlive_window_p); | ||
| 2808 | |||
| 2757 | #ifndef MULTI_FRAME | 2809 | #ifndef MULTI_FRAME |
| 2758 | /* Make sure all windows get marked */ | 2810 | /* Make sure all windows get marked */ |
| 2759 | staticpro (&minibuf_window); | 2811 | staticpro (&minibuf_window); |
| @@ -2838,6 +2890,7 @@ If there is only one window, it is split regardless of this value."); | |||
| 2838 | defsubr (&Sminibuffer_window); | 2890 | defsubr (&Sminibuffer_window); |
| 2839 | defsubr (&Swindow_minibuffer_p); | 2891 | defsubr (&Swindow_minibuffer_p); |
| 2840 | defsubr (&Swindowp); | 2892 | defsubr (&Swindowp); |
| 2893 | defsubr (&Slive_window_p); | ||
| 2841 | defsubr (&Spos_visible_in_window_p); | 2894 | defsubr (&Spos_visible_in_window_p); |
| 2842 | defsubr (&Swindow_buffer); | 2895 | defsubr (&Swindow_buffer); |
| 2843 | defsubr (&Swindow_height); | 2896 | defsubr (&Swindow_height); |