summaryrefslogtreecommitdiff
path: root/src/synaptics.c
diff options
context:
space:
mode:
authorHans de Goede <hdegoede@redhat.com>2014-02-21 10:31:41 +0100
committerPeter Hutterer <peter.hutterer@who-t.net>2014-02-26 14:42:15 +1000
commit3adaf4623845dce54129b6474f4f8f2966f9bc47 (patch)
treebda6f1f3cd151f94b7f03492f03f460c9c681864 /src/synaptics.c
parenteffeee86c1c286cd09ab750efc4932790dd560dd (diff)
Don't report motion inside soft-button areas
Unless the motion has started outside the soft-button area. Note that we must start reporting motions regardless of whether we think we're in the button area or not as soon as we've switched to using cumulative coordinates, since then the coordinates are no longer absolute. This fixes the reporting of unintended motion just before a click in a soft button area which sometimes causes mis-clicks. Signed-off-by: Hans de Goede <hdegoede@redhat.com> Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
Diffstat (limited to 'src/synaptics.c')
-rw-r--r--src/synaptics.c68
1 files changed, 66 insertions, 2 deletions
diff --git a/src/synaptics.c b/src/synaptics.c
index 6c27e19..494101b 100644
--- a/src/synaptics.c
+++ b/src/synaptics.c
@@ -1031,6 +1031,7 @@ SynapticsReset(SynapticsPrivate * priv)
priv->count_packet_finger = 0;
priv->finger_state = FS_UNTOUCHED;
priv->last_motion_millis = 0;
+ priv->inside_button_area = FALSE;
priv->tap_state = TS_START;
priv->tap_button = 0;
priv->tap_button_state = TBS_BUTTON_UP;
@@ -1531,6 +1532,56 @@ is_inside_sec_middlebutton_area(SynapticsParameters * para, int x, int y)
return is_inside_button_area(para, TOP_MIDDLE_BUTTON_AREA, x, y);
}
+static Bool
+is_inside_top_or_bottom_button_area(SynapticsParameters * para, int offset,
+ int x, int y)
+{
+ Bool inside_area = TRUE;
+ Bool right_valid, middle_valid;
+ int top, bottom;
+
+ /* We don't have a left button area, so we only check the y axis */
+ right_valid = para->softbutton_areas[offset][TOP] ||
+ para->softbutton_areas[offset][BOTTOM];
+ middle_valid = para->softbutton_areas[offset + 1][TOP] ||
+ para->softbutton_areas[offset + 1][BOTTOM];
+
+ if (!right_valid && !middle_valid)
+ return FALSE;
+
+ /* Check both buttons are horizontally aligned */
+ if (right_valid && middle_valid && (
+ para->softbutton_areas[offset][TOP] !=
+ para->softbutton_areas[offset + 1][TOP] ||
+ para->softbutton_areas[offset][BOTTOM] !=
+ para->softbutton_areas[offset + 1][BOTTOM]))
+ return FALSE;
+
+ if (right_valid) {
+ top = para->softbutton_areas[offset][TOP];
+ bottom = para->softbutton_areas[offset][BOTTOM];
+ }
+ else {
+ top = para->softbutton_areas[offset + 1][TOP];
+ bottom = para->softbutton_areas[offset + 1][BOTTOM];
+ }
+
+ if (top && y < top)
+ inside_area = FALSE;
+ else if (bottom && y > bottom)
+ inside_area = FALSE;
+
+ return inside_area;
+}
+
+static Bool
+is_inside_anybutton_area(SynapticsParameters * para, int x, int y)
+{
+ return
+ is_inside_top_or_bottom_button_area(para, BOTTOM_BUTTON_AREA, x, y) ||
+ is_inside_top_or_bottom_button_area(para, TOP_BUTTON_AREA, x, y);
+}
+
static CARD32
timerFunc(OsTimerPtr timer, CARD32 now, pointer arg)
{
@@ -3031,6 +3082,8 @@ HandleState(InputInfoPtr pInfo, struct SynapticsHwState *hw, CARD32 now,
int delay = 1000000000;
int timeleft;
Bool inside_active_area;
+ Bool using_cumulative_coords = FALSE;
+ Bool ignore_motion;
/* If touchpad is switched off, we skip the whole thing and return delay */
if (para->touchpad_off == TOUCHPAD_OFF) {
@@ -3056,6 +3109,7 @@ HandleState(InputInfoPtr pInfo, struct SynapticsHwState *hw, CARD32 now,
if (para->clickpad && (hw->left || hw->right || hw->middle)) {
hw->x = hw->cumulative_dx;
hw->y = hw->cumulative_dy;
+ using_cumulative_coords = TRUE;
}
/* apply hysteresis before doing anything serious. This cancels
@@ -3065,6 +3119,16 @@ HandleState(InputInfoPtr pInfo, struct SynapticsHwState *hw, CARD32 now,
inside_active_area = is_inside_active_area(priv, hw->x, hw->y);
+ /* Ignore motion *starting* inside softbuttonareas */
+ if (priv->finger_state < FS_TOUCHED)
+ priv->inside_button_area = is_inside_anybutton_area(para, hw->x, hw->y);
+ /* If we already have a finger down, clear inside_button_area if it goes
+ outside of the softbuttonareas */
+ else if (priv->inside_button_area && !is_inside_anybutton_area(para, hw->x, hw->y))
+ priv->inside_button_area = FALSE;
+
+ ignore_motion = !using_cumulative_coords && priv->inside_button_area;
+
/* these two just update hw->left, right, etc. */
update_hw_button_state(pInfo, hw, now, &delay);
if (priv->has_scrollbuttons)
@@ -3136,8 +3200,8 @@ HandleState(InputInfoPtr pInfo, struct SynapticsHwState *hw, CARD32 now,
}
/* Post events */
- if (finger >= FS_TOUCHED && (dx || dy) &&
- (para->touchpad_off != TOUCHPAD_CLICK_ONLY))
+ if (finger >= FS_TOUCHED && (dx || dy) && !ignore_motion &&
+ (para->touchpad_off != TOUCHPAD_CLICK_ONLY))
xf86PostMotionEvent(pInfo->dev, 0, 0, 2, dx, dy);
if (priv->mid_emu_state == MBE_LEFT_CLICK) {