OLD | NEW |
---|---|
1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 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/wm/window_state.h" | 5 #include "ash/wm/window_state.h" |
6 | 6 |
7 #include "ash/ash_switches.h" | 7 #include "ash/ash_switches.h" |
8 #include "ash/root_window_controller.h" | 8 #include "ash/root_window_controller.h" |
9 #include "ash/screen_util.h" | 9 #include "ash/screen_util.h" |
10 #include "ash/shell_window_ids.h" | 10 #include "ash/shell_window_ids.h" |
11 #include "ash/wm/default_state.h" | 11 #include "ash/wm/default_state.h" |
12 #include "ash/wm/window_properties.h" | 12 #include "ash/wm/window_properties.h" |
13 #include "ash/wm/window_state_delegate.h" | 13 #include "ash/wm/window_state_delegate.h" |
14 #include "ash/wm/window_state_observer.h" | 14 #include "ash/wm/window_state_observer.h" |
15 #include "ash/wm/window_util.h" | 15 #include "ash/wm/window_util.h" |
16 #include "ash/wm/wm_types.h" | 16 #include "ash/wm/wm_types.h" |
17 #include "base/auto_reset.h" | 17 #include "base/auto_reset.h" |
18 #include "base/command_line.h" | 18 #include "base/command_line.h" |
19 #include "ui/aura/client/aura_constants.h" | 19 #include "ui/aura/client/aura_constants.h" |
20 #include "ui/aura/layout_manager.h" | |
20 #include "ui/aura/window.h" | 21 #include "ui/aura/window.h" |
21 #include "ui/aura/window_delegate.h" | 22 #include "ui/aura/window_delegate.h" |
23 #include "ui/compositor/scoped_layer_animation_settings.h" | |
22 #include "ui/gfx/display.h" | 24 #include "ui/gfx/display.h" |
23 #include "ui/views/corewm/window_util.h" | 25 #include "ui/views/corewm/window_util.h" |
24 | 26 |
25 namespace ash { | 27 namespace ash { |
26 namespace wm { | 28 namespace wm { |
27 | 29 |
30 namespace { | |
31 | |
32 // A tentative class to set the bounds on the window. | |
33 // TODO(oshima): Once all logic are cleaned up, move this to the real layout | |
34 // manager with proper friendship. | |
pkotwicz
2014/02/12 05:44:48
Can you move adding this class as part of a differ
oshima
2014/02/12 14:08:33
Sorry, I didn't understand. Can you elaborate?
pkotwicz
2014/02/12 18:20:18
Can you remove this class from this CL?
oshima
2014/02/12 19:56:16
Sorry I still didn't understand. This is used in 4
pkotwicz
2014/02/12 22:27:27
I see now
| |
35 class BoundsSetter : public aura::LayoutManager { | |
36 public: | |
37 BoundsSetter() {} | |
38 virtual ~BoundsSetter() {} | |
39 | |
40 // aura::LayoutManager overrides: | |
41 virtual void OnWindowResized() OVERRIDE {} | |
42 virtual void OnWindowAddedToLayout(aura::Window* child) OVERRIDE {} | |
43 virtual void OnWillRemoveWindowFromLayout(aura::Window* child) OVERRIDE {} | |
44 virtual void OnWindowRemovedFromLayout(aura::Window* child) OVERRIDE {} | |
45 virtual void OnChildWindowVisibilityChanged( | |
46 aura::Window* child, bool visible) OVERRIDE {} | |
47 virtual void SetChildBounds( | |
48 aura::Window* child, const gfx::Rect& requested_bounds) OVERRIDE {} | |
49 | |
50 void SetBounds(aura::Window* window, const gfx::Rect& bounds) { | |
51 SetChildBoundsDirect(window, bounds); | |
52 } | |
53 | |
54 private: | |
55 DISALLOW_COPY_AND_ASSIGN(BoundsSetter); | |
56 }; | |
57 | |
58 WMEvent WMEventFromShowState(ui::WindowShowState requested_show_state) { | |
59 switch (requested_show_state) { | |
60 case ui::SHOW_STATE_DEFAULT: | |
61 case ui::SHOW_STATE_NORMAL: | |
62 return NORMAL; | |
63 case ui::SHOW_STATE_MINIMIZED: | |
64 return MINIMIZE; | |
65 case ui::SHOW_STATE_MAXIMIZED: | |
66 return MAXIMIZE; | |
67 case ui::SHOW_STATE_FULLSCREEN: | |
68 return FULLSCREEN; | |
69 case ui::SHOW_STATE_INACTIVE: | |
70 case ui::SHOW_STATE_DETACHED: | |
71 case ui::SHOW_STATE_END: | |
72 NOTREACHED() << "No WMEvent defined for the show type:" | |
73 << requested_show_state; | |
74 } | |
75 return NORMAL; | |
76 } | |
77 | |
78 } // namespace | |
79 | |
28 WindowState::WindowState(aura::Window* window) | 80 WindowState::WindowState(aura::Window* window) |
29 : window_(window), | 81 : window_(window), |
30 window_position_managed_(false), | 82 window_position_managed_(false), |
31 bounds_changed_by_user_(false), | 83 bounds_changed_by_user_(false), |
32 panel_attached_(true), | 84 panel_attached_(true), |
33 continue_drag_after_reparent_(false), | 85 continue_drag_after_reparent_(false), |
34 ignored_by_shelf_(false), | 86 ignored_by_shelf_(false), |
35 can_consume_system_keys_(false), | 87 can_consume_system_keys_(false), |
36 top_row_keys_are_function_keys_(false), | 88 top_row_keys_are_function_keys_(false), |
37 unminimize_to_restore_bounds_(false), | 89 unminimize_to_restore_bounds_(false), |
38 hide_shelf_when_fullscreen_(true), | 90 hide_shelf_when_fullscreen_(true), |
39 animate_to_fullscreen_(true), | 91 animate_to_fullscreen_(true), |
40 minimum_visibility_(false), | 92 minimum_visibility_(false), |
41 in_set_window_show_type_(false), | 93 ignore_property_change_(false), |
42 window_show_type_(ToWindowShowType(GetShowState())), | 94 window_show_type_(ToWindowShowType(GetShowState())), |
43 current_state_(new DefaultState) { | 95 current_state_(new DefaultState) { |
44 window_->AddObserver(this); | 96 window_->AddObserver(this); |
45 | |
46 #if defined(OS_CHROMEOS) | 97 #if defined(OS_CHROMEOS) |
47 // NOTE(pkotwicz): Animating to immersive fullscreen does not look good. When | 98 // NOTE(pkotwicz): Animating to immersive fullscreen does not look good. When |
48 // switches::UseImmersiveFullscreenForAllWindows() returns true, most windows | 99 // switches::UseImmersiveFullscreenForAllWindows() returns true, most windows |
49 // can be put into immersive fullscreen. It is not worth the added complexity | 100 // can be put into immersive fullscreen. It is not worth the added complexity |
50 // to only animate to fullscreen if the window is put into immersive | 101 // to only animate to fullscreen if the window is put into immersive |
51 // fullscreen. | 102 // fullscreen. |
52 animate_to_fullscreen_ = !switches::UseImmersiveFullscreenForAllWindows(); | 103 animate_to_fullscreen_ = !switches::UseImmersiveFullscreenForAllWindows(); |
53 #endif | 104 #endif |
54 } | 105 } |
55 | 106 |
(...skipping 209 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
265 void WindowState::DeleteDragDetails() { | 316 void WindowState::DeleteDragDetails() { |
266 drag_details_.reset(); | 317 drag_details_.reset(); |
267 } | 318 } |
268 | 319 |
269 void WindowState::SetAndClearRestoreBounds() { | 320 void WindowState::SetAndClearRestoreBounds() { |
270 DCHECK(HasRestoreBounds()); | 321 DCHECK(HasRestoreBounds()); |
271 SetBoundsInScreen(GetRestoreBoundsInScreen()); | 322 SetBoundsInScreen(GetRestoreBoundsInScreen()); |
272 ClearRestoreBounds(); | 323 ClearRestoreBounds(); |
273 } | 324 } |
274 | 325 |
326 void WindowState::AdjustSnappedBounds(gfx::Rect* bounds) { | |
327 if (is_dragged() || !IsSnapped()) | |
328 return; | |
329 gfx::Rect maximized_bounds = ScreenUtil::GetMaximizedWindowBoundsInParent( | |
330 window_); | |
331 if (window_show_type() == wm::SHOW_TYPE_LEFT_SNAPPED) | |
332 bounds->set_x(maximized_bounds.x()); | |
333 else if (window_show_type() == wm::SHOW_TYPE_RIGHT_SNAPPED) | |
334 bounds->set_x(maximized_bounds.right() - bounds->width()); | |
335 bounds->set_y(maximized_bounds.y()); | |
336 // TODO(varkha): Set width to 50% here for snapped windows. | |
337 bounds->set_height(maximized_bounds.height()); | |
338 } | |
339 | |
275 void WindowState::OnWindowPropertyChanged(aura::Window* window, | 340 void WindowState::OnWindowPropertyChanged(aura::Window* window, |
276 const void* key, | 341 const void* key, |
277 intptr_t old) { | 342 intptr_t old) { |
278 DCHECK_EQ(window, window_); | 343 DCHECK_EQ(window, window_); |
279 if (key == aura::client::kShowStateKey) | 344 if (key == aura::client::kShowStateKey && !ignore_property_change_) |
280 SetWindowShowType(ToWindowShowType(GetShowState())); | 345 OnWMEvent(WMEventFromShowState(GetShowState())); |
281 } | 346 } |
282 | 347 |
283 void WindowState::SnapWindow(WindowShowType left_or_right, | 348 void WindowState::SnapWindow(WindowShowType left_or_right, |
284 const gfx::Rect& bounds) { | 349 const gfx::Rect& bounds) { |
285 if (window_show_type_ == left_or_right) { | 350 if (window_show_type_ == left_or_right) { |
286 window_->SetBounds(bounds); | 351 window_->SetBounds(bounds); |
287 return; | 352 return; |
288 } | 353 } |
289 | 354 |
290 // Compute the bounds that the window will restore to. If the window does not | 355 // Compute the bounds that the window will restore to. If the window does not |
291 // already have restore bounds, it will be restored (when un-snapped) to the | 356 // already have restore bounds, it will be restored (when un-snapped) to the |
292 // last bounds that it had before getting snapped. | 357 // last bounds that it had before getting snapped. |
293 gfx::Rect restore_bounds_in_screen(HasRestoreBounds() ? | 358 gfx::Rect restore_bounds_in_screen(HasRestoreBounds() ? |
294 GetRestoreBoundsInScreen() : window_->GetBoundsInScreen()); | 359 GetRestoreBoundsInScreen() : window_->GetBoundsInScreen()); |
295 // Set the window's restore bounds so that WorkspaceLayoutManager knows | 360 // Set the window's restore bounds so that WorkspaceLayoutManager knows |
296 // which width to use when the snapped window is moved to the edge. | 361 // which width to use when the snapped window is moved to the edge. |
297 SetRestoreBoundsInParent(bounds); | 362 SetRestoreBoundsInParent(bounds); |
298 | 363 |
299 DCHECK(left_or_right == SHOW_TYPE_LEFT_SNAPPED || | 364 DCHECK(left_or_right == SHOW_TYPE_LEFT_SNAPPED || |
300 left_or_right == SHOW_TYPE_RIGHT_SNAPPED); | 365 left_or_right == SHOW_TYPE_RIGHT_SNAPPED); |
301 SetWindowShowType(left_or_right); | 366 OnWMEvent(left_or_right == SHOW_TYPE_LEFT_SNAPPED ? |
367 SNAP_LEFT : SNAP_RIGHT); | |
368 | |
302 // TODO(varkha): Ideally the bounds should be changed in a LayoutManager upon | 369 // TODO(varkha): Ideally the bounds should be changed in a LayoutManager upon |
303 // observing the WindowShowType change. | 370 // observing the WindowShowType change. |
304 // If the window is a child of kShellWindowId_DockedContainer such as during | 371 // If the window is a child of kShellWindowId_DockedContainer such as during |
305 // a drag, the window's bounds are not set in | 372 // a drag, the window's bounds are not set in |
306 // WorkspaceLayoutManager::OnWindowShowTypeChanged(). Set them here. Skip | 373 // WorkspaceLayoutManager::OnWindowShowTypeChanged(). Set them here. Skip |
307 // setting the bounds otherwise to avoid stopping the slide animation which | 374 // setting the bounds otherwise to avoid stopping the slide animation which |
308 // was started as a result of OnWindowShowTypeChanged(). | 375 // was started as a result of OnWindowShowTypeChanged(). |
309 if (IsDocked()) | 376 if (IsDocked()) |
310 window_->SetBounds(bounds); | 377 window_->SetBounds(bounds); |
311 SetRestoreBoundsInScreen(restore_bounds_in_screen); | 378 SetRestoreBoundsInScreen(restore_bounds_in_screen); |
312 } | 379 } |
313 | 380 |
314 void WindowState::SetWindowShowType(WindowShowType new_window_show_type) { | 381 void WindowState::UpdateWindowShowType(WindowShowType new_window_show_type) { |
315 if (in_set_window_show_type_) | |
316 return; | |
317 base::AutoReset<bool> resetter(&in_set_window_show_type_, true); | |
318 | |
319 ui::WindowShowState new_window_state = | 382 ui::WindowShowState new_window_state = |
320 ToWindowShowState(new_window_show_type); | 383 ToWindowShowState(new_window_show_type); |
384 base::AutoReset<bool> resetter(&ignore_property_change_, true); | |
321 if (new_window_state != GetShowState()) | 385 if (new_window_state != GetShowState()) |
322 window_->SetProperty(aura::client::kShowStateKey, new_window_state); | 386 window_->SetProperty(aura::client::kShowStateKey, new_window_state); |
323 WindowShowType old_window_show_type = window_show_type_; | |
324 window_show_type_ = new_window_show_type; | 387 window_show_type_ = new_window_show_type; |
325 if (old_window_show_type != window_show_type_) { | 388 } |
326 FOR_EACH_OBSERVER(WindowStateObserver, observer_list_, | 389 |
327 OnWindowShowTypeChanged(this, old_window_show_type)); | 390 void WindowState::NotifyPreShowTypeChange(WindowShowType old_window_show_type) { |
328 } | 391 FOR_EACH_OBSERVER(WindowStateObserver, observer_list_, |
392 OnPreWindowShowTypeChange(this, old_window_show_type)); | |
393 } | |
394 | |
395 void WindowState::NotifyPostShowTypeChange( | |
396 WindowShowType old_window_show_type) { | |
397 FOR_EACH_OBSERVER(WindowStateObserver, observer_list_, | |
398 OnPostWindowShowTypeChange(this, old_window_show_type)); | |
399 } | |
400 | |
401 void WindowState::SetBoundsDirect(const gfx::Rect& bounds) { | |
402 BoundsSetter().SetBounds(window_, bounds); | |
403 } | |
404 | |
405 void WindowState::SetBoundsDirectAnimated(const gfx::Rect& bounds) { | |
406 const int kBoundsChangeSlideDurationMs = 120; | |
407 | |
408 ui::Layer* layer = window_->layer(); | |
409 ui::ScopedLayerAnimationSettings slide_settings(layer->GetAnimator()); | |
410 slide_settings.SetPreemptionStrategy( | |
411 ui::LayerAnimator::IMMEDIATELY_ANIMATE_TO_NEW_TARGET); | |
412 slide_settings.SetTransitionDuration( | |
413 base::TimeDelta::FromMilliseconds(kBoundsChangeSlideDurationMs)); | |
414 SetBoundsDirect(bounds); | |
329 } | 415 } |
330 | 416 |
331 WindowState* GetActiveWindowState() { | 417 WindowState* GetActiveWindowState() { |
332 aura::Window* active = GetActiveWindow(); | 418 aura::Window* active = GetActiveWindow(); |
333 return active ? GetWindowState(active) : NULL; | 419 return active ? GetWindowState(active) : NULL; |
334 } | 420 } |
335 | 421 |
336 WindowState* GetWindowState(aura::Window* window) { | 422 WindowState* GetWindowState(aura::Window* window) { |
337 if (!window) | 423 if (!window) |
338 return NULL; | 424 return NULL; |
339 WindowState* settings = window->GetProperty(internal::kWindowStateKey); | 425 WindowState* settings = window->GetProperty(internal::kWindowStateKey); |
340 if(!settings) { | 426 if(!settings) { |
341 settings = new WindowState(window); | 427 settings = new WindowState(window); |
342 window->SetProperty(internal::kWindowStateKey, settings); | 428 window->SetProperty(internal::kWindowStateKey, settings); |
343 } | 429 } |
344 return settings; | 430 return settings; |
345 } | 431 } |
346 | 432 |
347 const WindowState* GetWindowState(const aura::Window* window) { | 433 const WindowState* GetWindowState(const aura::Window* window) { |
348 return GetWindowState(const_cast<aura::Window*>(window)); | 434 return GetWindowState(const_cast<aura::Window*>(window)); |
349 } | 435 } |
350 | 436 |
351 } // namespace wm | 437 } // namespace wm |
352 } // namespace ash | 438 } // namespace ash |
OLD | NEW |