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 <cinttypes>
19
20 #include <hitrace_meter.h>
21 #include <pointer_event.h>
22 #include "input_manager.h"
23 #include <transaction/rs_transaction.h>
24 #include <ui/rs_surface_node.h>
25
26 #include "display_manager.h"
27 #include "session/host/include/scene_persistent_storage.h"
28 #include "session/host/include/scene_session.h"
29 #include "session/host/include/session_utils.h"
30 #include "window_helper.h"
31 #include "session_helper.h"
32 #include "window_manager_hilog.h"
33 #include "wm_common_inner.h"
34 #include "ws_common.h"
35 #include "screen_session_manager_client/include/screen_session_manager_client.h"
36
37 #ifdef RES_SCHED_ENABLE
38 #include "res_type.h"
39 #include "res_sched_client.h"
40 #endif
41
42 namespace OHOS::Rosen {
43 namespace {
44 constexpr HiviewDFX::HiLogLabel LABEL = { LOG_CORE, HILOG_DOMAIN_WINDOW, "MoveDragController" };
45 }
46
MoveDragController(int32_t persistentId, bool isSystemWindow)47 MoveDragController::MoveDragController(int32_t persistentId, bool isSystemWindow)
48 {
49 persistentId_ = persistentId;
50 isSystemWindow_ = isSystemWindow;
51 }
52
OnConnect(ScreenId id)53 void MoveDragController::OnConnect(ScreenId id)
54 {
55 TLOGW(WmsLogTag::WMS_LAYOUT, "Moving or dragging is interrupt due to new screen %{public}" PRIu64
56 " connection.", id);
57 moveDragIsInterrupted_ = true;
58 }
59
OnDisconnect(ScreenId id)60 void MoveDragController::OnDisconnect(ScreenId id)
61 {
62 TLOGW(WmsLogTag::WMS_LAYOUT, "Moving or dragging is interrupt due to screen %{public}" PRIu64
63 " disconnection.", id);
64 moveDragIsInterrupted_ = true;
65 }
66
OnChange(ScreenId id)67 void MoveDragController::OnChange(ScreenId id)
68 {
69 TLOGW(WmsLogTag::WMS_LAYOUT, "Moving or dragging is interrupt due to screen %{public}" PRIu64
70 " change.", id);
71 moveDragIsInterrupted_ = true;
72 }
73
RegisterMoveDragCallback(const MoveDragCallback& callBack)74 void MoveDragController::RegisterMoveDragCallback(const MoveDragCallback& callBack)
75 {
76 moveDragCallback_ = callBack;
77 }
78
SetAsSystemWindow(bool isSystemWindow)79 void MoveDragController::SetAsSystemWindow(bool isSystemWindow)
80 {
81 isSystemWindow_ = isSystemWindow;
82 }
83
IsSystemWindow() const84 bool MoveDragController::IsSystemWindow() const
85 {
86 return isSystemWindow_;
87 }
88
NotifyWindowInputPidChange(bool isServerPid)89 void MoveDragController::NotifyWindowInputPidChange(bool isServerPid)
90 {
91 if (pidChangeCallback_) {
92 pidChangeCallback_(persistentId_, isServerPid);
93 WLOGFI("id: %{public}d, isServerPid:%{public}d", persistentId_, isServerPid);
94 }
95 }
96
HasPointDown()97 bool MoveDragController::HasPointDown()
98 {
99 return hasPointDown_;
100 }
101
SetStartMoveFlag(bool flag)102 void MoveDragController::SetStartMoveFlag(bool flag)
103 {
104 if (flag && (!hasPointDown_ || isStartDrag_)) {
105 WLOGFD("StartMove, but has not pointed down or is dragging, hasPointDown_: %{public}d, isStartFlag: %{public}d",
106 hasPointDown_, isStartDrag_);
107 return;
108 }
109 NotifyWindowInputPidChange(flag);
110 isStartMove_ = flag;
111 ResSchedReportData(OHOS::ResourceSchedule::ResType::RES_TYPE_MOVE_WINDOW, flag);
112 WLOGFI("SetStartMoveFlag, isStartMove_: %{public}d id:%{public}d", isStartMove_, persistentId_);
113 }
114
SetMovable(bool isMovable)115 void MoveDragController::SetMovable(bool isMovable)
116 {
117 isMovable_ = isMovable;
118 }
119
SetNotifyWindowPidChangeCallback(const NotifyWindowPidChangeCallback& callback)120 void MoveDragController::SetNotifyWindowPidChangeCallback(const NotifyWindowPidChangeCallback& callback)
121 {
122 pidChangeCallback_ = callback;
123 }
124
GetStartMoveFlag() const125 bool MoveDragController::GetStartMoveFlag() const
126 {
127 WLOGFD("GetStartMoveFlag, isStartMove_: %{public}d id:%{public}d", isStartMove_, persistentId_);
128 return isStartMove_;
129 }
130
GetStartDragFlag() const131 bool MoveDragController::GetStartDragFlag() const
132 {
133 return isStartDrag_;
134 }
135
GetMoveDragStartDisplayId() const136 uint64_t MoveDragController::GetMoveDragStartDisplayId() const
137 {
138 return moveDragStartDisplayId_;
139 }
140
GetMoveDragEndDisplayId() const141 uint64_t MoveDragController::GetMoveDragEndDisplayId() const
142 {
143 return moveDragEndDisplayId_;
144 }
145
GetInitParentNodeId() const146 uint64_t MoveDragController::GetInitParentNodeId() const
147 {
148 return initParentNodeId_;
149 }
150
GetDisplayIdsDuringMoveDrag()151 std::set<uint64_t> MoveDragController::GetDisplayIdsDuringMoveDrag()
152 {
153 std::lock_guard<std::mutex> lock(displayIdSetDuringMoveDragMutex_);
154 return displayIdSetDuringMoveDrag_;
155 }
156
GetMovable() const157 bool MoveDragController::GetMovable() const
158 {
159 return isMovable_;
160 }
161
GetTargetRect(TargetRectCoordinate coordinate) const162 WSRect MoveDragController::GetTargetRect(TargetRectCoordinate coordinate) const
163 {
164 DisplayId relatedDisplayId = DISPLAY_ID_INVALID;
165 switch (coordinate) {
166 case TargetRectCoordinate::GLOBAL:
167 return {
168 moveDragProperty_.targetRect_.posX_ + originalDisplayOffsetX_,
169 moveDragProperty_.targetRect_.posY_ + originalDisplayOffsetY_,
170 moveDragProperty_.targetRect_.width_,
171 moveDragProperty_.targetRect_.height_ };
172 case TargetRectCoordinate::RELATED_TO_START_DISPLAY:
173 return moveDragProperty_.targetRect_;
174 case TargetRectCoordinate::RELATED_TO_END_DISPLAY:
175 relatedDisplayId = moveDragEndDisplayId_;
176 break;
177 default:
178 return moveDragProperty_.targetRect_;
179 }
180 sptr<ScreenSession> screenSession =
181 ScreenSessionManagerClient::GetInstance().GetScreenSessionById(relatedDisplayId);
182 if (!screenSession) {
183 TLOGW(WmsLogTag::WMS_LAYOUT, "Screen session is null, return relative coordinates.");
184 return moveDragProperty_.targetRect_;
185 }
186 ScreenProperty screenProperty = screenSession->GetScreenProperty();
187 int32_t currentDisplayOffsetX = screenProperty.GetStartX();
188 int32_t currentDisplayOffsetY = screenProperty.GetStartY();
189 return {
190 moveDragProperty_.targetRect_.posX_ + originalDisplayOffsetX_ - currentDisplayOffsetX,
191 moveDragProperty_.targetRect_.posY_ + originalDisplayOffsetY_ - currentDisplayOffsetY,
192 moveDragProperty_.targetRect_.width_,
193 moveDragProperty_.targetRect_.height_ };
194 }
195
InitMoveDragProperty()196 void MoveDragController::InitMoveDragProperty()
197 {
198 moveDragProperty_ = { -1, -1, -1, -1, { 0, 0, 0, 0 }, { 0, 0, 0, 0 } };
199 }
200
InitCrossDisplayProperty(DisplayId displayId, uint64_t initParentNodeId)201 void MoveDragController::InitCrossDisplayProperty(DisplayId displayId, uint64_t initParentNodeId)
202 {
203 DMError error = ScreenManager::GetInstance().RegisterScreenListener(this);
204 if (error != DMError::DM_OK) {
205 TLOGW(WmsLogTag::WMS_LAYOUT, "Register ScreenListener false.");
206 }
207 {
208 std::lock_guard<std::mutex> lock(displayIdSetDuringMoveDragMutex_);
209 displayIdSetDuringMoveDrag_.insert(displayId);
210 }
211 moveDragStartDisplayId_ = displayId;
212 initParentNodeId_ = initParentNodeId;
213 sptr<ScreenSession> screenSession = ScreenSessionManagerClient::GetInstance().
214 GetScreenSessionById(moveDragStartDisplayId_);
215 if (!screenSession) {
216 return;
217 }
218 ScreenProperty screenProperty = screenSession->GetScreenProperty();
219 originalDisplayOffsetX_ = screenProperty.GetStartX();
220 originalDisplayOffsetY_ = screenProperty.GetStartY();
221 TLOGI(WmsLogTag::WMS_LAYOUT, "moveDragStartDisplayId: %{public}" PRIu64 ", "
222 "originalDisplayOffsetX: %{public}d, originalDisplayOffsetY: %{public}d",
223 moveDragStartDisplayId_, originalDisplayOffsetX_, originalDisplayOffsetY_);
224 }
225
ResetCrossMoveDragProperty()226 void MoveDragController::ResetCrossMoveDragProperty()
227 {
228 moveDragProperty_ = { -1, -1, -1, -1, { 0, 0, 0, 0 }, { 0, 0, 0, 0 } };
229 DMError error = ScreenManager::GetInstance().UnregisterScreenListener(this);
230 if (error != DMError::DM_OK) {
231 TLOGW(WmsLogTag::WMS_LAYOUT, "Register ScreenListener false.");
232 }
233 {
234 std::lock_guard<std::mutex> lock(displayIdSetDuringMoveDragMutex_);
235 displayIdSetDuringMoveDrag_.clear();
236 }
237 moveDragStartDisplayId_ = DISPLAY_ID_INVALID;
238 moveDragEndDisplayId_ = DISPLAY_ID_INVALID;
239 initParentNodeId_ = -1;
240 originalDisplayOffsetX_ = 0;
241 originalDisplayOffsetY_ = 0;
242 isSystemWindow_ = false;
243 moveDragIsInterrupted_ = false;
244 }
245
SetOriginalValue(int32_t pointerId, int32_t pointerType, int32_t pointerPosX, int32_t pointerPosY, const WSRect& winRect)246 void MoveDragController::SetOriginalValue(int32_t pointerId, int32_t pointerType,
247 int32_t pointerPosX, int32_t pointerPosY, const WSRect& winRect)
248 {
249 moveDragProperty_.pointerId_ = pointerId;
250 moveDragProperty_.pointerType_ = pointerType;
251 moveDragProperty_.originalPointerPosX_ = pointerPosX;
252 moveDragProperty_.originalPointerPosY_ = pointerPosY;
253 moveDragProperty_.originalRect_ = winRect;
254 }
255
GetFullScreenToFloatingRect(const WSRect& originalRect, const WSRect& windowRect)256 WSRect MoveDragController::GetFullScreenToFloatingRect(const WSRect& originalRect, const WSRect& windowRect)
257 {
258 if (moveTempProperty_.isEmpty()) {
259 TLOGI(WmsLogTag::WMS_LAYOUT, "move temporary property is empty");
260 return originalRect;
261 }
262 if (originalRect.width_ == 0) {
263 WLOGE("original rect witch is zero");
264 return windowRect;
265 }
266 float newPosX = static_cast<float>(windowRect.width_) / static_cast<float>(originalRect.width_) *
267 static_cast<float>(moveTempProperty_.lastDownPointerPosX_);
268 WSRect targetRect = {
269 moveTempProperty_.lastDownPointerPosX_ - static_cast<int32_t>(newPosX),
270 originalRect.posY_,
271 windowRect.width_,
272 windowRect.height_,
273 };
274 TLOGI(WmsLogTag::WMS_LAYOUT, "original rect [%{public}d,%{public}d,%{public}u,%{public}u]", targetRect.posX_,
275 targetRect.posY_, targetRect.width_, targetRect.height_);
276 return targetRect;
277 }
278
SetAspectRatio(float ratio)279 void MoveDragController::SetAspectRatio(float ratio)
280 {
281 aspectRatio_ = ratio;
282 }
283
ConsumeMoveEvent(const std::shared_ptr<MMI::PointerEvent>& pointerEvent, const WSRect& originalRect)284 bool MoveDragController::ConsumeMoveEvent(const std::shared_ptr<MMI::PointerEvent>& pointerEvent,
285 const WSRect& originalRect)
286 {
287 if (pointerEvent == nullptr) {
288 WLOGE("ConsumeMoveEvent stop because of nullptr");
289 return false;
290 }
291 if (GetStartDragFlag()) {
292 WLOGFI("the window is being resized");
293 return false;
294 }
295 int32_t pointerId = pointerEvent->GetPointerId();
296 int32_t startPointerId = moveDragProperty_.pointerId_;
297 int32_t startPointerType = moveDragProperty_.pointerType_;
298 if ((startPointerId != -1 && startPointerId != pointerId) ||
299 (startPointerType != -1 && pointerEvent->GetSourceType() != startPointerType)) {
300 WLOGFI("block unnecessary pointer event inside the window");
301 return false;
302 }
303 MMI::PointerEvent::PointerItem pointerItem;
304 int32_t sourceType = pointerEvent->GetSourceType();
305 if (!pointerEvent->GetPointerItem(pointerId, pointerItem) ||
306 (sourceType == MMI::PointerEvent::SOURCE_TYPE_MOUSE &&
307 (pointerEvent->GetButtonId() != MMI::PointerEvent::MOUSE_BUTTON_LEFT &&
308 !GetStartMoveFlag()))) {
309 WLOGFD("invalid pointerEvent id: %{public}d", persistentId_);
310 return false;
311 }
312
313 UpdateMoveTempProperty(pointerEvent);
314
315 int32_t action = pointerEvent->GetPointerAction();
316 if (!GetStartMoveFlag()) {
317 if (action == MMI::PointerEvent::POINTER_ACTION_DOWN ||
318 action == MMI::PointerEvent::POINTER_ACTION_BUTTON_DOWN) {
319 WLOGFD("Move event hasPointDown");
320 hasPointDown_ = true;
321 } else if (action == MMI::PointerEvent::POINTER_ACTION_UP ||
322 action == MMI::PointerEvent::POINTER_ACTION_BUTTON_UP ||
323 action == MMI::PointerEvent::POINTER_ACTION_CANCEL) {
324 WLOGFD("Reset hasPointDown_ when point up or cancel");
325 hasPointDown_ = false;
326 }
327 WLOGFD("No need to move action id: %{public}d", action);
328 return false;
329 }
330
331 SizeChangeReason reason = SizeChangeReason::MOVE;
332 bool ret = true;
333 switch (action) {
334 case MMI::PointerEvent::POINTER_ACTION_MOVE: {
335 if (moveDragIsInterrupted_) {
336 MoveDragInterrupt();
337 return true;
338 }
339 reason = SizeChangeReason::MOVE;
340 uint32_t oldWindowDragHotAreaType = windowDragHotAreaType_;
341 UpdateHotAreaType(pointerEvent);
342 ProcessWindowDragHotAreaFunc(oldWindowDragHotAreaType != windowDragHotAreaType_, reason);
343 break;
344 }
345 case MMI::PointerEvent::POINTER_ACTION_UP:
346 case MMI::PointerEvent::POINTER_ACTION_BUTTON_UP:
347 case MMI::PointerEvent::POINTER_ACTION_CANCEL:
348 case MMI::PointerEvent::POINTER_ACTION_DOWN:
349 case MMI::PointerEvent::POINTER_ACTION_BUTTON_DOWN: {
350 if (!hasPointDown_) {
351 return true;
352 }
353 if (moveDragIsInterrupted_) {
354 MoveDragInterrupt();
355 return true;
356 }
357 reason = SizeChangeReason::DRAG_END;
358 SetStartMoveFlag(false);
359 hasPointDown_ = false;
360 moveDragEndDisplayId_ = pointerEvent->GetTargetDisplayId();
361 ProcessWindowDragHotAreaFunc(windowDragHotAreaType_ != WINDOW_HOT_AREA_TYPE_UNDEFINED, reason);
362 // The Pointer up event sent to the ArkUI.
363 ret = false;
364 break;
365 }
366 default:
367 break;
368 }
369 if (CalcMoveTargetRect(pointerEvent, originalRect)) {
370 ProcessSessionRectChange(reason);
371 }
372 return ret;
373 }
374
ProcessWindowDragHotAreaFunc(bool isSendHotAreaMessage, const SizeChangeReason reason)375 void MoveDragController::ProcessWindowDragHotAreaFunc(bool isSendHotAreaMessage, const SizeChangeReason reason)
376 {
377 if (isSendHotAreaMessage) {
378 WLOGFI("ProcessWindowDragHotAreaFunc start, isSendHotAreaMessage: %{public}u, reason: %{public}d",
379 isSendHotAreaMessage, reason);
380 }
381 if (windowDragHotAreaFunc_ && isSendHotAreaMessage) {
382 windowDragHotAreaFunc_(hotAreaDisplayId_, windowDragHotAreaType_, reason);
383 }
384 }
385
UpdateGravityWhenDrag(const std::shared_ptr<MMI::PointerEvent>& pointerEvent, const std::shared_ptr<RSSurfaceNode>& surfaceNode)386 void MoveDragController::UpdateGravityWhenDrag(const std::shared_ptr<MMI::PointerEvent>& pointerEvent,
387 const std::shared_ptr<RSSurfaceNode>& surfaceNode)
388 {
389 if (surfaceNode == nullptr || pointerEvent == nullptr || type_ == AreaType::UNDEFINED) {
390 return;
391 }
392 if (pointerEvent->GetPointerAction() == MMI::PointerEvent::POINTER_ACTION_DOWN ||
393 pointerEvent->GetPointerAction() == MMI::PointerEvent::POINTER_ACTION_BUTTON_DOWN) {
394 bool isNeedFlush = false;
395 if (isStartDrag_ && isPcWindow_) {
396 surfaceNode->MarkUifirstNode(false);
397 isNeedFlush = true;
398 }
399 Gravity dragGravity = GRAVITY_MAP.at(type_);
400 if (dragGravity >= Gravity::TOP && dragGravity <= Gravity::BOTTOM_RIGHT) {
401 WLOGFI("begin SetFrameGravity:%{public}d, type:%{public}d", dragGravity, type_);
402 surfaceNode->SetFrameGravity(dragGravity);
403 RSTransaction::FlushImplicitTransaction();
404 } else if (isNeedFlush) {
405 RSTransaction::FlushImplicitTransaction();
406 }
407 return;
408 }
409 if (pointerEvent->GetPointerAction() == MMI::PointerEvent::POINTER_ACTION_BUTTON_UP ||
410 pointerEvent->GetPointerAction() == MMI::PointerEvent::POINTER_ACTION_UP ||
411 pointerEvent->GetPointerAction() == MMI::PointerEvent::POINTER_ACTION_CANCEL) {
412 if (!isStartDrag_ && isPcWindow_) {
413 surfaceNode->MarkUifirstNode(true);
414 }
415 surfaceNode->SetFrameGravity(Gravity::TOP_LEFT);
416 RSTransaction::FlushImplicitTransaction();
417 WLOGFI("recover gravity to TOP_LEFT");
418 }
419 }
420
CalcDragTargetRect(const std::shared_ptr<MMI::PointerEvent>& pointerEvent)421 void MoveDragController::CalcDragTargetRect(const std::shared_ptr<MMI::PointerEvent>& pointerEvent)
422 {
423 if (!IsSystemWindow() || static_cast<uint64_t>(pointerEvent->GetTargetDisplayId()) == moveDragStartDisplayId_) {
424 std::pair<int32_t, int32_t> trans = CalcUnifiedTranslate(pointerEvent);
425 moveDragProperty_.targetRect_ = MathHelper::GreatNotEqual(aspectRatio_, NEAR_ZERO) ?
426 CalcFixedAspectRatioTargetRect(
427 type_, trans.first, trans.second, aspectRatio_, moveDragProperty_.originalRect_) :
428 CalcFreeformTargetRect(type_, trans.first, trans.second, moveDragProperty_.originalRect_);
429 }
430 TLOGD(WmsLogTag::WMS_LAYOUT, "drag rect: %{public}s", moveDragProperty_.targetRect_.ToString().c_str());
431 }
432
ConsumeDragEvent(const std::shared_ptr<MMI::PointerEvent>& pointerEvent, const WSRect& originalRect, const sptr<WindowSessionProperty> property, const SystemSessionConfig& sysConfig)433 bool MoveDragController::ConsumeDragEvent(const std::shared_ptr<MMI::PointerEvent>& pointerEvent,
434 const WSRect& originalRect, const sptr<WindowSessionProperty> property, const SystemSessionConfig& sysConfig)
435 {
436 if (!CheckDragEventLegal(pointerEvent, property)) {
437 return false;
438 }
439 int32_t pointerId = pointerEvent->GetPointerId();
440 MMI::PointerEvent::PointerItem pointerItem;
441 if (!pointerEvent->GetPointerItem(pointerId, pointerItem)) {
442 WLOGE("Get PointerItem failed");
443 return false;
444 }
445 SizeChangeReason reason = SizeChangeReason::UNDEFINED;
446 switch (pointerEvent->GetPointerAction()) {
447 case MMI::PointerEvent::POINTER_ACTION_BUTTON_DOWN:
448 case MMI::PointerEvent::POINTER_ACTION_DOWN: {
449 if (!EventDownInit(pointerEvent, originalRect, property, sysConfig)) {
450 return false;
451 }
452 reason = SizeChangeReason::DRAG_START;
453 ResSchedReportData(OHOS::ResourceSchedule::ResType::RES_TYPE_RESIZE_WINDOW, true);
454 break;
455 }
456 case MMI::PointerEvent::POINTER_ACTION_MOVE: {
457 if (moveDragIsInterrupted_) {
458 MoveDragInterrupt();
459 return true;
460 }
461 reason = SizeChangeReason::DRAG;
462 break;
463 }
464 case MMI::PointerEvent::POINTER_ACTION_UP:
465 case MMI::PointerEvent::POINTER_ACTION_BUTTON_UP:
466 case MMI::PointerEvent::POINTER_ACTION_CANCEL: {
467 if (!hasPointDown_) {
468 return true;
469 }
470 auto screenRect = GetScreenRectById(moveDragStartDisplayId_);
471 if (moveDragIsInterrupted_ || screenRect == WSRect {-1, -1, -1, -1}) {
472 MoveDragInterrupt();
473 return true;
474 }
475 reason = SizeChangeReason::DRAG_END;
476 isStartDrag_ = false;
477 hasPointDown_ = false;
478 moveDragEndDisplayId_ = GetTargetRect(TargetRectCoordinate::GLOBAL).IsOverlap(screenRect) ?
479 moveDragStartDisplayId_ : pointerEvent->GetTargetDisplayId();
480 ResSchedReportData(OHOS::ResourceSchedule::ResType::RES_TYPE_RESIZE_WINDOW, false);
481 NotifyWindowInputPidChange(isStartDrag_);
482 break;
483 }
484 default:
485 return false;
486 }
487 CalcDragTargetRect(pointerEvent);
488 ProcessSessionRectChange(reason);
489 return true;
490 }
491
MoveDragInterrupt()492 void MoveDragController::MoveDragInterrupt()
493 {
494 TLOGI(WmsLogTag::WMS_LAYOUT, "Screen anomaly, MoveDrag has been interrupted.");
495 SizeChangeReason reason = SizeChangeReason::DRAG_END;
496 hasPointDown_ = false;
497 if (isStartDrag_) {
498 isStartDrag_ = false;
499 ResSchedReportData(OHOS::ResourceSchedule::ResType::RES_TYPE_RESIZE_WINDOW, false);
500 NotifyWindowInputPidChange(isStartDrag_);
501 };
502 if (GetStartMoveFlag()) {
503 SetStartMoveFlag(false);
504 ProcessWindowDragHotAreaFunc(windowDragHotAreaType_ != WINDOW_HOT_AREA_TYPE_UNDEFINED, reason);
505 };
506 moveDragEndDisplayId_ = moveDragStartDisplayId_;
507 moveDragProperty_.targetRect_ = moveDragProperty_.originalRect_;
508 ProcessSessionRectChange(reason);
509 }
510
GetScreenRectById(DisplayId displayId)511 WSRect MoveDragController::GetScreenRectById(DisplayId displayId)
512 {
513 sptr<ScreenSession> screenSession =
514 ScreenSessionManagerClient::GetInstance().GetScreenSessionById(displayId);
515 if (!screenSession) {
516 TLOGI(WmsLogTag::WMS_LAYOUT, "ScreenSession id null.");
517 return WSRect {-1, -1, -1, -1};
518 }
519 ScreenProperty screenProperty = screenSession->GetScreenProperty();
520 WSRect screenRect = {
521 screenProperty.GetStartX(),
522 screenProperty.GetStartY(),
523 screenProperty.GetBounds().rect_.GetWidth(),
524 screenProperty.GetBounds().rect_.GetHeight(),
525 };
526 return screenRect;
527 }
528
CalcUnifiedTranslate( const std::shared_ptr<MMI::PointerEvent>& pointerEvent)529 std::pair<int32_t, int32_t> MoveDragController::CalcUnifiedTranslate(
530 const std::shared_ptr<MMI::PointerEvent>& pointerEvent)
531 {
532 int32_t pointerId = pointerEvent->GetPointerId();
533 MMI::PointerEvent::PointerItem pointerItem;
534 pointerEvent->GetPointerItem(pointerId, pointerItem);
535 sptr<ScreenSession> screenSession = ScreenSessionManagerClient::GetInstance().
536 GetScreenSessionById(static_cast<uint64_t>(pointerEvent->GetTargetDisplayId()));
537 if (!screenSession) {
538 return std::make_pair(0, 0);
539 }
540 ScreenProperty screenProperty = screenSession->GetScreenProperty();
541 // calculate trans in unified coordinates
542 int32_t currentDisplayTranX = screenProperty.GetStartX();
543 int32_t currentDisplayTranY = screenProperty.GetStartY();
544 int32_t tranX = (pointerItem.GetDisplayX() + currentDisplayTranX) -
545 (moveDragProperty_.originalPointerPosX_ + originalDisplayOffsetX_);
546 int32_t tranY = (pointerItem.GetDisplayY() + currentDisplayTranY) -
547 (moveDragProperty_.originalPointerPosY_ + originalDisplayOffsetY_);
548 return std::make_pair(tranX, tranY);
549 }
550
CalcMoveTargetRect(const std::shared_ptr<MMI::PointerEvent>& pointerEvent, const WSRect& originalRect)551 bool MoveDragController::CalcMoveTargetRect(const std::shared_ptr<MMI::PointerEvent>& pointerEvent,
552 const WSRect& originalRect)
553 {
554 MMI::PointerEvent::PointerItem pointerItem;
555 int32_t pointerId = pointerEvent->GetPointerId();
556 pointerEvent->GetPointerItem(pointerId, pointerItem);
557 if (moveDragProperty_.isEmpty()) {
558 int32_t pointerDisplayX = pointerItem.GetDisplayX();
559 int32_t pointerDisplayY = pointerItem.GetDisplayY();
560 moveDragProperty_.pointerId_ = pointerId;
561 moveDragProperty_.pointerType_ = pointerEvent->GetSourceType();
562 moveDragProperty_.originalPointerPosX_ = pointerDisplayX;
563 moveDragProperty_.originalPointerPosY_ = pointerDisplayY;
564 int32_t pointerWindowX = pointerItem.GetWindowX();
565 int32_t pointerWindowY = pointerItem.GetWindowY();
566 moveDragProperty_.originalRect_ = originalRect;
567 moveDragProperty_.originalRect_.posX_ = pointerDisplayX - pointerWindowX;
568 moveDragProperty_.originalRect_.posY_ = pointerDisplayY - pointerWindowY;
569 return false;
570 };
571 if (!IsSystemWindow() || static_cast<uint64_t>(pointerEvent->GetTargetDisplayId()) == moveDragStartDisplayId_) {
572 std::pair<int32_t, int32_t> trans = CalcUnifiedTranslate(pointerEvent);
573 moveDragProperty_.targetRect_ = {
574 moveDragProperty_.originalRect_.posX_ + trans.first,
575 moveDragProperty_.originalRect_.posY_ + trans.second,
576 originalRect.width_,
577 originalRect.height_};
578 }
579 WLOGFD("move rect: %{public}s", moveDragProperty_.targetRect_.ToString().c_str());
580 return true;
581 }
582
EventDownInit(const std::shared_ptr<MMI::PointerEvent>& pointerEvent, const WSRect& originalRect, const sptr<WindowSessionProperty> property, const SystemSessionConfig& sysConfig)583 bool MoveDragController::EventDownInit(const std::shared_ptr<MMI::PointerEvent>& pointerEvent,
584 const WSRect& originalRect, const sptr<WindowSessionProperty> property, const SystemSessionConfig& sysConfig)
585 {
586 const auto& sourceType = pointerEvent->GetSourceType();
587 if (sourceType == MMI::PointerEvent::SOURCE_TYPE_MOUSE &&
588 pointerEvent->GetButtonId() != MMI::PointerEvent::MOUSE_BUTTON_LEFT) {
589 return false;
590 }
591 HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "MoveDragController::EventDownInit");
592 int32_t pointerId = pointerEvent->GetPointerId();
593 MMI::PointerEvent::PointerItem pointerItem;
594 pointerEvent->GetPointerItem(pointerId, pointerItem);
595 InitMoveDragProperty();
596 hasPointDown_ = true;
597 moveDragProperty_.originalRect_ = originalRect;
598 auto display = DisplayManager::GetInstance().GetDisplayById(pointerEvent->GetTargetDisplayId());
599 if (display) {
600 vpr_ = display->GetVirtualPixelRatio();
601 } else {
602 vpr_ = 1.5f; // 1.5f: default virtual pixel ratio
603 }
604 int outside = (sourceType == MMI::PointerEvent::SOURCE_TYPE_MOUSE) ? HOTZONE_POINTER * vpr_ :
605 HOTZONE_TOUCH * vpr_;
606 type_ = SessionHelper::GetAreaType(pointerItem.GetWindowX(), pointerItem.GetWindowY(), sourceType, outside, vpr_,
607 moveDragProperty_.originalRect_);
608 if (type_ == AreaType::UNDEFINED) {
609 return false;
610 }
611 InitDecorValue(property, sysConfig);
612 limits_ = property->GetWindowLimits();
613 moveDragProperty_.pointerId_ = pointerEvent->GetPointerId();
614 moveDragProperty_.pointerType_ = sourceType;
615 moveDragProperty_.originalPointerPosX_ = pointerItem.GetDisplayX();
616 moveDragProperty_.originalPointerPosY_ = pointerItem.GetDisplayY();
617 if (aspectRatio_ <= NEAR_ZERO) {
618 CalcFreeformTranslateLimits(type_);
619 }
620 moveDragProperty_.originalRect_.posX_ = pointerItem.GetDisplayX() - pointerItem.GetWindowX();
621 moveDragProperty_.originalRect_.posY_ = pointerItem.GetDisplayY() - pointerItem.GetWindowY();
622 mainMoveAxis_ = AxisType::UNDEFINED;
623 isStartDrag_ = true;
624 NotifyWindowInputPidChange(isStartDrag_);
625 return true;
626 }
627
CalcFreeformTargetRect(AreaType type, int32_t tranX, int32_t tranY, WSRect originalRect)628 WSRect MoveDragController::CalcFreeformTargetRect(AreaType type, int32_t tranX, int32_t tranY, WSRect originalRect)
629 {
630 WSRect targetRect = originalRect;
631 FixTranslateByLimits(tranX, tranY);
632 if (static_cast<uint32_t>(type) & static_cast<uint32_t>(AreaType::LEFT)) {
633 targetRect.posX_ += tranX;
634 targetRect.width_ -= tranX;
635 } else if (static_cast<uint32_t>(type) & static_cast<uint32_t>(AreaType::RIGHT)) {
636 targetRect.width_ += tranX;
637 }
638 if (static_cast<uint32_t>(type) & static_cast<uint32_t>(AreaType::TOP)) {
639 targetRect.posY_ += tranY;
640 targetRect.height_ -= tranY;
641 } else if (static_cast<uint32_t>(type) & static_cast<uint32_t>(AreaType::BOTTOM)) {
642 targetRect.height_ += tranY;
643 }
644 // check current ratio limits
645 if (targetRect.height_ == 0) {
646 return targetRect;
647 }
648 float curRatio = static_cast<float>(targetRect.width_) / static_cast<float>(targetRect.height_);
649 if (!MathHelper::GreatNotEqual(limits_.minRatio_, curRatio) &&
650 !MathHelper::GreatNotEqual(curRatio, limits_.maxRatio_)) {
651 return targetRect;
652 }
653 float newRatio = MathHelper::LessNotEqual(curRatio, limits_.minRatio_) ? limits_.minRatio_ : limits_.maxRatio_;
654 if (MathHelper::NearZero(newRatio)) {
655 return targetRect;
656 }
657 if ((static_cast<uint32_t>(type) & static_cast<uint32_t>(AreaType::LEFT)) ||
658 (static_cast<uint32_t>(type) & static_cast<uint32_t>(AreaType::RIGHT))) {
659 targetRect.height_ = static_cast<int32_t>(static_cast<float>(targetRect.width_) / newRatio);
660 } else {
661 targetRect.width_ = static_cast<int32_t>(static_cast<float>(targetRect.height_) * newRatio);
662 }
663 return targetRect;
664 }
665
CalcFixedAspectRatioTargetRect(AreaType type, int32_t tranX, int32_t tranY, float aspectRatio, WSRect originalRect)666 WSRect MoveDragController::CalcFixedAspectRatioTargetRect(AreaType type, int32_t tranX, int32_t tranY,
667 float aspectRatio, WSRect originalRect)
668 {
669 int32_t posX = originalRect.posX_;
670 int32_t posY = originalRect.posY_;
671 int32_t width = static_cast<int32_t>(originalRect.width_);
672 int32_t height = static_cast<int32_t>(originalRect.height_);
673 FixTranslateByLimits(tranX, tranY);
674 if (mainMoveAxis_ == AxisType::UNDEFINED) {
675 if (!InitMainAxis(type, tranX, tranY)) {
676 return originalRect;
677 }
678 }
679
680 ConvertXYByAspectRatio(tranX, tranY, aspectRatio);
681 switch (type) {
682 case AreaType::LEFT_TOP: {
683 return { posX + tranX, posY + tranY, width - tranX, height - tranY };
684 }
685 case AreaType::RIGHT_TOP: {
686 return { posX, posY + (mainMoveAxis_ == AxisType::X_AXIS ? (-tranY) : (tranY)),
687 width + (mainMoveAxis_ == AxisType::X_AXIS ? (tranX) : (-tranX)),
688 height + (mainMoveAxis_ == AxisType::X_AXIS ? (tranY) : (-tranY)) };
689 }
690 case AreaType::RIGHT_BOTTOM: {
691 return { posX, posY, width + tranX, height + tranY };
692 }
693 case AreaType::LEFT_BOTTOM: {
694 return { posX + (mainMoveAxis_ == AxisType::X_AXIS ? (tranX) : (-tranX)), posY,
695 width - (mainMoveAxis_ == AxisType::X_AXIS ? (tranX) : (-tranX)),
696 height - (mainMoveAxis_ == AxisType::X_AXIS ? (tranY) : (-tranY)) };
697 }
698 case AreaType::LEFT: {
699 return { posX + tranX, posY, width - tranX, height - tranY };
700 }
701 case AreaType::TOP: {
702 return { posX, posY + tranY, width - tranX, height - tranY };
703 }
704 case AreaType::RIGHT: {
705 return { posX, posY, width + tranX, height + tranY };
706 }
707 case AreaType::BOTTOM: {
708 return { posX, posY, width + tranX, height + tranY };
709 }
710 default:
711 break;
712 }
713 return originalRect;
714 }
715
CalcFreeformTranslateLimits(AreaType type)716 void MoveDragController::CalcFreeformTranslateLimits(AreaType type)
717 {
718 if (static_cast<uint32_t>(type) & static_cast<uint32_t>(AreaType::LEFT)) {
719 minTranX_ = moveDragProperty_.originalRect_.width_ - static_cast<int32_t>(limits_.maxWidth_);
720 maxTranX_ = moveDragProperty_.originalRect_.width_ - static_cast<int32_t>(limits_.minWidth_);
721 } else if (static_cast<uint32_t>(type) & static_cast<uint32_t>(AreaType::RIGHT)) {
722 minTranX_ = static_cast<int32_t>(limits_.minWidth_) - moveDragProperty_.originalRect_.width_;
723 maxTranX_ = static_cast<int32_t>(limits_.maxWidth_) - moveDragProperty_.originalRect_.width_;
724 }
725 if (static_cast<uint32_t>(type) & static_cast<uint32_t>(AreaType::TOP)) {
726 minTranY_ = moveDragProperty_.originalRect_.height_ - static_cast<int32_t>(limits_.maxHeight_);
727 maxTranY_ = moveDragProperty_.originalRect_.height_ - static_cast<int32_t>(limits_.minHeight_);
728 } else if (static_cast<uint32_t>(type) & static_cast<uint32_t>(AreaType::BOTTOM)) {
729 minTranY_ = static_cast<int32_t>(limits_.minHeight_) - moveDragProperty_.originalRect_.height_;
730 maxTranY_ = static_cast<int32_t>(limits_.maxHeight_) - moveDragProperty_.originalRect_.height_;
731 }
732 }
733
CalcFixedAspectRatioTranslateLimits(AreaType type, AxisType axis)734 void MoveDragController::CalcFixedAspectRatioTranslateLimits(AreaType type, AxisType axis)
735 {
736 int32_t minW = static_cast<int32_t>(limits_.minWidth_);
737 int32_t maxW = static_cast<int32_t>(limits_.maxWidth_);
738 int32_t minH = static_cast<int32_t>(limits_.minHeight_);
739 int32_t maxH = static_cast<int32_t>(limits_.maxHeight_);
740 if (isDecorEnable_) {
741 if (SessionUtils::ToLayoutWidth(minW, vpr_) < SessionUtils::ToLayoutHeight(minH, vpr_) * aspectRatio_) {
742 minW = SessionUtils::ToWinWidth(SessionUtils::ToLayoutHeight(minH, vpr_) * aspectRatio_, vpr_);
743 } else {
744 minH = SessionUtils::ToWinHeight(SessionUtils::ToLayoutWidth(minW, vpr_) / aspectRatio_, vpr_);
745 }
746 if (SessionUtils::ToLayoutWidth(maxW, vpr_) < SessionUtils::ToLayoutHeight(maxH, vpr_) * aspectRatio_) {
747 maxH = SessionUtils::ToWinHeight(SessionUtils::ToLayoutWidth(maxW, vpr_) * aspectRatio_, vpr_);
748 } else {
749 maxW = SessionUtils::ToWinWidth(SessionUtils::ToLayoutHeight(maxH, vpr_) / aspectRatio_, vpr_);
750 }
751 } else {
752 if (minW < minH * aspectRatio_) {
753 minW = minH * aspectRatio_;
754 } else {
755 minH = minW / aspectRatio_;
756 }
757 if (maxW < maxH * aspectRatio_) {
758 maxH = maxW * aspectRatio_;
759 } else {
760 maxW = maxH / aspectRatio_;
761 }
762 }
763
764 if (axis == AxisType::X_AXIS) {
765 if (static_cast<uint32_t>(type) & static_cast<uint32_t>(AreaType::LEFT)) {
766 minTranX_ = static_cast<int32_t>(moveDragProperty_.originalRect_.width_) - maxW;
767 maxTranX_ = static_cast<int32_t>(moveDragProperty_.originalRect_.width_) - minW;
768 } else if (static_cast<uint32_t>(type) & static_cast<uint32_t>(AreaType::RIGHT)) {
769 minTranX_ = minW - static_cast<int32_t>(moveDragProperty_.originalRect_.width_);
770 maxTranX_ = maxW - static_cast<int32_t>(moveDragProperty_.originalRect_.width_);
771 }
772 } else if (axis == AxisType::Y_AXIS) {
773 if (static_cast<uint32_t>(type) & static_cast<uint32_t>(AreaType::TOP)) {
774 minTranY_ = static_cast<int32_t>(moveDragProperty_.originalRect_.height_) - maxH;
775 maxTranY_ = static_cast<int32_t>(moveDragProperty_.originalRect_.height_) - minH;
776 } else if (static_cast<uint32_t>(type) & static_cast<uint32_t>(AreaType::BOTTOM)) {
777 minTranY_ = minH - static_cast<int32_t>(moveDragProperty_.originalRect_.height_);
778 maxTranY_ = maxH - static_cast<int32_t>(moveDragProperty_.originalRect_.height_);
779 }
780 }
781 }
782
FixTranslateByLimits(int32_t& tranX, int32_t& tranY)783 void MoveDragController::FixTranslateByLimits(int32_t& tranX, int32_t& tranY)
784 {
785 if (tranX < minTranX_) {
786 tranX = minTranX_;
787 } else if (tranX > maxTranX_) {
788 tranX = maxTranX_;
789 }
790 if (tranY < minTranY_) {
791 tranY = minTranY_;
792 } else if (tranY > maxTranY_) {
793 tranY = maxTranY_;
794 }
795 }
796
InitMainAxis(AreaType type, int32_t tranX, int32_t tranY)797 bool MoveDragController::InitMainAxis(AreaType type, int32_t tranX, int32_t tranY)
798 {
799 if (type == AreaType::LEFT || type == AreaType::RIGHT) {
800 mainMoveAxis_ = AxisType::X_AXIS;
801 } else if (type == AreaType::TOP || type == AreaType::BOTTOM) {
802 mainMoveAxis_ = AxisType::Y_AXIS;
803 } else if (tranX == 0 && tranY == 0) {
804 return false;
805 } else {
806 mainMoveAxis_ = (std::abs(tranX) > std::abs(tranY)) ? AxisType::X_AXIS : AxisType::Y_AXIS;
807 }
808 CalcFixedAspectRatioTranslateLimits(type, mainMoveAxis_);
809 return true;
810 }
811
ConvertXYByAspectRatio(int32_t& tx, int32_t& ty, float aspectRatio)812 void MoveDragController::ConvertXYByAspectRatio(int32_t& tx, int32_t& ty, float aspectRatio)
813 {
814 if (mainMoveAxis_ == AxisType::X_AXIS) {
815 ty = tx / aspectRatio;
816 } else if (mainMoveAxis_ == AxisType::Y_AXIS) {
817 tx = ty * aspectRatio;
818 }
819 return;
820 }
821
InitDecorValue(const sptr<WindowSessionProperty> property, const SystemSessionConfig& sysConfig)822 void MoveDragController::InitDecorValue(const sptr<WindowSessionProperty> property,
823 const SystemSessionConfig& sysConfig)
824 {
825 auto windowType = property->GetWindowType();
826 bool isMainWindow = WindowHelper::IsMainWindow(windowType);
827 bool isSubWindow = WindowHelper::IsSubWindow(windowType);
828 bool isDialogWindow = WindowHelper::IsDialogWindow(windowType);
829 isDecorEnable_ = (isMainWindow ||
830 ((isSubWindow || isDialogWindow) && property->IsDecorEnable())) &&
831 sysConfig.isSystemDecorEnable_ &&
832 WindowHelper::IsWindowModeSupported(sysConfig.decorModeSupportInfo_, property->GetWindowMode());
833 }
834
ProcessSessionRectChange(const SizeChangeReason reason)835 void MoveDragController::ProcessSessionRectChange(const SizeChangeReason reason)
836 {
837 if (moveDragCallback_) {
838 moveDragCallback_(reason);
839 }
840 }
841
GetVirtualPixelRatio() const842 float MoveDragController::GetVirtualPixelRatio() const
843 {
844 float vpr = 1.5;
845 auto displayInfo = DisplayManager::GetInstance().GetDefaultDisplay();
846 if (displayInfo != nullptr) {
847 vpr = displayInfo->GetVirtualPixelRatio();
848 }
849 WLOGFD("vpr: %{public}f", vpr);
850 return vpr;
851 }
852
UpdateDragType(int32_t startPointPosX, int32_t startPointPosY)853 void MoveDragController::UpdateDragType(int32_t startPointPosX, int32_t startPointPosY)
854 {
855 if (startPointPosX > rectExceptCorner_.posX_ &&
856 (startPointPosX < rectExceptCorner_.posX_ +
857 static_cast<int32_t>(rectExceptCorner_.width_))) {
858 dragType_ = DragType::DRAG_BOTTOM_OR_TOP;
859 } else if (startPointPosY > rectExceptCorner_.posY_ &&
860 (startPointPosY < rectExceptCorner_.posY_ +
861 static_cast<int32_t>(rectExceptCorner_.height_))) {
862 dragType_ = DragType::DRAG_LEFT_OR_RIGHT;
863 } else if ((startPointPosX <= rectExceptCorner_.posX_ && startPointPosY <= rectExceptCorner_.posY_) ||
864 (startPointPosX >= rectExceptCorner_.posX_ + static_cast<int32_t>(rectExceptCorner_.width_) &&
865 startPointPosY >= rectExceptCorner_.posY_ + static_cast<int32_t>(rectExceptCorner_.height_))) {
866 dragType_ = DragType::DRAG_LEFT_TOP_CORNER;
867 } else {
868 dragType_ = DragType::DRAG_RIGHT_TOP_CORNER;
869 }
870 }
871
IsPointInDragHotZone(int32_t startPointPosX, int32_t startPointPosY, int32_t sourceType, const WSRect& winRect)872 bool MoveDragController::IsPointInDragHotZone(int32_t startPointPosX, int32_t startPointPosY,
873 int32_t sourceType, const WSRect& winRect)
874 {
875 // calculate rect with hotzone
876 Rect rectWithHotzone;
877 rectWithHotzone.posX_ = winRect.posX_ - static_cast<int32_t>(HOTZONE_POINTER);
878 rectWithHotzone.posY_ = winRect.posY_ - static_cast<int32_t>(HOTZONE_POINTER);
879 rectWithHotzone.width_ = winRect.width_ + HOTZONE_POINTER * 2u; // double hotZone
880 rectWithHotzone.height_ = winRect.height_ + HOTZONE_POINTER * 2u; // double hotZone
881
882 if (sourceType == MMI::PointerEvent::SOURCE_TYPE_MOUSE &&
883 !WindowHelper::IsPointInTargetRectWithBound(startPointPosX, startPointPosY, rectWithHotzone)) {
884 return false;
885 } else if ((!WindowHelper::IsPointInTargetRect(startPointPosX,
886 startPointPosY, rectExceptFrame_)) ||
887 (!WindowHelper::IsPointInWindowExceptCorner(startPointPosX,
888 startPointPosY, rectExceptCorner_))) {
889 return true;
890 }
891 return false;
892 }
893
CalculateStartRectExceptHotZone(float vpr, const WSRect& winRect)894 void MoveDragController::CalculateStartRectExceptHotZone(float vpr, const WSRect& winRect)
895 {
896 rectExceptFrame_.posX_ = winRect.posX_ +
897 static_cast<int32_t>(WINDOW_FRAME_WIDTH * vpr);
898 rectExceptFrame_.posY_ = winRect.posY_ +
899 static_cast<int32_t>(WINDOW_FRAME_WIDTH * vpr);
900 rectExceptFrame_.width_ = winRect.width_ -
901 static_cast<uint32_t>((WINDOW_FRAME_WIDTH + WINDOW_FRAME_WIDTH) * vpr);
902 rectExceptFrame_.height_ = winRect.height_ -
903 static_cast<uint32_t>((WINDOW_FRAME_WIDTH + WINDOW_FRAME_WIDTH) * vpr);
904
905 rectExceptCorner_.posX_ = winRect.posX_ +
906 static_cast<int32_t>(WINDOW_FRAME_CORNER_WIDTH * vpr);
907 rectExceptCorner_.posY_ = winRect.posY_ +
908 static_cast<int32_t>(WINDOW_FRAME_CORNER_WIDTH * vpr);
909 rectExceptCorner_.width_ = winRect.width_ -
910 static_cast<uint32_t>((WINDOW_FRAME_CORNER_WIDTH + WINDOW_FRAME_CORNER_WIDTH) * vpr);
911 rectExceptCorner_.height_ = winRect.height_ -
912 static_cast<uint32_t>((WINDOW_FRAME_CORNER_WIDTH + WINDOW_FRAME_CORNER_WIDTH) * vpr);
913 }
914
UpdateMoveTempProperty(const std::shared_ptr<MMI::PointerEvent>& pointerEvent)915 WSError MoveDragController::UpdateMoveTempProperty(const std::shared_ptr<MMI::PointerEvent>& pointerEvent)
916 {
917 int32_t pointerId = pointerEvent->GetPointerId();
918 int32_t startPointerId = moveTempProperty_.pointerId_;
919 int32_t pointerType = pointerEvent->GetSourceType();
920 int32_t startPointerType = moveDragProperty_.pointerType_;
921 MMI::PointerEvent::PointerItem pointerItem;
922 int32_t sourceType = pointerEvent->GetSourceType();
923 if (!pointerEvent->GetPointerItem(pointerId, pointerItem) ||
924 (sourceType == MMI::PointerEvent::SOURCE_TYPE_MOUSE &&
925 pointerEvent->GetButtonId() != MMI::PointerEvent::MOUSE_BUTTON_LEFT)) {
926 WLOGFW("invalid pointerEvent");
927 return WSError::WS_ERROR_NULLPTR;
928 }
929
930 int32_t pointerDisplayX = pointerItem.GetDisplayX();
931 int32_t pointerDisplayY = pointerItem.GetDisplayY();
932 switch (pointerEvent->GetPointerAction()) {
933 case MMI::PointerEvent::POINTER_ACTION_BUTTON_DOWN:
934 case MMI::PointerEvent::POINTER_ACTION_DOWN:
935 moveTempProperty_.pointerId_ = pointerId;
936 moveTempProperty_.pointerType_ = pointerType;
937 moveTempProperty_.lastDownPointerPosX_ = pointerDisplayX;
938 moveTempProperty_.lastDownPointerPosY_ = pointerDisplayY;
939 moveTempProperty_.lastMovePointerPosX_ = pointerDisplayX;
940 moveTempProperty_.lastMovePointerPosY_ = pointerDisplayY;
941 moveTempProperty_.lastDownPointerWindowX_ = pointerItem.GetWindowX();
942 moveTempProperty_.lastDownPointerWindowY_ = pointerItem.GetWindowY();
943 break;
944 case MMI::PointerEvent::POINTER_ACTION_MOVE:
945 if ((startPointerId != -1 && startPointerId != pointerId) ||
946 (startPointerType != -1 && pointerType != startPointerType)) {
947 WLOGFI("block unnecessary pointer event inside the window");
948 return WSError::WS_DO_NOTHING;
949 }
950 moveTempProperty_.lastMovePointerPosX_ = pointerDisplayX;
951 moveTempProperty_.lastMovePointerPosY_ = pointerDisplayY;
952 break;
953 case MMI::PointerEvent::POINTER_ACTION_UP:
954 case MMI::PointerEvent::POINTER_ACTION_BUTTON_UP:
955 case MMI::PointerEvent::POINTER_ACTION_CANCEL: {
956 moveTempProperty_ = { -1, -1, -1, -1, -1, -1, -1, -1 };
957 break;
958 }
959 default:
960 break;
961 }
962 return WSError::WS_OK;
963 }
964
CalcFirstMoveTargetRect(const WSRect& windowRect, bool isFullToFloating)965 void MoveDragController::CalcFirstMoveTargetRect(const WSRect& windowRect, bool isFullToFloating)
966 {
967 if (!GetStartMoveFlag() || moveTempProperty_.isEmpty()) {
968 return;
969 }
970
971 WSRect originalRect = {
972 moveTempProperty_.lastDownPointerPosX_ - moveTempProperty_.lastDownPointerWindowX_,
973 moveTempProperty_.lastDownPointerPosY_ - moveTempProperty_.lastDownPointerWindowY_,
974 windowRect.width_,
975 windowRect.height_
976 };
977 if (isFullToFloating) {
978 originalRect.posX_ = windowRect.posX_;
979 originalRect.posY_ = windowRect.posY_;
980 }
981 SetOriginalValue(moveTempProperty_.pointerId_, moveTempProperty_.pointerType_,
982 moveTempProperty_.lastDownPointerPosX_, moveTempProperty_.lastDownPointerPosY_, originalRect);
983
984 int32_t offsetX = moveTempProperty_.lastMovePointerPosX_ - moveTempProperty_.lastDownPointerPosX_;
985 int32_t offsetY = moveTempProperty_.lastMovePointerPosY_ - moveTempProperty_.lastDownPointerPosY_;
986 WSRect targetRect = {
987 originalRect.posX_ + offsetX,
988 originalRect.posY_ + offsetY,
989 originalRect.width_,
990 originalRect.height_
991 };
992 WLOGFD("first move rect: [%{public}d, %{public}d, %{public}u, %{public}u]", targetRect.posX_, targetRect.posY_,
993 targetRect.width_, targetRect.height_);
994 moveDragProperty_.targetRect_ = targetRect;
995 ProcessSessionRectChange(SizeChangeReason::MOVE);
996 }
997
CheckDragEventLegal(const std::shared_ptr<MMI::PointerEvent>& pointerEvent, const sptr<WindowSessionProperty> property)998 bool MoveDragController::CheckDragEventLegal(const std::shared_ptr<MMI::PointerEvent>& pointerEvent,
999 const sptr<WindowSessionProperty> property)
1000 {
1001 if (pointerEvent == nullptr || property == nullptr) {
1002 WLOGE("ConsumeDragEvent stop because of nullptr");
1003 return false;
1004 }
1005 if (GetStartMoveFlag()) {
1006 WLOGFD("the window is being moved");
1007 return false;
1008 }
1009 if (!GetStartDragFlag() && pointerEvent->GetPointerAction() != MMI::PointerEvent::POINTER_ACTION_DOWN &&
1010 pointerEvent->GetPointerAction() != MMI::PointerEvent::POINTER_ACTION_BUTTON_DOWN) {
1011 return false;
1012 }
1013 int32_t pointerId = pointerEvent->GetPointerId();
1014 int32_t startPointerId = moveDragProperty_.pointerId_;
1015 if (GetStartDragFlag() && startPointerId != -1 && startPointerId != pointerId) {
1016 WLOGFI("block unnecessary pointer event inside the window");
1017 return false;
1018 }
1019 return true;
1020 }
1021
UpdateHotAreaType(const std::shared_ptr<MMI::PointerEvent>& pointerEvent)1022 void MoveDragController::UpdateHotAreaType(const std::shared_ptr<MMI::PointerEvent>& pointerEvent)
1023 {
1024 int32_t pointerId = pointerEvent->GetPointerId();
1025 MMI::PointerEvent::PointerItem pointerItem;
1026 if (!pointerEvent->GetPointerItem(pointerId, pointerItem)) {
1027 WLOGFW("invalid pointerEvent");
1028 return;
1029 }
1030 int32_t pointerDisplayX = pointerItem.GetDisplayX();
1031 int32_t pointerDisplayY = pointerItem.GetDisplayY();
1032 DisplayId displayId = pointerEvent->GetTargetDisplayId();
1033 uint32_t windowDragHotAreaType = SceneSession::GetWindowDragHotAreaType(displayId,
1034 WINDOW_HOT_AREA_TYPE_UNDEFINED, pointerDisplayX, pointerDisplayY);
1035 if (windowDragHotAreaType_ != windowDragHotAreaType) {
1036 WLOGFI("the pointerEvent is window drag hot area, old type is: %{public}d, new type is: %{public}d",
1037 windowDragHotAreaType_, windowDragHotAreaType);
1038 }
1039 if (hotAreaDisplayId_ != displayId) {
1040 TLOGI(WmsLogTag::WMS_LAYOUT, "displayId is changed, old: %{public}" PRIu64 ", new: %{public}" PRIu64,
1041 moveDragStartDisplayId_, displayId);
1042 hotAreaDisplayId_ = displayId;
1043 }
1044 windowDragHotAreaType_ = windowDragHotAreaType;
1045 }
1046
GetOriginalPointerPosX()1047 int32_t MoveDragController::GetOriginalPointerPosX()
1048 {
1049 return moveDragProperty_.originalPointerPosX_;
1050 }
1051
GetOriginalPointerPosY()1052 int32_t MoveDragController::GetOriginalPointerPosY()
1053 {
1054 return moveDragProperty_.originalPointerPosY_;
1055 }
1056
SetWindowDragHotAreaFunc(const NotifyWindowDragHotAreaFunc& func)1057 void MoveDragController::SetWindowDragHotAreaFunc(const NotifyWindowDragHotAreaFunc& func)
1058 {
1059 windowDragHotAreaFunc_ = func;
1060 }
1061
OnLostFocus()1062 void MoveDragController::OnLostFocus()
1063 {
1064 if (isStartMove_ || isStartDrag_) {
1065 WLOGFI("window id %{public}d lost focus, should stop MoveDrag isMove: %{public}d, isDrag: %{public}d",
1066 persistentId_, isStartMove_, isStartDrag_);
1067 isStartMove_ = false;
1068 isStartDrag_ = false;
1069 NotifyWindowInputPidChange(isStartDrag_);
1070 if (windowDragHotAreaType_ != WINDOW_HOT_AREA_TYPE_UNDEFINED) {
1071 ProcessWindowDragHotAreaFunc(true, SizeChangeReason::DRAG_END);
1072 }
1073 ProcessSessionRectChange(SizeChangeReason::DRAG_END);
1074 }
1075 }
1076
SetIsPcWindow(bool isPcWindow)1077 void MoveDragController::SetIsPcWindow(bool isPcWindow)
1078 {
1079 isPcWindow_ = isPcWindow;
1080 }
1081
GetNewAddedDisplayIdsDuringMoveDrag()1082 std::set<uint64_t> MoveDragController::GetNewAddedDisplayIdsDuringMoveDrag()
1083 {
1084 std::set<uint64_t> newAddedDisplayIdSet;
1085 WSRect windowRect = GetTargetRect(TargetRectCoordinate::GLOBAL);
1086 std::map<ScreenId, ScreenProperty> screenProperties = ScreenSessionManagerClient::GetInstance().
1087 GetAllScreensProperties();
1088 std::lock_guard<std::mutex> lock(displayIdSetDuringMoveDragMutex_);
1089 for (const auto& [screenId, screenProperty] : screenProperties) {
1090 if (displayIdSetDuringMoveDrag_.find(screenId) != displayIdSetDuringMoveDrag_.end()) {
1091 continue;
1092 }
1093 WSRect screenRect = {
1094 screenProperty.GetStartX(),
1095 screenProperty.GetStartY(),
1096 screenProperty.GetBounds().rect_.GetWidth(),
1097 screenProperty.GetBounds().rect_.GetHeight(),
1098 };
1099 if (windowRect.IsOverlap(screenRect)) {
1100 displayIdSetDuringMoveDrag_.insert(screenId);
1101 newAddedDisplayIdSet.insert(screenId);
1102 }
1103 }
1104 return newAddedDisplayIdSet;
1105 }
1106
ResSchedReportData(int32_t type, bool onOffTag)1107 void MoveDragController::ResSchedReportData(int32_t type, bool onOffTag)
1108 {
1109 #ifdef RES_SCHED_ENABLE
1110 std::unordered_map<std::string, std::string> payload;
1111 // 0 is start, 1 is end
1112 if (onOffTag) {
1113 OHOS::ResourceSchedule::ResSchedClient::GetInstance().ReportData(type, 0, payload);
1114 } else {
1115 OHOS::ResourceSchedule::ResSchedClient::GetInstance().ReportData(type, 1, payload);
1116 }
1117 WLOGFD("ResSchedReportData success type: %{public}d onOffTag: %{public}d", type, onOffTag);
1118 #endif
1119 }
1120 } // namespace OHOS::Rosen
1121