1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
ash / shelf / shelf.h [blame]
// Copyright 2016 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_H_
#define ASH_SHELF_SHELF_H_
#include <memory>
#include "ash/ash_export.h"
#include "ash/public/cpp/metrics_util.h"
#include "ash/public/cpp/shelf_types.h"
#include "ash/shelf/desk_button_widget.h"
#include "ash/shelf/shelf_layout_manager_observer.h"
#include "ash/shelf/shelf_locking_manager.h"
#include "base/memory/raw_ptr.h"
#include "base/memory/weak_ptr.h"
#include "base/observer_list.h"
namespace aura {
class Window;
}
namespace gfx {
class Rect;
}
namespace ui {
class GestureEvent;
class MouseWheelEvent;
class MouseEvent;
class ScrollEvent;
} // namespace ui
namespace ash {
enum class AnimationChangeType;
class HotseatWidget;
class HotseatWidgetAnimationMetricsReporter;
class NavigationWidgetAnimationMetricsReporter;
class ShelfFocusCycler;
class LoginShelfWidget;
class ShelfLayoutManager;
class ShelfLayoutManagerTest;
class ShelfLockingManager;
class ShelfNavigationWidget;
class ShelfView;
class ShelfWidget;
class StatusAreaWidget;
class ShelfObserver;
class WorkAreaInsets;
class ShelfTooltipManager;
// TODO(oshima) : move to .cc
// Returns a value based on shelf alignment.
template <typename T>
T SelectValueByShelfAlignment(ShelfAlignment alignment,
T bottom,
T left,
T right) {
switch (alignment) {
case ShelfAlignment::kBottom:
case ShelfAlignment::kBottomLocked:
return bottom;
case ShelfAlignment::kLeft:
return left;
case ShelfAlignment::kRight:
return right;
}
NOTREACHED();
}
bool IsHorizontalAlignment(ShelfAlignment alignment);
// Returns |horizontal| if shelf is horizontal, otherwise |vertical|.
template <typename T>
T PrimaryAxisValueByShelfAlignment(ShelfAlignment alignment,
T horizontal,
T vertical) {
return IsHorizontalAlignment(alignment) ? horizontal : vertical;
}
// Controller for the shelf state. One per display, because each display might
// have different shelf alignment, autohide, etc. Exists for the lifetime of the
// root window controller.
class ASH_EXPORT Shelf : public ShelfLayoutManagerObserver {
public:
// Used to maintain a lock for the auto-hide shelf. If lock, then we should
// not update the state of the auto-hide shelf.
class ScopedAutoHideLock {
public:
explicit ScopedAutoHideLock(Shelf* shelf) : shelf_(shelf) {
++shelf_->auto_hide_lock_;
}
ScopedAutoHideLock(const ScopedAutoHideLock&) = delete;
ScopedAutoHideLock& operator=(const ScopedAutoHideLock&) = delete;
~ScopedAutoHideLock() {
--shelf_->auto_hide_lock_;
DCHECK_GE(shelf_->auto_hide_lock_, 0);
}
private:
raw_ptr<Shelf> shelf_;
};
// Used to disable auto-hide shelf behavior while in scope. Note that
// disabling auto-hide behavior is of lower precedence than auto-hide behavior
// based on locks and session state, so it is not guaranteed to show the shelf
// in all cases.
class ScopedDisableAutoHide {
public:
explicit ScopedDisableAutoHide(Shelf* shelf);
ScopedDisableAutoHide(const ScopedDisableAutoHide&) = delete;
ScopedDisableAutoHide& operator=(const ScopedDisableAutoHide&) = delete;
~ScopedDisableAutoHide();
Shelf* weak_shelf() { return shelf_.get(); }
private:
// Save a `base::WeakPtr` to avoid a crash if `shelf_` is deallocated due to
// monitor disconnect.
base::WeakPtr<Shelf> const shelf_;
};
Shelf();
Shelf(const Shelf&) = delete;
Shelf& operator=(const Shelf&) = delete;
~Shelf() override;
// Returns the shelf for the display that |window| is on. Note that the shelf
// widget may not exist, or the shelf may not be visible.
static Shelf* ForWindow(aura::Window* window);
// Launch a 0-indexed shelf item in the shelf. A negative index launches the
// last shelf item in the shelf.
static void LaunchShelfItem(int item_index);
// Activates the shelf item specified by the index in the list of shelf items.
static void ActivateShelfItem(int item_index);
// Activates the shelf item specified by the index in the list of shelf items
// on the display identified by |display_id|.
static void ActivateShelfItemOnDisplay(int item_index, int64_t display_id);
// Updates the shelf visibility on all displays. This method exists for
// historical reasons. If a display or shelf instance is available, prefer
// Shelf::UpdateVisibilityState() below.
static void UpdateShelfVisibility();
void CreateNavigationWidget(aura::Window* container);
void CreateDeskButtonWidget(aura::Window* container);
void CreateHotseatWidget(aura::Window* container);
void CreateStatusAreaWidget(aura::Window* status_container);
void CreateShelfWidget(aura::Window* root);
// Begins shutdown of the ShelfWidget and all child widgets.
void ShutdownShelfWidget();
// Resets `shelf_widget_`.
void DestroyShelfWidget();
// Returns true if the shelf is visible. Shelf can be visible in 1)
// SHELF_VISIBLE or 2) SHELF_AUTO_HIDE but in SHELF_AUTO_HIDE_SHOWN. See
// details in ShelfLayoutManager::IsVisible.
bool IsVisible() const;
// Returns the window showing the shelf.
const aura::Window* GetWindow() const;
aura::Window* GetWindow();
void SetAlignment(ShelfAlignment alignment);
// Returns true if the shelf alignment is horizontal (i.e. at the bottom).
bool IsHorizontalAlignment() const;
// Returns a value based on shelf alignment.
template <typename T>
T SelectValueForShelfAlignment(T bottom, T left, T right) const {
return SelectValueByShelfAlignment(alignment_, bottom, left, right);
}
// Returns |horizontal| if shelf is horizontal, otherwise |vertical|.
template <typename T>
T PrimaryAxisValue(T horizontal, T vertical) const {
return IsHorizontalAlignment() ? horizontal : vertical;
}
void SetAutoHideBehavior(ShelfAutoHideBehavior behavior);
ShelfAutoHideState GetAutoHideState() const;
// Invoke when the auto-hide state may have changed (for example, when the
// system tray bubble opens it should force the shelf to be visible).
void UpdateAutoHideState();
ShelfBackgroundType GetBackgroundType() const;
void UpdateVisibilityState();
void MaybeUpdateShelfBackground();
ShelfVisibilityState GetVisibilityState() const;
gfx::Rect GetShelfBoundsInScreen() const;
// Returns the ideal bounds of the shelf assuming it is visible.
gfx::Rect GetIdealBounds() const;
// Returns the ideal bounds of the shelf, but in tablet mode always returns
// the bounds of the in-app shelf.
gfx::Rect GetIdealBoundsForWorkAreaCalculation();
// Returns the screen bounds of the item for the specified window. If there is
// no item for the specified window an empty rect is returned.
gfx::Rect GetScreenBoundsOfItemIconForWindow(aura::Window* window);
// Handles a gesture |event| coming from a source outside the shelf widget
// (e.g. the status area widget). Allows support for behaviors like toggling
// auto-hide with a swipe, even if that gesture event hits another window.
// Returns true if the event was handled.
bool ProcessGestureEvent(const ui::GestureEvent& event);
// Handles a mouse |event| coming from the Shelf.
void ProcessMouseEvent(const ui::MouseEvent& event);
// Handles a scroll |event| coming from the Shelf.
void ProcessScrollEvent(ui::ScrollEvent* event);
// Handles a mousewheel scroll event coming from the shelf.
void ProcessMouseWheelEvent(ui::MouseWheelEvent* event);
void AddObserver(ShelfObserver* observer);
void RemoveObserver(ShelfObserver* observer);
void NotifyShelfIconPositionsChanged();
StatusAreaWidget* GetStatusAreaWidget() const;
// Get the anchor rect that the system tray bubble and the notification center
// bubble will be anchored.
// x() and y() designates anchor point, but width() and height() are dummy.
// See also: BubbleDialogDelegateView::GetBubbleBounds()
gfx::Rect GetSystemTrayAnchorRect() const;
// Returns whether this shelf should be hidden on secondary display in a given
// |state|.
bool ShouldHideOnSecondaryDisplay(session_manager::SessionState state);
void SetVirtualKeyboardBoundsForTesting(const gfx::Rect& bounds);
ShelfLockingManager* GetShelfLockingManagerForTesting();
ShelfView* GetShelfViewForTesting();
ShelfLayoutManager* shelf_layout_manager() const {
return shelf_layout_manager_;
}
// Getters for the various shelf components.
ShelfWidget* shelf_widget() const { return shelf_widget_.get(); }
ShelfNavigationWidget* navigation_widget() const {
return navigation_widget_.get();
}
DeskButtonWidget* desk_button_widget() const {
return desk_button_widget_.get();
}
HotseatWidget* hotseat_widget() const { return hotseat_widget_.get(); }
StatusAreaWidget* status_area_widget() const {
return status_area_widget_.get();
}
LoginShelfWidget* login_shelf_widget() { return login_shelf_widget_.get(); }
ShelfAlignment alignment() const { return alignment_; }
ShelfAutoHideBehavior auto_hide_behavior() const {
return auto_hide_behavior_;
}
ShelfAlignment in_session_alignment() const {
return shelf_locking_manager_.in_session_alignment();
}
ShelfAutoHideBehavior in_session_auto_hide_behavior() const {
return shelf_locking_manager_.in_session_auto_hide_behavior();
}
ShelfFocusCycler* shelf_focus_cycler() { return shelf_focus_cycler_.get(); }
int auto_hide_lock() const { return auto_hide_lock_; }
int disable_auto_hide() const { return disable_auto_hide_; }
ShelfTooltipManager* tooltip() { return tooltip_.get(); }
// |target_state| is the hotseat state after hotseat transition animation.
metrics_util::ReportCallback GetHotseatTransitionReportCallback(
HotseatState target_state);
metrics_util::ReportCallback GetTranslucentBackgroundReportCallback(
HotseatState target_state);
metrics_util::ReportCallback GetNavigationWidgetAnimationReportCallback(
HotseatState target_hotseat_state);
protected:
// ShelfLayoutManagerObserver:
void WillDeleteShelfLayoutManager() override;
void OnShelfVisibilityStateChanged(ShelfVisibilityState new_state) override;
void OnAutoHideStateChanged(ShelfAutoHideState new_state) override;
void OnBackgroundUpdated(ShelfBackgroundType background_type,
AnimationChangeType change_type) override;
void OnHotseatStateChanged(HotseatState old_state,
HotseatState new_state) override;
void OnWorkAreaInsetsChanged() override;
private:
class AutoDimEventHandler;
class AutoHideEventHandler;
friend class DimShelfLayoutManagerTestBase;
friend class ShelfLayoutManagerTest;
// Uses Auto Dim Event Handler to update the shelf dim state.
void DimShelf();
void UndimShelf();
bool HasDimShelfTimer();
// Returns work area insets object for the window with this shelf.
WorkAreaInsets* GetWorkAreaInsets() const;
base::WeakPtr<Shelf> GetWeakPtr();
// Layout manager for the shelf container window. Instances are constructed by
// ShelfWidget and lifetimes are managed by the container windows themselves.
raw_ptr<ShelfLayoutManager> shelf_layout_manager_ = nullptr;
// Pointers to shelf components.
std::unique_ptr<ShelfNavigationWidget> navigation_widget_;
std::unique_ptr<DeskButtonWidget> desk_button_widget_;
std::unique_ptr<HotseatWidget> hotseat_widget_;
std::unique_ptr<StatusAreaWidget> status_area_widget_;
// Null during display teardown, see WindowTreeHostManager::DeleteHost() and
// RootWindowController::CloseAllChildWindows().
std::unique_ptr<ShelfWidget> shelf_widget_;
std::unique_ptr<LoginShelfWidget> login_shelf_widget_;
// These initial values hide the shelf until user preferences are available.
ShelfAlignment alignment_ = ShelfAlignment::kBottomLocked;
ShelfAutoHideBehavior auto_hide_behavior_ =
ShelfAutoHideBehavior::kAlwaysHidden;
// Sets shelf alignment to bottom during login and screen lock.
ShelfLockingManager shelf_locking_manager_;
base::ObserverList<ShelfObserver>::Unchecked observers_;
// Forwards mouse and gesture events to ShelfLayoutManager for auto-hide.
std::unique_ptr<AutoHideEventHandler> auto_hide_event_handler_;
// Forwards mouse and gesture events to ShelfLayoutManager for auto-dim.
std::unique_ptr<AutoDimEventHandler> auto_dim_event_handler_;
// Hands focus off to different parts of the shelf.
std::unique_ptr<ShelfFocusCycler> shelf_focus_cycler_;
// Animation metrics reporter for hotseat animations. Owned by the Shelf to
// ensure it outlives the Hotseat Widget.
std::unique_ptr<HotseatWidgetAnimationMetricsReporter>
hotseat_transition_metrics_reporter_;
// Metrics reporter for animations of the traslucent background in the
// hotseat. Owned by the Shelf to ensure it outlives the Hotseat Widget.
std::unique_ptr<HotseatWidgetAnimationMetricsReporter>
translucent_background_metrics_reporter_;
// Animation metrics reporter for navigation widget animations. Owned by the
// Shelf to ensure it outlives the Navigation Widget.
std::unique_ptr<NavigationWidgetAnimationMetricsReporter>
navigation_widget_metrics_reporter_;
// Used by ScopedAutoHideLock to maintain the state of the lock for auto-hide
// shelf.
int auto_hide_lock_ = 0;
// Used by `ScopedDisableAutoHide` to disable auto-hide shelf behavior.
int disable_auto_hide_ = 0;
std::unique_ptr<ShelfTooltipManager> tooltip_;
base::WeakPtrFactory<Shelf> weak_ptr_factory_{this};
};
} // namespace ash
#endif // ASH_SHELF_SHELF_H_