diff options
author | rohitrao@chromium.org <rohitrao@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-05-14 15:24:31 +0000 |
---|---|---|
committer | rohitrao@chromium.org <rohitrao@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-05-14 15:24:31 +0000 |
commit | 96649a0f3cafe764eb191532f635d99c234ea005 (patch) | |
tree | 4450b4a03d498df44850ef549814a458cbc77be9 /chrome/browser/cocoa | |
parent | 3313359d46d2a4f0e0dc8c4dc476462dec8c988a (diff) | |
download | chromium_src-96649a0f3cafe764eb191532f635d99c234ea005.zip chromium_src-96649a0f3cafe764eb191532f635d99c234ea005.tar.gz chromium_src-96649a0f3cafe764eb191532f635d99c234ea005.tar.bz2 |
Enable basic saving/restoring window placements on Mac.
Refactors the existing WindowSizer code to move platform-specific code
into separate files. Future CLs will add Mac support for muliple
monitors.
TEST=Browser windows should remember their position on Mac. The
corresponding behavior on Windows should not have changed.
Review URL: http://codereview.chromium.org/113286
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@16056 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/browser/cocoa')
-rw-r--r-- | chrome/browser/cocoa/browser_window_controller.mm | 51 | ||||
-rw-r--r-- | chrome/browser/cocoa/browser_window_controller_unittest.mm | 53 |
2 files changed, 103 insertions, 1 deletions
diff --git a/chrome/browser/cocoa/browser_window_controller.mm b/chrome/browser/cocoa/browser_window_controller.mm index 6d87b9d..283eb1e 100644 --- a/chrome/browser/cocoa/browser_window_controller.mm +++ b/chrome/browser/cocoa/browser_window_controller.mm @@ -7,6 +7,7 @@ #include "chrome/app/chrome_dll_resource.h" // IDC_* #include "chrome/browser/browser.h" #include "chrome/browser/browser_list.h" +#include "chrome/browser/browser_process.h" #include "chrome/browser/tab_contents/tab_contents.h" #include "chrome/browser/tab_contents/tab_contents_view.h" #include "chrome/browser/tabs/tab_strip_model.h" @@ -21,6 +22,7 @@ #import "chrome/browser/cocoa/tab_strip_controller.h" #import "chrome/browser/cocoa/tab_view.h" #import "chrome/browser/cocoa/toolbar_controller.h" +#include "chrome/common/pref_service.h" namespace { @@ -44,6 +46,12 @@ const int kWindowGradientHeight = 24; // frame changes. Re-positions the bookmark bar and the find bar. - (void)tabContentAreaFrameChanged:(id)sender; +// Saves the window's position in the local state preferences. +- (void)saveWindowPositionIfNeeded; + +// Saves the window's position to the given pref service. +- (void)saveWindowPositionToPrefs:(PrefService*)prefs; + // We need to adjust where sheets come out of the window, as by default they // erupt from the omnibox, which is rather weird. - (NSRect)window:(NSWindow *)window @@ -166,7 +174,7 @@ willPositionSheet:(NSWindow *)sheet - (void)windowWillClose:(NSNotification *)notification { DCHECK(!browser_->tabstrip_model()->count()); - // We can't acutally use |-autorelease| here because there's an embedded + // We can't actually use |-autorelease| here because there's an embedded // run loop in the |-performClose:| which contains its own autorelease pool. // Instead we use call it after a zero-length delay, which gets us back // to the main event loop. @@ -187,6 +195,11 @@ willPositionSheet:(NSWindow *)sheet if (!browser_->ShouldCloseWindow()) return NO; + // saveWindowPositionIfNeeded: only works if we are the last active + // window, but orderOut: ends up activating another window, so we + // have to save the window position before we call orderOut:. + [self saveWindowPositionIfNeeded]; + if (!browser_->tabstrip_model()->empty()) { // Tab strip isn't empty. Hide the frame (so it appears to have closed // immediately) and close all the tabs, allowing the renderers to shut @@ -203,6 +216,7 @@ willPositionSheet:(NSWindow *)sheet // Called right after our window became the main window. - (void)windowDidBecomeMain:(NSNotification *)notification { BrowserList::SetLastActive(browser_.get()); + [self saveWindowPositionIfNeeded]; } // Called when the user clicks the zoom button (or selects it from the Window @@ -580,6 +594,41 @@ willPositionSheet:(NSWindow *)sheet } } +- (void)saveWindowPositionIfNeeded { + if (browser_ != BrowserList::GetLastActive()) + return; + + if (!g_browser_process || !g_browser_process->local_state() || + !browser_->ShouldSaveWindowPlacement()) + return; + + [self saveWindowPositionToPrefs:g_browser_process->local_state()]; +} + +- (void)saveWindowPositionToPrefs:(PrefService*)prefs { + // Window placements are stored relative to the work area bounds, + // not the monitor bounds. + NSRect workFrame = [[[self window] screen] visibleFrame]; + + // Start with the window's frame, which is in virtual coordinates. + // Subtract the origin of the visibleFrame to get the window frame + // relative to the work area. + gfx::Rect bounds(NSRectToCGRect([[self window] frame])); + bounds.Offset(-workFrame.origin.x, -workFrame.origin.y); + + // Do some y twiddling to flip the coordinate system. + bounds.set_y(workFrame.size.height - bounds.y() - bounds.height()); + + DictionaryValue* windowPreferences = prefs->GetMutableDictionary( + browser_->GetWindowPlacementKey().c_str()); + windowPreferences->SetInteger(L"left", bounds.x()); + windowPreferences->SetInteger(L"top", bounds.y()); + windowPreferences->SetInteger(L"right", bounds.right()); + windowPreferences->SetInteger(L"bottom", bounds.bottom()); + windowPreferences->SetBoolean(L"maximized", false); + windowPreferences->SetBoolean(L"always_on_top", false); +} + - (NSRect)window:(NSWindow *)window willPositionSheet:(NSWindow *)sheet usingRect:(NSRect)defaultSheetRect { diff --git a/chrome/browser/cocoa/browser_window_controller_unittest.mm b/chrome/browser/cocoa/browser_window_controller_unittest.mm new file mode 100644 index 0000000..0dff06d --- /dev/null +++ b/chrome/browser/cocoa/browser_window_controller_unittest.mm @@ -0,0 +1,53 @@ +// Copyright (c) 2009 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "base/scoped_nsobject.h" +#include "base/scoped_nsautorelease_pool.h" +#include "base/scoped_ptr.h" +#include "chrome/browser/browser_process.h" +#include "chrome/browser/cocoa/browser_test_helper.h" +#include "chrome/browser/cocoa/browser_window_controller.h" +#include "chrome/browser/cocoa/cocoa_test_helper.h" +#include "chrome/common/pref_names.h" +#include "chrome/common/pref_service.h" +#include "chrome/test/testing_browser_process.h" +#include "testing/gtest/include/gtest/gtest.h" + +@interface BrowserWindowController (ExposedForTesting) +- (void)saveWindowPositionToPrefs:(PrefService*)prefs; +@end + +class BrowserWindowControllerTest : public testing::Test { + virtual void SetUp() { + controller_.reset([[BrowserWindowController alloc] + initWithBrowser:browser_helper_.browser() + takeOwnership:NO]); + } + + public: + // Order is very important here. We want the controller deleted + // before the pool, and want the pool deleted before + // BrowserTestHelper. + CocoaTestHelper cocoa_helper_; + BrowserTestHelper browser_helper_; + base::ScopedNSAutoreleasePool pool_; + scoped_nsobject<BrowserWindowController> controller_; +}; + +TEST_F(BrowserWindowControllerTest, TestSaveWindowPosition) { + PrefService* prefs = browser_helper_.profile()->GetPrefs(); + ASSERT_TRUE(prefs != NULL); + + // Check to make sure there is no existing pref for window placement. + ASSERT_TRUE(prefs->GetDictionary(prefs::kBrowserWindowPlacement) == NULL); + + // Ask the window to save its position, then check that a preference + // exists. We're technically passing in a pointer to the user prefs + // and not the local state prefs, but a PrefService* is a + // PrefService*, and this is a unittest. + [controller_ saveWindowPositionToPrefs:prefs]; + EXPECT_TRUE(prefs->GetDictionary(prefs::kBrowserWindowPlacement) != NULL); +} + +/* TODO(???): test other methods of BrowserWindowController */ |