OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "ash/display/display_controller.h" | 5 #include "ash/display/display_controller.h" |
6 | 6 |
7 #include <algorithm> | 7 #include <algorithm> |
8 #include <cmath> | 8 #include <cmath> |
9 | 9 |
10 #include "ash/ash_switches.h" | 10 #include "ash/ash_switches.h" |
11 #include "ash/display/display_manager.h" | 11 #include "ash/display/display_manager.h" |
12 #include "ash/host/root_window_host_factory.h" | 12 #include "ash/host/root_window_host_factory.h" |
13 #include "ash/root_window_controller.h" | 13 #include "ash/root_window_controller.h" |
14 #include "ash/screen_ash.h" | 14 #include "ash/screen_ash.h" |
15 #include "ash/shell.h" | 15 #include "ash/shell.h" |
16 #include "ash/wm/coordinate_conversion.h" | 16 #include "ash/wm/coordinate_conversion.h" |
17 #include "ash/wm/property_util.h" | 17 #include "ash/wm/property_util.h" |
18 #include "ash/wm/window_util.h" | 18 #include "ash/wm/window_util.h" |
19 #include "base/command_line.h" | 19 #include "base/command_line.h" |
20 #include "base/json/json_value_converter.h" | 20 #include "base/json/json_value_converter.h" |
21 #include "base/string_piece.h" | 21 #include "base/string_piece.h" |
22 #include "base/stringprintf.h" | 22 #include "base/stringprintf.h" |
23 #include "base/values.h" | 23 #include "base/values.h" |
24 #include "third_party/skia/include/utils/SkMatrix44.h" | 24 #include "third_party/skia/include/utils/SkMatrix44.h" |
| 25 #include "ui/aura/client/activation_client.h" |
| 26 #include "ui/aura/client/capture_client.h" |
| 27 #include "ui/aura/client/cursor_client.h" |
| 28 #include "ui/aura/client/focus_client.h" |
25 #include "ui/aura/client/screen_position_client.h" | 29 #include "ui/aura/client/screen_position_client.h" |
26 #include "ui/aura/env.h" | 30 #include "ui/aura/env.h" |
27 #include "ui/aura/root_window.h" | 31 #include "ui/aura/root_window.h" |
28 #include "ui/aura/window.h" | 32 #include "ui/aura/window.h" |
29 #include "ui/aura/window_property.h" | 33 #include "ui/aura/window_property.h" |
| 34 #include "ui/aura/window_tracker.h" |
30 #include "ui/compositor/compositor.h" | 35 #include "ui/compositor/compositor.h" |
31 #include "ui/compositor/dip_util.h" | 36 #include "ui/compositor/dip_util.h" |
32 #include "ui/gfx/display.h" | 37 #include "ui/gfx/display.h" |
33 #include "ui/gfx/screen.h" | 38 #include "ui/gfx/screen.h" |
34 | 39 |
35 #if defined(OS_CHROMEOS) | 40 #if defined(OS_CHROMEOS) |
36 #include "ash/display/output_configurator_animation.h" | 41 #include "ash/display/output_configurator_animation.h" |
37 #include "base/chromeos/chromeos_version.h" | 42 #include "base/chromeos/chromeos_version.h" |
38 #include "base/string_number_conversions.h" | 43 #include "base/string_number_conversions.h" |
39 #include "base/time.h" | 44 #include "base/time.h" |
(...skipping 174 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
214 ui::SetIntProperty(xwindow, | 219 ui::SetIntProperty(xwindow, |
215 kScaleFactorProp, | 220 kScaleFactorProp, |
216 kCARDINAL, | 221 kCARDINAL, |
217 100 * display.device_scale_factor()); | 222 100 * display.device_scale_factor()); |
218 #endif | 223 #endif |
219 RotateRootWindow(root, display, info); | 224 RotateRootWindow(root, display, info); |
220 } | 225 } |
221 | 226 |
222 } // namespace | 227 } // namespace |
223 | 228 |
| 229 namespace internal { |
| 230 |
| 231 // A utility class to store/restore focused/active window |
| 232 // when the display configuration has changed. |
| 233 class FocusActivationStore { |
| 234 public: |
| 235 FocusActivationStore() |
| 236 : activation_client_(NULL), |
| 237 capture_client_(NULL), |
| 238 focus_client_(NULL), |
| 239 focused_(NULL), |
| 240 active_(NULL) { |
| 241 } |
| 242 |
| 243 void Store() { |
| 244 if (!activation_client_) { |
| 245 aura::RootWindow* root = Shell::GetPrimaryRootWindow(); |
| 246 activation_client_ = aura::client::GetActivationClient(root); |
| 247 capture_client_ = aura::client::GetCaptureClient(root); |
| 248 focus_client_ = aura::client::GetFocusClient(root); |
| 249 } |
| 250 focused_ = focus_client_->GetFocusedWindow(); |
| 251 if (focused_) |
| 252 tracker_.Add(focused_); |
| 253 active_ = activation_client_->GetActiveWindow(); |
| 254 if (active_ && focused_ != active_) |
| 255 tracker_.Add(active_); |
| 256 |
| 257 // Deactivate the window to close menu / bubble windows. |
| 258 activation_client_->DeactivateWindow(active_); |
| 259 // Release capture if any. |
| 260 capture_client_->SetCapture(NULL); |
| 261 // Clear the focused window if any. This is necessary because a |
| 262 // window may be deleted when losing focus (fullscreen flash for |
| 263 // example). If the focused window is still alive after move, it'll |
| 264 // be re-focused below. |
| 265 focus_client_->FocusWindow(NULL); |
| 266 } |
| 267 |
| 268 void Restore() { |
| 269 // Restore focused or active window if it's still alive. |
| 270 if (focused_ && tracker_.Contains(focused_)) { |
| 271 focus_client_->FocusWindow(focused_); |
| 272 } else if (active_ && tracker_.Contains(active_)) { |
| 273 activation_client_->ActivateWindow(active_); |
| 274 } |
| 275 if (focused_) |
| 276 tracker_.Remove(focused_); |
| 277 if (active_) |
| 278 tracker_.Remove(active_); |
| 279 focused_ = NULL; |
| 280 active_ = NULL; |
| 281 } |
| 282 |
| 283 private: |
| 284 aura::client::ActivationClient* activation_client_; |
| 285 aura::client::CaptureClient* capture_client_; |
| 286 aura::client::FocusClient* focus_client_; |
| 287 aura::WindowTracker tracker_; |
| 288 aura::Window* focused_; |
| 289 aura::Window* active_; |
| 290 |
| 291 DISALLOW_COPY_AND_ASSIGN(FocusActivationStore); |
| 292 }; |
| 293 |
| 294 } // namespace internal |
| 295 |
224 //////////////////////////////////////////////////////////////////////////////// | 296 //////////////////////////////////////////////////////////////////////////////// |
225 // DisplayLayout | 297 // DisplayLayout |
226 | 298 |
227 // static | 299 // static |
228 DisplayLayout DisplayLayout::FromInts(int position, int offsets) { | 300 DisplayLayout DisplayLayout::FromInts(int position, int offsets) { |
229 return DisplayLayout(static_cast<Position>(position), offsets); | 301 return DisplayLayout(static_cast<Position>(position), offsets); |
230 } | 302 } |
231 | 303 |
232 DisplayLayout::DisplayLayout() | 304 DisplayLayout::DisplayLayout() |
233 : position(RIGHT), | 305 : position(RIGHT), |
(...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
320 | 392 |
321 bool DisplayController::DisplayChangeLimiter::IsThrottled() const { | 393 bool DisplayController::DisplayChangeLimiter::IsThrottled() const { |
322 return base::Time::Now() < throttle_timeout_; | 394 return base::Time::Now() < throttle_timeout_; |
323 } | 395 } |
324 | 396 |
325 //////////////////////////////////////////////////////////////////////////////// | 397 //////////////////////////////////////////////////////////////////////////////// |
326 // DisplayController | 398 // DisplayController |
327 | 399 |
328 DisplayController::DisplayController() | 400 DisplayController::DisplayController() |
329 : desired_primary_display_id_(gfx::Display::kInvalidDisplayID), | 401 : desired_primary_display_id_(gfx::Display::kInvalidDisplayID), |
330 primary_root_window_for_replace_(NULL) { | 402 primary_root_window_for_replace_(NULL), |
| 403 focus_activation_store_(new internal::FocusActivationStore()) { |
331 CommandLine* command_line = CommandLine::ForCurrentProcess(); | 404 CommandLine* command_line = CommandLine::ForCurrentProcess(); |
332 #if defined(OS_CHROMEOS) | 405 #if defined(OS_CHROMEOS) |
333 if (!command_line->HasSwitch(switches::kAshDisableDisplayChangeLimiter) && | 406 if (!command_line->HasSwitch(switches::kAshDisableDisplayChangeLimiter) && |
334 base::chromeos::IsRunningOnChromeOS()) | 407 base::chromeos::IsRunningOnChromeOS()) |
335 limiter_.reset(new DisplayChangeLimiter); | 408 limiter_.reset(new DisplayChangeLimiter); |
336 #endif | 409 #endif |
337 if (command_line->HasSwitch(switches::kAshSecondaryDisplayLayout)) { | 410 if (command_line->HasSwitch(switches::kAshSecondaryDisplayLayout)) { |
338 std::string value = command_line->GetSwitchValueASCII( | 411 std::string value = command_line->GetSwitchValueASCII( |
339 switches::kAshSecondaryDisplayLayout); | 412 switches::kAshSecondaryDisplayLayout); |
340 char layout; | 413 char layout; |
(...skipping 552 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
893 break; | 966 break; |
894 } | 967 } |
895 gfx::Insets insets = secondary_display->GetWorkAreaInsets(); | 968 gfx::Insets insets = secondary_display->GetWorkAreaInsets(); |
896 secondary_display->set_bounds( | 969 secondary_display->set_bounds( |
897 gfx::Rect(new_secondary_origin, secondary_bounds.size())); | 970 gfx::Rect(new_secondary_origin, secondary_bounds.size())); |
898 secondary_display->UpdateWorkAreaFromInsets(insets); | 971 secondary_display->UpdateWorkAreaFromInsets(insets); |
899 } | 972 } |
900 | 973 |
901 void DisplayController::NotifyDisplayConfigurationChanging() { | 974 void DisplayController::NotifyDisplayConfigurationChanging() { |
902 FOR_EACH_OBSERVER(Observer, observers_, OnDisplayConfigurationChanging()); | 975 FOR_EACH_OBSERVER(Observer, observers_, OnDisplayConfigurationChanging()); |
| 976 focus_activation_store_->Store(); |
903 } | 977 } |
904 | 978 |
905 void DisplayController::NotifyDisplayConfigurationChanged() { | 979 void DisplayController::NotifyDisplayConfigurationChanged() { |
| 980 focus_activation_store_->Restore(); |
| 981 |
906 internal::DisplayManager* display_manager = GetDisplayManager(); | 982 internal::DisplayManager* display_manager = GetDisplayManager(); |
907 if (display_manager->num_connected_displays() > 1) { | 983 if (display_manager->num_connected_displays() > 1) { |
908 DisplayIdPair pair = GetCurrentDisplayIdPair(); | 984 DisplayIdPair pair = GetCurrentDisplayIdPair(); |
909 bool exists = paired_layouts_.find(pair) != paired_layouts_.end(); | 985 bool exists = paired_layouts_.find(pair) != paired_layouts_.end(); |
910 if (exists || display_manager->IsMirrored()) { | 986 if (exists || display_manager->IsMirrored()) { |
911 if (!exists) | 987 if (!exists) |
912 paired_layouts_[pair] = default_display_layout_; | 988 paired_layouts_[pair] = default_display_layout_; |
913 paired_layouts_[pair].mirrored = display_manager->IsMirrored(); | 989 paired_layouts_[pair].mirrored = display_manager->IsMirrored(); |
914 } | 990 } |
915 } | 991 } |
(...skipping 11 matching lines...) Expand all Loading... |
927 } | 1003 } |
928 | 1004 |
929 void DisplayController::OnFadeOutForSwapDisplayFinished() { | 1005 void DisplayController::OnFadeOutForSwapDisplayFinished() { |
930 #if defined(OS_CHROMEOS) | 1006 #if defined(OS_CHROMEOS) |
931 SetPrimaryDisplay(ScreenAsh::GetSecondaryDisplay()); | 1007 SetPrimaryDisplay(ScreenAsh::GetSecondaryDisplay()); |
932 Shell::GetInstance()->output_configurator_animation()->StartFadeInAnimation(); | 1008 Shell::GetInstance()->output_configurator_animation()->StartFadeInAnimation(); |
933 #endif | 1009 #endif |
934 } | 1010 } |
935 | 1011 |
936 } // namespace ash | 1012 } // namespace ash |
OLD | NEW |