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 kWindowHeight = 600;
// Memory AutoRelease pool.
static NSAutoreleasePool* g_autopool = nil;
// Provide the CefAppProtocol implementation required by CEF.
@interface ClientApplication : NSApplication<CefAppProtocol> {
@private
@ -469,16 +466,22 @@ NSButton* MakeButton(NSRect* rect, NSString* title, NSView* parent) {
RunOtherTests(g_handler->GetBrowser());
}
// Sent by the default notification center immediately before the application
// terminates. Quitting CEF is handled in ClientHandler::OnBeforeClose().
// Called when the applications Quit menu item is selected.
- (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 {
// Release the handler.
g_handler = NULL;
[self release];
// Release the AutoRelease pool.
[g_autopool release];
ASSERT(false); // Not reached.
}
@end
@ -497,7 +500,7 @@ int main(int argc, char* argv[]) {
getcwd(szWorkingDir, sizeof(szWorkingDir));
// Initialize the AutoRelease pool.
g_autopool = [[NSAutoreleasePool alloc] init];
NSAutoreleasePool* autopool = [[NSAutoreleasePool alloc] init];
// Initialize the ClientApplication instance.
[ClientApplication sharedApplication];
@ -527,6 +530,15 @@ int main(int argc, char* argv[]) {
// Shut down CEF.
CefShutdown();
// Release the handler.
g_handler = NULL;
// Release the delegate.
[delegate release];
// Release the AutoRelease pool.
[autopool release];
return 0;
}

View File

@ -358,7 +358,8 @@ LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam,
DialogBox(hInst, MAKEINTRESOURCE(IDD_ABOUTBOX), hWnd, About);
return 0;
case IDM_EXIT:
DestroyWindow(hWnd);
if (g_handler.get())
g_handler->CloseAllBrowsers(false);
return 0;
case ID_WARN_CONSOLEMESSAGE:
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
m_Browser = browser;
m_BrowserId = browser->GetIdentifier();
} else if (browser->IsPopup()) {
// Add to the list of popup browsers.
m_PopupBrowsers.push_back(browser);
}
m_BrowserCount++;
@ -352,6 +355,15 @@ void ClientHandler::OnBeforeClose(CefRefPtr<CefBrowser> browser) {
m_OpenDevToolsURLs.find(browser->GetMainFrame()->GetURL());
if (it != m_OpenDevToolsURLs.end())
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) {
@ -560,6 +572,28 @@ void ClientHandler::SetButtonHwnds(CefWindowHandle backHwnd,
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() {
AutoLock lock_scope(this);
return m_LogFile;

View File

@ -6,6 +6,7 @@
#define CEF_TESTS_CEFCLIENT_CLIENT_HANDLER_H_
#pragma once
#include <list>
#include <map>
#include <set>
#include <string>
@ -236,6 +237,9 @@ class ClientHandler : public CefClient,
CefRefPtr<CefBrowser> GetBrowser() { return m_Browser; }
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
// combination with DoClose() and the OS close notification to properly handle
// 'onbeforeunload' JavaScript events during window close.
@ -295,6 +299,10 @@ class ClientHandler : public CefClient,
// The child browser window
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
CefWindowHandle m_MainHwnd;