]> git.eshelyaron.com Git - emacs.git/commitdiff
Improve smooth scroll
authorYuuki Harano <masm+github@masm11.me>
Sat, 28 Nov 2020 12:55:18 +0000 (21:55 +0900)
committerYuuki Harano <masm+github@masm11.me>
Sat, 28 Nov 2020 12:55:18 +0000 (21:55 +0900)
* 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
src/pgtkterm.h

index 0cf9bb84e76deb1169a8e2ec80a416c8f36cb64f..f3675b49fb7637b6b9199e93286e45c74d605736 100644 (file)
@@ -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);
index 09b3b21b170b33b716a649da7db2c26b6fbf58b7..5e71f9399870e0aca282c01b518b91c441863821 100644 (file)
@@ -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.  */