Created
January 31, 2015 05:21
-
-
Save galundin/736d7331a626a0deda13 to your computer and use it in GitHub Desktop.
xf86-input-synaptics driver hack to implement relative circular scrolling
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
From 8dadbeab277773242e1869bd7c764bd0ddf28063 Mon Sep 17 00:00:00 2001 | |
From: Andrew Lundin <galundin@yahoo.com> | |
Date: Fri, 30 Jan 2015 22:55:01 -0600 | |
Subject: [PATCH] Change circular scrolling from absolute to relative. | |
--- | |
src/synaptics.c | 41 ++++++++++++++++++++++++++++++++--------- | |
src/synapticsstr.h | 5 ++++- | |
2 files changed, 36 insertions(+), 10 deletions(-) | |
diff --git a/src/synaptics.c b/src/synaptics.c | |
index e6a90f2..03db536 100644 | |
--- a/src/synaptics.c | |
+++ b/src/synaptics.c | |
@@ -2627,17 +2627,40 @@ HandleScrolling(SynapticsPrivate * priv, struct SynapticsHwState *hw, | |
} | |
} | |
if (priv->circ_scroll_on) { | |
- /* + = counter clockwise, - = clockwise */ | |
- double delta = para->scroll_dist_circ; | |
- double diff = diffa(priv->scroll.last_a, angle(priv, hw->x, hw->y)); | |
- | |
- if (delta >= 0.005 && diff != 0.0) { | |
+ int dx = hw->x - priv->scroll.last_x; | |
+ int dy = hw->y - priv->scroll.last_y; | |
+ double d = sqrt(dx * dx + dy * dy); | |
+ double distance_factor = log(1 + fmin(d, priv->scroll.last_d) / 100); | |
+ double angle = atan2(-dy, dx); | |
+ double delta = diffa(priv->scroll.last_a, angle) * distance_factor; | |
+ double abs_delta = fabs(delta); | |
+ double filtered_delta = priv->scroll.filtered_delta; | |
+ double adaptive_delta = priv->scroll.adaptive_delta; | |
+ double divergence = fabs(adaptive_delta - filtered_delta); | |
+ double delta_error = delta - filtered_delta; | |
+ delta_error *= delta_error; | |
+ | |
+ /* adaptive filter */ | |
+ double weight = divergence * (1 + abs_delta) / (1 + delta_error * 100); | |
+ if (weight > 1) | |
+ weight = 1; | |
+ double decay = 1 + (hw->millis - priv->scroll.last_millis) / 50.0; | |
+ adaptive_delta = delta * weight + adaptive_delta * (1 - weight) / decay; | |
+ | |
+ double delta_unit = para->scroll_dist_circ; | |
+ if (delta_unit >= 0.005 && adaptive_delta != 0.0) { | |
+ double output_delta = adaptive_delta; | |
if (priv->circ_scroll_vert) | |
- priv->scroll.delta_y -= diff / delta * para->scroll_dist_vert; | |
+ priv->scroll.delta_y -= output_delta / delta_unit * para->scroll_dist_vert; | |
else | |
- priv->scroll.delta_x -= diff / delta * para->scroll_dist_horiz; | |
- priv->scroll.last_a = angle(priv, hw->x, hw->y); | |
- } | |
+ priv->scroll.delta_x -= output_delta / delta_unit * para->scroll_dist_horiz; | |
+ } | |
+ priv->scroll.last_x = hw->x; | |
+ priv->scroll.last_y = hw->y; | |
+ priv->scroll.last_a = angle; | |
+ priv->scroll.last_d = d; | |
+ priv->scroll.filtered_delta = (delta + filtered_delta) / 2; | |
+ priv->scroll.adaptive_delta = adaptive_delta; | |
} | |
if (priv->scroll.coast_speed_y) { | |
diff --git a/src/synapticsstr.h b/src/synapticsstr.h | |
index a17e39b..3bb3d9a 100644 | |
--- a/src/synapticsstr.h | |
+++ b/src/synapticsstr.h | |
@@ -255,7 +255,10 @@ struct _SynapticsPrivateRec { | |
int last_y; /* last y-scroll position */ | |
double delta_x; /* accumulated horiz scroll delta */ | |
double delta_y; /* accumulated vert scroll delta */ | |
- double last_a; /* last angle-scroll position */ | |
+ double last_a; /* angle of last segment of circular path */ | |
+ double last_d; /* length of last segment of circular path */ | |
+ double filtered_delta; /* naive filter for error estimation */ | |
+ double adaptive_delta; /* adaptive filtered circular delta */ | |
CARD32 last_millis; /* time last scroll event posted */ | |
double coast_speed_x; /* Horizontal coasting speed in scrolls/s */ | |
double coast_speed_y; /* Vertical coasting speed in scrolls/s */ | |
-- | |
1.7.10.4 |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment