views: Support specification of screen bounds for CefWindow creation (fixes issue #2980)

This commit is contained in:
Marshall Greenblatt 2020-09-02 14:25:25 -04:00
parent 4aad5f23a0
commit b579b37db4
10 changed files with 129 additions and 12 deletions

View File

@ -33,7 +33,7 @@
// by hand. See the translator.README.txt file in the tools directory for // by hand. See the translator.README.txt file in the tools directory for
// more information. // more information.
// //
// $hash=a0cec778fbaf0b1f5c9b3ef75dc7bbeeba777a44$ // $hash=734a13cd5ad9b0af1b29e1e91b406dd5e6740dc4$
// //
#ifndef CEF_INCLUDE_CAPI_VIEWS_CEF_WINDOW_DELEGATE_CAPI_H_ #ifndef CEF_INCLUDE_CAPI_VIEWS_CEF_WINDOW_DELEGATE_CAPI_H_
@ -87,6 +87,16 @@ typedef struct _cef_window_delegate_t {
int* is_menu, int* is_menu,
int* can_activate_menu); int* can_activate_menu);
///
// Return the initial bounds for |window| in screen coordinates. If this
// function returns an NULL CefRect then get_preferred_size() will be called
// to retrieve the size, and the window will be placed on the default screen
// with origin (0,0).
///
cef_rect_t(CEF_CALLBACK* get_initial_bounds)(
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. // 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 // The window will be resizable if can_resize() returns true (1). Use

View File

@ -42,13 +42,13 @@
// way that may cause binary incompatibility with other builds. The universal // way that may cause binary incompatibility with other builds. The universal
// hash value will change if any platform is affected whereas the platform hash // hash value will change if any platform is affected whereas the platform hash
// values will change only if that particular platform is affected. // values will change only if that particular platform is affected.
#define CEF_API_HASH_UNIVERSAL "09dba98bcfcdf8a84e6e1bddf9cfbfd02cdb9c41" #define CEF_API_HASH_UNIVERSAL "09d3d4f08869644fe3baa7a751de537f3446525b"
#if defined(OS_WIN) #if defined(OS_WIN)
#define CEF_API_HASH_PLATFORM "52cba70fb6dd7cfa07a64033875f2b9951ab194b" #define CEF_API_HASH_PLATFORM "3022db6736af26cc38158d38e22f74a51312a5c9"
#elif defined(OS_MAC) #elif defined(OS_MAC)
#define CEF_API_HASH_PLATFORM "40ddb93c4e9b9d0f81b62a61a595307c6ed204e5" #define CEF_API_HASH_PLATFORM "13e2e2451c2320f0d16b35ba53b3295409888dd8"
#elif defined(OS_LINUX) #elif defined(OS_LINUX)
#define CEF_API_HASH_PLATFORM "e48b0f06a363df82624951e4b85fb638bf0987c0" #define CEF_API_HASH_PLATFORM "d781b815150795b0bce95d72ce967b508c9a04d5"
#endif #endif
#ifdef __cplusplus #ifdef __cplusplus

View File

@ -78,6 +78,17 @@ class CefWindowDelegate : public CefPanelDelegate {
return nullptr; return nullptr;
} }
///
// Return the initial bounds for |window| in screen coordinates. If this
// method returns an empty CefRect then GetPreferredSize() will be called to
// retrieve the size, and the window will be placed on the default screen with
// origin (0,0).
///
/*--cef()--*/
virtual CefRect GetInitialBounds(CefRefPtr<CefWindow> window) {
return CefRect();
}
/// ///
// Return true if |window| should be created without a frame or title bar. The // Return true if |window| should be created without a frame or title bar. The
// window will be resizable if CanResize() returns true. Use // window will be resizable if CanResize() returns true. Use

View File

