On 02/07/2014 01:46 AM, Clinton Sprain wrote: > Discard cursor movements if they directly coincide with a change in the number of fingers detected. This helps with two issues - a sudden jump of the cursor when a second finger enters or leaves the touchpad, and an unexpected jump in page scrolling under the same scenario. The fix doesn't completely eliminate the problem but does greatly reduce its frequency and severity. > > Signed-off-by: Clinton Sprain <clintonsprain@xxxxxxxxx> > --- > drivers/input/mouse/appletouch.c | 23 +++++++++++++++++++---- > 1 file changed, 19 insertions(+), 4 deletions(-) > > diff --git a/drivers/input/mouse/appletouch.c b/drivers/input/mouse/appletouch.c > index edbdd95..370d0e9 100644 > --- a/drivers/input/mouse/appletouch.c > +++ b/drivers/input/mouse/appletouch.c > @@ -212,6 +212,7 @@ struct atp { > signed char xy_old[ATP_XSENSORS + ATP_YSENSORS]; > int xy_acc[ATP_XSENSORS + ATP_YSENSORS]; > int idlecount; /* number of empty packets */ > + int fingers_old; /* last reported finger count */ > struct work_struct work; > }; > > @@ -505,6 +506,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); > > @@ -587,7 +589,9 @@ 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); > + > + if (x && y && (fingers == dev->fingers_old)) { > if (dev->x_old != -1) { > x = (dev->x_old * 7 + x) >> 3; > y = (dev->y_old * 7 + y) >> 3; > @@ -604,7 +608,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); > } > dev->x_old = x; > dev->y_old = y; > @@ -620,6 +624,10 @@ static void atp_complete_geyser_1_2(struct urb *urb) > memset(dev->xy_acc, 0, sizeof(dev->xy_acc)); > } > > + if (fingers != dev->fingers_old) > + dev->x_old = dev->y_old = -1; > + dev->fingers_old = fingers; > + > input_report_key(dev->input, BTN_LEFT, key); > input_sync(dev->input); > > @@ -638,6 +646,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); > > @@ -699,7 +708,9 @@ 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); > + > + if (x && y && (fingers == dev->fingers_old)) { > if (dev->x_old != -1) { > x = (dev->x_old * 7 + x) >> 3; > y = (dev->y_old * 7 + y) >> 3; > @@ -716,7 +727,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); > } > dev->x_old = x; > dev->y_old = y; > @@ -732,6 +743,10 @@ static void atp_complete_geyser_3_4(struct urb *urb) > memset(dev->xy_acc, 0, sizeof(dev->xy_acc)); > } > > + if (fingers != dev->fingers_old) > + dev->x_old = dev->y_old = -1; > + dev->fingers_old = fingers; > + > input_report_key(dev->input, BTN_LEFT, key); > input_sync(dev->input); > > Reviewed-by: Henrik Rydberg <rydberg@xxxxxxxxxxx> Thanks, Henrik -- To unsubscribe from this list: send the line "unsubscribe linux-input" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html