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