From f8a575e441f49efeb1636de2150c20d9fed776cf Mon Sep 17 00:00:00 2001 From: Lukasz Kostyra Date: Mon, 7 Jul 2025 16:11:20 +0200 Subject: [PATCH] Adjust window focus management for Windows Glass --- .../native-glass/win/FullScreenWindow.cpp | 10 ++--- .../src/main/native-glass/win/GlassWindow.cpp | 37 +++++++++++++------ .../src/main/native-glass/win/GlassWindow.h | 1 + 3 files changed, 31 insertions(+), 17 deletions(-) diff --git a/modules/javafx.graphics/src/main/native-glass/win/FullScreenWindow.cpp b/modules/javafx.graphics/src/main/native-glass/win/FullScreenWindow.cpp index 5286f72aebb..9e654fac96b 100644 --- a/modules/javafx.graphics/src/main/native-glass/win/FullScreenWindow.cpp +++ b/modules/javafx.graphics/src/main/native-glass/win/FullScreenWindow.cpp @@ -264,14 +264,14 @@ LRESULT FullScreenWindow::WindowProc(UINT msg, WPARAM wParam, LPARAM lParam) case WM_ACTIVATE: { // The fActive shouldn't be WA_INACTIVE && the window shouldn't be minimized: - const bool isFocusGained = LOWORD(wParam) != WA_INACTIVE && HIWORD(wParam) == 0; + const bool isActive = LOWORD(wParam) != WA_INACTIVE && HIWORD(wParam) == 0; - if (!isFocusGained && IsCommonDialogOwner()) { + if (!isActive && IsCommonDialogOwner()) { // Remain in full screen while a file dialog is showing break; } - HWND hWndInsertAfter = isFocusGained ? HWND_TOPMOST : HWND_BOTTOM; + HWND hWndInsertAfter = isActive ? HWND_TOPMOST : HWND_BOTTOM; if (m_bgWindow) { ::SetWindowPos(m_bgWindow->GetHWND(), hWndInsertAfter, 0, 0, 0, 0, @@ -282,14 +282,14 @@ LRESULT FullScreenWindow::WindowProc(UINT msg, WPARAM wParam, LPARAM lParam) GlassWindow * window = GlassWindow::FromHandle(m_oldViewParent); if (window) { - window->HandleActivateEvent(isFocusGained ? + window->HandleActivateEvent(isActive ? com_sun_glass_events_WindowEvent_FOCUS_GAINED : com_sun_glass_events_WindowEvent_FOCUS_LOST); // Child windows don't have a taskbar button, therefore // we force exiting from the FS mode if the window looses // focus. - if (!isFocusGained) { + if (!isActive) { ExitFullScreenMode(FALSE); } } diff --git a/modules/javafx.graphics/src/main/native-glass/win/GlassWindow.cpp b/modules/javafx.graphics/src/main/native-glass/win/GlassWindow.cpp index 74216836442..94d95fe535c 100644 --- a/modules/javafx.graphics/src/main/native-glass/win/GlassWindow.cpp +++ b/modules/javafx.graphics/src/main/native-glass/win/GlassWindow.cpp @@ -383,17 +383,17 @@ LRESULT GlassWindow::WindowProc(UINT msg, WPARAM wParam, LPARAM lParam) case WM_ACTIVATE: { // The fActive shouldn't be WA_INACTIVE && the window shouldn't be minimized: - const bool isFocusGained = LOWORD(wParam) != WA_INACTIVE && HIWORD(wParam) == 0; + const bool isActive = LOWORD(wParam) != WA_INACTIVE && HIWORD(wParam) == 0; if (IsInFullScreenMode()) { - HWND hWndInsertAfter = isFocusGained ? HWND_TOPMOST : HWND_BOTTOM; + HWND hWndInsertAfter = isActive ? HWND_TOPMOST : HWND_BOTTOM; ::SetWindowPos(GetHWND(), hWndInsertAfter, 0, 0, 0, 0, SWP_ASYNCWINDOWPOS | SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOOWNERZORDER | SWP_NOSIZE); } if (!GetDelegateWindow()) { - HandleActivateEvent(isFocusGained ? - com_sun_glass_events_WindowEvent_FOCUS_GAINED : - com_sun_glass_events_WindowEvent_FOCUS_LOST); + HandleActivateEvent(isActive ? + com_sun_glass_events_WindowEvent_FOCUS_GAINED : + com_sun_glass_events_WindowEvent_FOCUS_LOST); } } // Let the DefWindowProc() set the focus to this window @@ -411,12 +411,12 @@ LRESULT GlassWindow::WindowProc(UINT msg, WPARAM wParam, LPARAM lParam) break; case WM_SETFOCUS: if (!GetDelegateWindow()) { - SetFocused(true); + HandleFocusEvent(com_sun_glass_events_WindowEvent_FOCUS_GAINED); } break; case WM_KILLFOCUS: if (!GetDelegateWindow()) { - SetFocused(false); + HandleFocusEvent(com_sun_glass_events_WindowEvent_FOCUS_LOST); } break; case WM_GETMINMAXINFO: @@ -810,12 +810,23 @@ void GlassWindow::HandleSizeEvent(int type, RECT *pRect) void GlassWindow::HandleActivateEvent(jint event) { - const bool active = event != com_sun_glass_events_WindowEvent_FOCUS_LOST; + const bool focus = event != com_sun_glass_events_WindowEvent_FOCUS_LOST; - if (!active) { + if (!focus) { UngrabFocus(); } + HandleFocusEvent(event); +} + +void GlassWindow::HandleFocusEvent(jint event) +{ + const bool focus = event != com_sun_glass_events_WindowEvent_FOCUS_LOST; + + if (focus == m_isFocused) return; + + SetFocused(focus); + JNIEnv* env = GetEnv(); env->CallVoidMethod(m_grefThis, javaIDs.Window.notifyFocus, event); CheckAndClearException(env); @@ -1869,13 +1880,15 @@ JNIEXPORT jboolean JNICALL Java_com_sun_glass_ui_win_WinWindow__1setVisible } } - - ::ShowWindow(hWnd, visible ? SW_SHOW : SW_HIDE); + ::ShowWindow(hWnd, visible ? SW_SHOWNA : SW_HIDE); if (visible) { if (pWindow) { if (pWindow->IsFocusable()) { - ::SetForegroundWindow(hWnd); + BOOL success = ::SetForegroundWindow(hWnd); + if (success == FALSE) { + pWindow->HandleFocusEvent(com_sun_glass_events_WindowEvent_FOCUS_LOST); + } } else { // JDK-8112905: // On some latest platform versions, unfocusable windows diff --git a/modules/javafx.graphics/src/main/native-glass/win/GlassWindow.h b/modules/javafx.graphics/src/main/native-glass/win/GlassWindow.h index f88dbdd29dd..01cce6c495c 100644 --- a/modules/javafx.graphics/src/main/native-glass/win/GlassWindow.h +++ b/modules/javafx.graphics/src/main/native-glass/win/GlassWindow.h @@ -96,6 +96,7 @@ class GlassWindow : public BaseWnd, public ViewContainer { HWND GetDelegateWindow() { return m_delegateWindow; } void HandleActivateEvent(jint event); + void HandleFocusEvent(jint event); void HandleCloseEvent(); virtual BOOL EnterFullScreenMode(GlassView * view, BOOL animate, BOOL keepRatio);