mirror of
https://bitbucket.org/chromiumembedded/cef
synced 2025-02-20 06:00:41 +01:00
Compare commits
14 Commits
02b371879b
...
48f3ef63e2
Author | SHA1 | Date | |
---|---|---|---|
|
48f3ef63e2 | ||
|
7268dc8cd3 | ||
|
45861b1b08 | ||
|
efe558cd28 | ||
|
f1e634393f | ||
|
0187046a2e | ||
|
6f4c2bf8df | ||
|
de2da368c6 | ||
|
4797681694 | ||
|
ffbc53a9e6 | ||
|
92f14410ae | ||
|
e68b0169a1 | ||
|
1fd6000c70 | ||
|
5e348cb1fc |
@ -288,6 +288,8 @@
|
|||||||
'tests/cefclient/browser/urlrequest_test.h',
|
'tests/cefclient/browser/urlrequest_test.h',
|
||||||
'tests/cefclient/browser/views_menu_bar.cc',
|
'tests/cefclient/browser/views_menu_bar.cc',
|
||||||
'tests/cefclient/browser/views_menu_bar.h',
|
'tests/cefclient/browser/views_menu_bar.h',
|
||||||
|
'tests/cefclient/browser/views_overlay_browser.cc',
|
||||||
|
'tests/cefclient/browser/views_overlay_browser.h',
|
||||||
'tests/cefclient/browser/views_overlay_controls.cc',
|
'tests/cefclient/browser/views_overlay_controls.cc',
|
||||||
'tests/cefclient/browser/views_overlay_controls.h',
|
'tests/cefclient/browser/views_overlay_controls.h',
|
||||||
'tests/cefclient/browser/views_style.cc',
|
'tests/cefclient/browser/views_style.cc',
|
||||||
|
@ -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=7c786570b1c7af912a31c6f0c3d742e8aeb38fd8$
|
// $hash=e9f34d90eb4af614e35cbb29da0639b62acec7fd$
|
||||||
//
|
//
|
||||||
|
|
||||||
#ifndef CEF_INCLUDE_CAPI_CEF_BROWSER_CAPI_H_
|
#ifndef CEF_INCLUDE_CAPI_CEF_BROWSER_CAPI_H_
|
||||||
@ -301,29 +301,62 @@ typedef struct _cef_browser_host_t {
|
|||||||
struct _cef_browser_host_t* self);
|
struct _cef_browser_host_t* self);
|
||||||
|
|
||||||
///
|
///
|
||||||
/// Request that the browser close. The JavaScript 'onbeforeunload' event will
|
/// Request that the browser close. Closing a browser is a multi-stage process
|
||||||
/// be fired. If |force_close| is false (0) the event handler, if any, will be
|
/// that may complete either synchronously or asynchronously, and involves
|
||||||
/// allowed to prompt the user and the user can optionally cancel the close.
|
/// callbacks such as cef_life_span_handler_t::DoClose (Alloy style only),
|
||||||
/// If |force_close| is true (1) the prompt will not be displayed and the
|
/// cef_life_span_handler_t::OnBeforeClose, and a top-level window close
|
||||||
/// close will proceed. Results in a call to
|
/// handler such as cef_window_delegate_t::CanClose (or platform-specific
|
||||||
/// cef_life_span_handler_t::do_close() if the event handler allows the close
|
/// equivalent). In some cases a close request may be delayed or canceled by
|
||||||
/// or if |force_close| is true (1). See cef_life_span_handler_t::do_close()
|
/// the user. Using try_close_browser() instead of close_browser() is
|
||||||
/// documentation for additional usage information.
|
/// recommended for most use cases. See cef_life_span_handler_t::do_close()
|
||||||
|
/// documentation for detailed usage and examples.
|
||||||
|
///
|
||||||
|
/// If |force_close| is false (0) then JavaScript unload handlers, if any, may
|
||||||
|
/// be fired and the close may be delayed or canceled by the user. If
|
||||||
|
/// |force_close| is true (1) then the user will not be prompted and the close
|
||||||
|
/// will proceed immediately (possibly asynchronously). If browser close is
|
||||||
|
/// delayed and not canceled the default behavior is to call the top-level
|
||||||
|
/// window close handler once the browser is ready to be closed. This default
|
||||||
|
/// behavior can be changed for Alloy style browsers by implementing
|
||||||
|
/// cef_life_span_handler_t::do_close(). is_ready_to_be_closed() can be used
|
||||||
|
/// to detect mandatory browser close events when customizing close behavior
|
||||||
|
/// on the browser process UI thread.
|
||||||
///
|
///
|
||||||
void(CEF_CALLBACK* close_browser)(struct _cef_browser_host_t* self,
|
void(CEF_CALLBACK* close_browser)(struct _cef_browser_host_t* self,
|
||||||
int force_close);
|
int force_close);
|
||||||
|
|
||||||
///
|
///
|
||||||
/// Helper for closing a browser. Call this function from the top-level window
|
/// Helper for closing a browser. This is similar in behavior to
|
||||||
/// close handler (if any). Internally this calls CloseBrowser(false (0)) if
|
/// CLoseBrowser(false (0)) but returns a boolean to reflect the immediate
|
||||||
/// the close has not yet been initiated. This function returns false (0)
|
/// close status. Call this function from a top-level window close handler
|
||||||
/// while the close is pending and true (1) after the close has completed. See
|
/// such as cef_window_delegate_t::CanClose (or platform-specific equivalent)
|
||||||
/// close_browser() and cef_life_span_handler_t::do_close() documentation for
|
/// to request that the browser close, and return the result to indicate if
|
||||||
/// additional usage information. This function must be called on the browser
|
/// the window close should proceed. Returns false (0) if the close will be
|
||||||
/// process UI thread.
|
/// delayed (JavaScript unload handlers triggered but still pending) or true
|
||||||
|
/// (1) if the close will proceed immediately (possibly asynchronously). See
|
||||||
|
/// close_browser() documentation for additional usage information. This
|
||||||
|
/// function must be called on the browser process UI thread.
|
||||||
///
|
///
|
||||||
int(CEF_CALLBACK* try_close_browser)(struct _cef_browser_host_t* self);
|
int(CEF_CALLBACK* try_close_browser)(struct _cef_browser_host_t* self);
|
||||||
|
|
||||||
|
///
|
||||||
|
/// Returns true (1) if the browser is ready to be closed, meaning that the
|
||||||
|
/// close has already been initiated and that JavaScript unload handlers have
|
||||||
|
/// already executed or should be ignored. This can be used from a top-level
|
||||||
|
/// window close handler such as cef_window_delegate_t::CanClose (or platform-
|
||||||
|
/// specific equivalent) to distringuish between potentially cancelable
|
||||||
|
/// browser close events (like the user clicking the top-level window close
|
||||||
|
/// button before browser close has started) and mandatory browser close
|
||||||
|
/// events (like JavaScript `window.close()` or after browser close has
|
||||||
|
/// started in response to [Try]close_browser()). Not completing the browser
|
||||||
|
/// close for mandatory close events (when this function returns true (1))
|
||||||
|
/// will leave the browser in a partially closed state that interferes with
|
||||||
|
/// proper functioning. See close_browser() documentation for additional usage
|
||||||
|
/// information. This function must be called on the browser process UI
|
||||||
|
/// thread.
|
||||||
|
///
|
||||||
|
int(CEF_CALLBACK* is_ready_to_be_closed)(struct _cef_browser_host_t* self);
|
||||||
|
|
||||||
///
|
///
|
||||||
/// Set whether the browser is focused.
|
/// Set whether the browser is focused.
|
||||||
///
|
///
|
||||||
|
@ -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=5232dd6bf16af9b6d195a47bb41de0dfb880a65e$
|
// $hash=6aad2ccf30a6c519bbeee64d83866e82a41a48d8$
|
||||||
//
|
//
|
||||||
|
|
||||||
#ifndef CEF_INCLUDE_CAPI_CEF_LIFE_SPAN_HANDLER_CAPI_H_
|
#ifndef CEF_INCLUDE_CAPI_CEF_LIFE_SPAN_HANDLER_CAPI_H_
|
||||||
@ -138,35 +138,44 @@ typedef struct _cef_life_span_handler_t {
|
|||||||
struct _cef_browser_t* browser);
|
struct _cef_browser_t* browser);
|
||||||
|
|
||||||
///
|
///
|
||||||
/// Called when a browser has received a request to close. This may result
|
/// Called when an Alloy style browser is ready to be closed, meaning that the
|
||||||
/// directly from a call to cef_browser_host_t::*close_browser() or indirectly
|
/// close has already been initiated and that JavaScript unload handlers have
|
||||||
/// if the browser is parented to a top-level window created by CEF and the
|
/// already executed or should be ignored. This may result directly from a
|
||||||
/// user attempts to close that window (by clicking the 'X', for example). The
|
/// call to cef_browser_host_t::[Try]close_browser() or indirectly if the
|
||||||
/// do_close() function will be called after the JavaScript 'onunload' event
|
/// browser's top-level parent window was created by CEF and the user attempts
|
||||||
/// has been fired.
|
/// to close that window (by clicking the 'X', for example). do_close() will
|
||||||
|
/// not be called if the browser's host window/view has already been destroyed
|
||||||
|
/// (via parent window/view hierarchy tear-down, for example), as it is no
|
||||||
|
/// longer possible to customize the close behavior at that point.
|
||||||
///
|
///
|
||||||
/// An application should handle top-level owner window close notifications by
|
/// An application should handle top-level parent window close notifications
|
||||||
/// calling cef_browser_host_t::try_close_browser() or
|
/// by calling cef_browser_host_t::try_close_browser() or
|
||||||
/// cef_browser_host_t::CloseBrowser(false (0)) instead of allowing the window
|
/// cef_browser_host_t::CloseBrowser(false (0)) instead of allowing the window
|
||||||
/// to close immediately (see the examples below). This gives CEF an
|
/// to close immediately (see the examples below). This gives CEF an
|
||||||
/// opportunity to process the 'onbeforeunload' event and optionally cancel
|
/// opportunity to process JavaScript unload handlers and optionally cancel
|
||||||
/// the close before do_close() is called.
|
/// the close before do_close() is called.
|
||||||
///
|
///
|
||||||
/// When windowed rendering is enabled CEF will internally create a window or
|
/// When windowed rendering is enabled CEF will create an internal child
|
||||||
/// view to host the browser. In that case returning false (0) from do_close()
|
/// window/view to host the browser. In that case returning false (0) from
|
||||||
/// will send the standard close notification to the browser's top-level owner
|
/// do_close() will send the standard close notification to the browser's top-
|
||||||
/// window (e.g. WM_CLOSE on Windows, performClose: on OS X, "delete_event" on
|
/// level parent window (e.g. WM_CLOSE on Windows, performClose: on OS X,
|
||||||
/// Linux or cef_window_delegate_t::can_close() callback from Views). If the
|
/// "delete_event" on Linux or cef_window_delegate_t::can_close() callback
|
||||||
/// browser's host window/view has already been destroyed (via view hierarchy
|
/// from Views).
|
||||||
/// tear-down, for example) then do_close() will not be called for that
|
|
||||||
/// browser since is no longer possible to cancel the close.
|
|
||||||
///
|
///
|
||||||
/// When windowed rendering is disabled returning false (0) from do_close()
|
/// When windowed rendering is disabled there is no internal window/view and
|
||||||
/// will cause the browser object to be destroyed immediately.
|
/// returning false (0) from do_close() will cause the browser object to be
|
||||||
|
/// destroyed immediately.
|
||||||
///
|
///
|
||||||
/// If the browser's top-level owner window requires a non-standard close
|
/// If the browser's top-level parent window requires a non-standard close
|
||||||
/// notification then send that notification from do_close() and return true
|
/// notification then send that notification from do_close() and return true
|
||||||
/// (1).
|
/// (1). You are still required to complete the browser close as soon as
|
||||||
|
/// possible (either by calling [Try]close_browser() or by proceeding with
|
||||||
|
/// window/view hierarchy tear-down), otherwise the browser will be left in a
|
||||||
|
/// partially closed state that interferes with proper functioning. Top-level
|
||||||
|
/// windows created on the browser process UI thread can alternately call
|
||||||
|
/// cef_browser_host_t::is_ready_to_be_closed() in the close handler to check
|
||||||
|
/// close status instead of relying on custom do_close() handling. See
|
||||||
|
/// documentation on that function for additional details.
|
||||||
///
|
///
|
||||||
/// The cef_life_span_handler_t::on_before_close() function will be called
|
/// The cef_life_span_handler_t::on_before_close() function will be called
|
||||||
/// after do_close() (if do_close() is called) and immediately before the
|
/// after do_close() (if do_close() is called) and immediately before the
|
||||||
@ -182,22 +191,26 @@ typedef struct _cef_life_span_handler_t {
|
|||||||
/// which sends a close notification
|
/// which sends a close notification
|
||||||
/// to the application's top-level window.
|
/// to the application's top-level window.
|
||||||
/// 2. Application's top-level window receives the close notification and
|
/// 2. Application's top-level window receives the close notification and
|
||||||
/// calls TryCloseBrowser() (which internally calls CloseBrowser(false)).
|
/// calls TryCloseBrowser() (similar to calling CloseBrowser(false)).
|
||||||
/// TryCloseBrowser() returns false so the client cancels the window
|
/// TryCloseBrowser() returns false so the client cancels the window
|
||||||
/// close.
|
/// close.
|
||||||
/// 3. JavaScript 'onbeforeunload' handler executes and shows the close
|
/// 3. JavaScript 'onbeforeunload' handler executes and shows the close
|
||||||
/// confirmation dialog (which can be overridden via
|
/// confirmation dialog (which can be overridden via
|
||||||
/// CefJSDialogHandler::OnBeforeUnloadDialog()).
|
/// CefJSDialogHandler::OnBeforeUnloadDialog()).
|
||||||
/// 4. User approves the close. 5. JavaScript 'onunload' handler executes.
|
/// 4. User approves the close. 5. JavaScript 'onunload' handler executes.
|
||||||
/// 6. CEF sends a close notification to the application's top-level window
|
/// 6. Application's do_close() handler is called and returns false (0) by
|
||||||
/// (because DoClose() returned false by default).
|
/// default.
|
||||||
/// 7. Application's top-level window receives the close notification and
|
/// 7. CEF sends a close notification to the application's top-level window
|
||||||
|
/// (because DoClose() returned false).
|
||||||
|
/// 8. Application's top-level window receives the close notification and
|
||||||
/// calls TryCloseBrowser(). TryCloseBrowser() returns true so the client
|
/// calls TryCloseBrowser(). TryCloseBrowser() returns true so the client
|
||||||
/// allows the window close.
|
/// allows the window close.
|
||||||
/// 8. Application's top-level window is destroyed. 9. Application's
|
/// 9. Application's top-level window is destroyed, triggering destruction
|
||||||
/// on_before_close() handler is called and the browser object
|
/// of the child browser window.
|
||||||
|
/// 10. Application's on_before_close() handler is called and the browser
|
||||||
|
/// object
|
||||||
/// is destroyed.
|
/// is destroyed.
|
||||||
/// 10. Application exits by calling cef_quit_message_loop() if no other
|
/// 11. Application exits by calling cef_quit_message_loop() if no other
|
||||||
/// browsers
|
/// browsers
|
||||||
/// exist.
|
/// exist.
|
||||||
///
|
///
|
||||||
@ -215,13 +228,17 @@ typedef struct _cef_life_span_handler_t {
|
|||||||
/// CefJSDialogHandler::OnBeforeUnloadDialog()).
|
/// CefJSDialogHandler::OnBeforeUnloadDialog()).
|
||||||
/// 4. User approves the close. 5. JavaScript 'onunload' handler executes.
|
/// 4. User approves the close. 5. JavaScript 'onunload' handler executes.
|
||||||
/// 6. Application's do_close() handler is called. Application will:
|
/// 6. Application's do_close() handler is called. Application will:
|
||||||
/// A. Set a flag to indicate that the next close attempt will be allowed.
|
/// A. Set a flag to indicate that the next top-level window close attempt
|
||||||
|
/// will be allowed.
|
||||||
/// B. Return false.
|
/// B. Return false.
|
||||||
/// 7. CEF sends an close notification to the application's top-level window.
|
/// 7. CEF sends a close notification to the application's top-level window
|
||||||
|
/// (because DoClose() returned false).
|
||||||
/// 8. Application's top-level window receives the close notification and
|
/// 8. Application's top-level window receives the close notification and
|
||||||
/// allows the window to close based on the flag from #6B.
|
/// allows the window to close based on the flag from #6A.
|
||||||
/// 9. Application's top-level window is destroyed. 10. Application's
|
/// 9. Application's top-level window is destroyed, triggering destruction
|
||||||
/// on_before_close() handler is called and the browser object
|
/// of the child browser window.
|
||||||
|
/// 10. Application's on_before_close() handler is called and the browser
|
||||||
|
/// object
|
||||||
/// is destroyed.
|
/// is destroyed.
|
||||||
/// 11. Application exits by calling cef_quit_message_loop() if no other
|
/// 11. Application exits by calling cef_quit_message_loop() if no other
|
||||||
/// browsers
|
/// browsers
|
||||||
|
@ -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 "9717d7221d63adfd79ee52e2a31c9ac7acdd6d50"
|
#define CEF_API_HASH_UNIVERSAL "676af077d6826353caf40425f5f2bae1262347ea"
|
||||||
#if defined(OS_WIN)
|
#if defined(OS_WIN)
|
||||||
#define CEF_API_HASH_PLATFORM "072a4fe61a512f21fd0d664495902fca6ec2193b"
|
#define CEF_API_HASH_PLATFORM "51848171cdea10858c4e0fca0f7099b0fdc759f9"
|
||||||
#elif defined(OS_MAC)
|
#elif defined(OS_MAC)
|
||||||
#define CEF_API_HASH_PLATFORM "ee7f0e9247add8df0827d02da32559e38e8079d0"
|
#define CEF_API_HASH_PLATFORM "8cc826c5f5fe97c275dfa3b9c020470678a5d2fd"
|
||||||
#elif defined(OS_LINUX)
|
#elif defined(OS_LINUX)
|
||||||
#define CEF_API_HASH_PLATFORM "88996e58ee062016efd054bfbafd03dd3daa99ed"
|
#define CEF_API_HASH_PLATFORM "0aec2348de1bf14fafa7a23baa0df942d342d409"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
|
@ -331,30 +331,63 @@ class CefBrowserHost : public virtual CefBaseRefCounted {
|
|||||||
virtual CefRefPtr<CefBrowser> GetBrowser() = 0;
|
virtual CefRefPtr<CefBrowser> GetBrowser() = 0;
|
||||||
|
|
||||||
///
|
///
|
||||||
/// Request that the browser close. The JavaScript 'onbeforeunload' event will
|
/// Request that the browser close. Closing a browser is a multi-stage process
|
||||||
/// be fired. If |force_close| is false the event handler, if any, will be
|
/// that may complete either synchronously or asynchronously, and involves
|
||||||
/// allowed to prompt the user and the user can optionally cancel the close.
|
/// callbacks such as CefLifeSpanHandler::DoClose (Alloy style only),
|
||||||
/// If |force_close| is true the prompt will not be displayed and the close
|
/// CefLifeSpanHandler::OnBeforeClose, and a top-level window close handler
|
||||||
/// will proceed. Results in a call to CefLifeSpanHandler::DoClose() if the
|
/// such as CefWindowDelegate::CanClose (or platform-specific equivalent). In
|
||||||
/// event handler allows the close or if |force_close| is true. See
|
/// some cases a close request may be delayed or canceled by the user. Using
|
||||||
/// CefLifeSpanHandler::DoClose() documentation for additional usage
|
/// TryCloseBrowser() instead of CloseBrowser() is recommended for most use
|
||||||
/// information.
|
/// cases. See CefLifeSpanHandler::DoClose() documentation for detailed usage
|
||||||
|
/// and examples.
|
||||||
|
///
|
||||||
|
/// If |force_close| is false then JavaScript unload handlers, if any, may be
|
||||||
|
/// fired and the close may be delayed or canceled by the user. If
|
||||||
|
/// |force_close| is true then the user will not be prompted and the close
|
||||||
|
/// will proceed immediately (possibly asynchronously). If browser close is
|
||||||
|
/// delayed and not canceled the default behavior is to call the top-level
|
||||||
|
/// window close handler once the browser is ready to be closed. This default
|
||||||
|
/// behavior can be changed for Alloy style browsers by implementing
|
||||||
|
/// CefLifeSpanHandler::DoClose(). IsReadyToBeClosed() can be used to detect
|
||||||
|
/// mandatory browser close events when customizing close behavior on the
|
||||||
|
/// browser process UI thread.
|
||||||
///
|
///
|
||||||
/*--cef()--*/
|
/*--cef()--*/
|
||||||
virtual void CloseBrowser(bool force_close) = 0;
|
virtual void CloseBrowser(bool force_close) = 0;
|
||||||
|
|
||||||
///
|
///
|
||||||
/// Helper for closing a browser. Call this method from the top-level window
|
/// Helper for closing a browser. This is similar in behavior to
|
||||||
/// close handler (if any). Internally this calls CloseBrowser(false) if the
|
/// CLoseBrowser(false) but returns a boolean to reflect the immediate close
|
||||||
/// close has not yet been initiated. This method returns false while the
|
/// status. Call this method from a top-level window close handler such as
|
||||||
/// close is pending and true after the close has completed. See
|
/// CefWindowDelegate::CanClose (or platform-specific equivalent) to request
|
||||||
/// CloseBrowser() and CefLifeSpanHandler::DoClose() documentation for
|
/// that the browser close, and return the result to indicate if the window
|
||||||
/// additional usage information. This method must be called on the browser
|
/// close should proceed. Returns false if the close will be delayed
|
||||||
/// process UI thread.
|
/// (JavaScript unload handlers triggered but still pending) or true if the
|
||||||
|
/// close will proceed immediately (possibly asynchronously). See
|
||||||
|
/// CloseBrowser() documentation for additional usage information. This method
|
||||||
|
/// must be called on the browser process UI thread.
|
||||||
///
|
///
|
||||||
/*--cef()--*/
|
/*--cef()--*/
|
||||||
virtual bool TryCloseBrowser() = 0;
|
virtual bool TryCloseBrowser() = 0;
|
||||||
|
|
||||||
|
///
|
||||||
|
/// Returns true if the browser is ready to be closed, meaning that the close
|
||||||
|
/// has already been initiated and that JavaScript unload handlers have
|
||||||
|
/// already executed or should be ignored. This can be used from a top-level
|
||||||
|
/// window close handler such as CefWindowDelegate::CanClose (or
|
||||||
|
/// platform-specific equivalent) to distringuish between potentially
|
||||||
|
/// cancelable browser close events (like the user clicking the top-level
|
||||||
|
/// window close button before browser close has started) and mandatory
|
||||||
|
/// browser close events (like JavaScript `window.close()` or after browser
|
||||||
|
/// close has started in response to [Try]CloseBrowser()). Not completing the
|
||||||
|
/// browser close for mandatory close events (when this method returns true)
|
||||||
|
/// will leave the browser in a partially closed state that interferes with
|
||||||
|
/// proper functioning. See CloseBrowser() documentation for additional usage
|
||||||
|
/// information. This method must be called on the browser process UI thread.
|
||||||
|
///
|
||||||
|
/*--cef()--*/
|
||||||
|
virtual bool IsReadyToBeClosed() = 0;
|
||||||
|
|
||||||
///
|
///
|
||||||
/// Set whether the browser is focused.
|
/// Set whether the browser is focused.
|
||||||
///
|
///
|
||||||
|
@ -131,34 +131,44 @@ class CefLifeSpanHandler : public virtual CefBaseRefCounted {
|
|||||||
virtual void OnAfterCreated(CefRefPtr<CefBrowser> browser) {}
|
virtual void OnAfterCreated(CefRefPtr<CefBrowser> browser) {}
|
||||||
|
|
||||||
///
|
///
|
||||||
/// Called when a browser has received a request to close. This may result
|
/// Called when an Alloy style browser is ready to be closed, meaning that the
|
||||||
/// directly from a call to CefBrowserHost::*CloseBrowser() or indirectly if
|
/// close has already been initiated and that JavaScript unload handlers have
|
||||||
/// the browser is parented to a top-level window created by CEF and the user
|
/// already executed or should be ignored. This may result directly from a
|
||||||
/// attempts to close that window (by clicking the 'X', for example). The
|
/// call to CefBrowserHost::[Try]CloseBrowser() or indirectly if the browser's
|
||||||
/// DoClose() method will be called after the JavaScript 'onunload' event has
|
/// top-level parent window was created by CEF and the user attempts to
|
||||||
/// been fired.
|
/// close that window (by clicking the 'X', for example). DoClose() will not
|
||||||
|
/// be called if the browser's host window/view has already been destroyed
|
||||||
|
/// (via parent window/view hierarchy tear-down, for example), as it is no
|
||||||
|
/// longer possible to customize the close behavior at that point.
|
||||||
///
|
///
|
||||||
/// An application should handle top-level owner window close notifications by
|
/// An application should handle top-level parent window close notifications
|
||||||
/// calling CefBrowserHost::TryCloseBrowser() or
|
/// by calling CefBrowserHost::TryCloseBrowser() or
|
||||||
/// CefBrowserHost::CloseBrowser(false) instead of allowing the window to
|
/// CefBrowserHost::CloseBrowser(false) instead of allowing the window to
|
||||||
/// close immediately (see the examples below). This gives CEF an opportunity
|
/// close immediately (see the examples below). This gives CEF an opportunity
|
||||||
/// to process the 'onbeforeunload' event and optionally cancel the close
|
/// to process JavaScript unload handlers and optionally cancel the close
|
||||||
/// before DoClose() is called.
|
/// before DoClose() is called.
|
||||||
///
|
///
|
||||||
/// When windowed rendering is enabled CEF will internally create a window or
|
/// When windowed rendering is enabled CEF will create an internal child
|
||||||
/// view to host the browser. In that case returning false from DoClose() will
|
/// window/view to host the browser. In that case returning false from
|
||||||
/// send the standard close notification to the browser's top-level owner
|
/// DoClose() will send the standard close notification to the browser's
|
||||||
/// window (e.g. WM_CLOSE on Windows, performClose: on OS X, "delete_event" on
|
/// top-level parent window (e.g. WM_CLOSE on Windows, performClose: on OS X,
|
||||||
/// Linux or CefWindowDelegate::CanClose() callback from Views). If the
|
/// "delete_event" on Linux or CefWindowDelegate::CanClose() callback from
|
||||||
/// browser's host window/view has already been destroyed (via view hierarchy
|
/// Views).
|
||||||
/// tear-down, for example) then DoClose() will not be called for that browser
|
|
||||||
/// since is no longer possible to cancel the close.
|
|
||||||
///
|
///
|
||||||
/// When windowed rendering is disabled returning false from DoClose() will
|
/// When windowed rendering is disabled there is no internal window/view
|
||||||
/// cause the browser object to be destroyed immediately.
|
/// and returning false from DoClose() will cause the browser object to be
|
||||||
|
/// destroyed immediately.
|
||||||
///
|
///
|
||||||
/// If the browser's top-level owner window requires a non-standard close
|
/// If the browser's top-level parent window requires a non-standard close
|
||||||
/// notification then send that notification from DoClose() and return true.
|
/// notification then send that notification from DoClose() and return true.
|
||||||
|
/// You are still required to complete the browser close as soon as possible
|
||||||
|
/// (either by calling [Try]CloseBrowser() or by proceeding with window/view
|
||||||
|
/// hierarchy tear-down), otherwise the browser will be left in a partially
|
||||||
|
/// closed state that interferes with proper functioning. Top-level windows
|
||||||
|
/// created on the browser process UI thread can alternately call
|
||||||
|
/// CefBrowserHost::IsReadyToBeClosed() in the close handler to check close
|
||||||
|
/// status instead of relying on custom DoClose() handling. See documentation
|
||||||
|
/// on that method for additional details.
|
||||||
///
|
///
|
||||||
/// The CefLifeSpanHandler::OnBeforeClose() method will be called after
|
/// The CefLifeSpanHandler::OnBeforeClose() method will be called after
|
||||||
/// DoClose() (if DoClose() is called) and immediately before the browser
|
/// DoClose() (if DoClose() is called) and immediately before the browser
|
||||||
@ -174,7 +184,7 @@ class CefLifeSpanHandler : public virtual CefBaseRefCounted {
|
|||||||
/// 1. User clicks the window close button which sends a close notification
|
/// 1. User clicks the window close button which sends a close notification
|
||||||
/// to the application's top-level window.
|
/// to the application's top-level window.
|
||||||
/// 2. Application's top-level window receives the close notification and
|
/// 2. Application's top-level window receives the close notification and
|
||||||
/// calls TryCloseBrowser() (which internally calls CloseBrowser(false)).
|
/// calls TryCloseBrowser() (similar to calling CloseBrowser(false)).
|
||||||
/// TryCloseBrowser() returns false so the client cancels the window
|
/// TryCloseBrowser() returns false so the client cancels the window
|
||||||
/// close.
|
/// close.
|
||||||
/// 3. JavaScript 'onbeforeunload' handler executes and shows the close
|
/// 3. JavaScript 'onbeforeunload' handler executes and shows the close
|
||||||
@ -182,15 +192,18 @@ class CefLifeSpanHandler : public virtual CefBaseRefCounted {
|
|||||||
/// CefJSDialogHandler::OnBeforeUnloadDialog()).
|
/// CefJSDialogHandler::OnBeforeUnloadDialog()).
|
||||||
/// 4. User approves the close.
|
/// 4. User approves the close.
|
||||||
/// 5. JavaScript 'onunload' handler executes.
|
/// 5. JavaScript 'onunload' handler executes.
|
||||||
/// 6. CEF sends a close notification to the application's top-level window
|
/// 6. Application's DoClose() handler is called and returns false by
|
||||||
/// (because DoClose() returned false by default).
|
/// default.
|
||||||
/// 7. Application's top-level window receives the close notification and
|
/// 7. CEF sends a close notification to the application's top-level window
|
||||||
|
/// (because DoClose() returned false).
|
||||||
|
/// 8. Application's top-level window receives the close notification and
|
||||||
/// calls TryCloseBrowser(). TryCloseBrowser() returns true so the client
|
/// calls TryCloseBrowser(). TryCloseBrowser() returns true so the client
|
||||||
/// allows the window close.
|
/// allows the window close.
|
||||||
/// 8. Application's top-level window is destroyed.
|
/// 9. Application's top-level window is destroyed, triggering destruction
|
||||||
/// 9. Application's OnBeforeClose() handler is called and the browser object
|
/// of the child browser window.
|
||||||
|
/// 10. Application's OnBeforeClose() handler is called and the browser object
|
||||||
/// is destroyed.
|
/// is destroyed.
|
||||||
/// 10. Application exits by calling CefQuitMessageLoop() if no other browsers
|
/// 11. Application exits by calling CefQuitMessageLoop() if no other browsers
|
||||||
/// exist.
|
/// exist.
|
||||||
///
|
///
|
||||||
/// Example 2: Using CefBrowserHost::CloseBrowser(false) and implementing the
|
/// Example 2: Using CefBrowserHost::CloseBrowser(false) and implementing the
|
||||||
@ -208,12 +221,15 @@ class CefLifeSpanHandler : public virtual CefBaseRefCounted {
|
|||||||
/// 4. User approves the close.
|
/// 4. User approves the close.
|
||||||
/// 5. JavaScript 'onunload' handler executes.
|
/// 5. JavaScript 'onunload' handler executes.
|
||||||
/// 6. Application's DoClose() handler is called. Application will:
|
/// 6. Application's DoClose() handler is called. Application will:
|
||||||
/// A. Set a flag to indicate that the next close attempt will be allowed.
|
/// A. Set a flag to indicate that the next top-level window close attempt
|
||||||
|
/// will be allowed.
|
||||||
/// B. Return false.
|
/// B. Return false.
|
||||||
/// 7. CEF sends an close notification to the application's top-level window.
|
/// 7. CEF sends a close notification to the application's top-level window
|
||||||
|
/// (because DoClose() returned false).
|
||||||
/// 8. Application's top-level window receives the close notification and
|
/// 8. Application's top-level window receives the close notification and
|
||||||
/// allows the window to close based on the flag from #6B.
|
/// allows the window to close based on the flag from #6A.
|
||||||
/// 9. Application's top-level window is destroyed.
|
/// 9. Application's top-level window is destroyed, triggering destruction
|
||||||
|
/// of the child browser window.
|
||||||
/// 10. Application's OnBeforeClose() handler is called and the browser object
|
/// 10. Application's OnBeforeClose() handler is called and the browser object
|
||||||
/// is destroyed.
|
/// is destroyed.
|
||||||
/// 11. Application exits by calling CefQuitMessageLoop() if no other browsers
|
/// 11. Application exits by calling CefQuitMessageLoop() if no other browsers
|
||||||
|
@ -452,6 +452,20 @@ bool CefBrowserHostBase::HasView() {
|
|||||||
return is_views_hosted_;
|
return is_views_hosted_;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool CefBrowserHostBase::IsReadyToBeClosed() {
|
||||||
|
if (!CEF_CURRENTLY_ON_UIT()) {
|
||||||
|
DCHECK(false) << "called on invalid thread";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (auto web_contents = GetWebContents()) {
|
||||||
|
return static_cast<content::RenderFrameHostImpl*>(
|
||||||
|
web_contents->GetPrimaryMainFrame())
|
||||||
|
->IsPageReadyToBeClosed();
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
void CefBrowserHostBase::SetFocus(bool focus) {
|
void CefBrowserHostBase::SetFocus(bool focus) {
|
||||||
if (!CEF_CURRENTLY_ON_UIT()) {
|
if (!CEF_CURRENTLY_ON_UIT()) {
|
||||||
CEF_POST_TASK(CEF_UIT,
|
CEF_POST_TASK(CEF_UIT,
|
||||||
|
@ -218,6 +218,7 @@ class CefBrowserHostBase : public CefBrowserHost,
|
|||||||
double GetZoomLevel() override;
|
double GetZoomLevel() override;
|
||||||
void SetZoomLevel(double zoomLevel) override;
|
void SetZoomLevel(double zoomLevel) override;
|
||||||
bool HasView() override;
|
bool HasView() override;
|
||||||
|
bool IsReadyToBeClosed() override;
|
||||||
void SetFocus(bool focus) override;
|
void SetFocus(bool focus) override;
|
||||||
void RunFileDialog(FileDialogMode mode,
|
void RunFileDialog(FileDialogMode mode,
|
||||||
const CefString& title,
|
const CefString& title,
|
||||||
|
@ -63,6 +63,10 @@ class PopupWindowDelegate : public CefWindowDelegate {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
cef_runtime_style_t GetWindowRuntimeStyle() override {
|
||||||
|
return browser_view_->GetRuntimeStyle();
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
CefRefPtr<CefBrowserView> browser_view_;
|
CefRefPtr<CefBrowserView> browser_view_;
|
||||||
|
|
||||||
@ -195,8 +199,9 @@ void CefBrowserPlatformDelegate::PopupWebContentsCreated(
|
|||||||
}
|
}
|
||||||
|
|
||||||
CefRefPtr<CefBrowserViewDelegate> new_delegate;
|
CefRefPtr<CefBrowserViewDelegate> new_delegate;
|
||||||
|
|
||||||
CefRefPtr<CefBrowserViewDelegate> opener_delegate;
|
CefRefPtr<CefBrowserViewDelegate> opener_delegate;
|
||||||
|
cef_runtime_style_t opener_runtime_style = CEF_RUNTIME_STYLE_DEFAULT;
|
||||||
|
|
||||||
auto browser_view = GetBrowserView();
|
auto browser_view = GetBrowserView();
|
||||||
if (browser_view) {
|
if (browser_view) {
|
||||||
// When |this| (the popup opener) is Views-hosted use the current delegate.
|
// When |this| (the popup opener) is Views-hosted use the current delegate.
|
||||||
@ -212,12 +217,22 @@ void CefBrowserPlatformDelegate::PopupWebContentsCreated(
|
|||||||
browser_view, settings, client, is_devtools);
|
browser_view, settings, client, is_devtools);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (browser_view) {
|
||||||
|
opener_runtime_style = browser_view->GetRuntimeStyle();
|
||||||
|
} else if (opener_delegate) {
|
||||||
|
opener_runtime_style = opener_delegate->GetBrowserRuntimeStyle();
|
||||||
|
}
|
||||||
|
|
||||||
// Create a new BrowserView for the popup.
|
// Create a new BrowserView for the popup.
|
||||||
CefRefPtr<CefBrowserViewImpl> new_browser_view =
|
CefRefPtr<CefBrowserViewImpl> new_browser_view =
|
||||||
CefBrowserViewImpl::CreateForPopup(settings, new_delegate, is_devtools);
|
CefBrowserViewImpl::CreateForPopup(settings, new_delegate, is_devtools,
|
||||||
|
opener_runtime_style);
|
||||||
|
|
||||||
// Associate the PlatformDelegate with the new BrowserView.
|
// Associate the PlatformDelegate with the new BrowserView.
|
||||||
new_platform_delegate->SetBrowserView(new_browser_view);
|
new_platform_delegate->SetBrowserView(new_browser_view);
|
||||||
|
|
||||||
|
// Keep the BrowserView alive until PopupBrowserCreated() is called.
|
||||||
|
new_browser_view->AddRef();
|
||||||
}
|
}
|
||||||
|
|
||||||
void CefBrowserPlatformDelegate::PopupBrowserCreated(
|
void CefBrowserPlatformDelegate::PopupBrowserCreated(
|
||||||
@ -255,6 +270,9 @@ void CefBrowserPlatformDelegate::PopupBrowserCreated(
|
|||||||
CefWindow::CreateTopLevelWindow(
|
CefWindow::CreateTopLevelWindow(
|
||||||
new PopupWindowDelegate(new_browser_view.get()));
|
new PopupWindowDelegate(new_browser_view.get()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Release the reference added in PopupWebContentsCreated().
|
||||||
|
new_browser_view->Release();
|
||||||
}
|
}
|
||||||
|
|
||||||
CefRefPtr<CefBrowserViewDelegate>
|
CefRefPtr<CefBrowserViewDelegate>
|
||||||
|
@ -165,14 +165,47 @@ void ChromeBrowserHostImpl::OnSetFocus(cef_focus_source_t source) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void ChromeBrowserHostImpl::CloseBrowser(bool force_close) {
|
void ChromeBrowserHostImpl::CloseBrowser(bool force_close) {
|
||||||
// Always do this asynchronously because TabStripModel is not re-entrant.
|
if (!CEF_CURRENTLY_ON_UIT()) {
|
||||||
CEF_POST_TASK(CEF_UIT, base::BindOnce(&ChromeBrowserHostImpl::DoCloseBrowser,
|
CEF_POST_TASK(CEF_UIT, base::BindOnce(&ChromeBrowserHostImpl::CloseBrowser,
|
||||||
this, force_close));
|
this, force_close));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!force_close) {
|
||||||
|
TryCloseBrowser();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Always do this asynchronously because TabStripModel is not re-entrant.
|
||||||
|
CEF_POST_TASK(CEF_UIT,
|
||||||
|
base::BindOnce(&ChromeBrowserHostImpl::DoCloseBrowser, this));
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ChromeBrowserHostImpl::TryCloseBrowser() {
|
bool ChromeBrowserHostImpl::TryCloseBrowser() {
|
||||||
// TODO(chrome): Handle the case where the browser may not close immediately.
|
if (!CEF_CURRENTLY_ON_UIT()) {
|
||||||
CloseBrowser(true);
|
DCHECK(false) << "called on invalid thread";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (auto* web_contents = GetWebContents()) {
|
||||||
|
// This check works as follows:
|
||||||
|
// 1. Returns false if the main frame is ready to close
|
||||||
|
// (IsPageReadyToBeClosed returns true).
|
||||||
|
// 2. Otherwise returns true if any frame in the frame tree needs to run
|
||||||
|
// beforeunload or unload-time event handlers.
|
||||||
|
// 3. Otherwise returns false.
|
||||||
|
if (web_contents->NeedToFireBeforeUnloadOrUnloadEvents()) {
|
||||||
|
// Will result in a call to Browser::BeforeUnloadFired and, if the close
|
||||||
|
// isn't canceled, Browser::CloseContents which indirectly calls
|
||||||
|
// TabStripModel::CloseWebContentsAt (similar to DoCloseBrowser but
|
||||||
|
// without CLOSE_USER_GESTURE). Additional calls to DispatchBeforeUnload
|
||||||
|
// while the unload is pending will be ignored.
|
||||||
|
web_contents->DispatchBeforeUnload(/*auto_cancel=*/false);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
CloseBrowser(/*force_close=*/true);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -551,7 +584,7 @@ void ChromeBrowserHostImpl::DestroyBrowser() {
|
|||||||
// WebContents first. See comments on CefBrowserHostBase::DestroyBrowser.
|
// WebContents first. See comments on CefBrowserHostBase::DestroyBrowser.
|
||||||
if (GetWebContents()) {
|
if (GetWebContents()) {
|
||||||
// Triggers a call to OnWebContentsDestroyed.
|
// Triggers a call to OnWebContentsDestroyed.
|
||||||
DoCloseBrowser(/*force_close=*/true);
|
DoCloseBrowser();
|
||||||
DCHECK(!GetWebContents());
|
DCHECK(!GetWebContents());
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -565,15 +598,13 @@ void ChromeBrowserHostImpl::DestroyBrowser() {
|
|||||||
CefBrowserHostBase::DestroyBrowser();
|
CefBrowserHostBase::DestroyBrowser();
|
||||||
}
|
}
|
||||||
|
|
||||||
void ChromeBrowserHostImpl::DoCloseBrowser(bool force_close) {
|
void ChromeBrowserHostImpl::DoCloseBrowser() {
|
||||||
CEF_REQUIRE_UIT();
|
CEF_REQUIRE_UIT();
|
||||||
if (browser_) {
|
if (browser_) {
|
||||||
// Like chrome::CloseTab() but specifying the WebContents.
|
// Like chrome::CloseTab() but specifying the WebContents.
|
||||||
const int tab_index = GetCurrentTabIndex();
|
const int tab_index = GetCurrentTabIndex();
|
||||||
if (tab_index != TabStripModel::kNoTab) {
|
if (tab_index != TabStripModel::kNoTab) {
|
||||||
// This will trigger destruction of the Browser and WebContents.
|
// This will trigger destruction of the Browser and WebContents.
|
||||||
// TODO(chrome): Handle the case where this method returns false,
|
|
||||||
// indicating that the contents were not closed immediately.
|
|
||||||
browser_->tab_strip_model()->CloseWebContentsAt(
|
browser_->tab_strip_model()->CloseWebContentsAt(
|
||||||
tab_index, TabCloseTypes::CLOSE_CREATE_HISTORICAL_TAB |
|
tab_index, TabCloseTypes::CLOSE_CREATE_HISTORICAL_TAB |
|
||||||
TabCloseTypes::CLOSE_USER_GESTURE);
|
TabCloseTypes::CLOSE_USER_GESTURE);
|
||||||
|
@ -169,7 +169,7 @@ class ChromeBrowserHostImpl : public CefBrowserHostBase {
|
|||||||
bool WillBeDestroyed() const override;
|
bool WillBeDestroyed() const override;
|
||||||
void DestroyBrowser() override;
|
void DestroyBrowser() override;
|
||||||
|
|
||||||
void DoCloseBrowser(bool force_close);
|
void DoCloseBrowser();
|
||||||
|
|
||||||
// Returns the current tab index for the associated WebContents, or
|
// Returns the current tab index for the associated WebContents, or
|
||||||
// TabStripModel::kNoTab if not found.
|
// TabStripModel::kNoTab if not found.
|
||||||
|
@ -17,6 +17,7 @@
|
|||||||
|
|
||||||
#if BUILDFLAG(IS_LINUX)
|
#if BUILDFLAG(IS_LINUX)
|
||||||
#include "base/linux_util.h"
|
#include "base/linux_util.h"
|
||||||
|
#include "cef/libcef/browser/printing/print_dialog_linux.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if BUILDFLAG(IS_WIN)
|
#if BUILDFLAG(IS_WIN)
|
||||||
@ -83,4 +84,11 @@ void ChromeBrowserMainExtraPartsCef::ToolkitInitialized() {
|
|||||||
// Override the default Chrome client.
|
// Override the default Chrome client.
|
||||||
SetConstrainedWindowViewsClient(CreateAlloyConstrainedWindowViewsClient(
|
SetConstrainedWindowViewsClient(CreateAlloyConstrainedWindowViewsClient(
|
||||||
CreateChromeConstrainedWindowViewsClient()));
|
CreateChromeConstrainedWindowViewsClient()));
|
||||||
|
|
||||||
|
#if BUILDFLAG(IS_LINUX)
|
||||||
|
auto printing_delegate = new CefPrintingContextLinuxDelegate();
|
||||||
|
auto default_delegate =
|
||||||
|
ui::PrintingContextLinuxDelegate::SetInstance(printing_delegate);
|
||||||
|
printing_delegate->SetDefaultDelegate(default_delegate);
|
||||||
|
#endif // BUILDFLAG(IS_LINUX)
|
||||||
}
|
}
|
||||||
|
@ -24,7 +24,8 @@ void CefBrowserPlatformDelegateChromeViews::SetBrowserView(
|
|||||||
CefRefPtr<CefBrowserView> browser_view) {
|
CefRefPtr<CefBrowserView> browser_view) {
|
||||||
DCHECK(!browser_view_);
|
DCHECK(!browser_view_);
|
||||||
DCHECK(browser_view);
|
DCHECK(browser_view);
|
||||||
browser_view_ = static_cast<CefBrowserViewImpl*>(browser_view.get());
|
browser_view_ =
|
||||||
|
static_cast<CefBrowserViewImpl*>(browser_view.get())->GetWeakPtr();
|
||||||
}
|
}
|
||||||
|
|
||||||
void CefBrowserPlatformDelegateChromeViews::WebContentsCreated(
|
void CefBrowserPlatformDelegateChromeViews::WebContentsCreated(
|
||||||
@ -37,8 +38,11 @@ void CefBrowserPlatformDelegateChromeViews::WebContentsCreated(
|
|||||||
void CefBrowserPlatformDelegateChromeViews::WebContentsDestroyed(
|
void CefBrowserPlatformDelegateChromeViews::WebContentsDestroyed(
|
||||||
content::WebContents* web_contents) {
|
content::WebContents* web_contents) {
|
||||||
CefBrowserPlatformDelegateChrome::WebContentsDestroyed(web_contents);
|
CefBrowserPlatformDelegateChrome::WebContentsDestroyed(web_contents);
|
||||||
|
// |browser_view_| may be destroyed before this callback arrives.
|
||||||
|
if (browser_view_) {
|
||||||
browser_view_->WebContentsDestroyed(web_contents);
|
browser_view_->WebContentsDestroyed(web_contents);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void CefBrowserPlatformDelegateChromeViews::BrowserCreated(
|
void CefBrowserPlatformDelegateChromeViews::BrowserCreated(
|
||||||
CefBrowserHostBase* browser) {
|
CefBrowserHostBase* browser) {
|
||||||
@ -48,7 +52,7 @@ void CefBrowserPlatformDelegateChromeViews::BrowserCreated(
|
|||||||
|
|
||||||
void CefBrowserPlatformDelegateChromeViews::NotifyBrowserCreated() {
|
void CefBrowserPlatformDelegateChromeViews::NotifyBrowserCreated() {
|
||||||
if (auto delegate = browser_view_->delegate()) {
|
if (auto delegate = browser_view_->delegate()) {
|
||||||
delegate->OnBrowserCreated(browser_view_, browser_.get());
|
delegate->OnBrowserCreated(browser_view_.get(), browser_.get());
|
||||||
|
|
||||||
// DevTools windows hide the notification bubble by default. However, we
|
// DevTools windows hide the notification bubble by default. However, we
|
||||||
// don't currently have the ability to intercept WebContents creation via
|
// don't currently have the ability to intercept WebContents creation via
|
||||||
@ -75,8 +79,9 @@ void CefBrowserPlatformDelegateChromeViews::NotifyBrowserCreated() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void CefBrowserPlatformDelegateChromeViews::NotifyBrowserDestroyed() {
|
void CefBrowserPlatformDelegateChromeViews::NotifyBrowserDestroyed() {
|
||||||
if (browser_view_->delegate()) {
|
// |browser_view_| may be destroyed before this callback arrives.
|
||||||
browser_view_->delegate()->OnBrowserDestroyed(browser_view_,
|
if (browser_view_ && browser_view_->delegate()) {
|
||||||
|
browser_view_->delegate()->OnBrowserDestroyed(browser_view_.get(),
|
||||||
browser_.get());
|
browser_.get());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -84,8 +89,12 @@ void CefBrowserPlatformDelegateChromeViews::NotifyBrowserDestroyed() {
|
|||||||
void CefBrowserPlatformDelegateChromeViews::BrowserDestroyed(
|
void CefBrowserPlatformDelegateChromeViews::BrowserDestroyed(
|
||||||
CefBrowserHostBase* browser) {
|
CefBrowserHostBase* browser) {
|
||||||
CefBrowserPlatformDelegateChrome::BrowserDestroyed(browser);
|
CefBrowserPlatformDelegateChrome::BrowserDestroyed(browser);
|
||||||
|
// |browser_view_| may be destroyed before this callback arrives.
|
||||||
|
if (browser_view_) {
|
||||||
browser_view_->BrowserDestroyed(browser);
|
browser_view_->BrowserDestroyed(browser);
|
||||||
}
|
}
|
||||||
|
browser_view_ = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
void CefBrowserPlatformDelegateChromeViews::CloseHostWindow() {
|
void CefBrowserPlatformDelegateChromeViews::CloseHostWindow() {
|
||||||
views::Widget* widget = GetWindowWidget();
|
views::Widget* widget = GetWindowWidget();
|
||||||
@ -100,7 +109,7 @@ CefWindowHandle CefBrowserPlatformDelegateChromeViews::GetHostWindowHandle()
|
|||||||
}
|
}
|
||||||
|
|
||||||
views::Widget* CefBrowserPlatformDelegateChromeViews::GetWindowWidget() const {
|
views::Widget* CefBrowserPlatformDelegateChromeViews::GetWindowWidget() const {
|
||||||
if (browser_view_->root_view()) {
|
if (browser_view_ && browser_view_->root_view()) {
|
||||||
return browser_view_->root_view()->GetWidget();
|
return browser_view_->root_view()->GetWidget();
|
||||||
}
|
}
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
@ -5,6 +5,7 @@
|
|||||||
#ifndef CEF_LIBCEF_BROWSER_CHROME_VIEWS_BROWSER_PLATFORM_DELEGATE_CHROME_VIEWS_H_
|
#ifndef CEF_LIBCEF_BROWSER_CHROME_VIEWS_BROWSER_PLATFORM_DELEGATE_CHROME_VIEWS_H_
|
||||||
#define CEF_LIBCEF_BROWSER_CHROME_VIEWS_BROWSER_PLATFORM_DELEGATE_CHROME_VIEWS_H_
|
#define CEF_LIBCEF_BROWSER_CHROME_VIEWS_BROWSER_PLATFORM_DELEGATE_CHROME_VIEWS_H_
|
||||||
|
|
||||||
|
#include "base/memory/weak_ptr.h"
|
||||||
#include "cef/libcef/browser/chrome/browser_platform_delegate_chrome.h"
|
#include "cef/libcef/browser/chrome/browser_platform_delegate_chrome.h"
|
||||||
#include "cef/libcef/browser/views/browser_view_impl.h"
|
#include "cef/libcef/browser/views/browser_view_impl.h"
|
||||||
|
|
||||||
@ -33,12 +34,17 @@ class CefBrowserPlatformDelegateChromeViews
|
|||||||
void SetBrowserView(CefRefPtr<CefBrowserView> browser_view) override;
|
void SetBrowserView(CefRefPtr<CefBrowserView> browser_view) override;
|
||||||
bool IsViewsHosted() const override;
|
bool IsViewsHosted() const override;
|
||||||
|
|
||||||
CefRefPtr<CefBrowserViewImpl> browser_view() const { return browser_view_; }
|
CefBrowserViewImpl* browser_view() const { return browser_view_.get(); }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
CefWindowImpl* GetWindowImpl() const;
|
CefWindowImpl* GetWindowImpl() const;
|
||||||
|
|
||||||
CefRefPtr<CefBrowserViewImpl> browser_view_;
|
// Holding a weak reference here because we want the CefBrowserViewImpl to be
|
||||||
|
// destroyed first if all references are released by the client.
|
||||||
|
// CefBrowserViewImpl destruction will then trigger destruction of any
|
||||||
|
// associated CefBrowserHostBase (which owns this CefBrowserPlatformDelegate
|
||||||
|
// object).
|
||||||
|
base::WeakPtr<CefBrowserViewImpl> browser_view_;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // CEF_LIBCEF_BROWSER_CHROME_VIEWS_BROWSER_PLATFORM_DELEGATE_CHROME_VIEWS_H_
|
#endif // CEF_LIBCEF_BROWSER_CHROME_VIEWS_BROWSER_PLATFORM_DELEGATE_CHROME_VIEWS_H_
|
||||||
|
@ -11,6 +11,13 @@ ChromeBrowserView::ChromeBrowserView(CefBrowserViewImpl* cef_browser_view)
|
|||||||
: ParentClass(cef_browser_view->delegate()),
|
: ParentClass(cef_browser_view->delegate()),
|
||||||
cef_browser_view_(cef_browser_view) {}
|
cef_browser_view_(cef_browser_view) {}
|
||||||
|
|
||||||
|
ChromeBrowserView::~ChromeBrowserView() {
|
||||||
|
if (cef_toolbar_) {
|
||||||
|
WillDestroyToolbar();
|
||||||
|
cef_toolbar_ = nullptr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void ChromeBrowserView::InitBrowser(std::unique_ptr<Browser> browser) {
|
void ChromeBrowserView::InitBrowser(std::unique_ptr<Browser> browser) {
|
||||||
DCHECK(!web_view_);
|
DCHECK(!web_view_);
|
||||||
|
|
||||||
|
@ -30,6 +30,7 @@ class ChromeBrowserView
|
|||||||
|
|
||||||
// |cef_browser_view| is non-nullptr and will outlive this object.
|
// |cef_browser_view| is non-nullptr and will outlive this object.
|
||||||
explicit ChromeBrowserView(CefBrowserViewImpl* cef_browser_view);
|
explicit ChromeBrowserView(CefBrowserViewImpl* cef_browser_view);
|
||||||
|
~ChromeBrowserView() override;
|
||||||
|
|
||||||
ChromeBrowserView(const ChromeBrowserView&) = delete;
|
ChromeBrowserView(const ChromeBrowserView&) = delete;
|
||||||
ChromeBrowserView& operator=(const ChromeBrowserView&) = delete;
|
ChromeBrowserView& operator=(const ChromeBrowserView&) = delete;
|
||||||
|
@ -449,9 +449,6 @@ void CefMainRunner::StartShutdownOnUIThread(
|
|||||||
content::BrowserTaskExecutor::RunAllPendingTasksOnThreadForTesting(
|
content::BrowserTaskExecutor::RunAllPendingTasksOnThreadForTesting(
|
||||||
content::BrowserThread::IO);
|
content::BrowserThread::IO);
|
||||||
|
|
||||||
static_cast<content::ContentMainRunnerImpl*>(main_runner_.get())
|
|
||||||
->ShutdownOnUIThread();
|
|
||||||
|
|
||||||
std::move(shutdown_on_ui_thread).Run();
|
std::move(shutdown_on_ui_thread).Run();
|
||||||
BeforeUIThreadShutdown();
|
BeforeUIThreadShutdown();
|
||||||
}
|
}
|
||||||
@ -462,6 +459,9 @@ void CefMainRunner::FinishShutdownOnUIThread() {
|
|||||||
// It is safe to call multiple times.
|
// It is safe to call multiple times.
|
||||||
ChromeProcessSingleton::DeleteInstance();
|
ChromeProcessSingleton::DeleteInstance();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static_cast<content::ContentMainRunnerImpl*>(main_runner_.get())
|
||||||
|
->ShutdownOnUIThread();
|
||||||
}
|
}
|
||||||
|
|
||||||
void CefMainRunner::BeforeUIThreadInitialize() {
|
void CefMainRunner::BeforeUIThreadInitialize() {
|
||||||
|
@ -27,7 +27,8 @@ void CefBrowserPlatformDelegateViews::SetBrowserView(
|
|||||||
CefRefPtr<CefBrowserView> browser_view) {
|
CefRefPtr<CefBrowserView> browser_view) {
|
||||||
DCHECK(!browser_view_);
|
DCHECK(!browser_view_);
|
||||||
DCHECK(browser_view);
|
DCHECK(browser_view);
|
||||||
browser_view_ = static_cast<CefBrowserViewImpl*>(browser_view.get());
|
browser_view_ =
|
||||||
|
static_cast<CefBrowserViewImpl*>(browser_view.get())->GetWeakPtr();
|
||||||
}
|
}
|
||||||
|
|
||||||
void CefBrowserPlatformDelegateViews::WebContentsCreated(
|
void CefBrowserPlatformDelegateViews::WebContentsCreated(
|
||||||
@ -41,7 +42,10 @@ void CefBrowserPlatformDelegateViews::WebContentsCreated(
|
|||||||
void CefBrowserPlatformDelegateViews::WebContentsDestroyed(
|
void CefBrowserPlatformDelegateViews::WebContentsDestroyed(
|
||||||
content::WebContents* web_contents) {
|
content::WebContents* web_contents) {
|
||||||
CefBrowserPlatformDelegateAlloy::WebContentsDestroyed(web_contents);
|
CefBrowserPlatformDelegateAlloy::WebContentsDestroyed(web_contents);
|
||||||
browser_view_->WebContentsCreated(web_contents);
|
// |browser_view_| may be destroyed before this callback arrives.
|
||||||
|
if (browser_view_) {
|
||||||
|
browser_view_->WebContentsDestroyed(web_contents);
|
||||||
|
}
|
||||||
native_delegate_->WebContentsDestroyed(web_contents);
|
native_delegate_->WebContentsDestroyed(web_contents);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -57,15 +61,16 @@ void CefBrowserPlatformDelegateViews::NotifyBrowserCreated() {
|
|||||||
DCHECK(browser_view_);
|
DCHECK(browser_view_);
|
||||||
DCHECK(browser_);
|
DCHECK(browser_);
|
||||||
if (browser_view_->delegate()) {
|
if (browser_view_->delegate()) {
|
||||||
browser_view_->delegate()->OnBrowserCreated(browser_view_, browser_.get());
|
browser_view_->delegate()->OnBrowserCreated(browser_view_.get(),
|
||||||
|
browser_.get());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void CefBrowserPlatformDelegateViews::NotifyBrowserDestroyed() {
|
void CefBrowserPlatformDelegateViews::NotifyBrowserDestroyed() {
|
||||||
DCHECK(browser_view_);
|
|
||||||
DCHECK(browser_);
|
DCHECK(browser_);
|
||||||
if (browser_view_->delegate()) {
|
// |browser_view_| may be destroyed before this callback arrives.
|
||||||
browser_view_->delegate()->OnBrowserDestroyed(browser_view_,
|
if (browser_view_ && browser_view_->delegate()) {
|
||||||
|
browser_view_->delegate()->OnBrowserDestroyed(browser_view_.get(),
|
||||||
browser_.get());
|
browser_.get());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -74,7 +79,10 @@ void CefBrowserPlatformDelegateViews::BrowserDestroyed(
|
|||||||
CefBrowserHostBase* browser) {
|
CefBrowserHostBase* browser) {
|
||||||
CefBrowserPlatformDelegateAlloy::BrowserDestroyed(browser);
|
CefBrowserPlatformDelegateAlloy::BrowserDestroyed(browser);
|
||||||
|
|
||||||
|
// |browser_view_| may be destroyed before this callback arrives.
|
||||||
|
if (browser_view_) {
|
||||||
browser_view_->BrowserDestroyed(browser);
|
browser_view_->BrowserDestroyed(browser);
|
||||||
|
}
|
||||||
browser_view_ = nullptr;
|
browser_view_ = nullptr;
|
||||||
native_delegate_->BrowserDestroyed(browser);
|
native_delegate_->BrowserDestroyed(browser);
|
||||||
}
|
}
|
||||||
|
@ -5,6 +5,7 @@
|
|||||||
#ifndef CEF_LIBCEF_BROWSER_VIEWS_BROWSER_PLATFORM_DELEGATE_VIEWS_H_
|
#ifndef CEF_LIBCEF_BROWSER_VIEWS_BROWSER_PLATFORM_DELEGATE_VIEWS_H_
|
||||||
#define CEF_LIBCEF_BROWSER_VIEWS_BROWSER_PLATFORM_DELEGATE_VIEWS_H_
|
#define CEF_LIBCEF_BROWSER_VIEWS_BROWSER_PLATFORM_DELEGATE_VIEWS_H_
|
||||||
|
|
||||||
|
#include "base/memory/weak_ptr.h"
|
||||||
#include "cef/libcef/browser/alloy/browser_platform_delegate_alloy.h"
|
#include "cef/libcef/browser/alloy/browser_platform_delegate_alloy.h"
|
||||||
#include "cef/libcef/browser/native/browser_platform_delegate_native.h"
|
#include "cef/libcef/browser/native/browser_platform_delegate_native.h"
|
||||||
#include "cef/libcef/browser/views/browser_view_impl.h"
|
#include "cef/libcef/browser/views/browser_view_impl.h"
|
||||||
@ -65,7 +66,13 @@ class CefBrowserPlatformDelegateViews
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
std::unique_ptr<CefBrowserPlatformDelegateNative> native_delegate_;
|
std::unique_ptr<CefBrowserPlatformDelegateNative> native_delegate_;
|
||||||
CefRefPtr<CefBrowserViewImpl> browser_view_;
|
|
||||||
|
// Holding a weak reference here because we want the CefBrowserViewImpl to be
|
||||||
|
// destroyed first if all references are released by the client.
|
||||||
|
// CefBrowserViewImpl destruction will then trigger destruction of any
|
||||||
|
// associated CefBrowserHostBase (which owns this CefBrowserPlatformDelegate
|
||||||
|
// object).
|
||||||
|
base::WeakPtr<CefBrowserViewImpl> browser_view_;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // CEF_LIBCEF_BROWSER_VIEWS_BROWSER_PLATFORM_DELEGATE_VIEWS_H_
|
#endif // CEF_LIBCEF_BROWSER_VIEWS_BROWSER_PLATFORM_DELEGATE_VIEWS_H_
|
||||||
|
@ -35,30 +35,39 @@ std::optional<cef_gesture_command_t> GetGestureCommand(
|
|||||||
return std::nullopt;
|
return std::nullopt;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ComputeAlloyStyle(CefBrowserViewDelegate* cef_delegate,
|
bool ComputeAlloyStyle(
|
||||||
bool is_devtools_popup) {
|
CefBrowserViewDelegate* cef_delegate,
|
||||||
|
bool is_devtools_popup,
|
||||||
|
std::optional<cef_runtime_style_t> opener_runtime_style) {
|
||||||
|
if (is_devtools_popup) {
|
||||||
// Alloy style is not supported with Chrome DevTools popups.
|
// Alloy style is not supported with Chrome DevTools popups.
|
||||||
const bool supports_alloy_style = !is_devtools_popup;
|
if (cef_delegate &&
|
||||||
const auto default_style = CEF_RUNTIME_STYLE_CHROME;
|
cef_delegate->GetBrowserRuntimeStyle() == CEF_RUNTIME_STYLE_ALLOY) {
|
||||||
|
|
||||||
auto result_style = default_style;
|
|
||||||
|
|
||||||
if (cef_delegate) {
|
|
||||||
auto requested_style = cef_delegate->GetBrowserRuntimeStyle();
|
|
||||||
if (requested_style == CEF_RUNTIME_STYLE_ALLOY) {
|
|
||||||
if (supports_alloy_style) {
|
|
||||||
result_style = requested_style;
|
|
||||||
} else {
|
|
||||||
LOG(ERROR) << "GetBrowserRuntimeStyle() requested Alloy style; only "
|
LOG(ERROR) << "GetBrowserRuntimeStyle() requested Alloy style; only "
|
||||||
"Chrome style is supported";
|
"Chrome style is supported for DevTools popups";
|
||||||
}
|
|
||||||
} else if (requested_style == CEF_RUNTIME_STYLE_CHROME) {
|
|
||||||
// Chrome style is always supported.
|
|
||||||
result_style = requested_style;
|
|
||||||
}
|
}
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
return result_style == CEF_RUNTIME_STYLE_ALLOY;
|
if (opener_runtime_style) {
|
||||||
|
// Popup style must match the opener style.
|
||||||
|
const bool opener_alloy_style =
|
||||||
|
*opener_runtime_style == CEF_RUNTIME_STYLE_ALLOY;
|
||||||
|
if (cef_delegate) {
|
||||||
|
const auto requested_style = cef_delegate->GetBrowserRuntimeStyle();
|
||||||
|
if (requested_style != CEF_RUNTIME_STYLE_DEFAULT &&
|
||||||
|
requested_style != (opener_alloy_style ? CEF_RUNTIME_STYLE_ALLOY
|
||||||
|
: CEF_RUNTIME_STYLE_CHROME)) {
|
||||||
|
LOG(ERROR)
|
||||||
|
<< "GetBrowserRuntimeStyle() for popups must match opener style";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return opener_alloy_style;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Chrome style is the default unless Alloy is specifically requested.
|
||||||
|
return cef_delegate &&
|
||||||
|
cef_delegate->GetBrowserRuntimeStyle() == CEF_RUNTIME_STYLE_ALLOY;
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
@ -111,7 +120,8 @@ CefRefPtr<CefBrowserViewImpl> CefBrowserViewImpl::Create(
|
|||||||
}
|
}
|
||||||
|
|
||||||
CefRefPtr<CefBrowserViewImpl> browser_view =
|
CefRefPtr<CefBrowserViewImpl> browser_view =
|
||||||
new CefBrowserViewImpl(delegate, /*is_devtools_popup=*/false);
|
new CefBrowserViewImpl(delegate, /*is_devtools_popup=*/false,
|
||||||
|
/*opener_runtime_style=*/std::nullopt);
|
||||||
browser_view->SetPendingBrowserCreateParams(
|
browser_view->SetPendingBrowserCreateParams(
|
||||||
window_info, client, url, settings, extra_info, request_context);
|
window_info, client, url, settings, extra_info, request_context);
|
||||||
browser_view->Initialize();
|
browser_view->Initialize();
|
||||||
@ -123,16 +133,38 @@ CefRefPtr<CefBrowserViewImpl> CefBrowserViewImpl::Create(
|
|||||||
CefRefPtr<CefBrowserViewImpl> CefBrowserViewImpl::CreateForPopup(
|
CefRefPtr<CefBrowserViewImpl> CefBrowserViewImpl::CreateForPopup(
|
||||||
const CefBrowserSettings& settings,
|
const CefBrowserSettings& settings,
|
||||||
CefRefPtr<CefBrowserViewDelegate> delegate,
|
CefRefPtr<CefBrowserViewDelegate> delegate,
|
||||||
bool is_devtools) {
|
bool is_devtools,
|
||||||
|
cef_runtime_style_t opener_runtime_style) {
|
||||||
CEF_REQUIRE_UIT_RETURN(nullptr);
|
CEF_REQUIRE_UIT_RETURN(nullptr);
|
||||||
|
|
||||||
CefRefPtr<CefBrowserViewImpl> browser_view =
|
CefRefPtr<CefBrowserViewImpl> browser_view =
|
||||||
new CefBrowserViewImpl(delegate, is_devtools);
|
new CefBrowserViewImpl(delegate, is_devtools, opener_runtime_style);
|
||||||
browser_view->Initialize();
|
browser_view->Initialize();
|
||||||
browser_view->SetDefaults(settings);
|
browser_view->SetDefaults(settings);
|
||||||
return browser_view;
|
return browser_view;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
CefBrowserViewImpl::~CefBrowserViewImpl() {
|
||||||
|
// We want no further callbacks to this object.
|
||||||
|
weak_ptr_factory_.InvalidateWeakPtrs();
|
||||||
|
|
||||||
|
// |browser_| may exist here if the BrowserView was removed from the Views
|
||||||
|
// hierarchy prior to tear-down and the last BrowserView reference was
|
||||||
|
// released. In that case DisassociateFromWidget() will be called when the
|
||||||
|
// BrowserView is removed from the Window but Detach() will not be called
|
||||||
|
// because the BrowserView was not destroyed via the Views hierarchy
|
||||||
|
// tear-down.
|
||||||
|
DCHECK(!cef_widget_);
|
||||||
|
if (browser_ && !browser_->WillBeDestroyed()) {
|
||||||
|
// With Alloy style |browser_| will disappear when WindowDestroyed()
|
||||||
|
// indirectly calls BrowserDestroyed() so keep a reference.
|
||||||
|
CefRefPtr<CefBrowserHostBase> browser = browser_;
|
||||||
|
|
||||||
|
// Force the browser to be destroyed.
|
||||||
|
browser->WindowDestroyed();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void CefBrowserViewImpl::WebContentsCreated(
|
void CefBrowserViewImpl::WebContentsCreated(
|
||||||
content::WebContents* web_contents) {
|
content::WebContents* web_contents) {
|
||||||
if (web_view()) {
|
if (web_view()) {
|
||||||
@ -269,8 +301,8 @@ void CefBrowserViewImpl::AddedToWidget() {
|
|||||||
CefWidget* cef_widget = CefWidget::GetForWidget(widget);
|
CefWidget* cef_widget = CefWidget::GetForWidget(widget);
|
||||||
DCHECK(cef_widget);
|
DCHECK(cef_widget);
|
||||||
|
|
||||||
if (!browser_) {
|
if (!browser_ && !is_alloy_style_) {
|
||||||
if (cef_widget->IsAlloyStyle() && !is_alloy_style_) {
|
if (cef_widget->IsAlloyStyle()) {
|
||||||
LOG(ERROR) << "Cannot add Chrome style BrowserView to Alloy style Window";
|
LOG(ERROR) << "Cannot add Chrome style BrowserView to Alloy style Window";
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -337,9 +369,12 @@ bool CefBrowserViewImpl::OnGestureEvent(ui::GestureEvent* event) {
|
|||||||
|
|
||||||
CefBrowserViewImpl::CefBrowserViewImpl(
|
CefBrowserViewImpl::CefBrowserViewImpl(
|
||||||
CefRefPtr<CefBrowserViewDelegate> delegate,
|
CefRefPtr<CefBrowserViewDelegate> delegate,
|
||||||
bool is_devtools_popup)
|
bool is_devtools_popup,
|
||||||
|
std::optional<cef_runtime_style_t> opener_runtime_style)
|
||||||
: ParentClass(delegate),
|
: ParentClass(delegate),
|
||||||
is_alloy_style_(ComputeAlloyStyle(delegate.get(), is_devtools_popup)),
|
is_alloy_style_(ComputeAlloyStyle(delegate.get(),
|
||||||
|
is_devtools_popup,
|
||||||
|
opener_runtime_style)),
|
||||||
weak_ptr_factory_(this) {}
|
weak_ptr_factory_(this) {}
|
||||||
|
|
||||||
void CefBrowserViewImpl::SetPendingBrowserCreateParams(
|
void CefBrowserViewImpl::SetPendingBrowserCreateParams(
|
||||||
|
@ -6,6 +6,8 @@
|
|||||||
#define CEF_LIBCEF_BROWSER_VIEWS_BROWSER_VIEW_IMPL_H_
|
#define CEF_LIBCEF_BROWSER_VIEWS_BROWSER_VIEW_IMPL_H_
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include <optional>
|
||||||
|
|
||||||
#include "base/functional/callback_forward.h"
|
#include "base/functional/callback_forward.h"
|
||||||
#include "base/memory/raw_ptr.h"
|
#include "base/memory/raw_ptr.h"
|
||||||
#include "base/memory/weak_ptr.h"
|
#include "base/memory/weak_ptr.h"
|
||||||
@ -33,6 +35,8 @@ class CefBrowserViewImpl
|
|||||||
CefBrowserViewImpl(const CefBrowserViewImpl&) = delete;
|
CefBrowserViewImpl(const CefBrowserViewImpl&) = delete;
|
||||||
CefBrowserViewImpl& operator=(const CefBrowserViewImpl&) = delete;
|
CefBrowserViewImpl& operator=(const CefBrowserViewImpl&) = delete;
|
||||||
|
|
||||||
|
~CefBrowserViewImpl() override;
|
||||||
|
|
||||||
// Create a new CefBrowserView instance. |delegate| may be nullptr.
|
// Create a new CefBrowserView instance. |delegate| may be nullptr.
|
||||||
// |window_info| will only be used when creating a Chrome child window.
|
// |window_info| will only be used when creating a Chrome child window.
|
||||||
static CefRefPtr<CefBrowserViewImpl> Create(
|
static CefRefPtr<CefBrowserViewImpl> Create(
|
||||||
@ -49,7 +53,8 @@ class CefBrowserViewImpl
|
|||||||
static CefRefPtr<CefBrowserViewImpl> CreateForPopup(
|
static CefRefPtr<CefBrowserViewImpl> CreateForPopup(
|
||||||
const CefBrowserSettings& settings,
|
const CefBrowserSettings& settings,
|
||||||
CefRefPtr<CefBrowserViewDelegate> delegate,
|
CefRefPtr<CefBrowserViewDelegate> delegate,
|
||||||
bool is_devtools);
|
bool is_devtools,
|
||||||
|
cef_runtime_style_t opener_runtime_style);
|
||||||
|
|
||||||
// Called from CefBrowserPlatformDelegate[Chrome]Views.
|
// Called from CefBrowserPlatformDelegate[Chrome]Views.
|
||||||
void WebContentsCreated(content::WebContents* web_contents);
|
void WebContentsCreated(content::WebContents* web_contents);
|
||||||
@ -96,12 +101,17 @@ class CefBrowserViewImpl
|
|||||||
bool IsAlloyStyle() const { return is_alloy_style_; }
|
bool IsAlloyStyle() const { return is_alloy_style_; }
|
||||||
bool IsChromeStyle() const { return !is_alloy_style_; }
|
bool IsChromeStyle() const { return !is_alloy_style_; }
|
||||||
|
|
||||||
|
base::WeakPtr<CefBrowserViewImpl> GetWeakPtr() {
|
||||||
|
return weak_ptr_factory_.GetWeakPtr();
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// Create a new implementation object.
|
// Create a new implementation object.
|
||||||
// Always call Initialize() after creation.
|
// Always call Initialize() after creation.
|
||||||
// |delegate| may be nullptr.
|
// |delegate| may be nullptr.
|
||||||
CefBrowserViewImpl(CefRefPtr<CefBrowserViewDelegate> delegate,
|
CefBrowserViewImpl(CefRefPtr<CefBrowserViewDelegate> delegate,
|
||||||
bool is_devtools_popup);
|
bool is_devtools_popup,
|
||||||
|
std::optional<cef_runtime_style_t> opener_runtime_style);
|
||||||
|
|
||||||
void SetPendingBrowserCreateParams(
|
void SetPendingBrowserCreateParams(
|
||||||
const CefWindowInfo& window_info,
|
const CefWindowInfo& window_info,
|
||||||
|
@ -52,6 +52,7 @@ class CefNativeWidgetMac : public views::NativeWidgetMac {
|
|||||||
bool IsCefWindowInitialized() const;
|
bool IsCefWindowInitialized() const;
|
||||||
|
|
||||||
raw_ptr<BrowserView, AcrossTasksDanglingUntriaged> browser_view_ = nullptr;
|
raw_ptr<BrowserView, AcrossTasksDanglingUntriaged> browser_view_ = nullptr;
|
||||||
|
bool initialized_ = false;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // CEF_LIBCEF_BROWSER_VIEWS_NATIVE_WIDGET_MAC_H_
|
#endif // CEF_LIBCEF_BROWSER_VIEWS_NATIVE_WIDGET_MAC_H_
|
||||||
|
@ -138,7 +138,12 @@ void CefNativeWidgetMac::OnWindowFullscreenTransitionComplete() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void CefNativeWidgetMac::OnWindowInitialized() {
|
void CefNativeWidgetMac::OnWindowInitialized() {
|
||||||
if (!browser_view_) {
|
// This connects the native widget with the command dispatcher so accelerators
|
||||||
|
// work even if a browser_view_ is not created later.
|
||||||
|
// The initialized_ check is necessary because the method can be called twice:
|
||||||
|
// 1. From NativeWidgetMac::InitNativeWidget
|
||||||
|
// 2. From ChromeBrowserFrame::Init
|
||||||
|
if (initialized_) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -146,10 +151,12 @@ void CefNativeWidgetMac::OnWindowInitialized() {
|
|||||||
if (auto* bridge = GetInProcessNSWindowBridge()) {
|
if (auto* bridge = GetInProcessNSWindowBridge()) {
|
||||||
bridge->SetCommandDispatcher([[ChromeCommandDispatcherDelegate alloc] init],
|
bridge->SetCommandDispatcher([[ChromeCommandDispatcherDelegate alloc] init],
|
||||||
[[BrowserWindowCommandHandler alloc] init]);
|
[[BrowserWindowCommandHandler alloc] init]);
|
||||||
} else {
|
initialized_ = true;
|
||||||
|
} else if (browser_view_) {
|
||||||
if (auto* host = GetHostForBrowser(browser_view_->browser())) {
|
if (auto* host = GetHostForBrowser(browser_view_->browser())) {
|
||||||
host->GetAppShim()->CreateCommandDispatcherForWidget(
|
host->GetAppShim()->CreateCommandDispatcherForWidget(
|
||||||
GetNSWindowHost()->bridged_native_widget_id());
|
GetNSWindowHost()->bridged_native_widget_id());
|
||||||
|
initialized_ = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -280,18 +280,17 @@ void CefOverlayViewHost::SetOverlayBounds(const gfx::Rect& bounds) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
gfx::Rect new_bounds = bounds;
|
// Empty bounds are not allowed.
|
||||||
|
if (bounds.IsEmpty()) {
|
||||||
// Keep the result inside the widget.
|
|
||||||
new_bounds.Intersect(window_view_->bounds());
|
|
||||||
|
|
||||||
if (new_bounds == bounds_) {
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
bounds_changing_ = true;
|
bounds_changing_ = true;
|
||||||
|
bounds_ = bounds;
|
||||||
|
|
||||||
|
// Keep the result inside the widget.
|
||||||
|
bounds_.Intersect(window_view_->bounds());
|
||||||
|
|
||||||
bounds_ = new_bounds;
|
|
||||||
if (view_->size() != bounds_.size()) {
|
if (view_->size() != bounds_.size()) {
|
||||||
view_->SetSize(bounds_.size());
|
view_->SetSize(bounds_.size());
|
||||||
}
|
}
|
||||||
@ -313,6 +312,11 @@ void CefOverlayViewHost::OnViewBoundsChanged(views::View* observed_view) {
|
|||||||
MoveIfNecessary();
|
MoveIfNecessary();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CefOverlayViewHost::OnViewIsDeleting(views::View* observed_view) {
|
||||||
|
view_ = nullptr;
|
||||||
|
Cleanup();
|
||||||
|
}
|
||||||
|
|
||||||
gfx::Rect CefOverlayViewHost::ComputeBounds() const {
|
gfx::Rect CefOverlayViewHost::ComputeBounds() const {
|
||||||
// This method is only used with corner docking.
|
// This method is only used with corner docking.
|
||||||
DCHECK_NE(docking_mode_, CEF_DOCKING_MODE_CUSTOM);
|
DCHECK_NE(docking_mode_, CEF_DOCKING_MODE_CUSTOM);
|
||||||
|
@ -44,6 +44,7 @@ class CefOverlayViewHost : public views::WidgetDelegate,
|
|||||||
|
|
||||||
// views::ViewObserver methods:
|
// views::ViewObserver methods:
|
||||||
void OnViewBoundsChanged(views::View* observed_view) override;
|
void OnViewBoundsChanged(views::View* observed_view) override;
|
||||||
|
void OnViewIsDeleting(views::View* observed_view) override;
|
||||||
|
|
||||||
cef_docking_mode_t docking_mode() const { return docking_mode_; }
|
cef_docking_mode_t docking_mode() const { return docking_mode_; }
|
||||||
CefRefPtr<CefOverlayController> controller() const { return cef_controller_; }
|
CefRefPtr<CefOverlayController> controller() const { return cef_controller_; }
|
||||||
|
@ -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=434a753c90262b051077f7a79f3106ac52ffbf75$
|
// $hash=8a2a8a4853c3869876ffad3e6c175945ac1c5021$
|
||||||
//
|
//
|
||||||
|
|
||||||
#include "libcef_dll/cpptoc/browser_host_cpptoc.h"
|
#include "libcef_dll/cpptoc/browser_host_cpptoc.h"
|
||||||
@ -191,6 +191,24 @@ browser_host_try_close_browser(struct _cef_browser_host_t* self) {
|
|||||||
return _retval;
|
return _retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int CEF_CALLBACK
|
||||||
|
browser_host_is_ready_to_be_closed(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)->IsReadyToBeClosed();
|
||||||
|
|
||||||
|
// Return type: bool
|
||||||
|
return _retval;
|
||||||
|
}
|
||||||
|
|
||||||
void CEF_CALLBACK browser_host_set_focus(struct _cef_browser_host_t* self,
|
void CEF_CALLBACK browser_host_set_focus(struct _cef_browser_host_t* self,
|
||||||
int focus) {
|
int focus) {
|
||||||
shutdown_checker::AssertNotShutdown();
|
shutdown_checker::AssertNotShutdown();
|
||||||
@ -1514,6 +1532,7 @@ CefBrowserHostCppToC::CefBrowserHostCppToC() {
|
|||||||
GetStruct()->get_browser = browser_host_get_browser;
|
GetStruct()->get_browser = browser_host_get_browser;
|
||||||
GetStruct()->close_browser = browser_host_close_browser;
|
GetStruct()->close_browser = browser_host_close_browser;
|
||||||
GetStruct()->try_close_browser = browser_host_try_close_browser;
|
GetStruct()->try_close_browser = browser_host_try_close_browser;
|
||||||
|
GetStruct()->is_ready_to_be_closed = browser_host_is_ready_to_be_closed;
|
||||||
GetStruct()->set_focus = browser_host_set_focus;
|
GetStruct()->set_focus = browser_host_set_focus;
|
||||||
GetStruct()->get_window_handle = browser_host_get_window_handle;
|
GetStruct()->get_window_handle = browser_host_get_window_handle;
|
||||||
GetStruct()->get_opener_window_handle = browser_host_get_opener_window_handle;
|
GetStruct()->get_opener_window_handle = browser_host_get_opener_window_handle;
|
||||||
|
@ -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=dac19ba091b3acf3e1587b176e28bc9f9c8c8dd0$
|
// $hash=2319d794dd3a38c448908114d1b4ea37b34f89dd$
|
||||||
//
|
//
|
||||||
|
|
||||||
#include "libcef_dll/ctocpp/browser_host_ctocpp.h"
|
#include "libcef_dll/ctocpp/browser_host_ctocpp.h"
|
||||||
@ -131,6 +131,23 @@ NO_SANITIZE("cfi-icall") bool CefBrowserHostCToCpp::TryCloseBrowser() {
|
|||||||
return _retval ? true : false;
|
return _retval ? true : false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
NO_SANITIZE("cfi-icall") bool CefBrowserHostCToCpp::IsReadyToBeClosed() {
|
||||||
|
shutdown_checker::AssertNotShutdown();
|
||||||
|
|
||||||
|
cef_browser_host_t* _struct = GetStruct();
|
||||||
|
if (CEF_MEMBER_MISSING(_struct, is_ready_to_be_closed)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
|
||||||
|
|
||||||
|
// Execute
|
||||||
|
int _retval = _struct->is_ready_to_be_closed(_struct);
|
||||||
|
|
||||||
|
// Return type: bool
|
||||||
|
return _retval ? true : false;
|
||||||
|
}
|
||||||
|
|
||||||
NO_SANITIZE("cfi-icall") void CefBrowserHostCToCpp::SetFocus(bool focus) {
|
NO_SANITIZE("cfi-icall") void CefBrowserHostCToCpp::SetFocus(bool focus) {
|
||||||
shutdown_checker::AssertNotShutdown();
|
shutdown_checker::AssertNotShutdown();
|
||||||
|
|
||||||
@ -1111,8 +1128,8 @@ void CefBrowserHostCToCpp::DragSourceSystemDragEnded() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
NO_SANITIZE("cfi-icall")
|
NO_SANITIZE("cfi-icall")
|
||||||
CefRefPtr<
|
CefRefPtr<CefNavigationEntry>
|
||||||
CefNavigationEntry> CefBrowserHostCToCpp::GetVisibleNavigationEntry() {
|
CefBrowserHostCToCpp::GetVisibleNavigationEntry() {
|
||||||
shutdown_checker::AssertNotShutdown();
|
shutdown_checker::AssertNotShutdown();
|
||||||
|
|
||||||
cef_browser_host_t* _struct = GetStruct();
|
cef_browser_host_t* _struct = GetStruct();
|
||||||
|
@ -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=9f40e4ce3e46a895b5bf644bebdc2d802c9b598b$
|
// $hash=73d8659f17a4ae3319b5bf20807d5c69a1759c04$
|
||||||
//
|
//
|
||||||
|
|
||||||
#ifndef CEF_LIBCEF_DLL_CTOCPP_BROWSER_HOST_CTOCPP_H_
|
#ifndef CEF_LIBCEF_DLL_CTOCPP_BROWSER_HOST_CTOCPP_H_
|
||||||
@ -41,6 +41,7 @@ class CefBrowserHostCToCpp : public CefCToCppRefCounted<CefBrowserHostCToCpp,
|
|||||||
CefRefPtr<CefBrowser> GetBrowser() override;
|
CefRefPtr<CefBrowser> GetBrowser() override;
|
||||||
void CloseBrowser(bool force_close) override;
|
void CloseBrowser(bool force_close) override;
|
||||||
bool TryCloseBrowser() override;
|
bool TryCloseBrowser() override;
|
||||||
|
bool IsReadyToBeClosed() override;
|
||||||
void SetFocus(bool focus) override;
|
void SetFocus(bool focus) override;
|
||||||
CefWindowHandle GetWindowHandle() override;
|
CefWindowHandle GetWindowHandle() override;
|
||||||
CefWindowHandle GetOpenerWindowHandle() override;
|
CefWindowHandle GetOpenerWindowHandle() override;
|
||||||
|
@ -4,6 +4,7 @@
|
|||||||
|
|
||||||
#include "include/wrapper/cef_message_router.h"
|
#include "include/wrapper/cef_message_router.h"
|
||||||
|
|
||||||
|
#include <algorithm>
|
||||||
#include <limits>
|
#include <limits>
|
||||||
#include <map>
|
#include <map>
|
||||||
#include <set>
|
#include <set>
|
||||||
|
@ -4,8 +4,16 @@
|
|||||||
|
|
||||||
#include "tests/cefclient/browser/default_client_handler.h"
|
#include "tests/cefclient/browser/default_client_handler.h"
|
||||||
|
|
||||||
|
#include "tests/cefclient/browser/main_context.h"
|
||||||
|
#include "tests/cefclient/browser/root_window_manager.h"
|
||||||
|
|
||||||
namespace client {
|
namespace client {
|
||||||
|
|
||||||
|
DefaultClientHandler::DefaultClientHandler(std::optional<bool> use_alloy_style)
|
||||||
|
: use_alloy_style_(
|
||||||
|
use_alloy_style.value_or(MainContext::Get()->UseAlloyStyleGlobal())) {
|
||||||
|
}
|
||||||
|
|
||||||
// static
|
// static
|
||||||
CefRefPtr<DefaultClientHandler> DefaultClientHandler::GetForClient(
|
CefRefPtr<DefaultClientHandler> DefaultClientHandler::GetForClient(
|
||||||
CefRefPtr<CefClient> client) {
|
CefRefPtr<CefClient> client) {
|
||||||
@ -16,4 +24,39 @@ CefRefPtr<DefaultClientHandler> DefaultClientHandler::GetForClient(
|
|||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool DefaultClientHandler::OnBeforePopup(
|
||||||
|
CefRefPtr<CefBrowser> browser,
|
||||||
|
CefRefPtr<CefFrame> frame,
|
||||||
|
const CefString& target_url,
|
||||||
|
const CefString& target_frame_name,
|
||||||
|
CefLifeSpanHandler::WindowOpenDisposition target_disposition,
|
||||||
|
bool user_gesture,
|
||||||
|
const CefPopupFeatures& popupFeatures,
|
||||||
|
CefWindowInfo& windowInfo,
|
||||||
|
CefRefPtr<CefClient>& client,
|
||||||
|
CefBrowserSettings& settings,
|
||||||
|
CefRefPtr<CefDictionaryValue>& extra_info,
|
||||||
|
bool* no_javascript_access) {
|
||||||
|
CEF_REQUIRE_UI_THREAD();
|
||||||
|
|
||||||
|
if (target_disposition == CEF_WOD_NEW_PICTURE_IN_PICTURE) {
|
||||||
|
// Use default handling for document picture-in-picture popups.
|
||||||
|
client = nullptr;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Used to configure default values.
|
||||||
|
RootWindowConfig config(/*command_line=*/nullptr);
|
||||||
|
|
||||||
|
// Potentially create a new RootWindow for the popup browser that will be
|
||||||
|
// created asynchronously.
|
||||||
|
MainContext::Get()->GetRootWindowManager()->CreateRootWindowAsPopup(
|
||||||
|
config.use_views, use_alloy_style_, config.with_controls,
|
||||||
|
/*is_osr=*/false, /*is_devtools=*/false, popupFeatures, windowInfo,
|
||||||
|
client, settings);
|
||||||
|
|
||||||
|
// Allow popup creation.
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace client
|
} // namespace client
|
||||||
|
@ -6,6 +6,8 @@
|
|||||||
#define CEF_TESTS_CEFCLIENT_BROWSER_DEFAULT_CLIENT_HANDLER_H_
|
#define CEF_TESTS_CEFCLIENT_BROWSER_DEFAULT_CLIENT_HANDLER_H_
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include <optional>
|
||||||
|
|
||||||
#include "tests/cefclient/browser/base_client_handler.h"
|
#include "tests/cefclient/browser/base_client_handler.h"
|
||||||
|
|
||||||
namespace client {
|
namespace client {
|
||||||
@ -14,18 +16,37 @@ namespace client {
|
|||||||
// style only.
|
// style only.
|
||||||
class DefaultClientHandler : public BaseClientHandler {
|
class DefaultClientHandler : public BaseClientHandler {
|
||||||
public:
|
public:
|
||||||
DefaultClientHandler() = default;
|
// If |use_alloy_style| is nullopt the global default will be used.
|
||||||
|
explicit DefaultClientHandler(
|
||||||
|
std::optional<bool> use_alloy_style = std::nullopt);
|
||||||
|
|
||||||
// Returns the DefaultClientHandler for |client|, or nullptr if |client| is
|
// Returns the DefaultClientHandler for |client|, or nullptr if |client| is
|
||||||
// not a DefaultClientHandler.
|
// not a DefaultClientHandler.
|
||||||
static CefRefPtr<DefaultClientHandler> GetForClient(
|
static CefRefPtr<DefaultClientHandler> GetForClient(
|
||||||
CefRefPtr<CefClient> client);
|
CefRefPtr<CefClient> client);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
bool OnBeforePopup(
|
||||||
|
CefRefPtr<CefBrowser> browser,
|
||||||
|
CefRefPtr<CefFrame> frame,
|
||||||
|
const CefString& target_url,
|
||||||
|
const CefString& target_frame_name,
|
||||||
|
CefLifeSpanHandler::WindowOpenDisposition target_disposition,
|
||||||
|
bool user_gesture,
|
||||||
|
const CefPopupFeatures& popupFeatures,
|
||||||
|
CefWindowInfo& windowInfo,
|
||||||
|
CefRefPtr<CefClient>& client,
|
||||||
|
CefBrowserSettings& settings,
|
||||||
|
CefRefPtr<CefDictionaryValue>& extra_info,
|
||||||
|
bool* no_javascript_access) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// Used to determine the object type.
|
// Used to determine the object type.
|
||||||
virtual const void* GetTypeKey() const override { return &kTypeKey; }
|
virtual const void* GetTypeKey() const override { return &kTypeKey; }
|
||||||
static constexpr int kTypeKey = 0;
|
static constexpr int kTypeKey = 0;
|
||||||
|
|
||||||
|
const bool use_alloy_style_;
|
||||||
|
|
||||||
IMPLEMENT_REFCOUNTING(DefaultClientHandler);
|
IMPLEMENT_REFCOUNTING(DefaultClientHandler);
|
||||||
DISALLOW_COPY_AND_ASSIGN(DefaultClientHandler);
|
DISALLOW_COPY_AND_ASSIGN(DefaultClientHandler);
|
||||||
};
|
};
|
||||||
|
@ -21,6 +21,7 @@
|
|||||||
#define IDC_NAV_STOP 203
|
#define IDC_NAV_STOP 203
|
||||||
#define ID_QUIT 32500
|
#define ID_QUIT 32500
|
||||||
#define ID_FIND 32501
|
#define ID_FIND 32501
|
||||||
|
#define ID_POPOUT_OVERLAY 32502
|
||||||
#define ID_TESTS_FIRST 32700
|
#define ID_TESTS_FIRST 32700
|
||||||
#define ID_TESTS_GETSOURCE 32700
|
#define ID_TESTS_GETSOURCE 32700
|
||||||
#define ID_TESTS_GETTEXT 32701
|
#define ID_TESTS_GETTEXT 32701
|
||||||
|
@ -134,8 +134,11 @@ scoped_refptr<RootWindow> RootWindowManager::CreateRootWindowAsPopup(
|
|||||||
|
|
||||||
if (MainContext::Get()->UseDefaultPopup() || (is_devtools && !use_views)) {
|
if (MainContext::Get()->UseDefaultPopup() || (is_devtools && !use_views)) {
|
||||||
// Use default window creation for the popup. A new |client| instance is
|
// Use default window creation for the popup. A new |client| instance is
|
||||||
// still required by cefclient architecture.
|
// required by cefclient architecture if the type is not already
|
||||||
client = new DefaultClientHandler();
|
// DefaultClientHandler.
|
||||||
|
if (!DefaultClientHandler::GetForClient(client)) {
|
||||||
|
client = new DefaultClientHandler(use_alloy_style);
|
||||||
|
}
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
315
tests/cefclient/browser/views_overlay_browser.cc
Normal file
315
tests/cefclient/browser/views_overlay_browser.cc
Normal file
@ -0,0 +1,315 @@
|
|||||||
|
// Copyright (c) 2024 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.
|
||||||
|
|
||||||
|
#include "tests/cefclient/browser/views_overlay_browser.h"
|
||||||
|
|
||||||
|
#include "include/views/cef_window.h"
|
||||||
|
#include "tests/cefclient/browser/resource.h"
|
||||||
|
#include "tests/cefclient/browser/views_window.h"
|
||||||
|
|
||||||
|
namespace client {
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
|
||||||
|
void AddPopOutAccelerator(CefRefPtr<CefWindow> window) {
|
||||||
|
// Add an accelerator to toggle the BrowserView popout. OnAccelerator will be
|
||||||
|
// called when the accelerator is triggered.
|
||||||
|
window->SetAccelerator(ID_POPOUT_OVERLAY, 'O', /*shift_pressed=*/false,
|
||||||
|
/*ctrl_pressed=*/false, /*alt_pressed=*/true,
|
||||||
|
/*high_priority=*/true);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Popout window delegate implementation.
|
||||||
|
class PopoutWindowDelegate : public CefWindowDelegate {
|
||||||
|
public:
|
||||||
|
PopoutWindowDelegate(base::WeakPtr<ViewsOverlayBrowser> overlay,
|
||||||
|
CefRefPtr<CefBrowserView> browser_view)
|
||||||
|
: overlay_(overlay), browser_view_(browser_view) {}
|
||||||
|
|
||||||
|
PopoutWindowDelegate(const PopoutWindowDelegate&) = delete;
|
||||||
|
PopoutWindowDelegate& operator=(const PopoutWindowDelegate&) = delete;
|
||||||
|
|
||||||
|
static PopoutWindowDelegate* GetForWindow(CefRefPtr<CefWindow> window) {
|
||||||
|
return static_cast<PopoutWindowDelegate*>(window->GetDelegate().get());
|
||||||
|
}
|
||||||
|
|
||||||
|
void OnWindowCreated(CefRefPtr<CefWindow> window) override {
|
||||||
|
window->AddChildView(browser_view_);
|
||||||
|
window->Show();
|
||||||
|
|
||||||
|
// Add the popout accelerator to the popout Window.
|
||||||
|
AddPopOutAccelerator(window);
|
||||||
|
|
||||||
|
browser_view_->RequestFocus();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CanClose(CefRefPtr<CefWindow> window) override {
|
||||||
|
CefRefPtr<CefBrowser> browser =
|
||||||
|
browser_view_ ? browser_view_->GetBrowser() : nullptr;
|
||||||
|
|
||||||
|
if (overlay_ && browser && !browser->GetHost()->IsReadyToBeClosed()) {
|
||||||
|
// Proceed with the window close, but don't close the browser. The browser
|
||||||
|
// will be returned to the overlay in OnWindowClosing().
|
||||||
|
return_to_overlay_ = true;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (browser) {
|
||||||
|
// We must close the browser, either because the popout Window is the
|
||||||
|
// final owner of the BrowserView, or because the browser is ready to be
|
||||||
|
// closed internally (e.g. `window.close()` was called).
|
||||||
|
return browser->GetHost()->TryCloseBrowser();
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void OnWindowClosing(CefRefPtr<CefWindow> window) override {
|
||||||
|
if (overlay_ && return_to_overlay_) {
|
||||||
|
// Give the browser back to the overlay.
|
||||||
|
overlay_->ToggleBrowserView();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void OnWindowDestroyed(CefRefPtr<CefWindow> window) override {
|
||||||
|
if (overlay_) {
|
||||||
|
overlay_->PopOutWindowDestroyed();
|
||||||
|
overlay_ = nullptr;
|
||||||
|
}
|
||||||
|
browser_view_ = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
cef_runtime_style_t GetWindowRuntimeStyle() override {
|
||||||
|
return browser_view_->GetRuntimeStyle();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool OnAccelerator(CefRefPtr<CefWindow> window, int command_id) override {
|
||||||
|
if (overlay_) {
|
||||||
|
return overlay_->OnAccelerator(window, command_id);
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
[[nodiscard]] CefRefPtr<CefBrowserView> DetachBrowserView() {
|
||||||
|
overlay_ = nullptr;
|
||||||
|
auto browser_view = browser_view_;
|
||||||
|
browser_view_ = nullptr;
|
||||||
|
return browser_view;
|
||||||
|
}
|
||||||
|
|
||||||
|
void OverlayDestroyed() { overlay_ = nullptr; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
base::WeakPtr<ViewsOverlayBrowser> overlay_;
|
||||||
|
CefRefPtr<CefBrowserView> browser_view_;
|
||||||
|
bool return_to_overlay_ = false;
|
||||||
|
|
||||||
|
IMPLEMENT_REFCOUNTING(PopoutWindowDelegate);
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace
|
||||||
|
|
||||||
|
ViewsOverlayBrowser::ViewsOverlayBrowser(ViewsWindow* owner_window)
|
||||||
|
: owner_window_(owner_window) {}
|
||||||
|
|
||||||
|
void ViewsOverlayBrowser::Initialize(
|
||||||
|
CefRefPtr<CefWindow> window,
|
||||||
|
CefRefPtr<CefClient> client,
|
||||||
|
const std::string& url,
|
||||||
|
const CefBrowserSettings& settings,
|
||||||
|
CefRefPtr<CefRequestContext> request_context) {
|
||||||
|
CHECK(!window_);
|
||||||
|
window_ = window;
|
||||||
|
CHECK(window_);
|
||||||
|
|
||||||
|
// Add the accelerator to the main window.
|
||||||
|
AddPopOutAccelerator(window_);
|
||||||
|
|
||||||
|
browser_view_ = CefBrowserView::CreateBrowserView(
|
||||||
|
client, url, settings, nullptr, request_context, this);
|
||||||
|
CHECK(browser_view_);
|
||||||
|
|
||||||
|
// Add the BrowserView to an overlay in the main window.
|
||||||
|
controller_ = window_->AddOverlayView(browser_view_, CEF_DOCKING_MODE_CUSTOM,
|
||||||
|
/*can_activate=*/true);
|
||||||
|
CHECK(controller_);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ViewsOverlayBrowser::Destroy() {
|
||||||
|
window_ = nullptr;
|
||||||
|
|
||||||
|
if (popout_window_) {
|
||||||
|
// The BrowserView is popped out, and the main Window is closed first.
|
||||||
|
// Let the popout Window handle BrowserView destruction.
|
||||||
|
PopoutWindowDelegate::GetForWindow(popout_window_)->OverlayDestroyed();
|
||||||
|
popout_window_->Close();
|
||||||
|
popout_window_ = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (controller_) {
|
||||||
|
if (controller_->IsValid()) {
|
||||||
|
controller_->Destroy();
|
||||||
|
}
|
||||||
|
controller_ = nullptr;
|
||||||
|
owner_window_->UpdateDraggableRegions();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (browser_view_) {
|
||||||
|
// We hold the last reference to the BrowserView, and releasing it will
|
||||||
|
// trigger overlay Browser destruction. OnBeforeClose for that Browser may
|
||||||
|
// be called synchronously or asynchronously depending on whether
|
||||||
|
// beforeunload needs to be dispatched.
|
||||||
|
DCHECK(browser_view_->HasOneRef());
|
||||||
|
browser_view_ = nullptr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ViewsOverlayBrowser::IsValid() const {
|
||||||
|
// Intentionally not checking |popout_window_->IsValid()| here because the
|
||||||
|
// pop-in behavior will be triggered by |popout_window_| closing.
|
||||||
|
return (controller_ && controller_->IsValid()) || popout_window_;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ViewsOverlayBrowser::ToggleBrowserView() {
|
||||||
|
if (browser_view_) {
|
||||||
|
PopOutBrowserView();
|
||||||
|
} else {
|
||||||
|
PopInBrowserView();
|
||||||
|
}
|
||||||
|
|
||||||
|
owner_window_->UpdateDraggableRegions();
|
||||||
|
}
|
||||||
|
|
||||||
|
void ViewsOverlayBrowser::PopOutBrowserView() {
|
||||||
|
CHECK(browser_view_);
|
||||||
|
|
||||||
|
DCHECK(controller_ && controller_->IsValid());
|
||||||
|
controller_->Destroy();
|
||||||
|
controller_ = nullptr;
|
||||||
|
|
||||||
|
// We hold the only reference to the BrowserView.
|
||||||
|
DCHECK(browser_view_->HasOneRef());
|
||||||
|
|
||||||
|
// Create a new popout Window and pass ownership of the BrowserView.
|
||||||
|
CHECK(!popout_window_);
|
||||||
|
popout_window_ = CefWindow::CreateTopLevelWindow(
|
||||||
|
new PopoutWindowDelegate(weak_ptr_factory_.GetWeakPtr(), browser_view_));
|
||||||
|
browser_view_ = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ViewsOverlayBrowser::PopInBrowserView() {
|
||||||
|
CHECK(!browser_view_);
|
||||||
|
|
||||||
|
// Resume ownership of the BrowserView and close the popout Window.
|
||||||
|
CHECK(popout_window_);
|
||||||
|
browser_view_ =
|
||||||
|
PopoutWindowDelegate::GetForWindow(popout_window_)->DetachBrowserView();
|
||||||
|
popout_window_->RemoveChildView(browser_view_);
|
||||||
|
popout_window_->Close();
|
||||||
|
popout_window_ = nullptr;
|
||||||
|
|
||||||
|
// We hold the only reference to the BrowserView.
|
||||||
|
DCHECK(browser_view_->HasOneRef());
|
||||||
|
|
||||||
|
// Add the BrowserView to an overlay in the main window.
|
||||||
|
controller_ = window_->AddOverlayView(browser_view_, CEF_DOCKING_MODE_CUSTOM,
|
||||||
|
/*can_activate=*/true);
|
||||||
|
CHECK(controller_);
|
||||||
|
|
||||||
|
// Make sure the overlay is positioned correctly.
|
||||||
|
UpdateBounds(last_insets_);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ViewsOverlayBrowser::UpdateBounds(CefInsets insets) {
|
||||||
|
last_insets_ = insets;
|
||||||
|
|
||||||
|
if (!controller_) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Update location bar size, position and visibility.
|
||||||
|
const auto window_bounds = window_->GetBounds();
|
||||||
|
|
||||||
|
// Client coordinates with insets.
|
||||||
|
CefRect bounds;
|
||||||
|
bounds.x = insets.left;
|
||||||
|
bounds.width = window_bounds.width - insets.left - insets.right;
|
||||||
|
bounds.y = insets.top;
|
||||||
|
bounds.height = window_bounds.height - insets.top - insets.bottom;
|
||||||
|
|
||||||
|
const auto min_size = browser_view_->GetMinimumSize();
|
||||||
|
if (bounds.width < min_size.width || bounds.height < min_size.height) {
|
||||||
|
// Not enough space.
|
||||||
|
controller_->SetVisible(false);
|
||||||
|
} else {
|
||||||
|
controller_->SetSize(CefSize(bounds.width, bounds.height));
|
||||||
|
controller_->SetBounds(bounds);
|
||||||
|
controller_->SetVisible(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ViewsOverlayBrowser::UpdateDraggableRegions(
|
||||||
|
std::vector<CefDraggableRegion>& window_regions) {
|
||||||
|
if (controller_ && controller_->IsVisible()) {
|
||||||
|
window_regions.emplace_back(controller_->GetBounds(),
|
||||||
|
/*draggable=*/false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ViewsOverlayBrowser::OnAccelerator(CefRefPtr<CefWindow> window,
|
||||||
|
int command_id) {
|
||||||
|
if (IsValid() && command_id == ID_POPOUT_OVERLAY) {
|
||||||
|
ToggleBrowserView();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ViewsOverlayBrowser::PopOutWindowDestroyed() {
|
||||||
|
popout_window_ = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
CefSize ViewsOverlayBrowser::GetMinimumSize(CefRefPtr<CefView> view) {
|
||||||
|
return CefSize(200, 200);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ViewsOverlayBrowser::OnBrowserDestroyed(
|
||||||
|
CefRefPtr<CefBrowserView> browser_view,
|
||||||
|
CefRefPtr<CefBrowser> browser) {
|
||||||
|
// Might be popped out currently.
|
||||||
|
if (!controller_) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Destroy the overlay controller if the browser is destroyed first (e.g. via
|
||||||
|
// `window.close()`).
|
||||||
|
controller_->Destroy();
|
||||||
|
controller_ = nullptr;
|
||||||
|
owner_window_->UpdateDraggableRegions();
|
||||||
|
}
|
||||||
|
|
||||||
|
CefRefPtr<CefBrowserViewDelegate>
|
||||||
|
ViewsOverlayBrowser::GetDelegateForPopupBrowserView(
|
||||||
|
CefRefPtr<CefBrowserView> browser_view,
|
||||||
|
const CefBrowserSettings& settings,
|
||||||
|
CefRefPtr<CefClient> client,
|
||||||
|
bool is_devtools) {
|
||||||
|
return owner_window_->GetDelegateForPopupBrowserView(browser_view, settings,
|
||||||
|
client, is_devtools);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ViewsOverlayBrowser::OnPopupBrowserViewCreated(
|
||||||
|
CefRefPtr<CefBrowserView> browser_view,
|
||||||
|
CefRefPtr<CefBrowserView> popup_browser_view,
|
||||||
|
bool is_devtools) {
|
||||||
|
return owner_window_->OnPopupBrowserViewCreated(
|
||||||
|
browser_view, popup_browser_view, is_devtools);
|
||||||
|
}
|
||||||
|
|
||||||
|
cef_runtime_style_t ViewsOverlayBrowser::GetBrowserRuntimeStyle() {
|
||||||
|
// Overlay browser view must always be Alloy style.
|
||||||
|
return CEF_RUNTIME_STYLE_ALLOY;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace client
|
86
tests/cefclient/browser/views_overlay_browser.h
Normal file
86
tests/cefclient/browser/views_overlay_browser.h
Normal file
@ -0,0 +1,86 @@
|
|||||||
|
// Copyright (c) 2024 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.
|
||||||
|
|
||||||
|
#ifndef CEF_TESTS_CEFCLIENT_BROWSER_VIEWS_OVERLAY_BROWSER_H_
|
||||||
|
#define CEF_TESTS_CEFCLIENT_BROWSER_VIEWS_OVERLAY_BROWSER_H_
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "include/base/cef_weak_ptr.h"
|
||||||
|
#include "include/views/cef_browser_view.h"
|
||||||
|
#include "include/views/cef_browser_view_delegate.h"
|
||||||
|
#include "include/views/cef_overlay_controller.h"
|
||||||
|
|
||||||
|
namespace client {
|
||||||
|
|
||||||
|
class ViewsWindow;
|
||||||
|
|
||||||
|
// Implements a browser view that receives absolute positioning on top of the
|
||||||
|
// main browser view. All methods must be called on the browser process UI
|
||||||
|
// thread.
|
||||||
|
class ViewsOverlayBrowser : public CefBrowserViewDelegate {
|
||||||
|
public:
|
||||||
|
explicit ViewsOverlayBrowser(ViewsWindow* owner_window);
|
||||||
|
|
||||||
|
void Initialize(CefRefPtr<CefWindow> window,
|
||||||
|
CefRefPtr<CefClient> client,
|
||||||
|
const std::string& url,
|
||||||
|
const CefBrowserSettings& settings,
|
||||||
|
CefRefPtr<CefRequestContext> request_context);
|
||||||
|
void Destroy();
|
||||||
|
|
||||||
|
bool IsValid() const;
|
||||||
|
|
||||||
|
// Move the overlay BrowserView to/from a popout Window.
|
||||||
|
void ToggleBrowserView();
|
||||||
|
|
||||||
|
// Update browser bounds.
|
||||||
|
void UpdateBounds(CefInsets insets);
|
||||||
|
|
||||||
|
// Exclude all regions obscured by overlays.
|
||||||
|
void UpdateDraggableRegions(std::vector<CefDraggableRegion>& window_regions);
|
||||||
|
|
||||||
|
bool OnAccelerator(CefRefPtr<CefWindow> window, int command_id);
|
||||||
|
|
||||||
|
void PopOutWindowDestroyed();
|
||||||
|
|
||||||
|
private:
|
||||||
|
// CefViewDelegate methods:
|
||||||
|
CefSize GetMinimumSize(CefRefPtr<CefView> view) override;
|
||||||
|
|
||||||
|
// CefBrowserViewDelegate methods:
|
||||||
|
void OnBrowserDestroyed(CefRefPtr<CefBrowserView> browser_view,
|
||||||
|
CefRefPtr<CefBrowser> browser) override;
|
||||||
|
CefRefPtr<CefBrowserViewDelegate> GetDelegateForPopupBrowserView(
|
||||||
|
CefRefPtr<CefBrowserView> browser_view,
|
||||||
|
const CefBrowserSettings& settings,
|
||||||
|
CefRefPtr<CefClient> client,
|
||||||
|
bool is_devtools) override;
|
||||||
|
bool OnPopupBrowserViewCreated(CefRefPtr<CefBrowserView> browser_view,
|
||||||
|
CefRefPtr<CefBrowserView> popup_browser_view,
|
||||||
|
bool is_devtools) override;
|
||||||
|
cef_runtime_style_t GetBrowserRuntimeStyle() override;
|
||||||
|
|
||||||
|
// Move the BrowserView to a new top-level Window.
|
||||||
|
void PopOutBrowserView();
|
||||||
|
|
||||||
|
// Return the BrowserView to the overlay.
|
||||||
|
void PopInBrowserView();
|
||||||
|
|
||||||
|
ViewsWindow* const owner_window_;
|
||||||
|
CefRefPtr<CefWindow> window_;
|
||||||
|
CefRefPtr<CefBrowserView> browser_view_;
|
||||||
|
CefRefPtr<CefOverlayController> controller_;
|
||||||
|
CefInsets last_insets_;
|
||||||
|
|
||||||
|
CefRefPtr<CefWindow> popout_window_;
|
||||||
|
|
||||||
|
base::WeakPtrFactory<ViewsOverlayBrowser> weak_ptr_factory_{this};
|
||||||
|
|
||||||
|
IMPLEMENT_REFCOUNTING(ViewsOverlayBrowser);
|
||||||
|
DISALLOW_COPY_AND_ASSIGN(ViewsOverlayBrowser);
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace client
|
||||||
|
|
||||||
|
#endif // CEF_TESTS_CEFCLIENT_BROWSER_VIEWS_OVERLAY_BROWSER_H_
|
@ -12,6 +12,7 @@
|
|||||||
#include "include/cef_i18n_util.h"
|
#include "include/cef_i18n_util.h"
|
||||||
#include "include/views/cef_box_layout.h"
|
#include "include/views/cef_box_layout.h"
|
||||||
#include "include/wrapper/cef_helpers.h"
|
#include "include/wrapper/cef_helpers.h"
|
||||||
|
#include "tests/cefclient/browser/default_client_handler.h"
|
||||||
#include "tests/cefclient/browser/main_context.h"
|
#include "tests/cefclient/browser/main_context.h"
|
||||||
#include "tests/cefclient/browser/resource.h"
|
#include "tests/cefclient/browser/resource.h"
|
||||||
#include "tests/cefclient/browser/views_style.h"
|
#include "tests/cefclient/browser/views_style.h"
|
||||||
@ -146,6 +147,14 @@ CefRefPtr<ViewsWindow> ViewsWindow::Create(
|
|||||||
CefRefPtr<ViewsWindow> views_window =
|
CefRefPtr<ViewsWindow> views_window =
|
||||||
new ViewsWindow(type, delegate, nullptr, command_line);
|
new ViewsWindow(type, delegate, nullptr, command_line);
|
||||||
|
|
||||||
|
// Only create an overlay browser for a primary window.
|
||||||
|
if (command_line->HasSwitch(switches::kShowOverlayBrowser)) {
|
||||||
|
views_window->with_overlay_browser_ = true;
|
||||||
|
views_window->initial_url_ = url;
|
||||||
|
views_window->settings_ = settings;
|
||||||
|
views_window->request_context_ = request_context;
|
||||||
|
}
|
||||||
|
|
||||||
const auto expected_browser_runtime_style = views_window->use_alloy_style_
|
const auto expected_browser_runtime_style = views_window->use_alloy_style_
|
||||||
? CEF_RUNTIME_STYLE_ALLOY
|
? CEF_RUNTIME_STYLE_ALLOY
|
||||||
: CEF_RUNTIME_STYLE_CHROME;
|
: CEF_RUNTIME_STYLE_CHROME;
|
||||||
@ -345,6 +354,8 @@ void ViewsWindow::SetDraggableRegions(
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
last_regions_ = regions;
|
||||||
|
|
||||||
// Convert the regions from BrowserView to Window coordinates.
|
// Convert the regions from BrowserView to Window coordinates.
|
||||||
std::vector<CefDraggableRegion> window_regions = regions;
|
std::vector<CefDraggableRegion> window_regions = regions;
|
||||||
for (auto& region : window_regions) {
|
for (auto& region : window_regions) {
|
||||||
@ -359,6 +370,11 @@ void ViewsWindow::SetDraggableRegions(
|
|||||||
overlay_controls_->UpdateDraggableRegions(window_regions);
|
overlay_controls_->UpdateDraggableRegions(window_regions);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (overlay_browser_) {
|
||||||
|
// Exclude all regions obscured by overlays.
|
||||||
|
overlay_browser_->UpdateDraggableRegions(window_regions);
|
||||||
|
}
|
||||||
|
|
||||||
window_->SetDraggableRegions(window_regions);
|
window_->SetDraggableRegions(window_regions);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -434,6 +450,10 @@ void ViewsWindow::SetTitlebarHeight(const std::optional<float>& height) {
|
|||||||
NudgeWindow();
|
NudgeWindow();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ViewsWindow::UpdateDraggableRegions() {
|
||||||
|
SetDraggableRegions(last_regions_);
|
||||||
|
}
|
||||||
|
|
||||||
CefRefPtr<CefBrowserViewDelegate> ViewsWindow::GetDelegateForPopupBrowserView(
|
CefRefPtr<CefBrowserViewDelegate> ViewsWindow::GetDelegateForPopupBrowserView(
|
||||||
CefRefPtr<CefBrowserView> browser_view,
|
CefRefPtr<CefBrowserView> browser_view,
|
||||||
const CefBrowserSettings& settings,
|
const CefBrowserSettings& settings,
|
||||||
@ -900,6 +920,8 @@ bool ViewsWindow::OnAccelerator(CefRefPtr<CefWindow> window, int command_id) {
|
|||||||
if (command_id == ID_QUIT) {
|
if (command_id == ID_QUIT) {
|
||||||
delegate_->OnExit();
|
delegate_->OnExit();
|
||||||
return true;
|
return true;
|
||||||
|
} else if (overlay_browser_) {
|
||||||
|
return overlay_browser_->OnAccelerator(window, command_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
@ -1001,6 +1023,19 @@ void ViewsWindow::OnWindowChanged(CefRefPtr<CefView> view, bool added) {
|
|||||||
CreateLocationBar(),
|
CreateLocationBar(),
|
||||||
chrome_toolbar_type_ != CEF_CTT_NONE);
|
chrome_toolbar_type_ != CEF_CTT_NONE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (with_overlay_browser_) {
|
||||||
|
overlay_browser_ = new ViewsOverlayBrowser(this);
|
||||||
|
|
||||||
|
// Use default behavior for the overlay browser. A new |client| instance
|
||||||
|
// is still required by cefclient architecture.
|
||||||
|
CefRefPtr<CefClient> client =
|
||||||
|
new DefaultClientHandler(/*use_alloy_style=*/true);
|
||||||
|
|
||||||
|
overlay_browser_->Initialize(window_, client, initial_url_, settings_,
|
||||||
|
request_context_);
|
||||||
|
request_context_ = nullptr;
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
// Remove any controls that may include the Chrome toolbar before removing
|
// Remove any controls that may include the Chrome toolbar before removing
|
||||||
// the BrowserView.
|
// the BrowserView.
|
||||||
@ -1015,6 +1050,10 @@ void ViewsWindow::OnWindowChanged(CefRefPtr<CefView> view, bool added) {
|
|||||||
location_bar_ = nullptr;
|
location_bar_ = nullptr;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (overlay_browser_) {
|
||||||
|
overlay_browser_->Destroy();
|
||||||
|
overlay_browser_ = nullptr;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1028,6 +1067,12 @@ void ViewsWindow::OnLayoutChanged(CefRefPtr<CefView> view,
|
|||||||
if (overlay_controls_) {
|
if (overlay_controls_) {
|
||||||
overlay_controls_->UpdateControls();
|
overlay_controls_->UpdateControls();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (overlay_browser_) {
|
||||||
|
// TODO: Consider modifying insets based on toolbar visibility.
|
||||||
|
CefInsets window_insets(200, 200, 200, 200);
|
||||||
|
overlay_browser_->UpdateBounds(window_insets);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ViewsWindow::OnThemeChanged(CefRefPtr<CefView> view) {
|
void ViewsWindow::OnThemeChanged(CefRefPtr<CefView> view) {
|
||||||
@ -1064,9 +1109,9 @@ ViewsWindow::ViewsWindow(WindowType type,
|
|||||||
with_controls_ = is_normal_type && delegate_->WithControls();
|
with_controls_ = is_normal_type && delegate_->WithControls();
|
||||||
|
|
||||||
const bool hide_frame = command_line->HasSwitch(switches::kHideFrame);
|
const bool hide_frame = command_line->HasSwitch(switches::kHideFrame);
|
||||||
const bool hide_overlays =
|
const bool show_overlays = is_normal_type && hide_frame && !with_controls_ &&
|
||||||
!is_normal_type || command_line->HasSwitch(switches::kHideOverlays);
|
!command_line->HasSwitch(switches::kHideOverlays);
|
||||||
const bool hide_toolbar = hide_overlays && !with_controls_;
|
const bool hide_toolbar = !show_overlays && !with_controls_;
|
||||||
const bool show_window_buttons =
|
const bool show_window_buttons =
|
||||||
command_line->HasSwitch(switches::kShowWindowButtons);
|
command_line->HasSwitch(switches::kShowWindowButtons);
|
||||||
accepts_first_mouse_ = command_line->HasSwitch(switches::kAcceptsFirstMouse);
|
accepts_first_mouse_ = command_line->HasSwitch(switches::kAcceptsFirstMouse);
|
||||||
@ -1075,7 +1120,7 @@ ViewsWindow::ViewsWindow(WindowType type,
|
|||||||
frameless_ = hide_frame;
|
frameless_ = hide_frame;
|
||||||
|
|
||||||
// With an overlay that mimics window controls.
|
// With an overlay that mimics window controls.
|
||||||
with_overlay_controls_ = hide_frame && !hide_overlays && !with_controls_;
|
with_overlay_controls_ = show_overlays;
|
||||||
|
|
||||||
// If window has frame or flag passed explicitly
|
// If window has frame or flag passed explicitly
|
||||||
with_standard_buttons_ = !frameless_ || show_window_buttons;
|
with_standard_buttons_ = !frameless_ || show_window_buttons;
|
||||||
@ -1313,12 +1358,12 @@ void ViewsWindow::SetMenuFocusable(bool focusable) {
|
|||||||
|
|
||||||
if (menu_bar_) {
|
if (menu_bar_) {
|
||||||
menu_bar_->SetMenuFocusable(focusable);
|
menu_bar_->SetMenuFocusable(focusable);
|
||||||
} else {
|
} else if (menu_button_) {
|
||||||
window_->GetViewForID(ID_MENU_BUTTON)->SetFocusable(focusable);
|
menu_button_->SetFocusable(focusable);
|
||||||
|
|
||||||
if (focusable) {
|
if (focusable) {
|
||||||
// Give focus to menu button.
|
// Give focus to menu button.
|
||||||
window_->GetViewForID(ID_MENU_BUTTON)->RequestFocus();
|
menu_button_->RequestFocus();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -27,6 +27,7 @@
|
|||||||
#include "tests/cefclient/browser/image_cache.h"
|
#include "tests/cefclient/browser/image_cache.h"
|
||||||
#include "tests/cefclient/browser/root_window.h"
|
#include "tests/cefclient/browser/root_window.h"
|
||||||
#include "tests/cefclient/browser/views_menu_bar.h"
|
#include "tests/cefclient/browser/views_menu_bar.h"
|
||||||
|
#include "tests/cefclient/browser/views_overlay_browser.h"
|
||||||
#include "tests/cefclient/browser/views_overlay_controls.h"
|
#include "tests/cefclient/browser/views_overlay_controls.h"
|
||||||
|
|
||||||
namespace client {
|
namespace client {
|
||||||
@ -128,6 +129,8 @@ class ViewsWindow : public CefBrowserViewDelegate,
|
|||||||
std::optional<CefRect>& dip_bounds);
|
std::optional<CefRect>& dip_bounds);
|
||||||
void SetTitlebarHeight(const std::optional<float>& height);
|
void SetTitlebarHeight(const std::optional<float>& height);
|
||||||
|
|
||||||
|
void UpdateDraggableRegions();
|
||||||
|
|
||||||
// CefBrowserViewDelegate methods:
|
// CefBrowserViewDelegate methods:
|
||||||
CefRefPtr<CefBrowserViewDelegate> GetDelegateForPopupBrowserView(
|
CefRefPtr<CefBrowserViewDelegate> GetDelegateForPopupBrowserView(
|
||||||
CefRefPtr<CefBrowserView> browser_view,
|
CefRefPtr<CefBrowserView> browser_view,
|
||||||
@ -251,7 +254,7 @@ class ViewsWindow : public CefBrowserViewDelegate,
|
|||||||
void NudgeWindow();
|
void NudgeWindow();
|
||||||
|
|
||||||
const WindowType type_;
|
const WindowType type_;
|
||||||
Delegate* delegate_; // Not owned by this object.
|
Delegate* const delegate_; // Not owned by this object.
|
||||||
const bool use_alloy_style_;
|
const bool use_alloy_style_;
|
||||||
bool use_alloy_style_window_;
|
bool use_alloy_style_window_;
|
||||||
CefRefPtr<CefBrowserView> browser_view_;
|
CefRefPtr<CefBrowserView> browser_view_;
|
||||||
@ -280,6 +283,13 @@ class ViewsWindow : public CefBrowserViewDelegate,
|
|||||||
|
|
||||||
CefRefPtr<ViewsOverlayControls> overlay_controls_;
|
CefRefPtr<ViewsOverlayControls> overlay_controls_;
|
||||||
|
|
||||||
|
// Overlay browser view state.
|
||||||
|
bool with_overlay_browser_ = false;
|
||||||
|
std::string initial_url_;
|
||||||
|
CefBrowserSettings settings_;
|
||||||
|
CefRefPtr<CefRequestContext> request_context_;
|
||||||
|
CefRefPtr<ViewsOverlayBrowser> overlay_browser_;
|
||||||
|
|
||||||
std::optional<float> default_titlebar_height_;
|
std::optional<float> default_titlebar_height_;
|
||||||
std::optional<float> override_titlebar_height_;
|
std::optional<float> override_titlebar_height_;
|
||||||
|
|
||||||
@ -293,6 +303,8 @@ class ViewsWindow : public CefBrowserViewDelegate,
|
|||||||
bool can_go_back_ = false;
|
bool can_go_back_ = false;
|
||||||
bool can_go_forward_ = false;
|
bool can_go_forward_ = false;
|
||||||
|
|
||||||
|
std::vector<CefDraggableRegion> last_regions_;
|
||||||
|
|
||||||
IMPLEMENT_REFCOUNTING(ViewsWindow);
|
IMPLEMENT_REFCOUNTING(ViewsWindow);
|
||||||
DISALLOW_COPY_AND_ASSIGN(ViewsWindow);
|
DISALLOW_COPY_AND_ASSIGN(ViewsWindow);
|
||||||
};
|
};
|
||||||
|
@ -6,6 +6,7 @@
|
|||||||
#include "include/test/cef_test_helpers.h"
|
#include "include/test/cef_test_helpers.h"
|
||||||
#include "include/wrapper/cef_closure_task.h"
|
#include "include/wrapper/cef_closure_task.h"
|
||||||
#include "tests/ceftests/routing_test_handler.h"
|
#include "tests/ceftests/routing_test_handler.h"
|
||||||
|
#include "tests/ceftests/test_util.h"
|
||||||
#include "tests/gtest/include/gtest/gtest.h"
|
#include "tests/gtest/include/gtest/gtest.h"
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
@ -58,6 +59,8 @@ class LifeSpanTestHandler : public RoutingTestHandler {
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool DoClose(CefRefPtr<CefBrowser> browser) override {
|
bool DoClose(CefRefPtr<CefBrowser> browser) override {
|
||||||
|
EXPECT_TRUE(browser->GetHost()->IsReadyToBeClosed());
|
||||||
|
|
||||||
if (executing_delay_close_) {
|
if (executing_delay_close_) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -75,6 +78,8 @@ class LifeSpanTestHandler : public RoutingTestHandler {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void OnBeforeClose(CefRefPtr<CefBrowser> browser) override {
|
void OnBeforeClose(CefRefPtr<CefBrowser> browser) override {
|
||||||
|
EXPECT_TRUE(browser->GetHost()->IsReadyToBeClosed());
|
||||||
|
|
||||||
if (!executing_delay_close_) {
|
if (!executing_delay_close_) {
|
||||||
got_before_close_.yes();
|
got_before_close_.yes();
|
||||||
EXPECT_TRUE(browser->IsSame(GetBrowser()));
|
EXPECT_TRUE(browser->IsSame(GetBrowser()));
|
||||||
@ -87,6 +92,8 @@ class LifeSpanTestHandler : public RoutingTestHandler {
|
|||||||
const CefString& message_text,
|
const CefString& message_text,
|
||||||
bool is_reload,
|
bool is_reload,
|
||||||
CefRefPtr<CefJSDialogCallback> callback) override {
|
CefRefPtr<CefJSDialogCallback> callback) override {
|
||||||
|
EXPECT_FALSE(browser->GetHost()->IsReadyToBeClosed());
|
||||||
|
|
||||||
if (executing_delay_close_) {
|
if (executing_delay_close_) {
|
||||||
callback->Continue(true, CefString());
|
callback->Continue(true, CefString());
|
||||||
return true;
|
return true;
|
||||||
@ -124,6 +131,8 @@ class LifeSpanTestHandler : public RoutingTestHandler {
|
|||||||
CefExecuteJavaScriptWithUserGestureForTests(frame, CefString());
|
CefExecuteJavaScriptWithUserGestureForTests(frame, CefString());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
EXPECT_FALSE(browser->GetHost()->IsReadyToBeClosed());
|
||||||
|
|
||||||
// Attempt to close the browser.
|
// Attempt to close the browser.
|
||||||
CloseBrowser(browser, settings_.force_close);
|
CloseBrowser(browser, settings_.force_close);
|
||||||
}
|
}
|
||||||
@ -180,12 +189,15 @@ class LifeSpanTestHandler : public RoutingTestHandler {
|
|||||||
|
|
||||||
TEST(LifeSpanTest, DoCloseAllow) {
|
TEST(LifeSpanTest, DoCloseAllow) {
|
||||||
LifeSpanTestHandler::Settings settings;
|
LifeSpanTestHandler::Settings settings;
|
||||||
settings.allow_do_close = true;
|
|
||||||
CefRefPtr<LifeSpanTestHandler> handler = new LifeSpanTestHandler(settings);
|
CefRefPtr<LifeSpanTestHandler> handler = new LifeSpanTestHandler(settings);
|
||||||
handler->ExecuteTest();
|
handler->ExecuteTest();
|
||||||
|
|
||||||
EXPECT_TRUE(handler->got_after_created_);
|
EXPECT_TRUE(handler->got_after_created_);
|
||||||
|
if (handler->use_alloy_style_browser()) {
|
||||||
EXPECT_TRUE(handler->got_do_close_);
|
EXPECT_TRUE(handler->got_do_close_);
|
||||||
|
} else {
|
||||||
|
EXPECT_FALSE(handler->got_do_close_);
|
||||||
|
}
|
||||||
EXPECT_TRUE(handler->got_before_close_);
|
EXPECT_TRUE(handler->got_before_close_);
|
||||||
EXPECT_FALSE(handler->got_before_unload_dialog_);
|
EXPECT_FALSE(handler->got_before_unload_dialog_);
|
||||||
EXPECT_TRUE(handler->got_unload_message_);
|
EXPECT_TRUE(handler->got_unload_message_);
|
||||||
@ -197,13 +209,16 @@ TEST(LifeSpanTest, DoCloseAllow) {
|
|||||||
|
|
||||||
TEST(LifeSpanTest, DoCloseAllowForce) {
|
TEST(LifeSpanTest, DoCloseAllowForce) {
|
||||||
LifeSpanTestHandler::Settings settings;
|
LifeSpanTestHandler::Settings settings;
|
||||||
settings.allow_do_close = true;
|
|
||||||
settings.force_close = true;
|
settings.force_close = true;
|
||||||
CefRefPtr<LifeSpanTestHandler> handler = new LifeSpanTestHandler(settings);
|
CefRefPtr<LifeSpanTestHandler> handler = new LifeSpanTestHandler(settings);
|
||||||
handler->ExecuteTest();
|
handler->ExecuteTest();
|
||||||
|
|
||||||
EXPECT_TRUE(handler->got_after_created_);
|
EXPECT_TRUE(handler->got_after_created_);
|
||||||
|
if (handler->use_alloy_style_browser()) {
|
||||||
EXPECT_TRUE(handler->got_do_close_);
|
EXPECT_TRUE(handler->got_do_close_);
|
||||||
|
} else {
|
||||||
|
EXPECT_FALSE(handler->got_do_close_);
|
||||||
|
}
|
||||||
EXPECT_TRUE(handler->got_before_close_);
|
EXPECT_TRUE(handler->got_before_close_);
|
||||||
EXPECT_FALSE(handler->got_before_unload_dialog_);
|
EXPECT_FALSE(handler->got_before_unload_dialog_);
|
||||||
EXPECT_TRUE(handler->got_unload_message_);
|
EXPECT_TRUE(handler->got_unload_message_);
|
||||||
@ -214,6 +229,11 @@ TEST(LifeSpanTest, DoCloseAllowForce) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
TEST(LifeSpanTest, DoCloseDisallow) {
|
TEST(LifeSpanTest, DoCloseDisallow) {
|
||||||
|
// Test not supported with Chrome style browser.
|
||||||
|
if (!UseAlloyStyleBrowserGlobal()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
LifeSpanTestHandler::Settings settings;
|
LifeSpanTestHandler::Settings settings;
|
||||||
settings.allow_do_close = false;
|
settings.allow_do_close = false;
|
||||||
CefRefPtr<LifeSpanTestHandler> handler = new LifeSpanTestHandler(settings);
|
CefRefPtr<LifeSpanTestHandler> handler = new LifeSpanTestHandler(settings);
|
||||||
@ -231,6 +251,11 @@ TEST(LifeSpanTest, DoCloseDisallow) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
TEST(LifeSpanTest, DoCloseDisallowForce) {
|
TEST(LifeSpanTest, DoCloseDisallowForce) {
|
||||||
|
// Test not supported with Chrome style browser.
|
||||||
|
if (!UseAlloyStyleBrowserGlobal()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
LifeSpanTestHandler::Settings settings;
|
LifeSpanTestHandler::Settings settings;
|
||||||
settings.allow_do_close = false;
|
settings.allow_do_close = false;
|
||||||
settings.force_close = true;
|
settings.force_close = true;
|
||||||
@ -249,6 +274,11 @@ TEST(LifeSpanTest, DoCloseDisallowForce) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
TEST(LifeSpanTest, DoCloseDisallowWithOnUnloadAllow) {
|
TEST(LifeSpanTest, DoCloseDisallowWithOnUnloadAllow) {
|
||||||
|
// Test not supported with Chrome style browser.
|
||||||
|
if (!UseAlloyStyleBrowserGlobal()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
LifeSpanTestHandler::Settings settings;
|
LifeSpanTestHandler::Settings settings;
|
||||||
settings.allow_do_close = false;
|
settings.allow_do_close = false;
|
||||||
settings.add_onunload_handler = true;
|
settings.add_onunload_handler = true;
|
||||||
@ -269,14 +299,17 @@ TEST(LifeSpanTest, DoCloseDisallowWithOnUnloadAllow) {
|
|||||||
|
|
||||||
TEST(LifeSpanTest, DoCloseAllowWithOnUnloadForce) {
|
TEST(LifeSpanTest, DoCloseAllowWithOnUnloadForce) {
|
||||||
LifeSpanTestHandler::Settings settings;
|
LifeSpanTestHandler::Settings settings;
|
||||||
settings.allow_do_close = true;
|
|
||||||
settings.add_onunload_handler = true;
|
settings.add_onunload_handler = true;
|
||||||
settings.force_close = true;
|
settings.force_close = true;
|
||||||
CefRefPtr<LifeSpanTestHandler> handler = new LifeSpanTestHandler(settings);
|
CefRefPtr<LifeSpanTestHandler> handler = new LifeSpanTestHandler(settings);
|
||||||
handler->ExecuteTest();
|
handler->ExecuteTest();
|
||||||
|
|
||||||
EXPECT_TRUE(handler->got_after_created_);
|
EXPECT_TRUE(handler->got_after_created_);
|
||||||
|
if (handler->use_alloy_style_browser()) {
|
||||||
EXPECT_TRUE(handler->got_do_close_);
|
EXPECT_TRUE(handler->got_do_close_);
|
||||||
|
} else {
|
||||||
|
EXPECT_FALSE(handler->got_do_close_);
|
||||||
|
}
|
||||||
EXPECT_TRUE(handler->got_before_close_);
|
EXPECT_TRUE(handler->got_before_close_);
|
||||||
EXPECT_TRUE(handler->got_before_unload_dialog_);
|
EXPECT_TRUE(handler->got_before_unload_dialog_);
|
||||||
EXPECT_TRUE(handler->got_unload_message_);
|
EXPECT_TRUE(handler->got_unload_message_);
|
||||||
@ -287,6 +320,11 @@ TEST(LifeSpanTest, DoCloseAllowWithOnUnloadForce) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
TEST(LifeSpanTest, DoCloseDisallowWithOnUnloadForce) {
|
TEST(LifeSpanTest, DoCloseDisallowWithOnUnloadForce) {
|
||||||
|
// Test not supported with Chrome style browser.
|
||||||
|
if (!UseAlloyStyleBrowserGlobal()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
LifeSpanTestHandler::Settings settings;
|
LifeSpanTestHandler::Settings settings;
|
||||||
settings.allow_do_close = false;
|
settings.allow_do_close = false;
|
||||||
settings.add_onunload_handler = true;
|
settings.add_onunload_handler = true;
|
||||||
@ -313,7 +351,11 @@ TEST(LifeSpanTest, OnUnloadAllow) {
|
|||||||
handler->ExecuteTest();
|
handler->ExecuteTest();
|
||||||
|
|
||||||
EXPECT_TRUE(handler->got_after_created_);
|
EXPECT_TRUE(handler->got_after_created_);
|
||||||
|
if (handler->use_alloy_style_browser()) {
|
||||||
EXPECT_TRUE(handler->got_do_close_);
|
EXPECT_TRUE(handler->got_do_close_);
|
||||||
|
} else {
|
||||||
|
EXPECT_FALSE(handler->got_do_close_);
|
||||||
|
}
|
||||||
EXPECT_TRUE(handler->got_before_close_);
|
EXPECT_TRUE(handler->got_before_close_);
|
||||||
EXPECT_TRUE(handler->got_before_unload_dialog_);
|
EXPECT_TRUE(handler->got_before_unload_dialog_);
|
||||||
EXPECT_TRUE(handler->got_unload_message_);
|
EXPECT_TRUE(handler->got_unload_message_);
|
||||||
|
@ -322,6 +322,8 @@ void TestHandler::OnAfterCreated(CefRefPtr<CefBrowser> browser) {
|
|||||||
void TestHandler::OnBeforeClose(CefRefPtr<CefBrowser> browser) {
|
void TestHandler::OnBeforeClose(CefRefPtr<CefBrowser> browser) {
|
||||||
EXPECT_UI_THREAD();
|
EXPECT_UI_THREAD();
|
||||||
|
|
||||||
|
EXPECT_TRUE(browser->GetHost()->IsReadyToBeClosed());
|
||||||
|
|
||||||
// Free the browser pointer so that the browser can be destroyed.
|
// Free the browser pointer so that the browser can be destroyed.
|
||||||
const int browser_id = browser->GetIdentifier();
|
const int browser_id = browser->GetIdentifier();
|
||||||
BrowserMap::iterator it = browser_map_.find(browser_id);
|
BrowserMap::iterator it = browser_map_.find(browser_id);
|
||||||
|
@ -522,68 +522,21 @@ void WindowIconFramelessImpl(CefRefPtr<CefWaitableEvent> event) {
|
|||||||
TestWindowDelegate::RunTest(event, std::move(config));
|
TestWindowDelegate::RunTest(event, std::move(config));
|
||||||
}
|
}
|
||||||
|
|
||||||
const int kChar = 'A';
|
constexpr int kChar = 'A';
|
||||||
const int kCloseWindowId = 2;
|
constexpr int kCloseWindowId = 2;
|
||||||
bool got_accelerator;
|
bool got_accelerator;
|
||||||
int got_key_event_alt_count;
|
|
||||||
bool got_key_event_char;
|
|
||||||
|
|
||||||
void TriggerAccelerator(CefRefPtr<CefWindow> window) {
|
void TriggerAccelerator(CefRefPtr<CefWindow> window) {
|
||||||
window->SendKeyPress(kChar, EVENTFLAG_ALT_DOWN);
|
window->SendKeyPress(kChar, EVENTFLAG_ALT_DOWN);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool OnKeyEvent(CefRefPtr<CefWindow> window, const CefKeyEvent& event) {
|
|
||||||
if (event.type != KEYEVENT_RAWKEYDOWN) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (event.windows_key_code == VK_MENU) {
|
|
||||||
// First we get the ALT key press in all cases.
|
|
||||||
EXPECT_FALSE(got_key_event_char);
|
|
||||||
if (got_key_event_alt_count == 0) {
|
|
||||||
EXPECT_FALSE(got_accelerator);
|
|
||||||
} else {
|
|
||||||
EXPECT_TRUE(got_accelerator);
|
|
||||||
}
|
|
||||||
|
|
||||||
EXPECT_EQ(EVENTFLAG_ALT_DOWN, static_cast<int>(event.modifiers));
|
|
||||||
got_key_event_alt_count++;
|
|
||||||
} else if (event.windows_key_code == kChar) {
|
|
||||||
// Then we get the char key press with the ALT modifier if the accelerator
|
|
||||||
// isn't registered.
|
|
||||||
EXPECT_TRUE(got_accelerator);
|
|
||||||
EXPECT_EQ(got_key_event_alt_count, 2);
|
|
||||||
EXPECT_FALSE(got_key_event_char);
|
|
||||||
|
|
||||||
EXPECT_EQ(EVENTFLAG_ALT_DOWN, static_cast<int>(event.modifiers));
|
|
||||||
got_key_event_char = true;
|
|
||||||
|
|
||||||
// Call this method just to make sure it doesn't crash.
|
|
||||||
window->RemoveAllAccelerators();
|
|
||||||
|
|
||||||
// End the test by closing the Window.
|
|
||||||
window->Close();
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool OnAccelerator(CefRefPtr<CefWindow> window, int command_id) {
|
bool OnAccelerator(CefRefPtr<CefWindow> window, int command_id) {
|
||||||
EXPECT_FALSE(got_accelerator);
|
EXPECT_FALSE(got_accelerator);
|
||||||
EXPECT_EQ(got_key_event_alt_count, 1);
|
|
||||||
EXPECT_FALSE(got_key_event_char);
|
|
||||||
|
|
||||||
EXPECT_EQ(kCloseWindowId, command_id);
|
EXPECT_EQ(kCloseWindowId, command_id);
|
||||||
got_accelerator = true;
|
got_accelerator = true;
|
||||||
|
|
||||||
// Remove the accelerator.
|
window->Close();
|
||||||
window->RemoveAccelerator(kCloseWindowId);
|
|
||||||
|
|
||||||
// Now send the event without the accelerator registered. Should result in a
|
|
||||||
// call to OnKeyEvent.
|
|
||||||
TriggerAccelerator(window);
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -598,25 +551,15 @@ void RunWindowAccelerator(CefRefPtr<CefWindow> window) {
|
|||||||
|
|
||||||
void VerifyWindowAccelerator(CefRefPtr<CefWindow> window) {
|
void VerifyWindowAccelerator(CefRefPtr<CefWindow> window) {
|
||||||
EXPECT_TRUE(got_accelerator);
|
EXPECT_TRUE(got_accelerator);
|
||||||
EXPECT_EQ(got_key_event_alt_count, 2);
|
|
||||||
EXPECT_TRUE(got_key_event_char);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Expected order of events:
|
|
||||||
// 1. OnKeyEvent for ALT key press.
|
|
||||||
// 2. OnAccelerator for ALT+Char key press (with accelerator registered).
|
|
||||||
// 3. OnKeyEvent for ALT key press.
|
|
||||||
// 4. OnKeyEvent for ALT+Char key press (without accelerator registered).
|
|
||||||
void WindowAcceleratorImpl(CefRefPtr<CefWaitableEvent> event) {
|
void WindowAcceleratorImpl(CefRefPtr<CefWaitableEvent> event) {
|
||||||
got_accelerator = false;
|
got_accelerator = false;
|
||||||
got_key_event_alt_count = 0;
|
|
||||||
got_key_event_char = false;
|
|
||||||
|
|
||||||
auto config = std::make_unique<TestWindowDelegate::Config>();
|
auto config = std::make_unique<TestWindowDelegate::Config>();
|
||||||
config->on_window_created = base::BindOnce(RunWindowAccelerator);
|
config->on_window_created = base::BindOnce(RunWindowAccelerator);
|
||||||
config->on_window_destroyed = base::BindOnce(VerifyWindowAccelerator);
|
config->on_window_destroyed = base::BindOnce(VerifyWindowAccelerator);
|
||||||
config->on_accelerator = base::BindRepeating(OnAccelerator);
|
config->on_accelerator = base::BindRepeating(OnAccelerator);
|
||||||
config->on_key_event = base::BindRepeating(OnKeyEvent);
|
|
||||||
config->close_window = false;
|
config->close_window = false;
|
||||||
TestWindowDelegate::RunTest(event, std::move(config));
|
TestWindowDelegate::RunTest(event, std::move(config));
|
||||||
}
|
}
|
||||||
|
@ -58,5 +58,6 @@ const char kHideWindowOnClose[] = "hide-window-on-close";
|
|||||||
const char kAcceptsFirstMouse[] = "accepts-first-mouse";
|
const char kAcceptsFirstMouse[] = "accepts-first-mouse";
|
||||||
const char kUseAlloyStyle[] = "use-alloy-style";
|
const char kUseAlloyStyle[] = "use-alloy-style";
|
||||||
const char kUseChromeStyleWindow[] = "use-chrome-style-window";
|
const char kUseChromeStyleWindow[] = "use-chrome-style-window";
|
||||||
|
const char kShowOverlayBrowser[] = "show-overlay-browser";
|
||||||
|
|
||||||
} // namespace client::switches
|
} // namespace client::switches
|
||||||
|
@ -52,6 +52,7 @@ extern const char kHideWindowOnClose[];
|
|||||||
extern const char kAcceptsFirstMouse[];
|
extern const char kAcceptsFirstMouse[];
|
||||||
extern const char kUseAlloyStyle[];
|
extern const char kUseAlloyStyle[];
|
||||||
extern const char kUseChromeStyleWindow[];
|
extern const char kUseChromeStyleWindow[];
|
||||||
|
extern const char kShowOverlayBrowser[];
|
||||||
|
|
||||||
} // namespace client::switches
|
} // namespace client::switches
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user