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