123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801 |
- // Copyright 2016 The Chromium Authors. All rights reserved.
- // Use of this source code is governed by a BSD-style license that can be
- // found in the LICENSE file.
- #include "ash/shelf/shelf.h"
- #include <memory>
- #include "ash/animation/animation_change_type.h"
- #include "ash/app_list/app_list_controller_impl.h"
- #include "ash/constants/ash_features.h"
- #include "ash/constants/ash_switches.h"
- #include "ash/public/cpp/keyboard/keyboard_controller_observer.h"
- #include "ash/public/cpp/shelf_item_delegate.h"
- #include "ash/public/cpp/shelf_model.h"
- #include "ash/public/cpp/shelf_types.h"
- #include "ash/public/cpp/shell_window_ids.h"
- #include "ash/root_window_controller.h"
- #include "ash/shelf/hotseat_widget.h"
- #include "ash/shelf/login_shelf_widget.h"
- #include "ash/shelf/shelf_controller.h"
- #include "ash/shelf/shelf_focus_cycler.h"
- #include "ash/shelf/shelf_layout_manager.h"
- #include "ash/shelf/shelf_layout_manager_observer.h"
- #include "ash/shelf/shelf_navigation_widget.h"
- #include "ash/shelf/shelf_observer.h"
- #include "ash/shelf/shelf_tooltip_manager.h"
- #include "ash/shelf/shelf_widget.h"
- #include "ash/shell.h"
- #include "ash/system/status_area_widget.h"
- #include "ash/wm/work_area_insets.h"
- #include "base/bind.h"
- #include "base/callback_helpers.h"
- #include "base/check.h"
- #include "base/i18n/rtl.h"
- #include "base/memory/weak_ptr.h"
- #include "base/metrics/histogram_macros.h"
- #include "base/notreached.h"
- #include "ui/display/types/display_constants.h"
- #include "ui/gfx/geometry/rect.h"
- namespace ash {
- namespace {
- bool IsAppListBackground(ShelfBackgroundType background_type) {
- switch (background_type) {
- case ShelfBackgroundType::kAppList:
- case ShelfBackgroundType::kHomeLauncher:
- case ShelfBackgroundType::kMaximizedWithAppList:
- return true;
- case ShelfBackgroundType::kDefaultBg:
- case ShelfBackgroundType::kMaximized:
- case ShelfBackgroundType::kOobe:
- case ShelfBackgroundType::kLogin:
- case ShelfBackgroundType::kLoginNonBlurredWallpaper:
- case ShelfBackgroundType::kOverview:
- case ShelfBackgroundType::kInApp:
- return false;
- }
- }
- bool IsBottomAlignment(ShelfAlignment alignment) {
- return alignment == ShelfAlignment::kBottom ||
- alignment == ShelfAlignment::kBottomLocked;
- }
- } // namespace
- // Records smoothness of bounds animations for the HotseatWidget.
- class HotseatWidgetAnimationMetricsReporter {
- public:
- // The different kinds of hotseat elements.
- enum class HotseatElementType {
- // The Hotseat Widget.
- kWidget,
- // The Hotseat Widget's translucent background.
- kTranslucentBackground
- };
- explicit HotseatWidgetAnimationMetricsReporter(
- HotseatElementType hotseat_element)
- : hotseat_element_(hotseat_element) {}
- ~HotseatWidgetAnimationMetricsReporter() = default;
- void ReportSmoothness(HotseatState target_state, int smoothness) {
- switch (target_state) {
- case HotseatState::kShownClamshell:
- case HotseatState::kShownHomeLauncher:
- if (hotseat_element_ == HotseatElementType::kWidget) {
- UMA_HISTOGRAM_PERCENTAGE(
- "Ash.HotseatWidgetAnimation.Widget.AnimationSmoothness."
- "TransitionToShownHotseat",
- smoothness);
- } else {
- UMA_HISTOGRAM_PERCENTAGE(
- "Ash.HotseatWidgetAnimation.TranslucentBackground."
- "AnimationSmoothness.TransitionToShownHotseat",
- smoothness);
- }
- break;
- case HotseatState::kExtended:
- if (hotseat_element_ == HotseatElementType::kWidget) {
- UMA_HISTOGRAM_PERCENTAGE(
- "Ash.HotseatWidgetAnimation.Widget.AnimationSmoothness."
- "TransitionToExtendedHotseat",
- smoothness);
- } else {
- UMA_HISTOGRAM_PERCENTAGE(
- "Ash.HotseatWidgetAnimation.TranslucentBackground."
- "AnimationSmoothness.TransitionToExtendedHotseat",
- smoothness);
- }
- break;
- case HotseatState::kHidden:
- if (hotseat_element_ == HotseatElementType::kWidget) {
- UMA_HISTOGRAM_PERCENTAGE(
- "Ash.HotseatWidgetAnimation.Widget.AnimationSmoothness."
- "TransitionToHiddenHotseat",
- smoothness);
- } else {
- UMA_HISTOGRAM_PERCENTAGE(
- "Ash.HotseatWidgetAnimation.TranslucentBackground."
- "AnimationSmoothness.TransitionToHiddenHotseat",
- smoothness);
- }
- break;
- case HotseatState::kNone:
- NOTREACHED();
- break;
- }
- }
- metrics_util::ReportCallback GetReportCallback(HotseatState target_state) {
- DCHECK_NE(target_state, HotseatState::kNone);
- return metrics_util::ForSmoothness(base::BindRepeating(
- &HotseatWidgetAnimationMetricsReporter::ReportSmoothness,
- weak_ptr_factory_.GetWeakPtr(), target_state));
- }
- private:
- // The element that is reporting an animation.
- const HotseatElementType hotseat_element_;
- base::WeakPtrFactory<HotseatWidgetAnimationMetricsReporter> weak_ptr_factory_{
- this};
- };
- // An animation metrics reporter for the shelf navigation widget.
- class ASH_EXPORT NavigationWidgetAnimationMetricsReporter {
- public:
- NavigationWidgetAnimationMetricsReporter() = default;
- ~NavigationWidgetAnimationMetricsReporter() = default;
- NavigationWidgetAnimationMetricsReporter(
- const NavigationWidgetAnimationMetricsReporter&) = delete;
- NavigationWidgetAnimationMetricsReporter& operator=(
- const NavigationWidgetAnimationMetricsReporter&) = delete;
- void ReportSmoothness(HotseatState target_hotseat_state, int smoothness) {
- switch (target_hotseat_state) {
- case HotseatState::kShownClamshell:
- case HotseatState::kShownHomeLauncher:
- UMA_HISTOGRAM_PERCENTAGE(
- "Ash.NavigationWidget.Widget.AnimationSmoothness."
- "TransitionToShownHotseat",
- smoothness);
- break;
- case HotseatState::kExtended:
- UMA_HISTOGRAM_PERCENTAGE(
- "Ash.NavigationWidget.Widget.AnimationSmoothness."
- "TransitionToExtendedHotseat",
- smoothness);
- break;
- case HotseatState::kHidden:
- UMA_HISTOGRAM_PERCENTAGE(
- "Ash.NavigationWidget.Widget.AnimationSmoothness."
- "TransitionToHiddenHotseat",
- smoothness);
- break;
- case HotseatState::kNone:
- NOTREACHED();
- break;
- }
- }
- metrics_util::ReportCallback GetReportCallback(
- HotseatState target_hotseat_state) {
- DCHECK_NE(target_hotseat_state, HotseatState::kNone);
- return metrics_util::ForSmoothness(base::BindRepeating(
- &NavigationWidgetAnimationMetricsReporter::ReportSmoothness,
- weak_ptr_factory_.GetWeakPtr(), target_hotseat_state));
- }
- private:
- base::WeakPtrFactory<NavigationWidgetAnimationMetricsReporter>
- weak_ptr_factory_{this};
- };
- // Shelf::AutoHideEventHandler -----------------------------------------------
- // Forwards mouse and gesture events to ShelfLayoutManager for auto-hide.
- class Shelf::AutoHideEventHandler : public ui::EventHandler {
- public:
- explicit AutoHideEventHandler(Shelf* shelf) : shelf_(shelf) {
- Shell::Get()->AddPreTargetHandler(this);
- }
- AutoHideEventHandler(const AutoHideEventHandler&) = delete;
- AutoHideEventHandler& operator=(const AutoHideEventHandler&) = delete;
- ~AutoHideEventHandler() override {
- Shell::Get()->RemovePreTargetHandler(this);
- }
- // ui::EventHandler:
- void OnMouseEvent(ui::MouseEvent* event) override {
- shelf_->shelf_layout_manager()->UpdateAutoHideForMouseEvent(
- event, static_cast<aura::Window*>(event->target()));
- }
- void OnGestureEvent(ui::GestureEvent* event) override {
- shelf_->shelf_layout_manager()->ProcessGestureEventOfAutoHideShelf(
- event, static_cast<aura::Window*>(event->target()));
- }
- void OnTouchEvent(ui::TouchEvent* event) override {
- if (shelf_->auto_hide_behavior() != ShelfAutoHideBehavior::kAlways)
- return;
- // The event target should be the shelf widget or the hotseat widget.
- if (!shelf_->shelf_layout_manager()->IsShelfWindow(
- static_cast<aura::Window*>(event->target()))) {
- return;
- }
- // The touch-pressing event may hide the shelf. Lock the shelf's auto hide
- // state to give the shelf a chance to handle the touch event before it
- // being hidden.
- ShelfLayoutManager* shelf_layout_manager = shelf_->shelf_layout_manager();
- if (event->type() == ui::ET_TOUCH_PRESSED && shelf_->IsVisible()) {
- shelf_layout_manager->LockAutoHideState(true);
- } else if (event->type() == ui::ET_TOUCH_RELEASED ||
- event->type() == ui::ET_TOUCH_CANCELLED) {
- // Unlock auto hide (and eventually recompute auto hide state).
- shelf_layout_manager->LockAutoHideState(false);
- }
- }
- private:
- Shelf* shelf_;
- };
- // Shelf::AutoDimEventHandler -----------------------------------------------
- // Handles mouse and touch events and determines whether ShelfLayoutManager
- // should update shelf opacity for auto-dimming.
- class Shelf::AutoDimEventHandler : public ui::EventHandler,
- public ShelfObserver {
- public:
- explicit AutoDimEventHandler(Shelf* shelf) : shelf_(shelf) {
- Shell::Get()->AddPreTargetHandler(this);
- shelf_observation_.Observe(shelf_);
- UndimShelf();
- }
- AutoDimEventHandler(const AutoDimEventHandler&) = delete;
- AutoDimEventHandler& operator=(const AutoDimEventHandler&) = delete;
- ~AutoDimEventHandler() override {
- Shell::Get()->RemovePreTargetHandler(this);
- }
- // ui::EventHandler:
- void OnMouseEvent(ui::MouseEvent* event) override {
- if (shelf_->shelf_layout_manager()->IsShelfWindow(
- static_cast<aura::Window*>(event->target()))) {
- UndimShelf();
- }
- }
- void OnTouchEvent(ui::TouchEvent* event) override {
- if (shelf_->shelf_layout_manager()->IsShelfWindow(
- static_cast<aura::Window*>(event->target()))) {
- UndimShelf();
- }
- }
- void StartDimShelfTimer() {
- dim_shelf_timer_.Start(
- FROM_HERE, kDimDelay,
- base::BindOnce(&AutoDimEventHandler::DimShelf, base::Unretained(this)));
- }
- void DimShelf() {
- // Attempt to dim the shelf. Stop the |dim_shelf_timer_| if successful.
- if (shelf_->shelf_layout_manager()->SetDimmed(true))
- dim_shelf_timer_.Stop();
- }
- // Sets shelf as active and sets timer to mark shelf as inactive.
- void UndimShelf() {
- shelf_->shelf_layout_manager()->SetDimmed(false);
- StartDimShelfTimer();
- }
- bool HasDimShelfTimer() { return dim_shelf_timer_.IsRunning(); }
- // ShelfObserver:
- void OnAutoHideStateChanged(ShelfAutoHideState new_state) override {
- // Shelf should be undimmed when it is shown.
- if (new_state == ShelfAutoHideState::SHELF_AUTO_HIDE_SHOWN)
- UndimShelf();
- }
- // ShelfObserver:
- void WillChangeVisibilityState(ShelfVisibilityState new_state) override {
- // Shelf should be undimmed when it is shown.
- if (new_state != ShelfVisibilityState::SHELF_HIDDEN)
- UndimShelf();
- }
- private:
- // Unowned pointer to the shelf that owns this event handler.
- Shelf* shelf_;
- // OneShotTimer that dims shelf due to inactivity.
- base::OneShotTimer dim_shelf_timer_;
- // An observer that notifies the AutoDimHandler that shelf visibility has
- // changed.
- base::ScopedObservation<Shelf, ShelfObserver> shelf_observation_{this};
- // Delay before dimming the shelf.
- const base::TimeDelta kDimDelay = base::Seconds(5);
- };
- // Shelf ---------------------------------------------------------------------
- Shelf::Shelf()
- : shelf_locking_manager_(this),
- shelf_focus_cycler_(std::make_unique<ShelfFocusCycler>(this)),
- tooltip_(std::make_unique<ShelfTooltipManager>(this)) {}
- Shelf::~Shelf() = default;
- // static
- Shelf* Shelf::ForWindow(aura::Window* window) {
- return RootWindowController::ForWindow(window)->shelf();
- }
- // static
- void Shelf::LaunchShelfItem(int item_index) {
- const int item_count = ShelfModel::Get()->item_count();
- // A negative argument will launch the last app. A positive argument will
- // launch the app at the corresponding index, unless it's higher than the
- // total number of apps, in which case we do nothing.
- if (item_index >= item_count)
- return;
- const int found_index = item_index >= 0 ? item_index : item_count - 1;
- // Set this one as active (or advance to the next item of its kind).
- ActivateShelfItem(found_index);
- }
- // static
- void Shelf::ActivateShelfItem(int item_index) {
- ActivateShelfItemOnDisplay(item_index, display::kInvalidDisplayId);
- }
- // static
- void Shelf::ActivateShelfItemOnDisplay(int item_index, int64_t display_id) {
- const ShelfModel* shelf_model = ShelfModel::Get();
- const ShelfItem& item = shelf_model->items()[item_index];
- ShelfItemDelegate* item_delegate = shelf_model->GetShelfItemDelegate(item.id);
- std::unique_ptr<ui::Event> event = std::make_unique<ui::KeyEvent>(
- ui::ET_KEY_RELEASED, ui::VKEY_UNKNOWN, ui::EF_NONE);
- item_delegate->ItemSelected(std::move(event), display_id, LAUNCH_FROM_SHELF,
- base::DoNothing(), base::NullCallback());
- }
- // static
- void Shelf::UpdateShelfVisibility() {
- for (auto* root : Shell::Get()->GetAllRootWindows()) {
- Shelf::ForWindow(root)->UpdateVisibilityState();
- }
- }
- void Shelf::CreateNavigationWidget(aura::Window* container) {
- DCHECK(container);
- DCHECK(!navigation_widget_);
- navigation_widget_ = std::make_unique<ShelfNavigationWidget>(
- this, hotseat_widget()->GetShelfView());
- navigation_widget_->Initialize(container);
- navigation_widget_metrics_reporter_ =
- std::make_unique<NavigationWidgetAnimationMetricsReporter>();
- }
- void Shelf::CreateHotseatWidget(aura::Window* container) {
- DCHECK(container);
- DCHECK(!hotseat_widget_);
- hotseat_widget_ = std::make_unique<HotseatWidget>();
- translucent_background_metrics_reporter_ =
- std::make_unique<HotseatWidgetAnimationMetricsReporter>(
- HotseatWidgetAnimationMetricsReporter::HotseatElementType::
- kTranslucentBackground);
- hotseat_widget_->Initialize(container, this);
- shelf_widget_->RegisterHotseatWidget(hotseat_widget());
- hotseat_transition_metrics_reporter_ =
- std::make_unique<HotseatWidgetAnimationMetricsReporter>(
- HotseatWidgetAnimationMetricsReporter::HotseatElementType::kWidget);
- }
- void Shelf::CreateStatusAreaWidget(aura::Window* shelf_container) {
- DCHECK(shelf_container);
- DCHECK(!status_area_widget_);
- status_area_widget_ =
- std::make_unique<StatusAreaWidget>(shelf_container, this);
- status_area_widget_->Initialize();
- }
- void Shelf::CreateShelfWidget(aura::Window* root) {
- DCHECK(!shelf_widget_);
- aura::Window* shelf_container =
- root->GetChildById(kShellWindowId_ShelfContainer);
- shelf_widget_ = std::make_unique<ShelfWidget>(this);
- DCHECK(!shelf_layout_manager_);
- shelf_layout_manager_ = shelf_widget_->shelf_layout_manager();
- shelf_layout_manager_->AddObserver(this);
- // Create the various shelf components.
- CreateHotseatWidget(shelf_container);
- CreateNavigationWidget(shelf_container);
- if (features::IsUseLoginShelfWidgetEnabled()) {
- login_shelf_widget_ =
- std::make_unique<LoginShelfWidget>(/*shelf=*/this, shelf_container);
- }
- // Must occur after |shelf_widget_| is constructed because the system tray
- // constructors call back into Shelf::shelf_widget().
- CreateStatusAreaWidget(shelf_container);
- shelf_widget_->Initialize(shelf_container);
- shelf_widget_->GetNativeWindow()->parent()->StackChildAtBottom(
- shelf_widget_->GetNativeWindow());
- // The Hotseat should be above everything in the shelf.
- hotseat_widget()->StackAtTop();
- }
- void Shelf::ShutdownShelfWidget() {
- for (auto& observer : observers_)
- observer.OnShelfShuttingDown();
- // Remove observers prior to destroying child widgets, this prevents
- // activation changes from triggering during shutdown, see
- // https://crbug.com/1307898.
- shelf_widget_->Shutdown();
- // The contents view of the hotseat widget may rely on the status area widget.
- // So do explicit destruction here.
- hotseat_widget_.reset();
- status_area_widget_.reset();
- navigation_widget_.reset();
- login_shelf_widget_.reset();
- }
- void Shelf::DestroyShelfWidget() {
- DCHECK(shelf_widget_);
- shelf_widget_.reset();
- }
- bool Shelf::IsVisible() const {
- return shelf_layout_manager_->IsVisible();
- }
- const aura::Window* Shelf::GetWindow() const {
- return shelf_widget_ ? shelf_widget_->GetNativeWindow() : nullptr;
- }
- aura::Window* Shelf::GetWindow() {
- return const_cast<aura::Window*>(const_cast<const Shelf*>(this)->GetWindow());
- }
- void Shelf::SetAlignment(ShelfAlignment alignment) {
- if (!shelf_widget_)
- return;
- if (alignment_ == alignment)
- return;
- if (shelf_locking_manager_.is_locked() &&
- alignment != ShelfAlignment::kBottomLocked) {
- shelf_locking_manager_.set_stored_alignment(alignment);
- return;
- }
- bool needs_relayout =
- !IsBottomAlignment(alignment_) || !IsBottomAlignment(alignment);
- ShelfAlignment old_alignment = alignment_;
- alignment_ = alignment;
- tooltip_->Close();
- if (needs_relayout) {
- shelf_layout_manager_->LayoutShelf();
- Shell::Get()->NotifyShelfAlignmentChanged(GetWindow()->GetRootWindow(),
- old_alignment);
- }
- }
- bool IsHorizontalAlignment(ShelfAlignment alignment) {
- switch (alignment) {
- case ShelfAlignment::kBottom:
- case ShelfAlignment::kBottomLocked:
- return true;
- case ShelfAlignment::kLeft:
- case ShelfAlignment::kRight:
- return false;
- }
- NOTREACHED();
- return true;
- }
- bool Shelf::IsHorizontalAlignment() const {
- return ash::IsHorizontalAlignment(alignment_);
- }
- void Shelf::SetAutoHideBehavior(ShelfAutoHideBehavior auto_hide_behavior) {
- DCHECK(shelf_layout_manager_);
- if (auto_hide_behavior_ == auto_hide_behavior)
- return;
- auto_hide_behavior_ = auto_hide_behavior;
- for (auto& observer : observers_)
- observer.OnShelfAutoHideBehaviorChanged();
- }
- ShelfAutoHideState Shelf::GetAutoHideState() const {
- return shelf_layout_manager_->auto_hide_state();
- }
- void Shelf::UpdateAutoHideState() {
- shelf_layout_manager_->UpdateAutoHideState();
- }
- ShelfBackgroundType Shelf::GetBackgroundType() const {
- return shelf_widget_ ? shelf_widget_->GetBackgroundType()
- : ShelfBackgroundType::kDefaultBg;
- }
- void Shelf::UpdateVisibilityState() {
- if (shelf_layout_manager_)
- shelf_layout_manager_->UpdateVisibilityState();
- }
- void Shelf::MaybeUpdateShelfBackground() {
- if (!shelf_layout_manager_)
- return;
- shelf_layout_manager_->MaybeUpdateShelfBackground(
- AnimationChangeType::ANIMATE);
- }
- ShelfVisibilityState Shelf::GetVisibilityState() const {
- return shelf_layout_manager_ ? shelf_layout_manager_->visibility_state()
- : SHELF_HIDDEN;
- }
- gfx::Rect Shelf::GetShelfBoundsInScreen() const {
- return shelf_widget()->GetTargetBounds();
- }
- gfx::Rect Shelf::GetIdealBounds() const {
- return shelf_layout_manager_->GetIdealBounds();
- }
- gfx::Rect Shelf::GetIdealBoundsForWorkAreaCalculation() {
- return shelf_layout_manager_->GetIdealBoundsForWorkAreaCalculation();
- }
- gfx::Rect Shelf::GetScreenBoundsOfItemIconForWindow(aura::Window* window) {
- if (!shelf_widget_)
- return gfx::Rect();
- return shelf_widget_->GetScreenBoundsOfItemIconForWindow(window);
- }
- bool Shelf::ProcessGestureEvent(const ui::GestureEvent& event) {
- // Can be called at login screen.
- if (!shelf_layout_manager_)
- return false;
- return shelf_layout_manager_->ProcessGestureEvent(event);
- }
- void Shelf::ProcessMouseEvent(const ui::MouseEvent& event) {
- if (shelf_layout_manager_)
- shelf_layout_manager_->ProcessMouseEventFromShelf(event);
- }
- void Shelf::ProcessScrollEvent(ui::ScrollEvent* event) {
- if (event->finger_count() != 2 || event->type() != ui::ET_SCROLL)
- return;
- if (!shelf_layout_manager_->is_active_session_state())
- return;
- // Productivity launcher does not show or hide on scroll events. The legacy
- // peeking launcher had this behavior, but it doesn't make sense for a bubble.
- if (features::IsProductivityLauncherEnabled())
- return;
- auto* app_list_controller = Shell::Get()->app_list_controller();
- DCHECK(app_list_controller);
- // If the App List is not visible, send Scroll events to the
- // |shelf_layout_manager_| because these events are used to show the App
- // List.
- if (app_list_controller->IsVisible(shelf_layout_manager_->display_.id())) {
- app_list_controller->ProcessScrollEvent(*event);
- } else {
- shelf_layout_manager_->ProcessScrollEventFromShelf(event);
- }
- event->SetHandled();
- }
- void Shelf::ProcessMouseWheelEvent(ui::MouseWheelEvent* event) {
- if (!shelf_layout_manager_->is_active_session_state() ||
- !IsHorizontalAlignment())
- return;
- // Productivity launcher does not show or hide on wheel events. The legacy
- // peeking launcher had this behavior, but it doesn't make sense for a bubble.
- if (features::IsProductivityLauncherEnabled())
- return;
- auto* app_list_controller = Shell::Get()->app_list_controller();
- DCHECK(app_list_controller);
- // If the App List is not visible, send MouseWheel events to the
- // |shelf_layout_manager_| because these events are used to show the App List.
- if (app_list_controller->IsVisible(shelf_layout_manager_->display_.id())) {
- app_list_controller->ProcessMouseWheelEvent(*event);
- } else {
- shelf_layout_manager_->ProcessMouseWheelEventFromShelf(event);
- }
- event->SetHandled();
- }
- void Shelf::AddObserver(ShelfObserver* observer) {
- observers_.AddObserver(observer);
- }
- void Shelf::RemoveObserver(ShelfObserver* observer) {
- observers_.RemoveObserver(observer);
- }
- void Shelf::NotifyShelfIconPositionsChanged() {
- for (auto& observer : observers_)
- observer.OnShelfIconPositionsChanged();
- }
- StatusAreaWidget* Shelf::GetStatusAreaWidget() const {
- return shelf_widget_ ? shelf_widget_->status_area_widget() : nullptr;
- }
- gfx::Rect Shelf::GetSystemTrayAnchorRect() const {
- gfx::Rect work_area = GetWorkAreaInsets()->user_work_area_bounds();
- switch (alignment_) {
- case ShelfAlignment::kBottom:
- case ShelfAlignment::kBottomLocked:
- return gfx::Rect(
- base::i18n::IsRTL() ? work_area.x() : work_area.right() - 1,
- work_area.bottom() - 1, 0, 0);
- case ShelfAlignment::kLeft:
- return gfx::Rect(work_area.x(), work_area.bottom() - 1, 0, 0);
- case ShelfAlignment::kRight:
- return gfx::Rect(work_area.right() - 1, work_area.bottom() - 1, 0, 0);
- }
- NOTREACHED();
- return gfx::Rect();
- }
- bool Shelf::ShouldHideOnSecondaryDisplay(session_manager::SessionState state) {
- if (Shell::GetPrimaryRootWindowController()->shelf() == this)
- return false;
- return state != session_manager::SessionState::ACTIVE;
- }
- void Shelf::SetVirtualKeyboardBoundsForTesting(const gfx::Rect& bounds) {
- KeyboardStateDescriptor state;
- state.is_visible = !bounds.IsEmpty();
- state.visual_bounds = bounds;
- state.occluded_bounds_in_screen = bounds;
- state.displaced_bounds_in_screen = gfx::Rect();
- WorkAreaInsets* work_area_insets = GetWorkAreaInsets();
- work_area_insets->OnKeyboardVisibilityChanged(state.is_visible);
- work_area_insets->OnKeyboardVisibleBoundsChanged(state.visual_bounds);
- work_area_insets->OnKeyboardOccludedBoundsChanged(
- state.occluded_bounds_in_screen);
- work_area_insets->OnKeyboardDisplacingBoundsChanged(
- state.displaced_bounds_in_screen);
- work_area_insets->OnKeyboardAppearanceChanged(state);
- }
- ShelfLockingManager* Shelf::GetShelfLockingManagerForTesting() {
- return &shelf_locking_manager_;
- }
- ShelfView* Shelf::GetShelfViewForTesting() {
- return shelf_widget_->shelf_view_for_testing();
- }
- metrics_util::ReportCallback Shelf::GetHotseatTransitionReportCallback(
- HotseatState target_state) {
- return hotseat_transition_metrics_reporter_->GetReportCallback(target_state);
- }
- metrics_util::ReportCallback Shelf::GetTranslucentBackgroundReportCallback(
- HotseatState target_state) {
- return translucent_background_metrics_reporter_->GetReportCallback(
- target_state);
- }
- metrics_util::ReportCallback Shelf::GetNavigationWidgetAnimationReportCallback(
- HotseatState target_hotseat_state) {
- return navigation_widget_metrics_reporter_->GetReportCallback(
- target_hotseat_state);
- }
- void Shelf::WillDeleteShelfLayoutManager() {
- // Clear event handlers that might forward events to the destroyed instance.
- auto_hide_event_handler_.reset();
- auto_dim_event_handler_.reset();
- navigation_widget_metrics_reporter_.reset();
- DCHECK(shelf_layout_manager_);
- shelf_layout_manager_->RemoveObserver(this);
- shelf_layout_manager_ = nullptr;
- }
- void Shelf::WillChangeVisibilityState(ShelfVisibilityState new_state) {
- for (auto& observer : observers_)
- observer.WillChangeVisibilityState(new_state);
- if (new_state != SHELF_AUTO_HIDE) {
- auto_hide_event_handler_.reset();
- } else if (!auto_hide_event_handler_) {
- auto_hide_event_handler_ = std::make_unique<AutoHideEventHandler>(this);
- }
- if (!auto_dim_event_handler_ && switches::IsUsingShelfAutoDim()) {
- auto_dim_event_handler_ = std::make_unique<AutoDimEventHandler>(this);
- }
- }
- void Shelf::OnAutoHideStateChanged(ShelfAutoHideState new_state) {
- for (auto& observer : observers_)
- observer.OnAutoHideStateChanged(new_state);
- }
- void Shelf::OnBackgroundUpdated(ShelfBackgroundType background_type,
- AnimationChangeType change_type) {
- if (background_type == GetBackgroundType())
- return;
- // Shelf should undim when transitioning to show app list.
- if (auto_dim_event_handler_ && IsAppListBackground(background_type))
- UndimShelf();
- for (auto& observer : observers_)
- observer.OnBackgroundTypeChanged(background_type, change_type);
- }
- void Shelf::OnHotseatStateChanged(HotseatState old_state,
- HotseatState new_state) {
- for (auto& observer : observers_)
- observer.OnHotseatStateChanged(old_state, new_state);
- }
- void Shelf::OnWorkAreaInsetsChanged() {
- for (auto& observer : observers_)
- observer.OnShelfWorkAreaInsetsChanged();
- }
- void Shelf::DimShelf() {
- auto_dim_event_handler_->DimShelf();
- }
- void Shelf::UndimShelf() {
- auto_dim_event_handler_->UndimShelf();
- }
- bool Shelf::HasDimShelfTimer() {
- return auto_dim_event_handler_->HasDimShelfTimer();
- }
- WorkAreaInsets* Shelf::GetWorkAreaInsets() const {
- const aura::Window* window = GetWindow();
- DCHECK(window);
- return WorkAreaInsets::ForWindow(window->GetRootWindow());
- }
- } // namespace ash
|