summaryrefslogtreecommitdiffstats
path: root/chrome/browser/cocoa
diff options
context:
space:
mode:
authorrohitrao@chromium.org <rohitrao@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-05-14 15:24:31 +0000
committerrohitrao@chromium.org <rohitrao@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-05-14 15:24:31 +0000
commit96649a0f3cafe764eb191532f635d99c234ea005 (patch)
tree4450b4a03d498df44850ef549814a458cbc77be9 /chrome/browser/cocoa
parent3313359d46d2a4f0e0dc8c4dc476462dec8c988a (diff)
downloadchromium_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.mm51
-rw-r--r--chrome/browser/cocoa/browser_window_controller_unittest.mm53
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 */