summaryrefslogtreecommitdiffstats
path: root/usr.sbin/moused
diff options
context:
space:
mode:
authoriedowse <iedowse@FreeBSD.org>2001-07-08 20:23:59 +0000
committeriedowse <iedowse@FreeBSD.org>2001-07-08 20:23:59 +0000
commitb4102478b4b5d9dcced92cc121e35f09d658dfb7 (patch)
tree78c345b2d8fc9d6dd6908fd624adccabcb6093a6 /usr.sbin/moused
parentfb991ec59e228fda4c5428b2389b2c563a2f9db7 (diff)
downloadFreeBSD-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.
Diffstat (limited to 'usr.sbin/moused')
-rw-r--r--usr.sbin/moused/moused.c33
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);
OpenPOWER on IntegriCloud