Chromium Code Reviews| OLD | NEW |
|---|---|
| 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 282 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 307 window->GetProperty(kShowStateKey)); | 310 window->GetProperty(kShowStateKey)); |
| 308 if (controller_->IsEnabled() && | 311 if (controller_->IsEnabled() && |
| 309 show_state != ui::SHOW_STATE_FULLSCREEN && | 312 show_state != ui::SHOW_STATE_FULLSCREEN && |
| 310 show_state != ui::SHOW_STATE_MINIMIZED) { | 313 show_state != ui::SHOW_STATE_MINIMIZED) { |
| 311 controller_->browser_view_->FullScreenStateChanged(); | 314 controller_->browser_view_->FullScreenStateChanged(); |
| 312 } | 315 } |
| 313 return; | 316 return; |
| 314 } | 317 } |
| 315 using ash::internal::kImmersiveModeKey; | 318 using ash::internal::kImmersiveModeKey; |
| 316 if (key == kImmersiveModeKey) { | 319 if (key == kImmersiveModeKey) { |
| 317 // Another component has toggled immersive mode. | 320 bool should_enable = window->GetProperty(kImmersiveModeKey); |
|
James Cook
2013/04/22 18:14:16
Do we still need kImmersiveModeKey? I don't think
| |
| 318 controller_->SetEnabled(window->GetProperty(kImmersiveModeKey)); | 321 if (controller_->IsEnabled() != should_enable) { |
| 322 // The user may be in tab fullscreen when a client sets | |
| 323 // kImmersiveModeKey. Entering browser / immersive fullscreen while the | |
| 324 // user is already in tab fullscreen is unsupported. Crash if a client | |
| 325 // uses kImmersiveModeKey to enter fullscreen. | |
| 326 CHECK(!should_enable); | |
| 327 controller_->browser_view_->ExitFullscreen(); | |
| 328 } | |
| 319 return; | 329 return; |
| 320 } | 330 } |
| 321 } | 331 } |
| 322 | 332 |
| 323 private: | 333 private: |
| 324 ImmersiveModeControllerAsh* controller_; // Not owned. | 334 ImmersiveModeControllerAsh* controller_; // Not owned. |
| 325 | 335 |
| 326 DISALLOW_COPY_AND_ASSIGN(WindowObserver); | 336 DISALLOW_COPY_AND_ASSIGN(WindowObserver); |
| 327 }; | 337 }; |
| 328 | 338 |
| 329 //////////////////////////////////////////////////////////////////////////////// | 339 //////////////////////////////////////////////////////////////////////////////// |
| 330 | 340 |
| 331 ImmersiveModeControllerAsh::ImmersiveModeControllerAsh() | 341 ImmersiveModeControllerAsh::ImmersiveModeControllerAsh() |
| 332 : browser_view_(NULL), | 342 : browser_view_(NULL), |
| 333 enabled_(false), | 343 enabled_(false), |
| 334 reveal_state_(CLOSED), | 344 reveal_state_(CLOSED), |
| 335 revealed_lock_count_(0), | 345 revealed_lock_count_(0), |
| 336 hide_tab_indicators_(false), | 346 tab_indicator_visibility_(TAB_INDICATORS_SHOW), |
| 337 native_window_(NULL), | 347 native_window_(NULL), |
| 338 weak_ptr_factory_(ALLOW_THIS_IN_INITIALIZER_LIST(this)) { | 348 weak_ptr_factory_(ALLOW_THIS_IN_INITIALIZER_LIST(this)) { |
| 339 } | 349 } |
| 340 | 350 |
| 341 ImmersiveModeControllerAsh::~ImmersiveModeControllerAsh() { | 351 ImmersiveModeControllerAsh::~ImmersiveModeControllerAsh() { |
| 342 // The browser view is being destroyed so there's no need to update its | 352 // The browser view is being destroyed so there's no need to update its |
| 343 // layout or layers, even if the top views are revealed. But the window | 353 // layout or layers, even if the top views are revealed. But the window |
| 344 // observers still need to be removed. | 354 // observers still need to be removed. |
| 345 EnableWindowObservers(false); | 355 EnableWindowObservers(false); |
| 346 } | 356 } |
| (...skipping 17 matching lines...) Expand all Loading... | |
| 364 | 374 |
| 365 void ImmersiveModeControllerAsh::Init(BrowserView* browser_view) { | 375 void ImmersiveModeControllerAsh::Init(BrowserView* browser_view) { |
| 366 browser_view_ = browser_view; | 376 browser_view_ = browser_view; |
| 367 // Browser view is detached from its widget during destruction. Cache the | 377 // Browser view is detached from its widget during destruction. Cache the |
| 368 // window pointer so |this| can stop observing during destruction. | 378 // window pointer so |this| can stop observing during destruction. |
| 369 native_window_ = browser_view_->GetNativeWindow(); | 379 native_window_ = browser_view_->GetNativeWindow(); |
| 370 DCHECK(native_window_); | 380 DCHECK(native_window_); |
| 371 EnableWindowObservers(true); | 381 EnableWindowObservers(true); |
| 372 | 382 |
| 373 // Optionally allow the tab indicators to be hidden. | 383 // Optionally allow the tab indicators to be hidden. |
| 374 hide_tab_indicators_ = CommandLine::ForCurrentProcess()-> | 384 if (CommandLine::ForCurrentProcess()-> |
| 375 HasSwitch(ash::switches::kAshImmersiveHideTabIndicators); | 385 HasSwitch(ash::switches::kAshImmersiveHideTabIndicators)) { |
| 386 tab_indicator_visibility_ = TAB_INDICATORS_FORCE_HIDE; | |
| 387 } | |
| 376 | 388 |
| 377 anchored_widget_manager_.reset(new AnchoredWidgetManager(this)); | 389 anchored_widget_manager_.reset(new AnchoredWidgetManager(this)); |
| 378 } | 390 } |
| 379 | 391 |
| 380 void ImmersiveModeControllerAsh::SetEnabled(bool enabled) { | 392 void ImmersiveModeControllerAsh::SetEnabled(bool enabled) { |
| 381 DCHECK(browser_view_) << "Must initialize before enabling"; | 393 DCHECK(browser_view_) << "Must initialize before enabling"; |
| 382 if (enabled_ == enabled) | 394 if (enabled_ == enabled) |
| 383 return; | 395 return; |
| 384 enabled_ = enabled; | 396 enabled_ = enabled; |
| 385 | 397 |
| (...skipping 28 matching lines...) Expand all Loading... | |
| 414 EnablePaintToLayer(false); | 426 EnablePaintToLayer(false); |
| 415 browser_view_->GetWidget()->non_client_view()->frame_view()-> | 427 browser_view_->GetWidget()->non_client_view()->frame_view()-> |
| 416 ResetWindowControls(); | 428 ResetWindowControls(); |
| 417 browser_view_->tabstrip()->SetImmersiveStyle(false); | 429 browser_view_->tabstrip()->SetImmersiveStyle(false); |
| 418 } | 430 } |
| 419 // Don't need explicit layout because we're inside a fullscreen transition | 431 // Don't need explicit layout because we're inside a fullscreen transition |
| 420 // and it blocks layout calls. | 432 // and it blocks layout calls. |
| 421 | 433 |
| 422 // This causes a no-op call to SetEnabled() since enabled_ is already set. | 434 // This causes a no-op call to SetEnabled() since enabled_ is already set. |
| 423 native_window_->SetProperty(ash::internal::kImmersiveModeKey, enabled_); | 435 native_window_->SetProperty(ash::internal::kImmersiveModeKey, enabled_); |
| 424 // Ash on Windows may not have a shell. | 436 |
| 425 if (ash::Shell::HasInstance()) { | 437 UpdateUseMinimalChrome(true); |
| 426 // Shelf auto-hides in immersive mode. | |
| 427 ash::Shell::GetInstance()->UpdateShelfVisibility(); | |
| 428 } | |
| 429 } | 438 } |
| 430 | 439 |
| 431 bool ImmersiveModeControllerAsh::IsEnabled() const { | 440 bool ImmersiveModeControllerAsh::IsEnabled() const { |
| 432 return enabled_; | 441 return enabled_; |
| 433 } | 442 } |
| 434 | 443 |
| 435 bool ImmersiveModeControllerAsh::ShouldHideTabIndicators() const { | 444 bool ImmersiveModeControllerAsh::ShouldHideTabIndicators() const { |
| 436 return hide_tab_indicators_; | 445 return tab_indicator_visibility_ != TAB_INDICATORS_SHOW; |
| 437 } | 446 } |
| 438 | 447 |
| 439 bool ImmersiveModeControllerAsh::ShouldHideTopViews() const { | 448 bool ImmersiveModeControllerAsh::ShouldHideTopViews() const { |
| 440 return enabled_ && reveal_state_ == CLOSED; | 449 return enabled_ && reveal_state_ == CLOSED; |
| 441 } | 450 } |
| 442 | 451 |
| 443 bool ImmersiveModeControllerAsh::IsRevealed() const { | 452 bool ImmersiveModeControllerAsh::IsRevealed() const { |
| 444 return enabled_ && reveal_state_ != CLOSED; | 453 return enabled_ && reveal_state_ != CLOSED; |
| 445 } | 454 } |
| 446 | 455 |
| (...skipping 21 matching lines...) Expand all Loading... | |
| 468 anchored_widget_manager_->RemoveAnchoredWidget(widget); | 477 anchored_widget_manager_->RemoveAnchoredWidget(widget); |
| 469 } | 478 } |
| 470 | 479 |
| 471 void ImmersiveModeControllerAsh::OnTopContainerBoundsChanged() { | 480 void ImmersiveModeControllerAsh::OnTopContainerBoundsChanged() { |
| 472 anchored_widget_manager_->MaybeRepositionAnchoredWidgets(); | 481 anchored_widget_manager_->MaybeRepositionAnchoredWidgets(); |
| 473 } | 482 } |
| 474 | 483 |
| 475 //////////////////////////////////////////////////////////////////////////////// | 484 //////////////////////////////////////////////////////////////////////////////// |
| 476 // Observers: | 485 // Observers: |
| 477 | 486 |
| 487 void ImmersiveModeControllerAsh::Observe( | |
| 488 int type, | |
| 489 const content::NotificationSource& source, | |
| 490 const content::NotificationDetails& details) { | |
| 491 DCHECK_EQ(chrome::NOTIFICATION_FULLSCREEN_CHANGED, type); | |
| 492 UpdateUseMinimalChrome(false); | |
| 493 } | |
| 494 | |
| 478 void ImmersiveModeControllerAsh::OnMouseEvent(ui::MouseEvent* event) { | 495 void ImmersiveModeControllerAsh::OnMouseEvent(ui::MouseEvent* event) { |
| 479 if (!enabled_) | 496 if (!enabled_) |
| 480 return; | 497 return; |
| 481 | 498 |
| 482 if (event->flags() & ui::EF_IS_SYNTHESIZED) | 499 if (event->flags() & ui::EF_IS_SYNTHESIZED) |
| 483 return; | 500 return; |
| 484 | 501 |
| 485 // Handle ET_MOUSE_PRESSED and ET_MOUSE_RELEASED so that we get the updated | 502 // Handle ET_MOUSE_PRESSED and ET_MOUSE_RELEASED so that we get the updated |
| 486 // mouse position ASAP once a nested message loop finishes running. | 503 // mouse position ASAP once a nested message loop finishes running. |
| 487 if (event->type() != ui::ET_MOUSE_MOVED && | 504 if (event->type() != ui::ET_MOUSE_MOVED && |
| (...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 551 void ImmersiveModeControllerAsh::OnImplicitAnimationsCompleted() { | 568 void ImmersiveModeControllerAsh::OnImplicitAnimationsCompleted() { |
| 552 if (reveal_state_ == SLIDING_OPEN) | 569 if (reveal_state_ == SLIDING_OPEN) |
| 553 OnSlideOpenAnimationCompleted(); | 570 OnSlideOpenAnimationCompleted(); |
| 554 else if (reveal_state_ == SLIDING_CLOSED) | 571 else if (reveal_state_ == SLIDING_CLOSED) |
| 555 OnSlideClosedAnimationCompleted(); | 572 OnSlideClosedAnimationCompleted(); |
| 556 } | 573 } |
| 557 | 574 |
| 558 //////////////////////////////////////////////////////////////////////////////// | 575 //////////////////////////////////////////////////////////////////////////////// |
| 559 // Testing interface: | 576 // Testing interface: |
| 560 | 577 |
| 561 void ImmersiveModeControllerAsh::SetHideTabIndicatorsForTest(bool hide) { | 578 void ImmersiveModeControllerAsh::SetForceHideTabIndicatorsForTest(bool force) { |
| 562 hide_tab_indicators_ = hide; | 579 if (force) |
| 580 tab_indicator_visibility_ = TAB_INDICATORS_FORCE_HIDE; | |
| 581 else if (tab_indicator_visibility_ == TAB_INDICATORS_FORCE_HIDE) | |
| 582 tab_indicator_visibility_ = TAB_INDICATORS_HIDE; | |
| 583 UpdateUseMinimalChrome(false); | |
| 563 } | 584 } |
| 564 | 585 |
| 565 void ImmersiveModeControllerAsh::StartRevealForTest(bool hovered) { | 586 void ImmersiveModeControllerAsh::StartRevealForTest(bool hovered) { |
| 566 MaybeStartReveal(ANIMATE_NO); | 587 MaybeStartReveal(ANIMATE_NO); |
| 567 MoveMouse(browser_view_->top_container(), hovered); | 588 MoveMouse(browser_view_->top_container(), hovered); |
| 568 UpdateMouseRevealedLock(false); | 589 UpdateMouseRevealedLock(false); |
| 569 } | 590 } |
| 570 | 591 |
| 571 void ImmersiveModeControllerAsh::SetMouseHoveredForTest(bool hovered) { | 592 void ImmersiveModeControllerAsh::SetMouseHoveredForTest(bool hovered) { |
| 572 MoveMouse(browser_view_->top_container(), hovered); | 593 MoveMouse(browser_view_->top_container(), hovered); |
| (...skipping 21 matching lines...) Expand all Loading... | |
| 594 } | 615 } |
| 595 | 616 |
| 596 if (enable) | 617 if (enable) |
| 597 native_window_->AddPreTargetHandler(this); | 618 native_window_->AddPreTargetHandler(this); |
| 598 else | 619 else |
| 599 native_window_->RemovePreTargetHandler(this); | 620 native_window_->RemovePreTargetHandler(this); |
| 600 | 621 |
| 601 // The window observer adds and removes itself from the native window. | 622 // The window observer adds and removes itself from the native window. |
| 602 window_observer_.reset(enable ? new WindowObserver(this) : NULL); | 623 window_observer_.reset(enable ? new WindowObserver(this) : NULL); |
| 603 | 624 |
| 625 if (enable) { | |
| 626 registrar_.Add( | |
| 627 this, | |
| 628 chrome::NOTIFICATION_FULLSCREEN_CHANGED, | |
| 629 content::Source<FullscreenController>( | |
| 630 browser_view_->browser()->fullscreen_controller())); | |
| 631 } else { | |
| 632 registrar_.Remove( | |
| 633 this, | |
| 634 chrome::NOTIFICATION_FULLSCREEN_CHANGED, | |
| 635 content::Source<FullscreenController>( | |
| 636 browser_view_->browser()->fullscreen_controller())); | |
| 637 } | |
| 638 | |
| 604 if (!enable) | 639 if (!enable) |
| 605 StopObservingImplicitAnimations(); | 640 StopObservingImplicitAnimations(); |
| 606 } | 641 } |
| 607 | 642 |
| 608 void ImmersiveModeControllerAsh::UpdateMouseRevealedLock(bool maybe_drag) { | 643 void ImmersiveModeControllerAsh::UpdateMouseRevealedLock(bool maybe_drag) { |
| 609 if (!enabled_) | 644 if (!enabled_) |
| 610 return; | 645 return; |
| 611 | 646 |
| 612 // Hover cannot initiate a reveal when the top-of-window views are sliding | 647 // Hover cannot initiate a reveal when the top-of-window views are sliding |
| 613 // closed or are closed. (With the exception of hovering at y = 0 which is | 648 // 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 Loading... | |
| 670 } | 705 } |
| 671 | 706 |
| 672 if (hold_lock) { | 707 if (hold_lock) { |
| 673 if (!focus_revealed_lock_.get()) | 708 if (!focus_revealed_lock_.get()) |
| 674 focus_revealed_lock_.reset(GetRevealedLock()); | 709 focus_revealed_lock_.reset(GetRevealedLock()); |
| 675 } else { | 710 } else { |
| 676 focus_revealed_lock_.reset(); | 711 focus_revealed_lock_.reset(); |
| 677 } | 712 } |
| 678 } | 713 } |
| 679 | 714 |
| 715 void ImmersiveModeControllerAsh::UpdateUseMinimalChrome(bool skip_layout) { | |
| 716 bool use_minimal_chrome = !browser_view_->browser()->fullscreen_controller()-> | |
| 717 IsFullscreenForTabOrPending(); | |
| 718 native_window_->SetProperty(ash::internal::kFullscreenUsesMinimalChromeKey, | |
| 719 use_minimal_chrome); | |
| 720 | |
| 721 TabIndicatorVisibility previous_tab_indicator_visibility = | |
| 722 tab_indicator_visibility_; | |
| 723 if (tab_indicator_visibility_ != TAB_INDICATORS_FORCE_HIDE) { | |
| 724 tab_indicator_visibility_ = use_minimal_chrome ? | |
| 725 TAB_INDICATORS_SHOW : TAB_INDICATORS_HIDE; | |
| 726 } | |
| 727 | |
| 728 if (!enabled_) | |
| 729 return; | |
| 730 | |
| 731 // Ash on Windows may not have a shell. | |
| 732 if (ash::Shell::HasInstance()) { | |
| 733 // When using minimal chrome, the shelf is auto-hidden. The auto-hidden | |
| 734 // shelf displays a 3px 'light bar' when it is closed. | |
| 735 ash::Shell::GetInstance()->UpdateShelfVisibility(); | |
| 736 } | |
| 737 | |
| 738 if (tab_indicator_visibility_ != previous_tab_indicator_visibility) { | |
| 739 // If the top-of-window views are revealed or animating, the change will | |
| 740 // take effect with the layout once the top-of-window views are closed. | |
| 741 if (!skip_layout && reveal_state_ == CLOSED) | |
| 742 LayoutBrowserView(true); | |
| 743 } | |
| 744 } | |
| 745 | |
| 680 int ImmersiveModeControllerAsh::GetAnimationDuration(Animate animate) const { | 746 int ImmersiveModeControllerAsh::GetAnimationDuration(Animate animate) const { |
| 681 switch (animate) { | 747 switch (animate) { |
| 682 case ANIMATE_NO: | 748 case ANIMATE_NO: |
| 683 return 0; | 749 return 0; |
| 684 case ANIMATE_SLOW: | 750 case ANIMATE_SLOW: |
| 685 return kRevealSlowAnimationDurationMs; | 751 return kRevealSlowAnimationDurationMs; |
| 686 case ANIMATE_FAST: | 752 case ANIMATE_FAST: |
| 687 return kRevealFastAnimationDurationMs; | 753 return kRevealFastAnimationDurationMs; |
| 688 } | 754 } |
| 689 NOTREACHED(); | 755 NOTREACHED(); |
| (...skipping 156 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 846 ui::ScopedLayerAnimationSettings settings(layer->GetAnimator()); | 912 ui::ScopedLayerAnimationSettings settings(layer->GetAnimator()); |
| 847 settings.SetTweenType(ui::Tween::EASE_OUT); | 913 settings.SetTweenType(ui::Tween::EASE_OUT); |
| 848 settings.SetTransitionDuration( | 914 settings.SetTransitionDuration( |
| 849 base::TimeDelta::FromMilliseconds(duration_ms)); | 915 base::TimeDelta::FromMilliseconds(duration_ms)); |
| 850 settings.SetPreemptionStrategy( | 916 settings.SetPreemptionStrategy( |
| 851 ui::LayerAnimator::IMMEDIATELY_ANIMATE_TO_NEW_TARGET); | 917 ui::LayerAnimator::IMMEDIATELY_ANIMATE_TO_NEW_TARGET); |
| 852 if (observer) | 918 if (observer) |
| 853 settings.AddObserver(observer); | 919 settings.AddObserver(observer); |
| 854 layer->SetTransform(target_transform); | 920 layer->SetTransform(target_transform); |
| 855 } | 921 } |
| OLD | NEW |