Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(45)

Side by Side Diff: ash/wm/tablet_mode/tablet_mode_window_state.cc

Issue 2909763002: Revert of Rename MaximizeMode to TabletMode (Closed)
Patch Set: Created 3 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « ash/wm/tablet_mode/tablet_mode_window_state.h ('k') | ash/wm/window_positioner.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
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/tablet_mode/tablet_mode_window_state.h"
6
7 #include <utility>
8
9 #include "ash/public/cpp/shell_window_ids.h"
10 #include "ash/screen_util.h"
11 #include "ash/shell.h"
12 #include "ash/wm/screen_pinning_controller.h"
13 #include "ash/wm/tablet_mode/tablet_mode_window_manager.h"
14 #include "ash/wm/window_animation_types.h"
15 #include "ash/wm/window_properties.h"
16 #include "ash/wm/window_state_util.h"
17 #include "ash/wm/wm_event.h"
18 #include "ash/wm_window.h"
19 #include "ui/aura/window.h"
20 #include "ui/aura/window_delegate.h"
21 #include "ui/compositor/layer.h"
22 #include "ui/gfx/geometry/rect.h"
23
24 namespace ash {
25 namespace {
26
27 // Sets the restore bounds and show state overrides. These values take
28 // precedence over the restore bounds and restore show state (if set).
29 // If |bounds_override| is empty the values are cleared.
30 void SetWindowRestoreOverrides(aura::Window* window,
31 const gfx::Rect& bounds_override,
32 ui::WindowShowState window_state_override) {
33 if (bounds_override.IsEmpty()) {
34 window->ClearProperty(kRestoreShowStateOverrideKey);
35 window->ClearProperty(kRestoreBoundsOverrideKey);
36 return;
37 }
38 window->SetProperty(kRestoreShowStateOverrideKey, window_state_override);
39 window->SetProperty(kRestoreBoundsOverrideKey,
40 new gfx::Rect(bounds_override));
41 }
42
43 // Returns the biggest possible size for a window which is about to be
44 // maximized.
45 gfx::Size GetMaximumSizeOfWindow(wm::WindowState* window_state) {
46 DCHECK(window_state->CanMaximize() || window_state->CanResize());
47
48 gfx::Size workspace_size =
49 ScreenUtil::GetMaximizedWindowBoundsInParent(window_state->window())
50 .size();
51
52 gfx::Size size = window_state->window()->delegate()
53 ? window_state->window()->delegate()->GetMaximumSize()
54 : gfx::Size();
55 if (size.IsEmpty())
56 return workspace_size;
57
58 size.SetToMin(workspace_size);
59 return size;
60 }
61
62 // Returns the centered bounds of the given bounds in the work area.
63 gfx::Rect GetCenteredBounds(const gfx::Rect& bounds_in_parent,
64 wm::WindowState* state_object) {
65 gfx::Rect work_area_in_parent =
66 ScreenUtil::GetDisplayWorkAreaBoundsInParent(state_object->window());
67 work_area_in_parent.ClampToCenteredSize(bounds_in_parent.size());
68 return work_area_in_parent;
69 }
70
71 // Returns the maximized/full screen and/or centered bounds of a window.
72 gfx::Rect GetBoundsInMaximizedMode(wm::WindowState* state_object) {
73 if (state_object->IsFullscreen() || state_object->IsPinned())
74 return ScreenUtil::GetDisplayBoundsInParent(state_object->window());
75
76 gfx::Rect bounds_in_parent;
77 // Make the window as big as possible.
78 if (state_object->CanMaximize() || state_object->CanResize()) {
79 bounds_in_parent.set_size(GetMaximumSizeOfWindow(state_object));
80 } else {
81 // We prefer the user given window dimensions over the current windows
82 // dimensions since they are likely to be the result from some other state
83 // object logic.
84 if (state_object->HasRestoreBounds())
85 bounds_in_parent = state_object->GetRestoreBoundsInParent();
86 else
87 bounds_in_parent = state_object->window()->bounds();
88 }
89 return GetCenteredBounds(bounds_in_parent, state_object);
90 }
91
92 gfx::Rect GetRestoreBounds(wm::WindowState* window_state) {
93 if (window_state->IsMinimized() || window_state->IsMaximized() ||
94 window_state->IsFullscreen()) {
95 gfx::Rect restore_bounds = window_state->GetRestoreBoundsInScreen();
96 if (!restore_bounds.IsEmpty())
97 return restore_bounds;
98 }
99 return window_state->window()->GetBoundsInScreen();
100 }
101
102 } // namespace
103
104 // static
105 void TabletModeWindowState::UpdateWindowPosition(
106 wm::WindowState* window_state) {
107 gfx::Rect bounds_in_parent = GetBoundsInMaximizedMode(window_state);
108 if (bounds_in_parent == window_state->window()->bounds())
109 return;
110 window_state->SetBoundsDirect(bounds_in_parent);
111 }
112
113 TabletModeWindowState::TabletModeWindowState(aura::Window* window,
114 TabletModeWindowManager* creator)
115 : window_(window),
116 creator_(creator),
117 current_state_type_(wm::GetWindowState(window)->GetStateType()),
118 defer_bounds_updates_(false) {
119 old_state_.reset(wm::GetWindowState(window)
120 ->SetStateObject(std::unique_ptr<State>(this))
121 .release());
122 }
123
124 TabletModeWindowState::~TabletModeWindowState() {
125 creator_->WindowStateDestroyed(window_);
126 }
127
128 void TabletModeWindowState::LeaveTabletMode(wm::WindowState* window_state) {
129 // Note: When we return we will destroy ourselves with the |our_reference|.
130 std::unique_ptr<wm::WindowState::State> our_reference =
131 window_state->SetStateObject(std::move(old_state_));
132 }
133
134 void TabletModeWindowState::SetDeferBoundsUpdates(bool defer_bounds_updates) {
135 if (defer_bounds_updates_ == defer_bounds_updates)
136 return;
137
138 defer_bounds_updates_ = defer_bounds_updates;
139 if (!defer_bounds_updates_)
140 UpdateBounds(wm::GetWindowState(window_), true);
141 }
142
143 void TabletModeWindowState::OnWMEvent(wm::WindowState* window_state,
144 const wm::WMEvent* event) {
145 // Ignore events that are sent during the exit transition.
146 if (ignore_wm_events_) {
147 return;
148 }
149
150 switch (event->type()) {
151 case wm::WM_EVENT_TOGGLE_FULLSCREEN:
152 ToggleFullScreen(window_state, window_state->delegate());
153 break;
154 case wm::WM_EVENT_FULLSCREEN:
155 UpdateWindow(window_state, wm::WINDOW_STATE_TYPE_FULLSCREEN, true);
156 break;
157 case wm::WM_EVENT_PIN:
158 if (!Shell::Get()->screen_pinning_controller()->IsPinned())
159 UpdateWindow(window_state, wm::WINDOW_STATE_TYPE_PINNED, true);
160 break;
161 case wm::WM_EVENT_TRUSTED_PIN:
162 if (!Shell::Get()->screen_pinning_controller()->IsPinned())
163 UpdateWindow(window_state, wm::WINDOW_STATE_TYPE_TRUSTED_PINNED, true);
164 break;
165 case wm::WM_EVENT_TOGGLE_MAXIMIZE_CAPTION:
166 case wm::WM_EVENT_TOGGLE_VERTICAL_MAXIMIZE:
167 case wm::WM_EVENT_TOGGLE_HORIZONTAL_MAXIMIZE:
168 case wm::WM_EVENT_TOGGLE_MAXIMIZE:
169 case wm::WM_EVENT_CYCLE_SNAP_LEFT:
170 case wm::WM_EVENT_CYCLE_SNAP_RIGHT:
171 case wm::WM_EVENT_CENTER:
172 case wm::WM_EVENT_SNAP_LEFT:
173 case wm::WM_EVENT_SNAP_RIGHT:
174 case wm::WM_EVENT_NORMAL:
175 case wm::WM_EVENT_MAXIMIZE:
176 UpdateWindow(window_state, GetMaximizedOrCenteredWindowType(window_state),
177 true);
178 return;
179 case wm::WM_EVENT_MINIMIZE:
180 UpdateWindow(window_state, wm::WINDOW_STATE_TYPE_MINIMIZED, true);
181 return;
182 case wm::WM_EVENT_SHOW_INACTIVE:
183 return;
184 case wm::WM_EVENT_SET_BOUNDS:
185 if (current_state_type_ == wm::WINDOW_STATE_TYPE_MAXIMIZED) {
186 // Having a maximized window, it could have been created with an empty
187 // size and the caller should get his size upon leaving the maximized
188 // mode. As such we set the restore bounds to the requested bounds.
189 gfx::Rect bounds_in_parent =
190 (static_cast<const wm::SetBoundsEvent*>(event))->requested_bounds();
191 if (!bounds_in_parent.IsEmpty())
192 window_state->SetRestoreBoundsInParent(bounds_in_parent);
193 } else if (current_state_type_ != wm::WINDOW_STATE_TYPE_MINIMIZED &&
194 current_state_type_ != wm::WINDOW_STATE_TYPE_FULLSCREEN &&
195 current_state_type_ != wm::WINDOW_STATE_TYPE_PINNED &&
196 current_state_type_ != wm::WINDOW_STATE_TYPE_TRUSTED_PINNED) {
197 // In all other cases (except for minimized windows) we respect the
198 // requested bounds and center it to a fully visible area on the screen.
199 gfx::Rect bounds_in_parent =
200 (static_cast<const wm::SetBoundsEvent*>(event))->requested_bounds();
201 bounds_in_parent = GetCenteredBounds(bounds_in_parent, window_state);
202 if (bounds_in_parent != window_state->window()->bounds()) {
203 if (window_state->window()->IsVisible())
204 window_state->SetBoundsDirectAnimated(bounds_in_parent);
205 else
206 window_state->SetBoundsDirect(bounds_in_parent);
207 }
208 }
209 break;
210 case wm::WM_EVENT_ADDED_TO_WORKSPACE:
211 if (current_state_type_ != wm::WINDOW_STATE_TYPE_MAXIMIZED &&
212 current_state_type_ != wm::WINDOW_STATE_TYPE_FULLSCREEN &&
213 current_state_type_ != wm::WINDOW_STATE_TYPE_MINIMIZED) {
214 wm::WindowStateType new_state =
215 GetMaximizedOrCenteredWindowType(window_state);
216 UpdateWindow(window_state, new_state, true);
217 }
218 break;
219 case wm::WM_EVENT_WORKAREA_BOUNDS_CHANGED:
220 if (current_state_type_ != wm::WINDOW_STATE_TYPE_MINIMIZED)
221 UpdateBounds(window_state, true);
222 break;
223 case wm::WM_EVENT_DISPLAY_BOUNDS_CHANGED:
224 // Don't animate on a screen rotation - just snap to new size.
225 if (current_state_type_ != wm::WINDOW_STATE_TYPE_MINIMIZED)
226 UpdateBounds(window_state, false);
227 break;
228 }
229 }
230
231 wm::WindowStateType TabletModeWindowState::GetType() const {
232 return current_state_type_;
233 }
234
235 void TabletModeWindowState::AttachState(
236 wm::WindowState* window_state,
237 wm::WindowState::State* previous_state) {
238 current_state_type_ = previous_state->GetType();
239
240 gfx::Rect restore_bounds = GetRestoreBounds(window_state);
241 if (!restore_bounds.IsEmpty()) {
242 // We do not want to do a session restore to our window states. Therefore
243 // we tell the window to use the current default states instead.
244 SetWindowRestoreOverrides(window_state->window(), restore_bounds,
245 window_state->GetShowState());
246 }
247
248 // Initialize the state to a good preset.
249 if (current_state_type_ != wm::WINDOW_STATE_TYPE_MAXIMIZED &&
250 current_state_type_ != wm::WINDOW_STATE_TYPE_MINIMIZED &&
251 current_state_type_ != wm::WINDOW_STATE_TYPE_FULLSCREEN &&
252 current_state_type_ != wm::WINDOW_STATE_TYPE_PINNED &&
253 current_state_type_ != wm::WINDOW_STATE_TYPE_TRUSTED_PINNED) {
254 UpdateWindow(window_state, GetMaximizedOrCenteredWindowType(window_state),
255 true);
256 }
257
258 window_state->set_can_be_dragged(false);
259 }
260
261 void TabletModeWindowState::DetachState(wm::WindowState* window_state) {
262 // From now on, we can use the default session restore mechanism again.
263 SetWindowRestoreOverrides(window_state->window(), gfx::Rect(),
264 ui::SHOW_STATE_NORMAL);
265 window_state->set_can_be_dragged(true);
266 }
267
268 void TabletModeWindowState::UpdateWindow(wm::WindowState* window_state,
269 wm::WindowStateType target_state,
270 bool animated) {
271 DCHECK(target_state == wm::WINDOW_STATE_TYPE_MINIMIZED ||
272 target_state == wm::WINDOW_STATE_TYPE_MAXIMIZED ||
273 target_state == wm::WINDOW_STATE_TYPE_PINNED ||
274 target_state == wm::WINDOW_STATE_TYPE_TRUSTED_PINNED ||
275 (target_state == wm::WINDOW_STATE_TYPE_NORMAL &&
276 !window_state->CanMaximize()) ||
277 target_state == wm::WINDOW_STATE_TYPE_FULLSCREEN);
278
279 if (current_state_type_ == target_state) {
280 if (target_state == wm::WINDOW_STATE_TYPE_MINIMIZED)
281 return;
282 // If the state type did not change, update it accordingly.
283 UpdateBounds(window_state, animated);
284 return;
285 }
286
287 const wm::WindowStateType old_state_type = current_state_type_;
288 current_state_type_ = target_state;
289 window_state->UpdateWindowPropertiesFromStateType();
290 window_state->NotifyPreStateTypeChange(old_state_type);
291
292 if (target_state == wm::WINDOW_STATE_TYPE_MINIMIZED) {
293 ::wm::SetWindowVisibilityAnimationType(
294 window_state->window(), wm::WINDOW_VISIBILITY_ANIMATION_TYPE_MINIMIZE);
295 window_state->window()->Hide();
296 if (window_state->IsActive())
297 window_state->Deactivate();
298 } else {
299 UpdateBounds(window_state, animated);
300 }
301
302 window_state->NotifyPostStateTypeChange(old_state_type);
303
304 if (old_state_type == wm::WINDOW_STATE_TYPE_PINNED ||
305 target_state == wm::WINDOW_STATE_TYPE_PINNED ||
306 old_state_type == wm::WINDOW_STATE_TYPE_TRUSTED_PINNED ||
307 target_state == wm::WINDOW_STATE_TYPE_TRUSTED_PINNED) {
308 Shell::Get()->screen_pinning_controller()->SetPinnedWindow(
309 WmWindow::Get(window_state->window()));
310 }
311
312 if ((window_state->window()->layer()->GetTargetVisibility() ||
313 old_state_type == wm::WINDOW_STATE_TYPE_MINIMIZED) &&
314 !window_state->window()->layer()->visible()) {
315 // The layer may be hidden if the window was previously minimized. Make
316 // sure it's visible.
317 window_state->window()->Show();
318 }
319 }
320
321 wm::WindowStateType TabletModeWindowState::GetMaximizedOrCenteredWindowType(
322 wm::WindowState* window_state) {
323 return window_state->CanMaximize() ? wm::WINDOW_STATE_TYPE_MAXIMIZED
324 : wm::WINDOW_STATE_TYPE_NORMAL;
325 }
326
327 void TabletModeWindowState::UpdateBounds(wm::WindowState* window_state,
328 bool animated) {
329 if (defer_bounds_updates_)
330 return;
331 gfx::Rect bounds_in_parent = GetBoundsInMaximizedMode(window_state);
332 // If we have a target bounds rectangle, we center it and set it
333 // accordingly.
334 if (!bounds_in_parent.IsEmpty() &&
335 bounds_in_parent != window_state->window()->bounds()) {
336 if (current_state_type_ == wm::WINDOW_STATE_TYPE_MINIMIZED ||
337 !window_state->window()->IsVisible() || !animated) {
338 window_state->SetBoundsDirect(bounds_in_parent);
339 } else {
340 // If we animate (to) tablet mode, we want to use the cross fade to
341 // avoid flashing.
342 if (window_state->IsMaximized())
343 window_state->SetBoundsDirectCrossFade(bounds_in_parent);
344 else
345 window_state->SetBoundsDirectAnimated(bounds_in_parent);
346 }
347 }
348 }
349
350 } // namespace ash
OLDNEW
« no previous file with comments | « ash/wm/tablet_mode/tablet_mode_window_state.h ('k') | ash/wm/window_positioner.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698