> 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.

Lukasz Kostyra has updated the pull request with a new target base due to a 
merge or a rebase. The incremental webrev excludes the unrelated changes 
brought in by the merge/rebase. The pull request contains two additional 
commits since the last revision:

 - Merge remote-tracking branch 'origin/master' into isFocused_fix-8359899
 - Adjust window focus management for Windows Glass

-------------

Changes:
  - all: https://git.openjdk.org/jfx/pull/1849/files
  - new: https://git.openjdk.org/jfx/pull/1849/files/f8a575e4..00c2d60e

Webrevs:
 - full: https://webrevs.openjdk.org/?repo=jfx&pr=1849&range=01
 - incr: https://webrevs.openjdk.org/?repo=jfx&pr=1849&range=00-01

  Stats: 904516 lines in 10126 files changed: 386268 ins; 394150 del; 124098 mod
  Patch: https://git.openjdk.org/jfx/pull/1849.diff
  Fetch: git fetch https://git.openjdk.org/jfx.git pull/1849/head:pull/1849

PR: https://git.openjdk.org/jfx/pull/1849

Reply via email to