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

Side by Side Diff: ash/display/display_controller.cc

Issue 10961021: Return primary display if out of bounds point or NULL ponter is passed to gfx::Screen::GeDisplayNea (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: fix a few other tests that were using native coordinate. it shoud use screen coordinate now. Created 8 years, 3 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/display/display_controller.h ('k') | ash/display/display_controller_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/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"
(...skipping 17 matching lines...) Expand all
28 28
29 #if defined(OS_CHROMEOS) 29 #if defined(OS_CHROMEOS)
30 #include "base/chromeos/chromeos_version.h" 30 #include "base/chromeos/chromeos_version.h"
31 #endif 31 #endif
32 32
33 namespace ash { 33 namespace ash {
34 namespace { 34 namespace {
35 35
36 // Primary display stored in global object as it can be 36 // Primary display stored in global object as it can be
37 // accessed after Shell is deleted. 37 // accessed after Shell is deleted.
38 gfx::Display* primary_display = NULL; 38 int64 primary_display_id = gfx::Display::kInvalidDisplayID;
39 39
40 // The maximum value for 'offset' in DisplayLayout in case of outliers. Need 40 // The maximum value for 'offset' in DisplayLayout in case of outliers. Need
41 // to change this value in case to support even larger displays. 41 // to change this value in case to support even larger displays.
42 const int kMaxValidOffset = 10000; 42 const int kMaxValidOffset = 10000;
43 43
44 // The number of pixels to overlap between the primary and secondary displays, 44 // The number of pixels to overlap between the primary and secondary displays,
45 // in case that the offset value is too large. 45 // in case that the offset value is too large.
46 const int kMinimumOverlapForInvalidOffset = 50; 46 const int kMinimumOverlapForInvalidOffset = 50;
47 47
48 bool GetPositionFromString(const base::StringPiece& position, 48 bool GetPositionFromString(const base::StringPiece& position,
(...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after
149 149
150 // static 150 // static
151 void DisplayLayout::RegisterJSONConverter( 151 void DisplayLayout::RegisterJSONConverter(
152 base::JSONValueConverter<DisplayLayout>* converter) { 152 base::JSONValueConverter<DisplayLayout>* converter) {
153 converter->RegisterCustomField<Position>( 153 converter->RegisterCustomField<Position>(
154 "position", &DisplayLayout::position, &GetPositionFromString); 154 "position", &DisplayLayout::position, &GetPositionFromString);
155 converter->RegisterIntField("offset", &DisplayLayout::offset); 155 converter->RegisterIntField("offset", &DisplayLayout::offset);
156 } 156 }
157 157
158 DisplayController::DisplayController() { 158 DisplayController::DisplayController() {
159 // Reinstantiate display to make sure that tests don't use 159 // Reset primary display to make sure that tests don't use
160 // stale display info from previous tests. 160 // stale display info from previous tests.
161 delete primary_display; 161 primary_display_id = gfx::Display::kInvalidDisplayID;
162 primary_display = new gfx::Display();
163 162
164 GetDisplayManager()->AddObserver(this); 163 GetDisplayManager()->AddObserver(this);
165 } 164 }
166 165
167 DisplayController::~DisplayController() { 166 DisplayController::~DisplayController() {
168 GetDisplayManager()->RemoveObserver(this); 167 GetDisplayManager()->RemoveObserver(this);
169 // Delete all root window controllers, which deletes root window 168 // Delete all root window controllers, which deletes root window
170 // from the last so that the primary root window gets deleted last. 169 // from the last so that the primary root window gets deleted last.
171 for (std::map<int64, aura::RootWindow*>::const_reverse_iterator it = 170 for (std::map<int64, aura::RootWindow*>::const_reverse_iterator it =
172 root_windows_.rbegin(); it != root_windows_.rend(); ++it) { 171 root_windows_.rbegin(); it != root_windows_.rend(); ++it) {
173 internal::RootWindowController* controller = 172 internal::RootWindowController* controller =
174 GetRootWindowController(it->second); 173 GetRootWindowController(it->second);
175 DCHECK(controller); 174 DCHECK(controller);
176 delete controller; 175 delete controller;
177 } 176 }
178 } 177 }
179 // static 178 // static
180 gfx::Display DisplayController::GetPrimaryDisplay() { 179 const gfx::Display& DisplayController::GetPrimaryDisplay() {
181 DCHECK(primary_display); 180 DCHECK_NE(primary_display_id, gfx::Display::kInvalidDisplayID);
182 return *primary_display; 181 return GetDisplayManager()->GetDisplayForId(primary_display_id);
183 } 182 }
184 183
185 void DisplayController::InitPrimaryDisplay() { 184 void DisplayController::InitPrimaryDisplay() {
186 const gfx::Display* primary_candidate = GetDisplayManager()->GetDisplayAt(0); 185 const gfx::Display* primary_candidate = GetDisplayManager()->GetDisplayAt(0);
187 #if defined(OS_CHROMEOS) 186 #if defined(OS_CHROMEOS)
188 if (base::chromeos::IsRunningOnChromeOS()) { 187 if (base::chromeos::IsRunningOnChromeOS()) {
189 internal::MultiDisplayManager* display_manager = GetDisplayManager(); 188 internal::MultiDisplayManager* display_manager = GetDisplayManager();
190 // On ChromeOS device, root windows are stacked vertically, and 189 // On ChromeOS device, root windows are stacked vertically, and
191 // default primary is the one on top. 190 // default primary is the one on top.
192 int count = display_manager->GetNumDisplays(); 191 int count = display_manager->GetNumDisplays();
193 int y = primary_candidate->bounds_in_pixel().y(); 192 int y = primary_candidate->bounds_in_pixel().y();
194 for (int i = 1; i < count; ++i) { 193 for (int i = 1; i < count; ++i) {
195 const gfx::Display* display = display_manager->GetDisplayAt(i); 194 const gfx::Display* display = display_manager->GetDisplayAt(i);
196 if (display_manager->IsInternalDisplayId(display->id())) { 195 if (display_manager->IsInternalDisplayId(display->id())) {
197 primary_candidate = display; 196 primary_candidate = display;
198 break; 197 break;
199 } else if (display->bounds_in_pixel().y() < y) { 198 } else if (display->bounds_in_pixel().y() < y) {
200 primary_candidate = display; 199 primary_candidate = display;
201 y = display->bounds_in_pixel().y(); 200 y = display->bounds_in_pixel().y();
202 } 201 }
203 } 202 }
204 } 203 }
205 #endif 204 #endif
206 *primary_display = *primary_candidate; 205 primary_display_id = primary_candidate->id();
207 aura::RootWindow* root = AddRootWindowForDisplay(*primary_display); 206 aura::RootWindow* root = AddRootWindowForDisplay(*primary_candidate);
208 root->SetHostBounds(primary_display->bounds_in_pixel()); 207 root->SetHostBounds(primary_candidate->bounds_in_pixel());
209 UpdateDisplayBoundsForLayout(); 208 UpdateDisplayBoundsForLayout();
210 } 209 }
211 210
212 void DisplayController::InitSecondaryDisplays() { 211 void DisplayController::InitSecondaryDisplays() {
213 internal::MultiDisplayManager* display_manager = GetDisplayManager(); 212 internal::MultiDisplayManager* display_manager = GetDisplayManager();
214 for (size_t i = 0; i < display_manager->GetNumDisplays(); ++i) { 213 for (size_t i = 0; i < display_manager->GetNumDisplays(); ++i) {
215 const gfx::Display* display = display_manager->GetDisplayAt(i); 214 const gfx::Display* display = display_manager->GetDisplayAt(i);
216 if (primary_display->id() != display->id()) { 215 if (primary_display_id != display->id()) {
217 aura::RootWindow* root = AddRootWindowForDisplay(*display); 216 aura::RootWindow* root = AddRootWindowForDisplay(*display);
218 Shell::GetInstance()->InitRootWindowForSecondaryDisplay(root); 217 Shell::GetInstance()->InitRootWindowForSecondaryDisplay(root);
219 } 218 }
220 } 219 }
221 CommandLine* command_line = CommandLine::ForCurrentProcess(); 220 CommandLine* command_line = CommandLine::ForCurrentProcess();
222 if (command_line->HasSwitch(switches::kAshSecondaryDisplayLayout)) { 221 if (command_line->HasSwitch(switches::kAshSecondaryDisplayLayout)) {
223 std::string value = command_line->GetSwitchValueASCII( 222 std::string value = command_line->GetSwitchValueASCII(
224 switches::kAshSecondaryDisplayLayout); 223 switches::kAshSecondaryDisplayLayout);
225 char layout; 224 char layout;
226 int offset; 225 int offset;
(...skipping 15 matching lines...) Expand all
242 void DisplayController::AddObserver(Observer* observer) { 241 void DisplayController::AddObserver(Observer* observer) {
243 observers_.AddObserver(observer); 242 observers_.AddObserver(observer);
244 } 243 }
245 244
246 void DisplayController::RemoveObserver(Observer* observer) { 245 void DisplayController::RemoveObserver(Observer* observer) {
247 observers_.RemoveObserver(observer); 246 observers_.RemoveObserver(observer);
248 } 247 }
249 248
250 aura::RootWindow* DisplayController::GetPrimaryRootWindow() { 249 aura::RootWindow* DisplayController::GetPrimaryRootWindow() {
251 DCHECK(!root_windows_.empty()); 250 DCHECK(!root_windows_.empty());
252 return root_windows_[primary_display->id()]; 251 return root_windows_[primary_display_id];
253 } 252 }
254 253
255 aura::RootWindow* DisplayController::GetRootWindowForDisplayId(int64 id) { 254 aura::RootWindow* DisplayController::GetRootWindowForDisplayId(int64 id) {
256 return root_windows_[id]; 255 return root_windows_[id];
257 } 256 }
258 257
259 void DisplayController::CloseChildWindows() { 258 void DisplayController::CloseChildWindows() {
260 for (std::map<int64, aura::RootWindow*>::const_iterator it = 259 for (std::map<int64, aura::RootWindow*>::const_iterator it =
261 root_windows_.begin(); it != root_windows_.end(); ++it) { 260 root_windows_.begin(); it != root_windows_.end(); ++it) {
262 aura::RootWindow* root_window = it->second; 261 aura::RootWindow* root_window = it->second;
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after
344 DCHECK(new_primary_display.is_valid()); 343 DCHECK(new_primary_display.is_valid());
345 DCHECK(display_manager->IsActiveDisplay(new_primary_display)); 344 DCHECK(display_manager->IsActiveDisplay(new_primary_display));
346 345
347 if (!new_primary_display.is_valid() || 346 if (!new_primary_display.is_valid() ||
348 !display_manager->IsActiveDisplay(new_primary_display)) { 347 !display_manager->IsActiveDisplay(new_primary_display)) {
349 LOG(ERROR) << "Invalid or non-existent display is requested:" 348 LOG(ERROR) << "Invalid or non-existent display is requested:"
350 << new_primary_display.ToString(); 349 << new_primary_display.ToString();
351 return; 350 return;
352 } 351 }
353 352
354 if (primary_display->id() == new_primary_display.id() || 353 if (primary_display_id == new_primary_display.id() ||
355 root_windows_.size() < 2) { 354 root_windows_.size() < 2) {
356 return; 355 return;
357 } 356 }
358 357
359 aura::RootWindow* non_primary_root = root_windows_[new_primary_display.id()]; 358 aura::RootWindow* non_primary_root = root_windows_[new_primary_display.id()];
360 LOG_IF(ERROR, !non_primary_root) 359 LOG_IF(ERROR, !non_primary_root)
361 << "Unknown display is requested in SetPrimaryDisplay: id=" 360 << "Unknown display is requested in SetPrimaryDisplay: id="
362 << new_primary_display.id(); 361 << new_primary_display.id();
363 if (!non_primary_root) 362 if (!non_primary_root)
364 return; 363 return;
365 364
366 gfx::Display old_primary_display = *primary_display; 365 gfx::Display old_primary_display = GetPrimaryDisplay();
367 366
368 // Swap root windows between current and new primary display. 367 // Swap root windows between current and new primary display.
369 aura::RootWindow* primary_root = root_windows_[primary_display->id()]; 368 aura::RootWindow* primary_root = root_windows_[primary_display_id];
370 DCHECK(primary_root); 369 DCHECK(primary_root);
371 DCHECK_NE(primary_root, non_primary_root); 370 DCHECK_NE(primary_root, non_primary_root);
372 371
373 root_windows_[new_primary_display.id()] = primary_root; 372 root_windows_[new_primary_display.id()] = primary_root;
374 primary_root->SetProperty(internal::kDisplayIdKey, new_primary_display.id()); 373 primary_root->SetProperty(internal::kDisplayIdKey, new_primary_display.id());
375 374
376 root_windows_[old_primary_display.id()] = non_primary_root; 375 root_windows_[old_primary_display.id()] = non_primary_root;
377 non_primary_root->SetProperty(internal::kDisplayIdKey, 376 non_primary_root->SetProperty(internal::kDisplayIdKey,
378 old_primary_display.id()); 377 old_primary_display.id());
379 378
380 *primary_display = new_primary_display; 379 primary_display_id = new_primary_display.id();
381 380
382 // Update the layout. 381 // Update the layout.
383 SetLayoutForDisplayName( 382 SetLayoutForDisplayName(
384 display_manager->GetDisplayNameFor(old_primary_display), 383 display_manager->GetDisplayNameFor(old_primary_display),
385 GetLayoutForDisplay(new_primary_display).Invert()); 384 GetLayoutForDisplay(new_primary_display).Invert());
386 385
387 // Update the dispay manager with new display info. 386 // Update the dispay manager with new display info.
388 std::vector<gfx::Display> displays; 387 std::vector<gfx::Display> displays;
389 displays.push_back(*primary_display); 388 displays.push_back(GetDisplayManager()->GetDisplayForId(primary_display_id));
390 displays.push_back(*GetSecondaryDisplay()); 389 displays.push_back(*GetSecondaryDisplay());
391 GetDisplayManager()->set_force_bounds_changed(true); 390 GetDisplayManager()->set_force_bounds_changed(true);
392 GetDisplayManager()->OnNativeDisplaysChanged(displays); 391 GetDisplayManager()->OnNativeDisplaysChanged(displays);
393 GetDisplayManager()->set_force_bounds_changed(false); 392 GetDisplayManager()->set_force_bounds_changed(false);
394 } 393 }
395 394
396 gfx::Display* DisplayController::GetSecondaryDisplay() { 395 gfx::Display* DisplayController::GetSecondaryDisplay() {
397 internal::MultiDisplayManager* display_manager = GetDisplayManager(); 396 internal::MultiDisplayManager* display_manager = GetDisplayManager();
398 CHECK_EQ(2U, display_manager->GetNumDisplays()); 397 CHECK_EQ(2U, display_manager->GetNumDisplays());
399 return display_manager->GetDisplayAt(0)->id() == primary_display->id() ? 398 return display_manager->GetDisplayAt(0)->id() == primary_display_id ?
400 display_manager->GetDisplayAt(1) : display_manager->GetDisplayAt(0); 399 display_manager->GetDisplayAt(1) : display_manager->GetDisplayAt(0);
401 } 400 }
402 401
403 void DisplayController::OnDisplayBoundsChanged(const gfx::Display& display) { 402 void DisplayController::OnDisplayBoundsChanged(const gfx::Display& display) {
404 if (display.id() == primary_display->id())
405 *primary_display = display;
406 NotifyDisplayConfigurationChanging(); 403 NotifyDisplayConfigurationChanging();
407 UpdateDisplayBoundsForLayout(); 404 UpdateDisplayBoundsForLayout();
408 root_windows_[display.id()]->SetHostBounds(display.bounds_in_pixel()); 405 root_windows_[display.id()]->SetHostBounds(display.bounds_in_pixel());
409 } 406 }
410 407
411 void DisplayController::OnDisplayAdded(const gfx::Display& display) { 408 void DisplayController::OnDisplayAdded(const gfx::Display& display) {
412 DCHECK(!root_windows_.empty()); 409 DCHECK(!root_windows_.empty());
413 NotifyDisplayConfigurationChanging(); 410 NotifyDisplayConfigurationChanging();
414 aura::RootWindow* root = AddRootWindowForDisplay(display); 411 aura::RootWindow* root = AddRootWindowForDisplay(display);
415 Shell::GetInstance()->InitRootWindowForSecondaryDisplay(root); 412 Shell::GetInstance()->InitRootWindowForSecondaryDisplay(root);
416 UpdateDisplayBoundsForLayout(); 413 UpdateDisplayBoundsForLayout();
417 } 414 }
418 415
419 void DisplayController::OnDisplayRemoved(const gfx::Display& display) { 416 void DisplayController::OnDisplayRemoved(const gfx::Display& display) {
420 aura::RootWindow* root_to_delete = root_windows_[display.id()]; 417 aura::RootWindow* root_to_delete = root_windows_[display.id()];
421 DCHECK(root_to_delete) << display.ToString(); 418 DCHECK(root_to_delete) << display.ToString();
422 NotifyDisplayConfigurationChanging(); 419 NotifyDisplayConfigurationChanging();
423 420
424 // Display for root window will be deleted when the Primary RootWindow 421 // Display for root window will be deleted when the Primary RootWindow
425 // is deleted by the Shell. 422 // is deleted by the Shell.
426 root_windows_.erase(display.id()); 423 root_windows_.erase(display.id());
427 424
428 // When the primary root window's display is removed, move the primary 425 // When the primary root window's display is removed, move the primary
429 // root to the other display. 426 // root to the other display.
430 if (primary_display->id() == display.id()) { 427 if (primary_display_id == display.id()) {
431 DCHECK_EQ(1U, root_windows_.size()); 428 DCHECK_EQ(1U, root_windows_.size());
432 *primary_display = *GetSecondaryDisplay(); 429 primary_display_id = GetSecondaryDisplay()->id();
433 aura::RootWindow* primary_root = root_to_delete; 430 aura::RootWindow* primary_root = root_to_delete;
434 431
435 // Delete the other root instead. 432 // Delete the other root instead.
436 root_to_delete = root_windows_[primary_display->id()]; 433 root_to_delete = root_windows_[primary_display_id];
437 root_to_delete->SetProperty(internal::kDisplayIdKey, display.id()); 434 root_to_delete->SetProperty(internal::kDisplayIdKey, display.id());
438 435
439 // Setup primary root. 436 // Setup primary root.
440 root_windows_[primary_display->id()] = primary_root; 437 root_windows_[primary_display_id] = primary_root;
441 primary_root->SetProperty(internal::kDisplayIdKey, primary_display->id()); 438 primary_root->SetProperty(internal::kDisplayIdKey, primary_display_id);
442 439
443 OnDisplayBoundsChanged(*primary_display); 440 OnDisplayBoundsChanged(
441 GetDisplayManager()->GetDisplayForId(primary_display_id));
444 } 442 }
445 internal::RootWindowController* controller = 443 internal::RootWindowController* controller =
446 GetRootWindowController(root_to_delete); 444 GetRootWindowController(root_to_delete);
447 DCHECK(controller); 445 DCHECK(controller);
448 controller->MoveWindowsTo(GetPrimaryRootWindow()); 446 controller->MoveWindowsTo(GetPrimaryRootWindow());
449 // Delete most of root window related objects, but don't delete 447 // Delete most of root window related objects, but don't delete
450 // root window itself yet because the stak may be using it. 448 // root window itself yet because the stak may be using it.
451 controller->Shutdown(); 449 controller->Shutdown();
452 MessageLoop::current()->DeleteSoon(FROM_HERE, controller); 450 MessageLoop::current()->DeleteSoon(FROM_HERE, controller);
453 } 451 }
(...skipping 12 matching lines...) Expand all
466 root->ConfineCursorToWindow(); 464 root->ConfineCursorToWindow();
467 #endif 465 #endif
468 return root; 466 return root;
469 } 467 }
470 468
471 void DisplayController::UpdateDisplayBoundsForLayout() { 469 void DisplayController::UpdateDisplayBoundsForLayout() {
472 if (gfx::Screen::GetNumDisplays() <= 1) 470 if (gfx::Screen::GetNumDisplays() <= 1)
473 return; 471 return;
474 472
475 DCHECK_EQ(2, gfx::Screen::GetNumDisplays()); 473 DCHECK_EQ(2, gfx::Screen::GetNumDisplays());
476 const gfx::Rect& primary_bounds = primary_display->bounds(); 474 const gfx::Rect& primary_bounds = GetPrimaryDisplay().bounds();
477 475
478 gfx::Display* secondary_display = GetSecondaryDisplay(); 476 gfx::Display* secondary_display = GetSecondaryDisplay();
479 const gfx::Rect& secondary_bounds = secondary_display->bounds(); 477 const gfx::Rect& secondary_bounds = secondary_display->bounds();
480 gfx::Point new_secondary_origin = primary_bounds.origin(); 478 gfx::Point new_secondary_origin = primary_bounds.origin();
481 479
482 const DisplayLayout& layout = GetLayoutForDisplay(*secondary_display); 480 const DisplayLayout& layout = GetLayoutForDisplay(*secondary_display);
483 DisplayLayout::Position position = layout.position; 481 DisplayLayout::Position position = layout.position;
484 482
485 // Ignore the offset in case the secondary display doesn't share edges with 483 // Ignore the offset in case the secondary display doesn't share edges with
486 // the primary display. 484 // the primary display.
(...skipping 27 matching lines...) Expand all
514 secondary_display->set_bounds( 512 secondary_display->set_bounds(
515 gfx::Rect(new_secondary_origin, secondary_bounds.size())); 513 gfx::Rect(new_secondary_origin, secondary_bounds.size()));
516 secondary_display->UpdateWorkAreaFromInsets(insets); 514 secondary_display->UpdateWorkAreaFromInsets(insets);
517 } 515 }
518 516
519 void DisplayController::NotifyDisplayConfigurationChanging() { 517 void DisplayController::NotifyDisplayConfigurationChanging() {
520 FOR_EACH_OBSERVER(Observer, observers_, OnDisplayConfigurationChanging()); 518 FOR_EACH_OBSERVER(Observer, observers_, OnDisplayConfigurationChanging());
521 } 519 }
522 520
523 } // namespace ash 521 } // namespace ash
OLDNEW
« no previous file with comments | « ash/display/display_controller.h ('k') | ash/display/display_controller_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698