• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #include "ash/wm/lock_window_state.h"
6 
7 #include "ash/screen_util.h"
8 #include "ash/shell.h"
9 #include "ash/wm/lock_layout_manager.h"
10 #include "ash/wm/window_animations.h"
11 #include "ash/wm/window_state.h"
12 #include "ash/wm/window_state_delegate.h"
13 #include "ash/wm/window_state_util.h"
14 #include "ash/wm/window_util.h"
15 #include "ash/wm/wm_event.h"
16 #include "ui/aura/window.h"
17 #include "ui/aura/window_delegate.h"
18 #include "ui/gfx/rect.h"
19 #include "ui/keyboard/keyboard_controller.h"
20 #include "ui/keyboard/keyboard_util.h"
21 #include "ui/wm/core/window_animations.h"
22 
23 namespace ash {
24 
LockWindowState(aura::Window * window)25 LockWindowState::LockWindowState(aura::Window* window)
26     : current_state_type_(wm::GetWindowState(window)->GetStateType()) {
27 }
28 
~LockWindowState()29 LockWindowState::~LockWindowState() {
30 }
31 
OnWMEvent(wm::WindowState * window_state,const wm::WMEvent * event)32 void LockWindowState::OnWMEvent(wm::WindowState* window_state,
33                                 const wm::WMEvent* event) {
34   aura::Window* window = window_state->window();
35   gfx::Rect bounds = window->bounds();
36 
37   switch (event->type()) {
38     case wm::WM_EVENT_TOGGLE_FULLSCREEN:
39       ToggleFullScreen(window_state, window_state->delegate());
40       break;
41     case wm::WM_EVENT_FULLSCREEN:
42       UpdateWindow(window_state, wm::WINDOW_STATE_TYPE_FULLSCREEN);
43       break;
44     case wm::WM_EVENT_TOGGLE_MAXIMIZE_CAPTION:
45     case wm::WM_EVENT_TOGGLE_VERTICAL_MAXIMIZE:
46     case wm::WM_EVENT_TOGGLE_HORIZONTAL_MAXIMIZE:
47     case wm::WM_EVENT_TOGGLE_MAXIMIZE:
48     case wm::WM_EVENT_CENTER:
49     case wm::WM_EVENT_SNAP_LEFT:
50     case wm::WM_EVENT_SNAP_RIGHT:
51     case wm::WM_EVENT_NORMAL:
52     case wm::WM_EVENT_MAXIMIZE:
53       UpdateWindow(window_state,
54                    GetMaximizedOrCenteredWindowType(window_state));
55       return;
56     case wm::WM_EVENT_MINIMIZE:
57       UpdateWindow(window_state, wm::WINDOW_STATE_TYPE_MINIMIZED);
58       return;
59     case wm::WM_EVENT_SHOW_INACTIVE:
60       return;
61     case wm::WM_EVENT_SET_BOUNDS:
62       if (window_state->IsMaximized() || window_state->IsFullscreen()) {
63         UpdateBounds(window_state);
64       } else {
65         const ash::wm::SetBoundsEvent* bounds_event =
66             static_cast<const ash::wm::SetBoundsEvent*>(event);
67         window_state->SetBoundsConstrained(bounds_event->requested_bounds());
68       }
69       break;
70     case wm::WM_EVENT_ADDED_TO_WORKSPACE:
71       if (current_state_type_ != wm::WINDOW_STATE_TYPE_MAXIMIZED &&
72           current_state_type_ != wm::WINDOW_STATE_TYPE_MINIMIZED &&
73           current_state_type_ != wm::WINDOW_STATE_TYPE_FULLSCREEN) {
74         UpdateWindow(window_state,
75                      GetMaximizedOrCenteredWindowType(window_state));
76       }
77       break;
78     case wm::WM_EVENT_WORKAREA_BOUNDS_CHANGED:
79     case wm::WM_EVENT_DISPLAY_BOUNDS_CHANGED:
80       UpdateBounds(window_state);
81       break;
82   }
83 }
84 
GetType() const85 wm::WindowStateType LockWindowState::GetType() const {
86   return current_state_type_;
87 }
88 
AttachState(wm::WindowState * window_state,wm::WindowState::State * previous_state)89 void LockWindowState::AttachState(wm::WindowState* window_state,
90                                   wm::WindowState::State* previous_state) {
91   current_state_type_ = previous_state->GetType();
92 
93   // Initialize the state to a good preset.
94   if (current_state_type_ != wm::WINDOW_STATE_TYPE_MAXIMIZED &&
95       current_state_type_ != wm::WINDOW_STATE_TYPE_MINIMIZED &&
96       current_state_type_ != wm::WINDOW_STATE_TYPE_FULLSCREEN) {
97     UpdateWindow(window_state,
98                  GetMaximizedOrCenteredWindowType(window_state));
99   }
100 }
101 
DetachState(wm::WindowState * window_state)102 void LockWindowState::DetachState(wm::WindowState* window_state) {
103 }
104 
105 // static
SetLockWindowState(aura::Window * window)106 wm::WindowState* LockWindowState::SetLockWindowState(aura::Window* window) {
107   scoped_ptr<wm::WindowState::State> lock_state(new LockWindowState(window));
108   scoped_ptr<wm::WindowState::State> old_state(
109       wm::GetWindowState(window)->SetStateObject(lock_state.Pass()));
110   return wm::GetWindowState(window);
111 }
112 
UpdateWindow(wm::WindowState * window_state,wm::WindowStateType target_state)113 void LockWindowState::UpdateWindow(wm::WindowState* window_state,
114                                    wm::WindowStateType target_state) {
115   DCHECK(target_state == wm::WINDOW_STATE_TYPE_MINIMIZED ||
116          target_state == wm::WINDOW_STATE_TYPE_MAXIMIZED ||
117          (target_state == wm::WINDOW_STATE_TYPE_NORMAL &&
118               !window_state->CanMaximize()) ||
119          target_state == wm::WINDOW_STATE_TYPE_FULLSCREEN);
120 
121   if (target_state == wm::WINDOW_STATE_TYPE_MINIMIZED) {
122     if (current_state_type_ == wm::WINDOW_STATE_TYPE_MINIMIZED)
123       return;
124 
125     current_state_type_ = target_state;
126     ::wm::SetWindowVisibilityAnimationType(
127         window_state->window(), WINDOW_VISIBILITY_ANIMATION_TYPE_MINIMIZE);
128     window_state->window()->Hide();
129     if (window_state->IsActive())
130       window_state->Deactivate();
131     return;
132   }
133 
134   if (current_state_type_ == target_state) {
135     // If the state type did not change, update it accordingly.
136     UpdateBounds(window_state);
137     return;
138   }
139 
140   const wm::WindowStateType old_state_type = current_state_type_;
141   current_state_type_ = target_state;
142   window_state->UpdateWindowShowStateFromStateType();
143   window_state->NotifyPreStateTypeChange(old_state_type);
144   UpdateBounds(window_state);
145   window_state->NotifyPostStateTypeChange(old_state_type);
146 
147   if ((window_state->window()->TargetVisibility() ||
148       old_state_type == wm::WINDOW_STATE_TYPE_MINIMIZED) &&
149       !window_state->window()->layer()->visible()) {
150     // The layer may be hidden if the window was previously minimized. Make
151     // sure it's visible.
152     window_state->window()->Show();
153   }
154 }
155 
GetMaximizedOrCenteredWindowType(wm::WindowState * window_state)156 wm::WindowStateType LockWindowState::GetMaximizedOrCenteredWindowType(
157       wm::WindowState* window_state) {
158   return window_state->CanMaximize() ? wm::WINDOW_STATE_TYPE_MAXIMIZED :
159                                        wm::WINDOW_STATE_TYPE_NORMAL;
160 }
161 
UpdateBounds(wm::WindowState * window_state)162 void LockWindowState::UpdateBounds(wm::WindowState* window_state) {
163   if (!window_state->IsMaximized() && !window_state->IsFullscreen())
164     return;
165 
166   keyboard::KeyboardController* keyboard_controller =
167       keyboard::KeyboardController::GetInstance();
168   gfx::Rect keyboard_bounds;
169 
170   if (keyboard_controller && !keyboard::IsKeyboardOverscrollEnabled())
171     keyboard_bounds = keyboard_controller->current_keyboard_bounds();
172 
173   gfx::Rect bounds =
174       ScreenUtil::GetDisplayBoundsInParent(window_state->window());
175   bounds.set_height(bounds.height() - keyboard_bounds.height());
176   window_state->SetBoundsDirect(bounds);
177 }
178 
179 }  // namespace ash
180