diff options
author | Peter Hutterer <peter.hutterer@redhat.com> | 2008-09-06 03:03:42 +0930 |
---|---|---|
committer | Peter Hutterer <peter.hutterer@redhat.com> | 2008-09-09 19:13:57 +0930 |
commit | db7dc1085e43ccdd796c67174289313ed4852c13 (patch) | |
tree | f84e118325cf07a7984a06bad80990d3b865e6a1 /src | |
parent | 5d3a47eed9f5330982d10c3acc15c486e3c86beb (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>
Diffstat (limited to 'src')
-rw-r--r-- | src/synaptics.c | 28 | ||||
-rw-r--r-- | src/synapticsstr.h | 4 |
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 */ |