[client/idd] input: wait for valid keyboard LED feedback

Do not publish the default all-off LED value until Windows supplies a
real HID output report. Treat the first all-off report as valid and
retain known state across pipe reconnects.

Serialize feedback processing with connection invalidation so a stale
message cannot restore validity after disconnect.
This commit is contained in:
Geoffrey McRae
2026-08-21 13:55:15 +10:00
parent 7ca94e8959
commit efb397bbaf
3 changed files with 23 additions and 13 deletions

View File

@@ -636,6 +636,11 @@ bool CInputPipeServer::OnPipeMessage(
const LGInputPipeMessage& frame = const LGInputPipeMessage& frame =
*static_cast<const LGInputPipeMessage *>(message); *static_cast<const LGInputPipeMessage *>(message);
CSRWExclusiveLock connectionLock(m_connectionLock);
if (!(Atomic::Load(m_state, std::memory_order_relaxed) & 1))
return true;
if (frame.magic != LG_INPUT_PIPE_MAGIC || if (frame.magic != LG_INPUT_PIPE_MAGIC ||
frame.version != LG_INPUT_PIPE_VERSION || frame.version != LG_INPUT_PIPE_VERSION ||
frame.type != LG_INPUT_PIPE_MESSAGE_KEYBOARD_LEDS || frame.type != LG_INPUT_PIPE_MESSAGE_KEYBOARD_LEDS ||

View File

@@ -82,9 +82,12 @@ void CInputPipeClient::OnPipeConnected()
{ {
CSRWExclusiveLock lock(m_feedbackLock); CSRWExclusiveLock lock(m_feedbackLock);
m_feedbackSequence = 0; m_feedbackSequence = 0;
m_feedbackReady = SendKeyboardLEDsLocked(); m_feedbackReady = true;
if (!m_feedbackReady) if (m_keyboardLEDsValid && !SendKeyboardLEDsLocked())
{
m_feedbackReady = false;
DEBUG_WARN("Failed to report LGInput keyboard LEDs"); DEBUG_WARN("Failed to report LGInput keyboard LEDs");
}
} }
DEBUG_INFO("Connected to the LGIdd input transport"); DEBUG_INFO("Connected to the LGIdd input transport");
} }
@@ -353,10 +356,11 @@ void CInputPipeClient::UpdateKeyboardLEDs(uint8_t leds)
leds &= mask; leds &= mask;
CSRWExclusiveLock lock(m_feedbackLock); CSRWExclusiveLock lock(m_feedbackLock);
if (m_keyboardLEDs == leds) if (m_keyboardLEDsValid && m_keyboardLEDs == leds)
return; return;
m_keyboardLEDs = leds; m_keyboardLEDs = leds;
m_keyboardLEDsValid = true;
if (m_feedbackReady && !SendKeyboardLEDsLocked()) if (m_feedbackReady && !SendKeyboardLEDsLocked())
{ {
m_feedbackReady = false; m_feedbackReady = false;

View File

@@ -50,13 +50,14 @@ private:
CPipeEndpoint m_endpoint; CPipeEndpoint m_endpoint;
CSRWLock m_feedbackLock; CSRWLock m_feedbackLock;
bool m_feedbackReady = false; bool m_feedbackReady = false;
uint64_t m_feedbackSequence = 0; bool m_keyboardLEDsValid = false;
uint8_t m_keyboardLEDs = 0; uint64_t m_feedbackSequence = 0;
uint64_t m_lastSequence = 0; uint8_t m_keyboardLEDs = 0;
uint64_t m_statReceived = 0; uint64_t m_lastSequence = 0;
uint64_t m_statMalformed = 0; uint64_t m_statReceived = 0;
uint64_t m_statSequenceResets = 0; uint64_t m_statMalformed = 0;
uint64_t m_statSubmitFailed = 0; uint64_t m_statSequenceResets = 0;
ULONGLONG m_lastStatistics = 0; uint64_t m_statSubmitFailed = 0;
ULONGLONG m_lastStatistics = 0;
}; };