// Copyright 2012 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef ASH_SHELF_SHELF_LAYOUT_MANAGER_H_
#define ASH_SHELF_SHELF_LAYOUT_MANAGER_H_
#include <memory>
#include <optional>
#include "ash/ash_export.h"
#include "ash/drag_drop/scoped_drag_drop_observer.h"
#include "ash/public/cpp/app_list/app_list_controller_observer.h"
#include "ash/public/cpp/session/session_observer.h"
#include "ash/public/cpp/shelf_config.h"
#include "ash/public/cpp/shelf_types.h"
#include "ash/public/cpp/wallpaper/wallpaper_controller.h"
#include "ash/public/cpp/wallpaper/wallpaper_controller_observer.h"
#include "ash/shelf/drag_window_from_shelf_controller.h"
#include "ash/shelf/shelf.h"
#include "ash/shelf/shelf_metrics.h"
#include "ash/shelf/shelf_observer.h"
#include "ash/shelf/shelf_widget.h"
#include "ash/shell_observer.h"
#include "ash/system/locale/locale_update_controller_impl.h"
#include "ash/wm/desks/desks_controller.h"
#include "ash/wm/lock_state_observer.h"
#include "ash/wm/overview/overview_observer.h"
#include "ash/wm/snap_group/snap_group.h"
#include "ash/wm/snap_group/snap_group_observer.h"
#include "ash/wm/splitview/split_view_controller.h"
#include "ash/wm/splitview/split_view_observer.h"
#include "ash/wm/wm_default_layout_manager.h"
#include "ash/wm/workspace/workspace_types.h"
#include "base/cancelable_callback.h"
#include "base/memory/raw_ptr.h"
#include "base/memory/weak_ptr.h"
#include "base/observer_list.h"
#include "base/scoped_observation.h"
#include "base/strings/string_number_conversions.h"
#include "base/timer/timer.h"
#include "ui/compositor/layer_animation_observer.h"
#include "ui/display/display.h"
#include "ui/display/display_observer.h"
#include "ui/gfx/geometry/insets.h"
#include "ui/gfx/geometry/rect.h"
#include "ui/wm/public/activation_change_observer.h"
namespace ui {
class EventHandler;
class LocatedEvent;
class MouseEvent;
class MouseWheelEvent;
class PresentationTimeRecorder;
} // namespace ui
namespace ash {
enum class AnimationChangeType;
class DragWindowFromShelfController;
class HomeToOverviewNudgeController;
class InAppToHomeNudgeController;
class PanelLayoutManagerTest;
class Shelf;
class ShelfLayoutManagerObserver;
class ShelfLayoutManagerTestBase;
class ShelfWidget;
class SwipeHomeToOverviewController;
// ShelfLayoutManager is the layout manager responsible for the shelf and
// status widgets. The shelf is given the total available width and told the
// width of the status area. This allows the shelf to draw the background and
// layout to the status area.
// To respond to bounds changes in the status area StatusAreaLayoutManager works
// closely with ShelfLayoutManager.
class ASH_EXPORT ShelfLayoutManager : public AppListControllerObserver,
public ShelfObserver,
public ShellObserver,
public SplitViewObserver,
public SnapGroupObserver,
public OverviewObserver,
public wm::ActivationChangeObserver,
public LockStateObserver,
public WmDefaultLayoutManager,
public display::DisplayObserver,
public SessionObserver,
public WallpaperControllerObserver,
public LocaleChangeObserver,
public DesksController::Observer,
public ShelfConfig::Observer {
public:
// See `drag_status_`. Visible for testing.
enum DragStatus {
kDragNone,
kDragAttempt,
kDragInProgress,
kDragCancelInProgress,
kDragCompleteInProgress,
kDragHomeToOverviewInProgress,
kFlingBubbleLauncherInProgress,
};
// Suspend work area updates within its scope. Note that relevant
// ShelfLayoutManager must outlive this class.
class ScopedSuspendWorkAreaUpdate {
public:
// |manager| is the ShelfLayoutManager whose visibility update is suspended.
explicit ScopedSuspendWorkAreaUpdate(ShelfLayoutManager* manager);
ScopedSuspendWorkAreaUpdate(const ScopedSuspendWorkAreaUpdate&) = delete;
ScopedSuspendWorkAreaUpdate& operator=(const ScopedSuspendWorkAreaUpdate&) =
delete;
~ScopedSuspendWorkAreaUpdate();
private:
const raw_ptr<ShelfLayoutManager> manager_;
};
// Used to maintain a lock for the shelf visibility state. If locked, then we
// should not update the state of the shelf visibility.
class ScopedVisibilityLock {
public:
explicit ScopedVisibilityLock(ShelfLayoutManager* shelf);
~ScopedVisibilityLock();
private:
base::WeakPtr<ShelfLayoutManager> shelf_;
};
ShelfLayoutManager(ShelfWidget* shelf_widget, Shelf* shelf);
ShelfLayoutManager(const ShelfLayoutManager&) = delete;
ShelfLayoutManager& operator=(const ShelfLayoutManager&) = delete;
~ShelfLayoutManager() override;
// Initializes observers.
void InitObservers();
// Clears internal data for shutdown process.
void PrepareForShutdown();
// Returns whether the shelf and its contents (shelf, status) are visible
// on the screen.
bool IsVisible() const;
// Returns the ideal bounds of the shelf assuming it is visible.
gfx::Rect GetIdealBounds() const;
// Returns the ideal bounds of the shelf, but always returns in-app shelf
// bounds in tablet mode.
gfx::Rect GetIdealBoundsForWorkAreaCalculation() const;
// Sets the bounds of the shelf and status widgets.
void LayoutShelf(bool animate = false);
// Sets display work area insets for the current shelf state, and target
// bounds.
void UpdateShelfWorkAreaInsets();
// Updates display work area to account for the current shelf state and
// bounds.
void UpdateDisplayWorkArea();
// Updates the visibility state. Relayouts the shelf if the visibility state
// changes, or if `force_layout` is set.
// `force_layout` should be used when state is set in response to events that
// both affect the shelf bounds/layout and may change shelf visibility.
void UpdateVisibilityState(bool force_layout);
// Shows the shelf and hotseat for the back gesture.
void UpdateVisibilityStateForBackGesture();
// Invoked by the shelf when the auto-hide state may have changed.
void UpdateAutoHideState();
// Updates the auto-hide state for mouse events.
void UpdateAutoHideForMouseEvent(ui::MouseEvent* event, aura::Window* target);
// Shows or hides contextual nudges for shelf gestures, depending on the shelf
// state.
void UpdateContextualNudges();
// Hides any visible contextual nudge for shelf gestures.
void HideContextualNudges();
// Called by AutoHideEventHandler to process the gesture events when shelf is
// auto hidden.
void ProcessGestureEventOfAutoHideShelf(ui::GestureEvent* event,
aura::Window* target);
// Handles events that are detected while the hotseat is kExtended in in-app
// shelf.
void ProcessGestureEventOfInAppHotseat(ui::GestureEvent* event,
aura::Window* target);
// Updates the auto-dim state. Returns true if successful.
bool SetDimmed(bool dimmed);
void AddObserver(ShelfLayoutManagerObserver* observer);
void RemoveObserver(ShelfLayoutManagerObserver* observer);
// Processes a gesture event and updates the status of the shelf when
// appropriate. Returns true if the gesture has been handled and it should not
// be processed any further, false otherwise.
bool ProcessGestureEvent(const ui::GestureEvent& event_in_screen);
// Handles mouse events from the shelf.
void ProcessMouseEventFromShelf(const ui::MouseEvent& event_in_screen);
// Handles events from ShelfWidget.
void ProcessGestureEventFromShelfWidget(ui::GestureEvent* event_in_screen);
// Handles mouse wheel events from the shelf.
void ProcessMouseWheelEventFromShelf(ui::MouseWheelEvent* event);
// Handles scroll events from the shelf.
void ProcessScrollEventFromShelf(ui::ScrollEvent* event);
// Returns whether the current state of the shelf allows a gesture fling or
// scroll to show the bubble launcher.
bool IsBubbleLauncherShowOnGestureScrollAvailable();
// Handles a fling event over the shelf. Returns whether the event was handled
// by the manager or false if it was ignored.
bool MaybeHandleShelfFling(const ui::GestureEvent& event_in_screen);
// Cleans up after a fling event was successfully completed on the shelf.
void CompleteShelfFling(const ui::LocatedEvent& event_in_screen);
// Returns true if the location is within the bounds of the area designated to
// receive the gesture fling or scroll over the shelf to show the bubble
// launcher.
bool IsLocationInBubbleLauncherShowBounds(
const gfx::Point& location_in_screen);
// Contains logic that is the same between mouse wheel and gesture scrolling.
void ProcessScrollOffset(int offset, const ui::LocatedEvent& event);
// Computes how the shelf background should be painted based on the current
// state.
ShelfBackgroundType ComputeShelfBackgroundType() const;
// Updates the background of the shelf if it has changed.
void MaybeUpdateShelfBackground(AnimationChangeType change_type);
// Returns whether the shelf should show a blurred background. This may
// return false even if background blur is enabled depending on the session
// state.
bool ShouldBlurShelfBackground();
// Returns true if at least one window is visible.
bool HasVisibleWindow() const;
// Cancel the drag if the shelf is in drag progress.
void CancelDragOnShelfIfInProgress();
// Suspends shelf visibility updates, to be used during shutdown. Since there
// is no balanced "resume" public API, the suspension will be indefinite.
void SuspendVisibilityUpdateForShutdown();
// Called when ShelfItems are interacted with in the shelf.
void OnShelfItemSelected(ShelfAction action);
// WmDefaultLayoutManager:
void OnWindowResized() override;
void SetChildBounds(aura::Window* child,
const gfx::Rect& requested_bounds) override;
// ShelfObserver:
void OnShelfAutoHideBehaviorChanged() override;
// ShellObserver:
void OnUserWorkAreaInsetsChanged(aura::Window* root_window) override;
void OnPinnedStateChanged(aura::Window* pinned_window) override;
void OnShellDestroying() override;
// SplitViewObserver:
void OnSplitViewStateChanged(SplitViewController::State previous_state,
SplitViewController::State state) override;
// SnapGroupObserver:
void OnSnapGroupAdded(SnapGroup* snap_group) override;
void OnSnapGroupRemoving(SnapGroup* snap_group,
SnapGroupExitPoint exit_pint) override;
// OverviewObserver:
void OnOverviewModeWillStart() override;
void OnOverviewModeStarting() override;
void OnOverviewModeStartingAnimationComplete(bool canceled) override;
void OnOverviewModeEnding(OverviewSession* overview_session) override;
void OnOverviewModeEndingAnimationComplete(bool canceled) override;
void OnOverviewModeEnded() override;
// AppListControllerObserver:
void OnAppListVisibilityWillChange(bool shown, int64_t display_id) override;
void OnAppListVisibilityChanged(bool shown, int64_t display_id) override;
// wm::ActivationChangeObserver:
void OnWindowActivated(ActivationReason reason,
aura::Window* gained_active,
aura::Window* lost_active) override;
// LockStateObserver:
void OnLockStateEvent(LockStateObserver::EventType event) override;
// SessionObserver:
void OnSessionStateChanged(session_manager::SessionState state) override;
void OnLoginStatusChanged(LoginStatus loing_status) override;
// WallpaperControllerObserver:
void OnWallpaperBlurChanged() override;
void OnFirstWallpaperShown() override;
// DisplayObserver:
void OnDisplayMetricsChanged(const display::Display& display,
uint32_t changed_metrics) override;
// LocaleChangeObserver:
void OnLocaleChanged() override;
// DesksController::Observer:
void OnDeskSwitchAnimationLaunching() override;
void OnDeskSwitchAnimationFinished() override;
ShelfVisibilityState visibility_state() const {
return state_.visibility_state.value_or(SHELF_VISIBLE);
}
ShelfBackgroundType shelf_background_type() const {
return shelf_background_type_;
}
bool is_active_session_state() const { return state_.IsActiveSessionState(); }
bool is_shelf_auto_hidden() const { return state_.IsShelfAutoHidden(); }
// Locks or unlocks the state of shelf auto-hide. On unlock, the auto-hide
// state will be recomputed.
void LockAutoHideState(bool lock_auto_hide_state);
ShelfAutoHideBehavior auto_hide_behavior() const {
return shelf_->auto_hide_behavior();
}
// ShelfConfig::Observer:
void OnShelfConfigUpdated() override;
float GetOpacity() const;
bool updating_bounds() const { return phase_ == ShelfLayoutPhase::kMoving; }
ShelfAutoHideState auto_hide_state() const { return state_.auto_hide_state; }
HotseatState hotseat_state() const {
return shelf_widget_->hotseat_widget()->state();
}
DragWindowFromShelfController* window_drag_controller_for_testing() {
return window_drag_controller_.get();
}
SwipeHomeToOverviewController*
swipe_home_to_overview_controller_for_testing() {
return swipe_home_to_overview_controller_.get();
}
HomeToOverviewNudgeController*
home_to_overview_nudge_controller_for_testing() {
return home_to_overview_nudge_controller_.get();
}
DragStatus drag_status_for_test() const { return drag_status_; }
// Gets the target HotseatState based on the current state of HomeLauncher,
// Overview, Shelf, and any active gestures.
// TODO(manucornet): Move this to the hotseat class.
HotseatState CalculateHotseatState(ShelfVisibilityState visibility_state,
ShelfAutoHideState auto_hide_state) const;
// Called when the shelf alignment changes - updates shelf visibility state
// and bounds to reflect the new shelf alignment.
void HandleShelfAlignmentChange();
// Called when the visibility for a tray bubble in the shelf's status area
// changes.
void OnShelfTrayBubbleVisibilityChanged(bool bubble_shown);
void UpdateWorkAreaInsetsAndNotifyObservers(
const gfx::Rect& shelf_bounds_for_workarea_calculation,
const gfx::Insets& shelf_insets,
const gfx::Insets& in_session_shelf_insets);
// Called from the scrollable shelf container when it updates its bounds.
void HandleScrollableShelfContainerBoundsChange();
private:
void UpdateWorkAreaInsetsAndNotifyObserversInternal(
const gfx::Rect& shelf_bounds_for_workarea_calculation,
const gfx::Insets& shelf_insets,
const gfx::Insets& in_session_shelf_insets);
class UpdateShelfObserver;
friend class AshMessagePopupCollectionTest;
friend class DimShelfLayoutManagerTestBase;
friend class NotificationTrayTest;
friend class PanelLayoutManagerTest;
friend class Shelf;
friend class ShelfLayoutManagerTestBase;
friend class ShelfLayoutManagerWindowDraggingTest;
friend class SystemNudgeTest;
friend class TrayBackgroundViewTest;
friend class UnifiedSystemTrayTest;
struct State {
State();
// Returns true when a secondary user is being added to an existing session.
bool IsAddingSecondaryUser() const;
bool IsScreenLocked() const;
// Returns whether the session is in an active state.
bool IsActiveSessionState() const;
// Returns whether shelf is in auto-hide mode and is currently hidden.
bool IsShelfAutoHidden() const;
// Returns whether shelf is currently visible.
bool IsShelfVisible() const;
// Returns whether shelf is in auto-hide mode in session and suupposed to be
// hidden.
bool IsShelfAutoHiddenInSession() const;
// Returns true if the two states are considered equal. As
// |auto_hide_state| only matters if |visibility_state| is
// |SHELF_AUTO_HIDE|, Equals() ignores the |auto_hide_state| as
// appropriate.
bool Equals(const State& other) const;
std::optional<ShelfVisibilityState> visibility_state;
ShelfAutoHideState auto_hide_state = SHELF_AUTO_HIDE_HIDDEN;
WorkspaceWindowState window_state = WorkspaceWindowState::kDefault;
// In session state.
ShelfVisibilityState in_session_visibility_state = SHELF_VISIBLE;
ShelfAutoHideState in_session_auto_hide_state = SHELF_AUTO_HIDE_HIDDEN;
// True when the system is in the cancelable, pre-lock screen animation.
bool pre_lock_screen_animation_active = false;
session_manager::SessionState session_state =
session_manager::SessionState::UNKNOWN;
};
// An enumration describing the various phases in which the shelf can be when
// managing the bounds and opacity of its components.
enum class ShelfLayoutPhase {
kAtRest, // No activity
kAiming, // Calculating target bounds
kMoving, // Laying out and animating to target bounds
};
// Suspends/resumes work area updates.
void SuspendWorkAreaUpdate();
void ResumeWorkAreaUpdate();
// Sets the visibility of the shelf to |state|.
// Relayouts the shelf if the shelf state (visibility, or autohide state)
// changes, or if `force_layout` is set.
// `force_layout` should be used when state is set in response to events that
// both affect the shelf bounds/layout and may change shelf visibility.
void SetState(ShelfVisibilityState visibility_state, bool force_layout);
// Returns shelf visibility state based on current value of auto-hide
// behavior setting.
ShelfVisibilityState CalculateShelfVisibility();
// Updates the shelf dim state.
void UpdateShelfIconOpacity();
// Updates the bounds and opacity of the shelf and status widgets.
void UpdateBoundsAndOpacity(bool animate);
// Returns true if a maximized or fullscreen window is being dragged from the
// top of the display or from the caption area. Note currently for this case
// it's only allowed in tablet mode, not in laptop mode.
bool IsDraggingWindowFromTopOrCaptionArea() const;
// Calculates shelf target bounds assuming visibility of
// `state.visibilty_state` and `hotseat_target_state`.
void UpdateTargetBounds(const State& state,
HotseatState hotseat_target_state);
// Calculates the target bounds using `state_`.
void CalculateTargetBounds();
// Updates the target bounds if a gesture-drag is in progress. This is only
// used by |CalculateTargetBounds()|.
void UpdateTargetBoundsForGesture(HotseatState target_hotseat_state);
// Updates the auto-hide state for drag-drop actions.
void UpdateAutoHideForDragDrop(ScopedDragDropObserver::EventType event_type,
const ui::DropTargetEvent* event);
// Updates the auto-hide state immediately.
void UpdateAutoHideStateNow();
// Starts the auto-hide timer, so that the shelf will be hidden after the
// timeout (unless something else happens to interrupt / reset it).
void StartAutoHideTimer();
// Stops the auto-hide timer and clears
// |mouse_over_shelf_when_auto_hide_timer_started_|.
void StopAutoHideTimer();
// Returns the bounds of an additional region which can trigger showing the
// shelf. This region exists to make it easier to trigger showing the shelf
// when the shelf is auto hidden and the shelf is on the boundary between
// two displays.
gfx::Rect GetAutoHideShowShelfRegionInScreen() const;
// Returns the auto-hide state. This value is determined from the shelf and
// tray.
ShelfAutoHideState CalculateAutoHideState(
ShelfVisibilityState visibility_state) const;
// Returns the auto-hide state based on the position of an ongoing drag-drop.
ShelfAutoHideState CalculateAutoHideStateBasedOnDragLocation() const;
// Returns the auto-hide state if the cursor's current position can be used to
// make a decision, or no value if its position gives no useful information.
std::optional<ShelfAutoHideState>
CalculateAutoHideStateBasedOnCursorLocation() const;
// Returns true if |window| is a descendant of the shelf.
bool IsShelfWindow(aura::Window* window);
// Returns true if |window| is a descendant of the status area.
bool IsStatusAreaWindow(aura::Window* window);
// Called when the LoginUI changes from visible to invisible.
void UpdateShelfVisibilityAfterLoginUIChange();
// Compute |target_bounds| opacity based on gesture and shelf visibility.
float ComputeTargetOpacity(const State& state) const;
// Returns true if there is a fullscreen window open that causes the shelf
// to be hidden.
bool IsShelfHiddenForFullscreen() const;
// Returns true if there is a fullscreen or maximized window open that causes
// the shelf to be auto hidden.
bool IsShelfAutoHideForFullscreenMaximized() const;
// Returns whether the active window for the shelf is a defined stylus app
// in `kStylusAppIds`.
bool IsActiveWindowStylusApp() const;
// Returns true if the home gesture handler should handle the event.
bool ShouldHomeGestureHandleEvent(float scroll_y) const;
// Gesture drag related functions:
bool StartGestureDrag(const ui::GestureEvent& gesture_in_screen);
void UpdateGestureDrag(const ui::GestureEvent& gesture_in_screen);
// Mouse drag related functions:
void AttemptToDragByMouse(const ui::MouseEvent& mouse_in_screen);
void StartMouseDrag(const ui::MouseEvent& mouse_in_screen);
void UpdateMouseDrag(const ui::MouseEvent& mouse_in_screen);
void ReleaseMouseDrag(const ui::MouseEvent& mouse_in_screen);
// Drag related functions, utilized by both gesture drag and mouse drag:
bool IsDragAllowed() const;
bool StartShelfDrag(const ui::LocatedEvent& event_in_screen,
const gfx::Vector2dF& scroll_hint);
// Sets the Hotseat up to be dragged, if applicable.
void MaybeSetupHotseatDrag(const ui::LocatedEvent& event_in_screen);
void UpdateDrag(const ui::LocatedEvent& event_in_screen,
float scroll_x,
float scroll_y);
void CompleteDrag(const ui::LocatedEvent& event_in_screen);
void CompleteDragHomeToOverview(const ui::LocatedEvent& event_in_screen);
void CancelDrag(std::optional<ShelfWindowDragResult> window_drag_result);
void CompleteDragWithChangedVisibility();
// Returns true if the gesture is swiping up on a hidden shelf or swiping down
// on a visible shelf; other gestures should not change shelf visibility.
bool IsSwipingCorrectDirection();
// Returns true if should change the visibility of the shelf after drag.
bool ShouldChangeVisibilityAfterDrag(
const ui::LocatedEvent& gesture_in_screen);
// Updates the mask to limit the content to the non lock screen container.
// The mask will be removed if the workspace state is either in fullscreen
// or maximized.
void UpdateWorkspaceMask(WorkspaceWindowState window_state);
// Sends a11y alert for entering/exiting
// WorkspaceWindowState::kFullscreen workspace state.
void SendA11yAlertForFullscreenWorkspaceState(
WorkspaceWindowState current_workspace_window_state);
// Maybe start/update/end the window drag when swiping up from the shelf.
bool MaybeStartDragWindowFromShelf(const ui::LocatedEvent& event_in_screen,
const gfx::Vector2dF& scroll);
void MaybeUpdateWindowDrag(const ui::LocatedEvent& event_in_screen,
const gfx::Vector2dF& scroll);
std::optional<ShelfWindowDragResult> MaybeEndWindowDrag(
const ui::LocatedEvent& event_in_screen);
// If overview session is active, goes to home screen if the gesture should
// initiate transition to home. It handles the gesture only if the
// |window_drag_controller_| is not handling a window drag (for example, in
// split view mode).
bool MaybeEndDragFromOverviewToHome(const ui::LocatedEvent& event_in_screen);
void MaybeCancelWindowDrag();
bool IsWindowDragInProgress() const;
// Updates the visibility state because of the change on a status area tray.
void UpdateVisibilityStateForTrayBubbleChange(bool bubble_shown);
bool IsShelfContainerAnimating() const;
// Calculates target bounds for the hotseat widget and the desk button widget.
void CalculateDeskButtonAndHotseatTargetBounds();
bool in_shutdown_ = false;
// True if the last mouse event was a mouse drag.
bool in_mouse_drag_ = false;
// True if a mouse or gesture drag is in progress.
bool in_drag_drop_ = false;
// Current state.
State state_;
ShelfLayoutPhase phase_ = ShelfLayoutPhase::kAtRest;
bool updating_work_area_ = false;
float target_opacity_ = 0.0f;
const raw_ptr<ShelfWidget> shelf_widget_;
const raw_ptr<Shelf> shelf_;
// Count of pending visibility update suspensions. Skip updating the shelf
// visibility state if it is greater than 0.
int suspend_visibility_update_ = 0;
// Count of pending work area update suspensions. Skip updating the work
// area if it is greater than 0.
int suspend_work_area_update_ = 0;
base::OneShotTimer auto_hide_timer_;
// Whether the mouse was over the shelf when the auto-hide timer started.
// False when neither the auto-hide timer nor the timer task are running.
bool mouse_over_shelf_when_auto_hide_timer_started_ = false;
// Whether a drag was over the shelf when the auto-hide timer started.
// False when neither the auto-hide timer nor the timer task are running.
bool drag_over_shelf_when_auto_hide_timer_started_ = false;
// Whether the mouse pointer (not the touch pointer) was over the shelf last
// time we saw it. This is used to differentiate between mouse and touch in
// the shelf auto-hide behavior.
bool last_seen_mouse_position_was_over_shelf_ = false;
// Whether the last location update from a drag-drop was over the shelf.
bool last_seen_drag_position_was_over_shelf_ = false;
base::ObserverList<ShelfLayoutManagerObserver>::Unchecked observers_;
// The enum keeps track of the present status of the drag (from gesture or
// mouse). The shelf reacts to drags, and can be set to auto hide for certain
// events. For example, swiping up from the shelf in tablet mode can open the
// fullscreen app list. Some shelf behaviour (e.g. visibility state,
// background color etc.) are affected by various stages of the drag.
DragStatus drag_status_ = kDragNone;
// Whether the hotseat is being dragged.
bool hotseat_is_in_drag_ = false;
// Whether the EXTENDED hotseat should be hidden. Set when HotseatEventHandler
// detects that the background has been interacted with.
bool should_hide_hotseat_ = false;
// Whether the overview mode is about to start. This becomes false again
// once the overview mode has actually started.
bool overview_mode_will_start_ = false;
// Tracks the amount of the drag. The value is only valid when
// |drag_status_| is set to kDragInProgress.
float drag_amount_ = 0.f;
// The velocity of the last drag event. Used to determine final state of the
// hotseat.
int last_drag_velocity_ = 0;
// Manage the auto-hide state during drag.
ShelfAutoHideState drag_auto_hide_state_ = SHELF_AUTO_HIDE_SHOWN;
// Whether background blur is enabled.
const bool is_background_blur_enabled_;
// Pretarget handler responsible for hiding the hotseat.
std::unique_ptr<ui::EventHandler> hotseat_event_handler_;
// Stores the previous workspace state. Used by
// SendA11yAlertForFullscreenWorkspaceState to compare with current workspace
// state to determite whether need to send an a11y alert.
WorkspaceWindowState previous_workspace_window_state_ =
WorkspaceWindowState::kDefault;
// The display on which this shelf is shown.
display::Display display_;
// The current shelf background. Should not be assigned to directly, use
// MaybeUpdateShelfBackground() instead.
ShelfBackgroundType shelf_background_type_ = ShelfBackgroundType::kDefaultBg;
ScopedSessionObserver scoped_session_observer_{this};
base::ScopedObservation<WallpaperController, WallpaperControllerObserver>
wallpaper_controller_observation_{this};
display::ScopedDisplayObserver display_observer_{this};
// Observer that allows drag events to un-hide an auto-hidden shelf.
std::unique_ptr<ScopedDragDropObserver> drag_drop_observer_;
// Location of the most recent mouse drag event in screen coordinates.
gfx::Point last_mouse_drag_position_in_screen_;
// Location of the most recent drag-drop event in screen coordinates.
gfx::Point last_drag_drop_position_in_screen_;
// Location of the beginning of a drag in screen coordinates.
gfx::Point drag_start_point_in_screen_;
// When it is true, |CalculateAutoHideState| returns the current auto-hide
// state.
bool is_auto_hide_state_locked_ = false;
// An optional ScopedSuspendWorkAreaUpdate that gets created when suspend
// visibility update is requested for overview and resets when overview no
// longer needs it. It is used because OnOverviewModeStarting() and
// OnOverviewModeStartingAnimationComplete() calls are not balanced.
std::optional<ScopedSuspendWorkAreaUpdate> overview_suspend_work_area_update_;
// The window drag controller that will be used when a window can be dragged
// up from shelf to homescreen, overview or splitview.
std::unique_ptr<DragWindowFromShelfController> window_drag_controller_;
// The gesture controller that switches from home screen to overview when it
// detects an upward swipe from the home launcher shelf area.
std::unique_ptr<SwipeHomeToOverviewController>
swipe_home_to_overview_controller_;
std::unique_ptr<HomeToOverviewNudgeController>
home_to_overview_nudge_controller_;
// Controller for the visibility of the InAppToHome gesture contextual nudge.
std::unique_ptr<InAppToHomeNudgeController> in_app_to_home_nudge_controller_;
// Whether upward fling from shelf should be handled as potential gesture from
// overview to home. This is set to false when the swipe is handled by
// |window_drag_controller_|, when the swipe is associated with a window
// to drag. Note that the gesture will be handled only when the overview
// session is active.
bool allow_fling_from_overview_to_home_ = true;
// Indicates whether shelf drag gesture can start window drag from shelf to
// overview or home when hotseat is in extended state (the window drag will
// only be allowed if drag started within shelf bounds).
bool allow_window_drag_on_extended_hotseat_ = false;
// Tracks whether the shelf is currently dimmed for inactivity.
bool dimmed_for_inactivity_ = false;
// Tracks whether the shelf and hotseat have been asked to be shown and
// extended by the back gesture.
bool state_forced_by_back_gesture_ = false;
// Indicates whether shelf layout during shelf state update (in `SetState()`)
// should be animated. If the shelf bounds and layout should be updated
// without animation, `state_change_animation_disabled_` should be set before
// calling `SetState()` or `UpdateVisibility()`.
bool state_change_animation_disabled_ = false;
// Callback to update the shelf's state when the visibility of system tray
// changes.
base::CancelableOnceClosure visibility_update_for_tray_callback_;
// Records the presentation time for hotseat dragging.
std::unique_ptr<ui::PresentationTimeRecorder>
hotseat_presentation_time_recorder_;
base::WeakPtrFactory<ShelfLayoutManager> weak_factory_{this};
};
} // namespace ash
#endif // ASH_SHELF_SHELF_LAYOUT_MANAGER_H_