Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(8)

Side by Side Diff: ash/monitor/multi_monitor_manager.cc

Issue 9960042: Refactor screen/monitor so that gfx::Screen returns monitor object. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: sync Created 8 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « ash/monitor/multi_monitor_manager.h ('k') | ash/monitor/multi_monitor_manager_unittest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "ash/monitor/multi_monitor_manager.h" 5 #include "ash/monitor/multi_monitor_manager.h"
6 6
7 #include <string> 7 #include <string>
8 #include <vector> 8 #include <vector>
9 9
10 #include "base/command_line.h" 10 #include "base/command_line.h"
11 #include "base/stl_util.h" 11 #include "base/stl_util.h"
12 #include "base/string_split.h" 12 #include "base/string_split.h"
13 #include "ui/aura/aura_switches.h" 13 #include "ui/aura/aura_switches.h"
14 #include "ui/aura/env.h" 14 #include "ui/aura/env.h"
15 #include "ui/aura/monitor.h"
16 #include "ui/aura/root_window.h" 15 #include "ui/aura/root_window.h"
17 #include "ui/aura/root_window_host.h" 16 #include "ui/aura/root_window_host.h"
17 #include "ui/aura/window_property.h"
18 #include "ui/gfx/monitor.h"
18 #include "ui/gfx/rect.h" 19 #include "ui/gfx/rect.h"
19 #include "ui/aura/window_property.h"
20 20
21 DECLARE_WINDOW_PROPERTY_TYPE(aura::Monitor*); 21 DECLARE_WINDOW_PROPERTY_TYPE(int);
22 22
23 namespace ash { 23 namespace ash {
24 namespace internal { 24 namespace internal {
25 namespace { 25 namespace {
26 26 gfx::Monitor& GetInvalidMonitor() {
27 aura::Monitor* Copy(aura::Monitor* m) { 27 static gfx::Monitor* invalid_monitor = new gfx::Monitor();
28 aura::Monitor* monitor = new aura::Monitor; 28 return *invalid_monitor;
29 monitor->set_bounds(m->bounds());
30 return monitor;
31 } 29 }
32
33 } // namespace 30 } // namespace
34 31
35 DEFINE_WINDOW_PROPERTY_KEY(aura::Monitor*, kMonitorKey, NULL); 32 using aura::RootWindow;
36 33 using aura::Window;
34 using gfx::Monitor;
37 using std::string; 35 using std::string;
38 using std::vector; 36 using std::vector;
39 using aura::Monitor; 37
40 using aura::RootWindow; 38 DEFINE_WINDOW_PROPERTY_KEY(int, kMonitorIdKey, -1);
41 using aura::Window;
42 39
43 MultiMonitorManager::MultiMonitorManager() { 40 MultiMonitorManager::MultiMonitorManager() {
44 Init(); 41 Init();
45 } 42 }
46 43
47 MultiMonitorManager::~MultiMonitorManager() { 44 MultiMonitorManager::~MultiMonitorManager() {
48 STLDeleteContainerPointers(monitors_.begin(), monitors_.end());
49 } 45 }
50 46
51 // static 47 // static
52 void MultiMonitorManager::AddRemoveMonitor() { 48 void MultiMonitorManager::AddRemoveMonitor() {
53 MultiMonitorManager* manager = static_cast<MultiMonitorManager*>( 49 MultiMonitorManager* manager = static_cast<MultiMonitorManager*>(
54 aura::Env::GetInstance()->monitor_manager()); 50 aura::Env::GetInstance()->monitor_manager());
55 manager->AddRemoveMonitorImpl(); 51 manager->AddRemoveMonitorImpl();
56 } 52 }
57 53
58 void MultiMonitorManager::CycleMonitor() { 54 void MultiMonitorManager::CycleMonitor() {
59 MultiMonitorManager* manager = static_cast<MultiMonitorManager*>( 55 MultiMonitorManager* manager = static_cast<MultiMonitorManager*>(
60 aura::Env::GetInstance()->monitor_manager()); 56 aura::Env::GetInstance()->monitor_manager());
61 manager->CycleMonitorImpl(); 57 manager->CycleMonitorImpl();
62 } 58 }
63 59
64 void MultiMonitorManager::OnNativeMonitorsChanged( 60 void MultiMonitorManager::OnNativeMonitorsChanged(
65 const std::vector<const aura::Monitor*>& new_monitors) { 61 const std::vector<Monitor>& new_monitors) {
66 size_t min = std::min(monitors_.size(), new_monitors.size()); 62 size_t min = std::min(monitors_.size(), new_monitors.size());
67 63
68 // For m19, we only care about 1st monitor as primary, and 64 // For m19, we only care about 1st monitor as primary, and
69 // don't differentiate the rest of monitors as all secondary 65 // don't differentiate the rest of monitors as all secondary
70 // monitors have the same content. 66 // monitors have the same content. ID for primary monitor stays the same
67 // because we never remove it, we don't update IDs for other monitors
68 // , for now, because they're the same.
71 // TODO(oshima): Fix this so that we can differentiate outputs 69 // TODO(oshima): Fix this so that we can differentiate outputs
72 // and keep a content on one monitor stays on the same monitor 70 // and keep a content on one monitor stays on the same monitor
73 // when a monitor is added or removed. 71 // when a monitor is added or removed.
74 for (size_t i = 0; i < min; ++i) { 72 for (size_t i = 0; i < min; ++i) {
75 Monitor* current_monitor = monitors_[i]; 73 Monitor& current_monitor = monitors_[i];
76 const Monitor* new_monitor = new_monitors[i]; 74 const Monitor& new_monitor = new_monitors[i];
77 if (current_monitor->bounds() != new_monitor->bounds()) { 75 if (current_monitor.bounds() != new_monitor.bounds()) {
78 current_monitor->set_bounds(new_monitor->bounds()); 76 current_monitor.SetBoundsAndUpdateWorkArea(new_monitor.bounds());
79 NotifyBoundsChanged(current_monitor); 77 NotifyBoundsChanged(current_monitor);
80 } 78 }
81 } 79 }
82 80
83 if (monitors_.size() < new_monitors.size()) { 81 if (monitors_.size() < new_monitors.size()) {
84 // New monitors added 82 // New monitors added
85 for (size_t i = min; i < new_monitors.size(); ++i) { 83 for (size_t i = min; i < new_monitors.size(); ++i) {
86 Monitor* monitor = new Monitor(); 84 //
87 monitor->set_bounds(new_monitors[i]->bounds()); 85 monitors_.push_back(Monitor(i));
88 monitors_.push_back(monitor); 86 gfx::Monitor& monitor = monitors_.back();
87 monitor.SetBoundsAndUpdateWorkArea(new_monitors[i].bounds());
89 NotifyMonitorAdded(monitor); 88 NotifyMonitorAdded(monitor);
90 } 89 }
91 } else { 90 } else {
92 // Monitors are removed. We keep the monitor for the primary 91 // Monitors are removed. We keep the monitor for the primary
93 // monitor (at index 0) because it needs the monitor information 92 // monitor (at index 0) because it needs the monitor information
94 // even if it doesn't exit. 93 // even if it doesn't exit.
95 while (monitors_.size() > new_monitors.size() && monitors_.size() > 1) { 94 while (monitors_.size() > new_monitors.size() && monitors_.size() > 1) {
96 Monitor* monitor = monitors_.back(); 95 Monitors::reverse_iterator iter = monitors_.rbegin();
97 NotifyMonitorRemoved(monitor); 96 NotifyMonitorRemoved(*iter);
98 monitors_.erase(std::find(monitors_.begin(), monitors_.end(), monitor)); 97 monitors_.erase(iter.base() - 1);
99 delete monitor;
100 } 98 }
101 } 99 }
102 } 100 }
103 101
104 RootWindow* MultiMonitorManager::CreateRootWindowForMonitor( 102 RootWindow* MultiMonitorManager::CreateRootWindowForMonitor(
105 Monitor* monitor) { 103 const Monitor& monitor) {
106 RootWindow* root_window = new RootWindow(monitor->bounds()); 104 RootWindow* root_window = new RootWindow(monitor.bounds());
107 // No need to remove RootWindowObserver because 105 // No need to remove RootWindowObserver because
108 // the MonitorManager object outlives RootWindow objects. 106 // the MonitorManager object outlives RootWindow objects.
109 root_window->AddRootWindowObserver(this); 107 root_window->AddRootWindowObserver(this);
110 root_window->SetProperty(kMonitorKey, monitor); 108 root_window->SetProperty(kMonitorIdKey, monitor.id());
111 return root_window; 109 return root_window;
112 } 110 }
113 111
114 const Monitor* MultiMonitorManager::GetMonitorNearestWindow( 112 const Monitor& MultiMonitorManager::GetMonitorAt(size_t index) {
113 return index < monitors_.size() ? monitors_[index] : GetInvalidMonitor();
114 }
115
116 size_t MultiMonitorManager::GetNumMonitors() const {
117 return monitors_.size();
118 }
119
120 const Monitor& MultiMonitorManager::GetMonitorNearestWindow(
115 const Window* window) const { 121 const Window* window) const {
116 if (!window) { 122 if (!window) {
117 MultiMonitorManager* manager = const_cast<MultiMonitorManager*>(this); 123 MultiMonitorManager* manager = const_cast<MultiMonitorManager*>(this);
118 return manager->GetMonitorAt(0); 124 return manager->GetMonitorAt(0);
119 } 125 }
120 const RootWindow* root = window->GetRootWindow(); 126 const RootWindow* root = window->GetRootWindow();
121 return root ? root->GetProperty(kMonitorKey) : NULL; 127 MultiMonitorManager* that = const_cast<MultiMonitorManager*>(this);
128 return root ?
129 that->FindMonitorById(root->GetProperty(kMonitorIdKey)) :
130 GetInvalidMonitor();
122 } 131 }
123 132
124 const Monitor* MultiMonitorManager::GetMonitorNearestPoint( 133 const Monitor& MultiMonitorManager::GetMonitorNearestPoint(
125 const gfx::Point& point) const { 134 const gfx::Point& point) const {
126 // TODO(oshima): For m19, mouse is constrained within 135 // TODO(oshima): For m19, mouse is constrained within
127 // the primary window. 136 // the primary window.
128 MultiMonitorManager* manager = const_cast<MultiMonitorManager*>(this); 137 MultiMonitorManager* manager = const_cast<MultiMonitorManager*>(this);
129 return manager->GetMonitorAt(0); 138 return manager->GetMonitorAt(0);
130 } 139 }
131 140
132 Monitor* MultiMonitorManager::GetMonitorAt(size_t index) {
133 return index < monitors_.size() ? monitors_[index] : NULL;
134 }
135
136 size_t MultiMonitorManager::GetNumMonitors() const {
137 return monitors_.size();
138 }
139
140 Monitor* MultiMonitorManager::GetMonitorNearestWindow(const Window* window) {
141 const MonitorManager* manager = this;
142 return const_cast<Monitor*>(manager->GetMonitorNearestWindow(window));
143 }
144
145 void MultiMonitorManager::OnRootWindowResized(const aura::RootWindow* root, 141 void MultiMonitorManager::OnRootWindowResized(const aura::RootWindow* root,
146 const gfx::Size& old_size) { 142 const gfx::Size& old_size) {
147 if (!use_fullscreen_host_window()) { 143 if (!use_fullscreen_host_window()) {
148 Monitor* monitor = root->GetProperty(kMonitorKey); 144 int monitor_id = root->GetProperty(kMonitorIdKey);
149 monitor->set_size(root->GetHostSize()); 145 Monitor& monitor = FindMonitorById(monitor_id);
146 monitor.SetSizeAndUpdateWorkArea(root->GetHostSize());
150 NotifyBoundsChanged(monitor); 147 NotifyBoundsChanged(monitor);
151 } 148 }
152 } 149 }
153 150
151 bool MultiMonitorManager::UpdateWorkAreaOfMonitorNearestWindow(
152 const aura::Window* window,
153 const gfx::Insets& insets) {
154 const RootWindow* root = window->GetRootWindow();
155 Monitor& monitor = FindMonitorById(root->GetProperty(kMonitorIdKey));
156 gfx::Rect old_work_area = monitor.work_area();
157 monitor.UpdateWorkAreaWithInsets(insets);
158 return old_work_area != monitor.work_area();
159 }
160
154 void MultiMonitorManager::Init() { 161 void MultiMonitorManager::Init() {
155 // TODO(oshima): Move this logic to MonitorChangeObserver. 162 // TODO(oshima): Move this logic to MonitorChangeObserver.
156 const string size_str = CommandLine::ForCurrentProcess()->GetSwitchValueASCII( 163 const string size_str = CommandLine::ForCurrentProcess()->GetSwitchValueASCII(
157 switches::kAuraHostWindowSize); 164 switches::kAuraHostWindowSize);
158 vector<string> parts; 165 vector<string> parts;
159 base::SplitString(size_str, ',', &parts); 166 base::SplitString(size_str, ',', &parts);
160 for (vector<string>::const_iterator iter = parts.begin(); 167 for (vector<string>::const_iterator iter = parts.begin();
161 iter != parts.end(); ++iter) { 168 iter != parts.end(); ++iter) {
162 monitors_.push_back(CreateMonitorFromSpec(*iter)); 169 monitors_.push_back(CreateMonitorFromSpec(*iter));
163 } 170 }
164 if (monitors_.empty()) 171 if (monitors_.empty())
165 monitors_.push_back(CreateMonitorFromSpec("" /* default */)); 172 monitors_.push_back(CreateMonitorFromSpec("" /* default */));
166 } 173 }
167 174
168 void MultiMonitorManager::AddRemoveMonitorImpl() { 175 void MultiMonitorManager::AddRemoveMonitorImpl() {
169 std::vector<const Monitor*> new_monitors; 176 std::vector<Monitor> new_monitors;
170 if (monitors_.size() > 1) { 177 if (monitors_.size() > 1) {
171 // Remove if there is more than one monitor. 178 // Remove if there is more than one monitor.
172 int count = monitors_.size() - 1; 179 int count = monitors_.size() - 1;
173 for (Monitors::const_iterator iter = monitors_.begin(); count-- > 0; ++iter) 180 for (Monitors::const_iterator iter = monitors_.begin(); count-- > 0; ++iter)
174 new_monitors.push_back(Copy(*iter)); 181 new_monitors.push_back(*iter);
175 } else { 182 } else {
176 // Add if there is only one monitor. 183 // Add if there is only one monitor.
177 new_monitors.push_back(Copy(monitors_[0])); 184 new_monitors.push_back(monitors_[0]);
178 aura::Monitor* extra_monitor = new Monitor; 185 new_monitors.push_back(CreateMonitorFromSpec("50+50-1280x768"));
179 extra_monitor->set_bounds(gfx::Rect(100, 100, 1440, 800));
180 new_monitors.push_back(extra_monitor);
181 } 186 }
182 if (new_monitors.size()) 187 if (new_monitors.size())
183 OnNativeMonitorsChanged(new_monitors); 188 OnNativeMonitorsChanged(new_monitors);
184 STLDeleteContainerPointers(new_monitors.begin(), new_monitors.end());
185 } 189 }
186 190
187 void MultiMonitorManager::CycleMonitorImpl() { 191 void MultiMonitorManager::CycleMonitorImpl() {
188 if (monitors_.size() > 1) { 192 if (monitors_.size() > 1) {
189 std::vector<const Monitor*> new_monitors; 193 std::vector<Monitor> new_monitors;
190 for (Monitors::const_iterator iter = monitors_.begin() + 1; 194 for (Monitors::const_iterator iter = monitors_.begin() + 1;
191 iter != monitors_.end(); ++iter) 195 iter != monitors_.end(); ++iter) {
192 new_monitors.push_back(Copy(*iter)); 196 gfx::Monitor monitor = *iter;
193 new_monitors.push_back(Copy(monitors_.front())); 197 new_monitors.push_back(monitor);
198 }
199 new_monitors.push_back(monitors_.front());
194 OnNativeMonitorsChanged(new_monitors); 200 OnNativeMonitorsChanged(new_monitors);
195 STLDeleteContainerPointers(new_monitors.begin(), new_monitors.end());
196 } 201 }
197 } 202 }
198 203
204 gfx::Monitor& MultiMonitorManager::FindMonitorById(int id) {
205 for (Monitors::iterator iter = monitors_.begin();
206 iter != monitors_.end(); ++iter) {
207 if ((*iter).id() == id)
208 return *iter;
209 }
210 DLOG(FATAL) << "Could not find monitor by id:" << id;
211 return GetInvalidMonitor();
212 }
213
199 } // namespace internal 214 } // namespace internal
200 } // namespace ash 215 } // namespace ash
OLDNEW
« no previous file with comments | « ash/monitor/multi_monitor_manager.h ('k') | ash/monitor/multi_monitor_manager_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698