- add sources.
[platform/framework/web/crosswalk.git] / src / chrome / browser / ui / cocoa / window_size_autosaver.mm
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.
4
5 #import <Cocoa/Cocoa.h>
6
7 #import "chrome/browser/ui/cocoa/window_size_autosaver.h"
8
9 #include "base/prefs/pref_service.h"
10 #include "base/prefs/scoped_user_pref_update.h"
11
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;
16
17 // Minimum restored window height, see |kMinWindowWidth|.
18 const int kMinWindowHeight = 17;
19
20 @interface WindowSizeAutosaver (Private)
21 - (void)save:(NSNotification*)notification;
22 - (void)restore;
23 @end
24
25 @implementation WindowSizeAutosaver
26
27 - (id)initWithWindow:(NSWindow*)window
28          prefService:(PrefService*)prefs
29                 path:(const char*)path {
30   if ((self = [super init])) {
31     window_ = window;
32     prefService_ = prefs;
33     path_ = path;
34
35     [self restore];
36     [[NSNotificationCenter defaultCenter]
37       addObserver:self
38          selector:@selector(save:)
39              name:NSWindowDidMoveNotification
40            object:window_];
41     [[NSNotificationCenter defaultCenter]
42       addObserver:self
43          selector:@selector(save:)
44              name:NSWindowDidResizeNotification
45            object:window_];
46   }
47   return self;
48 }
49
50 - (void)dealloc {
51   [[NSNotificationCenter defaultCenter] removeObserver:self];
52   [super dealloc];
53 }
54
55 - (void)save:(NSNotification*)notification {
56   DictionaryPrefUpdate update(prefService_, path_);
57   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));
68   } else {
69     // Save the origin of the window.
70     windowPrefs->SetInteger("x", frame.origin.x);
71     windowPrefs->SetInteger("y", frame.origin.y);
72   }
73 }
74
75 - (void)restore {
76   // Get the positioning information.
77   const DictionaryValue* windowPrefs = prefService_->GetDictionary(path_);
78   if ([window_ styleMask] & NSResizableWindowMask) {
79     int x1, x2, y1, y2;
80     if (!windowPrefs->GetInteger("left", &x1) ||
81         !windowPrefs->GetInteger("right", &x2) ||
82         !windowPrefs->GetInteger("top", &y1) ||
83         !windowPrefs->GetInteger("bottom", &y2)) {
84       return;
85     }
86     if (x2 - x1 < kMinWindowWidth || y2 - y1 < kMinWindowHeight) {
87       // Windows should never be very small.
88       DictionaryPrefUpdate update(prefService_, path_);
89       DictionaryValue* mutableWindowPrefs = update.Get();
90       mutableWindowPrefs->Remove("left", NULL);
91       mutableWindowPrefs->Remove("right", NULL);
92       mutableWindowPrefs->Remove("top", NULL);
93       mutableWindowPrefs->Remove("bottom", NULL);
94     } else {
95       [window_ setFrame:NSMakeRect(x1, y1, x2 - x1, y2 - y1) display:YES];
96
97       // Make sure the window is on-screen.
98       [window_ cascadeTopLeftFromPoint:NSZeroPoint];
99     }
100   } else {
101     int x, y;
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];
108   }
109 }
110
111 @end
112