Reputation: 405
it is a very simple QT+CEF windows application, see https://github.com/GreatTux/CefMinGWQt
when I close the main window CEF trigger the breakpoint: I guess I failed here:
void CefBrowserMainParts::PostMainMessageLoopRun() {
....
#ifndef NDEBUG
// No CefBrowserContext instances should exist at this point.
DCHECK_EQ(0, CefBrowserContext::DebugObjCt);
#endif
}
I don't know what is the correct way to free the browser resource, I have looked a lot of examples on web, almost all of them got this problem on my Windows 7+vs2010 env
I also try this but doesn't work
void ClientHandler::OnBeforeClose(CefRefPtr<CefBrowser> browser) {
if(m_browser.get())
m_browser = NULL;
==== trace ===
libcef.dll!base::debug::BreakDebugger() Line 21 C++
libcef.dll!logging::LogMessage::~LogMessage() Line 604 C++
libcef.dll!CefBrowserMainParts::PostMainMessageLoopRun() Line 189 C++
libcef.dll!content::BrowserMainLoop::ShutdownThreadsAndCleanUp() Line 946 + 0x27 bytes C++
libcef.dll!content::BrowserMainRunnerImpl::Shutdown() Line 293 C++
libcef.dll!CefMainDelegate::ShutdownBrowser() Line 659 + 0x1b bytes C++
libcef.dll!CefContext::FinalizeShutdown() Line 462 C++
libcef.dll!CefContext::Shutdown() Line 345 C++
libcef.dll!CefShutdown() Line 171 C++
libcef.dll!cef_shutdown() Line 192 C++
qtloop.exe!CefShutdown() Line 180 + 0x8 bytes C++
qtloop.exe!main(int argc=1, char * * argv=0x00375b90) Line 35 C++
qtloop.exe!WinMain(HINSTANCE__ * __formal=0x00fe0000, HINSTANCE__ * __formal=0x00fe0000, HINSTANCE__ * __formal=0x00fe0000, HINSTANCE__ * __formal=0x00fe0000) Line 113 + 0xd bytes C++
qtloop.exe!__tmainCRTStartup() Line 547 + 0x2c bytes C
qtloop.exe!WinMainCRTStartup() Line 371 C
Upvotes: 2
Views: 2438
Reputation: 1
you need hook window close operating, and make sure cef browser closed firstly.
Standard process is(Excerpts from cef comment, has a little modify):
//
// 1. User clicks the window close button which sends a close notification to
// the application's top-level window.
// 2. Application's top-level window receives the close notification and:
// A. Calls CefBrowserHost::CloseBrowser(false).
// B. Cancels the window close.
// 3. JavaScript 'onbeforeunload' handler executes and shows the close
// confirmation dialog (which can be overridden via
// CefJSDialogHandler::OnBeforeUnloadDialog()).
// 4. User approves the close.
// 5. JavaScript 'onunload' handler executes.
// 6. Application's DoClose() handler is called. Application will:
// A. Set a flag to indicate that the next close attempt will be allowed.
// B. Return false.
// 7. Sends an close notification to the application's top-level window.
// 8. Application's top-level window receives the close notification and
// allows the window to close based on the flag from #6B.
// 9. Application's top-level window is destroyed.
// 10. Application's OnBeforeClose() handler is called and the browser object
// is destroyed.
// 11. Application exits by calling CefQuitMessageLoop() if no other browsers
// exist.
///
I have written a project named QCefWidget, it based on QT + CEF OSR. It has a perfect exit logic. You can refer to it
Upvotes: 0
Reputation: 131
When you close the mainwindow, Qt not destory it immediately, so cef browser not release. And at this time app.exec() was return, and CefShowDown() was run and trigger the debug check.
I have also encountered the same problem. It was because there also has browsers not free when you Shutdown Cef
DCHECK_EQ(0, CefBrowserContext::DebugObjCt);
I read this artical and read the source code of cef close process
https://github.com/fanfeilong/cefutil/blob/master/doc/CEF_Close.md
I solved the problem, the key point is that, when you called
GetHost()->CloseBrowser(false)
on cef embed parent window's closeEvent and ignore the first closeEvent
then cef will send close to the parent root window again if user allowed to close.
void CefBrowserHostImpl::PlatformCloseWindow() {
if (window_info_.window != NULL) {
HWND frameWnd = GetAncestor(window_info_.window, GA_ROOT);
PostMessage(frameWnd, WM_CLOSE, 0, 0);
}
}
when you recive the second close, you need to make sure close the window and destory the window which cef embed immediately. Cef was need the WM_DESTROY Event to free resource and call OnBeforeClose.
Upvotes: 2