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