diff options
author | pinkerton@google.com <pinkerton@google.com@0039d316-1c4b-4281-b951-d872f2087c98> | 2008-11-13 22:14:35 +0000 |
---|---|---|
committer | pinkerton@google.com <pinkerton@google.com@0039d316-1c4b-4281-b951-d872f2087c98> | 2008-11-13 22:14:35 +0000 |
commit | 70c17183f996b9d0bf13d0d5d7154dc9c9cc4cdb (patch) | |
tree | 8d1c89e7ca926f05beb7a1f35473c758a08acf07 /webkit/tools/test_shell/test_shell_mac.mm | |
parent | 848ebfe4cfbaedfd8f2e5104690598cd9658526d (diff) | |
download | chromium_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.mm | 73 |
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); |