From 5b402ce5cece938a25bb9b78955de97bf1f8ac04 Mon Sep 17 00:00:00 2001 From: treeform Date: Wed, 25 Feb 2026 16:51:32 -0800 Subject: [PATCH 1/3] Window loosing or gaining focus must reset the keys. --- src/windy/platforms/macos/platform.nim | 15 ++++++++++++++- tests/manual_alttab.nim | 25 +++++++++++++++++++++++++ 2 files changed, 39 insertions(+), 1 deletion(-) create mode 100644 tests/manual_alttab.nim diff --git a/src/windy/platforms/macos/platform.nim b/src/windy/platforms/macos/platform.nim index 1b1557eb..5021eb09 100644 --- a/src/windy/platforms/macos/platform.nim +++ b/src/windy/platforms/macos/platform.nim @@ -326,6 +326,15 @@ proc windowDidMove( if window != nil and window.onMove != nil: window.onMove() +proc clearAllButtons(window: Window) = + ## Clears all pressed buttons to avoid stuck input state. + if window == nil: + return + + let buttons = window.state.buttonDown + for button in buttons: + window.handleButtonRelease(button) + proc canBecomeKeyWindow( self: ID, cmd: SEL, @@ -341,6 +350,7 @@ proc windowDidBecomeKey( let window = windows.forNSWindow(self.NSWindow) if window == nil: return + window.clearAllButtons() if window.onFocusChange != nil: window.onFocusChange() handleMouseMove(window, window.inner.mouseLocationOutsideOfEventStream) @@ -351,7 +361,10 @@ proc windowDidResignKey( notification: NSNotification ): ID {.cdecl.} = let window = windows.forNSWindow(self.NSWindow) - if window != nil and window.onFocusChange != nil: + if window == nil: + return + window.clearAllButtons() + if window.onFocusChange != nil: window.onFocusChange() # When loosing focus, prev mouse position is not valid. window.state.hasPrevMouse = false diff --git a/tests/manual_alttab.nim b/tests/manual_alttab.nim new file mode 100644 index 00000000..62fb532f --- /dev/null +++ b/tests/manual_alttab.nim @@ -0,0 +1,25 @@ +import opengl, os, windy + +let window = newWindow("Windy Callbacks", ivec2(1280, 800)) +window.runeInputEnabled = true + +window.makeContextCurrent() +loadExtensions() + +window.onFrame = proc() = + glClear(GL_COLOR_BUFFER_BIT) + + # Print if alt is down, when mouse is down: + if window.buttonDown[KeyLeftSuper] or window.buttonDown[KeyRightSuper]: + echo "alt is down and mouse is down" + glClearColor(1.0f, 0.0f, 0.0f, 1.0f) + else: + glClearColor(0.0f, 0.0f, 0.0f, 1.0f) + + window.swapBuffers() + +while not window.closeRequested: + + if window.minimized or not window.visible: + sleep(10) + pollEvents() From a0f851464c9b4021770ea9fdd5b5298e4c05d7bc Mon Sep 17 00:00:00 2001 From: treeform Date: Thu, 26 Feb 2026 06:11:10 -0800 Subject: [PATCH 2/3] Clear all buttons on windows too. --- src/windy/internal.nim | 5 +++++ src/windy/platforms/macos/platform.nim | 12 ++---------- src/windy/platforms/win32/platform.nim | 19 ++++++++++--------- tests/manual_alttab.nim | 10 +++++++--- 4 files changed, 24 insertions(+), 22 deletions(-) diff --git a/src/windy/internal.nim b/src/windy/internal.nim index a5fdcb48..3d125239 100644 --- a/src/windy/internal.nim +++ b/src/windy/internal.nim @@ -151,6 +151,11 @@ template handleButtonReleaseTemplate*() = if window.onButtonRelease != nil: window.onButtonRelease(button) +template clearButtonsTemplate*() = + let buttons = window.state.buttonDown + for button in buttons: + window.handleButtonRelease(button) + template handleRuneTemplate*() = if not window.state.runeInputEnabled: return diff --git a/src/windy/platforms/macos/platform.nim b/src/windy/platforms/macos/platform.nim index 5021eb09..87b7e3e3 100644 --- a/src/windy/platforms/macos/platform.nim +++ b/src/windy/platforms/macos/platform.nim @@ -326,14 +326,6 @@ proc windowDidMove( if window != nil and window.onMove != nil: window.onMove() -proc clearAllButtons(window: Window) = - ## Clears all pressed buttons to avoid stuck input state. - if window == nil: - return - - let buttons = window.state.buttonDown - for button in buttons: - window.handleButtonRelease(button) proc canBecomeKeyWindow( self: ID, @@ -350,7 +342,7 @@ proc windowDidBecomeKey( let window = windows.forNSWindow(self.NSWindow) if window == nil: return - window.clearAllButtons() + clearButtonsTemplate() if window.onFocusChange != nil: window.onFocusChange() handleMouseMove(window, window.inner.mouseLocationOutsideOfEventStream) @@ -363,7 +355,7 @@ proc windowDidResignKey( let window = windows.forNSWindow(self.NSWindow) if window == nil: return - window.clearAllButtons() + clearButtonsTemplate() if window.onFocusChange != nil: window.onFocusChange() # When loosing focus, prev mouse position is not valid. diff --git a/src/windy/platforms/win32/platform.nim b/src/windy/platforms/win32/platform.nim index 64359b46..2769dc96 100644 --- a/src/windy/platforms/win32/platform.nim +++ b/src/windy/platforms/win32/platform.nim @@ -253,7 +253,7 @@ proc destroy(window: Window) = window.onButtonRelease = nil window.onRune = nil window.onImeChange = nil - + # Destroy graphics context window.destoryGraphicsContext() @@ -889,6 +889,7 @@ proc wndProc( window.onFrame() return 0 of WM_SETFOCUS, WM_KILLFOCUS: + clearButtonsTemplate() if window.onFocusChange != nil: window.onFocusChange() return 0 @@ -1068,10 +1069,10 @@ when Backend == OpenGLBackend: proc createGraphicsContext( - window: Window, - depthBits: int, + window: Window, + depthBits: int, stencilBits: int, - msaa: MSAA, + msaa: MSAA, vsync: bool, openglVersion: OpenGLVersion ) = @@ -1167,10 +1168,10 @@ elif Backend == DirectXBackend: discard proc createGraphicsContext( - window: Window, - depthBits: int, - stencilBits: int, - msaa: MSAA, + window: Window, + depthBits: int, + stencilBits: int, + msaa: MSAA, vsync: bool, openglVersion: OpenGLVersion ) = @@ -1231,7 +1232,7 @@ proc newWindow*( result.style = style result.visible = visible - + except WindyError as e: destroy result diff --git a/tests/manual_alttab.nim b/tests/manual_alttab.nim index 62fb532f..f9e0b308 100644 --- a/tests/manual_alttab.nim +++ b/tests/manual_alttab.nim @@ -10,9 +10,13 @@ window.onFrame = proc() = glClear(GL_COLOR_BUFFER_BIT) # Print if alt is down, when mouse is down: - if window.buttonDown[KeyLeftSuper] or window.buttonDown[KeyRightSuper]: - echo "alt is down and mouse is down" - glClearColor(1.0f, 0.0f, 0.0f, 1.0f) + if window.buttonDown[KeyLeftSuper] or + window.buttonDown[KeyRightSuper] or + window.buttonDown[KeyLeftAlt] or + window.buttonDown[KeyRightAlt] or + window.buttonDown[KeyLeftControl] or + window.buttonDown[KeyRightControl]: + glClearColor(1.0f, 0.0f, 0.0f, 1.0f) else: glClearColor(0.0f, 0.0f, 0.0f, 1.0f) From a04025391371b89614d47690cbe793180a0de7f7 Mon Sep 17 00:00:00 2001 From: treeform Date: Thu, 26 Feb 2026 08:12:19 -0800 Subject: [PATCH 3/3] rename file. --- tests/{manual_alttab.nim => manual_alt_tab.nim} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename tests/{manual_alttab.nim => manual_alt_tab.nim} (100%) diff --git a/tests/manual_alttab.nim b/tests/manual_alt_tab.nim similarity index 100% rename from tests/manual_alttab.nim rename to tests/manual_alt_tab.nim