summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPeter Hutterer <peter.hutterer@redhat.com>2008-09-06 03:03:42 +0930
committerPeter Hutterer <peter.hutterer@redhat.com>2008-09-09 19:13:57 +0930
commitdb7dc1085e43ccdd796c67174289313ed4852c13 (patch)
treef84e118325cf07a7984a06bad80990d3b865e6a1
parent5d3a47eed9f5330982d10c3acc15c486e3c86beb (diff)
Don't lose button up event if timeout is cancelled in the same ReadInput cycle
On a left/right button press, middle button emulation springs into action and changes the reported hw state. It then returns a delay that is supposed to set a timer. No button event is posted to the server, the timer ensures that it'll be posted later. If however - in the same cycle - the button up is reported, but with a hardware time > middle emulation timeout, the middle button emulation is canceled. The hw state is reset to button down, and processing continues, reporting the button down event. Since this is in the same cycle, the new delay overrides the previous one and the timer is never set. Introduce a new state into MB emulation that forces the click event if the above situation occurs. Red Hat Bug 233717 <http://bugzilla.redhat.com/show_bug.cgi?id=233717>
-rw-r--r--src/synaptics.c28
-rw-r--r--src/synapticsstr.h4
2 files changed, 29 insertions, 3 deletions
diff --git a/src/synaptics.c b/src/synaptics.c
index 8475d1a..7aa5c79 100644
--- a/src/synaptics.c
+++ b/src/synaptics.c
@@ -878,6 +878,8 @@ HandleMidButtonEmulation(SynapticsPrivate *priv, struct SynapticsHwState *hw, in
while (!done) {
switch (priv->mid_emu_state) {
+ case MBE_LEFT_CLICK:
+ case MBE_RIGHT_CLICK:
case MBE_OFF:
priv->button_delay_millis = hw->millis;
if (hw->left) {
@@ -893,7 +895,12 @@ HandleMidButtonEmulation(SynapticsPrivate *priv, struct SynapticsHwState *hw, in
hw->millis);
if (timeleft > 0)
*delay = MIN(*delay, timeleft);
- if (!hw->left || (timeleft <= 0)) {
+
+ /* timeout, but within the same ReadInput cycle! */
+ if ((timeleft <= 0) && !hw->left) {
+ priv->mid_emu_state = MBE_LEFT_CLICK;
+ done = TRUE;
+ } else if ((!hw->left) || (timeleft <= 0)) {
hw->left = TRUE;
priv->mid_emu_state = MBE_TIMEOUT;
done = TRUE;
@@ -909,7 +916,12 @@ HandleMidButtonEmulation(SynapticsPrivate *priv, struct SynapticsHwState *hw, in
hw->millis);
if (timeleft > 0)
*delay = MIN(*delay, timeleft);
- if (!hw->right || (timeleft <= 0)) {
+
+ /* timeout, but within the same ReadInput cycle! */
+ if ((timeleft <= 0) && !hw->right) {
+ priv->mid_emu_state = MBE_RIGHT_CLICK;
+ done = TRUE;
+ } else if (!hw->right || (timeleft <= 0)) {
hw->right = TRUE;
priv->mid_emu_state = MBE_TIMEOUT;
done = TRUE;
@@ -1919,6 +1931,18 @@ HandleState(LocalDevicePtr local, struct SynapticsHwState *hw)
if (dx || dy)
xf86PostMotionEvent(local->dev, 0, 0, 2, dx, dy);
+ if (priv->mid_emu_state == MBE_LEFT_CLICK)
+ {
+ xf86PostButtonEvent(local->dev, FALSE, 1, 1, 0, 0);
+ xf86PostButtonEvent(local->dev, FALSE, 1, 0, 0, 0);
+ priv->mid_emu_state = MBE_OFF;
+ } else if (priv->mid_emu_state == MBE_RIGHT_CLICK)
+ {
+ xf86PostButtonEvent(local->dev, FALSE, 3, 1, 0, 0);
+ xf86PostButtonEvent(local->dev, FALSE, 3, 0, 0, 0);
+ priv->mid_emu_state = MBE_OFF;
+ }
+
change = buttons ^ priv->lastButtons;
while (change) {
id = ffs(change); /* number of first set bit 1..32 is returned */
diff --git a/src/synapticsstr.h b/src/synapticsstr.h
index ca61a9c..5d61d0e 100644
--- a/src/synapticsstr.h
+++ b/src/synapticsstr.h
@@ -54,7 +54,9 @@ enum MidButtonEmulation {
MBE_RIGHT, /* Right button pressed, waiting for left button or timeout */
MBE_MID, /* Left and right buttons pressed, waiting for both buttons
to be released */
- MBE_TIMEOUT /* Waiting for both buttons to be released. */
+ MBE_TIMEOUT, /* Waiting for both buttons to be released. */
+ MBE_LEFT_CLICK, /* Emulate left button click. */
+ MBE_RIGHT_CLICK, /* Emulate right button click. */
};
/* See docs/tapndrag.dia for a state machine diagram */