/* Window creation, deletion and examination for GNU Emacs.
Does not include redisplay.
Copyright (C) 1985, 1986, 1987, 1993, 1994, 1995, 1996, 1997, 1998, 2000,
- 2001, 2002, 2003, 2004, 2005, 2006, 2007 Free Software Foundation, Inc.
+ 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008
+ Free Software Foundation, Inc.
This file is part of GNU Emacs.
GNU Emacs is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
-the Free Software Foundation; either version 2, or (at your option)
+the Free Software Foundation; either version 3, or (at your option)
any later version.
GNU Emacs is distributed in the hope that it will be useful,
#include "dispextern.h"
#include "blockinput.h"
#include "intervals.h"
+#include "termhooks.h" /* For FRAME_TERMINAL. */
#ifdef HAVE_X_WINDOWS
#include "xterm.h"
static void window_scroll_pixel_based P_ ((Lisp_Object, int, int, int));
static void window_scroll_line_based P_ ((Lisp_Object, int, int, int));
static int window_min_size_1 P_ ((struct window *, int));
+static int window_min_size_2 P_ ((struct window *, int));
static int window_min_size P_ ((struct window *, int, int, int *));
static void size_window P_ ((Lisp_Object, int, int, int, int, int));
static int freeze_window_start P_ ((struct window *, void *));
EMACS_INT split_height_threshold;
+/* How to split windows (horizontally/vertically/hybrid). */
+
+Lisp_Object Vsplit_window_preferred_function;
+
/* Number of lines of continuity in scrolling by screenfuls. */
EMACS_INT next_screen_context_lines;
return make_number (window_box_text_cols (decode_any_window (window)));
}
+DEFUN ("window-full-width-p", Fwindow_full_width_p, Swindow_full_width_p, 0, 1, 0,
+ doc: /* Return t if WINDOW is as wide as its frame.
+WINDOW defaults to the selected window. */)
+ (window)
+ Lisp_Object window;
+{
+ return WINDOW_FULL_WIDTH_P (decode_any_window (window)) ? Qt : Qnil;
+}
+
DEFUN ("window-hscroll", Fwindow_hscroll, Swindow_hscroll, 0, 1, 0,
doc: /* Return the number of columns by which WINDOW is scrolled from left margin.
WINDOW defaults to the selected window. */)
if (WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_LEFT (w)
|| WINDOW_RIGHTMOST_P (w))
{
- if (!WINDOW_LEFTMOST_P (w) && abs (*x - x0) < grabbable_width)
+ if (!WINDOW_LEFTMOST_P (w) && eabs (*x - x0) < grabbable_width)
{
/* Convert X and Y to window relative coordinates.
Vertical border is at the left edge of window. */
}
else
{
- if (abs (*x - x1) < grabbable_width)
+ if (eabs (*x - x1) < grabbable_width)
{
/* Convert X and Y to window relative coordinates.
Vertical border is at the right edge of window. */
if (!w->pseudo_window_p
&& !WINDOW_HAS_VERTICAL_SCROLL_BAR (w)
&& !WINDOW_RIGHTMOST_P (w)
- && (abs (*x - right_x) < grabbable_width))
+ && (eabs (*x - right_x) < grabbable_width))
{
/* Convert X and Y to window relative coordinates.
Vertical border is at the right edge of window. */
if (!EQ (window, pwindow))
break;
/* Otherwise, try another window for SWINDOW. */
- swindow = Fnext_window (swindow, Qlambda, Qnil);;
+ swindow = Fnext_window (swindow, Qlambda, Qnil);
/* If we get back to the frame's selected window,
it means there was no acceptable alternative,
else if (EQ (all_frames, Qvisible))
{
FRAME_SAMPLE_VISIBILITY (f);
- candidate_p = FRAME_VISIBLE_P (f);
+ candidate_p = FRAME_VISIBLE_P (f)
+ && (FRAME_TERMINAL (XFRAME (w->frame))
+ == FRAME_TERMINAL (XFRAME (selected_frame)));
+
}
else if (INTEGERP (all_frames) && XINT (all_frames) == 0)
{
FRAME_SAMPLE_VISIBILITY (f);
- candidate_p = FRAME_VISIBLE_P (f) || FRAME_ICONIFIED_P (f);
+ candidate_p = (FRAME_VISIBLE_P (f) || FRAME_ICONIFIED_P (f)
+#ifdef HAVE_X_WINDOWS
+ /* Yuck!! If we've just created the frame and the
+ window-manager requested the user to place it
+ manually, the window may still not be considered
+ `visible'. I'd argue it should be at least
+ something like `iconified', but don't know how to do
+ that yet. --Stef */
+ || (FRAME_X_P (f) && f->output_data.x->asked_for_visible
+ && !f->output_data.x->has_been_visible)
+#endif
+ )
+ && (FRAME_TERMINAL (XFRAME (w->frame))
+ == FRAME_TERMINAL (XFRAME (selected_frame)));
}
else if (WINDOWP (all_frames))
candidate_p = (EQ (FRAME_MINIBUF_WINDOW (f), all_frames)
if (NILP (best_window))
best_window = window;
else if (EQ (window, selected_window))
- /* For compatibility with 20.x, prefer to return
- selected-window. */
+ /* Prefer to return selected-window. */
+ RETURN_UNGCPRO (window);
+ else if (EQ (Fwindow_frame (window), selected_frame))
+ /* Prefer windows on the current frame. */
best_window = window;
}
break;
DEFUN ("get-lru-window", Fget_lru_window, Sget_lru_window, 0, 2, 0,
doc: /* Return the window least recently selected or used for display.
+\(LRU means Least Recently Used.)
+
Return a full-width window if possible.
A minibuffer window is never a candidate.
A dedicated window is never a candidate, unless DEDICATED is non-nil,
*cols = MIN_SAFE_WINDOW_WIDTH;
}
-
/* Value is non-zero if window W is fixed-size. WIDTH_P non-zero means
check if W's width can be changed, otherwise check W's height.
CHECK_SIBLINGS_P non-zero means check resizablity of WINDOW's
{
Lisp_Object child;
- for (child = w->prev; !NILP (child); child = XWINDOW (child)->prev)
+ for (child = w->prev; WINDOWP (child); child = XWINDOW (child)->prev)
if (!window_fixed_size_p (XWINDOW (child), width_p, 0))
break;
if (NILP (child))
- for (child = w->next; !NILP (child); child = XWINDOW (child)->next)
+ for (child = w->next; WINDOWP (child); child = XWINDOW (child)->next)
if (!window_fixed_size_p (XWINDOW (child), width_p, 0))
break;
return fixed_p;
}
+/* Return the minimum size for leaf window W. WIDTH_P non-zero means
+ take into account fringes and the scrollbar of W. WIDTH_P zero means
+ take into account mode-line of W. Return 1 for the minibuffer. */
+
+static int
+window_min_size_2 (w, width_p)
+ struct window *w;
+ int width_p;
+{
+ int size;
+
+ if (width_p)
+ size = max (window_min_width,
+ (MIN_SAFE_WINDOW_WIDTH
+ + WINDOW_FRINGE_COLS (w)
+ + WINDOW_SCROLL_BAR_COLS (w)));
+ else if (MINI_WINDOW_P (w))
+ size = 1;
+ else
+ size = max (window_min_height,
+ (MIN_SAFE_WINDOW_HEIGHT
+ /* Don't count the header-line here. It would break
+ splitting a window with a header-line when the new
+ window shall have a height of two (calculator does
+ that). */
+ + (WINDOW_WANTS_MODELINE_P (w) ? 1 : 0)));
+
+ return size;
+}
/* Return the minimum size of window W, not taking fixed-width windows
into account. WIDTH_P non-zero means return the minimum width,
}
}
else
- {
- if (width_p)
- size = max (window_min_width,
- (MIN_SAFE_WINDOW_WIDTH
- + WINDOW_FRINGE_COLS (w)
- + WINDOW_SCROLL_BAR_COLS (w)));
- else
- {
- if (MINI_WINDOW_P (w)
- || (!WINDOW_WANTS_MODELINE_P (w)
- && !WINDOW_WANTS_HEADER_LINE_P (w)))
- size = 1;
- else
- size = window_min_height;
- }
- }
+ size = window_min_size_2 (w, width_p);
return size;
}
Lisp_Object child, *forward, *sideward;
int old_size, min_size, safe_min_size;
- /* We test nodelete_p != 2 and nodelete_p != 1 below, so it
- seems like it's too soon to do this here. ++KFS. */
- if (nodelete_p == 2)
- nodelete_p = 0;
-
check_min_window_sizes ();
size = max (0, size);
{
old_size = WINDOW_TOTAL_COLS (w);
min_size = window_min_width;
- /* Ensure that there is room for the scroll bar and fringes!
- We may reduce display margins though. */
- safe_min_size = (MIN_SAFE_WINDOW_WIDTH
- + WINDOW_FRINGE_COLS (w)
- + WINDOW_SCROLL_BAR_COLS (w));
+ safe_min_size = window_min_size_2 (w, 1);
}
else
{
old_size = XINT (w->total_lines);
min_size = window_min_height;
- safe_min_size = MIN_SAFE_WINDOW_HEIGHT;
+ safe_min_size = window_min_size_2 (w, 0);
}
if (old_size < min_size && nodelete_p != 2)
w->too_small_ok = Qt;
+ /* Move the following test here since otherwise the
+ preceding test doesn't make sense. martin. */
+ if (nodelete_p == 2)
+ nodelete_p = 0;
+
/* Maybe delete WINDOW if it's too small. */
if (nodelete_p != 1 && !NILP (w->parent))
{
EXFUN (Fset_window_fringes, 4);
EXFUN (Fset_window_scroll_bars, 4);
+void
+run_window_configuration_change_hook (struct frame *f)
+{
+ if (! NILP (Vwindow_configuration_change_hook)
+ && ! NILP (Vrun_hooks))
+ {
+ int count = SPECPDL_INDEX ();
+ if (SELECTED_FRAME () != f)
+ {
+ Lisp_Object frame;
+ XSETFRAME (frame, f);
+ record_unwind_protect (Fselect_frame, Fselected_frame ());
+ Fselect_frame (frame);
+ }
+ call1 (Vrun_hooks, Qwindow_configuration_change_hook);
+ unbind_to (count, Qnil);
+ }
+}
+
/* Make WINDOW display BUFFER as its contents. RUN_HOOKS_P non-zero
means it's allowed to run hooks. See make_frame for a case where
it's not allowed. KEEP_MARGINS_P non-zero means that the current
struct window *w = XWINDOW (window);
struct buffer *b = XBUFFER (buffer);
int count = SPECPDL_INDEX ();
+ int samebuf = EQ (buffer, w->buffer);
w->buffer = buffer;
XSETFASTINT (w->window_end_vpos, 0);
bzero (&w->last_cursor, sizeof w->last_cursor);
w->window_end_valid = Qnil;
- w->hscroll = w->min_hscroll = make_number (0);
- w->vscroll = 0;
- set_marker_both (w->pointm, buffer, BUF_PT (b), BUF_PT_BYTE (b));
- set_marker_restricted (w->start,
- make_number (b->last_window_start),
- buffer);
- w->start_at_line_beg = Qnil;
- w->force_start = Qnil;
- XSETFASTINT (w->last_modified, 0);
- XSETFASTINT (w->last_overlay_modified, 0);
+ if (!(keep_margins_p && samebuf))
+ { /* If we're not actually changing the buffer, Don't reset hscroll and
+ vscroll. This case happens for example when called from
+ change_frame_size_1, where we use a dummy call to
+ Fset_window_buffer on the frame's selected window (and no other)
+ just in order to run window-configuration-change-hook.
+ Resetting hscroll and vscroll here is problematic for things like
+ image-mode and doc-view-mode since it resets the image's position
+ whenever we resize the frame. */
+ w->hscroll = w->min_hscroll = make_number (0);
+ w->vscroll = 0;
+ set_marker_both (w->pointm, buffer, BUF_PT (b), BUF_PT_BYTE (b));
+ set_marker_restricted (w->start,
+ make_number (b->last_window_start),
+ buffer);
+ w->start_at_line_beg = Qnil;
+ w->force_start = Qnil;
+ XSETFASTINT (w->last_modified, 0);
+ XSETFASTINT (w->last_overlay_modified, 0);
+ }
+ /* Maybe we could move this into the `if' but it's not obviously safe and
+ I doubt it's worth the trouble. */
windows_or_buffers_changed++;
/* We must select BUFFER for running the window-scroll-functions.
if (! NILP (Vwindow_scroll_functions))
run_hook_with_args_2 (Qwindow_scroll_functions, window,
Fmarker_position (w->start));
-
- if (! NILP (Vwindow_configuration_change_hook)
- && ! NILP (Vrun_hooks))
- call1 (Vrun_hooks, Qwindow_configuration_change_hook);
+ run_window_configuration_change_hook (XFRAME (WINDOW_FRAME (w)));
}
unbind_to (count, Qnil);
if (EQ (window, selected_window))
return window;
+ sf = SELECTED_FRAME ();
+ if (XFRAME (WINDOW_FRAME (w)) != sf)
+ {
+ XFRAME (WINDOW_FRAME (w))->selected_window = window;
+ /* Use this rather than Fhandle_switch_frame
+ so that FRAME_FOCUS_FRAME is moved appropriately as we
+ move around in the state where a minibuffer in a separate
+ frame is active. */
+ Fselect_frame (WINDOW_FRAME (w));
+ /* Fselect_frame called us back so we've done all the work already. */
+ eassert (EQ (window, selected_window));
+ return window;
+ }
+ else
+ sf->selected_window = window;
+
/* Store the current buffer's actual point into the
old selected window. It belongs to that window,
and when the window is not selected, must be in the window. */
}
selected_window = window;
- sf = SELECTED_FRAME ();
- if (XFRAME (WINDOW_FRAME (w)) != sf)
- {
- XFRAME (WINDOW_FRAME (w))->selected_window = window;
- /* Use this rather than Fhandle_switch_frame
- so that FRAME_FOCUS_FRAME is moved appropriately as we
- move around in the state where a minibuffer in a separate
- frame is active. */
- Fselect_frame (WINDOW_FRAME (w));
- }
- else
- sf->selected_window = window;
if (NILP (norecord))
record_buffer (w->buffer);
if displaying the buffer causes two vertically adjacent windows to be
displayed. */)
(buffer, not_this_window, frame)
- register Lisp_Object buffer, not_this_window, frame;
+ Lisp_Object buffer, not_this_window, frame;
{
register Lisp_Object window, tem, swp;
struct frame *f;
|| !NILP (XWINDOW (FRAME_ROOT_WINDOW (f))->dedicated))
{
Lisp_Object frames;
+ struct gcpro gcpro1;
+ GCPRO1 (buffer);
frames = Qnil;
if (FRAME_MINIBUF_ONLY_P (f))
XSETFRAME (frames, last_nonminibuf_frame);
- /* Don't try to create a window if we would get an error. */
- if (split_height_threshold < window_min_height << 1)
- split_height_threshold = window_min_height << 1;
/* Note that both Fget_largest_window and Fget_lru_window
ignore minibuffers and dedicated windows.
else
window = Fget_largest_window (frames, Qt);
- /* If we got a tall enough full-width window that can be split,
- split it. */
+ /* If the largest window is tall enough, full-width, and either eligible
+ for splitting or the only window, split it. */
if (!NILP (window)
&& ! FRAME_NO_SPLIT_P (XFRAME (XWINDOW (window)->frame))
- && window_height (window) >= split_height_threshold
- && WINDOW_FULL_WIDTH_P (XWINDOW (window)))
- window = Fsplit_window (window, Qnil, Qnil);
+ && WINDOW_FULL_WIDTH_P (XWINDOW (window))
+ && (window_height (window) >= split_height_threshold
+ || (NILP (XWINDOW (window)->parent)))
+ && (window_height (window)
+ >= (2 * window_min_size_2 (XWINDOW (window), 0))))
+ window = call1 (Vsplit_window_preferred_function, window);
else
{
Lisp_Object upper, lower, other;
window = Fget_lru_window (frames, Qt);
- /* If the LRU window is selected, and big enough,
- and can be split, split it. */
+ /* If the LRU window is tall enough, and either eligible for
+ splitting and selected or the only window, split it. */
if (!NILP (window)
&& ! FRAME_NO_SPLIT_P (XFRAME (XWINDOW (window)->frame))
- && (EQ (window, selected_window)
- || EQ (XWINDOW (window)->parent, Qnil))
- && window_height (window) >= window_min_height << 1)
- window = Fsplit_window (window, Qnil, Qnil);
+ && ((EQ (window, selected_window)
+ && window_height (window) >= split_height_threshold)
+ || (NILP (XWINDOW (window)->parent)))
+ && (window_height (window)
+ >= (2 * window_min_size_2 (XWINDOW (window), 0))))
+ window = call1 (Vsplit_window_preferred_function, window);
else
window = Fget_lru_window (frames, Qnil);
/* If Fget_lru_window returned nil, try other approaches. */
0);
}
}
+ UNGCPRO;
}
else
window = Fget_lru_window (Qnil, Qnil);
if (NILP (horflag))
{
- if (size_int < window_min_height)
+ int window_safe_height = window_min_size_2 (o, 0);
+
+ if (size_int < window_safe_height)
error ("Window height %d too small (after splitting)", size_int);
- if (size_int + window_min_height > XFASTINT (o->total_lines))
+ if (size_int + window_safe_height > XFASTINT (o->total_lines))
error ("Window height %d too small (after splitting)",
XFASTINT (o->total_lines) - size_int);
if (NILP (o->parent)
}
else
{
- if (size_int < window_min_width)
+ int window_safe_width = window_min_size_2 (o, 1);
+
+ if (size_int < window_safe_width)
error ("Window width %d too small (after splitting)", size_int);
-
- if (size_int + window_min_width > XFASTINT (o->total_cols))
+ if (size_int + window_safe_width > XFASTINT (o->total_cols))
error ("Window width %d too small (after splitting)",
XFASTINT (o->total_cols) - size_int);
if (NILP (o->parent)
DEFUN ("shrink-window", Fshrink_window, Sshrink_window, 1, 2, "p",
doc: /* Make current window ARG lines smaller.
From program, optional second arg non-nil means shrink sideways arg columns.
-Interactively, if an argument is not given, make the window one line smaller. Only
-siblings to the right or below are changed. */)
+Interactively, if an argument is not given, make the window one line smaller.
+Only siblings to the right or below are changed. */)
(arg, side)
Lisp_Object arg, side;
{
/* Find the total we can get from other siblings without deleting them. */
maximum = 0;
- for (next = p->next; ! NILP (next); next = XWINDOW (next)->next)
+ for (next = p->next; WINDOWP (next); next = XWINDOW (next)->next)
maximum += (*sizefun) (next) - window_min_size (XWINDOW (next),
horiz_flag, 0, 0);
- for (prev = p->prev; ! NILP (prev); prev = XWINDOW (prev)->prev)
+ for (prev = p->prev; WINDOWP (prev); prev = XWINDOW (prev)->prev)
maximum += (*sizefun) (prev) - window_min_size (XWINDOW (prev),
horiz_flag, 0, 0);
Lisp_Object s;
int n = 1;
- for (s = w->next; !NILP (s); s = XWINDOW (s)->next)
+ for (s = w->next; WINDOWP (s); s = XWINDOW (s)->next)
if (!window_fixed_size_p (XWINDOW (s), horiz_flag, 0))
++n;
- for (s = w->prev; !NILP (s); s = XWINDOW (s)->prev)
+ for (s = w->prev; WINDOWP (s); s = XWINDOW (s)->prev)
if (!window_fixed_size_p (XWINDOW (s), horiz_flag, 0))
++n;
/* Don't make this window too small. */
if (XINT (CURSIZE (window)) + delta
- < (horiz_flag ? window_min_width : window_min_height))
+ < window_min_size_2 (XWINDOW (window), horiz_flag))
{
Fset_window_configuration (old_config);
error ("Cannot adjust window size as specified");
/* Find the last child. We are taking space from lowest windows
first, so we iterate over children from the last child
backwards. */
- for (child = w->vchild; !NILP (child); child = XWINDOW (child)->next)
+ for (child = w->vchild; WINDOWP (child); child = XWINDOW (child)->next)
last_child = child;
/* Assign new heights. We leave only MIN_SAFE_WINDOW_HEIGHT. */
{
int count = SPECPDL_INDEX ();
- xassert (abs (direction) == 1);
+ xassert (eabs (direction) == 1);
/* If selected window's buffer isn't current, make it current for
the moment. But don't screw up if window_scroll gets an error. */
struct save_window_data
{
- EMACS_INT size_from_Lisp_Vector_struct;
+ EMACS_UINT size;
struct Lisp_Vector *next_from_Lisp_Vector_struct;
- Lisp_Object frame_cols, frame_lines, frame_menu_bar_lines;
- Lisp_Object frame_tool_bar_lines;
Lisp_Object selected_frame;
Lisp_Object current_window;
Lisp_Object current_buffer;
Lisp_Object minibuf_selected_window;
Lisp_Object root_window;
Lisp_Object focus_frame;
- /* Record the values of window-min-width and window-min-height
- so that window sizes remain consistent with them. */
- Lisp_Object min_width, min_height;
/* A vector, each of whose elements is a struct saved_window
for one window. */
Lisp_Object saved_windows;
+
+ /* All fields above are traced by the GC.
+ From `fame-cols' down, the fields are ignored by the GC. */
+
+ int frame_cols, frame_lines, frame_menu_bar_lines;
+ int frame_tool_bar_lines;
+ /* Record the values of window-min-width and window-min-height
+ so that window sizes remain consistent with them. */
+ int min_width, min_height;
};
/* This is saved as a Lisp_Vector */
struct saved_window
{
/* these first two must agree with struct Lisp_Vector in lisp.h */
- EMACS_INT size_from_Lisp_Vector_struct;
+ EMACS_UINT size;
struct Lisp_Vector *next_from_Lisp_Vector_struct;
Lisp_Object window;
if it runs during this. */
BLOCK_INPUT;
- if (XFASTINT (data->frame_lines) != previous_frame_lines
- || XFASTINT (data->frame_cols) != previous_frame_cols)
- change_frame_size (f, XFASTINT (data->frame_lines),
- XFASTINT (data->frame_cols), 0, 0, 0);
+ if (data->frame_lines != previous_frame_lines
+ || data->frame_cols != previous_frame_cols)
+ change_frame_size (f, data->frame_lines,
+ data->frame_cols, 0, 0, 0);
#if defined (HAVE_WINDOW_SYSTEM) || defined (MSDOS)
- if (XFASTINT (data->frame_menu_bar_lines)
+ if (data->frame_menu_bar_lines
!= previous_frame_menu_bar_lines)
- x_set_menu_bar_lines (f, data->frame_menu_bar_lines, make_number (0));
+ x_set_menu_bar_lines (f, make_number (data->frame_menu_bar_lines),
+ make_number (0));
#ifdef HAVE_WINDOW_SYSTEM
- if (XFASTINT (data->frame_tool_bar_lines)
+ if (data->frame_tool_bar_lines
!= previous_frame_tool_bar_lines)
- x_set_tool_bar_lines (f, data->frame_tool_bar_lines, make_number (0));
+ x_set_tool_bar_lines (f, make_number (data->frame_tool_bar_lines),
+ make_number (0));
#endif
#endif
Fset_buffer (new_current_buffer);
/* Restore the minimum heights recorded in the configuration. */
- window_min_height = XINT (data->min_height);
- window_min_width = XINT (data->min_width);
+ window_min_height = data->min_height;
+ window_min_width = data->min_width;
Vminibuf_scroll_window = data->minibuf_scroll_window;
minibuf_selected_window = data->minibuf_selected_window;
register Lisp_Object tem;
register int n_windows;
register struct save_window_data *data;
- register struct Lisp_Vector *vec;
register int i;
FRAME_PTR f;
f = XFRAME (frame);
n_windows = count_windows (XWINDOW (FRAME_ROOT_WINDOW (f)));
- vec = allocate_other_vector (VECSIZE (struct save_window_data));
- data = (struct save_window_data *)vec;
+ data = ALLOCATE_PSEUDOVECTOR (struct save_window_data, frame_cols,
+ PVEC_WINDOW_CONFIGURATION);
- XSETFASTINT (data->frame_cols, FRAME_COLS (f));
- XSETFASTINT (data->frame_lines, FRAME_LINES (f));
- XSETFASTINT (data->frame_menu_bar_lines, FRAME_MENU_BAR_LINES (f));
- XSETFASTINT (data->frame_tool_bar_lines, FRAME_TOOL_BAR_LINES (f));
+ data->frame_cols = FRAME_COLS (f);
+ data->frame_lines = FRAME_LINES (f);
+ data->frame_menu_bar_lines = FRAME_MENU_BAR_LINES (f);
+ data->frame_tool_bar_lines = FRAME_TOOL_BAR_LINES (f);
data->selected_frame = selected_frame;
data->current_window = FRAME_SELECTED_WINDOW (f);
XSETBUFFER (data->current_buffer, current_buffer);
data->minibuf_selected_window = minibuf_level > 0 ? minibuf_selected_window : Qnil;
data->root_window = FRAME_ROOT_WINDOW (f);
data->focus_frame = FRAME_FOCUS_FRAME (f);
- XSETINT (data->min_height, window_min_height);
- XSETINT (data->min_width, window_min_width);
+ data->min_height = window_min_height;
+ data->min_width = window_min_width;
tem = Fmake_vector (make_number (n_windows), Qnil);
data->saved_windows = tem;
for (i = 0; i < n_windows; i++)
Also restore the choice of selected window.
Also restore which buffer is current.
Does not restore the value of point in current buffer.
-usage: (save-window-excursion BODY ...) */)
+usage: (save-window-excursion BODY...) */)
(args)
Lisp_Object args;
{
vertical_type = Qnil;
}
- if (!(EQ (vertical_type, Qnil)
+ if (!(NILP (vertical_type)
|| EQ (vertical_type, Qleft)
|| EQ (vertical_type, Qright)
|| EQ (vertical_type, Qt)))
struct window *w;
void *freeze_p;
{
- if (w == XWINDOW (selected_window)
- || MINI_WINDOW_P (w)
- || (MINI_WINDOW_P (XWINDOW (selected_window))
- && ! NILP (Vminibuf_scroll_window)
- && w == XWINDOW (Vminibuf_scroll_window)))
+ if (MINI_WINDOW_P (w)
+ || (WINDOWP (selected_window) /* Can be nil in corner cases. */
+ && (w == XWINDOW (selected_window)
+ || (MINI_WINDOW_P (XWINDOW (selected_window))
+ && ! NILP (Vminibuf_scroll_window)
+ && w == XWINDOW (Vminibuf_scroll_window)))))
freeze_p = NULL;
w->frozen_window_start_p = freeze_p != NULL;
sw1 = XVECTOR (d1->saved_windows);
sw2 = XVECTOR (d2->saved_windows);
- if (! EQ (d1->frame_cols, d2->frame_cols))
+ if (d1->frame_cols != d2->frame_cols)
return 0;
- if (! EQ (d1->frame_lines, d2->frame_lines))
+ if (d1->frame_lines != d2->frame_lines)
return 0;
- if (! EQ (d1->frame_menu_bar_lines, d2->frame_menu_bar_lines))
+ if (d1->frame_menu_bar_lines != d2->frame_menu_bar_lines)
return 0;
if (! EQ (d1->selected_frame, d2->selected_frame))
return 0;
if everything else compares equal. */
if (! EQ (d1->focus_frame, d2->focus_frame))
return 0;
- if (! EQ (d1->min_width, d2->min_width))
+ if (d1->min_width != d2->min_width)
return 0;
- if (! EQ (d1->min_height, d2->min_height))
+ if (d1->min_height != d2->min_height)
return 0;
/* Verify that the two confis have the same number of windows. */
If there is only one window, it is split regardless of this value. */);
split_height_threshold = 500;
+ DEFVAR_LISP ("split-window-preferred-function",
+ &Vsplit_window_preferred_function,
+ doc: /* Function to use to split a window.
+This is used by `display-buffer' to allow the user to choose whether
+to split windows horizontally or vertically or some mix of the two.
+It is called with a window as single argument and should split it in two
+and return the new window. */);
+ Vsplit_window_preferred_function = intern ("split-window");
+
DEFVAR_INT ("window-min-height", &window_min_height,
doc: /* *Delete any window less than this tall (including its mode line).
The value is in line units. */);
defsubr (&Swindow_buffer);
defsubr (&Swindow_height);
defsubr (&Swindow_width);
+ defsubr (&Swindow_full_width_p);
defsubr (&Swindow_hscroll);
defsubr (&Sset_window_hscroll);
defsubr (&Swindow_redisplay_end_trigger);