summaryrefslogtreecommitdiff
path: root/src/xdisp.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/xdisp.c')
-rw-r--r--src/xdisp.c106
1 files changed, 46 insertions, 60 deletions
diff --git a/src/xdisp.c b/src/xdisp.c
index 168922ef06b..0e329dfe6e9 100644
--- a/src/xdisp.c
+++ b/src/xdisp.c
@@ -9859,6 +9859,32 @@ move_it_by_lines (struct it *it, ptrdiff_t dvpos)
}
}
+int
+partial_line_height (struct it *it_origin)
+{
+ int partial_height;
+ void *it_data = NULL;
+ struct it it;
+ SAVE_IT (it, *it_origin, it_data);
+ move_it_to (&it, ZV, -1, it.last_visible_y, -1,
+ MOVE_TO_POS | MOVE_TO_Y);
+ if (it.what == IT_EOB)
+ {
+ int vis_height = it.last_visible_y - it.current_y;
+ int height = it.ascent + it.descent;
+ partial_height = (vis_height < height) ? vis_height : 0;
+ }
+ else
+ {
+ int last_line_y = it.current_y;
+ move_it_by_lines (&it, 1);
+ partial_height = (it.current_y > it.last_visible_y)
+ ? it.last_visible_y - last_line_y : 0;
+ }
+ RESTORE_IT (&it, &it, it_data);
+ return partial_height;
+}
+
/* Return true if IT points into the middle of a display vector. */
bool
@@ -15316,7 +15342,6 @@ try_scrolling (Lisp_Object window, bool just_this_one_p,
bool temp_scroll_step, bool last_line_misfit)
{
struct window *w = XWINDOW (window);
- struct frame *f = XFRAME (w->frame);
struct text_pos pos, startp;
struct it it;
int this_scroll_margin, scroll_max, rc, height;
@@ -15327,8 +15352,6 @@ try_scrolling (Lisp_Object window, bool just_this_one_p,
/* We will never try scrolling more than this number of lines. */
int scroll_limit = SCROLL_LIMIT;
int frame_line_height = default_line_pixel_height (w);
- int window_total_lines
- = WINDOW_TOTAL_LINES (w) * FRAME_LINE_HEIGHT (f) / frame_line_height;
#ifdef GLYPH_DEBUG
debug_method_add (w, "try_scrolling");
@@ -15336,13 +15359,7 @@ try_scrolling (Lisp_Object window, bool just_this_one_p,
SET_TEXT_POS_FROM_MARKER (startp, w->start);
- /* Compute scroll margin height in pixels. We scroll when point is
- within this distance from the top or bottom of the window. */
- if (scroll_margin > 0)
- this_scroll_margin = min (scroll_margin, window_total_lines / 4)
- * frame_line_height;
- else
- this_scroll_margin = 0;
+ this_scroll_margin = window_scroll_margin (w, MARGIN_IN_PIXELS);
/* Force arg_scroll_conservatively to have a reasonable value, to
avoid scrolling too far away with slow move_it_* functions. Note
@@ -15377,7 +15394,8 @@ try_scrolling (Lisp_Object window, bool just_this_one_p,
/* Compute the pixel ypos of the scroll margin, then move IT to
either that ypos or PT, whichever comes first. */
start_display (&it, w, startp);
- scroll_margin_y = it.last_visible_y - this_scroll_margin
+ scroll_margin_y = it.last_visible_y - partial_line_height (&it)
+ - this_scroll_margin
- frame_line_height * extra_scroll_margin_lines;
move_it_to (&it, PT, -1, scroll_margin_y - 1, -1,
(MOVE_TO_POS | MOVE_TO_Y));
@@ -15816,23 +15834,12 @@ try_cursor_movement (Lisp_Object window, struct text_pos startp,
{
int this_scroll_margin, top_scroll_margin;
struct glyph_row *row = NULL;
- int frame_line_height = default_line_pixel_height (w);
- int window_total_lines
- = WINDOW_TOTAL_LINES (w) * FRAME_LINE_HEIGHT (f) / frame_line_height;
#ifdef GLYPH_DEBUG
debug_method_add (w, "cursor movement");
#endif
- /* Scroll if point within this distance from the top or bottom
- of the window. This is a pixel value. */
- if (scroll_margin > 0)
- {
- this_scroll_margin = min (scroll_margin, window_total_lines / 4);
- this_scroll_margin *= frame_line_height;
- }
- else
- this_scroll_margin = 0;
+ this_scroll_margin = window_scroll_margin (w, MARGIN_IN_PIXELS);
top_scroll_margin = this_scroll_margin;
if (WINDOW_WANTS_HEADER_LINE_P (w))
@@ -16280,7 +16287,7 @@ redisplay_window (Lisp_Object window, bool just_this_one_p)
int centering_position = -1;
bool last_line_misfit = false;
ptrdiff_t beg_unchanged, end_unchanged;
- int frame_line_height;
+ int frame_line_height, margin;
bool use_desired_matrix;
void *itdata = NULL;
@@ -16310,6 +16317,8 @@ redisplay_window (Lisp_Object window, bool just_this_one_p)
restart:
reconsider_clip_changes (w);
frame_line_height = default_line_pixel_height (w);
+ margin = window_scroll_margin (w, MARGIN_IN_LINES);
+
/* Has the mode line to be updated? */
update_mode_line = (w->update_mode_line
@@ -16614,10 +16623,7 @@ redisplay_window (Lisp_Object window, bool just_this_one_p)
/* Some people insist on not letting point enter the scroll
margin, even though this part handles windows that didn't
scroll at all. */
- int window_total_lines
- = WINDOW_TOTAL_LINES (w) * FRAME_LINE_HEIGHT (f) / frame_line_height;
- int margin = min (scroll_margin, window_total_lines / 4);
- int pixel_margin = margin * frame_line_height;
+ int pixel_margin = margin * frame_line_height;
bool header_line = WINDOW_WANTS_HEADER_LINE_P (w);
/* Note: We add an extra FRAME_LINE_HEIGHT, because the loop
@@ -16901,12 +16907,6 @@ redisplay_window (Lisp_Object window, bool just_this_one_p)
it.current_y = it.last_visible_y;
if (centering_position < 0)
{
- int window_total_lines
- = WINDOW_TOTAL_LINES (w) * FRAME_LINE_HEIGHT (f) / frame_line_height;
- int margin
- = scroll_margin > 0
- ? min (scroll_margin, window_total_lines / 4)
- : 0;
ptrdiff_t margin_pos = CHARPOS (startp);
Lisp_Object aggressive;
bool scrolling_up;
@@ -17150,10 +17150,6 @@ redisplay_window (Lisp_Object window, bool just_this_one_p)
{
int window_total_lines
= WINDOW_TOTAL_LINES (w) * FRAME_LINE_HEIGHT (f) / frame_line_height;
- int margin =
- scroll_margin > 0
- ? min (scroll_margin, window_total_lines / 4)
- : 0;
bool move_down = w->cursor.vpos >= window_total_lines / 2;
move_it_by_lines (&it, move_down ? margin + 1 : -(margin + 1));
@@ -17359,7 +17355,6 @@ try_window (Lisp_Object window, struct text_pos pos, int flags)
struct it it;
struct glyph_row *last_text_row = NULL;
struct frame *f = XFRAME (w->frame);
- int frame_line_height = default_line_pixel_height (w);
/* Make POS the new window start. */
set_marker_both (w->start, Qnil, CHARPOS (pos), BYTEPOS (pos));
@@ -17385,17 +17380,7 @@ try_window (Lisp_Object window, struct text_pos pos, int flags)
if ((flags & TRY_WINDOW_CHECK_MARGINS)
&& !MINI_WINDOW_P (w))
{
- int this_scroll_margin;
- int window_total_lines
- = WINDOW_TOTAL_LINES (w) * FRAME_LINE_HEIGHT (f) / frame_line_height;
-
- if (scroll_margin > 0)
- {
- this_scroll_margin = min (scroll_margin, window_total_lines / 4);
- this_scroll_margin *= frame_line_height;
- }
- else
- this_scroll_margin = 0;
+ int this_scroll_margin = window_scroll_margin (w, MARGIN_IN_PIXELS);
if ((w->cursor.y >= 0 /* not vscrolled */
&& w->cursor.y < this_scroll_margin
@@ -18679,15 +18664,8 @@ try_window_id (struct window *w)
/* Don't let the cursor end in the scroll margins. */
{
- int this_scroll_margin, cursor_height;
- int frame_line_height = default_line_pixel_height (w);
- int window_total_lines
- = WINDOW_TOTAL_LINES (w) * FRAME_LINE_HEIGHT (it.f) / frame_line_height;
-
- this_scroll_margin =
- max (0, min (scroll_margin, window_total_lines / 4));
- this_scroll_margin *= frame_line_height;
- cursor_height = MATRIX_ROW (w->desired_matrix, w->cursor.vpos)->height;
+ int this_scroll_margin = window_scroll_margin (w, MARGIN_IN_PIXELS);
+ int cursor_height = MATRIX_ROW (w->desired_matrix, w->cursor.vpos)->height;
if ((w->cursor.y < this_scroll_margin
&& CHARPOS (start) > BEGV)
@@ -22635,7 +22613,7 @@ move_elt_to_front (Lisp_Object elt, Lisp_Object list)
else
prev = tail;
tail = XCDR (tail);
- QUIT;
+ maybe_quit ();
}
/* Not found--return unchanged LIST. */
@@ -31569,6 +31547,14 @@ Recenter the window whenever point gets within this many lines
of the top or bottom of the window. */);
scroll_margin = 0;
+ DEFVAR_LISP ("maximum-scroll-margin", Vmaximum_scroll_margin,
+ doc: /* Maximum effective value of `scroll-margin'.
+Given as a fraction of the current window's lines. The value should
+be a floating point number between 0.0 and 0.5. The effective maximum
+is limited to (/ (1- window-lines) 2). Non-float values for this
+variable are ignored and the default 0.25 is used instead. */);
+ Vmaximum_scroll_margin = make_float (0.25);
+
DEFVAR_LISP ("display-pixels-per-inch", Vdisplay_pixels_per_inch,
doc: /* Pixels per inch value for non-window system displays.
Value is a number or a cons (WIDTH-DPI . HEIGHT-DPI). */);