mirror of
https://bitbucket.org/chromiumembedded/cef
synced 2025-02-09 00:28:59 +01:00
Add support for modal dialogs (issue #250).
git-svn-id: https://chromiumembedded.googlecode.com/svn/trunk@255 5089003a-bbd8-11dd-ad1f-f1f9622dbc98
This commit is contained in:
parent
d757adb020
commit
02d6f3e384
@ -612,6 +612,14 @@ public:
|
|||||||
/*--cef()--*/
|
/*--cef()--*/
|
||||||
virtual CefWindowHandle GetWindowHandle() =0;
|
virtual CefWindowHandle GetWindowHandle() =0;
|
||||||
|
|
||||||
|
///
|
||||||
|
// Retrieve the window handle of the browser that opened this browser. Will
|
||||||
|
// return NULL for non-popup windows. This method can be used in combination
|
||||||
|
// with custom handling of modal windows.
|
||||||
|
///
|
||||||
|
/*--cef()--*/
|
||||||
|
virtual CefWindowHandle GetOpenerWindowHandle() =0;
|
||||||
|
|
||||||
///
|
///
|
||||||
// Returns true if the window is a popup window.
|
// Returns true if the window is a popup window.
|
||||||
///
|
///
|
||||||
@ -972,10 +980,28 @@ public:
|
|||||||
virtual void OnAfterCreated(CefRefPtr<CefBrowser> browser) {}
|
virtual void OnAfterCreated(CefRefPtr<CefBrowser> browser) {}
|
||||||
|
|
||||||
///
|
///
|
||||||
// Called just before a window is closed.
|
// Called just before a window is closed. If this is a modal window and you
|
||||||
|
// handled the RunModal() event you can use this callback to restore
|
||||||
|
// the opener window to a usable state.
|
||||||
///
|
///
|
||||||
/*--cef()--*/
|
/*--cef()--*/
|
||||||
virtual void OnBeforeClose(CefRefPtr<CefBrowser> browser) {}
|
virtual void OnBeforeClose(CefRefPtr<CefBrowser> browser) {}
|
||||||
|
|
||||||
|
///
|
||||||
|
// Called to enter the modal loop. Provide your own modal loop here. Return
|
||||||
|
// true if you ran your own modal loop and false to use the default. You can
|
||||||
|
// also use this event to know when a modal window is about to start.
|
||||||
|
///
|
||||||
|
/*--cef()--*/
|
||||||
|
virtual bool RunModal(CefRefPtr<CefBrowser> browser) { return false; }
|
||||||
|
|
||||||
|
///
|
||||||
|
// Called when a modal browser window has been destroyed. You must implement
|
||||||
|
// this if you are handling RunModal(). You can also use this event to know
|
||||||
|
// when a modal window is about to be closed.
|
||||||
|
///
|
||||||
|
/*--cef()--*/
|
||||||
|
virtual void QuitModal(CefRefPtr<CefBrowser> browser) { }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -451,6 +451,14 @@ typedef struct _cef_browser_t
|
|||||||
cef_window_handle_t (CEF_CALLBACK *get_window_handle)(
|
cef_window_handle_t (CEF_CALLBACK *get_window_handle)(
|
||||||
struct _cef_browser_t* self);
|
struct _cef_browser_t* self);
|
||||||
|
|
||||||
|
///
|
||||||
|
// Retrieve the window handle of the browser that opened this browser. Will
|
||||||
|
// return NULL for non-popup windows. This function can be used in combination
|
||||||
|
// with custom handling of modal windows.
|
||||||
|
///
|
||||||
|
cef_window_handle_t (CEF_CALLBACK *get_opener_window_handle)(
|
||||||
|
struct _cef_browser_t* self);
|
||||||
|
|
||||||
///
|
///
|
||||||
// Returns true (1) if the window is a popup window.
|
// Returns true (1) if the window is a popup window.
|
||||||
///
|
///
|
||||||
@ -815,11 +823,29 @@ typedef struct _cef_life_span_handler_t
|
|||||||
struct _cef_browser_t* browser);
|
struct _cef_browser_t* browser);
|
||||||
|
|
||||||
///
|
///
|
||||||
// Called just before a window is closed.
|
// Called just before a window is closed. If this is a modal window and you
|
||||||
|
// handled the run_modal() event you can use this callback to restore the
|
||||||
|
// opener window to a usable state.
|
||||||
///
|
///
|
||||||
void (CEF_CALLBACK *on_before_close)(struct _cef_life_span_handler_t* self,
|
void (CEF_CALLBACK *on_before_close)(struct _cef_life_span_handler_t* self,
|
||||||
struct _cef_browser_t* browser);
|
struct _cef_browser_t* browser);
|
||||||
|
|
||||||
|
///
|
||||||
|
// Called to enter the modal loop. Provide your own modal loop here. Return
|
||||||
|
// true (1) if you ran your own modal loop and false (0) to use the default.
|
||||||
|
// You can also use this event to know when a modal window is about to start.
|
||||||
|
///
|
||||||
|
int (CEF_CALLBACK *run_modal)(struct _cef_life_span_handler_t* self,
|
||||||
|
struct _cef_browser_t* browser);
|
||||||
|
|
||||||
|
///
|
||||||
|
// Called when a modal browser window has been destroyed. You must implement
|
||||||
|
// this if you are handling run_modal(). You can also use this event to know
|
||||||
|
// when a modal window is about to be closed.
|
||||||
|
///
|
||||||
|
void (CEF_CALLBACK *quit_modal)(struct _cef_life_span_handler_t* self,
|
||||||
|
struct _cef_browser_t* browser);
|
||||||
|
|
||||||
} cef_life_span_handler_t;
|
} cef_life_span_handler_t;
|
||||||
|
|
||||||
|
|
||||||
|
@ -150,7 +150,7 @@ CefRefPtr<CefBrowser> CefBrowser::CreateBrowserSync(
|
|||||||
}
|
}
|
||||||
|
|
||||||
CefRefPtr<CefBrowser> browser(
|
CefRefPtr<CefBrowser> browser(
|
||||||
new CefBrowserImpl(windowInfo, settings, false, client));
|
new CefBrowserImpl(windowInfo, settings, NULL, client));
|
||||||
static_cast<CefBrowserImpl*>(browser.get())->UIT_CreateBrowser(url);
|
static_cast<CefBrowserImpl*>(browser.get())->UIT_CreateBrowser(url);
|
||||||
|
|
||||||
return browser;
|
return browser;
|
||||||
@ -158,12 +158,17 @@ CefRefPtr<CefBrowser> CefBrowser::CreateBrowserSync(
|
|||||||
|
|
||||||
|
|
||||||
CefBrowserImpl::CefBrowserImpl(const CefWindowInfo& windowInfo,
|
CefBrowserImpl::CefBrowserImpl(const CefWindowInfo& windowInfo,
|
||||||
const CefBrowserSettings& settings, bool popup,
|
const CefBrowserSettings& settings,
|
||||||
|
gfx::NativeView opener,
|
||||||
CefRefPtr<CefClient> client)
|
CefRefPtr<CefClient> client)
|
||||||
: window_info_(windowInfo), settings_(settings), is_popup_(popup),
|
: window_info_(windowInfo), settings_(settings), opener_(opener),
|
||||||
is_modal_(false), client_(client), webviewhost_(NULL), popuphost_(NULL),
|
is_modal_(false), client_(client), webviewhost_(NULL), popuphost_(NULL),
|
||||||
zoom_level_(0.0), can_go_back_(false), can_go_forward_(false),
|
zoom_level_(0.0), can_go_back_(false), can_go_forward_(false),
|
||||||
main_frame_(NULL), unique_id_(0)
|
main_frame_(NULL), unique_id_(0)
|
||||||
|
#if defined(OS_WIN)
|
||||||
|
, opener_was_disabled_by_modal_loop_(false),
|
||||||
|
internal_modal_message_loop_is_active_(false)
|
||||||
|
#endif
|
||||||
{
|
{
|
||||||
delegate_.reset(new BrowserWebViewDelegate(this));
|
delegate_.reset(new BrowserWebViewDelegate(this));
|
||||||
popup_delegate_.reset(new BrowserWebViewDelegate(this));
|
popup_delegate_.reset(new BrowserWebViewDelegate(this));
|
||||||
@ -674,13 +679,28 @@ WebFrame* CefBrowserImpl::UIT_GetWebFrame(CefRefPtr<CefFrame> frame)
|
|||||||
|
|
||||||
void CefBrowserImpl::UIT_DestroyBrowser()
|
void CefBrowserImpl::UIT_DestroyBrowser()
|
||||||
{
|
{
|
||||||
if(client_.get()) {
|
#if defined(OS_WIN)
|
||||||
|
if (is_modal_) {
|
||||||
|
// Exit our own internal modal message loop now.
|
||||||
|
if (internal_modal_message_loop_is_active_) {
|
||||||
|
MessageLoop* message_loop = MessageLoop::current();
|
||||||
|
message_loop->QuitNow();
|
||||||
|
}
|
||||||
|
|
||||||
|
// If the client implemented its own modal loop then the above would not
|
||||||
|
// run, so this call is for the client to exit its loop. Otherwise,
|
||||||
|
// QuitModal can be used to let clients know that the modal loop is about
|
||||||
|
// to exit.
|
||||||
|
if (client_.get()) {
|
||||||
CefRefPtr<CefLifeSpanHandler> handler = client_->GetLifeSpanHandler();
|
CefRefPtr<CefLifeSpanHandler> handler = client_->GetLifeSpanHandler();
|
||||||
if (handler.get()) {
|
if (handler.get()) {
|
||||||
// Notify the handler that the window is about to be closed.
|
// Notify the handler that it can exit its modal loop if it was in one.
|
||||||
handler->OnBeforeClose(this);
|
handler->QuitModal(this);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
UIT_GetWebViewDelegate()->RevokeDragDrop();
|
UIT_GetWebViewDelegate()->RevokeDragDrop();
|
||||||
|
|
||||||
// If the current browser window is a dev tools client then disconnect from
|
// If the current browser window is a dev tools client then disconnect from
|
||||||
@ -716,10 +736,20 @@ void CefBrowserImpl::UIT_DestroyBrowser()
|
|||||||
void CefBrowserImpl::UIT_CloseBrowser()
|
void CefBrowserImpl::UIT_CloseBrowser()
|
||||||
{
|
{
|
||||||
REQUIRE_UIT();
|
REQUIRE_UIT();
|
||||||
if (!IsWindowRenderingDisabled())
|
if (IsWindowRenderingDisabled()) {
|
||||||
UIT_CloseView(UIT_GetMainWndHandle());
|
// There is no window here so we need to notify the client that this
|
||||||
else
|
// browser instance is about to go away.
|
||||||
|
if (client_.get()) {
|
||||||
|
CefRefPtr<CefLifeSpanHandler> handler = client_->GetLifeSpanHandler();
|
||||||
|
if (handler.get()) {
|
||||||
|
// Notify the handler that the window is about to be closed.
|
||||||
|
handler->OnBeforeClose(this);
|
||||||
|
}
|
||||||
|
}
|
||||||
UIT_DestroyBrowser();
|
UIT_DestroyBrowser();
|
||||||
|
} else {
|
||||||
|
UIT_CloseView(UIT_GetMainWndHandle());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void CefBrowserImpl::UIT_LoadURL(CefRefPtr<CefFrame> frame,
|
void CefBrowserImpl::UIT_LoadURL(CefRefPtr<CefFrame> frame,
|
||||||
@ -1082,8 +1112,11 @@ CefRefPtr<CefBrowserImpl> CefBrowserImpl::UIT_CreatePopupWindow(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Modal windows need to know which window is being suspended (the opener)
|
||||||
|
// so that it can be disabled while the modal window is open.
|
||||||
CefRefPtr<CefBrowserImpl> browser(
|
CefRefPtr<CefBrowserImpl> browser(
|
||||||
new CefBrowserImpl(info, settings, true, client));
|
new CefBrowserImpl(info, settings, UIT_GetMainWndHandle(), client));
|
||||||
|
|
||||||
// Don't pass the URL to UIT_CreateBrowser for popup windows or the URL will
|
// Don't pass the URL to UIT_CreateBrowser for popup windows or the URL will
|
||||||
// be loaded twice.
|
// be loaded twice.
|
||||||
browser->UIT_CreateBrowser(CefString());
|
browser->UIT_CreateBrowser(CefString());
|
||||||
|
@ -50,7 +50,8 @@ public:
|
|||||||
};
|
};
|
||||||
|
|
||||||
CefBrowserImpl(const CefWindowInfo& windowInfo,
|
CefBrowserImpl(const CefWindowInfo& windowInfo,
|
||||||
const CefBrowserSettings& settings, bool popup,
|
const CefBrowserSettings& settings,
|
||||||
|
gfx::NativeView opener,
|
||||||
CefRefPtr<CefClient> client);
|
CefRefPtr<CefClient> client);
|
||||||
virtual ~CefBrowserImpl() {}
|
virtual ~CefBrowserImpl() {}
|
||||||
|
|
||||||
@ -71,6 +72,8 @@ public:
|
|||||||
virtual void StopLoad() OVERRIDE;
|
virtual void StopLoad() OVERRIDE;
|
||||||
virtual void SetFocus(bool enable) OVERRIDE;
|
virtual void SetFocus(bool enable) OVERRIDE;
|
||||||
virtual CefWindowHandle GetWindowHandle() OVERRIDE;
|
virtual CefWindowHandle GetWindowHandle() OVERRIDE;
|
||||||
|
virtual CefWindowHandle GetOpenerWindowHandle() OVERRIDE
|
||||||
|
{ return opener_window(); }
|
||||||
virtual bool IsPopup() OVERRIDE { return is_popup(); }
|
virtual bool IsPopup() OVERRIDE { return is_popup(); }
|
||||||
virtual CefRefPtr<CefClient> GetClient() OVERRIDE { return client_; }
|
virtual CefRefPtr<CefClient> GetClient() OVERRIDE { return client_; }
|
||||||
virtual CefRefPtr<CefFrame> GetMainFrame() OVERRIDE
|
virtual CefRefPtr<CefFrame> GetMainFrame() OVERRIDE
|
||||||
@ -309,7 +312,8 @@ public:
|
|||||||
// These variables are read-only.
|
// These variables are read-only.
|
||||||
const CefBrowserSettings& settings() const { return settings_; }
|
const CefBrowserSettings& settings() const { return settings_; }
|
||||||
const FilePath& file_system_root() const { return file_system_root_.path(); }
|
const FilePath& file_system_root() const { return file_system_root_.path(); }
|
||||||
bool is_popup() { return is_popup_; }
|
gfx::NativeView opener_window() { return opener_; }
|
||||||
|
bool is_popup() { return (opener_ != NULL); }
|
||||||
|
|
||||||
// These variables may be read/written from multiple threads.
|
// These variables may be read/written from multiple threads.
|
||||||
void set_zoom_level(double zoomLevel);
|
void set_zoom_level(double zoomLevel);
|
||||||
@ -318,6 +322,17 @@ public:
|
|||||||
bool can_go_back();
|
bool can_go_back();
|
||||||
bool can_go_forward();
|
bool can_go_forward();
|
||||||
|
|
||||||
|
#if defined(OS_WIN)
|
||||||
|
void set_opener_was_disabled_by_modal_loop(bool disabled)
|
||||||
|
{
|
||||||
|
opener_was_disabled_by_modal_loop_ = disabled;
|
||||||
|
}
|
||||||
|
void set_internal_modal_message_loop_is_active(bool active)
|
||||||
|
{
|
||||||
|
internal_modal_message_loop_is_active_ = active;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
void set_popup_rect(const gfx::Rect& rect) { popup_rect_ = rect; }
|
void set_popup_rect(const gfx::Rect& rect) { popup_rect_ = rect; }
|
||||||
|
|
||||||
static bool ImplementsThreadSafeReferenceCounting() { return true; }
|
static bool ImplementsThreadSafeReferenceCounting() { return true; }
|
||||||
@ -332,7 +347,8 @@ protected:
|
|||||||
protected:
|
protected:
|
||||||
CefWindowInfo window_info_;
|
CefWindowInfo window_info_;
|
||||||
CefBrowserSettings settings_;
|
CefBrowserSettings settings_;
|
||||||
bool is_popup_;
|
// Handle of the browser window that opened this window.
|
||||||
|
gfx::NativeView opener_;
|
||||||
bool is_modal_;
|
bool is_modal_;
|
||||||
CefRefPtr<CefClient> client_;
|
CefRefPtr<CefClient> client_;
|
||||||
scoped_ptr<WebViewHost> webviewhost_;
|
scoped_ptr<WebViewHost> webviewhost_;
|
||||||
@ -355,6 +371,10 @@ protected:
|
|||||||
#if defined(OS_WIN)
|
#if defined(OS_WIN)
|
||||||
// Context object used to manage printing.
|
// Context object used to manage printing.
|
||||||
printing::PrintingContext print_context_;
|
printing::PrintingContext print_context_;
|
||||||
|
|
||||||
|
// Used to re-enable the opener when a modal window gets closed.
|
||||||
|
bool opener_was_disabled_by_modal_loop_;
|
||||||
|
bool internal_modal_message_loop_is_active_;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
typedef std::map<CefString, CefFrame*> FrameMap;
|
typedef std::map<CefString, CefFrame*> FrameMap;
|
||||||
|
@ -38,6 +38,35 @@ LRESULT CALLBACK CefBrowserImpl::WndProc(HWND hwnd, UINT message,
|
|||||||
static_cast<CefBrowserImpl*>(ui::GetWindowUserData(hwnd));
|
static_cast<CefBrowserImpl*>(ui::GetWindowUserData(hwnd));
|
||||||
|
|
||||||
switch (message) {
|
switch (message) {
|
||||||
|
case WM_CLOSE:
|
||||||
|
// It is the responsibility of the client to send this message to this
|
||||||
|
// window if it is created as a child window of a client's frame window.
|
||||||
|
// This is particularly important when this window is modal.
|
||||||
|
if(browser) {
|
||||||
|
// Here the window really is about to get closed.
|
||||||
|
if (browser->client_.get()) {
|
||||||
|
CefRefPtr<CefLifeSpanHandler> handler =
|
||||||
|
browser->client_->GetLifeSpanHandler();
|
||||||
|
if (handler.get()) {
|
||||||
|
// Notify the handler that the window is about to be closed.
|
||||||
|
handler->OnBeforeClose(browser);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// We must re-enable the opener (owner of the modal window)
|
||||||
|
// before we close the popup to avoid focus/activation/z-order issues.
|
||||||
|
if (browser->opener_ && browser->opener_was_disabled_by_modal_loop_) {
|
||||||
|
HWND owner = ::GetAncestor(browser->opener_, GA_ROOT);
|
||||||
|
::EnableWindow(owner, TRUE);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Don't do the default if this is a contained window as the destruction
|
||||||
|
// will occur when the parent frame window is destroyed.
|
||||||
|
if (::GetAncestor(hwnd, GA_ROOT) != hwnd)
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
case WM_DESTROY:
|
case WM_DESTROY:
|
||||||
if (browser) {
|
if (browser) {
|
||||||
// Clear the user data pointer.
|
// Clear the user data pointer.
|
||||||
|
@ -178,8 +178,48 @@ void BrowserWebViewDelegate::runModal() {
|
|||||||
|
|
||||||
browser_->UIT_SetIsModal(true);
|
browser_->UIT_SetIsModal(true);
|
||||||
|
|
||||||
// TODO(CEF): Add a handler notification for modal windows so the client can
|
CefRefPtr<CefClient> client = browser_->GetClient();
|
||||||
// make the window behave modally.
|
CefRefPtr<CefLifeSpanHandler> handler;
|
||||||
|
|
||||||
|
if( client.get())
|
||||||
|
handler = client->GetLifeSpanHandler();
|
||||||
|
|
||||||
|
bool handled(false);
|
||||||
|
|
||||||
|
if (handler.get()) {
|
||||||
|
// Let the client override the modal message loop.
|
||||||
|
handled = handler->RunModal(browser_);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!handled) {
|
||||||
|
HWND child = ::GetAncestor(browser_->UIT_GetMainWndHandle(), GA_ROOT);
|
||||||
|
HWND owner = ::GetAncestor(browser_->opener_window(), GA_ROOT);
|
||||||
|
|
||||||
|
if (child && owner) {
|
||||||
|
// Set the owner so that Windows keeps this window above the owner.
|
||||||
|
::SetWindowLong(child, GWL_HWNDPARENT, (LONG)owner);
|
||||||
|
// Disable the owner if it is enabled so that you can't interact with it.
|
||||||
|
// while this child window is open.
|
||||||
|
if (::IsWindowEnabled(owner)) {
|
||||||
|
::EnableWindow(owner, FALSE);
|
||||||
|
browser_->set_opener_was_disabled_by_modal_loop(true);
|
||||||
|
}
|
||||||
|
DWORD dwStyle = ::GetWindowLong(child, GWL_STYLE);
|
||||||
|
DWORD dwNewStyle = dwStyle | WS_POPUP;
|
||||||
|
if(dwStyle != dwNewStyle)
|
||||||
|
::SetWindowLong(child, GWL_STYLE, dwNewStyle);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Tell the browser to exit this message loop when this window closes.
|
||||||
|
browser_->set_internal_modal_message_loop_is_active(true);
|
||||||
|
|
||||||
|
// Start a new message loop here and return when this window closes.
|
||||||
|
MessageLoop* message_loop = MessageLoop::current();
|
||||||
|
bool old_state = message_loop->NestableTasksAllowed();
|
||||||
|
message_loop->SetNestableTasksAllowed(true);
|
||||||
|
message_loop->Run();
|
||||||
|
message_loop->SetNestableTasksAllowed(old_state);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// WebPluginPageDelegate ------------------------------------------------------
|
// WebPluginPageDelegate ------------------------------------------------------
|
||||||
|
@ -160,6 +160,16 @@ cef_window_handle_t CEF_CALLBACK browser_get_window_handle(
|
|||||||
return CefBrowserCppToC::Get(self)->GetWindowHandle();
|
return CefBrowserCppToC::Get(self)->GetWindowHandle();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
cef_window_handle_t CEF_CALLBACK browser_get_opener_window_handle(
|
||||||
|
struct _cef_browser_t* self)
|
||||||
|
{
|
||||||
|
DCHECK(self);
|
||||||
|
if(!self)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
return CefBrowserCppToC::Get(self)->GetOpenerWindowHandle();
|
||||||
|
}
|
||||||
|
|
||||||
int CEF_CALLBACK browser_is_popup(struct _cef_browser_t* self)
|
int CEF_CALLBACK browser_is_popup(struct _cef_browser_t* self)
|
||||||
{
|
{
|
||||||
DCHECK(self);
|
DCHECK(self);
|
||||||
@ -450,6 +460,7 @@ CefBrowserCppToC::CefBrowserCppToC(CefBrowser* cls)
|
|||||||
struct_.struct_.stop_load = browser_stop_load;
|
struct_.struct_.stop_load = browser_stop_load;
|
||||||
struct_.struct_.set_focus = browser_set_focus;
|
struct_.struct_.set_focus = browser_set_focus;
|
||||||
struct_.struct_.get_window_handle = browser_get_window_handle;
|
struct_.struct_.get_window_handle = browser_get_window_handle;
|
||||||
|
struct_.struct_.get_opener_window_handle = browser_get_opener_window_handle;
|
||||||
struct_.struct_.is_popup = browser_is_popup;
|
struct_.struct_.is_popup = browser_is_popup;
|
||||||
struct_.struct_.get_client = browser_get_client;
|
struct_.struct_.get_client = browser_get_client;
|
||||||
struct_.struct_.get_main_frame = browser_get_main_frame;
|
struct_.struct_.get_main_frame = browser_get_main_frame;
|
||||||
|
@ -97,6 +97,30 @@ void CEF_CALLBACK life_span_handler_on_before_close(
|
|||||||
CefBrowserCToCpp::Wrap(browser));
|
CefBrowserCToCpp::Wrap(browser));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int CEF_CALLBACK life_span_handler_run_modal(
|
||||||
|
struct _cef_life_span_handler_t* self, cef_browser_t* browser)
|
||||||
|
{
|
||||||
|
DCHECK(self);
|
||||||
|
DCHECK(browser);
|
||||||
|
if (!self || !browser)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
return CefLifeSpanHandlerCppToC::Get(self)->RunModal(
|
||||||
|
CefBrowserCToCpp::Wrap(browser));
|
||||||
|
}
|
||||||
|
|
||||||
|
void CEF_CALLBACK life_span_handler_quit_modal(
|
||||||
|
struct _cef_life_span_handler_t* self, cef_browser_t* browser)
|
||||||
|
{
|
||||||
|
DCHECK(self);
|
||||||
|
DCHECK(browser);
|
||||||
|
if (!self || !browser)
|
||||||
|
return;
|
||||||
|
|
||||||
|
CefLifeSpanHandlerCppToC::Get(self)->QuitModal(
|
||||||
|
CefBrowserCToCpp::Wrap(browser));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// CONSTRUCTOR - Do not edit by hand.
|
// CONSTRUCTOR - Do not edit by hand.
|
||||||
|
|
||||||
@ -107,6 +131,8 @@ CefLifeSpanHandlerCppToC::CefLifeSpanHandlerCppToC(CefLifeSpanHandler* cls)
|
|||||||
struct_.struct_.on_before_popup = life_span_handler_on_before_popup;
|
struct_.struct_.on_before_popup = life_span_handler_on_before_popup;
|
||||||
struct_.struct_.on_after_created = life_span_handler_on_after_created;
|
struct_.struct_.on_after_created = life_span_handler_on_after_created;
|
||||||
struct_.struct_.on_before_close = life_span_handler_on_before_close;
|
struct_.struct_.on_before_close = life_span_handler_on_before_close;
|
||||||
|
struct_.struct_.run_modal = life_span_handler_run_modal;
|
||||||
|
struct_.struct_.quit_modal = life_span_handler_quit_modal;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifndef NDEBUG
|
#ifndef NDEBUG
|
||||||
|
@ -120,6 +120,14 @@ CefWindowHandle CefBrowserCToCpp::GetWindowHandle()
|
|||||||
return struct_->get_window_handle(struct_);
|
return struct_->get_window_handle(struct_);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
CefWindowHandle CefBrowserCToCpp::GetOpenerWindowHandle()
|
||||||
|
{
|
||||||
|
if (CEF_MEMBER_MISSING(struct_, get_opener_window_handle))
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
return struct_->get_opener_window_handle(struct_);
|
||||||
|
}
|
||||||
|
|
||||||
bool CefBrowserCToCpp::IsPopup()
|
bool CefBrowserCToCpp::IsPopup()
|
||||||
{
|
{
|
||||||
if(CEF_MEMBER_MISSING(struct_, is_popup))
|
if(CEF_MEMBER_MISSING(struct_, is_popup))
|
||||||
|
@ -41,6 +41,7 @@ public:
|
|||||||
virtual void StopLoad() OVERRIDE;
|
virtual void StopLoad() OVERRIDE;
|
||||||
virtual void SetFocus(bool enable) OVERRIDE;
|
virtual void SetFocus(bool enable) OVERRIDE;
|
||||||
virtual CefWindowHandle GetWindowHandle() OVERRIDE;
|
virtual CefWindowHandle GetWindowHandle() OVERRIDE;
|
||||||
|
virtual CefWindowHandle GetOpenerWindowHandle() OVERRIDE;
|
||||||
virtual bool IsPopup() OVERRIDE;
|
virtual bool IsPopup() OVERRIDE;
|
||||||
virtual CefRefPtr<CefClient> GetClient() OVERRIDE;
|
virtual CefRefPtr<CefClient> GetClient() OVERRIDE;
|
||||||
virtual CefRefPtr<CefFrame> GetMainFrame() OVERRIDE;
|
virtual CefRefPtr<CefFrame> GetMainFrame() OVERRIDE;
|
||||||
|
@ -52,7 +52,7 @@ void CefLifeSpanHandlerCToCpp::OnAfterCreated(CefRefPtr<CefBrowser> browser)
|
|||||||
if (CEF_MEMBER_MISSING(struct_, on_after_created))
|
if (CEF_MEMBER_MISSING(struct_, on_after_created))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
return struct_->on_after_created(struct_, CefBrowserCppToC::Wrap(browser));
|
struct_->on_after_created(struct_, CefBrowserCppToC::Wrap(browser));
|
||||||
}
|
}
|
||||||
|
|
||||||
void CefLifeSpanHandlerCToCpp::OnBeforeClose(CefRefPtr<CefBrowser> browser)
|
void CefLifeSpanHandlerCToCpp::OnBeforeClose(CefRefPtr<CefBrowser> browser)
|
||||||
@ -60,7 +60,25 @@ void CefLifeSpanHandlerCToCpp::OnBeforeClose(CefRefPtr<CefBrowser> browser)
|
|||||||
if (CEF_MEMBER_MISSING(struct_, on_before_close))
|
if (CEF_MEMBER_MISSING(struct_, on_before_close))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
return struct_->on_before_close(struct_, CefBrowserCppToC::Wrap(browser));
|
struct_->on_before_close(struct_, CefBrowserCppToC::Wrap(browser));
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CefLifeSpanHandlerCToCpp::RunModal(CefRefPtr<CefBrowser> browser)
|
||||||
|
{
|
||||||
|
if (CEF_MEMBER_MISSING(struct_, run_modal))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
int rv = struct_->run_modal(struct_, CefBrowserCppToC::Wrap(browser));
|
||||||
|
|
||||||
|
return (rv ? true : false);
|
||||||
|
}
|
||||||
|
|
||||||
|
void CefLifeSpanHandlerCToCpp::QuitModal(CefRefPtr<CefBrowser> browser)
|
||||||
|
{
|
||||||
|
if (CEF_MEMBER_MISSING(struct_, quit_modal))
|
||||||
|
return;
|
||||||
|
|
||||||
|
struct_->quit_modal(struct_, CefBrowserCppToC::Wrap(browser));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -39,6 +39,8 @@ public:
|
|||||||
CefBrowserSettings& settings) OVERRIDE;
|
CefBrowserSettings& settings) OVERRIDE;
|
||||||
virtual void OnAfterCreated(CefRefPtr<CefBrowser> browser) OVERRIDE;
|
virtual void OnAfterCreated(CefRefPtr<CefBrowser> browser) OVERRIDE;
|
||||||
virtual void OnBeforeClose(CefRefPtr<CefBrowser> browser) OVERRIDE;
|
virtual void OnBeforeClose(CefRefPtr<CefBrowser> browser) OVERRIDE;
|
||||||
|
virtual bool RunModal(CefRefPtr<CefBrowser> browser) OVERRIDE;
|
||||||
|
virtual void QuitModal(CefRefPtr<CefBrowser> browser) OVERRIDE;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // BUILDING_CEF_SHARED
|
#endif // BUILDING_CEF_SHARED
|
||||||
|
@ -307,3 +307,8 @@ void RunDragDropTest(CefRefPtr<CefBrowser> browser)
|
|||||||
{
|
{
|
||||||
browser->GetMainFrame()->LoadURL("http://html5demos.com/drag");
|
browser->GetMainFrame()->LoadURL("http://html5demos.com/drag");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void RunModalDialogTest(CefRefPtr<CefBrowser> browser)
|
||||||
|
{
|
||||||
|
browser->GetMainFrame()->LoadURL("http://tests/modalmain");
|
||||||
|
}
|
||||||
|
@ -31,5 +31,6 @@ void RunXMLHTTPRequestTest(CefRefPtr<CefBrowser> browser);
|
|||||||
void RunWebURLRequestTest(CefRefPtr<CefBrowser> browser);
|
void RunWebURLRequestTest(CefRefPtr<CefBrowser> browser);
|
||||||
void RunDOMAccessTest(CefRefPtr<CefBrowser> browser);
|
void RunDOMAccessTest(CefRefPtr<CefBrowser> browser);
|
||||||
void RunDragDropTest(CefRefPtr<CefBrowser> browser);
|
void RunDragDropTest(CefRefPtr<CefBrowser> browser);
|
||||||
|
void RunModalDialogTest(CefRefPtr<CefBrowser> browser);
|
||||||
|
|
||||||
#endif // _CEFCLIENT_H
|
#endif // _CEFCLIENT_H
|
||||||
|
@ -35,6 +35,8 @@ IDS_LOGOBALL BINARY "res\\logoball.png"
|
|||||||
IDS_LOCALSTORAGE BINARY "res\\localstorage.html"
|
IDS_LOCALSTORAGE BINARY "res\\localstorage.html"
|
||||||
IDS_XMLHTTPREQUEST BINARY "res\\xmlhttprequest.html"
|
IDS_XMLHTTPREQUEST BINARY "res\\xmlhttprequest.html"
|
||||||
IDS_DOMACCESS BINARY "res\\domaccess.html"
|
IDS_DOMACCESS BINARY "res\\domaccess.html"
|
||||||
|
IDS_MODALMAIN BINARY "res\\modalmain.html"
|
||||||
|
IDS_MODALDIALOG BINARY "res\\modaldialog.html"
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
//
|
//
|
||||||
@ -92,6 +94,7 @@ BEGIN
|
|||||||
MENUITEM "Reset Zoom", ID_TESTS_ZOOM_RESET
|
MENUITEM "Reset Zoom", ID_TESTS_ZOOM_RESET
|
||||||
MENUITEM "Show Developer Tools", ID_TESTS_DEVTOOLS_SHOW
|
MENUITEM "Show Developer Tools", ID_TESTS_DEVTOOLS_SHOW
|
||||||
MENUITEM "Close Developer Tools", ID_TESTS_DEVTOOLS_CLOSE
|
MENUITEM "Close Developer Tools", ID_TESTS_DEVTOOLS_CLOSE
|
||||||
|
MENUITEM "Modal Dialog", ID_TESTS_MODALDIALOG
|
||||||
END
|
END
|
||||||
END
|
END
|
||||||
|
|
||||||
|
@ -560,6 +560,10 @@ LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
|
|||||||
if (browser.get())
|
if (browser.get())
|
||||||
browser->CloseDevTools();
|
browser->CloseDevTools();
|
||||||
return 0;
|
return 0;
|
||||||
|
case ID_TESTS_MODALDIALOG:
|
||||||
|
if(browser.get())
|
||||||
|
RunModalDialogTest(browser);
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@ -607,6 +611,18 @@ LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case WM_CLOSE:
|
||||||
|
// All clients must forward the WM_CLOSE call to all contained browser
|
||||||
|
// windows to give those windows a chance to cleanup before the window
|
||||||
|
// closes. Don't forward this message if you are cancelling the request.
|
||||||
|
if(g_handler.get())
|
||||||
|
{
|
||||||
|
HWND hWnd = g_handler->GetBrowserHwnd();
|
||||||
|
if (hWnd)
|
||||||
|
::SendMessage(hWnd, WM_CLOSE, 0, 0);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
case WM_DESTROY:
|
case WM_DESTROY:
|
||||||
// The frame window has exited
|
// The frame window has exited
|
||||||
PostQuitMessage(0);
|
PostQuitMessage(0);
|
||||||
|
@ -87,6 +87,14 @@ bool ClientHandler::OnBeforeResourceLoad(CefRefPtr<CefBrowser> browser,
|
|||||||
resourceStream = GetBinaryResourceReader(IDS_LOGOBALL);
|
resourceStream = GetBinaryResourceReader(IDS_LOGOBALL);
|
||||||
response->SetMimeType("image/png");
|
response->SetMimeType("image/png");
|
||||||
response->SetStatus(200);
|
response->SetStatus(200);
|
||||||
|
} else if(url == "http://tests/modalmain") {
|
||||||
|
resourceStream = GetBinaryResourceReader(IDS_MODALMAIN);
|
||||||
|
response->SetMimeType("text/html");
|
||||||
|
response->SetStatus(200);
|
||||||
|
} else if(url == "http://tests/modaldialog") {
|
||||||
|
resourceStream = GetBinaryResourceReader(IDS_MODALDIALOG);
|
||||||
|
response->SetMimeType("text/html");
|
||||||
|
response->SetStatus(200);
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
|
78
tests/cefclient/res/modaldialog.html
Normal file
78
tests/cefclient/res/modaldialog.html
Normal file
@ -0,0 +1,78 @@
|
|||||||
|
<!doctype html>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<title>A Modal Dialog</title>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
Argument:<input id="argument" type="text" size="32"><br>
|
||||||
|
<br>
|
||||||
|
Reply:<input id="reply" type="text" autofocus="autofocus" size="32"><br>
|
||||||
|
<p>
|
||||||
|
<button onclick="OnOK(false)">Cancel</button> <button onclick="OnOK(true)">OK</button>
|
||||||
|
</p>
|
||||||
|
<p id="time"></p>
|
||||||
|
<script>
|
||||||
|
|
||||||
|
function init()
|
||||||
|
{
|
||||||
|
timer();
|
||||||
|
setInterval(timer, 200);
|
||||||
|
setValueToId('argument', dialogArguments.msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
function timer()
|
||||||
|
{
|
||||||
|
updateId("time",new Date().toLocaleString());
|
||||||
|
}
|
||||||
|
|
||||||
|
function updateId(id, html, append)
|
||||||
|
{
|
||||||
|
id = document.getElementById(id);
|
||||||
|
if (typeof html == "boolean")
|
||||||
|
html = html?"Yes":"No";
|
||||||
|
if (append)
|
||||||
|
id.innerHTML += html + '<br>';
|
||||||
|
else
|
||||||
|
id.innerHTML = html;
|
||||||
|
}
|
||||||
|
|
||||||
|
function setValueToId(id, v)
|
||||||
|
{
|
||||||
|
id = document.getElementById(id);
|
||||||
|
id.value = v;
|
||||||
|
}
|
||||||
|
|
||||||
|
function getValueFromId(id)
|
||||||
|
{
|
||||||
|
id = document.getElementById(id);
|
||||||
|
if (id)
|
||||||
|
return id.value;
|
||||||
|
else
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
function OnOK(what)
|
||||||
|
{
|
||||||
|
if (what)
|
||||||
|
returnValue = { dialogResult:true, msg: "'"+ getValueFromId('reply') + "'" };
|
||||||
|
else
|
||||||
|
returnValue = { dialogResult:false, msg:'(cancelled)' };
|
||||||
|
window.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
function keydown(e)
|
||||||
|
{
|
||||||
|
if (!e) e= event;
|
||||||
|
if (e.keyCode == 27) {
|
||||||
|
OnOK(false);
|
||||||
|
} else if (e.keyCode == 13) {
|
||||||
|
OnOK(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
document.addEventListener('keydown', keydown, false);
|
||||||
|
window.addEventListener('load', init, false);
|
||||||
|
|
||||||
|
</script>
|
||||||
|
</body>
|
||||||
|
</html>
|
57
tests/cefclient/res/modalmain.html
Normal file
57
tests/cefclient/res/modalmain.html
Normal file
@ -0,0 +1,57 @@
|
|||||||
|
<!doctype html>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<title>Test Modal Dialog</title>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
|
||||||
|
<h3>Test Modal Dialog</h3>
|
||||||
|
Click this <button onclick="doModal()">button</button> to open a modal dialog.
|
||||||
|
|
||||||
|
<h3>Time (timers are suppresed while the modal dialog is open)</h3>
|
||||||
|
<div id="time"></div>
|
||||||
|
|
||||||
|
<h3>Result Log</h3>
|
||||||
|
<div id="result"></div>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
|
||||||
|
function init()
|
||||||
|
{
|
||||||
|
timer();
|
||||||
|
setInterval(timer, 200);
|
||||||
|
}
|
||||||
|
|
||||||
|
function timer()
|
||||||
|
{
|
||||||
|
updateId("time",new Date().toLocaleString());
|
||||||
|
}
|
||||||
|
|
||||||
|
function updateId(id, html, append)
|
||||||
|
{
|
||||||
|
id = document.getElementById(id);
|
||||||
|
if (typeof html == "boolean")
|
||||||
|
html = html?"Yes":"No";
|
||||||
|
if (append)
|
||||||
|
id.innerHTML += html + '<br>';
|
||||||
|
else
|
||||||
|
id.innerHTML = html;
|
||||||
|
}
|
||||||
|
|
||||||
|
function doModal()
|
||||||
|
{
|
||||||
|
updateId('result', "Modal dialog is open...", true);
|
||||||
|
var result = window.showModalDialog("http://tests/modaldialog", { msg:"Hi from parent"} );
|
||||||
|
if (typeof result == "object") {
|
||||||
|
updateId('result', "Result: " + result.msg, true);
|
||||||
|
} else {
|
||||||
|
updateId('result', "Dialog was closed", true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
window.addEventListener('load', init, false);
|
||||||
|
|
||||||
|
</script>
|
||||||
|
|
||||||
|
</body>
|
||||||
|
</html>
|
@ -51,6 +51,7 @@
|
|||||||
#define ID_TESTS_DOMACCESS 32791
|
#define ID_TESTS_DOMACCESS 32791
|
||||||
#define ID_TESTS_DRAGDROP 32792
|
#define ID_TESTS_DRAGDROP 32792
|
||||||
#define ID_TESTS_OSRAPP 32793
|
#define ID_TESTS_OSRAPP 32793
|
||||||
|
#define ID_TESTS_MODALDIALOG 32794
|
||||||
#define IDC_STATIC -1
|
#define IDC_STATIC -1
|
||||||
#define IDS_LOGO 1000
|
#define IDS_LOGO 1000
|
||||||
#define IDS_UIPLUGIN 1001
|
#define IDS_UIPLUGIN 1001
|
||||||
@ -59,6 +60,8 @@
|
|||||||
#define IDS_XMLHTTPREQUEST 1004
|
#define IDS_XMLHTTPREQUEST 1004
|
||||||
#define IDS_DOMACCESS 1005
|
#define IDS_DOMACCESS 1005
|
||||||
#define IDS_OSRPLUGIN 1006
|
#define IDS_OSRPLUGIN 1006
|
||||||
|
#define IDS_MODALMAIN 1007
|
||||||
|
#define IDS_MODALDIALOG 1008
|
||||||
|
|
||||||
// Avoid files associated with MacOS
|
// Avoid files associated with MacOS
|
||||||
#define _X86_
|
#define _X86_
|
||||||
@ -69,7 +72,7 @@
|
|||||||
#ifndef APSTUDIO_READONLY_SYMBOLS
|
#ifndef APSTUDIO_READONLY_SYMBOLS
|
||||||
#define _APS_NO_MFC 1
|
#define _APS_NO_MFC 1
|
||||||
#define _APS_NEXT_RESOURCE_VALUE 130
|
#define _APS_NEXT_RESOURCE_VALUE 130
|
||||||
#define _APS_NEXT_COMMAND_VALUE 32793
|
#define _APS_NEXT_COMMAND_VALUE 32795
|
||||||
#define _APS_NEXT_CONTROL_VALUE 1000
|
#define _APS_NEXT_CONTROL_VALUE 1000
|
||||||
#define _APS_NEXT_SYMED_VALUE 110
|
#define _APS_NEXT_SYMED_VALUE 110
|
||||||
#endif
|
#endif
|
||||||
|
Loading…
x
Reference in New Issue
Block a user