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