diff options
| author | Martin Rudalics | 2011-06-09 08:35:02 +0200 |
|---|---|---|
| committer | Martin Rudalics | 2011-06-09 08:35:02 +0200 |
| commit | 1a13852e906ca4f4f98a65106496d2cb1c517d64 (patch) | |
| tree | ed4ed7a0b5ae9c961570bb41479a2bdf57763adf /src/window.c | |
| parent | e8b08aeecad0dc735d8f40ddabc8c0c249dedb21 (diff) | |
| download | emacs-1a13852e906ca4f4f98a65106496d2cb1c517d64.tar.gz emacs-1a13852e906ca4f4f98a65106496d2cb1c517d64.zip | |
Final preparations for new window resize code.
* window.c (replace_window): Rename second argument REPLACEMENT to
NEW. New third argument SETFLAG. Rewrite.
(delete_window, make_dummy_parent): Call replace_window with
third argument 1.
(window_list_1): Move down in code.
(run_window_configuration_change_hook): Move set_buffer part
before select_frame_norecord part in order to unwind correctly.
Rename count1 to count.
(recombine_windows, delete_deletable_window, resize_root_window)
(Fdelete_other_windows_internal)
(Frun_window_configuration_change_hook, make_parent_window)
(resize_window_check, resize_window_apply, Fresize_window_apply)
(resize_frame_windows, Fsplit_window_internal)
(Fdelete_window_internal, Fresize_mini_window_internal): New
functions.
(syms_of_window): New variables Vwindow_splits and Vwindow_nest.
Diffstat (limited to 'src/window.c')
| -rw-r--r-- | src/window.c | 1271 |
1 files changed, 1187 insertions, 84 deletions
diff --git a/src/window.c b/src/window.c index 393a2478ce1..dd8cdab77a4 100644 --- a/src/window.c +++ b/src/window.c | |||
| @@ -90,6 +90,7 @@ static int foreach_window_1 (struct window *, | |||
| 90 | int (* fn) (struct window *, void *), | 90 | int (* fn) (struct window *, void *), |
| 91 | void *); | 91 | void *); |
| 92 | static Lisp_Object window_list_1 (Lisp_Object, Lisp_Object, Lisp_Object); | 92 | static Lisp_Object window_list_1 (Lisp_Object, Lisp_Object, Lisp_Object); |
| 93 | static void resize_window_apply (struct window *, int); | ||
| 93 | static Lisp_Object select_window (Lisp_Object, Lisp_Object, int); | 94 | static Lisp_Object select_window (Lisp_Object, Lisp_Object, int); |
| 94 | 95 | ||
| 95 | /* This is the window in which the terminal's cursor should | 96 | /* This is the window in which the terminal's cursor should |
| @@ -1853,60 +1854,146 @@ unshow_buffer (register struct window *w) | |||
| 1853 | BVAR (b, last_selected_window) = Qnil; | 1854 | BVAR (b, last_selected_window) = Qnil; |
| 1854 | } | 1855 | } |
| 1855 | 1856 | ||
| 1856 | /* Put replacement into the window structure in place of old. */ | 1857 | /* Put NEW into the window structure in place of OLD. SETFLAG zero |
| 1858 | means change window structure only. Otherwise store geometry and | ||
| 1859 | other settings as well. */ | ||
| 1857 | static void | 1860 | static void |
| 1858 | replace_window (Lisp_Object old, Lisp_Object replacement) | 1861 | replace_window (Lisp_Object old, Lisp_Object new, int setflag) |
| 1859 | { | 1862 | { |
| 1860 | register Lisp_Object tem; | 1863 | register Lisp_Object tem; |
| 1861 | register struct window *o = XWINDOW (old), *p = XWINDOW (replacement); | 1864 | register struct window *o = XWINDOW (old), *n = XWINDOW (new); |
| 1862 | |||
| 1863 | /* If OLD is its frame's root_window, then replacement is the new | ||
| 1864 | root_window for that frame. */ | ||
| 1865 | 1865 | ||
| 1866 | /* If OLD is its frame's root window, then NEW is the new | ||
| 1867 | root window for that frame. */ | ||
| 1866 | if (EQ (old, FRAME_ROOT_WINDOW (XFRAME (o->frame)))) | 1868 | if (EQ (old, FRAME_ROOT_WINDOW (XFRAME (o->frame)))) |
| 1867 | FRAME_ROOT_WINDOW (XFRAME (o->frame)) = replacement; | 1869 | FRAME_ROOT_WINDOW (XFRAME (o->frame)) = new; |
| 1868 | 1870 | ||
| 1869 | p->left_col = o->left_col; | 1871 | if (setflag) |
| 1870 | p->top_line = o->top_line; | 1872 | { |
| 1871 | p->total_cols = o->total_cols; | 1873 | n->left_col = o->left_col; |
| 1872 | p->total_lines = o->total_lines; | 1874 | n->top_line = o->top_line; |
| 1873 | p->desired_matrix = p->current_matrix = 0; | 1875 | n->total_cols = o->total_cols; |
| 1874 | p->vscroll = 0; | 1876 | n->total_lines = o->total_lines; |
| 1875 | memset (&p->cursor, 0, sizeof (p->cursor)); | 1877 | n->normal_cols = o->normal_cols; |
| 1876 | memset (&p->last_cursor, 0, sizeof (p->last_cursor)); | 1878 | o->normal_cols = make_float (1.0); |
| 1877 | memset (&p->phys_cursor, 0, sizeof (p->phys_cursor)); | 1879 | n->normal_lines = o->normal_lines; |
| 1878 | p->phys_cursor_type = -1; | 1880 | o->normal_lines = make_float (1.0); |
| 1879 | p->phys_cursor_width = -1; | 1881 | n->desired_matrix = n->current_matrix = 0; |
| 1880 | p->must_be_updated_p = 0; | 1882 | n->vscroll = 0; |
| 1881 | p->pseudo_window_p = 0; | 1883 | memset (&n->cursor, 0, sizeof (n->cursor)); |
| 1882 | XSETFASTINT (p->window_end_vpos, 0); | 1884 | memset (&n->last_cursor, 0, sizeof (n->last_cursor)); |
| 1883 | XSETFASTINT (p->window_end_pos, 0); | 1885 | memset (&n->phys_cursor, 0, sizeof (n->phys_cursor)); |
| 1884 | p->window_end_valid = Qnil; | 1886 | n->phys_cursor_type = -1; |
| 1885 | p->frozen_window_start_p = 0; | 1887 | n->phys_cursor_width = -1; |
| 1886 | p->orig_top_line = p->orig_total_lines = Qnil; | 1888 | n->must_be_updated_p = 0; |
| 1887 | 1889 | n->pseudo_window_p = 0; | |
| 1888 | p->next = tem = o->next; | 1890 | XSETFASTINT (n->window_end_vpos, 0); |
| 1891 | XSETFASTINT (n->window_end_pos, 0); | ||
| 1892 | n->window_end_valid = Qnil; | ||
| 1893 | n->frozen_window_start_p = 0; | ||
| 1894 | n->orig_top_line = n->orig_total_lines = Qnil; | ||
| 1895 | } | ||
| 1896 | |||
| 1897 | n->next = tem = o->next; | ||
| 1889 | if (!NILP (tem)) | 1898 | if (!NILP (tem)) |
| 1890 | XWINDOW (tem)->prev = replacement; | 1899 | XWINDOW (tem)->prev = new; |
| 1891 | 1900 | ||
| 1892 | p->prev = tem = o->prev; | 1901 | n->prev = tem = o->prev; |
| 1893 | if (!NILP (tem)) | 1902 | if (!NILP (tem)) |
| 1894 | XWINDOW (tem)->next = replacement; | 1903 | XWINDOW (tem)->next = new; |
| 1895 | 1904 | ||
| 1896 | p->parent = tem = o->parent; | 1905 | n->parent = tem = o->parent; |
| 1897 | if (!NILP (tem)) | 1906 | if (!NILP (tem)) |
| 1898 | { | 1907 | { |
| 1899 | if (EQ (XWINDOW (tem)->vchild, old)) | 1908 | if (EQ (XWINDOW (tem)->vchild, old)) |
| 1900 | XWINDOW (tem)->vchild = replacement; | 1909 | XWINDOW (tem)->vchild = new; |
| 1901 | if (EQ (XWINDOW (tem)->hchild, old)) | 1910 | if (EQ (XWINDOW (tem)->hchild, old)) |
| 1902 | XWINDOW (tem)->hchild = replacement; | 1911 | XWINDOW (tem)->hchild = new; |
| 1903 | } | 1912 | } |
| 1913 | } | ||
| 1914 | |||
| 1915 | /* If window WINDOW and its parent window are iso-combined, merge | ||
| 1916 | WINDOW's children into those of its parent window and mark WINDOW as | ||
| 1917 | deleted. */ | ||
| 1918 | |||
| 1919 | static void | ||
| 1920 | recombine_windows (Lisp_Object window) | ||
| 1921 | { | ||
| 1922 | struct window *w, *p, *c; | ||
| 1923 | Lisp_Object parent, child; | ||
| 1924 | int horflag; | ||
| 1925 | |||
| 1926 | w = XWINDOW (window); | ||
| 1927 | parent = w->parent; | ||
| 1928 | if (!NILP (parent) && NILP (w->nest)) | ||
| 1929 | { | ||
| 1930 | p = XWINDOW (parent); | ||
| 1931 | if (((!NILP (p->vchild) && !NILP (w->vchild)) | ||
| 1932 | || (!NILP (p->hchild) && !NILP (w->hchild)))) | ||
| 1933 | /* WINDOW and PARENT are both either a vertical or a horizontal | ||
| 1934 | combination. */ | ||
| 1935 | { | ||
| 1936 | horflag = NILP (w->vchild); | ||
| 1937 | child = horflag ? w->hchild : w->vchild; | ||
| 1938 | c = XWINDOW (child); | ||
| 1939 | |||
| 1940 | /* Splice WINDOW's children into its parent's children and | ||
| 1941 | assign new normal sizes. */ | ||
| 1942 | if (NILP (w->prev)) | ||
| 1943 | if (horflag) | ||
| 1944 | p->hchild = child; | ||
| 1945 | else | ||
| 1946 | p->vchild = child; | ||
| 1947 | else | ||
| 1948 | { | ||
| 1949 | c->prev = w->prev; | ||
| 1950 | XWINDOW (w->prev)->next = child; | ||
| 1951 | } | ||
| 1952 | |||
| 1953 | while (c) | ||
| 1954 | { | ||
| 1955 | c->parent = parent; | ||
| 1956 | |||
| 1957 | if (horflag) | ||
| 1958 | c->normal_cols | ||
| 1959 | = make_float (XFLOATINT (c->total_cols) | ||
| 1960 | / XFLOATINT (p->total_cols)); | ||
| 1961 | else | ||
| 1962 | c->normal_lines | ||
| 1963 | = make_float (XFLOATINT (c->total_lines) | ||
| 1964 | / XFLOATINT (p->total_lines)); | ||
| 1965 | |||
| 1966 | if (NILP (c->next)) | ||
| 1967 | { | ||
| 1968 | if (!NILP (w->next)) | ||
| 1969 | { | ||
| 1970 | c->next = w->next; | ||
| 1971 | XWINDOW (c->next)->prev = child; | ||
| 1972 | } | ||
| 1973 | |||
| 1974 | c = 0; | ||
| 1975 | } | ||
| 1976 | else | ||
| 1977 | { | ||
| 1978 | child = c->next; | ||
| 1979 | c = XWINDOW (child); | ||
| 1980 | } | ||
| 1981 | } | ||
| 1904 | 1982 | ||
| 1905 | /*** Here, if replacement is a vertical combination | 1983 | /* WINDOW can be deleted now. */ |
| 1906 | and so is its new parent, we should make replacement's | 1984 | w->vchild = w->hchild = Qnil; |
| 1907 | children be children of that parent instead. ***/ | 1985 | } |
| 1986 | } | ||
| 1908 | } | 1987 | } |
| 1909 | 1988 | ||
| 1989 | /* If WINDOW can be deleted, delete it. */ | ||
| 1990 | Lisp_Object | ||
| 1991 | delete_deletable_window (Lisp_Object window) | ||
| 1992 | { | ||
| 1993 | if (!NILP (call1 (Qwindow_deletable_p, window))) | ||
| 1994 | call1 (Qdelete_window, window); | ||
| 1995 | } | ||
| 1996 | |||
| 1910 | DEFUN ("delete-window", Fdelete_window, Sdelete_window, 0, 1, "", | 1997 | DEFUN ("delete-window", Fdelete_window, Sdelete_window, 0, 1, "", |
| 1911 | doc: /* Remove WINDOW from its frame. | 1998 | doc: /* Remove WINDOW from its frame. |
| 1912 | WINDOW defaults to the selected window. Return nil. | 1999 | WINDOW defaults to the selected window. Return nil. |
| @@ -2067,7 +2154,7 @@ delete_window (register Lisp_Object window) | |||
| 2067 | if (NILP (tem)) | 2154 | if (NILP (tem)) |
| 2068 | tem = par->vchild; | 2155 | tem = par->vchild; |
| 2069 | if (NILP (XWINDOW (tem)->next)) { | 2156 | if (NILP (XWINDOW (tem)->next)) { |
| 2070 | replace_window (parent, tem); | 2157 | replace_window (parent, tem, 1); |
| 2071 | par = XWINDOW (tem); | 2158 | par = XWINDOW (tem); |
| 2072 | } | 2159 | } |
| 2073 | 2160 | ||
| @@ -2427,43 +2514,6 @@ reverse order. */) | |||
| 2427 | } | 2514 | } |
| 2428 | 2515 | ||
| 2429 | 2516 | ||
| 2430 | DEFUN ("window-list-1", Fwindow_list_1, Swindow_list_1, 0, 3, 0, | ||
| 2431 | doc: /* Return a list of all live windows. | ||
| 2432 | WINDOW specifies the first window to list and defaults to the selected | ||
| 2433 | window. | ||
| 2434 | |||
| 2435 | Optional argument MINIBUF nil or omitted means consider the minibuffer | ||
| 2436 | window only if the minibuffer is active. MINIBUF t means consider the | ||
| 2437 | minibuffer window even if the minibuffer is not active. Any other value | ||
| 2438 | means do not consider the minibuffer window even if the minibuffer is | ||
| 2439 | active. | ||
| 2440 | |||
| 2441 | Optional argument ALL-FRAMES nil or omitted means consider all windows | ||
| 2442 | on WINDOW's frame, plus the minibuffer window if specified by the | ||
| 2443 | MINIBUF argument. If the minibuffer counts, consider all windows on all | ||
| 2444 | frames that share that minibuffer too. The following non-nil values of | ||
| 2445 | ALL-FRAMES have special meanings: | ||
| 2446 | |||
| 2447 | - t means consider all windows on all existing frames. | ||
| 2448 | |||
| 2449 | - `visible' means consider all windows on all visible frames. | ||
| 2450 | |||
| 2451 | - 0 (the number zero) means consider all windows on all visible and | ||
| 2452 | iconified frames. | ||
| 2453 | |||
| 2454 | - A frame means consider all windows on that frame only. | ||
| 2455 | |||
| 2456 | Anything else means consider all windows on WINDOW's frame and no | ||
| 2457 | others. | ||
| 2458 | |||
| 2459 | If WINDOW is not on the list of windows returned, some other window will | ||
| 2460 | be listed first but no error is signalled. */) | ||
| 2461 | (Lisp_Object window, Lisp_Object minibuf, Lisp_Object all_frames) | ||
| 2462 | { | ||
| 2463 | return window_list_1 (window, minibuf, all_frames); | ||
| 2464 | } | ||
| 2465 | |||
| 2466 | |||
| 2467 | DEFUN ("other-window", Fother_window, Sother_window, 1, 2, "p", | 2517 | DEFUN ("other-window", Fother_window, Sother_window, 1, 2, "p", |
| 2468 | doc: /* Select another window in cyclic ordering of windows. | 2518 | doc: /* Select another window in cyclic ordering of windows. |
| 2469 | COUNT specifies the number of windows to skip, starting with the | 2519 | COUNT specifies the number of windows to skip, starting with the |
| @@ -2547,6 +2597,41 @@ MINIBUF neither nil nor t means never include the minibuffer window. */) | |||
| 2547 | } | 2597 | } |
| 2548 | 2598 | ||
| 2549 | 2599 | ||
| 2600 | DEFUN ("window-list-1", Fwindow_list_1, Swindow_list_1, 0, 3, 0, | ||
| 2601 | doc: /* Return a list of all live windows. | ||
| 2602 | WINDOW specifies the first window to list and defaults to the selected | ||
| 2603 | window. | ||
| 2604 | |||
| 2605 | Optional argument MINIBUF nil or omitted means consider the minibuffer | ||
| 2606 | window only if the minibuffer is active. MINIBUF t means consider the | ||
| 2607 | minibuffer window even if the minibuffer is not active. Any other value | ||
| 2608 | means do not consider the minibuffer window even if the minibuffer is | ||
| 2609 | active. | ||
| 2610 | |||
| 2611 | Optional argument ALL-FRAMES nil or omitted means consider all windows | ||
| 2612 | on WINDOW's frame, plus the minibuffer window if specified by the | ||
| 2613 | MINIBUF argument. If the minibuffer counts, consider all windows on all | ||
| 2614 | frames that share that minibuffer too. The following non-nil values of | ||
| 2615 | ALL-FRAMES have special meanings: | ||
| 2616 | |||
| 2617 | - t means consider all windows on all existing frames. | ||
| 2618 | |||
| 2619 | - `visible' means consider all windows on all visible frames. | ||
| 2620 | |||
| 2621 | - 0 (the number zero) means consider all windows on all visible and | ||
| 2622 | iconified frames. | ||
| 2623 | |||
| 2624 | - A frame means consider all windows on that frame only. | ||
| 2625 | |||
| 2626 | Anything else means consider all windows on WINDOW's frame and no | ||
| 2627 | others. | ||
| 2628 | |||
| 2629 | If WINDOW is not on the list of windows returned, some other window will | ||
| 2630 | be listed first but no error is signalled. */) | ||
| 2631 | (Lisp_Object window, Lisp_Object minibuf, Lisp_Object all_frames) | ||
| 2632 | { | ||
| 2633 | return window_list_1 (window, minibuf, all_frames); | ||
| 2634 | } | ||
| 2550 | 2635 | ||
| 2551 | /* Look at all windows, performing an operation specified by TYPE | 2636 | /* Look at all windows, performing an operation specified by TYPE |
| 2552 | with argument OBJ. | 2637 | with argument OBJ. |
| @@ -2801,6 +2886,248 @@ selected frame and no others. */) | |||
| 2801 | return Qnil; | 2886 | return Qnil; |
| 2802 | } | 2887 | } |
| 2803 | 2888 | ||
| 2889 | Lisp_Object | ||
| 2890 | resize_root_window (Lisp_Object window, Lisp_Object delta, Lisp_Object horizontal, Lisp_Object ignore) | ||
| 2891 | { | ||
| 2892 | return call4 (Qresize_root_window, window, delta, horizontal, ignore); | ||
| 2893 | } | ||
| 2894 | |||
| 2895 | |||
| 2896 | DEFUN ("delete-other-windows-internal", Fdelete_other_windows_internal, | ||
| 2897 | Sdelete_other_windows_internal, 0, 2, "", | ||
| 2898 | doc: /* Make WINDOW fill its frame. | ||
| 2899 | Only the frame WINDOW is on is affected. WINDOW may be any window and | ||
| 2900 | defaults to the selected one. | ||
| 2901 | |||
| 2902 | Optional argument ROOT, if non-nil, must specify an internal window | ||
| 2903 | containing WINDOW as a subwindow. If this is the case, replace ROOT by | ||
| 2904 | WINDOW and leave alone any windows not contained in ROOT. | ||
| 2905 | |||
| 2906 | When WINDOW is live try to reduce display jumps by keeping the text | ||
| 2907 | previously visible in WINDOW in the same place on the frame. Doing this | ||
| 2908 | depends on the value of (window-start WINDOW), so if calling this | ||
| 2909 | function in a program gives strange scrolling, make sure the | ||
| 2910 | window-start value is reasonable when this function is called. */) | ||
| 2911 | (Lisp_Object window, Lisp_Object root) | ||
| 2912 | { | ||
| 2913 | struct window *w, *r, *s; | ||
| 2914 | struct frame *f; | ||
| 2915 | Lisp_Object sibling, pwindow, swindow, delta; | ||
| 2916 | EMACS_INT startpos; | ||
| 2917 | int top, new_top, resize_failed; | ||
| 2918 | |||
| 2919 | w = decode_any_window (window); | ||
| 2920 | XSETWINDOW (window, w); | ||
| 2921 | f = XFRAME (w->frame); | ||
| 2922 | |||
| 2923 | if (NILP (root)) | ||
| 2924 | /* ROOT is the frame's root window. */ | ||
| 2925 | { | ||
| 2926 | root = FRAME_ROOT_WINDOW (f); | ||
| 2927 | r = XWINDOW (root); | ||
| 2928 | } | ||
| 2929 | else | ||
| 2930 | /* ROOT must be an ancestor of WINDOW. */ | ||
| 2931 | { | ||
| 2932 | r = decode_any_window (root); | ||
| 2933 | pwindow = XWINDOW (window)->parent; | ||
| 2934 | while (!NILP (pwindow)) | ||
| 2935 | if (EQ (pwindow, root)) | ||
| 2936 | break; | ||
| 2937 | else | ||
| 2938 | pwindow = XWINDOW (pwindow)->parent; | ||
| 2939 | if (!EQ (pwindow, root)) | ||
| 2940 | error ("Specified root is not an ancestor of specified window"); | ||
| 2941 | } | ||
| 2942 | |||
| 2943 | if (EQ (window, root)) | ||
| 2944 | /* A noop. */ | ||
| 2945 | return Qnil; | ||
| 2946 | /* I don't understand the "top > 0" part below. If we deal with a | ||
| 2947 | standalone minibuffer it would have been caught by the preceding | ||
| 2948 | test. */ | ||
| 2949 | else if (MINI_WINDOW_P (w)) /* && top > 0) */ | ||
| 2950 | error ("Can't expand minibuffer to full frame"); | ||
| 2951 | |||
| 2952 | if (!NILP (w->buffer)) | ||
| 2953 | { | ||
| 2954 | startpos = marker_position (w->start); | ||
| 2955 | top = WINDOW_TOP_EDGE_LINE (w) | ||
| 2956 | - FRAME_TOP_MARGIN (XFRAME (WINDOW_FRAME (w))); | ||
| 2957 | /* Make sure WINDOW is the frame's selected window. */ | ||
| 2958 | if (!EQ (window, FRAME_SELECTED_WINDOW (f))) | ||
| 2959 | { | ||
| 2960 | if (EQ (selected_frame, w->frame)) | ||
| 2961 | Fselect_window (window, Qnil); | ||
| 2962 | else | ||
| 2963 | FRAME_SELECTED_WINDOW (f) = window; | ||
| 2964 | } | ||
| 2965 | } | ||
| 2966 | else | ||
| 2967 | { | ||
| 2968 | /* See if the frame's selected window is a subwindow of WINDOW, by | ||
| 2969 | finding all the selected window's parents and comparing each | ||
| 2970 | one with WINDOW. If it isn't we need a new selected window for | ||
| 2971 | this frame. */ | ||
| 2972 | swindow = FRAME_SELECTED_WINDOW (f); | ||
| 2973 | while (1) | ||
| 2974 | { | ||
| 2975 | pwindow = swindow; | ||
| 2976 | while (!NILP (pwindow) && !EQ (window, pwindow)) | ||
| 2977 | pwindow = XWINDOW (pwindow)->parent; | ||
| 2978 | |||
| 2979 | if (EQ (window, pwindow)) | ||
| 2980 | /* If WINDOW is an ancestor of SWINDOW, then SWINDOW is ok | ||
| 2981 | as the new selected window. */ | ||
| 2982 | break; | ||
| 2983 | else | ||
| 2984 | /* Else try the previous window of SWINDOW. */ | ||
| 2985 | swindow = Fprevious_window (swindow, Qlambda, Qnil); | ||
| 2986 | } | ||
| 2987 | |||
| 2988 | if (!EQ (swindow, FRAME_SELECTED_WINDOW (f))) | ||
| 2989 | { | ||
| 2990 | if (EQ (selected_frame, w->frame)) | ||
| 2991 | Fselect_window (swindow, Qnil); | ||
| 2992 | else | ||
| 2993 | FRAME_SELECTED_WINDOW (f) = swindow; | ||
| 2994 | } | ||
| 2995 | } | ||
| 2996 | |||
| 2997 | BLOCK_INPUT; | ||
| 2998 | free_window_matrices (r); | ||
| 2999 | |||
| 3000 | windows_or_buffers_changed++; | ||
| 3001 | Vwindow_list = Qnil; | ||
| 3002 | FRAME_WINDOW_SIZES_CHANGED (f) = 1; | ||
| 3003 | |||
| 3004 | if (NILP (w->buffer)) | ||
| 3005 | { | ||
| 3006 | resize_failed = 0; | ||
| 3007 | /* Resize subwindows vertically. */ | ||
| 3008 | XSETINT (delta, XINT (r->total_lines) - XINT (w->total_lines)); | ||
| 3009 | w->top_line = r->top_line; | ||
| 3010 | resize_root_window (window, delta, Qnil, Qnil); | ||
| 3011 | if (resize_window_check (w, 0)) | ||
| 3012 | resize_window_apply (w, 0); | ||
| 3013 | else | ||
| 3014 | { | ||
| 3015 | resize_root_window (window, delta, Qnil, Qt); | ||
| 3016 | if (resize_window_check (w, 0)) | ||
| 3017 | resize_window_apply (w, 0); | ||
| 3018 | else | ||
| 3019 | resize_failed = 1; | ||
| 3020 | } | ||
| 3021 | |||
| 3022 | /* Resize subwindows horizontally. */ | ||
| 3023 | if (!resize_failed) | ||
| 3024 | { | ||
| 3025 | w->left_col = r->left_col; | ||
| 3026 | XSETINT (delta, XINT (r->total_cols) - XINT (w->total_cols)); | ||
| 3027 | w->left_col = r->left_col; | ||
| 3028 | resize_root_window (window, delta, Qt, Qnil); | ||
| 3029 | if (resize_window_check (w, 1)) | ||
| 3030 | resize_window_apply (w, 1); | ||
| 3031 | else | ||
| 3032 | { | ||
| 3033 | resize_root_window (window, delta, Qt, Qt); | ||
| 3034 | if (resize_window_check (w, 1)) | ||
| 3035 | resize_window_apply (w, 1); | ||
| 3036 | else | ||
| 3037 | resize_failed = 1; | ||
| 3038 | } | ||
| 3039 | } | ||
| 3040 | |||
| 3041 | if (resize_failed) | ||
| 3042 | /* Play safe, if we still can ... */ | ||
| 3043 | { | ||
| 3044 | window = swindow; | ||
| 3045 | w = XWINDOW (window); | ||
| 3046 | } | ||
| 3047 | } | ||
| 3048 | |||
| 3049 | /* Cleanly unlink WINDOW from window-tree. */ | ||
| 3050 | if (!NILP (w->prev)) | ||
| 3051 | /* Get SIBLING above (on the left of) WINDOW. */ | ||
| 3052 | { | ||
| 3053 | sibling = w->prev; | ||
| 3054 | s = XWINDOW (sibling); | ||
| 3055 | s->next = w->next; | ||
| 3056 | if (!NILP (s->next)) | ||
| 3057 | XWINDOW (s->next)->prev = sibling; | ||
| 3058 | } | ||
| 3059 | else | ||
| 3060 | /* Get SIBLING below (on the right of) WINDOW. */ | ||
| 3061 | { | ||
| 3062 | sibling = w->next; | ||
| 3063 | s = XWINDOW (sibling); | ||
| 3064 | s->prev = Qnil; | ||
| 3065 | if (!NILP (XWINDOW (w->parent)->vchild)) | ||
| 3066 | XWINDOW (w->parent)->vchild = sibling; | ||
| 3067 | else | ||
| 3068 | XWINDOW (w->parent)->hchild = sibling; | ||
| 3069 | } | ||
| 3070 | |||
| 3071 | /* Delete ROOT and all subwindows of ROOT. */ | ||
| 3072 | if (!NILP (r->vchild)) | ||
| 3073 | { | ||
| 3074 | delete_all_subwindows (r->vchild); | ||
| 3075 | r->vchild = Qnil; | ||
| 3076 | } | ||
| 3077 | else if (!NILP (r->hchild)) | ||
| 3078 | { | ||
| 3079 | delete_all_subwindows (r->hchild); | ||
| 3080 | r->hchild = Qnil; | ||
| 3081 | } | ||
| 3082 | |||
| 3083 | replace_window (root, window, 1); | ||
| 3084 | |||
| 3085 | /* Reset WINDOW's splits status. */ | ||
| 3086 | w->splits = Qnil; | ||
| 3087 | |||
| 3088 | /* This must become SWINDOW anyway ....... */ | ||
| 3089 | if (!NILP (w->buffer) && !resize_failed) | ||
| 3090 | { | ||
| 3091 | /* Try to minimize scrolling, by setting the window start to the | ||
| 3092 | point will cause the text at the old window start to be at the | ||
| 3093 | same place on the frame. But don't try to do this if the | ||
| 3094 | window start is outside the visible portion (as might happen | ||
| 3095 | when the display is not current, due to typeahead). */ | ||
| 3096 | new_top = WINDOW_TOP_EDGE_LINE (w) - FRAME_TOP_MARGIN (XFRAME (WINDOW_FRAME (w))); | ||
| 3097 | if (new_top != top | ||
| 3098 | && startpos >= BUF_BEGV (XBUFFER (w->buffer)) | ||
| 3099 | && startpos <= BUF_ZV (XBUFFER (w->buffer))) | ||
| 3100 | { | ||
| 3101 | struct position pos; | ||
| 3102 | struct buffer *obuf = current_buffer; | ||
| 3103 | |||
| 3104 | Fset_buffer (w->buffer); | ||
| 3105 | /* This computation used to temporarily move point, but that | ||
| 3106 | can have unwanted side effects due to text properties. */ | ||
| 3107 | pos = *vmotion (startpos, -top, w); | ||
| 3108 | |||
| 3109 | set_marker_both (w->start, w->buffer, pos.bufpos, pos.bytepos); | ||
| 3110 | w->window_end_valid = Qnil; | ||
| 3111 | w->start_at_line_beg = ((pos.bytepos == BEGV_BYTE | ||
| 3112 | || FETCH_BYTE (pos.bytepos - 1) == '\n') ? Qt | ||
| 3113 | : Qnil); | ||
| 3114 | /* We need to do this, so that the window-scroll-functions | ||
| 3115 | get called. */ | ||
| 3116 | w->optional_new_start = Qt; | ||
| 3117 | |||
| 3118 | set_buffer_internal (obuf); | ||
| 3119 | } | ||
| 3120 | } | ||
| 3121 | |||
| 3122 | adjust_glyphs (f); | ||
| 3123 | UNBLOCK_INPUT; | ||
| 3124 | |||
| 3125 | run_window_configuration_change_hook (f); | ||
| 3126 | |||
| 3127 | return Qnil; | ||
| 3128 | } | ||
| 3129 | |||
| 3130 | |||
| 2804 | DEFUN ("delete-other-windows", Fdelete_other_windows, Sdelete_other_windows, | 3131 | DEFUN ("delete-other-windows", Fdelete_other_windows, Sdelete_other_windows, |
| 2805 | 0, 1, "", | 3132 | 0, 1, "", |
| 2806 | doc: /* Make WINDOW (or the selected window) fill its frame. | 3133 | doc: /* Make WINDOW (or the selected window) fill its frame. |
| @@ -3676,12 +4003,6 @@ run_window_configuration_change_hook (struct frame *f) | |||
| 3676 | if (NILP (Vrun_hooks)) | 4003 | if (NILP (Vrun_hooks)) |
| 3677 | return; | 4004 | return; |
| 3678 | 4005 | ||
| 3679 | if (SELECTED_FRAME () != f) | ||
| 3680 | { | ||
| 3681 | record_unwind_protect (select_frame_norecord, Fselected_frame ()); | ||
| 3682 | Fselect_frame (frame, Qt); | ||
| 3683 | } | ||
| 3684 | |||
| 3685 | /* Use the right buffer. Matters when running the local hooks. */ | 4006 | /* Use the right buffer. Matters when running the local hooks. */ |
| 3686 | if (current_buffer != XBUFFER (Fwindow_buffer (Qnil))) | 4007 | if (current_buffer != XBUFFER (Fwindow_buffer (Qnil))) |
| 3687 | { | 4008 | { |
| @@ -3689,6 +4010,12 @@ run_window_configuration_change_hook (struct frame *f) | |||
| 3689 | Fset_buffer (Fwindow_buffer (Qnil)); | 4010 | Fset_buffer (Fwindow_buffer (Qnil)); |
| 3690 | } | 4011 | } |
| 3691 | 4012 | ||
| 4013 | if (SELECTED_FRAME () != f) | ||
| 4014 | { | ||
| 4015 | record_unwind_protect (select_frame_norecord, Fselected_frame ()); | ||
| 4016 | select_frame_norecord (frame); | ||
| 4017 | } | ||
| 4018 | |||
| 3692 | /* Look for buffer-local values. */ | 4019 | /* Look for buffer-local values. */ |
| 3693 | { | 4020 | { |
| 3694 | Lisp_Object windows = Fwindow_list (frame, Qlambda, Qnil); | 4021 | Lisp_Object windows = Fwindow_list (frame, Qlambda, Qnil); |
| @@ -3699,12 +4026,12 @@ run_window_configuration_change_hook (struct frame *f) | |||
| 3699 | if (!NILP (Flocal_variable_p (Qwindow_configuration_change_hook, | 4026 | if (!NILP (Flocal_variable_p (Qwindow_configuration_change_hook, |
| 3700 | buffer))) | 4027 | buffer))) |
| 3701 | { | 4028 | { |
| 3702 | int count1 = SPECPDL_INDEX (); | 4029 | int count = SPECPDL_INDEX (); |
| 3703 | record_unwind_protect (select_window_norecord, Fselected_window ()); | 4030 | record_unwind_protect (select_window_norecord, Fselected_window ()); |
| 3704 | select_window_norecord (window); | 4031 | select_window_norecord (window); |
| 3705 | run_funs (Fbuffer_local_value (Qwindow_configuration_change_hook, | 4032 | run_funs (Fbuffer_local_value (Qwindow_configuration_change_hook, |
| 3706 | buffer)); | 4033 | buffer)); |
| 3707 | unbind_to (count1, Qnil); | 4034 | unbind_to (count, Qnil); |
| 3708 | } | 4035 | } |
| 3709 | } | 4036 | } |
| 3710 | } | 4037 | } |
| @@ -3713,6 +4040,16 @@ run_window_configuration_change_hook (struct frame *f) | |||
| 3713 | unbind_to (count, Qnil); | 4040 | unbind_to (count, Qnil); |
| 3714 | } | 4041 | } |
| 3715 | 4042 | ||
| 4043 | DEFUN ("run-window-configuration-change-hook", Frun_window_configuration_change_hook, | ||
| 4044 | Srun_window_configuration_change_hook, 1, 1, 0, | ||
| 4045 | doc: /* Run `window-configuration-change-hook' for FRAME. */) | ||
| 4046 | (Lisp_Object frame) | ||
| 4047 | { | ||
| 4048 | CHECK_LIVE_FRAME (frame); | ||
| 4049 | run_window_configuration_change_hook (XFRAME (frame)); | ||
| 4050 | return Qnil; | ||
| 4051 | } | ||
| 4052 | |||
| 3716 | /* Make WINDOW display BUFFER as its contents. RUN_HOOKS_P non-zero | 4053 | /* Make WINDOW display BUFFER as its contents. RUN_HOOKS_P non-zero |
| 3717 | means it's allowed to run hooks. See make_frame for a case where | 4054 | means it's allowed to run hooks. See make_frame for a case where |
| 3718 | it's not allowed. KEEP_MARGINS_P non-zero means that the current | 4055 | it's not allowed. KEEP_MARGINS_P non-zero means that the current |
| @@ -4019,7 +4356,7 @@ make_dummy_parent (Lisp_Object window) | |||
| 4019 | XSETFASTINT (p->clone_number, sequence_number); | 4356 | XSETFASTINT (p->clone_number, sequence_number); |
| 4020 | 4357 | ||
| 4021 | /* Put new into window structure in place of window */ | 4358 | /* Put new into window structure in place of window */ |
| 4022 | replace_window (window, new); | 4359 | replace_window (window, new, 1); |
| 4023 | 4360 | ||
| 4024 | o->next = Qnil; | 4361 | o->next = Qnil; |
| 4025 | o->prev = Qnil; | 4362 | o->prev = Qnil; |
| @@ -4037,6 +4374,43 @@ make_dummy_parent (Lisp_Object window) | |||
| 4037 | 4374 | ||
| 4038 | } | 4375 | } |
| 4039 | 4376 | ||
| 4377 | /* Make new window, have it replace WINDOW in window-tree, and make | ||
| 4378 | WINDOW its only vertical child (HORFLAG 1 means make WINDOW its only | ||
| 4379 | horizontal child). */ | ||
| 4380 | static void | ||
| 4381 | make_parent_window (Lisp_Object window, int horflag) | ||
| 4382 | { | ||
| 4383 | Lisp_Object parent; | ||
| 4384 | register struct window *o, *p; | ||
| 4385 | int i; | ||
| 4386 | |||
| 4387 | o = XWINDOW (window); | ||
| 4388 | p = allocate_window (); | ||
| 4389 | for (i = 0; i < VECSIZE (struct window); ++i) | ||
| 4390 | ((struct Lisp_Vector *) p)->contents[i] | ||
| 4391 | = ((struct Lisp_Vector *) o)->contents[i]; | ||
| 4392 | XSETWINDOW (parent, p); | ||
| 4393 | |||
| 4394 | ++sequence_number; | ||
| 4395 | XSETFASTINT (p->sequence_number, sequence_number); | ||
| 4396 | XSETFASTINT (p->clone_number, sequence_number); | ||
| 4397 | |||
| 4398 | replace_window (window, parent, 1); | ||
| 4399 | |||
| 4400 | o->next = Qnil; | ||
| 4401 | o->prev = Qnil; | ||
| 4402 | o->parent = parent; | ||
| 4403 | |||
| 4404 | p->hchild = horflag ? window : Qnil; | ||
| 4405 | p->vchild = horflag ? Qnil : window; | ||
| 4406 | p->start = Qnil; | ||
| 4407 | p->pointm = Qnil; | ||
| 4408 | p->buffer = Qnil; | ||
| 4409 | p->splits = Qnil; | ||
| 4410 | p->nest = Qnil; | ||
| 4411 | p->window_parameters = Qnil; | ||
| 4412 | } | ||
| 4413 | |||
| 4040 | /* Make new window from scratch. */ | 4414 | /* Make new window from scratch. */ |
| 4041 | Lisp_Object | 4415 | Lisp_Object |
| 4042 | make_window (void) | 4416 | make_window (void) |
| @@ -4138,6 +4512,654 @@ Note: This function does not operate on any subwindows of WINDOW. */) | |||
| 4138 | return w->new_normal; | 4512 | return w->new_normal; |
| 4139 | } | 4513 | } |
| 4140 | 4514 | ||
| 4515 | /* Return 1 if setting w->total_lines (w->total_cols if HORFLAG is | ||
| 4516 | non-zero) to w->new_total would result in correct heights (widths) | ||
| 4517 | for window W and recursively all subwindows of W. | ||
| 4518 | |||
| 4519 | Note: This function does not check any of `window-fixed-size-p', | ||
| 4520 | `window-min-height' or `window-min-width'. It does check that window | ||
| 4521 | sizes do not drop below one line (two columns). */ | ||
| 4522 | int | ||
| 4523 | resize_window_check (struct window *w, int horflag) | ||
| 4524 | { | ||
| 4525 | struct window *c; | ||
| 4526 | |||
| 4527 | if (!NILP (w->vchild)) | ||
| 4528 | /* W is a vertical combination. */ | ||
| 4529 | { | ||
| 4530 | c = XWINDOW (w->vchild); | ||
| 4531 | if (horflag) | ||
| 4532 | /* All subwindows of W must have the same width as W. */ | ||
| 4533 | { | ||
| 4534 | while (c) | ||
| 4535 | { | ||
| 4536 | if ((XINT (c->new_total) != XINT (w->new_total)) | ||
| 4537 | || !resize_window_check (c, horflag)) | ||
| 4538 | return 0; | ||
| 4539 | c = NILP (c->next) ? 0 : XWINDOW (c->next); | ||
| 4540 | } | ||
| 4541 | return 1; | ||
| 4542 | } | ||
| 4543 | else | ||
| 4544 | /* The sum of the heights of the subwindows of W must equal W's | ||
| 4545 | height. */ | ||
| 4546 | { | ||
| 4547 | int sum_of_sizes = 0; | ||
| 4548 | while (c) | ||
| 4549 | { | ||
| 4550 | if (!resize_window_check (c, horflag)) | ||
| 4551 | return 0; | ||
| 4552 | sum_of_sizes = sum_of_sizes + XINT (c->new_total); | ||
| 4553 | c = NILP (c->next) ? 0 : XWINDOW (c->next); | ||
| 4554 | } | ||
| 4555 | return (sum_of_sizes == XINT (w->new_total)); | ||
| 4556 | } | ||
| 4557 | } | ||
| 4558 | else if (!NILP (w->hchild)) | ||
| 4559 | /* W is a horizontal combination. */ | ||
| 4560 | { | ||
| 4561 | c = XWINDOW (w->hchild); | ||
| 4562 | if (horflag) | ||
| 4563 | /* The sum of the widths of the subwindows of W must equal W's | ||
| 4564 | width. */ | ||
| 4565 | { | ||
| 4566 | int sum_of_sizes = 0; | ||
| 4567 | while (c) | ||
| 4568 | { | ||
| 4569 | if (!resize_window_check (c, horflag)) | ||
| 4570 | return 0; | ||
| 4571 | sum_of_sizes = sum_of_sizes + XINT (c->new_total); | ||
| 4572 | c = NILP (c->next) ? 0 : XWINDOW (c->next); | ||
| 4573 | } | ||
| 4574 | return (sum_of_sizes == XINT (w->new_total)); | ||
| 4575 | } | ||
| 4576 | else | ||
| 4577 | /* All subwindows of W must have the same height as W. */ | ||
| 4578 | { | ||
| 4579 | while (c) | ||
| 4580 | { | ||
| 4581 | if ((XINT (c->new_total) != XINT (w->new_total)) | ||
| 4582 | || !resize_window_check (c, horflag)) | ||
| 4583 | return 0; | ||
| 4584 | c = NILP (c->next) ? 0 : XWINDOW (c->next); | ||
| 4585 | } | ||
| 4586 | return 1; | ||
| 4587 | } | ||
| 4588 | } | ||
| 4589 | else | ||
| 4590 | /* A leaf window. Make sure it's not too small. The following | ||
| 4591 | hardcodes the values of `window-safe-min-width' (2) and | ||
| 4592 | `window-safe-min-height' (1) which are defined in window.el. */ | ||
| 4593 | return XINT (w->new_total) >= (horflag ? 2 : 1); | ||
| 4594 | } | ||
| 4595 | |||
| 4596 | /* Set w->total_lines (w->total_cols if HORIZONTAL is non-zero) to | ||
| 4597 | w->new_total for window W and recursively all subwindows of W. Also | ||
| 4598 | calculate and assign the new vertical (horizontal) start positions of | ||
| 4599 | each of these windows. | ||
| 4600 | |||
| 4601 | This function does not perform any error checks. Make sure you have | ||
| 4602 | run resize_window_check on W before applying this function. */ | ||
| 4603 | void | ||
| 4604 | resize_window_apply (struct window *w, int horflag) | ||
| 4605 | { | ||
| 4606 | struct window *c, *p; | ||
| 4607 | int pos; | ||
| 4608 | |||
| 4609 | /* Note: Assigning new_normal requires that the new total size of the | ||
| 4610 | parent window has been set *before*. */ | ||
| 4611 | if (horflag) | ||
| 4612 | { | ||
| 4613 | w->total_cols = w->new_total; | ||
| 4614 | if (NUMBERP (w->new_normal)) | ||
| 4615 | w->normal_cols = w->new_normal; | ||
| 4616 | |||
| 4617 | pos = XINT (w->left_col); | ||
| 4618 | } | ||
| 4619 | else | ||
| 4620 | { | ||
| 4621 | w->total_lines = w->new_total; | ||
| 4622 | if (NUMBERP (w->new_normal)) | ||
| 4623 | w->normal_lines = w->new_normal; | ||
| 4624 | |||
| 4625 | pos = XINT (w->top_line); | ||
| 4626 | } | ||
| 4627 | |||
| 4628 | if (!NILP (w->vchild)) | ||
| 4629 | /* W is a vertical combination. */ | ||
| 4630 | { | ||
| 4631 | c = XWINDOW (w->vchild); | ||
| 4632 | while (c) | ||
| 4633 | { | ||
| 4634 | if (horflag) | ||
| 4635 | XSETFASTINT (c->left_col, pos); | ||
| 4636 | else | ||
| 4637 | XSETFASTINT (c->top_line, pos); | ||
| 4638 | resize_window_apply (c, horflag); | ||
| 4639 | if (!horflag) | ||
| 4640 | pos = pos + XINT (c->total_lines); | ||
| 4641 | c = NILP (c->next) ? 0 : XWINDOW (c->next); | ||
| 4642 | } | ||
| 4643 | } | ||
| 4644 | else if (!NILP (w->hchild)) | ||
| 4645 | /* W is a horizontal combination. */ | ||
| 4646 | { | ||
| 4647 | c = XWINDOW (w->hchild); | ||
| 4648 | while (c) | ||
| 4649 | { | ||
| 4650 | if (horflag) | ||
| 4651 | XSETFASTINT (c->left_col, pos); | ||
| 4652 | else | ||
| 4653 | XSETFASTINT (c->top_line, pos); | ||
| 4654 | resize_window_apply (c, horflag); | ||
| 4655 | if (horflag) | ||
| 4656 | pos = pos + XINT (c->total_cols); | ||
| 4657 | c = NILP (c->next) ? 0 : XWINDOW (c->next); | ||
| 4658 | } | ||
| 4659 | } | ||
| 4660 | |||
| 4661 | /* Clear out some redisplay caches. */ | ||
| 4662 | XSETFASTINT (w->last_modified, 0); | ||
| 4663 | XSETFASTINT (w->last_overlay_modified, 0); | ||
| 4664 | } | ||
| 4665 | |||
| 4666 | |||
| 4667 | DEFUN ("resize-window-apply", Fresize_window_apply, Sresize_window_apply, 1, 2, 0, | ||
| 4668 | doc: /* Apply requested size values for window-tree of FRAME. | ||
| 4669 | Optional argument HORIZONTAL omitted or nil means apply requested height | ||
| 4670 | values. HORIZONTAL non-nil means apply requested width values. | ||
| 4671 | |||
| 4672 | This function checks whether the requested values sum up to a valid | ||
| 4673 | window layout, recursively assigns the new sizes of all subwindows and | ||
| 4674 | calculates and assigns the new start positions of these windows. | ||
| 4675 | |||
| 4676 | Note: This function does not check any of `window-fixed-size-p', | ||
| 4677 | `window-min-height' or `window-min-width'. All these checks have to | ||
| 4678 | be applied on the Elisp level. */) | ||
| 4679 | (Lisp_Object frame, Lisp_Object horizontal) | ||
| 4680 | { | ||
| 4681 | struct frame *f; | ||
| 4682 | struct window *r; | ||
| 4683 | int horflag = !NILP (horizontal); | ||
| 4684 | |||
| 4685 | if (NILP (frame)) | ||
| 4686 | frame = selected_frame; | ||
| 4687 | CHECK_LIVE_FRAME (frame); | ||
| 4688 | |||
| 4689 | f = XFRAME (frame); | ||
| 4690 | r = XWINDOW (FRAME_ROOT_WINDOW (f)); | ||
| 4691 | |||
| 4692 | if (!resize_window_check (r, horflag) | ||
| 4693 | || ! EQ (r->new_total, (horflag ? r->total_cols : r->total_lines))) | ||
| 4694 | return Qnil; | ||
| 4695 | |||
| 4696 | BLOCK_INPUT; | ||
| 4697 | resize_window_apply (r, horflag); | ||
| 4698 | |||
| 4699 | windows_or_buffers_changed++; | ||
| 4700 | FRAME_WINDOW_SIZES_CHANGED (f) = 1; | ||
| 4701 | |||
| 4702 | adjust_glyphs (f); | ||
| 4703 | UNBLOCK_INPUT; | ||
| 4704 | |||
| 4705 | run_window_configuration_change_hook (f); | ||
| 4706 | |||
| 4707 | return Qt; | ||
| 4708 | } | ||
| 4709 | |||
| 4710 | |||
| 4711 | /* Resize frame F's windows when number of lines of F is set to SIZE. | ||
| 4712 | HORFLAG 1 means resize windows when number of columns of F is set to | ||
| 4713 | SIZE. | ||
| 4714 | |||
| 4715 | This function can delete all windows but the selected one in order to | ||
| 4716 | satisfy the request. The result will be meaningful if and only if | ||
| 4717 | F's windows have meaningful sizes when you call this. */ | ||
| 4718 | void | ||
| 4719 | resize_frame_windows (struct frame *f, int size, int horflag) | ||
| 4720 | { | ||
| 4721 | Lisp_Object root = f->root_window; | ||
| 4722 | struct window *r = XWINDOW (root); | ||
| 4723 | Lisp_Object mini = f->minibuffer_window; | ||
| 4724 | struct window *m; | ||
| 4725 | /* new_size is the new size of the frame's root window. */ | ||
| 4726 | int new_size = (horflag | ||
| 4727 | ? size | ||
| 4728 | : (size | ||
| 4729 | - FRAME_TOP_MARGIN (f) | ||
| 4730 | - ((FRAME_HAS_MINIBUF_P (f) && !FRAME_MINIBUF_ONLY_P (f)) | ||
| 4731 | ? 1 : 0))); | ||
| 4732 | |||
| 4733 | XSETFASTINT (r->top_line, FRAME_TOP_MARGIN (f)); | ||
| 4734 | if (NILP (r->vchild) && NILP (r->hchild)) | ||
| 4735 | /* For a leaf root window just set the size. */ | ||
| 4736 | if (horflag) | ||
| 4737 | XSETFASTINT (r->total_cols, new_size); | ||
| 4738 | else | ||
| 4739 | XSETFASTINT (r->total_lines, new_size); | ||
| 4740 | else | ||
| 4741 | { | ||
| 4742 | /* old_size is the old size of the frame's root window. */ | ||
| 4743 | int old_size = XFASTINT (horflag ? r->total_cols : r->total_lines); | ||
| 4744 | Lisp_Object delta; | ||
| 4745 | |||
| 4746 | XSETINT (delta, new_size - old_size); | ||
| 4747 | /* Try a "normal" resize first. */ | ||
| 4748 | resize_root_window (root, delta, horflag ? Qt : Qnil, Qnil); | ||
| 4749 | if (resize_window_check (r, horflag) && new_size == XINT (r->new_total)) | ||
| 4750 | resize_window_apply (r, horflag); | ||
| 4751 | else | ||
| 4752 | { | ||
| 4753 | /* Try with "reasonable" minimum sizes next. */ | ||
| 4754 | resize_root_window (root, delta, horflag ? Qt : Qnil, Qt); | ||
| 4755 | if (resize_window_check (r, horflag) | ||
| 4756 | && new_size == XINT (r->new_total)) | ||
| 4757 | resize_window_apply (r, horflag); | ||
| 4758 | else | ||
| 4759 | { | ||
| 4760 | /* Finally, try with "safe" minimum sizes. */ | ||
| 4761 | resize_root_window (root, delta, horflag ? Qt : Qnil, Qsafe); | ||
| 4762 | if (resize_window_check (r, horflag) | ||
| 4763 | && new_size == XINT (r->new_total)) | ||
| 4764 | resize_window_apply (r, horflag); | ||
| 4765 | else | ||
| 4766 | { | ||
| 4767 | /* We lost. Delete all windows but the frame's | ||
| 4768 | selected one. */ | ||
| 4769 | root = f->selected_window; | ||
| 4770 | Fdelete_other_windows_internal (root, Qnil); | ||
| 4771 | if (horflag) | ||
| 4772 | XSETFASTINT (XWINDOW (root)->total_cols, new_size); | ||
| 4773 | else | ||
| 4774 | XSETFASTINT (XWINDOW (root)->total_lines, new_size); | ||
| 4775 | } | ||
| 4776 | } | ||
| 4777 | } | ||
| 4778 | } | ||
| 4779 | |||
| 4780 | if (FRAME_HAS_MINIBUF_P (f) && !FRAME_MINIBUF_ONLY_P (f)) | ||
| 4781 | { | ||
| 4782 | m = XWINDOW (mini); | ||
| 4783 | if (horflag) | ||
| 4784 | XSETFASTINT (m->total_cols, size); | ||
| 4785 | else | ||
| 4786 | { | ||
| 4787 | /* Are we sure we always want 1 line here? */ | ||
| 4788 | XSETFASTINT (m->total_lines, 1); | ||
| 4789 | XSETFASTINT (m->top_line, XINT (r->top_line) + XINT (r->total_lines)); | ||
| 4790 | } | ||
| 4791 | } | ||
| 4792 | } | ||
| 4793 | |||
| 4794 | |||
| 4795 | DEFUN ("split-window-internal", Fsplit_window_internal, Ssplit_window_internal, 4, 4, 0, | ||
| 4796 | doc: /* Split window OLD. | ||
| 4797 | Second argument TOTAL-SIZE specifies the number of lines or columns of the | ||
| 4798 | new window. In any case TOTAL-SIZE must be a positive integer | ||
| 4799 | |||
| 4800 | Third argument SIDE nil (or `below') specifies that the new window shall | ||
| 4801 | be located below WINDOW. SIDE `above' means the new window shall be | ||
| 4802 | located above WINDOW. In both cases TOTAL-SIZE specifies the number of | ||
| 4803 | lines of the new window including space reserved for the mode and/or | ||
| 4804 | header line. | ||
| 4805 | |||
| 4806 | SIDE t (or `right') specifies that the new window shall be located on | ||
| 4807 | the right side of WINDOW. SIDE `left' means the new window shall be | ||
| 4808 | located on the left of WINDOW. In both cases TOTAL-SIZE specifies the | ||
| 4809 | number of columns of the new window including space reserved for fringes | ||
| 4810 | and the scrollbar or a divider column. | ||
| 4811 | |||
| 4812 | Fourth argument NORMAL-SIZE specifies the normal size of the new window | ||
| 4813 | according to the SIDE argument. | ||
| 4814 | |||
| 4815 | The new total and normal sizes of all involved windows must have been | ||
| 4816 | set correctly. See the code of `split-window' for how this is done. */) | ||
| 4817 | (Lisp_Object old, Lisp_Object total_size, Lisp_Object side, Lisp_Object normal_size) | ||
| 4818 | { | ||
| 4819 | /* OLD (*o) is the window we have to split. (*p) is either OLD's | ||
| 4820 | parent window or an internal window we have to install as OLD's new | ||
| 4821 | parent. REFERENCE (*r) must denote a live window, or is set to OLD | ||
| 4822 | provided OLD is a leaf window, or to the frame's selected window. | ||
| 4823 | NEW (*n) is the new window created with some parameters taken from | ||
| 4824 | REFERENCE (*r). */ | ||
| 4825 | register Lisp_Object new, frame, reference; | ||
| 4826 | register struct window *o, *p, *n, *r; | ||
| 4827 | struct frame *f; | ||
| 4828 | int horflag | ||
| 4829 | /* HORFLAG is 1 when we split side-by-side, 0 otherwise. */ | ||
| 4830 | = EQ (side, Qt) || EQ (side, Qleft) || EQ (side, Qright); | ||
| 4831 | int do_nest = 0; | ||
| 4832 | |||
| 4833 | CHECK_WINDOW (old); | ||
| 4834 | o = XWINDOW (old); | ||
| 4835 | frame = WINDOW_FRAME (o); | ||
| 4836 | f = XFRAME (frame); | ||
| 4837 | |||
| 4838 | CHECK_NUMBER (total_size); | ||
| 4839 | |||
| 4840 | /* Set do_nest to 1 if we have to make a new parent window. We do | ||
| 4841 | that if either `window-nest' is non-nil, or OLD has no parent, or | ||
| 4842 | OLD is ortho-combined. */ | ||
| 4843 | do_nest = | ||
| 4844 | !NILP (Vwindow_nest) | ||
| 4845 | || NILP (o->parent) | ||
| 4846 | || NILP (horflag | ||
| 4847 | ? (XWINDOW (o->parent)->hchild) | ||
| 4848 | : (XWINDOW (o->parent)->vchild)); | ||
| 4849 | |||
| 4850 | /* We need a live reference window to initialize some parameters. */ | ||
| 4851 | if (WINDOW_LIVE_P (old)) | ||
| 4852 | /* OLD is live, use it as reference window. */ | ||
| 4853 | reference = old; | ||
| 4854 | else | ||
| 4855 | /* Use the frame's selected window as reference window. */ | ||
| 4856 | reference = FRAME_SELECTED_WINDOW (f); | ||
| 4857 | r = XWINDOW (reference); | ||
| 4858 | |||
| 4859 | /* The following bugs are caught by `split-window'. */ | ||
| 4860 | if (MINI_WINDOW_P (o)) | ||
| 4861 | error ("Attempt to split minibuffer window"); | ||
| 4862 | else if (XINT (total_size) < (horflag ? 2 : 1)) | ||
| 4863 | error ("Size of new window too small (after split)"); | ||
| 4864 | else if (!do_nest && !NILP (Vwindow_splits)) | ||
| 4865 | /* `window-splits' non-nil means try to resize OLD's siblings | ||
| 4866 | proportionally. */ | ||
| 4867 | { | ||
| 4868 | p = XWINDOW (o->parent); | ||
| 4869 | /* Temporarily pretend we split the parent window. */ | ||
| 4870 | XSETINT (p->new_total, | ||
| 4871 | XINT (horflag ? p->total_cols : p->total_lines) | ||
| 4872 | - XINT (total_size)); | ||
| 4873 | if (!resize_window_check (p, horflag)) | ||
| 4874 | error ("Window sizes don't fit"); | ||
| 4875 | else | ||
| 4876 | /* Undo the temporary pretension. */ | ||
| 4877 | p->new_total = horflag ? p->total_cols : p->total_lines; | ||
| 4878 | } | ||
| 4879 | else | ||
| 4880 | { | ||
| 4881 | if (!resize_window_check (o, horflag)) | ||
| 4882 | error ("Resizing old window failed"); | ||
| 4883 | else if (XINT (total_size) + XINT (o->new_total) | ||
| 4884 | != XINT (horflag ? o->total_cols : o->total_lines)) | ||
| 4885 | error ("Sum of sizes of old and new window don't fit"); | ||
| 4886 | } | ||
| 4887 | |||
| 4888 | /* This is our point of no return. */ | ||
| 4889 | if (do_nest) | ||
| 4890 | { | ||
| 4891 | /* Save the old value of o->normal_cols/lines. It gets corrupted | ||
| 4892 | by make_parent_window and we need it below for assigning it to | ||
| 4893 | p->new_normal. */ | ||
| 4894 | Lisp_Object new_normal = horflag ? o->normal_cols : o->normal_lines; | ||
| 4895 | |||
| 4896 | make_parent_window (old, horflag); | ||
| 4897 | p = XWINDOW (o->parent); | ||
| 4898 | /* Store value of `window-nest' in new parent's nest slot. */ | ||
| 4899 | p->nest = Vwindow_nest; | ||
| 4900 | /* Have PARENT inherit splits slot value from OLD. */ | ||
| 4901 | p->splits = o->splits; | ||
| 4902 | /* Store value of `window-splits' in OLD's splits slot. */ | ||
| 4903 | o->splits = Vwindow_splits; | ||
| 4904 | /* These get applied below. */ | ||
| 4905 | p->new_total = horflag ? o->total_cols : o->total_lines; | ||
| 4906 | p->new_normal = new_normal; | ||
| 4907 | } | ||
| 4908 | else | ||
| 4909 | p = XWINDOW (o->parent); | ||
| 4910 | |||
| 4911 | windows_or_buffers_changed++; | ||
| 4912 | FRAME_WINDOW_SIZES_CHANGED (f) = 1; | ||
| 4913 | new = make_window (); | ||
| 4914 | n = XWINDOW (new); | ||
| 4915 | n->frame = frame; | ||
| 4916 | n->parent = o->parent; | ||
| 4917 | n->vchild = n->hchild = Qnil; | ||
| 4918 | |||
| 4919 | if (EQ (side, Qabove) || EQ (side, Qleft)) | ||
| 4920 | { | ||
| 4921 | n->prev = o->prev; | ||
| 4922 | if (NILP (n->prev)) | ||
| 4923 | if (horflag) | ||
| 4924 | p->hchild = new; | ||
| 4925 | else | ||
| 4926 | p->vchild = new; | ||
| 4927 | else | ||
| 4928 | XWINDOW (n->prev)->next = new; | ||
| 4929 | n->next = old; | ||
| 4930 | o->prev = new; | ||
| 4931 | } | ||
| 4932 | else | ||
| 4933 | { | ||
| 4934 | n->next = o->next; | ||
| 4935 | if (!NILP (n->next)) | ||
| 4936 | XWINDOW (n->next)->prev = new; | ||
| 4937 | n->prev = old; | ||
| 4938 | o->next = new; | ||
| 4939 | } | ||
| 4940 | |||
| 4941 | n->buffer = Qt; | ||
| 4942 | n->window_end_valid = Qnil; | ||
| 4943 | memset (&n->last_cursor, 0, sizeof n->last_cursor); | ||
| 4944 | |||
| 4945 | /* Get special geometry settings from reference window. */ | ||
| 4946 | n->left_margin_cols = r->left_margin_cols; | ||
| 4947 | n->right_margin_cols = r->right_margin_cols; | ||
| 4948 | n->left_fringe_width = r->left_fringe_width; | ||
| 4949 | n->right_fringe_width = r->right_fringe_width; | ||
| 4950 | n->fringes_outside_margins = r->fringes_outside_margins; | ||
| 4951 | n->scroll_bar_width = r->scroll_bar_width; | ||
| 4952 | n->vertical_scroll_bar_type = r->vertical_scroll_bar_type; | ||
| 4953 | |||
| 4954 | /* Store `window-splits' in NEW's splits slot. */ | ||
| 4955 | n->splits = Vwindow_splits; | ||
| 4956 | |||
| 4957 | /* Directly assign orthogonal coordinates and sizes. */ | ||
| 4958 | if (horflag) | ||
| 4959 | { | ||
| 4960 | n->top_line = o->top_line; | ||
| 4961 | n->total_lines = o->total_lines; | ||
| 4962 | } | ||
| 4963 | else | ||
| 4964 | { | ||
| 4965 | n->left_col = o->left_col; | ||
| 4966 | n->total_cols = o->total_cols; | ||
| 4967 | } | ||
| 4968 | |||
| 4969 | /* Iso-coordinates and sizes are assigned by resize_window_apply, | ||
| 4970 | get them ready here. */ | ||
| 4971 | n->new_total = total_size; | ||
| 4972 | n->new_normal = normal_size; | ||
| 4973 | |||
| 4974 | BLOCK_INPUT; | ||
| 4975 | resize_window_apply (p, horflag); | ||
| 4976 | adjust_glyphs (f); | ||
| 4977 | /* Set buffer of NEW to buffer of reference window. Don't run | ||
| 4978 | any hooks. */ | ||
| 4979 | set_window_buffer (new, r->buffer, 0, 1); | ||
| 4980 | UNBLOCK_INPUT; | ||
| 4981 | |||
| 4982 | /* Maybe we should run the scroll functions in Elisp (which already | ||
| 4983 | runs the configuration change hook). */ | ||
| 4984 | if (! NILP (Vwindow_scroll_functions)) | ||
| 4985 | run_hook_with_args_2 (Qwindow_scroll_functions, new, | ||
| 4986 | Fmarker_position (n->start)); | ||
| 4987 | /* Return NEW. */ | ||
| 4988 | return new; | ||
| 4989 | } | ||
| 4990 | |||
| 4991 | |||
| 4992 | DEFUN ("delete-window-internal", Fdelete_window_internal, Sdelete_window_internal, 1, 1, 0, | ||
| 4993 | doc: /* Remove WINDOW from its frame. | ||
| 4994 | WINDOW defaults to the selected window. Return nil. Signal an error | ||
| 4995 | when WINDOW is the only window on its frame. */) | ||
| 4996 | (register Lisp_Object window) | ||
| 4997 | { | ||
| 4998 | register Lisp_Object parent, sibling, frame, root; | ||
| 4999 | struct window *w, *p, *s, *r; | ||
| 5000 | struct frame *f; | ||
| 5001 | int horflag; | ||
| 5002 | int before_sibling = 0; | ||
| 5003 | |||
| 5004 | w = decode_any_window (window); | ||
| 5005 | XSETWINDOW (window, w); | ||
| 5006 | if (NILP (w->buffer) && NILP (w->hchild) && NILP (w->vchild)) | ||
| 5007 | /* It's a no-op to delete an already deleted window. */ | ||
| 5008 | return Qnil; | ||
| 5009 | |||
| 5010 | parent = w->parent; | ||
| 5011 | if (NILP (parent)) | ||
| 5012 | /* Never delete a minibuffer or frame root window. */ | ||
| 5013 | error ("Attempt to delete minibuffer or sole ordinary window"); | ||
| 5014 | else if (NILP (w->prev) && NILP (w->next)) | ||
| 5015 | /* Rather bow out here, this case should be handled on the Elisp | ||
| 5016 | level. */ | ||
| 5017 | error ("Attempt to delete sole window of parent"); | ||
| 5018 | |||
| 5019 | p = XWINDOW (parent); | ||
| 5020 | horflag = NILP (p->vchild); | ||
| 5021 | |||
| 5022 | frame = WINDOW_FRAME (w); | ||
| 5023 | f = XFRAME (frame); | ||
| 5024 | |||
| 5025 | root = FRAME_ROOT_WINDOW (f); | ||
| 5026 | r = XWINDOW (root); | ||
| 5027 | |||
| 5028 | /* Unlink WINDOW from window tree. */ | ||
| 5029 | if (NILP (w->prev)) | ||
| 5030 | /* Get SIBLING below (on the right of) WINDOW. */ | ||
| 5031 | { | ||
| 5032 | /* before_sibling 1 means WINDOW is the first child of its | ||
| 5033 | parent and thus before the sibling. */ | ||
| 5034 | before_sibling = 1; | ||
| 5035 | sibling = w->next; | ||
| 5036 | s = XWINDOW (sibling); | ||
| 5037 | s->prev = Qnil; | ||
| 5038 | if (horflag) | ||
| 5039 | p->hchild = sibling; | ||
| 5040 | else | ||
| 5041 | p->vchild = sibling; | ||
| 5042 | } | ||
| 5043 | else | ||
| 5044 | /* Get SIBLING above (on the left of) WINDOW. */ | ||
| 5045 | { | ||
| 5046 | sibling = w->prev; | ||
| 5047 | s = XWINDOW (sibling); | ||
| 5048 | s->next = w->next; | ||
| 5049 | if (!NILP (s->next)) | ||
| 5050 | XWINDOW (s->next)->prev = sibling; | ||
| 5051 | } | ||
| 5052 | |||
| 5053 | if (resize_window_check (r, horflag) | ||
| 5054 | && EQ (r->new_total, (horflag ? r->total_cols : r->total_lines))) | ||
| 5055 | /* We can delete WINDOW now. */ | ||
| 5056 | { | ||
| 5057 | /* Block input. */ | ||
| 5058 | BLOCK_INPUT; | ||
| 5059 | resize_window_apply (p, horflag); | ||
| 5060 | |||
| 5061 | windows_or_buffers_changed++; | ||
| 5062 | Vwindow_list = Qnil; | ||
| 5063 | FRAME_WINDOW_SIZES_CHANGED (f) = 1; | ||
| 5064 | |||
| 5065 | w->next = Qnil; /* Don't delete w->next too. */ | ||
| 5066 | free_window_matrices (w); | ||
| 5067 | |||
| 5068 | if (!NILP (w->vchild)) | ||
| 5069 | { | ||
| 5070 | delete_all_subwindows (w->vchild); | ||
| 5071 | w->vchild = Qnil; | ||
| 5072 | } | ||
| 5073 | else if (!NILP (w->hchild)) | ||
| 5074 | { | ||
| 5075 | delete_all_subwindows (w->hchild); | ||
| 5076 | w->hchild = Qnil; | ||
| 5077 | } | ||
| 5078 | else if (!NILP (w->buffer)) | ||
| 5079 | { | ||
| 5080 | unshow_buffer (w); | ||
| 5081 | unchain_marker (XMARKER (w->pointm)); | ||
| 5082 | unchain_marker (XMARKER (w->start)); | ||
| 5083 | w->buffer = Qnil; | ||
| 5084 | } | ||
| 5085 | |||
| 5086 | if (NILP (s->prev) && NILP (s->next)) | ||
| 5087 | /* A matrjoshka where SIBLING has become the only child of | ||
| 5088 | PARENT. */ | ||
| 5089 | { | ||
| 5090 | /* Put SIBLING into PARENT's place. */ | ||
| 5091 | replace_window (parent, sibling, 0); | ||
| 5092 | /* Have SIBLING inherit the following three slot values from | ||
| 5093 | PARENT (the nest slot is not inherited). */ | ||
| 5094 | s->normal_cols = p->normal_cols; | ||
| 5095 | s->normal_lines = p->normal_lines; | ||
| 5096 | s->splits = p->splits; | ||
| 5097 | /* Mark PARENT as deleted. */ | ||
| 5098 | p->vchild = p->hchild = Qnil; | ||
| 5099 | /* Try to merge SIBLING into its new parent. */ | ||
| 5100 | recombine_windows (sibling); | ||
| 5101 | } | ||
| 5102 | |||
| 5103 | adjust_glyphs (f); | ||
| 5104 | |||
| 5105 | if (!WINDOW_LIVE_P (FRAME_SELECTED_WINDOW (f))) | ||
| 5106 | /* We deleted the frame's selected window. */ | ||
| 5107 | { | ||
| 5108 | /* Use the frame's first window as fallback ... */ | ||
| 5109 | Lisp_Object new_selected_window = Fframe_first_window (frame); | ||
| 5110 | /* ... but preferably use its most recently used window. */ | ||
| 5111 | Lisp_Object mru_window; | ||
| 5112 | |||
| 5113 | /* `get-mru-window' might fail for some reason so play it safe | ||
| 5114 | - promote the first window _without recording it_ first. */ | ||
| 5115 | if (EQ (FRAME_SELECTED_WINDOW (f), selected_window)) | ||
| 5116 | Fselect_window (new_selected_window, Qt); | ||
| 5117 | else | ||
| 5118 | FRAME_SELECTED_WINDOW (f) = new_selected_window; | ||
| 5119 | |||
| 5120 | UNBLOCK_INPUT; | ||
| 5121 | |||
| 5122 | /* Now look whether `get-mru-window' gets us something. */ | ||
| 5123 | mru_window = call1 (Qget_mru_window, frame); | ||
| 5124 | if (WINDOW_LIVE_P (mru_window) | ||
| 5125 | && EQ (XWINDOW (mru_window)->frame, frame)) | ||
| 5126 | new_selected_window = mru_window; | ||
| 5127 | |||
| 5128 | /* If all ended up well, we now promote the mru window. */ | ||
| 5129 | if (EQ (FRAME_SELECTED_WINDOW (f), selected_window)) | ||
| 5130 | Fselect_window (new_selected_window, Qnil); | ||
| 5131 | else | ||
| 5132 | FRAME_SELECTED_WINDOW (f) = new_selected_window; | ||
| 5133 | } | ||
| 5134 | else | ||
| 5135 | UNBLOCK_INPUT; | ||
| 5136 | |||
| 5137 | /* Must be run by the caller: | ||
| 5138 | run_window_configuration_change_hook (f); */ | ||
| 5139 | } | ||
| 5140 | else | ||
| 5141 | /* We failed: Relink WINDOW into window tree. */ | ||
| 5142 | { | ||
| 5143 | if (before_sibling) | ||
| 5144 | { | ||
| 5145 | s->prev = window; | ||
| 5146 | if (horflag) | ||
| 5147 | p->hchild = window; | ||
| 5148 | else | ||
| 5149 | p->vchild = window; | ||
| 5150 | } | ||
| 5151 | else | ||
| 5152 | { | ||
| 5153 | s->next = window; | ||
| 5154 | if (!NILP (w->next)) | ||
| 5155 | XWINDOW (w->next)->prev = window; | ||
| 5156 | } | ||
| 5157 | error ("Deletion failed"); | ||
| 5158 | } | ||
| 5159 | |||
| 5160 | return Qnil; | ||
| 5161 | } | ||
| 5162 | |||
| 4141 | DEFUN ("split-window", Fsplit_window, Ssplit_window, 0, 3, "", | 5163 | DEFUN ("split-window", Fsplit_window, Ssplit_window, 0, 3, "", |
| 4142 | doc: /* Split WINDOW, putting SIZE lines in the first of the pair. | 5164 | doc: /* Split WINDOW, putting SIZE lines in the first of the pair. |
| 4143 | WINDOW defaults to selected one and SIZE to half its size. | 5165 | WINDOW defaults to selected one and SIZE to half its size. |
| @@ -4279,6 +5301,46 @@ See Info node `(elisp)Splitting Windows' for more details and examples. */) | |||
| 4279 | Fset_window_buffer (new, o->buffer, Qt); | 5301 | Fset_window_buffer (new, o->buffer, Qt); |
| 4280 | return new; | 5302 | return new; |
| 4281 | } | 5303 | } |
| 5304 | |||
| 5305 | DEFUN ("resize-mini-window-internal", Fresize_mini_window_internal, Sresize_mini_window_internal, 1, 1, 0, | ||
| 5306 | doc: /* Resize minibuffer window WINDOW. */) | ||
| 5307 | (Lisp_Object window) | ||
| 5308 | { | ||
| 5309 | struct window *w = XWINDOW (window); | ||
| 5310 | struct window *r; | ||
| 5311 | struct frame *f; | ||
| 5312 | int height; | ||
| 5313 | |||
| 5314 | CHECK_WINDOW (window); | ||
| 5315 | f = XFRAME (w->frame); | ||
| 5316 | |||
| 5317 | if (!EQ (FRAME_MINIBUF_WINDOW (XFRAME (w->frame)), window)) | ||
| 5318 | error ("Not a valid minibuffer window"); | ||
| 5319 | else if (FRAME_MINIBUF_ONLY_P (f)) | ||
| 5320 | error ("Cannot resize a minibuffer-only frame"); | ||
| 5321 | |||
| 5322 | r = XWINDOW (FRAME_ROOT_WINDOW (f)); | ||
| 5323 | height = XINT (r->total_lines) + XINT (w->total_lines); | ||
| 5324 | if (resize_window_check (r, 0) | ||
| 5325 | && XINT (w->new_total) > 0 | ||
| 5326 | && height == XINT (r->new_total) + XINT (w->new_total)) | ||
| 5327 | { | ||
| 5328 | BLOCK_INPUT; | ||
| 5329 | resize_window_apply (r, 0); | ||
| 5330 | |||
| 5331 | w->total_lines = w->new_total; | ||
| 5332 | XSETFASTINT (w->top_line, XINT (r->top_line) + XINT (r->total_lines)); | ||
| 5333 | |||
| 5334 | windows_or_buffers_changed++; | ||
| 5335 | FRAME_WINDOW_SIZES_CHANGED (f) = 1; | ||
| 5336 | adjust_glyphs (f); | ||
| 5337 | UNBLOCK_INPUT; | ||
| 5338 | |||
| 5339 | run_window_configuration_change_hook (f); | ||
| 5340 | return Qt; | ||
| 5341 | } | ||
| 5342 | else error ("Failed to resize minibuffer window"); | ||
| 5343 | } | ||
| 4282 | 5344 | ||
| 4283 | DEFUN ("enlarge-window", Fenlarge_window, Senlarge_window, 1, 2, "p", | 5345 | DEFUN ("enlarge-window", Fenlarge_window, Senlarge_window, 1, 2, "p", |
| 4284 | doc: /* Make selected window SIZE lines taller. | 5346 | doc: /* Make selected window SIZE lines taller. |
| @@ -7527,6 +8589,41 @@ will redraw the entire frame; the special value `tty' causes the | |||
| 7527 | frame to be redrawn only if it is a tty frame. */); | 8589 | frame to be redrawn only if it is a tty frame. */); |
| 7528 | Vrecenter_redisplay = Qtty; | 8590 | Vrecenter_redisplay = Qtty; |
| 7529 | 8591 | ||
| 8592 | DEFVAR_LISP ("window-splits", Vwindow_splits, | ||
| 8593 | doc: /* Non-nil means splitting windows is handled specially. | ||
| 8594 | If this variable is nil, splitting a window gets the entire screen space | ||
| 8595 | for displaying the new window from the window to split. If this | ||
| 8596 | variable is non-nil, splitting a window may resize all windows in the | ||
| 8597 | same combination. This also allows to split a window that is otherwise | ||
| 8598 | too small or of fixed size. | ||
| 8599 | |||
| 8600 | The value of this variable is also assigned to the split status of the | ||
| 8601 | new window and, provided the old and new window form a new combination, | ||
| 8602 | to the window that was split as well. The split status of a window can | ||
| 8603 | be retrieved with the function `window-splits' and altered by the | ||
| 8604 | function `set-window-splits'. | ||
| 8605 | |||
| 8606 | If the value of the variable `window-nest' is non-nil, the space for the | ||
| 8607 | new window is exclusively taken from the window that shall be split, but | ||
| 8608 | the split status of the window that is split as well as that of the new | ||
| 8609 | window are still set to the value of this variable. */); | ||
| 8610 | Vwindow_splits = Qnil; | ||
| 8611 | |||
| 8612 | DEFVAR_LISP ("window-nest", Vwindow_nest, | ||
| 8613 | doc: /* Non-nil means splitting a window makes a new parent window. | ||
| 8614 | If this variable is nil, splitting a window will create a new parent | ||
| 8615 | window only if the window has no parent window or the window shall | ||
| 8616 | become a combination orthogonal to the one it it is part of. | ||
| 8617 | |||
| 8618 | If this variable is non-nil, splitting a window always creates a new | ||
| 8619 | parent window. If all splits behave this way, each frame's window tree | ||
| 8620 | is a binary tree and every window but the frame's root window has | ||
| 8621 | exactly one sibling. | ||
| 8622 | |||
| 8623 | The value of this variable is also assigned to the nest status of the | ||
| 8624 | new parent window. The nest status of a window can be retrieved via the | ||
| 8625 | function `window-nest' and altered by the function `set-window-nest'. */); | ||
| 8626 | Vwindow_nest = Qnil; | ||
| 7530 | 8627 | ||
| 7531 | defsubr (&Sselected_window); | 8628 | defsubr (&Sselected_window); |
| 7532 | defsubr (&Sminibuffer_window); | 8629 | defsubr (&Sminibuffer_window); |
| @@ -7560,6 +8657,7 @@ frame to be redrawn only if it is a tty frame. */); | |||
| 7560 | defsubr (&Swindow_new_normal); | 8657 | defsubr (&Swindow_new_normal); |
| 7561 | defsubr (&Sset_window_new_total); | 8658 | defsubr (&Sset_window_new_total); |
| 7562 | defsubr (&Sset_window_new_normal); | 8659 | defsubr (&Sset_window_new_normal); |
| 8660 | defsubr (&Sresize_window_apply); | ||
| 7563 | defsubr (&Swindow_body_size); | 8661 | defsubr (&Swindow_body_size); |
| 7564 | defsubr (&Swindow_hscroll); | 8662 | defsubr (&Swindow_hscroll); |
| 7565 | defsubr (&Sset_window_hscroll); | 8663 | defsubr (&Sset_window_hscroll); |
| @@ -7590,12 +8688,17 @@ frame to be redrawn only if it is a tty frame. */); | |||
| 7590 | defsubr (&Sdelete_windows_on); | 8688 | defsubr (&Sdelete_windows_on); |
| 7591 | defsubr (&Sreplace_buffer_in_windows); | 8689 | defsubr (&Sreplace_buffer_in_windows); |
| 7592 | defsubr (&Sdelete_window); | 8690 | defsubr (&Sdelete_window); |
| 8691 | defsubr (&Sdelete_other_windows_internal); | ||
| 8692 | defsubr (&Sdelete_window_internal); | ||
| 8693 | defsubr (&Sresize_mini_window_internal); | ||
| 7593 | defsubr (&Sset_window_buffer); | 8694 | defsubr (&Sset_window_buffer); |
| 7594 | defsubr (&Sset_window_clone_number); | 8695 | defsubr (&Sset_window_clone_number); |
| 8696 | defsubr (&Srun_window_configuration_change_hook); | ||
| 7595 | defsubr (&Sselect_window); | 8697 | defsubr (&Sselect_window); |
| 7596 | defsubr (&Sforce_window_update); | 8698 | defsubr (&Sforce_window_update); |
| 7597 | defsubr (&Stemp_output_buffer_show); | 8699 | defsubr (&Stemp_output_buffer_show); |
| 7598 | defsubr (&Ssplit_window); | 8700 | defsubr (&Ssplit_window); |
| 8701 | defsubr (&Ssplit_window_internal); | ||
| 7599 | defsubr (&Senlarge_window); | 8702 | defsubr (&Senlarge_window); |
| 7600 | defsubr (&Sshrink_window); | 8703 | defsubr (&Sshrink_window); |
| 7601 | defsubr (&Sadjust_window_trailing_edge); | 8704 | defsubr (&Sadjust_window_trailing_edge); |