Chromium Code Reviews| OLD | NEW |
|---|---|
| 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/display/display_controller.h" | 5 #include "ash/display/display_controller.h" |
| 6 | 6 |
| 7 #include <algorithm> | 7 #include <algorithm> |
| 8 | 8 |
| 9 #include "ash/ash_switches.h" | 9 #include "ash/ash_switches.h" |
| 10 #include "ash/display/multi_display_manager.h" | 10 #include "ash/display/multi_display_manager.h" |
| 11 #include "ash/root_window_controller.h" | 11 #include "ash/root_window_controller.h" |
| 12 #include "ash/screen_ash.h" | |
| 13 #include "ash/shell.h" | 12 #include "ash/shell.h" |
| 14 #include "ash/wm/coordinate_conversion.h" | 13 #include "ash/wm/coordinate_conversion.h" |
| 15 #include "ash/wm/property_util.h" | 14 #include "ash/wm/property_util.h" |
| 16 #include "ash/wm/window_util.h" | 15 #include "ash/wm/window_util.h" |
| 17 #include "base/command_line.h" | 16 #include "base/command_line.h" |
| 18 #include "base/json/json_value_converter.h" | 17 #include "base/json/json_value_converter.h" |
| 19 #include "base/string_piece.h" | 18 #include "base/string_piece.h" |
| 19 #include "base/stringprintf.h" | |
| 20 #include "base/values.h" | 20 #include "base/values.h" |
| 21 #include "ui/aura/client/screen_position_client.h" | 21 #include "ui/aura/client/screen_position_client.h" |
| 22 #include "ui/aura/env.h" | 22 #include "ui/aura/env.h" |
| 23 #include "ui/aura/root_window.h" | 23 #include "ui/aura/root_window.h" |
| 24 #include "ui/aura/window.h" | 24 #include "ui/aura/window.h" |
| 25 #include "ui/compositor/dip_util.h" | 25 #include "ui/compositor/dip_util.h" |
| 26 #include "ui/gfx/display.h" | 26 #include "ui/gfx/display.h" |
| 27 #include "ui/gfx/screen.h" | 27 #include "ui/gfx/screen.h" |
| 28 | 28 |
| 29 #if defined(OS_CHROMEOS) | 29 #if defined(OS_CHROMEOS) |
| (...skipping 20 matching lines...) Expand all Loading... | |
| 50 *field = DisplayLayout::BOTTOM; | 50 *field = DisplayLayout::BOTTOM; |
| 51 return true; | 51 return true; |
| 52 } else if (position == "right") { | 52 } else if (position == "right") { |
| 53 *field = DisplayLayout::RIGHT; | 53 *field = DisplayLayout::RIGHT; |
| 54 return true; | 54 return true; |
| 55 } else if (position == "left") { | 55 } else if (position == "left") { |
| 56 *field = DisplayLayout::LEFT; | 56 *field = DisplayLayout::LEFT; |
| 57 return true; | 57 return true; |
| 58 } | 58 } |
| 59 LOG(ERROR) << "Invalid position value: " << position; | 59 LOG(ERROR) << "Invalid position value: " << position; |
| 60 return false; | |
| 61 } | |
| 60 | 62 |
| 61 return false; | 63 std::string GetStringFromPosition(DisplayLayout::Position position) { |
| 64 switch (position) { | |
| 65 case DisplayLayout::TOP: | |
| 66 return std::string("top"); | |
| 67 case DisplayLayout::BOTTOM: | |
| 68 return std::string("bottom"); | |
| 69 case DisplayLayout::RIGHT: | |
| 70 return std::string("right"); | |
| 71 case DisplayLayout::LEFT: | |
| 72 return std::string("left"); | |
| 73 default: | |
|
sky
2012/09/18 03:52:47
remove default and put NOTREACHED outside of switc
oshima
2012/09/18 09:30:48
Done.
| |
| 74 NOTREACHED() << "unknown position value:" << position; | |
| 75 return std::string("unknown"); | |
| 76 } | |
| 77 } | |
| 78 | |
| 79 internal::MultiDisplayManager* GetDisplayManager() { | |
| 80 return static_cast<internal::MultiDisplayManager*>( | |
| 81 aura::Env::GetInstance()->display_manager()); | |
| 62 } | 82 } |
| 63 | 83 |
| 64 } // namespace | 84 } // namespace |
| 65 | 85 |
| 66 DisplayLayout::DisplayLayout() | 86 DisplayLayout::DisplayLayout() |
| 67 : position(RIGHT), | 87 : position(RIGHT), |
| 68 offset(0) {} | 88 offset(0) {} |
| 69 | 89 |
| 70 DisplayLayout::DisplayLayout(DisplayLayout::Position position, int offset) | 90 DisplayLayout::DisplayLayout(DisplayLayout::Position position, int offset) |
| 71 : position(position), | 91 : position(position), |
| 72 offset(offset) { | 92 offset(offset) { |
| 73 DCHECK_LE(TOP, position); | 93 DCHECK_LE(TOP, position); |
| 74 DCHECK_GE(LEFT, position); | 94 DCHECK_GE(LEFT, position); |
| 75 | 95 |
| 76 // Set the default value to |position| in case position is invalid. DCHECKs | 96 // Set the default value to |position| in case position is invalid. DCHECKs |
| 77 // above doesn't stop in Release builds. | 97 // above doesn't stop in Release builds. |
| 78 if (TOP > position || LEFT < position) | 98 if (TOP > position || LEFT < position) |
| 79 this->position = RIGHT; | 99 this->position = RIGHT; |
| 80 | 100 |
| 81 DCHECK_GE(kMaxValidOffset, abs(offset)); | 101 DCHECK_GE(kMaxValidOffset, abs(offset)); |
| 82 } | 102 } |
| 83 | 103 |
| 104 DisplayLayout DisplayLayout::Invert() const { | |
| 105 Position inverted_position = RIGHT; | |
| 106 switch (position) { | |
| 107 case TOP: | |
| 108 inverted_position = BOTTOM; | |
| 109 break; | |
| 110 case BOTTOM: | |
| 111 inverted_position = TOP; | |
| 112 break; | |
| 113 case RIGHT: | |
| 114 inverted_position = LEFT; | |
| 115 break; | |
| 116 case LEFT: | |
| 117 inverted_position = RIGHT; | |
| 118 break; | |
| 119 default: | |
|
sky
2012/09/18 03:52:47
Saem comment as line 73 above.
oshima
2012/09/18 09:30:48
Done.
| |
| 120 NOTREACHED(); | |
| 121 } | |
| 122 return DisplayLayout(inverted_position, -offset); | |
| 123 } | |
| 124 | |
| 84 // static | 125 // static |
| 85 bool DisplayLayout::ConvertFromValue(const base::Value& value, | 126 bool DisplayLayout::ConvertFromValue(const base::Value& value, |
| 86 DisplayLayout* layout) { | 127 DisplayLayout* layout) { |
| 87 base::JSONValueConverter<DisplayLayout> converter; | 128 base::JSONValueConverter<DisplayLayout> converter; |
| 88 return converter.Convert(value, layout); | 129 return converter.Convert(value, layout); |
| 89 } | 130 } |
| 90 | 131 |
| 91 // static | 132 // static |
| 92 bool DisplayLayout::ConvertToValue(const DisplayLayout& layout, | 133 bool DisplayLayout::ConvertToValue(const DisplayLayout& layout, |
| 93 base::Value* value) { | 134 base::Value* value) { |
| 94 base::DictionaryValue* dict_value = NULL; | 135 base::DictionaryValue* dict_value = NULL; |
| 95 if (!value->GetAsDictionary(&dict_value) || dict_value == NULL) | 136 if (!value->GetAsDictionary(&dict_value) || dict_value == NULL) |
| 96 return false; | 137 return false; |
| 97 | 138 |
| 98 std::string position_value; | 139 const std::string position_str = GetStringFromPosition(layout.position); |
| 99 switch (layout.position) { | 140 dict_value->SetString("position", position_str); |
| 100 case TOP: | |
| 101 position_value = "top"; | |
| 102 break; | |
| 103 case BOTTOM: | |
| 104 position_value = "bottom"; | |
| 105 break; | |
| 106 case RIGHT: | |
| 107 position_value = "right"; | |
| 108 break; | |
| 109 case LEFT: | |
| 110 position_value = "left"; | |
| 111 break; | |
| 112 default: | |
| 113 return false; | |
| 114 } | |
| 115 | |
| 116 dict_value->SetString("position", position_value); | |
| 117 dict_value->SetInteger("offset", layout.offset); | 141 dict_value->SetInteger("offset", layout.offset); |
| 118 return true; | 142 return true; |
| 119 } | 143 } |
| 120 | 144 |
| 145 std::string DisplayLayout::ToString() const { | |
| 146 const std::string position_str = GetStringFromPosition(position); | |
| 147 return StringPrintf("%s, %d", position_str.c_str(), offset); | |
| 148 } | |
| 149 | |
| 121 // static | 150 // static |
| 122 void DisplayLayout::RegisterJSONConverter( | 151 void DisplayLayout::RegisterJSONConverter( |
| 123 base::JSONValueConverter<DisplayLayout>* converter) { | 152 base::JSONValueConverter<DisplayLayout>* converter) { |
| 124 converter->RegisterCustomField<Position>( | 153 converter->RegisterCustomField<Position>( |
| 125 "position", &DisplayLayout::position, &GetPositionFromString); | 154 "position", &DisplayLayout::position, &GetPositionFromString); |
| 126 converter->RegisterIntField("offset", &DisplayLayout::offset); | 155 converter->RegisterIntField("offset", &DisplayLayout::offset); |
| 127 } | 156 } |
| 128 | 157 |
| 129 DisplayController::DisplayController() { | 158 DisplayController::DisplayController() { |
| 130 aura::Env::GetInstance()->display_manager()->AddObserver(this); | 159 GetDisplayManager()->AddObserver(this); |
| 131 } | 160 } |
| 132 | 161 |
| 133 DisplayController::~DisplayController() { | 162 DisplayController::~DisplayController() { |
| 134 aura::Env::GetInstance()->display_manager()->RemoveObserver(this); | 163 GetDisplayManager()->RemoveObserver(this); |
| 135 // Delete all root window controllers, which deletes root window | 164 // Delete all root window controllers, which deletes root window |
| 136 // from the last so that the primary root window gets deleted last. | 165 // from the last so that the primary root window gets deleted last. |
| 137 for (std::map<int64, aura::RootWindow*>::const_reverse_iterator it = | 166 for (std::map<int64, aura::RootWindow*>::const_reverse_iterator it = |
| 138 root_windows_.rbegin(); it != root_windows_.rend(); ++it) { | 167 root_windows_.rbegin(); it != root_windows_.rend(); ++it) { |
| 139 internal::RootWindowController* controller = | 168 internal::RootWindowController* controller = |
| 140 GetRootWindowController(it->second); | 169 GetRootWindowController(it->second); |
| 141 DCHECK(controller); | 170 DCHECK(controller); |
| 142 delete controller; | 171 delete controller; |
| 143 } | 172 } |
| 144 } | 173 } |
| 145 | 174 |
| 146 void DisplayController::InitPrimaryDisplay() { | 175 void DisplayController::InitPrimaryDisplay() { |
| 147 aura::DisplayManager* display_manager = | 176 const gfx::Display* primary_candidate = GetDisplayManager()->GetDisplayAt(0); |
| 148 aura::Env::GetInstance()->display_manager(); | 177 #if defined(OS_CHROMEOS) |
| 149 const gfx::Display* display = display_manager->GetDisplayAt(0); | 178 if (base::chromeos::IsRunningOnChromeOS()) { |
| 150 aura::RootWindow* root = AddRootWindowForDisplay(*display); | 179 // On ChromeOS device, root windows are stacked vertically, and |
| 151 root->SetHostBounds(display->bounds_in_pixel()); | 180 // default primary is the one on top. |
| 181 internal::MultiDisplayManager* display_manager = GetDisplayManager(); | |
| 182 int count = display_manager->GetNumDisplays(); | |
| 183 int y = primary_candidate->bounds_in_pixel().y(); | |
| 184 for (int i = 1; i < count; ++i) { | |
| 185 const gfx::Display* display = display_manager->GetDisplayAt(i); | |
| 186 if (display->bounds_in_pixel().y() < y) { | |
| 187 primary_candidate = display; | |
| 188 y = display->bounds_in_pixel().y(); | |
| 189 } | |
| 190 } | |
| 191 } | |
| 192 #endif | |
| 193 primary_display_ = *primary_candidate; | |
| 194 aura::RootWindow* root = AddRootWindowForDisplay(primary_display_); | |
| 195 root->SetHostBounds(primary_display_.bounds_in_pixel()); | |
| 152 } | 196 } |
| 153 | 197 |
| 154 void DisplayController::InitSecondaryDisplays() { | 198 void DisplayController::InitSecondaryDisplays() { |
| 155 aura::DisplayManager* display_manager = | 199 internal::MultiDisplayManager* display_manager = GetDisplayManager(); |
| 156 aura::Env::GetInstance()->display_manager(); | |
| 157 for (size_t i = 1; i < display_manager->GetNumDisplays(); ++i) { | 200 for (size_t i = 1; i < display_manager->GetNumDisplays(); ++i) { |
| 158 const gfx::Display* display = display_manager->GetDisplayAt(i); | 201 const gfx::Display* display = display_manager->GetDisplayAt(i); |
| 159 aura::RootWindow* root = AddRootWindowForDisplay(*display); | 202 aura::RootWindow* root = AddRootWindowForDisplay(*display); |
| 160 Shell::GetInstance()->InitRootWindowForSecondaryDisplay(root); | 203 Shell::GetInstance()->InitRootWindowForSecondaryDisplay(root); |
| 161 } | 204 } |
| 162 CommandLine* command_line = CommandLine::ForCurrentProcess(); | 205 CommandLine* command_line = CommandLine::ForCurrentProcess(); |
| 163 if (command_line->HasSwitch(switches::kAshSecondaryDisplayLayout)) { | 206 if (command_line->HasSwitch(switches::kAshSecondaryDisplayLayout)) { |
| 164 std::string value = command_line->GetSwitchValueASCII( | 207 std::string value = command_line->GetSwitchValueASCII( |
| 165 switches::kAshSecondaryDisplayLayout); | 208 switches::kAshSecondaryDisplayLayout); |
| 166 char layout; | 209 char layout; |
| (...skipping 16 matching lines...) Expand all Loading... | |
| 183 void DisplayController::AddObserver(Observer* observer) { | 226 void DisplayController::AddObserver(Observer* observer) { |
| 184 observers_.AddObserver(observer); | 227 observers_.AddObserver(observer); |
| 185 } | 228 } |
| 186 | 229 |
| 187 void DisplayController::RemoveObserver(Observer* observer) { | 230 void DisplayController::RemoveObserver(Observer* observer) { |
| 188 observers_.RemoveObserver(observer); | 231 observers_.RemoveObserver(observer); |
| 189 } | 232 } |
| 190 | 233 |
| 191 aura::RootWindow* DisplayController::GetPrimaryRootWindow() { | 234 aura::RootWindow* DisplayController::GetPrimaryRootWindow() { |
| 192 DCHECK(!root_windows_.empty()); | 235 DCHECK(!root_windows_.empty()); |
| 193 aura::DisplayManager* display_manager = | 236 return root_windows_[primary_display_.id()]; |
| 194 aura::Env::GetInstance()->display_manager(); | |
| 195 return root_windows_[display_manager->GetDisplayAt(0)->id()]; | |
| 196 } | 237 } |
| 197 | 238 |
| 198 aura::RootWindow* DisplayController::GetRootWindowForDisplayId(int64 id) { | 239 aura::RootWindow* DisplayController::GetRootWindowForDisplayId(int64 id) { |
| 199 return root_windows_[id]; | 240 return root_windows_[id]; |
| 200 } | 241 } |
| 201 | 242 |
| 202 void DisplayController::CloseChildWindows() { | 243 void DisplayController::CloseChildWindows() { |
| 203 for (std::map<int64, aura::RootWindow*>::const_iterator it = | 244 for (std::map<int64, aura::RootWindow*>::const_iterator it = |
| 204 root_windows_.begin(); it != root_windows_.end(); ++it) { | 245 root_windows_.begin(); it != root_windows_.end(); ++it) { |
| 205 aura::RootWindow* root_window = it->second; | 246 aura::RootWindow* root_window = it->second; |
| (...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 253 const DisplayLayout& layout) { | 294 const DisplayLayout& layout) { |
| 254 DisplayLayout& display_for_name = secondary_layouts_[name]; | 295 DisplayLayout& display_for_name = secondary_layouts_[name]; |
| 255 if (display_for_name.position != layout.position || | 296 if (display_for_name.position != layout.position || |
| 256 display_for_name.offset != layout.offset) { | 297 display_for_name.offset != layout.offset) { |
| 257 secondary_layouts_[name] = layout; | 298 secondary_layouts_[name] = layout; |
| 258 NotifyDisplayConfigurationChanging(); | 299 NotifyDisplayConfigurationChanging(); |
| 259 UpdateDisplayBoundsForLayout(); | 300 UpdateDisplayBoundsForLayout(); |
| 260 } | 301 } |
| 261 } | 302 } |
| 262 | 303 |
| 263 const DisplayLayout& DisplayController::GetLayoutForDisplayName( | 304 const DisplayLayout& DisplayController::GetLayoutForDisplay( |
| 264 const std::string& name) { | 305 const gfx::Display& display) { |
| 306 const std::string& name = GetDisplayManager()->GetDisplayNameFor(display); | |
| 265 std::map<std::string, DisplayLayout>::const_iterator it = | 307 std::map<std::string, DisplayLayout>::const_iterator it = |
| 266 secondary_layouts_.find(name); | 308 secondary_layouts_.find(name); |
| 267 | 309 |
| 268 if (it != secondary_layouts_.end()) | 310 if (it != secondary_layouts_.end()) |
| 269 return it->second; | 311 return it->second; |
| 270 return default_display_layout_; | 312 return default_display_layout_; |
| 271 } | 313 } |
| 272 | 314 |
| 315 void DisplayController::SetPrimaryDisplay( | |
| 316 const gfx::Display& new_primary_display) { | |
| 317 internal::MultiDisplayManager* display_manager = GetDisplayManager(); | |
| 318 DCHECK(new_primary_display.is_valid()); | |
| 319 DCHECK(display_manager->IsActiveDisplay(new_primary_display)); | |
| 320 | |
| 321 if (!new_primary_display.is_valid() || | |
| 322 !display_manager->IsActiveDisplay(new_primary_display)) { | |
| 323 LOG(ERROR) << "Invalid or non-existent display is requested:" | |
| 324 << new_primary_display.ToString(); | |
| 325 return; | |
| 326 } | |
| 327 | |
| 328 if (primary_display_.id() == new_primary_display.id() || | |
| 329 root_windows_.size() < 2) { | |
| 330 return; | |
| 331 } | |
| 332 | |
| 333 aura::RootWindow* non_primary_root = root_windows_[new_primary_display.id()]; | |
| 334 LOG_IF(ERROR, !non_primary_root) | |
| 335 << "Unknown display is requested in SetPrimaryDisplay: id=" | |
| 336 << new_primary_display.id(); | |
| 337 if (!non_primary_root) | |
| 338 return; | |
| 339 | |
| 340 gfx::Display old_primary_display = primary_display_; | |
| 341 | |
| 342 // Swap root windows between current and new primary display. | |
| 343 aura::RootWindow* primary_root = root_windows_[primary_display_.id()]; | |
| 344 DCHECK(primary_root); | |
| 345 DCHECK_NE(primary_root, non_primary_root); | |
| 346 | |
| 347 root_windows_[new_primary_display.id()] = primary_root; | |
| 348 primary_root->SetProperty(internal::kDisplayIdKey, new_primary_display.id()); | |
| 349 | |
| 350 root_windows_[old_primary_display.id()] = non_primary_root; | |
| 351 non_primary_root->SetProperty(internal::kDisplayIdKey, | |
| 352 old_primary_display.id()); | |
| 353 | |
| 354 primary_display_ = new_primary_display; | |
| 355 // The primary's origin is 0.0. | |
| 356 gfx::Rect bounds = primary_display_.bounds(); | |
| 357 bounds.set_origin(gfx::Point(0, 0)); // primary should be at (0, 0); | |
| 358 primary_display_.set_bounds(bounds); | |
| 359 | |
| 360 // Update the layout. | |
| 361 const DisplayLayout& layout = GetLayoutForDisplay(new_primary_display); | |
| 362 SetLayoutForDisplayName( | |
| 363 display_manager->GetDisplayNameFor(old_primary_display), | |
| 364 layout.Invert()); | |
| 365 | |
| 366 // Update the dispay manager with new display info. | |
| 367 std::vector<gfx::Display> displays; | |
| 368 displays.push_back(primary_display_); | |
| 369 displays.push_back(GetSecondaryDisplay()); | |
| 370 GetDisplayManager()->set_force_bounds_changed(true); | |
| 371 GetDisplayManager()->OnNativeDisplaysChanged(displays); | |
| 372 GetDisplayManager()->set_force_bounds_changed(false); | |
| 373 } | |
| 374 | |
| 375 const gfx::Display& DisplayController::GetSecondaryDisplay() const { | |
| 376 internal::MultiDisplayManager* display_manager = GetDisplayManager(); | |
| 377 CHECK_EQ(2U, display_manager->GetNumDisplays()); | |
| 378 return display_manager->GetDisplayAt(0)->id() == primary_display_.id() ? | |
| 379 *display_manager->GetDisplayAt(1) : *display_manager->GetDisplayAt(0); | |
| 380 } | |
| 381 | |
| 273 void DisplayController::OnDisplayBoundsChanged(const gfx::Display& display) { | 382 void DisplayController::OnDisplayBoundsChanged(const gfx::Display& display) { |
| 383 if (display.id() == primary_display_.id()) | |
| 384 primary_display_ = display; | |
| 274 NotifyDisplayConfigurationChanging(); | 385 NotifyDisplayConfigurationChanging(); |
| 386 UpdateDisplayBoundsForLayout(); | |
| 275 root_windows_[display.id()]->SetHostBounds(display.bounds_in_pixel()); | 387 root_windows_[display.id()]->SetHostBounds(display.bounds_in_pixel()); |
| 276 UpdateDisplayBoundsForLayout(); | |
| 277 } | 388 } |
| 278 | 389 |
| 279 void DisplayController::OnDisplayAdded(const gfx::Display& display) { | 390 void DisplayController::OnDisplayAdded(const gfx::Display& display) { |
| 280 DCHECK(!root_windows_.empty()); | 391 DCHECK(!root_windows_.empty()); |
| 281 NotifyDisplayConfigurationChanging(); | 392 NotifyDisplayConfigurationChanging(); |
| 282 aura::RootWindow* root = AddRootWindowForDisplay(display); | 393 aura::RootWindow* root = AddRootWindowForDisplay(display); |
| 283 Shell::GetInstance()->InitRootWindowForSecondaryDisplay(root); | 394 Shell::GetInstance()->InitRootWindowForSecondaryDisplay(root); |
| 284 UpdateDisplayBoundsForLayout(); | 395 UpdateDisplayBoundsForLayout(); |
| 285 } | 396 } |
| 286 | 397 |
| 287 void DisplayController::OnDisplayRemoved(const gfx::Display& display) { | 398 void DisplayController::OnDisplayRemoved(const gfx::Display& display) { |
| 288 aura::RootWindow* root = root_windows_[display.id()]; | 399 aura::RootWindow* root_to_delete = root_windows_[display.id()]; |
| 289 DCHECK(root); | 400 DCHECK(root_to_delete); |
| 290 // Primary display should never be removed by DisplayManager. | |
| 291 DCHECK(root != GetPrimaryRootWindow()); | |
| 292 NotifyDisplayConfigurationChanging(); | 401 NotifyDisplayConfigurationChanging(); |
| 402 | |
| 293 // Display for root window will be deleted when the Primary RootWindow | 403 // Display for root window will be deleted when the Primary RootWindow |
| 294 // is deleted by the Shell. | 404 // is deleted by the Shell. |
| 295 if (root != GetPrimaryRootWindow()) { | 405 root_windows_.erase(display.id()); |
| 296 root_windows_.erase(display.id()); | 406 |
| 297 internal::RootWindowController* controller = | 407 // When the primary root window's display is removed, move the primary |
| 298 GetRootWindowController(root); | 408 // root to the other display. |
| 299 DCHECK(controller); | 409 if (primary_display_.id() == display.id()) { |
| 300 controller->MoveWindowsTo(GetPrimaryRootWindow()); | 410 DCHECK_EQ(1U, root_windows_.size()); |
| 301 // Delete most of root window related objects, but don't delete | 411 primary_display_ = GetSecondaryDisplay(); |
| 302 // root window itself yet because the stak may be using it. | 412 aura::RootWindow* primary_root = root_to_delete; |
| 303 controller->Shutdown(); | 413 |
| 304 MessageLoop::current()->DeleteSoon(FROM_HERE, controller); | 414 // Delete the other root instead. |
| 415 root_to_delete = root_windows_[primary_display_.id()]; | |
| 416 root_to_delete->SetProperty(internal::kDisplayIdKey, display.id()); | |
| 417 | |
| 418 // Setup primary root. | |
| 419 root_windows_[primary_display_.id()] = primary_root; | |
| 420 primary_root->SetProperty(internal::kDisplayIdKey, primary_display_.id()); | |
| 421 | |
| 422 std::vector<gfx::Display> displays; | |
| 423 displays.push_back(primary_display_); | |
| 424 GetDisplayManager()->set_force_bounds_changed(true); | |
| 425 GetDisplayManager()->OnNativeDisplaysChanged(displays); | |
| 426 GetDisplayManager()->set_force_bounds_changed(false); | |
| 305 } | 427 } |
| 428 internal::RootWindowController* controller = | |
| 429 GetRootWindowController(root_to_delete); | |
| 430 DCHECK(controller); | |
| 431 controller->MoveWindowsTo(GetPrimaryRootWindow()); | |
| 432 // Delete most of root window related objects, but don't delete | |
| 433 // root window itself yet because the stak may be using it. | |
| 434 controller->Shutdown(); | |
| 435 MessageLoop::current()->DeleteSoon(FROM_HERE, controller); | |
| 306 } | 436 } |
| 307 | 437 |
| 308 aura::RootWindow* DisplayController::AddRootWindowForDisplay( | 438 aura::RootWindow* DisplayController::AddRootWindowForDisplay( |
| 309 const gfx::Display& display) { | 439 const gfx::Display& display) { |
| 310 static bool force_constrain_pointer_to_root = | 440 static bool force_constrain_pointer_to_root = |
| 311 CommandLine::ForCurrentProcess()->HasSwitch( | 441 CommandLine::ForCurrentProcess()->HasSwitch( |
| 312 switches::kAshConstrainPointerToRoot); | 442 switches::kAshConstrainPointerToRoot); |
| 313 | 443 |
| 314 aura::RootWindow* root = aura::Env::GetInstance()->display_manager()-> | 444 aura::RootWindow* root = |
| 315 CreateRootWindowForDisplay(display); | 445 GetDisplayManager()->CreateRootWindowForDisplay(display); |
| 316 root_windows_[display.id()] = root; | 446 root_windows_[display.id()] = root; |
| 317 | 447 |
| 318 #if defined(OS_CHROMEOS) | 448 #if defined(OS_CHROMEOS) |
| 319 if (base::chromeos::IsRunningOnChromeOS() || force_constrain_pointer_to_root) | 449 if (base::chromeos::IsRunningOnChromeOS() || force_constrain_pointer_to_root) |
| 320 root->ConfineCursorToWindow(); | 450 root->ConfineCursorToWindow(); |
| 321 #endif | 451 #endif |
| 322 return root; | 452 return root; |
| 323 } | 453 } |
| 324 | 454 |
| 325 void DisplayController::UpdateDisplayBoundsForLayout() { | 455 void DisplayController::UpdateDisplayBoundsForLayout() { |
| 326 if (gfx::Screen::GetNumDisplays() <= 1) | 456 if (gfx::Screen::GetNumDisplays() <= 1) |
| 327 return; | 457 return; |
| 328 | 458 |
| 329 DCHECK_EQ(2, gfx::Screen::GetNumDisplays()); | 459 DCHECK_EQ(2, gfx::Screen::GetNumDisplays()); |
| 330 aura::DisplayManager* display_manager = | 460 aura::DisplayManager* display_manager = GetDisplayManager(); |
| 331 aura::Env::GetInstance()->display_manager(); | 461 const gfx::Rect& primary_bounds = primary_display_.bounds(); |
| 332 const gfx::Rect& primary_bounds = display_manager->GetDisplayAt(0)->bounds(); | 462 |
| 333 gfx::Display* secondary_display = display_manager->GetDisplayAt(1); | 463 gfx::Display* secondary_display = |
| 334 const std::string& secondary_name = display_manager->GetDisplayNameAt(1); | 464 primary_display_.id() == display_manager->GetDisplayAt(0)->id() ? |
| 465 display_manager->GetDisplayAt(1) : | |
| 466 display_manager->GetDisplayAt(0); | |
| 335 const gfx::Rect& secondary_bounds = secondary_display->bounds(); | 467 const gfx::Rect& secondary_bounds = secondary_display->bounds(); |
| 336 gfx::Point new_secondary_origin = primary_bounds.origin(); | 468 gfx::Point new_secondary_origin = primary_bounds.origin(); |
| 337 | 469 |
| 338 const DisplayLayout* layout = &default_display_layout_; | 470 const DisplayLayout& layout = GetLayoutForDisplay(*secondary_display); |
| 339 std::map<std::string, DisplayLayout>::const_iterator iter = | |
| 340 secondary_layouts_.find(secondary_name); | |
| 341 if (iter != secondary_layouts_.end()) | |
| 342 layout = &iter->second; | |
| 343 | 471 |
| 344 DisplayLayout::Position position = layout->position; | 472 DisplayLayout::Position position = layout.position; |
| 345 | 473 |
| 346 // Ignore the offset in case the secondary display doesn't share edges with | 474 // Ignore the offset in case the secondary display doesn't share edges with |
| 347 // the primary display. | 475 // the primary display. |
| 348 int offset = layout->offset; | 476 int offset = layout.offset; |
| 349 if (position == DisplayLayout::TOP || position == DisplayLayout::BOTTOM) { | 477 if (position == DisplayLayout::TOP || position == DisplayLayout::BOTTOM) { |
| 350 offset = std::min( | 478 offset = std::min( |
| 351 offset, primary_bounds.width() - kMinimumOverlapForInvalidOffset); | 479 offset, primary_bounds.width() - kMinimumOverlapForInvalidOffset); |
| 352 offset = std::max( | 480 offset = std::max( |
| 353 offset, -secondary_bounds.width() + kMinimumOverlapForInvalidOffset); | 481 offset, -secondary_bounds.width() + kMinimumOverlapForInvalidOffset); |
| 354 } else { | 482 } else { |
| 355 offset = std::min( | 483 offset = std::min( |
| 356 offset, primary_bounds.height() - kMinimumOverlapForInvalidOffset); | 484 offset, primary_bounds.height() - kMinimumOverlapForInvalidOffset); |
| 357 offset = std::max( | 485 offset = std::max( |
| 358 offset, -secondary_bounds.height() + kMinimumOverlapForInvalidOffset); | 486 offset, -secondary_bounds.height() + kMinimumOverlapForInvalidOffset); |
| (...skipping 16 matching lines...) Expand all Loading... | |
| 375 secondary_display->set_bounds( | 503 secondary_display->set_bounds( |
| 376 gfx::Rect(new_secondary_origin, secondary_bounds.size())); | 504 gfx::Rect(new_secondary_origin, secondary_bounds.size())); |
| 377 secondary_display->UpdateWorkAreaFromInsets(insets); | 505 secondary_display->UpdateWorkAreaFromInsets(insets); |
| 378 } | 506 } |
| 379 | 507 |
| 380 void DisplayController::NotifyDisplayConfigurationChanging() { | 508 void DisplayController::NotifyDisplayConfigurationChanging() { |
| 381 FOR_EACH_OBSERVER(Observer, observers_, OnDisplayConfigurationChanging()); | 509 FOR_EACH_OBSERVER(Observer, observers_, OnDisplayConfigurationChanging()); |
| 382 } | 510 } |
| 383 | 511 |
| 384 } // namespace ash | 512 } // namespace ash |
| OLD | NEW |