tmk / tmk_keyboard

Keyboard firmwares for Atmel AVR and Cortex-M
3.96k stars 1.7k forks source link

Mouse movement slow and jittering #745

Open stevium opened 1 year ago

stevium commented 1 year ago

I have received a new Usb2Usb controller, flashed TMK on it, and connected HHKB Classic.

Everything seems fine, except that mouse movement appear to be slow and jittering.

When I try to move the cursor in one direction, first it moves a bit, then there is a short pause, and then movement is resumed. Can this delay on press-and-hold be removed somehow?

I'm coming here with previous YDKB experience using YangBLE controller, and the TMK implementation seems way less smooth and irresponsive, to the point that it's hard to move and causes finger fatigue because you need to hold the button for too long in order to move the cursor from point A to point B.

Similar behavior is with medium and fast speed applied, the offset distance is higher, but still, there is quite a bit of delay on press and hold.

To me, it looks like the frequency of actions being set from the controller is too low, and we should be sending more frequent but granular movements.

Edit: attached a video demonstrating the difference

https://user-images.githubusercontent.com/15067828/183748065-52a0e938-bed0-49d7-a915-01960208f62f.mp4

tmk commented 1 year ago

Mouse key is implemented here:

https://github.com/tmk/tmk_keyboard/blob/5f7d388dee73ccbd61d40d581e83acc632fa4855/tmk_core/common/mousekey.c

You can change some values or replace all codes in the file as you like. Share your result if you find better configuration or codes.

I tried USB-USB converter with keymap like below on Ubuntu 20.04(with 1920x1080 + 1200x1600 monitor), and confirmed that mouse keys worked as expected.

#include "unimap_trans.h"

#define AC_FN1 ACTION_LAYER_MOMENTARY(1)
#define AC_SPC2    ACTION_LAYER_TAP_KEY(2, KC_SPC)
#define AC_SCL2    ACTION_LAYER_TAP_KEY(2, KC_SCLN)
#define AC_BACK    ACTION_MODS_KEY(MOD_LALT, KC_LEFT)
#define AC_FRWD    ACTION_MODS_KEY(MOD_LALT, KC_RIGHT)

