From patchwork Sat Jan 18 01:58:02 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Clinton Sprain X-Patchwork-Id: 3507791 Return-Path: X-Original-To: patchwork-linux-input@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork2.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.19.201]) by patchwork2.web.kernel.org (Postfix) with ESMTP id AF071C02DC for ; Sat, 18 Jan 2014 01:58:08 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id B61992017D for ; Sat, 18 Jan 2014 01:58:07 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id C1E4020142 for ; Sat, 18 Jan 2014 01:58:06 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752520AbaARB6F (ORCPT ); Fri, 17 Jan 2014 20:58:05 -0500 Received: from mail-ig0-f182.google.com ([209.85.213.182]:57783 "EHLO mail-ig0-f182.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752219AbaARB6F (ORCPT ); Fri, 17 Jan 2014 20:58:05 -0500 Received: by mail-ig0-f182.google.com with SMTP id uy17so3209723igb.3 for ; Fri, 17 Jan 2014 17:58:04 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=message-id:date:from:user-agent:mime-version:to:cc:subject :references:in-reply-to:content-type:content-transfer-encoding; bh=zBox8n4pl9p2DP8wqdD5PItyT7fLuMXJOhAkVmrnlGM=; b=OgYQcIJpoqWFSa4dgNOuCRf8if1YrEv0vO5n/UKnAErLLy851AYRW4XoG7lHtoev1F LPq08tFuzmbBsj+Bqg1+Bqu7OnzaaIV0pcq3jdHlD2uuUj7pN8pL8F4wwo5ygribhQ/9 X7uLcWsitpcMTS4sVe7oK3TCv5SU6D+5vor9pYi0Uk51yUBf9jD8APukoBZKdh3khp7N rgOEO7sICHI3M+G4O9hWfmEsrcgWqePq+muT8wBdUsmF5+9P2UiZpfigz9rhubhXmzEB FqbcpPSA4PV+JeCawITU/ThSeSF6Qeodg4ckaWFxCnHPpSieh4W2EOIDMN2oubtG2sVd 27gg== X-Received: by 10.43.140.77 with SMTP id iz13mr4524934icc.47.1390010284274; Fri, 17 Jan 2014 17:58:04 -0800 (PST) Received: from [10.105.2.128] (pat-wlanguest-a.epic.com. [199.204.56.140]) by mx.google.com with ESMTPSA id w4sm6637023igb.5.2014.01.17.17.58.02 for (version=TLSv1 cipher=ECDHE-RSA-RC4-SHA bits=128/128); Fri, 17 Jan 2014 17:58:03 -0800 (PST) Message-ID: <52D9DFAA.10205@gmail.com> Date: Fri, 17 Jan 2014 19:58:02 -0600 From: Clinton Sprain User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:24.0) Gecko/20100101 Thunderbird/24.2.0 MIME-Version: 1.0 To: linux-input@vger.kernel.org CC: Dmitry Torokhov , Henrik Rydberg Subject: [PATCH 3/3] input: appletouch: fix jumps when additional fingers are detected References: <52D9DE7A.7040509@gmail.com> In-Reply-To: <52D9DE7A.7040509@gmail.com> Sender: linux-input-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-input@vger.kernel.org X-Spam-Status: No, score=-7.1 required=5.0 tests=BAYES_00, DKIM_ADSP_CUSTOM_MED, DKIM_SIGNED, FREEMAIL_FROM, RCVD_IN_DNSWL_HI, RP_MATCHES_RCVD, T_DKIM_INVALID, UNPARSEABLE_RELAY autolearn=ham version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP Discard cursor movements if they directly coincide with a change in the number of fingers detected. This helps mitigate two issues - a sudden jump of the cursor when a second finger enters or leaves the trackpad, and an unexpected jump in page scrolling under the same scenario. This doesn't completely eliminate all jumps but does greatly reduce their frequency and velocity. Signed-off-by: Clinton Sprain --- drivers/input/mouse/appletouch.c | 41 ++++++++++++++++++++++++++++++++++---- 1 file changed, 37 insertions(+), 4 deletions(-) diff --git a/drivers/input/mouse/appletouch.c b/drivers/input/mouse/appletouch.c index 4a3bbcd..406054a 100644 --- a/drivers/input/mouse/appletouch.c +++ b/drivers/input/mouse/appletouch.c @@ -218,6 +218,7 @@ struct atp { int xy_acc[ATP_XSENSORS + ATP_YSENSORS]; int idlecount; /* number of empty packets */ struct work_struct work; + int fingers_old; /* last # of fingers detected*/ }; #define dbg_dump(msg, tab) \ { \ @@ -538,6 +539,7 @@ static void atp_complete_geyser_1_2(struct urb *urb) int x, y, x_z, y_z, x_f, y_f; int retval, i, j; int key; + int fingers; struct atp *dev = urb->context; int status = atp_status_check(urb); @@ -621,7 +623,16 @@ static void atp_complete_geyser_1_2(struct urb *urb) dev->info->yfact, &y_z, &y_f); key = dev->data[dev->info->datalen - 1] & ATP_STATUS_BUTTON; - if (x && y) { + fingers = max(x_f, y_f); + + /* + * Only act if we have valid x/y and # of fingers did not change. + * If the # of fingers just changed, acting on the new x/y values will + * cause the cursor to jump across the screen or the page to scroll + * unexpectedly. + */ + + if (x && y && (dev->fingers_old == fingers)) { if (dev->x_old != -1) { if (legacy == true) { x = atp_smooth_legacy(x, dev->x_old); @@ -646,7 +657,7 @@ static void atp_complete_geyser_1_2(struct urb *urb) input_report_abs(dev->input, ABS_Y, y); input_report_abs(dev->input, ABS_PRESSURE, min(ATP_PRESSURE, x_z + y_z)); - atp_report_fingers(dev->input, max(x_f, y_f)); + atp_report_fingers(dev->input, fingers); } atp_refresh_old_xy(x, y, dev); @@ -661,6 +672,12 @@ static void atp_complete_geyser_1_2(struct urb *urb) memset(dev->xy_acc, 0, sizeof(dev->xy_acc)); } + /* if # of fingers changed, old x/y values are no longer useful */ + if (dev->fingers_old != fingers) + atp_reset_old_xy(dev); + + dev->fingers_old = fingers; + input_report_key(dev->input, BTN_LEFT, key); input_sync(dev->input); @@ -679,6 +696,7 @@ static void atp_complete_geyser_3_4(struct urb *urb) int x, y, x_z, y_z, x_f, y_f; int retval, i, j; int key; + int fingers; struct atp *dev = urb->context; int status = atp_status_check(urb); @@ -740,7 +758,16 @@ static void atp_complete_geyser_3_4(struct urb *urb) dev->info->yfact, &y_z, &y_f); key = dev->data[dev->info->datalen - 1] & ATP_STATUS_BUTTON; - if (x && y) { + fingers = max(x_f, y_f); + + /* + * Only act if we have valid x/y and # of fingers did not change. + * If the # of fingers just changed, acting on the new x/y values will + * cause the cursor to jump across the screen or the page to scroll + * unexpectedly. + */ + + if (x && y && (dev->fingers_old == fingers)) { if (dev->x_old != -1) { if (legacy == true) { x = atp_smooth_legacy(x, dev->x_old); @@ -765,7 +792,7 @@ static void atp_complete_geyser_3_4(struct urb *urb) input_report_abs(dev->input, ABS_Y, y); input_report_abs(dev->input, ABS_PRESSURE, min(ATP_PRESSURE, x_z + y_z)); - atp_report_fingers(dev->input, max(x_f, y_f)); + atp_report_fingers(dev->input, fingers); } atp_refresh_old_xy(x, y, dev); @@ -780,6 +807,12 @@ static void atp_complete_geyser_3_4(struct urb *urb) memset(dev->xy_acc, 0, sizeof(dev->xy_acc)); } + /* if # of fingers changed, old x/y values are no longer useful */ + if (dev->fingers_old != fingers) + atp_reset_old_xy(dev); + + dev->fingers_old = fingers; + input_report_key(dev->input, BTN_LEFT, key); input_sync(dev->input);