/* 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 Free Software Foundation, Inc.
+ 2001, 2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc.
This file is part of GNU Emacs.
Lisp_Object Qwindowp, Qwindow_live_p, Qwindow_configuration_p;
+Lisp_Object Qscroll_up, Qscroll_down;
Lisp_Object Qwindow_size_fixed;
extern Lisp_Object Qleft_margin, Qright_margin;
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 P_ ((struct window *, int, int, int *));
-static void size_window P_ ((Lisp_Object, int, int, int));
+static void size_window P_ ((Lisp_Object, int, int, int, int, int));
static int freeze_window_start P_ ((struct window *, void *));
static int window_fixed_size_p P_ ((struct window *, int, int));
-static void enlarge_window P_ ((Lisp_Object, int, int, int));
+static void enlarge_window P_ ((Lisp_Object, int, int));
static Lisp_Object window_list P_ ((void));
static int add_window_to_list P_ ((struct window *, void *));
static int candidate_window_p P_ ((Lisp_Object, Lisp_Object, Lisp_Object,
Lisp_Object Vscroll_preserve_screen_position;
+/* Incremented by 1 whenever a window is deleted. */
+
+int window_deletion_count;
+
+/* Used by the function window_scroll_pixel_based */
+
+static int window_scroll_pixel_based_preserve_y;
+
#if 0 /* This isn't used anywhere. */
/* Nonzero means we can split a frame even if it is "unsplittable". */
static int inhibit_frame_unsplittable;
If a character is only partially visible, nil is returned, unless the
optional argument PARTIALLY is non-nil.
If POS is only out of view because of horizontal scrolling, return non-nil.
+If POS is t, it specifies the position of the last visible glyph in WINDOW.
POS defaults to point in WINDOW; WINDOW defaults to the selected window.
If POS is visible, return t if PARTIALLY is nil; if PARTIALLY is non-nil,
-return value is a list (X Y PARTIAL) where X and Y are the pixel coordinates
-relative to the top left corner of the window. PARTIAL is nil if the character
-after POS is fully visible; otherwise it is a cons (RTOP . RBOT) where RTOP
-and RBOT are the number of pixels invisible at the top and bottom of the row. */)
+return value is a list of 2 or 6 elements (X Y [RTOP RBOT ROWH VPOS]),
+where X and Y are the pixel coordinates relative to the top left corner
+of the window. The remaining elements are omitted if the character after
+POS is fully visible; otherwise, RTOP and RBOT are the number of pixels
+off-window at the top and bottom of the row, ROWH is the height of the
+display row, and VPOS is the row number (0-based) containing POS. */)
(pos, window, partially)
Lisp_Object pos, window, partially;
{
register struct buffer *buf;
struct text_pos top;
Lisp_Object in_window = Qnil;
- int rtop, rbot, fully_p = 1;
+ int rtop, rbot, rowh, vpos, fully_p = 1;
int x, y;
w = decode_window (window);
buf = XBUFFER (w->buffer);
SET_TEXT_POS_FROM_MARKER (top, w->start);
- if (!NILP (pos))
+ if (EQ (pos, Qt))
+ posint = -1;
+ else if (!NILP (pos))
{
CHECK_NUMBER_COERCE_MARKER (pos);
posint = XINT (pos);
/* If position is above window start or outside buffer boundaries,
or if window start is out of range, position is not visible. */
- if (posint >= CHARPOS (top)
- && posint <= BUF_ZV (buf)
+ if ((EQ (pos, Qt)
+ || (posint >= CHARPOS (top) && posint <= BUF_ZV (buf)))
&& CHARPOS (top) >= BUF_BEGV (buf)
&& CHARPOS (top) <= BUF_ZV (buf)
- && pos_visible_p (w, posint, &x, &y, &rtop, &rbot, NILP (partially))
+ && pos_visible_p (w, posint, &x, &y, &rtop, &rbot, &rowh, &vpos)
&& (fully_p = !rtop && !rbot, (!NILP (partially) || fully_p)))
in_window = Qt;
if (!NILP (in_window) && !NILP (partially))
- in_window = Fcons (make_number (x),
- Fcons (make_number (y),
- Fcons ((fully_p ? Qnil
- : Fcons (make_number (rtop),
- make_number (rbot))),
- Qnil)));
+ {
+ Lisp_Object part = Qnil;
+ if (!fully_p)
+ part = list4 (make_number (rtop), make_number (rbot),
+ make_number (rowh), make_number (vpos));
+ in_window = Fcons (make_number (x),
+ Fcons (make_number (y), part));
+ }
+
return in_window;
}
+DEFUN ("window-line-height", Fwindow_line_height,
+ Swindow_line_height, 0, 2, 0,
+ doc: /* Return height in pixels of text line LINE in window WINDOW.
+If WINDOW is nil or omitted, use selected window.
+
+Return height of current line if LINE is omitted or nil. Return height of
+header or mode line if LINE is `header-line' and `mode-line'.
+Otherwise, LINE is a text line number starting from 0. A negative number
+counts from the end of the window.
+
+Value is a list (HEIGHT VPOS YPOS OFFBOT), where HEIGHT is the height
+in pixels of the visible part of the line, VPOS and YPOS are the
+vertical position in lines and pixels of the row, relative to the top
+of the first text line, and OFFBOT is the number of off-window pixels at
+the bottom of the text row. If there are off-window pixels at the top
+of the (first) text row, YPOS is negative.
+
+Return nil if window display is not up-to-date. In that case, use
+`pos-visible-in-window-p' to obtain the information. */)
+ (line, window)
+ Lisp_Object line, window;
+{
+ register struct window *w;
+ register struct buffer *b;
+ struct glyph_row *row, *end_row;
+ int max_y, crop, i, n;
+
+ w = decode_window (window);
+
+ if (noninteractive
+ || w->pseudo_window_p)
+ return Qnil;
+
+ CHECK_BUFFER (w->buffer);
+ b = XBUFFER (w->buffer);
+
+ /* Fail if current matrix is not up-to-date. */
+ if (NILP (w->window_end_valid)
+ || current_buffer->clip_changed
+ || current_buffer->prevent_redisplay_optimizations_p
+ || XFASTINT (w->last_modified) < BUF_MODIFF (b)
+ || XFASTINT (w->last_overlay_modified) < BUF_OVERLAY_MODIFF (b))
+ return Qnil;
+
+ if (NILP (line))
+ {
+ i = w->cursor.vpos;
+ if (i < 0 || i >= w->current_matrix->nrows
+ || (row = MATRIX_ROW (w->current_matrix, i), !row->enabled_p))
+ return Qnil;
+ max_y = window_text_bottom_y (w);
+ goto found_row;
+ }
+
+ if (EQ (line, Qheader_line))
+ {
+ if (!WINDOW_WANTS_HEADER_LINE_P (w))
+ return Qnil;
+ row = MATRIX_HEADER_LINE_ROW (w->current_matrix);
+ if (!row->enabled_p)
+ return Qnil;
+ return list4 (make_number (row->height),
+ make_number (0), make_number (0),
+ make_number (0));
+ }
+
+ if (EQ (line, Qmode_line))
+ {
+ row = MATRIX_MODE_LINE_ROW (w->current_matrix);
+ if (!row->enabled_p)
+ return Qnil;
+ return list4 (make_number (row->height),
+ make_number (0), /* not accurate */
+ make_number (WINDOW_HEADER_LINE_HEIGHT (w)
+ + window_text_bottom_y (w)),
+ make_number (0));
+ }
+
+ CHECK_NUMBER (line);
+ n = XINT (line);
+
+ row = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
+ end_row = MATRIX_BOTTOM_TEXT_ROW (w->current_matrix, w);
+ max_y = window_text_bottom_y (w);
+ i = 0;
+
+ while ((n < 0 || i < n)
+ && row <= end_row && row->enabled_p
+ && row->y + row->height < max_y)
+ row++, i++;
+
+ if (row > end_row || !row->enabled_p)
+ return Qnil;
+
+ if (++n < 0)
+ {
+ if (-n > i)
+ return Qnil;
+ row += n;
+ i += n;
+ }
+
+ found_row:
+ crop = max (0, (row->y + row->height) - max_y);
+ return list4 (make_number (row->height + min (0, row->y) - crop),
+ make_number (i),
+ make_number (row->y),
+ make_number (crop));
+}
+
+
\f
static struct window *
decode_window (window)
Return NCOL. NCOL should be zero or positive.
Note that if `automatic-hscrolling' is non-nil, you cannot scroll the
-window so that the location of point becomes invisible. */)
+window so that the location of point moves off-window. */)
(window, ncol)
Lisp_Object window, ncol;
{
|| WINDOW_RIGHTMOST_P (w))
{
if (!WINDOW_LEFTMOST_P (w) && abs (*x - x0) < grabbable_width)
- return ON_VERTICAL_BORDER;
+ {
+ /* Convert X and Y to window relative coordinates.
+ Vertical border is at the left edge of window. */
+ *x = max (0, *x - x0);
+ *y -= top_y;
+ return ON_VERTICAL_BORDER;
+ }
}
else
{
if (abs (*x - x1) < grabbable_width)
- return ON_VERTICAL_BORDER;
+ {
+ /* Convert X and Y to window relative coordinates.
+ Vertical border is at the right edge of window. */
+ *x = min (x1, *x) - x0;
+ *y -= top_y;
+ return ON_VERTICAL_BORDER;
+ }
}
if (*x < x0 || *x >= x1)
&& !WINDOW_HAS_VERTICAL_SCROLL_BAR (w)
&& !WINDOW_RIGHTMOST_P (w)
&& (abs (*x - right_x) < grabbable_width))
- return ON_VERTICAL_BORDER;
+ {
+ /* Convert X and Y to window relative coordinates.
+ Vertical border is at the right edge of window. */
+ *x = min (right_x, *x) - left_x;
+ *y -= top_y;
+ return ON_VERTICAL_BORDER;
+ }
}
else
{
{
/* On the border on the right side of the window? Assume that
this area begins at RIGHT_X minus a canonical char width. */
+ *x = min (right_x, *x) - left_x;
+ *y -= top_y;
return ON_VERTICAL_BORDER;
}
}
Lisp_Object value;
struct window *w = decode_window (window);
Lisp_Object buf;
+ struct buffer *b;
buf = w->buffer;
CHECK_BUFFER (buf);
+ b = XBUFFER (buf);
#if 0 /* This change broke some things. We should make it later. */
/* If we don't know the end position, return nil.
if (! NILP (update)
&& ! (! NILP (w->window_end_valid)
- && XFASTINT (w->last_modified) >= MODIFF)
+ && XFASTINT (w->last_modified) >= BUF_MODIFF (b))
&& !noninteractive)
{
struct text_pos startp;
struct it it;
- struct buffer *old_buffer = NULL, *b = XBUFFER (buf);
+ struct buffer *old_buffer = NULL;
+
+ /* Cannot use Fvertical_motion because that function doesn't
+ cope with variable-height lines. */
+ if (b != current_buffer)
+ {
+ old_buffer = current_buffer;
+ set_buffer_internal (b);
+ }
/* In case W->start is out of the range, use something
reasonable. This situation occurred when loading a file with
else
SET_TEXT_POS_FROM_MARKER (startp, w->start);
- /* Cannot use Fvertical_motion because that function doesn't
- cope with variable-height lines. */
- if (b != current_buffer)
- {
- old_buffer = current_buffer;
- set_buffer_internal (b);
- }
-
start_display (&it, w, startp);
move_it_vertically (&it, window_box_height (w));
if (it.current_y < it.last_visible_y)
set_buffer_internal (old_buffer);
}
else
- XSETINT (value, BUF_Z (XBUFFER (buf)) - XFASTINT (w->window_end_pos));
+ XSETINT (value, BUF_Z (b) - XFASTINT (w->window_end_pos));
return value;
}
CHECK_WINDOW (window);
p = XWINDOW (window);
- /* It's okay to delete an already-deleted window. */
+ /* It's a no-op to delete an already-deleted window. */
if (NILP (p->buffer)
&& NILP (p->hchild)
&& NILP (p->vchild))
}
}
+ /* Now we know we can delete this one. */
+ window_deletion_count++;
+
tem = p->buffer;
/* tem is null for dummy parent windows
(which have inferiors but not any contents themselves) */
All windows on current frame are arranged in a cyclic order.
This command selects the window ARG steps away in that order.
A negative ARG moves in the opposite order. The optional second
-argument ALL_FRAMES has the same meaning as in `next-window', which see. */)
+argument ALL-FRAMES has the same meaning as in `next-window', which see. */)
(arg, all_frames)
Lisp_Object arg, all_frames;
{
Lisp_Object frame, minibuf, window;
{
if (NILP (window))
- window = selected_window;
+ window = FRAMEP (frame) ? XFRAME (frame)->selected_window : selected_window;
+ CHECK_WINDOW (window);
if (NILP (frame))
frame = selected_frame;
GCPRO1 (windows);
best_window = Qnil;
- for (; CONSP (windows); windows = CDR (windows))
+ for (; CONSP (windows); windows = XCDR (windows))
{
struct window *w;
break;
case GET_LRU_WINDOW:
- /* t as arg means consider only full-width windows */
- if (!NILP (obj) && !WINDOW_FULL_WIDTH_P (w))
- break;
- /* Ignore dedicated windows and minibuffers. */
- if (MINI_WINDOW_P (w) || (!mini && EQ (w->dedicated, Qt)))
+ /* `obj' is an integer encoding a bitvector.
+ `obj & 1' means consider only full-width windows.
+ `obj & 2' means consider also dedicated windows. */
+ if (((XINT (obj) & 1) && !WINDOW_FULL_WIDTH_P (w))
+ || (!(XINT (obj) & 2) && !NILP (w->dedicated))
+ /* Minibuffer windows are always ignored. */
+ || MINI_WINDOW_P (w))
break;
if (NILP (best_window)
|| (XFASTINT (XWINDOW (best_window)->use_time)
break;
case GET_LARGEST_WINDOW:
- {
+ { /* nil `obj' means to ignore dedicated windows. */
/* Ignore dedicated windows and minibuffers. */
- if (MINI_WINDOW_P (w) || (!mini && EQ (w->dedicated, Qt)))
+ if (MINI_WINDOW_P (w) || (NILP (obj) && !NILP (w->dedicated)))
break;
if (NILP (best_window))
{
register Lisp_Object w;
/* First try for a window that is full-width */
- w = window_loop (GET_LRU_WINDOW, Qt, !NILP (dedicated), frame);
+ w = window_loop (GET_LRU_WINDOW,
+ NILP (dedicated) ? make_number (1) : make_number (3),
+ 0, frame);
if (!NILP (w) && !EQ (w, selected_window))
return w;
/* If none of them, try the rest */
- return window_loop (GET_LRU_WINDOW, Qnil, !NILP (dedicated), frame);
+ return window_loop (GET_LRU_WINDOW,
+ NILP (dedicated) ? make_number (0) : make_number (2),
+ 0, frame);
}
DEFUN ("get-largest-window", Fget_largest_window, Sget_largest_window, 0, 2, 0,
(frame, dedicated)
Lisp_Object frame, dedicated;
{
- return window_loop (GET_LARGEST_WINDOW, Qnil, !NILP (dedicated),
+ return window_loop (GET_LARGEST_WINDOW, dedicated, 0,
frame);
}
else
{
if (width_p)
- size = window_min_width;
+ size = max (window_min_width,
+ (MIN_SAFE_WINDOW_WIDTH
+ + WINDOW_FRINGE_COLS (w)
+ + WINDOW_SCROLL_BAR_COLS (w)));
else
{
if (MINI_WINDOW_P (w)
/* Set WINDOW's height or width to SIZE. WIDTH_P non-zero means set
WINDOW's width. Resize WINDOW's children, if any, so that they
- keep their proportionate size relative to WINDOW. Propagate
- WINDOW's top or left edge position to children. Delete windows
- that become too small unless NODELETE_P is non-zero.
+ keep their proportionate size relative to WINDOW.
+
+ If FIRST_ONLY is 1, change only the first of WINDOW's children when
+ they are in series. If LAST_ONLY is 1, change only the last of
+ WINDOW's children when they are in series.
+
+ Propagate WINDOW's top or left edge position to children. Delete
+ windows that become too small unless NODELETE_P is non-zero.
If NODELETE_P is 2, that means we do delete windows that are
too small, even if they were too small before! */
static void
-size_window (window, size, width_p, nodelete_p)
+size_window (window, size, width_p, nodelete_p, first_only, last_only)
Lisp_Object window;
int size, width_p, nodelete_p;
+ int first_only, last_only;
{
struct window *w = XWINDOW (window);
struct window *c;
if (!NILP (*sideward))
{
+ /* We have a chain of parallel siblings whose size should all change. */
for (child = *sideward; !NILP (child); child = c->next)
{
c = XWINDOW (child);
c->left_col = w->left_col;
else
c->top_line = w->top_line;
- size_window (child, size, width_p, nodelete_p);
+ size_window (child, size, width_p, nodelete_p,
+ first_only, last_only);
}
}
+ else if (!NILP (*forward) && last_only)
+ {
+ /* Change the last in a series of siblings. */
+ Lisp_Object last_child;
+ int child_size;
+
+ for (child = *forward; !NILP (child); child = c->next)
+ {
+ c = XWINDOW (child);
+ last_child = child;
+ }
+
+ child_size = XINT (width_p ? c->total_cols : c->total_lines);
+ size_window (last_child,
+ size - old_size + child_size,
+ width_p, nodelete_p, first_only, last_only);
+ }
+ else if (!NILP (*forward) && first_only)
+ {
+ /* Change the first in a series of siblings. */
+ int child_size;
+
+ child = *forward;
+ c = XWINDOW (child);
+
+ if (width_p)
+ c->left_col = w->left_col;
+ else
+ c->top_line = w->top_line;
+
+ child_size = XINT (width_p ? c->total_cols : c->total_lines);
+ size_window (child,
+ size - old_size + child_size,
+ width_p, nodelete_p, first_only, last_only);
+ }
else if (!NILP (*forward))
{
int fixed_size, each, extra, n;
int last_pos, first_pos, nchildren, total;
int *new_sizes = NULL;
- /* Determine the fixed-size portion of the this window, and the
+ /* Determine the fixed-size portion of this window, and the
number of child windows. */
fixed_size = nchildren = nfixed = total = 0;
for (child = *forward; !NILP (child); child = c->next, ++nchildren)
/* Set new height. Note that size_window also propagates
edge positions to children, so it's not a no-op if we
didn't change the child's size. */
- size_window (child, new_size, width_p, 1);
+ size_window (child, new_size, width_p, 1, first_only, last_only);
/* Remember the bottom/right edge position of this child; it
will be used to set the top/left edge of the next child. */
int child_size;
c = XWINDOW (child);
child_size = width_p ? XINT (c->total_cols) : XINT (c->total_lines);
- size_window (child, child_size, width_p, 2);
+ size_window (child, child_size, width_p, 2, first_only, last_only);
}
}
}
int height;
int nodelete;
{
- size_window (window, height, 0, nodelete);
+ size_window (window, height, 0, nodelete, 0, 0);
}
int width;
int nodelete;
{
- size_window (window, width, 1, nodelete);
+ size_window (window, width, 1, nodelete, 0, 0);
}
/* Change window heights in windows rooted in WINDOW by N lines. */
The variables `special-display-buffer-names',
`special-display-regexps', `same-window-buffer-names', and
`same-window-regexps' customize how certain buffer names are handled.
-The latter two take effect only if NOT-THIS-WINDOW is t.
+The latter two take effect only if NOT-THIS-WINDOW is nil.
If optional argument FRAME is `visible', search all visible frames.
If FRAME is 0, search all visible and iconified frames.
+ XFASTINT (XWINDOW (window)->total_lines));
enlarge_window (upper,
total / 2 - XFASTINT (XWINDOW (upper)->total_lines),
- 0, 0);
+ 0);
}
}
}
DEFUN ("force-window-update", Fforce_window_update, Sforce_window_update,
0, 1, 0,
- doc: /* Force redisplay of all windows.
+ doc: /* Force all windows to be updated on next redisplay.
If optional arg OBJECT is a window, force redisplay of that window only.
If OBJECT is a buffer or buffer name, force redisplay of all windows
displaying that buffer. */)
#endif
set_buffer_internal (old);
- if (!EQ (Vtemp_buffer_show_function, Qnil))
+ if (!NILP (Vtemp_buffer_show_function))
call1 (Vtemp_buffer_show_function, buf);
else
{
Interactively, all arguments are nil.
Returns the newly created window (which is the lower or rightmost one).
-The upper or leftmost window is the original one and remains selected.
+The upper or leftmost window is the original one, and remains selected
+if it was selected before.
+
See Info node `(elisp)Splitting Windows' for more details and examples.*/)
(window, size, horflag)
Lisp_Object window, size, horflag;
return new;
}
\f
-DEFUN ("enlarge-window", Fenlarge_window, Senlarge_window, 1, 3, "p",
+DEFUN ("enlarge-window", Fenlarge_window, Senlarge_window, 1, 2, "p",
doc: /* Make current window ARG lines bigger.
From program, optional second arg non-nil means grow sideways ARG columns.
Interactively, if an argument is not given, make the window one line bigger.
-
-Optional third arg PRESERVE-BEFORE, if non-nil, means do not change the size
-of the siblings above or to the left of the selected window. Only
-siblings to the right or below are changed. */)
- (arg, side, preserve_before)
- register Lisp_Object arg, side, preserve_before;
+If HORIZONTAL is non-nil, enlarge horizontally instead of vertically.
+This function can delete windows, even the second window, if they get
+too small. */)
+ (arg, horizontal)
+ Lisp_Object arg, horizontal;
{
CHECK_NUMBER (arg);
- enlarge_window (selected_window, XINT (arg), !NILP (side),
- !NILP (preserve_before));
+ enlarge_window (selected_window, XINT (arg), !NILP (horizontal));
if (! NILP (Vwindow_configuration_change_hook))
call1 (Vrun_hooks, Qwindow_configuration_change_hook);
return Qnil;
}
-DEFUN ("shrink-window", Fshrink_window, Sshrink_window, 1, 3, "p",
+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.
-
-Optional third arg PRESERVE-BEFORE, if non-nil, means do not change the size
-of the siblings above or to the left of the selected window. Only
+Interactively, if an argument is not given, make the window one line smaller. Only
siblings to the right or below are changed. */)
- (arg, side, preserve_before)
- register Lisp_Object arg, side, preserve_before;
+ (arg, side)
+ Lisp_Object arg, side;
{
CHECK_NUMBER (arg);
- enlarge_window (selected_window, -XINT (arg), !NILP (side),
- !NILP (preserve_before));
+ enlarge_window (selected_window, -XINT (arg), !NILP (side));
if (! NILP (Vwindow_configuration_change_hook))
call1 (Vrun_hooks, Qwindow_configuration_change_hook);
#define CURBEG(w) \
- *(widthflag ? &(XWINDOW (w)->left_col) : &(XWINDOW (w)->top_line))
+ *(horiz_flag ? &(XWINDOW (w)->left_col) : &(XWINDOW (w)->top_line))
#define CURSIZE(w) \
- *(widthflag ? &(XWINDOW (w)->total_cols) : &(XWINDOW (w)->total_lines))
+ *(horiz_flag ? &(XWINDOW (w)->total_cols) : &(XWINDOW (w)->total_lines))
-/* Enlarge WINDOW by DELTA. WIDTHFLAG non-zero means
- increase its width. Siblings of the selected window are resized to
- fulfill the size request. If they become too small in the process,
- they will be deleted.
+/* Enlarge WINDOW by DELTA.
+ HORIZ_FLAG nonzero means enlarge it horizontally;
+ zero means do it vertically.
- If PRESERVE_BEFORE is nonzero, that means don't alter
- the siblings to the left or above WINDOW. */
+ Siblings of the selected window are resized to fulfill the size
+ request. If they become too small in the process, they will be
+ deleted. */
static void
-enlarge_window (window, delta, widthflag, preserve_before)
+enlarge_window (window, delta, horiz_flag)
Lisp_Object window;
- int delta, widthflag, preserve_before;
+ int delta, horiz_flag;
{
Lisp_Object parent, next, prev;
struct window *p;
Lisp_Object *sizep;
int maximum;
int (*sizefun) P_ ((Lisp_Object))
- = widthflag ? window_width : window_height;
+ = horiz_flag ? window_width : window_height;
void (*setsizefun) P_ ((Lisp_Object, int, int))
- = (widthflag ? set_window_width : set_window_height);
+ = (horiz_flag ? set_window_width : set_window_height);
/* Check values of window_min_width and window_min_height for
validity. */
check_min_window_sizes ();
/* Give up if this window cannot be resized. */
- if (window_fixed_size_p (XWINDOW (window), widthflag, 1))
+ if (window_fixed_size_p (XWINDOW (window), horiz_flag, 1))
error ("Window is not resizable");
/* Find the parent of the selected window. */
if (NILP (parent))
{
- if (widthflag)
+ if (horiz_flag)
error ("No other window to side of this one");
break;
}
- if (widthflag
+ if (horiz_flag
? !NILP (XWINDOW (parent)->hchild)
: !NILP (XWINDOW (parent)->vchild))
break;
/* Compute the maximum size increment this window can have. */
- if (preserve_before)
- {
- if (!NILP (parent))
- {
- maxdelta = (*sizefun) (parent) - XINT (*sizep);
- /* Subtract size of siblings before, since we can't take that. */
- maxdelta -= XINT (CURBEG (window)) - XINT (CURBEG (parent));
- }
- else
- maxdelta = (!NILP (p->next) ? ((*sizefun) (p->next)
- - window_min_size (XWINDOW (p->next),
- widthflag, 0, 0))
- : (delta = 0));
- }
- else
- maxdelta = (!NILP (parent) ? (*sizefun) (parent) - XINT (*sizep)
- /* This is a main window followed by a minibuffer. */
- : !NILP (p->next) ? ((*sizefun) (p->next)
- - window_min_size (XWINDOW (p->next),
- widthflag, 0, 0))
- /* This is a minibuffer following a main window. */
- : !NILP (p->prev) ? ((*sizefun) (p->prev)
- - window_min_size (XWINDOW (p->prev),
- widthflag, 0, 0))
- /* This is a frame with only one window, a minibuffer-only
- or a minibufferless frame. */
- : (delta = 0));
+ maxdelta = (!NILP (parent) ? (*sizefun) (parent) - XINT (*sizep)
+ /* This is a main window followed by a minibuffer. */
+ : !NILP (p->next) ? ((*sizefun) (p->next)
+ - window_min_size (XWINDOW (p->next),
+ horiz_flag, 0, 0))
+ /* This is a minibuffer following a main window. */
+ : !NILP (p->prev) ? ((*sizefun) (p->prev)
+ - window_min_size (XWINDOW (p->prev),
+ horiz_flag, 0, 0))
+ /* This is a frame with only one window, a minibuffer-only
+ or a minibufferless frame. */
+ : (delta = 0));
if (delta > maxdelta)
/* This case traps trying to make the minibuffer
delta = maxdelta;
}
- if (XINT (*sizep) + delta < window_min_size (XWINDOW (window), widthflag, 0, 0))
+ if (XINT (*sizep) + delta < window_min_size (XWINDOW (window), horiz_flag, 0, 0))
{
delete_window (window);
return;
maximum = 0;
for (next = p->next; ! NILP (next); next = XWINDOW (next)->next)
maximum += (*sizefun) (next) - window_min_size (XWINDOW (next),
- widthflag, 0, 0);
- if (! preserve_before)
- for (prev = p->prev; ! NILP (prev); prev = XWINDOW (prev)->prev)
- maximum += (*sizefun) (prev) - window_min_size (XWINDOW (prev),
- widthflag, 0, 0);
+ horiz_flag, 0, 0);
+ for (prev = p->prev; ! NILP (prev); prev = XWINDOW (prev)->prev)
+ maximum += (*sizefun) (prev) - window_min_size (XWINDOW (prev),
+ horiz_flag, 0, 0);
/* If we can get it all from them without deleting them, do so. */
if (delta <= maximum)
moving away from this window in both directions alternately,
and take as much as we can get without deleting that sibling. */
while (delta != 0
- && (!NILP (next) || (!preserve_before && !NILP (prev))))
+ && (!NILP (next) || !NILP (prev)))
{
if (! NILP (next))
{
int this_one = ((*sizefun) (next)
- window_min_size (XWINDOW (next),
- widthflag, 0, &fixed_p));
+ horiz_flag, 0, &fixed_p));
if (!fixed_p)
{
if (this_one > delta)
if (delta == 0)
break;
- if (!preserve_before && ! NILP (prev))
+ if (! NILP (prev))
{
int this_one = ((*sizefun) (prev)
- window_min_size (XWINDOW (prev),
- widthflag, 0, &fixed_p));
+ horiz_flag, 0, &fixed_p));
if (!fixed_p)
{
if (this_one > delta)
int n = 1;
for (s = w->next; !NILP (s); s = XWINDOW (s)->next)
- if (!window_fixed_size_p (XWINDOW (s), widthflag, 0))
+ if (!window_fixed_size_p (XWINDOW (s), horiz_flag, 0))
++n;
for (s = w->prev; !NILP (s); s = XWINDOW (s)->prev)
- if (!window_fixed_size_p (XWINDOW (s), widthflag, 0))
+ if (!window_fixed_size_p (XWINDOW (s), horiz_flag, 0))
++n;
delta1 = n * delta;
adjust_glyphs (XFRAME (WINDOW_FRAME (XWINDOW (window))));
}
+
+/* Adjust the size of WINDOW by DELTA, moving only its trailing edge.
+ HORIZ_FLAG nonzero means adjust the width, moving the right edge.
+ zero means adjust the height, moving the bottom edge.
+
+ Following siblings of the selected window are resized to fulfill
+ the size request. If they become too small in the process, they
+ are not deleted; instead, we signal an error. */
+
+static void
+adjust_window_trailing_edge (window, delta, horiz_flag)
+ Lisp_Object window;
+ int delta, horiz_flag;
+{
+ Lisp_Object parent, child;
+ struct window *p;
+ Lisp_Object old_config = Fcurrent_window_configuration (Qnil);
+ int delcount = window_deletion_count;
+
+ /* Check values of window_min_width and window_min_height for
+ validity. */
+ check_min_window_sizes ();
+
+ if (NILP (window))
+ window = Fselected_window ();
+
+ CHECK_WINDOW (window);
+
+ /* Give up if this window cannot be resized. */
+ if (window_fixed_size_p (XWINDOW (window), horiz_flag, 1))
+ error ("Window is not resizable");
+
+ while (1)
+ {
+ Lisp_Object first_parallel = Qnil;
+
+ if (NILP (window))
+ {
+ /* This happens if WINDOW on the previous iteration was
+ at top level of the window tree. */
+ Fset_window_configuration (old_config);
+ error ("Specified window edge is fixed");
+ }
+
+ p = XWINDOW (window);
+ parent = p->parent;
+
+ /* See if this level has windows in parallel in the specified
+ direction. If so, set FIRST_PARALLEL to the first one. */
+ if (horiz_flag)
+ {
+ if (! NILP (parent) && !NILP (XWINDOW (parent)->vchild))
+ first_parallel = XWINDOW (parent)->vchild;
+ else if (NILP (parent) && !NILP (p->next))
+ {
+ /* Handle the vertical chain of main window and minibuffer
+ which has no parent. */
+ first_parallel = window;
+ while (! NILP (XWINDOW (first_parallel)->prev))
+ first_parallel = XWINDOW (first_parallel)->prev;
+ }
+ }
+ else
+ {
+ if (! NILP (parent) && !NILP (XWINDOW (parent)->hchild))
+ first_parallel = XWINDOW (parent)->hchild;
+ }
+
+ /* If this level's succession is in the desired dimension,
+ and this window is the last one, and there is no higher level,
+ its trailing edge is fixed. */
+ if (NILP (XWINDOW (window)->next) && NILP (first_parallel)
+ && NILP (parent))
+ {
+ Fset_window_configuration (old_config);
+ error ("Specified window edge is fixed");
+ }
+
+ /* Don't make this window too small. */
+ if (XINT (CURSIZE (window)) + delta
+ < (horiz_flag ? window_min_width : window_min_height))
+ {
+ Fset_window_configuration (old_config);
+ error ("Cannot adjust window size as specified");
+ }
+
+ /* Clear out some redisplay caches. */
+ XSETFASTINT (p->last_modified, 0);
+ XSETFASTINT (p->last_overlay_modified, 0);
+
+ /* Adjust this window's edge. */
+ XSETINT (CURSIZE (window),
+ XINT (CURSIZE (window)) + delta);
+
+ /* If this window has following siblings in the desired dimension,
+ make them smaller, and exit the loop.
+
+ (If we reach the top of the tree and can never do this,
+ we will fail and report an error, above.) */
+ if (NILP (first_parallel))
+ {
+ if (!NILP (p->next))
+ {
+ /* This may happen for the minibuffer. In that case
+ the window_deletion_count check below does not work. */
+ if (XINT (CURSIZE (p->next)) - delta <= 0)
+ {
+ Fset_window_configuration (old_config);
+ error ("Cannot adjust window size as specified");
+ }
+
+ XSETINT (CURBEG (p->next),
+ XINT (CURBEG (p->next)) + delta);
+ size_window (p->next, XINT (CURSIZE (p->next)) - delta,
+ horiz_flag, 0, 1, 0);
+ break;
+ }
+ }
+ else
+ /* Here we have a chain of parallel siblings, in the other dimension.
+ Change the size of the other siblings. */
+ for (child = first_parallel;
+ ! NILP (child);
+ child = XWINDOW (child)->next)
+ if (! EQ (child, window))
+ size_window (child, XINT (CURSIZE (child)) + delta,
+ horiz_flag, 0, 0, 1);
+
+ window = parent;
+ }
+
+ /* If we made a window so small it got deleted,
+ we failed. Report failure. */
+ if (delcount != window_deletion_count)
+ {
+ Fset_window_configuration (old_config);
+ error ("Cannot adjust window size as specified");
+ }
+
+ /* Adjust glyph matrices. */
+ adjust_glyphs (XFRAME (WINDOW_FRAME (XWINDOW (window))));
+}
+
#undef CURBEG
#undef CURSIZE
+DEFUN ("adjust-window-trailing-edge", Fadjust_window_trailing_edge,
+ Sadjust_window_trailing_edge, 3, 3, 0,
+ doc: /* Adjust the bottom or right edge of WINDOW by DELTA.
+If HORIZONTAL is non-nil, that means adjust the width, moving the right edge.
+Otherwise, adjust the height, moving the bottom edge.
+
+Following siblings of the selected window are resized to fulfill
+the size request. If they become too small in the process, they
+are not deleted; instead, we signal an error. */)
+ (window, delta, horizontal)
+ Lisp_Object window, delta, horizontal;
+{
+ CHECK_NUMBER (delta);
+ adjust_window_trailing_edge (window, XINT (delta), !NILP (horizontal));
+
+ if (! NILP (Vwindow_configuration_change_hook))
+ call1 (Vrun_hooks, Qwindow_configuration_change_hook);
+
+ return Qnil;
+}
+
\f
/***********************************************************************
among the other windows. */
Lisp_Object window;
XSETWINDOW (window, w);
- enlarge_window (window, 1 - XFASTINT (w->total_lines), 0, 0);
+ enlarge_window (window, 1 - XFASTINT (w->total_lines), 0);
}
}
struct it it;
struct window *w = XWINDOW (window);
struct text_pos start;
- Lisp_Object tem;
int this_scroll_margin;
- int preserve_y;
/* True if we fiddled the window vscroll field without really scrolling. */
int vscrolled = 0;
+ int x, y, rtop, rbot, rowh, vpos;
SET_TEXT_POS_FROM_MARKER (start, w->start);
the screen. Allow PT to be partially visible, otherwise
something like (scroll-down 1) with PT in the line before
the partially visible one would recenter. */
- tem = Fpos_visible_in_window_p (make_number (PT), window, Qt);
- if (NILP (tem))
+
+ if (!pos_visible_p (w, PT, &x, &y, &rtop, &rbot, &rowh, &vpos))
{
/* Move backward half the height of the window. Performance note:
vmotion used here is about 10% faster, but would give wrong
}
else if (auto_window_vscroll_p)
{
- if (tem = XCAR (XCDR (XCDR (tem))), CONSP (tem))
+ if (rtop || rbot) /* partially visible */
{
int px;
int dy = WINDOW_FRAME_LINE_HEIGHT (w);
dy);
dy *= n;
- if (n < 0 && (px = XINT (XCAR (tem))) > 0)
+ if (n < 0)
{
- px = max (0, -w->vscroll - min (px, -dy));
- Fset_window_vscroll (window, make_number (px), Qt);
- return;
+ /* Only vscroll backwards if already vscrolled forwards. */
+ if (w->vscroll < 0 && rtop > 0)
+ {
+ px = max (0, -w->vscroll - min (rtop, -dy));
+ Fset_window_vscroll (window, make_number (px), Qt);
+ return;
+ }
}
- if (n > 0 && (px = XINT (XCDR (tem))) > 0)
+ if (n > 0)
{
- px = max (0, -w->vscroll + min (px, dy));
- Fset_window_vscroll (window, make_number (px), Qt);
- return;
+ /* Do vscroll if already vscrolled or only display line. */
+ if (rbot > 0 && (w->vscroll < 0 || vpos == 0))
+ {
+ px = max (0, -w->vscroll + min (rbot, dy));
+ Fset_window_vscroll (window, make_number (px), Qt);
+ return;
+ }
+
+ /* Maybe modify window start instead of scrolling. */
+ if (rbot > 0 || w->vscroll < 0)
+ {
+ int spos;
+
+ Fset_window_vscroll (window, make_number (0), Qt);
+ /* If there are other text lines above the current row,
+ move window start to current row. Else to next row. */
+ if (rbot > 0)
+ spos = XINT (Fline_beginning_position (Qnil));
+ else
+ spos = min (XINT (Fline_end_position (Qnil)) + 1, ZV);
+ set_marker_restricted (w->start, make_number (spos),
+ w->buffer);
+ w->start_at_line_beg = Qt;
+ w->update_mode_line = Qt;
+ XSETFASTINT (w->last_modified, 0);
+ XSETFASTINT (w->last_overlay_modified, 0);
+ /* Set force_start so that redisplay_window will run the
+ window-scroll-functions. */
+ w->force_start = Qt;
+ return;
+ }
}
}
+ /* Cancel previous vscroll. */
Fset_window_vscroll (window, make_number (0), Qt);
}
point in the same window line as it is now, so get that line. */
if (!NILP (Vscroll_preserve_screen_position))
{
- start_display (&it, w, start);
- move_it_to (&it, PT, -1, -1, -1, MOVE_TO_POS);
- preserve_y = it.current_y;
+ /* We preserve the goal pixel coordinate across consecutive
+ calls to scroll-up or scroll-down. This avoids the
+ possibility of point becoming "stuck" on a tall line when
+ scrolling by one line. */
+ if (window_scroll_pixel_based_preserve_y < 0
+ || (!EQ (current_kboard->Vlast_command, Qscroll_up)
+ && !EQ (current_kboard->Vlast_command, Qscroll_down)))
+ {
+ start_display (&it, w, start);
+ move_it_to (&it, PT, -1, -1, -1, MOVE_TO_POS);
+ window_scroll_pixel_based_preserve_y = it.current_y;
+ }
}
else
- preserve_y = -1;
+ window_scroll_pixel_based_preserve_y = -1;
/* Move iterator it from start the specified distance forward or
backward. The result is the new window start. */
if (dy <= 0)
{
move_it_vertically_backward (&it, -dy);
- /* Ensure we actually does move, e.g. in case we are currently
+ /* Ensure we actually do move, e.g. in case we are currently
looking at an image that is taller that the window height. */
while (start_pos == IT_CHARPOS (it)
&& start_pos > BEGV)
{
move_it_to (&it, ZV, -1, it.current_y + dy, -1,
MOVE_TO_POS | MOVE_TO_Y);
- /* Ensure we actually does move, e.g. in case we are currently
+ /* Ensure we actually do move, e.g. in case we are currently
looking at an image that is taller that the window height. */
while (start_pos == IT_CHARPOS (it)
&& start_pos < ZV)
{
if (it.current_y < it.last_visible_y
&& (it.current_y + it.max_ascent + it.max_descent
- >= it.last_visible_y))
+ > it.last_visible_y))
{
/* The last line was only partially visible, make it fully
visible. */
}
else if (noerror)
return;
+ else if (n < 0) /* could happen with empty buffers */
+ xsignal0 (Qbeginning_of_buffer);
else
- Fsignal (Qend_of_buffer, Qnil);
+ xsignal0 (Qend_of_buffer);
}
else
{
else if (noerror)
return;
else
- Fsignal (Qbeginning_of_buffer, Qnil);
+ xsignal0 (Qbeginning_of_buffer);
}
/* If control gets here, then we vscrolled. */
|| EQ (Vscroll_preserve_screen_position, Qt)))
/* We found PT at a legitimate height. Leave it alone. */
;
- else if (preserve_y >= 0)
+ else if (window_scroll_pixel_based_preserve_y >= 0)
{
/* If we have a header line, take account of it.
This is necessary because we set it.current_y to 0, above. */
- if (WINDOW_WANTS_HEADER_LINE_P (w))
- preserve_y -= CURRENT_HEADER_LINE_HEIGHT (w);
-
- move_it_to (&it, -1, -1, preserve_y, -1, MOVE_TO_Y);
+ move_it_to (&it, -1, -1,
+ window_scroll_pixel_based_preserve_y
+ - (WINDOW_WANTS_HEADER_LINE_P (w) ? 1 : 0 ),
+ -1, MOVE_TO_Y);
SET_PT_BOTH (IT_CHARPOS (it), IT_BYTEPOS (it));
}
else
int charpos, bytepos;
int partial_p;
- /* Save our position, for the preserve_y case. */
+ /* Save our position, for the
+ window_scroll_pixel_based_preserve_y case. */
charpos = IT_CHARPOS (it);
bytepos = IT_BYTEPOS (it);
|| EQ (Vscroll_preserve_screen_position, Qt)))
/* We found PT before we found the display margin, so PT is ok. */
;
- else if (preserve_y >= 0)
+ else if (window_scroll_pixel_based_preserve_y >= 0)
{
SET_TEXT_POS_FROM_MARKER (start, w->start);
start_display (&it, w, start);
-#if 0 /* It's wrong to subtract this here
- because we called start_display again
- and did not alter it.current_y this time. */
-
- /* If we have a header line, take account of it. */
- if (WINDOW_WANTS_HEADER_LINE_P (w))
- preserve_y -= CURRENT_HEADER_LINE_HEIGHT (w);
-#endif
-
- move_it_to (&it, -1, -1, preserve_y, -1, MOVE_TO_Y);
+ /* It would be wrong to subtract CURRENT_HEADER_LINE_HEIGHT
+ here because we called start_display again and did not
+ alter it.current_y this time. */
+ move_it_to (&it, -1, -1, window_scroll_pixel_based_preserve_y, -1,
+ MOVE_TO_Y);
SET_PT_BOTH (IT_CHARPOS (it), IT_BYTEPOS (it));
}
else
if (noerror)
return;
else
- Fsignal (Qbeginning_of_buffer, Qnil);
+ xsignal0 (Qbeginning_of_buffer);
}
if (pos < ZV)
if (noerror)
return;
else
- Fsignal (Qend_of_buffer, Qnil);
+ xsignal0 (Qend_of_buffer);
}
}
Lisp_Object left_margin_cols, right_margin_cols;
Lisp_Object left_fringe_width, right_fringe_width, fringes_outside_margins;
Lisp_Object scroll_bar_width, vertical_scroll_bar_type;
+ Lisp_Object dedicated;
};
#define SAVED_WINDOW_N(swv,n) \
(object)
Lisp_Object object;
{
- if (WINDOW_CONFIGURATIONP (object))
- return Qt;
- return Qnil;
+ return WINDOW_CONFIGURATIONP (object) ? Qt : Qnil;
}
DEFUN ("window-configuration-frame", Fwindow_configuration_frame, Swindow_configuration_frame, 1, 1, 0,
register struct save_window_data *data;
struct Lisp_Vector *saved_windows;
- if (! WINDOW_CONFIGURATIONP (config))
- wrong_type_argument (Qwindow_configuration_p, config);
+ CHECK_WINDOW_CONFIGURATION (config);
data = (struct save_window_data *) XVECTOR (config);
saved_windows = XVECTOR (data->saved_windows);
FRAME_PTR f;
int old_point = -1;
- while (!WINDOW_CONFIGURATIONP (configuration))
- wrong_type_argument (Qwindow_configuration_p, configuration);
+ CHECK_WINDOW_CONFIGURATION (configuration);
data = (struct save_window_data *) XVECTOR (configuration);
saved_windows = XVECTOR (data->saved_windows);
else
{
if (XBUFFER (new_current_buffer) == current_buffer)
- old_point = PT;
+ /* The code further down "preserves point" by saving here PT in
+ old_point and then setting it later back into PT. When the
+ current-selected-window and the final-selected-window both show
+ the current buffer, this suffers from the problem that the
+ current PT is the window-point of the current-selected-window,
+ while the final PT is the point of the final-selected-window, so
+ this copy from one PT to the other would end up moving the
+ window-point of the final-selected-window to the window-point of
+ the current-selected-window. So we have to be careful which
+ point of the current-buffer we copy into old_point. */
+ if (EQ (XWINDOW (data->current_window)->buffer, new_current_buffer)
+ && WINDOWP (selected_window)
+ && EQ (XWINDOW (selected_window)->buffer, new_current_buffer)
+ && !EQ (selected_window, data->current_window))
+ old_point = XMARKER (XWINDOW (data->current_window)->pointm)->charpos;
+ else
+ old_point = PT;
else
/* BUF_PT (XBUFFER (new_current_buffer)) gives us the position of
point in new_current_buffer as of the last time this buffer was
w->fringes_outside_margins = p->fringes_outside_margins;
w->scroll_bar_width = p->scroll_bar_width;
w->vertical_scroll_bar_type = p->vertical_scroll_bar_type;
+ w->dedicated = p->dedicated;
XSETFASTINT (w->last_modified, 0);
XSETFASTINT (w->last_overlay_modified, 0);
p->fringes_outside_margins = w->fringes_outside_margins;
p->scroll_bar_width = w->scroll_bar_width;
p->vertical_scroll_bar_type = w->vertical_scroll_bar_type;
+ p->dedicated = w->dedicated;
if (!NILP (w->buffer))
{
/* Save w's value of point in the window configuration.
if (!NILP (right_width))
CHECK_NATNUM (right_width);
- if (!EQ (w->left_fringe_width, left_width)
- || !EQ (w->right_fringe_width, right_width)
- || !EQ (w->fringes_outside_margins, outside_margins))
+ /* Do nothing on a tty. */
+ if (FRAME_WINDOW_P (WINDOW_XFRAME (w))
+ && (!EQ (w->left_fringe_width, left_width)
+ || !EQ (w->right_fringe_width, right_width)
+ || !EQ (w->fringes_outside_margins, outside_margins)))
{
w->left_fringe_width = left_width;
w->right_fringe_width = right_width;
Lisp_Object window;
{
struct window *w = decode_window (window);
+
return Fcons (make_number (WINDOW_LEFT_FRINGE_WIDTH (w)),
Fcons (make_number (WINDOW_RIGHT_FRINGE_WIDTH (w)),
- Fcons ((WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w) ?
- Qt : Qnil), Qnil)));
+ Fcons ((WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w)
+ ? Qt : Qnil), Qnil)));
}
Third parameter VERTICAL-TYPE specifies the type of the vertical scroll
bar: left, right, or nil.
If WIDTH is nil, use the frame's scroll-bar width.
-If TYPE is t, use the frame's scroll-bar type. */)
+If VERTICAL-TYPE is t, use the frame's scroll-bar type.
+Fourth parameter HORIZONTAL-TYPE is currently unused. */)
(window, width, vertical_type, horizontal_type)
Lisp_Object window, width, vertical_type, horizontal_type;
{
doc: /* Return the amount by which WINDOW is scrolled vertically.
Use the selected window if WINDOW is nil or omitted.
Normally, value is a multiple of the canonical character height of WINDOW;
-optional second arg PIXELS_P means value is measured in pixels. */)
+optional second arg PIXELS-P means value is measured in pixels. */)
(window, pixels_p)
Lisp_Object window, pixels_p;
{
doc: /* Set amount by which WINDOW should be scrolled vertically to VSCROLL.
WINDOW nil means use the selected window. Normally, VSCROLL is a
non-negative multiple of the canonical character height of WINDOW;
-optional third arg PIXELS_P non-nil means that VSCROLL is in pixels.
+optional third arg PIXELS-P non-nil means that VSCROLL is in pixels.
If PIXELS-P is nil, VSCROLL may have to be rounded so that it
corresponds to an integral number of pixels. The return value is the
result of this rounding.
int (* fn) P_ ((struct window *, void *));
void *user_data;
{
- foreach_window_1 (XWINDOW (FRAME_ROOT_WINDOW (f)), fn, user_data);
+ /* Fdelete_frame may set FRAME_ROOT_WINDOW (f) to Qnil. */
+ if (WINDOWP (FRAME_ROOT_WINDOW (f)))
+ foreach_window_1 (XWINDOW (FRAME_ROOT_WINDOW (f)), fn, user_data);
}
struct Lisp_Vector *sw1, *sw2;
int i;
- if (!WINDOW_CONFIGURATIONP (c1))
- wrong_type_argument (Qwindow_configuration_p, c1);
- if (!WINDOW_CONFIGURATIONP (c2))
- wrong_type_argument (Qwindow_configuration_p, c2);
+ CHECK_WINDOW_CONFIGURATION (c1);
+ CHECK_WINDOW_CONFIGURATION (c2);
d1 = (struct save_window_data *) XVECTOR (c1);
d2 = (struct save_window_data *) XVECTOR (c2);
void
syms_of_window ()
{
+ Qscroll_up = intern ("scroll-up");
+ staticpro (&Qscroll_up);
+
+ Qscroll_down = intern ("scroll-down");
+ staticpro (&Qscroll_down);
+
Qwindow_size_fixed = intern ("window-size-fixed");
staticpro (&Qwindow_size_fixed);
Fset (Qwindow_size_fixed, Qnil);
minibuf_selected_window = Qnil;
staticpro (&minibuf_selected_window);
+ window_scroll_pixel_based_preserve_y = -1;
+
DEFVAR_LISP ("temp-buffer-show-function", &Vtemp_buffer_show_function,
doc: /* Non-nil means call as function to display a help buffer.
The function is called with one argument, the buffer to be displayed.
next_screen_context_lines = 2;
DEFVAR_INT ("split-height-threshold", &split_height_threshold,
- doc: /* *A window must be at least this tall to be eligible for splitting by `display-buffer'.
+ doc: /* *A window must be at least this tall to be eligible for splitting
+by `display-buffer'. The value is in line units.
If there is only one window, it is split regardless of this value. */);
split_height_threshold = 500;
DEFVAR_INT ("window-min-height", &window_min_height,
- doc: /* *Delete any window less than this tall (including its mode line). */);
+ doc: /* *Delete any window less than this tall (including its mode line).
+The value is in line units. */);
window_min_height = 4;
DEFVAR_INT ("window-min-width", &window_min_width,
- doc: /* *Delete any window less than this wide. */);
+ doc: /* *Delete any window less than this wide (measured in characters). */);
window_min_width = 10;
DEFVAR_LISP ("scroll-preserve-screen-position",
defsubr (&Swindowp);
defsubr (&Swindow_live_p);
defsubr (&Spos_visible_in_window_p);
+ defsubr (&Swindow_line_height);
defsubr (&Swindow_buffer);
defsubr (&Swindow_height);
defsubr (&Swindow_width);
defsubr (&Ssplit_window);
defsubr (&Senlarge_window);
defsubr (&Sshrink_window);
+ defsubr (&Sadjust_window_trailing_edge);
defsubr (&Sscroll_up);
defsubr (&Sscroll_down);
defsubr (&Sscroll_left);