X-Git-Url: https://code.delx.au/gnu-emacs/blobdiff_plain/f92ac2e82ed199d6f25d2a59508e08addb1150ac..44782dea433ce567bf69612a74b62432d68cd4b3:/src/window.c
diff --git a/src/window.c b/src/window.c
index 0fcf82d43f..733cf75d13 100644
--- a/src/window.c
+++ b/src/window.c
@@ -1,14 +1,14 @@
/* Window creation, deletion and examination for GNU Emacs.
Does not include redisplay.
- Copyright (C) 1985-1987, 1993-1998, 2000-2015 Free Software
+ Copyright (C) 1985-1987, 1993-1998, 2000-2016 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 3 of the License, or
-(at your option) any later version.
+the Free Software Foundation, either version 3 of the License, or (at
+your option) any later version.
GNU Emacs is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
@@ -23,11 +23,9 @@ along with GNU Emacs. If not, see . */
#include
#include "lisp.h"
-#include "character.h"
#include "buffer.h"
#include "keyboard.h"
#include "keymap.h"
-#include "menu.h"
#include "frame.h"
#include "window.h"
#include "commands.h"
@@ -36,8 +34,8 @@ along with GNU Emacs. If not, see . */
#include "disptab.h"
#include "dispextern.h"
#include "blockinput.h"
-#include "intervals.h"
#include "termhooks.h" /* For FRAME_TERMINAL. */
+#include "xwidget.h"
#ifdef HAVE_WINDOW_SYSTEM
#include TERM_HEADER
#endif /* HAVE_WINDOW_SYSTEM */
@@ -208,6 +206,20 @@ wset_combination (struct window *w, bool horflag, Lisp_Object val)
w->horizontal = horflag;
}
+static void
+wset_update_mode_line (struct window *w)
+{
+ /* If this window is the selected window on its frame, set the
+ global variable update_mode_lines, so that x_consider_frame_title
+ will consider this frame's title for redisplay. */
+ Lisp_Object fselected_window = XFRAME (WINDOW_FRAME (w))->selected_window;
+
+ if (WINDOWP (fselected_window) && XWINDOW (fselected_window) == w)
+ update_mode_lines = 42;
+ else
+ w->update_mode_line = true;
+}
+
/* True if leaf window W doesn't reflect the actual state
of displayed buffer due to its text or overlays change. */
@@ -641,7 +653,7 @@ DEFUN ("window-combination-limit", Fwindow_combination_limit, Swindow_combinatio
WINDOW must be a valid window used in horizontal or vertical combination.
If the return value is nil, child windows of WINDOW can be recombined with
WINDOW's siblings. A return value of t means that child windows of
-WINDOW are never \(re-)combined with WINDOW's siblings. */)
+WINDOW are never (re-)combined with WINDOW's siblings. */)
(Lisp_Object window)
{
struct window *w;
@@ -1101,186 +1113,6 @@ end-trigger value is reset to nil. */)
return value;
}
-DEFUN ("window-edges", Fwindow_edges, Swindow_edges, 0, 1, 0,
- doc: /* Return a list of the edge coordinates of WINDOW.
-WINDOW must be a valid window and defaults to the selected one.
-
-The returned list has the form (LEFT TOP RIGHT BOTTOM). TOP and BOTTOM
-count by lines, and LEFT and RIGHT count by columns, all relative to 0,
-0 at top left corner of frame.
-
-RIGHT is one more than the rightmost column occupied by WINDOW. BOTTOM
-is one more than the bottommost row occupied by WINDOW. The edges
-include the space used by WINDOW's scroll bar, display margins, fringes,
-header line, and/or mode line. For the edges of just the text area, use
-`window-inside-edges'. */)
- (Lisp_Object window)
-{
- register struct window *w = decode_valid_window (window);
-
- return list4i (WINDOW_LEFT_EDGE_COL (w), WINDOW_TOP_EDGE_LINE (w),
- WINDOW_RIGHT_EDGE_COL (w), WINDOW_BOTTOM_EDGE_LINE (w));
-}
-
-DEFUN ("window-pixel-edges", Fwindow_pixel_edges, Swindow_pixel_edges, 0, 1, 0,
- doc: /* Return a list of the edge pixel coordinates of WINDOW.
-WINDOW must be a valid window and defaults to the selected one.
-
-The returned list has the form (LEFT TOP RIGHT BOTTOM), all relative to
-0, 0 at the top left corner of the frame.
-
-RIGHT is one more than the rightmost x position occupied by WINDOW.
-BOTTOM is one more than the bottommost y position occupied by WINDOW.
-The pixel edges include the space used by WINDOW's scroll bar, display
-margins, fringes, header line, and/or mode line. For the pixel edges
-of just the text area, use `window-inside-pixel-edges'. */)
- (Lisp_Object window)
-{
- register struct window *w = decode_valid_window (window);
-
- return list4i (WINDOW_LEFT_EDGE_X (w), WINDOW_TOP_EDGE_Y (w),
- WINDOW_RIGHT_EDGE_X (w), WINDOW_BOTTOM_EDGE_Y (w));
-}
-
-static void
-calc_absolute_offset (struct window *w, int *add_x, int *add_y)
-{
- struct frame *f = XFRAME (w->frame);
- *add_y = f->top_pos;
-#ifdef FRAME_MENUBAR_HEIGHT
- *add_y += FRAME_MENUBAR_HEIGHT (f);
-#endif
-#ifdef FRAME_TOOLBAR_TOP_HEIGHT
- *add_y += FRAME_TOOLBAR_TOP_HEIGHT (f);
-#elif defined (FRAME_TOOLBAR_HEIGHT)
- *add_y += FRAME_TOOLBAR_HEIGHT (f);
-#endif
-#ifdef FRAME_NS_TITLEBAR_HEIGHT
- *add_y += FRAME_NS_TITLEBAR_HEIGHT (f);
-#endif
- *add_x = f->left_pos;
-#ifdef FRAME_TOOLBAR_LEFT_WIDTH
- *add_x += FRAME_TOOLBAR_LEFT_WIDTH (f);
-#endif
-}
-
-DEFUN ("window-absolute-pixel-edges", Fwindow_absolute_pixel_edges,
- Swindow_absolute_pixel_edges, 0, 1, 0,
- doc: /* Return a list of the edge pixel coordinates of WINDOW.
-WINDOW must be a valid window and defaults to the selected one.
-
-The returned list has the form (LEFT TOP RIGHT BOTTOM), all relative to
-0, 0 at the top left corner of the display.
-
-RIGHT is one more than the rightmost x position occupied by WINDOW.
-BOTTOM is one more than the bottommost y position occupied by WINDOW.
-The pixel edges include the space used by WINDOW's scroll bar, display
-margins, fringes, header line, and/or mode line. For the pixel edges
-of just the text area, use `window-inside-absolute-pixel-edges'. */)
- (Lisp_Object window)
-{
- register struct window *w = decode_valid_window (window);
- int add_x, add_y;
-
- calc_absolute_offset (w, &add_x, &add_y);
-
- return list4i (WINDOW_LEFT_EDGE_X (w) + add_x,
- WINDOW_TOP_EDGE_Y (w) + add_y,
- WINDOW_RIGHT_EDGE_X (w) + add_x,
- WINDOW_BOTTOM_EDGE_Y (w) + add_y);
-}
-
-DEFUN ("window-inside-edges", Fwindow_inside_edges, Swindow_inside_edges, 0, 1, 0,
- doc: /* Return a list of the edge coordinates of WINDOW.
-WINDOW must be a live window and defaults to the selected one.
-
-The returned list has the form (LEFT TOP RIGHT BOTTOM). TOP and BOTTOM
-count by lines, and LEFT and RIGHT count by columns, all relative to 0,
-0 at top left corner of frame.
-
-RIGHT is one more than the rightmost column of WINDOW's text area.
-BOTTOM is one more than the bottommost row of WINDOW's text area. The
-inside edges do not include the space used by the WINDOW's scroll bar,
-display margins, fringes, header line, and/or mode line. */)
- (Lisp_Object window)
-{
- register struct window *w = decode_live_window (window);
-
- return list4i ((WINDOW_BOX_LEFT_EDGE_COL (w)
- + WINDOW_LEFT_MARGIN_COLS (w)
- + ((WINDOW_LEFT_FRINGE_WIDTH (w)
- + WINDOW_FRAME_COLUMN_WIDTH (w) - 1)
- / WINDOW_FRAME_COLUMN_WIDTH (w))),
- (WINDOW_TOP_EDGE_LINE (w)
- + WINDOW_HEADER_LINE_LINES (w)),
- (WINDOW_BOX_RIGHT_EDGE_COL (w)
- - WINDOW_RIGHT_MARGIN_COLS (w)
- - ((WINDOW_RIGHT_FRINGE_WIDTH (w)
- + WINDOW_FRAME_COLUMN_WIDTH (w) - 1)
- / WINDOW_FRAME_COLUMN_WIDTH (w))),
- (WINDOW_BOTTOM_EDGE_LINE (w)
- - WINDOW_MODE_LINE_LINES (w)));
-}
-
-DEFUN ("window-inside-pixel-edges", Fwindow_inside_pixel_edges, Swindow_inside_pixel_edges, 0, 1, 0,
- doc: /* Return a list of the edge pixel coordinates of WINDOW's text area.
-WINDOW must be a live window and defaults to the selected one.
-
-The returned list has the form (LEFT TOP RIGHT BOTTOM), all relative to
-(0,0) at the top left corner of the frame's window area.
-
-RIGHT is one more than the rightmost x position of WINDOW's text area.
-BOTTOM is one more than the bottommost y position of WINDOW's text area.
-The inside edges do not include the space used by WINDOW's scroll bar,
-display margins, fringes, header line, and/or mode line. */)
- (Lisp_Object window)
-{
- register struct window *w = decode_live_window (window);
-
- return list4i ((WINDOW_BOX_LEFT_EDGE_X (w)
- + WINDOW_LEFT_MARGIN_WIDTH (w)
- + WINDOW_LEFT_FRINGE_WIDTH (w)),
- (WINDOW_TOP_EDGE_Y (w)
- + WINDOW_HEADER_LINE_HEIGHT (w)),
- (WINDOW_BOX_RIGHT_EDGE_X (w)
- - WINDOW_RIGHT_MARGIN_WIDTH (w)
- - WINDOW_RIGHT_FRINGE_WIDTH (w)),
- (WINDOW_BOTTOM_EDGE_Y (w)
- - WINDOW_MODE_LINE_HEIGHT (w)));
-}
-
-DEFUN ("window-inside-absolute-pixel-edges",
- Fwindow_inside_absolute_pixel_edges,
- Swindow_inside_absolute_pixel_edges, 0, 1, 0,
- doc: /* Return a list of the edge pixel coordinates of WINDOW's text area.
-WINDOW must be a live window and defaults to the selected one.
-
-The returned list has the form (LEFT TOP RIGHT BOTTOM), all relative to
-(0,0) at the top left corner of the frame's window area.
-
-RIGHT is one more than the rightmost x position of WINDOW's text area.
-BOTTOM is one more than the bottommost y position of WINDOW's text area.
-The inside edges do not include the space used by WINDOW's scroll bar,
-display margins, fringes, header line, and/or mode line. */)
- (Lisp_Object window)
-{
- register struct window *w = decode_live_window (window);
- int add_x, add_y;
-
- calc_absolute_offset (w, &add_x, &add_y);
-
- return list4i ((WINDOW_BOX_LEFT_EDGE_X (w)
- + WINDOW_LEFT_MARGIN_WIDTH (w)
- + WINDOW_LEFT_FRINGE_WIDTH (w) + add_x),
- (WINDOW_TOP_EDGE_Y (w)
- + WINDOW_HEADER_LINE_HEIGHT (w) + add_y),
- (WINDOW_BOX_RIGHT_EDGE_X (w)
- - WINDOW_RIGHT_MARGIN_WIDTH (w)
- - WINDOW_RIGHT_FRINGE_WIDTH (w) + add_x),
- (WINDOW_BOTTOM_EDGE_Y (w)
- - WINDOW_MODE_LINE_HEIGHT (w) + add_y));
-}
-
/* Test if the character at column X, row Y is within window W.
If it is not, return ON_NOTHING;
if it is on the window's vertical divider, return
@@ -1471,10 +1303,18 @@ window_relative_x_coord (struct window *w, enum window_part part, int x)
+ window_box_width (w, RIGHT_MARGIN_AREA)
+ ((WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w))
? WINDOW_RIGHT_FRINGE_WIDTH (w) : 0));
- }
- /* ON_SCROLL_BAR, ON_NOTHING, and ON_VERTICAL_BORDER: */
- return 0;
+ case ON_NOTHING:
+ case ON_VERTICAL_BORDER:
+ case ON_VERTICAL_SCROLL_BAR:
+ case ON_HORIZONTAL_SCROLL_BAR:
+ case ON_RIGHT_DIVIDER:
+ case ON_BOTTOM_DIVIDER:
+ return 0;
+
+ default:
+ emacs_abort ();
+ }
}
@@ -1748,7 +1588,11 @@ if it isn't already recorded. */)
|| b->clip_changed
|| b->prevent_redisplay_optimizations_p
|| window_outdated (w))
- && !noninteractive)
+ /* Don't call display routines if we didn't yet create any real
+ frames, because the glyph matrices are not yet allocated in
+ that case. This could happen in some code that runs in the
+ daemon during initialization (e.g., see bug#20565). */
+ && !(noninteractive || FRAME_INITIAL_P (WINDOW_XFRAME (w))))
{
struct text_pos startp;
struct it it;
@@ -1837,7 +1681,7 @@ overriding motion of point in order to display at this exact start. */)
w->start_at_line_beg = false;
if (NILP (noforce))
w->force_start = true;
- w->update_mode_line = true;
+ wset_update_mode_line (w);
/* Bug#15957. */
w->window_end_valid = false;
wset_redisplay (w);
@@ -1854,8 +1698,10 @@ Return nil if that position is scrolled vertically out of view. 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.
+specifies either the first position displayed on the last visible
+screen line in WINDOW, or the end-of-buffer position, whichever comes
+first. 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,
the return value is a list of 2 or 6 elements (X Y [RTOP RBOT ROWH VPOS]),
@@ -2809,7 +2655,6 @@ window_loop (enum window_loop type, Lisp_Object obj, bool mini,
Lisp_Object window, windows, best_window, frame_arg;
bool frame_best_window_flag = false;
struct frame *f;
- struct gcpro gcpro1;
/* If we're only looping through windows on a particular frame,
frame points to that frame. If we're looping through windows
@@ -2843,7 +2688,6 @@ window_loop (enum window_loop type, Lisp_Object obj, bool mini,
window = FRAME_SELECTED_WINDOW (SELECTED_FRAME ());
windows = window_list_1 (window, mini ? Qt : Qnil, frame_arg);
- GCPRO1 (windows);
best_window = Qnil;
for (; CONSP (windows); windows = XCDR (windows))
@@ -2871,7 +2715,7 @@ window_loop (enum window_loop type, Lisp_Object obj, bool mini,
{
if (EQ (window, selected_window))
/* Preferably return the selected window. */
- RETURN_UNGCPRO (window);
+ return window;
else if (EQ (XWINDOW (window)->frame, selected_frame)
&& !frame_best_window_flag)
/* Prefer windows on the current frame (but don't
@@ -2937,7 +2781,6 @@ window_loop (enum window_loop type, Lisp_Object obj, bool mini,
}
}
- UNGCPRO;
return best_window;
}
@@ -3443,7 +3286,8 @@ set_window_buffer (Lisp_Object window, Lisp_Object buffer,
/* Maybe we could move this into the `if' but it's not obviously safe and
I doubt it's worth the trouble. */
wset_redisplay (w);
- w->update_mode_line = true;
+
+ wset_update_mode_line (w);
/* We must select BUFFER to run the window-scroll-functions and to look up
the buffer-local value of Vwindow_point_insertion_type. */
@@ -4127,9 +3971,11 @@ values. */)
}
-/* Resize frame F's windows when number of lines of F is set to SIZE.
- HORFLAG means resize windows when number of columns of F is set to
- SIZE. PIXELWISE means to interpret SIZE as pixels. */
+/* Resize frame F's windows when F's width or height is set to SIZE.
+ If HORFLAG is zero, F's width was set to SIZE, otherwise its height
+ was set. SIZE is interpreted in F's canonical character units
+ (a.k.a. "columns" or "lines"), unless PIXELWISE is non-zero, which
+ means to interpret SIZE in pixel units. */
void
resize_frame_windows (struct frame *f, int size, bool horflag, bool pixelwise)
{
@@ -4140,7 +3986,6 @@ resize_frame_windows (struct frame *f, int size, bool horflag, bool pixelwise)
/* old_size is the old size of the frame's root window. */
int old_size = horflag ? r->total_cols : r->total_lines;
int old_pixel_size = horflag ? r->pixel_width : r->pixel_height;
- int old_pixel_top = r->pixel_top;
/* new_size is the new size of the frame's root window. */
int new_size, new_pixel_size;
int unit = horflag ? FRAME_COLUMN_WIDTH (f) : FRAME_LINE_HEIGHT (f);
@@ -4170,11 +4015,8 @@ resize_frame_windows (struct frame *f, int size, bool horflag, bool pixelwise)
new_pixel_size = new_size * unit;
}
- r->top_line = FRAME_TOP_MARGIN (f);
- r->pixel_top = FRAME_TOP_MARGIN_HEIGHT (f);
-
if (new_pixel_size == old_pixel_size
- && r->pixel_top == old_pixel_top)
+ && (horflag || r->pixel_top == FRAME_TOP_MARGIN_HEIGHT (f)))
;
else if (WINDOW_LEAF_P (r))
/* For a leaf root window just set the size. */
@@ -4185,6 +4027,9 @@ resize_frame_windows (struct frame *f, int size, bool horflag, bool pixelwise)
}
else
{
+ r->top_line = FRAME_TOP_MARGIN (f);
+ r->pixel_top = FRAME_TOP_MARGIN_HEIGHT (f);
+
r->total_lines = new_size;
r->pixel_height = new_pixel_size;
}
@@ -4192,6 +4037,12 @@ resize_frame_windows (struct frame *f, int size, bool horflag, bool pixelwise)
{
Lisp_Object delta;
+ if (!horflag)
+ {
+ r->top_line = FRAME_TOP_MARGIN (f);
+ r->pixel_top = FRAME_TOP_MARGIN_HEIGHT (f);
+ }
+
if (pixelwise)
XSETINT (delta, new_pixel_size - old_pixel_size);
else
@@ -4216,37 +4067,6 @@ resize_frame_windows (struct frame *f, int size, bool horflag, bool pixelwise)
{
window_resize_apply (r, horflag);
window_pixel_to_total (r->frame, horflag ? Qt : Qnil);
-#if false /* Let's try without safe sizes and/or killing other windows. */
- }
- else
- {
- /* Finally, try with "safe" minimum sizes. */
- resize_root_window (root, delta, horflag ? Qt : Qnil, Qsafe,
- pixelwise ? Qt : Qnil);
- if (window_resize_check (r, horflag)
- && new_pixel_size == XINT (r->new_pixel))
- {
- window_resize_apply (r, horflag);
- window_pixel_to_total (r->frame, horflag ? Qt : Qnil);
- }
- else
- {
- /* We lost. Delete all windows but the frame's
- selected one. */
- root = f->selected_window;
- Fdelete_other_windows_internal (root, Qnil);
- if (horflag)
- {
- XWINDOW (root)->total_cols = new_size;
- XWINDOW (root)->pixel_width = new_pixel_size;
- }
- else
- {
- XWINDOW (root)->total_lines = new_size;
- XWINDOW (root)->pixel_height = new_pixel_size;
- }
- }
-#endif /* false */
}
}
}
@@ -4256,7 +4076,7 @@ resize_frame_windows (struct frame *f, int size, bool horflag, bool pixelwise)
m = XWINDOW (mini);
if (horflag)
{
- m->total_cols = size;
+ m->total_cols = new_size;
m->pixel_width = new_pixel_size;
}
else
@@ -4269,6 +4089,7 @@ resize_frame_windows (struct frame *f, int size, bool horflag, bool pixelwise)
}
}
+ FRAME_WINDOW_SIZES_CHANGED (f) = true;
fset_redisplay (f);
}
@@ -4550,6 +4371,7 @@ Signal an error when WINDOW is the only window on its frame. */)
/* Block input. */
block_input ();
+ xwidget_view_delete_all_in_window (w);
window_resize_apply (p, horflag);
/* If this window is referred to by the dpyinfo's mouse
highlight, invalidate that slot to be safe (Bug#9904). */
@@ -4707,6 +4529,7 @@ grow_mini_window (struct window *w, int delta, bool pixelwise)
/* Enforce full redisplay of the frame. */
/* FIXME: Shouldn't window--resize-root-window-vertically do it? */
fset_redisplay (f);
+ FRAME_WINDOW_SIZES_CHANGED (f) = true;
adjust_frame_glyphs (f);
unblock_input ();
}
@@ -4746,6 +4569,7 @@ shrink_mini_window (struct window *w, bool pixelwise)
/* Enforce full redisplay of the frame. */
/* FIXME: Shouldn't window--resize-root-window-vertically do it? */
fset_redisplay (f);
+ FRAME_WINDOW_SIZES_CHANGED (f) = true;
adjust_frame_glyphs (f);
unblock_input ();
}
@@ -4989,7 +4813,7 @@ window_scroll_pixel_based (Lisp_Object window, int n, bool whole, bool noerror)
set_marker_restricted (w->start, make_number (spos),
w->contents);
w->start_at_line_beg = true;
- w->update_mode_line = true;
+ wset_update_mode_line (w);
/* Set force_start so that redisplay_window will run the
window-scroll-functions. */
w->force_start = true;
@@ -5137,7 +4961,7 @@ window_scroll_pixel_based (Lisp_Object window, int n, bool whole, bool noerror)
IT_BYTEPOS (it));
bytepos = marker_byte_position (w->start);
w->start_at_line_beg = (pos == BEGV || FETCH_BYTE (bytepos - 1) == '\n');
- w->update_mode_line = true;
+ wset_update_mode_line (w);
/* Set force_start so that redisplay_window will run the
window-scroll-functions. */
w->force_start = true;
@@ -5159,27 +4983,34 @@ window_scroll_pixel_based (Lisp_Object window, int n, bool whole, bool noerror)
if (n > 0)
{
+ int last_y = it.last_visible_y - this_scroll_margin - 1;
+
/* We moved the window start towards ZV, so PT may be now
in the scroll margin at the top. */
move_it_to (&it, PT, -1, -1, -1, MOVE_TO_POS);
- if (IT_CHARPOS (it) == PT && it.current_y >= this_scroll_margin
+ if (IT_CHARPOS (it) == PT
+ && it.current_y >= this_scroll_margin
+ && it.current_y <= last_y - WINDOW_HEADER_LINE_HEIGHT (w)
&& (NILP (Vscroll_preserve_screen_position)
|| EQ (Vscroll_preserve_screen_position, Qt)))
/* We found PT at a legitimate height. Leave it alone. */
;
- 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. */
- move_it_to (&it, -1,
- window_scroll_pixel_based_preserve_x,
- (window_scroll_pixel_based_preserve_y
- - WINDOW_WANTS_HEADER_LINE_P (w)),
- -1, MOVE_TO_Y | MOVE_TO_X);
- SET_PT_BOTH (IT_CHARPOS (it), IT_BYTEPOS (it));
- }
else
{
+ if (window_scroll_pixel_based_preserve_y >= 0)
+ {
+ /* Don't enter the scroll margin at the end of the window. */
+ int goal_y = min (last_y, window_scroll_pixel_based_preserve_y);
+
+ /* If we have a header line, take account of it. This
+ is necessary because we set it.current_y to 0, above. */
+ move_it_to (&it, -1,
+ window_scroll_pixel_based_preserve_x,
+ goal_y - WINDOW_HEADER_LINE_HEIGHT (w),
+ -1, MOVE_TO_Y | MOVE_TO_X);
+ }
+
+ /* Get out of the scroll margin at the top of the window. */
while (it.current_y < this_scroll_margin)
{
int prev = it.current_y;
@@ -5203,7 +5034,7 @@ window_scroll_pixel_based (Lisp_Object window, int n, bool whole, bool noerror)
/* We moved the window start towards BEGV, so PT may be now
in the scroll margin at the bottom. */
move_it_to (&it, PT, -1,
- (it.last_visible_y - CURRENT_HEADER_LINE_HEIGHT (w)
+ (it.last_visible_y - WINDOW_HEADER_LINE_HEIGHT (w)
- this_scroll_margin - 1),
-1,
MOVE_TO_POS | MOVE_TO_Y);
@@ -5254,14 +5085,20 @@ window_scroll_pixel_based (Lisp_Object window, int n, bool whole, bool noerror)
;
else if (window_scroll_pixel_based_preserve_y >= 0)
{
+ int goal_y = min (it.last_visible_y - this_scroll_margin - 1,
+ window_scroll_pixel_based_preserve_y);
+
+ /* Don't let the preserved screen Y coordinate put us inside
+ any of the two margins. */
+ if (goal_y < this_scroll_margin)
+ goal_y = this_scroll_margin;
SET_TEXT_POS_FROM_MARKER (start, w->start);
start_display (&it, w, start);
/* 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, window_scroll_pixel_based_preserve_x,
- window_scroll_pixel_based_preserve_y, -1,
- MOVE_TO_Y | MOVE_TO_X);
+ goal_y, -1, MOVE_TO_Y | MOVE_TO_X);
SET_PT_BOTH (IT_CHARPOS (it), IT_BYTEPOS (it));
}
else
@@ -5371,12 +5208,13 @@ window_scroll_line_based (Lisp_Object window, int n, bool whole, bool noerror)
set_marker_restricted_both (w->start, w->contents, pos, pos_byte);
w->start_at_line_beg = !NILP (bolp);
- w->update_mode_line = true;
+ wset_update_mode_line (w);
/* Set force_start so that redisplay_window will run
the window-scroll-functions. */
w->force_start = true;
if (!NILP (Vscroll_preserve_screen_position)
+ && this_scroll_margin == 0
&& (whole || !EQ (Vscroll_preserve_screen_position, Qt)))
{
SET_PT_BOTH (pos, pos_byte);
@@ -5402,8 +5240,16 @@ window_scroll_line_based (Lisp_Object window, int n, bool whole, bool noerror)
marker_byte_position (opoint_marker));
else if (!NILP (Vscroll_preserve_screen_position))
{
+ int nlines = window_scroll_preserve_vpos;
+
SET_PT_BOTH (pos, pos_byte);
- Fvertical_motion (original_pos, window, Qnil);
+ if (window_scroll_preserve_vpos < this_scroll_margin)
+ nlines = this_scroll_margin;
+ else if (window_scroll_preserve_vpos
+ >= w->total_lines - this_scroll_margin)
+ nlines = w->total_lines - this_scroll_margin - 1;
+ Fvertical_motion (Fcons (make_number (window_scroll_preserve_hpos),
+ make_number (nlines)), window, Qnil);
}
else
SET_PT (top_margin);
@@ -5429,8 +5275,16 @@ window_scroll_line_based (Lisp_Object window, int n, bool whole, bool noerror)
{
if (!NILP (Vscroll_preserve_screen_position))
{
+ int nlines = window_scroll_preserve_vpos;
+
SET_PT_BOTH (pos, pos_byte);
- Fvertical_motion (original_pos, window, Qnil);
+ if (window_scroll_preserve_vpos < this_scroll_margin)
+ nlines = this_scroll_margin;
+ else if (window_scroll_preserve_vpos
+ >= ht - this_scroll_margin)
+ nlines = ht - this_scroll_margin - 1;
+ Fvertical_motion (Fcons (make_number (window_scroll_preserve_hpos),
+ make_number (nlines)), window, Qnil);
}
else
Fvertical_motion (make_number (-1), window, Qnil);
@@ -6778,7 +6632,6 @@ apply_window_adjustment (struct window *w)
eassert (w);
clear_glyph_matrix (w->current_matrix);
w->window_end_valid = false;
- windows_or_buffers_changed = 30;
wset_redisplay (w);
adjust_frame_glyphs (XFRAME (WINDOW_FRAME (w)));
}
@@ -7325,7 +7178,6 @@ syms_of_window (void)
DEFSYM (Qwindow_size, "window-size");
DEFSYM (Qtemp_buffer_show_hook, "temp-buffer-show-hook");
DEFSYM (Qabove, "above");
- DEFSYM (Qbelow, "below");
DEFSYM (Qclone_of, "clone-of");
DEFSYM (Qfloor, "floor");
DEFSYM (Qceiling, "ceiling");
@@ -7411,7 +7263,7 @@ resizing a window preferably resizes one adjacent window only.
If this variable is t, splitting a window tries to get the space
proportionally from all windows in the same combination. This also
-allows to split a window that is otherwise too small or of fixed size.
+allows splitting a window that is otherwise too small or of fixed size.
Resizing and deleting a window proportionally resize all windows in the
same combination.
@@ -7545,18 +7397,12 @@ displayed after a scrolling operation to be somewhat inaccurate. */);
defsubr (&Sset_window_hscroll);
defsubr (&Swindow_redisplay_end_trigger);
defsubr (&Sset_window_redisplay_end_trigger);
- defsubr (&Swindow_edges);
- defsubr (&Swindow_pixel_edges);
- defsubr (&Swindow_absolute_pixel_edges);
defsubr (&Swindow_mode_line_height);
defsubr (&Swindow_header_line_height);
defsubr (&Swindow_right_divider_width);
defsubr (&Swindow_bottom_divider_width);
defsubr (&Swindow_scroll_bar_width);
defsubr (&Swindow_scroll_bar_height);
- defsubr (&Swindow_inside_edges);
- defsubr (&Swindow_inside_pixel_edges);
- defsubr (&Swindow_inside_absolute_pixel_edges);
defsubr (&Scoordinates_in_window_p);
defsubr (&Swindow_at);
defsubr (&Swindow_point);