Skip to content

Commit

Permalink
Fix the mousekey scrolling (#9174)
Browse files Browse the repository at this point in the history
Mousekey scrolling should have a separate repeat variable
to keep track of scrolling acceleration, instead of being
tied to mouse movement scolling in mousekeys. The send function
should record when the last movement was made since this is
when movement is actually sent. Doing this fixes the bug where
the initial press of a mousekey scroll button causes a double scroll.

Signed-off-by: Daniel Hong <[email protected]>
  • Loading branch information
dhong44 authored Jul 16, 2020
1 parent f95d445 commit 5a4ec42
Showing 1 changed file with 43 additions and 39 deletions.
82 changes: 43 additions & 39 deletions tmk_core/common/mousekey.c
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ static report_mouse_t mouse_report = {0};
static void mousekey_debug(void);
static uint8_t mousekey_accel = 0;
static uint8_t mousekey_repeat = 0;
static uint16_t last_timer = 0;
static uint8_t mousekey_wheel_repeat = 0;

#ifndef MK_3_SPEED

Expand Down Expand Up @@ -92,27 +92,30 @@ static uint8_t wheel_unit(void) {
unit = (MOUSEKEY_WHEEL_DELTA * mk_wheel_max_speed) / 2;
} else if (mousekey_accel & (1 << 2)) {
unit = (MOUSEKEY_WHEEL_DELTA * mk_wheel_max_speed);
} else if (mousekey_repeat == 0) {
} else if (mousekey_wheel_repeat == 0) {
unit = MOUSEKEY_WHEEL_DELTA;
} else if (mousekey_repeat >= mk_wheel_time_to_max) {
} else if (mousekey_wheel_repeat >= mk_wheel_time_to_max) {
unit = MOUSEKEY_WHEEL_DELTA * mk_wheel_max_speed;
} else {
unit = (MOUSEKEY_WHEEL_DELTA * mk_wheel_max_speed * mousekey_repeat) / mk_wheel_time_to_max;
unit = (MOUSEKEY_WHEEL_DELTA * mk_wheel_max_speed * mousekey_wheel_repeat) / mk_wheel_time_to_max;
}
return (unit > MOUSEKEY_WHEEL_MAX ? MOUSEKEY_WHEEL_MAX : (unit == 0 ? 1 : unit));
}

