[PATCH v3 16/23] Revise palm check logic
Daniel Stone
daniel at fooishbar.org
Thu Jun 23 15:12:51 PDT 2011
From: Derek Foreman <derek.foreman at collabora.co.uk>
Make the palm-check logic more stable and reliable, and make sure that
any palms are blocked for the duration of their presses.
Signed-off-by: Derek Foreman <derek.foreman at collabora.co.uk>
Reviewed-by: Daniel Stone <daniel at fooishbar.org>
Reviewed-by: Peter Hutterer <peter.hutterer at who-t.net>
---
src/synaptics.c | 54 +++++++++++++++++++++++++++------------------------
src/synapticsstr.h | 3 +-
2 files changed, 30 insertions(+), 27 deletions(-)
v3: Only trigger on sufficient width and pressure, not just either.
diff --git a/src/synaptics.c b/src/synaptics.c
index 0ce8024..0b15056 100644
--- a/src/synaptics.c
+++ b/src/synaptics.c
@@ -1358,12 +1358,16 @@ SynapticsDetectFinger(SynapticsPrivate *priv, struct SynapticsHwState *hw)
enum FingerState finger;
/* finger detection thru pressure and threshold */
+ if (hw->z < para->finger_low)
+ return FS_UNTOUCHED;
+
+ if (priv->finger_state == FS_BLOCKED)
+ return FS_BLOCKED;
+
if (hw->z > para->finger_press && priv->finger_state < FS_PRESSED)
finger = FS_PRESSED;
- else if (hw->z > para->finger_high && priv->finger_state < FS_TOUCHED)
+ else if (hw->z > para->finger_high && priv->finger_state == FS_UNTOUCHED)
finger = FS_TOUCHED;
- else if (hw->z < para->finger_low && priv->finger_state > FS_UNTOUCHED)
- finger = FS_UNTOUCHED;
else
finger = priv->finger_state;
@@ -1371,17 +1375,16 @@ SynapticsDetectFinger(SynapticsPrivate *priv, struct SynapticsHwState *hw)
return finger;
/* palm detection */
- if (finger) {
- if ((hw->z > para->palm_min_z) && (hw->fingerWidth > para->palm_min_width))
- priv->palm = TRUE;
- } else {
- priv->palm = FALSE;
- }
- if (hw->x == 0)
+
+ if ((hw->z > para->palm_min_z) && (hw->fingerWidth > para->palm_min_width))
+ return FS_BLOCKED;
+
+ if (hw->x == 0 || priv->finger_state == FS_UNTOUCHED)
priv->avg_width = 0;
else
priv->avg_width += (hw->fingerWidth - priv->avg_width + 1) / 2;
- if (finger && !priv->finger_state) {
+
+ if (finger != FS_UNTOUCHED && priv->finger_state == FS_UNTOUCHED) {
int safe_width = MAX(hw->fingerWidth, priv->avg_width);
if (hw->numFingers > 1 || /* more than one finger -> not a palm */
@@ -1398,9 +1401,6 @@ SynapticsDetectFinger(SynapticsPrivate *priv, struct SynapticsHwState *hw)
}
priv->prev_z = hw->z;
- if (priv->palm)
- finger = FS_UNTOUCHED;
-
return finger;
}
@@ -1542,12 +1542,12 @@ HandleTapProcessing(SynapticsPrivate *priv, struct SynapticsHwState *hw,
edge_type edge;
int delay = 1000000000;
- if (priv->palm)
+ if (priv->finger_state == FS_BLOCKED)
return delay;
- touch = finger && !priv->finger_state;
- release = !finger && priv->finger_state;
- move = (finger &&
+ touch = finger >= FS_TOUCHED && priv->finger_state == FS_UNTOUCHED;
+ release = finger == FS_UNTOUCHED && priv->finger_state >= FS_TOUCHED;
+ move = (finger >= FS_TOUCHED &&
(priv->tap_max_fingers <= ((priv->horiz_scroll_twofinger_on || priv->vert_scroll_twofinger_on)? 2 : 1)) &&
((abs(hw->x - priv->touch_on.x) >= para->tap_move) ||
(abs(hw->y - priv->touch_on.y) >= para->tap_move)));
@@ -1984,7 +1984,7 @@ ComputeDeltas(SynapticsPrivate *priv, const struct SynapticsHwState *hw,
}
}
- if (!inside_area || !moving_state || priv->palm ||
+ if (!inside_area || !moving_state || priv->finger_state == FS_BLOCKED ||
priv->vert_scroll_edge_on || priv->horiz_scroll_edge_on ||
priv->vert_scroll_twofinger_on || priv->horiz_scroll_twofinger_on ||
priv->circ_scroll_on || priv->prevFingers != hw->numFingers)
@@ -2107,7 +2107,7 @@ HandleScrolling(SynapticsPrivate *priv, struct SynapticsHwState *hw,
sd->left = sd->right = sd->up = sd->down = 0;
- if (priv->synpara.touchpad_off == 2) {
+ if ((priv->synpara.touchpad_off == 2) || (priv->finger_state == FS_BLOCKED)) {
stop_coasting(priv);
priv->circ_scroll_on = FALSE;
priv->vert_scroll_edge_on = FALSE;
@@ -2118,7 +2118,7 @@ HandleScrolling(SynapticsPrivate *priv, struct SynapticsHwState *hw,
}
/* scroll detection */
- if (finger && !priv->finger_state) {
+ if (finger && priv->finger_state == FS_UNTOUCHED) {
stop_coasting(priv);
if (para->circular_scrolling) {
if ((para->circular_trigger == 0 && edge) ||
@@ -2156,7 +2156,7 @@ HandleScrolling(SynapticsPrivate *priv, struct SynapticsHwState *hw,
}
}
}
- if (finger && !priv->finger_state) {
+ if (finger && priv->finger_state == FS_UNTOUCHED) {
if (!priv->vert_scroll_twofinger_on && !priv->horiz_scroll_twofinger_on) {
if ((para->scroll_edge_vert) && (para->scroll_dist_vert != 0) &&
(edge & RIGHT_EDGE)) {
@@ -2589,7 +2589,7 @@ HandleState(InputInfoPtr pInfo, struct SynapticsHwState *hw, CARD32 now,
{
SynapticsPrivate *priv = (SynapticsPrivate *) (pInfo->private);
SynapticsParameters *para = &priv->synpara;
- int finger;
+ enum FingerState finger;
int dx, dy, buttons, id;
edge_type edge = NO_EDGE;
int change;
@@ -2643,7 +2643,10 @@ HandleState(InputInfoPtr pInfo, struct SynapticsHwState *hw, CARD32 now,
/* no edge or finger detection outside of area */
if (inside_active_area) {
edge = edge_detection(priv, hw->x, hw->y);
- finger = SynapticsDetectFinger(priv, hw);
+ if (!from_timer)
+ finger = SynapticsDetectFinger(priv, hw);
+ else
+ finger = priv->finger_state;
}
/* tap and drag detection. Needs to be performed even if the finger is in
@@ -2655,7 +2658,8 @@ HandleState(InputInfoPtr pInfo, struct SynapticsHwState *hw, CARD32 now,
if (inside_active_area)
{
/* Don't bother about scrolling in the dead area of the touchpad. */
- timeleft = HandleScrolling(priv, hw, edge, finger, &scroll);
+ timeleft = HandleScrolling(priv, hw, edge, (finger >= FS_TOUCHED),
+ &scroll);
if (timeleft > 0)
delay = MIN(delay, timeleft);
diff --git a/src/synapticsstr.h b/src/synapticsstr.h
index 67ca27b..596ea54 100644
--- a/src/synapticsstr.h
+++ b/src/synapticsstr.h
@@ -52,6 +52,7 @@ typedef struct _SynapticsMoveHist
} SynapticsMoveHistRec;
enum FingerState { /* Note! The order matters. Compared with < operator. */
+ FS_BLOCKED = -1,
FS_UNTOUCHED = 0, /* this is 0 so it's the initialized value. */
FS_TOUCHED = 1,
FS_PRESSED = 2,
@@ -233,8 +234,6 @@ typedef struct _SynapticsPrivateRec
int repeatButtons; /* buttons for repeat */
int nextRepeat; /* Time when to trigger next auto repeat event */
int lastButtons; /* last state of the buttons */
- int palm; /* Set to true when palm detected, reset to false when
- palm/finger contact disappears */
int prev_z; /* previous z value, for palm detection */
int prevFingers; /* previous numFingers, for transition detection */
int avg_width; /* weighted average of previous fingerWidth values */
--
1.7.5.4
More information about the xorg-devel
mailing list