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

Side by Side Diff: ash/wm/workspace/workspace_manager.cc

Issue 19460014: Do not create workspace for fullscreen. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 7 years, 5 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 | Annotate | Revision Log
« no previous file with comments | « ash/wm/workspace/workspace_manager.h ('k') | ash/wm/workspace/workspace_manager_unittest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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/wm/workspace/workspace_manager.h" 5 #include "ash/wm/workspace/workspace_manager.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 #include <functional> 8 #include <functional>
9 9
10 #include "ash/root_window_controller.h" 10 #include "ash/root_window_controller.h"
(...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after
106 DISALLOW_COPY_AND_ASSIGN(LayoutManagerImpl); 106 DISALLOW_COPY_AND_ASSIGN(LayoutManagerImpl);
107 }; 107 };
108 108
109 // WorkspaceManager ----------------------------------------------------------- 109 // WorkspaceManager -----------------------------------------------------------
110 110
111 WorkspaceManager::WorkspaceManager(Window* contents_window) 111 WorkspaceManager::WorkspaceManager(Window* contents_window)
112 : contents_window_(contents_window), 112 : contents_window_(contents_window),
113 active_workspace_(NULL), 113 active_workspace_(NULL),
114 shelf_(NULL), 114 shelf_(NULL),
115 in_move_(false), 115 in_move_(false),
116 clear_unminimizing_workspace_factory_(this),
117 unminimizing_workspace_(NULL),
118 app_terminating_(false), 116 app_terminating_(false),
119 creating_fade_(false) { 117 creating_fade_(false) {
120 // Clobber any existing event filter. 118 // Clobber any existing event filter.
121 contents_window->SetEventFilter(NULL); 119 contents_window->SetEventFilter(NULL);
122 // |contents_window| takes ownership of LayoutManagerImpl. 120 // |contents_window| takes ownership of LayoutManagerImpl.
123 contents_window->SetLayoutManager(new LayoutManagerImpl(this)); 121 contents_window->SetLayoutManager(new LayoutManagerImpl(this));
124 active_workspace_ = CreateWorkspace(false); 122 active_workspace_ = new Workspace(this, contents_window_);
125 workspaces_.push_back(active_workspace_); 123 workspaces_.push_back(active_workspace_);
126 active_workspace_->window()->Show(); 124 active_workspace_->window()->Show();
127 Shell::GetInstance()->AddShellObserver(this); 125 Shell::GetInstance()->AddShellObserver(this);
128 126
129 if (ash::WorkspaceCyclerConfiguration::IsCyclerEnabled()) 127 if (ash::WorkspaceCyclerConfiguration::IsCyclerEnabled())
130 workspace_cycler_.reset(new WorkspaceCycler(this)); 128 workspace_cycler_.reset(new WorkspaceCycler(this));
131 } 129 }
132 130
133 WorkspaceManager::~WorkspaceManager() { 131 WorkspaceManager::~WorkspaceManager() {
134 Shell::GetInstance()->RemoveShellObserver(this); 132 Shell::GetInstance()->RemoveShellObserver(this);
135 // Release the windows, they'll be destroyed when |contents_window_| is 133 // Release the windows, they'll be destroyed when |contents_window_| is
136 // destroyed. 134 // destroyed.
137 std::for_each(workspaces_.begin(), workspaces_.end(), 135 std::for_each(workspaces_.begin(), workspaces_.end(),
138 std::mem_fun(&Workspace::ReleaseWindow)); 136 std::mem_fun(&Workspace::ReleaseWindow));
139 std::for_each(pending_workspaces_.begin(), pending_workspaces_.end(), 137 std::for_each(pending_workspaces_.begin(), pending_workspaces_.end(),
140 std::mem_fun(&Workspace::ReleaseWindow)); 138 std::mem_fun(&Workspace::ReleaseWindow));
141 std::for_each(to_delete_.begin(), to_delete_.end(), 139 std::for_each(to_delete_.begin(), to_delete_.end(),
142 std::mem_fun(&Workspace::ReleaseWindow)); 140 std::mem_fun(&Workspace::ReleaseWindow));
143 STLDeleteElements(&workspaces_); 141 STLDeleteElements(&workspaces_);
144 STLDeleteElements(&pending_workspaces_); 142 STLDeleteElements(&pending_workspaces_);
145 STLDeleteElements(&to_delete_); 143 STLDeleteElements(&to_delete_);
146 } 144 }
147 145
148 // static
149 bool WorkspaceManager::WillRestoreToWorkspace(Window* window) {
150 return wm::IsWindowMinimized(window) &&
151 window->GetProperty(aura::client::kRestoreShowStateKey) ==
152 ui::SHOW_STATE_FULLSCREEN;
153 }
154
155 WorkspaceWindowState WorkspaceManager::GetWindowState() const { 146 WorkspaceWindowState WorkspaceManager::GetWindowState() const {
156 if (!shelf_) 147 if (!shelf_)
157 return WORKSPACE_WINDOW_STATE_DEFAULT; 148 return WORKSPACE_WINDOW_STATE_DEFAULT;
158 149
159 const bool is_active_fullscreen = active_workspace_->is_fullscreen();
160 const gfx::Rect shelf_bounds(shelf_->GetIdealBounds()); 150 const gfx::Rect shelf_bounds(shelf_->GetIdealBounds());
161 const Window::Windows& windows(active_workspace_->window()->children()); 151 const Window::Windows& windows(active_workspace_->window()->children());
162 bool window_overlaps_launcher = false; 152 bool window_overlaps_launcher = false;
163 bool has_maximized_window = false; 153 bool has_maximized_window = false;
164 for (Window::Windows::const_iterator i = windows.begin(); 154 for (Window::Windows::const_iterator i = windows.begin();
165 i != windows.end(); ++i) { 155 i != windows.end(); ++i) {
166 if (GetIgnoredByShelf(*i)) 156 if (GetIgnoredByShelf(*i))
167 continue; 157 continue;
168 ui::Layer* layer = (*i)->layer(); 158 ui::Layer* layer = (*i)->layer();
169 if (!layer->GetTargetVisibility() || layer->GetTargetOpacity() == 0.0f) 159 if (!layer->GetTargetVisibility() || layer->GetTargetOpacity() == 0.0f)
170 continue; 160 continue;
171 if (wm::IsWindowMaximized(*i)) { 161 if (wm::IsWindowMaximized(*i)) {
172 // An untracked window may still be fullscreen so we keep iterating when 162 // An untracked window may still be fullscreen so we keep iterating when
173 // we hit a maximized window. 163 // we hit a maximized window.
174 has_maximized_window = true; 164 has_maximized_window = true;
175 } else if (is_active_fullscreen && wm::IsWindowFullscreen(*i)) { 165 } else if (wm::IsWindowFullscreen(*i)) {
176 // Ignore fullscreen windows if we're in the desktop. Such a state
177 // is transitory and means we haven't yet switched. If we did consider
178 // such windows we'll return the wrong thing, which can lead to
179 // prematurely anging the launcher state and clobbering restore bounds.
180 return WORKSPACE_WINDOW_STATE_FULL_SCREEN; 166 return WORKSPACE_WINDOW_STATE_FULL_SCREEN;
181 } 167 }
182 if (!window_overlaps_launcher && (*i)->bounds().Intersects(shelf_bounds)) 168 if (!window_overlaps_launcher && (*i)->bounds().Intersects(shelf_bounds))
183 window_overlaps_launcher = true; 169 window_overlaps_launcher = true;
184 } 170 }
185 if (has_maximized_window) 171 if (has_maximized_window)
186 return WORKSPACE_WINDOW_STATE_MAXIMIZED; 172 return WORKSPACE_WINDOW_STATE_MAXIMIZED;
187 173
188 return window_overlaps_launcher ? 174 return window_overlaps_launcher ?
189 WORKSPACE_WINDOW_STATE_WINDOW_OVERLAPS_SHELF : 175 WORKSPACE_WINDOW_STATE_WINDOW_OVERLAPS_SHELF :
(...skipping 21 matching lines...) Expand all
211 // have to allow dragging of a fullscreen window to work in this case. 197 // have to allow dragging of a fullscreen window to work in this case.
212 // . The window persists across all workspaces. For example, the task 198 // . The window persists across all workspaces. For example, the task
213 // manager is in the desktop worskpace and the current workspace is 199 // manager is in the desktop worskpace and the current workspace is
214 // fullscreen. If we swapped to the desktop you would lose context. 200 // fullscreen. If we swapped to the desktop you would lose context.
215 // Instead we reparent. The exception to this is if the window is 201 // Instead we reparent. The exception to this is if the window is
216 // fullscreen (it needs its own workspace then) or we're in the process of 202 // fullscreen (it needs its own workspace then) or we're in the process of
217 // fullscreen. If we're in the process of fullscreen the window needs its 203 // fullscreen. If we're in the process of fullscreen the window needs its
218 // own workspace. 204 // own workspace.
219 if (!GetTrackedByWorkspace(window) || 205 if (!GetTrackedByWorkspace(window) ||
220 (GetPersistsAcrossAllWorkspaces(window) && 206 (GetPersistsAcrossAllWorkspaces(window) &&
221 !wm::IsWindowFullscreen(window) && !WillRestoreToWorkspace(window))) { 207 !wm::IsWindowFullscreen(window))) {
222 ReparentWindow(window, active_workspace_->window(), NULL); 208 ReparentWindow(window, active_workspace_->window(), NULL);
223 } else { 209 } else {
224 SetActiveWorkspace(workspace, SWITCH_WINDOW_MADE_ACTIVE); 210 SetActiveWorkspace(workspace, SWITCH_WINDOW_MADE_ACTIVE);
225 } 211 }
226 } 212 }
227
228 if (workspace->is_fullscreen() && wm::IsWindowFullscreen(window)) {
229 // Clicking on the fullscreen window in a fullscreen workspace. Force all
230 // other windows to drop to the desktop.
231 MoveChildrenToDesktop(workspace->window(), NULL);
232 }
233 } 213 }
234 214
235 Window* WorkspaceManager::GetActiveWorkspaceWindow() { 215 Window* WorkspaceManager::GetActiveWorkspaceWindow() {
236 return active_workspace_->window(); 216 return active_workspace_->window();
237 } 217 }
238 218
239 Window* WorkspaceManager::GetParentForNewWindow(Window* window) { 219 Window* WorkspaceManager::GetParentForNewWindow(Window* window) {
240 // Try to put windows with transient parents in the same workspace as their 220 // Try to put windows with transient parents in the same workspace as their
241 // transient parent. 221 // transient parent.
242 if (window->transient_parent() && !wm::IsWindowFullscreen(window)) { 222 if (window->transient_parent()) {
243 Workspace* workspace = FindBy(window->transient_parent()); 223 Workspace* workspace = FindBy(window->transient_parent());
244 if (workspace) 224 if (workspace)
245 return workspace->window(); 225 return workspace->window();
246 // Fall through to normal logic. 226 // Fall through to normal logic.
247 } 227 }
248 228
249 if (!GetTrackedByWorkspace(window)) 229 if (!GetTrackedByWorkspace(window))
250 return active_workspace_->window(); 230 return active_workspace_->window();
251 231
252 if (wm::IsWindowFullscreen(window)) {
253 // Wait for the window to be made active before showing the workspace.
254 Workspace* workspace = CreateWorkspace(true);
255 pending_workspaces_.insert(workspace);
256 return workspace->window();
257 }
258
259 if (!GetTrackedByWorkspace(window) || GetPersistsAcrossAllWorkspaces(window))
260 return active_workspace_->window();
261
262 return desktop_workspace()->window(); 232 return desktop_workspace()->window();
263 } 233 }
264 234
265 bool WorkspaceManager::CanStartCyclingThroughWorkspaces() const { 235 bool WorkspaceManager::CanStartCyclingThroughWorkspaces() const {
266 return workspace_cycler_.get() && workspaces_.size() > 1u; 236 return workspace_cycler_.get() && workspaces_.size() > 1u;
267 } 237 }
268 238
269 void WorkspaceManager::InitWorkspaceCyclerAnimatorWithCurrentState( 239 void WorkspaceManager::InitWorkspaceCyclerAnimatorWithCurrentState(
270 WorkspaceCyclerAnimator* animator) { 240 WorkspaceCyclerAnimator* animator) {
271 if (animator) 241 if (animator)
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after
332 } 302 }
333 303
334 Workspace* last_active = active_workspace_; 304 Workspace* last_active = active_workspace_;
335 active_workspace_ = workspace; 305 active_workspace_ = workspace;
336 306
337 // The display work-area may have changed while |workspace| was not the active 307 // The display work-area may have changed while |workspace| was not the active
338 // workspace. Give it a chance to adjust its state for the new work-area. 308 // workspace. Give it a chance to adjust its state for the new work-area.
339 active_workspace_->workspace_layout_manager()-> 309 active_workspace_->workspace_layout_manager()->
340 OnDisplayWorkAreaInsetsChanged(); 310 OnDisplayWorkAreaInsetsChanged();
341 311
342 const bool is_unminimizing_fullscreen_window = 312 contents_window_->StackChildAtTop(last_active->window());
343 unminimizing_workspace_ && unminimizing_workspace_ == active_workspace_ &&
344 active_workspace_->is_fullscreen();
345 if (is_unminimizing_fullscreen_window) {
346 // If we're unminimizing a window it needs to be on the top, otherwise you
347 // won't see the animation.
348 contents_window_->StackChildAtTop(active_workspace_->window());
349 } else if (active_workspace_->is_fullscreen() &&
350 last_active->is_fullscreen() &&
351 reason != SWITCH_FULLSCREEN_FROM_FULLSCREEN_WORKSPACE) {
352 // When switching between fullscreen windows we need the last active
353 // workspace on top of the new, otherwise the animations won't look
354 // right. Since only one workspace is visible at a time stacking order of
355 // the workspace windows ultimately doesn't matter.
356 contents_window_->StackChildAtTop(last_active->window());
357 }
358 313
359 HideWorkspace(last_active, reason, is_unminimizing_fullscreen_window); 314 HideWorkspace(last_active, reason);
360 ShowWorkspace(workspace, last_active, reason); 315 ShowWorkspace(workspace, last_active, reason);
361 316
362 UpdateShelfVisibility(); 317 UpdateShelfVisibility();
363 318
364 // Showing or hiding a workspace may change the "solo window" status of 319 // Showing or hiding a workspace may change the "solo window" status of
365 // a window, requiring the header to be updated. 320 // a window, requiring the header to be updated.
366 FramePainter::UpdateSoloWindowHeader(contents_window_->GetRootWindow()); 321 FramePainter::UpdateSoloWindowHeader(contents_window_->GetRootWindow());
367 } 322 }
368 323
369 WorkspaceManager::Workspaces::iterator 324 WorkspaceManager::Workspaces::iterator
370 WorkspaceManager::FindWorkspace(Workspace* workspace) { 325 WorkspaceManager::FindWorkspace(Workspace* workspace) {
371 return std::find(workspaces_.begin(), workspaces_.end(), workspace); 326 return std::find(workspaces_.begin(), workspaces_.end(), workspace);
372 } 327 }
373 328
374 Workspace* WorkspaceManager::CreateWorkspace(bool fullscreen) { 329 Workspace* WorkspaceManager::CreateWorkspaceForTest() {
375 return new Workspace(this, contents_window_, fullscreen); 330 return new Workspace(this, contents_window_);
376 } 331 }
377 332
378 void WorkspaceManager::MoveWorkspaceToPendingOrDelete( 333 void WorkspaceManager::MoveWorkspaceToPendingOrDelete(
379 Workspace* workspace, 334 Workspace* workspace,
380 Window* stack_beneath, 335 Window* stack_beneath,
381 SwitchReason reason) { 336 SwitchReason reason) {
382 // We're all ready moving windows. 337 // We're all ready moving windows.
383 if (in_move_) 338 if (in_move_)
384 return; 339 return;
385 340
(...skipping 11 matching lines...) Expand all
397 352
398 MoveChildrenToDesktop(workspace->window(), stack_beneath); 353 MoveChildrenToDesktop(workspace->window(), stack_beneath);
399 354
400 { 355 {
401 Workspaces::iterator workspace_i(FindWorkspace(workspace)); 356 Workspaces::iterator workspace_i(FindWorkspace(workspace));
402 if (workspace_i != workspaces_.end()) 357 if (workspace_i != workspaces_.end())
403 workspaces_.erase(workspace_i); 358 workspaces_.erase(workspace_i);
404 } 359 }
405 360
406 if (workspace->window()->children().empty()) { 361 if (workspace->window()->children().empty()) {
407 if (workspace == unminimizing_workspace_)
408 unminimizing_workspace_ = NULL;
409 pending_workspaces_.erase(workspace); 362 pending_workspaces_.erase(workspace);
410 ScheduleDelete(workspace); 363 ScheduleDelete(workspace);
411 } else { 364 } else {
412 pending_workspaces_.insert(workspace); 365 pending_workspaces_.insert(workspace);
413 } 366 }
414 } 367 }
415 368
416 void WorkspaceManager::MoveChildrenToDesktop(aura::Window* window, 369 void WorkspaceManager::MoveChildrenToDesktop(aura::Window* window,
417 aura::Window* stack_beneath) { 370 aura::Window* stack_beneath) {
418 // Build the list of windows to move. Exclude fullscreen and windows with 371 // Build the list of windows to move. Exclude fullscreen and windows with
419 // transient parents. 372 // transient parents.
420 Window::Windows to_move; 373 Window::Windows to_move;
421 for (size_t i = 0; i < window->children().size(); ++i) { 374 for (size_t i = 0; i < window->children().size(); ++i) {
422 Window* child = window->children()[i]; 375 Window* child = window->children()[i];
423 if (!child->transient_parent() && !wm::IsWindowFullscreen(child) && 376 if (!child->transient_parent() && !wm::IsWindowFullscreen(child)) {
424 !WillRestoreToWorkspace(child)) {
425 to_move.push_back(child); 377 to_move.push_back(child);
426 } 378 }
427 } 379 }
428 // Move the windows, but make sure the window is still a child of |window| 380 // Move the windows, but make sure the window is still a child of |window|
429 // (moving may cascade and cause other windows to move). 381 // (moving may cascade and cause other windows to move).
430 for (size_t i = 0; i < to_move.size(); ++i) { 382 for (size_t i = 0; i < to_move.size(); ++i) {
431 if (std::find(window->children().begin(), window->children().end(), 383 if (std::find(window->children().begin(), window->children().end(),
432 to_move[i]) != window->children().end()) { 384 to_move[i]) != window->children().end()) {
433 ReparentWindow(to_move[i], desktop_workspace()->window(), 385 ReparentWindow(to_move[i], desktop_workspace()->window(),
434 stack_beneath); 386 stack_beneath);
(...skipping 12 matching lines...) Expand all
447 SetActiveWorkspace(*(workspace_i - 1), reason); 399 SetActiveWorkspace(*(workspace_i - 1), reason);
448 } 400 }
449 401
450 void WorkspaceManager::ScheduleDelete(Workspace* workspace) { 402 void WorkspaceManager::ScheduleDelete(Workspace* workspace) {
451 to_delete_.insert(workspace); 403 to_delete_.insert(workspace);
452 delete_timer_.Stop(); 404 delete_timer_.Stop();
453 delete_timer_.Start(FROM_HERE, base::TimeDelta::FromSeconds(1), this, 405 delete_timer_.Start(FROM_HERE, base::TimeDelta::FromSeconds(1), this,
454 &WorkspaceManager::ProcessDeletion); 406 &WorkspaceManager::ProcessDeletion);
455 } 407 }
456 408
457 void WorkspaceManager::SetUnminimizingWorkspace(Workspace* workspace) {
458 // The normal sequence of unminimizing a window is: Show() the window, which
459 // triggers changing the kShowStateKey to NORMAL and lastly the window is made
460 // active. This means at the time the window is unminimized we don't know if
461 // the workspace it is in is going to become active. To track this
462 // |unminimizing_workspace_| is set at the time we unminimize and a task is
463 // schedule to reset it. This way when we get the activate we know we're in
464 // the process unminimizing and can do the right animation.
465 unminimizing_workspace_ = workspace;
466 if (unminimizing_workspace_) {
467 base::MessageLoop::current()->PostTask(
468 FROM_HERE,
469 base::Bind(&WorkspaceManager::SetUnminimizingWorkspace,
470 clear_unminimizing_workspace_factory_.GetWeakPtr(),
471 static_cast<Workspace*>(NULL)));
472 }
473 }
474
475 void WorkspaceManager::FadeDesktop(aura::Window* window, 409 void WorkspaceManager::FadeDesktop(aura::Window* window,
476 base::TimeDelta duration) { 410 base::TimeDelta duration) {
477 if (views::corewm::WindowAnimationsDisabled(NULL) || 411 if (views::corewm::WindowAnimationsDisabled(NULL) ||
478 ui::ScopedAnimationDurationScaleMode::duration_scale_mode() == 412 ui::ScopedAnimationDurationScaleMode::duration_scale_mode() ==
479 ui::ScopedAnimationDurationScaleMode::ZERO_DURATION) 413 ui::ScopedAnimationDurationScaleMode::ZERO_DURATION)
480 return; 414 return;
481 415
482 base::AutoReset<bool> reseter(&creating_fade_, true); 416 base::AutoReset<bool> reseter(&creating_fade_, true);
483 DesktopBackgroundFadeController::Direction direction; 417 DesktopBackgroundFadeController::Direction direction;
484 aura::Window* parent = NULL; 418 aura::Window* parent = NULL;
(...skipping 20 matching lines...) Expand all
505 Workspace* last_active, 439 Workspace* last_active,
506 SwitchReason reason) const { 440 SwitchReason reason) const {
507 WorkspaceAnimationDetails details; 441 WorkspaceAnimationDetails details;
508 details.direction = 442 details.direction =
509 (last_active == desktop_workspace() || reason == SWITCH_INITIAL) ? 443 (last_active == desktop_workspace() || reason == SWITCH_INITIAL) ?
510 WORKSPACE_ANIMATE_DOWN : WORKSPACE_ANIMATE_UP; 444 WORKSPACE_ANIMATE_DOWN : WORKSPACE_ANIMATE_UP;
511 445
512 switch (reason) { 446 switch (reason) {
513 case SWITCH_WINDOW_MADE_ACTIVE: 447 case SWITCH_WINDOW_MADE_ACTIVE:
514 case SWITCH_TRACKED_BY_WORKSPACE_CHANGED: 448 case SWITCH_TRACKED_BY_WORKSPACE_CHANGED:
515 case SWITCH_WINDOW_REMOVED:
516 case SWITCH_VISIBILITY_CHANGED:
517 case SWITCH_MINIMIZED:
518 details.animate = details.animate_scale = true; 449 details.animate = details.animate_scale = true;
519 details.animate_opacity = last_active == desktop_workspace(); 450 details.animate_opacity = last_active == desktop_workspace();
520 break; 451 break;
521 452
522 case SWITCH_INITIAL: 453 case SWITCH_INITIAL:
523 details.animate = details.animate_opacity = details.animate_scale = true; 454 details.animate = details.animate_opacity = details.animate_scale = true;
524 details.pause_time_ms = kInitialPauseTimeMS; 455 details.pause_time_ms = kInitialPauseTimeMS;
525 break; 456 break;
526 457
527 // Remaining cases require no animation. 458 // Remaining cases require no animation.
528 default: 459 default:
529 break; 460 break;
530 } 461 }
531 ash::internal::ShowWorkspace(workspace->window(), details); 462 ash::internal::ShowWorkspace(workspace->window(), details);
532 } 463 }
533 464
534 void WorkspaceManager::HideWorkspace( 465 void WorkspaceManager::HideWorkspace(
535 Workspace* workspace, 466 Workspace* workspace,
536 SwitchReason reason, 467 SwitchReason reason) const {
537 bool is_unminimizing_fullscreen_window) const {
538 WorkspaceAnimationDetails details; 468 WorkspaceAnimationDetails details;
539 details.direction = active_workspace_ == desktop_workspace() ? 469 details.direction = active_workspace_ == desktop_workspace() ?
540 WORKSPACE_ANIMATE_UP : WORKSPACE_ANIMATE_DOWN; 470 WORKSPACE_ANIMATE_UP : WORKSPACE_ANIMATE_DOWN;
541 switch (reason) { 471 switch (reason) {
542 case SWITCH_WINDOW_MADE_ACTIVE: 472 case SWITCH_WINDOW_MADE_ACTIVE:
543 case SWITCH_TRACKED_BY_WORKSPACE_CHANGED: 473 case SWITCH_TRACKED_BY_WORKSPACE_CHANGED:
544 details.animate_opacity = 474 details.animate_opacity =
545 ((active_workspace_ == desktop_workspace() || 475 ((active_workspace_ == desktop_workspace() ||
546 workspace != desktop_workspace()) && 476 workspace != desktop_workspace()));
547 !is_unminimizing_fullscreen_window);
548 details.animate_scale = true; 477 details.animate_scale = true;
549 details.animate = true; 478 details.animate = true;
550 break; 479 break;
551 480
552 case SWITCH_VISIBILITY_CHANGED:
553 // The window is most likely closing. Make the workspace visible for the
554 // duration of the switch so that the close animation is visible.
555 details.animate = true;
556 details.animate_scale = true;
557 break;
558
559 case SWITCH_FULLSCREEN_FROM_FULLSCREEN_WORKSPACE:
560 case SWITCH_MAXIMIZED_OR_RESTORED:
561 if (active_workspace_->is_fullscreen()) {
562 // Delay the hide until the animation is done.
563 details.duration =
564 base::TimeDelta::FromMilliseconds(kCrossFadeSwitchTimeMS);
565 details.animate = true;
566 }
567 break;
568
569 // Remaining cases require no animation. 481 // Remaining cases require no animation.
570 default: 482 default:
571 break; 483 break;
572 } 484 }
573 ash::internal::HideWorkspace(workspace->window(), details); 485 ash::internal::HideWorkspace(workspace->window(), details);
574 } 486 }
575 487
576 void WorkspaceManager::ProcessDeletion() { 488 void WorkspaceManager::ProcessDeletion() {
577 std::set<Workspace*> to_delete; 489 std::set<Workspace*> to_delete;
578 to_delete.swap(to_delete_); 490 to_delete.swap(to_delete_);
(...skipping 29 matching lines...) Expand all
608 520
609 void WorkspaceManager::OnWillRemoveWindowFromWorkspace(Workspace* workspace, 521 void WorkspaceManager::OnWillRemoveWindowFromWorkspace(Workspace* workspace,
610 Window* child) { 522 Window* child) {
611 if (child->TargetVisibility()) 523 if (child->TargetVisibility())
612 RearrangeVisibleWindowOnHideOrRemove(child); 524 RearrangeVisibleWindowOnHideOrRemove(child);
613 child->ClearProperty(kWorkspaceKey); 525 child->ClearProperty(kWorkspaceKey);
614 } 526 }
615 527
616 void WorkspaceManager::OnWindowRemovedFromWorkspace(Workspace* workspace, 528 void WorkspaceManager::OnWindowRemovedFromWorkspace(Workspace* workspace,
617 Window* child) { 529 Window* child) {
618 if (workspace->ShouldMoveToPending())
619 MoveWorkspaceToPendingOrDelete(workspace, NULL, SWITCH_WINDOW_REMOVED);
620 UpdateShelfVisibility(); 530 UpdateShelfVisibility();
621 } 531 }
622 532
623 void WorkspaceManager::OnWorkspaceChildWindowVisibilityChanged( 533 void WorkspaceManager::OnWorkspaceChildWindowVisibilityChanged(
624 Workspace* workspace, 534 Workspace* workspace,
625 Window* child) { 535 Window* child) {
626 if (workspace->ShouldMoveToPending()) { 536 if (child->TargetVisibility())
627 MoveWorkspaceToPendingOrDelete(workspace, NULL, SWITCH_VISIBILITY_CHANGED); 537 RearrangeVisibleWindowOnShow(child);
628 } else { 538 else
629 if (child->TargetVisibility()) 539 RearrangeVisibleWindowOnHideOrRemove(child);
630 RearrangeVisibleWindowOnShow(child); 540 if (workspace == active_workspace_) {
631 else 541 UpdateShelfVisibility();
632 RearrangeVisibleWindowOnHideOrRemove(child); 542 FramePainter::UpdateSoloWindowHeader(child->GetRootWindow());
633 if (workspace == active_workspace_) {
634 UpdateShelfVisibility();
635 FramePainter::UpdateSoloWindowHeader(child->GetRootWindow());
636 }
637 } 543 }
638 } 544 }
639 545
640 void WorkspaceManager::OnWorkspaceWindowChildBoundsChanged( 546 void WorkspaceManager::OnWorkspaceWindowChildBoundsChanged(
641 Workspace* workspace, 547 Workspace* workspace,
642 Window* child) { 548 Window* child) {
643 if (workspace == active_workspace_) 549 if (workspace == active_workspace_)
644 UpdateShelfVisibility(); 550 UpdateShelfVisibility();
645 } 551 }
646 552
647 void WorkspaceManager::OnWorkspaceWindowShowStateChanged( 553 void WorkspaceManager::OnWorkspaceWindowShowStateChanged(
648 Workspace* workspace, 554 Workspace* workspace,
649 Window* child, 555 Window* child,
650 ui::WindowShowState last_show_state, 556 ui::WindowShowState last_show_state) {
651 ui::Layer* old_layer) {
652 // |child| better still be in |workspace| else things have gone wrong. 557 // |child| better still be in |workspace| else things have gone wrong.
653 DCHECK_EQ(workspace, child->GetProperty(kWorkspaceKey)); 558 DCHECK_EQ(workspace, child->GetProperty(kWorkspaceKey));
654 559
655 if (wm::IsWindowMinimized(child)) { 560 if (!wm::IsWindowMinimized(child) && workspace != desktop_workspace()) {
656 if (workspace->ShouldMoveToPending()) 561 {
657 MoveWorkspaceToPendingOrDelete(workspace, NULL, SWITCH_MINIMIZED); 562 base::AutoReset<bool> setter(&in_move_, true);
658 DCHECK(!old_layer); 563 ReparentWindow(child, desktop_workspace()->window(), NULL);
659 } else {
660 // Set of cases to deal with:
661 // . More than one fullscreen window: move newly fullscreen window into
662 // own workspace.
663 // . One fullscreen window and not in a fullscreen workspace: move window
664 // into own workspace.
665 // . No fullscreen window and not in desktop: move to desktop and further
666 // any existing windows are stacked beneath |child|.
667 const bool is_active = wm::IsActiveWindow(child);
668 Workspace* new_workspace = NULL;
669 const int full_count = workspace->GetNumFullscreenWindows();
670 base::TimeDelta duration = (old_layer && !wm::IsWindowFullscreen(child)) ?
671 GetCrossFadeDuration(old_layer->bounds(), child->bounds()) :
672 base::TimeDelta::FromMilliseconds(kCrossFadeSwitchTimeMS);
673 if (full_count == 0) {
674 if (workspace != desktop_workspace()) {
675 {
676 base::AutoReset<bool> setter(&in_move_, true);
677 ReparentWindow(child, desktop_workspace()->window(), NULL);
678 }
679 DCHECK(!is_active || old_layer);
680 new_workspace = desktop_workspace();
681 SetActiveWorkspace(new_workspace, SWITCH_MAXIMIZED_OR_RESTORED);
682 MoveWorkspaceToPendingOrDelete(workspace, child,
683 SWITCH_MAXIMIZED_OR_RESTORED);
684 if (FindWorkspace(workspace) == workspaces_.end())
685 workspace = NULL;
686 }
687 } else if ((full_count == 1 && workspace == desktop_workspace()) ||
688 full_count > 1) {
689 new_workspace = CreateWorkspace(true);
690 pending_workspaces_.insert(new_workspace);
691 ReparentWindow(child, new_workspace->window(), NULL);
692 } 564 }
693 if (is_active && new_workspace) { 565 SetActiveWorkspace(desktop_workspace(), SWITCH_MAXIMIZED_OR_RESTORED);
694 // |old_layer| may be NULL if as part of processing 566 MoveWorkspaceToPendingOrDelete(workspace,
695 // WorkspaceLayoutManager::OnWindowPropertyChanged() the window is made 567 child,
696 // active. 568 SWITCH_MAXIMIZED_OR_RESTORED);
697 if (old_layer) {
698 SetActiveWorkspace(new_workspace,
699 full_count >= 2 ?
700 SWITCH_FULLSCREEN_FROM_FULLSCREEN_WORKSPACE :
701 SWITCH_MAXIMIZED_OR_RESTORED);
702 CrossFadeWindowBetweenWorkspaces(new_workspace->window(), child,
703 old_layer);
704 if (workspace == desktop_workspace() ||
705 new_workspace == desktop_workspace()) {
706 FadeDesktop(child, duration);
707 }
708 } else {
709 SetActiveWorkspace(new_workspace, SWITCH_OTHER);
710 }
711 } else {
712 if (last_show_state == ui::SHOW_STATE_MINIMIZED)
713 SetUnminimizingWorkspace(new_workspace ? new_workspace : workspace);
714 DCHECK(!old_layer);
715 }
716 } 569 }
717 UpdateShelfVisibility(); 570 UpdateShelfVisibility();
718 } 571 }
719 572
720 void WorkspaceManager::OnTrackedByWorkspaceChanged(Workspace* workspace, 573 void WorkspaceManager::OnTrackedByWorkspaceChanged(Workspace* workspace,
721 aura::Window* window) { 574 aura::Window* window) {
722 Workspace* new_workspace = NULL; 575 if (workspace == active_workspace_)
723 if (wm::IsWindowFullscreen(window)) {
724 if (workspace->is_fullscreen() &&
725 workspace->GetNumFullscreenWindows() == 1) {
726 // If |window| is the only window in a fullscreen workspace then leave
727 // it there. Additionally animate it back to the origin.
728 ui::ScopedLayerAnimationSettings settings(window->layer()->GetAnimator());
729 // All bounds changes get routed through WorkspaceLayoutManager and since
730 // the window is fullscreen WorkspaceLayoutManager is going to force a
731 // value. In other words, it doesn't matter what we supply to SetBounds()
732 // here.
733 window->SetBounds(gfx::Rect());
734 return;
735 }
736 new_workspace = CreateWorkspace(true);
737 pending_workspaces_.insert(new_workspace);
738 } else if (workspace->is_fullscreen()) {
739 new_workspace = desktop_workspace();
740 } else {
741 return; 576 return;
742 } 577
743 // If the window is active we need to make sure the destination Workspace 578 // If the window is active we need to make sure the destination Workspace
744 // window is showing. Otherwise the window will be parented to a hidden window 579 // window is showing. Otherwise the window will be parented to a hidden window
745 // and lose activation. 580 // and lose activation.
746 const bool is_active = wm::IsActiveWindow(window); 581 const bool is_active = wm::IsActiveWindow(window);
747 if (is_active) 582 if (is_active)
748 new_workspace->window()->Show(); 583 workspace->window()->Show();
749 ReparentWindow(window, new_workspace->window(), NULL); 584 ReparentWindow(window, workspace->window(), NULL);
750 if (is_active) { 585 if (is_active)
751 SetActiveWorkspace(new_workspace, SWITCH_TRACKED_BY_WORKSPACE_CHANGED); 586 SetActiveWorkspace(workspace, SWITCH_TRACKED_BY_WORKSPACE_CHANGED);
752 }
753 } 587 }
754 588
755 } // namespace internal 589 } // namespace internal
756 } // namespace ash 590 } // namespace ash
OLDNEW
« no previous file with comments | « ash/wm/workspace/workspace_manager.h ('k') | ash/wm/workspace/workspace_manager_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698