digistump / DigistumpArduino

Files to add Digistump support (Digispark, Pro, DigiX) to Arduino 1.6.X (1.6.5+)
932 stars 377 forks source link

Cannot send a modifier key (ctrl, shift, alt) alone #138

Closed forrestbao closed 3 years ago

forrestbao commented 3 years ago

Hi, I am trying to send only one modifier key stroke to the computer from ATtiny85. I do not intent to press the modifier key with another key at the same time. I referred to the USB HID keyboard usage IDs. For example, left shift should be 0xE1, Right Alt should be 0xE5. But after using DigiKeyboard.sendKeyStroke(0xE1), my PC-end program does not read a left shift press. In contrast, the same program could read the left shift press from my keyboard. What is the proper way to send only one stroke on a pressed-alone modifier key?

ArminJo commented 3 years ago

Try sendKeyPress(0,MODIFIERKEY_LEFT_SHIFT) or sendKeyPress(0xE1).

forrestbao commented 3 years ago

thanks @ArminJo I have figured out. The USB HID usage code for the modifier keys (like 0xe1 for left shift) should NOT be used. Instead, send the one-hot encodings of them in the modifier field along with the key byte 0. By "one-hot encodings" I mean this:

#define MOD_CONTROL_LEFT    (1<<0)
#define MOD_SHIFT_LEFT      (1<<1)
#define MOD_ALT_LEFT        (1<<2)
#define MOD_GUI_LEFT        (1<<3)
#define MOD_CONTROL_RIGHT   (1<<4)
#define MOD_SHIFT_RIGHT     (1<<5)
#define MOD_ALT_RIGHT       (1<<6)
#define MOD_GUI_RIGHT       (1<<7)

So, sendKeyStroke(0, 0x01) or sendKeyStroke(0, MOD_CONTROL_LEFT) means sending a key stroke of left ctrl, sendKeyStroke(0, 0x02) means a key stroke of left shift, sendKeyStroke(0, 0xe1) means a key stroke of right alt. etc.

sendKeyStroke or sendKeyPress won't make a difference in successfully send a key press.

ArminJo commented 3 years ago

Thanks a lot for testing 🥇 I documented it now in keylayouts.h. You can use the already defined macros from keylayouts.h

#define MODIFIERKEY_CTRL        ( 0x01 | 0xE000 )
#define MODIFIERKEY_SHIFT       ( 0x02 | 0xE000 )
#define MODIFIERKEY_ALT         ( 0x04 | 0xE000 )
#define MODIFIERKEY_GUI         ( 0x08 | 0xE000 )
#define MODIFIERKEY_LEFT_CTRL   ( 0x01 | 0xE000 )
#define MODIFIERKEY_LEFT_SHIFT  ( 0x02 | 0xE000 )
#define MODIFIERKEY_LEFT_ALT    ( 0x04 | 0xE000 )
#define MODIFIERKEY_LEFT_GUI    ( 0x08 | 0xE000 )
#define MODIFIERKEY_RIGHT_CTRL  ( 0x10 | 0xE000 )
#define MODIFIERKEY_RIGHT_SHIFT ( 0x20 | 0xE000 )
#define MODIFIERKEY_RIGHT_ALT   ( 0x40 | 0xE000 )
#define MODIFIERKEY_RIGHT_GUI   ( 0x80 | 0xE000 )