@ -254,13 +254,15 @@ void CefWindowView::CreateWidget() {
views::Widget::InitParams params; views::Widget::InitParams params;
params.delegate = this; params.delegate = this;
params.type = views::Widget::InitParams::TYPE_WINDOW; params.type = views::Widget::InitParams::TYPE_WINDOW;
params.bounds = gfx::Rect(CalculatePreferredSize());
bool can_activate = true; bool can_activate = true;
if (cef_delegate()) { if (cef_delegate()) {
CefRefPtr<CefWindow> cef_window = GetCefWindow(); CefRefPtr<CefWindow> cef_window = GetCefWindow();
is_frameless_ = cef_delegate()->IsFrameless(cef_window); is_frameless_ = cef_delegate()->IsFrameless(cef_window);
auto bounds = cef_delegate()->GetInitialBounds(cef_window);
params.bounds = gfx::Rect(bounds.x, bounds.y, bounds.width, bounds.height);
bool is_menu = false; bool is_menu = false;
bool can_activate_menu = true; bool can_activate_menu = true;
CefRefPtr<CefWindow> parent_window = cef_delegate()->GetParentWindow( CefRefPtr<CefWindow> parent_window = cef_delegate()->GetParentWindow(
@ -283,6 +285,11 @@ void CefWindowView::CreateWidget() {
} }
} }
if (params.bounds.IsEmpty()) {
// The window will be placed on the default screen with origin (0,0).
params.bounds = gfx::Rect(CalculatePreferredSize());
}
#if defined(OS_WIN) #if defined(OS_WIN)
if (is_frameless_) { if (is_frameless_) {
// Don't show the native window caption. Setting this value on Linux will // Don't show the native window caption. Setting this value on Linux will

View File

@ -9,7 +9,7 @@
// implementations. See the translator.README.txt file in the tools directory // implementations. See the translator.README.txt file in the tools directory
// for more information. // for more information.
// //
// $hash=52b31a63bbe83937a9f5dc557accfc1e84af6d84$ // $hash=fc5a46d1a73e61c08ec1266ac1c481dc65aedf6b$
// //
#include "libcef_dll/cpptoc/views/window_delegate_cpptoc.h" #include "libcef_dll/cpptoc/views/window_delegate_cpptoc.h"
@ -108,6 +108,29 @@ window_delegate_get_parent_window(struct _cef_window_delegate_t* self,
return CefWindowCToCpp::Unwrap(_retval); return CefWindowCToCpp::Unwrap(_retval);
} }
cef_rect_t CEF_CALLBACK
window_delegate_get_initial_bounds(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 CefRect();
// Verify param: window; type: refptr_diff
DCHECK(window);
if (!window)
return CefRect();
// Execute
cef_rect_t _retval = CefWindowDelegateCppToC::Get(self)->GetInitialBounds(
CefWindowCToCpp::Wrap(window));
// Return type: simple
return _retval;
}
int CEF_CALLBACK int CEF_CALLBACK
window_delegate_is_frameless(struct _cef_window_delegate_t* self, window_delegate_is_frameless(struct _cef_window_delegate_t* self,
cef_window_t* window) { cef_window_t* window) {
@ -475,6 +498,7 @@ CefWindowDelegateCppToC::CefWindowDelegateCppToC() {
GetStruct()->on_window_created = window_delegate_on_window_created; GetStruct()->on_window_created = window_delegate_on_window_created;
GetStruct()->on_window_destroyed = window_delegate_on_window_destroyed; GetStruct()->on_window_destroyed = window_delegate_on_window_destroyed;
GetStruct()->get_parent_window = window_delegate_get_parent_window; GetStruct()->get_parent_window = window_delegate_get_parent_window;
GetStruct()->get_initial_bounds = window_delegate_get_initial_bounds;
GetStruct()->is_frameless = window_delegate_is_frameless; GetStruct()->is_frameless = window_delegate_is_frameless;
GetStruct()->can_resize = window_delegate_can_resize; GetStruct()->can_resize = window_delegate_can_resize;
GetStruct()->can_maximize = window_delegate_can_maximize; GetStruct()->can_maximize = window_delegate_can_maximize;

View File

@ -9,7 +9,7 @@
// implementations. See the translator.README.txt file in the tools directory // implementations. See the translator.README.txt file in the tools directory
// for more information. // for more information.
// //
// $hash=42f9fdcc49577f6d052e4f357138efe4443a72d9$ // $hash=c2193e3a76df58538caf73c332d4148d00e235d4$
// //
#include "libcef_dll/ctocpp/views/window_delegate_ctocpp.h" #include "libcef_dll/ctocpp/views/window_delegate_ctocpp.h"
@ -104,6 +104,29 @@ CefRefPtr<CefWindow> CefWindowDelegateCToCpp::GetParentWindow(
return CefWindowCppToC::Unwrap(_retval); return CefWindowCppToC::Unwrap(_retval);
} }
NO_SANITIZE("cfi-icall")
CefRect CefWindowDelegateCToCpp::GetInitialBounds(CefRefPtr<CefWindow> window) {
shutdown_checker::AssertNotShutdown();
cef_window_delegate_t* _struct = GetStruct();
if (CEF_MEMBER_MISSING(_struct, get_initial_bounds))
return CefRect();
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
// Verify param: window; type: refptr_diff
DCHECK(window.get());
if (!window.get())
return CefRect();
// Execute
cef_rect_t _retval =
_struct->get_initial_bounds(_struct, CefWindowCppToC::Wrap(window));
// Return type: simple
return _retval;
}
NO_SANITIZE("cfi-icall") NO_SANITIZE("cfi-icall")
bool CefWindowDelegateCToCpp::IsFrameless(CefRefPtr<CefWindow> window) { bool CefWindowDelegateCToCpp::IsFrameless(CefRefPtr<CefWindow> window) {
shutdown_checker::AssertNotShutdown(); shutdown_checker::AssertNotShutdown();

View File

@ -9,7 +9,7 @@
// implementations. See the translator.README.txt file in the tools directory // implementations. See the translator.README.txt file in the tools directory
// for more information. // for more information.
// //
// $hash=e1c4def5dc9c50b90a1a57bb7769f18763827b25$ // $hash=2e94fea293b3a9e82cdb57d9e3cb630c13ce0ede$
// //
#ifndef CEF_LIBCEF_DLL_CTOCPP_VIEWS_WINDOW_DELEGATE_CTOCPP_H_ #ifndef CEF_LIBCEF_DLL_CTOCPP_VIEWS_WINDOW_DELEGATE_CTOCPP_H_
@ -42,6 +42,7 @@ class CefWindowDelegateCToCpp
CefRefPtr<CefWindow> GetParentWindow(CefRefPtr<CefWindow> window, CefRefPtr<CefWindow> GetParentWindow(CefRefPtr<CefWindow> window,
bool* is_menu, bool* is_menu,
bool* can_activate_menu) override; bool* can_activate_menu) override;
CefRect GetInitialBounds(CefRefPtr<CefWindow> window) override;
bool IsFrameless(CefRefPtr<CefWindow> window) override; bool IsFrameless(CefRefPtr<CefWindow> window) override;
bool CanResize(CefRefPtr<CefWindow> window) override; bool CanResize(CefRefPtr<CefWindow> window) override;
bool CanMaximize(CefRefPtr<CefWindow> window) override; bool CanMaximize(CefRefPtr<CefWindow> window) override;

View File

@ -70,9 +70,24 @@ void TestWindowDelegate::OnWindowCreated(CefRefPtr<CefWindow> window) {
EXPECT_TRUE(window->GetDisplay().get()); EXPECT_TRUE(window->GetDisplay().get());
// Size will come from GetPreferredSize() on initial Window creation. // Size will come from GetGetInitialBounds() or GetPreferredSize() on
// initial Window creation.
EXPECT_TRUE(got_get_initial_bounds_);
if (config_.window_origin.IsEmpty())
EXPECT_TRUE(got_get_preferred_size_); EXPECT_TRUE(got_get_preferred_size_);
else
EXPECT_FALSE(got_get_preferred_size_);
CefRect client_bounds = window->GetBounds(); CefRect client_bounds = window->GetBounds();
if (!config_.window_origin.IsEmpty()) {
EXPECT_EQ(config_.window_origin.x, client_bounds.x);
EXPECT_EQ(config_.window_origin.y, client_bounds.y);
} else {
// Default origin is (0,0).
EXPECT_EQ(0, client_bounds.x);
EXPECT_EQ(0, client_bounds.y);
}
if (config_.frameless) { if (config_.frameless) {
EXPECT_EQ(config_.window_size, client_bounds.width); EXPECT_EQ(config_.window_size, client_bounds.width);
EXPECT_EQ(config_.window_size, client_bounds.height); EXPECT_EQ(config_.window_size, client_bounds.height);
@ -124,6 +139,17 @@ bool TestWindowDelegate::IsFrameless(CefRefPtr<CefWindow> window) {
return config_.frameless; return config_.frameless;
} }
CefRect TestWindowDelegate::GetInitialBounds(CefRefPtr<CefWindow> window) {
got_get_initial_bounds_ = true;
if (!config_.window_origin.IsEmpty()) {
return CefRect(config_.window_origin.x, config_.window_origin.y,
window_size_.width, window_size_.height);
}
// Call GetPreferredSize().
return CefRect();
}
CefSize TestWindowDelegate::GetPreferredSize(CefRefPtr<CefView> view) { CefSize TestWindowDelegate::GetPreferredSize(CefRefPtr<CefView> view) {
got_get_preferred_size_ = true; got_get_preferred_size_ = true;
return window_size_; return window_size_;

View File

@ -28,6 +28,7 @@ class TestWindowDelegate : public CefWindowDelegate {
bool frameless = false; bool frameless = false;
bool close_window = true; bool close_window = true;
int window_size = kWSize; int window_size = kWSize;
CefPoint window_origin = {};
}; };
// Creates a Window with a new TestWindowDelegate instance and executes // Creates a Window with a new TestWindowDelegate instance and executes
@ -42,6 +43,7 @@ class TestWindowDelegate : public CefWindowDelegate {
void OnWindowCreated(CefRefPtr<CefWindow> window) override; void OnWindowCreated(CefRefPtr<CefWindow> window) override;
void OnWindowDestroyed(CefRefPtr<CefWindow> window) override; void OnWindowDestroyed(CefRefPtr<CefWindow> window) override;
bool IsFrameless(CefRefPtr<CefWindow> window) override; bool IsFrameless(CefRefPtr<CefWindow> window) override;
CefRect GetInitialBounds(CefRefPtr<CefWindow> window) override;
CefSize GetPreferredSize(CefRefPtr<CefView> view) override; CefSize GetPreferredSize(CefRefPtr<CefView> view) override;
bool OnAccelerator(CefRefPtr<CefWindow> window, int command_id) override; bool OnAccelerator(CefRefPtr<CefWindow> window, int command_id) override;
bool OnKeyEvent(CefRefPtr<CefWindow> window, bool OnKeyEvent(CefRefPtr<CefWindow> window,
@ -62,6 +64,7 @@ class TestWindowDelegate : public CefWindowDelegate {
CefRefPtr<CefWindow> window_; CefRefPtr<CefWindow> window_;
bool got_get_initial_bounds_ = false;
bool got_get_preferred_size_ = false; bool got_get_preferred_size_ = false;
// Must be the last member. // Must be the last member.

View File

@ -47,12 +47,23 @@ void WindowCreateFramelessImpl(CefRefPtr<CefWaitableEvent> event) {
TestWindowDelegate::RunTest(event, config); TestWindowDelegate::RunTest(event, config);
} }
void RunWindowShowHide(CefRefPtr<CefWindow> window) { void RunWindowShow(CefRefPtr<CefWindow> window) {
EXPECT_FALSE(window->IsVisible()); EXPECT_FALSE(window->IsVisible());
EXPECT_FALSE(window->IsDrawn()); EXPECT_FALSE(window->IsDrawn());
window->Show(); window->Show();
EXPECT_TRUE(window->IsVisible()); EXPECT_TRUE(window->IsVisible());
EXPECT_TRUE(window->IsDrawn()); EXPECT_TRUE(window->IsDrawn());
}
void WindowCreateWithOriginImpl(CefRefPtr<CefWaitableEvent> event) {
TestWindowDelegate::Config config;
config.window_origin = {100, 200};
config.on_window_created = base::Bind(RunWindowShow);
TestWindowDelegate::RunTest(event, config);
}
void RunWindowShowHide(CefRefPtr<CefWindow> window) {
RunWindowShow(window);
window->Hide(); window->Hide();
EXPECT_FALSE(window->IsVisible()); EXPECT_FALSE(window->IsVisible());
EXPECT_FALSE(window->IsDrawn()); EXPECT_FALSE(window->IsDrawn());
@ -481,6 +492,7 @@ void WindowAcceleratorImpl(CefRefPtr<CefWaitableEvent> event) {
// we presume that Chromium is testing). // we presume that Chromium is testing).
WINDOW_TEST_ASYNC(WindowCreate) WINDOW_TEST_ASYNC(WindowCreate)
WINDOW_TEST_ASYNC(WindowCreateFrameless) WINDOW_TEST_ASYNC(WindowCreateFrameless)
WINDOW_TEST_ASYNC(WindowCreateWithOrigin)
WINDOW_TEST_ASYNC(WindowShowHide) WINDOW_TEST_ASYNC(WindowShowHide)
WINDOW_TEST_ASYNC(WindowShowHideFrameless) WINDOW_TEST_ASYNC(WindowShowHideFrameless)
WINDOW_TEST_ASYNC(WindowLayoutAndCoords) WINDOW_TEST_ASYNC(WindowLayoutAndCoords)