Commit 5aed69af authored by Eli Zaretskii's avatar Eli Zaretskii

Fix 'recenter' when visual-line-mode is turned on

* src/window.c (Frecenter): Use the same code for GUI and TTY
frames alike; use vmotion only for "initial" frames.  This is
because vmotion doesn't support visual-line-mode.  Rewrite the
'iarg >= 0' case to use move_it_* functions instead of using
vmotion, for the same reason.  Fix the clipping of the argument
value to support scroll-margin in all cases and avoid unwarranted
recentering.  Reported by Milan Stanojević <milanst@gmail.com> in
http://lists.gnu.org/archive/html/help-gnu-emacs/2015-04/msg00092.html,
which see.
parent 3638632f
...@@ -5799,10 +5799,9 @@ and redisplay normally--don't erase and redraw the frame. */) ...@@ -5799,10 +5799,9 @@ and redisplay normally--don't erase and redraw the frame. */)
this_scroll_margin this_scroll_margin
= max (0, min (scroll_margin, w->total_lines / 4)); = max (0, min (scroll_margin, w->total_lines / 4));
/* Handle centering on a graphical frame specially. Such frames can /* Don't use redisplay code for initial frames, as the necessary
have variable-height lines and centering point on the basis of data structures might not be set up yet then. */
line counts would lead to strange effects. */ if (!FRAME_INITIAL_P (XFRAME (w->frame)))
if (FRAME_WINDOW_P (XFRAME (w->frame)))
{ {
if (center_p) if (center_p)
{ {
...@@ -5824,9 +5823,11 @@ and redisplay normally--don't erase and redraw the frame. */) ...@@ -5824,9 +5823,11 @@ and redisplay normally--don't erase and redraw the frame. */)
ptrdiff_t nlines = min (PTRDIFF_MAX, -iarg); ptrdiff_t nlines = min (PTRDIFF_MAX, -iarg);
int extra_line_spacing; int extra_line_spacing;
int h = window_box_height (w); int h = window_box_height (w);
int ht = window_internal_height (w);
void *itdata = bidi_shelve_cache (); void *itdata = bidi_shelve_cache ();
iarg = - max (-iarg, this_scroll_margin); nlines = clip_to_bounds (this_scroll_margin + 1, nlines,
ht - this_scroll_margin);
SET_TEXT_POS (pt, PT, PT_BYTE); SET_TEXT_POS (pt, PT, PT_BYTE);
start_display (&it, w, pt); start_display (&it, w, pt);
...@@ -5890,13 +5891,33 @@ and redisplay normally--don't erase and redraw the frame. */) ...@@ -5890,13 +5891,33 @@ and redisplay normally--don't erase and redraw the frame. */)
} }
else else
{ {
struct position pos; struct it it;
struct text_pos pt;
ptrdiff_t nlines = min (PTRDIFF_MAX, iarg);
int ht = window_internal_height (w);
void *itdata = bidi_shelve_cache ();
nlines = clip_to_bounds (this_scroll_margin, nlines,
ht - this_scroll_margin - 1);
SET_TEXT_POS (pt, PT, PT_BYTE);
start_display (&it, w, pt);
iarg = max (iarg, this_scroll_margin); /* Move to the beginning of screen line containing PT. */
move_it_by_lines (&it, 0);
/* Move back to find the point which is ARG screen lines above PT. */
if (nlines > 0)
{
it.current_y = 0;
it.vpos = 0;
move_it_by_lines (&it, -nlines);
}
pos = *vmotion (PT, PT_BYTE, -iarg, w); charpos = IT_CHARPOS (it);
charpos = pos.bufpos; bytepos = IT_BYTEPOS (it);
bytepos = pos.bytepos;
bidi_unshelve_cache (itdata, 0);
} }
} }
else else
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment