mirror of
https://github.com/ddeverill/SteamlessController.git
synced 2026-10-22 06:32:20 -05:00
Record what the pads are set to, not just when control was taken (#95)
Two rounds of #95 diagnostics produced logs that could not answer the question they were collected for, and both times the reason was the same: the only line describing the trackpad setup came from EnableGameMode, and it was gated on a pad already being claimed for the desktop at that moment. That gate assumes configuration precedes enabling. It usually does not — the settings window is how you configure a pad, and people open it after turning the app on. The reporter's last log never enabled at all; the maintainer's next one enabled first and configured five seconds later. Neither produced the wheel line, so neither could say whether the pad under test was even in scroll mode. So the pad setup is now logged where it is applied rather than only where control is taken, once per change: PADS: left=scroll (natural, speed 25%, wheel correction x0.30, net 8% of calibrated) right=pointer The net figure is the point. A scroll-feels-wrong report has two independent multipliers behind it — the user's speed setting and the machine's lines-per-notch — and neither alone explains the feel, so the line carries both and their product. The correction is dropped on a machine left at the Windows default, where saying it three times adds nothing. The line also says when game mode is off, because settings changed then do nothing whatsoever and until now nothing told anybody. That is the exact shape of the reporter's "no change even at 25%". The enable-time environment line loses its gate as well. Withholding it when no pad is claimed hid it from the report most likely to need it — a trackpad doing nothing at all, which deserves a line saying so rather than silence. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
1 parent
341d3e3ae0
commit
36b94872c1
2 files changed
+85
-2
No files matched your search
@@ -472,6 +472,62 @@ void ControllerManager::ReleaseDevices() {
|
||||
NotifyStateChanged();
|
||||
}
|
||||
|
||||
|
||||
// One pad, in the terms a bug report is written in.
|
||||
//
|
||||
// Scroll carries more than the others because a scroll-feels-wrong report has
|
||||
// two independent multipliers behind it, and neither alone explains the feel:
|
||||
// the user's own speed setting, and the machine's lines-per-notch, which
|
||||
// Windows applies to every wheel event after we send it. The net figure is
|
||||
// what the pad actually does relative to the calibrated feel, and it is the
|
||||
// number worth comparing between two machines.
|
||||
static std::string DescribePad(const TrackpadSettings& pad) {
|
||||
switch (pad.mode) {
|
||||
case TrackpadMode::MousePointer: return "pointer";
|
||||
case TrackpadMode::DS4Touchpad: return "ds4 touchpad";
|
||||
case TrackpadMode::SingleButton: return "single button";
|
||||
case TrackpadMode::DirectionalPad:
|
||||
return std::string("dpad (")
|
||||
+ (pad.diagonals == DiagonalMode::FourWay ? "4-way" : "8-way") + ")";
|
||||
case TrackpadMode::ScrollWheel: {
|
||||
const float correction =
|
||||
InputInjection::WheelCorrection(InputInjection::WheelLinesPerNotch());
|
||||
const char* dir = pad.scrollDir == ScrollDirection::Reversed ? "reversed"
|
||||
: "natural";
|
||||
char buf[160];
|
||||
// The correction is 1.0 on a machine left at the Windows default, where
|
||||
// repeating it and the net figure would say the same thing three times.
|
||||
if (std::fabs(correction - 1.0f) < 0.005f)
|
||||
snprintf(buf, sizeof(buf), "scroll (%s, speed %u%%)", dir, pad.scrollSpeed);
|
||||
else
|
||||
snprintf(buf, sizeof(buf),
|
||||
"scroll (%s, speed %u%%, wheel correction x%.2f, net %.0f%% of "
|
||||
"calibrated)",
|
||||
dir, pad.scrollSpeed, static_cast<double>(correction),
|
||||
static_cast<double>(pad.scrollSpeed) * correction);
|
||||
return buf;
|
||||
}
|
||||
default: return "none";
|
||||
}
|
||||
}
|
||||
|
||||
void ControllerManager::LogPadSettings() {
|
||||
std::string line = "PADS: left=" + DescribePad(m_profile.leftPad)
|
||||
+ " right=" + DescribePad(m_profile.rightPad);
|
||||
|
||||
// The failure this exists to make visible: settings changed with game mode
|
||||
// off do nothing at all, and until now nothing said so. Two #95 sessions
|
||||
// were spent that way — one where the pad was never claimed, one where it
|
||||
// was configured after the claim.
|
||||
if (!IsGameModeActive())
|
||||
line += " — game mode is off, so these are not driving anything yet";
|
||||
|
||||
if (line == m_lastPadDescription) return;
|
||||
m_lastPadDescription = line;
|
||||
// %s rather than the line as a format: it contains per-cent signs.
|
||||
EventLog::Write("%s", line.c_str());
|
||||
}
|
||||
|
||||
void ControllerManager::ApplyPadSettings(Slot& slot) {
|
||||
slot.leftPad.SetPad(true);
|
||||
slot.rightPad.SetPad(false);
|
||||
@@ -513,6 +569,9 @@ void ControllerManager::SetProfile(const ControllerProfile& profile) {
|
||||
// live inside the per-slot TrackpadInput objects, so those are pushed.
|
||||
for (auto& slot : m_slots)
|
||||
ApplyPadSettings(*slot);
|
||||
|
||||
// After the push, so what is logged is what the pads are now set to.
|
||||
LogPadSettings();
|
||||
}
|
||||
|
||||
// Sends the key or mouse event a binding stands for. Gamepad actions reach the
|
||||
@@ -932,19 +991,30 @@ ControllerManager::EnableGameModeSlot(Slot& slot, bool& padUnavailableOut, bool
|
||||
// Takeover is the moment users report the trackpad arriving dead, and what
|
||||
// decides whether injection can land is whatever window happens to be in
|
||||
// front right then — so record it here rather than reconstructing it later.
|
||||
if (m_profile.leftPad.ClaimedForDesktop() || m_profile.rightPad.ClaimedForDesktop())
|
||||
InputInjection::LogEnvironment("game mode taken");
|
||||
//
|
||||
// Unconditional. It used to fire only when a pad was already claimed for
|
||||
// the desktop, which quietly withheld it from the two reports most likely
|
||||
// to need it: a pad configured after enabling, and a trackpad that does
|
||||
// nothing because no pad is claimed at all. The second is worth a line
|
||||
// saying so, not silence.
|
||||
InputInjection::LogEnvironment("game mode taken");
|
||||
slot.gameModeActive = true;
|
||||
slot.leftPad.Reset();
|
||||
slot.rightPad.Reset();
|
||||
ReleaseHeldPaddleInputs(slot);
|
||||
ApplyPadSettings(slot);
|
||||
// After gameModeActive, so the line does not claim the pads are inert.
|
||||
LogPadSettings();
|
||||
StartReadLoop(slot);
|
||||
return GameModeOutcome::Enabled;
|
||||
}
|
||||
|
||||
void ControllerManager::DisableGameModeSlot(Slot& slot) {
|
||||
if (!slot.gameModeActive) return;
|
||||
// Forget what was last logged, so the next enable states the pad setup
|
||||
// again rather than deduplicating against a previous session's line. Each
|
||||
// enable in the log should be readable without scrolling back past it.
|
||||
m_lastPadDescription.clear();
|
||||
EventLog::Write("GAMEMODE: disabled %ls", slot.path.c_str());
|
||||
StopReadLoop(slot);
|
||||
if (slot.sc->IsOpen())
|
||||
|
||||
@@ -150,6 +150,16 @@ private:
|
||||
// its virtual controller. Shared by SetProfile and slot creation.
|
||||
void ApplyPadSettings(Slot& slot);
|
||||
|
||||
// Records what the pads are set to, once per change.
|
||||
//
|
||||
// The enable-time environment line cannot answer this. It fires from
|
||||
// EnableGameMode and describes the moment control was taken, so a pad
|
||||
// configured afterwards — the ordinary order, since the settings window is
|
||||
// how you configure one — is never described at all. Two rounds of #95
|
||||
// diagnostics went by on logs that could not say whether the pad under
|
||||
// test was even in scroll mode.
|
||||
void LogPadSettings();
|
||||
|
||||
StateChangedFn m_onStateChanged;
|
||||
AlertFn m_alertFn;
|
||||
std::vector<std::unique_ptr<Slot>> m_slots;
|
||||
@@ -167,6 +177,9 @@ private:
|
||||
Pounce m_pounce;
|
||||
bool m_lastPadDriverMissing = false;
|
||||
std::wstring m_lastBusReport;
|
||||
// The last line LogPadSettings wrote, so a setting that did not change
|
||||
// does not write one. SetProfile runs on every foreground switch.
|
||||
std::string m_lastPadDescription;
|
||||
ControllerProfile m_profile;
|
||||
|
||||
std::atomic<bool> m_capturing{false};
|
||||
|
||||
Reference in new issue
Block a user