1f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)// Copyright 2013 The Chromium Authors. All rights reserved. 2f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 3f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)// found in the LICENSE file. 4f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 5f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "ash/wm/immersive_fullscreen_controller.h" 6f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 7f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include <set> 8f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 95d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "ash/ash_constants.h" 10f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "ash/shell.h" 115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "ash/wm/resize_handle_window_targeter.h" 12f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "ash/wm/window_state.h" 135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "base/metrics/histogram.h" 14f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "ui/aura/client/aura_constants.h" 15f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "ui/aura/client/capture_client.h" 16f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "ui/aura/client/cursor_client.h" 17f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "ui/aura/client/screen_position_client.h" 18f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "ui/aura/env.h" 19f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "ui/aura/window.h" 20a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "ui/aura/window_event_dispatcher.h" 21f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "ui/gfx/animation/slide_animation.h" 22f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "ui/gfx/display.h" 23f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "ui/gfx/point.h" 24f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "ui/gfx/rect.h" 25f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "ui/gfx/screen.h" 26f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "ui/views/bubble/bubble_delegate.h" 27f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "ui/views/view.h" 28f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "ui/views/widget/widget.h" 29a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "ui/wm/core/transient_window_manager.h" 30a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "ui/wm/core/window_util.h" 31effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch#include "ui/wm/public/activation_client.h" 32f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 33f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)using views::View; 34f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 35f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)namespace ash { 36f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 37f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)namespace { 38f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 39f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)// Duration for the reveal show/hide slide animation. The slower duration is 40f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)// used for the initial slide out to give the user more change to see what 41f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)// happened. 42f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)const int kRevealSlowAnimationDurationMs = 400; 43f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)const int kRevealFastAnimationDurationMs = 200; 44f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 45f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)// The delay in milliseconds between the mouse stopping at the top edge of the 46f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)// screen and the top-of-window views revealing. 47f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)const int kMouseRevealDelayMs = 200; 48f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 49f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)// The maximum amount of pixels that the cursor can move for the cursor to be 50f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)// considered "stopped". This allows the user to reveal the top-of-window views 51f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)// without holding the cursor completely still. 52f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)const int kMouseRevealXThresholdPixels = 3; 53f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 54f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)// Used to multiply x value of an update in check to determine if gesture is 55f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)// vertical. This is used to make sure that gesture is close to vertical instead 56f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)// of just more vertical then horizontal. 57f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)const int kSwipeVerticalThresholdMultiplier = 3; 58f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 59f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)// The height in pixels of the region above the top edge of the display which 60f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)// hosts the immersive fullscreen window in which mouse events are ignored 61f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)// (cannot reveal or unreveal the top-of-window views). 62f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)// See ShouldIgnoreMouseEventAtLocation() for more details. 63f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)const int kHeightOfDeadRegionAboveTopContainer = 10; 64f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 65f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)// Returns the BubbleDelegateView corresponding to |maybe_bubble| if 66f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)// |maybe_bubble| is a bubble. 67f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)views::BubbleDelegateView* AsBubbleDelegate(aura::Window* maybe_bubble) { 68f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (!maybe_bubble) 69f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) return NULL; 70f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) views::Widget* widget = views::Widget::GetWidgetForNativeView(maybe_bubble); 71f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (!widget) 72f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) return NULL; 73f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) return widget->widget_delegate()->AsBubbleDelegate(); 74f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)} 75f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 76f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)// Returns true if |maybe_transient| is a transient child of |toplevel|. 77f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)bool IsWindowTransientChildOf(aura::Window* maybe_transient, 78f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) aura::Window* toplevel) { 79f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (!maybe_transient || !toplevel) 80f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) return false; 81f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 82f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) for (aura::Window* window = maybe_transient; window; 83a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) window = ::wm::GetTransientParent(window)) { 84f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (window == toplevel) 85f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) return true; 86f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } 87f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) return false; 88f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)} 89f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 90f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)// Returns the location of |event| in screen coordinates. 91f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)gfx::Point GetEventLocationInScreen(const ui::LocatedEvent& event) { 92f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) gfx::Point location_in_screen = event.location(); 93f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) aura::Window* target = static_cast<aura::Window*>(event.target()); 94f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) aura::client::ScreenPositionClient* screen_position_client = 95f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) aura::client::GetScreenPositionClient(target->GetRootWindow()); 96f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) screen_position_client->ConvertPointToScreen(target, &location_in_screen); 97f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) return location_in_screen; 98f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)} 99f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 100f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)// Returns the bounds of the display nearest to |window| in screen coordinates. 101f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)gfx::Rect GetDisplayBoundsInScreen(aura::Window* window) { 102f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) return Shell::GetScreen()->GetDisplayNearestWindow(window).bounds(); 103f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)} 104f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 105f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)} // namespace 106f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 107a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch// The height in pixels of the region below the top edge of the display in which 108a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch// the mouse can trigger revealing the top-of-window views. 109a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch#if defined(OS_WIN) 110a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch// Windows 8 reserves some pixels at the top of the screen for the hand icon 111a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch// that allows you to drag a metro app off the screen, so a few additional 112a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch// pixels of space must be reserved for the mouse reveal. 113a02191e04bc25c4935f804f2c080ae28663d096dBen Murdochconst int ImmersiveFullscreenController::kMouseRevealBoundsHeight = 9; 114a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch#else 115a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch// The height must be greater than 1px because the top pixel is used to trigger 116a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch// moving the cursor between displays if the user has a vertical display layout 117a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch// (primary display above/below secondary display). 118a02191e04bc25c4935f804f2c080ae28663d096dBen Murdochconst int ImmersiveFullscreenController::kMouseRevealBoundsHeight = 3; 119a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch#endif 120a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch 121f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)//////////////////////////////////////////////////////////////////////////////// 122f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 123f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)// Class which keeps the top-of-window views revealed as long as one of the 124f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)// bubbles it is observing is visible. The logic to keep the top-of-window 125f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)// views revealed based on the visibility of bubbles anchored to 126f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)// children of |ImmersiveFullscreenController::top_container_| is separate from 127f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)// the logic related to |ImmersiveFullscreenController::focus_revealed_lock_| 128f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)// so that bubbles which are not activatable and bubbles which do not close 129f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)// upon deactivation also keep the top-of-window views revealed for the 130f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)// duration of their visibility. 131f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)class ImmersiveFullscreenController::BubbleManager 132f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) : public aura::WindowObserver { 133f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) public: 134f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) explicit BubbleManager(ImmersiveFullscreenController* controller); 135f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) virtual ~BubbleManager(); 136f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 137f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // Start / stop observing changes to |bubble|'s visibility. 138f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) void StartObserving(aura::Window* bubble); 139f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) void StopObserving(aura::Window* bubble); 140f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 141f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) private: 142f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // Updates |revealed_lock_| based on whether any of |bubbles_| is visible. 143f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) void UpdateRevealedLock(); 144f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 145f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // aura::WindowObserver overrides: 146f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) virtual void OnWindowVisibilityChanged(aura::Window* window, 147f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) bool visible) OVERRIDE; 148f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) virtual void OnWindowDestroying(aura::Window* window) OVERRIDE; 149f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 150f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) ImmersiveFullscreenController* controller_; 151f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 152f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) std::set<aura::Window*> bubbles_; 153f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 154f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // Lock which keeps the top-of-window views revealed based on whether any of 155f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // |bubbles_| is visible. 156f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) scoped_ptr<ImmersiveRevealedLock> revealed_lock_; 157f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 158f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) DISALLOW_COPY_AND_ASSIGN(BubbleManager); 159f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}; 160f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 161f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)ImmersiveFullscreenController::BubbleManager::BubbleManager( 162f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) ImmersiveFullscreenController* controller) 163f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) : controller_(controller) { 164f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)} 165f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 166f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)ImmersiveFullscreenController::BubbleManager::~BubbleManager() { 167f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) for (std::set<aura::Window*>::const_iterator it = bubbles_.begin(); 168f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) it != bubbles_.end(); ++it) { 169f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) (*it)->RemoveObserver(this); 170f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } 171f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)} 172f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 173f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)void ImmersiveFullscreenController::BubbleManager::StartObserving( 174f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) aura::Window* bubble) { 175f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (bubbles_.insert(bubble).second) { 176f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) bubble->AddObserver(this); 177f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) UpdateRevealedLock(); 178f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } 179f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)} 180f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 181f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)void ImmersiveFullscreenController::BubbleManager::StopObserving( 182f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) aura::Window* bubble) { 183f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (bubbles_.erase(bubble)) { 184f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) bubble->RemoveObserver(this); 185f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) UpdateRevealedLock(); 186f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } 187f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)} 188f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 189f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)void ImmersiveFullscreenController::BubbleManager::UpdateRevealedLock() { 190f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) bool has_visible_bubble = false; 191f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) for (std::set<aura::Window*>::const_iterator it = bubbles_.begin(); 192f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) it != bubbles_.end(); ++it) { 193f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if ((*it)->IsVisible()) { 194f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) has_visible_bubble = true; 195f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) break; 196f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } 197f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } 198f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 199f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) bool was_revealed = controller_->IsRevealed(); 200f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (has_visible_bubble) { 201f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (!revealed_lock_.get()) { 202f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // Reveal the top-of-window views without animating because it looks 203f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // weird for the top-of-window views to animate and the bubble not to 204f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // animate along with the top-of-window views. 205f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) revealed_lock_.reset(controller_->GetRevealedLock( 206f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) ImmersiveFullscreenController::ANIMATE_REVEAL_NO)); 207f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } 208f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } else { 209f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) revealed_lock_.reset(); 210f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } 211f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 212f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (!was_revealed && revealed_lock_.get()) { 213f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // Currently, there is no nice way for bubbles to reposition themselves 214f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // whenever the anchor view moves. Tell the bubbles to reposition themselves 215f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // explicitly instead. The hidden bubbles are also repositioned because 216f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // BubbleDelegateView does not reposition its widget as a result of a 217f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // visibility change. 218f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) for (std::set<aura::Window*>::const_iterator it = bubbles_.begin(); 219f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) it != bubbles_.end(); ++it) { 220f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) AsBubbleDelegate(*it)->OnAnchorBoundsChanged(); 221f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } 222f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } 223f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)} 224f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 225f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)void ImmersiveFullscreenController::BubbleManager::OnWindowVisibilityChanged( 226f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) aura::Window*, 227f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) bool visible) { 228f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) UpdateRevealedLock(); 229f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)} 230f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 231f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)void ImmersiveFullscreenController::BubbleManager::OnWindowDestroying( 232f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) aura::Window* window) { 233f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) StopObserving(window); 234f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)} 235f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 236f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)//////////////////////////////////////////////////////////////////////////////// 237f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 238f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)ImmersiveFullscreenController::ImmersiveFullscreenController() 239f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) : delegate_(NULL), 240f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) top_container_(NULL), 241f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) widget_(NULL), 242f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) native_window_(NULL), 243f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) observers_enabled_(false), 244f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) enabled_(false), 245f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) reveal_state_(CLOSED), 246f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) revealed_lock_count_(0), 247f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) mouse_x_when_hit_top_in_screen_(-1), 248f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) gesture_begun_(false), 249f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) animation_(new gfx::SlideAnimation(this)), 250f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) animations_disabled_for_test_(false), 251f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) weak_ptr_factory_(this) { 252f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)} 253f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 254f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)ImmersiveFullscreenController::~ImmersiveFullscreenController() { 255f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) EnableWindowObservers(false); 256f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)} 257f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 258f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)void ImmersiveFullscreenController::Init(Delegate* delegate, 259f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) views::Widget* widget, 260f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) views::View* top_container) { 261f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) delegate_ = delegate; 262f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) top_container_ = top_container; 263f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) widget_ = widget; 264f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) native_window_ = widget_->GetNativeWindow(); 2655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) native_window_->SetEventTargeter(scoped_ptr<ui::EventTargeter>( 2665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) new ResizeHandleWindowTargeter(native_window_, this))); 267f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)} 268f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 2695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void ImmersiveFullscreenController::SetEnabled(WindowType window_type, 2705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) bool enabled) { 271f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (enabled_ == enabled) 272f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) return; 273f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) enabled_ = enabled; 274f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 275f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) EnableWindowObservers(enabled_); 276f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 27746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) ash::wm::WindowState* window_state = wm::GetWindowState(native_window_); 278f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // Auto hide the shelf in immersive fullscreen instead of hiding it. 27946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) window_state->set_hide_shelf_when_fullscreen(!enabled); 28046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 28146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) // Update the window's immersive mode state for the window manager. 28246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) window_state->set_in_immersive_fullscreen(enabled); 28346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 284f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) Shell::GetInstance()->UpdateShelfVisibility(); 285f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 286f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (enabled_) { 287f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // Animate enabling immersive mode by sliding out the top-of-window views. 288f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // No animation occurs if a lock is holding the top-of-window views open. 289f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 290f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // Do a reveal to set the initial state for the animation. (And any 291f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // required state in case the animation cannot run because of a lock holding 292f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // the top-of-window views open.) 293f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) MaybeStartReveal(ANIMATE_NO); 294f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 295f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // Reset the located event and the focus revealed locks so that they do not 296f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // affect whether the top-of-window views are hidden. 297f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) located_event_revealed_lock_.reset(); 298f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) focus_revealed_lock_.reset(); 299f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 300f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // Try doing the animation. 301f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) MaybeEndReveal(ANIMATE_SLOW); 302f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 303f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (reveal_state_ == REVEALED) { 304f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // Reveal was unsuccessful. Reacquire the revealed locks if appropriate. 305a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) UpdateLocatedEventRevealedLock(NULL); 306f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) UpdateFocusRevealedLock(); 307a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) } else { 308a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) // Clearing focus is important because it closes focus-related popups like 309a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) // the touch selection handles. 310a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) widget_->GetFocusManager()->ClearFocus(); 311f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } 312f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } else { 313f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // Stop cursor-at-top tracking. 314f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) top_edge_hover_timer_.Stop(); 315f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) reveal_state_ = CLOSED; 316f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 317f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) delegate_->OnImmersiveFullscreenExited(); 318f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } 3195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 3205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (enabled_) { 3215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) UMA_HISTOGRAM_ENUMERATION("Ash.ImmersiveFullscreen.WindowType", 3225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) window_type, 3235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) WINDOW_TYPE_COUNT); 3245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 325f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)} 326f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 327f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)bool ImmersiveFullscreenController::IsEnabled() const { 328f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) return enabled_; 329f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)} 330f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 331f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)bool ImmersiveFullscreenController::IsRevealed() const { 332f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) return enabled_ && reveal_state_ != CLOSED; 333f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)} 334f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 335f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)ImmersiveRevealedLock* ImmersiveFullscreenController::GetRevealedLock( 336f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) AnimateReveal animate_reveal) { 337f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) return new ImmersiveRevealedLock(weak_ptr_factory_.GetWeakPtr(), 338f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) animate_reveal); 339f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)} 340f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 341f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)//////////////////////////////////////////////////////////////////////////////// 342f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)// Testing interface: 343f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 344f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)void ImmersiveFullscreenController::SetupForTest() { 345f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) DCHECK(!enabled_); 346f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) animations_disabled_for_test_ = true; 347f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 348f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // Move the mouse off of the top-of-window views so that it does not keep the 349f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // top-of-window views revealed. 350f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) std::vector<gfx::Rect> bounds_in_screen( 351f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) delegate_->GetVisibleBoundsInScreen()); 352f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) DCHECK(!bounds_in_screen.empty()); 353f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) int bottommost_in_screen = bounds_in_screen[0].bottom(); 354f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) for (size_t i = 1; i < bounds_in_screen.size(); ++i) { 355f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (bounds_in_screen[i].bottom() > bottommost_in_screen) 356f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) bottommost_in_screen = bounds_in_screen[i].bottom(); 357f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } 358f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) gfx::Point cursor_pos(0, bottommost_in_screen + 100); 359f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) aura::Env::GetInstance()->set_last_mouse_location(cursor_pos); 360a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) UpdateLocatedEventRevealedLock(NULL); 361f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)} 362f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 363f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)//////////////////////////////////////////////////////////////////////////////// 364f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)// ui::EventHandler overrides: 365f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 366f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)void ImmersiveFullscreenController::OnMouseEvent(ui::MouseEvent* event) { 367f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (!enabled_) 368f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) return; 369f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 370f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (event->type() != ui::ET_MOUSE_MOVED && 371f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) event->type() != ui::ET_MOUSE_PRESSED && 372f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) event->type() != ui::ET_MOUSE_RELEASED && 373f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) event->type() != ui::ET_MOUSE_CAPTURE_CHANGED) { 374f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) return; 375f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } 376f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 377a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) // Mouse hover can initiate revealing the top-of-window views while |widget_| 378a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) // is inactive. 379f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 380a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) if (reveal_state_ == SLIDING_OPEN || reveal_state_ == REVEALED) { 381a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) top_edge_hover_timer_.Stop(); 382a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) UpdateLocatedEventRevealedLock(event); 383a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) } else if (event->type() != ui::ET_MOUSE_CAPTURE_CHANGED) { 384a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) // Trigger a reveal if the cursor pauses at the top of the screen for a 385a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) // while. 386f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) UpdateTopEdgeHoverTimer(event); 387a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) } 388f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)} 389f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 390f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)void ImmersiveFullscreenController::OnTouchEvent(ui::TouchEvent* event) { 391f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (!enabled_ || event->type() != ui::ET_TOUCH_PRESSED) 392f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) return; 393f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 394a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) // Touch should not initiate revealing the top-of-window views while |widget_| 395a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) // is inactive. 396a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) if (!widget_->IsActive()) 397a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) return; 398a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 399a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) UpdateLocatedEventRevealedLock(event); 400f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)} 401f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 402f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)void ImmersiveFullscreenController::OnGestureEvent(ui::GestureEvent* event) { 403f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (!enabled_) 404f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) return; 405f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 406f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // Touch gestures should not initiate revealing the top-of-window views while 407a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) // |widget_| is inactive. 408a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) if (!widget_->IsActive()) 409f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) return; 410f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 411f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) switch (event->type()) { 412a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch#if defined(OS_WIN) 413a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch case ui::ET_GESTURE_WIN8_EDGE_SWIPE: 414a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch UpdateRevealedLocksForSwipe(GetSwipeType(event)); 415a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch event->SetHandled(); 416a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch break; 417a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch#endif 418f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) case ui::ET_GESTURE_SCROLL_BEGIN: 419f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (ShouldHandleGestureEvent(GetEventLocationInScreen(*event))) { 420f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) gesture_begun_ = true; 421a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) // Do not consume the event. Otherwise, we end up consuming all 422a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) // ui::ET_GESTURE_SCROLL_BEGIN events in the top-of-window views 423a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) // when the top-of-window views are revealed. 424f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } 425f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) break; 426f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) case ui::ET_GESTURE_SCROLL_UPDATE: 427f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (gesture_begun_) { 428f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (UpdateRevealedLocksForSwipe(GetSwipeType(event))) 429f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) event->SetHandled(); 430f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) gesture_begun_ = false; 431f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } 432f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) break; 433f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) case ui::ET_GESTURE_SCROLL_END: 434f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) case ui::ET_SCROLL_FLING_START: 435f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) gesture_begun_ = false; 436f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) break; 437f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) default: 438f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) break; 439f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } 440f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)} 441f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 442f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)//////////////////////////////////////////////////////////////////////////////// 443f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)// views::FocusChangeListener overrides: 444f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 445f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)void ImmersiveFullscreenController::OnWillChangeFocus( 446f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) views::View* focused_before, 447f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) views::View* focused_now) { 448f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)} 449f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 450f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)void ImmersiveFullscreenController::OnDidChangeFocus( 451f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) views::View* focused_before, 452f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) views::View* focused_now) { 453f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) UpdateFocusRevealedLock(); 454f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)} 455f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 456f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)//////////////////////////////////////////////////////////////////////////////// 457f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)// views::WidgetObserver overrides: 458f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 459f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)void ImmersiveFullscreenController::OnWidgetDestroying(views::Widget* widget) { 460f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) EnableWindowObservers(false); 461f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) native_window_ = NULL; 462f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 463f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // Set |enabled_| to false such that any calls to MaybeStartReveal() and 464f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // MaybeEndReveal() have no effect. 465f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) enabled_ = false; 466f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)} 467f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 468f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)void ImmersiveFullscreenController::OnWidgetActivationChanged( 469f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) views::Widget* widget, 470f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) bool active) { 471f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) UpdateFocusRevealedLock(); 472f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)} 473f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 474f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)//////////////////////////////////////////////////////////////////////////////// 475f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)// gfx::AnimationDelegate overrides: 476f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 477f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)void ImmersiveFullscreenController::AnimationEnded( 478f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) const gfx::Animation* animation) { 479f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (reveal_state_ == SLIDING_OPEN) { 480f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) OnSlideOpenAnimationCompleted(); 481f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } else if (reveal_state_ == SLIDING_CLOSED) { 482f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) OnSlideClosedAnimationCompleted(); 483f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } 484f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)} 485f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 486f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)void ImmersiveFullscreenController::AnimationProgressed( 487f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) const gfx::Animation* animation) { 488f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) delegate_->SetVisibleFraction(animation->GetCurrentValue()); 489f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)} 490f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 491f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)//////////////////////////////////////////////////////////////////////////////// 492f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)// aura::WindowObserver overrides: 493f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 4945d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void ImmersiveFullscreenController::OnTransientChildAdded( 4955d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) aura::Window* window, 4965d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) aura::Window* transient) { 497f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) views::BubbleDelegateView* bubble_delegate = AsBubbleDelegate(transient); 498f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (bubble_delegate && 499f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) bubble_delegate->GetAnchorView() && 500f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) top_container_->Contains(bubble_delegate->GetAnchorView())) { 501f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // Observe the aura::Window because the BubbleDelegateView may not be 502f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // parented to the widget's root view yet so |bubble_delegate->GetWidget()| 503f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // may still return NULL. 504f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) bubble_manager_->StartObserving(transient); 505f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } 506f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)} 507f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 5085d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void ImmersiveFullscreenController::OnTransientChildRemoved( 509f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) aura::Window* window, 510f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) aura::Window* transient) { 511f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) bubble_manager_->StopObserving(transient); 512f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)} 513f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 514f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)//////////////////////////////////////////////////////////////////////////////// 515f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)// ash::ImmersiveRevealedLock::Delegate overrides: 516f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 517f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)void ImmersiveFullscreenController::LockRevealedState( 518f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) AnimateReveal animate_reveal) { 519f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) ++revealed_lock_count_; 520f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) Animate animate = (animate_reveal == ANIMATE_REVEAL_YES) ? 521f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) ANIMATE_FAST : ANIMATE_NO; 522f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) MaybeStartReveal(animate); 523f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)} 524f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 525f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)void ImmersiveFullscreenController::UnlockRevealedState() { 526f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) --revealed_lock_count_; 527f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) DCHECK_GE(revealed_lock_count_, 0); 528f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (revealed_lock_count_ == 0) { 529f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // Always animate ending the reveal fast. 530f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) MaybeEndReveal(ANIMATE_FAST); 531f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } 532f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)} 533f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 534f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)//////////////////////////////////////////////////////////////////////////////// 535f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)// private: 536f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 537f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)void ImmersiveFullscreenController::EnableWindowObservers(bool enable) { 538f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (observers_enabled_ == enable) 539f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) return; 540f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) observers_enabled_ = enable; 541f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 542a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) views::FocusManager* focus_manager = widget_->GetFocusManager(); 543f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 544f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (enable) { 545a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) widget_->AddObserver(this); 546f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) focus_manager->AddFocusChangeListener(this); 547f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) Shell::GetInstance()->AddPreTargetHandler(this); 548a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) ::wm::TransientWindowManager::Get(native_window_)-> 5495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) AddObserver(this); 550f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 551f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) RecreateBubbleManager(); 552f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } else { 553a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) widget_->RemoveObserver(this); 554f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) focus_manager->RemoveFocusChangeListener(this); 555f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) Shell::GetInstance()->RemovePreTargetHandler(this); 556a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) ::wm::TransientWindowManager::Get(native_window_)-> 5575d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) RemoveObserver(this); 558f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 559f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // We have stopped observing whether transient children are added or removed 560f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // to |native_window_|. The set of bubbles that BubbleManager is observing 561f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // will become stale really quickly. Destroy BubbleManager and recreate it 562f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // when we start observing |native_window_| again. 563f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) bubble_manager_.reset(); 564f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 565f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) animation_->Stop(); 566f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } 567f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)} 568f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 569f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)void ImmersiveFullscreenController::UpdateTopEdgeHoverTimer( 570f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) ui::MouseEvent* event) { 571f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) DCHECK(enabled_); 572a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) DCHECK(reveal_state_ == SLIDING_CLOSED || reveal_state_ == CLOSED); 573a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 574a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) // Check whether |native_window_| is the event target's parent window instead 575a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) // of checking for activation. This allows the timer to be started when 576a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) // |widget_| is inactive but prevents starting the timer if the mouse is over 577a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) // a portion of the top edge obscured by an unrelated widget. 578a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) if (!top_edge_hover_timer_.IsRunning() && 579a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) !native_window_->Contains(static_cast<aura::Window*>(event->target()))) { 580f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) return; 581f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } 582f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 583a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) // Mouse hover should not initiate revealing the top-of-window views while a 584a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) // window has mouse capture. 585a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) if (aura::client::GetCaptureWindow(native_window_)) 586a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) return; 587a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 588f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) gfx::Point location_in_screen = GetEventLocationInScreen(*event); 589f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (ShouldIgnoreMouseEventAtLocation(location_in_screen)) 590f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) return; 591f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 592f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // Stop the timer if the cursor left the top edge or is on a different 593f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // display. 594f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) gfx::Rect hit_bounds_in_screen = GetDisplayBoundsInScreen(native_window_); 595f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) hit_bounds_in_screen.set_height(kMouseRevealBoundsHeight); 596f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (!hit_bounds_in_screen.Contains(location_in_screen)) { 597f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) top_edge_hover_timer_.Stop(); 598f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) return; 599f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } 600f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 601f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // The cursor is now at the top of the screen. Consider the cursor "not 602f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // moving" even if it moves a little bit because users don't have perfect 603f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // pointing precision. (The y position is not tested because 604f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // |hit_bounds_in_screen| is short.) 605f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (top_edge_hover_timer_.IsRunning() && 606f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) abs(location_in_screen.x() - mouse_x_when_hit_top_in_screen_) <= 607f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) kMouseRevealXThresholdPixels) 608f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) return; 609f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 610f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // Start the reveal if the cursor doesn't move for some amount of time. 611f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) mouse_x_when_hit_top_in_screen_ = location_in_screen.x(); 612f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) top_edge_hover_timer_.Stop(); 613f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // Timer is stopped when |this| is destroyed, hence Unretained() is safe. 614f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) top_edge_hover_timer_.Start( 615f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) FROM_HERE, 616f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) base::TimeDelta::FromMilliseconds(kMouseRevealDelayMs), 617f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) base::Bind( 618f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) &ImmersiveFullscreenController::AcquireLocatedEventRevealedLock, 619f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) base::Unretained(this))); 620f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)} 621f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 622f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)void ImmersiveFullscreenController::UpdateLocatedEventRevealedLock( 623a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) ui::LocatedEvent* event) { 624f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (!enabled_) 625f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) return; 626f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) DCHECK(!event || event->IsMouseEvent() || event->IsTouchEvent()); 627f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 628f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // Neither the mouse nor touch can initiate a reveal when the top-of-window 629f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // views are sliding closed or are closed with the following exceptions: 630f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // - Hovering at y = 0 which is handled in OnMouseEvent(). 631f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // - Doing a SWIPE_OPEN edge gesture which is handled in OnGestureEvent(). 632a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) if (reveal_state_ == CLOSED || reveal_state_ == SLIDING_CLOSED) 633f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) return; 634f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 635a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) // For the sake of simplicity, ignore |widget_|'s activation in computing 636a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) // whether the top-of-window views should stay revealed. Ideally, the 637a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) // top-of-window views would stay revealed only when the mouse cursor is 638a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) // hovered above a non-obscured portion of the top-of-window views. The 639a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) // top-of-window views may be partially obscured when |widget_| is inactive. 640f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 641f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // Ignore all events while a window has capture. This keeps the top-of-window 642f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // views revealed during a drag. 643f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (aura::client::GetCaptureWindow(native_window_)) 644f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) return; 645f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 646f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) gfx::Point location_in_screen; 647f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (event && event->type() != ui::ET_MOUSE_CAPTURE_CHANGED) { 648f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) location_in_screen = GetEventLocationInScreen(*event); 649f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } else { 650f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) aura::client::CursorClient* cursor_client = aura::client::GetCursorClient( 651f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) native_window_->GetRootWindow()); 652f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (!cursor_client->IsMouseEventsEnabled()) { 653f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // If mouse events are disabled, the user's last interaction was probably 654f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // via touch. Do no do further processing in this case as there is no easy 655f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // way of retrieving the position of the user's last touch. 656f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) return; 657f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } 658f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) location_in_screen = aura::Env::GetInstance()->last_mouse_location(); 659f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } 660f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 661f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if ((!event || event->IsMouseEvent()) && 662f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) ShouldIgnoreMouseEventAtLocation(location_in_screen)) { 663f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) return; 664f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } 665f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 666f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // The visible bounds of |top_container_| should be contained in 667f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // |hit_bounds_in_screen|. 668f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) std::vector<gfx::Rect> hit_bounds_in_screen = 669f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) delegate_->GetVisibleBoundsInScreen(); 670f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) bool keep_revealed = false; 671f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) for (size_t i = 0; i < hit_bounds_in_screen.size(); ++i) { 672f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // Allow the cursor to move slightly off the top-of-window views before 673f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // sliding closed. In the case of ImmersiveModeControllerAsh, this helps 674f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // when the user is attempting to click on the bookmark bar and overshoots 675f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // slightly. 676f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (event && event->type() == ui::ET_MOUSE_MOVED) { 677f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) const int kBoundsOffsetY = 8; 678f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) hit_bounds_in_screen[i].Inset(0, 0, 0, -kBoundsOffsetY); 679f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } 680f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 681f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (hit_bounds_in_screen[i].Contains(location_in_screen)) { 682f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) keep_revealed = true; 683f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) break; 684f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } 685f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } 686f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 687f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (keep_revealed) 688f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) AcquireLocatedEventRevealedLock(); 689f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) else 690f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) located_event_revealed_lock_.reset(); 691f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)} 692f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 693f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)void ImmersiveFullscreenController::AcquireLocatedEventRevealedLock() { 694f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // CAUTION: Acquiring the lock results in a reentrant call to 695f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // AcquireLocatedEventRevealedLock() when 696f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // |ImmersiveFullscreenController::animations_disabled_for_test_| is true. 697f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (!located_event_revealed_lock_.get()) 698f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) located_event_revealed_lock_.reset(GetRevealedLock(ANIMATE_REVEAL_YES)); 699f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)} 700f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 701f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)void ImmersiveFullscreenController::UpdateFocusRevealedLock() { 702f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (!enabled_) 703f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) return; 704f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 705f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) bool hold_lock = false; 706a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) if (widget_->IsActive()) { 707a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) views::View* focused_view = widget_->GetFocusManager()->GetFocusedView(); 708f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (top_container_->Contains(focused_view)) 709f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) hold_lock = true; 710f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } else { 711f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) aura::Window* active_window = aura::client::GetActivationClient( 712f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) native_window_->GetRootWindow())->GetActiveWindow(); 713f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) views::BubbleDelegateView* bubble_delegate = 714f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) AsBubbleDelegate(active_window); 715f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (bubble_delegate && bubble_delegate->anchor_widget()) { 716f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // BubbleManager will already have locked the top-of-window views if the 717f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // bubble is anchored to a child of |top_container_|. Don't acquire 718f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // |focus_revealed_lock_| here for the sake of simplicity. 719f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // Note: Instead of checking for the existence of the |anchor_view|, 720f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // the existence of the |anchor_widget| is performed to avoid the case 721f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // where the view is already gone (and the widget is still running). 722f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } else { 723f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // The currently active window is not |native_window_| and it is not a 724f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // bubble with an anchor view. The top-of-window views should be revealed 725f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // if: 726f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // 1) The active window is a transient child of |native_window_|. 727f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // 2) The top-of-window views are already revealed. This restriction 728f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // prevents a transient window opened by the web contents while the 729f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // top-of-window views are hidden from from initiating a reveal. 730f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // The top-of-window views will stay revealed till |native_window_| is 731f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // reactivated. 732f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (IsRevealed() && 733f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) IsWindowTransientChildOf(active_window, native_window_)) { 734f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) hold_lock = true; 735f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } 736f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } 737f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } 738f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 739f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (hold_lock) { 740f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (!focus_revealed_lock_.get()) 741f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) focus_revealed_lock_.reset(GetRevealedLock(ANIMATE_REVEAL_YES)); 742f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } else { 743f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) focus_revealed_lock_.reset(); 744f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } 745f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)} 746f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 747f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)bool ImmersiveFullscreenController::UpdateRevealedLocksForSwipe( 748f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) SwipeType swipe_type) { 749f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (!enabled_ || swipe_type == SWIPE_NONE) 750f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) return false; 751f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 752f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // Swipes while |native_window_| is inactive should have been filtered out in 753f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // OnGestureEvent(). 754a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) DCHECK(widget_->IsActive()); 755f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 756f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (reveal_state_ == SLIDING_CLOSED || reveal_state_ == CLOSED) { 757f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (swipe_type == SWIPE_OPEN && !located_event_revealed_lock_.get()) { 758f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) located_event_revealed_lock_.reset(GetRevealedLock(ANIMATE_REVEAL_YES)); 759f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) return true; 760f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } 761f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } else { 762f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (swipe_type == SWIPE_CLOSE) { 763f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // Attempt to end the reveal. If other code is holding onto a lock, the 764f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // attempt will be unsuccessful. 765f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) located_event_revealed_lock_.reset(); 766f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) focus_revealed_lock_.reset(); 767f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 768a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) if (reveal_state_ == SLIDING_CLOSED || reveal_state_ == CLOSED) { 769a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) widget_->GetFocusManager()->ClearFocus(); 770f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) return true; 771a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) } 772f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 773f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // Ending the reveal was unsuccessful. Reaquire the locks if appropriate. 774a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) UpdateLocatedEventRevealedLock(NULL); 775f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) UpdateFocusRevealedLock(); 776f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } 777f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } 778f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) return false; 779f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)} 780f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 781f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)int ImmersiveFullscreenController::GetAnimationDuration(Animate animate) const { 782f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) switch (animate) { 783f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) case ANIMATE_NO: 784f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) return 0; 785f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) case ANIMATE_SLOW: 786f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) return kRevealSlowAnimationDurationMs; 787f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) case ANIMATE_FAST: 788f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) return kRevealFastAnimationDurationMs; 789f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } 790f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) NOTREACHED(); 791f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) return 0; 792f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)} 793f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 794f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)void ImmersiveFullscreenController::MaybeStartReveal(Animate animate) { 795f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (!enabled_) 796f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) return; 797f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 798f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (animations_disabled_for_test_) 799f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) animate = ANIMATE_NO; 800f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 801f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // Callers with ANIMATE_NO expect this function to synchronously reveal the 802f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // top-of-window views. 803f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (reveal_state_ == REVEALED || 804f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) (reveal_state_ == SLIDING_OPEN && animate != ANIMATE_NO)) { 805f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) return; 806f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } 807f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 808f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) RevealState previous_reveal_state = reveal_state_; 809f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) reveal_state_ = SLIDING_OPEN; 810f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (previous_reveal_state == CLOSED) { 811f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) delegate_->OnImmersiveRevealStarted(); 812f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 813f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // Do not do any more processing if OnImmersiveRevealStarted() changed 814f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // |reveal_state_|. 815f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (reveal_state_ != SLIDING_OPEN) 816f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) return; 817f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } 818f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // Slide in the reveal view. 819f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (animate == ANIMATE_NO) { 820f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) animation_->Reset(1); 821f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) OnSlideOpenAnimationCompleted(); 822f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } else { 823f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) animation_->SetSlideDuration(GetAnimationDuration(animate)); 824f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) animation_->Show(); 825f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } 826f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)} 827f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 828f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)void ImmersiveFullscreenController::OnSlideOpenAnimationCompleted() { 829f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) DCHECK_EQ(SLIDING_OPEN, reveal_state_); 830f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) reveal_state_ = REVEALED; 831f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) delegate_->SetVisibleFraction(1); 832f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 833f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // The user may not have moved the mouse since the reveal was initiated. 834f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // Update the revealed lock to reflect the mouse's current state. 835a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) UpdateLocatedEventRevealedLock(NULL); 836f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)} 837f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 838f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)void ImmersiveFullscreenController::MaybeEndReveal(Animate animate) { 839f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (!enabled_ || revealed_lock_count_ != 0) 840f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) return; 841f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 842f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (animations_disabled_for_test_) 843f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) animate = ANIMATE_NO; 844f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 845f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // Callers with ANIMATE_NO expect this function to synchronously close the 846f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // top-of-window views. 847f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (reveal_state_ == CLOSED || 848f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) (reveal_state_ == SLIDING_CLOSED && animate != ANIMATE_NO)) { 849f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) return; 850f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } 851f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 852f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) reveal_state_ = SLIDING_CLOSED; 853f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) int duration_ms = GetAnimationDuration(animate); 854f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (duration_ms > 0) { 855f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) animation_->SetSlideDuration(duration_ms); 856f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) animation_->Hide(); 857f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } else { 858f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) animation_->Reset(0); 859f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) OnSlideClosedAnimationCompleted(); 860f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } 861f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)} 862f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 863f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)void ImmersiveFullscreenController::OnSlideClosedAnimationCompleted() { 864f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) DCHECK_EQ(SLIDING_CLOSED, reveal_state_); 865f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) reveal_state_ = CLOSED; 866f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) delegate_->OnImmersiveRevealEnded(); 867f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)} 868f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 869f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)ImmersiveFullscreenController::SwipeType 870f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)ImmersiveFullscreenController::GetSwipeType(ui::GestureEvent* event) const { 871a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch#if defined(OS_WIN) 872a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch if (event->type() == ui::ET_GESTURE_WIN8_EDGE_SWIPE) 873a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch return SWIPE_OPEN; 874a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch#endif 875f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (event->type() != ui::ET_GESTURE_SCROLL_UPDATE) 876f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) return SWIPE_NONE; 877f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // Make sure that it is a clear vertical gesture. 878cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (std::abs(event->details().scroll_y()) <= 879cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) kSwipeVerticalThresholdMultiplier * std::abs(event->details().scroll_x())) 880f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) return SWIPE_NONE; 881f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (event->details().scroll_y() < 0) 882f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) return SWIPE_CLOSE; 883f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) else if (event->details().scroll_y() > 0) 884f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) return SWIPE_OPEN; 885f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) return SWIPE_NONE; 886f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)} 887f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 888f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)bool ImmersiveFullscreenController::ShouldIgnoreMouseEventAtLocation( 889f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) const gfx::Point& location) const { 890f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // Ignore mouse events in the region immediately above the top edge of the 891f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // display. This is to handle the case of a user with a vertical display 892f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // layout (primary display above/below secondary display) and the immersive 893f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // fullscreen window on the bottom display. It is really hard to trigger a 894f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // reveal in this case because: 895f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // - It is hard to stop the cursor in the top |kMouseRevealBoundsHeight| 896f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // pixels of the bottom display. 897f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // - The cursor is warped to the top display if the cursor gets to the top 898f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // edge of the bottom display. 899f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // Mouse events are ignored in the bottom few pixels of the top display 900f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // (Mouse events in this region cannot start or end a reveal). This allows a 901f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // user to overshoot the top of the bottom display and still reveal the 902f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // top-of-window views. 903f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) gfx::Rect dead_region = GetDisplayBoundsInScreen(native_window_); 904f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) dead_region.set_y(dead_region.y() - kHeightOfDeadRegionAboveTopContainer); 905f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) dead_region.set_height(kHeightOfDeadRegionAboveTopContainer); 906f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) return dead_region.Contains(location); 907f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)} 908f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 909f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)bool ImmersiveFullscreenController::ShouldHandleGestureEvent( 910f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) const gfx::Point& location) const { 911a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) DCHECK(widget_->IsActive()); 912f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (reveal_state_ == REVEALED) { 913f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) std::vector<gfx::Rect> hit_bounds_in_screen( 914f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) delegate_->GetVisibleBoundsInScreen()); 915f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) for (size_t i = 0; i < hit_bounds_in_screen.size(); ++i) { 916f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (hit_bounds_in_screen[i].Contains(location)) 917f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) return true; 918f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } 919f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) return false; 920f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } 921f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 922f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // When the top-of-window views are not fully revealed, handle gestures which 923f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // start in the top few pixels of the screen. 924f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) gfx::Rect hit_bounds_in_screen(GetDisplayBoundsInScreen(native_window_)); 9255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) hit_bounds_in_screen.set_height(kImmersiveFullscreenTopEdgeInset); 926f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (hit_bounds_in_screen.Contains(location)) 927f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) return true; 928f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 929f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // There may be a bezel sensor off screen logically above 930f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // |hit_bounds_in_screen|. The check for the event not contained by the 931f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // closest screen ensures that the event is from a valid bezel (as opposed to 932f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // another screen in an extended desktop). 933f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) gfx::Rect screen_bounds = 934f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) Shell::GetScreen()->GetDisplayNearestPoint(location).bounds(); 935f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) return (!screen_bounds.Contains(location) && 936f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) location.y() < hit_bounds_in_screen.y() && 937f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) location.x() >= hit_bounds_in_screen.x() && 938f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) location.x() < hit_bounds_in_screen.right()); 939f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)} 940f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 941f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)void ImmersiveFullscreenController::RecreateBubbleManager() { 942f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) bubble_manager_.reset(new BubbleManager(this)); 943f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) const std::vector<aura::Window*> transient_children = 944a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) ::wm::GetTransientChildren(native_window_); 945f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) for (size_t i = 0; i < transient_children.size(); ++i) { 946f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) aura::Window* transient_child = transient_children[i]; 947f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) views::BubbleDelegateView* bubble_delegate = 948f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) AsBubbleDelegate(transient_child); 949f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (bubble_delegate && 950f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) bubble_delegate->GetAnchorView() && 951f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) top_container_->Contains(bubble_delegate->GetAnchorView())) { 952f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) bubble_manager_->StartObserving(transient_child); 953f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } 954f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } 955f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)} 956f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 957f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)} // namespace ash 958