commit 4f2001a6c39e051d22db3d88377e5de414aac97d
parent 1619b579fa72a45217ceeab062cd5dc6c9961a37
Author: lumidify <nobody@lumidify.org>
Date: Sat, 30 Oct 2021 09:11:58 +0200
Sort of fix cursor movement when scrolling whole screens
Diffstat:
2 files changed, 16 insertions(+), 8 deletions(-)
diff --git a/buffer.h b/buffer.h
@@ -33,8 +33,7 @@ struct ledit_buffer {
int trailing_bytes; /* same thing, but with bytes instead of utf8 characters */
int end_of_soft_line; /* used to handle special behavior at end end of soft line */
long total_height; /* total pixel height of all lines */
- double display_offset; /* current pixel offset of viewport - this
- * is a double to make scrolling smoother */
+ long display_offset; /* current pixel offset of viewport */
int selecting;
ledit_range sel; /* current selection; all entries -1 if no selection */
ledit_cache *cache;
diff --git a/keys_basic.c b/keys_basic.c
@@ -345,8 +345,8 @@ delete_selection(ledit_buffer *buffer) {
/* get the number of times a command should be repeated, or -1 if anything
invalid was on the stack - this is for commands that just take a repeat
- count and nothin else (cursor movement keys are different because they
- can use other elements on the key stack to, for instance, call a callback
+ count and nothing else (cursor movement keys are different because they
+ can use other elements on the key stack too, for instance call a callback
as is done for deletion */
static int
get_key_repeat(void) {
@@ -368,13 +368,23 @@ get_key_repeat(void) {
return num;
}
-/* movement is multiplied to the window height and added to the display offset
- the cursor is moved to the top if movement is upwards, to the bottom otherwise */
+/* movement is multiplied with the window height and the result is added to the display offset
+ the cursor is moved to the bottom if movement is upwards, to the top otherwise
+ (unless the screen is already at the very top or bottom - then it is the other way around) */
static void
move_screen(ledit_buffer *buffer, int movement) {
int w, h;
ledit_window_get_textview_size(buffer->window, &w, &h);
+ /* FIXME: overflow */
long total = movement * (long)h;
+ /* new pixel position of cursor */
+ /* FIXME: in certain cases, just using h as the y position could make it
+ move slightly further down than a screen once ensure_cursor_shown is called */
+ int y = movement > 0 ? 0 : h;
+ if (buffer->display_offset + total < 0)
+ y = 0;
+ else if (buffer->display_offset + total + h > buffer->total_height)
+ y = h;
ledit_buffer_scroll(buffer, buffer->display_offset + total);
ledit_buffer_wipe_line_cursor_attrs(buffer, buffer->cur_line);
/* try to keep current x position of cursor */
@@ -382,9 +392,8 @@ move_screen(ledit_buffer *buffer, int movement) {
int x, softline;
/* FIXME: properly document what uses PANGO_SCALE and what not */
ledit_pos_to_x_softline(ll, buffer->cur_index, &x, &softline);
- /* if movement is up, move cursor to top, else to bottom of current screen */
ledit_xy_to_line_byte(
- buffer, x / PANGO_SCALE, movement < 0 ? 0 : h, 0,
+ buffer, x / PANGO_SCALE, y, 0,
&buffer->cur_line, &buffer->cur_index
);
ledit_buffer_set_line_cursor_attrs(buffer, buffer->cur_line, buffer->cur_index);