15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved. 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file. 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ash/display/display_controller.h" 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <algorithm> 8c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include <cmath> 9c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include <map> 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ash/ash_switches.h" 127dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#include "ash/display/display_layout_store.h" 132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ash/display/display_manager.h" 147dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#include "ash/display/mirror_window_controller.h" 15868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "ash/display/root_window_transformers.h" 162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ash/host/root_window_host_factory.h" 175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ash/root_window_controller.h" 182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ash/screen_ash.h" 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ash/shell.h" 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ash/wm/coordinate_conversion.h" 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ash/wm/property_util.h" 227dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#include "ash/wm/window_properties.h" 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ash/wm/window_util.h" 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/command_line.h" 25868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/stringprintf.h" 26c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "third_party/skia/include/utils/SkMatrix44.h" 27c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "ui/aura/client/activation_client.h" 28c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "ui/aura/client/capture_client.h" 29c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "ui/aura/client/cursor_client.h" 30c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "ui/aura/client/focus_client.h" 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/aura/client/screen_position_client.h" 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/aura/root_window.h" 33868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "ui/aura/root_window_transformer.h" 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/aura/window.h" 352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ui/aura/window_property.h" 36c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "ui/aura/window_tracker.h" 37c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "ui/compositor/compositor.h" 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/compositor/dip_util.h" 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/gfx/display.h" 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/gfx/screen.h" 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_CHROMEOS) 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/chromeos/chromeos_version.h" 44eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "base/time/time.h" 45c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#if defined(USE_X11) 46c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "ash/display/output_configurator_animation.h" 472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chromeos/display/output_configurator.h" 482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ui/base/x/x11_util.h" 492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Including this at the bottom to avoid other 512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// potential conflict with chrome headers. 522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include <X11/extensions/Xrandr.h> 532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#undef RootWindow 54c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#endif // defined(USE_X11) 552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#endif // defined(OS_CHROMEOS) 562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 577dbb3d5cf0c15f500944d211057644d6a2f37371Ben MurdochDECLARE_WINDOW_PROPERTY_TYPE(int64); 587dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace ash { 605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace { 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Primary display stored in global object as it can be 632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// accessed after Shell is deleted. A separate display instance is created 642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// during the shutdown instead of always keeping two display instances 652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// (one here and another one in display_manager) in sync, which is error prone. 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int64 primary_display_id = gfx::Display::kInvalidDisplayID; 672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)gfx::Display* primary_display_for_shutdown = NULL; 682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Keeps the number of displays during the shutdown after 692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// ash::Shell:: is deleted. 702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)int num_displays_for_shutdown = -1; 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Specifies how long the display change should have been disabled 732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// after each display change operations. 742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// |kCycleDisplayThrottleTimeoutMs| is set to be longer to avoid 752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// changing the settings while the system is still configurating 762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// displays. It will be overriden by |kAfterDisplayChangeThrottleTimeoutMs| 772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// when the display change happens, so the actual timeout is much shorter. 782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)const int64 kAfterDisplayChangeThrottleTimeoutMs = 500; 792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)const int64 kCycleDisplayThrottleTimeoutMs = 4000; 802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)const int64 kSwapDisplayThrottleTimeoutMs = 500; 812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 82c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)internal::DisplayManager* GetDisplayManager() { 83c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return Shell::GetInstance()->display_manager(); 842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void SetDisplayPropertiesOnHostWindow(aura::RootWindow* root, 872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const gfx::Display& display) { 882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) internal::DisplayInfo info = 892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) GetDisplayManager()->GetDisplayInfo(display.id()); 90c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#if defined(OS_CHROMEOS) && defined(USE_X11) 912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Native window property (Atom in X11) that specifies the display's 922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // rotation, scale factor and if it's internal display. They are 932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // read and used by touchpad/mouse driver directly on X (contact 942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // adlr@ for more details on touchpad/mouse driver side). The value 952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // of the rotation is one of 0 (normal), 1 (90 degrees clockwise), 2 962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // (180 degree) or 3 (270 degrees clockwise). The value of the 972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // scale factor is in percent (100, 140, 200 etc). 982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const char kRotationProp[] = "_CHROME_DISPLAY_ROTATION"; 992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const char kScaleFactorProp[] = "_CHROME_DISPLAY_SCALE_FACTOR"; 1002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const char kInternalProp[] = "_CHROME_DISPLAY_INTERNAL"; 1012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const char kCARDINAL[] = "CARDINAL"; 1022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int xrandr_rotation = RR_Rotate_0; 1032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) switch (info.rotation()) { 1042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) case gfx::Display::ROTATE_0: 1052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) xrandr_rotation = RR_Rotate_0; 1062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) break; 1072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) case gfx::Display::ROTATE_90: 1082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) xrandr_rotation = RR_Rotate_90; 1092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) break; 1102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) case gfx::Display::ROTATE_180: 1112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) xrandr_rotation = RR_Rotate_180; 1122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) break; 1132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) case gfx::Display::ROTATE_270: 1142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) xrandr_rotation = RR_Rotate_270; 1152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) break; 1162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 1172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int internal = display.IsInternal() ? 1 : 0; 1192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) gfx::AcceleratedWidget xwindow = root->GetAcceleratedWidget(); 1202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ui::SetIntProperty(xwindow, kInternalProp, kCARDINAL, internal); 1212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ui::SetIntProperty(xwindow, kRotationProp, kCARDINAL, xrandr_rotation); 1222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ui::SetIntProperty(xwindow, 1232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) kScaleFactorProp, 1242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) kCARDINAL, 1252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 100 * display.device_scale_factor()); 1262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#endif 127c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) scoped_ptr<aura::RootWindowTransformer> transformer( 128868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) internal::CreateRootWindowTransformerForDisplay(root, display)); 129c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) root->SetRootWindowTransformer(transformer.Pass()); 1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace 1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 134c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)namespace internal { 135c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 1367dbb3d5cf0c15f500944d211057644d6a2f37371Ben MurdochDEFINE_WINDOW_PROPERTY_KEY(int64, kDisplayIdKey, 1377dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch gfx::Display::kInvalidDisplayID); 1387dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 139c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// A utility class to store/restore focused/active window 140c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// when the display configuration has changed. 141c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)class FocusActivationStore { 142c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) public: 143c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) FocusActivationStore() 144c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) : activation_client_(NULL), 145c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) capture_client_(NULL), 146c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) focus_client_(NULL), 147c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) focused_(NULL), 148c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) active_(NULL) { 149c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 150c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 151c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) void Store() { 152c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (!activation_client_) { 153c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) aura::RootWindow* root = Shell::GetPrimaryRootWindow(); 154c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) activation_client_ = aura::client::GetActivationClient(root); 155c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) capture_client_ = aura::client::GetCaptureClient(root); 156c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) focus_client_ = aura::client::GetFocusClient(root); 157c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 158c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) focused_ = focus_client_->GetFocusedWindow(); 159c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (focused_) 160c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) tracker_.Add(focused_); 161c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) active_ = activation_client_->GetActiveWindow(); 162c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (active_ && focused_ != active_) 163c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) tracker_.Add(active_); 164c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 165c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Deactivate the window to close menu / bubble windows. 166c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) activation_client_->DeactivateWindow(active_); 167c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Release capture if any. 168c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) capture_client_->SetCapture(NULL); 169c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Clear the focused window if any. This is necessary because a 170c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // window may be deleted when losing focus (fullscreen flash for 171c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // example). If the focused window is still alive after move, it'll 172c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // be re-focused below. 173c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) focus_client_->FocusWindow(NULL); 174c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 175c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 176c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) void Restore() { 177c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Restore focused or active window if it's still alive. 178c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (focused_ && tracker_.Contains(focused_)) { 179c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) focus_client_->FocusWindow(focused_); 180c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } else if (active_ && tracker_.Contains(active_)) { 181c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) activation_client_->ActivateWindow(active_); 182c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 183c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (focused_) 184c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) tracker_.Remove(focused_); 185c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (active_) 186c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) tracker_.Remove(active_); 187c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) focused_ = NULL; 188c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) active_ = NULL; 189c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 190c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 191c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) private: 192c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) aura::client::ActivationClient* activation_client_; 193c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) aura::client::CaptureClient* capture_client_; 194c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) aura::client::FocusClient* focus_client_; 195c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) aura::WindowTracker tracker_; 196c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) aura::Window* focused_; 197c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) aura::Window* active_; 198c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 199c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) DISALLOW_COPY_AND_ASSIGN(FocusActivationStore); 200c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}; 201c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 202c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} // namespace internal 203c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 2042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)//////////////////////////////////////////////////////////////////////////////// 2052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// DisplayChangeLimiter 2062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)DisplayController::DisplayChangeLimiter::DisplayChangeLimiter() 2082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) : throttle_timeout_(base::Time::Now()) { 2092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 2102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void DisplayController::DisplayChangeLimiter::SetThrottleTimeout( 2122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int64 throttle_ms) { 2132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) throttle_timeout_ = 2142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::Time::Now() + base::TimeDelta::FromMilliseconds(throttle_ms); 2152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 2162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool DisplayController::DisplayChangeLimiter::IsThrottled() const { 2182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return base::Time::Now() < throttle_timeout_; 2192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 2202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)//////////////////////////////////////////////////////////////////////////////// 2222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// DisplayController 2232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)DisplayController::DisplayController() 225c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) : primary_root_window_for_replace_(NULL), 2267dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch focus_activation_store_(new internal::FocusActivationStore()), 2277dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch mirror_window_controller_(new internal::MirrorWindowController) { 2282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) CommandLine* command_line = CommandLine::ForCurrentProcess(); 2292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#if defined(OS_CHROMEOS) 2302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!command_line->HasSwitch(switches::kAshDisableDisplayChangeLimiter) && 2312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::chromeos::IsRunningOnChromeOS()) 2322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) limiter_.reset(new DisplayChangeLimiter); 2332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#endif 2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Reset primary display to make sure that tests don't use 2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // stale display info from previous tests. 2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) primary_display_id = gfx::Display::kInvalidDisplayID; 2372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) delete primary_display_for_shutdown; 2382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) primary_display_for_shutdown = NULL; 2392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) num_displays_for_shutdown = -1; 2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)DisplayController::~DisplayController() { 2432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(primary_display_for_shutdown); 2442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 2452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void DisplayController::Start() { 2472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Shell::GetScreen()->AddObserver(this); 2487dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch Shell::GetInstance()->display_manager()->set_delegate(this); 2492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 2502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void DisplayController::Shutdown() { 2527dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch // Unset the display manager's delegate here because 2537dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch // DisplayManager outlives DisplayController. 2547dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch Shell::GetInstance()->display_manager()->set_delegate(NULL); 2557dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 2567dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch mirror_window_controller_.reset(); 2577dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 2582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(!primary_display_for_shutdown); 2592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) primary_display_for_shutdown = new gfx::Display( 2602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) GetDisplayManager()->GetDisplayForId(primary_display_id)); 2612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) num_displays_for_shutdown = GetDisplayManager()->GetNumDisplays(); 2622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Shell::GetScreen()->RemoveObserver(this); 2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Delete all root window controllers, which deletes root window 2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // from the last so that the primary root window gets deleted last. 2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (std::map<int64, aura::RootWindow*>::const_reverse_iterator it = 2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) root_windows_.rbegin(); it != root_windows_.rend(); ++it) { 2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) internal::RootWindowController* controller = 2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GetRootWindowController(it->second); 2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(controller); 2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) delete controller; 2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static 2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const gfx::Display& DisplayController::GetPrimaryDisplay() { 2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK_NE(primary_display_id, gfx::Display::kInvalidDisplayID); 2782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (primary_display_for_shutdown) 2792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return *primary_display_for_shutdown; 2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return GetDisplayManager()->GetDisplayForId(primary_display_id); 2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// static 2842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)int DisplayController::GetNumDisplays() { 2852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (num_displays_for_shutdown >= 0) 2862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return num_displays_for_shutdown; 2872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return GetDisplayManager()->GetNumDisplays(); 2882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 2892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void DisplayController::InitPrimaryDisplay() { 2912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const gfx::Display* primary_candidate = 2922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) GetDisplayManager()->GetPrimaryDisplayCandidate(); 2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) primary_display_id = primary_candidate->id(); 2942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) AddRootWindowForDisplay(*primary_candidate); 2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void DisplayController::InitSecondaryDisplays() { 2982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) internal::DisplayManager* display_manager = GetDisplayManager(); 299eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch UpdateDisplayBoundsForLayout(); 3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (size_t i = 0; i < display_manager->GetNumDisplays(); ++i) { 301ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch const gfx::Display& display = display_manager->GetDisplayAt(i); 302ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch if (primary_display_id != display.id()) { 303ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch aura::RootWindow* root = AddRootWindowForDisplay(display); 3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Shell::GetInstance()->InitRootWindowForSecondaryDisplay(root); 3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 307c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (display_manager->GetNumDisplays() > 1) { 308c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) DisplayIdPair pair = GetCurrentDisplayIdPair(); 309c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) DisplayLayout layout = GetCurrentDisplayLayout(); 310c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) SetPrimaryDisplayId( 311c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) layout.primary_id == gfx::Display::kInvalidDisplayID ? 312c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) pair.first : layout.primary_id); 313c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 314eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch UpdateHostWindowNames(); 3155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void DisplayController::AddObserver(Observer* observer) { 3185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) observers_.AddObserver(observer); 3195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void DisplayController::RemoveObserver(Observer* observer) { 3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) observers_.RemoveObserver(observer); 3235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)aura::RootWindow* DisplayController::GetPrimaryRootWindow() { 3265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(!root_windows_.empty()); 3275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return root_windows_[primary_display_id]; 3285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)aura::RootWindow* DisplayController::GetRootWindowForDisplayId(int64 id) { 3315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return root_windows_[id]; 3325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void DisplayController::CloseChildWindows() { 3355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (std::map<int64, aura::RootWindow*>::const_iterator it = 3365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) root_windows_.begin(); it != root_windows_.end(); ++it) { 3375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) aura::RootWindow* root_window = it->second; 3385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) internal::RootWindowController* controller = 3395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GetRootWindowController(root_window); 3405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (controller) { 3415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) controller->CloseChildWindows(); 3425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 3435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) while (!root_window->children().empty()) { 3445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) aura::Window* child = root_window->children()[0]; 3455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) delete child; 3465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)std::vector<aura::RootWindow*> DisplayController::GetAllRootWindows() { 3525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::vector<aura::RootWindow*> windows; 3535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (std::map<int64, aura::RootWindow*>::const_iterator it = 3545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) root_windows_.begin(); it != root_windows_.end(); ++it) { 3555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(it->second); 3565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (GetRootWindowController(it->second)) 3575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) windows.push_back(it->second); 3585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return windows; 3605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)gfx::Insets DisplayController::GetOverscanInsets(int64 display_id) const { 3635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return GetDisplayManager()->GetOverscanInsets(display_id); 3645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void DisplayController::SetOverscanInsets(int64 display_id, 3672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const gfx::Insets& insets_in_dip) { 3682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) GetDisplayManager()->SetOverscanInsets(display_id, insets_in_dip); 3692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 3702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)std::vector<internal::RootWindowController*> 3725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)DisplayController::GetAllRootWindowControllers() { 3735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::vector<internal::RootWindowController*> controllers; 3745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (std::map<int64, aura::RootWindow*>::const_iterator it = 3755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) root_windows_.begin(); it != root_windows_.end(); ++it) { 3765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) internal::RootWindowController* controller = 3775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GetRootWindowController(it->second); 3785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (controller) 3795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) controllers.push_back(controller); 3805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return controllers; 3825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void DisplayController::SetLayoutForCurrentDisplays( 3852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const DisplayLayout& layout_relative_to_primary) { 3862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK_EQ(2U, GetDisplayManager()->GetNumDisplays()); 3872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (GetDisplayManager()->GetNumDisplays() < 2) 3882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return; 3892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const gfx::Display& primary = GetPrimaryDisplay(); 3902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const DisplayIdPair pair = GetCurrentDisplayIdPair(); 3912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Invert if the primary was swapped. 3922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DisplayLayout to_set = pair.first == primary.id() ? 3932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) layout_relative_to_primary : layout_relative_to_primary.Invert(); 3942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3957dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch internal::DisplayLayoutStore* layout_store = 3967dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch GetDisplayManager()->layout_store(); 3977dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch DisplayLayout current_layout = 3987dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch layout_store->GetRegisteredDisplayLayout(pair); 3992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (to_set.position != current_layout.position || 4002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) to_set.offset != current_layout.offset) { 401c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) to_set.primary_id = primary.id(); 4027dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch layout_store->RegisterLayoutForDisplayIdPair( 4037dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch pair.first, pair.second, to_set); 4047dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch PreDisplayConfigurationChange(); 405eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // TODO(oshima): Call UpdateDisplays instead. 4065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) UpdateDisplayBoundsForLayout(); 4074311e82a78ceafbe0585f51d4c8a86df9f21aa0dBen Murdoch // Primary's bounds stay the same. Just notify bounds change 4084311e82a78ceafbe0585f51d4c8a86df9f21aa0dBen Murdoch // on the secondary. 4094311e82a78ceafbe0585f51d4c8a86df9f21aa0dBen Murdoch Shell::GetInstance()->screen()->NotifyBoundsChanged( 4104311e82a78ceafbe0585f51d4c8a86df9f21aa0dBen Murdoch ScreenAsh::GetSecondaryDisplay()); 4117dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch PostDisplayConfigurationChange(); 4125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 415eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen MurdochDisplayLayout DisplayController::GetCurrentDisplayLayout() { 4162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK_EQ(2U, GetDisplayManager()->num_connected_displays()); 4172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Invert if the primary was swapped. 4182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (GetDisplayManager()->num_connected_displays() > 1) { 4192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DisplayIdPair pair = GetCurrentDisplayIdPair(); 4207dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch return GetDisplayManager()->layout_store()-> 4217dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch ComputeDisplayLayoutForDisplayIdPair(pair); 4222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 4237dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch NOTREACHED() << "DisplayLayout is requested for single display"; 4242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // On release build, just fallback to default instead of blowing up. 4257dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch DisplayLayout layout = 4267dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch GetDisplayManager()->layout_store()->default_display_layout(); 427eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch layout.primary_id = primary_display_id; 428eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch return layout; 4295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)DisplayIdPair DisplayController::GetCurrentDisplayIdPair() const { 4322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) internal::DisplayManager* display_manager = GetDisplayManager(); 4332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const gfx::Display& primary = GetPrimaryDisplay(); 434868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (display_manager->IsMirrored()) { 435868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return std::make_pair(primary.id(), 436868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) display_manager->mirrored_display().id()); 437868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 4382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const gfx::Display& secondary = ScreenAsh::GetSecondaryDisplay(); 4402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (primary.IsInternal() || 4412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) GetDisplayManager()->first_display_id() == primary.id()) { 4422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return std::make_pair(primary.id(), secondary.id()); 4432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } else { 4442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Display has been Swapped. 4452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return std::make_pair(secondary.id(), primary.id()); 4462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 4472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 4482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 44990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)void DisplayController::ToggleMirrorMode() { 45090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) internal::DisplayManager* display_manager = GetDisplayManager(); 45190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) if (display_manager->num_connected_displays() <= 1) 45290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) return; 45390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 454c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (limiter_) { 4552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (limiter_->IsThrottled()) 4562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return; 4572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) limiter_->SetThrottleTimeout(kCycleDisplayThrottleTimeoutMs); 4582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 459c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#if defined(OS_CHROMEOS) && defined(USE_X11) 4602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Shell* shell = Shell::GetInstance(); 46190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) internal::OutputConfiguratorAnimation* animation = 46290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) shell->output_configurator_animation(); 46390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) animation->StartFadeOutAnimation(base::Bind( 46490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) base::IgnoreResult(&internal::DisplayManager::SetMirrorMode), 46590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) base::Unretained(display_manager), 46690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) !display_manager->IsMirrored())); 4672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#endif 4682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 4692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void DisplayController::SwapPrimaryDisplay() { 471c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (limiter_) { 4722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (limiter_->IsThrottled()) 4732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return; 4742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) limiter_->SetThrottleTimeout(kSwapDisplayThrottleTimeoutMs); 4752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 4762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (Shell::GetScreen()->GetNumDisplays() > 1) { 478c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#if defined(OS_CHROMEOS) && defined(USE_X11) 4792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) internal::OutputConfiguratorAnimation* animation = 4802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Shell::GetInstance()->output_configurator_animation(); 4812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (animation) { 4822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) animation->StartFadeOutAnimation(base::Bind( 4832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) &DisplayController::OnFadeOutForSwapDisplayFinished, 4842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::Unretained(this))); 4852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } else { 4862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) SetPrimaryDisplay(ScreenAsh::GetSecondaryDisplay()); 4872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 4882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#else 4892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) SetPrimaryDisplay(ScreenAsh::GetSecondaryDisplay()); 4902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#endif 4915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void DisplayController::SetPrimaryDisplayId(int64 id) { 495c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) DCHECK_NE(gfx::Display::kInvalidDisplayID, id); 496c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (id == gfx::Display::kInvalidDisplayID || primary_display_id == id) 4975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 4985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 499c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const gfx::Display& display = GetDisplayManager()->GetDisplayForId(id); 500c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (display.is_valid()) 501c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) SetPrimaryDisplay(display); 5025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void DisplayController::SetPrimaryDisplay( 5055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const gfx::Display& new_primary_display) { 5062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) internal::DisplayManager* display_manager = GetDisplayManager(); 5075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(new_primary_display.is_valid()); 5085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(display_manager->IsActiveDisplay(new_primary_display)); 5095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!new_primary_display.is_valid() || 5115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) !display_manager->IsActiveDisplay(new_primary_display)) { 5125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LOG(ERROR) << "Invalid or non-existent display is requested:" 5135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) << new_primary_display.ToString(); 5145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 5155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (primary_display_id == new_primary_display.id() || 5185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) root_windows_.size() < 2) { 5195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 5205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) aura::RootWindow* non_primary_root = root_windows_[new_primary_display.id()]; 5235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LOG_IF(ERROR, !non_primary_root) 5245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) << "Unknown display is requested in SetPrimaryDisplay: id=" 5255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) << new_primary_display.id(); 5265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!non_primary_root) 5275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 5285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gfx::Display old_primary_display = GetPrimaryDisplay(); 5305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Swap root windows between current and new primary display. 5325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) aura::RootWindow* primary_root = root_windows_[primary_display_id]; 5335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(primary_root); 5345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK_NE(primary_root, non_primary_root); 5355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) root_windows_[new_primary_display.id()] = primary_root; 5375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) primary_root->SetProperty(internal::kDisplayIdKey, new_primary_display.id()); 5385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) root_windows_[old_primary_display.id()] = non_primary_root; 5405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) non_primary_root->SetProperty(internal::kDisplayIdKey, 5415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) old_primary_display.id()); 5425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) primary_display_id = new_primary_display.id(); 5447dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch GetDisplayManager()->layout_store()->UpdatePrimaryDisplayId( 5457dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch GetCurrentDisplayIdPair(), primary_display_id); 5465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5477dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch UpdateWorkAreaOfDisplayNearestWindow( 5485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) primary_root, old_primary_display.GetWorkAreaInsets()); 5497dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch UpdateWorkAreaOfDisplayNearestWindow( 5505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) non_primary_root, new_primary_display.GetWorkAreaInsets()); 5515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Update the dispay manager with new display info. 5532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) std::vector<internal::DisplayInfo> display_info_list; 5542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) display_info_list.push_back(display_manager->GetDisplayInfo( 5552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) primary_display_id)); 5562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) display_info_list.push_back(display_manager->GetDisplayInfo( 557ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch ScreenAsh::GetSecondaryDisplay().id())); 5585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GetDisplayManager()->set_force_bounds_changed(true); 5592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) GetDisplayManager()->UpdateDisplays(display_info_list); 5605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GetDisplayManager()->set_force_bounds_changed(false); 5615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 563c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void DisplayController::EnsurePointerInDisplays() { 5647dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch // If the mouse is currently on a display in native location, 5657dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch // use the same native location. Otherwise find the display closest 5667dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch // to the current cursor location in screen coordinates. 5677dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 5687dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch gfx::Point point_in_screen = Shell::GetScreen()->GetCursorScreenPoint(); 5697dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch gfx::Point target_location_in_native; 570c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) int64 closest_distance_squared = -1; 571c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) internal::DisplayManager* display_manager = GetDisplayManager(); 572c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 573c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) aura::RootWindow* dst_root_window = NULL; 574c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) for (size_t i = 0; i < display_manager->GetNumDisplays(); ++i) { 575ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch const gfx::Display& display = display_manager->GetDisplayAt(i); 5767dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch const internal::DisplayInfo display_info = 577ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch display_manager->GetDisplayInfo(display.id()); 578ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch aura::RootWindow* root_window = GetRootWindowForDisplayId(display.id()); 5797dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch if (display_info.bounds_in_pixel().Contains( 5807dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch cursor_location_in_native_coords_for_restore_)) { 581c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) dst_root_window = root_window; 5827dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch target_location_in_native = cursor_location_in_native_coords_for_restore_; 583c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) break; 584c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 585ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch gfx::Point center = display.bounds().CenterPoint(); 586c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Use the distance squared from the center of the dislay. This is not 587c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // exactly "closest" display, but good enough to pick one 588c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // appropriate (and there are at most two displays). 589c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // We don't care about actual distance, only relative to other displays, so 590c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // using the LengthSquared() is cheaper than Length(). 591c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 5927dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch int64 distance_squared = (center - point_in_screen).LengthSquared(); 593c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (closest_distance_squared < 0 || 594c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) closest_distance_squared > distance_squared) { 595ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch aura::RootWindow* root_window = GetRootWindowForDisplayId(display.id()); 5967dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch aura::client::ScreenPositionClient* client = 5977dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch aura::client::GetScreenPositionClient(root_window); 5987dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch client->ConvertPointFromScreen(root_window, ¢er); 5997dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch root_window->ConvertPointToNativeScreen(¢er); 600c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) dst_root_window = root_window; 6017dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch target_location_in_native = center; 602c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) closest_distance_squared = distance_squared; 603c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 604c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 6057dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch dst_root_window->ConvertPointFromNativeScreen(&target_location_in_native); 6067dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch dst_root_window->MoveCursorTo(target_location_in_native); 6077dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch} 6087dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 6097dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochbool DisplayController::UpdateWorkAreaOfDisplayNearestWindow( 6107dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch const aura::Window* window, 6117dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch const gfx::Insets& insets) { 612ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch const aura::RootWindow* root_window = window->GetRootWindow(); 613ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch int64 id = root_window->GetProperty(internal::kDisplayIdKey); 614ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch // if id is |kInvaildDisplayID|, it's being deleted. 615ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch DCHECK(id != gfx::Display::kInvalidDisplayID); 616ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch return GetDisplayManager()->UpdateWorkAreaOfDisplay(id, insets); 6177dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch} 6187dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 6197dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochconst gfx::Display& DisplayController::GetDisplayNearestWindow( 6207dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch const aura::Window* window) const { 6217dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch if (!window) 6227dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch return GetPrimaryDisplay(); 6237dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch const aura::RootWindow* root_window = window->GetRootWindow(); 6247dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch if (!root_window) 6257dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch return GetPrimaryDisplay(); 6267dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch int64 id = root_window->GetProperty(internal::kDisplayIdKey); 6277dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch // if id is |kInvaildDisplayID|, it's being deleted. 6287dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch DCHECK(id != gfx::Display::kInvalidDisplayID); 629c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 6307dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch internal::DisplayManager* display_manager = GetDisplayManager(); 6317dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch // RootWindow needs Display to determine its device scale factor. 6327dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch // TODO(oshima): We don't need full display info for mirror 6337dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch // window. Refactor so that RootWindow doesn't use it. 6347dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch if (display_manager->mirrored_display().id() == id) 6357dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch return display_manager->mirrored_display(); 636c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 637ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch return display_manager->GetDisplayForId(id); 638c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 639c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 6407dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochconst gfx::Display& DisplayController::GetDisplayNearestPoint( 6417dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch const gfx::Point& point) const { 6427dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch // Fallback to the primary display if there is no root display containing 6437dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch // the |point|. 6447dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch const gfx::Display& display = 6457dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch GetDisplayManager()->FindDisplayContainingPoint(point); 6467dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch return display.is_valid() ? display : GetPrimaryDisplay(); 6477dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch} 6487dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 6497dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochconst gfx::Display& DisplayController::GetDisplayMatching( 6507dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch const gfx::Rect& rect) const { 6517dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch if (rect.IsEmpty()) 6527dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch return GetDisplayNearestPoint(rect.origin()); 6537dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 6547dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch int max_area = 0; 6557dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch const gfx::Display* matching = NULL; 6567dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch for (size_t i = 0; i < GetDisplayManager()->GetNumDisplays(); ++i) { 657ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch const gfx::Display& display = GetDisplayManager()->GetDisplayAt(i); 658ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch gfx::Rect intersect = gfx::IntersectRects(display.bounds(), rect); 6597dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch int area = intersect.width() * intersect.height(); 6607dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch if (area > max_area) { 6617dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch max_area = area; 662ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch matching = &display; 663c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 664c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 6657dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch // Fallback to the primary display if there is no matching display. 6667dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch return matching ? *matching : GetPrimaryDisplay(); 667c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 668c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 6695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void DisplayController::OnDisplayBoundsChanged(const gfx::Display& display) { 6702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const internal::DisplayInfo& display_info = 6712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) GetDisplayManager()->GetDisplayInfo(display.id()); 6722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(!display_info.bounds_in_pixel().IsEmpty()); 6732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) aura::RootWindow* root = root_windows_[display.id()]; 674c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) root->SetHostBounds(display_info.bounds_in_pixel()); 675eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch SetDisplayPropertiesOnHostWindow(root, display); 6765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void DisplayController::OnDisplayAdded(const gfx::Display& display) { 6792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (primary_root_window_for_replace_) { 6802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(root_windows_.empty()); 6812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) primary_display_id = display.id(); 6822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) root_windows_[display.id()] = primary_root_window_for_replace_; 6832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) primary_root_window_for_replace_->SetProperty( 6842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) internal::kDisplayIdKey, display.id()); 6852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) primary_root_window_for_replace_ = NULL; 6862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const internal::DisplayInfo& display_info = 6872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) GetDisplayManager()->GetDisplayInfo(display.id()); 688c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) root_windows_[display.id()]->SetHostBounds( 689c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) display_info.bounds_in_pixel()); 6902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } else { 691c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (primary_display_id == gfx::Display::kInvalidDisplayID) 692c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) primary_display_id = display.id(); 6932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(!root_windows_.empty()); 6942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) aura::RootWindow* root = AddRootWindowForDisplay(display); 6952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Shell::GetInstance()->InitRootWindowForSecondaryDisplay(root); 6962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 6975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void DisplayController::OnDisplayRemoved(const gfx::Display& display) { 7005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) aura::RootWindow* root_to_delete = root_windows_[display.id()]; 7015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(root_to_delete) << display.ToString(); 7025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Display for root window will be deleted when the Primary RootWindow 7045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // is deleted by the Shell. 7055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) root_windows_.erase(display.id()); 7065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // When the primary root window's display is removed, move the primary 7085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // root to the other display. 7095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (primary_display_id == display.id()) { 7102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Temporarily store the primary root window in 7112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // |primary_root_window_for_replace_| when replacing the display. 7122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (root_windows_.size() == 0) { 7132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) primary_display_id = gfx::Display::kInvalidDisplayID; 7142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) primary_root_window_for_replace_ = root_to_delete; 7152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return; 7162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 7175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK_EQ(1U, root_windows_.size()); 718ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch primary_display_id = ScreenAsh::GetSecondaryDisplay().id(); 7195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) aura::RootWindow* primary_root = root_to_delete; 7205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Delete the other root instead. 7225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) root_to_delete = root_windows_[primary_display_id]; 7235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) root_to_delete->SetProperty(internal::kDisplayIdKey, display.id()); 7245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Setup primary root. 7265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) root_windows_[primary_display_id] = primary_root; 7275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) primary_root->SetProperty(internal::kDisplayIdKey, primary_display_id); 7285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) OnDisplayBoundsChanged( 7305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GetDisplayManager()->GetDisplayForId(primary_display_id)); 7315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 7325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) internal::RootWindowController* controller = 7335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GetRootWindowController(root_to_delete); 7345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(controller); 7355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) controller->MoveWindowsTo(GetPrimaryRootWindow()); 7365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Delete most of root window related objects, but don't delete 7375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // root window itself yet because the stack may be using it. 7385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) controller->Shutdown(); 739c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::MessageLoop::current()->DeleteSoon(FROM_HERE, controller); 7405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 7415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7427dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochvoid DisplayController::OnRootWindowHostResized(const aura::RootWindow* root) { 7437dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch internal::DisplayManager* display_manager = GetDisplayManager(); 7447dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch gfx::Display display = GetDisplayNearestWindow(root); 7457dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch if (display_manager->UpdateDisplayBounds( 7467dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch display.id(), 7477dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch gfx::Rect(root->GetHostOrigin(), root->GetHostSize()))) { 7487dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch mirror_window_controller_->UpdateWindow(); 7497dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch } 7507dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch} 7517dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 7527dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochvoid DisplayController::CreateOrUpdateMirrorWindow( 7537dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch const internal::DisplayInfo& info) { 7547dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch mirror_window_controller_->UpdateWindow(info); 7557dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch} 7567dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 7577dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochvoid DisplayController::CloseMirrorWindow() { 7587dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch mirror_window_controller_->Close(); 7597dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch} 7607dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 7617dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochvoid DisplayController::PreDisplayConfigurationChange() { 7627dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch FOR_EACH_OBSERVER(Observer, observers_, OnDisplayConfigurationChanging()); 7637dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch focus_activation_store_->Store(); 7647dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 7657dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch gfx::Point point_in_screen = Shell::GetScreen()->GetCursorScreenPoint(); 7667dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch gfx::Display display = 7677dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch Shell::GetScreen()->GetDisplayNearestPoint(point_in_screen); 7687dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch aura::RootWindow* root_window = GetRootWindowForDisplayId(display.id()); 7697dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 7707dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch aura::client::ScreenPositionClient* client = 7717dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch aura::client::GetScreenPositionClient(root_window); 7727dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch client->ConvertPointFromScreen(root_window, &point_in_screen); 7737dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch root_window->ConvertPointToNativeScreen(&point_in_screen); 7747dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch cursor_location_in_native_coords_for_restore_ = point_in_screen; 7757dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch} 7767dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 7777dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochvoid DisplayController::PostDisplayConfigurationChange() { 7787dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch if (limiter_) 7797dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch limiter_->SetThrottleTimeout(kAfterDisplayChangeThrottleTimeoutMs); 7807dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 7817dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch focus_activation_store_->Restore(); 7827dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 7837dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch internal::DisplayManager* display_manager = GetDisplayManager(); 7847dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch internal::DisplayLayoutStore* layout_store = display_manager->layout_store(); 7857dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch if (display_manager->num_connected_displays() > 1) { 7867dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch DisplayIdPair pair = GetCurrentDisplayIdPair(); 7877dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch layout_store->UpdateMirrorStatus(pair, display_manager->IsMirrored()); 7887dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch DisplayLayout layout = layout_store->GetRegisteredDisplayLayout(pair); 7897dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 7907dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch if (Shell::GetScreen()->GetNumDisplays() > 1 ) { 7917dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch int64 primary_id = layout.primary_id; 7927dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch SetPrimaryDisplayId( 7937dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch primary_id == gfx::Display::kInvalidDisplayID ? 7947dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch pair.first : primary_id); 7957dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch // Update the primary_id in case the above call is 7967dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch // ignored. Happens when a) default layout's primary id 7977dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch // doesn't exist, or b) the primary_id has already been 7987dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch // set to the same and didn't update it. 7997dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch layout_store->UpdatePrimaryDisplayId(pair, GetPrimaryDisplay().id()); 8007dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch } 8017dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch } 8027dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch FOR_EACH_OBSERVER(Observer, observers_, OnDisplayConfigurationChanged()); 8037dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch UpdateHostWindowNames(); 8047dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch EnsurePointerInDisplays(); 8057dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch} 8067dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 80790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)aura::RootWindow* DisplayController::AddRootWindowForDisplay( 8082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const gfx::Display& display) { 8092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) static int root_window_count = 0; 8102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const internal::DisplayInfo& display_info = 8112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) GetDisplayManager()->GetDisplayInfo(display.id()); 8122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const gfx::Rect& bounds_in_pixel = display_info.bounds_in_pixel(); 8132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) aura::RootWindow::CreateParams params(bounds_in_pixel); 8142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) params.host = Shell::GetInstance()->root_window_host_factory()-> 8152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) CreateRootWindowHost(bounds_in_pixel); 8162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) aura::RootWindow* root_window = new aura::RootWindow(params); 8172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) root_window->SetName( 8182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::StringPrintf("RootWindow-%d", root_window_count++)); 819c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) root_window->compositor()->SetBackgroundColor(SK_ColorBLACK); 8202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // No need to remove RootWindowObserver because 8217dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch // the DisplayController object outlives RootWindow objects. 8227dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch root_window->AddRootWindowObserver(this); 8232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) root_window->SetProperty(internal::kDisplayIdKey, display.id()); 8242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) root_window->Init(); 8252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 82690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) root_windows_[display.id()] = root_window; 82790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) SetDisplayPropertiesOnHostWindow(root_window, display); 8285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_CHROMEOS) 8305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static bool force_constrain_pointer_to_root = 8315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CommandLine::ForCurrentProcess()->HasSwitch( 8325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) switches::kAshConstrainPointerToRoot); 8335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (base::chromeos::IsRunningOnChromeOS() || force_constrain_pointer_to_root) 83490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) root_window->ConfineCursorToWindow(); 8355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 83690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) return root_window; 8375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 8385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void DisplayController::UpdateDisplayBoundsForLayout() { 8402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (Shell::GetScreen()->GetNumDisplays() < 2 || 8412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) GetDisplayManager()->num_connected_displays() < 2) { 8425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 8432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 8445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK_EQ(2, Shell::GetScreen()->GetNumDisplays()); 8455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const DisplayLayout layout = GetCurrentDisplayLayout(); 847ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch Shell::GetInstance()->display_manager()->UpdateDisplayBoundsForLayoutById( 848ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch layout, GetPrimaryDisplay(), 849ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch ScreenAsh::GetSecondaryDisplay().id()); 8505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 8515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void DisplayController::OnFadeOutForSwapDisplayFinished() { 853c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#if defined(OS_CHROMEOS) && defined(USE_X11) 8542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) SetPrimaryDisplay(ScreenAsh::GetSecondaryDisplay()); 8552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Shell::GetInstance()->output_configurator_animation()->StartFadeInAnimation(); 8562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#endif 8572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 8582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 859eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochvoid DisplayController::UpdateHostWindowNames() { 860eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#if defined(USE_X11) 861eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // crbug.com/120229 - set the window title for the primary dislpay 862eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // to "aura_root_0" so gtalk can find the primary root window to broadcast. 863eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // TODO(jhorwich) Remove this once Chrome supports window-based broadcasting. 864eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch aura::RootWindow* primary = Shell::GetPrimaryRootWindow(); 865eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch Shell::RootWindowList root_windows = Shell::GetAllRootWindows(); 866eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch for (size_t i = 0; i < root_windows.size(); ++i) { 867eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch std::string name = 868eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch root_windows[i] == primary ? "aura_root_0" : "aura_root_x"; 869eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch gfx::AcceleratedWidget xwindow = root_windows[i]->GetAcceleratedWidget(); 870eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch XStoreName(ui::GetXDisplay(), xwindow, name.c_str()); 871eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch } 872eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#endif 873eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch} 874eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 8755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace ash 876