From 100d76b88fdf430b207a5c5c17170c1f2dd26e3b Mon Sep 17 00:00:00 2001 From: DanS Date: Tue, 13 Oct 2026 18:16:50 -0500 Subject: [PATCH] fix(input): handle the first Alt+wheel while idle in the wait path Alt + mouse wheel adjusts the font scale, but it was only handled in the poll loop that runs after the app wakes. When the app was idle it blocks in a single timed wait, and that first wheel event went straight to ImGui, scrolling the window instead of changing the scale until a later event arrived. - The Alt+wheel handling is pulled into a shared helper used by both the idle wait path and the poll loop, so the first event while idle is consumed and triggers a redraw. - Behaviour is otherwise unchanged: the visual scale updates smoothly and the font atlas is rebuilt once scrolling stops. Co-Authored-By: Claude Opus 4.8 --- src/main.cpp | 45 +++++++++++++++++++++++---------------------- 1 file changed, 23 insertions(+), 22 deletions(-) diff --git a/src/main.cpp b/src/main.cpp index cbeced4..23596eb 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1639,6 +1639,25 @@ int main(int argc, char* argv[]) else if (isWindowStateEvent(e.type)) settleFrames = kSettleFrames; }; + // Deferred font-scale commit: smooth visual update during Alt+scroll, + // atlas rebuild after scrolling stops (~200ms idle). + Uint64 fontScaleCommitTick = 0; // 0 = nothing pending + // Alt + scroll wheel -> font scale. Returns true if the event was consumed. + auto handleAltWheel = [&](const SDL_Event& e) -> bool { + if (e.type != SDL_EVENT_MOUSE_WHEEL) return false; + if (!(SDL_GetModState() & SDL_KMOD_ALT)) return false; + float step = 0.05f * e.wheel.y; + float cur = dragonx::ui::Layout::userFontScale(); + float next = std::max(1.0f, std::min(1.5f, cur + step)); + if (next != cur) { + // Smooth preview — no atlas rebuild yet + dragonx::ui::Layout::setUserFontScaleVisual(next); + // Schedule atlas rebuild after scrolling stops + fontScaleCommitTick = SDL_GetTicks() + 200; + } + return true; + }; + // Headless verification hook (DRAGONX_FULL_SWEEP=1, handled after present), hoisted so the pacing // decision can keep its warm-up frames coming. #if DRAGONX_ENABLE_UI_SWEEP @@ -1726,7 +1745,8 @@ int main(int argc, char* argv[]) SDL_Event waitEvent; if (waitMs > 0 && SDL_WaitEventTimeout(&waitEvent, waitMs)) { noteEvent(waitEvent); - ImGui_ImplSDL3_ProcessEvent(&waitEvent); + if (handleAltWheel(waitEvent)) needsRedraw = true; + else ImGui_ImplSDL3_ProcessEvent(&waitEvent); if (waitEvent.type == SDL_EVENT_QUIT) { app.beginShutdown(); } @@ -1828,29 +1848,10 @@ int main(int argc, char* argv[]) // Poll remaining events SDL_Event event; - // Deferred font-scale commit: smooth visual update during Alt+scroll, - // atlas rebuild after scrolling stops (~200ms idle). - static Uint64 fontScaleCommitTick = 0; // 0 = nothing pending - while (SDL_PollEvent(&event)) { noteEvent(event); - // Alt + scroll wheel: smooth font scale adjustment - if (event.type == SDL_EVENT_MOUSE_WHEEL) { - SDL_Keymod mods = SDL_GetModState(); - if (mods & SDL_KMOD_ALT) { - float step = 0.05f * event.wheel.y; - float cur = dragonx::ui::Layout::userFontScale(); - float next = std::max(1.0f, std::min(1.5f, cur + step)); - if (next != cur) { - // Smooth preview — no atlas rebuild yet - dragonx::ui::Layout::setUserFontScaleVisual(next); - // Schedule atlas rebuild after scrolling stops - fontScaleCommitTick = SDL_GetTicks() + 200; - } - // Don't pass Alt+scroll to ImGui (would scroll windows) - continue; - } - } + // Alt + scroll wheel: smooth font scale adjustment (don't pass to ImGui: would scroll windows) + if (handleAltWheel(event)) continue; ImGui_ImplSDL3_ProcessEvent(&event); if (event.type == SDL_EVENT_QUIT) {