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
ash / display / display_alignment_controller.h [blame]
// Copyright 2020 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_DISPLAY_DISPLAY_ALIGNMENT_CONTROLLER_H_
#define ASH_DISPLAY_DISPLAY_ALIGNMENT_CONTROLLER_H_
#include <memory>
#include "ash/ash_export.h"
#include "ash/public/cpp/session/session_observer.h"
#include "ui/display/manager/display_manager_observer.h"
#include "ui/events/event_handler.h"
#include "ui/gfx/geometry/vector2d.h"
namespace base {
class OneShotTimer;
} // namespace base
namespace ash {
class DisplayAlignmentIndicator;
// DisplayAlignmentController is responsible for creating new
// DisplayAlignmentIndicators when the activation criteria is met.
// TODO(1091497): Consider combining DisplayHighlightController and
// DisplayAlignmentController.
class ASH_EXPORT DisplayAlignmentController
: public ui::EventHandler,
public display::DisplayManagerObserver,
public SessionObserver {
public:
enum class DisplayAlignmentState {
// No indicators shown and mouse is not on edge
kIdle,
// Mouse is currently on one of the edges.
kOnEdge,
// The indicators are visible.
kIndicatorsVisible,
// A display is being dragged around in display layouts. Preview indicators
// are being updated and shown.
kLayoutPreview,
// Screen is locked or there is only one display.
kDisabled,
};
DisplayAlignmentController();
DisplayAlignmentController(const DisplayAlignmentController&) = delete;
DisplayAlignmentController& operator=(const DisplayAlignmentController&) =
delete;
~DisplayAlignmentController() override;
// display::DisplayManagerObserver
void OnDidApplyDisplayChanges() override;
void OnDisplaysInitialized() override;
// ui::EventHandler:
void OnMouseEvent(ui::MouseEvent* event) override;
// SessionObserver:
void OnLockStateChanged(bool locked) override;
// Update positions of display alignment preview highlights. Display being
// dragged is specified by |display_id|. |preview_indicators_| is
// populated with indicators from this display and its neighbors as
// it is not possible for |display_id| to change mid-drag.
void DisplayDragged(int64_t display_id, int32_t delta_x, int32_t delta_y);
void SetTimerForTesting(std::unique_ptr<base::OneShotTimer> timer);
const std::vector<std::unique_ptr<DisplayAlignmentIndicator>>&
GetActiveIndicatorsForTesting();
int64_t GetDraggedDisplayIdForTesting() const;
private:
// Show all indicators on |src_display| and other indicators that shares
// an edge with |src_display|. Indicators on other displays are shown without
// pills. All indicators are created in this method and stored in
// |active_indicators_| to be destroyed in ResetState().
void ShowIndicators(const display::Display& src_display);
// Clears all indicators, containers, timer, and resets the state back to
// kIdle.
void ResetState();
// Used to transition to kDisable if required. Called whenever display
// configuration or lock state updates.
void RefreshState();
// Updates, shows/hides preview indicators according to changes reported by
// DisplayDragged().
void ComputePreviewIndicators();
// Stores all DisplayAlignmentIndicators currently being shown. All indicators
// should either belong to or be a shared edge of display with
// |triggered_display_id_|. Indicators are created upon activation in
// ShowIndicators() or upon adjusting display layout in
// ComputePreviewIndicators() and cleared in ResetState().
std::vector<std::unique_ptr<DisplayAlignmentIndicator>> active_indicators_;
// Timer used for both edge trigger timeouts and hiding indicators.
std::unique_ptr<base::OneShotTimer> action_trigger_timer_;
// Tracks current state of the controller. Mostly used to determine if action
// is taken in OnMouseEvent();
DisplayAlignmentState current_state_ = DisplayAlignmentState::kIdle;
// Tracks if the screen is locked to disable highlights.
bool is_locked_ = false;
// Keeps track of the most recent display where the mouse hit the edge.
// Prevents activating indicators when user hits edges of different displays.
int64_t triggered_display_id_ = display::kInvalidDisplayId;
// Number of times the mouse was on an edge of some display specified by
// |triggered_display_id_| recently.
int trigger_count_ = 0;
// ID of display currently beign dragged. Cannot change from one valid
// ID to another as dropping the dragged display causes changes to display
// configuration, resetting this ID.
int64_t dragged_display_id_;
// The difference between dragged display's actual position and preview
// position. Is an accumulation of |delta_x| and |delta_y| from
// DisplayDragged(). The offset is reset when a configuration event occurs.
gfx::Vector2d dragged_offset_;
};
} // namespace ash
#endif // ASH_DISPLAY_DISPLAY_ALIGNMENT_CONTROLLER_H_