On Fri, 11 Sep 2026 05:28:16 GMT, Prasanta Sadhukhan <[email protected]> wrote:
> Few ModalFocusTransferTests tests were failing in macos due to focus not > coming back to expected component. > The `FocusTransferDWFDocModalTest, FocusTransferDWFModelessTest, > FocusTransferDWFNonModalTest` > tests opens in this sequence Dialog → Window → Frame (DWF) and when Frame > closes, > it expects the focus to come back to Window but it goes back to Dialog. > It does not seem to be timing failures as waiting longer in the test doesn't > fix this. > The tests expose a macOS AWT focus-model gap for java.awt.Window. > On macOS, an ordinary Window is treated as a “simple window” > https://github.com/openjdk/jdk/blob/7f068889b2d65a5ae2e10124da0f79eb20067521/src/java.desktop/macosx/classes/sun/lwawt/LWWindowPeer.java#L1304-L1306 > A simple Window is deliberately not made the native macOS key window. > Instead, AWT gives native focus to its nearest Frame or Dialog owner, then > synthesizes Java-level focus events for the Window > > When Frame closes, AppKit activates the native Dialog and > `LWWindowPeer.notifyActivation()` translated that Java focus for the Dialog. > But the logical previous focused window was the Window, so its Open button > never regained focus. > > The same issue occurs in the Frame → Window → Dialog (FWD) tests which are > `FocusTransferFWDAppModal*Test, FocusTransferFWDDocModal*Test, > FocusTransferFWDModeless*Test and FocusTransferFWDNonModal*Test` > The native Frame is reactivated after the Dialog closes, but Java focus > should return to the intermediate Window. > > As mentioned, waiting longer in the test doesn't fix this...the wrong Java > focused window is selected deterministically after the native activation > event. > > I tried with a native Cocoa program mimicking Dialog->Window->Frame opening > testing which component regains focus when Frame is closed and it turns out > to be Window unlike Java's Dialog so it is a product issue. > > A product fix is done so that it preserves the existing macOS design—an AWT > Window is still not made natively focusable. > Instead it restores the correct Java-level focus history > When a native Frame or Dialog gains focus while a simple Window has Java > focus, it records that Window as its possible restore target > When the simple Window’s nearest native owner becomes active, > AWT restores Java focus to the remembered Window, but only when it is still > visible, focusable, and unblocked. > > The static handoff reference is made WeakReference as > a strong static reference retained a disposed peer, which retained its > MainFrame and all child components,... "hidden" means the native Frame or Dialog that had Java focus immediately before it was hidden/closed. It is the focus-transition source so the peer is undergoing setVisible(false) or dispose()—it is no longer eligible to receive focus. But I will search for better name along with making it more synchronized and test. ------------- PR Comment: https://git.openjdk.org/jdk/pull/32831#issuecomment-5692850549
