1 // Copyright (c) 2011 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #import <Cocoa/Cocoa.h>
7 #import "chrome/browser/ui/cocoa/window_size_autosaver.h"
9 #include "base/prefs/pref_service.h"
10 #include "base/prefs/scoped_user_pref_update.h"
12 // If the window width stored in the prefs is smaller than this, the size is
13 // not restored but instead cleared from the profile -- to protect users from
14 // accidentally making their windows very small and then not finding them again.
15 const int kMinWindowWidth = 101;
17 // Minimum restored window height, see |kMinWindowWidth|.
18 const int kMinWindowHeight = 17;
20 @interface WindowSizeAutosaver (Private)
21 - (void)save:(NSNotification*)notification;
25 @implementation WindowSizeAutosaver
27 - (id)initWithWindow:(NSWindow*)window
28 prefService:(PrefService*)prefs
29 path:(const char*)path {
30 if ((self = [super init])) {
36 [[NSNotificationCenter defaultCenter]
38 selector:@selector(save:)
39 name:NSWindowDidMoveNotification
41 [[NSNotificationCenter defaultCenter]
43 selector:@selector(save:)
44 name:NSWindowDidResizeNotification
51 [[NSNotificationCenter defaultCenter] removeObserver:self];
55 - (void)save:(NSNotification*)notification {
56 DictionaryPrefUpdate update(prefService_, path_);
57 base::DictionaryValue* windowPrefs = update.Get();
58 NSRect frame = [window_ frame];
59 if ([window_ styleMask] & NSResizableWindowMask) {
60 // Save the origin of the window.
61 windowPrefs->SetInteger("left", NSMinX(frame));
62 windowPrefs->SetInteger("right", NSMaxX(frame));
63 // windows's and linux's profiles have top < bottom due to having their
64 // screen origin in the upper left, while cocoa's is in the lower left. To
65 // keep the top < bottom invariant, store top in bottom and vice versa.
66 windowPrefs->SetInteger("top", NSMinY(frame));
67 windowPrefs->SetInteger("bottom", NSMaxY(frame));
69 // Save the origin of the window.
70 windowPrefs->SetInteger("x", frame.origin.x);
71 windowPrefs->SetInteger("y", frame.origin.y);
76 // Get the positioning information.
77 const base::DictionaryValue* windowPrefs = prefService_->GetDictionary(path_);
78 if ([window_ styleMask] & NSResizableWindowMask) {
80 if (!windowPrefs->GetInteger("left", &x1) ||
81 !windowPrefs->GetInteger("right", &x2) ||
82 !windowPrefs->GetInteger("top", &y1) ||
83 !windowPrefs->GetInteger("bottom", &y2)) {
86 if (x2 - x1 < kMinWindowWidth || y2 - y1 < kMinWindowHeight) {
87 // Windows should never be very small.
88 DictionaryPrefUpdate update(prefService_, path_);
89 base::DictionaryValue* mutableWindowPrefs = update.Get();
90 mutableWindowPrefs->Remove("left", NULL);
91 mutableWindowPrefs->Remove("right", NULL);
92 mutableWindowPrefs->Remove("top", NULL);
93 mutableWindowPrefs->Remove("bottom", NULL);
95 [window_ setFrame:NSMakeRect(x1, y1, x2 - x1, y2 - y1) display:YES];
97 // Make sure the window is on-screen.
98 [window_ cascadeTopLeftFromPoint:NSZeroPoint];
102 if (!windowPrefs->GetInteger("x", &x) ||
103 !windowPrefs->GetInteger("y", &y))
104 return; // Nothing stored.
105 // Turn the origin (lower-left) into an upper-left window point.
106 NSPoint upperLeft = NSMakePoint(x, y + NSHeight([window_ frame]));
107 [window_ cascadeTopLeftFromPoint:upperLeft];