summaryrefslogtreecommitdiffstats
path: root/webkit/tools/test_shell/test_shell_mac.mm
diff options
context:
space:
mode:
authorpinkerton@google.com <pinkerton@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2008-11-13 22:14:35 +0000
committerpinkerton@google.com <pinkerton@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2008-11-13 22:14:35 +0000
commit70c17183f996b9d0bf13d0d5d7154dc9c9cc4cdb (patch)
tree8d1c89e7ca926f05beb7a1f35473c758a08acf07 /webkit/tools/test_shell/test_shell_mac.mm
parent848ebfe4cfbaedfd8f2e5104690598cd9658526d (diff)
downloadchromium_src-70c17183f996b9d0bf13d0d5d7154dc9c9cc4cdb.zip
chromium_src-70c17183f996b9d0bf13d0d5d7154dc9c9cc4cdb.tar.gz
chromium_src-70c17183f996b9d0bf13d0d5d7154dc9c9cc4cdb.tar.bz2
correctly close windows w/out leaking from JS, correctly clean up after ourselves when manually quitting test shell. This fixes the window.closed property in layout tests as well.
Review URL: http://codereview.chromium.org/10656 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@5391 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'webkit/tools/test_shell/test_shell_mac.mm')
-rw-r--r--webkit/tools/test_shell/test_shell_mac.mm73
1 files changed, 72 insertions, 1 deletions
diff --git a/webkit/tools/test_shell/test_shell_mac.mm b/webkit/tools/test_shell/test_shell_mac.mm
index 71606ba..31677d2 100644
--- a/webkit/tools/test_shell/test_shell_mac.mm
+++ b/webkit/tools/test_shell/test_shell_mac.mm
@@ -62,10 +62,70 @@ const int kTestWindowYLocation = -14000;
base::LazyInstance <std::map<gfx::WindowHandle, TestShell *> >
TestShell::window_map_(base::LINKER_INITIALIZED);
+// Receives notification that the window is closing so that it can start the
+// tear-down process. Is responsible for deleting itself when done.
+@interface WindowCloseDelegate : NSObject {
+}
+@end
+
+@implementation WindowCloseDelegate
+
+// Called when the window is about to close. Perform the self-destruction
+// sequence by getting rid of the shell and removing it and the window from
+// the various global lists. Instead of doing it here, however, we fire off
+// a delayed call to |-cleanup:| to allow everything to get off the stack
+// before we go deleting objects. By returning YES, we allow the window to be
+// removed from the screen.
+- (BOOL)windowShouldClose:(id)window {
+ // Try to make the window go away, but it may not when running layout
+ // tests due to the quirkyness of autorelease pools and having no main loop.
+ [window autorelease];
+
+ // clean ourselves up and do the work after clearing the stack of anything
+ // that might have the shell on it.
+ [self performSelectorOnMainThread:@selector(cleanup:)
+ withObject:window
+ waitUntilDone:NO];
+
+ return YES;
+}
+
+// does the work of removing the window from our various bookkeeping lists
+// and gets rid of the shell.
+- (void)cleanup:(id)window {
+ BOOL found = TestShell::RemoveWindowFromList(window);
+ DCHECK(found);
+ TestShell::DestroyAssociatedShell(window);
+
+ [self release];
+}
+
+@end
+
// Mac-specific stuff to do when the dtor is called. Nothing to do in our
// case.
void TestShell::PlatformCleanUp() {
+}
+
+// static
+void TestShell::DestroyAssociatedShell(gfx::WindowHandle handle) {
+ TestShell* shell = window_map_.Get()[handle];
+ if (shell)
+ window_map_.Get().erase(handle);
+ delete shell;
+}
+// static
+void TestShell::PlatformShutdown() {
+ // for each window in the window list, release it and destroy its shell
+ for (WindowList::iterator it = TestShell::windowList()->begin();
+ it != TestShell::windowList()->end();
+ ++it) {
+ DestroyAssociatedShell(*it);
+ [*it release];
+ }
+ // assert if we have anything left over, that would be bad.
+ DCHECK(window_map_.Get().size() == 0);
}
// static
@@ -109,7 +169,18 @@ bool TestShell::Initialize(const std::wstring& startingURL) {
defer:NO];
[m_mainWnd setTitle:@"TestShell"];
- // create webview
+ // Create a window delegate to watch for when it's asked to go away. It will
+ // clean itself up so we don't need to hold a reference.
+ [m_mainWnd setDelegate:[[WindowCloseDelegate alloc] init]];
+
+ // Rely on the window delegate to clean us up rather than immediately
+ // releasing when the window gets closed. We use the delegate to do
+ // everything from the autorelease pool so the shell isn't on the stack
+ // during cleanup (ie, a window close from javascript).
+ [m_mainWnd setReleasedWhenClosed:NO];
+
+ // Create a webview. Note that |web_view| takes ownership of this shell so we
+ // will get cleaned up when it gets destroyed.
m_webViewHost.reset(
WebViewHost::Create(m_mainWnd, delegate_.get(), *TestShell::web_prefs_));
webView()->SetUseEditorDelegate(true);