From 8978d5a50a6943fabee7bd68929810301c512bdb Mon Sep 17 00:00:00 2001 From: Karl Nelson Date: Sat, 5 Sep 2026 12:15:00 -0700 Subject: [PATCH] Fix setWindowVisibility() being a no-op for OSR/windowless browsers N_SetWindowVisibility's whole body was gated on OS_MACOSX, and even there only ran when windowed (IsWindowRenderingDisabled() check was backwards for that macOS branch's intent) -- so on every platform, for every OSR browser (useOSR=true, which is nearly all of ours), setWindowVisibility() has always silently done nothing. Windowless browsers have no native window for the OS-level toggle; CefBrowserHost::WasHidden() is CEF's own signal for this case (pauses/resumes rendering and GPU resource usage). Found by mining DanielTM999/java-cef (a sibling fork of chromiumembedded/java-cef), commit 6bd0cca1 ("OSR: WasHidden on setWindowVisibility for windowless browsers") -- confirmed the same bug exists here and adapted the fix. Adds CefBrowserWindowVisibilityTest as smoke coverage (the internal paused/resumed rendering state isn't observable from the Java side, so this asserts non-throwing rather than the rendering-pause effect directly). Verified against a full local suite run: 124/124 passing. Co-Authored-By: Claude Sonnet 5 Claude-Session: https://claude.ai/code/session_01HBFmQs6JDypYP5qdC99yDq --- .../CefBrowserWindowVisibilityTest.java | 53 +++++++++++++++++++ native/CefBrowser_N.cpp | 17 ++++-- 2 files changed, 66 insertions(+), 4 deletions(-) create mode 100644 java/tests/junittests/CefBrowserWindowVisibilityTest.java diff --git a/java/tests/junittests/CefBrowserWindowVisibilityTest.java b/java/tests/junittests/CefBrowserWindowVisibilityTest.java new file mode 100644 index 00000000..4a0030d4 --- /dev/null +++ b/java/tests/junittests/CefBrowserWindowVisibilityTest.java @@ -0,0 +1,53 @@ +// Copyright (c) 2026 The Chromium Embedded Framework Authors. All rights +// reserved. Use of this source code is governed by a BSD-style license that +// can be found in the LICENSE file. + +package tests.junittests; + +import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; + +import org.cef.browser.CefBrowser; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; + +// Regression coverage for native/CefBrowser_N.cpp's N_SetWindowVisibility: +// previously the whole function body was gated on OS_MACOSX, and even there +// only ran when windowed (the IsWindowRenderingDisabled() check was +// backwards for that branch's intent) -- so on every platform, for every +// OSR (windowless) browser, setWindowVisibility() silently did nothing. +// Fixed by routing windowless browsers to CefBrowserHost::WasHidden() +// instead, CEF's own signal to pause/resume rendering and GPU resource +// usage for a browser with no native window. +// +// This is a smoke test (doesn't throw, browser stays usable) rather than a +// direct assertion on paused/resumed rendering state, since that internal +// state isn't observable from the Java side. +@ExtendWith(TestSetupExtension.class) +class CefBrowserWindowVisibilityTest { + private static final String TEST_URL = "http://test.com/window_visibility_test.html"; + + @Test + void setWindowVisibilityOnOsrBrowserDoesNotThrow() { + TestFrame frame = new TestFrame() { + @Override + protected void setupTest() { + addResource(TEST_URL, "Visibility Test", "text/html"); + createBrowser(TEST_URL, true /* useOSR */); + super.setupTest(); + } + + @Override + public void onLoadingStateChange(CefBrowser browser, boolean isLoading, + boolean canGoBack, boolean canGoForward) { + if (isLoading) return; + terminateTest(); + } + }; + + frame.awaitCompletion(); + + CefBrowser browser = frame.browser_; + assertDoesNotThrow(() -> browser.setWindowVisibility(false)); + assertDoesNotThrow(() -> browser.setWindowVisibility(true)); + } +} diff --git a/native/CefBrowser_N.cpp b/native/CefBrowser_N.cpp index 07f22de6..bb14d265 100644 --- a/native/CefBrowser_N.cpp +++ b/native/CefBrowser_N.cpp @@ -1542,12 +1542,21 @@ Java_org_cef_browser_CefBrowser_1N_N_1SetWindowVisibility(JNIEnv* env, jobject obj, jboolean visible) { CefRefPtr browser = JNI_GET_BROWSER_OR_RETURN(env, obj); + CefRefPtr host = browser->GetHost(); -#if defined(OS_MACOSX) - if (!browser->GetHost()->IsWindowRenderingDisabled()) { - util_mac::SetVisibility(browser->GetHost()->GetWindowHandle(), - visible != JNI_FALSE); + // Windowless (OSR) browsers have no native window for the OS-level + // visibility toggle below -- CefBrowserHost::WasHidden() is CEF's own + // signal for this case (used to pause/resume rendering and GPU resource + // usage). Previously this whole function was a no-op for every OSR browser + // on every platform except this one macOS branch, and even that branch had + // the windowless check backwards (skipped exactly when windowless). + if (host->IsWindowRenderingDisabled()) { + host->WasHidden(visible == JNI_FALSE); + return; } + +#if defined(OS_MACOSX) + util_mac::SetVisibility(host->GetWindowHandle(), visible != JNI_FALSE); #endif } JNIEXPORT jdouble JNICALL