Skip to content
Merged
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
36 changes: 31 additions & 5 deletions src/events/SDL_keyboard.c
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ typedef struct SDL_Keyboard
SDL_Keymod modstate;
Uint8 keysource[SDL_SCANCODE_COUNT];
bool keystate[SDL_SCANCODE_COUNT];
Uint8 keyrefcount[SDL_SCANCODE_COUNT]; // how many devices hold this key //
SDL_Keymap *keymap;
Uint32 keycode_options;
bool autorelease_pending;
Expand Down Expand Up @@ -88,6 +89,12 @@ static void SDLCALL SDL_KeycodeOptionsChanged(void *userdata, const char *name,
// Public functions
bool SDL_InitKeyboard(void)
{
// Init key reference counts to 0
SDL_Keyboard *keyboard = &SDL_keyboard;
for (int i = 0; i < SDL_SCANCODE_COUNT; ++i) {
keyboard->keyrefcount[i] = 0;
}

SDL_AddHintCallback(SDL_HINT_KEYCODE_OPTIONS,
SDL_KeycodeOptionsChanged, &SDL_keyboard);

Expand Down Expand Up @@ -225,6 +232,7 @@ void SDL_ResetKeyboard(void)
if (keyboard->keystate[scancode]) {
SDL_SendKeyboardKey(0, SDL_GLOBAL_KEYBOARD_ID, 0, (SDL_Scancode)scancode, false);
}
keyboard->keyrefcount[scancode] = 0; // Reset reference count
}
}

Expand Down Expand Up @@ -522,6 +530,7 @@ static bool SDL_SendKeyboardKeyInternal(Uint64 timestamp, Uint32 flags, SDL_Keyb
SDL_Keycode keycode = SDLK_UNKNOWN;
Uint32 type;
bool repeat = false;
bool last_release = true;
const Uint8 source = flags & KEYBOARD_SOURCE_MASK;

#ifdef DEBUG_KEYBOARD
Expand All @@ -538,6 +547,9 @@ static bool SDL_SendKeyboardKeyInternal(Uint64 timestamp, Uint32 flags, SDL_Keyb
if (scancode > SDL_SCANCODE_UNKNOWN && scancode < SDL_SCANCODE_COUNT) {
// Drop events that don't change state
if (down) {
if (keyboard->keyrefcount[scancode] < 255) {
keyboard->keyrefcount[scancode]++;
}
if (keyboard->keystate[scancode]) {
if (!(keyboard->keysource[scancode] & source)) {
keyboard->keysource[scancode] |= source;
Expand All @@ -547,14 +559,25 @@ static bool SDL_SendKeyboardKeyInternal(Uint64 timestamp, Uint32 flags, SDL_Keyb
}
keyboard->keysource[scancode] |= source;
} else {
if (!keyboard->keystate[scancode]) {
return false;
if (keyboard->keyrefcount[scancode] > 0) {
keyboard->keyrefcount[scancode]--;
}
if (keyboard->keyrefcount[scancode] == 0) {
keyboard->keysource[scancode] = 0;
last_release = true;
} else {
last_release = false;
}
keyboard->keysource[scancode] = 0;
}

// Update internal keyboard state
keyboard->keystate[scancode] = down;
if (down) {
keyboard->keystate[scancode] = true;
} else {
if (keyboard->keyrefcount[scancode] == 0) {
keyboard->keystate[scancode] = false;
}
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
} else {
if (keyboard->keyrefcount[scancode] == 0) {
keyboard->keystate[scancode] = false;
}
} else if (last_release) {
keyboard->keystate[scancode] = false;

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This was resolved without accepting the suggestion. Was it incorrect?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Functionaly they're the same, but yours is tighter.

}

keycode = SDL_GetKeyFromScancode(scancode, keyboard->modstate, true);

Expand Down Expand Up @@ -621,7 +644,9 @@ static bool SDL_SendKeyboardKeyInternal(Uint64 timestamp, Uint32 flags, SDL_Keyb
break;
}
} else {
keyboard->modstate &= ~modifier;
if (last_release) {
keyboard->modstate &= ~modifier;
}
}
}

Expand Down Expand Up @@ -658,6 +683,7 @@ static bool SDL_SendKeyboardKeyInternal(Uint64 timestamp, Uint32 flags, SDL_Keyb
return posted;
}


void SDL_SendKeyboardUnicodeKey(Uint64 timestamp, Uint32 ch)
{
SDL_Keyboard *keyboard = &SDL_keyboard;
Expand Down
Loading