mirror of
https://github.com/ddeverill/SteamlessController.git
synced 2026-10-22 06:32:20 -05:00
Repeat held key bindings at the system typematic rate
Holding a paddle bound to a letter produced exactly one character. The emission loop only acts on edges, so a held paddle sent one key-down and nothing further until release. That was the correct consequence of the design rather than a fault in the send path: auto-repeat is not something Windows synthesises for a key it believes is down. A physical keyboard repeats because its own firmware keeps sending make codes while the key is held, and Windows forwards each one. Injected input has no firmware behind it, so the repeat has to be generated here. Re-send the press while the paddle is held, after the user's configured delay and at their configured rate — SPI_GETKEYBOARDDELAY and SPI_GETKEYBOARDSPEED — so a paddle behaves like the key it is bound to rather than at a rate invented here. Both are captured at press time, so the rate cannot shift mid-hold. The read loop already ticks at report rate, so this is a per-frame elapsed check with no new thread or timer. Keys only. Mice do not repeat when held, so mouse-button bindings keep their one-shot behaviour, and gamepad bindings are held state in the pad report, where a repeat would mean nothing. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
1 parent
b5b7e28cf1
commit
7b2391dd95
3 files changed
+58
-1
No files matched your search
@@ -151,3 +151,21 @@ void SendKeyInput(uint16_t vk, bool down) {
|
||||
if (!down) input.ki.dwFlags |= KEYEVENTF_KEYUP;
|
||||
SendInput(1, &input, sizeof(INPUT));
|
||||
}
|
||||
|
||||
std::chrono::milliseconds KeyRepeatDelay() {
|
||||
// 0-3, meaning roughly 250ms to 1000ms in 250ms steps.
|
||||
DWORD setting = 1;
|
||||
if (!SystemParametersInfoW(SPI_GETKEYBOARDDELAY, 0, &setting, 0) || setting > 3)
|
||||
setting = 1;
|
||||
return std::chrono::milliseconds(250 * (static_cast<int>(setting) + 1));
|
||||
}
|
||||
|
||||
std::chrono::milliseconds KeyRepeatInterval() {
|
||||
// 0-31, meaning roughly 2.5 to 30 repeats per second. Windows documents only
|
||||
// the endpoints, so interpolate the rate between them.
|
||||
DWORD setting = 31;
|
||||
if (!SystemParametersInfoW(SPI_GETKEYBOARDSPEED, 0, &setting, 0) || setting > 31)
|
||||
setting = 31;
|
||||
const double perSecond = 2.5 + (30.0 - 2.5) * (static_cast<double>(setting) / 31.0);
|
||||
return std::chrono::milliseconds(static_cast<long long>(1000.0 / perSecond + 0.5));
|
||||
}
|
||||
Reference in new issue
Block a user