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

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

Issue 2265563002: Shuffles around immersive related classes (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@immersive_pure_virtual
Patch Set: move comment Created 4 years, 4 months 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
OLDNEW
(Empty)
1 // Copyright 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "ash/wm/immersive_fullscreen_controller.h"
6
7 #include <set>
8
9 #include "ash/common/ash_constants.h"
10 #include "ash/common/wm/immersive/wm_immersive_fullscreen_controller_delegate.h"
11 #include "ash/shared/immersive_context.h"
12 #include "ash/shared/immersive_focus_watcher.h"
13 #include "ash/shared/immersive_gesture_handler.h"
14 #include "ash/wm/immersive_handler_factory.h"
15 #include "base/metrics/histogram.h"
16 #include "ui/display/display.h"
17 #include "ui/display/screen.h"
18 #include "ui/events/base_event_utils.h"
19 #include "ui/gfx/animation/slide_animation.h"
20 #include "ui/gfx/geometry/point.h"
21 #include "ui/gfx/geometry/rect.h"
22 #include "ui/views/bubble/bubble_dialog_delegate.h"
23 #include "ui/views/view.h"
24 #include "ui/views/widget/widget.h"
25
26 namespace ash {
27
28 namespace {
29
30 // Duration for the reveal show/hide slide animation. The slower duration is
31 // used for the initial slide out to give the user more change to see what
32 // happened.
33 const int kRevealSlowAnimationDurationMs = 400;
34 const int kRevealFastAnimationDurationMs = 200;
35
36 // The delay in milliseconds between the mouse stopping at the top edge of the
37 // screen and the top-of-window views revealing.
38 const int kMouseRevealDelayMs = 200;
39
40 // The maximum amount of pixels that the cursor can move for the cursor to be
41 // considered "stopped". This allows the user to reveal the top-of-window views
42 // without holding the cursor completely still.
43 const int kMouseRevealXThresholdPixels = 3;
44
45 // Used to multiply x value of an update in check to determine if gesture is
46 // vertical. This is used to make sure that gesture is close to vertical instead
47 // of just more vertical then horizontal.
48 const int kSwipeVerticalThresholdMultiplier = 3;
49
50 // The height in pixels of the region above the top edge of the display which
51 // hosts the immersive fullscreen window in which mouse events are ignored
52 // (cannot reveal or unreveal the top-of-window views).
53 // See ShouldIgnoreMouseEventAtLocation() for more details.
54 const int kHeightOfDeadRegionAboveTopContainer = 10;
55
56 } // namespace
57
58 // The height in pixels of the region below the top edge of the display in which
59 // the mouse can trigger revealing the top-of-window views.
60 // The height must be greater than 1px because the top pixel is used to trigger
61 // moving the cursor between displays if the user has a vertical display layout
62 // (primary display above/below secondary display).
63 const int ImmersiveFullscreenController::kMouseRevealBoundsHeight = 3;
64
65 ////////////////////////////////////////////////////////////////////////////////
66
67 ImmersiveFullscreenController::ImmersiveFullscreenController()
68 : delegate_(NULL),
69 top_container_(NULL),
70 widget_(NULL),
71 observers_enabled_(false),
72 enabled_(false),
73 reveal_state_(CLOSED),
74 revealed_lock_count_(0),
75 mouse_x_when_hit_top_in_screen_(-1),
76 gesture_begun_(false),
77 animation_(new gfx::SlideAnimation(this)),
78 animations_disabled_for_test_(false),
79 weak_ptr_factory_(this) {}
80
81 ImmersiveFullscreenController::~ImmersiveFullscreenController() {
82 EnableWindowObservers(false);
83 }
84
85 void ImmersiveFullscreenController::Init(
86 WmImmersiveFullscreenControllerDelegate* delegate,
87 views::Widget* widget,
88 views::View* top_container) {
89 delegate_ = delegate;
90 top_container_ = top_container;
91 widget_ = widget;
92 ImmersiveContext::Get()->InstallResizeHandleWindowTargeter(this);
93 }
94
95 void ImmersiveFullscreenController::SetEnabled(WindowType window_type,
96 bool enabled) {
97 if (enabled_ == enabled)
98 return;
99 enabled_ = enabled;
100
101 EnableWindowObservers(enabled_);
102
103 ImmersiveContext::Get()->OnEnteringOrExitingImmersive(this, enabled);
104
105 if (enabled_) {
106 // Animate enabling immersive mode by sliding out the top-of-window views.
107 // No animation occurs if a lock is holding the top-of-window views open.
108
109 // Do a reveal to set the initial state for the animation. (And any
110 // required state in case the animation cannot run because of a lock holding
111 // the top-of-window views open.)
112 MaybeStartReveal(ANIMATE_NO);
113
114 // Reset the located event so that it does not affect whether the
115 // top-of-window views are hidden.
116 located_event_revealed_lock_.reset();
117
118 // Try doing the animation.
119 MaybeEndReveal(ANIMATE_SLOW);
120
121 if (reveal_state_ == REVEALED) {
122 // Reveal was unsuccessful. Reacquire the revealed locks if appropriate.
123 UpdateLocatedEventRevealedLock();
124 if (immersive_focus_watcher_)
125 immersive_focus_watcher_->UpdateFocusRevealedLock();
126 }
127 } else {
128 // Stop cursor-at-top tracking.
129 top_edge_hover_timer_.Stop();
130 reveal_state_ = CLOSED;
131
132 delegate_->OnImmersiveFullscreenExited();
133 }
134
135 if (enabled_) {
136 UMA_HISTOGRAM_ENUMERATION("Ash.ImmersiveFullscreen.WindowType", window_type,
137 WINDOW_TYPE_COUNT);
138 }
139 }
140
141 bool ImmersiveFullscreenController::IsEnabled() const {
142 return enabled_;
143 }
144
145 bool ImmersiveFullscreenController::IsRevealed() const {
146 return enabled_ && reveal_state_ != CLOSED;
147 }
148
149 ImmersiveRevealedLock* ImmersiveFullscreenController::GetRevealedLock(
150 AnimateReveal animate_reveal) {
151 return new ImmersiveRevealedLock(weak_ptr_factory_.GetWeakPtr(),
152 animate_reveal);
153 }
154
155 ////////////////////////////////////////////////////////////////////////////////
156
157 void ImmersiveFullscreenController::OnMouseEvent(
158 const ui::MouseEvent& event,
159 const gfx::Point& location_in_screen,
160 views::Widget* target) {
161 if (!enabled_)
162 return;
163
164 if (event.type() != ui::ET_MOUSE_MOVED &&
165 event.type() != ui::ET_MOUSE_PRESSED &&
166 event.type() != ui::ET_MOUSE_RELEASED &&
167 event.type() != ui::ET_MOUSE_CAPTURE_CHANGED) {
168 return;
169 }
170
171 // Mouse hover can initiate revealing the top-of-window views while |widget_|
172 // is inactive.
173
174 if (reveal_state_ == SLIDING_OPEN || reveal_state_ == REVEALED) {
175 top_edge_hover_timer_.Stop();
176 UpdateLocatedEventRevealedLock(&event, location_in_screen);
177 } else if (event.type() != ui::ET_MOUSE_CAPTURE_CHANGED) {
178 // Trigger a reveal if the cursor pauses at the top of the screen for a
179 // while.
180 UpdateTopEdgeHoverTimer(event, location_in_screen, target);
181 }
182 }
183
184 void ImmersiveFullscreenController::OnTouchEvent(
185 const ui::TouchEvent& event,
186 const gfx::Point& location_in_screen) {
187 if (!enabled_ || event.type() != ui::ET_TOUCH_PRESSED)
188 return;
189
190 // Touch should not initiate revealing the top-of-window views while |widget_|
191 // is inactive.
192 if (!widget_->IsActive())
193 return;
194
195 UpdateLocatedEventRevealedLock(&event, location_in_screen);
196 }
197
198 void ImmersiveFullscreenController::OnGestureEvent(
199 ui::GestureEvent* event,
200 const gfx::Point& location_in_screen) {
201 if (!enabled_)
202 return;
203
204 // Touch gestures should not initiate revealing the top-of-window views while
205 // |widget_| is inactive.
206 if (!widget_->IsActive())
207 return;
208
209 switch (event->type()) {
210 case ui::ET_GESTURE_SCROLL_BEGIN:
211 if (ShouldHandleGestureEvent(location_in_screen)) {
212 gesture_begun_ = true;
213 // Do not consume the event. Otherwise, we end up consuming all
214 // ui::ET_GESTURE_SCROLL_BEGIN events in the top-of-window views
215 // when the top-of-window views are revealed.
216 }
217 break;
218 case ui::ET_GESTURE_SCROLL_UPDATE:
219 if (gesture_begun_) {
220 if (UpdateRevealedLocksForSwipe(GetSwipeType(*event)))
221 event->SetHandled();
222 gesture_begun_ = false;
223 }
224 break;
225 case ui::ET_GESTURE_SCROLL_END:
226 case ui::ET_SCROLL_FLING_START:
227 gesture_begun_ = false;
228 break;
229 default:
230 break;
231 }
232 }
233
234 void ImmersiveFullscreenController::OnPointerEventObserved(
235 const ui::PointerEvent& event,
236 const gfx::Point& location_in_screen,
237 views::Widget* target) {
238 if (event.IsMousePointerEvent()) {
239 const ui::MouseEvent mouse_event(event);
240 OnMouseEvent(mouse_event, location_in_screen, target);
241 } else {
242 DCHECK(event.IsTouchPointerEvent());
243 const ui::TouchEvent touch_event(event);
244 OnTouchEvent(touch_event, location_in_screen);
245 }
246 }
247
248 void ImmersiveFullscreenController::OnMouseCaptureChanged() {
249 const ui::MouseEvent event(ui::ET_MOUSE_CAPTURE_CHANGED, gfx::Point(),
250 gfx::Point(), ui::EventTimeForNow(), 0, 0);
251 OnMouseEvent(event, display::Screen::GetScreen()->GetCursorScreenPoint(),
252 nullptr);
253 }
254
255 ////////////////////////////////////////////////////////////////////////////////
256 // views::WidgetObserver overrides:
257
258 void ImmersiveFullscreenController::OnWidgetDestroying(views::Widget* widget) {
259 EnableWindowObservers(false);
260 widget_window_ = nullptr;
261
262 // Set |enabled_| to false such that any calls to MaybeStartReveal() and
263 // MaybeEndReveal() have no effect.
264 enabled_ = false;
265 }
266
267 ////////////////////////////////////////////////////////////////////////////////
268 // gfx::AnimationDelegate overrides:
269
270 void ImmersiveFullscreenController::AnimationEnded(
271 const gfx::Animation* animation) {
272 if (reveal_state_ == SLIDING_OPEN) {
273 OnSlideOpenAnimationCompleted();
274 } else if (reveal_state_ == SLIDING_CLOSED) {
275 OnSlideClosedAnimationCompleted();
276 }
277 }
278
279 void ImmersiveFullscreenController::AnimationProgressed(
280 const gfx::Animation* animation) {
281 delegate_->SetVisibleFraction(animation->GetCurrentValue());
282 }
283
284 ////////////////////////////////////////////////////////////////////////////////
285 // ImmersiveRevealedLock::Delegate overrides:
286
287 void ImmersiveFullscreenController::LockRevealedState(
288 AnimateReveal animate_reveal) {
289 ++revealed_lock_count_;
290 Animate animate =
291 (animate_reveal == ANIMATE_REVEAL_YES) ? ANIMATE_FAST : ANIMATE_NO;
292 MaybeStartReveal(animate);
293 }
294
295 void ImmersiveFullscreenController::UnlockRevealedState() {
296 --revealed_lock_count_;
297 DCHECK_GE(revealed_lock_count_, 0);
298 if (revealed_lock_count_ == 0) {
299 // Always animate ending the reveal fast.
300 MaybeEndReveal(ANIMATE_FAST);
301 }
302 }
303
304 ////////////////////////////////////////////////////////////////////////////////
305 // private:
306
307 void ImmersiveFullscreenController::EnableWindowObservers(bool enable) {
308 if (observers_enabled_ == enable)
309 return;
310 observers_enabled_ = enable;
311
312 if (enable) {
313 immersive_focus_watcher_ =
314 ImmersiveHandlerFactory::Get()->CreateFocusWatcher(this);
315 immersive_gesture_handler_ =
316 ImmersiveHandlerFactory::Get()->CreateGestureHandler(this);
317 widget_->AddObserver(this);
318 const bool wants_moves = true;
319 ImmersiveContext::Get()->AddPointerWatcher(this, wants_moves);
320 } else {
321 ImmersiveContext::Get()->RemovePointerWatcher(this);
322 widget_->RemoveObserver(this);
323 immersive_gesture_handler_.reset();
324 immersive_focus_watcher_.reset();
325
326 animation_->Stop();
327 }
328 }
329
330 void ImmersiveFullscreenController::UpdateTopEdgeHoverTimer(
331 const ui::MouseEvent& event,
332 const gfx::Point& location_in_screen,
333 views::Widget* target) {
334 DCHECK(enabled_);
335 DCHECK(reveal_state_ == SLIDING_CLOSED || reveal_state_ == CLOSED);
336
337 // Check whether |widget_| is the event target instead of checking for
338 // activation. This allows the timer to be started when |widget_| is inactive
339 // but prevents starting the timer if the mouse is over a portion of the top
340 // edge obscured by an unrelated widget.
341 if (!top_edge_hover_timer_.IsRunning() && target != widget_) {
342 return;
343 }
344
345 // Mouse hover should not initiate revealing the top-of-window views while a
346 // window has mouse capture.
347 if (ImmersiveContext::Get()->DoesAnyWindowHaveCapture())
348 return;
349
350 if (ShouldIgnoreMouseEventAtLocation(location_in_screen))
351 return;
352
353 // Stop the timer if the cursor left the top edge or is on a different
354 // display.
355 gfx::Rect hit_bounds_in_screen = GetDisplayBoundsInScreen();
356 hit_bounds_in_screen.set_height(kMouseRevealBoundsHeight);
357 if (!hit_bounds_in_screen.Contains(location_in_screen)) {
358 top_edge_hover_timer_.Stop();
359 return;
360 }
361
362 // The cursor is now at the top of the screen. Consider the cursor "not
363 // moving" even if it moves a little bit because users don't have perfect
364 // pointing precision. (The y position is not tested because
365 // |hit_bounds_in_screen| is short.)
366 if (top_edge_hover_timer_.IsRunning() &&
367 abs(location_in_screen.x() - mouse_x_when_hit_top_in_screen_) <=
368 kMouseRevealXThresholdPixels)
369 return;
370
371 // Start the reveal if the cursor doesn't move for some amount of time.
372 mouse_x_when_hit_top_in_screen_ = location_in_screen.x();
373 top_edge_hover_timer_.Stop();
374 // Timer is stopped when |this| is destroyed, hence Unretained() is safe.
375 top_edge_hover_timer_.Start(
376 FROM_HERE, base::TimeDelta::FromMilliseconds(kMouseRevealDelayMs),
377 base::Bind(
378 &ImmersiveFullscreenController::AcquireLocatedEventRevealedLock,
379 base::Unretained(this)));
380 }
381
382 void ImmersiveFullscreenController::UpdateLocatedEventRevealedLock(
383 const ui::LocatedEvent* event,
384 const gfx::Point& location_in_screen) {
385 if (!enabled_)
386 return;
387 DCHECK(!event || event->IsMouseEvent() || event->IsTouchEvent());
388
389 // Neither the mouse nor touch can initiate a reveal when the top-of-window
390 // views are sliding closed or are closed with the following exceptions:
391 // - Hovering at y = 0 which is handled in OnMouseEvent().
392 // - Doing a SWIPE_OPEN edge gesture which is handled in OnGestureEvent().
393 if (reveal_state_ == CLOSED || reveal_state_ == SLIDING_CLOSED)
394 return;
395
396 // For the sake of simplicity, ignore |widget_|'s activation in computing
397 // whether the top-of-window views should stay revealed. Ideally, the
398 // top-of-window views would stay revealed only when the mouse cursor is
399 // hovered above a non-obscured portion of the top-of-window views. The
400 // top-of-window views may be partially obscured when |widget_| is inactive.
401
402 // Ignore all events while a window has capture. This keeps the top-of-window
403 // views revealed during a drag.
404 if (ImmersiveContext::Get()->DoesAnyWindowHaveCapture())
405 return;
406
407 if ((!event || event->IsMouseEvent()) &&
408 ShouldIgnoreMouseEventAtLocation(location_in_screen)) {
409 return;
410 }
411
412 // The visible bounds of |top_container_| should be contained in
413 // |hit_bounds_in_screen|.
414 std::vector<gfx::Rect> hit_bounds_in_screen =
415 delegate_->GetVisibleBoundsInScreen();
416 bool keep_revealed = false;
417 for (size_t i = 0; i < hit_bounds_in_screen.size(); ++i) {
418 // Allow the cursor to move slightly off the top-of-window views before
419 // sliding closed. In the case of ImmersiveModeControllerAsh, this helps
420 // when the user is attempting to click on the bookmark bar and overshoots
421 // slightly.
422 if (event && event->type() == ui::ET_MOUSE_MOVED) {
423 const int kBoundsOffsetY = 8;
424 hit_bounds_in_screen[i].Inset(0, 0, 0, -kBoundsOffsetY);
425 }
426
427 if (hit_bounds_in_screen[i].Contains(location_in_screen)) {
428 keep_revealed = true;
429 break;
430 }
431 }
432
433 if (keep_revealed)
434 AcquireLocatedEventRevealedLock();
435 else
436 located_event_revealed_lock_.reset();
437 }
438
439 void ImmersiveFullscreenController::UpdateLocatedEventRevealedLock() {
440 if (!ImmersiveContext::Get()->IsMouseEventsEnabled()) {
441 // If mouse events are disabled, the user's last interaction was probably
442 // via touch. Do no do further processing in this case as there is no easy
443 // way of retrieving the position of the user's last touch.
444 return;
445 }
446 UpdateLocatedEventRevealedLock(
447 nullptr, display::Screen::GetScreen()->GetCursorScreenPoint());
448 }
449
450 void ImmersiveFullscreenController::AcquireLocatedEventRevealedLock() {
451 // CAUTION: Acquiring the lock results in a reentrant call to
452 // AcquireLocatedEventRevealedLock() when
453 // |ImmersiveFullscreenController::animations_disabled_for_test_| is true.
454 if (!located_event_revealed_lock_.get())
455 located_event_revealed_lock_.reset(GetRevealedLock(ANIMATE_REVEAL_YES));
456 }
457
458 bool ImmersiveFullscreenController::UpdateRevealedLocksForSwipe(
459 SwipeType swipe_type) {
460 if (!enabled_ || swipe_type == SWIPE_NONE)
461 return false;
462
463 // Swipes while |widget_| is inactive should have been filtered out in
464 // OnGestureEvent().
465 DCHECK(widget_->IsActive());
466
467 if (reveal_state_ == SLIDING_CLOSED || reveal_state_ == CLOSED) {
468 if (swipe_type == SWIPE_OPEN && !located_event_revealed_lock_.get()) {
469 located_event_revealed_lock_.reset(GetRevealedLock(ANIMATE_REVEAL_YES));
470 return true;
471 }
472 } else {
473 if (swipe_type == SWIPE_CLOSE) {
474 // Attempt to end the reveal. If other code is holding onto a lock, the
475 // attempt will be unsuccessful.
476 located_event_revealed_lock_.reset();
477 if (immersive_focus_watcher_)
478 immersive_focus_watcher_->ReleaseLock();
479
480 if (reveal_state_ == SLIDING_CLOSED || reveal_state_ == CLOSED) {
481 widget_->GetFocusManager()->ClearFocus();
482 return true;
483 }
484
485 // Ending the reveal was unsuccessful. Reaquire the locks if appropriate.
486 UpdateLocatedEventRevealedLock();
487 if (immersive_focus_watcher_)
488 immersive_focus_watcher_->UpdateFocusRevealedLock();
489 }
490 }
491 return false;
492 }
493
494 int ImmersiveFullscreenController::GetAnimationDuration(Animate animate) const {
495 switch (animate) {
496 case ANIMATE_NO:
497 return 0;
498 case ANIMATE_SLOW:
499 return kRevealSlowAnimationDurationMs;
500 case ANIMATE_FAST:
501 return kRevealFastAnimationDurationMs;
502 }
503 NOTREACHED();
504 return 0;
505 }
506
507 void ImmersiveFullscreenController::MaybeStartReveal(Animate animate) {
508 if (!enabled_)
509 return;
510
511 if (animations_disabled_for_test_)
512 animate = ANIMATE_NO;
513
514 // Callers with ANIMATE_NO expect this function to synchronously reveal the
515 // top-of-window views.
516 if (reveal_state_ == REVEALED ||
517 (reveal_state_ == SLIDING_OPEN && animate != ANIMATE_NO)) {
518 return;
519 }
520
521 RevealState previous_reveal_state = reveal_state_;
522 reveal_state_ = SLIDING_OPEN;
523 if (previous_reveal_state == CLOSED) {
524 delegate_->OnImmersiveRevealStarted();
525
526 // Do not do any more processing if OnImmersiveRevealStarted() changed
527 // |reveal_state_|.
528 if (reveal_state_ != SLIDING_OPEN)
529 return;
530 }
531 // Slide in the reveal view.
532 if (animate == ANIMATE_NO) {
533 animation_->Reset(1);
534 OnSlideOpenAnimationCompleted();
535 } else {
536 animation_->SetSlideDuration(GetAnimationDuration(animate));
537 animation_->Show();
538 }
539 }
540
541 void ImmersiveFullscreenController::OnSlideOpenAnimationCompleted() {
542 DCHECK_EQ(SLIDING_OPEN, reveal_state_);
543 reveal_state_ = REVEALED;
544 delegate_->SetVisibleFraction(1);
545
546 // The user may not have moved the mouse since the reveal was initiated.
547 // Update the revealed lock to reflect the mouse's current state.
548 UpdateLocatedEventRevealedLock();
549 }
550
551 void ImmersiveFullscreenController::MaybeEndReveal(Animate animate) {
552 if (!enabled_ || revealed_lock_count_ != 0)
553 return;
554
555 if (animations_disabled_for_test_)
556 animate = ANIMATE_NO;
557
558 // Callers with ANIMATE_NO expect this function to synchronously close the
559 // top-of-window views.
560 if (reveal_state_ == CLOSED ||
561 (reveal_state_ == SLIDING_CLOSED && animate != ANIMATE_NO)) {
562 return;
563 }
564
565 reveal_state_ = SLIDING_CLOSED;
566 int duration_ms = GetAnimationDuration(animate);
567 if (duration_ms > 0) {
568 animation_->SetSlideDuration(duration_ms);
569 animation_->Hide();
570 } else {
571 animation_->Reset(0);
572 OnSlideClosedAnimationCompleted();
573 }
574 }
575
576 void ImmersiveFullscreenController::OnSlideClosedAnimationCompleted() {
577 DCHECK_EQ(SLIDING_CLOSED, reveal_state_);
578 reveal_state_ = CLOSED;
579 delegate_->OnImmersiveRevealEnded();
580 }
581
582 ImmersiveFullscreenController::SwipeType
583 ImmersiveFullscreenController::GetSwipeType(
584 const ui::GestureEvent& event) const {
585 if (event.type() != ui::ET_GESTURE_SCROLL_UPDATE)
586 return SWIPE_NONE;
587 // Make sure that it is a clear vertical gesture.
588 if (std::abs(event.details().scroll_y()) <=
589 kSwipeVerticalThresholdMultiplier * std::abs(event.details().scroll_x()))
590 return SWIPE_NONE;
591 if (event.details().scroll_y() < 0)
592 return SWIPE_CLOSE;
593 if (event.details().scroll_y() > 0)
594 return SWIPE_OPEN;
595 return SWIPE_NONE;
596 }
597
598 bool ImmersiveFullscreenController::ShouldIgnoreMouseEventAtLocation(
599 const gfx::Point& location) const {
600 // Ignore mouse events in the region immediately above the top edge of the
601 // display. This is to handle the case of a user with a vertical display
602 // layout (primary display above/below secondary display) and the immersive
603 // fullscreen window on the bottom display. It is really hard to trigger a
604 // reveal in this case because:
605 // - It is hard to stop the cursor in the top |kMouseRevealBoundsHeight|
606 // pixels of the bottom display.
607 // - The cursor is warped to the top display if the cursor gets to the top
608 // edge of the bottom display.
609 // Mouse events are ignored in the bottom few pixels of the top display
610 // (Mouse events in this region cannot start or end a reveal). This allows a
611 // user to overshoot the top of the bottom display and still reveal the
612 // top-of-window views.
613 gfx::Rect dead_region = GetDisplayBoundsInScreen();
614 dead_region.set_y(dead_region.y() - kHeightOfDeadRegionAboveTopContainer);
615 dead_region.set_height(kHeightOfDeadRegionAboveTopContainer);
616 return dead_region.Contains(location);
617 }
618
619 bool ImmersiveFullscreenController::ShouldHandleGestureEvent(
620 const gfx::Point& location) const {
621 DCHECK(widget_->IsActive());
622 if (reveal_state_ == REVEALED) {
623 std::vector<gfx::Rect> hit_bounds_in_screen(
624 delegate_->GetVisibleBoundsInScreen());
625 for (size_t i = 0; i < hit_bounds_in_screen.size(); ++i) {
626 if (hit_bounds_in_screen[i].Contains(location))
627 return true;
628 }
629 return false;
630 }
631
632 // When the top-of-window views are not fully revealed, handle gestures which
633 // start in the top few pixels of the screen.
634 gfx::Rect hit_bounds_in_screen(GetDisplayBoundsInScreen());
635 hit_bounds_in_screen.set_height(kImmersiveFullscreenTopEdgeInset);
636 if (hit_bounds_in_screen.Contains(location))
637 return true;
638
639 // There may be a bezel sensor off screen logically above
640 // |hit_bounds_in_screen|. The check for the event not contained by the
641 // closest screen ensures that the event is from a valid bezel (as opposed to
642 // another screen in an extended desktop).
643 gfx::Rect screen_bounds =
644 display::Screen::GetScreen()->GetDisplayNearestPoint(location).bounds();
645 return (!screen_bounds.Contains(location) &&
646 location.y() < hit_bounds_in_screen.y() &&
647 location.x() >= hit_bounds_in_screen.x() &&
648 location.x() < hit_bounds_in_screen.right());
649 }
650
651 gfx::Rect ImmersiveFullscreenController::GetDisplayBoundsInScreen() const {
652 return ImmersiveContext::Get()->GetDisplayBoundsInScreen(widget_);
653 }
654
655 } // 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