aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorEli Zaretskii2015-04-10 13:09:42 +0300
committerEli Zaretskii2015-04-10 13:09:42 +0300
commit5aed69af5e224bdaf38b3f890e57864f8435b4f5 (patch)
treee14642f6402fb193e4093d7bdaae095880951a86 /src
parent3638632f0bde06aac848655e28e28d188b48cd64 (diff)
downloademacs-5aed69af5e224bdaf38b3f890e57864f8435b4f5.tar.gz
emacs-5aed69af5e224bdaf38b3f890e57864f8435b4f5.zip
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.
Diffstat (limited to 'src')
-rw-r--r--src/window.c41
1 files changed, 31 insertions, 10 deletions
diff --git a/src/window.c b/src/window.c
index d59616d0545..55fcb8cf02f 100644
--- a/src/window.c
+++ b/src/window.c
@@ -5799,10 +5799,9 @@ and redisplay normally--don't erase and redraw the frame. */)
5799 this_scroll_margin 5799 this_scroll_margin
5800 = max (0, min (scroll_margin, w->total_lines / 4)); 5800 = max (0, min (scroll_margin, w->total_lines / 4));
5801 5801
5802 /* Handle centering on a graphical frame specially. Such frames can 5802 /* Don't use redisplay code for initial frames, as the necessary
5803 have variable-height lines and centering point on the basis of 5803 data structures might not be set up yet then. */
5804 line counts would lead to strange effects. */ 5804 if (!FRAME_INITIAL_P (XFRAME (w->frame)))
5805 if (FRAME_WINDOW_P (XFRAME (w->frame)))
5806 { 5805 {
5807 if (center_p) 5806 if (center_p)
5808 { 5807 {
@@ -5824,9 +5823,11 @@ and redisplay normally--don't erase and redraw the frame. */)
5824 ptrdiff_t nlines = min (PTRDIFF_MAX, -iarg); 5823 ptrdiff_t nlines = min (PTRDIFF_MAX, -iarg);
5825 int extra_line_spacing; 5824 int extra_line_spacing;
5826 int h = window_box_height (w); 5825 int h = window_box_height (w);
5826 int ht = window_internal_height (w);
5827 void *itdata = bidi_shelve_cache (); 5827 void *itdata = bidi_shelve_cache ();
5828 5828
5829 iarg = - max (-iarg, this_scroll_margin); 5829 nlines = clip_to_bounds (this_scroll_margin + 1, nlines,
5830 ht - this_scroll_margin);
5830 5831
5831 SET_TEXT_POS (pt, PT, PT_BYTE); 5832 SET_TEXT_POS (pt, PT, PT_BYTE);
5832 start_display (&it, w, pt); 5833 start_display (&it, w, pt);
@@ -5890,13 +5891,33 @@ and redisplay normally--don't erase and redraw the frame. */)
5890 } 5891 }
5891 else 5892 else
5892 { 5893 {
5893 struct position pos; 5894 struct it it;
5895 struct text_pos pt;
5896 ptrdiff_t nlines = min (PTRDIFF_MAX, iarg);
5897 int ht = window_internal_height (w);
5898 void *itdata = bidi_shelve_cache ();
5899
5900 nlines = clip_to_bounds (this_scroll_margin, nlines,
5901 ht - this_scroll_margin - 1);
5902
5903 SET_TEXT_POS (pt, PT, PT_BYTE);
5904 start_display (&it, w, pt);
5894 5905
5895 iarg = max (iarg, this_scroll_margin); 5906 /* Move to the beginning of screen line containing PT. */
5907 move_it_by_lines (&it, 0);
5908
5909 /* Move back to find the point which is ARG screen lines above PT. */
5910 if (nlines > 0)
5911 {
5912 it.current_y = 0;
5913 it.vpos = 0;
5914 move_it_by_lines (&it, -nlines);
5915 }
5896 5916
5897 pos = *vmotion (PT, PT_BYTE, -iarg, w); 5917 charpos = IT_CHARPOS (it);
5898 charpos = pos.bufpos; 5918 bytepos = IT_BYTEPOS (it);
5899 bytepos = pos.bytepos; 5919
5920 bidi_unshelve_cache (itdata, 0);
5900 } 5921 }
5901 } 5922 }
5902 else 5923 else