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

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