#ifdef KEYMAP_SECTION_ENABLE
const action_t actionmaps[][UNIMAP_ROWS][UNIMAP_COLS] __attribute__ ((section (".keymap.keymaps"))) = {
#else
const action_t actionmaps[][UNIMAP_ROWS][UNIMAP_COLS] PROGMEM = {
#endif
    UNIMAP(
              F13, F14, F15, F16, F17, F18, F19, F20, F21, F22, F23, F24,
    ESC,      F1,  F2,  F3,  F4,  F5,  F6,  F7,  F8,  F9,  F10, F11, F12,           PSCR,SLCK,PAUS,         VOLD,VOLU,MUTE,
    GRV, 1,   2,   3,   4,   5,   6,   7,   8,   9,   0,   MINS,EQL, JYEN,BSPC,     INS, HOME,PGUP,    NLCK,PSLS,PAST,PMNS,
    TAB, Q,   W,   E,   R,   T,   Y,   U,   I,   O,   P,   LBRC,RBRC,     BSLS,     DEL, END, PGDN,    P7,  P8,  P9,  PPLS,
    CAPS,A,   S,   D,   F,   G,   H,   J,   K,   L,   SCL2,QUOT,     NUHS,ENT,                         P4,  P5,  P6,  PCMM,
    LSFT,NUBS,Z,   X,   C,   V,   B,   N,   M,   COMM,DOT, SLSH,     RO,  RSFT,          UP,           P1,  P2,  P3,  PENT,
    LCTL,LGUI,LALT,MHEN,          SPC2,          HENK,KANA,RALT,RGUI,FN1, RCTL,     LEFT,DOWN,RGHT,    P0,       PDOT,PEQL
    ),
    UNIMAP(
              TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,
    GRV,      TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,          TRNS,TRNS,BTLD,         TRNS,TRNS,TRNS,
    ESC, F1,  F2,  F3,  F4,  F5,  F6,  F7,  F8,  F9,  F10, F11, F12, INS, DEL,      TRNS,TRNS,TRNS,    TRNS,TRNS,TRNS,TRNS,
    TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,PSCR,SLCK,PAUS,UP,  INS,      TRNS,     TRNS,TRNS,TRNS,    TRNS,TRNS,TRNS,TRNS,
    TRNS,VOLD,VOLU,MUTE,TRNS,TRNS,TRNS,TRNS,HOME,PGUP,LEFT,RGHT,     TRNS,TRNS,                        TRNS,TRNS,TRNS,TRNS,
    TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,END, PGDN,DOWN,     TRNS,TRNS,          PGUP,         TRNS,TRNS,TRNS,TRNS,
    TRNS,TRNS,TRNS,TRNS,          TRNS,          TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,     HOME,PGDN,END,     TRNS,     TRNS,TRNS
    ),
    UNIMAP(
              TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,
    GRV,      TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,          TRNS,TRNS,BTLD,         TRNS,TRNS,TRNS,
    ESC, F1,  F2,  F3,  F4,  F5,  F6,  F7,  F8,  F9,  F10, F11, F12, INS, DEL,      TRNS,TRNS,TRNS,    TRNS,TRNS,TRNS,TRNS,
    TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,WH_L,WH_D,MS_U,WH_U,WH_R,BTN4,BTN5,     TRNS,     TRNS,TRNS,TRNS,    TRNS,TRNS,TRNS,TRNS,
    TRNS,VOLD,VOLU,MUTE,TRNS,TRNS,TRNS,MS_L,MS_D,MS_R,BTN1,TRNS,     TRNS,TRNS,                        TRNS,TRNS,TRNS,TRNS,
    TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,BTN3,BTN2,BTN1,BACK,FRWD,TRNS,     TRNS,TRNS,          PGUP,         TRNS,TRNS,TRNS,TRNS,
    TRNS,TRNS,TRNS,TRNS,          TRNS,          TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,     HOME,PGDN,END,     TRNS,     TRNS,TRNS
    ),
};
stevium commented 1 year ago

Thanks a lot for the suggestion, I will try configuring the source code when I find time to, as I left my USB-USB HHKB Classic at the office, and kept using HHKB Pro 2 as a primary one, because of smoother mouse movements.

But in general, I think the TMK mouse algorithm is okay. Of course, the speed could be tweaked to one's personal taste.

But the problem is in direction switching. I have updated the issue description demonstrating TMK vs YDKB both on default speed without acceleration applied.

I also have Ubuntu 20, and back in 2019 I also used Hasu Bluetooth Controller with HHKB Pro 2, and as I can tell it behaved similarly to USB-USB.

Can you please double-check if you are able to reproduce this behavior, or you don't see any delay when starting the movement, on pres-&-hold?

tmk commented 1 year ago

In TMK acceleration value is reset to 0 once you release all of mouse keys, you will have to hold both MS_L and MS_R temporarily before releasing one, to change direction with kepping its acceleration. It requires a bit awkward and busy fingering. This behaviour can be changed.

It would be good place to learn if YDKB implementation is available in public.

stevium commented 1 year ago

Yes, the suggestion for switching direction seems to be working. But still, the initial movement on Press-And-Hold has a short delay, which is decreasing the responsiveness significantly.

It looks like YDKB work is based on fork of TMK actually: https://github.com/ydkb/tmk_keyboard

tmk commented 1 year ago

I didn't find significant difference on their codes with a quick glance. I don't have time to look into YDKB codes further. Let me know if you have something interesting.

As for the delay in TMK it seems to be configurable to some extent.

You can change its behaviour by define custom values in your config.h, perhaps.

#define MOUSEKEY_DELAY 300
#define MOUSEKEY_INTERVAL 50

https://github.com/tmk/tmk_keyboard/blob/5f7d388dee73ccbd61d40d581e83acc632fa4855/tmk_core/common/mousekey.c#L35-L53

Each values are explained here, perhaps. https://en.wikipedia.org/wiki/Mouse_keys

Default values are defined here: https://github.com/tmk/tmk_keyboard/blob/5f7d388dee73ccbd61d40d581e83acc632fa4855/tmk_core/common/mousekey.h

stevium commented 1 year ago

I just found some time to recompile the source and add my mappings there.

Setting the MOUSEKEY_DELAY to 0 and changing MOUSEKEY_INTERVAL to 25 improved the speed and experience tremendously.

This is like a dream come true.

Thank you very much for an amazing work, and my appologies for not reading the specification fully before opening the issue.