OLD | NEW |
| (Empty) |
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 | |
3 // found in the LICENSE file. | |
4 | |
5 #include "ash/monitor/monitor_controller.h" | |
6 | |
7 #include "ash/ash_switches.h" | |
8 #include "ash/monitor/multi_monitor_manager.h" | |
9 #include "ash/root_window_controller.h" | |
10 #include "ash/shell.h" | |
11 #include "ash/wm/window_util.h" | |
12 #include "base/command_line.h" | |
13 #include "ui/aura/env.h" | |
14 #include "ui/aura/root_window.h" | |
15 #include "ui/aura/window.h" | |
16 #include "ui/gfx/display.h" | |
17 #include "ui/gfx/screen.h" | |
18 | |
19 namespace ash { | |
20 namespace internal { | |
21 namespace { | |
22 // True if the extended desktop mode is enabled. | |
23 bool extended_desktop_enabled = false; | |
24 | |
25 // True if the virtual screen coordinates is enabled. | |
26 bool virtual_screen_coordinates_enabled = false; | |
27 } | |
28 | |
29 MonitorController::MonitorController() | |
30 : secondary_display_layout_(RIGHT) { | |
31 aura::Env::GetInstance()->monitor_manager()->AddObserver(this); | |
32 } | |
33 | |
34 MonitorController::~MonitorController() { | |
35 aura::Env::GetInstance()->monitor_manager()->RemoveObserver(this); | |
36 // Delete all root window controllers, which deletes root window | |
37 // from the last so that the primary root window gets deleted last. | |
38 for (std::map<int, aura::RootWindow*>::const_reverse_iterator it = | |
39 root_windows_.rbegin(); it != root_windows_.rend(); ++it) { | |
40 internal::RootWindowController* controller = | |
41 wm::GetRootWindowController(it->second); | |
42 // RootWindow may not have RootWindowController in non | |
43 // extended desktop mode. | |
44 if (controller) | |
45 delete controller; | |
46 else | |
47 delete it->second; | |
48 } | |
49 } | |
50 | |
51 void MonitorController::InitPrimaryDisplay() { | |
52 aura::MonitorManager* monitor_manager = | |
53 aura::Env::GetInstance()->monitor_manager(); | |
54 const gfx::Display& display = monitor_manager->GetDisplayAt(0); | |
55 DCHECK_EQ(0, display.id()); | |
56 aura::RootWindow* root = AddRootWindowForDisplay(display); | |
57 root->SetHostBounds(display.bounds_in_pixel()); | |
58 } | |
59 | |
60 void MonitorController::InitSecondaryDisplays() { | |
61 aura::MonitorManager* monitor_manager = | |
62 aura::Env::GetInstance()->monitor_manager(); | |
63 for (size_t i = 1; i < monitor_manager->GetNumDisplays(); ++i) { | |
64 const gfx::Display& display = monitor_manager->GetDisplayAt(i); | |
65 aura::RootWindow* root = AddRootWindowForDisplay(display); | |
66 Shell::GetInstance()->InitRootWindowForSecondaryMonitor(root); | |
67 } | |
68 } | |
69 | |
70 aura::RootWindow* MonitorController::GetPrimaryRootWindow() { | |
71 DCHECK(!root_windows_.empty()); | |
72 return root_windows_[0]; | |
73 } | |
74 | |
75 void MonitorController::CloseChildWindows() { | |
76 for (std::map<int, aura::RootWindow*>::const_iterator it = | |
77 root_windows_.begin(); it != root_windows_.end(); ++it) { | |
78 aura::RootWindow* root_window = it->second; | |
79 internal::RootWindowController* controller = | |
80 wm::GetRootWindowController(root_window); | |
81 if (controller) { | |
82 controller->CloseChildWindows(); | |
83 } else { | |
84 while (!root_window->children().empty()) { | |
85 aura::Window* child = root_window->children()[0]; | |
86 delete child; | |
87 } | |
88 } | |
89 } | |
90 } | |
91 | |
92 std::vector<aura::RootWindow*> MonitorController::GetAllRootWindows() { | |
93 std::vector<aura::RootWindow*> windows; | |
94 for (std::map<int, aura::RootWindow*>::const_iterator it = | |
95 root_windows_.begin(); it != root_windows_.end(); ++it) { | |
96 DCHECK(it->second); | |
97 if (wm::GetRootWindowController(it->second)) | |
98 windows.push_back(it->second); | |
99 } | |
100 return windows; | |
101 } | |
102 | |
103 std::vector<internal::RootWindowController*> | |
104 MonitorController::GetAllRootWindowControllers() { | |
105 std::vector<internal::RootWindowController*> controllers; | |
106 for (std::map<int, aura::RootWindow*>::const_iterator it = | |
107 root_windows_.begin(); it != root_windows_.end(); ++it) { | |
108 internal::RootWindowController* controller = | |
109 wm::GetRootWindowController(it->second); | |
110 if (controller) | |
111 controllers.push_back(controller); | |
112 } | |
113 return controllers; | |
114 } | |
115 | |
116 void MonitorController::SetSecondaryDisplayLayout( | |
117 SecondaryDisplayLayout layout) { | |
118 secondary_display_layout_ = layout; | |
119 } | |
120 | |
121 bool MonitorController::WarpMouseCursorIfNecessary( | |
122 aura::Window* current_root, | |
123 const gfx::Point& location_in_root) { | |
124 if (root_windows_.size() < 2) | |
125 return false; | |
126 // Only 1 external display is supported in extended desktop mode. | |
127 DCHECK_EQ(2U, root_windows_.size()); | |
128 | |
129 bool in_primary = current_root == root_windows_[0]; | |
130 | |
131 std::map<int, aura::RootWindow*>::iterator iter = root_windows_.begin(); | |
132 aura::RootWindow* alternate_root = iter->second != current_root ? | |
133 iter->second : (++iter)->second; | |
134 gfx::Rect alternate_bounds = alternate_root->bounds(); | |
135 gfx::Point alternate_point; | |
136 | |
137 gfx::Rect display_area( | |
138 gfx::Screen::GetDisplayNearestWindow(current_root).bounds()); | |
139 | |
140 // TODO(oshima): This is temporary code until the virtual screen | |
141 // coordinate is implemented. | |
142 if (location_in_root.x() <= display_area.x()) { | |
143 if (location_in_root.y() < alternate_bounds.height() && | |
144 ((in_primary && secondary_display_layout_ == LEFT) || | |
145 (!in_primary && secondary_display_layout_ == RIGHT))) { | |
146 alternate_point = gfx::Point( | |
147 alternate_bounds.right() - (location_in_root.x() - display_area.x()), | |
148 location_in_root.y()); | |
149 } else { | |
150 alternate_root = NULL; | |
151 } | |
152 } else if (location_in_root.x() >= display_area.right() - 1) { | |
153 if (location_in_root.y() < alternate_bounds.height() && | |
154 ((in_primary && secondary_display_layout_ == RIGHT) || | |
155 (!in_primary && secondary_display_layout_ == LEFT))) { | |
156 alternate_point = gfx::Point(location_in_root.x() - display_area.right(), | |
157 location_in_root.y()); | |
158 } else { | |
159 alternate_root = NULL; | |
160 } | |
161 } else if (location_in_root.y() < display_area.y()) { | |
162 if (location_in_root.x() < alternate_bounds.width() && | |
163 ((in_primary && secondary_display_layout_ == TOP) || | |
164 (!in_primary && secondary_display_layout_ == BOTTOM))) { | |
165 alternate_point = gfx::Point( | |
166 location_in_root.x(), | |
167 alternate_bounds.bottom() - | |
168 (location_in_root.y() - display_area.y())); | |
169 } else { | |
170 alternate_root = NULL; | |
171 } | |
172 } else if (location_in_root.y() >= display_area.bottom() - 1) { | |
173 if (location_in_root.x() < alternate_bounds.width() && | |
174 ((in_primary && secondary_display_layout_ == BOTTOM) || | |
175 (!in_primary && secondary_display_layout_ == TOP))) { | |
176 alternate_point = gfx::Point( | |
177 location_in_root.x(), location_in_root.y() - display_area.bottom()); | |
178 } else { | |
179 alternate_root = NULL; | |
180 } | |
181 } else { | |
182 alternate_root = NULL; | |
183 } | |
184 if (alternate_root) { | |
185 DCHECK_NE(alternate_root, current_root); | |
186 alternate_root->MoveCursorTo(alternate_point); | |
187 return true; | |
188 } | |
189 return false; | |
190 } | |
191 | |
192 void MonitorController::OnDisplayBoundsChanged(const gfx::Display& display) { | |
193 root_windows_[display.id()]->SetHostBounds(display.bounds_in_pixel()); | |
194 } | |
195 | |
196 void MonitorController::OnDisplayAdded(const gfx::Display& display) { | |
197 if (root_windows_.empty()) { | |
198 DCHECK_EQ(0, display.id()); | |
199 root_windows_[display.id()] = Shell::GetPrimaryRootWindow(); | |
200 Shell::GetPrimaryRootWindow()->SetHostBounds(display.bounds_in_pixel()); | |
201 return; | |
202 } | |
203 aura::RootWindow* root = AddRootWindowForDisplay(display); | |
204 Shell::GetInstance()->InitRootWindowForSecondaryMonitor(root); | |
205 } | |
206 | |
207 void MonitorController::OnDisplayRemoved(const gfx::Display& display) { | |
208 aura::RootWindow* root = root_windows_[display.id()]; | |
209 DCHECK(root); | |
210 // Primary monitor should never be removed by MonitorManager. | |
211 DCHECK(root != Shell::GetPrimaryRootWindow()); | |
212 // Monitor for root window will be deleted when the Primary RootWindow | |
213 // is deleted by the Shell. | |
214 if (root != Shell::GetPrimaryRootWindow()) { | |
215 root_windows_.erase(display.id()); | |
216 internal::RootWindowController* controller = | |
217 wm::GetRootWindowController(root); | |
218 if (controller) { | |
219 controller->MoveWindowsTo(Shell::GetPrimaryRootWindow()); | |
220 delete controller; | |
221 } else { | |
222 delete root; | |
223 } | |
224 } | |
225 } | |
226 | |
227 // static | |
228 bool MonitorController::IsExtendedDesktopEnabled(){ | |
229 return extended_desktop_enabled || | |
230 CommandLine::ForCurrentProcess()->HasSwitch( | |
231 switches::kAshExtendedDesktop); | |
232 } | |
233 | |
234 // static | |
235 void MonitorController::SetExtendedDesktopEnabled(bool enabled) { | |
236 extended_desktop_enabled = enabled; | |
237 } | |
238 | |
239 // static | |
240 bool MonitorController::IsVirtualScreenCoordinatesEnabled() { | |
241 return virtual_screen_coordinates_enabled || | |
242 CommandLine::ForCurrentProcess()->HasSwitch( | |
243 switches::kAshVirtualScreenCoordinates); | |
244 } | |
245 | |
246 // static | |
247 void MonitorController::SetVirtualScreenCoordinatesEnabled(bool enabled) { | |
248 virtual_screen_coordinates_enabled = enabled; | |
249 } | |
250 | |
251 aura::RootWindow* MonitorController::AddRootWindowForDisplay( | |
252 const gfx::Display& display) { | |
253 aura::RootWindow* root = aura::Env::GetInstance()->monitor_manager()-> | |
254 CreateRootWindowForMonitor(display); | |
255 root_windows_[display.id()] = root; | |
256 // Confine the cursor within the window if | |
257 // 1) Extended desktop is enabled or | |
258 // 2) the display is primary monitor and the host window | |
259 // is set to be fullscreen (this is old behavior). | |
260 if (IsExtendedDesktopEnabled() || | |
261 (aura::MonitorManager::use_fullscreen_host_window() && | |
262 display.id() == 0)) { | |
263 root->ConfineCursorToWindow(); | |
264 } | |
265 return root; | |
266 } | |
267 | |
268 } // namespace internal | |
269 } // namespace ash | |
OLD | NEW |