arduino-libraries / Keyboard

GNU Lesser General Public License v3.0
223 stars 157 forks source link

Keyboard.print() and Keyboard.println() do not reliably ouput uppercase characters #81

Closed dbhaig closed 1 year ago

dbhaig commented 1 year ago

This code:

Keyboard.println("abcdefghijklmnopqrstuvwxyz");

Gives the expected output:

abcdefghijklmnopqrstuvwxyz

This code:

Keyboard.println("ABCDEFGHIJKLOMNPQRSTUVWXYZ");

Gives an output with some characters lower case, such as:

abCdEFGHIjklOMNPQRStUvwXYZ

or

aBcdeFGHIjKLOMNPQrsTuVWXYz

Sketch

#include "Keyboard.h"

void setup() {
  Keyboard.begin();
}

void loop() {
  Keyboard.print("abcdefghijklmnopqrstuvwxyz");
  delay(2000);
  Keyboard.print("ABCDEFGHIJKLONOPQRSTUVWXYZ");
  delay(2000);
}
edgar-bonet commented 1 year ago

I cannot reproduce. This issue looks somewhat similar to #18, which seems to happen only when the keystrokes sent by the Arduino are received by the Windows RDP Client. I suspect the problem to be specific to some applications/environments that may not correctly process the shifted keystrokes sent by this library. Could you please tell us about the environment you are using? I am using X11 on Ubuntu 20.04, and shifted keys work just fine.

I have a theory. When you type “A” on a physical keyboard, the following happens:

  1. You press the Shift key, and the keyboard sends a key report to the host computer telling it that the Shift key is pressed.

  2. You press the A key, and the keyboard sends another key report saying that both Shift and A are pressed.

  3. You release A, the keyboard sends a key report with only Shift pressed.

  4. You release Shift, the keyboard sends a last key report telling that no key is currently pressed.

That is a total of four key reports. In contrast, when your Arduino executes

Keyboard.print('A');

Only two key reports are sent:

This creates an ambiguity about which key, among Shift and A, was pressed first. The host cannot know. If it assumes Shift was pressed first (which seems to happen on most environments), the keystroke is interpreted as an uppercase “A”. If it assumes A was first, that would be a lowercase “a” followed by a gratuitous press on the Shift key.

If my theory is correct, this could be fixed by sending an extra key report for Shift alone before the key report with both keys. I implemented this idea in the branch "shift-first" of my fork. Could you please give it a try? If it fixes your issue, I will submit a pull request.

dbhaig commented 1 year ago

@edgar-bonet Thank you for the quick response. I am running Ubuntu 22.04.1 LTS.

Something seems to have changed, since you are unable to replicate the issue and, after further testing, I have found that the issue does not occur when connected to:

I tried the changes you made in your "shift-first" fork, however, the results were the same on Ubuntu 22.04.1 box.

Thanks

dbhaig commented 1 year ago

@edgar-bonet It seems to be a Gnome issue. (Gnome 3.44.0 for Gnome 42)

When I use an xterm window instead, the issue does not occur!