cefclient: Request all browser windows to close in response to the application’s Quit/Exit menu item (issue #853).

git-svn-id: https://chromiumembedded.googlecode.com/svn/trunk@1172 5089003a-bbd8-11dd-ad1f-f1f9622dbc98
This commit is contained in:
Marshall Greenblatt 2013-04-03 19:29:47 +00:00
parent 5533ceb06b
commit 758470dfca
4 changed files with 69 additions and 14 deletions

View File

@ -36,9 +36,6 @@ char szWorkingDir[512]; // The current working directory
const int kWindowWidth = 800; const int kWindowWidth = 800;
const int kWindowHeight = 600; const int kWindowHeight = 600;
// Memory AutoRelease pool.
static NSAutoreleasePool* g_autopool = nil;
// Provide the CefAppProtocol implementation required by CEF. // Provide the CefAppProtocol implementation required by CEF.
@interface ClientApplication : NSApplication<CefAppProtocol> { @interface ClientApplication : NSApplication<CefAppProtocol> {
@private @private
@ -469,16 +466,22 @@ NSButton* MakeButton(NSRect* rect, NSString* title, NSView* parent) {
RunOtherTests(g_handler->GetBrowser()); RunOtherTests(g_handler->GetBrowser());
} }
// Sent by the default notification center immediately before the application // Called when the applications Quit menu item is selected.
// terminates. Quitting CEF is handled in ClientHandler::OnBeforeClose(). - (NSApplicationTerminateReply)applicationShouldTerminate:
(NSApplication *)sender {
// Request that all browser windows close.
if (g_handler.get())
g_handler->CloseAllBrowsers(false);
// Cancel the termination. The application will exit after all windows have
// closed.
return NSTerminateCancel;
}
// Sent immediately before the application terminates. This signal should not
// be called because we cancel the termination.
- (void)applicationWillTerminate:(NSNotification *)aNotification { - (void)applicationWillTerminate:(NSNotification *)aNotification {
// Release the handler. ASSERT(false); // Not reached.
g_handler = NULL;
[self release];
// Release the AutoRelease pool.
[g_autopool release];
} }
@end @end
@ -497,7 +500,7 @@ int main(int argc, char* argv[]) {
getcwd(szWorkingDir, sizeof(szWorkingDir)); getcwd(szWorkingDir, sizeof(szWorkingDir));
// Initialize the AutoRelease pool. // Initialize the AutoRelease pool.
g_autopool = [[NSAutoreleasePool alloc] init]; NSAutoreleasePool* autopool = [[NSAutoreleasePool alloc] init];
// Initialize the ClientApplication instance. // Initialize the ClientApplication instance.
[ClientApplication sharedApplication]; [ClientApplication sharedApplication];
@ -527,6 +530,15 @@ int main(int argc, char* argv[]) {
// Shut down CEF. // Shut down CEF.
CefShutdown(); CefShutdown();
// Release the handler.
g_handler = NULL;
// Release the delegate.
[delegate release];
// Release the AutoRelease pool.
[autopool release];
return 0; return 0;
} }

View File

@ -358,7 +358,8 @@ LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam,
DialogBox(hInst, MAKEINTRESOURCE(IDD_ABOUTBOX), hWnd, About); DialogBox(hInst, MAKEINTRESOURCE(IDD_ABOUTBOX), hWnd, About);
return 0; return 0;
case IDM_EXIT: case IDM_EXIT:
DestroyWindow(hWnd); if (g_handler.get())
g_handler->CloseAllBrowsers(false);
return 0; return 0;
case ID_WARN_CONSOLEMESSAGE: case ID_WARN_CONSOLEMESSAGE:
if (g_handler.get()) { if (g_handler.get()) {

View File

@ -311,6 +311,9 @@ void ClientHandler::OnAfterCreated(CefRefPtr<CefBrowser> browser) {
// We need to keep the main child window, but not popup windows // We need to keep the main child window, but not popup windows
m_Browser = browser; m_Browser = browser;
m_BrowserId = browser->GetIdentifier(); m_BrowserId = browser->GetIdentifier();
} else if (browser->IsPopup()) {
// Add to the list of popup browsers.
m_PopupBrowsers.push_back(browser);
} }
m_BrowserCount++; m_BrowserCount++;
@ -352,6 +355,15 @@ void ClientHandler::OnBeforeClose(CefRefPtr<CefBrowser> browser) {
m_OpenDevToolsURLs.find(browser->GetMainFrame()->GetURL()); m_OpenDevToolsURLs.find(browser->GetMainFrame()->GetURL());
if (it != m_OpenDevToolsURLs.end()) if (it != m_OpenDevToolsURLs.end())
m_OpenDevToolsURLs.erase(it); m_OpenDevToolsURLs.erase(it);
// Remove from the browser popup list.
BrowserList::iterator bit = m_PopupBrowsers.begin();
for (; bit != m_PopupBrowsers.end(); ++bit) {
if ((*bit)->IsSame(browser)) {
m_PopupBrowsers.erase(bit);
break;
}
}
} }
if (--m_BrowserCount == 0) { if (--m_BrowserCount == 0) {
@ -560,6 +572,28 @@ void ClientHandler::SetButtonHwnds(CefWindowHandle backHwnd,
m_StopHwnd = stopHwnd; m_StopHwnd = stopHwnd;
} }
void ClientHandler::CloseAllBrowsers(bool force_close) {
if (!CefCurrentlyOn(TID_UI)) {
// Execute on the UI thread.
CefPostTask(TID_UI,
NewCefRunnableMethod(this, &ClientHandler::CloseAllBrowsers,
force_close));
return;
}
if (!m_PopupBrowsers.empty()) {
// Request that any popup browsers close.
BrowserList::const_iterator it = m_PopupBrowsers.begin();
for (; it != m_PopupBrowsers.end(); ++it)
(*it)->GetHost()->CloseBrowser(force_close);
}
if (m_Browser.get()) {
// Request that the main browser close.
m_Browser->GetHost()->CloseBrowser(force_close);
}
}
std::string ClientHandler::GetLogFile() { std::string ClientHandler::GetLogFile() {
AutoLock lock_scope(this); AutoLock lock_scope(this);
return m_LogFile; return m_LogFile;

View File

@ -6,6 +6,7 @@
#define CEF_TESTS_CEFCLIENT_CLIENT_HANDLER_H_ #define CEF_TESTS_CEFCLIENT_CLIENT_HANDLER_H_
#pragma once #pragma once
#include <list>
#include <map> #include <map>
#include <set> #include <set>
#include <string> #include <string>
@ -236,6 +237,9 @@ class ClientHandler : public CefClient,
CefRefPtr<CefBrowser> GetBrowser() { return m_Browser; } CefRefPtr<CefBrowser> GetBrowser() { return m_Browser; }
int GetBrowserId() { return m_BrowserId; } int GetBrowserId() { return m_BrowserId; }
// Request that all existing browser windows close.
void CloseAllBrowsers(bool force_close);
// Returns true if the main browser window is currently closing. Used in // Returns true if the main browser window is currently closing. Used in
// combination with DoClose() and the OS close notification to properly handle // combination with DoClose() and the OS close notification to properly handle
// 'onbeforeunload' JavaScript events during window close. // 'onbeforeunload' JavaScript events during window close.
@ -295,6 +299,10 @@ class ClientHandler : public CefClient,
// The child browser window // The child browser window
CefRefPtr<CefBrowser> m_Browser; CefRefPtr<CefBrowser> m_Browser;
// List of any popup browser windows. Only accessed on the CEF UI thread.
typedef std::list<CefRefPtr<CefBrowser> > BrowserList;
BrowserList m_PopupBrowsers;
// The main frame window handle // The main frame window handle
CefWindowHandle m_MainHwnd; CefWindowHandle m_MainHwnd;