1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
|
// Copyright 2013 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef ASH_WM_IMMERSIVE_FULLSCREEN_CONTROLLER_H_
#define ASH_WM_IMMERSIVE_FULLSCREEN_CONTROLLER_H_
#include <vector>
#include "ash/ash_export.h"
#include "ash/wm/immersive_revealed_lock.h"
#include "base/timer/timer.h"
#include "ui/aura/window_observer.h"
#include "ui/events/event_handler.h"
#include "ui/gfx/animation/animation_delegate.h"
#include "ui/views/focus/focus_manager.h"
#include "ui/views/widget/widget_observer.h"
#include "ui/wm/core/transient_window_observer.h"
namespace aura {
class Window;
}
namespace gfx {
class Point;
class Rect;
class SlideAnimation;
}
namespace ui {
class LocatedEvent;
}
namespace views {
class View;
class Widget;
}
namespace ash {
class ASH_EXPORT ImmersiveFullscreenController
: public gfx::AnimationDelegate,
public ui::EventHandler,
public views::corewm::TransientWindowObserver,
public views::FocusChangeListener,
public views::WidgetObserver,
public ImmersiveRevealedLock::Delegate {
public:
// The enum is used for an enumerated histogram. New items should be only
// added to the end.
enum WindowType {
WINDOW_TYPE_OTHER,
WINDOW_TYPE_BROWSER,
WINDOW_TYPE_HOSTED_APP,
WINDOW_TYPE_PACKAGED_APP,
WINDOW_TYPE_COUNT
};
class Delegate {
public:
// Called when a reveal of the top-of-window views starts.
virtual void OnImmersiveRevealStarted() = 0;
// Called when the top-of-window views have finished closing. This call
// implies a visible fraction of 0. SetVisibleFraction(0) may not be called
// prior to OnImmersiveRevealEnded().
virtual void OnImmersiveRevealEnded() = 0;
// Called as a result of disabling immersive fullscreen via SetEnabled().
virtual void OnImmersiveFullscreenExited() = 0;
// Called to update the fraction of the top-of-window views height which is
// visible.
virtual void SetVisibleFraction(double visible_fraction) = 0;
// Returns a list of rects whose union makes up the top-of-window views.
// The returned list is used for hittesting when the top-of-window views
// are revealed. GetVisibleBoundsInScreen() must return a valid value when
// not in immersive fullscreen for the sake of SetupForTest().
virtual std::vector<gfx::Rect> GetVisibleBoundsInScreen() const = 0;
protected:
virtual ~Delegate() {}
};
ImmersiveFullscreenController();
virtual ~ImmersiveFullscreenController();
// Initializes the controller. Must be called prior to enabling immersive
// fullscreen via SetEnabled(). |top_container| is used to keep the
// top-of-window views revealed when a child of |top_container| has focus.
// |top_container| does not affect which mouse and touch events keep the
// top-of-window views revealed.
void Init(Delegate* delegate,
views::Widget* widget,
views::View* top_container);
// Enables or disables immersive fullscreen.
// |window_type| is the type of window which is put in immersive fullscreen.
// It is only used for histogramming.
void SetEnabled(WindowType window_type, bool enable);
// Returns true if |native_window_| is in immersive fullscreen.
bool IsEnabled() const;
// Returns true if |native_window_| is in immersive fullscreen and the
// top-of-window views are fully or partially visible.
bool IsRevealed() const;
// Returns a lock which will keep the top-of-window views revealed for its
// lifetime. Several locks can be obtained. When all of the locks are
// destroyed, if immersive fullscreen is enabled and there is nothing else
// keeping the top-of-window views revealed, the top-of-window views will be
// closed. This method always returns a valid lock regardless of whether
// immersive fullscreen is enabled. The lock's lifetime can span immersive
// fullscreen being enabled / disabled. If acquiring the lock causes a reveal,
// the top-of-window views will animate according to |animate_reveal|. The
// caller takes ownership of the returned lock.
ImmersiveRevealedLock* GetRevealedLock(
AnimateReveal animate_reveal) WARN_UNUSED_RESULT;
// Disables animations and moves the mouse so that it is not over the
// top-of-window views for the sake of testing.
void SetupForTest();
// ui::EventHandler overrides:
virtual void OnMouseEvent(ui::MouseEvent* event) OVERRIDE;
virtual void OnTouchEvent(ui::TouchEvent* event) OVERRIDE;
virtual void OnGestureEvent(ui::GestureEvent* event) OVERRIDE;
// views::FocusChangeObserver overrides:
virtual void OnWillChangeFocus(views::View* focused_before,
views::View* focused_now) OVERRIDE;
virtual void OnDidChangeFocus(views::View* focused_before,
views::View* focused_now) OVERRIDE;
// views::WidgetObserver overrides:
virtual void OnWidgetDestroying(views::Widget* widget) OVERRIDE;
virtual void OnWidgetActivationChanged(views::Widget* widget,
bool active) OVERRIDE;
// gfx::AnimationDelegate overrides:
virtual void AnimationEnded(const gfx::Animation* animation) OVERRIDE;
virtual void AnimationProgressed(const gfx::Animation* animation) OVERRIDE;
// views::corewm::TransientWindowObserver overrides:
virtual void OnTransientChildAdded(aura::Window* window,
aura::Window* transient) OVERRIDE;
virtual void OnTransientChildRemoved(aura::Window* window,
aura::Window* transient) OVERRIDE;
// ash::ImmersiveRevealedLock::Delegate overrides:
virtual void LockRevealedState(AnimateReveal animate_reveal) OVERRIDE;
virtual void UnlockRevealedState() OVERRIDE;
private:
friend class ImmersiveFullscreenControllerTest;
enum Animate {
ANIMATE_NO,
ANIMATE_SLOW,
ANIMATE_FAST,
};
enum RevealState {
CLOSED,
SLIDING_OPEN,
REVEALED,
SLIDING_CLOSED,
};
enum SwipeType {
SWIPE_OPEN,
SWIPE_CLOSE,
SWIPE_NONE
};
// Enables or disables observers for mouse, touch, focus, and activation.
void EnableWindowObservers(bool enable);
// Updates |top_edge_hover_timer_| based on a mouse |event|. If the mouse is
// hovered at the top of the screen the timer is started. If the mouse moves
// away from the top edge, or moves too much in the x direction, the timer is
// stopped.
void UpdateTopEdgeHoverTimer(ui::MouseEvent* event);
// Updates |located_event_revealed_lock_| based on the current mouse state and
// the current touch state.
// |event| is NULL if the source event is not known.
void UpdateLocatedEventRevealedLock(ui::LocatedEvent* event);
// Acquires |located_event_revealed_lock_| if it is not already held.
void AcquireLocatedEventRevealedLock();
// Updates |focus_revealed_lock_| based on the currently active view and the
// currently active widget.
void UpdateFocusRevealedLock();
// Update |located_event_revealed_lock_| and |focus_revealed_lock_| as a
// result of a gesture of |swipe_type|. Returns true if any locks were
// acquired or released.
bool UpdateRevealedLocksForSwipe(SwipeType swipe_type);
// Returns the animation duration given |animate|.
int GetAnimationDuration(Animate animate) const;
// Temporarily reveals the top-of-window views while in immersive mode,
// hiding them when the cursor exits the area of the top views. If |animate|
// is not ANIMATE_NO, slides in the view, otherwise shows it immediately.
void MaybeStartReveal(Animate animate);
// Called when the animation to slide open the top-of-window views has
// completed.
void OnSlideOpenAnimationCompleted();
// Hides the top-of-window views if immersive mode is enabled and nothing is
// keeping them revealed. Optionally animates.
void MaybeEndReveal(Animate animate);
// Called when the animation to slide out the top-of-window views has
// completed.
void OnSlideClosedAnimationCompleted();
// Returns the type of swipe given |event|.
SwipeType GetSwipeType(ui::GestureEvent* event) const;
// Returns true if a mouse event at |location_in_screen| should be ignored.
// Ignored mouse events should not contribute to revealing or unrevealing the
// top-of-window views.
bool ShouldIgnoreMouseEventAtLocation(
const gfx::Point& location_in_screen) const;
// True when |location| is "near" to the top container. When the top container
// is not closed "near" means within the displayed bounds or above it. When
// the top container is closed "near" means either within the displayed
// bounds, above it, or within a few pixels below it. This allow the container
// to steal enough pixels to detect a swipe in and handles the case that there
// is a bezel sensor above the top container.
bool ShouldHandleGestureEvent(const gfx::Point& location) const;
// Recreate |bubble_manager_| and start observing any bubbles anchored to a
// child of |top_container_|.
void RecreateBubbleManager();
// Not owned.
Delegate* delegate_;
views::View* top_container_;
views::Widget* widget_;
aura::Window* native_window_;
// True if the observers have been enabled.
bool observers_enabled_;
// True when in immersive fullscreen.
bool enabled_;
// State machine for the revealed/closed animations.
RevealState reveal_state_;
int revealed_lock_count_;
// Timer to track cursor being held at the top edge of the screen.
base::OneShotTimer<ImmersiveFullscreenController> top_edge_hover_timer_;
// The cursor x position in screen coordinates when the cursor first hit the
// top edge of the screen.
int mouse_x_when_hit_top_in_screen_;
// Tracks if the controller has seen a ET_GESTURE_SCROLL_BEGIN, without the
// following events.
bool gesture_begun_;
// Lock which keeps the top-of-window views revealed based on the current
// mouse state and the current touch state. Acquiring the lock is used to
// trigger a reveal when the user moves the mouse to the top of the screen
// and when the user does a SWIPE_OPEN edge gesture.
scoped_ptr<ImmersiveRevealedLock> located_event_revealed_lock_;
// Lock which keeps the top-of-window views revealed based on the focused view
// and the active widget. Acquiring the lock never triggers a reveal because
// a view is not focusable till a reveal has made it visible.
scoped_ptr<ImmersiveRevealedLock> focus_revealed_lock_;
// The animation which controls sliding the top-of-window views in and out.
scoped_ptr<gfx::SlideAnimation> animation_;
// Whether the animations are disabled for testing.
bool animations_disabled_for_test_;
// Manages bubbles which are anchored to a child of |top_container_|.
class BubbleManager;
scoped_ptr<BubbleManager> bubble_manager_;
base::WeakPtrFactory<ImmersiveFullscreenController> weak_ptr_factory_;
DISALLOW_COPY_AND_ASSIGN(ImmersiveFullscreenController);
};
} // namespace ash
#endif // ASH_WM_IMMERSIVE_FULLSCREEN_CONTROLLER_H_
|