diff options
author | iedowse <iedowse@FreeBSD.org> | 2001-07-08 20:23:59 +0000 |
---|---|---|
committer | iedowse <iedowse@FreeBSD.org> | 2001-07-08 20:23:59 +0000 |
commit | b4102478b4b5d9dcced92cc121e35f09d658dfb7 (patch) | |
tree | 78c345b2d8fc9d6dd6908fd624adccabcb6093a6 | |
parent | fb991ec59e228fda4c5428b2389b2c563a2f9db7 (diff) | |
download | FreeBSD-src-b4102478b4b5d9dcced92cc121e35f09d658dfb7.zip FreeBSD-src-b4102478b4b5d9dcced92cc121e35f09d658dfb7.tar.gz |
The state machine for 3-button emulation defers some button events
until a 20ms select(2) timeout occurs, but if there is a continuous
stream of movement events, button events can be delayed indefinitely
because the select never has to wait long enough for a timeout.
The delay and mouse event reordering that result are very noticable
and sometimes quite frustrating when dragging windows etc. in X.
Add a simple mechanism that avoids this re-ordering. While a button
event is deferred, we discard up to 3 movement events to allow for
mouse jitter. If more movement events occur, then we immediately
timeout the deferred button event and let the movement proceed.
This change only affects the 3-button emulation case.
-rw-r--r-- | usr.sbin/moused/moused.c | 33 |
1 files changed, 29 insertions, 4 deletions
diff --git a/usr.sbin/moused/moused.c b/usr.sbin/moused/moused.c index 8944d93..72aa6f7 100644 --- a/usr.sbin/moused/moused.c +++ b/usr.sbin/moused/moused.c @@ -76,6 +76,9 @@ static const char rcsid[] = #define DFLT_CLICKTHRESHOLD 500 /* 0.5 second */ #define DFLT_BUTTON2TIMEOUT 100 /* 0.1 second */ +/* Abort 3-button emulation delay after this many movement events. */ +#define BUTTON2_MAXMOVE 3 + #define TRUE 1 #define FALSE 0 @@ -428,6 +431,7 @@ static struct button_state zstate[4]; /* Z/W axis state */ #define A(b1, b3) (((b1) ? 2 : 0) | ((b3) ? 1 : 0)) #define A_TIMEOUT 4 +#define S_DELAYED(st) (states[st].s[A_TIMEOUT] != (st)) static struct { int s[A_TIMEOUT + 1]; @@ -458,6 +462,7 @@ static struct { }; static int mouse_button_state; static struct timeval mouse_button_state_tv; +static int mouse_move_delayed; static jmp_buf env; @@ -851,6 +856,7 @@ moused(void) bzero(&mouse, sizeof(mouse)); mouse_button_state = S0; gettimeofday(&mouse_button_state_tv, NULL); + mouse_move_delayed = 0; for (i = 0; i < MOUSE_MAXBUTTON; ++i) { bstate[i].count = 0; bstate[i].tv = mouse_button_state_tv; @@ -1970,10 +1976,29 @@ r_statetrans(mousestatus_t *a1, mousestatus_t *a2, int trans) debug("state:%d, trans:%d -> state:%d", mouse_button_state, trans, states[mouse_button_state].s[trans]); - if (mouse_button_state != states[mouse_button_state].s[trans]) { - gettimeofday(&mouse_button_state_tv, NULL); - changed = TRUE; - } + /* + * Avoid re-ordering button and movement events. While a button + * event is deferred, throw away up to BUTTON2_MAXMOVE movement + * events to allow for mouse jitter. If more movement events + * occur, then complete the deferred button events immediately. + */ + if ((a2->dx != 0 || a2->dy != 0) && + S_DELAYED(states[mouse_button_state].s[trans])) { + if (++mouse_move_delayed > BUTTON2_MAXMOVE) { + mouse_move_delayed = 0; + mouse_button_state = + states[mouse_button_state].s[A_TIMEOUT]; + changed = TRUE; + } else { + a2->dx = a2->dy = 0; + mouse_move_delayed++; + } + } else + mouse_move_delayed = 0; + if (mouse_button_state != states[mouse_button_state].s[trans]) + changed = TRUE; + if (changed) + gettimeofday(&mouse_button_state_tv, NULL); mouse_button_state = states[mouse_button_state].s[trans]; a2->button &= ~(MOUSE_BUTTON1DOWN | MOUSE_BUTTON2DOWN | MOUSE_BUTTON3DOWN); |