From fc68127ce8b273834bed951510d5bb39d12e5615 Mon Sep 17 00:00:00 2001 From: Yuuki Harano Date: Sat, 28 Nov 2020 21:55:18 +0900 Subject: [PATCH] Improve smooth scroll * src/pgtkterm.c (scroll_event): Accumulate deltas and calculate the number of lines. (pgtk_term_init): Set smooth scroll parameters. * src/pgtkterm.h (scroll): New members to store parameters. --- src/pgtkterm.c | 80 +++++++++++++++++++++++++++++++------------------- src/pgtkterm.h | 6 ++++ 2 files changed, 56 insertions(+), 30 deletions(-) diff --git a/src/pgtkterm.c b/src/pgtkterm.c index 0cf9bb84e76..f3675b49fb7 100644 --- a/src/pgtkterm.c +++ b/src/pgtkterm.c @@ -6530,6 +6530,8 @@ scroll_event (GtkWidget * widget, GdkEvent * event, gpointer * user_data) union buffered_input_event inev; struct frame *f, *frame; struct pgtk_display_info *dpyinfo; + GdkScrollDirection dir; + double delta_x, delta_y; EVENT_INIT (inev.ie); inev.ie.kind = NO_EVENT; @@ -6543,7 +6545,7 @@ scroll_event (GtkWidget * widget, GdkEvent * event, gpointer * user_data) else f = pgtk_any_window_to_frame (gtk_widget_get_window (widget)); - inev.ie.kind = WHEEL_EVENT; + inev.ie.kind = NO_EVENT; inev.ie.timestamp = event->scroll.time; inev.ie.modifiers = pgtk_gtk_to_emacs_modifiers (FRAME_DISPLAY_INFO (f), event->scroll.state); @@ -6552,50 +6554,64 @@ scroll_event (GtkWidget * widget, GdkEvent * event, gpointer * user_data) XSETFRAME (inev.ie.frame_or_window, f); inev.ie.arg = Qnil; - switch (event->scroll.direction) + if (gdk_event_get_scroll_direction (event, &dir)) { - case GDK_SCROLL_UP: - inev.ie.kind = WHEEL_EVENT; - inev.ie.modifiers |= up_modifier; - break; - case GDK_SCROLL_DOWN: - inev.ie.kind = WHEEL_EVENT; - inev.ie.modifiers |= down_modifier; - break; - case GDK_SCROLL_LEFT: - inev.ie.kind = HORIZ_WHEEL_EVENT; - inev.ie.modifiers |= up_modifier; - break; - case GDK_SCROLL_RIGHT: - inev.ie.kind = HORIZ_WHEEL_EVENT; - inev.ie.modifiers |= down_modifier; - break; - case GDK_SCROLL_SMOOTH: - if (event->scroll.delta_y >= 0.5) + switch (dir) { + case GDK_SCROLL_UP: + inev.ie.kind = WHEEL_EVENT; + inev.ie.modifiers |= up_modifier; + break; + case GDK_SCROLL_DOWN: inev.ie.kind = WHEEL_EVENT; inev.ie.modifiers |= down_modifier; + break; + case GDK_SCROLL_LEFT: + inev.ie.kind = HORIZ_WHEEL_EVENT; + inev.ie.modifiers |= up_modifier; + break; + case GDK_SCROLL_RIGHT: + inev.ie.kind = HORIZ_WHEEL_EVENT; + inev.ie.modifiers |= down_modifier; + break; } - else if (event->scroll.delta_y <= -0.5) + } + else if (gdk_event_get_scroll_deltas (event, &delta_x, &delta_y)) + { + dpyinfo->scroll.acc_x += delta_x; + dpyinfo->scroll.acc_y += delta_y; + if (dpyinfo->scroll.acc_y >= dpyinfo->scroll.y_per_line) { + int nlines = dpyinfo->scroll.acc_y / dpyinfo->scroll.y_per_line; + inev.ie.kind = WHEEL_EVENT; + inev.ie.modifiers |= down_modifier; + inev.ie.arg = make_fixnum(nlines); + dpyinfo->scroll.acc_y -= dpyinfo->scroll.y_per_line * nlines; + } + else if (dpyinfo->scroll.acc_y <= -dpyinfo->scroll.y_per_line) + { + int nlines = -dpyinfo->scroll.acc_y / dpyinfo->scroll.y_per_line; inev.ie.kind = WHEEL_EVENT; inev.ie.modifiers |= up_modifier; + inev.ie.arg = make_fixnum(nlines); + dpyinfo->scroll.acc_y -= -dpyinfo->scroll.y_per_line * nlines; } - else if (event->scroll.delta_x >= 0.5) + else if (dpyinfo->scroll.acc_x >= dpyinfo->scroll.x_per_char) { + int nchars = dpyinfo->scroll.acc_x / dpyinfo->scroll.x_per_char; inev.ie.kind = HORIZ_WHEEL_EVENT; - inev.ie.modifiers |= down_modifier; + inev.ie.modifiers |= up_modifier; + inev.ie.arg = make_fixnum(nchars); + dpyinfo->scroll.acc_x -= dpyinfo->scroll.x_per_char * nchars; } - else if (event->scroll.delta_x <= -0.5) + else if (dpyinfo->scroll.acc_x <= -dpyinfo->scroll.x_per_char) { + int nchars = -dpyinfo->scroll.acc_x / dpyinfo->scroll.x_per_char; inev.ie.kind = HORIZ_WHEEL_EVENT; - inev.ie.modifiers |= up_modifier; + inev.ie.modifiers |= down_modifier; + inev.ie.arg = make_fixnum(nchars); + dpyinfo->scroll.acc_x -= -dpyinfo->scroll.x_per_char * nchars; } - else - return TRUE; - break; - default: - return TRUE; } if (inev.ie.kind != NO_EVENT) @@ -6943,6 +6959,10 @@ pgtk_term_init (Lisp_Object display_name, char *resource_name) dpyinfo->resy = dpi; } + /* smooth scroll setting */ + dpyinfo->scroll.x_per_char = 2; + dpyinfo->scroll.y_per_line = 2; + x_setup_pointer_blanking (dpyinfo); xsettings_initialize (dpyinfo); diff --git a/src/pgtkterm.h b/src/pgtkterm.h index 09b3b21b170..5e71f939987 100644 --- a/src/pgtkterm.h +++ b/src/pgtkterm.h @@ -246,6 +246,12 @@ struct pgtk_display_info GtkIMContext *context; struct frame *focused_frame; } im; + + struct + { + double acc_x, acc_y; + double x_per_char, y_per_line; + } scroll; }; /* This is a chain of structures for all the PGTK displays currently in use. */ -- 2.39.5