/* 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 Free Software Foundation, Inc.
This file is part of GNU Emacs.
You should have received a copy of the GNU General Public License
along with GNU Emacs; see the file COPYING. If not, write to
-the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
-Boston, MA 02111-1307, USA. */
+the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+Boston, MA 02110-1301, USA. */
#include <config.h>
#include "lisp.h"
/* Check if we have a v/hchild with a v/hchild. In that case remove
one of them. */
-
+
if (! NILP (par->vchild) && ! NILP (XWINDOW (par->vchild)->vchild))
{
p = XWINDOW (par->vchild);
/* 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
+ && (NILP (Vscroll_preserve_screen_position)
+ || EQ (Vscroll_preserve_screen_position, Qt)))
/* We found PT at a legitimate height. Leave it alone. */
;
else if (preserve_y >= 0)
/* 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 - this_scroll_margin - 1, -1,
+ (it.last_visible_y - CURRENT_HEADER_LINE_HEIGHT (w)
+ - this_scroll_margin - 1),
+ -1,
MOVE_TO_POS | MOVE_TO_Y);
/* Save our position, in case it's correct. */
partial_p = it.current_y > it.last_visible_y;
}
- if (charpos == PT && !partial_p)
+ if (charpos == PT && !partial_p
+ && (NILP (Vscroll_preserve_screen_position)
+ || EQ (Vscroll_preserve_screen_position, Qt)))
/* We found PT before we found the display margin, so PT is ok. */
;
else if (preserve_y >= 0)
the window-scroll-functions. */
w->force_start = Qt;
- if (whole && !NILP (Vscroll_preserve_screen_position))
+ if (!NILP (Vscroll_preserve_screen_position)
+ && (whole || !EQ (Vscroll_preserve_screen_position, Qt)))
{
SET_PT_BOTH (pos, pos_byte);
Fvertical_motion (make_number (original_vpos), window);
struct buffer *obuf = current_buffer;
int center_p = 0;
int charpos, bytepos;
+ int iarg;
+ int this_scroll_margin;
/* If redisplay is suppressed due to an error, try again. */
obuf->display_error_modiff = 0;
{
arg = Fprefix_numeric_value (arg);
CHECK_NUMBER (arg);
+ iarg = XINT (arg);
}
set_buffer_internal (buf);
+ /* Do this after making BUF current
+ in case scroll_margin is buffer-local. */
+ this_scroll_margin = max (0, scroll_margin);
+ this_scroll_margin = min (this_scroll_margin,
+ XFASTINT (w->total_lines) / 4);
+
/* Handle centering on a graphical frame specially. Such frames can
have variable-height lines and centering point on the basis of
line counts would lead to strange effects. */
charpos = IT_CHARPOS (it);
bytepos = IT_BYTEPOS (it);
}
- else if (XINT (arg) < 0)
+ else if (iarg < 0)
{
struct it it;
struct text_pos pt;
- int nlines = - XINT (arg);
+ int nlines = -iarg;
int extra_line_spacing;
int h = window_box_height (w);
+ iarg = - max (-iarg, this_scroll_margin);
+
SET_TEXT_POS (pt, PT, PT_BYTE);
start_display (&it, w, pt);
else
{
struct position pos;
- pos = *vmotion (PT, - XINT (arg), w);
+
+ iarg = max (iarg, this_scroll_margin);
+
+ pos = *vmotion (PT, -iarg, w);
charpos = pos.bufpos;
bytepos = pos.bytepos;
}
int ht = window_internal_height (w);
if (center_p)
- arg = make_number (ht / 2);
- else if (XINT (arg) < 0)
- arg = make_number (XINT (arg) + ht);
+ iarg = ht / 2;
+ else if (iarg < 0)
+ iarg += ht;
+
+ /* Don't let it get into the margin at either top or bottom. */
+ iarg = max (iarg, this_scroll_margin);
+ iarg = min (iarg, ht - this_scroll_margin - 1);
- pos = *vmotion (PT, - XINT (arg), w);
+ pos = *vmotion (PT, - iarg, w);
charpos = pos.bufpos;
bytepos = pos.bytepos;
}
struct window *w = XWINDOW (selected_window);
int lines, start;
Lisp_Object window;
+#if 0
+ int this_scroll_margin;
+#endif
window = selected_window;
start = marker_position (w->start);
Fgoto_char (w->start);
lines = displayed_window_lines (w);
+
+#if 0
+ this_scroll_margin = max (0, scroll_margin);
+ this_scroll_margin = min (this_scroll_margin, lines / 4);
+#endif
+
if (NILP (arg))
XSETFASTINT (arg, lines / 2);
else
{
- arg = Fprefix_numeric_value (arg);
- if (XINT (arg) < 0)
- XSETINT (arg, XINT (arg) + lines);
+ int iarg = XINT (Fprefix_numeric_value (arg));
+
+ if (iarg < 0)
+ iarg = iarg + lines;
+
+#if 0 /* This code would prevent move-to-window-line from moving point
+ to a place inside the scroll margins (which would cause the
+ next redisplay to scroll). I wrote this code, but then concluded
+ it is probably better not to install it. However, it is here
+ inside #if 0 so as not to lose it. -- rms. */
+
+ /* Don't let it get into the margin at either top or bottom. */
+ iarg = max (iarg, this_scroll_margin);
+ iarg = min (iarg, lines - this_scroll_margin - 1);
+#endif
+
+ arg = make_number (iarg);
}
/* Skip past a partially visible first line. */
Lisp_Object scroll_bar_width, vertical_scroll_bar_type;
};
-#define SAVED_WINDOW_VECTOR_SIZE 24 /* Arg to Fmake_vector */
-
#define SAVED_WINDOW_N(swv,n) \
((struct saved_window *) (XVECTOR ((swv)->contents[(n)])))
data->saved_windows = tem;
for (i = 0; i < n_windows; i++)
XVECTOR (tem)->contents[i]
- = Fmake_vector (make_number (SAVED_WINDOW_VECTOR_SIZE), Qnil);
+ = Fmake_vector (make_number (VECSIZE (struct saved_window)), Qnil);
save_window_save (FRAME_ROOT_WINDOW (f), XVECTOR (tem), 0);
XSETWINDOW_CONFIGURATION (tem, data);
return (tem);
reserve for the left marginal area. Optional third arg RIGHT-WIDTH
does the same for the right marginal area. A nil width parameter
means no margin. */)
- (window, left, right)
- Lisp_Object window, left, right;
+ (window, left_width, right_width)
+ Lisp_Object window, left_width, right_width;
{
struct window *w = decode_window (window);
/* Translate negative or zero widths to nil.
Margins that are too wide have to be checked elsewhere. */
- if (!NILP (left))
+ if (!NILP (left_width))
{
- CHECK_NUMBER (left);
- if (XINT (left) <= 0)
- left = Qnil;
+ CHECK_NUMBER (left_width);
+ if (XINT (left_width) <= 0)
+ left_width = Qnil;
}
- if (!NILP (right))
+ if (!NILP (right_width))
{
- CHECK_NUMBER (right);
- if (XINT (right) <= 0)
- right = Qnil;
+ CHECK_NUMBER (right_width);
+ if (XINT (right_width) <= 0)
+ right_width = Qnil;
}
- if (!EQ (w->left_margin_cols, left)
- || !EQ (w->right_margin_cols, right))
+ if (!EQ (w->left_margin_cols, left_width)
+ || !EQ (w->right_margin_cols, right_width))
{
- w->left_margin_cols = left;
- w->right_margin_cols = right;
+ w->left_margin_cols = left_width;
+ w->right_margin_cols = right_width;
adjust_window_margins (w);
If optional fourth arg OUTSIDE-MARGINS is non-nil, draw the fringes
outside of the display margins. By default, fringes are drawn between
display marginal areas and the text area. */)
- (window, left, right, outside_margins)
- Lisp_Object window, left, right, outside_margins;
+ (window, left_width, right_width, outside_margins)
+ Lisp_Object window, left_width, right_width, outside_margins;
{
struct window *w = decode_window (window);
- if (!NILP (left))
- CHECK_NATNUM (left);
- if (!NILP (right))
- CHECK_NATNUM (right);
+ if (!NILP (left_width))
+ CHECK_NATNUM (left_width);
+ if (!NILP (right_width))
+ CHECK_NATNUM (right_width);
- if (!EQ (w->left_fringe_width, left)
- || !EQ (w->right_fringe_width, right)
+ if (!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;
- w->right_fringe_width = right;
+ w->left_fringe_width = left_width;
+ w->right_fringe_width = right_width;
w->fringes_outside_margins = outside_margins;
adjust_window_margins (w);
DEFVAR_LISP ("scroll-preserve-screen-position",
&Vscroll_preserve_screen_position,
- doc: /* *Non-nil means scroll commands move point to keep its screen line unchanged.
-This is only when it is impossible to keep point fixed and still
-scroll as specified. */);
+ doc: /* *Controls if scroll commands move point to keep its screen line unchanged.
+A value of nil means point does not keep its screen position except
+at the scroll margin or window boundary respectively.
+A value of t means point keeps its screen position if the scroll
+command moved it vertically out of the window, e.g. when scrolling
+by full screens.
+Any other value means point always keeps its screen position. */);
Vscroll_preserve_screen_position = Qnil;
DEFVAR_LISP ("window-configuration-change-hook",