From 9d1cdd020f4bc877cb9675afeed439c6e4749ec2 Mon Sep 17 00:00:00 2001 From: Marshall Greenblatt Date: Tue, 7 Nov 2023 16:40:29 -0500 Subject: [PATCH] mac: Update CSS on fullscreen window exit (fixes #3597) --- include/capi/cef_browser_capi.h | 25 ++++++++++++++- include/cef_api_hash.h | 8 ++--- include/cef_browser.h | 24 +++++++++++++++ libcef/browser/browser_host_base.cc | 25 +++++++++++++++ libcef/browser/browser_host_base.h | 2 ++ libcef/browser/views/native_widget_mac.mm | 6 ++++ libcef_dll/cpptoc/browser_host_cpptoc.cc | 37 ++++++++++++++++++++++- libcef_dll/ctocpp/browser_host_ctocpp.cc | 34 ++++++++++++++++++++- libcef_dll/ctocpp/browser_host_ctocpp.h | 4 ++- tests/cefclient/browser/views_window.cc | 12 ++++++++ tests/cefclient/resources/window.html | 19 ++++++++++-- 11 files changed, 186 insertions(+), 10 deletions(-) diff --git a/include/capi/cef_browser_capi.h b/include/capi/cef_browser_capi.h index 11f90d9e0..3a8a64a1c 100644 --- a/include/capi/cef_browser_capi.h +++ b/include/capi/cef_browser_capi.h @@ -33,7 +33,7 @@ // by hand. See the translator.README.txt file in the tools directory for // more information. // -// $hash=db4fce1215cb4f69346ef2d048974ba34187b2b1$ +// $hash=13ba2d807f2c1ac3adfc65f2bdb269baecba57ec$ // #ifndef CEF_INCLUDE_CAPI_CEF_BROWSER_CAPI_H_ @@ -932,6 +932,29 @@ typedef struct _cef_browser_host_t { /// be called on the UI thread. /// int(CEF_CALLBACK* is_audio_muted)(struct _cef_browser_host_t* self); + + /// + /// Returns true (1) if the renderer is currently in browser fullscreen. This + /// differs from window fullscreen in that browser fullscreen is entered using + /// the JavaScript Fullscreen API and modifies CSS attributes such as the + /// ::backdrop pseudo-element and :fullscreen pseudo-structure. This function + /// can only be called on the UI thread. + /// + int(CEF_CALLBACK* is_fullscreen)(struct _cef_browser_host_t* self); + + /// + /// Requests the renderer to exit browser fullscreen. In most cases exiting + /// window fullscreen should also exit browser fullscreen. With the Alloy + /// runtime this function should be called in response to a user action such + /// as clicking the green traffic light button on MacOS + /// (cef_window_delegate_t::OnWindowFullscreenTransition callback) or pressing + /// the "ESC" key (cef_keyboard_handler_t::OnPreKeyEvent callback). With the + /// Chrome runtime these standard exit actions are handled internally but + /// new/additional user actions can use this function. Set |will_cause_resize| + /// to true (1) if exiting browser fullscreen will cause a view resize. + /// + void(CEF_CALLBACK* exit_fullscreen)(struct _cef_browser_host_t* self, + int will_cause_resize); } cef_browser_host_t; /// diff --git a/include/cef_api_hash.h b/include/cef_api_hash.h index 90142ccb0..46e515395 100644 --- a/include/cef_api_hash.h +++ b/include/cef_api_hash.h @@ -42,13 +42,13 @@ // way that may cause binary incompatibility with other builds. The universal // hash value will change if any platform is affected whereas the platform hash // values will change only if that particular platform is affected. -#define CEF_API_HASH_UNIVERSAL "4acea2e5c7a3e281d9652802ae1d24b25eef299b" +#define CEF_API_HASH_UNIVERSAL "87db318fb26ee0debfcb686433bd334ea7b9923d" #if defined(OS_WIN) -#define CEF_API_HASH_PLATFORM "3a181fdfaa42d2214c77cd83f76886b0657b0b53" +#define CEF_API_HASH_PLATFORM "aee3b3f687dce72a3370f98309bb43f722596b83" #elif defined(OS_MAC) -#define CEF_API_HASH_PLATFORM "06bfe874ee215bde0a415bac7ac37ecf4969d4ca" +#define CEF_API_HASH_PLATFORM "1cc534c1000bf82e8db52b8635272bb18daec4c2" #elif defined(OS_LINUX) -#define CEF_API_HASH_PLATFORM "1615f7e7079d89e2e81f683d4a8480455b5f2a60" +#define CEF_API_HASH_PLATFORM "47f4af678148110cb790fb48a957fb522446ecf2" #endif #ifdef __cplusplus diff --git a/include/cef_browser.h b/include/cef_browser.h index 051a1e078..20e0a7f9e 100644 --- a/include/cef_browser.h +++ b/include/cef_browser.h @@ -964,6 +964,30 @@ class CefBrowserHost : public virtual CefBaseRefCounted { /// /*--cef()--*/ virtual bool IsAudioMuted() = 0; + + /// + /// Returns true if the renderer is currently in browser fullscreen. This + /// differs from window fullscreen in that browser fullscreen is entered using + /// the JavaScript Fullscreen API and modifies CSS attributes such as the + /// ::backdrop pseudo-element and :fullscreen pseudo-class. This method can + /// only be called on the UI thread. + /// + /*--cef()--*/ + virtual bool IsFullscreen() = 0; + + /// + /// Requests the renderer to exit browser fullscreen. In most cases exiting + /// window fullscreen should also exit browser fullscreen. With the Alloy + /// runtime this method should be called in response to a user action such as + /// clicking the green traffic light button on MacOS + /// (CefWindowDelegate::OnWindowFullscreenTransition callback) or pressing the + /// "ESC" key (CefKeyboardHandler::OnPreKeyEvent callback). With the Chrome + /// runtime these standard exit actions are handled internally but + /// new/additional user actions can use this method. Set |will_cause_resize| + /// to true if exiting browser fullscreen will cause a view resize. + /// + /*--cef()--*/ + virtual void ExitFullscreen(bool will_cause_resize) = 0; }; #endif // CEF_INCLUDE_CEF_BROWSER_H_ diff --git a/libcef/browser/browser_host_base.cc b/libcef/browser/browser_host_base.cc index 3082319b2..414d4e087 100644 --- a/libcef/browser/browser_host_base.cc +++ b/libcef/browser/browser_host_base.cc @@ -633,6 +633,31 @@ void CefBrowserHostBase::NotifyMoveOrResizeStarted() { #endif } +bool CefBrowserHostBase::IsFullscreen() { + if (!CEF_CURRENTLY_ON_UIT()) { + DCHECK(false) << "called on invalid thread"; + return false; + } + + if (auto web_contents = GetWebContents()) { + return web_contents->IsFullscreen(); + } + return false; +} + +void CefBrowserHostBase::ExitFullscreen(bool will_cause_resize) { + if (!CEF_CURRENTLY_ON_UIT()) { + CEF_POST_TASK(CEF_UIT, base::BindOnce(&CefBrowserHostBase::ExitFullscreen, + this, will_cause_resize)); + return; + } + + auto web_contents = GetWebContents(); + if (web_contents && web_contents->IsFullscreen()) { + web_contents->ExitFullscreen(will_cause_resize); + } +} + void CefBrowserHostBase::ReplaceMisspelling(const CefString& word) { if (!CEF_CURRENTLY_ON_UIT()) { CEF_POST_TASK( diff --git a/libcef/browser/browser_host_base.h b/libcef/browser/browser_host_base.h index 9c968a413..3d7d9c44e 100644 --- a/libcef/browser/browser_host_base.h +++ b/libcef/browser/browser_host_base.h @@ -212,6 +212,8 @@ class CefBrowserHostBase : public CefBrowserHost, bool current_only) override; CefRefPtr GetVisibleNavigationEntry() override; void NotifyMoveOrResizeStarted() override; + bool IsFullscreen() override; + void ExitFullscreen(bool will_cause_resize) override; // CefBrowser methods: bool IsValid() override; diff --git a/libcef/browser/views/native_widget_mac.mm b/libcef/browser/views/native_widget_mac.mm index ae648a23f..9367f3133 100644 --- a/libcef/browser/views/native_widget_mac.mm +++ b/libcef/browser/views/native_widget_mac.mm @@ -121,12 +121,18 @@ void CefNativeWidgetMac::OnWindowFullscreenTransitionStart() { views::NativeWidgetMac::OnWindowFullscreenTransitionStart(); if (IsCefWindowInitialized()) { window_delegate_->OnWindowFullscreenTransition(window_, false); + if (browser_view_) { + browser_view_->FullscreenStateChanging(); + } } } void CefNativeWidgetMac::OnWindowFullscreenTransitionComplete() { views::NativeWidgetMac::OnWindowFullscreenTransitionComplete(); if (IsCefWindowInitialized()) { + if (browser_view_) { + browser_view_->FullscreenStateChanged(); + } window_delegate_->OnWindowFullscreenTransition(window_, true); } } diff --git a/libcef_dll/cpptoc/browser_host_cpptoc.cc b/libcef_dll/cpptoc/browser_host_cpptoc.cc index 7811734f5..a96e08d53 100644 --- a/libcef_dll/cpptoc/browser_host_cpptoc.cc +++ b/libcef_dll/cpptoc/browser_host_cpptoc.cc @@ -9,7 +9,7 @@ // implementations. See the translator.README.txt file in the tools directory // for more information. // -// $hash=497607653318fe0245cbe18c8911e39867e16249$ +// $hash=5358aa617ebb6d7d074e2d346599fbd6777f1770$ // #include "libcef_dll/cpptoc/browser_host_cpptoc.h" @@ -1435,6 +1435,39 @@ int CEF_CALLBACK browser_host_is_audio_muted(struct _cef_browser_host_t* self) { return _retval; } +int CEF_CALLBACK browser_host_is_fullscreen(struct _cef_browser_host_t* self) { + shutdown_checker::AssertNotShutdown(); + + // AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING + + DCHECK(self); + if (!self) { + return 0; + } + + // Execute + bool _retval = CefBrowserHostCppToC::Get(self)->IsFullscreen(); + + // Return type: bool + return _retval; +} + +void CEF_CALLBACK browser_host_exit_fullscreen(struct _cef_browser_host_t* self, + int will_cause_resize) { + shutdown_checker::AssertNotShutdown(); + + // AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING + + DCHECK(self); + if (!self) { + return; + } + + // Execute + CefBrowserHostCppToC::Get(self)->ExitFullscreen(will_cause_resize ? true + : false); +} + } // namespace // CONSTRUCTOR - Do not edit by hand. @@ -1512,6 +1545,8 @@ CefBrowserHostCppToC::CefBrowserHostCppToC() { GetStruct()->is_background_host = browser_host_is_background_host; GetStruct()->set_audio_muted = browser_host_set_audio_muted; GetStruct()->is_audio_muted = browser_host_is_audio_muted; + GetStruct()->is_fullscreen = browser_host_is_fullscreen; + GetStruct()->exit_fullscreen = browser_host_exit_fullscreen; } // DESTRUCTOR - Do not edit by hand. diff --git a/libcef_dll/ctocpp/browser_host_ctocpp.cc b/libcef_dll/ctocpp/browser_host_ctocpp.cc index e2d78a16b..ee13bbb8e 100644 --- a/libcef_dll/ctocpp/browser_host_ctocpp.cc +++ b/libcef_dll/ctocpp/browser_host_ctocpp.cc @@ -9,7 +9,7 @@ // implementations. See the translator.README.txt file in the tools directory // for more information. // -// $hash=cd4e4aa1670f0c887090e23f5e7e3a01e5de9d13$ +// $hash=4d51bbece0dd5773f9c97163008d6b2f4bf1ccbf$ // #include "libcef_dll/ctocpp/browser_host_ctocpp.h" @@ -1229,6 +1229,38 @@ NO_SANITIZE("cfi-icall") bool CefBrowserHostCToCpp::IsAudioMuted() { return _retval ? true : false; } +NO_SANITIZE("cfi-icall") bool CefBrowserHostCToCpp::IsFullscreen() { + shutdown_checker::AssertNotShutdown(); + + cef_browser_host_t* _struct = GetStruct(); + if (CEF_MEMBER_MISSING(_struct, is_fullscreen)) { + return false; + } + + // AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING + + // Execute + int _retval = _struct->is_fullscreen(_struct); + + // Return type: bool + return _retval ? true : false; +} + +NO_SANITIZE("cfi-icall") +void CefBrowserHostCToCpp::ExitFullscreen(bool will_cause_resize) { + shutdown_checker::AssertNotShutdown(); + + cef_browser_host_t* _struct = GetStruct(); + if (CEF_MEMBER_MISSING(_struct, exit_fullscreen)) { + return; + } + + // AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING + + // Execute + _struct->exit_fullscreen(_struct, will_cause_resize); +} + // CONSTRUCTOR - Do not edit by hand. CefBrowserHostCToCpp::CefBrowserHostCToCpp() {} diff --git a/libcef_dll/ctocpp/browser_host_ctocpp.h b/libcef_dll/ctocpp/browser_host_ctocpp.h index 32d852d6d..305ef1fe5 100644 --- a/libcef_dll/ctocpp/browser_host_ctocpp.h +++ b/libcef_dll/ctocpp/browser_host_ctocpp.h @@ -9,7 +9,7 @@ // implementations. See the translator.README.txt file in the tools directory // for more information. // -// $hash=b4e11c91197cd5d6ccbe3a0d96aaae3792a6e05c$ +// $hash=5c1df6572bffebd983970394be27397837db0b25$ // #ifndef CEF_LIBCEF_DLL_CTOCPP_BROWSER_HOST_CTOCPP_H_ @@ -134,6 +134,8 @@ class CefBrowserHostCToCpp : public CefCToCppRefCounted window, if (should_change && with_controls_) { ShowTopControls(!window->IsFullscreen()); } + + // With Alloy runtime we need to explicitly exit browser fullscreen when + // exiting window fullscreen. Chrome runtime handles this internally. + if (!MainContext::Get()->UseChromeRuntime() && should_change && + !window->IsFullscreen()) { + CefRefPtr browser = browser_view_->GetBrowser(); + if (browser && browser->GetHost()->IsFullscreen()) { + // Will not cause a resize because the fullscreen transition has already + // begun. + browser->GetHost()->ExitFullscreen(/*will_cause_resize=*/false); + } + } } void ViewsWindow::OnWindowCreated(CefRefPtr window) { diff --git a/tests/cefclient/resources/window.html b/tests/cefclient/resources/window.html index f40e792ef..17f53d23a 100644 --- a/tests/cefclient/resources/window.html +++ b/tests/cefclient/resources/window.html @@ -2,6 +2,12 @@ Window Test +