/* 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;
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;
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;
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)
{
if (!NILP (XWINDOW (window)->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,
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;
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. */
|| 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
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.
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.