• 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     void SetStartDragFlag(bool flag);
72     bool GetStartMoveFlag() const;
73     bool GetStartDragFlag() const;
74     bool HasPointDown();
75     void SetMovable(bool movable);
76     bool GetMovable() const;
77     void SetNotifyWindowPidChangeCallback(const NotifyWindowPidChangeCallback& callback);
78     WSRect GetTargetRect(TargetRectCoordinate coordinate) const;
79     WSRect GetTargetRectByDisplayId(DisplayId displayId) const;
80     void SetTargetRect(const WSRect& rect);
81     WSRect GetOriginalRect() const;
82     void InitMoveDragProperty();
83     void SetOriginalMoveDragPos(int32_t pointerId, int32_t pointerType, int32_t pointerPosX,
84                                 int32_t pointerPosY, int32_t pointerWindowX, int32_t pointerWindowY,
85                                 const WSRect& winRect);
86     void SetAspectRatio(float ratio);
87     bool ConsumeMoveEvent(const std::shared_ptr<MMI::PointerEvent>& pointerEvent, const WSRect& originalRect);
88     bool ConsumeDragEvent(const std::shared_ptr<MMI::PointerEvent>& pointerEvent, const WSRect& originalRect,
89         const sptr<WindowSessionProperty> property, const SystemSessionConfig& sysConfig);
90     void ModifyWindowCoordinatesWhenMoveEnd(const std::shared_ptr<MMI::PointerEvent>& pointerEvent);
91     void CalcFirstMoveTargetRect(const WSRect& windowRect, bool useWindowRect);
92     WSRect GetFullScreenToFloatingRect(const WSRect& originalRect, const WSRect& windowRect);
93     int32_t GetOriginalPointerPosX();
94     int32_t GetOriginalPointerPosY();
95     int32_t GetPointerType() const;
96     void SetWindowDragHotAreaFunc(const NotifyWindowDragHotAreaFunc& func);
97     void UpdateGravityWhenDrag(const std::shared_ptr<MMI::PointerEvent>& pointerEvent,
98         const std::shared_ptr<RSSurfaceNode>& surfaceNode);
99     void UpdateSubWindowGravityWhenFollow(const sptr<MoveDragController>& followedController,
100         const std::shared_ptr<RSSurfaceNode>& surfaceNode);
101     void OnLostFocus();
GetAreaType()102     AreaType GetAreaType() const { return type_; };
103     void SetScale(float scalex, float scaley);
104     void SetParentRect(const Rect& parentRect);
105     Gravity GetGravity() const;
106 
107     /*
108      * Cross Display Move Drag
109      */
110     uint64_t GetMoveDragStartDisplayId() const;
111     uint64_t GetMoveDragEndDisplayId() const;
112     uint64_t GetInitParentNodeId() const;
113     std::set<uint64_t> GetDisplayIdsDuringMoveDrag();
114     std::set<uint64_t> GetNewAddedDisplayIdsDuringMoveDrag();
115     void InitCrossDisplayProperty(DisplayId displayId, uint64_t parentNodeId);
116     WSRect GetScreenRectById(DisplayId displayId);
117     DisplayId GetMoveInputBarStartDisplayId();
118     void ResetCrossMoveDragProperty();
119     void MoveDragInterrupted(bool resetPosition = true);
120     void SetMoveAvailableArea(const DMRect& area);
121     void UpdateMoveAvailableArea(DisplayId targetDisplayId);
122     void SetCurrentScreenProperty(DisplayId targetDisplayId);
123     void SetMoveInputBarStartDisplayId(DisplayId displayId);
124     void SetInputBarCrossAttr(MoveDirection moveDirection, DisplayId targetDisplayId);
125     void SetOriginalDisplayOffset(int32_t offsetX, int32_t offsetY);
SetOriginalPositionZ(float originalPositionZ)126     void SetOriginalPositionZ(float originalPositionZ) { originalPositionZ_ = originalPositionZ; }
GetOriginalPositionZ()127     float GetOriginalPositionZ() const { return originalPositionZ_; }
128     bool IsSupportWindowDragCrossDisplay();
129 
130     /*
131      * Monitor screen connection status
132      */
133     void OnConnect(ScreenId screenId) override;
134     void OnDisconnect(ScreenId screenId) override;
135     void OnChange(ScreenId screenId) override;
136 
137     /*
138      * PC Window Layout
139      */
140     struct MoveCoordinateProperty {
141         int32_t pointerWindowX = 0;
142         int32_t pointerWindowY = 0;
143         int32_t pointerPosX = 0;
144         int32_t pointerPosY = 0;
145         DisplayId displayId = DISPLAY_ID_INVALID;
146         WSRect winRect = { 0, 0, 0, 0 };
147     };
148     void HandleStartMovingWithCoordinate(const MoveCoordinateProperty& property);
149     void SetSpecifyMoveStartDisplay(DisplayId displayId);
150     void ClearSpecifyMoveStartDisplay();
151     WSRect GetTargetDisplayRectRelatedToStartDisplay(WSRect rect, DisplayId displayId) const;
152     void StopMoving();
SetLastDragEndRect(const WSRect & rect)153     void SetLastDragEndRect(const WSRect& rect) { lastDragEndRect_ = rect; }
GetLastDragEndRect()154     WSRect GetLastDragEndRect() const { return lastDragEndRect_; }
155 
156 private:
157     struct MoveDragProperty {
158         int32_t pointerId_ = -1;
159         int32_t pointerType_ = -1;
160         int32_t originalPointerPosX_ = -1;
161         int32_t originalPointerPosY_ = -1;
162         // the x coordinate of the pointer related to the active window
163         int32_t originalPointerWindowX_ = -1;
164         // the y coordinate of the pointer related to the active window
165         int32_t originalPointerWindowY_ = -1;
166         // the x coordinate scale of the active window
167         float scaleX_ = 1.0f;
168         // the y coordinate scale of the active window
169         float scaleY_ = 1.0f;
170         WSRect originalRect_ = { 0, 0, 0, 0 };
171         WSRect targetRect_ = { 0, 0, 0, 0 };
172 
isEmptyMoveDragProperty173         bool isEmpty() const
174         {
175             return (pointerId_ == -1 && originalPointerPosX_ == -1 && originalPointerPosY_ == -1);
176         }
177     };
178 
179     struct MoveTempProperty {
180         int32_t pointerId_ = -1;
181         int32_t pointerType_ = -1;
182         int32_t lastDownPointerPosX_ = -1;
183         int32_t lastDownPointerPosY_ = -1;
184         int32_t lastDownPointerWindowX_ = -1;
185         int32_t lastDownPointerWindowY_ = -1;
186         int32_t lastMovePointerPosX_ = -1;
187         int32_t lastMovePointerPosY_ = -1;
188 
isEmptyMoveTempProperty189         bool isEmpty() const
190         {
191             return (pointerId_ == -1 && lastDownPointerPosX_ == -1 && lastDownPointerPosY_ == -1);
192         }
193     };
194 
195     struct ScreenSizeProperty {
196         uint32_t currentDisplayStartX = 0;
197         uint32_t currentDisplayStartY = 0;
198         int32_t currentDisplayLeft = 0;
199         int32_t currentDisplayTop = 0;
200         int32_t width = 0;
201         int32_t height = 0;
202 
IsEmptyScreenSizeProperty203         bool IsEmpty() const
204         {
205             return (currentDisplayStartX == 0 && currentDisplayStartY == 0 && currentDisplayLeft == 0 &&
206                     currentDisplayTop == 0 && width == 0 && height == 0);
207         }
208 
ResetScreenSizeProperty209         void Reset()
210         {
211             currentDisplayStartX = 0;
212             currentDisplayStartY = 0;
213             currentDisplayLeft = 0;
214             currentDisplayTop = 0;
215             width = 0;
216             height = 0;
217         }
218 
ToStringScreenSizeProperty219         std::string ToString() const
220         {
221             if (IsEmpty()) {
222                 return "empty";
223             }
224 
225             std::ostringstream ss;
226             ss << "currentDisplayStartX: " << currentDisplayStartX << ","
227                << "currentDisplayStartY: " << currentDisplayStartY << ","
228                << "currentDisplayLeft: " << currentDisplayLeft << ","
229                << "currentDisplayTop: " << currentDisplayTop << ","
230                << "width: " << width << "," << "height: " << height;
231             return ss.str();
232         }
233     };
234     enum AxisType { UNDEFINED, X_AXIS, Y_AXIS };
235     constexpr static float NEAR_ZERO = 0.001f;
236 
237     bool CalcMoveTargetRect(const std::shared_ptr<MMI::PointerEvent>& pointerEvent, const WSRect& originalRect);
238     void CalcDragTargetRect(const std::shared_ptr<MMI::PointerEvent>& pointerEvent, SizeChangeReason reason);
239     bool EventDownInit(const std::shared_ptr<MMI::PointerEvent>& pointerEvent, const WSRect& originalRect,
240         const sptr<WindowSessionProperty> property, const SystemSessionConfig& sysConfig);
241     bool CalcMoveInputBarRect(const std::shared_ptr<MMI::PointerEvent>& pointerEvent, const WSRect& originalRect);
242     void AdjustTargetPositionByAvailableArea(int32_t& moveDragFinalX, int32_t& moveDragFinalY);
243     MoveDirection CalcMoveDirection(DisplayId lastDisplayId, DisplayId currentDisplayId);
244 
245     void InitializeMoveDragPropertyNotValid(const std::shared_ptr<MMI::PointerEvent>& pointerEvent,
246                                             const WSRect& originalRect);
247     bool CheckAndInitializeMoveDragProperty(const std::shared_ptr<MMI::PointerEvent>& pointerEvent,
248                                             const WSRect& originalRect);
249     void HandleLeftToRightCross(DisplayId targetDisplayId, int32_t pointerDisplayX, int32_t pointerDisplayY,
250             int32_t& moveDragFinalX, int32_t& moveDragFinalY);
251     void HandleRightToLeftCross(DisplayId targetDisplayId, int32_t pointerDisplayX, int32_t pointerDisplayY,
252             int32_t& moveDragFinalX, int32_t& moveDragFinalY);
253     void HandleUpToBottomCross(DisplayId targetDisplayId, int32_t pointerDisplayX, int32_t pointerDisplayY,
254             int32_t& moveDragFinalX, int32_t& moveDragFinalY);
255     void HandleBottomToUpCross(DisplayId targetDisplayId, int32_t pointerDisplayX, int32_t pointerDisplayY,
256             int32_t& moveDragFinalX, int32_t& moveDragFinalY);
257     void CalcMoveForSameDisplay(const std::shared_ptr<MMI::PointerEvent>& pointerEvent,
258                                 int32_t& moveDragFinalX, int32_t& moveDragFinalY);
259     AreaType GetAreaType(int32_t pointWinX, int32_t pointWinY, int32_t sourceType, const WSRect& rect);
260     WSRect CalcFreeformTargetRect(AreaType type, int32_t tranX, int32_t tranY, WSRect originalRect);
261     WSRect CalcFixedAspectRatioTargetRect(AreaType type, int32_t tranX, int32_t tranY, float aspectRatio,
262         WSRect originalRect);
263     void CalcFreeformTranslateLimits(AreaType type);
264     void CalcFixedAspectRatioTranslateLimits(AreaType type);
265     void FixTranslateByLimits(int32_t& tranX, int32_t& tranY);
266     bool InitMainAxis(AreaType type, int32_t tranX, int32_t tranY);
267     void ConvertXYByAspectRatio(int32_t& tx, int32_t& ty, float aspectRatio);
268     int32_t ConvertByAreaType(int32_t tran) const;
269     void ProcessSessionRectChange(SizeChangeReason reason);
270     void InitDecorValue(const sptr<WindowSessionProperty> property, const SystemSessionConfig& sysConfig);
271 
272     float GetVirtualPixelRatio() const;
273     void UpdateDragType(int32_t startPointPosX, int32_t startPointPosY);
274     bool IsPointInDragHotZone(int32_t startPointPosX, int32_t startPointPosY,
275         int32_t sourceType, const WSRect& winRect);
276     void CalculateStartRectExceptHotZone(float vpr, const WSRect& winRect);
277     WSError UpdateMoveTempProperty(const std::shared_ptr<MMI::PointerEvent>& pointerEvent);
278     bool CheckDragEventLegal(const std::shared_ptr<MMI::PointerEvent>& pointerEvent,
279         const sptr<WindowSessionProperty> property);
280     void ResSchedReportData(int32_t type, bool onOffTag);
281     void NotifyWindowInputPidChange(bool isServerPid);
282 
283     /*
284      * Cross Display Move Drag
285      */
286     std::pair<int32_t, int32_t> CalcUnifiedTranslate(const std::shared_ptr<MMI::PointerEvent>& pointerEvent);
287 
288     bool isStartMove_ = false;
289     bool isStartDrag_ = false;
290     bool isMovable_ = true;
291     bool isDecorEnable_ = true;
292     bool hasPointDown_ = false;
293     bool isAdaptToDragScale_ = false;
294     float aspectRatio_ = 0.0f;
295     float vpr_ = 1.0f;
296     int32_t minTranX_ = INT32_MIN;
297     int32_t minTranY_ = INT32_MIN;
298     int32_t maxTranX_ = INT32_MAX;
299     int32_t maxTranY_ = INT32_MAX;
300     AreaType type_ = AreaType::UNDEFINED;
301     AreaType dragAreaType_ = AreaType::UNDEFINED;
302     AxisType mainMoveAxis_ = AxisType::UNDEFINED;
303     WindowLimits limits_;
304     MoveDragProperty moveDragProperty_;
305     MoveDragCallback moveDragCallback_;
306     int32_t persistentId_;
307     WindowType winType_;
308 
309     enum class DragType : uint32_t {
310         DRAG_UNDEFINED,
311         DRAG_LEFT_OR_RIGHT,
312         DRAG_BOTTOM_OR_TOP,
313         DRAG_LEFT_TOP_CORNER,
314         DRAG_RIGHT_TOP_CORNER,
315     };
316     const std::map<DragType, uint32_t> STYLEID_MAP = {
317         {DragType::DRAG_UNDEFINED,        MMI::MOUSE_ICON::DEFAULT},
318         {DragType::DRAG_BOTTOM_OR_TOP,    MMI::MOUSE_ICON::NORTH_SOUTH},
319         {DragType::DRAG_LEFT_OR_RIGHT,    MMI::MOUSE_ICON::WEST_EAST},
320         {DragType::DRAG_LEFT_TOP_CORNER,  MMI::MOUSE_ICON::NORTH_WEST_SOUTH_EAST},
321         {DragType::DRAG_RIGHT_TOP_CORNER, MMI::MOUSE_ICON::NORTH_EAST_SOUTH_WEST}
322     };
323     Rect rectExceptFrame_ { 0, 0, 0, 0 };
324     Rect rectExceptCorner_ { 0, 0, 0, 0 };
325     Rect parentRect_ { 0, 0, 0, 0};
326     uint32_t mouseStyleID_ = 0;
327     DragType dragType_ = DragType::DRAG_UNDEFINED;
328     MoveTempProperty moveTempProperty_;
329 
330     void UpdateHotAreaType(const std::shared_ptr<MMI::PointerEvent>& pointerEvent);
331     void ProcessWindowDragHotAreaFunc(bool flag, SizeChangeReason reason);
332     uint32_t windowDragHotAreaType_ = WINDOW_HOT_AREA_TYPE_UNDEFINED;
333     NotifyWindowDragHotAreaFunc windowDragHotAreaFunc_;
334     NotifyWindowPidChangeCallback pidChangeCallback_;
335 
336     const std::map<AreaType, Gravity> GRAVITY_MAP = {
337         {AreaType::LEFT,          Gravity::TOP_RIGHT},
338         {AreaType::TOP,           Gravity::BOTTOM_LEFT},
339         {AreaType::RIGHT,         Gravity::TOP_LEFT},
340         {AreaType::BOTTOM,        Gravity::TOP_LEFT},
341         {AreaType::LEFT_TOP,      Gravity::BOTTOM_RIGHT},
342         {AreaType::RIGHT_TOP,     Gravity::BOTTOM_LEFT},
343         {AreaType::RIGHT_BOTTOM,  Gravity::TOP_LEFT},
344         {AreaType::LEFT_BOTTOM,   Gravity::TOP_RIGHT}
345     };
346 
347     /*
348      * Cross Display Move Drag
349      */
350     bool moveDragIsInterrupted_ = false;
351     DisplayId moveDragStartDisplayId_ = DISPLAY_ID_INVALID;
352     DisplayId moveDragEndDisplayId_ = DISPLAY_ID_INVALID;
353     uint64_t initParentNodeId_ = -1ULL;
354     DisplayId hotAreaDisplayId_ = 0;
355     int32_t originalDisplayOffsetX_ = 0;
356     int32_t originalDisplayOffsetY_ = 0;
357     float originalPositionZ_ = 0.0f;
358     std::mutex displayIdSetDuringMoveDragMutex_;
359     std::set<uint64_t> displayIdSetDuringMoveDrag_;
360     DMRect moveAvailableArea_ = {0, 0, 0, 0};
361     DisplayId moveInputBarStartDisplayId_ = DISPLAY_ID_INVALID;
362     ScreenSizeProperty screenSizeProperty_;
363     // Above guarded by displayIdSetDuringMoveDragMutex_
364     std::mutex specifyMoveStartMutex_;
365     DisplayId specifyMoveStartDisplayId_ = DISPLAY_ID_INVALID;
366     bool isSpecifyMoveStart_ = false;
367     bool isAdaptToProportionalScale_ = false;
368     // Above guarded by specifyMoveStartMutex_
369 
370     /*
371      * PC Window Layout
372      */
373     WSRect lastDragEndRect_ = { 0, 0, 0, 0 };
374 };
375 } // namespace OHOS::Rosen
376 #endif // OHOS_ROSEN_WINDOW_SCENE_MOVE_DRAG_CONTROLLER_H
377