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 #include "session/host/include/move_drag_controller.h"
17
18 #include <hitrace_meter.h>
19 #include <pointer_event.h>
20 #include <transaction/rs_transaction.h>
21 #include <ui/rs_surface_node.h>
22
23 #include <cinttypes>
24
25 #include "display_manager.h"
26 #include "input_manager.h"
27 #include "screen_session_manager_client/include/screen_session_manager_client.h"
28 #include "session/host/include/scene_persistent_storage.h"
29 #include "session/host/include/scene_session.h"
30 #include "session/host/include/session_utils.h"
31 #include "session_helper.h"
32 #include "window_helper.h"
33 #include "window_manager_hilog.h"
34 #include "wm_common_inner.h"
35
36 #ifdef RES_SCHED_ENABLE
37 #include "res_sched_client.h"
38 #include "res_type.h"
39 #endif
40
41 namespace OHOS::Rosen {
42 namespace {
43 constexpr HiviewDFX::HiLogLabel LABEL = {LOG_CORE, HILOG_DOMAIN_WINDOW, "MoveDragController"};
44 }
45
MoveDragController(int32_t persistentId,WindowType winType)46 MoveDragController::MoveDragController(int32_t persistentId, WindowType winType)
47 {
48 persistentId_ = persistentId;
49 winType_ = winType;
50 }
51
OnConnect(ScreenId id)52 void MoveDragController::OnConnect(ScreenId id)
53 {
54 TLOGW(WmsLogTag::WMS_LAYOUT, "Moving or dragging is interrupt due to new screen %{public}" PRIu64 " connection.",
55 id);
56 moveDragIsInterrupted_ = true;
57 }
58
OnDisconnect(ScreenId id)59 void MoveDragController::OnDisconnect(ScreenId id)
60 {
61 TLOGW(WmsLogTag::WMS_LAYOUT, "Moving or dragging is interrupt due to screen %{public}" PRIu64 " disconnection.",
62 id);
63 moveDragIsInterrupted_ = true;
64 }
65
OnChange(ScreenId id)66 void MoveDragController::OnChange(ScreenId id)
67 {
68 TLOGW(WmsLogTag::WMS_LAYOUT, "Moving or dragging is interrupt due to screen %{public}" PRIu64 " change.", id);
69 moveDragIsInterrupted_ = true;
70 }
71
RegisterMoveDragCallback(const MoveDragCallback & callBack)72 void MoveDragController::RegisterMoveDragCallback(const MoveDragCallback& callBack)
73 {
74 moveDragCallback_ = callBack;
75 }
76
NotifyWindowInputPidChange(bool isServerPid)77 void MoveDragController::NotifyWindowInputPidChange(bool isServerPid)
78 {
79 if (pidChangeCallback_) {
80 pidChangeCallback_(persistentId_, isServerPid);
81 WLOGFI("id: %{public}d, isServerPid:%{public}d", persistentId_, isServerPid);
82 }
83 }
84
HasPointDown()85 bool MoveDragController::HasPointDown()
86 {
87 return hasPointDown_;
88 }
89
SetStartMoveFlag(bool flag)90 void MoveDragController::SetStartMoveFlag(bool flag)
91 {
92 if (flag && (!hasPointDown_ || isStartDrag_)) {
93 WLOGFD("StartMove, but has not pointed down or is dragging, hasPointDown_: %{public}d, isStartFlag: %{public}d",
94 hasPointDown_, isStartDrag_);
95 return;
96 }
97 NotifyWindowInputPidChange(flag);
98 isStartMove_ = flag;
99 ResSchedReportData(OHOS::ResourceSchedule::ResType::RES_TYPE_MOVE_WINDOW, flag);
100 WLOGFI("SetStartMoveFlag, isStartMove_: %{public}d id:%{public}d", isStartMove_, persistentId_);
101 }
102
SetMovable(bool isMovable)103 void MoveDragController::SetMovable(bool isMovable)
104 {
105 isMovable_ = isMovable;
106 }
107
SetNotifyWindowPidChangeCallback(const NotifyWindowPidChangeCallback & callback)108 void MoveDragController::SetNotifyWindowPidChangeCallback(const NotifyWindowPidChangeCallback& callback)
109 {
110 pidChangeCallback_ = callback;
111 }
112
GetStartMoveFlag() const113 bool MoveDragController::GetStartMoveFlag() const
114 {
115 WLOGFD("GetStartMoveFlag, isStartMove_: %{public}d id:%{public}d", isStartMove_, persistentId_);
116 return isStartMove_;
117 }
118
GetStartDragFlag() const119 bool MoveDragController::GetStartDragFlag() const
120 {
121 return isStartDrag_;
122 }
123
GetMoveDragStartDisplayId() const124 uint64_t MoveDragController::GetMoveDragStartDisplayId() const
125 {
126 return moveDragStartDisplayId_;
127 }
128
GetMoveDragEndDisplayId() const129 uint64_t MoveDragController::GetMoveDragEndDisplayId() const
130 {
131 return moveDragEndDisplayId_;
132 }
133
GetInitParentNodeId() const134 uint64_t MoveDragController::GetInitParentNodeId() const
135 {
136 return initParentNodeId_;
137 }
138
GetDisplayIdsDuringMoveDrag()139 std::set<uint64_t> MoveDragController::GetDisplayIdsDuringMoveDrag()
140 {
141 std::lock_guard<std::mutex> lock(displayIdSetDuringMoveDragMutex_);
142 return displayIdSetDuringMoveDrag_;
143 }
144
GetMovable() const145 bool MoveDragController::GetMovable() const
146 {
147 return isMovable_;
148 }
149
SetTargetRect(const WSRect & rect)150 void MoveDragController::SetTargetRect(const WSRect& rect)
151 {
152 moveDragProperty_.targetRect_ = rect;
153 }
154
GetOriginalRect() const155 WSRect MoveDragController::GetOriginalRect() const
156 {
157 return moveDragProperty_.originalRect_;
158 }
159
GetTargetRect(TargetRectCoordinate coordinate) const160 WSRect MoveDragController::GetTargetRect(TargetRectCoordinate coordinate) const
161 {
162 DisplayId relatedDisplayId = DISPLAY_ID_INVALID;
163 switch (coordinate) {
164 case TargetRectCoordinate::GLOBAL:
165 return {moveDragProperty_.targetRect_.posX_ + originalDisplayOffsetX_,
166 moveDragProperty_.targetRect_.posY_ + originalDisplayOffsetY_,
167 moveDragProperty_.targetRect_.width_,
168 moveDragProperty_.targetRect_.height_};
169 case TargetRectCoordinate::RELATED_TO_START_DISPLAY:
170 return moveDragProperty_.targetRect_;
171 case TargetRectCoordinate::RELATED_TO_END_DISPLAY:
172 relatedDisplayId = moveDragEndDisplayId_;
173 break;
174 default:
175 return moveDragProperty_.targetRect_;
176 }
177 return GetTargetRectByDisplayId(relatedDisplayId);
178 }
179
GetTargetRectByDisplayId(DisplayId displayId) const180 WSRect MoveDragController::GetTargetRectByDisplayId(DisplayId displayId) const
181 {
182 sptr<ScreenSession> screenSession =
183 ScreenSessionManagerClient::GetInstance().GetScreenSessionById(displayId);
184 if (!screenSession) {
185 TLOGW(WmsLogTag::WMS_LAYOUT, "Screen session is null, return relative coordinates.");
186 return moveDragProperty_.targetRect_;
187 }
188 ScreenProperty screenProperty = screenSession->GetScreenProperty();
189 int32_t currentDisplayOffsetX = static_cast<int32_t>(screenProperty.GetStartX());
190 int32_t currentDisplayOffsetY = static_cast<int32_t>(screenProperty.GetStartY());
191 return {moveDragProperty_.targetRect_.posX_ + originalDisplayOffsetX_ - currentDisplayOffsetX,
192 moveDragProperty_.targetRect_.posY_ + originalDisplayOffsetY_ - currentDisplayOffsetY,
193 moveDragProperty_.targetRect_.width_,
194 moveDragProperty_.targetRect_.height_};
195 }
196
UpdateSubWindowGravityWhenFollow(const sptr<MoveDragController> & followedController,const std::shared_ptr<RSSurfaceNode> & surfaceNode)197 void MoveDragController::UpdateSubWindowGravityWhenFollow(const sptr<MoveDragController>& followedController,
198 const std::shared_ptr<RSSurfaceNode>& surfaceNode)
199 {
200 if (surfaceNode == nullptr || followedController == nullptr) {
201 TLOGE(WmsLogTag::WMS_LAYOUT, "surfaceNode or followedController is null");
202 return;
203 }
204 auto type = followedController->GetAreaType();
205 if (type == AreaType::UNDEFINED) {
206 TLOGI(WmsLogTag::WMS_LAYOUT, "type undefined");
207 return;
208 }
209 Gravity dragGravity = GRAVITY_MAP.at(type);
210 if (dragGravity >= Gravity::TOP && dragGravity <= Gravity::BOTTOM_RIGHT) {
211 TLOGI(WmsLogTag::WMS_LAYOUT, "begin SetFrameGravity when follow, gravity:%{public}d, type:%{public}d",
212 dragGravity, type);
213 surfaceNode->SetFrameGravity(dragGravity);
214 RSTransaction::FlushImplicitTransaction();
215 }
216 }
217
218 /** @note @window.drag */
InitMoveDragProperty()219 void MoveDragController::InitMoveDragProperty()
220 {
221 moveDragProperty_ = {-1, -1, -1, -1, -1, -1, {0, 0, 0, 0}, {0, 0, 0, 0}};
222 }
223
InitCrossDisplayProperty(DisplayId displayId,uint64_t initParentNodeId)224 void MoveDragController::InitCrossDisplayProperty(DisplayId displayId, uint64_t initParentNodeId)
225 {
226 DMError error = ScreenManager::GetInstance().RegisterScreenListener(this);
227 if (error != DMError::DM_OK) {
228 TLOGW(WmsLogTag::WMS_LAYOUT, "Register ScreenListener false.");
229 }
230 {
231 std::lock_guard<std::mutex> lock(displayIdSetDuringMoveDragMutex_);
232 displayIdSetDuringMoveDrag_.insert(displayId);
233 }
234 moveDragStartDisplayId_ = displayId;
235 initParentNodeId_ = initParentNodeId;
236 sptr<ScreenSession> screenSession =
237 ScreenSessionManagerClient::GetInstance().GetScreenSessionById(moveDragStartDisplayId_);
238 if (!screenSession) {
239 return;
240 }
241 ScreenProperty screenProperty = screenSession->GetScreenProperty();
242 originalDisplayOffsetX_ = static_cast<int32_t>(screenProperty.GetStartX());
243 originalDisplayOffsetY_ = static_cast<int32_t>(screenProperty.GetStartY());
244 TLOGI(WmsLogTag::WMS_LAYOUT, "moveDragStartDisplayId: %{public}" PRIu64 ", "
245 "originalDisplayOffsetX: %{public}d, originalDisplayOffsetY: %{public}d",
246 moveDragStartDisplayId_, originalDisplayOffsetX_, originalDisplayOffsetY_);
247 }
248
249 /** @note @window.drag */
ResetCrossMoveDragProperty()250 void MoveDragController::ResetCrossMoveDragProperty()
251 {
252 moveDragProperty_ = {-1, -1, -1, -1, -1, -1, {0, 0, 0, 0}, {0, 0, 0, 0}};
253 DMError error = ScreenManager::GetInstance().UnregisterScreenListener(this);
254 if (error != DMError::DM_OK) {
255 TLOGW(WmsLogTag::WMS_LAYOUT, "Register ScreenListener false.");
256 }
257 {
258 std::lock_guard<std::mutex> lock(displayIdSetDuringMoveDragMutex_);
259 displayIdSetDuringMoveDrag_.clear();
260 }
261 moveDragStartDisplayId_ = DISPLAY_ID_INVALID;
262 moveInputBarStartDisplayId_ = DISPLAY_ID_INVALID;
263 moveDragEndDisplayId_ = DISPLAY_ID_INVALID;
264 initParentNodeId_ = -1;
265 originalDisplayOffsetX_ = 0;
266 originalDisplayOffsetY_ = 0;
267 moveDragIsInterrupted_ = false;
268 }
269
SetOriginalMoveDragPos(int32_t pointerId,int32_t pointerType,int32_t pointerPosX,int32_t pointerPosY,int32_t pointerWindowX,int32_t pointerWindowY,const WSRect & winRect)270 void MoveDragController::SetOriginalMoveDragPos(int32_t pointerId, int32_t pointerType, int32_t pointerPosX,
271 int32_t pointerPosY, int32_t pointerWindowX, int32_t pointerWindowY, const WSRect& winRect)
272 {
273 moveDragProperty_.pointerId_ = pointerId;
274 moveDragProperty_.pointerType_ = pointerType;
275 moveDragProperty_.originalPointerPosX_ = pointerPosX;
276 moveDragProperty_.originalPointerPosY_ = pointerPosY;
277 moveDragProperty_.originalPointerWindowX_ = pointerWindowX;
278 moveDragProperty_.originalPointerWindowY_ = pointerWindowY;
279 moveDragProperty_.originalRect_ = winRect;
280 }
281
282 /** @note @window.drag */
GetFullScreenToFloatingRect(const WSRect & originalRect,const WSRect & windowRect)283 WSRect MoveDragController::GetFullScreenToFloatingRect(const WSRect& originalRect, const WSRect& windowRect)
284 {
285 if (moveTempProperty_.isEmpty()) {
286 TLOGI(WmsLogTag::WMS_LAYOUT, "move temporary property is empty");
287 return originalRect;
288 }
289 if (originalRect.width_ == 0) {
290 TLOGI(WmsLogTag::WMS_LAYOUT, "original rect witch is zero");
291 return windowRect;
292 }
293 // Drag and drop to full screen in proportion
294 float newPosX = static_cast<float>(windowRect.width_) / static_cast<float>(originalRect.width_) *
295 static_cast<float>(moveTempProperty_.lastDownPointerPosX_ - originalRect.posX_);
296 WSRect targetRect = {
297 moveTempProperty_.lastDownPointerPosX_ - static_cast<int32_t>(newPosX),
298 originalRect.posY_,
299 windowRect.width_,
300 windowRect.height_,
301 };
302 TLOGI(WmsLogTag::WMS_LAYOUT, "target rect [%{public}d,%{public}d,%{public}u,%{public}u]", targetRect.posX_,
303 targetRect.posY_, targetRect.width_, targetRect.height_);
304 return targetRect;
305 }
306
SetAspectRatio(float ratio)307 void MoveDragController::SetAspectRatio(float ratio)
308 {
309 aspectRatio_ = ratio;
310 }
311
ConsumeMoveEvent(const std::shared_ptr<MMI::PointerEvent> & pointerEvent,const WSRect & originalRect)312 bool MoveDragController::ConsumeMoveEvent(const std::shared_ptr<MMI::PointerEvent>& pointerEvent,
313 const WSRect& originalRect)
314 {
315 if (pointerEvent == nullptr) {
316 WLOGE("ConsumeMoveEvent stop because of nullptr");
317 return false;
318 }
319 if (GetStartDragFlag()) {
320 WLOGFI("the window is being resized");
321 return false;
322 }
323 int32_t pointerId = pointerEvent->GetPointerId();
324 int32_t startPointerId = moveDragProperty_.pointerId_;
325 int32_t startPointerType = moveDragProperty_.pointerType_;
326 if ((startPointerId != -1 && startPointerId != pointerId) ||
327 (startPointerType != -1 && pointerEvent->GetSourceType() != startPointerType)) {
328 WLOGFI("block unnecessary pointer event inside the window");
329 return false;
330 }
331 MMI::PointerEvent::PointerItem pointerItem;
332 int32_t sourceType = pointerEvent->GetSourceType();
333 if (!pointerEvent->GetPointerItem(pointerId, pointerItem) ||
334 (sourceType == MMI::PointerEvent::SOURCE_TYPE_MOUSE &&
335 (pointerEvent->GetButtonId() != MMI::PointerEvent::MOUSE_BUTTON_LEFT && !GetStartMoveFlag()))) {
336 WLOGFD("invalid pointerEvent id: %{public}d", persistentId_);
337 return false;
338 }
339
340 UpdateMoveTempProperty(pointerEvent);
341
342 int32_t action = pointerEvent->GetPointerAction();
343 if (!GetStartMoveFlag()) {
344 if (action == MMI::PointerEvent::POINTER_ACTION_DOWN ||
345 action == MMI::PointerEvent::POINTER_ACTION_BUTTON_DOWN) {
346 WLOGFD("Move event hasPointDown");
347 hasPointDown_ = true;
348 } else if (action == MMI::PointerEvent::POINTER_ACTION_UP ||
349 action == MMI::PointerEvent::POINTER_ACTION_BUTTON_UP ||
350 action == MMI::PointerEvent::POINTER_ACTION_CANCEL) {
351 WLOGFD("Reset hasPointDown_ when point up or cancel");
352 hasPointDown_ = false;
353 }
354 WLOGFD("No need to move action id: %{public}d", action);
355 return false;
356 }
357
358 SizeChangeReason reason = SizeChangeReason::DRAG_MOVE;
359 bool ret = true;
360 switch (action) {
361 case MMI::PointerEvent::POINTER_ACTION_MOVE: {
362 if (moveDragIsInterrupted_) {
363 MoveDragInterrupted();
364 return true;
365 }
366 reason = SizeChangeReason::DRAG_MOVE;
367 uint32_t oldWindowDragHotAreaType = windowDragHotAreaType_;
368 moveDragEndDisplayId_ = static_cast<uint64_t>(pointerEvent->GetTargetDisplayId());
369 UpdateHotAreaType(pointerEvent);
370 ProcessWindowDragHotAreaFunc(oldWindowDragHotAreaType != windowDragHotAreaType_, reason);
371 break;
372 }
373 case MMI::PointerEvent::POINTER_ACTION_UP:
374 case MMI::PointerEvent::POINTER_ACTION_BUTTON_UP:
375 case MMI::PointerEvent::POINTER_ACTION_CANCEL:
376 case MMI::PointerEvent::POINTER_ACTION_DOWN:
377 case MMI::PointerEvent::POINTER_ACTION_BUTTON_DOWN: {
378 if (!hasPointDown_) {
379 return true;
380 }
381 if (moveDragIsInterrupted_) {
382 MoveDragInterrupted();
383 return true;
384 }
385 reason = SizeChangeReason::DRAG_END;
386 SetStartMoveFlag(false);
387 hasPointDown_ = false;
388 moveDragEndDisplayId_ = static_cast<uint64_t>(pointerEvent->GetTargetDisplayId());
389 UpdateHotAreaType(pointerEvent);
390 ProcessWindowDragHotAreaFunc(windowDragHotAreaType_ != WINDOW_HOT_AREA_TYPE_UNDEFINED, reason);
391 isMoveDragHotAreaCrossDisplay_ = windowDragHotAreaType_ != WINDOW_HOT_AREA_TYPE_UNDEFINED;
392 // The Pointer up event sent to the ArkUI.
393 ret = false;
394 break;
395 }
396 default:
397 break;
398 }
399
400 if (WindowHelper::IsInputWindow(winType_) && CalcMoveInputBarRect(pointerEvent, originalRect)) {
401 ProcessSessionRectChange(reason);
402 return ret;
403 }
404
405 if (CalcMoveTargetRect(pointerEvent, originalRect)) {
406 ProcessSessionRectChange(reason);
407 }
408 return ret;
409 }
410
411 /** @note @window.drag */
ProcessWindowDragHotAreaFunc(bool isSendHotAreaMessage,SizeChangeReason reason)412 void MoveDragController::ProcessWindowDragHotAreaFunc(bool isSendHotAreaMessage, SizeChangeReason reason)
413 {
414 if (isSendHotAreaMessage) {
415 WLOGFI("ProcessWindowDragHotAreaFunc start, isSendHotAreaMessage: %{public}u, reason: %{public}d",
416 isSendHotAreaMessage, reason);
417 }
418 if (windowDragHotAreaFunc_ && isSendHotAreaMessage) {
419 windowDragHotAreaFunc_(hotAreaDisplayId_, windowDragHotAreaType_, reason);
420 }
421 }
422
423 /** @note @window.drag */
UpdateGravityWhenDrag(const std::shared_ptr<MMI::PointerEvent> & pointerEvent,const std::shared_ptr<RSSurfaceNode> & surfaceNode)424 void MoveDragController::UpdateGravityWhenDrag(const std::shared_ptr<MMI::PointerEvent>& pointerEvent,
425 const std::shared_ptr<RSSurfaceNode>& surfaceNode)
426 {
427 if (surfaceNode == nullptr || pointerEvent == nullptr || type_ == AreaType::UNDEFINED) {
428 return;
429 }
430 if (pointerEvent->GetPointerAction() == MMI::PointerEvent::POINTER_ACTION_DOWN ||
431 pointerEvent->GetPointerAction() == MMI::PointerEvent::POINTER_ACTION_BUTTON_DOWN) {
432 Gravity dragGravity = GRAVITY_MAP.at(type_);
433 if (dragGravity >= Gravity::TOP && dragGravity <= Gravity::BOTTOM_RIGHT) {
434 WLOGFI("begin SetFrameGravity:%{public}d, type:%{public}d", dragGravity, type_);
435 surfaceNode->SetFrameGravity(dragGravity);
436 RSTransaction::FlushImplicitTransaction();
437 }
438 return;
439 }
440 }
441
442 /** @note @window.drag */
CalcDragTargetRect(const std::shared_ptr<MMI::PointerEvent> & pointerEvent,SizeChangeReason reason)443 void MoveDragController::CalcDragTargetRect(const std::shared_ptr<MMI::PointerEvent>& pointerEvent,
444 SizeChangeReason reason)
445 {
446 if (reason == SizeChangeReason::DRAG_START) {
447 moveDragProperty_.targetRect_ = moveDragProperty_.originalRect_;
448 TLOGD(WmsLogTag::WMS_LAYOUT, "drag rect:%{public}s", moveDragProperty_.targetRect_.ToString().c_str());
449 return;
450 }
451 std::pair<int32_t, int32_t> trans = CalcUnifiedTranslate(pointerEvent);
452 if (!WindowHelper::IsSystemWindow(winType_) ||
453 static_cast<uint64_t>(pointerEvent->GetTargetDisplayId()) == moveDragStartDisplayId_) {
454 moveDragProperty_.targetRect_ =
455 MathHelper::GreatNotEqual(aspectRatio_, NEAR_ZERO) ?
456 CalcFixedAspectRatioTargetRect(type_, trans.first, trans.second,
457 aspectRatio_, moveDragProperty_.originalRect_):
458 CalcFreeformTargetRect(type_, trans.first, trans.second, moveDragProperty_.originalRect_);
459 }
460 TLOGD(WmsLogTag::WMS_LAYOUT, "drag rect:%{public}s, tranX:%{public}d, tranY:%{public}d",
461 moveDragProperty_.targetRect_.ToString().c_str(), trans.first, trans.second);
462 }
463
464 /** @note @window.drag */
ConsumeDragEvent(const std::shared_ptr<MMI::PointerEvent> & pointerEvent,const WSRect & originalRect,const sptr<WindowSessionProperty> property,const SystemSessionConfig & sysConfig)465 bool MoveDragController::ConsumeDragEvent(const std::shared_ptr<MMI::PointerEvent>& pointerEvent,
466 const WSRect& originalRect, const sptr<WindowSessionProperty> property, const SystemSessionConfig& sysConfig)
467 {
468 if (!CheckDragEventLegal(pointerEvent, property)) {
469 return false;
470 }
471 int32_t pointerId = pointerEvent->GetPointerId();
472 int32_t startPointerId = moveDragProperty_.pointerId_;
473 int32_t startPointerType = moveDragProperty_.pointerType_;
474 if ((startPointerId != -1 && startPointerId != pointerId) ||
475 (startPointerType != -1 && pointerEvent->GetSourceType() != startPointerType)) {
476 TLOGE(WmsLogTag::WMS_LAYOUT, "block unnecessary pointer event inside the window");
477 return false;
478 }
479 MMI::PointerEvent::PointerItem pointerItem;
480 if (!pointerEvent->GetPointerItem(pointerId, pointerItem)) {
481 WLOGE("Get PointerItem failed");
482 return false;
483 }
484 SizeChangeReason reason = SizeChangeReason::UNDEFINED;
485 switch (pointerEvent->GetPointerAction()) {
486 case MMI::PointerEvent::POINTER_ACTION_BUTTON_DOWN:
487 case MMI::PointerEvent::POINTER_ACTION_DOWN: {
488 if (!EventDownInit(pointerEvent, originalRect, property, sysConfig)) {
489 return false;
490 }
491 reason = SizeChangeReason::DRAG_START;
492 ResSchedReportData(OHOS::ResourceSchedule::ResType::RES_TYPE_RESIZE_WINDOW, true);
493 break;
494 }
495 case MMI::PointerEvent::POINTER_ACTION_MOVE: {
496 if (moveDragIsInterrupted_) {
497 MoveDragInterrupted();
498 return true;
499 }
500 reason = SizeChangeReason::DRAG;
501 break;
502 }
503 case MMI::PointerEvent::POINTER_ACTION_UP:
504 case MMI::PointerEvent::POINTER_ACTION_BUTTON_UP:
505 case MMI::PointerEvent::POINTER_ACTION_CANCEL: {
506 if (!hasPointDown_) {
507 return true;
508 }
509 auto screenRect = GetScreenRectById(moveDragStartDisplayId_);
510 if (moveDragIsInterrupted_ || screenRect == WSRect{-1, -1, -1, -1}) {
511 MoveDragInterrupted();
512 return true;
513 }
514 reason = SizeChangeReason::DRAG_END;
515 isStartDrag_ = false;
516 hasPointDown_ = false;
517 moveDragEndDisplayId_ = GetTargetRect(TargetRectCoordinate::GLOBAL).IsOverlap(screenRect) ?
518 moveDragStartDisplayId_ : static_cast<uint64_t>(pointerEvent->GetTargetDisplayId());
519 ResSchedReportData(OHOS::ResourceSchedule::ResType::RES_TYPE_RESIZE_WINDOW, false);
520 NotifyWindowInputPidChange(isStartDrag_);
521 break;
522 }
523 default:
524 return false;
525 }
526 CalcDragTargetRect(pointerEvent, reason);
527 ProcessSessionRectChange(reason);
528 return true;
529 }
530
MoveDragInterrupted(bool resetPosition)531 void MoveDragController::MoveDragInterrupted(bool resetPosition)
532 {
533 TLOGI(WmsLogTag::WMS_LAYOUT, "Screen anomaly, MoveDrag has been interrupted.");
534 SizeChangeReason reason = SizeChangeReason::DRAG_END;
535 hasPointDown_ = false;
536 if (isStartDrag_) {
537 isStartDrag_ = false;
538 ResSchedReportData(OHOS::ResourceSchedule::ResType::RES_TYPE_RESIZE_WINDOW, false);
539 NotifyWindowInputPidChange(isStartDrag_);
540 };
541 if (GetStartMoveFlag()) {
542 SetStartMoveFlag(false);
543 ProcessWindowDragHotAreaFunc(windowDragHotAreaType_ != WINDOW_HOT_AREA_TYPE_UNDEFINED, reason);
544 };
545 if (resetPosition) {
546 moveDragEndDisplayId_ = moveDragStartDisplayId_;
547 moveDragProperty_.targetRect_ = moveDragProperty_.originalRect_;
548 }
549 ProcessSessionRectChange(reason);
550 }
551
StopMoving()552 void MoveDragController::StopMoving()
553 {
554 TLOGD(WmsLogTag::WMS_LAYOUT_PC, "in");
555 SizeChangeReason reason = SizeChangeReason::DRAG_END;
556 hasPointDown_ = false;
557 if (GetStartMoveFlag()) {
558 SetStartMoveFlag(false);
559 ProcessWindowDragHotAreaFunc(windowDragHotAreaType_ != WINDOW_HOT_AREA_TYPE_UNDEFINED, reason);
560 };
561 ProcessSessionRectChange(reason);
562 }
563
GetScreenRectById(DisplayId displayId)564 WSRect MoveDragController::GetScreenRectById(DisplayId displayId)
565 {
566 sptr<ScreenSession> screenSession = ScreenSessionManagerClient::GetInstance().GetScreenSessionById(displayId);
567 if (!screenSession) {
568 TLOGI(WmsLogTag::WMS_LAYOUT, "ScreenSession id null.");
569 return WSRect{-1, -1, -1, -1};
570 }
571 ScreenProperty screenProperty = screenSession->GetScreenProperty();
572 WSRect screenRect = {
573 screenProperty.GetStartX(),
574 screenProperty.GetStartY(),
575 screenProperty.GetBounds().rect_.GetWidth(),
576 screenProperty.GetBounds().rect_.GetHeight(),
577 };
578 return screenRect;
579 }
580
SetMoveAvailableArea(const DMRect & area)581 void MoveDragController::SetMoveAvailableArea(const DMRect& area)
582 {
583 moveAvailableArea_.posX_ = area.posX_;
584 moveAvailableArea_.posY_ = area.posY_;
585 moveAvailableArea_.width_ = area.width_;
586 moveAvailableArea_.height_ = area.height_;
587 }
588
UpdateMoveAvailableArea(DisplayId targetDisplayId)589 void MoveDragController::UpdateMoveAvailableArea(DisplayId targetDisplayId)
590 {
591 sptr<Display> display = DisplayManager::GetInstance().GetDisplayById(targetDisplayId);
592 if (display == nullptr) {
593 TLOGD(WmsLogTag::WMS_KEYBOARD, "Failed to get display");
594 return;
595 }
596 DMRect availableArea;
597 DMError ret = display->GetAvailableArea(availableArea);
598 if (ret != DMError::DM_OK) {
599 return;
600 }
601 SetMoveAvailableArea(availableArea);
602 }
603
SetMoveInputBarStartDisplayId(DisplayId displayId)604 void MoveDragController::SetMoveInputBarStartDisplayId(DisplayId displayId)
605 {
606 moveInputBarStartDisplayId_ = displayId;
607 }
608
GetMoveInputBarStartDisplayId()609 DisplayId MoveDragController::GetMoveInputBarStartDisplayId()
610 {
611 return moveInputBarStartDisplayId_;
612 }
613
SetCurrentScreenProperty(DisplayId targetDisplayId)614 void MoveDragController::SetCurrentScreenProperty(DisplayId targetDisplayId)
615 {
616 sptr<ScreenSession> currentScreenSession =
617 ScreenSessionManagerClient::GetInstance().GetScreenSessionById(targetDisplayId);
618 if (currentScreenSession == nullptr) {
619 TLOGW(WmsLogTag::WMS_KEYBOARD, "Screen session is null");
620 return;
621 }
622 ScreenProperty currentScreenProperty = currentScreenSession->GetScreenProperty();
623 screenSizeProperty_.currentDisplayStartX = currentScreenProperty.GetStartX();
624 screenSizeProperty_.currentDisplayStartY = currentScreenProperty.GetStartY();
625 screenSizeProperty_.currentDisplayLeft = currentScreenProperty.GetBounds().rect_.left_;
626 screenSizeProperty_.currentDisplayTop = currentScreenProperty.GetBounds().rect_.top_;
627 screenSizeProperty_.width = currentScreenProperty.GetBounds().rect_.width_;
628 screenSizeProperty_.height = currentScreenProperty.GetBounds().rect_.height_;
629 }
630
CalcUnifiedTranslate(const std::shared_ptr<MMI::PointerEvent> & pointerEvent)631 std::pair<int32_t, int32_t> MoveDragController::CalcUnifiedTranslate(
632 const std::shared_ptr<MMI::PointerEvent>& pointerEvent)
633 {
634 int32_t pointerId = pointerEvent->GetPointerId();
635 MMI::PointerEvent::PointerItem pointerItem;
636 pointerEvent->GetPointerItem(pointerId, pointerItem);
637 sptr<ScreenSession> screenSession = ScreenSessionManagerClient::GetInstance().GetScreenSessionById(
638 static_cast<uint64_t>(pointerEvent->GetTargetDisplayId()));
639 if (!screenSession) {
640 return std::make_pair(0, 0);
641 }
642 ScreenProperty screenProperty = screenSession->GetScreenProperty();
643 // calculate trans in unified coordinates
644 int32_t currentDisplayTranX = static_cast<int32_t>(screenProperty.GetStartX());
645 int32_t currentDisplayTranY = static_cast<int32_t>(screenProperty.GetStartY());
646 int32_t tranX = (pointerItem.GetDisplayX() + currentDisplayTranX) -
647 (moveDragProperty_.originalPointerPosX_ + originalDisplayOffsetX_);
648 int32_t tranY = (pointerItem.GetDisplayY() + currentDisplayTranY) -
649 (moveDragProperty_.originalPointerPosY_ + originalDisplayOffsetY_);
650 return std::make_pair(tranX, tranY);
651 }
652
AdjustTargetPositionByAvailableArea(int32_t & moveDragFinalX,int32_t & moveDragFinalY)653 void MoveDragController::AdjustTargetPositionByAvailableArea(int32_t& moveDragFinalX, int32_t& moveDragFinalY)
654 {
655 moveDragFinalX = std::max(moveAvailableArea_.posX_, moveDragFinalX);
656 moveDragFinalY = std::max(moveAvailableArea_.posY_, moveDragFinalY);
657
658 int32_t rightBoundsLimit = moveAvailableArea_.posX_ + static_cast<int32_t>(moveAvailableArea_.width_) -
659 moveDragProperty_.originalRect_.width_;
660 int32_t bottomBoundsLimit = moveAvailableArea_.posY_ + static_cast<int32_t>(moveAvailableArea_.height_) -
661 moveDragProperty_.originalRect_.height_;
662
663 if (moveDragFinalX >= rightBoundsLimit) {
664 moveDragFinalX = rightBoundsLimit;
665 }
666 if (moveDragFinalY >= bottomBoundsLimit) {
667 moveDragFinalY = bottomBoundsLimit;
668 }
669 }
670
CalcMoveDirection(DisplayId lastDisplayId,DisplayId currentDisplayId)671 MoveDirection MoveDragController::CalcMoveDirection(DisplayId lastDisplayId, DisplayId currentDisplayId)
672 {
673 sptr<ScreenSession> lastScreenSession =
674 ScreenSessionManagerClient::GetInstance().GetScreenSessionById(lastDisplayId);
675 sptr<ScreenSession> currentScreenSession =
676 ScreenSessionManagerClient::GetInstance().GetScreenSessionById(currentDisplayId);
677 if (!lastScreenSession || !currentScreenSession) {
678 TLOGW(WmsLogTag::WMS_KEYBOARD, "Screen session is null, return default mouse move direction.");
679 return MoveDirection::UNKNOWN;
680 }
681
682 ScreenProperty lastScreenProperty = lastScreenSession->GetScreenProperty();
683 ScreenProperty currentScreenProperty = currentScreenSession->GetScreenProperty();
684
685 uint32_t lastOriginStartX = lastScreenProperty.GetStartX();
686 uint32_t lastOriginStartY = lastScreenProperty.GetStartY();
687 uint32_t currentOriginStartX = currentScreenProperty.GetStartX();
688 uint32_t currentOriginStartY = currentScreenProperty.GetStartY();
689
690 uint32_t lastScreenWidth = lastScreenProperty.GetBounds().rect_.width_;
691 uint32_t lastScreenHeight = lastScreenProperty.GetBounds().rect_.height_;
692 uint32_t currentScreenWidth = currentScreenProperty.GetBounds().rect_.width_;
693 uint32_t currentScreenHeight = currentScreenProperty.GetBounds().rect_.height_;
694
695 if (currentOriginStartX == lastOriginStartX + lastScreenWidth) {
696 return MoveDirection::LEFT_TO_RIGHT;
697 } else if (currentOriginStartX == lastOriginStartX - currentScreenWidth) {
698 return MoveDirection::RIGHT_TO_LEFT;
699 } else if (currentOriginStartY == lastOriginStartY + lastScreenHeight) {
700 return MoveDirection::UP_TO_BOTTOM;
701 } else if (currentOriginStartY == lastOriginStartY - currentScreenHeight) {
702 return MoveDirection::BOTTOM_TO_UP;
703 }
704
705 return MoveDirection::UNKNOWN;
706 }
707
SetOriginalDisplayOffset(int32_t offsetX,int32_t offsetY)708 void MoveDragController::SetOriginalDisplayOffset(int32_t offsetX, int32_t offsetY)
709 {
710 originalDisplayOffsetX_ = offsetX;
711 originalDisplayOffsetY_ = offsetY;
712 }
713
SetInputBarCrossAttr(MoveDirection moveDirection,DisplayId targetDisplayId)714 void MoveDragController::SetInputBarCrossAttr(MoveDirection moveDirection, DisplayId targetDisplayId)
715 {
716 if (moveDirection == MoveDirection::LEFT_TO_RIGHT ||
717 moveDirection == MoveDirection::RIGHT_TO_LEFT) {
718 UpdateMoveAvailableArea(targetDisplayId);
719 }
720 moveInputBarStartDisplayId_ = targetDisplayId;
721 SetOriginalDisplayOffset(screenSizeProperty_.currentDisplayStartX, screenSizeProperty_.currentDisplayStartY);
722 screenSizeProperty_.Reset();
723 }
724
InitializeMoveDragPropertyNotValid(const std::shared_ptr<MMI::PointerEvent> & pointerEvent,const WSRect & originalRect)725 void MoveDragController::InitializeMoveDragPropertyNotValid(const std::shared_ptr<MMI::PointerEvent>& pointerEvent,
726 const WSRect& originalRect)
727 {
728 MMI::PointerEvent::PointerItem pointerItem;
729 int32_t pointerId = pointerEvent->GetPointerId();
730 pointerEvent->GetPointerItem(pointerId, pointerItem);
731
732 int32_t pointerDisplayX = pointerItem.GetDisplayX();
733 int32_t pointerDisplayY = pointerItem.GetDisplayY();
734 moveDragProperty_.pointerId_ = pointerId;
735 moveDragProperty_.pointerType_ = pointerEvent->GetSourceType();
736 moveDragProperty_.originalPointerPosX_ = pointerDisplayX;
737 moveDragProperty_.originalPointerPosY_ = pointerDisplayY;
738 int32_t pointerWindowX = pointerItem.GetWindowX();
739 int32_t pointerWindowY = pointerItem.GetWindowY();
740 moveDragProperty_.originalRect_ = originalRect;
741 moveDragProperty_.originalRect_.posX_ = pointerDisplayX - pointerWindowX;
742 moveDragProperty_.originalRect_.posY_ = pointerDisplayY - pointerWindowY;
743 }
744
CheckAndInitializeMoveDragProperty(const std::shared_ptr<MMI::PointerEvent> & pointerEvent,const WSRect & originalRect)745 bool MoveDragController::CheckAndInitializeMoveDragProperty(const std::shared_ptr<MMI::PointerEvent>& pointerEvent,
746 const WSRect& originalRect)
747 {
748 if (moveDragProperty_.isEmpty()) {
749 InitializeMoveDragPropertyNotValid(pointerEvent, originalRect);
750 return false;
751 }
752 return true;
753 }
754
HandleLeftToRightCross(DisplayId targetDisplayId,int32_t pointerDisplayX,int32_t pointerDisplayY,int32_t & moveDragFinalX,int32_t & moveDragFinalY)755 void MoveDragController::HandleLeftToRightCross(DisplayId targetDisplayId,
756 int32_t pointerDisplayX,
757 int32_t pointerDisplayY,
758 int32_t& moveDragFinalX,
759 int32_t& moveDragFinalY)
760 {
761 if (pointerDisplayX > moveDragProperty_.originalPointerWindowX_) {
762 moveDragFinalX = pointerDisplayX - moveDragProperty_.originalPointerWindowX_;
763 } else {
764 moveDragFinalX = 0;
765 }
766 moveDragFinalY = pointerDisplayY - moveDragProperty_.originalPointerWindowY_;
767 SetInputBarCrossAttr(MoveDirection::LEFT_TO_RIGHT, targetDisplayId);
768 }
769
HandleRightToLeftCross(DisplayId targetDisplayId,int32_t pointerDisplayX,int32_t pointerDisplayY,int32_t & moveDragFinalX,int32_t & moveDragFinalY)770 void MoveDragController::HandleRightToLeftCross(DisplayId targetDisplayId,
771 int32_t pointerDisplayX,
772 int32_t pointerDisplayY,
773 int32_t& moveDragFinalX,
774 int32_t& moveDragFinalY)
775 {
776 int32_t boundaryPos = screenSizeProperty_.width -
777 moveDragProperty_.originalRect_.width_ + moveDragProperty_.originalPointerWindowX_;
778 if (pointerDisplayX <= boundaryPos) {
779 moveDragFinalX = pointerDisplayX - moveDragProperty_.originalPointerWindowX_;
780 } else {
781 moveDragFinalX = screenSizeProperty_.width - moveDragProperty_.originalRect_.width_;
782 }
783 moveDragFinalY = pointerDisplayY - moveDragProperty_.originalPointerWindowY_;
784 SetInputBarCrossAttr(MoveDirection::RIGHT_TO_LEFT, targetDisplayId);
785 }
786
HandleUpToBottomCross(DisplayId targetDisplayId,int32_t pointerDisplayX,int32_t pointerDisplayY,int32_t & moveDragFinalX,int32_t & moveDragFinalY)787 void MoveDragController::HandleUpToBottomCross(DisplayId targetDisplayId,
788 int32_t pointerDisplayX,
789 int32_t pointerDisplayY,
790 int32_t& moveDragFinalX,
791 int32_t& moveDragFinalY)
792 {
793 UpdateMoveAvailableArea(targetDisplayId);
794 int32_t statusBarHeight = moveAvailableArea_.posY_ - screenSizeProperty_.currentDisplayTop;
795 if (pointerDisplayY >= statusBarHeight + moveDragProperty_.originalPointerWindowY_) {
796 moveDragFinalY = pointerDisplayY - moveDragProperty_.originalPointerWindowY_;
797 } else {
798 moveDragFinalY = statusBarHeight;
799 }
800 moveDragFinalX = pointerDisplayX - moveDragProperty_.originalPointerWindowX_;
801 SetInputBarCrossAttr(MoveDirection::UP_TO_BOTTOM, targetDisplayId);
802 }
803
HandleBottomToUpCross(DisplayId targetDisplayId,int32_t pointerDisplayX,int32_t pointerDisplayY,int32_t & moveDragFinalX,int32_t & moveDragFinalY)804 void MoveDragController::HandleBottomToUpCross(DisplayId targetDisplayId,
805 int32_t pointerDisplayX,
806 int32_t pointerDisplayY,
807 int32_t& moveDragFinalX,
808 int32_t& moveDragFinalY)
809 {
810 UpdateMoveAvailableArea(targetDisplayId);
811 int32_t dockBarHeight = screenSizeProperty_.currentDisplayTop - moveAvailableArea_.posY_ -
812 static_cast<int32_t>(moveAvailableArea_.height_);
813 int32_t boundaryPos =
814 screenSizeProperty_.height - dockBarHeight - moveDragProperty_.originalPointerWindowY_;
815 if (pointerDisplayY <= boundaryPos) {
816 moveDragFinalY = pointerDisplayY - moveDragProperty_.originalPointerWindowY_;
817 } else {
818 moveDragFinalY = screenSizeProperty_.height - dockBarHeight - moveDragProperty_.originalPointerWindowY_;
819 }
820 moveDragFinalX = pointerDisplayX - moveDragProperty_.originalPointerWindowX_;
821 SetInputBarCrossAttr(MoveDirection::BOTTOM_TO_UP, targetDisplayId);
822 }
823
CalcMoveForSameDisplay(const std::shared_ptr<MMI::PointerEvent> & pointerEvent,int32_t & moveDragFinalX,int32_t & moveDragFinalY)824 void MoveDragController::CalcMoveForSameDisplay(const std::shared_ptr<MMI::PointerEvent>& pointerEvent,
825 int32_t& moveDragFinalX, int32_t& moveDragFinalY)
826 {
827 MMI::PointerEvent::PointerItem pointerItem;
828 int32_t pointerId = pointerEvent->GetPointerId();
829 pointerEvent->GetPointerItem(pointerId, pointerItem);
830 int32_t pointerDisplayX = pointerItem.GetDisplayX();
831 int32_t pointerDisplayY = pointerItem.GetDisplayY();
832 moveDragFinalX = pointerDisplayX - moveDragProperty_.originalPointerWindowX_;
833 moveDragFinalY = pointerDisplayY - moveDragProperty_.originalPointerWindowY_;
834 AdjustTargetPositionByAvailableArea(moveDragFinalX, moveDragFinalY);
835 }
836
CalcMoveInputBarRect(const std::shared_ptr<MMI::PointerEvent> & pointerEvent,const WSRect & originalRect)837 bool MoveDragController::CalcMoveInputBarRect(const std::shared_ptr<MMI::PointerEvent>& pointerEvent,
838 const WSRect& originalRect)
839 {
840 if (!CheckAndInitializeMoveDragProperty(pointerEvent, originalRect)) {
841 return false;
842 }
843
844 MMI::PointerEvent::PointerItem pointerItem;
845 int32_t pointerId = pointerEvent->GetPointerId();
846 pointerEvent->GetPointerItem(pointerId, pointerItem);
847 DisplayId targetDisplayId = static_cast<DisplayId>(pointerEvent->GetTargetDisplayId());
848 int32_t moveDragFinalX = 0;
849 int32_t moveDragFinalY = 0;
850 int32_t pointerDisplayX = pointerItem.GetDisplayX();
851 int32_t pointerDisplayY = pointerItem.GetDisplayY();
852
853 if (targetDisplayId == moveInputBarStartDisplayId_) {
854 CalcMoveForSameDisplay(pointerEvent, moveDragFinalX, moveDragFinalY);
855 } else {
856 MoveDirection moveDirection =
857 CalcMoveDirection(moveInputBarStartDisplayId_, pointerEvent->GetTargetDisplayId());
858 if (screenSizeProperty_.IsEmpty()) {
859 SetCurrentScreenProperty(targetDisplayId);
860 }
861
862 switch (moveDirection) {
863 case MoveDirection::LEFT_TO_RIGHT:
864 HandleLeftToRightCross(
865 targetDisplayId, pointerDisplayX, pointerDisplayY, moveDragFinalX, moveDragFinalY);
866 break;
867 case MoveDirection::RIGHT_TO_LEFT:
868 HandleRightToLeftCross(
869 targetDisplayId, pointerDisplayX, pointerDisplayY, moveDragFinalX, moveDragFinalY);
870 break;
871 case MoveDirection::UP_TO_BOTTOM:
872 HandleUpToBottomCross(
873 targetDisplayId, pointerDisplayX, pointerDisplayY, moveDragFinalX, moveDragFinalY);
874 break;
875 case MoveDirection::BOTTOM_TO_UP:
876 HandleBottomToUpCross(
877 targetDisplayId, pointerDisplayX, pointerDisplayY, moveDragFinalX, moveDragFinalY);
878 break;
879 default:
880 moveDragFinalX = moveDragProperty_.targetRect_.posX_;
881 moveDragFinalY = moveDragProperty_.targetRect_.posY_;
882 break;
883 }
884 }
885 moveDragProperty_.targetRect_ = { moveDragFinalX, moveDragFinalY, originalRect.width_, originalRect.height_ };
886 TLOGD(WmsLogTag::WMS_KEYBOARD, "move rect: %{public}s", moveDragProperty_.targetRect_.ToString().c_str());
887 return true;
888 }
889
CalcMoveTargetRect(const std::shared_ptr<MMI::PointerEvent> & pointerEvent,const WSRect & originalRect)890 bool MoveDragController::CalcMoveTargetRect(const std::shared_ptr<MMI::PointerEvent>& pointerEvent,
891 const WSRect& originalRect)
892 {
893 MMI::PointerEvent::PointerItem pointerItem;
894 int32_t pointerId = pointerEvent->GetPointerId();
895 pointerEvent->GetPointerItem(pointerId, pointerItem);
896 if (moveDragProperty_.isEmpty()) {
897 InitializeMoveDragPropertyNotValid(pointerEvent, originalRect);
898 return false;
899 };
900 if (!WindowHelper::IsSystemWindow(winType_) ||
901 static_cast<uint64_t>(pointerEvent->GetTargetDisplayId()) == moveDragStartDisplayId_) {
902 std::pair<int32_t, int32_t> trans = CalcUnifiedTranslate(pointerEvent);
903 moveDragProperty_.targetRect_ = {
904 moveDragProperty_.originalRect_.posX_ + trans.first,
905 moveDragProperty_.originalRect_.posY_ + trans.second,
906 originalRect.width_,
907 originalRect.height_
908 };
909 }
910 TLOGD(WmsLogTag::WMS_LAYOUT, "move rect: %{public}s", moveDragProperty_.targetRect_.ToString().c_str());
911 return true;
912 }
913
914 /** @note @window.drag */
EventDownInit(const std::shared_ptr<MMI::PointerEvent> & pointerEvent,const WSRect & originalRect,const sptr<WindowSessionProperty> property,const SystemSessionConfig & sysConfig)915 bool MoveDragController::EventDownInit(const std::shared_ptr<MMI::PointerEvent>& pointerEvent,
916 const WSRect& originalRect, const sptr<WindowSessionProperty> property, const SystemSessionConfig& sysConfig)
917 {
918 const auto& sourceType = pointerEvent->GetSourceType();
919 if (sourceType == MMI::PointerEvent::SOURCE_TYPE_MOUSE &&
920 pointerEvent->GetButtonId() != MMI::PointerEvent::MOUSE_BUTTON_LEFT) {
921 TLOGD(WmsLogTag::WMS_LAYOUT, "Mouse click event but not left click");
922 return false;
923 }
924 HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "MoveDragController::EventDownInit");
925 int32_t pointerId = pointerEvent->GetPointerId();
926 MMI::PointerEvent::PointerItem pointerItem;
927 pointerEvent->GetPointerItem(pointerId, pointerItem);
928 InitMoveDragProperty();
929 hasPointDown_ = true;
930 moveDragProperty_.originalRect_ = originalRect;
931 auto display = DisplayManager::GetInstance().GetDisplayById(
932 static_cast<uint64_t>(pointerEvent->GetTargetDisplayId()));
933 if (display) {
934 vpr_ = display->GetVirtualPixelRatio();
935 } else {
936 vpr_ = 1.5f; // 1.5f: default virtual pixel ratio
937 }
938 int outside = (sourceType == MMI::PointerEvent::SOURCE_TYPE_MOUSE) ? HOTZONE_POINTER * vpr_ : HOTZONE_TOUCH * vpr_;
939 type_ = SessionHelper::GetAreaType(pointerItem.GetWindowX(), pointerItem.GetWindowY(), sourceType, outside, vpr_,
940 moveDragProperty_.originalRect_);
941 if (type_ == AreaType::UNDEFINED) {
942 return false;
943 }
944 InitDecorValue(property, sysConfig);
945 limits_ = property->GetWindowLimits();
946 moveDragProperty_.pointerId_ = pointerEvent->GetPointerId();
947 moveDragProperty_.pointerType_ = sourceType;
948 moveDragProperty_.originalPointerPosX_ = pointerItem.GetDisplayX();
949 moveDragProperty_.originalPointerPosY_ = pointerItem.GetDisplayY();
950 if (aspectRatio_ <= NEAR_ZERO) {
951 CalcFreeformTranslateLimits(type_);
952 }
953 moveDragProperty_.originalRect_.posX_ = pointerItem.GetDisplayX() - pointerItem.GetWindowX();
954 moveDragProperty_.originalRect_.posY_ = pointerItem.GetDisplayY() - pointerItem.GetWindowY();
955 mainMoveAxis_ = AxisType::UNDEFINED;
956 isStartDrag_ = true;
957 NotifyWindowInputPidChange(isStartDrag_);
958 return true;
959 }
960
961 /** @note @window.drag */
CalcFreeformTargetRect(AreaType type,int32_t tranX,int32_t tranY,WSRect originalRect)962 WSRect MoveDragController::CalcFreeformTargetRect(AreaType type, int32_t tranX, int32_t tranY, WSRect originalRect)
963 {
964 WSRect targetRect = originalRect;
965 FixTranslateByLimits(tranX, tranY);
966 TLOGD(WmsLogTag::WMS_LAYOUT, "areaType:%{public}u", type);
967 if (static_cast<uint32_t>(type) & static_cast<uint32_t>(AreaType::LEFT)) {
968 targetRect.posX_ += tranX;
969 targetRect.width_ -= tranX;
970 } else if (static_cast<uint32_t>(type) & static_cast<uint32_t>(AreaType::RIGHT)) {
971 targetRect.width_ += tranX;
972 }
973 if (static_cast<uint32_t>(type) & static_cast<uint32_t>(AreaType::TOP)) {
974 targetRect.posY_ += tranY;
975 targetRect.height_ -= tranY;
976 } else if (static_cast<uint32_t>(type) & static_cast<uint32_t>(AreaType::BOTTOM)) {
977 targetRect.height_ += tranY;
978 }
979 // check current ratio limits
980 if (targetRect.height_ == 0) {
981 return targetRect;
982 }
983 float curRatio = static_cast<float>(targetRect.width_) / static_cast<float>(targetRect.height_);
984 if (!MathHelper::GreatNotEqual(limits_.minRatio_, curRatio) &&
985 !MathHelper::GreatNotEqual(curRatio, limits_.maxRatio_)) {
986 return targetRect;
987 }
988 float newRatio = MathHelper::LessNotEqual(curRatio, limits_.minRatio_) ? limits_.minRatio_ : limits_.maxRatio_;
989 if (MathHelper::NearZero(newRatio)) {
990 return targetRect;
991 }
992 if ((static_cast<uint32_t>(type) & static_cast<uint32_t>(AreaType::LEFT)) ||
993 (static_cast<uint32_t>(type) & static_cast<uint32_t>(AreaType::RIGHT))) {
994 targetRect.height_ = static_cast<int32_t>(static_cast<float>(targetRect.width_) / newRatio);
995 } else {
996 targetRect.width_ = static_cast<int32_t>(static_cast<float>(targetRect.height_) * newRatio);
997 }
998 TLOGD(WmsLogTag::WMS_LAYOUT, "curRatio:%{public}f, newRatio:%{public}f", curRatio, newRatio);
999 return targetRect;
1000 }
1001
CalcFixedAspectRatioTargetRect(AreaType type,int32_t tranX,int32_t tranY,float aspectRatio,WSRect originalRect)1002 WSRect MoveDragController::CalcFixedAspectRatioTargetRect(AreaType type, int32_t tranX, int32_t tranY,
1003 float aspectRatio, WSRect originalRect)
1004 {
1005 TLOGD(WmsLogTag::WMS_LAYOUT, "in");
1006 int32_t posX = originalRect.posX_;
1007 int32_t posY = originalRect.posY_;
1008 int32_t width = static_cast<int32_t>(originalRect.width_);
1009 int32_t height = static_cast<int32_t>(originalRect.height_);
1010 if (mainMoveAxis_ == AxisType::UNDEFINED) {
1011 if (!InitMainAxis(type, tranX, tranY)) {
1012 return originalRect;
1013 }
1014 }
1015
1016 TLOGD(WmsLogTag::WMS_LAYOUT, "ratio:%{public}f, areaType:%{public}u", aspectRatio, type);
1017 ConvertXYByAspectRatio(tranX, tranY, aspectRatio);
1018 FixTranslateByLimits(tranX, tranY);
1019 switch (type) {
1020 // tranX and tranY is signed
1021 case AreaType::LEFT_TOP: {
1022 return {posX + tranX, posY + tranY, width - tranX, height - tranY};
1023 }
1024 case AreaType::RIGHT_TOP: {
1025 return {posX, posY + tranY, width + tranX, height - tranY};
1026 }
1027 case AreaType::RIGHT_BOTTOM: {
1028 return {posX, posY, width + tranX, height + tranY};
1029 }
1030 case AreaType::LEFT_BOTTOM: {
1031 return {posX + tranX, posY, width - tranX, height + tranY};
1032 }
1033 case AreaType::LEFT: {
1034 return {posX + tranX, posY, width - tranX, height + tranY};
1035 }
1036 case AreaType::TOP: {
1037 return {posX, posY + tranY, width + tranX, height - tranY};
1038 }
1039 case AreaType::RIGHT: {
1040 return {posX, posY, width + tranX, height + tranY};
1041 }
1042 case AreaType::BOTTOM: {
1043 return {posX, posY, width + tranX, height + tranY};
1044 }
1045 default:
1046 break;
1047 }
1048 return originalRect;
1049 }
1050
CalcFreeformTranslateLimits(AreaType type)1051 void MoveDragController::CalcFreeformTranslateLimits(AreaType type)
1052 {
1053 TLOGD(WmsLogTag::WMS_LAYOUT, "areaType:%{public}u, minWidth:%{public}u, maxWidth:%{public}u, "
1054 "minHeight:%{public}u, maxHeight:%{public}u", type,
1055 limits_.minWidth_, limits_.maxWidth_, limits_.minHeight_, limits_.maxHeight_);
1056 if (static_cast<uint32_t>(type) & static_cast<uint32_t>(AreaType::LEFT)) {
1057 minTranX_ = moveDragProperty_.originalRect_.width_ - static_cast<int32_t>(limits_.maxWidth_);
1058 maxTranX_ = moveDragProperty_.originalRect_.width_ - static_cast<int32_t>(limits_.minWidth_);
1059 } else if (static_cast<uint32_t>(type) & static_cast<uint32_t>(AreaType::RIGHT)) {
1060 minTranX_ = static_cast<int32_t>(limits_.minWidth_) - moveDragProperty_.originalRect_.width_;
1061 maxTranX_ = static_cast<int32_t>(limits_.maxWidth_) - moveDragProperty_.originalRect_.width_;
1062 }
1063 if (static_cast<uint32_t>(type) & static_cast<uint32_t>(AreaType::TOP)) {
1064 minTranY_ = moveDragProperty_.originalRect_.height_ - static_cast<int32_t>(limits_.maxHeight_);
1065 maxTranY_ = moveDragProperty_.originalRect_.height_ - static_cast<int32_t>(limits_.minHeight_);
1066 } else if (static_cast<uint32_t>(type) & static_cast<uint32_t>(AreaType::BOTTOM)) {
1067 minTranY_ = static_cast<int32_t>(limits_.minHeight_) - moveDragProperty_.originalRect_.height_;
1068 maxTranY_ = static_cast<int32_t>(limits_.maxHeight_) - moveDragProperty_.originalRect_.height_;
1069 }
1070 }
1071
CalcFixedAspectRatioTranslateLimits(AreaType type)1072 void MoveDragController::CalcFixedAspectRatioTranslateLimits(AreaType type)
1073 {
1074 int32_t minW = static_cast<int32_t>(limits_.minWidth_);
1075 int32_t maxW = static_cast<int32_t>(limits_.maxWidth_);
1076 int32_t minH = static_cast<int32_t>(limits_.minHeight_);
1077 int32_t maxH = static_cast<int32_t>(limits_.maxHeight_);
1078 if (isDecorEnable_) {
1079 if (SessionUtils::ToLayoutWidth(minW, vpr_) < SessionUtils::ToLayoutHeight(minH, vpr_) * aspectRatio_) {
1080 minW = SessionUtils::ToWinWidth(SessionUtils::ToLayoutHeight(minH, vpr_) * aspectRatio_, vpr_);
1081 minH = SessionUtils::ToLayoutHeight(minH, vpr_);
1082 } else {
1083 minH = SessionUtils::ToWinHeight(SessionUtils::ToLayoutWidth(minW, vpr_) / aspectRatio_, vpr_);
1084 minW = SessionUtils::ToLayoutWidth(minW, vpr_);
1085 }
1086 if (SessionUtils::ToLayoutWidth(maxW, vpr_) < SessionUtils::ToLayoutHeight(maxH, vpr_) * aspectRatio_) {
1087 maxH = SessionUtils::ToWinHeight(SessionUtils::ToLayoutWidth(maxW, vpr_) / aspectRatio_, vpr_);
1088 maxW = SessionUtils::ToLayoutWidth(maxW, vpr_);
1089 } else {
1090 maxW = SessionUtils::ToWinWidth(SessionUtils::ToLayoutHeight(maxH, vpr_) * aspectRatio_, vpr_);
1091 maxH = SessionUtils::ToLayoutHeight(maxH, vpr_);
1092 }
1093 } else {
1094 // width = height * aspectRatio
1095 if (minW < minH * aspectRatio_) {
1096 minW = minH * aspectRatio_;
1097 } else {
1098 minH = minW / aspectRatio_;
1099 }
1100 if (maxW < maxH * aspectRatio_) {
1101 maxH = maxW / aspectRatio_;
1102 } else {
1103 maxW = maxH * aspectRatio_;
1104 }
1105 }
1106
1107 const static std::map<AreaType, std::function<void(int32_t, int32_t, int32_t, int32_t)>> calcMinMaxTranMap = {
1108 { AreaType::LEFT, [this](int32_t maxW, int32_t minW, int32_t maxH, int32_t minH) {
1109 minTranX_ = static_cast<int32_t>(moveDragProperty_.originalRect_.width_) - maxW;
1110 maxTranX_ = static_cast<int32_t>(moveDragProperty_.originalRect_.width_) - minW;
1111 minTranY_ = minH - static_cast<int32_t>(moveDragProperty_.originalRect_.height_);
1112 maxTranY_ = maxH - static_cast<int32_t>(moveDragProperty_.originalRect_.height_);
1113 }},
1114 { AreaType::LEFT_TOP, [this](int32_t maxW, int32_t minW, int32_t maxH, int32_t minH) {
1115 minTranX_ = static_cast<int32_t>(moveDragProperty_.originalRect_.width_) - maxW;
1116 maxTranX_ = static_cast<int32_t>(moveDragProperty_.originalRect_.width_) - minW;
1117 minTranY_ = static_cast<int32_t>(moveDragProperty_.originalRect_.height_) - maxH;
1118 maxTranY_ = static_cast<int32_t>(moveDragProperty_.originalRect_.height_) - minH;
1119 }},
1120 { AreaType::LEFT_BOTTOM, [this](int32_t maxW, int32_t minW, int32_t maxH, int32_t minH) {
1121 minTranX_ = static_cast<int32_t>(moveDragProperty_.originalRect_.width_) - maxW;
1122 maxTranX_ = static_cast<int32_t>(moveDragProperty_.originalRect_.width_) - minW;
1123 minTranY_ = minH - static_cast<int32_t>(moveDragProperty_.originalRect_.height_);
1124 maxTranY_ = maxH - static_cast<int32_t>(moveDragProperty_.originalRect_.height_);
1125 }},
1126 { AreaType::RIGHT, [this](int32_t maxW, int32_t minW, int32_t maxH, int32_t minH) {
1127 minTranX_ = minW - static_cast<int32_t>(moveDragProperty_.originalRect_.width_);
1128 maxTranX_ = maxW - static_cast<int32_t>(moveDragProperty_.originalRect_.width_);
1129 minTranY_ = minH - static_cast<int32_t>(moveDragProperty_.originalRect_.height_);
1130 maxTranY_ = maxH - static_cast<int32_t>(moveDragProperty_.originalRect_.height_);
1131 }},
1132 { AreaType::RIGHT_TOP, [this](int32_t maxW, int32_t minW, int32_t maxH, int32_t minH) {
1133 minTranX_ = minW - static_cast<int32_t>(moveDragProperty_.originalRect_.width_);
1134 maxTranX_ = maxW - static_cast<int32_t>(moveDragProperty_.originalRect_.width_);
1135 minTranY_ = static_cast<int32_t>(moveDragProperty_.originalRect_.height_) - maxH;
1136 maxTranY_ = static_cast<int32_t>(moveDragProperty_.originalRect_.height_) - minH;
1137 }},
1138 { AreaType::RIGHT_BOTTOM, [this](int32_t maxW, int32_t minW, int32_t maxH, int32_t minH) {
1139 minTranX_ = minW - static_cast<int32_t>(moveDragProperty_.originalRect_.width_);
1140 maxTranX_ = maxW - static_cast<int32_t>(moveDragProperty_.originalRect_.width_);
1141 minTranY_ = minH - static_cast<int32_t>(moveDragProperty_.originalRect_.height_);
1142 maxTranY_ = maxH - static_cast<int32_t>(moveDragProperty_.originalRect_.height_);
1143 }},
1144 { AreaType::TOP, [this](int32_t maxW, int32_t minW, int32_t maxH, int32_t minH) {
1145 minTranX_ = minW - static_cast<int32_t>(moveDragProperty_.originalRect_.width_);
1146 maxTranX_ = maxW - static_cast<int32_t>(moveDragProperty_.originalRect_.width_);
1147 minTranY_ = static_cast<int32_t>(moveDragProperty_.originalRect_.height_) - maxH;
1148 maxTranY_ = static_cast<int32_t>(moveDragProperty_.originalRect_.height_) - minH;
1149 }},
1150 { AreaType::BOTTOM, [this](int32_t maxW, int32_t minW, int32_t maxH, int32_t minH) {
1151 minTranX_ = minW - static_cast<int32_t>(moveDragProperty_.originalRect_.width_);
1152 maxTranX_ = maxW - static_cast<int32_t>(moveDragProperty_.originalRect_.width_);
1153 minTranY_ = minH - static_cast<int32_t>(moveDragProperty_.originalRect_.height_);
1154 maxTranY_ = maxH - static_cast<int32_t>(moveDragProperty_.originalRect_.height_);
1155 }},
1156 };
1157 if (calcMinMaxTranMap.find(type) == calcMinMaxTranMap.end()) {
1158 TLOGE(WmsLogTag::WMS_LAYOUT, "not find type:%{public}d", type);
1159 return;
1160 }
1161 calcMinMaxTranMap.at(type)(maxW, minW, maxH, minH);
1162 }
1163
FixTranslateByLimits(int32_t & tranX,int32_t & tranY)1164 void MoveDragController::FixTranslateByLimits(int32_t& tranX, int32_t& tranY)
1165 {
1166 if (tranX < minTranX_) {
1167 tranX = minTranX_;
1168 } else if (tranX > maxTranX_) {
1169 tranX = maxTranX_;
1170 }
1171 if (tranY < minTranY_) {
1172 tranY = minTranY_;
1173 } else if (tranY > maxTranY_) {
1174 tranY = maxTranY_;
1175 }
1176 TLOGD(WmsLogTag::WMS_LAYOUT, "tranX:%{public}d, tranY:%{public}d, minTranX:%{public}d, maxTranX:%{public}d, "
1177 "minTranY:%{public}d, maxTranY:%{public}d", tranX, tranY, minTranX_, maxTranX_, minTranY_, maxTranY_);
1178 }
1179
InitMainAxis(AreaType type,int32_t tranX,int32_t tranY)1180 bool MoveDragController::InitMainAxis(AreaType type, int32_t tranX, int32_t tranY)
1181 {
1182 if (type == AreaType::LEFT || type == AreaType::RIGHT) {
1183 mainMoveAxis_ = AxisType::X_AXIS;
1184 } else if (type == AreaType::TOP || type == AreaType::BOTTOM) {
1185 mainMoveAxis_ = AxisType::Y_AXIS;
1186 } else if (tranX == 0 && tranY == 0) {
1187 return false;
1188 } else {
1189 mainMoveAxis_ = (std::abs(tranX) > std::abs(tranY)) ? AxisType::X_AXIS : AxisType::Y_AXIS;
1190 }
1191 CalcFixedAspectRatioTranslateLimits(type);
1192 return true;
1193 }
1194
ConvertByAreaType(int32_t tran) const1195 int32_t MoveDragController::ConvertByAreaType(int32_t tran) const
1196 {
1197 const static std::map<AreaType, int32_t> areaTypeMap = {
1198 { AreaType::LEFT, NEGATIVE_CORRELATION },
1199 { AreaType::RIGHT, POSITIVE_CORRELATION },
1200 { AreaType::TOP, NEGATIVE_CORRELATION },
1201 { AreaType::BOTTOM, POSITIVE_CORRELATION },
1202 { AreaType::LEFT_TOP, POSITIVE_CORRELATION },
1203 { AreaType::RIGHT_TOP, NEGATIVE_CORRELATION },
1204 { AreaType::LEFT_BOTTOM, NEGATIVE_CORRELATION },
1205 { AreaType::RIGHT_BOTTOM, POSITIVE_CORRELATION },
1206 };
1207 if (areaTypeMap.find(type_) == areaTypeMap.end()) {
1208 TLOGE(WmsLogTag::WMS_LAYOUT, "not find type:%{public}d", type_);
1209 return tran;
1210 }
1211 return areaTypeMap.at(type_) * tran;
1212 }
1213
ConvertXYByAspectRatio(int32_t & tx,int32_t & ty,float aspectRatio)1214 void MoveDragController::ConvertXYByAspectRatio(int32_t& tx, int32_t& ty, float aspectRatio)
1215 {
1216 if (mainMoveAxis_ == AxisType::X_AXIS) {
1217 ty = tx / aspectRatio;
1218 ty = ConvertByAreaType(ty);
1219 } else if (mainMoveAxis_ == AxisType::Y_AXIS) {
1220 tx = ty * aspectRatio;
1221 tx = ConvertByAreaType(tx);
1222 }
1223 }
1224
InitDecorValue(const sptr<WindowSessionProperty> property,const SystemSessionConfig & sysConfig)1225 void MoveDragController::InitDecorValue(const sptr<WindowSessionProperty> property,
1226 const SystemSessionConfig& sysConfig)
1227 {
1228 auto windowType = property->GetWindowType();
1229 bool isMainWindow = WindowHelper::IsMainWindow(windowType);
1230 bool isSubWindow = WindowHelper::IsSubWindow(windowType);
1231 bool isDialogWindow = WindowHelper::IsDialogWindow(windowType);
1232 isDecorEnable_ = (isMainWindow || ((isSubWindow || isDialogWindow) && property->IsDecorEnable())) &&
1233 sysConfig.isSystemDecorEnable_ &&
1234 WindowHelper::IsWindowModeSupported(sysConfig.decorWindowModeSupportType_, property->GetWindowMode());
1235 }
1236
1237 /** @note @window.drag */
ProcessSessionRectChange(SizeChangeReason reason)1238 void MoveDragController::ProcessSessionRectChange(SizeChangeReason reason)
1239 {
1240 if (moveDragCallback_) {
1241 moveDragCallback_(reason);
1242 }
1243 }
1244
GetVirtualPixelRatio() const1245 float MoveDragController::GetVirtualPixelRatio() const
1246 {
1247 float vpr = 1.5;
1248 auto displayInfo = DisplayManager::GetInstance().GetDefaultDisplay();
1249 if (displayInfo != nullptr) {
1250 vpr = displayInfo->GetVirtualPixelRatio();
1251 }
1252 WLOGFD("vpr: %{public}f", vpr);
1253 return vpr;
1254 }
1255
UpdateDragType(int32_t startPointPosX,int32_t startPointPosY)1256 void MoveDragController::UpdateDragType(int32_t startPointPosX, int32_t startPointPosY)
1257 {
1258 if (startPointPosX > rectExceptCorner_.posX_ &&
1259 (startPointPosX < rectExceptCorner_.posX_ + static_cast<int32_t>(rectExceptCorner_.width_))) {
1260 dragType_ = DragType::DRAG_BOTTOM_OR_TOP;
1261 } else if (startPointPosY > rectExceptCorner_.posY_ &&
1262 (startPointPosY < rectExceptCorner_.posY_ + static_cast<int32_t>(rectExceptCorner_.height_))) {
1263 dragType_ = DragType::DRAG_LEFT_OR_RIGHT;
1264 } else if ((startPointPosX <= rectExceptCorner_.posX_ && startPointPosY <= rectExceptCorner_.posY_) ||
1265 (startPointPosX >= rectExceptCorner_.posX_ + static_cast<int32_t>(rectExceptCorner_.width_) &&
1266 startPointPosY >= rectExceptCorner_.posY_ + static_cast<int32_t>(rectExceptCorner_.height_))) {
1267 dragType_ = DragType::DRAG_LEFT_TOP_CORNER;
1268 } else {
1269 dragType_ = DragType::DRAG_RIGHT_TOP_CORNER;
1270 }
1271 }
1272
IsPointInDragHotZone(int32_t startPointPosX,int32_t startPointPosY,int32_t sourceType,const WSRect & winRect)1273 bool MoveDragController::IsPointInDragHotZone(int32_t startPointPosX, int32_t startPointPosY, int32_t sourceType,
1274 const WSRect& winRect)
1275 {
1276 // calculate rect with hotzone
1277 Rect rectWithHotzone;
1278 rectWithHotzone.posX_ = winRect.posX_ - static_cast<int32_t>(HOTZONE_POINTER);
1279 rectWithHotzone.posY_ = winRect.posY_ - static_cast<int32_t>(HOTZONE_POINTER);
1280 rectWithHotzone.width_ = winRect.width_ + HOTZONE_POINTER * 2u; // double hotZone
1281 rectWithHotzone.height_ = winRect.height_ + HOTZONE_POINTER * 2u; // double hotZone
1282
1283 if (sourceType == MMI::PointerEvent::SOURCE_TYPE_MOUSE &&
1284 !WindowHelper::IsPointInTargetRectWithBound(startPointPosX, startPointPosY, rectWithHotzone)) {
1285 return false;
1286 } else if ((!WindowHelper::IsPointInTargetRect(startPointPosX, startPointPosY, rectExceptFrame_)) ||
1287 (!WindowHelper::IsPointInWindowExceptCorner(startPointPosX, startPointPosY, rectExceptCorner_))) {
1288 return true;
1289 }
1290 return false;
1291 }
1292
CalculateStartRectExceptHotZone(float vpr,const WSRect & winRect)1293 void MoveDragController::CalculateStartRectExceptHotZone(float vpr, const WSRect& winRect)
1294 {
1295 rectExceptFrame_.posX_ = winRect.posX_ + static_cast<int32_t>(WINDOW_FRAME_WIDTH * vpr);
1296 rectExceptFrame_.posY_ = winRect.posY_ + static_cast<int32_t>(WINDOW_FRAME_WIDTH * vpr);
1297 rectExceptFrame_.width_ = winRect.width_ - static_cast<uint32_t>((WINDOW_FRAME_WIDTH + WINDOW_FRAME_WIDTH) * vpr);
1298 rectExceptFrame_.height_ = winRect.height_ - static_cast<uint32_t>((WINDOW_FRAME_WIDTH + WINDOW_FRAME_WIDTH) * vpr);
1299
1300 rectExceptCorner_.posX_ = winRect.posX_ + static_cast<int32_t>(WINDOW_FRAME_CORNER_WIDTH * vpr);
1301 rectExceptCorner_.posY_ = winRect.posY_ + static_cast<int32_t>(WINDOW_FRAME_CORNER_WIDTH * vpr);
1302 rectExceptCorner_.width_ =
1303 winRect.width_ - static_cast<uint32_t>((WINDOW_FRAME_CORNER_WIDTH + WINDOW_FRAME_CORNER_WIDTH) * vpr);
1304 rectExceptCorner_.height_ =
1305 winRect.height_ - static_cast<uint32_t>((WINDOW_FRAME_CORNER_WIDTH + WINDOW_FRAME_CORNER_WIDTH) * vpr);
1306 }
1307
UpdateMoveTempProperty(const std::shared_ptr<MMI::PointerEvent> & pointerEvent)1308 WSError MoveDragController::UpdateMoveTempProperty(const std::shared_ptr<MMI::PointerEvent>& pointerEvent)
1309 {
1310 int32_t pointerId = pointerEvent->GetPointerId();
1311 int32_t startPointerId = moveTempProperty_.pointerId_;
1312 int32_t pointerType = pointerEvent->GetSourceType();
1313 int32_t startPointerType = moveDragProperty_.pointerType_;
1314 MMI::PointerEvent::PointerItem pointerItem;
1315 int32_t sourceType = pointerEvent->GetSourceType();
1316 if (!pointerEvent->GetPointerItem(pointerId, pointerItem) ||
1317 (sourceType == MMI::PointerEvent::SOURCE_TYPE_MOUSE &&
1318 pointerEvent->GetButtonId() != MMI::PointerEvent::MOUSE_BUTTON_LEFT)) {
1319 WLOGFW("invalid pointerEvent");
1320 return WSError::WS_ERROR_NULLPTR;
1321 }
1322
1323 int32_t pointerDisplayX = pointerItem.GetDisplayX();
1324 int32_t pointerDisplayY = pointerItem.GetDisplayY();
1325 int32_t pointerDisplayWindowX = pointerItem.GetWindowX();
1326 int32_t pointerDisplayWindowY = pointerItem.GetWindowY();
1327 switch (pointerEvent->GetPointerAction()) {
1328 case MMI::PointerEvent::POINTER_ACTION_BUTTON_DOWN:
1329 case MMI::PointerEvent::POINTER_ACTION_DOWN:
1330 moveTempProperty_.pointerId_ = pointerId;
1331 moveTempProperty_.pointerType_ = pointerType;
1332 moveTempProperty_.lastDownPointerPosX_ = pointerDisplayX;
1333 moveTempProperty_.lastDownPointerPosY_ = pointerDisplayY;
1334 moveTempProperty_.lastMovePointerPosX_ = pointerDisplayX;
1335 moveTempProperty_.lastMovePointerPosY_ = pointerDisplayY;
1336 moveTempProperty_.lastDownPointerWindowX_ = pointerItem.GetWindowX();
1337 moveTempProperty_.lastDownPointerWindowY_ = pointerItem.GetWindowY();
1338 break;
1339 case MMI::PointerEvent::POINTER_ACTION_MOVE:
1340 if ((startPointerId != -1 && startPointerId != pointerId) ||
1341 (startPointerType != -1 && pointerType != startPointerType)) {
1342 WLOGFI("block unnecessary pointer event inside the window");
1343 return WSError::WS_DO_NOTHING;
1344 }
1345 moveTempProperty_.lastMovePointerPosX_ = pointerDisplayX;
1346 moveTempProperty_.lastMovePointerPosY_ = pointerDisplayY;
1347 lastMovePointerPosX_ = pointerDisplayX;
1348 break;
1349 case MMI::PointerEvent::POINTER_ACTION_UP:
1350 case MMI::PointerEvent::POINTER_ACTION_BUTTON_UP:
1351 case MMI::PointerEvent::POINTER_ACTION_CANCEL: {
1352 moveTempProperty_ = {-1, -1, -1, -1, -1, -1, -1, -1};
1353 break;
1354 }
1355 default:
1356 break;
1357 }
1358 return WSError::WS_OK;
1359 }
1360
HandleStartMovingWithCoordinate(int32_t offsetX,int32_t offsetY,int32_t pointerPosX,int32_t pointerPosY,const WSRect & winRect)1361 void MoveDragController::HandleStartMovingWithCoordinate(int32_t offsetX, int32_t offsetY,
1362 int32_t pointerPosX, int32_t pointerPosY, const WSRect& winRect)
1363 {
1364 moveTempProperty_.lastDownPointerPosX_ = pointerPosX;
1365 moveTempProperty_.lastDownPointerPosY_ = pointerPosY;
1366 moveTempProperty_.lastMovePointerPosX_ = pointerPosX;
1367 moveTempProperty_.lastMovePointerPosY_ = pointerPosY;
1368 moveTempProperty_.lastDownPointerWindowX_ = offsetX;
1369 moveTempProperty_.lastDownPointerWindowY_ = offsetY;
1370
1371 moveDragProperty_.targetRect_ = winRect;
1372 ProcessSessionRectChange(SizeChangeReason::DRAG_END);
1373 }
1374
1375 /** @note @window.drag */
CalcFirstMoveTargetRect(const WSRect & windowRect,bool isFullToFloating)1376 void MoveDragController::CalcFirstMoveTargetRect(const WSRect& windowRect, bool isFullToFloating)
1377 {
1378 if (!GetStartMoveFlag() || moveTempProperty_.isEmpty()) {
1379 return;
1380 }
1381
1382 WSRect originalRect = {
1383 moveTempProperty_.lastDownPointerPosX_ - moveTempProperty_.lastDownPointerWindowX_,
1384 moveTempProperty_.lastDownPointerPosY_ - moveTempProperty_.lastDownPointerWindowY_,
1385 windowRect.width_,
1386 windowRect.height_
1387 };
1388 if (isFullToFloating) {
1389 originalRect.posX_ = windowRect.posX_;
1390 originalRect.posY_ = windowRect.posY_;
1391 }
1392 SetOriginalMoveDragPos(moveTempProperty_.pointerId_,
1393 moveTempProperty_.pointerType_,
1394 moveTempProperty_.lastDownPointerPosX_,
1395 moveTempProperty_.lastDownPointerPosY_,
1396 moveTempProperty_.lastDownPointerWindowX_,
1397 moveTempProperty_.lastDownPointerWindowY_,
1398 originalRect);
1399
1400 int32_t offsetX = moveTempProperty_.lastMovePointerPosX_ - moveTempProperty_.lastDownPointerPosX_;
1401 int32_t offsetY = moveTempProperty_.lastMovePointerPosY_ - moveTempProperty_.lastDownPointerPosY_;
1402 WSRect targetRect = {
1403 originalRect.posX_ + offsetX,
1404 originalRect.posY_ + offsetY,
1405 originalRect.width_,
1406 originalRect.height_
1407 };
1408 TLOGI(WmsLogTag::WMS_LAYOUT, "first move rect: [%{public}d, %{public}d, %{public}u, %{public}u]", targetRect.posX_,
1409 targetRect.posY_, targetRect.width_, targetRect.height_);
1410 moveDragProperty_.targetRect_ = targetRect;
1411 ProcessSessionRectChange(SizeChangeReason::DRAG_MOVE);
1412 }
1413
CheckDragEventLegal(const std::shared_ptr<MMI::PointerEvent> & pointerEvent,const sptr<WindowSessionProperty> property)1414 bool MoveDragController::CheckDragEventLegal(const std::shared_ptr<MMI::PointerEvent>& pointerEvent,
1415 const sptr<WindowSessionProperty> property)
1416 {
1417 if (pointerEvent == nullptr || property == nullptr) {
1418 WLOGE("ConsumeDragEvent stop because of nullptr");
1419 return false;
1420 }
1421 if (GetStartMoveFlag()) {
1422 WLOGFD("the window is being moved");
1423 return false;
1424 }
1425 if (!GetStartDragFlag() && pointerEvent->GetPointerAction() != MMI::PointerEvent::POINTER_ACTION_DOWN &&
1426 pointerEvent->GetPointerAction() != MMI::PointerEvent::POINTER_ACTION_BUTTON_DOWN) {
1427 return false;
1428 }
1429 int32_t pointerId = pointerEvent->GetPointerId();
1430 int32_t startPointerId = moveDragProperty_.pointerId_;
1431 if (GetStartDragFlag() && startPointerId != -1 && startPointerId != pointerId) {
1432 WLOGFI("block unnecessary pointer event inside the window");
1433 return false;
1434 }
1435 return true;
1436 }
1437
1438 /** @note @window.drag */
UpdateHotAreaType(const std::shared_ptr<MMI::PointerEvent> & pointerEvent)1439 void MoveDragController::UpdateHotAreaType(const std::shared_ptr<MMI::PointerEvent>& pointerEvent)
1440 {
1441 int32_t pointerId = pointerEvent->GetPointerId();
1442 MMI::PointerEvent::PointerItem pointerItem;
1443 if (!pointerEvent->GetPointerItem(pointerId, pointerItem)) {
1444 WLOGFW("invalid pointerEvent");
1445 return;
1446 }
1447 int32_t pointerDisplayX = pointerItem.GetDisplayX();
1448 int32_t pointerDisplayY = pointerItem.GetDisplayY();
1449 DisplayId displayId = static_cast<uint64_t>(pointerEvent->GetTargetDisplayId());
1450 uint32_t windowDragHotAreaType = SceneSession::GetWindowDragHotAreaType(displayId, WINDOW_HOT_AREA_TYPE_UNDEFINED,
1451 pointerDisplayX, pointerDisplayY);
1452 if (windowDragHotAreaType_ != windowDragHotAreaType) {
1453 WLOGFI("the pointerEvent is window drag hot area, old type is: %{public}d, new type is: %{public}d",
1454 windowDragHotAreaType_, windowDragHotAreaType);
1455 }
1456 if (hotAreaDisplayId_ != displayId) {
1457 TLOGI(WmsLogTag::WMS_LAYOUT, "displayId is changed, old: %{public}" PRIu64 ", new: %{public}" PRIu64,
1458 moveDragStartDisplayId_, displayId);
1459 hotAreaDisplayId_ = displayId;
1460 }
1461 windowDragHotAreaType_ = windowDragHotAreaType;
1462 }
1463
GetOriginalPointerPosX()1464 int32_t MoveDragController::GetOriginalPointerPosX()
1465 {
1466 return moveDragProperty_.originalPointerPosX_;
1467 }
1468
GetOriginalPointerPosY()1469 int32_t MoveDragController::GetOriginalPointerPosY()
1470 {
1471 return moveDragProperty_.originalPointerPosY_;
1472 }
1473
GetPointerType() const1474 int32_t MoveDragController::GetPointerType() const
1475 {
1476 return moveDragProperty_.pointerType_;
1477 }
1478
SetWindowDragHotAreaFunc(const NotifyWindowDragHotAreaFunc & func)1479 void MoveDragController::SetWindowDragHotAreaFunc(const NotifyWindowDragHotAreaFunc& func)
1480 {
1481 windowDragHotAreaFunc_ = func;
1482 }
1483
OnLostFocus()1484 void MoveDragController::OnLostFocus()
1485 {
1486 TLOGW(WmsLogTag::WMS_LAYOUT, "window id %{public}d lost focus, should stop MoveDrag isMove: %{public}d,"
1487 "isDrag: %{public}d", persistentId_, isStartMove_, isStartDrag_);
1488 if (isStartMove_ || isStartDrag_) {
1489 MoveDragInterrupted(false);
1490 }
1491 }
1492
GetNewAddedDisplayIdsDuringMoveDrag()1493 std::set<uint64_t> MoveDragController::GetNewAddedDisplayIdsDuringMoveDrag()
1494 {
1495 std::set<uint64_t> newAddedDisplayIdSet;
1496 WSRect windowRect = GetTargetRect(TargetRectCoordinate::GLOBAL);
1497 std::map<ScreenId, ScreenProperty> screenProperties =
1498 ScreenSessionManagerClient::GetInstance().GetAllScreensProperties();
1499 std::lock_guard<std::mutex> lock(displayIdSetDuringMoveDragMutex_);
1500 for (const auto& [screenId, screenProperty] : screenProperties) {
1501 if (displayIdSetDuringMoveDrag_.find(screenId) != displayIdSetDuringMoveDrag_.end()) {
1502 continue;
1503 }
1504 WSRect screenRect = {
1505 screenProperty.GetStartX(),
1506 screenProperty.GetStartY(),
1507 screenProperty.GetBounds().rect_.GetWidth(),
1508 screenProperty.GetBounds().rect_.GetHeight(),
1509 };
1510 if (windowRect.IsOverlap(screenRect)) {
1511 displayIdSetDuringMoveDrag_.insert(screenId);
1512 newAddedDisplayIdSet.insert(screenId);
1513 }
1514 }
1515 return newAddedDisplayIdSet;
1516 }
1517
ResSchedReportData(int32_t type,bool onOffTag)1518 void MoveDragController::ResSchedReportData(int32_t type, bool onOffTag)
1519 {
1520 #ifdef RES_SCHED_ENABLE
1521 std::unordered_map<std::string, std::string> payload;
1522 // 0 is start, 1 is end
1523 if (onOffTag) {
1524 OHOS::ResourceSchedule::ResSchedClient::GetInstance().ReportData(type, 0, payload);
1525 } else {
1526 OHOS::ResourceSchedule::ResSchedClient::GetInstance().ReportData(type, 1, payload);
1527 }
1528 WLOGFD("ResSchedReportData success type: %{public}d onOffTag: %{public}d", type, onOffTag);
1529 #endif
1530 }
1531
GetLastMovePointerPosX() const1532 int32_t MoveDragController::GetLastMovePointerPosX() const
1533 {
1534 return lastMovePointerPosX_;
1535 }
1536
SetLastMovePointerPosX(int32_t lastMovePointerPosX)1537 void MoveDragController::SetLastMovePointerPosX(int32_t lastMovePointerPosX)
1538 {
1539 lastMovePointerPosX_ = lastMovePointerPosX;
1540 }
1541
IsMoveDragHotAreaCrossDisplay() const1542 bool MoveDragController::IsMoveDragHotAreaCrossDisplay() const
1543 {
1544 return isMoveDragHotAreaCrossDisplay_;
1545 }
1546
SetMoveDragHotAreaCrossDisplay(bool isMoveDragHotAreaCrossDisplay)1547 void MoveDragController::SetMoveDragHotAreaCrossDisplay(bool isMoveDragHotAreaCrossDisplay)
1548 {
1549 isMoveDragHotAreaCrossDisplay_ = isMoveDragHotAreaCrossDisplay;
1550 }
1551 } // namespace OHOS::Rosen
1552