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

Side by Side Diff: ash/wm/immersive_fullscreen_controller.cc

Issue 48963002: [Refactor] Move the non-browser specific logic of ImmersiveModeControllerAsh into ash part 2 (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 7 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright 2012 The Chromium Authors. All rights reserved. 1 // Copyright 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "chrome/browser/ui/views/frame/immersive_mode_controller_ash.h" 5 #include "ash/wm/immersive_fullscreen_controller.h"
6 6
7 #include <set> 7 #include <set>
8 #include <vector>
9 8
10 #include "ash/shell.h" 9 #include "ash/shell.h"
11 #include "ash/wm/window_state.h" 10 #include "ash/wm/window_state.h"
12 #include "chrome/browser/chrome_notification_types.h"
13 #include "chrome/browser/ui/fullscreen/fullscreen_controller.h"
14 #include "chrome/browser/ui/views/bookmarks/bookmark_bar_view.h"
15 #include "chrome/browser/ui/views/frame/top_container_view.h"
16 #include "content/public/browser/notification_service.h"
17 #include "content/public/browser/web_contents.h"
18 #include "content/public/browser/web_contents_view.h"
19 #include "ui/aura/client/activation_client.h" 11 #include "ui/aura/client/activation_client.h"
20 #include "ui/aura/client/aura_constants.h" 12 #include "ui/aura/client/aura_constants.h"
21 #include "ui/aura/client/capture_client.h" 13 #include "ui/aura/client/capture_client.h"
22 #include "ui/aura/client/cursor_client.h" 14 #include "ui/aura/client/cursor_client.h"
23 #include "ui/aura/client/screen_position_client.h" 15 #include "ui/aura/client/screen_position_client.h"
24 #include "ui/aura/env.h" 16 #include "ui/aura/env.h"
25 #include "ui/aura/root_window.h" 17 #include "ui/aura/root_window.h"
26 #include "ui/aura/window.h" 18 #include "ui/aura/window.h"
27 #include "ui/gfx/animation/slide_animation.h" 19 #include "ui/gfx/animation/slide_animation.h"
20 #include "ui/gfx/display.h"
21 #include "ui/gfx/point.h"
22 #include "ui/gfx/rect.h"
23 #include "ui/gfx/screen.h"
28 #include "ui/views/bubble/bubble_delegate.h" 24 #include "ui/views/bubble/bubble_delegate.h"
29 #include "ui/views/view.h" 25 #include "ui/views/view.h"
30 #include "ui/views/widget/widget.h" 26 #include "ui/views/widget/widget.h"
31 #include "ui/views/window/non_client_view.h"
32 27
33 using views::View; 28 using views::View;
34 29
30 namespace ash {
31
35 namespace { 32 namespace {
36 33
37 // The slide open/closed animation looks better if it starts and ends just a
38 // few pixels before the view goes completely off the screen, which reduces
39 // the visual "pop" as the 2-pixel tall immersive-style tabs become visible.
40 const int kAnimationOffsetY = 3;
41
42 // Duration for the reveal show/hide slide animation. The slower duration is 34 // Duration for the reveal show/hide slide animation. The slower duration is
43 // used for the initial slide out to give the user more change to see what 35 // used for the initial slide out to give the user more change to see what
44 // happened. 36 // happened.
45 const int kRevealSlowAnimationDurationMs = 400; 37 const int kRevealSlowAnimationDurationMs = 400;
46 const int kRevealFastAnimationDurationMs = 200; 38 const int kRevealFastAnimationDurationMs = 200;
47 39
48 // The delay in milliseconds between the mouse stopping at the top edge of the 40 // The delay in milliseconds between the mouse stopping at the top edge of the
49 // screen and the top-of-window views revealing. 41 // screen and the top-of-window views revealing.
50 const int kMouseRevealDelayMs = 200; 42 const int kMouseRevealDelayMs = 200;
51 43
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
105 // Returns the location of |event| in screen coordinates. 97 // Returns the location of |event| in screen coordinates.
106 gfx::Point GetEventLocationInScreen(const ui::LocatedEvent& event) { 98 gfx::Point GetEventLocationInScreen(const ui::LocatedEvent& event) {
107 gfx::Point location_in_screen = event.location(); 99 gfx::Point location_in_screen = event.location();
108 aura::Window* target = static_cast<aura::Window*>(event.target()); 100 aura::Window* target = static_cast<aura::Window*>(event.target());
109 aura::client::ScreenPositionClient* screen_position_client = 101 aura::client::ScreenPositionClient* screen_position_client =
110 aura::client::GetScreenPositionClient(target->GetRootWindow()); 102 aura::client::GetScreenPositionClient(target->GetRootWindow());
111 screen_position_client->ConvertPointToScreen(target, &location_in_screen); 103 screen_position_client->ConvertPointToScreen(target, &location_in_screen);
112 return location_in_screen; 104 return location_in_screen;
113 } 105 }
114 106
115 //////////////////////////////////////////////////////////////////////////////// 107 // Returns the bounds of the display nearest to |window| in screen coordinates.
116 108 gfx::Rect GetDisplayBoundsInScreen(aura::Window* window) {
117 class RevealedLockAsh : public ImmersiveRevealedLock { 109 return Shell::GetScreen()->GetDisplayNearestWindow(window).bounds();
118 public: 110 }
119 RevealedLockAsh(const base::WeakPtr<ImmersiveModeControllerAsh>& controller,
120 ImmersiveModeController::AnimateReveal animate_reveal)
121 : controller_(controller) {
122 DCHECK(controller_);
123 controller_->LockRevealedState(animate_reveal);
124 }
125
126 virtual ~RevealedLockAsh() {
127 if (controller_)
128 controller_->UnlockRevealedState();
129 }
130
131 private:
132 base::WeakPtr<ImmersiveModeControllerAsh> controller_;
133
134 DISALLOW_COPY_AND_ASSIGN(RevealedLockAsh);
135 };
136 111
137 } // namespace 112 } // namespace
138 113
139 //////////////////////////////////////////////////////////////////////////////// 114 ////////////////////////////////////////////////////////////////////////////////
140 115
141 // Class which keeps the top-of-window views revealed as long as one of the 116 // Class which keeps the top-of-window views revealed as long as one of the
142 // bubbles it is observing is visible. The logic to keep the top-of-window 117 // bubbles it is observing is visible. The logic to keep the top-of-window
143 // views revealed based on the visibility of bubbles anchored to 118 // views revealed based on the visibility of bubbles anchored to
144 // children of |ImmersiveModeController::top_container_| is separate from 119 // children of |ImmersiveFullscreenController::top_container_| is separate from
145 // the logic related to |ImmersiveModeControllerAsh::focus_revealed_lock_| 120 // the logic related to |ImmersiveFullscreenController::focus_revealed_lock_|
146 // so that bubbles which are not activatable and bubbles which do not close 121 // so that bubbles which are not activatable and bubbles which do not close
147 // upon deactivation also keep the top-of-window views revealed for the 122 // upon deactivation also keep the top-of-window views revealed for the
148 // duration of their visibility. 123 // duration of their visibility.
149 class ImmersiveModeControllerAsh::BubbleManager : public aura::WindowObserver { 124 class ImmersiveFullscreenController::BubbleManager
125 : public aura::WindowObserver {
150 public: 126 public:
151 explicit BubbleManager(ImmersiveModeControllerAsh* controller); 127 explicit BubbleManager(ImmersiveFullscreenController* controller);
152 virtual ~BubbleManager(); 128 virtual ~BubbleManager();
153 129
154 // Start / stop observing changes to |bubble|'s visibility. 130 // Start / stop observing changes to |bubble|'s visibility.
155 void StartObserving(aura::Window* bubble); 131 void StartObserving(aura::Window* bubble);
156 void StopObserving(aura::Window* bubble); 132 void StopObserving(aura::Window* bubble);
157 133
158 private: 134 private:
159 // Updates |revealed_lock_| based on whether any of |bubbles_| is visible. 135 // Updates |revealed_lock_| based on whether any of |bubbles_| is visible.
160 void UpdateRevealedLock(); 136 void UpdateRevealedLock();
161 137
162 // aura::WindowObserver overrides: 138 // aura::WindowObserver overrides:
163 virtual void OnWindowVisibilityChanged(aura::Window* window, 139 virtual void OnWindowVisibilityChanged(aura::Window* window,
164 bool visible) OVERRIDE; 140 bool visible) OVERRIDE;
165 virtual void OnWindowDestroying(aura::Window* window) OVERRIDE; 141 virtual void OnWindowDestroying(aura::Window* window) OVERRIDE;
166 142
167 ImmersiveModeControllerAsh* controller_; 143 ImmersiveFullscreenController* controller_;
168 144
169 std::set<aura::Window*> bubbles_; 145 std::set<aura::Window*> bubbles_;
170 146
171 // Lock which keeps the top-of-window views revealed based on whether any of 147 // Lock which keeps the top-of-window views revealed based on whether any of
172 // |bubbles_| is visible. 148 // |bubbles_| is visible.
173 scoped_ptr<ImmersiveRevealedLock> revealed_lock_; 149 scoped_ptr<ImmersiveRevealedLock> revealed_lock_;
174 150
175 DISALLOW_COPY_AND_ASSIGN(BubbleManager); 151 DISALLOW_COPY_AND_ASSIGN(BubbleManager);
176 }; 152 };
177 153
178 ImmersiveModeControllerAsh::BubbleManager::BubbleManager( 154 ImmersiveFullscreenController::BubbleManager::BubbleManager(
179 ImmersiveModeControllerAsh* controller) 155 ImmersiveFullscreenController* controller)
180 : controller_(controller) { 156 : controller_(controller) {
181 } 157 }
182 158
183 ImmersiveModeControllerAsh::BubbleManager::~BubbleManager() { 159 ImmersiveFullscreenController::BubbleManager::~BubbleManager() {
184 for (std::set<aura::Window*>::const_iterator it = bubbles_.begin(); 160 for (std::set<aura::Window*>::const_iterator it = bubbles_.begin();
185 it != bubbles_.end(); ++it) { 161 it != bubbles_.end(); ++it) {
186 (*it)->RemoveObserver(this); 162 (*it)->RemoveObserver(this);
187 } 163 }
188 } 164 }
189 165
190 void ImmersiveModeControllerAsh::BubbleManager::StartObserving( 166 void ImmersiveFullscreenController::BubbleManager::StartObserving(
191 aura::Window* bubble) { 167 aura::Window* bubble) {
192 if (bubbles_.insert(bubble).second) { 168 if (bubbles_.insert(bubble).second) {
193 bubble->AddObserver(this); 169 bubble->AddObserver(this);
194 UpdateRevealedLock(); 170 UpdateRevealedLock();
195 } 171 }
196 } 172 }
197 173
198 void ImmersiveModeControllerAsh::BubbleManager::StopObserving( 174 void ImmersiveFullscreenController::BubbleManager::StopObserving(
199 aura::Window* bubble) { 175 aura::Window* bubble) {
200 if (bubbles_.erase(bubble)) { 176 if (bubbles_.erase(bubble)) {
201 bubble->RemoveObserver(this); 177 bubble->RemoveObserver(this);
202 UpdateRevealedLock(); 178 UpdateRevealedLock();
203 } 179 }
204 } 180 }
205 181
206 void ImmersiveModeControllerAsh::BubbleManager::UpdateRevealedLock() { 182 void ImmersiveFullscreenController::BubbleManager::UpdateRevealedLock() {
207 bool has_visible_bubble = false; 183 bool has_visible_bubble = false;
208 for (std::set<aura::Window*>::const_iterator it = bubbles_.begin(); 184 for (std::set<aura::Window*>::const_iterator it = bubbles_.begin();
209 it != bubbles_.end(); ++it) { 185 it != bubbles_.end(); ++it) {
210 if ((*it)->IsVisible()) { 186 if ((*it)->IsVisible()) {
211 has_visible_bubble = true; 187 has_visible_bubble = true;
212 break; 188 break;
213 } 189 }
214 } 190 }
215 191
216 bool was_revealed = controller_->IsRevealed(); 192 bool was_revealed = controller_->IsRevealed();
217 if (has_visible_bubble) { 193 if (has_visible_bubble) {
218 if (!revealed_lock_.get()) { 194 if (!revealed_lock_.get()) {
219 // Reveal the top-of-window views without animating because it looks 195 // Reveal the top-of-window views without animating because it looks
220 // weird for the top-of-window views to animate and the bubble not to 196 // weird for the top-of-window views to animate and the bubble not to
221 // animate along with the top-of-window views. 197 // animate along with the top-of-window views.
222 revealed_lock_.reset(controller_->GetRevealedLock( 198 revealed_lock_.reset(controller_->GetRevealedLock(
223 ImmersiveModeController::ANIMATE_REVEAL_NO)); 199 ImmersiveFullscreenController::ANIMATE_REVEAL_NO));
224 } 200 }
225 } else { 201 } else {
226 revealed_lock_.reset(); 202 revealed_lock_.reset();
227 } 203 }
228 204
229 if (!was_revealed && revealed_lock_.get()) { 205 if (!was_revealed && revealed_lock_.get()) {
230 // Currently, there is no nice way for bubbles to reposition themselves 206 // Currently, there is no nice way for bubbles to reposition themselves
231 // whenever the anchor view moves. Tell the bubbles to reposition themselves 207 // whenever the anchor view moves. Tell the bubbles to reposition themselves
232 // explicitly instead. The hidden bubbles are also repositioned because 208 // explicitly instead. The hidden bubbles are also repositioned because
233 // BubbleDelegateView does not reposition its widget as a result of a 209 // BubbleDelegateView does not reposition its widget as a result of a
234 // visibility change. 210 // visibility change.
235 for (std::set<aura::Window*>::const_iterator it = bubbles_.begin(); 211 for (std::set<aura::Window*>::const_iterator it = bubbles_.begin();
236 it != bubbles_.end(); ++it) { 212 it != bubbles_.end(); ++it) {
237 AsBubbleDelegate(*it)->OnAnchorViewBoundsChanged(); 213 AsBubbleDelegate(*it)->OnAnchorViewBoundsChanged();
238 } 214 }
239 } 215 }
240 } 216 }
241 217
242 void ImmersiveModeControllerAsh::BubbleManager::OnWindowVisibilityChanged( 218 void ImmersiveFullscreenController::BubbleManager::OnWindowVisibilityChanged(
243 aura::Window*, 219 aura::Window*,
244 bool visible) { 220 bool visible) {
245 UpdateRevealedLock(); 221 UpdateRevealedLock();
246 } 222 }
247 223
248 void ImmersiveModeControllerAsh::BubbleManager::OnWindowDestroying( 224 void ImmersiveFullscreenController::BubbleManager::OnWindowDestroying(
249 aura::Window* window) { 225 aura::Window* window) {
250 StopObserving(window); 226 StopObserving(window);
251 } 227 }
252 228
253 //////////////////////////////////////////////////////////////////////////////// 229 ////////////////////////////////////////////////////////////////////////////////
254 230
255 ImmersiveModeControllerAsh::ImmersiveModeControllerAsh() 231 ImmersiveFullscreenController::ImmersiveFullscreenController()
256 : delegate_(NULL), 232 : delegate_(NULL),
233 top_container_(NULL),
257 widget_(NULL), 234 widget_(NULL),
258 top_container_(NULL), 235 native_window_(NULL),
259 observers_enabled_(false), 236 observers_enabled_(false),
260 enabled_(false), 237 enabled_(false),
261 reveal_state_(CLOSED), 238 reveal_state_(CLOSED),
262 revealed_lock_count_(0), 239 revealed_lock_count_(0),
263 tab_indicator_visibility_(TAB_INDICATORS_HIDE),
264 mouse_x_when_hit_top_in_screen_(-1), 240 mouse_x_when_hit_top_in_screen_(-1),
265 gesture_begun_(false), 241 gesture_begun_(false),
266 native_window_(NULL),
267 animation_(new gfx::SlideAnimation(this)), 242 animation_(new gfx::SlideAnimation(this)),
268 animations_disabled_for_test_(false), 243 animations_disabled_for_test_(false),
269 weak_ptr_factory_(this) { 244 weak_ptr_factory_(this) {
270 } 245 }
271 246
272 ImmersiveModeControllerAsh::~ImmersiveModeControllerAsh() { 247 ImmersiveFullscreenController::~ImmersiveFullscreenController() {
273 // The browser view is being destroyed so there's no need to update its
274 // layout or layers, even if the top views are revealed. But the window
275 // observers still need to be removed.
276 EnableWindowObservers(false); 248 EnableWindowObservers(false);
277 } 249 }
278 250
279 void ImmersiveModeControllerAsh::LockRevealedState( 251 void ImmersiveFullscreenController::Init(Delegate* delegate,
280 AnimateReveal animate_reveal) { 252 views::Widget* widget,
281 ++revealed_lock_count_; 253 views::View* top_container) {
282 Animate animate = (animate_reveal == ANIMATE_REVEAL_YES) ? 254 delegate_ = delegate;
283 ANIMATE_FAST : ANIMATE_NO; 255 top_container_ = top_container;
284 MaybeStartReveal(animate); 256 widget_ = widget;
257 native_window_ = widget_->GetNativeWindow();
285 } 258 }
286 259
287 void ImmersiveModeControllerAsh::UnlockRevealedState() { 260 void ImmersiveFullscreenController::SetEnabled(bool enabled) {
288 --revealed_lock_count_;
289 DCHECK_GE(revealed_lock_count_, 0);
290 if (revealed_lock_count_ == 0) {
291 // Always animate ending the reveal fast.
292 MaybeEndReveal(ANIMATE_FAST);
293 }
294 }
295
296 void ImmersiveModeControllerAsh::Init(
297 Delegate* delegate,
298 views::Widget* widget,
299 views::View* top_container) {
300 delegate_ = delegate;
301 widget_ = widget;
302 // Browser view is detached from its widget during destruction. Cache the
303 // window pointer so |this| can stop observing during destruction.
304 native_window_ = widget_->GetNativeWindow();
305 top_container_ = top_container;
306 }
307
308 void ImmersiveModeControllerAsh::SetEnabled(bool enabled) {
309 DCHECK(native_window_) << "Must initialize before enabling";
310 if (enabled_ == enabled) 261 if (enabled_ == enabled)
311 return; 262 return;
312 enabled_ = enabled; 263 enabled_ = enabled;
313 264
314 EnableWindowObservers(enabled_); 265 EnableWindowObservers(enabled_);
315 266
316 UpdateUseMinimalChrome(LAYOUT_NO); 267 // Auto hide the shelf in immersive fullscreen instead of hiding it.
268 wm::GetWindowState(native_window_)->set_hide_shelf_when_fullscreen(!enabled);
269 Shell::GetInstance()->UpdateShelfVisibility();
317 270
318 if (enabled_) { 271 if (enabled_) {
319 // Animate enabling immersive mode by sliding out the top-of-window views. 272 // Animate enabling immersive mode by sliding out the top-of-window views.
320 // No animation occurs if a lock is holding the top-of-window views open. 273 // No animation occurs if a lock is holding the top-of-window views open.
321 274
322 // Do a reveal to set the initial state for the animation. (And any 275 // Do a reveal to set the initial state for the animation. (And any
323 // required state in case the animation cannot run because of a lock holding 276 // required state in case the animation cannot run because of a lock holding
324 // the top-of-window views open.) This call has the side effect of relaying 277 // the top-of-window views open.)
325 // out |browser_view_|'s root view.
326 MaybeStartReveal(ANIMATE_NO); 278 MaybeStartReveal(ANIMATE_NO);
327 279
328 // Reset the located event and the focus revealed locks so that they do not 280 // Reset the located event and the focus revealed locks so that they do not
329 // affect whether the top-of-window views are hidden. 281 // affect whether the top-of-window views are hidden.
330 located_event_revealed_lock_.reset(); 282 located_event_revealed_lock_.reset();
331 focus_revealed_lock_.reset(); 283 focus_revealed_lock_.reset();
332 284
333 // Try doing the animation. 285 // Try doing the animation.
334 MaybeEndReveal(ANIMATE_SLOW); 286 MaybeEndReveal(ANIMATE_SLOW);
335 287
336 if (reveal_state_ == REVEALED) { 288 if (reveal_state_ == REVEALED) {
337 // Reveal was unsuccessful. Reacquire the revealed locks if appropriate. 289 // Reveal was unsuccessful. Reacquire the revealed locks if appropriate.
338 UpdateLocatedEventRevealedLock(NULL, ALLOW_REVEAL_WHILE_CLOSING_NO); 290 UpdateLocatedEventRevealedLock(NULL, ALLOW_REVEAL_WHILE_CLOSING_NO);
339 UpdateFocusRevealedLock(); 291 UpdateFocusRevealedLock();
340 } 292 }
341 } else { 293 } else {
342 // Stop cursor-at-top tracking. 294 // Stop cursor-at-top tracking.
343 top_edge_hover_timer_.Stop(); 295 top_edge_hover_timer_.Stop();
344 // Snap immediately to the closed state.
345 reveal_state_ = CLOSED; 296 reveal_state_ = CLOSED;
346 top_container_->SetPaintToLayer(false);
347 delegate_->SetImmersiveStyle(false);
348 SetRenderWindowTopInsetsForTouch(0);
349 297
350 // Layout the root view so that incognito avatar icon, if any, gets laid 298 delegate_->OnImmersiveFullscreenExited();
351 // out.
352 LayoutBrowserRootView();
353 } 299 }
354 } 300 }
355 301
356 bool ImmersiveModeControllerAsh::IsEnabled() const { 302 bool ImmersiveFullscreenController::IsEnabled() const {
357 return enabled_; 303 return enabled_;
358 } 304 }
359 305
360 bool ImmersiveModeControllerAsh::ShouldHideTabIndicators() const { 306 bool ImmersiveFullscreenController::IsRevealed() const {
361 return tab_indicator_visibility_ != TAB_INDICATORS_SHOW;
362 }
363
364 bool ImmersiveModeControllerAsh::ShouldHideTopViews() const {
365 return enabled_ && reveal_state_ == CLOSED;
366 }
367
368 bool ImmersiveModeControllerAsh::IsRevealed() const {
369 return enabled_ && reveal_state_ != CLOSED; 307 return enabled_ && reveal_state_ != CLOSED;
370 } 308 }
371 309
372 int ImmersiveModeControllerAsh::GetTopContainerVerticalOffset( 310 ImmersiveRevealedLock* ImmersiveFullscreenController::GetRevealedLock(
373 const gfx::Size& top_container_size) const { 311 AnimateReveal animate_reveal) {
374 if (!enabled_ || reveal_state_ == REVEALED || reveal_state_ == CLOSED) 312 return new ImmersiveRevealedLock(weak_ptr_factory_.GetWeakPtr(),
375 return 0; 313 animate_reveal);
376
377 return animation_->CurrentValueBetween(
378 -top_container_size.height() + kAnimationOffsetY, 0);
379 } 314 }
380 315
381 ImmersiveRevealedLock* ImmersiveModeControllerAsh::GetRevealedLock( 316 ////////////////////////////////////////////////////////////////////////////////
382 AnimateReveal animate_reveal) { 317 // Testing interface:
383 return new RevealedLockAsh(weak_ptr_factory_.GetWeakPtr(), animate_reveal);
384 }
385 318
386 void ImmersiveModeControllerAsh::OnFindBarVisibleBoundsChanged( 319 void ImmersiveFullscreenController::SetupForTest() {
387 const gfx::Rect& new_visible_bounds_in_screen) {
388 find_bar_visible_bounds_in_screen_ = new_visible_bounds_in_screen;
389 }
390
391 void ImmersiveModeControllerAsh::SetupForTest() {
392 DCHECK(!enabled_); 320 DCHECK(!enabled_);
393 animations_disabled_for_test_ = true; 321 animations_disabled_for_test_ = true;
394 322
395 // Move the mouse off of the top-of-window views so that it does not keep 323 // Move the mouse off of the top-of-window views so that it does not keep the
396 // the top-of-window views revealed. 324 // top-of-window views revealed.
397 gfx::Point cursor_pos(0, top_container_->bounds().bottom() + 100); 325 std::vector<gfx::Rect> bounds_in_screen(
398 views::View::ConvertPointToScreen(top_container_, &cursor_pos); 326 delegate_->GetVisibleBoundsInScreen());
327 DCHECK(!bounds_in_screen.empty());
328 int bottommost_in_screen = bounds_in_screen[0].bottom();
329 for (size_t i = 1; i < bounds_in_screen.size(); ++i) {
330 if (bounds_in_screen[i].bottom() > bottommost_in_screen)
331 bottommost_in_screen = bounds_in_screen[i].bottom();
332 }
333 gfx::Point cursor_pos(0, bottommost_in_screen + 100);
399 aura::Env::GetInstance()->set_last_mouse_location(cursor_pos); 334 aura::Env::GetInstance()->set_last_mouse_location(cursor_pos);
400 UpdateLocatedEventRevealedLock(NULL, ALLOW_REVEAL_WHILE_CLOSING_NO); 335 UpdateLocatedEventRevealedLock(NULL, ALLOW_REVEAL_WHILE_CLOSING_NO);
401 } 336 }
402 337
403 //////////////////////////////////////////////////////////////////////////////// 338 ////////////////////////////////////////////////////////////////////////////////
404 // Observers: 339 // ui::EventHandler overrides:
405 340
406 void ImmersiveModeControllerAsh::Observe( 341 void ImmersiveFullscreenController::OnMouseEvent(ui::MouseEvent* event) {
407 int type,
408 const content::NotificationSource& source,
409 const content::NotificationDetails& details) {
410 DCHECK_EQ(chrome::NOTIFICATION_FULLSCREEN_CHANGED, type);
411 if (enabled_)
412 UpdateUseMinimalChrome(LAYOUT_YES);
413 }
414
415 void ImmersiveModeControllerAsh::OnMouseEvent(ui::MouseEvent* event) {
416 if (!enabled_) 342 if (!enabled_)
417 return; 343 return;
418 344
419 if (event->type() != ui::ET_MOUSE_MOVED && 345 if (event->type() != ui::ET_MOUSE_MOVED &&
420 event->type() != ui::ET_MOUSE_PRESSED && 346 event->type() != ui::ET_MOUSE_PRESSED &&
421 event->type() != ui::ET_MOUSE_RELEASED && 347 event->type() != ui::ET_MOUSE_RELEASED &&
422 event->type() != ui::ET_MOUSE_CAPTURE_CHANGED) { 348 event->type() != ui::ET_MOUSE_CAPTURE_CHANGED) {
423 return; 349 return;
424 } 350 }
425 351
426 // Mouse hover should not initiate revealing the top-of-window views while 352 // Mouse hover should not initiate revealing the top-of-window views while
427 // |native_window_| is inactive. 353 // |native_window_| is inactive.
428 if (!views::Widget::GetWidgetForNativeWindow(native_window_)->IsActive()) 354 if (!views::Widget::GetWidgetForNativeWindow(native_window_)->IsActive())
429 return; 355 return;
430 356
431 // Mouse hover should not initiate revealing the top-of-window views while 357 // Mouse hover should not initiate revealing the top-of-window views while
432 // a window has mouse capture. 358 // a window has mouse capture.
433 if (aura::client::GetCaptureWindow(native_window_)) 359 if (aura::client::GetCaptureWindow(native_window_))
434 return; 360 return;
435 361
436 if (IsRevealed()) 362 if (IsRevealed())
437 UpdateLocatedEventRevealedLock(event, ALLOW_REVEAL_WHILE_CLOSING_NO); 363 UpdateLocatedEventRevealedLock(event, ALLOW_REVEAL_WHILE_CLOSING_NO);
438 364
439 // Trigger a reveal if the cursor pauses at the top of the screen for a 365 // Trigger a reveal if the cursor pauses at the top of the screen for a
440 // while. 366 // while.
441 if (event->type() != ui::ET_MOUSE_CAPTURE_CHANGED) 367 if (event->type() != ui::ET_MOUSE_CAPTURE_CHANGED)
442 UpdateTopEdgeHoverTimer(event); 368 UpdateTopEdgeHoverTimer(event);
443 } 369 }
444 370
445 void ImmersiveModeControllerAsh::OnTouchEvent(ui::TouchEvent* event) { 371 void ImmersiveFullscreenController::OnTouchEvent(ui::TouchEvent* event) {
446 if (!enabled_ || event->type() != ui::ET_TOUCH_PRESSED) 372 if (!enabled_ || event->type() != ui::ET_TOUCH_PRESSED)
447 return; 373 return;
448 374
449 UpdateLocatedEventRevealedLock(event, ALLOW_REVEAL_WHILE_CLOSING_NO); 375 UpdateLocatedEventRevealedLock(event, ALLOW_REVEAL_WHILE_CLOSING_NO);
450 } 376 }
451 377
452 void ImmersiveModeControllerAsh::OnGestureEvent(ui::GestureEvent* event) { 378 void ImmersiveFullscreenController::OnGestureEvent(ui::GestureEvent* event) {
453 if (!enabled_) 379 if (!enabled_)
454 return; 380 return;
455 381
456 // Touch gestures should not initiate revealing the top-of-window views while 382 // Touch gestures should not initiate revealing the top-of-window views while
457 // |native_window_| is inactive. 383 // |native_window_| is inactive.
458 if (!views::Widget::GetWidgetForNativeWindow(native_window_)->IsActive()) 384 if (!views::Widget::GetWidgetForNativeWindow(native_window_)->IsActive())
459 return; 385 return;
460 386
461 switch (event->type()) { 387 switch (event->type()) {
462 case ui::ET_GESTURE_SCROLL_BEGIN: 388 case ui::ET_GESTURE_SCROLL_BEGIN:
(...skipping 11 matching lines...) Expand all
474 break; 400 break;
475 case ui::ET_GESTURE_SCROLL_END: 401 case ui::ET_GESTURE_SCROLL_END:
476 case ui::ET_SCROLL_FLING_START: 402 case ui::ET_SCROLL_FLING_START:
477 gesture_begun_ = false; 403 gesture_begun_ = false;
478 break; 404 break;
479 default: 405 default:
480 break; 406 break;
481 } 407 }
482 } 408 }
483 409
484 void ImmersiveModeControllerAsh::OnWillChangeFocus(views::View* focused_before, 410 ////////////////////////////////////////////////////////////////////////////////
485 views::View* focused_now) { 411 // views::FocusChangeListener overrides:
412
413 void ImmersiveFullscreenController::OnWillChangeFocus(
414 views::View* focused_before,
415 views::View* focused_now) {
486 } 416 }
487 417
488 void ImmersiveModeControllerAsh::OnDidChangeFocus(views::View* focused_before, 418 void ImmersiveFullscreenController::OnDidChangeFocus(
489 views::View* focused_now) { 419 views::View* focused_before,
420 views::View* focused_now) {
490 UpdateFocusRevealedLock(); 421 UpdateFocusRevealedLock();
491 } 422 }
492 423
493 void ImmersiveModeControllerAsh::OnWidgetDestroying(views::Widget* widget) { 424 ////////////////////////////////////////////////////////////////////////////////
425 // views::WidgetObserver overrides:
426
427 void ImmersiveFullscreenController::OnWidgetDestroying(views::Widget* widget) {
494 EnableWindowObservers(false); 428 EnableWindowObservers(false);
495 native_window_ = NULL; 429 native_window_ = NULL;
496 430
497 // Set |enabled_| to false such that any calls to MaybeStartReveal() and 431 // Set |enabled_| to false such that any calls to MaybeStartReveal() and
498 // MaybeEndReveal() have no effect. 432 // MaybeEndReveal() have no effect.
499 enabled_ = false; 433 enabled_ = false;
500 } 434 }
501 435
502 void ImmersiveModeControllerAsh::OnWidgetActivationChanged( 436 void ImmersiveFullscreenController::OnWidgetActivationChanged(
503 views::Widget* widget, 437 views::Widget* widget,
504 bool active) { 438 bool active) {
505 // Mouse hover should not initiate revealing the top-of-window views while 439 // Mouse hover should not initiate revealing the top-of-window views while
506 // |native_window_| is inactive. 440 // |native_window_| is inactive.
507 top_edge_hover_timer_.Stop(); 441 top_edge_hover_timer_.Stop();
508 442
509 UpdateFocusRevealedLock(); 443 UpdateFocusRevealedLock();
510 444
511 // Allow the top-of-window views to stay revealed if all of the revealed locks 445 // Allow the top-of-window views to stay revealed if all of the revealed locks
512 // were released in the process of activating |widget| but the mouse is still 446 // were released in the process of activating |widget| but the mouse is still
513 // hovered above the top-of-window views. For instance, if the bubble which 447 // hovered above the top-of-window views. For instance, if the bubble which
514 // has been keeping the top-of-window views revealed is hidden but the mouse 448 // has been keeping the top-of-window views revealed is hidden but the mouse
515 // is hovered above the top-of-window views, the top-of-window views should 449 // is hovered above the top-of-window views, the top-of-window views should
516 // stay revealed. We cannot call UpdateLocatedEventRevealedLock() from 450 // stay revealed. We cannot call UpdateLocatedEventRevealedLock() from
517 // BubbleManager::UpdateRevealedLock() because |widget| is not yet active 451 // BubbleManager::UpdateRevealedLock() because |widget| is not yet active
518 // at that time. 452 // at that time.
519 UpdateLocatedEventRevealedLock(NULL, ALLOW_REVEAL_WHILE_CLOSING_YES); 453 UpdateLocatedEventRevealedLock(NULL, ALLOW_REVEAL_WHILE_CLOSING_YES);
520 } 454 }
521 455
522 //////////////////////////////////////////////////////////////////////////////// 456 ////////////////////////////////////////////////////////////////////////////////
523 // Animation delegate: 457 // gfx::AnimationDelegate overrides:
524 458
525 void ImmersiveModeControllerAsh::AnimationEnded( 459 void ImmersiveFullscreenController::AnimationEnded(
526 const gfx::Animation* animation) { 460 const gfx::Animation* animation) {
527 if (reveal_state_ == SLIDING_OPEN) { 461 if (reveal_state_ == SLIDING_OPEN) {
528 // AnimationProgressed() is called immediately before AnimationEnded() 462 OnSlideOpenAnimationCompleted();
529 // and does a layout.
530 OnSlideOpenAnimationCompleted(LAYOUT_NO);
531 } else if (reveal_state_ == SLIDING_CLOSED) { 463 } else if (reveal_state_ == SLIDING_CLOSED) {
532 OnSlideClosedAnimationCompleted(); 464 OnSlideClosedAnimationCompleted();
533 } 465 }
534 } 466 }
535 467
536 void ImmersiveModeControllerAsh::AnimationProgressed( 468 void ImmersiveFullscreenController::AnimationProgressed(
537 const gfx::Animation* animation) { 469 const gfx::Animation* animation) {
538 // Relayout. This will also move any views whose position depends on the 470 delegate_->SetVisibleFraction(animation->GetCurrentValue());
539 // top container position such as the find bar.
540 // We do not call LayoutBrowserRootView() here because we are not toggling
541 // the tab strip's immersive style so relaying out the non client view is not
542 // necessary.
543 top_container_->parent()->Layout();
544 } 471 }
545 472
546 //////////////////////////////////////////////////////////////////////////////// 473 ////////////////////////////////////////////////////////////////////////////////
547 // aura::WindowObserver overrides: 474 // aura::WindowObserver overrides:
548 475
549 void ImmersiveModeControllerAsh::OnWindowPropertyChanged(aura::Window* window, 476 void ImmersiveFullscreenController::OnAddTransientChild(aura::Window* window,
550 const void* key,
551 intptr_t old) {
552 if (!enabled_)
553 return;
554
555 if (key == aura::client::kShowStateKey) {
556 // Disable immersive mode when the user exits fullscreen without going
557 // through FullscreenController::ToggleFullscreenMode(). This is the case
558 // if the user exits fullscreen via the restore button.
559 ui::WindowShowState show_state = static_cast<ui::WindowShowState>(
560 native_window_->GetProperty(aura::client::kShowStateKey));
561 if (show_state != ui::SHOW_STATE_FULLSCREEN &&
562 show_state != ui::SHOW_STATE_MINIMIZED) {
563 delegate_->FullscreenStateChanged();
564 }
565 }
566 }
567
568 void ImmersiveModeControllerAsh::OnAddTransientChild(aura::Window* window,
569 aura::Window* transient) { 477 aura::Window* transient) {
570 views::BubbleDelegateView* bubble_delegate = AsBubbleDelegate(transient); 478 views::BubbleDelegateView* bubble_delegate = AsBubbleDelegate(transient);
571 if (bubble_delegate && 479 if (bubble_delegate &&
572 bubble_delegate->GetAnchorView() && 480 bubble_delegate->GetAnchorView() &&
573 top_container_->Contains(bubble_delegate->GetAnchorView())) { 481 top_container_->Contains(bubble_delegate->GetAnchorView())) {
574 // Observe the aura::Window because the BubbleDelegateView may not be 482 // Observe the aura::Window because the BubbleDelegateView may not be
575 // parented to the widget's root view yet so |bubble_delegate->GetWidget()| 483 // parented to the widget's root view yet so |bubble_delegate->GetWidget()|
576 // may still return NULL. 484 // may still return NULL.
577 bubble_manager_->StartObserving(transient); 485 bubble_manager_->StartObserving(transient);
578 } 486 }
579 } 487 }
580 488
581 void ImmersiveModeControllerAsh::OnRemoveTransientChild( 489 void ImmersiveFullscreenController::OnRemoveTransientChild(
582 aura::Window* window, 490 aura::Window* window,
583 aura::Window* transient) { 491 aura::Window* transient) {
584 bubble_manager_->StopObserving(transient); 492 bubble_manager_->StopObserving(transient);
585 } 493 }
586 494
587 //////////////////////////////////////////////////////////////////////////////// 495 ////////////////////////////////////////////////////////////////////////////////
496 // ash::ImmersiveRevealedLock::Delegate overrides:
497
498 void ImmersiveFullscreenController::LockRevealedState(
499 AnimateReveal animate_reveal) {
500 ++revealed_lock_count_;
501 Animate animate = (animate_reveal == ANIMATE_REVEAL_YES) ?
502 ANIMATE_FAST : ANIMATE_NO;
503 MaybeStartReveal(animate);
504 }
505
506 void ImmersiveFullscreenController::UnlockRevealedState() {
507 --revealed_lock_count_;
508 DCHECK_GE(revealed_lock_count_, 0);
509 if (revealed_lock_count_ == 0) {
510 // Always animate ending the reveal fast.
511 MaybeEndReveal(ANIMATE_FAST);
512 }
513 }
514
515 ////////////////////////////////////////////////////////////////////////////////
588 // private: 516 // private:
589 517
590 void ImmersiveModeControllerAsh::EnableWindowObservers(bool enable) { 518 void ImmersiveFullscreenController::EnableWindowObservers(bool enable) {
591 if (observers_enabled_ == enable) 519 if (observers_enabled_ == enable)
592 return; 520 return;
593 observers_enabled_ = enable; 521 observers_enabled_ = enable;
594 522
595 if (!native_window_) {
596 NOTREACHED() << "ImmersiveModeControllerAsh not initialized";
597 return;
598 }
599
600 views::Widget* widget = 523 views::Widget* widget =
601 views::Widget::GetWidgetForNativeWindow(native_window_); 524 views::Widget::GetWidgetForNativeWindow(native_window_);
602 views::FocusManager* focus_manager = widget->GetFocusManager(); 525 views::FocusManager* focus_manager = widget->GetFocusManager();
526
603 if (enable) { 527 if (enable) {
604 widget->AddObserver(this); 528 widget->AddObserver(this);
605 focus_manager->AddFocusChangeListener(this); 529 focus_manager->AddFocusChangeListener(this);
530 Shell::GetInstance()->AddPreTargetHandler(this);
531 native_window_->AddObserver(this);
532
533 RecreateBubbleManager();
606 } else { 534 } else {
607 widget->RemoveObserver(this); 535 widget->RemoveObserver(this);
608 focus_manager->RemoveFocusChangeListener(this); 536 focus_manager->RemoveFocusChangeListener(this);
609 } 537 Shell::GetInstance()->RemovePreTargetHandler(this);
538 native_window_->RemoveObserver(this);
610 539
611 if (enable)
612 ash::Shell::GetInstance()->AddPreTargetHandler(this);
613 else
614 ash::Shell::GetInstance()->RemovePreTargetHandler(this);
615
616 if (enable) {
617 native_window_->AddObserver(this);
618 } else {
619 native_window_->RemoveObserver(this);
620 }
621
622 if (enable) {
623 RecreateBubbleManager();
624 } else {
625 // We have stopped observing whether transient children are added or removed 540 // We have stopped observing whether transient children are added or removed
626 // to |native_window_|. The set of bubbles that BubbleManager is observing 541 // to |native_window_|. The set of bubbles that BubbleManager is observing
627 // will become stale really quickly. Destroy BubbleManager and recreate it 542 // will become stale really quickly. Destroy BubbleManager and recreate it
628 // when we start observing |native_window_| again. 543 // when we start observing |native_window_| again.
629 bubble_manager_.reset(); 544 bubble_manager_.reset();
545
546 animation_->Stop();
630 } 547 }
631
632 if (enable) {
633 registrar_.Add(
634 this,
635 chrome::NOTIFICATION_FULLSCREEN_CHANGED,
636 content::Source<FullscreenController>(
637 delegate_->GetFullscreenController()));
638 } else {
639 registrar_.Remove(
640 this,
641 chrome::NOTIFICATION_FULLSCREEN_CHANGED,
642 content::Source<FullscreenController>(
643 delegate_->GetFullscreenController()));
644 }
645
646 if (!enable)
647 animation_->Stop();
648 } 548 }
649 549
650 void ImmersiveModeControllerAsh::UpdateTopEdgeHoverTimer( 550 void ImmersiveFullscreenController::UpdateTopEdgeHoverTimer(
651 ui::MouseEvent* event) { 551 ui::MouseEvent* event) {
652 DCHECK(enabled_); 552 DCHECK(enabled_);
653 // Stop the timer if the top-of-window views are already revealed. 553 // Stop the timer if the top-of-window views are already revealed.
654 if (reveal_state_ == SLIDING_OPEN || reveal_state_ == REVEALED) { 554 if (reveal_state_ == SLIDING_OPEN || reveal_state_ == REVEALED) {
655 top_edge_hover_timer_.Stop(); 555 top_edge_hover_timer_.Stop();
656 return; 556 return;
657 } 557 }
658 558
659 gfx::Point location_in_screen = GetEventLocationInScreen(*event); 559 gfx::Point location_in_screen = GetEventLocationInScreen(*event);
660 if (ShouldIgnoreMouseEventAtLocation(location_in_screen)) 560 if (ShouldIgnoreMouseEventAtLocation(location_in_screen))
661 return; 561 return;
662 562
663 // Stop the timer if the cursor left the top edge or is on a different 563 // Stop the timer if the cursor left the top edge or is on a different
664 // display. The bounds of |top_container_|'s parent are used to infer the hit 564 // display.
665 // bounds because |top_container_| will be partially offscreen if it is 565 gfx::Rect hit_bounds_in_screen = GetDisplayBoundsInScreen(native_window_);
666 // animating closed.
667 gfx::Rect hit_bounds_in_screen =
668 top_container_->parent()->GetBoundsInScreen();
669 hit_bounds_in_screen.set_height(kMouseRevealBoundsHeight); 566 hit_bounds_in_screen.set_height(kMouseRevealBoundsHeight);
670 if (!hit_bounds_in_screen.Contains(location_in_screen)) { 567 if (!hit_bounds_in_screen.Contains(location_in_screen)) {
671 top_edge_hover_timer_.Stop(); 568 top_edge_hover_timer_.Stop();
672 return; 569 return;
673 } 570 }
674 571
675 // The cursor is now at the top of the screen. Consider the cursor "not 572 // The cursor is now at the top of the screen. Consider the cursor "not
676 // moving" even if it moves a little bit because users don't have perfect 573 // moving" even if it moves a little bit because users don't have perfect
677 // pointing precision. (The y position is not tested because 574 // pointing precision. (The y position is not tested because
678 // |hit_bounds_in_screen| is short.) 575 // |hit_bounds_in_screen| is short.)
679 if (top_edge_hover_timer_.IsRunning() && 576 if (top_edge_hover_timer_.IsRunning() &&
680 abs(location_in_screen.x() - mouse_x_when_hit_top_in_screen_) <= 577 abs(location_in_screen.x() - mouse_x_when_hit_top_in_screen_) <=
681 kMouseRevealXThresholdPixels) 578 kMouseRevealXThresholdPixels)
682 return; 579 return;
683 580
684 // Start the reveal if the cursor doesn't move for some amount of time. 581 // Start the reveal if the cursor doesn't move for some amount of time.
685 mouse_x_when_hit_top_in_screen_ = location_in_screen.x(); 582 mouse_x_when_hit_top_in_screen_ = location_in_screen.x();
686 top_edge_hover_timer_.Stop(); 583 top_edge_hover_timer_.Stop();
687 // Timer is stopped when |this| is destroyed, hence Unretained() is safe. 584 // Timer is stopped when |this| is destroyed, hence Unretained() is safe.
688 top_edge_hover_timer_.Start( 585 top_edge_hover_timer_.Start(
689 FROM_HERE, 586 FROM_HERE,
690 base::TimeDelta::FromMilliseconds(kMouseRevealDelayMs), 587 base::TimeDelta::FromMilliseconds(kMouseRevealDelayMs),
691 base::Bind(&ImmersiveModeControllerAsh::AcquireLocatedEventRevealedLock, 588 base::Bind(
692 base::Unretained(this))); 589 &ImmersiveFullscreenController::AcquireLocatedEventRevealedLock,
590 base::Unretained(this)));
693 } 591 }
694 592
695 void ImmersiveModeControllerAsh::UpdateLocatedEventRevealedLock( 593 void ImmersiveFullscreenController::UpdateLocatedEventRevealedLock(
696 ui::LocatedEvent* event, 594 ui::LocatedEvent* event,
697 AllowRevealWhileClosing allow_reveal_while_closing) { 595 AllowRevealWhileClosing allow_reveal_while_closing) {
698 if (!enabled_) 596 if (!enabled_)
699 return; 597 return;
700 DCHECK(!event || event->IsMouseEvent() || event->IsTouchEvent()); 598 DCHECK(!event || event->IsMouseEvent() || event->IsTouchEvent());
701 599
702 // Neither the mouse nor touch can initiate a reveal when the top-of-window 600 // Neither the mouse nor touch can initiate a reveal when the top-of-window
703 // views are sliding closed or are closed with the following exceptions: 601 // views are sliding closed or are closed with the following exceptions:
704 // - Hovering at y = 0 which is handled in OnMouseEvent(). 602 // - Hovering at y = 0 which is handled in OnMouseEvent().
705 // - Doing a SWIPE_OPEN edge gesture which is handled in OnGestureEvent(). 603 // - Doing a SWIPE_OPEN edge gesture which is handled in OnGestureEvent().
(...skipping 28 matching lines...) Expand all
734 return; 632 return;
735 } 633 }
736 location_in_screen = aura::Env::GetInstance()->last_mouse_location(); 634 location_in_screen = aura::Env::GetInstance()->last_mouse_location();
737 } 635 }
738 636
739 if ((!event || event->IsMouseEvent()) && 637 if ((!event || event->IsMouseEvent()) &&
740 ShouldIgnoreMouseEventAtLocation(location_in_screen)) { 638 ShouldIgnoreMouseEventAtLocation(location_in_screen)) {
741 return; 639 return;
742 } 640 }
743 641
744 gfx::Rect hit_bounds_in_top_container = top_container_->GetVisibleBounds(); 642 // The visible bounds of |top_container_| should be contained in
745 // TODO(tdanderson): Implement View::ConvertRectToScreen(); 643 // |hit_bounds_in_screen|.
746 gfx::Point hit_bounds_in_screen_origin = hit_bounds_in_top_container.origin(); 644 std::vector<gfx::Rect> hit_bounds_in_screen =
747 views::View::ConvertPointToScreen(top_container_, 645 delegate_->GetVisibleBoundsInScreen();
748 &hit_bounds_in_screen_origin); 646 bool keep_revealed = false;
749 gfx::Rect hit_bounds_in_screen(hit_bounds_in_screen_origin, 647 for (size_t i = 0; i < hit_bounds_in_screen.size(); ++i) {
750 hit_bounds_in_top_container.size()); 648 // Allow the cursor to move slightly off the top-of-window views before
649 // sliding closed. In the case of ImmersiveModeControllerAsh, this helps
650 // when the user is attempting to click on the bookmark bar and overshoots
651 // slightly.
652 if (event && event->type() == ui::ET_MOUSE_MOVED) {
653 const int kBoundsOffsetY = 8;
654 hit_bounds_in_screen[i].Inset(0, 0, 0, -kBoundsOffsetY);
655 }
751 656
752 gfx::Rect find_bar_hit_bounds_in_screen = find_bar_visible_bounds_in_screen_; 657 if (hit_bounds_in_screen[i].Contains(location_in_screen)) {
753 658 keep_revealed = true;
754 // Allow the cursor to move slightly off the top-of-window views before 659 break;
755 // sliding closed. This helps when the user is attempting to click on the 660 }
756 // bookmark bar and overshoots slightly.
757 if (event && event->type() == ui::ET_MOUSE_MOVED) {
758 const int kBoundsOffsetY = 8;
759 hit_bounds_in_screen.Inset(0, 0, 0, -kBoundsOffsetY);
760 find_bar_hit_bounds_in_screen.Inset(0, 0, 0, -kBoundsOffsetY);
761 } 661 }
762 662
763 if (hit_bounds_in_screen.Contains(location_in_screen) || 663 if (keep_revealed)
764 find_bar_hit_bounds_in_screen.Contains(location_in_screen)) {
765 AcquireLocatedEventRevealedLock(); 664 AcquireLocatedEventRevealedLock();
766 } else { 665 else
767 located_event_revealed_lock_.reset(); 666 located_event_revealed_lock_.reset();
768 }
769 } 667 }
770 668
771 void ImmersiveModeControllerAsh::AcquireLocatedEventRevealedLock() { 669 void ImmersiveFullscreenController::AcquireLocatedEventRevealedLock() {
772 // CAUTION: Acquiring the lock results in a reentrant call to 670 // CAUTION: Acquiring the lock results in a reentrant call to
773 // AcquireLocatedEventRevealedLock() when 671 // AcquireLocatedEventRevealedLock() when
774 // |ImmersiveModeControllerAsh::animations_disabled_for_test_| is true. 672 // |ImmersiveFullscreenController::animations_disabled_for_test_| is true.
775 if (!located_event_revealed_lock_.get()) 673 if (!located_event_revealed_lock_.get())
776 located_event_revealed_lock_.reset(GetRevealedLock(ANIMATE_REVEAL_YES)); 674 located_event_revealed_lock_.reset(GetRevealedLock(ANIMATE_REVEAL_YES));
777 } 675 }
778 676
779 void ImmersiveModeControllerAsh::UpdateFocusRevealedLock() { 677 void ImmersiveFullscreenController::UpdateFocusRevealedLock() {
780 if (!enabled_) 678 if (!enabled_)
781 return; 679 return;
782 680
783 bool hold_lock = false; 681 bool hold_lock = false;
784 views::Widget* widget = 682 views::Widget* widget =
785 views::Widget::GetWidgetForNativeWindow(native_window_); 683 views::Widget::GetWidgetForNativeWindow(native_window_);
786 if (widget->IsActive()) { 684 if (widget->IsActive()) {
787 views::View* focused_view = widget->GetFocusManager()->GetFocusedView(); 685 views::View* focused_view = widget->GetFocusManager()->GetFocusedView();
788 if (top_container_->Contains(focused_view)) 686 if (top_container_->Contains(focused_view))
789 hold_lock = true; 687 hold_lock = true;
(...skipping 27 matching lines...) Expand all
817 } 715 }
818 716
819 if (hold_lock) { 717 if (hold_lock) {
820 if (!focus_revealed_lock_.get()) 718 if (!focus_revealed_lock_.get())
821 focus_revealed_lock_.reset(GetRevealedLock(ANIMATE_REVEAL_YES)); 719 focus_revealed_lock_.reset(GetRevealedLock(ANIMATE_REVEAL_YES));
822 } else { 720 } else {
823 focus_revealed_lock_.reset(); 721 focus_revealed_lock_.reset();
824 } 722 }
825 } 723 }
826 724
827 bool ImmersiveModeControllerAsh::UpdateRevealedLocksForSwipe( 725 bool ImmersiveFullscreenController::UpdateRevealedLocksForSwipe(
828 SwipeType swipe_type) { 726 SwipeType swipe_type) {
829 if (!enabled_ || swipe_type == SWIPE_NONE) 727 if (!enabled_ || swipe_type == SWIPE_NONE)
830 return false; 728 return false;
831 729
832 // Swipes while |native_window_| is inactive should have been filtered out in 730 // Swipes while |native_window_| is inactive should have been filtered out in
833 // OnGestureEvent(). 731 // OnGestureEvent().
834 DCHECK(views::Widget::GetWidgetForNativeWindow(native_window_)->IsActive()); 732 DCHECK(views::Widget::GetWidgetForNativeWindow(native_window_)->IsActive());
835 733
836 if (reveal_state_ == SLIDING_CLOSED || reveal_state_ == CLOSED) { 734 if (reveal_state_ == SLIDING_CLOSED || reveal_state_ == CLOSED) {
837 if (swipe_type == SWIPE_OPEN && !located_event_revealed_lock_.get()) { 735 if (swipe_type == SWIPE_OPEN && !located_event_revealed_lock_.get()) {
(...skipping 11 matching lines...) Expand all
849 return true; 747 return true;
850 748
851 // Ending the reveal was unsuccessful. Reaquire the locks if appropriate. 749 // Ending the reveal was unsuccessful. Reaquire the locks if appropriate.
852 UpdateLocatedEventRevealedLock(NULL, ALLOW_REVEAL_WHILE_CLOSING_NO); 750 UpdateLocatedEventRevealedLock(NULL, ALLOW_REVEAL_WHILE_CLOSING_NO);
853 UpdateFocusRevealedLock(); 751 UpdateFocusRevealedLock();
854 } 752 }
855 } 753 }
856 return false; 754 return false;
857 } 755 }
858 756
859 void ImmersiveModeControllerAsh::UpdateUseMinimalChrome(Layout layout) { 757 int ImmersiveFullscreenController::GetAnimationDuration(Animate animate) const {
860 // May be NULL in tests.
861 FullscreenController* fullscreen_controller =
862 delegate_->GetFullscreenController();
863 bool in_tab_fullscreen = fullscreen_controller ?
864 fullscreen_controller->IsFullscreenForTabOrPending() : false;
865 bool use_minimal_chrome = !in_tab_fullscreen && enabled_;
866
867 // When using minimal chrome, the shelf is auto-hidden. The auto-hidden shelf
868 // displays a 3px 'light bar' when it is closed. Otherwise, the shelf is
869 // hidden completely and cannot be revealed.
870 ash::wm::GetWindowState(native_window_)->set_hide_shelf_when_fullscreen(
871 !use_minimal_chrome);
872
873 TabIndicatorVisibility previous_tab_indicator_visibility =
874 tab_indicator_visibility_;
875 if (tab_indicator_visibility_ != TAB_INDICATORS_FORCE_HIDE) {
876 tab_indicator_visibility_ = use_minimal_chrome ?
877 TAB_INDICATORS_SHOW : TAB_INDICATORS_HIDE;
878 }
879
880 ash::Shell::GetInstance()->UpdateShelfVisibility();
881
882 if (tab_indicator_visibility_ != previous_tab_indicator_visibility) {
883 // If the top-of-window views are revealed or animating, the change will
884 // take effect with the layout once the top-of-window views are closed.
885 if (layout == LAYOUT_YES && reveal_state_ == CLOSED)
886 LayoutBrowserRootView();
887 }
888 }
889
890 int ImmersiveModeControllerAsh::GetAnimationDuration(Animate animate) const {
891 switch (animate) { 758 switch (animate) {
892 case ANIMATE_NO: 759 case ANIMATE_NO:
893 return 0; 760 return 0;
894 case ANIMATE_SLOW: 761 case ANIMATE_SLOW:
895 return kRevealSlowAnimationDurationMs; 762 return kRevealSlowAnimationDurationMs;
896 case ANIMATE_FAST: 763 case ANIMATE_FAST:
897 return kRevealFastAnimationDurationMs; 764 return kRevealFastAnimationDurationMs;
898 } 765 }
899 NOTREACHED(); 766 NOTREACHED();
900 return 0; 767 return 0;
901 } 768 }
902 769
903 void ImmersiveModeControllerAsh::MaybeStartReveal(Animate animate) { 770 void ImmersiveFullscreenController::MaybeStartReveal(Animate animate) {
904 if (!enabled_) 771 if (!enabled_)
905 return; 772 return;
906 773
907 if (animations_disabled_for_test_) 774 if (animations_disabled_for_test_)
908 animate = ANIMATE_NO; 775 animate = ANIMATE_NO;
909 776
910 // Callers with ANIMATE_NO expect this function to synchronously reveal the 777 // Callers with ANIMATE_NO expect this function to synchronously reveal the
911 // top-of-window views. 778 // top-of-window views.
912 if (reveal_state_ == REVEALED || 779 if (reveal_state_ == REVEALED ||
913 (reveal_state_ == SLIDING_OPEN && animate != ANIMATE_NO)) { 780 (reveal_state_ == SLIDING_OPEN && animate != ANIMATE_NO)) {
914 return; 781 return;
915 } 782 }
916 783
917 RevealState previous_reveal_state = reveal_state_; 784 RevealState previous_reveal_state = reveal_state_;
918 reveal_state_ = SLIDING_OPEN; 785 reveal_state_ = SLIDING_OPEN;
919 if (previous_reveal_state == CLOSED) { 786 if (previous_reveal_state == CLOSED) {
920 // Turn on layer painting so that we can overlap the web contents. 787 delegate_->OnImmersiveRevealStarted();
921 top_container_->SetPaintToLayer(true);
922 788
923 // Ensure window caption buttons are updated and the view bounds are 789 // Do not do any more processing if OnImmersiveRevealStarted() changed
924 // computed at normal (non-immersive-style) size. The layout call moves the
925 // top-of-window views to their initial offscreen position for the
926 // animation.
927 delegate_->SetImmersiveStyle(false);
928 SetRenderWindowTopInsetsForTouch(0);
929 LayoutBrowserRootView();
930
931 // Do not do any more processing if LayoutBrowserView() changed
932 // |reveal_state_|. 790 // |reveal_state_|.
933 if (reveal_state_ != SLIDING_OPEN) { 791 if (reveal_state_ != SLIDING_OPEN)
934 if (reveal_state_ == REVEALED)
935 FOR_EACH_OBSERVER(Observer, observers_, OnImmersiveRevealStarted());
936 return; 792 return;
937 }
938 } 793 }
939 // Slide in the reveal view. 794 // Slide in the reveal view.
940 if (animate == ANIMATE_NO) { 795 if (animate == ANIMATE_NO) {
941 animation_->Reset(1); 796 animation_->Reset(1);
942 OnSlideOpenAnimationCompleted(LAYOUT_YES); 797 OnSlideOpenAnimationCompleted();
943 } else { 798 } else {
944 animation_->SetSlideDuration(GetAnimationDuration(animate)); 799 animation_->SetSlideDuration(GetAnimationDuration(animate));
945 animation_->Show(); 800 animation_->Show();
946 } 801 }
947
948 if (previous_reveal_state == CLOSED)
949 FOR_EACH_OBSERVER(Observer, observers_, OnImmersiveRevealStarted());
950 } 802 }
951 803
952 void ImmersiveModeControllerAsh::LayoutBrowserRootView() { 804 void ImmersiveFullscreenController::OnSlideOpenAnimationCompleted() {
953 // Update the window caption buttons.
954 widget_->non_client_view()->frame_view()->ResetWindowControls();
955 // Layout all views, including BrowserView.
956 widget_->GetRootView()->Layout();
957 }
958
959 void ImmersiveModeControllerAsh::OnSlideOpenAnimationCompleted(Layout layout) {
960 DCHECK_EQ(SLIDING_OPEN, reveal_state_); 805 DCHECK_EQ(SLIDING_OPEN, reveal_state_);
961 reveal_state_ = REVEALED; 806 reveal_state_ = REVEALED;
962 807 delegate_->SetVisibleFraction(1);
963 if (layout == LAYOUT_YES)
964 top_container_->parent()->Layout();
965 808
966 // The user may not have moved the mouse since the reveal was initiated. 809 // The user may not have moved the mouse since the reveal was initiated.
967 // Update the revealed lock to reflect the mouse's current state. 810 // Update the revealed lock to reflect the mouse's current state.
968 UpdateLocatedEventRevealedLock(NULL, ALLOW_REVEAL_WHILE_CLOSING_NO); 811 UpdateLocatedEventRevealedLock(NULL, ALLOW_REVEAL_WHILE_CLOSING_NO);
969 } 812 }
970 813
971 void ImmersiveModeControllerAsh::MaybeEndReveal(Animate animate) { 814 void ImmersiveFullscreenController::MaybeEndReveal(Animate animate) {
972 if (!enabled_ || revealed_lock_count_ != 0) 815 if (!enabled_ || revealed_lock_count_ != 0)
973 return; 816 return;
974 817
975 if (animations_disabled_for_test_) 818 if (animations_disabled_for_test_)
976 animate = ANIMATE_NO; 819 animate = ANIMATE_NO;
977 820
978 // Callers with ANIMATE_NO expect this function to synchronously close the 821 // Callers with ANIMATE_NO expect this function to synchronously close the
979 // top-of-window views. 822 // top-of-window views.
980 if (reveal_state_ == CLOSED || 823 if (reveal_state_ == CLOSED ||
981 (reveal_state_ == SLIDING_CLOSED && animate != ANIMATE_NO)) { 824 (reveal_state_ == SLIDING_CLOSED && animate != ANIMATE_NO)) {
982 return; 825 return;
983 } 826 }
984 827
985 reveal_state_ = SLIDING_CLOSED; 828 reveal_state_ = SLIDING_CLOSED;
986 int duration_ms = GetAnimationDuration(animate); 829 int duration_ms = GetAnimationDuration(animate);
987 if (duration_ms > 0) { 830 if (duration_ms > 0) {
988 animation_->SetSlideDuration(duration_ms); 831 animation_->SetSlideDuration(duration_ms);
989 animation_->Hide(); 832 animation_->Hide();
990 } else { 833 } else {
991 animation_->Reset(0); 834 animation_->Reset(0);
992 OnSlideClosedAnimationCompleted(); 835 OnSlideClosedAnimationCompleted();
993 } 836 }
994 } 837 }
995 838
996 void ImmersiveModeControllerAsh::OnSlideClosedAnimationCompleted() { 839 void ImmersiveFullscreenController::OnSlideClosedAnimationCompleted() {
997 DCHECK_EQ(SLIDING_CLOSED, reveal_state_); 840 DCHECK_EQ(SLIDING_CLOSED, reveal_state_);
998 reveal_state_ = CLOSED; 841 reveal_state_ = CLOSED;
999 // Layers aren't needed after animation completes. 842 delegate_->OnImmersiveRevealEnded();
1000 top_container_->SetPaintToLayer(false);
1001 // Update tabstrip for closed state.
1002 delegate_->SetImmersiveStyle(true);
1003 SetRenderWindowTopInsetsForTouch(kNearTopContainerDistance);
1004 LayoutBrowserRootView();
1005 } 843 }
1006 844
1007 ImmersiveModeControllerAsh::SwipeType ImmersiveModeControllerAsh::GetSwipeType( 845 ImmersiveFullscreenController::SwipeType
1008 ui::GestureEvent* event) const { 846 ImmersiveFullscreenController::GetSwipeType(ui::GestureEvent* event) const {
1009 if (event->type() != ui::ET_GESTURE_SCROLL_UPDATE) 847 if (event->type() != ui::ET_GESTURE_SCROLL_UPDATE)
1010 return SWIPE_NONE; 848 return SWIPE_NONE;
1011 // Make sure that it is a clear vertical gesture. 849 // Make sure that it is a clear vertical gesture.
1012 if (abs(event->details().scroll_y()) <= 850 if (abs(event->details().scroll_y()) <=
1013 kSwipeVerticalThresholdMultiplier * abs(event->details().scroll_x())) 851 kSwipeVerticalThresholdMultiplier * abs(event->details().scroll_x()))
1014 return SWIPE_NONE; 852 return SWIPE_NONE;
1015 if (event->details().scroll_y() < 0) 853 if (event->details().scroll_y() < 0)
1016 return SWIPE_CLOSE; 854 return SWIPE_CLOSE;
1017 else if (event->details().scroll_y() > 0) 855 else if (event->details().scroll_y() > 0)
1018 return SWIPE_OPEN; 856 return SWIPE_OPEN;
1019 return SWIPE_NONE; 857 return SWIPE_NONE;
1020 } 858 }
1021 859
1022 bool ImmersiveModeControllerAsh::ShouldIgnoreMouseEventAtLocation( 860 bool ImmersiveFullscreenController::ShouldIgnoreMouseEventAtLocation(
1023 const gfx::Point& location) const { 861 const gfx::Point& location) const {
1024 // Ignore mouse events in the region immediately above the top edge of the 862 // Ignore mouse events in the region immediately above the top edge of the
1025 // display. This is to handle the case of a user with a vertical display 863 // display. This is to handle the case of a user with a vertical display
1026 // layout (primary display above/below secondary display) and the immersive 864 // layout (primary display above/below secondary display) and the immersive
1027 // fullscreen window on the bottom display. It is really hard to trigger a 865 // fullscreen window on the bottom display. It is really hard to trigger a
1028 // reveal in this case because: 866 // reveal in this case because:
1029 // - It is hard to stop the cursor in the top |kMouseRevealBoundsHeight| 867 // - It is hard to stop the cursor in the top |kMouseRevealBoundsHeight|
1030 // pixels of the bottom display. 868 // pixels of the bottom display.
1031 // - The cursor is warped to the top display if the cursor gets to the top 869 // - The cursor is warped to the top display if the cursor gets to the top
1032 // edge of the bottom display. 870 // edge of the bottom display.
1033 // Mouse events are ignored in the bottom few pixels of the top display 871 // Mouse events are ignored in the bottom few pixels of the top display
1034 // (Mouse events in this region cannot start or end a reveal). This allows a 872 // (Mouse events in this region cannot start or end a reveal). This allows a
1035 // user to overshoot the top of the bottom display and still reveal the 873 // user to overshoot the top of the bottom display and still reveal the
1036 // top-of-window views. 874 // top-of-window views.
1037 gfx::Rect dead_region = top_container_->parent()->GetBoundsInScreen(); 875 gfx::Rect dead_region = GetDisplayBoundsInScreen(native_window_);
1038 dead_region.set_y(dead_region.y() - kHeightOfDeadRegionAboveTopContainer); 876 dead_region.set_y(dead_region.y() - kHeightOfDeadRegionAboveTopContainer);
1039 dead_region.set_height(kHeightOfDeadRegionAboveTopContainer); 877 dead_region.set_height(kHeightOfDeadRegionAboveTopContainer);
1040 return dead_region.Contains(location); 878 return dead_region.Contains(location);
1041 } 879 }
1042 880
1043 bool ImmersiveModeControllerAsh::ShouldHandleGestureEvent( 881 bool ImmersiveFullscreenController::ShouldHandleGestureEvent(
1044 const gfx::Point& location) const { 882 const gfx::Point& location) const {
1045 gfx::Rect top_container_bounds_in_screen = 883 if (reveal_state_ == REVEALED) {
1046 top_container_->GetBoundsInScreen(); 884 std::vector<gfx::Rect> hit_bounds_in_screen(
885 delegate_->GetVisibleBoundsInScreen());
886 for (size_t i = 0; i < hit_bounds_in_screen.size(); ++i) {
887 if (hit_bounds_in_screen[i].Contains(location))
888 return true;
889 }
890 return false;
891 }
1047 892
1048 // All of the gestures that are of interest start in a region with left & 893 // When the top-of-window views are not fully revealed, handle gestures which
1049 // right edges agreeing with |top_container_|. When CLOSED it is difficult to 894 // start in the top few pixels of the screen.
1050 // hit the bounds due to small size of the tab strip, so the hit target needs 895 gfx::Rect hit_bounds_in_screen(GetDisplayBoundsInScreen(native_window_));
1051 // to be extended on the bottom, thus the inset call. 896 hit_bounds_in_screen.set_height(kNearTopContainerDistance);
1052 gfx::Rect near_bounds = top_container_bounds_in_screen; 897 if (hit_bounds_in_screen.Contains(location))
1053 if (reveal_state_ == CLOSED)
1054 near_bounds.Inset(gfx::Insets(0, 0, -kNearTopContainerDistance, 0));
1055 if (near_bounds.Contains(location))
1056 return true; 898 return true;
1057 899
1058 // There may be a bezel sensor off screen logically above |top_container_| 900 // There may be a bezel sensor off screen logically above
1059 // thus the test needs to include gestures starting above, but this needs to 901 // |hit_bounds_in_screen|. The check for the event not contained by the
1060 // be distinguished from events originating on another screen from 902 // closest screen ensures that the event is from a valid bezel (as opposed to
1061 // (potentially) an extended desktop. The check for the event not contained by 903 // another screen in an extended desktop).
1062 // the closest screen ensures that the event is from a valid bezel and can be
1063 // interpreted as such.
1064 gfx::Rect screen_bounds = 904 gfx::Rect screen_bounds =
1065 ash::Shell::GetScreen()->GetDisplayNearestPoint(location).bounds(); 905 Shell::GetScreen()->GetDisplayNearestPoint(location).bounds();
1066 return (!screen_bounds.Contains(location) && 906 return (!screen_bounds.Contains(location) &&
1067 location.y() < top_container_bounds_in_screen.y() && 907 location.y() < hit_bounds_in_screen.y() &&
1068 location.x() >= top_container_bounds_in_screen.x() && 908 location.x() >= hit_bounds_in_screen.x() &&
1069 location.x() < top_container_bounds_in_screen.right()); 909 location.x() < hit_bounds_in_screen.right());
1070 } 910 }
1071 911
1072 void ImmersiveModeControllerAsh::SetRenderWindowTopInsetsForTouch( 912 void ImmersiveFullscreenController::RecreateBubbleManager() {
1073 int top_inset) {
1074 content::WebContents* contents = delegate_->GetWebContents();
1075 if (contents) {
1076 aura::Window* window = contents->GetView()->GetContentNativeView();
1077 // |window| is NULL if the renderer crashed.
1078 if (window) {
1079 gfx::Insets inset(top_inset, 0, 0, 0);
1080 window->SetHitTestBoundsOverrideOuter(
1081 window->hit_test_bounds_override_outer_mouse(),
1082 inset);
1083 }
1084 }
1085 }
1086
1087 void ImmersiveModeControllerAsh::RecreateBubbleManager() {
1088 bubble_manager_.reset(new BubbleManager(this)); 913 bubble_manager_.reset(new BubbleManager(this));
1089 const std::vector<aura::Window*> transient_children = 914 const std::vector<aura::Window*> transient_children =
1090 native_window_->transient_children(); 915 native_window_->transient_children();
1091 for (size_t i = 0; i < transient_children.size(); ++i) { 916 for (size_t i = 0; i < transient_children.size(); ++i) {
1092 aura::Window* transient_child = transient_children[i]; 917 aura::Window* transient_child = transient_children[i];
1093 views::BubbleDelegateView* bubble_delegate = 918 views::BubbleDelegateView* bubble_delegate =
1094 AsBubbleDelegate(transient_child); 919 AsBubbleDelegate(transient_child);
1095 if (bubble_delegate && 920 if (bubble_delegate &&
1096 bubble_delegate->GetAnchorView() && 921 bubble_delegate->GetAnchorView() &&
1097 top_container_->Contains(bubble_delegate->GetAnchorView())) { 922 top_container_->Contains(bubble_delegate->GetAnchorView())) {
1098 bubble_manager_->StartObserving(transient_child); 923 bubble_manager_->StartObserving(transient_child);
1099 } 924 }
1100 } 925 }
1101 } 926 }
927
928 } // namespace ash
OLDNEW
« no previous file with comments | « ash/wm/immersive_fullscreen_controller.h ('k') | ash/wm/immersive_fullscreen_controller_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698