void mousekey_task(void) {
// report cursor and scroll movement independently
report_mouse_t const tmpmr = mouse_report;
if ((mouse_report.x || mouse_report.y) && timer_elapsed(last_timer_c) > (mousekey_repeat ? mk_interval : mk_delay * 10)) {

mouse_report.x = 0;
mouse_report.y = 0;
mouse_report.v = 0;
mouse_report.h = 0;

if ((tmpmr.x || tmpmr.y) && timer_elapsed(last_timer_c) > (mousekey_repeat ? mk_interval : mk_delay * 10)) {
if (mousekey_repeat != UINT8_MAX) mousekey_repeat++;
mouse_report.v = 0;
mouse_report.h = 0;
if (mouse_report.x > 0) mouse_report.x = move_unit();
if (mouse_report.x < 0) mouse_report.x = move_unit() * -1;
if (mouse_report.y > 0) mouse_report.y = move_unit();
if (mouse_report.y < 0) mouse_report.y = move_unit() * -1;
if (tmpmr.x != 0) mouse_report.x = move_unit() * ((tmpmr.x > 0) ? 1 : -1);
if (tmpmr.y != 0) mouse_report.y = move_unit() * ((tmpmr.y > 0) ? 1 : -1);

/* diagonal move [1/sqrt(2)] */
if (mouse_report.x && mouse_report.y) {
mouse_report.x = times_inv_sqrt2(mouse_report.x);
Expand All @@ -124,18 +127,12 @@ void mousekey_task(void) {
mouse_report.y = 1;
}
}
mousekey_send();
last_timer_c = last_timer;
mouse_report = tmpmr;
}
if ((mouse_report.v || mouse_report.h) && timer_elapsed(last_timer_w) > (mousekey_repeat ? mk_wheel_interval : mk_wheel_delay * 10)) {
if (mousekey_repeat != UINT8_MAX) mousekey_repeat++;
mouse_report.x = 0;
mouse_report.y = 0;
if (mouse_report.v > 0) mouse_report.v = wheel_unit();
if (mouse_report.v < 0) mouse_report.v = wheel_unit() * -1;
if (mouse_report.h > 0) mouse_report.h = wheel_unit();
if (mouse_report.h < 0) mouse_report.h = wheel_unit() * -1;
if ((tmpmr.v || tmpmr.h) && timer_elapsed(last_timer_w) > (mousekey_wheel_repeat ? mk_wheel_interval : mk_wheel_delay * 10)) {
if (mousekey_wheel_repeat != UINT8_MAX) mousekey_wheel_repeat++;
if (tmpmr.v != 0) mouse_report.v = wheel_unit() * ((tmpmr.v > 0) ? 1 : -1);
if (tmpmr.h != 0) mouse_report.h = wheel_unit() * ((tmpmr.h > 0) ? 1 : -1);

/* diagonal move [1/sqrt(2)] */
if (mouse_report.v && mouse_report.h) {
mouse_report.v = times_inv_sqrt2(mouse_report.v);
Expand All @@ -147,10 +144,10 @@ void mousekey_task(void) {
mouse_report.h = 1;
}
}
mousekey_send();
last_timer_w = last_timer;
mouse_report = tmpmr;
}

if (mouse_report.x || mouse_report.y || mouse_report.v || mouse_report.h) mousekey_send();
mouse_report = tmpmr;
}

void mousekey_on(uint8_t code) {
Expand Down Expand Up @@ -186,6 +183,7 @@ void mousekey_on(uint8_t code) {
mousekey_accel |= (1 << 1);
else if (code == KC_MS_ACCEL2)
mousekey_accel |= (1 << 2);

}

void mousekey_off(uint8_t code) {
Expand Down Expand Up @@ -221,7 +219,8 @@ void mousekey_off(uint8_t code) {
mousekey_accel &= ~(1 << 1);
else if (code == KC_MS_ACCEL2)
mousekey_accel &= ~(1 << 2);
if (mouse_report.x == 0 && mouse_report.y == 0 && mouse_report.v == 0 && mouse_report.h == 0) mousekey_repeat = 0;
if (mouse_report.x == 0 && mouse_report.y == 0) mousekey_repeat = 0;
if (mouse_report.v == 0 && mouse_report.h == 0) mousekey_wheel_repeat = 0;
}

#else /* #ifndef MK_3_SPEED */
Expand All @@ -243,20 +242,22 @@ uint16_t w_intervals[mkspd_COUNT] = {MK_W_INTERVAL_UNMOD, MK_W_INTERVAL_0
void mousekey_task(void) {
// report cursor and scroll movement independently
report_mouse_t const tmpmr = mouse_report;
if ((mouse_report.x || mouse_report.y) && timer_elapsed(last_timer_c) > c_intervals[mk_speed]) {
mouse_report.h = 0;
mouse_report.v = 0;
mousekey_send();
last_timer_c = last_timer;
mouse_report = tmpmr;
mouse_report.x = 0;
mouse_report.y = 0;
mouse_report.v = 0;
mouse_report.h = 0;

if ((tmpmr.x || tmpmr.y) && timer_elapsed(last_timer_c) > c_intervals[mk_speed]) {
mouse_report.x = tmpmr.x;
mouse_report.y = tmpmr.y;
}
if ((mouse_report.h || mouse_report.v) && timer_elapsed(last_timer_w) > w_intervals[mk_speed]) {
mouse_report.x = 0;
mouse_report.y = 0;
mousekey_send();
last_timer_w = last_timer;
mouse_report = tmpmr;
if ((tmpmr.h || tmpmr.v) && timer_elapsed(last_timer_w) > w_intervals[mk_speed]) {
mouse_report.v = tmpmr.v;
mouse_report.h = tmpmr.h;
}

if (mouse_report.x || mouse_report.y || mouse_report.v || mouse_report.h) mousekey_send();
mouse_report = tmpmr;
}

void adjust_speed(void) {
Expand Down Expand Up @@ -371,13 +372,16 @@ void mousekey_off(uint8_t code) {

void mousekey_send(void) {
mousekey_debug();
uint16_t time = timer_read();
if (mouse_report.x || mouse_report.y) last_timer_c = time;
if (mouse_report.v || mouse_report.h) last_timer_w = time;
host_mouse_send(&mouse_report);
last_timer = timer_read();
}

void mousekey_clear(void) {
mouse_report = (report_mouse_t){};
mousekey_repeat = 0;
mousekey_wheel_repeat = 0;
mousekey_accel = 0;
}

Expand Down

0 comments on commit 5a4ec42

Please sign in to comment.