15d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved. 25d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// found in the LICENSE file. 45d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 55d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "ash/wm/workspace_controller.h" 65d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 75d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "ash/root_window_controller.h" 85d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "ash/shelf/shelf_layout_manager.h" 95d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "ash/shell.h" 105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "ash/shell_window_ids.h" 115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "ash/wm/window_animations.h" 125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "ash/wm/window_state.h" 135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "ash/wm/window_util.h" 145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "ash/wm/workspace/workspace_event_handler.h" 155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "ash/wm/workspace/workspace_layout_manager.h" 165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "ash/wm/workspace/workspace_layout_manager_delegate.h" 175c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu#include "ui/aura/client/aura_constants.h" 185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "ui/aura/window.h" 195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "ui/aura/window_event_dispatcher.h" 205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "ui/compositor/layer.h" 215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "ui/compositor/scoped_layer_animation_settings.h" 225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "ui/wm/core/visibility_controller.h" 235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "ui/wm/core/window_animations.h" 245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "ui/wm/public/activation_client.h" 255c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu 26a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)namespace ash { 275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)namespace { 285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// Amount of time to pause before animating anything. Only used during initial 305c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu// animation (when logging in). 315c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liuconst int kInitialPauseTimeMS = 750; 325c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu 335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// Returns true if there are visible docked windows in the same screen as the 345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// |shelf|. 3523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)bool IsDockedAreaVisible(const ShelfLayoutManager* shelf) { 3623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) return shelf->dock_bounds().width() > 0; 375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 38e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch 39e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch} // namespace 405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)WorkspaceController::WorkspaceController(aura::Window* viewport) 425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) : viewport_(viewport), 435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) shelf_(NULL), 445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) event_handler_(new WorkspaceEventHandler), 455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) layout_manager_(new WorkspaceLayoutManager(viewport)) { 465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) SetWindowVisibilityAnimationTransition( 475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) viewport_, ::wm::ANIMATE_NONE); 485f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) viewport_->SetLayoutManager(layout_manager_); 505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) viewport_->AddPreTargetHandler(event_handler_.get()); 511320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci viewport_->AddPostTargetHandler(event_handler_.get()); 525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 531320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)WorkspaceController::~WorkspaceController() { 555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) viewport_->SetLayoutManager(NULL); 565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) viewport_->RemovePreTargetHandler(event_handler_.get()); 575d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) viewport_->RemovePostTargetHandler(event_handler_.get()); 585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)WorkspaceWindowState WorkspaceController::GetWindowState() const { 61a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (!shelf_) 625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return WORKSPACE_WINDOW_STATE_DEFAULT; 63a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) const aura::Window* topmost_fullscreen_window = GetRootWindowController( 64a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) viewport_->GetRootWindow())->GetWindowForFullscreenMode(); 655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (topmost_fullscreen_window && 665c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu !wm::GetWindowState(topmost_fullscreen_window)->ignored_by_shelf()) { 675c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu return WORKSPACE_WINDOW_STATE_FULL_SCREEN; 685c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu } 695c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu 705f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) // These are the container ids of containers which may contain windows that 715f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) // may overlap the launcher shelf and affect its transparency. 725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const int kWindowContainerIds[] = {kShellWindowId_DefaultContainer, 735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) kShellWindowId_DockedContainer, }; 745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const gfx::Rect shelf_bounds(shelf_->GetIdealBounds()); 755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) bool window_overlaps_launcher = false; 76e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch for (size_t idx = 0; idx < arraysize(kWindowContainerIds); idx++) { 77e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch const aura::Window* container = Shell::GetContainer( 78e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch viewport_->GetRootWindow(), kWindowContainerIds[idx]); 795d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const aura::Window::Windows& windows(container->children()); 805d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) for (aura::Window::Windows::const_iterator i = windows.begin(); 810529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch i != windows.end(); ++i) { 825f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) wm::WindowState* window_state = wm::GetWindowState(*i); 835f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if (window_state->ignored_by_shelf()) 845f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) continue; 855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ui::Layer* layer = (*i)->layer(); 860529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch if (!layer->GetTargetVisibility()) 870529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch continue; 880529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch if (window_state->IsMaximized()) 895d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return WORKSPACE_WINDOW_STATE_MAXIMIZED; 90e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch if (!window_overlaps_launcher && 910529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch ((*i)->bounds().Intersects(shelf_bounds))) { 92e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch window_overlaps_launcher = true; 930529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch } 94e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch } 95a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) } 96a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 97effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch return (window_overlaps_launcher || IsDockedAreaVisible(shelf_)) ? 98a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) WORKSPACE_WINDOW_STATE_WINDOW_OVERLAPS_SHELF : 99a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) WORKSPACE_WINDOW_STATE_DEFAULT; 100a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)} 101a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 1020529e5d033099cbfc42635f6f6183833b09dff6eBen Murdochvoid WorkspaceController::SetShelf(ShelfLayoutManager* shelf) { 1030529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch shelf_ = shelf; 1045f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) layout_manager_->SetShelf(shelf); 10503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)} 1061320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 1071320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccivoid WorkspaceController::DoInitialAnimation() { 1085d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) viewport_->Show(); 1090529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch 1105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) viewport_->layer()->SetOpacity(0.0f); 111c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch SetTransformForScaleAnimation( 112c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch viewport_->layer(), LAYER_SCALE_ANIMATION_ABOVE); 1135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1145c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu // In order for pause to work we need to stop animations. 1155f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) viewport_->layer()->GetAnimator()->StopAnimating(); 1165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1170529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch { 1180529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch ui::ScopedLayerAnimationSettings settings( 1190529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch viewport_->layer()->GetAnimator()); 1205c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu 1215c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu settings.SetPreemptionStrategy(ui::LayerAnimator::ENQUEUE_NEW_ANIMATION); 1225c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu viewport_->layer()->GetAnimator()->SchedulePauseForProperties( 1235c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu base::TimeDelta::FromMilliseconds(kInitialPauseTimeMS), 1245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ui::LayerAnimationElement::TRANSFORM | 1255c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu ui::LayerAnimationElement::OPACITY | 126a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) ui::LayerAnimationElement::BRIGHTNESS | 1275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ui::LayerAnimationElement::VISIBILITY); 128a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) settings.SetTweenType(gfx::Tween::EASE_OUT); 129a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) settings.SetTransitionDuration( 1305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) base::TimeDelta::FromMilliseconds(kCrossFadeDurationMS)); 1315f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) viewport_->layer()->SetTransform(gfx::Transform()); 132a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) viewport_->layer()->SetOpacity(1.0f); 1330529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch } 134a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)} 135a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 1365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void WorkspaceController::SetMaximizeBackdropDelegate( 1375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) scoped_ptr<WorkspaceLayoutManagerDelegate> delegate) { 1385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) layout_manager_->SetMaximizeBackdropDelegate(delegate.Pass()); 1395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 1405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} // namespace ash 1425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)