From 1ca15ab88b30beb353627ec9ec73137a0226f017 Mon Sep 17 00:00:00 2001 From: Marshall Greenblatt Date: Tue, 7 Sep 2021 17:04:55 +0300 Subject: [PATCH] views: Support configuration of initial window show state Known issues: - Exiting full-screen mode currently crashes with the Chrome runtime (see issue #3182). --- include/capi/views/cef_window_delegate_capi.h | 9 ++++++- include/cef_api_hash.h | 8 +++--- include/internal/cef_types.h | 12 ++++++++- include/views/cef_window_delegate.h | 8 ++++++ .../chrome/chrome_browser_host_impl.cc | 2 -- .../views/browser_platform_delegate_views.cc | 10 +++++-- libcef/browser/views/window_view.cc | 16 +++++++++++ .../cpptoc/views/window_delegate_cpptoc.cc | 27 ++++++++++++++++++- .../ctocpp/views/window_delegate_ctocpp.cc | 26 +++++++++++++++++- .../ctocpp/views/window_delegate_ctocpp.h | 3 ++- patch/patch.cfg | 2 ++ patch/patches/views_widget.patch | 15 ++++++++--- tests/cefclient/browser/views_window.cc | 22 ++++++++++++++- tests/cefclient/browser/views_window.h | 2 ++ tests/shared/common/client_switches.cc | 1 + tests/shared/common/client_switches.h | 1 + 16 files changed, 147 insertions(+), 17 deletions(-) diff --git a/include/capi/views/cef_window_delegate_capi.h b/include/capi/views/cef_window_delegate_capi.h index 4cf6188c4..8efb574d9 100644 --- a/include/capi/views/cef_window_delegate_capi.h +++ b/include/capi/views/cef_window_delegate_capi.h @@ -33,7 +33,7 @@ // by hand. See the translator.README.txt file in the tools directory for // more information. // -// $hash=b43e6106fde84f3bab4dd566efab23a50adaf94d$ +// $hash=839098c445b1d3203bc482fc5d1555e1f9b87646$ // #ifndef CEF_INCLUDE_CAPI_VIEWS_CEF_WINDOW_DELEGATE_CAPI_H_ @@ -99,6 +99,13 @@ typedef struct _cef_window_delegate_t { struct _cef_window_delegate_t* self, struct _cef_window_t* window); + /// + // Return the initial show state for |window|. + /// + cef_show_state_t(CEF_CALLBACK* get_initial_show_state)( + struct _cef_window_delegate_t* self, + struct _cef_window_t* window); + /// // Return true (1) if |window| should be created without a frame or title bar. // The window will be resizable if can_resize() returns true (1). Use diff --git a/include/cef_api_hash.h b/include/cef_api_hash.h index 7d0559122..5721d0f07 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 "b737ecfff4042edbbcb166d0af38556cb0ab8212" +#define CEF_API_HASH_UNIVERSAL "6198f526f7dcccda1b66b81826ac030c1f76fd15" #if defined(OS_WIN) -#define CEF_API_HASH_PLATFORM "7a55350a33b3cb6cb82659df7f4ee756b95482ef" +#define CEF_API_HASH_PLATFORM "7b514a69fd70f75f8a7ddba848136a9cdd8182d4" #elif defined(OS_MAC) -#define CEF_API_HASH_PLATFORM "24e05cd9bb4be12dfec61c5e19f0b279fc658f1d" +#define CEF_API_HASH_PLATFORM "e33e34f6268be00c7eb4a69bdc97d6f5f3bc6154" #elif defined(OS_LINUX) -#define CEF_API_HASH_PLATFORM "55203c04095f193d3eb9966c40b601aad54188d2" +#define CEF_API_HASH_PLATFORM "edbea2dd852cfcf63a0f57d7495e5d69e87f0052" #endif #ifdef __cplusplus diff --git a/include/internal/cef_types.h b/include/internal/cef_types.h index df593e314..a58a5bd35 100644 --- a/include/internal/cef_types.h +++ b/include/internal/cef_types.h @@ -1159,7 +1159,7 @@ typedef enum { // A resource that a plugin requested. /// RT_PLUGIN_RESOURCE, - + /// // A main-frame service worker navigation preload request. /// @@ -3219,6 +3219,16 @@ typedef enum { CEF_DOCKING_MODE_CUSTOM, } cef_docking_mode_t; +/// +// Show states supported by CefWindowDelegate::GetInitialShowState. +/// +typedef enum { + CEF_SHOW_STATE_NORMAL = 1, + CEF_SHOW_STATE_MINIMIZED, + CEF_SHOW_STATE_MAXIMIZED, + CEF_SHOW_STATE_FULLSCREEN, +} cef_show_state_t; + #ifdef __cplusplus } #endif diff --git a/include/views/cef_window_delegate.h b/include/views/cef_window_delegate.h index b167096eb..00a604d19 100644 --- a/include/views/cef_window_delegate.h +++ b/include/views/cef_window_delegate.h @@ -91,6 +91,14 @@ class CefWindowDelegate : public CefPanelDelegate { return CefRect(); } + /// + // Return the initial show state for |window|. + /// + /*--cef(default_retval=CEF_SHOW_STATE_NORMAL)--*/ + virtual cef_show_state_t GetInitialShowState(CefRefPtr window) { + return CEF_SHOW_STATE_NORMAL; + } + /// // Return true if |window| should be created without a frame or title bar. The // window will be resizable if CanResize() returns true. Use diff --git a/libcef/browser/chrome/chrome_browser_host_impl.cc b/libcef/browser/chrome/chrome_browser_host_impl.cc index 4252f59d2..6c7118195 100644 --- a/libcef/browser/chrome/chrome_browser_host_impl.cc +++ b/libcef/browser/chrome/chrome_browser_host_impl.cc @@ -56,8 +56,6 @@ CefRefPtr ChromeBrowserHostImpl::Create( ChromeBrowserHostImpl::GetBrowserForContents(web_contents); CHECK(browser_host); - browser->window()->Show(); - return browser_host; } diff --git a/libcef/browser/views/browser_platform_delegate_views.cc b/libcef/browser/views/browser_platform_delegate_views.cc index 323c6eb75..635f4f46f 100644 --- a/libcef/browser/views/browser_platform_delegate_views.cc +++ b/libcef/browser/views/browser_platform_delegate_views.cc @@ -218,9 +218,15 @@ void CefBrowserPlatformDelegateViews::SendTouchEvent( } void CefBrowserPlatformDelegateViews::SendFocusEvent(bool setFocus) { - // Will result in a call to WebContents::Focus(). - if (setFocus && browser_view_->root_view()) + // Will activate the Widget and result in a call to WebContents::Focus(). + if (setFocus && browser_view_->root_view()) { + if (auto widget = GetWindowWidget()) { + // Don't activate a minimized Widget, or it will be shown. + if (widget->IsMinimized()) + return; + } browser_view_->root_view()->RequestFocus(); + } } gfx::Point CefBrowserPlatformDelegateViews::GetScreenPoint( diff --git a/libcef/browser/views/window_view.cc b/libcef/browser/views/window_view.cc index a8ace4c6c..1d1b7418b 100644 --- a/libcef/browser/views/window_view.cc +++ b/libcef/browser/views/window_view.cc @@ -276,6 +276,22 @@ void CefWindowView::CreateWidget() { SetCanResize(cef_delegate()->CanResize(cef_window)); + const auto show_state = cef_delegate()->GetInitialShowState(cef_window); + switch (show_state) { + case CEF_SHOW_STATE_NORMAL: + params.show_state = ui::SHOW_STATE_NORMAL; + break; + case CEF_SHOW_STATE_MINIMIZED: + params.show_state = ui::SHOW_STATE_MINIMIZED; + break; + case CEF_SHOW_STATE_MAXIMIZED: + params.show_state = ui::SHOW_STATE_MAXIMIZED; + break; + case CEF_SHOW_STATE_FULLSCREEN: + params.show_state = ui::SHOW_STATE_FULLSCREEN; + break; + } + bool is_menu = false; bool can_activate_menu = true; CefRefPtr parent_window = cef_delegate()->GetParentWindow( diff --git a/libcef_dll/cpptoc/views/window_delegate_cpptoc.cc b/libcef_dll/cpptoc/views/window_delegate_cpptoc.cc index c979e76f8..7b2d78cef 100644 --- a/libcef_dll/cpptoc/views/window_delegate_cpptoc.cc +++ b/libcef_dll/cpptoc/views/window_delegate_cpptoc.cc @@ -9,7 +9,7 @@ // implementations. See the translator.README.txt file in the tools directory // for more information. // -// $hash=d6a40fcd6be6297224b573ac1600701ff6818680$ +// $hash=3e70670085e23c885d7fe0006e782c5293d1430a$ // #include "libcef_dll/cpptoc/views/window_delegate_cpptoc.h" @@ -131,6 +131,30 @@ window_delegate_get_initial_bounds(struct _cef_window_delegate_t* self, return _retval; } +cef_show_state_t CEF_CALLBACK +window_delegate_get_initial_show_state(struct _cef_window_delegate_t* self, + cef_window_t* window) { + shutdown_checker::AssertNotShutdown(); + + // AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING + + DCHECK(self); + if (!self) + return CEF_SHOW_STATE_NORMAL; + // Verify param: window; type: refptr_diff + DCHECK(window); + if (!window) + return CEF_SHOW_STATE_NORMAL; + + // Execute + cef_show_state_t _retval = + CefWindowDelegateCppToC::Get(self)->GetInitialShowState( + CefWindowCToCpp::Wrap(window)); + + // Return type: simple + return _retval; +} + int CEF_CALLBACK window_delegate_is_frameless(struct _cef_window_delegate_t* self, cef_window_t* window) { @@ -548,6 +572,7 @@ CefWindowDelegateCppToC::CefWindowDelegateCppToC() { GetStruct()->on_window_destroyed = window_delegate_on_window_destroyed; GetStruct()->get_parent_window = window_delegate_get_parent_window; GetStruct()->get_initial_bounds = window_delegate_get_initial_bounds; + GetStruct()->get_initial_show_state = window_delegate_get_initial_show_state; GetStruct()->is_frameless = window_delegate_is_frameless; GetStruct()->can_resize = window_delegate_can_resize; GetStruct()->can_maximize = window_delegate_can_maximize; diff --git a/libcef_dll/ctocpp/views/window_delegate_ctocpp.cc b/libcef_dll/ctocpp/views/window_delegate_ctocpp.cc index e30e1078e..56828caa0 100644 --- a/libcef_dll/ctocpp/views/window_delegate_ctocpp.cc +++ b/libcef_dll/ctocpp/views/window_delegate_ctocpp.cc @@ -9,7 +9,7 @@ // implementations. See the translator.README.txt file in the tools directory // for more information. // -// $hash=1035cc694edfd110c5a64b042a6e7ca2e975003a$ +// $hash=45534cf82be12888d9966a92a26d676203ae7c13$ // #include "libcef_dll/ctocpp/views/window_delegate_ctocpp.h" @@ -127,6 +127,30 @@ CefRect CefWindowDelegateCToCpp::GetInitialBounds(CefRefPtr window) { return _retval; } +NO_SANITIZE("cfi-icall") +cef_show_state_t CefWindowDelegateCToCpp::GetInitialShowState( + CefRefPtr window) { + shutdown_checker::AssertNotShutdown(); + + cef_window_delegate_t* _struct = GetStruct(); + if (CEF_MEMBER_MISSING(_struct, get_initial_show_state)) + return CEF_SHOW_STATE_NORMAL; + + // AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING + + // Verify param: window; type: refptr_diff + DCHECK(window.get()); + if (!window.get()) + return CEF_SHOW_STATE_NORMAL; + + // Execute + cef_show_state_t _retval = + _struct->get_initial_show_state(_struct, CefWindowCppToC::Wrap(window)); + + // Return type: simple + return _retval; +} + NO_SANITIZE("cfi-icall") bool CefWindowDelegateCToCpp::IsFrameless(CefRefPtr window) { shutdown_checker::AssertNotShutdown(); diff --git a/libcef_dll/ctocpp/views/window_delegate_ctocpp.h b/libcef_dll/ctocpp/views/window_delegate_ctocpp.h index 7ad9857bf..355d07b5c 100644 --- a/libcef_dll/ctocpp/views/window_delegate_ctocpp.h +++ b/libcef_dll/ctocpp/views/window_delegate_ctocpp.h @@ -9,7 +9,7 @@ // implementations. See the translator.README.txt file in the tools directory // for more information. // -// $hash=8a77494e63a8e06241f675c020532ac20fbaaab0$ +// $hash=eb73d2c218d13a126f8cb3b9b5b70454c2d31ec9$ // #ifndef CEF_LIBCEF_DLL_CTOCPP_VIEWS_WINDOW_DELEGATE_CTOCPP_H_ @@ -43,6 +43,7 @@ class CefWindowDelegateCToCpp bool* is_menu, bool* can_activate_menu) override; CefRect GetInitialBounds(CefRefPtr window) override; + cef_show_state_t GetInitialShowState(CefRefPtr window) override; bool IsFrameless(CefRefPtr window) override; bool CanResize(CefRefPtr window) override; bool CanMaximize(CefRefPtr window) override; diff --git a/patch/patch.cfg b/patch/patch.cfg index 9099c428c..731b6e4f5 100644 --- a/patch/patch.cfg +++ b/patch/patch.cfg @@ -108,6 +108,8 @@ patches = [ # # Windows: Fix focus assignment when clicking WebView with external parent. # https://bitbucket.org/chromiumembedded/cef/issues/3031 + # + # Fix minimize & fullscreen behavior on initial Widget creation. 'name': 'views_widget', }, { diff --git a/patch/patches/views_widget.patch b/patch/patches/views_widget.patch index be1396dea..bd165d0d3 100644 --- a/patch/patches/views_widget.patch +++ b/patch/patches/views_widget.patch @@ -272,7 +272,7 @@ index db1299089169f..a9c331c37b210 100644 // a reference. corewm::TooltipWin* tooltip_; diff --git ui/views/widget/widget.cc ui/views/widget/widget.cc -index 37047c631afc3..aafa6a6fd0b38 100644 +index 37047c631afc3..bcfe411fc6838 100644 --- ui/views/widget/widget.cc +++ ui/views/widget/widget.cc @@ -359,7 +359,8 @@ void Widget::Init(InitParams params) { @@ -285,7 +285,16 @@ index 37047c631afc3..aafa6a6fd0b38 100644 if (params.opacity == views::Widget::InitParams::WindowOpacity::kInferred && params.type != views::Widget::InitParams::TYPE_WINDOW) { -@@ -441,7 +442,12 @@ void Widget::Init(InitParams params) { +@@ -435,13 +436,21 @@ void Widget::Init(InitParams params) { + + if (show_state == ui::SHOW_STATE_MAXIMIZED) { + Maximize(); ++ saved_show_state_ = ui::SHOW_STATE_MAXIMIZED; + } else if (show_state == ui::SHOW_STATE_MINIMIZED) { + Minimize(); + saved_show_state_ = ui::SHOW_STATE_MINIMIZED; ++ } else if (show_state == ui::SHOW_STATE_FULLSCREEN) { ++ SetFullscreen(true); } } else if (delegate) { SetContentsView(delegate->TransferOwnershipOfContentsView()); @@ -299,7 +308,7 @@ index 37047c631afc3..aafa6a6fd0b38 100644 } native_theme_observation_.Observe(GetNativeTheme()); -@@ -1418,10 +1424,16 @@ void Widget::OnNativeWidgetDestroyed() { +@@ -1418,10 +1427,16 @@ void Widget::OnNativeWidgetDestroyed() { } gfx::Size Widget::GetMinimumSize() const { diff --git a/tests/cefclient/browser/views_window.cc b/tests/cefclient/browser/views_window.cc index 62b4e74b5..49a72ba24 100644 --- a/tests/cefclient/browser/views_window.cc +++ b/tests/cefclient/browser/views_window.cc @@ -133,7 +133,7 @@ void ViewsWindow::Show() { CEF_REQUIRE_UI_THREAD(); if (window_) window_->Show(); - if (browser_view_) { + if (browser_view_ && !window_->IsMinimized()) { // Give keyboard focus to the BrowserView. browser_view_->RequestFocus(); } @@ -529,6 +529,11 @@ void ViewsWindow::OnWindowCreated(CefRefPtr window) { // Add keyboard accelerators to the Window. AddAccelerators(); + + // Hide the top controls while in full-screen mode. + if (initial_show_state_ == CEF_SHOW_STATE_FULLSCREEN) { + ShowTopControls(false); + } } else { // Add the BrowserView as the only child of the Window. window_->AddChildView(browser_view_); @@ -599,6 +604,11 @@ CefRect ViewsWindow::GetInitialBounds(CefRefPtr window) { return CefRect(); } +cef_show_state_t ViewsWindow::GetInitialShowState(CefRefPtr window) { + CEF_REQUIRE_UI_THREAD(); + return initial_show_state_; +} + bool ViewsWindow::IsFrameless(CefRefPtr window) { CEF_REQUIRE_UI_THREAD(); return frameless_; @@ -786,6 +796,16 @@ ViewsWindow::ViewsWindow(Delegate* delegate, chrome_toolbar_type_ = CEF_CTT_NONE; } + const std::string& show_state = + command_line->GetSwitchValue(switches::kInitialShowState); + if (show_state == "minimized") { + initial_show_state_ = CEF_SHOW_STATE_MINIMIZED; + } else if (show_state == "maximized") { + initial_show_state_ = CEF_SHOW_STATE_MAXIMIZED; + } else if (show_state == "fullscreen") { + initial_show_state_ = CEF_SHOW_STATE_FULLSCREEN; + } + #if !defined(OS_MAC) // On Mac we don't show a top menu on the window. The options are available in // the app menu instead. diff --git a/tests/cefclient/browser/views_window.h b/tests/cefclient/browser/views_window.h index 3ca8fb5af..0472cf98b 100644 --- a/tests/cefclient/browser/views_window.h +++ b/tests/cefclient/browser/views_window.h @@ -157,6 +157,7 @@ class ViewsWindow : public CefBrowserViewDelegate, bool* is_menu, bool* can_activate_menu) override; CefRect GetInitialBounds(CefRefPtr window) override; + cef_show_state_t GetInitialShowState(CefRefPtr window) override; bool IsFrameless(CefRefPtr window) override; bool CanResize(CefRefPtr window) override; bool CanClose(CefRefPtr window) override; @@ -236,6 +237,7 @@ class ViewsWindow : public CefBrowserViewDelegate, int last_focused_view_; CefSize minimum_window_size_; + cef_show_state_t initial_show_state_ = CEF_SHOW_STATE_NORMAL; CefRefPtr overlay_controls_; diff --git a/tests/shared/common/client_switches.cc b/tests/shared/common/client_switches.cc index d85fa6b00..18b19d47f 100644 --- a/tests/shared/common/client_switches.cc +++ b/tests/shared/common/client_switches.cc @@ -46,6 +46,7 @@ const char kLoadExtension[] = "load-extension"; const char kNoActivate[] = "no-activate"; const char kEnableChromeRuntime[] = "enable-chrome-runtime"; const char kShowChromeToolbar[] = "show-chrome-toolbar"; +const char kInitialShowState[] = "initial-show-state"; } // namespace switches } // namespace client diff --git a/tests/shared/common/client_switches.h b/tests/shared/common/client_switches.h index 73918d3b6..43cc0af3a 100644 --- a/tests/shared/common/client_switches.h +++ b/tests/shared/common/client_switches.h @@ -40,6 +40,7 @@ extern const char kLoadExtension[]; extern const char kNoActivate[]; extern const char kEnableChromeRuntime[]; extern const char kShowChromeToolbar[]; +extern const char kInitialShowState[]; } // namespace switches } // namespace client