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 is cleaned up, move this to the real layout |
| 34 // manager with proper friendship. |
| 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 return SHOW_INACTIVE; |
| 71 case ui::SHOW_STATE_DETACHED: |
| 72 case ui::SHOW_STATE_END: |
| 73 NOTREACHED() << "No WMEvent defined for the show type:" |
| 74 << requested_show_state; |
| 75 } |
| 76 return NORMAL; |
| 77 } |
| 78 |
| 79 } // namespace |
| 80 |
28 WindowState::WindowState(aura::Window* window) | 81 WindowState::WindowState(aura::Window* window) |
29 : window_(window), | 82 : window_(window), |
30 window_position_managed_(false), | 83 window_position_managed_(false), |
31 bounds_changed_by_user_(false), | 84 bounds_changed_by_user_(false), |
32 panel_attached_(true), | 85 panel_attached_(true), |
33 continue_drag_after_reparent_(false), | 86 continue_drag_after_reparent_(false), |
34 ignored_by_shelf_(false), | 87 ignored_by_shelf_(false), |
35 can_consume_system_keys_(false), | 88 can_consume_system_keys_(false), |
36 top_row_keys_are_function_keys_(false), | 89 top_row_keys_are_function_keys_(false), |
37 unminimize_to_restore_bounds_(false), | 90 unminimize_to_restore_bounds_(false), |
38 hide_shelf_when_fullscreen_(true), | 91 hide_shelf_when_fullscreen_(true), |
39 animate_to_fullscreen_(true), | 92 animate_to_fullscreen_(true), |
40 minimum_visibility_(false), | 93 minimum_visibility_(false), |
41 in_set_window_show_type_(false), | 94 ignore_property_change_(false), |
42 window_show_type_(ToWindowShowType(GetShowState())), | 95 window_show_type_(ToWindowShowType(GetShowState())), |
43 current_state_(new DefaultState) { | 96 current_state_(new DefaultState) { |
44 window_->AddObserver(this); | 97 window_->AddObserver(this); |
45 | |
46 #if defined(OS_CHROMEOS) | 98 #if defined(OS_CHROMEOS) |
47 // NOTE(pkotwicz): Animating to immersive fullscreen does not look good. When | 99 // NOTE(pkotwicz): Animating to immersive fullscreen does not look good. When |
48 // switches::UseImmersiveFullscreenForAllWindows() returns true, most windows | 100 // switches::UseImmersiveFullscreenForAllWindows() returns true, most windows |
49 // can be put into immersive fullscreen. It is not worth the added complexity | 101 // 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 | 102 // to only animate to fullscreen if the window is put into immersive |
51 // fullscreen. | 103 // fullscreen. |
52 animate_to_fullscreen_ = !switches::UseImmersiveFullscreenForAllWindows(); | 104 animate_to_fullscreen_ = !switches::UseImmersiveFullscreenForAllWindows(); |
53 #endif | 105 #endif |
54 } | 106 } |
55 | 107 |
(...skipping 119 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
175 void WindowState::Activate() { | 227 void WindowState::Activate() { |
176 ActivateWindow(window_); | 228 ActivateWindow(window_); |
177 } | 229 } |
178 | 230 |
179 void WindowState::Deactivate() { | 231 void WindowState::Deactivate() { |
180 DeactivateWindow(window_); | 232 DeactivateWindow(window_); |
181 } | 233 } |
182 | 234 |
183 void WindowState::Restore() { | 235 void WindowState::Restore() { |
184 if (!IsNormalShowType()) | 236 if (!IsNormalShowType()) |
185 SetWindowShowType(SHOW_TYPE_NORMAL); | 237 OnWMEvent(NORMAL); |
186 } | 238 } |
187 | 239 |
188 void WindowState::ToggleFullscreen() { | 240 void WindowState::ToggleFullscreen() { |
189 // Window which cannot be maximized should not be fullscreened. | 241 OnWMEvent(TOGGLE_FULLSCREEN); |
190 // It can, however, be restored if it was fullscreened. | |
191 bool is_fullscreen = IsFullscreen(); | |
192 if (!is_fullscreen && !CanMaximize()) | |
193 return; | |
194 if (delegate_ && delegate_->ToggleFullscreen(this)) | |
195 return; | |
196 if (is_fullscreen) { | |
197 Restore(); | |
198 } else { | |
199 window_->SetProperty(aura::client::kShowStateKey, | |
200 ui::SHOW_STATE_FULLSCREEN); | |
201 } | |
202 } | 242 } |
203 | 243 |
204 void WindowState::OnWMEvent(WMEvent event) { | 244 void WindowState::OnWMEvent(WMEvent event) { |
205 current_state_->OnWMEvent(this, event); | 245 current_state_->OnWMEvent(this, event); |
206 } | 246 } |
207 | 247 |
208 void WindowState::SetBoundsInScreen( | 248 void WindowState::SetBoundsInScreen( |
209 const gfx::Rect& bounds_in_screen) { | 249 const gfx::Rect& bounds_in_screen) { |
210 gfx::Rect bounds_in_parent = | 250 gfx::Rect bounds_in_parent = |
211 ScreenUtil::ConvertRectFromScreen(window_->parent(), | 251 ScreenUtil::ConvertRectFromScreen(window_->parent(), |
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
266 void WindowState::DeleteDragDetails() { | 306 void WindowState::DeleteDragDetails() { |
267 drag_details_.reset(); | 307 drag_details_.reset(); |
268 } | 308 } |
269 | 309 |
270 void WindowState::SetAndClearRestoreBounds() { | 310 void WindowState::SetAndClearRestoreBounds() { |
271 DCHECK(HasRestoreBounds()); | 311 DCHECK(HasRestoreBounds()); |
272 SetBoundsInScreen(GetRestoreBoundsInScreen()); | 312 SetBoundsInScreen(GetRestoreBoundsInScreen()); |
273 ClearRestoreBounds(); | 313 ClearRestoreBounds(); |
274 } | 314 } |
275 | 315 |
| 316 void WindowState::AdjustSnappedBounds(gfx::Rect* bounds) { |
| 317 if (is_dragged() || !IsSnapped()) |
| 318 return; |
| 319 gfx::Rect maximized_bounds = ScreenUtil::GetMaximizedWindowBoundsInParent( |
| 320 window_); |
| 321 if (window_show_type() == SHOW_TYPE_LEFT_SNAPPED) |
| 322 bounds->set_x(maximized_bounds.x()); |
| 323 else if (window_show_type() == SHOW_TYPE_RIGHT_SNAPPED) |
| 324 bounds->set_x(maximized_bounds.right() - bounds->width()); |
| 325 bounds->set_y(maximized_bounds.y()); |
| 326 bounds->set_height(maximized_bounds.height()); |
| 327 } |
| 328 |
276 void WindowState::OnWindowPropertyChanged(aura::Window* window, | 329 void WindowState::OnWindowPropertyChanged(aura::Window* window, |
277 const void* key, | 330 const void* key, |
278 intptr_t old) { | 331 intptr_t old) { |
279 DCHECK_EQ(window, window_); | 332 DCHECK_EQ(window, window_); |
280 if (key == aura::client::kShowStateKey) | 333 if (key == aura::client::kShowStateKey && !ignore_property_change_) |
281 SetWindowShowType(ToWindowShowType(GetShowState())); | 334 OnWMEvent(WMEventFromShowState(GetShowState())); |
282 } | 335 } |
283 | 336 |
284 void WindowState::SnapWindow(WindowShowType left_or_right, | 337 void WindowState::SnapWindow(WindowShowType left_or_right, |
285 const gfx::Rect& bounds) { | 338 const gfx::Rect& bounds) { |
286 if (window_show_type_ == left_or_right) { | 339 if (window_show_type_ == left_or_right) { |
287 window_->SetBounds(bounds); | 340 window_->SetBounds(bounds); |
288 return; | 341 return; |
289 } | 342 } |
290 | 343 |
291 // Compute the bounds that the window will restore to. If the window does not | 344 // Compute the bounds that the window will restore to. If the window does not |
292 // already have restore bounds, it will be restored (when un-snapped) to the | 345 // already have restore bounds, it will be restored (when un-snapped) to the |
293 // last bounds that it had before getting snapped. | 346 // last bounds that it had before getting snapped. |
294 gfx::Rect restore_bounds_in_screen(HasRestoreBounds() ? | 347 gfx::Rect restore_bounds_in_screen(HasRestoreBounds() ? |
295 GetRestoreBoundsInScreen() : window_->GetBoundsInScreen()); | 348 GetRestoreBoundsInScreen() : window_->GetBoundsInScreen()); |
296 // Set the window's restore bounds so that WorkspaceLayoutManager knows | 349 // Set the window's restore bounds so that WorkspaceLayoutManager knows |
297 // which width to use when the snapped window is moved to the edge. | 350 // which width to use when the snapped window is moved to the edge. |
298 SetRestoreBoundsInParent(bounds); | 351 SetRestoreBoundsInParent(bounds); |
299 | 352 |
300 DCHECK(left_or_right == SHOW_TYPE_LEFT_SNAPPED || | 353 DCHECK(left_or_right == SHOW_TYPE_LEFT_SNAPPED || |
301 left_or_right == SHOW_TYPE_RIGHT_SNAPPED); | 354 left_or_right == SHOW_TYPE_RIGHT_SNAPPED); |
302 SetWindowShowType(left_or_right); | 355 OnWMEvent(left_or_right == SHOW_TYPE_LEFT_SNAPPED ? |
| 356 SNAP_LEFT : SNAP_RIGHT); |
| 357 |
303 // TODO(varkha): Ideally the bounds should be changed in a LayoutManager upon | 358 // TODO(varkha): Ideally the bounds should be changed in a LayoutManager upon |
304 // observing the WindowShowType change. | 359 // observing the WindowShowType change. |
305 // If the window is a child of kShellWindowId_DockedContainer such as during | 360 // If the window is a child of kShellWindowId_DockedContainer such as during |
306 // a drag, the window's bounds are not set in | 361 // a drag, the window's bounds are not set in |
307 // WorkspaceLayoutManager::OnWindowShowTypeChanged(). Set them here. Skip | 362 // WorkspaceLayoutManager::OnWindowShowTypeChanged(). Set them here. Skip |
308 // setting the bounds otherwise to avoid stopping the slide animation which | 363 // setting the bounds otherwise to avoid stopping the slide animation which |
309 // was started as a result of OnWindowShowTypeChanged(). | 364 // was started as a result of OnWindowShowTypeChanged(). |
310 if (IsDocked()) | 365 if (IsDocked()) |
311 window_->SetBounds(bounds); | 366 window_->SetBounds(bounds); |
312 SetRestoreBoundsInScreen(restore_bounds_in_screen); | 367 SetRestoreBoundsInScreen(restore_bounds_in_screen); |
313 } | 368 } |
314 | 369 |
315 void WindowState::SetWindowShowType(WindowShowType new_window_show_type) { | 370 void WindowState::UpdateWindowShowType(WindowShowType new_window_show_type) { |
316 if (in_set_window_show_type_) | |
317 return; | |
318 base::AutoReset<bool> resetter(&in_set_window_show_type_, true); | |
319 | |
320 ui::WindowShowState new_window_state = | 371 ui::WindowShowState new_window_state = |
321 ToWindowShowState(new_window_show_type); | 372 ToWindowShowState(new_window_show_type); |
322 if (new_window_state != GetShowState()) | 373 if (new_window_state != GetShowState()) { |
| 374 base::AutoReset<bool> resetter(&ignore_property_change_, true); |
323 window_->SetProperty(aura::client::kShowStateKey, new_window_state); | 375 window_->SetProperty(aura::client::kShowStateKey, new_window_state); |
324 WindowShowType old_window_show_type = window_show_type_; | 376 } |
325 window_show_type_ = new_window_show_type; | 377 window_show_type_ = new_window_show_type; |
326 if (old_window_show_type != window_show_type_) { | 378 } |
327 FOR_EACH_OBSERVER(WindowStateObserver, observer_list_, | 379 |
328 OnWindowShowTypeChanged(this, old_window_show_type)); | 380 void WindowState::NotifyPreShowTypeChange(WindowShowType old_window_show_type) { |
329 } | 381 FOR_EACH_OBSERVER(WindowStateObserver, observer_list_, |
| 382 OnPreWindowShowTypeChange(this, old_window_show_type)); |
| 383 } |
| 384 |
| 385 void WindowState::NotifyPostShowTypeChange( |
| 386 WindowShowType old_window_show_type) { |
| 387 FOR_EACH_OBSERVER(WindowStateObserver, observer_list_, |
| 388 OnPostWindowShowTypeChange(this, old_window_show_type)); |
| 389 } |
| 390 |
| 391 void WindowState::SetBoundsDirect(const gfx::Rect& bounds) { |
| 392 BoundsSetter().SetBounds(window_, bounds); |
| 393 } |
| 394 |
| 395 void WindowState::SetBoundsDirectAnimated(const gfx::Rect& bounds) { |
| 396 const int kBoundsChangeSlideDurationMs = 120; |
| 397 |
| 398 ui::Layer* layer = window_->layer(); |
| 399 ui::ScopedLayerAnimationSettings slide_settings(layer->GetAnimator()); |
| 400 slide_settings.SetPreemptionStrategy( |
| 401 ui::LayerAnimator::IMMEDIATELY_ANIMATE_TO_NEW_TARGET); |
| 402 slide_settings.SetTransitionDuration( |
| 403 base::TimeDelta::FromMilliseconds(kBoundsChangeSlideDurationMs)); |
| 404 SetBoundsDirect(bounds); |
330 } | 405 } |
331 | 406 |
332 WindowState* GetActiveWindowState() { | 407 WindowState* GetActiveWindowState() { |
333 aura::Window* active = GetActiveWindow(); | 408 aura::Window* active = GetActiveWindow(); |
334 return active ? GetWindowState(active) : NULL; | 409 return active ? GetWindowState(active) : NULL; |
335 } | 410 } |
336 | 411 |
337 WindowState* GetWindowState(aura::Window* window) { | 412 WindowState* GetWindowState(aura::Window* window) { |
338 if (!window) | 413 if (!window) |
339 return NULL; | 414 return NULL; |
340 WindowState* settings = window->GetProperty(internal::kWindowStateKey); | 415 WindowState* settings = window->GetProperty(internal::kWindowStateKey); |
341 if(!settings) { | 416 if(!settings) { |
342 settings = new WindowState(window); | 417 settings = new WindowState(window); |
343 window->SetProperty(internal::kWindowStateKey, settings); | 418 window->SetProperty(internal::kWindowStateKey, settings); |
344 } | 419 } |
345 return settings; | 420 return settings; |
346 } | 421 } |
347 | 422 |
348 const WindowState* GetWindowState(const aura::Window* window) { | 423 const WindowState* GetWindowState(const aura::Window* window) { |
349 return GetWindowState(const_cast<aura::Window*>(window)); | 424 return GetWindowState(const_cast<aura::Window*>(window)); |
350 } | 425 } |
351 | 426 |
352 } // namespace wm | 427 } // namespace wm |
353 } // namespace ash | 428 } // namespace ash |
OLD | NEW |