/* Window creation, deletion and examination for GNU Emacs.
Does not include redisplay.
- Copyright (C) 1985-1987, 1993-1998, 2000-2014 Free Software
+ Copyright (C) 1985-1987, 1993-1998, 2000-2015 Free Software
Foundation, Inc.
This file is part of GNU Emacs.
static Lisp_Object Qwindow_pixel_to_total;
static Lisp_Object Qscroll_up, Qscroll_down, Qscroll_command;
static Lisp_Object Qsafe, Qabove, Qbelow, Qwindow_size, Qclone_of;
+static Lisp_Object Qfloor, Qceiling;
+static Lisp_Object Qwindow_point_insertion_type;
static int displayed_window_lines (struct window *);
static int count_windows (struct window *);
/* Hook to run when window config changes. */
static Lisp_Object Qwindow_configuration_change_hook;
-/* Used by the function window_scroll_pixel_based */
+/* Used by the function window_scroll_pixel_based. */
static int window_scroll_pixel_based_preserve_x;
static int window_scroll_pixel_based_preserve_y;
DEFUN ("window-valid-p", Fwindow_valid_p, Swindow_valid_p, 1, 1, 0,
doc: /* Return t if OBJECT is a valid window and nil otherwise.
A valid window is either a window that displays a buffer or an internal
-window. Deleted windows are not live. */)
+window. Windows that have been deleted are not valid. */)
(Lisp_Object object)
{
return WINDOW_VALID_P (object) ? Qt : Qnil;
DEFUN ("select-window", Fselect_window, Sselect_window, 1, 2, 0,
doc: /* Select WINDOW which must be a live window.
Also make WINDOW's frame the selected frame and WINDOW that frame's
-selected window. In addition, make WINDOW's buffer current and set that
+selected window. In addition, make WINDOW's buffer current and set its
buffer's value of `point' to the value of WINDOW's `window-point'.
Return WINDOW.
front of the buffer list and do not make this window the most recently
selected one.
-Note that the main editor command loop sets the current buffer to the
-buffer of the selected window before each command. */)
+Run `buffer-list-update-hook' unless NORECORD is non-nil. Note that
+applications and internal routines often select a window temporarily for
+various purposes; mostly, to simplify coding. As a rule, such
+selections should be not recorded and therefore will not pollute
+`buffer-list-update-hook'. Selections that "really count" are those
+causing a visible change in the next redisplay of WINDOW's frame and
+should be always recorded. So if you think of running a function each
+time a window gets selected put it on `buffer-list-update-hook'.
+
+Also note that the main editor command loop sets the current buffer to
+the buffer of the selected window before each command. */)
(register Lisp_Object window, Lisp_Object norecord)
{
return select_window (window, norecord, 0);
}
\f
DEFUN ("window-pixel-width", Fwindow_pixel_width, Swindow_pixel_width, 0, 1, 0,
- doc: /* Return the pixel width of window WINDOW.
+ doc: /* Return the width of window WINDOW in pixels.
WINDOW must be a valid window and defaults to the selected one.
The return value includes the fringes and margins of WINDOW as well as
}
DEFUN ("window-pixel-height", Fwindow_pixel_height, Swindow_pixel_height, 0, 1, 0,
- doc: /* Return the pixel height of window WINDOW.
+ doc: /* Return the height of window WINDOW in pixels.
WINDOW must be a valid window and defaults to the selected one.
-The return value includes the mode line and header line, if any. If
-WINDOW is an internal window, its pixel height is the height of the
-screen areas spanned by its children. */)
+The return value includes the mode line and header line and the bottom
+divider, if any. If WINDOW is an internal window, its pixel height is
+the height of the screen areas spanned by its children. */)
(Lisp_Object window)
{
return make_number (decode_valid_window (window)->pixel_height);
}
-DEFUN ("window-total-height", Fwindow_total_height, Swindow_total_height, 0, 1, 0,
- doc: /* Return the total height, in lines, of window WINDOW.
+DEFUN ("window-total-height", Fwindow_total_height, Swindow_total_height, 0, 2, 0,
+ doc: /* Return the height of window WINDOW in lines.
WINDOW must be a valid window and defaults to the selected one.
-The return value includes the mode line and header line, if any.
-If WINDOW is an internal window, the total height is the height
-of the screen areas spanned by its children.
+The return value includes the heights of WINDOW's mode and header line
+and its bottom divider, if any. If WINDOW is an internal window, the
+total height is the height of the screen areas spanned by its children.
-On a graphical display, this total height is reported as an
-integer multiple of the default character height. */)
- (Lisp_Object window)
+If WINDOW's pixel height is not an integral multiple of its frame's
+character height, the number of lines occupied by WINDOW is rounded
+internally. This is done in a way such that, if WINDOW is a parent
+window, the sum of the total heights of all its children internally
+equals the total height of WINDOW.
+
+If the optional argument ROUND is `ceiling', return the smallest integer
+larger than WINDOW's pixel height divided by the character height of
+WINDOW's frame. ROUND `floor' means to return the largest integer
+smaller than WINDOW's pixel height divided by the character height of
+WINDOW's frame. Any other value of ROUND means to return the internal
+total height of WINDOW. */)
+ (Lisp_Object window, Lisp_Object round)
{
- return make_number (decode_valid_window (window)->total_lines);
+ struct window *w = decode_valid_window (window);
+
+ if (! EQ (round, Qfloor) && ! EQ (round, Qceiling))
+ return make_number (w->total_lines);
+ else
+ {
+ int unit = FRAME_LINE_HEIGHT (WINDOW_XFRAME (w));
+
+ return make_number (EQ (round, Qceiling)
+ ? ((w->pixel_height + unit - 1) /unit)
+ : (w->pixel_height / unit));
+ }
}
-DEFUN ("window-total-width", Fwindow_total_width, Swindow_total_width, 0, 1, 0,
- doc: /* Return the total width, in columns, of window WINDOW.
+DEFUN ("window-total-width", Fwindow_total_width, Swindow_total_width, 0, 2, 0,
+ doc: /* Return the total width of window WINDOW in columns.
WINDOW must be a valid window and defaults to the selected one.
-The return value includes any vertical dividers or scroll bars
-belonging to WINDOW. If WINDOW is an internal window, the total width
-is the width of the screen areas spanned by its children.
-
-On a graphical display, this total width is reported as an
-integer multiple of the default character width. */)
- (Lisp_Object window)
+The return value includes the widths of WINDOW's fringes, margins,
+scroll bars and its right divider, if any. If WINDOW is an internal
+window, the total width is the width of the screen areas spanned by its
+children.
+
+If WINDOW's pixel width is not an integral multiple of its frame's
+character width, the number of lines occupied by WINDOW is rounded
+internally. This is done in a way such that, if WINDOW is a parent
+window, the sum of the total widths of all its children internally
+equals the total width of WINDOW.
+
+If the optional argument ROUND is `ceiling', return the smallest integer
+larger than WINDOW's pixel width divided by the character width of
+WINDOW's frame. ROUND `floor' means to return the largest integer
+smaller than WINDOW's pixel width divided by the character width of
+WINDOW's frame. Any other value of ROUND means to return the internal
+total width of WINDOW. */)
+ (Lisp_Object window, Lisp_Object round)
{
- return make_number (decode_valid_window (window)->total_cols);
+ struct window *w = decode_valid_window (window);
+
+ if (! EQ (round, Qfloor) && ! EQ (round, Qceiling))
+ return make_number (w->total_cols);
+ else
+ {
+ int unit = FRAME_COLUMN_WIDTH (WINDOW_XFRAME (w));
+
+ return make_number (EQ (round, Qceiling)
+ ? ((w->pixel_width + unit - 1) /unit)
+ : (w->pixel_width / unit));
+ }
}
DEFUN ("window-new-total", Fwindow_new_total, Swindow_new_total, 0, 1, 0,
doc: /* Return the new total size of window WINDOW.
-WINDOW must be a valid window and defaults to the selected one. */)
+WINDOW must be a valid window and defaults to the selected one.
+
+The new total size of WINDOW is the value set by the last call of
+`set-window-new-total' for WINDOW. If it is valid, it will be shortly
+installed as WINDOW's total height (see `window-total-height') or total
+width (see `window-total-width'). */)
(Lisp_Object window)
{
return decode_valid_window (window)->new_total;
DEFUN ("window-normal-size", Fwindow_normal_size, Swindow_normal_size, 0, 2, 0,
doc: /* Return the normal height of window WINDOW.
WINDOW must be a valid window and defaults to the selected one.
-If HORIZONTAL is non-nil, return the normal width of WINDOW. */)
+If HORIZONTAL is non-nil, return the normal width of WINDOW.
+
+The normal height of a frame's root window or a window that is
+horizontally combined (a window that has a left or right sibling) is
+1.0. The normal height of a window that is vertically combined (has a
+sibling above or below) is the fraction of the window's height with
+respect to its parent. The sum of the normal heights of all windows in a
+vertical combination equals 1.0.
+
+Similarly, the normal width of a frame's root window or a window that is
+vertically combined equals 1.0. The normal width of a window that is
+horizontally combined is the fraction of the window's width with respect
+to its parent. The sum of the normal widths of all windows in a
+horizontal combination equals 1.0.
+
+The normal sizes of windows are used to restore the proportional sizes
+of windows after they have been shrunk to their minimum sizes; for
+example when a frame is temporarily made very small and afterwards gets
+re-enlarged to its previous size. */)
(Lisp_Object window, Lisp_Object horizontal)
{
struct window *w = decode_valid_window (window);
DEFUN ("window-new-normal", Fwindow_new_normal, Swindow_new_normal, 0, 1, 0,
doc: /* Return new normal size of window WINDOW.
-WINDOW must be a valid window and defaults to the selected one. */)
+WINDOW must be a valid window and defaults to the selected one.
+
+The new normal size of WINDOW is the value set by the last call of
+`set-window-new-normal' for WINDOW. If valid, it will be shortly
+installed as WINDOW's normal size (see `window-normal-size'). */)
(Lisp_Object window)
{
return decode_valid_window (window)->new_normal;
DEFUN ("window-new-pixel", Fwindow_new_pixel, Swindow_new_pixel, 0, 1, 0,
doc: /* Return new pixel size of window WINDOW.
-WINDOW must be a valid window and defaults to the selected one. */)
+WINDOW must be a valid window and defaults to the selected one.
+
+The new pixel size of WINDOW is the value set by the last call of
+`set-window-new-pixel' for WINDOW. If it is valid, it will be shortly
+installed as WINDOW's pixel height (see `window-pixel-height') or pixel
+width (see `window-pixel-width'). */)
(Lisp_Object window)
{
return decode_valid_window (window)->new_pixel;
return make_number (decode_valid_window (window)->top_line);
}
-/* Return the number of lines of W's body. Don't count any mode or
- header line of W. */
-
+/* Return the number of lines/pixels of W's body. Don't count any mode
+ or header line or horizontal divider of W. Rounds down to nearest
+ integer when not working pixelwise. */
static int
window_body_height (struct window *w, bool pixelwise)
{
- int pixels = (w->pixel_height
- - WINDOW_BOTTOM_DIVIDER_WIDTH (w)
+ int height = (w->pixel_height
- WINDOW_HEADER_LINE_HEIGHT (w)
- - WINDOW_MODE_LINE_HEIGHT (w));
- int unit = FRAME_LINE_HEIGHT (WINDOW_XFRAME (w));
+ - WINDOW_MODE_LINE_HEIGHT (w)
+ - WINDOW_BOTTOM_DIVIDER_WIDTH (w));
- return pixelwise ? pixels : ((pixels + unit - 1) / unit);
+ /* Don't return a negative value. */
+ return max (pixelwise
+ ? height
+ : height / FRAME_LINE_HEIGHT (WINDOW_XFRAME (w)),
+ 0);
}
-/* Return the number of columns of W's body. Don't count columns
- occupied by the scroll bar or the vertical bar separating W from its
- right sibling. On window-systems don't count fringes or display
- margins either. */
+/* Return the number of columns/pixels of W's body. Don't count columns
+ occupied by the scroll bar or the divider/vertical bar separating W
+ from its right sibling or margins. On window-systems don't count
+ fringes either. Round down to nearest integer when not working
+ pixelwise. */
int
window_body_width (struct window *w, bool pixelwise)
{
struct frame *f = XFRAME (WINDOW_FRAME (w));
- int pixels = (w->pixel_width
- - WINDOW_RIGHT_DIVIDER_WIDTH (w)
- - (WINDOW_HAS_VERTICAL_SCROLL_BAR (w)
- ? WINDOW_SCROLL_BAR_AREA_WIDTH (w)
- : ((!FRAME_WINDOW_P (f)
- && !WINDOW_RIGHTMOST_P (w)
- && !WINDOW_RIGHT_DIVIDER_WIDTH (w)
- && !WINDOW_FULL_WIDTH_P (w))
- /* According to Eli this is either 1 or 0. */
- ? 1 : 0))
+ int width = (w->pixel_width
+ - WINDOW_RIGHT_DIVIDER_WIDTH (w)
+ - (WINDOW_HAS_VERTICAL_SCROLL_BAR (w)
+ ? WINDOW_SCROLL_BAR_AREA_WIDTH (w)
+ : ((!FRAME_WINDOW_P (f)
+ && !WINDOW_RIGHTMOST_P (w)
+ && !WINDOW_RIGHT_DIVIDER_WIDTH (w))
+ /* A vertical bar is either 1 or 0. */
+ ? 1 : 0))
- WINDOW_MARGINS_WIDTH (w)
- (FRAME_WINDOW_P (f)
? WINDOW_FRINGES_WIDTH (w)
: 0));
- int unit = FRAME_COLUMN_WIDTH (WINDOW_XFRAME (w));
- return pixelwise ? pixels : ((pixels + unit - 1) / unit);
+ /* Don't return a negative value. */
+ return max (pixelwise
+ ? width
+ : width / FRAME_COLUMN_WIDTH (WINDOW_XFRAME (w)),
+ 0);
}
DEFUN ("window-body-height", Fwindow_body_height, Swindow_body_height, 0, 2, 0,
- doc: /* Return the height, in lines, of WINDOW's text area.
-WINDOW must be a live window and defaults to the selected one.
-
-Optional argument PIXELWISE non-nil means return the height in pixels.
-
-The returned height does not include the mode line or header line. On a
-graphical display, the height is expressed as an integer multiple of the
-default character height if PIXELWISE is nil.
-
-If PIXELWISE is nil and a line at the bottom of the text area is only
-partially visible, that counts as a whole line; to exclude
-partially-visible lines, use `window-text-height'. */)
+ doc: /* Return the height of WINDOW's text area.
+WINDOW must be a live window and defaults to the selected one. Optional
+argument PIXELWISE non-nil means return the height of WINDOW's text area
+in pixels. The return value does not include the mode line or header
+line or any horizontal divider.
+
+If PIXELWISE is nil, return the largest integer smaller than WINDOW's
+pixel height divided by the character height of WINDOW's frame. This
+means that if a line at the bottom of the text area is only partially
+visible, that line is not counted. */)
(Lisp_Object window, Lisp_Object pixelwise)
{
return make_number (window_body_height (decode_live_window (window),
}
DEFUN ("window-body-width", Fwindow_body_width, Swindow_body_width, 0, 2, 0,
- doc: /* Return the width, in columns, of WINDOW's text area.
-WINDOW must be a live window and defaults to the selected one.
-
-Optional argument PIXELWISE non-nil means return the width in pixels.
-
-The return value does not include any vertical dividers, fringe or
-marginal areas, or scroll bars. On a graphical display, the width is
-expressed as an integer multiple of the default character width if
-PIXELWISE is nil.
-
-If PIXELWISE is nil and a column at the right of the text area is only
-partially visible, that counts as a whole column; to exclude
-partially-visible columns, use `window-text-width'. */)
+ doc: /* Return the width of WINDOW's text area.
+WINDOW must be a live window and defaults to the selected one. Optional
+argument PIXELWISE non-nil means return the width in pixels. The return
+value does not include any vertical dividers, fringes or marginal areas,
+or scroll bars.
+
+If PIXELWISE is nil, return the largest integer smaller than WINDOW's
+pixel width divided by the character width of WINDOW's frame. This
+means that if a column at the right of the text area is only partially
+visible, that column is not counted.
+
+Note that the returned value includes the column reserved for the
+continuation glyph. */)
(Lisp_Object window, Lisp_Object pixelwise)
{
return make_number (window_body_width (decode_live_window (window),
DEFUN ("window-mode-line-height", Fwindow_mode_line_height,
Swindow_mode_line_height, 0, 1, 0,
- doc: /* Return the height in pixel of WINDOW's mode-line.
+ doc: /* Return the height in pixels of WINDOW's mode-line.
WINDOW must be a live window and defaults to the selected one. */)
(Lisp_Object window)
{
DEFUN ("window-header-line-height", Fwindow_header_line_height,
Swindow_header_line_height, 0, 1, 0,
- doc: /* Return the height in pixel of WINDOW's header-line.
+ doc: /* Return the height in pixels of WINDOW's header-line.
WINDOW must be a live window and defaults to the selected one. */)
(Lisp_Object window)
{
DEFUN ("window-right-divider-width", Fwindow_right_divider_width,
Swindow_right_divider_width, 0, 1, 0,
- doc: /* Return the width of WINDOW's right divider.
+ doc: /* Return the width in pixels of WINDOW's right divider.
WINDOW must be a live window and defaults to the selected one. */)
(Lisp_Object window)
{
DEFUN ("window-bottom-divider-width", Fwindow_bottom_divider_width,
Swindow_bottom_divider_width, 0, 1, 0,
- doc: /* Return the width of WINDOW's bottom divider.
+ doc: /* Return the width in pixels of WINDOW's bottom divider.
WINDOW must be a live window and defaults to the selected one. */)
(Lisp_Object window)
{
return (make_number (WINDOW_BOTTOM_DIVIDER_WIDTH (decode_live_window (window))));
}
+DEFUN ("window-scroll-bar-width", Fwindow_scroll_bar_width,
+ Swindow_scroll_bar_width, 0, 1, 0,
+ doc: /* Return the width in pixels of WINDOW's vertical scrollbar.
+WINDOW must be a live window and defaults to the selected one. */)
+ (Lisp_Object window)
+{
+ return (make_number (WINDOW_SCROLL_BAR_AREA_WIDTH (decode_live_window (window))));
+}
+
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 must be a live window and defaults to the selected one. */)
if (y < top_y || y >= bottom_y || x < left_x || x >= right_x)
return ON_NOTHING;
- /* On vertical window divider (which prevails horizontal
- dividers)? */
- if (!WINDOW_RIGHTMOST_P (w)
- && WINDOW_RIGHT_DIVIDER_WIDTH (w)
- && x >= right_x - WINDOW_RIGHT_DIVIDER_WIDTH (w)
- && x <= right_x)
- return ON_RIGHT_DIVIDER;
- /* On the horizontal window divider? */
- else if (WINDOW_BOTTOM_DIVIDER_WIDTH (w)
- && y >= (bottom_y - WINDOW_BOTTOM_DIVIDER_WIDTH (w))
- && y <= bottom_y)
+ /* On the horizontal window divider (which prevails the vertical
+ divider)? */
+ if (WINDOW_BOTTOM_DIVIDER_WIDTH (w) > 0
+ && y >= (bottom_y - WINDOW_BOTTOM_DIVIDER_WIDTH (w))
+ && y <= bottom_y)
return ON_BOTTOM_DIVIDER;
+ /* On vertical window divider? */
+ else if (!WINDOW_RIGHTMOST_P (w)
+ && WINDOW_RIGHT_DIVIDER_WIDTH (w) > 0
+ && x >= right_x - WINDOW_RIGHT_DIVIDER_WIDTH (w)
+ && x <= right_x)
+ return ON_RIGHT_DIVIDER;
/* On the mode or header line? */
else if ((WINDOW_WANTS_MODELINE_P (w)
&& y >= (bottom_y
resize windows horizontally in case we're using toolkit scroll
bars. Note: If scrollbars are on the left, the window that
must be eventually resized is that on the left of WINDOW. */
- if ((WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_LEFT (w)
- && !WINDOW_LEFTMOST_P (w)
- && eabs (x - left_x) < grabbable_width)
- || (!WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_LEFT (w)
- && !WINDOW_RIGHTMOST_P (w)
- && eabs (x - right_x) < grabbable_width))
+ if ((WINDOW_RIGHT_DIVIDER_WIDTH (w) == 0)
+ && ((WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_LEFT (w)
+ && !WINDOW_LEFTMOST_P (w)
+ && eabs (x - left_x) < grabbable_width)
+ || (!WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_LEFT (w)
+ && !WINDOW_RIGHTMOST_P (w)
+ && eabs (x - right_x) < grabbable_width)))
return ON_VERTICAL_BORDER;
else
return part;
if (FRAME_WINDOW_P (f))
{
if (!w->pseudo_window_p
+ && WINDOW_RIGHT_DIVIDER_WIDTH (w) == 0
&& !WINDOW_HAS_VERTICAL_SCROLL_BAR (w)
&& !WINDOW_RIGHTMOST_P (w)
&& (eabs (x - right_x) < grabbable_width))
/* Need to say "x > right_x" rather than >=, since on character
terminals, the vertical line's x coordinate is right_x. */
else if (!w->pseudo_window_p
+ && WINDOW_RIGHT_DIVIDER_WIDTH (w) == 0
&& !WINDOW_RIGHTMOST_P (w)
/* Why check ux if we are not the rightmost window? Also
shouldn't a pseudo window always be rightmost? */
? (x >= left_x + WINDOW_LEFT_FRINGE_WIDTH (w))
: (x < left_x + lmargin_width)))
return ON_LEFT_MARGIN;
-
- return ON_LEFT_FRINGE;
+ else
+ return ON_LEFT_FRINGE;
}
if (x >= text_right)
? (x < right_x - WINDOW_RIGHT_FRINGE_WIDTH (w))
: (x >= right_x - rmargin_width)))
return ON_RIGHT_MARGIN;
-
- return ON_RIGHT_FRINGE;
+ else
+ return ON_RIGHT_FRINGE;
}
/* Everything special ruled out - must be on text area */
case ON_TEXT:
return x - window_box_left (w, TEXT_AREA);
+ case ON_HEADER_LINE:
+ case ON_MODE_LINE:
case ON_LEFT_FRINGE:
return x - left_x;
frame.
If COORDINATES are in the text portion of WINDOW,
the coordinates relative to the window are returned.
+If they are in the bottom divider of WINDOW, `bottom-divider' is returned.
+If they are in the right divider of WINDOW, `right-divider' is returned.
If they are in the mode line of WINDOW, `mode-line' is returned.
-If they are in the top mode line of WINDOW, `header-line' is returned.
+If they are in the header line of WINDOW, `header-line' is returned.
If they are in the left fringe of WINDOW, `left-fringe' is returned.
If they are in the right fringe of WINDOW, `right-fringe' is returned.
If they are on the border between WINDOW and its right sibling,
Optional argument ADD non-nil means add SIZE to the new pixel size of
WINDOW and return the sum.
+The new pixel size of WINDOW, if valid, will be shortly installed as
+WINDOW's pixel height (see `window-pixel-height') or pixel width (see
+`window-pixel-width').
+
Note: This function does not operate on any child windows of WINDOW. */)
(Lisp_Object window, Lisp_Object size, Lisp_Object add)
{
Optional argument ADD non-nil means add SIZE to the new total size of
WINDOW and return the sum.
+The new total size of WINDOW, if valid, will be shortly installed as
+WINDOW's total height (see `window-total-height') or total width (see
+`window-total-width').
+
Note: This function does not operate on any child windows of WINDOW. */)
(Lisp_Object window, Lisp_Object size, Lisp_Object add)
{
WINDOW must be a valid window and defaults to the selected one.
Return SIZE.
+The new normal size of WINDOW, if valid, will be shortly installed as
+WINDOW's normal size (see `window-normal-size').
+
Note: This function does not operate on any child windows of WINDOW. */)
(Lisp_Object window, Lisp_Object size)
{
}
-/* Set w->pixel_height (w->pixel_height if HORIZONTAL is non-zero) to
+/* Set w->pixel_height (w->pixel_width if HORFLAG is non-zero) to
w->new_pixel for window W and recursively all child windows of W.
Also calculate and assign the new vertical (horizontal) pixel start
positions of each of these windows.
}
}
else
- /* Bug#15957. */
- w->window_end_valid = 0;
+ {
+ adjust_window_margins (w);
+ /* Bug#15957. */
+ w->window_end_valid = 0;
+ }
}
-/* Set w->total_lines (w->total_cols if HORIZONTAL is non-zero) to
+/* Set w->total_lines (w->total_cols if HORFLAG is non-zero) to
w->new_total for window W and recursively all child windows of W.
Also calculate and assign the new vertical (horizontal) start
positions of each of these windows. */
Optional argument HORIZONTAL omitted or nil means apply requested
height values. HORIZONTAL non-nil means apply requested width values.
-This function checks whether the requested values sum up to a valid
-window layout, recursively assigns the new sizes of all child windows
-and calculates and assigns the new start positions of these windows.
+The requested size values are those set by `set-window-new-pixel' and
+`set-window-new-normal'. This function checks whether the requested
+values sum up to a valid window layout, recursively assigns the new
+sizes of all child windows and calculates and assigns the new start
+positions of these windows.
+
+Return t if the requested values have been applied correctly, nil
+otherwise.
Note: This function does not check any of `window-fixed-size-p',
`window-min-height' or `window-min-width'. All these checks have to
block_input ();
window_resize_apply (r, 0);
- w->total_lines = XFASTINT (w->new_total);
- w->top_line = r->top_line + r->total_lines;
w->pixel_height = XFASTINT (w->new_pixel);
+ w->total_lines = w->pixel_height / FRAME_LINE_HEIGHT (f);
w->pixel_top = r->pixel_top + r->pixel_height;
+ w->top_line = r->top_line + r->total_lines;
fset_redisplay (f);
FRAME_WINDOW_SIZES_CHANGED (f) = 1;
/* The function move_iterator_vertically may move over more than
the specified y-distance. If it->w is small, e.g. a
mini-buffer window, we may end up in front of the window's
- display area. This is the case when Start displaying at the
- start of the line containing PT in this case. */
+ display area. Start displaying at the start of the line
+ containing PT in this case. */
if (it.current_y <= 0)
{
init_iterator (&it, w, PT, PT_BYTE, NULL, DEFAULT_FACE_ID);
{
int px;
int dy = frame_line_height;
+ /* In the below we divide the window box height by the
+ frame's line height to make the result predictable when
+ the window box is not an integral multiple of the line
+ height. This is important to ensure we get back to the
+ same position when scrolling up, then down. */
if (whole)
- dy = max ((window_box_height (w)
- - next_screen_context_lines * dy),
+ dy = max ((window_box_height (w) / dy
+ - next_screen_context_lines) * dy,
dy);
dy *= n;
{
ptrdiff_t start_pos = IT_CHARPOS (it);
int dy = frame_line_height;
- dy = max ((window_box_height (w)
- - next_screen_context_lines * dy),
+ /* In the below we divide the window box height by the frame's
+ line height to make the result predictable when the window
+ box is not an integral multiple of the line height. This is
+ important to ensure we get back to the same position when
+ scrolling up, then down. */
+ dy = max ((window_box_height (w) / dy - next_screen_context_lines) * dy,
dy) * n;
/* Note that move_it_vertically always moves the iterator to the
charpos = IT_CHARPOS (it);
bytepos = IT_BYTEPOS (it);
+ /* If PT is in the screen line at the last fully visible line,
+ move_it_to will stop at X = 0 in that line, because the
+ required Y coordinate is reached there. See if we can get to
+ PT without descending lower in Y, and if we can, it means we
+ reached PT before the scroll margin. */
+ if (charpos != PT)
+ {
+ struct it it2;
+ void *it_data;
+
+ it2 = it;
+ it_data = bidi_shelve_cache ();
+ move_it_to (&it, PT, -1, -1, -1, MOVE_TO_POS);
+ if (IT_CHARPOS (it) == PT && it.current_y == it2.current_y)
+ {
+ charpos = IT_CHARPOS (it);
+ bytepos = IT_BYTEPOS (it);
+ bidi_unshelve_cache (it_data, 1);
+ }
+ else
+ {
+ it = it2;
+ bidi_unshelve_cache (it_data, 0);
+ }
+ }
+
/* See if point is on a partially visible line at the end. */
if (it.what == IT_EOB)
partial_p = it.current_y + it.ascent + it.descent > it.last_visible_y;
if (MINI_WINDOW_P (XWINDOW (selected_window))
&& !NILP (Vminibuf_scroll_window))
window = Vminibuf_scroll_window;
- /* If buffer is specified, scroll that buffer. */
- else if (!NILP (Vother_window_scroll_buffer))
+ /* If buffer is specified and live, scroll that buffer. */
+ else if (!NILP (Vother_window_scroll_buffer)
+ && BUFFERP (Vother_window_scroll_buffer)
+ && BUFFER_LIVE_P (XBUFFER (Vother_window_scroll_buffer)))
{
window = Fget_buffer_window (Vother_window_scroll_buffer, Qnil);
if (NILP (window))
w->start_at_line_beg = (bytepos == BEGV_BYTE ||
FETCH_BYTE (bytepos - 1) == '\n');
+ wset_redisplay (w);
+
set_buffer_internal (obuf);
return Qnil;
}
else
p->pointm = Fcopy_marker (w->pointm, Qnil);
XMARKER (p->pointm)->insertion_type
- = !NILP (Vwindow_point_insertion_type);
+ = !NILP (buffer_local_value_1 /* Don't signal error if void. */
+ (Qwindow_point_insertion_type, w->contents));
p->start = Fcopy_marker (w->start, Qnil);
p->start_at_line_beg = w->start_at_line_beg ? Qt : Qnil;
DEFSYM (Qabove, "above");
DEFSYM (Qbelow, "below");
DEFSYM (Qclone_of, "clone-of");
+ DEFSYM (Qfloor, "floor");
+ DEFSYM (Qceiling, "ceiling");
staticpro (&Vwindow_list);
mode_line_in_non_selected_windows = 1;
DEFVAR_LISP ("other-window-scroll-buffer", Vother_window_scroll_buffer,
- doc: /* If non-nil, this is a buffer and \\[scroll-other-window] should scroll its window. */);
+ doc: /* If this is a live buffer, \\[scroll-other-window] should scroll its window. */);
Vother_window_scroll_buffer = Qnil;
DEFVAR_BOOL ("auto-window-vscroll", auto_window_vscroll_p,
DEFVAR_LISP ("window-point-insertion-type", Vwindow_point_insertion_type,
doc: /* Type of marker to use for `window-point'. */);
Vwindow_point_insertion_type = Qnil;
+ DEFSYM (Qwindow_point_insertion_type, "window_point_insertion_type");
DEFVAR_LISP ("window-configuration-change-hook",
Vwindow_configuration_change_hook,
Vwindow_persistent_parameters = list1 (Fcons (Qclone_of, Qt));
DEFVAR_BOOL ("window-resize-pixelwise", window_resize_pixelwise,
- doc: /* Non-nil means resizing windows works pixelwise.
-Functions currently affected by this option are `split-window',
-`maximize-window', `minimize-window', `fit-window-to-buffer' and
-`fit-frame-to-buffer' and all functions symmetrically resizing a
-parent window.
+ doc: /* Non-nil means resize windows pixelwise.
+This currently affects the functions: `split-window', `maximize-window',
+`minimize-window', `fit-window-to-buffer' and `fit-frame-to-buffer', and
+all functions that symmetrically resize a parent window.
Note that when a frame's pixel size is not a multiple of the
frame's character size, at least one window may get resized
defsubr (&Swindow_header_line_height);
defsubr (&Swindow_right_divider_width);
defsubr (&Swindow_bottom_divider_width);
+ defsubr (&Swindow_scroll_bar_width);
defsubr (&Swindow_inside_edges);
defsubr (&Swindow_inside_pixel_edges);
defsubr (&Swindow_inside_absolute_pixel_edges);