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

Side by Side Diff: chrome/browser/ui/views/frame/immersive_mode_controller_ash.cc

Issue 14340007: Hide the tab indicators and the shelf when in immersive + tab fullscreen (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 7 years, 7 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 | 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 "chrome/browser/ui/views/frame/immersive_mode_controller_ash.h"
6 6
7 #include "ash/ash_switches.h" 7 #include "ash/ash_switches.h"
8 #include "ash/shell.h" 8 #include "ash/shell.h"
9 #include "ash/wm/window_properties.h" 9 #include "ash/wm/window_properties.h"
10 #include "base/command_line.h" 10 #include "base/command_line.h"
11 #include "chrome/browser/ui/fullscreen/fullscreen_controller.h"
11 #include "chrome/browser/ui/views/bookmarks/bookmark_bar_view.h" 12 #include "chrome/browser/ui/views/bookmarks/bookmark_bar_view.h"
12 #include "chrome/browser/ui/views/frame/browser_view.h" 13 #include "chrome/browser/ui/views/frame/browser_view.h"
13 #include "chrome/browser/ui/views/frame/top_container_view.h" 14 #include "chrome/browser/ui/views/frame/top_container_view.h"
14 #include "chrome/browser/ui/views/tabs/tab_strip.h" 15 #include "chrome/browser/ui/views/tabs/tab_strip.h"
16 #include "chrome/common/chrome_notification_types.h"
17 #include "content/public/browser/notification_service.h"
15 #include "ui/aura/client/activation_client.h" 18 #include "ui/aura/client/activation_client.h"
16 #include "ui/aura/client/aura_constants.h" 19 #include "ui/aura/client/aura_constants.h"
17 #include "ui/aura/client/capture_client.h" 20 #include "ui/aura/client/capture_client.h"
18 #include "ui/aura/env.h" 21 #include "ui/aura/env.h"
19 #include "ui/aura/window.h" 22 #include "ui/aura/window.h"
20 #include "ui/aura/window_observer.h" 23 #include "ui/aura/window_observer.h"
21 #include "ui/compositor/layer_animation_observer.h" 24 #include "ui/compositor/layer_animation_observer.h"
22 #include "ui/compositor/scoped_layer_animation_settings.h" 25 #include "ui/compositor/scoped_layer_animation_settings.h"
23 #include "ui/gfx/screen.h" 26 #include "ui/gfx/screen.h"
24 #include "ui/gfx/transform.h" 27 #include "ui/gfx/transform.h"
(...skipping 285 matching lines...) Expand 10 before | Expand all | Expand 10 after
310 // Disable immersive mode when leaving the fullscreen state. 313 // Disable immersive mode when leaving the fullscreen state.
311 ui::WindowShowState show_state = static_cast<ui::WindowShowState>( 314 ui::WindowShowState show_state = static_cast<ui::WindowShowState>(
312 window->GetProperty(kShowStateKey)); 315 window->GetProperty(kShowStateKey));
313 if (controller_->IsEnabled() && 316 if (controller_->IsEnabled() &&
314 show_state != ui::SHOW_STATE_FULLSCREEN && 317 show_state != ui::SHOW_STATE_FULLSCREEN &&
315 show_state != ui::SHOW_STATE_MINIMIZED) { 318 show_state != ui::SHOW_STATE_MINIMIZED) {
316 controller_->browser_view_->FullScreenStateChanged(); 319 controller_->browser_view_->FullScreenStateChanged();
317 } 320 }
318 return; 321 return;
319 } 322 }
320 using ash::internal::kImmersiveModeKey;
321 if (key == kImmersiveModeKey) {
322 // Another component has toggled immersive mode.
323 controller_->SetEnabled(window->GetProperty(kImmersiveModeKey));
324 return;
325 }
326 } 323 }
327 324
328 private: 325 private:
329 ImmersiveModeControllerAsh* controller_; // Not owned. 326 ImmersiveModeControllerAsh* controller_; // Not owned.
330 327
331 DISALLOW_COPY_AND_ASSIGN(WindowObserver); 328 DISALLOW_COPY_AND_ASSIGN(WindowObserver);
332 }; 329 };
333 330
334 //////////////////////////////////////////////////////////////////////////////// 331 ////////////////////////////////////////////////////////////////////////////////
335 332
336 ImmersiveModeControllerAsh::ImmersiveModeControllerAsh() 333 ImmersiveModeControllerAsh::ImmersiveModeControllerAsh()
337 : browser_view_(NULL), 334 : browser_view_(NULL),
335 observers_enabled_(false),
338 enabled_(false), 336 enabled_(false),
339 reveal_state_(CLOSED), 337 reveal_state_(CLOSED),
340 revealed_lock_count_(0), 338 revealed_lock_count_(0),
341 hide_tab_indicators_(false), 339 tab_indicator_visibility_(TAB_INDICATORS_HIDE),
342 native_window_(NULL), 340 native_window_(NULL),
343 weak_ptr_factory_(ALLOW_THIS_IN_INITIALIZER_LIST(this)) { 341 weak_ptr_factory_(ALLOW_THIS_IN_INITIALIZER_LIST(this)) {
344 } 342 }
345 343
346 ImmersiveModeControllerAsh::~ImmersiveModeControllerAsh() { 344 ImmersiveModeControllerAsh::~ImmersiveModeControllerAsh() {
347 // The browser view is being destroyed so there's no need to update its 345 // The browser view is being destroyed so there's no need to update its
348 // layout or layers, even if the top views are revealed. But the window 346 // layout or layers, even if the top views are revealed. But the window
349 // observers still need to be removed. 347 // observers still need to be removed.
350 EnableWindowObservers(false); 348 EnableWindowObservers(false);
351 } 349 }
(...skipping 18 matching lines...) Expand all
370 void ImmersiveModeControllerAsh::MaybeRevealWithoutAnimation() { 368 void ImmersiveModeControllerAsh::MaybeRevealWithoutAnimation() {
371 MaybeStartReveal(ANIMATE_NO); 369 MaybeStartReveal(ANIMATE_NO);
372 } 370 }
373 371
374 void ImmersiveModeControllerAsh::Init(BrowserView* browser_view) { 372 void ImmersiveModeControllerAsh::Init(BrowserView* browser_view) {
375 browser_view_ = browser_view; 373 browser_view_ = browser_view;
376 // Browser view is detached from its widget during destruction. Cache the 374 // Browser view is detached from its widget during destruction. Cache the
377 // window pointer so |this| can stop observing during destruction. 375 // window pointer so |this| can stop observing during destruction.
378 native_window_ = browser_view_->GetNativeWindow(); 376 native_window_ = browser_view_->GetNativeWindow();
379 DCHECK(native_window_); 377 DCHECK(native_window_);
380 EnableWindowObservers(true);
381 378
382 // Optionally allow the tab indicators to be hidden. 379 // Optionally allow the tab indicators to be hidden.
383 hide_tab_indicators_ = CommandLine::ForCurrentProcess()-> 380 if (CommandLine::ForCurrentProcess()->
384 HasSwitch(ash::switches::kAshImmersiveHideTabIndicators); 381 HasSwitch(ash::switches::kAshImmersiveHideTabIndicators)) {
382 tab_indicator_visibility_ = TAB_INDICATORS_FORCE_HIDE;
383 }
385 384
386 anchored_widget_manager_.reset(new AnchoredWidgetManager(this)); 385 anchored_widget_manager_.reset(new AnchoredWidgetManager(this));
387 } 386 }
388 387
389 void ImmersiveModeControllerAsh::SetEnabled(bool enabled) { 388 void ImmersiveModeControllerAsh::SetEnabled(bool enabled) {
390 DCHECK(browser_view_) << "Must initialize before enabling"; 389 DCHECK(browser_view_) << "Must initialize before enabling";
391 if (enabled_ == enabled) 390 if (enabled_ == enabled)
392 return; 391 return;
393 enabled_ = enabled; 392 enabled_ = enabled;
394 393
394 // Delay the initialization of the window observers till the first call to
395 // SetEnabled(true) because FullscreenController is not yet initialized when
396 // Init() is called.
397 EnableWindowObservers(true);
398
395 if (enabled_) { 399 if (enabled_) {
396 // Animate enabling immersive mode by sliding out the top-of-window views. 400 // Animate enabling immersive mode by sliding out the top-of-window views.
397 // No animation occurs if a lock is holding the top-of-window views open. 401 // No animation occurs if a lock is holding the top-of-window views open.
398 402
399 // Do a reveal to set the initial state for the animation. (And any 403 // Do a reveal to set the initial state for the animation. (And any
400 // required state in case the animation cannot run because of a lock holding 404 // required state in case the animation cannot run because of a lock holding
401 // the top-of-window views open.) 405 // the top-of-window views open.)
402 MaybeStartReveal(ANIMATE_NO); 406 MaybeStartReveal(ANIMATE_NO);
403 407
404 // Reset the mouse and the focus revealed locks so that they do not affect 408 // Reset the mouse and the focus revealed locks so that they do not affect
(...skipping 16 matching lines...) Expand all
421 // Snap immediately to the closed state. 425 // Snap immediately to the closed state.
422 reveal_state_ = CLOSED; 426 reveal_state_ = CLOSED;
423 EnablePaintToLayer(false); 427 EnablePaintToLayer(false);
424 browser_view_->GetWidget()->non_client_view()->frame_view()-> 428 browser_view_->GetWidget()->non_client_view()->frame_view()->
425 ResetWindowControls(); 429 ResetWindowControls();
426 browser_view_->tabstrip()->SetImmersiveStyle(false); 430 browser_view_->tabstrip()->SetImmersiveStyle(false);
427 } 431 }
428 // Don't need explicit layout because we're inside a fullscreen transition 432 // Don't need explicit layout because we're inside a fullscreen transition
429 // and it blocks layout calls. 433 // and it blocks layout calls.
430 434
431 // This causes a no-op call to SetEnabled() since enabled_ is already set. 435 UpdateUseMinimalChrome(LAYOUT_NO);
432 native_window_->SetProperty(ash::internal::kImmersiveModeKey, enabled_);
433 // Ash on Windows may not have a shell.
434 if (ash::Shell::HasInstance()) {
435 // Shelf auto-hides in immersive mode.
436 ash::Shell::GetInstance()->UpdateShelfVisibility();
437 }
438 } 436 }
439 437
440 bool ImmersiveModeControllerAsh::IsEnabled() const { 438 bool ImmersiveModeControllerAsh::IsEnabled() const {
441 return enabled_; 439 return enabled_;
442 } 440 }
443 441
444 bool ImmersiveModeControllerAsh::ShouldHideTabIndicators() const { 442 bool ImmersiveModeControllerAsh::ShouldHideTabIndicators() const {
445 return hide_tab_indicators_; 443 return tab_indicator_visibility_ != TAB_INDICATORS_SHOW;
446 } 444 }
447 445
448 bool ImmersiveModeControllerAsh::ShouldHideTopViews() const { 446 bool ImmersiveModeControllerAsh::ShouldHideTopViews() const {
449 return enabled_ && reveal_state_ == CLOSED; 447 return enabled_ && reveal_state_ == CLOSED;
450 } 448 }
451 449
452 bool ImmersiveModeControllerAsh::IsRevealed() const { 450 bool ImmersiveModeControllerAsh::IsRevealed() const {
453 return enabled_ && reveal_state_ != CLOSED; 451 return enabled_ && reveal_state_ != CLOSED;
454 } 452 }
455 453
(...skipping 21 matching lines...) Expand all
477 anchored_widget_manager_->RemoveAnchoredWidget(widget); 475 anchored_widget_manager_->RemoveAnchoredWidget(widget);
478 } 476 }
479 477
480 void ImmersiveModeControllerAsh::OnTopContainerBoundsChanged() { 478 void ImmersiveModeControllerAsh::OnTopContainerBoundsChanged() {
481 anchored_widget_manager_->MaybeRepositionAnchoredWidgets(); 479 anchored_widget_manager_->MaybeRepositionAnchoredWidgets();
482 } 480 }
483 481
484 //////////////////////////////////////////////////////////////////////////////// 482 ////////////////////////////////////////////////////////////////////////////////
485 // Observers: 483 // Observers:
486 484
485 void ImmersiveModeControllerAsh::Observe(
486 int type,
487 const content::NotificationSource& source,
488 const content::NotificationDetails& details) {
489 DCHECK_EQ(chrome::NOTIFICATION_FULLSCREEN_CHANGED, type);
490 if (enabled_)
491 UpdateUseMinimalChrome(LAYOUT_YES);
492 }
493
487 void ImmersiveModeControllerAsh::OnMouseEvent(ui::MouseEvent* event) { 494 void ImmersiveModeControllerAsh::OnMouseEvent(ui::MouseEvent* event) {
488 if (!enabled_) 495 if (!enabled_)
489 return; 496 return;
490 497
491 if (event->flags() & ui::EF_IS_SYNTHESIZED) 498 if (event->flags() & ui::EF_IS_SYNTHESIZED)
492 return; 499 return;
493 500
494 // Handle ET_MOUSE_PRESSED and ET_MOUSE_RELEASED so that we get the updated 501 // Handle ET_MOUSE_PRESSED and ET_MOUSE_RELEASED so that we get the updated
495 // mouse position ASAP once a nested message loop finishes running. 502 // mouse position ASAP once a nested message loop finishes running.
496 if (event->type() != ui::ET_MOUSE_MOVED && 503 if (event->type() != ui::ET_MOUSE_MOVED &&
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after
560 void ImmersiveModeControllerAsh::OnImplicitAnimationsCompleted() { 567 void ImmersiveModeControllerAsh::OnImplicitAnimationsCompleted() {
561 if (reveal_state_ == SLIDING_OPEN) 568 if (reveal_state_ == SLIDING_OPEN)
562 OnSlideOpenAnimationCompleted(); 569 OnSlideOpenAnimationCompleted();
563 else if (reveal_state_ == SLIDING_CLOSED) 570 else if (reveal_state_ == SLIDING_CLOSED)
564 OnSlideClosedAnimationCompleted(); 571 OnSlideClosedAnimationCompleted();
565 } 572 }
566 573
567 //////////////////////////////////////////////////////////////////////////////// 574 ////////////////////////////////////////////////////////////////////////////////
568 // Testing interface: 575 // Testing interface:
569 576
570 void ImmersiveModeControllerAsh::SetHideTabIndicatorsForTest(bool hide) { 577 void ImmersiveModeControllerAsh::SetForceHideTabIndicatorsForTest(bool force) {
571 hide_tab_indicators_ = hide; 578 if (force)
579 tab_indicator_visibility_ = TAB_INDICATORS_FORCE_HIDE;
580 else if (tab_indicator_visibility_ == TAB_INDICATORS_FORCE_HIDE)
581 tab_indicator_visibility_ = TAB_INDICATORS_HIDE;
582 UpdateUseMinimalChrome(LAYOUT_YES);
572 } 583 }
573 584
574 void ImmersiveModeControllerAsh::StartRevealForTest(bool hovered) { 585 void ImmersiveModeControllerAsh::StartRevealForTest(bool hovered) {
575 MaybeStartReveal(ANIMATE_NO); 586 MaybeStartReveal(ANIMATE_NO);
576 MoveMouse(browser_view_->top_container(), hovered); 587 MoveMouse(browser_view_->top_container(), hovered);
577 UpdateMouseRevealedLock(false); 588 UpdateMouseRevealedLock(false);
578 } 589 }
579 590
580 void ImmersiveModeControllerAsh::SetMouseHoveredForTest(bool hovered) { 591 void ImmersiveModeControllerAsh::SetMouseHoveredForTest(bool hovered) {
581 MoveMouse(browser_view_->top_container(), hovered); 592 MoveMouse(browser_view_->top_container(), hovered);
582 UpdateMouseRevealedLock(false); 593 UpdateMouseRevealedLock(false);
583 } 594 }
584 595
585 //////////////////////////////////////////////////////////////////////////////// 596 ////////////////////////////////////////////////////////////////////////////////
586 // private: 597 // private:
587 598
588 void ImmersiveModeControllerAsh::EnableWindowObservers(bool enable) { 599 void ImmersiveModeControllerAsh::EnableWindowObservers(bool enable) {
600 if (observers_enabled_ == enable)
601 return;
602 observers_enabled_ = enable;
603
589 if (!native_window_) { 604 if (!native_window_) {
590 DCHECK(!enable) << "ImmersiveModeControllerAsh not initialized"; 605 NOTREACHED() << "ImmersiveModeControllerAsh not initialized";
591 return; 606 return;
592 } 607 }
593 608
594 views::Widget* widget = 609 views::Widget* widget =
595 views::Widget::GetWidgetForNativeWindow(native_window_); 610 views::Widget::GetWidgetForNativeWindow(native_window_);
596 views::FocusManager* focus_manager = widget->GetFocusManager(); 611 views::FocusManager* focus_manager = widget->GetFocusManager();
597 if (enable) { 612 if (enable) {
598 widget->AddObserver(this); 613 widget->AddObserver(this);
599 focus_manager->AddFocusChangeListener(this); 614 focus_manager->AddFocusChangeListener(this);
600 } else { 615 } else {
601 widget->RemoveObserver(this); 616 widget->RemoveObserver(this);
602 focus_manager->RemoveFocusChangeListener(this); 617 focus_manager->RemoveFocusChangeListener(this);
603 } 618 }
604 619
605 if (enable) 620 if (enable)
606 native_window_->AddPreTargetHandler(this); 621 native_window_->AddPreTargetHandler(this);
607 else 622 else
608 native_window_->RemovePreTargetHandler(this); 623 native_window_->RemovePreTargetHandler(this);
609 624
610 // The window observer adds and removes itself from the native window. 625 // The window observer adds and removes itself from the native window.
611 window_observer_.reset(enable ? new WindowObserver(this) : NULL); 626 window_observer_.reset(enable ? new WindowObserver(this) : NULL);
612 627
628 if (enable) {
629 registrar_.Add(
630 this,
631 chrome::NOTIFICATION_FULLSCREEN_CHANGED,
632 content::Source<FullscreenController>(
633 browser_view_->browser()->fullscreen_controller()));
634 } else {
635 registrar_.Remove(
636 this,
637 chrome::NOTIFICATION_FULLSCREEN_CHANGED,
638 content::Source<FullscreenController>(
639 browser_view_->browser()->fullscreen_controller()));
640 }
641
613 if (!enable) 642 if (!enable)
614 StopObservingImplicitAnimations(); 643 StopObservingImplicitAnimations();
615 } 644 }
616 645
617 void ImmersiveModeControllerAsh::UpdateMouseRevealedLock(bool maybe_drag) { 646 void ImmersiveModeControllerAsh::UpdateMouseRevealedLock(bool maybe_drag) {
618 if (!enabled_) 647 if (!enabled_)
619 return; 648 return;
620 649
621 // Hover cannot initiate a reveal when the top-of-window views are sliding 650 // Hover cannot initiate a reveal when the top-of-window views are sliding
622 // closed or are closed. (With the exception of hovering at y = 0 which is 651 // closed or are closed. (With the exception of hovering at y = 0 which is
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after
679 } 708 }
680 709
681 if (hold_lock) { 710 if (hold_lock) {
682 if (!focus_revealed_lock_.get()) 711 if (!focus_revealed_lock_.get())
683 focus_revealed_lock_.reset(GetRevealedLock(ANIMATE_REVEAL_YES)); 712 focus_revealed_lock_.reset(GetRevealedLock(ANIMATE_REVEAL_YES));
684 } else { 713 } else {
685 focus_revealed_lock_.reset(); 714 focus_revealed_lock_.reset();
686 } 715 }
687 } 716 }
688 717
718 void ImmersiveModeControllerAsh::UpdateUseMinimalChrome(Layout layout) {
719 bool in_tab_fullscreen = browser_view_->browser()->fullscreen_controller()->
720 IsFullscreenForTabOrPending();
721 bool use_minimal_chrome = !in_tab_fullscreen && enabled_;
722 native_window_->SetProperty(ash::internal::kFullscreenUsesMinimalChromeKey,
723 use_minimal_chrome);
724
725 TabIndicatorVisibility previous_tab_indicator_visibility =
726 tab_indicator_visibility_;
727 if (tab_indicator_visibility_ != TAB_INDICATORS_FORCE_HIDE) {
728 tab_indicator_visibility_ = use_minimal_chrome ?
729 TAB_INDICATORS_SHOW : TAB_INDICATORS_HIDE;
730 }
731
732 // Ash on Windows may not have a shell.
733 if (ash::Shell::HasInstance()) {
734 // When using minimal chrome, the shelf is auto-hidden. The auto-hidden
735 // shelf displays a 3px 'light bar' when it is closed.
736 ash::Shell::GetInstance()->UpdateShelfVisibility();
737 }
738
739 if (tab_indicator_visibility_ != previous_tab_indicator_visibility) {
740 // If the top-of-window views are revealed or animating, the change will
741 // take effect with the layout once the top-of-window views are closed.
742 if (layout == LAYOUT_YES && reveal_state_ == CLOSED)
743 LayoutBrowserView(true);
744 }
745 }
746
689 int ImmersiveModeControllerAsh::GetAnimationDuration(Animate animate) const { 747 int ImmersiveModeControllerAsh::GetAnimationDuration(Animate animate) const {
690 switch (animate) { 748 switch (animate) {
691 case ANIMATE_NO: 749 case ANIMATE_NO:
692 return 0; 750 return 0;
693 case ANIMATE_SLOW: 751 case ANIMATE_SLOW:
694 return kRevealSlowAnimationDurationMs; 752 return kRevealSlowAnimationDurationMs;
695 case ANIMATE_FAST: 753 case ANIMATE_FAST:
696 return kRevealFastAnimationDurationMs; 754 return kRevealFastAnimationDurationMs;
697 } 755 }
698 NOTREACHED(); 756 NOTREACHED();
(...skipping 156 matching lines...) Expand 10 before | Expand all | Expand 10 after
855 ui::ScopedLayerAnimationSettings settings(layer->GetAnimator()); 913 ui::ScopedLayerAnimationSettings settings(layer->GetAnimator());
856 settings.SetTweenType(ui::Tween::EASE_OUT); 914 settings.SetTweenType(ui::Tween::EASE_OUT);
857 settings.SetTransitionDuration( 915 settings.SetTransitionDuration(
858 base::TimeDelta::FromMilliseconds(duration_ms)); 916 base::TimeDelta::FromMilliseconds(duration_ms));
859 settings.SetPreemptionStrategy( 917 settings.SetPreemptionStrategy(
860 ui::LayerAnimator::IMMEDIATELY_ANIMATE_TO_NEW_TARGET); 918 ui::LayerAnimator::IMMEDIATELY_ANIMATE_TO_NEW_TARGET);
861 if (observer) 919 if (observer)
862 settings.AddObserver(observer); 920 settings.AddObserver(observer);
863 layer->SetTransform(target_transform); 921 layer->SetTransform(target_transform);
864 } 922 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698