diff --git a/include/cef.h b/include/cef.h index d1fc4f28c..5c3f91b2d 100644 --- a/include/cef.h +++ b/include/cef.h @@ -414,6 +414,10 @@ public: CefRefPtr handler, const CefString& url); + // Closes this browser window. + /*--cef()--*/ + virtual void CloseBrowser() =0; + // Returns true if the browser can navigate backwards. /*--cef()--*/ virtual bool CanGoBack() =0; diff --git a/include/cef_capi.h b/include/cef_capi.h index 7a590328e..3602544a5 100644 --- a/include/cef_capi.h +++ b/include/cef_capi.h @@ -231,6 +231,9 @@ typedef struct _cef_browser_t // Base structure. cef_base_t base; + // Closes this browser window. + void (CEF_CALLBACK *close_browser)(struct _cef_browser_t* self); + // Returns true (1) if the browser can navigate backwards. int (CEF_CALLBACK *can_go_back)(struct _cef_browser_t* self); diff --git a/include/cef_win.h b/include/cef_win.h index 186e8397d..4dad42d56 100644 --- a/include/cef_win.h +++ b/include/cef_win.h @@ -126,8 +126,8 @@ public: void SetAsChild(HWND hWndParent, RECT windowRect) { - m_dwStyle = WS_CHILD | WS_VISIBLE | WS_CLIPCHILDREN - | WS_CLIPSIBLINGS | WS_TABSTOP; + m_dwStyle = WS_CHILD | WS_CLIPCHILDREN | WS_CLIPSIBLINGS | WS_TABSTOP | + WS_VISIBLE; m_hWndParent = hWndParent; m_x = windowRect.left; m_y = windowRect.top; @@ -137,7 +137,8 @@ public: void SetAsPopup(HWND hWndParent, const CefString& windowName) { - m_dwStyle = WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN | WS_CLIPSIBLINGS; + m_dwStyle = WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN | WS_CLIPSIBLINGS | + WS_VISIBLE; m_hWndParent = hWndParent; m_x = CW_USEDEFAULT; m_y = CW_USEDEFAULT; diff --git a/libcef/browser_impl.cc b/libcef/browser_impl.cc index c528a8ef1..fde30db7e 100644 --- a/libcef/browser_impl.cc +++ b/libcef/browser_impl.cc @@ -146,6 +146,11 @@ CefBrowserImpl::CefBrowserImpl(const CefWindowInfo& windowInfo, } } +void CefBrowserImpl::CloseBrowser() +{ + CefThread::PostTask(CefThread::UI, FROM_HERE, NewRunnableMethod(this, + &CefBrowserImpl::UIT_CloseBrowser)); +} void CefBrowserImpl::GoBack() { CefThread::PostTask(CefThread::UI, FROM_HERE, NewRunnableMethod(this, @@ -768,7 +773,10 @@ bool CefBrowserImpl::UIT_Navigate(const BrowserNavigationEntry& entry, // thread for additional details: // http://groups.google.com/group/chromium-dev/browse_thread/thread/42bcd31b59e3a168 view->setFocusedFrame(frame); - UIT_SetFocus(UIT_GetWebViewHost(), true); + + // Give focus to the window if it is currently visible. + if(IsWindowVisible(UIT_GetMainWndHandle())) + UIT_SetFocus(UIT_GetWebViewHost(), true); } return true; diff --git a/libcef/browser_impl.h b/libcef/browser_impl.h index 15c14da40..6af0caefe 100644 --- a/libcef/browser_impl.h +++ b/libcef/browser_impl.h @@ -48,6 +48,7 @@ public: #endif // CefBrowser methods + virtual void CloseBrowser(); virtual bool CanGoBack() { return can_go_back(); } virtual void GoBack(); virtual bool CanGoForward() { return can_go_forward(); } diff --git a/libcef/browser_impl_win.cc b/libcef/browser_impl_win.cc index 3e386985f..3a4790dfb 100644 --- a/libcef/browser_impl_win.cc +++ b/libcef/browser_impl_win.cc @@ -141,8 +141,16 @@ void CefBrowserImpl::UIT_CreateBrowser(const CefString& url) // Size the web view window to the browser window RECT cr; GetClientRect(window_info_.m_hWnd, &cr); + + // Respect the WS_VISIBLE window style when setting the window's position + UINT flags = SWP_NOZORDER; + if (window_info_.m_dwStyle & WS_VISIBLE) + flags |= SWP_SHOWWINDOW; + else + flags |= SWP_NOACTIVATE; + SetWindowPos(UIT_GetWebViewWndHandle(), NULL, cr.left, cr.top, cr.right, - cr.bottom, SWP_NOZORDER | SWP_SHOWWINDOW); + cr.bottom, flags); if(handler_.get()) { // Notify the handler that we're done creating the new window diff --git a/libcef/browser_webview_delegate_win.cc b/libcef/browser_webview_delegate_win.cc index 135a32846..208cf5e91 100644 --- a/libcef/browser_webview_delegate_win.cc +++ b/libcef/browser_webview_delegate_win.cc @@ -55,10 +55,13 @@ WebWidget* BrowserWebViewDelegate::createPopupMenu( void BrowserWebViewDelegate::show(WebNavigationPolicy) { if (this == browser_->UIT_GetWebViewDelegate()) { - // Restore the window and bring it to the top. + // Restore the window and bring it to the top if the window is currently + // visible. HWND root = GetAncestor(browser_->UIT_GetMainWndHandle(), GA_ROOT); - ShowWindow(root, SW_SHOWNORMAL); - SetWindowPos(root, HWND_TOP, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE); + if(IsWindowVisible(root)) { + ShowWindow(root, SW_SHOWNORMAL); + SetWindowPos(root, HWND_TOP, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE); + } } else if (this == browser_->UIT_GetPopupDelegate()) { // Show popup widgets without activation. ShowWindow(browser_->UIT_GetPopupWndHandle(), SW_SHOWNA); diff --git a/libcef_dll/cpptoc/browser_cpptoc.cc b/libcef_dll/cpptoc/browser_cpptoc.cc index c37c34ece..725c5cba0 100644 --- a/libcef_dll/cpptoc/browser_cpptoc.cc +++ b/libcef_dll/cpptoc/browser_cpptoc.cc @@ -55,6 +55,15 @@ CEF_EXPORT cef_browser_t* cef_browser_create_sync(cef_window_info_t* windowInfo, // MEMBER FUNCTIONS - Body may be edited by hand. +void CEF_CALLBACK browser_close_browser(struct _cef_browser_t* self) +{ + DCHECK(self); + if(!self) + return; + + CefBrowserCppToC::Get(self)->CloseBrowser(); +} + int CEF_CALLBACK browser_can_go_back(struct _cef_browser_t* self) { DCHECK(self); @@ -282,6 +291,7 @@ void CEF_CALLBACK browser_close_dev_tools(struct _cef_browser_t* self) CefBrowserCppToC::CefBrowserCppToC(CefBrowser* cls) : CefCppToC(cls) { + struct_.struct_.close_browser = browser_close_browser; struct_.struct_.can_go_back = browser_can_go_back; struct_.struct_.go_back = browser_go_back; struct_.struct_.can_go_forward = browser_can_go_forward; diff --git a/libcef_dll/ctocpp/browser_ctocpp.cc b/libcef_dll/ctocpp/browser_ctocpp.cc index b7f0fc6b5..10f348c23 100644 --- a/libcef_dll/ctocpp/browser_ctocpp.cc +++ b/libcef_dll/ctocpp/browser_ctocpp.cc @@ -38,6 +38,14 @@ CefRefPtr CefBrowser::CreateBrowserSync(CefWindowInfo& windowInfo, // VIRTUAL METHODS - Body may be edited by hand. +void CefBrowserCToCpp::CloseBrowser() +{ + if(CEF_MEMBER_MISSING(struct_, close_browser)) + return; + + struct_->close_browser(struct_); +} + bool CefBrowserCToCpp::CanGoBack() { if(CEF_MEMBER_MISSING(struct_, can_go_back)) diff --git a/libcef_dll/ctocpp/browser_ctocpp.h b/libcef_dll/ctocpp/browser_ctocpp.h index 827e39d47..dab09ca90 100644 --- a/libcef_dll/ctocpp/browser_ctocpp.h +++ b/libcef_dll/ctocpp/browser_ctocpp.h @@ -31,6 +31,7 @@ public: virtual ~CefBrowserCToCpp() {} // CefBrowser methods + virtual void CloseBrowser(); virtual bool CanGoBack(); virtual void GoBack(); virtual bool CanGoForward(); diff --git a/tests/cefclient/cefclient.cpp b/tests/cefclient/cefclient.cpp index 7e48f516d..61e97e440 100644 --- a/tests/cefclient/cefclient.cpp +++ b/tests/cefclient/cefclient.cpp @@ -14,6 +14,40 @@ #include #include +// Define this value to redirect all popup URLs to the main application browser +// window. +//#define TEST_REDIRECT_POPUP_URLS + +#ifdef TEST_REDIRECT_POPUP_URLS +// Handler for popup windows that loads the request in an existing browser +// window. +class ClientPopupHandler : public ClientHandler +{ +public: + ClientPopupHandler(CefRefPtr parentBrowser) + : m_ParentBrowser(parentBrowser) + { + } + virtual ~ClientPopupHandler() + { + } + + virtual RetVal HandleBeforeBrowse(CefRefPtr browser, + CefRefPtr frame, + CefRefPtr request, + NavType navType, bool isRedirect) + { + REQUIRE_UI_THREAD(); + + m_ParentBrowser->GetMainFrame()->LoadRequest(request); + browser->CloseBrowser(); + return RV_HANDLED; + } + +protected: + CefRefPtr m_ParentBrowser; +}; +#endif // TEST_REDIRECT_POPUP_URLS // ClientHandler::ClientDownloadListener implementation @@ -46,6 +80,30 @@ ClientHandler::~ClientHandler() { } +CefHandler::RetVal ClientHandler::HandleBeforeCreated( + CefRefPtr parentBrowser, CefWindowInfo& createInfo, bool popup, + const CefPopupFeatures& popupFeatures, CefRefPtr& handler, + CefString& url, CefBrowserSettings& settings) +{ + REQUIRE_UI_THREAD(); + +#ifdef TEST_REDIRECT_POPUP_URLS + if(popup) { + std::string urlStr = url; + if(urlStr.find("resources/inspector/devtools.html") == std::string::npos) { + // Show all popup windows excluding DevTools in the current window. +#ifdef _WIN32 + // Make the popup window hidden. + createInfo.m_dwStyle &= ~WS_VISIBLE; +#endif + handler = new ClientPopupHandler(m_Browser); + } + } +#endif // TEST_REDIRECT_POPUP_URLS + + return RV_CONTINUE; +} + CefHandler::RetVal ClientHandler::HandleAfterCreated( CefRefPtr browser) { diff --git a/tests/cefclient/cefclient.h b/tests/cefclient/cefclient.h index d90270839..ed47a1bf9 100644 --- a/tests/cefclient/cefclient.h +++ b/tests/cefclient/cefclient.h @@ -30,7 +30,7 @@ public: }; ClientHandler(); - ~ClientHandler(); + virtual ~ClientHandler(); // Called on the UI thread before a new window is created. The |parentBrowser| // parameter will point to the parent browser window, if any. The |popup| @@ -47,11 +47,7 @@ public: const CefPopupFeatures& popupFeatures, CefRefPtr& handler, CefString& url, - CefBrowserSettings& settings) - { - REQUIRE_UI_THREAD(); - return RV_CONTINUE; - } + CefBrowserSettings& settings); // Called on the UI thread after a new window is created. The return value is // currently ignored.