• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2023 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #ifndef OHOS_ROSEN_WINDOW_SCENE_MOVE_DRAG_CONTROLLER_H
17 #define OHOS_ROSEN_WINDOW_SCENE_MOVE_DRAG_CONTROLLER_H
18 
19 #include <mutex>
20 
21 #include <refbase.h>
22 #include <struct_multimodal.h>
23 
24 #include "common/include/window_session_property.h"
25 #include "property/rs_properties_def.h"
26 #include "screen_manager.h"
27 #include "window.h"
28 #include "ws_common_inner.h"
29 
30 namespace OHOS::MMI {
31 class PointerEvent;
32 } // namespace MMI
33 
34 namespace OHOS::Rosen {
35 
36 using MoveDragCallback = std::function<void(const SizeChangeReason)>;
37 
38 using NotifyWindowDragHotAreaFunc = std::function<void(DisplayId displayId, uint32_t type,
39     SizeChangeReason reason)>;
40 
41 using NotifyWindowPidChangeCallback = std::function<void(int32_t windowId, bool startMoving)>;
42 
43 const uint32_t WINDOW_HOT_AREA_TYPE_UNDEFINED = 0;
44 const int32_t POSITIVE_CORRELATION = 1;
45 const int32_t NEGATIVE_CORRELATION = -1;
46 
47 enum class MoveDirection : uint32_t {
48     UNKNOWN,
49     LEFT_TO_RIGHT,
50     RIGHT_TO_LEFT,
51     UP_TO_BOTTOM,
52     BOTTOM_TO_UP,
53 };
54 
55 class MoveDragController : public ScreenManager::IScreenListener {
56 public:
57     MoveDragController(int32_t persistentId, WindowType winType);
58     ~MoveDragController() = default;
59 
60     /*
61      * Cross Display Move Drag
62      */
63     enum class TargetRectCoordinate {
64         RELATED_TO_START_DISPLAY,
65         RELATED_TO_END_DISPLAY,
66         GLOBAL
67     };
68 
69     void RegisterMoveDragCallback(const MoveDragCallback& callBack);
70     void SetStartMoveFlag(bool flag);
71     bool GetStartMoveFlag() const;
72     bool GetStartDragFlag() const;
73     bool HasPointDown();
74     void SetMovable(bool movable);
75     bool GetMovable() const;
76     void SetNotifyWindowPidChangeCallback(const NotifyWindowPidChangeCallback& callback);
77     WSRect GetTargetRect(TargetRectCoordinate coordinate) const;
78     WSRect GetTargetRectByDisplayId(DisplayId displayId) const;
79     void SetTargetRect(const WSRect& rect);
80     WSRect GetOriginalRect() const;
81     void InitMoveDragProperty();
82     void SetOriginalMoveDragPos(int32_t pointerId, int32_t pointerType, int32_t pointerPosX,
83                                 int32_t pointerPosY, int32_t pointerWindowX, int32_t pointerWindowY,
84                                 const WSRect& winRect);
85     void SetAspectRatio(float ratio);
86     bool ConsumeMoveEvent(const std::shared_ptr<MMI::PointerEvent>& pointerEvent, const WSRect& originalRect);
87     bool ConsumeDragEvent(const std::shared_ptr<MMI::PointerEvent>& pointerEvent, const WSRect& originalRect,
88         const sptr<WindowSessionProperty> property, const SystemSessionConfig& sysConfig);
89     void CalcFirstMoveTargetRect(const WSRect& windowRect, bool isFullToFloating);
90     WSRect GetFullScreenToFloatingRect(const WSRect& originalRect, const WSRect& windowRect);
91     int32_t GetOriginalPointerPosX();
92     int32_t GetOriginalPointerPosY();
93     int32_t GetPointerType() const;
94     void SetWindowDragHotAreaFunc(const NotifyWindowDragHotAreaFunc& func);
95     void UpdateGravityWhenDrag(const std::shared_ptr<MMI::PointerEvent>& pointerEvent,
96         const std::shared_ptr<RSSurfaceNode>& surfaceNode);
97     void UpdateSubWindowGravityWhenFollow(const sptr<MoveDragController>& followedController,
98         const std::shared_ptr<RSSurfaceNode>& surfaceNode);
99     void OnLostFocus();
GetAreaType()100     AreaType GetAreaType() const { return type_; };
101 
102     /*
103      * Cross Display Move Drag
104      */
105     uint64_t GetMoveDragStartDisplayId() const;
106     uint64_t GetMoveDragEndDisplayId() const;
107     uint64_t GetInitParentNodeId() const;
108     std::set<uint64_t> GetDisplayIdsDuringMoveDrag();
109     std::set<uint64_t> GetNewAddedDisplayIdsDuringMoveDrag();
110     void InitCrossDisplayProperty(DisplayId displayId, uint64_t parentNodeId);
111     WSRect GetScreenRectById(DisplayId displayId);
112     DisplayId GetMoveInputBarStartDisplayId();
113     void ResetCrossMoveDragProperty();
114     void MoveDragInterrupted(bool resetPosition = true);
115     void SetMoveAvailableArea(const DMRect& area);
116     void UpdateMoveAvailableArea(DisplayId targetDisplayId);
117     void SetCurrentScreenProperty(DisplayId targetDisplayId);
118     void SetMoveInputBarStartDisplayId(DisplayId displayId);
119     void SetInputBarCrossAttr(MoveDirection moveDirection, DisplayId targetDisplayId);
120     void SetOriginalDisplayOffset(int32_t offsetX, int32_t offsetY);
SetOriginalPositionZ(float originalPositionZ)121     void SetOriginalPositionZ(float originalPositionZ) { originalPositionZ_ = originalPositionZ; }
GetOriginalPositionZ()122     float GetOriginalPositionZ() const { return originalPositionZ_; }
123 
124     /*
125      * Monitor screen connection status
126      */
127     void OnConnect(ScreenId screenId) override;
128     void OnDisconnect(ScreenId screenId) override;
129     void OnChange(ScreenId screenId) override;
130 
131     /*
132      * PC Window Layout
133      */
134     void HandleStartMovingWithCoordinate(int32_t offsetX, int32_t offsetY,
135         int32_t pointerPosX, int32_t pointerPosY, const WSRect& winRect);
136     void StopMoving();
137     int32_t GetLastMovePointerPosX() const;
138     void SetLastMovePointerPosX(int32_t lastMovePointerPosX);
139     bool IsMoveDragHotAreaCrossDisplay() const;
140     void SetMoveDragHotAreaCrossDisplay(bool isMoveDragHotAreaCrossDisplay);
141 
142 private:
143     struct MoveDragProperty {
144         int32_t pointerId_ = -1;
145         int32_t pointerType_ = -1;
146         int32_t originalPointerPosX_ = -1;
147         int32_t originalPointerPosY_ = -1;
148         // the x coordinate of the pointer related to the active window
149         int32_t originalPointerWindowX_ = -1;
150         // the y coordinate of the pointer related to the active window
151         int32_t originalPointerWindowY_ = -1;
152         WSRect originalRect_ = { 0, 0, 0, 0 };
153         WSRect targetRect_ = { 0, 0, 0, 0 };
154 
isEmptyMoveDragProperty155         bool isEmpty() const
156         {
157             return (pointerId_ == -1 && originalPointerPosX_ == -1 && originalPointerPosY_ == -1);
158         }
159     };
160 
161     struct MoveTempProperty {
162         int32_t pointerId_ = -1;
163         int32_t pointerType_ = -1;
164         int32_t lastDownPointerPosX_ = -1;
165         int32_t lastDownPointerPosY_ = -1;
166         int32_t lastDownPointerWindowX_ = -1;
167         int32_t lastDownPointerWindowY_ = -1;
168         int32_t lastMovePointerPosX_ = -1;
169         int32_t lastMovePointerPosY_ = -1;
170 
isEmptyMoveTempProperty171         bool isEmpty() const
172         {
173             return (pointerId_ == -1 && lastDownPointerPosX_ == -1 && lastDownPointerPosY_ == -1);
174         }
175     };
176 
177     struct ScreenSizeProperty {
178         uint32_t currentDisplayStartX = 0;
179         uint32_t currentDisplayStartY = 0;
180         int32_t currentDisplayLeft = 0;
181         int32_t currentDisplayTop = 0;
182         int32_t width = 0;
183         int32_t height = 0;
184 
IsEmptyScreenSizeProperty185         bool IsEmpty() const
186         {
187             return (currentDisplayStartX == 0 && currentDisplayStartY == 0 && currentDisplayLeft == 0 &&
188                     currentDisplayTop == 0 && width == 0 && height == 0);
189         }
190 
ResetScreenSizeProperty191         void Reset()
192         {
193             currentDisplayStartX = 0;
194             currentDisplayStartY = 0;
195             currentDisplayLeft = 0;
196             currentDisplayTop = 0;
197             width = 0;
198             height = 0;
199         }
200 
ToStringScreenSizeProperty201         std::string ToString() const
202         {
203             if (IsEmpty()) {
204                 return "empty";
205             }
206 
207             std::ostringstream ss;
208             ss << "currentDisplayStartX: " << currentDisplayStartX << ","
209                << "currentDisplayStartY: " << currentDisplayStartY << ","
210                << "currentDisplayLeft: " << currentDisplayLeft << ","
211                << "currentDisplayTop: " << currentDisplayTop << ","
212                << "width: " << width << "," << "height: " << height;
213             return ss.str();
214         }
215     };
216     enum AxisType { UNDEFINED, X_AXIS, Y_AXIS };
217     constexpr static float NEAR_ZERO = 0.001f;
218 
219     bool CalcMoveTargetRect(const std::shared_ptr<MMI::PointerEvent>& pointerEvent, const WSRect& originalRect);
220     void CalcDragTargetRect(const std::shared_ptr<MMI::PointerEvent>& pointerEvent, SizeChangeReason reason);
221     bool EventDownInit(const std::shared_ptr<MMI::PointerEvent>& pointerEvent, const WSRect& originalRect,
222         const sptr<WindowSessionProperty> property, const SystemSessionConfig& sysConfig);
223     bool CalcMoveInputBarRect(const std::shared_ptr<MMI::PointerEvent>& pointerEvent, const WSRect& originalRect);
224     void AdjustTargetPositionByAvailableArea(int32_t& moveDragFinalX, int32_t& moveDragFinalY);
225     MoveDirection CalcMoveDirection(DisplayId lastDisplayId, DisplayId currentDisplayId);
226 
227     void InitializeMoveDragPropertyNotValid(const std::shared_ptr<MMI::PointerEvent>& pointerEvent,
228                                             const WSRect& originalRect);
229     bool CheckAndInitializeMoveDragProperty(const std::shared_ptr<MMI::PointerEvent>& pointerEvent,
230                                             const WSRect& originalRect);
231     void HandleLeftToRightCross(DisplayId targetDisplayId, int32_t pointerDisplayX, int32_t pointerDisplayY,
232             int32_t& moveDragFinalX, int32_t& moveDragFinalY);
233     void HandleRightToLeftCross(DisplayId targetDisplayId, int32_t pointerDisplayX, int32_t pointerDisplayY,
234             int32_t& moveDragFinalX, int32_t& moveDragFinalY);
235     void HandleUpToBottomCross(DisplayId targetDisplayId, int32_t pointerDisplayX, int32_t pointerDisplayY,
236             int32_t& moveDragFinalX, int32_t& moveDragFinalY);
237     void HandleBottomToUpCross(DisplayId targetDisplayId, int32_t pointerDisplayX, int32_t pointerDisplayY,
238             int32_t& moveDragFinalX, int32_t& moveDragFinalY);
239     void CalcMoveForSameDisplay(const std::shared_ptr<MMI::PointerEvent>& pointerEvent,
240                                 int32_t& moveDragFinalX, int32_t& moveDragFinalY);
241     AreaType GetAreaType(int32_t pointWinX, int32_t pointWinY, int32_t sourceType, const WSRect& rect);
242     WSRect CalcFreeformTargetRect(AreaType type, int32_t tranX, int32_t tranY, WSRect originalRect);
243     WSRect CalcFixedAspectRatioTargetRect(AreaType type, int32_t tranX, int32_t tranY, float aspectRatio,
244         WSRect originalRect);
245     void CalcFreeformTranslateLimits(AreaType type);
246     void CalcFixedAspectRatioTranslateLimits(AreaType type);
247     void FixTranslateByLimits(int32_t& tranX, int32_t& tranY);
248     bool InitMainAxis(AreaType type, int32_t tranX, int32_t tranY);
249     void ConvertXYByAspectRatio(int32_t& tx, int32_t& ty, float aspectRatio);
250     int32_t ConvertByAreaType(int32_t tran) const;
251     void ProcessSessionRectChange(SizeChangeReason reason);
252     void InitDecorValue(const sptr<WindowSessionProperty> property, const SystemSessionConfig& sysConfig);
253 
254     float GetVirtualPixelRatio() const;
255     void UpdateDragType(int32_t startPointPosX, int32_t startPointPosY);
256     bool IsPointInDragHotZone(int32_t startPointPosX, int32_t startPointPosY,
257         int32_t sourceType, const WSRect& winRect);
258     void CalculateStartRectExceptHotZone(float vpr, const WSRect& winRect);
259     WSError UpdateMoveTempProperty(const std::shared_ptr<MMI::PointerEvent>& pointerEvent);
260     bool CheckDragEventLegal(const std::shared_ptr<MMI::PointerEvent>& pointerEvent,
261         const sptr<WindowSessionProperty> property);
262     void ResSchedReportData(int32_t type, bool onOffTag);
263     void NotifyWindowInputPidChange(bool isServerPid);
264 
265     /*
266      * Cross Display Move Drag
267      */
268     std::pair<int32_t, int32_t> CalcUnifiedTranslate(const std::shared_ptr<MMI::PointerEvent>& pointerEvent);
269 
270     bool isStartMove_ = false;
271     bool isStartDrag_ = false;
272     bool isMovable_ = true;
273     bool isDecorEnable_ = true;
274     bool hasPointDown_ = false;
275     float aspectRatio_ = 0.0f;
276     float vpr_ = 1.0f;
277     int32_t minTranX_ = INT32_MIN;
278     int32_t minTranY_ = INT32_MIN;
279     int32_t maxTranX_ = INT32_MAX;
280     int32_t maxTranY_ = INT32_MAX;
281     AreaType type_ = AreaType::UNDEFINED;
282     AxisType mainMoveAxis_ = AxisType::UNDEFINED;
283     WindowLimits limits_;
284     MoveDragProperty moveDragProperty_;
285     MoveDragCallback moveDragCallback_;
286     int32_t persistentId_;
287     WindowType winType_;
288 
289     enum class DragType : uint32_t {
290         DRAG_UNDEFINED,
291         DRAG_LEFT_OR_RIGHT,
292         DRAG_BOTTOM_OR_TOP,
293         DRAG_LEFT_TOP_CORNER,
294         DRAG_RIGHT_TOP_CORNER,
295     };
296     const std::map<DragType, uint32_t> STYLEID_MAP = {
297         {DragType::DRAG_UNDEFINED,        MMI::MOUSE_ICON::DEFAULT},
298         {DragType::DRAG_BOTTOM_OR_TOP,    MMI::MOUSE_ICON::NORTH_SOUTH},
299         {DragType::DRAG_LEFT_OR_RIGHT,    MMI::MOUSE_ICON::WEST_EAST},
300         {DragType::DRAG_LEFT_TOP_CORNER,  MMI::MOUSE_ICON::NORTH_WEST_SOUTH_EAST},
301         {DragType::DRAG_RIGHT_TOP_CORNER, MMI::MOUSE_ICON::NORTH_EAST_SOUTH_WEST}
302     };
303     Rect rectExceptFrame_ { 0, 0, 0, 0 };
304     Rect rectExceptCorner_ { 0, 0, 0, 0 };
305     uint32_t mouseStyleID_ = 0;
306     DragType dragType_ = DragType::DRAG_UNDEFINED;
307     MoveTempProperty moveTempProperty_;
308 
309     void UpdateHotAreaType(const std::shared_ptr<MMI::PointerEvent>& pointerEvent);
310     void ProcessWindowDragHotAreaFunc(bool flag, SizeChangeReason reason);
311     uint32_t windowDragHotAreaType_ = WINDOW_HOT_AREA_TYPE_UNDEFINED;
312     NotifyWindowDragHotAreaFunc windowDragHotAreaFunc_;
313     NotifyWindowPidChangeCallback pidChangeCallback_;
314 
315     const std::map<AreaType, Gravity> GRAVITY_MAP = {
316         {AreaType::LEFT,          Gravity::TOP_RIGHT},
317         {AreaType::TOP,           Gravity::BOTTOM_LEFT},
318         {AreaType::RIGHT,         Gravity::TOP_LEFT},
319         {AreaType::BOTTOM,        Gravity::TOP_LEFT},
320         {AreaType::LEFT_TOP,      Gravity::BOTTOM_RIGHT},
321         {AreaType::RIGHT_TOP,     Gravity::BOTTOM_LEFT},
322         {AreaType::RIGHT_BOTTOM,  Gravity::TOP_LEFT},
323         {AreaType::LEFT_BOTTOM,   Gravity::TOP_RIGHT}
324     };
325 
326     /*
327      * Cross Display Move Drag
328      */
329     bool moveDragIsInterrupted_ = false;
330     DisplayId moveDragStartDisplayId_ = DISPLAY_ID_INVALID;
331     DisplayId moveDragEndDisplayId_ = DISPLAY_ID_INVALID;
332     uint64_t initParentNodeId_ = -1ULL;
333     DisplayId hotAreaDisplayId_ = 0;
334     int32_t originalDisplayOffsetX_ = 0;
335     int32_t originalDisplayOffsetY_ = 0;
336     float originalPositionZ_ = 0.0f;
337     std::mutex displayIdSetDuringMoveDragMutex_;
338     std::set<uint64_t> displayIdSetDuringMoveDrag_;
339     DMRect moveAvailableArea_ = {0, 0, 0, 0};
340     DisplayId moveInputBarStartDisplayId_ = DISPLAY_ID_INVALID;
341     ScreenSizeProperty screenSizeProperty_;
342     int32_t lastMovePointerPosX_ = -1;
343     bool isMoveDragHotAreaCrossDisplay_ = false;
344     // Above guarded by displayIdSetDuringMoveDragMutex_
345 };
346 } // namespace OHOS::Rosen
347 #endif // OHOS_ROSEN_WINDOW_SCENE_MOVE_DRAG_CONTROLLER_H
348