Bluetooth HID not registering VoiceOver control+option pressed simultaneously

I am building a Bluetooth LE HID for navigating VoiceOver on iPhone using keyboard shortcuts. The hardware is an Adafruit Bluefruit LE 32u4 board. So far I got combinations of modifier keys working on other platforms (Android, windows 10). However, when I try to trigger the control-option-h shortcut it doesn't work.

In the VoiceOver practice/help screen it shows 'control', 'option', 'h' really quickly after each other. How do I get the control-option-h key combination to register as a single press?


I'm using the Adafruit Bluefruit LE nRF51 library and send keys using the AT+BLEKEYBOARDCODE commands.

When I try another combination like left_arrow+right_arrow it does show up as a simultaneous press "left arrow + right arrow". Individually the keys register correctly, so the ALT key does gets registered as the option key.


I have also tried splitting the presses into separate packages, shown below. On Android the combinations also work when put into a single package.

I have fiddled with delays on the 32u4 side of things and also tried increasing the 'key repetition interval' in the iPhone's settings as well as turning that off completely.

The code I use is as follows, where

data
is an array of 8
uint8_t
's. The control-option-h keycombo has data
{5, 0, 11, 0, 0, 0, 0, 0}
. (CTRL = 1, Alt/Option = 4. 4+1 = 5. And the H key has code 11).

 
  ble.atcommand("AT+BLEKEYBOARDCODE", data, 8);
  //release with all zeros
  ble.atcommand("AT+BLEKEYBOARDCODE", (uint8_t*) &emptyArray, 8);


Since this didn't work I also tried pressing control first, option second, then 'H' and only then releasing:

  uint8_t mydata[8] = {0};
  ble.atcommand("AT+BLEKEYBOARDCODE", mydata, 8);
  delay(100);
  mydata[0] = 1;
  ble.atcommand("AT+BLEKEYBOARDCODE", mydata, 8);
  delay(100);
  mydata[0] = 5;
  ble.atcommand("AT+BLEKEYBOARDCODE", mydata, 8);
  delay(100);
  mydata[2] = 11;
  ble.atcommand("AT+BLEKEYBOARDCODE", mydata, 8);
  delay(200);
  mydata[0] = 0;
  mydata[2] = 0;
  ble.atcommand("AT+BLEKEYBOARDCODE", mydata, 8);
  delay(100);


Which should simulate a more natural way a human would press a key combo, but alas it didn't work either.

As described above, the combination shows up as rapid sequential key presses, instead of one simultaneous one. I am at a loss on how to proceed further and find it weird that it did work on Android. The iPhone I'm testing on has iOS 11.4.1. And has VoiceOver enabled.

Any ideas what could be going wrong or where I should look?

Replies

In the end I found this old Stack overflow question which dealt with the exact same problem. This answer solved the issue: https://stackoverflow.com/a/24910560/5479787

Turns out I was really close with my second block of code, but not close enough 🙂