On Wed, 16 Jul 2025 08:50:31 GMT, Lukasz Kostyra <[email protected]> wrote:
> This PR fixes `isFocused()` returning invalid value when Stage fails to > receive focus after calling `Stage.show()`. This problem is Windows-only. > > In Windows the `SetForegroundWindow()` API lists [a set of conditions to > successfully grant focus to a > Window](https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-setforegroundwindow#remarks). > If any of the conditions are not met, the API will return FALSE. JavaFX did > not respect that and instead assumed that receiving `WM_ACTIVATE` with our > Window being activated is enough to assume the Window is in focus (which in > some cases is not true). > > I first tried reacting to `WM_SETFOCUS` and `WM_KILLFOCUS` but it seems those > messages are not sent when the window is shown for the first time (instead > `WM_ACTIVATE` is used). > > To correct this behavior, I noticed the following path is the most reliable: > - Call `ShowWindow()` using `SW_SHOWNA` instead of `SW_SHOW` - that makes the > window visible but does NOT activate it > - Call `SetForegroundWindow()` - that will attempt to give the Window focus > and will also activate it if it is successful > - If successful, Java `notifyFocus` callback will be called via > `WM_ACTIVATE` handler > - If it fails, we call the `notifyFocus` callback manually informing the > upper layers the focus is lost. This establishes the correct state of > `Window.focused` property. > > With this change I observed that all tests pass as intended as long as two > conditions are met (these are needed to satisfy `SetForegroundWindow()` > restrictions): > - Gradle build is ran without the Gradle daemon > - The terminal running Gradle test is in foreground > > If any of above two conditions is not met, some tests (including canary test > from https://github.com/openjdk/jfx/pull/1804) now timeout/fail when checking > whether `Window.isFocused()` is true. > > Manually started JavaFX apps (ex. Ensemble) run as they used to and still > receive focus upon Stage showing. I didn't get a chance to look into other solutions yet, but I will be investigating that soon. ------------- PR Comment: https://git.openjdk.org/jfx/pull/1849#issuecomment-3436732981
