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" 125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "ash/display/cursor_window_controller.h" 137dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#include "ash/display/display_layout_store.h" 142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ash/display/display_manager.h" 157dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#include "ash/display/mirror_window_controller.h" 16868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "ash/display/root_window_transformers.h" 17a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch#include "ash/host/ash_window_tree_host.h" 18cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "ash/host/ash_window_tree_host_init_params.h" 19a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch#include "ash/host/root_window_transformer.h" 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ash/root_window_controller.h" 2158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)#include "ash/root_window_settings.h" 225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "ash/screen_util.h" 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ash/shell.h" 245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "ash/shell_delegate.h" 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ash/wm/coordinate_conversion.h" 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/command_line.h" 271320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "base/stl_util.h" 28868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/stringprintf.h" 2946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)#include "base/strings/utf_string_conversions.h" 30c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "ui/aura/client/capture_client.h" 31c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "ui/aura/client/focus_client.h" 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/aura/client/screen_position_client.h" 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/aura/window.h" 34a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "ui/aura/window_event_dispatcher.h" 352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ui/aura/window_property.h" 36c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "ui/aura/window_tracker.h" 37a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch#include "ui/aura/window_tree_host.h" 38c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "ui/compositor/compositor.h" 395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "ui/compositor/compositor_vsync_manager.h" 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/gfx/display.h" 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/gfx/screen.h" 42effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch#include "ui/wm/public/activation_client.h" 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_CHROMEOS) 455c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu#include "ash/display/display_configurator_animation.h" 464e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "base/sys_info.h" 47eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "base/time/time.h" 48cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#endif // defined(OS_CHROMEOS) 49cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 50c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#if defined(USE_X11) 512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ui/base/x/x11_util.h" 5268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)#include "ui/gfx/x/x11_types.h" 532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Including this at the bottom to avoid other 552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// potential conflict with chrome headers. 562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include <X11/extensions/Xrandr.h> 572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#undef RootWindow 58c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#endif // defined(USE_X11) 59cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace ash { 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace { 635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Primary display stored in global object as it can be 652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// accessed after Shell is deleted. A separate display instance is created 662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// during the shutdown instead of always keeping two display instances 672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// (one here and another one in display_manager) in sync, which is error prone. 68cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// This is initialized in the constructor, and then in CreatePrimaryHost(). 69cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)int64 primary_display_id = -1; 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Specifies how long the display change should have been disabled 722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// after each display change operations. 732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// |kCycleDisplayThrottleTimeoutMs| is set to be longer to avoid 742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// changing the settings while the system is still configurating 752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// displays. It will be overriden by |kAfterDisplayChangeThrottleTimeoutMs| 762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// when the display change happens, so the actual timeout is much shorter. 772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)const int64 kAfterDisplayChangeThrottleTimeoutMs = 500; 782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)const int64 kCycleDisplayThrottleTimeoutMs = 4000; 792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)const int64 kSwapDisplayThrottleTimeoutMs = 500; 802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 81c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen MurdochDisplayManager* GetDisplayManager() { 82c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return Shell::GetInstance()->display_manager(); 832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 85a02191e04bc25c4935f804f2c080ae28663d096dBen Murdochvoid SetDisplayPropertiesOnHost(AshWindowTreeHost* ash_host, 86a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) const gfx::Display& display) { 87c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch DisplayInfo info = GetDisplayManager()->GetDisplayInfo(display.id()); 88a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch aura::WindowTreeHost* host = ash_host->AsWindowTreeHost(); 89c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#if defined(OS_CHROMEOS) && defined(USE_X11) 902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Native window property (Atom in X11) that specifies the display's 912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // rotation, scale factor and if it's internal display. They are 922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // read and used by touchpad/mouse driver directly on X (contact 932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // adlr@ for more details on touchpad/mouse driver side). The value 942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // of the rotation is one of 0 (normal), 1 (90 degrees clockwise), 2 952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // (180 degree) or 3 (270 degrees clockwise). The value of the 962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // scale factor is in percent (100, 140, 200 etc). 972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const char kRotationProp[] = "_CHROME_DISPLAY_ROTATION"; 982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const char kScaleFactorProp[] = "_CHROME_DISPLAY_SCALE_FACTOR"; 992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const char kInternalProp[] = "_CHROME_DISPLAY_INTERNAL"; 1002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const char kCARDINAL[] = "CARDINAL"; 1012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int xrandr_rotation = RR_Rotate_0; 1022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) switch (info.rotation()) { 1032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) case gfx::Display::ROTATE_0: 1042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) xrandr_rotation = RR_Rotate_0; 1052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) break; 1062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) case gfx::Display::ROTATE_90: 1072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) xrandr_rotation = RR_Rotate_90; 1082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) break; 1092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) case gfx::Display::ROTATE_180: 1102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) xrandr_rotation = RR_Rotate_180; 1112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) break; 1122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) case gfx::Display::ROTATE_270: 1132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) xrandr_rotation = RR_Rotate_270; 1142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) break; 1152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 1162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int internal = display.IsInternal() ? 1 : 0; 118a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) gfx::AcceleratedWidget xwindow = host->GetAcceleratedWidget(); 1192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ui::SetIntProperty(xwindow, kInternalProp, kCARDINAL, internal); 1202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ui::SetIntProperty(xwindow, kRotationProp, kCARDINAL, xrandr_rotation); 1212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ui::SetIntProperty(xwindow, 1222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) kScaleFactorProp, 1232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) kCARDINAL, 1242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 100 * display.device_scale_factor()); 1252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#endif 126a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch scoped_ptr<RootWindowTransformer> transformer( 127c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch CreateRootWindowTransformerForDisplay(host->window(), display)); 128a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch ash_host->SetRootWindowTransformer(transformer.Pass()); 1295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1301320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci DisplayMode mode = 1311320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci GetDisplayManager()->GetActiveModeForDisplayId(display.id()); 1321320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (mode.refresh_rate > 0.0f) { 133a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) host->compositor()->vsync_manager()->SetAuthoritativeVSyncInterval( 134a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) base::TimeDelta::FromMicroseconds( 135a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) base::Time::kMicrosecondsPerSecond / mode.refresh_rate)); 1365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 139a02191e04bc25c4935f804f2c080ae28663d096dBen Murdochaura::Window* GetWindow(AshWindowTreeHost* ash_host) { 140f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) CHECK(ash_host->AsWindowTreeHost()); 141a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch return ash_host->AsWindowTreeHost()->window(); 142a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch} 143a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch 1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace 1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 146c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// A utility class to store/restore focused/active window 147c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// when the display configuration has changed. 148c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)class FocusActivationStore { 149c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) public: 150c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) FocusActivationStore() 151c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) : activation_client_(NULL), 152c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) capture_client_(NULL), 153c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) focus_client_(NULL), 154c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) focused_(NULL), 155c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) active_(NULL) { 156c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 157c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 158f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) void Store(bool clear_focus) { 159c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (!activation_client_) { 1601e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) aura::Window* root = Shell::GetPrimaryRootWindow(); 161c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) activation_client_ = aura::client::GetActivationClient(root); 162c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) capture_client_ = aura::client::GetCaptureClient(root); 163c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) focus_client_ = aura::client::GetFocusClient(root); 164c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 165c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) focused_ = focus_client_->GetFocusedWindow(); 166c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (focused_) 167c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) tracker_.Add(focused_); 168c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) active_ = activation_client_->GetActiveWindow(); 169c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (active_ && focused_ != active_) 170c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) tracker_.Add(active_); 171c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 172c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Deactivate the window to close menu / bubble windows. 173f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (clear_focus) 174d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) activation_client_->DeactivateWindow(active_); 175d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 176c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Release capture if any. 177c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) capture_client_->SetCapture(NULL); 178c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Clear the focused window if any. This is necessary because a 179c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // window may be deleted when losing focus (fullscreen flash for 180c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // example). If the focused window is still alive after move, it'll 181c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // be re-focused below. 182f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (clear_focus) 183d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) focus_client_->FocusWindow(NULL); 184c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 185c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 186c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) void Restore() { 187c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Restore focused or active window if it's still alive. 188c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (focused_ && tracker_.Contains(focused_)) { 189c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) focus_client_->FocusWindow(focused_); 190c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } else if (active_ && tracker_.Contains(active_)) { 191c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) activation_client_->ActivateWindow(active_); 192c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 193c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (focused_) 194c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) tracker_.Remove(focused_); 195c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (active_) 196c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) tracker_.Remove(active_); 197c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) focused_ = NULL; 198c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) active_ = NULL; 199c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 200c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 201c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) private: 202c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) aura::client::ActivationClient* activation_client_; 203c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) aura::client::CaptureClient* capture_client_; 204c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) aura::client::FocusClient* focus_client_; 205c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) aura::WindowTracker tracker_; 206c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) aura::Window* focused_; 207c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) aura::Window* active_; 208c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 209c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) DISALLOW_COPY_AND_ASSIGN(FocusActivationStore); 210c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}; 211c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 2122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)//////////////////////////////////////////////////////////////////////////////// 2132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// DisplayChangeLimiter 2142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)DisplayController::DisplayChangeLimiter::DisplayChangeLimiter() 2162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) : throttle_timeout_(base::Time::Now()) { 2172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 2182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void DisplayController::DisplayChangeLimiter::SetThrottleTimeout( 2202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int64 throttle_ms) { 2212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) throttle_timeout_ = 2222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::Time::Now() + base::TimeDelta::FromMilliseconds(throttle_ms); 2232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 2242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool DisplayController::DisplayChangeLimiter::IsThrottled() const { 2262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return base::Time::Now() < throttle_timeout_; 2272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 2282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)//////////////////////////////////////////////////////////////////////////////// 2302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// DisplayController 2312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)DisplayController::DisplayController() 233a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch : primary_tree_host_for_replace_(NULL), 234c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch focus_activation_store_(new FocusActivationStore()), 235c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch cursor_window_controller_(new CursorWindowController()), 236f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) mirror_window_controller_(new MirrorWindowController()), 237f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) weak_ptr_factory_(this) { 2382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#if defined(OS_CHROMEOS) 239a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (base::SysInfo::IsRunningOnChromeOS()) 2402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) limiter_.reset(new DisplayChangeLimiter); 2412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#endif 2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Reset primary display to make sure that tests don't use 2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // stale display info from previous tests. 2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) primary_display_id = gfx::Display::kInvalidDisplayID; 2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)DisplayController::~DisplayController() { 2482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 2492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void DisplayController::Start() { 2512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Shell::GetScreen()->AddObserver(this); 2527dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch Shell::GetInstance()->display_manager()->set_delegate(this); 2532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 2542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void DisplayController::Shutdown() { 2567dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch // Unset the display manager's delegate here because 2577dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch // DisplayManager outlives DisplayController. 2587dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch Shell::GetInstance()->display_manager()->set_delegate(NULL); 2597dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 2605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) cursor_window_controller_.reset(); 2617dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch mirror_window_controller_.reset(); 2627dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 2632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Shell::GetScreen()->RemoveObserver(this); 2641320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 2651320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci int64 primary_id = Shell::GetScreen()->GetPrimaryDisplay().id(); 2661320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 2671320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // Delete non primary root window controllers first, then 2681320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // delete the primary root window controller. 2691320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci aura::Window::Windows root_windows = DisplayController::GetAllRootWindows(); 2701320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci std::vector<RootWindowController*> to_delete; 2711320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci RootWindowController* primary_rwc = NULL; 2721320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci for (aura::Window::Windows::iterator iter = root_windows.begin(); 2731320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci iter != root_windows.end(); 2741320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci ++iter) { 2751320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci RootWindowController* rwc = GetRootWindowController(*iter); 2761320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (GetRootWindowSettings(*iter)->display_id == primary_id) 2771320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci primary_rwc = rwc; 2781320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci else 2791320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci to_delete.push_back(rwc); 2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2811320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci CHECK(primary_rwc); 2821320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 2831320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci STLDeleteElements(&to_delete); 2841320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci delete primary_rwc; 2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 287cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)void DisplayController::CreatePrimaryHost( 288cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) const AshWindowTreeHostInitParams& init_params) { 2893551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) const gfx::Display& primary_candidate = 2902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) GetDisplayManager()->GetPrimaryDisplayCandidate(); 2913551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) primary_display_id = primary_candidate.id(); 292f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) CHECK_NE(gfx::Display::kInvalidDisplayID, primary_display_id); 293cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) AddWindowTreeHostForDisplay(primary_candidate, init_params); 2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 296a02191e04bc25c4935f804f2c080ae28663d096dBen Murdochvoid DisplayController::InitDisplays() { 297a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch RootWindowController::CreateForPrimaryDisplay( 298a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch window_tree_hosts_[primary_display_id]); 299a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch 300c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch DisplayManager* display_manager = GetDisplayManager(); 3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (size_t i = 0; i < display_manager->GetNumDisplays(); ++i) { 302ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch const gfx::Display& display = display_manager->GetDisplayAt(i); 303ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch if (primary_display_id != display.id()) { 304cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) AshWindowTreeHost* ash_host = AddWindowTreeHostForDisplay( 305cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) display, AshWindowTreeHostInitParams()); 306a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch RootWindowController::CreateForSecondaryDisplay(ash_host); 3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 309eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch UpdateHostWindowNames(); 310cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 311cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) FOR_EACH_OBSERVER(Observer, observers_, OnDisplaysInitialized()); 3125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void DisplayController::AddObserver(Observer* observer) { 3155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) observers_.AddObserver(observer); 3165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void DisplayController::RemoveObserver(Observer* observer) { 3195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) observers_.RemoveObserver(observer); 3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// static 3235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)int64 DisplayController::GetPrimaryDisplayId() { 324f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) CHECK_NE(gfx::Display::kInvalidDisplayID, primary_display_id); 3255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return primary_display_id; 3265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 3275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 3281e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)aura::Window* DisplayController::GetPrimaryRootWindow() { 329a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch return GetRootWindowForDisplayId(primary_display_id); 3305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3321e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)aura::Window* DisplayController::GetRootWindowForDisplayId(int64 id) { 3331320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci CHECK_EQ(1u, window_tree_hosts_.count(id)); 334f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) AshWindowTreeHost* host = window_tree_hosts_[id]; 335f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) CHECK(host); 336f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) return GetWindow(host); 3375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void DisplayController::CloseChildWindows() { 340a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch for (WindowTreeHostMap::const_iterator it = window_tree_hosts_.begin(); 341a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch it != window_tree_hosts_.end(); 342a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch ++it) { 343a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch aura::Window* root_window = GetWindow(it->second); 344c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch RootWindowController* controller = GetRootWindowController(root_window); 3455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (controller) { 3465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) controller->CloseChildWindows(); 3475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 3485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) while (!root_window->children().empty()) { 3495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) aura::Window* child = root_window->children()[0]; 3505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) delete child; 3515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 356f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)aura::Window::Windows DisplayController::GetAllRootWindows() { 357f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) aura::Window::Windows windows; 358a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch for (WindowTreeHostMap::const_iterator it = window_tree_hosts_.begin(); 359a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch it != window_tree_hosts_.end(); 360a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch ++it) { 3615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(it->second); 362a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch if (GetRootWindowController(GetWindow(it->second))) 363a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch windows.push_back(GetWindow(it->second)); 3645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return windows; 3665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)gfx::Insets DisplayController::GetOverscanInsets(int64 display_id) const { 3695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return GetDisplayManager()->GetOverscanInsets(display_id); 3705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void DisplayController::SetOverscanInsets(int64 display_id, 3732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const gfx::Insets& insets_in_dip) { 3742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) GetDisplayManager()->SetOverscanInsets(display_id, insets_in_dip); 3752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 3762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 377c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdochstd::vector<RootWindowController*> 3785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)DisplayController::GetAllRootWindowControllers() { 379c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch std::vector<RootWindowController*> controllers; 380a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch for (WindowTreeHostMap::const_iterator it = window_tree_hosts_.begin(); 381a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch it != window_tree_hosts_.end(); 382a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch ++it) { 383a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch RootWindowController* controller = 384a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch GetRootWindowController(GetWindow(it->second)); 3855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (controller) 3865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) controllers.push_back(controller); 3875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return controllers; 3895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 39190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)void DisplayController::ToggleMirrorMode() { 392c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch DisplayManager* display_manager = GetDisplayManager(); 39390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) if (display_manager->num_connected_displays() <= 1) 39490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) return; 39590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 396c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (limiter_) { 3972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (limiter_->IsThrottled()) 3982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return; 3992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) limiter_->SetThrottleTimeout(kCycleDisplayThrottleTimeoutMs); 4002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 401effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch#if defined(OS_CHROMEOS) 4022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Shell* shell = Shell::GetInstance(); 4035c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu DisplayConfiguratorAnimation* animation = 4045c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu shell->display_configurator_animation(); 405c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch animation->StartFadeOutAnimation( 406f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) base::Bind(&DisplayController::SetMirrorModeAfterAnimation, 407f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) weak_ptr_factory_.GetWeakPtr(), 408c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch !display_manager->IsMirrored())); 4092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#endif 4102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 4112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void DisplayController::SwapPrimaryDisplay() { 413c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (limiter_) { 4142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (limiter_->IsThrottled()) 4152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return; 4162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) limiter_->SetThrottleTimeout(kSwapDisplayThrottleTimeoutMs); 4172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 4182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (Shell::GetScreen()->GetNumDisplays() > 1) { 420effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch#if defined(OS_CHROMEOS) 4215c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu DisplayConfiguratorAnimation* animation = 4225c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu Shell::GetInstance()->display_configurator_animation(); 4232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (animation) { 4242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) animation->StartFadeOutAnimation(base::Bind( 4252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) &DisplayController::OnFadeOutForSwapDisplayFinished, 426f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) weak_ptr_factory_.GetWeakPtr())); 4272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } else { 4285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) SetPrimaryDisplay(ScreenUtil::GetSecondaryDisplay()); 4292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 4302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#else 4315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) SetPrimaryDisplay(ScreenUtil::GetSecondaryDisplay()); 4322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#endif 4335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void DisplayController::SetPrimaryDisplayId(int64 id) { 437c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) DCHECK_NE(gfx::Display::kInvalidDisplayID, id); 438c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (id == gfx::Display::kInvalidDisplayID || primary_display_id == id) 4395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 4405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 441c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const gfx::Display& display = GetDisplayManager()->GetDisplayForId(id); 442c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (display.is_valid()) 443c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) SetPrimaryDisplay(display); 4445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void DisplayController::SetPrimaryDisplay( 4475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const gfx::Display& new_primary_display) { 448c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch DisplayManager* display_manager = GetDisplayManager(); 4495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(new_primary_display.is_valid()); 4505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(display_manager->IsActiveDisplay(new_primary_display)); 4515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!new_primary_display.is_valid() || 4535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) !display_manager->IsActiveDisplay(new_primary_display)) { 4545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LOG(ERROR) << "Invalid or non-existent display is requested:" 4555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) << new_primary_display.ToString(); 4565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 4575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (primary_display_id == new_primary_display.id() || 460a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch window_tree_hosts_.size() < 2) { 4615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 4625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 464a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch AshWindowTreeHost* non_primary_host = 465a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch window_tree_hosts_[new_primary_display.id()]; 466a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch LOG_IF(ERROR, !non_primary_host) 4675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) << "Unknown display is requested in SetPrimaryDisplay: id=" 4685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) << new_primary_display.id(); 469a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch if (!non_primary_host) 4705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 4715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) gfx::Display old_primary_display = Shell::GetScreen()->GetPrimaryDisplay(); 4735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Swap root windows between current and new primary display. 475a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch AshWindowTreeHost* primary_host = window_tree_hosts_[primary_display_id]; 476f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) CHECK(primary_host); 477f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) CHECK_NE(primary_host, non_primary_host); 4785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 479a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch window_tree_hosts_[new_primary_display.id()] = primary_host; 480a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch GetRootWindowSettings(GetWindow(primary_host))->display_id = 481a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch new_primary_display.id(); 4825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 483a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch window_tree_hosts_[old_primary_display.id()] = non_primary_host; 484a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch GetRootWindowSettings(GetWindow(non_primary_host))->display_id = 48558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) old_primary_display.id(); 4865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) primary_display_id = new_primary_display.id(); 4887dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch GetDisplayManager()->layout_store()->UpdatePrimaryDisplayId( 4893551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) display_manager->GetCurrentDisplayIdPair(), primary_display_id); 4905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 491a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch UpdateWorkAreaOfDisplayNearestWindow(GetWindow(primary_host), 492a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch old_primary_display.GetWorkAreaInsets()); 493a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch UpdateWorkAreaOfDisplayNearestWindow(GetWindow(non_primary_host), 494a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch new_primary_display.GetWorkAreaInsets()); 4955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Update the dispay manager with new display info. 497c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch std::vector<DisplayInfo> display_info_list; 4982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) display_info_list.push_back(display_manager->GetDisplayInfo( 4992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) primary_display_id)); 5002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) display_info_list.push_back(display_manager->GetDisplayInfo( 5015d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ScreenUtil::GetSecondaryDisplay().id())); 5025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GetDisplayManager()->set_force_bounds_changed(true); 5032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) GetDisplayManager()->UpdateDisplays(display_info_list); 5045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GetDisplayManager()->set_force_bounds_changed(false); 5055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 507c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void DisplayController::EnsurePointerInDisplays() { 5087dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch // If the mouse is currently on a display in native location, 5097dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch // use the same native location. Otherwise find the display closest 5107dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch // to the current cursor location in screen coordinates. 5117dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 5127dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch gfx::Point point_in_screen = Shell::GetScreen()->GetCursorScreenPoint(); 5137dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch gfx::Point target_location_in_native; 514c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) int64 closest_distance_squared = -1; 515c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch DisplayManager* display_manager = GetDisplayManager(); 516c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 5171e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) aura::Window* dst_root_window = NULL; 518c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) for (size_t i = 0; i < display_manager->GetNumDisplays(); ++i) { 519ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch const gfx::Display& display = display_manager->GetDisplayAt(i); 520c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch const DisplayInfo display_info = 521ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch display_manager->GetDisplayInfo(display.id()); 5221e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) aura::Window* root_window = GetRootWindowForDisplayId(display.id()); 52368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) if (display_info.bounds_in_native().Contains( 5247dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch cursor_location_in_native_coords_for_restore_)) { 525c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) dst_root_window = root_window; 5267dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch target_location_in_native = cursor_location_in_native_coords_for_restore_; 527c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) break; 528c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 529ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch gfx::Point center = display.bounds().CenterPoint(); 530c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Use the distance squared from the center of the dislay. This is not 531c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // exactly "closest" display, but good enough to pick one 532c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // appropriate (and there are at most two displays). 533c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // We don't care about actual distance, only relative to other displays, so 534c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // using the LengthSquared() is cheaper than Length(). 535c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 5367dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch int64 distance_squared = (center - point_in_screen).LengthSquared(); 537c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (closest_distance_squared < 0 || 538c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) closest_distance_squared > distance_squared) { 5391e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) aura::Window* root_window = GetRootWindowForDisplayId(display.id()); 5407dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch aura::client::ScreenPositionClient* client = 5417dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch aura::client::GetScreenPositionClient(root_window); 5427dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch client->ConvertPointFromScreen(root_window, ¢er); 543a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) root_window->GetHost()->ConvertPointToNativeScreen(¢er); 544c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) dst_root_window = root_window; 5457dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch target_location_in_native = center; 546c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) closest_distance_squared = distance_squared; 547c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 548c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 549a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) dst_root_window->GetHost()->ConvertPointFromNativeScreen( 5501e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) &target_location_in_native); 5517dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch dst_root_window->MoveCursorTo(target_location_in_native); 5527dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch} 5537dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 5547dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochbool DisplayController::UpdateWorkAreaOfDisplayNearestWindow( 5557dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch const aura::Window* window, 5567dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch const gfx::Insets& insets) { 5571e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) const aura::Window* root_window = window->GetRootWindow(); 558c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch int64 id = GetRootWindowSettings(root_window)->display_id; 559ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch // if id is |kInvaildDisplayID|, it's being deleted. 560ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch DCHECK(id != gfx::Display::kInvalidDisplayID); 561ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch return GetDisplayManager()->UpdateWorkAreaOfDisplay(id, insets); 5627dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch} 5637dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 5645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void DisplayController::OnDisplayAdded(const gfx::Display& display) { 565a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch if (primary_tree_host_for_replace_) { 566a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch DCHECK(window_tree_hosts_.empty()); 5672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) primary_display_id = display.id(); 568a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch window_tree_hosts_[display.id()] = primary_tree_host_for_replace_; 569a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch GetRootWindowSettings(GetWindow(primary_tree_host_for_replace_)) 570a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch ->display_id = display.id(); 571a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch primary_tree_host_for_replace_ = NULL; 572c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch const DisplayInfo& display_info = 5732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) GetDisplayManager()->GetDisplayInfo(display.id()); 574a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch AshWindowTreeHost* ash_host = window_tree_hosts_[display.id()]; 575a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch ash_host->AsWindowTreeHost()->SetBounds(display_info.bounds_in_native()); 576a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch SetDisplayPropertiesOnHost(ash_host, display); 5772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } else { 578c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (primary_display_id == gfx::Display::kInvalidDisplayID) 579c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) primary_display_id = display.id(); 580a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch DCHECK(!window_tree_hosts_.empty()); 581cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) AshWindowTreeHost* ash_host = AddWindowTreeHostForDisplay( 582cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) display, AshWindowTreeHostInitParams()); 583a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch RootWindowController::CreateForSecondaryDisplay(ash_host); 5842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 5855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void DisplayController::OnDisplayRemoved(const gfx::Display& display) { 588a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch AshWindowTreeHost* host_to_delete = window_tree_hosts_[display.id()]; 589f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) CHECK(host_to_delete) << display.ToString(); 5905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Display for root window will be deleted when the Primary RootWindow 5925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // is deleted by the Shell. 593a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch window_tree_hosts_.erase(display.id()); 5945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // When the primary root window's display is removed, move the primary 5965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // root to the other display. 5975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (primary_display_id == display.id()) { 5982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Temporarily store the primary root window in 5992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // |primary_root_window_for_replace_| when replacing the display. 600a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch if (window_tree_hosts_.size() == 0) { 6012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) primary_display_id = gfx::Display::kInvalidDisplayID; 602a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch primary_tree_host_for_replace_ = host_to_delete; 6032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return; 6042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 605a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch DCHECK_EQ(1U, window_tree_hosts_.size()); 6065d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) primary_display_id = ScreenUtil::GetSecondaryDisplay().id(); 607a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch AshWindowTreeHost* primary_host = host_to_delete; 6085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 609a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch // Delete the other host instead. 610a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch host_to_delete = window_tree_hosts_[primary_display_id]; 611a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch GetRootWindowSettings(GetWindow(host_to_delete))->display_id = display.id(); 6125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Setup primary root. 614a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch window_tree_hosts_[primary_display_id] = primary_host; 615a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch GetRootWindowSettings(GetWindow(primary_host))->display_id = 616a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch primary_display_id; 6175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 618cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) OnDisplayMetricsChanged( 619cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) GetDisplayManager()->GetDisplayForId(primary_display_id), 620cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) DISPLAY_METRIC_BOUNDS); 6215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 622a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch RootWindowController* controller = 623a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch GetRootWindowController(GetWindow(host_to_delete)); 6245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(controller); 6255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) controller->MoveWindowsTo(GetPrimaryRootWindow()); 6265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Delete most of root window related objects, but don't delete 6275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // root window itself yet because the stack may be using it. 6285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) controller->Shutdown(); 629c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::MessageLoop::current()->DeleteSoon(FROM_HERE, controller); 6305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 632cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)void DisplayController::OnDisplayMetricsChanged(const gfx::Display& display, 633cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) uint32_t metrics) { 634cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (!(metrics & (DISPLAY_METRIC_BOUNDS | DISPLAY_METRIC_ROTATION | 635cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) DISPLAY_METRIC_DEVICE_SCALE_FACTOR))) 636cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) return; 637cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) const DisplayInfo& display_info = 638cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) GetDisplayManager()->GetDisplayInfo(display.id()); 639cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) DCHECK(!display_info.bounds_in_native().IsEmpty()); 640cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) AshWindowTreeHost* ash_host = window_tree_hosts_[display.id()]; 641cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) ash_host->AsWindowTreeHost()->SetBounds(display_info.bounds_in_native()); 642cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) SetDisplayPropertiesOnHost(ash_host, display); 643cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)} 644cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 645a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)void DisplayController::OnHostResized(const aura::WindowTreeHost* host) { 6465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) gfx::Display display = Shell::GetScreen()->GetDisplayNearestWindow( 647a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) const_cast<aura::Window*>(host->window())); 6485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 649c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch DisplayManager* display_manager = GetDisplayManager(); 650a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (display_manager->UpdateDisplayBounds(display.id(), host->GetBounds())) { 6517dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch mirror_window_controller_->UpdateWindow(); 6525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) cursor_window_controller_->UpdateContainer(); 6537dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch } 6547dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch} 6557dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 6561e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)void DisplayController::CreateOrUpdateNonDesktopDisplay( 657c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch const DisplayInfo& info) { 6581e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) switch (GetDisplayManager()->second_display_mode()) { 659c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch case DisplayManager::MIRRORING: 6601e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) mirror_window_controller_->UpdateWindow(info); 6615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) cursor_window_controller_->UpdateContainer(); 6621e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) break; 663c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch case DisplayManager::EXTENDED: 6641e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) NOTREACHED(); 6651e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) } 6667dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch} 6677dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 6681e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)void DisplayController::CloseNonDesktopDisplay() { 6697dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch mirror_window_controller_->Close(); 6701320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // If cursor_compositing is enabled for large cursor, the cursor window is 6711320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // always on the desktop display (the visible cursor on the non-desktop 6721320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // display is drawn through compositor mirroring). Therefore, it's unnecessary 6731320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // to handle the cursor_window at all. See: http://crbug.com/412910 6741320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (!cursor_window_controller_->is_cursor_compositing_enabled()) 6751320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci cursor_window_controller_->UpdateContainer(); 6767dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch} 6777dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 678f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)void DisplayController::PreDisplayConfigurationChange(bool clear_focus) { 6797dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch FOR_EACH_OBSERVER(Observer, observers_, OnDisplayConfigurationChanging()); 680f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) focus_activation_store_->Store(clear_focus); 6815d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) gfx::Screen* screen = Shell::GetScreen(); 6825d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) gfx::Point point_in_screen = screen->GetCursorScreenPoint(); 6835d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) gfx::Display display = screen->GetDisplayNearestPoint(point_in_screen); 6841e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) aura::Window* root_window = GetRootWindowForDisplayId(display.id()); 6857dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 6867dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch aura::client::ScreenPositionClient* client = 6877dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch aura::client::GetScreenPositionClient(root_window); 6887dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch client->ConvertPointFromScreen(root_window, &point_in_screen); 689a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) root_window->GetHost()->ConvertPointToNativeScreen(&point_in_screen); 6907dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch cursor_location_in_native_coords_for_restore_ = point_in_screen; 6917dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch} 6927dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 6937dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochvoid DisplayController::PostDisplayConfigurationChange() { 6947dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch if (limiter_) 6957dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch limiter_->SetThrottleTimeout(kAfterDisplayChangeThrottleTimeoutMs); 6967dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 6977dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch focus_activation_store_->Restore(); 6987dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 699c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch DisplayManager* display_manager = GetDisplayManager(); 700c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch DisplayLayoutStore* layout_store = display_manager->layout_store(); 7017dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch if (display_manager->num_connected_displays() > 1) { 7023551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) DisplayIdPair pair = display_manager->GetCurrentDisplayIdPair(); 7037dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch layout_store->UpdateMirrorStatus(pair, display_manager->IsMirrored()); 7047dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch DisplayLayout layout = layout_store->GetRegisteredDisplayLayout(pair); 7057dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 7067dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch if (Shell::GetScreen()->GetNumDisplays() > 1 ) { 7077dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch int64 primary_id = layout.primary_id; 7087dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch SetPrimaryDisplayId( 7097dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch primary_id == gfx::Display::kInvalidDisplayID ? 7107dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch pair.first : primary_id); 7117dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch // Update the primary_id in case the above call is 7127dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch // ignored. Happens when a) default layout's primary id 7137dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch // doesn't exist, or b) the primary_id has already been 7147dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch // set to the same and didn't update it. 7155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) layout_store->UpdatePrimaryDisplayId( 7165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) pair, Shell::GetScreen()->GetPrimaryDisplay().id()); 7177dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch } 7187dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch } 7197dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch FOR_EACH_OBSERVER(Observer, observers_, OnDisplayConfigurationChanged()); 7207dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch UpdateHostWindowNames(); 7217dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch EnsurePointerInDisplays(); 7227dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch} 7237dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 724a02191e04bc25c4935f804f2c080ae28663d096dBen MurdochAshWindowTreeHost* DisplayController::AddWindowTreeHostForDisplay( 725cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) const gfx::Display& display, 726cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) const AshWindowTreeHostInitParams& init_params) { 727a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) static int host_count = 0; 728c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch const DisplayInfo& display_info = 7292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) GetDisplayManager()->GetDisplayInfo(display.id()); 730cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) AshWindowTreeHostInitParams params_with_bounds(init_params); 731cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) params_with_bounds.initial_bounds = display_info.bounds_in_native(); 732cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) AshWindowTreeHost* ash_host = AshWindowTreeHost::Create(params_with_bounds); 733a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch aura::WindowTreeHost* host = ash_host->AsWindowTreeHost(); 734a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch 735a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) host->window()->SetName(base::StringPrintf("RootWindow-%d", host_count++)); 736116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch host->window()->SetTitle(base::UTF8ToUTF16(display_info.name())); 737a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) host->compositor()->SetBackgroundColor(SK_ColorBLACK); 738a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // No need to remove our observer observer because the DisplayController 739a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // outlives the host. 740a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) host->AddObserver(this); 741c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch InitRootWindowSettings(host->window())->display_id = display.id(); 742a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) host->InitHost(); 743a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 744a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch window_tree_hosts_[display.id()] = ash_host; 745a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch SetDisplayPropertiesOnHost(ash_host, display); 7465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_CHROMEOS) 7485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static bool force_constrain_pointer_to_root = 7495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CommandLine::ForCurrentProcess()->HasSwitch( 7505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) switches::kAshConstrainPointerToRoot); 7514e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) if (base::SysInfo::IsRunningOnChromeOS() || force_constrain_pointer_to_root) 752a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch ash_host->ConfineCursorToRootWindow(); 7535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 754a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch return ash_host; 7555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 7565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void DisplayController::OnFadeOutForSwapDisplayFinished() { 758effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch#if defined(OS_CHROMEOS) 7595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) SetPrimaryDisplay(ScreenUtil::GetSecondaryDisplay()); 7605c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu Shell::GetInstance()->display_configurator_animation() 7615c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu ->StartFadeInAnimation(); 7622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#endif 7632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 7642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 765f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)void DisplayController::SetMirrorModeAfterAnimation(bool mirror) { 766f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) GetDisplayManager()->SetMirrorMode(mirror); 767f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)} 768f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 769eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochvoid DisplayController::UpdateHostWindowNames() { 770eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#if defined(USE_X11) 771eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // crbug.com/120229 - set the window title for the primary dislpay 772eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // to "aura_root_0" so gtalk can find the primary root window to broadcast. 773eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // TODO(jhorwich) Remove this once Chrome supports window-based broadcasting. 7741e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) aura::Window* primary = Shell::GetPrimaryRootWindow(); 775f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) aura::Window::Windows root_windows = Shell::GetAllRootWindows(); 776eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch for (size_t i = 0; i < root_windows.size(); ++i) { 777eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch std::string name = 778eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch root_windows[i] == primary ? "aura_root_0" : "aura_root_x"; 7791e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) gfx::AcceleratedWidget xwindow = 780a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) root_windows[i]->GetHost()->GetAcceleratedWidget(); 78168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) XStoreName(gfx::GetXDisplay(), xwindow, name.c_str()); 782eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch } 783eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#endif 784eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch} 785eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 7865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace ash 787