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