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, { 0, 0, 0, 0 }, { 0, 0, 0, 0 } };
103 }
104
SetOriginalValue(int32_t pointerId,int32_t pointerType,int32_t pointerPosX,int32_t pointerPosY,const WSRect & winRect)105 void MoveDragController::SetOriginalValue(int32_t pointerId, int32_t pointerType,
106 int32_t pointerPosX, int32_t pointerPosY, const WSRect& winRect)
107 {
108 moveDragProperty_.pointerId_ = pointerId;
109 moveDragProperty_.pointerType_ = pointerType;
110 moveDragProperty_.originalPointerPosX_ = pointerPosX;
111 moveDragProperty_.originalPointerPosY_ = pointerPosY;
112 moveDragProperty_.originalRect_ = winRect;
113 }
114
GetFullScreenToFloatingRect(const WSRect & originalRect,const WSRect & windowRect)115 WSRect MoveDragController::GetFullScreenToFloatingRect(const WSRect& originalRect, const WSRect& windowRect)
116 {
117 if (moveTempProperty_.isEmpty()) {
118 TLOGI(WmsLogTag::WMS_LAYOUT, "move temporary property is empty");
119 return originalRect;
120 }
121 if (originalRect.width_ == 0) {
122 TLOGI(WmsLogTag::WMS_LAYOUT, "original rect witch is zero");
123 return windowRect;
124 }
125 // Drag and drop to full screen in proportion
126 float newPosX = static_cast<float>(windowRect.width_) / static_cast<float>(originalRect.width_) *
127 static_cast<float>(moveTempProperty_.lastDownPointerPosX_ - originalRect.posX_);
128 WSRect targetRect = {
129 moveTempProperty_.lastDownPointerPosX_ - static_cast<int32_t>(newPosX),
130 originalRect.posY_,
131 windowRect.width_,
132 windowRect.height_,
133 };
134 TLOGI(WmsLogTag::WMS_LAYOUT, "target rect [%{public}d,%{public}d,%{public}u,%{public}u]", targetRect.posX_,
135 targetRect.posY_, targetRect.width_, targetRect.height_);
136 return targetRect;
137 }
138
SetAspectRatio(float ratio)139 void MoveDragController::SetAspectRatio(float ratio)
140 {
141 aspectRatio_ = ratio;
142 }
143
ConsumeMoveEvent(const std::shared_ptr<MMI::PointerEvent> & pointerEvent,const WSRect & originalRect)144 bool MoveDragController::ConsumeMoveEvent(const std::shared_ptr<MMI::PointerEvent>& pointerEvent,
145 const WSRect& originalRect)
146 {
147 if (pointerEvent == nullptr) {
148 WLOGE("ConsumeMoveEvent stop because of nullptr");
149 return false;
150 }
151 if (GetStartDragFlag()) {
152 WLOGFI("the window is being resized");
153 return false;
154 }
155 int32_t pointerId = pointerEvent->GetPointerId();
156 int32_t startPointerId = moveDragProperty_.pointerId_;
157 int32_t startPointerType = moveDragProperty_.pointerType_;
158 if ((startPointerId != -1 && startPointerId != pointerId) ||
159 (startPointerType != -1 && pointerEvent->GetSourceType() != startPointerType)) {
160 WLOGFI("block unnecessary pointer event inside the window");
161 return false;
162 }
163 MMI::PointerEvent::PointerItem pointerItem;
164 int32_t sourceType = pointerEvent->GetSourceType();
165 if (!pointerEvent->GetPointerItem(pointerId, pointerItem) ||
166 (sourceType == MMI::PointerEvent::SOURCE_TYPE_MOUSE &&
167 (pointerEvent->GetButtonId() != MMI::PointerEvent::MOUSE_BUTTON_LEFT &&
168 !GetStartMoveFlag()))) {
169 WLOGFD("invalid pointerEvent id: %{public}d", persistentId_);
170 return false;
171 }
172
173 UpdateMoveTempProperty(pointerEvent);
174
175 int32_t action = pointerEvent->GetPointerAction();
176 if (!GetStartMoveFlag()) {
177 if (action == MMI::PointerEvent::POINTER_ACTION_DOWN ||
178 action == MMI::PointerEvent::POINTER_ACTION_BUTTON_DOWN) {
179 WLOGFD("Move event hasPointDown");
180 hasPointDown_ = true;
181 } else if (action == MMI::PointerEvent::POINTER_ACTION_UP ||
182 action == MMI::PointerEvent::POINTER_ACTION_BUTTON_UP ||
183 action == MMI::PointerEvent::POINTER_ACTION_CANCEL) {
184 WLOGFD("Reset hasPointDown_ when point up or cancel");
185 hasPointDown_ = false;
186 }
187 WLOGFD("No need to move action id: %{public}d", action);
188 return false;
189 }
190
191 SizeChangeReason reason = SizeChangeReason::DRAG_MOVE;
192 bool ret = true;
193 switch (action) {
194 case MMI::PointerEvent::POINTER_ACTION_MOVE: {
195 reason = SizeChangeReason::DRAG_MOVE;
196 uint32_t oldWindowDragHotAreaType = windowDragHotAreaType_;
197 UpdateHotAreaType(pointerEvent);
198 ProcessWindowDragHotAreaFunc(oldWindowDragHotAreaType != windowDragHotAreaType_, reason);
199 break;
200 }
201 case MMI::PointerEvent::POINTER_ACTION_UP:
202 case MMI::PointerEvent::POINTER_ACTION_BUTTON_UP:
203 case MMI::PointerEvent::POINTER_ACTION_CANCEL:
204 case MMI::PointerEvent::POINTER_ACTION_DOWN:
205 case MMI::PointerEvent::POINTER_ACTION_BUTTON_DOWN: {
206 reason = SizeChangeReason::DRAG_END;
207 SetStartMoveFlag(false);
208 hasPointDown_ = false;
209 ProcessWindowDragHotAreaFunc(windowDragHotAreaType_ != WINDOW_HOT_AREA_TYPE_UNDEFINED, reason);
210 // The Pointer up event sent to the ArkUI.
211 ret = false;
212 break;
213 }
214 default:
215 break;
216 }
217 if (CalcMoveTargetRect(pointerEvent, originalRect)) {
218 ProcessSessionRectChange(reason);
219 }
220 return ret;
221 }
222
ProcessWindowDragHotAreaFunc(bool isSendHotAreaMessage,const SizeChangeReason & reason)223 void MoveDragController::ProcessWindowDragHotAreaFunc(bool isSendHotAreaMessage, const SizeChangeReason& reason)
224 {
225 if (isSendHotAreaMessage) {
226 WLOGFI("ProcessWindowDragHotAreaFunc start, isSendHotAreaMessage: %{public}u, reason: %{public}d",
227 isSendHotAreaMessage, reason);
228 }
229 if (windowDragHotAreaFunc_ && isSendHotAreaMessage) {
230 windowDragHotAreaFunc_(windowDragHotAreaType_, reason);
231 }
232 }
233
UpdateGravityWhenDrag(const std::shared_ptr<MMI::PointerEvent> & pointerEvent,const std::shared_ptr<RSSurfaceNode> & surfaceNode)234 void MoveDragController::UpdateGravityWhenDrag(const std::shared_ptr<MMI::PointerEvent>& pointerEvent,
235 const std::shared_ptr<RSSurfaceNode>& surfaceNode)
236 {
237 if (surfaceNode == nullptr || pointerEvent == nullptr || type_ == AreaType::UNDEFINED) {
238 return;
239 }
240 if (pointerEvent->GetPointerAction() == MMI::PointerEvent::POINTER_ACTION_DOWN ||
241 pointerEvent->GetPointerAction() == MMI::PointerEvent::POINTER_ACTION_BUTTON_DOWN) {
242 Gravity dragGravity = GRAVITY_MAP.at(type_);
243 if (dragGravity >= Gravity::TOP && dragGravity <= Gravity::BOTTOM_RIGHT) {
244 WLOGFI("begin SetFrameGravity:%{public}d, type:%{public}d", dragGravity, type_);
245 surfaceNode->SetFrameGravity(dragGravity);
246 RSTransaction::FlushImplicitTransaction();
247 }
248 return;
249 }
250 if (pointerEvent->GetPointerAction() == MMI::PointerEvent::POINTER_ACTION_BUTTON_UP ||
251 pointerEvent->GetPointerAction() == MMI::PointerEvent::POINTER_ACTION_UP ||
252 pointerEvent->GetPointerAction() == MMI::PointerEvent::POINTER_ACTION_CANCEL) {
253 surfaceNode->SetFrameGravity(Gravity::TOP_LEFT);
254 RSTransaction::FlushImplicitTransaction();
255 WLOGFI("recover gravity to TOP_LEFT");
256 }
257 }
258
ConsumeDragEvent(const std::shared_ptr<MMI::PointerEvent> & pointerEvent,const WSRect & originalRect,const sptr<WindowSessionProperty> property,const SystemSessionConfig & sysConfig)259 bool MoveDragController::ConsumeDragEvent(const std::shared_ptr<MMI::PointerEvent>& pointerEvent,
260 const WSRect& originalRect, const sptr<WindowSessionProperty> property, const SystemSessionConfig& sysConfig)
261 {
262 if (!CheckDragEventLegal(pointerEvent, property)) {
263 return false;
264 }
265
266 int32_t pointerId = pointerEvent->GetPointerId();
267 MMI::PointerEvent::PointerItem pointerItem;
268 if (!pointerEvent->GetPointerItem(pointerId, pointerItem)) {
269 WLOGE("Get PointerItem failed");
270 return false;
271 }
272
273 SizeChangeReason reason = SizeChangeReason::UNDEFINED;
274 switch (pointerEvent->GetPointerAction()) {
275 case MMI::PointerEvent::POINTER_ACTION_BUTTON_DOWN:
276 case MMI::PointerEvent::POINTER_ACTION_DOWN: {
277 if (!EventDownInit(pointerEvent, originalRect, property, sysConfig)) {
278 return false;
279 }
280 reason = SizeChangeReason::DRAG_START;
281 ResSchedReportData(OHOS::ResourceSchedule::ResType::RES_TYPE_RESIZE_WINDOW, true);
282 break;
283 }
284 case MMI::PointerEvent::POINTER_ACTION_MOVE: {
285 reason = SizeChangeReason::DRAG;
286 break;
287 }
288 case MMI::PointerEvent::POINTER_ACTION_UP:
289 case MMI::PointerEvent::POINTER_ACTION_BUTTON_UP:
290 case MMI::PointerEvent::POINTER_ACTION_CANCEL: {
291 reason = SizeChangeReason::DRAG_END;
292 isStartDrag_ = false;
293 hasPointDown_ = false;
294 ResSchedReportData(OHOS::ResourceSchedule::ResType::RES_TYPE_RESIZE_WINDOW, false);
295 NotifyWindowInputPidChange(isStartDrag_);
296 break;
297 }
298 default:
299 return false;
300 }
301 int32_t tranX = pointerItem.GetDisplayX() - moveDragProperty_.originalPointerPosX_;
302 int32_t tranY = pointerItem.GetDisplayY() - moveDragProperty_.originalPointerPosY_;
303
304 if (aspectRatio_ > NEAR_ZERO) {
305 moveDragProperty_.targetRect_ = CalcFixedAspectRatioTargetRect(type_, tranX, tranY, aspectRatio_,
306 moveDragProperty_.originalRect_);
307 } else {
308 moveDragProperty_.targetRect_ = CalcFreeformTargetRect(type_, tranX, tranY, moveDragProperty_.originalRect_);
309 }
310 TLOGD(WmsLogTag::WMS_LAYOUT, "targetRect:%{public}s, originalRect:%{public}s, tranX:%{public}d, tranY:%{public}d",
311 moveDragProperty_.targetRect_.ToString().c_str(), moveDragProperty_.originalRect_.ToString().c_str(),
312 tranX, tranY);
313 ProcessSessionRectChange(reason);
314 return true;
315 }
316
CalcMoveTargetRect(const std::shared_ptr<MMI::PointerEvent> & pointerEvent,const WSRect & originalRect)317 bool MoveDragController::CalcMoveTargetRect(const std::shared_ptr<MMI::PointerEvent>& pointerEvent,
318 const WSRect& originalRect)
319 {
320 MMI::PointerEvent::PointerItem pointerItem;
321 int32_t pointerId = pointerEvent->GetPointerId();
322 pointerEvent->GetPointerItem(pointerId, pointerItem);
323 int32_t pointerDisplayX = pointerItem.GetDisplayX();
324 int32_t pointerDisplayY = pointerItem.GetDisplayY();
325 if (moveDragProperty_.isEmpty()) {
326 moveDragProperty_.pointerId_ = pointerId;
327 moveDragProperty_.pointerType_ = pointerEvent->GetSourceType();
328 moveDragProperty_.originalPointerPosX_ = pointerDisplayX;
329 moveDragProperty_.originalPointerPosY_ = pointerDisplayY;
330 int32_t pointerWindowX = pointerItem.GetWindowX();
331 int32_t pointerWindowY = pointerItem.GetWindowY();
332 moveDragProperty_.originalRect_ = originalRect;
333 moveDragProperty_.originalRect_.posX_ = pointerDisplayX - pointerWindowX;
334 moveDragProperty_.originalRect_.posY_ = pointerDisplayY - pointerWindowY;
335 return false;
336 } else {
337 int32_t offsetX = pointerDisplayX - moveDragProperty_.originalPointerPosX_;
338 int32_t offsetY = pointerDisplayY - moveDragProperty_.originalPointerPosY_;
339 moveDragProperty_.targetRect_ = {
340 moveDragProperty_.originalRect_.posX_ + offsetX,
341 moveDragProperty_.originalRect_.posY_ + offsetY,
342 originalRect.width_,
343 originalRect.height_};
344 WLOGFD("move rect: [%{public}d, %{public}d, %{public}u, %{public}u]",
345 moveDragProperty_.targetRect_.posX_, moveDragProperty_.targetRect_.posY_,
346 moveDragProperty_.targetRect_.width_, moveDragProperty_.targetRect_.height_);
347 return true;
348 }
349 }
350
EventDownInit(const std::shared_ptr<MMI::PointerEvent> & pointerEvent,const WSRect & originalRect,const sptr<WindowSessionProperty> property,const SystemSessionConfig & sysConfig)351 bool MoveDragController::EventDownInit(const std::shared_ptr<MMI::PointerEvent>& pointerEvent,
352 const WSRect& originalRect, const sptr<WindowSessionProperty> property, const SystemSessionConfig& sysConfig)
353 {
354 const auto& sourceType = pointerEvent->GetSourceType();
355 if (sourceType == MMI::PointerEvent::SOURCE_TYPE_MOUSE &&
356 pointerEvent->GetButtonId() != MMI::PointerEvent::MOUSE_BUTTON_LEFT) {
357 TLOGD(WmsLogTag::WMS_LAYOUT, "Mouse click event but not left click");
358 return false;
359 }
360 HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "MoveDragController::EventDownInit");
361 int32_t pointerId = pointerEvent->GetPointerId();
362 MMI::PointerEvent::PointerItem pointerItem;
363 pointerEvent->GetPointerItem(pointerId, pointerItem);
364 InitMoveDragProperty();
365 hasPointDown_ = true;
366 moveDragProperty_.originalRect_ = originalRect;
367 auto display = DisplayManager::GetInstance().GetDisplayById(pointerEvent->GetTargetDisplayId());
368 if (display) {
369 vpr_ = display->GetVirtualPixelRatio();
370 } else {
371 vpr_ = 1.5f; // 1.5f: default virtual pixel ratio
372 }
373 int outside = (sourceType == MMI::PointerEvent::SOURCE_TYPE_MOUSE) ? HOTZONE_POINTER * vpr_ :
374 HOTZONE_TOUCH * vpr_;
375 type_ = SessionHelper::GetAreaType(pointerItem.GetWindowX(), pointerItem.GetWindowY(), sourceType, outside, vpr_,
376 moveDragProperty_.originalRect_);
377 if (type_ == AreaType::UNDEFINED) {
378 return false;
379 }
380 InitDecorValue(property, sysConfig);
381 limits_ = property->GetWindowLimits();
382 moveDragProperty_.pointerId_ = pointerEvent->GetPointerId();
383 moveDragProperty_.pointerType_ = sourceType;
384 moveDragProperty_.originalPointerPosX_ = pointerItem.GetDisplayX();
385 moveDragProperty_.originalPointerPosY_ = pointerItem.GetDisplayY();
386 if (aspectRatio_ <= NEAR_ZERO) {
387 CalcFreeformTranslateLimits(type_);
388 }
389 moveDragProperty_.originalRect_.posX_ = pointerItem.GetDisplayX() - pointerItem.GetWindowX();
390 moveDragProperty_.originalRect_.posY_ = pointerItem.GetDisplayY() - pointerItem.GetWindowY();
391 mainMoveAxis_ = AxisType::UNDEFINED;
392 isStartDrag_ = true;
393 NotifyWindowInputPidChange(isStartDrag_);
394 return true;
395 }
396
CalcFreeformTargetRect(AreaType type,int32_t tranX,int32_t tranY,WSRect originalRect)397 WSRect MoveDragController::CalcFreeformTargetRect(AreaType type, int32_t tranX, int32_t tranY, WSRect originalRect)
398 {
399 WSRect targetRect = originalRect;
400 FixTranslateByLimits(tranX, tranY);
401 TLOGD(WmsLogTag::WMS_LAYOUT, "areaType:%{public}u", type);
402 if (static_cast<uint32_t>(type) & static_cast<uint32_t>(AreaType::LEFT)) {
403 targetRect.posX_ += tranX;
404 targetRect.width_ -= tranX;
405 } else if (static_cast<uint32_t>(type) & static_cast<uint32_t>(AreaType::RIGHT)) {
406 targetRect.width_ += tranX;
407 }
408 if (static_cast<uint32_t>(type) & static_cast<uint32_t>(AreaType::TOP)) {
409 targetRect.posY_ += tranY;
410 targetRect.height_ -= tranY;
411 } else if (static_cast<uint32_t>(type) & static_cast<uint32_t>(AreaType::BOTTOM)) {
412 targetRect.height_ += tranY;
413 }
414 // check current ratio limits
415 if (targetRect.height_ == 0) {
416 return targetRect;
417 }
418 float curRatio = static_cast<float>(targetRect.width_) / static_cast<float>(targetRect.height_);
419 if (!MathHelper::GreatNotEqual(limits_.minRatio_, curRatio) &&
420 !MathHelper::GreatNotEqual(curRatio, limits_.maxRatio_)) {
421 return targetRect;
422 }
423 float newRatio = MathHelper::LessNotEqual(curRatio, limits_.minRatio_) ? limits_.minRatio_ : limits_.maxRatio_;
424 if (MathHelper::NearZero(newRatio)) {
425 return targetRect;
426 }
427 if ((static_cast<uint32_t>(type) & static_cast<uint32_t>(AreaType::LEFT)) ||
428 (static_cast<uint32_t>(type) & static_cast<uint32_t>(AreaType::RIGHT))) {
429 targetRect.height_ = static_cast<int32_t>(static_cast<float>(targetRect.width_) / newRatio);
430 } else {
431 targetRect.width_ = static_cast<int32_t>(static_cast<float>(targetRect.height_) * newRatio);
432 }
433 TLOGD(WmsLogTag::WMS_LAYOUT, "curRatio:%{public}f, newRatio:%{public}f", curRatio, newRatio);
434 return targetRect;
435 }
436
CalcFixedAspectRatioTargetRect(AreaType type,int32_t tranX,int32_t tranY,float aspectRatio,WSRect originalRect)437 WSRect MoveDragController::CalcFixedAspectRatioTargetRect(AreaType type, int32_t tranX, int32_t tranY,
438 float aspectRatio, WSRect originalRect)
439 {
440 TLOGD(WmsLogTag::WMS_LAYOUT, "in");
441 int32_t posX = originalRect.posX_;
442 int32_t posY = originalRect.posY_;
443 int32_t width = static_cast<int32_t>(originalRect.width_);
444 int32_t height = static_cast<int32_t>(originalRect.height_);
445 FixTranslateByLimits(tranX, tranY);
446 if (mainMoveAxis_ == AxisType::UNDEFINED) {
447 if (!InitMainAxis(type, tranX, tranY)) {
448 return originalRect;
449 }
450 }
451
452 TLOGD(WmsLogTag::WMS_LAYOUT, "ratio:%{public}f, areaType:%{public}u", aspectRatio, type);
453 ConvertXYByAspectRatio(tranX, tranY, aspectRatio);
454 switch (type) {
455 case AreaType::LEFT_TOP: {
456 return { posX + tranX, posY + tranY, width - tranX, height - tranY };
457 }
458 case AreaType::RIGHT_TOP: {
459 return { posX, posY + (mainMoveAxis_ == AxisType::X_AXIS ? (-tranY) : (tranY)),
460 width + (mainMoveAxis_ == AxisType::X_AXIS ? (tranX) : (-tranX)),
461 height + (mainMoveAxis_ == AxisType::X_AXIS ? (tranY) : (-tranY)) };
462 }
463 case AreaType::RIGHT_BOTTOM: {
464 return { posX, posY, width + tranX, height + tranY };
465 }
466 case AreaType::LEFT_BOTTOM: {
467 return { posX + (mainMoveAxis_ == AxisType::X_AXIS ? (tranX) : (-tranX)), posY,
468 width - (mainMoveAxis_ == AxisType::X_AXIS ? (tranX) : (-tranX)),
469 height - (mainMoveAxis_ == AxisType::X_AXIS ? (tranY) : (-tranY)) };
470 }
471 case AreaType::LEFT: {
472 return { posX + tranX, posY, width - tranX, height - tranY };
473 }
474 case AreaType::TOP: {
475 return { posX, posY + tranY, width - tranX, height - tranY };
476 }
477 case AreaType::RIGHT: {
478 return { posX, posY, width + tranX, height + tranY };
479 }
480 case AreaType::BOTTOM: {
481 return { posX, posY, width + tranX, height + tranY };
482 }
483 default:
484 break;
485 }
486 return originalRect;
487 }
488
CalcFreeformTranslateLimits(AreaType type)489 void MoveDragController::CalcFreeformTranslateLimits(AreaType type)
490 {
491 TLOGD(WmsLogTag::WMS_LAYOUT, "areaType:%{public}u, minWidth:%{public}u, maxWidth:%{public}u, "
492 "minHeight:%{public}u, maxHeight:%{public}u", type,
493 limits_.minWidth_, limits_.maxWidth_, limits_.minHeight_, limits_.maxHeight_);
494 if (static_cast<uint32_t>(type) & static_cast<uint32_t>(AreaType::LEFT)) {
495 minTranX_ = moveDragProperty_.originalRect_.width_ - static_cast<int32_t>(limits_.maxWidth_);
496 maxTranX_ = moveDragProperty_.originalRect_.width_ - static_cast<int32_t>(limits_.minWidth_);
497 } else if (static_cast<uint32_t>(type) & static_cast<uint32_t>(AreaType::RIGHT)) {
498 minTranX_ = static_cast<int32_t>(limits_.minWidth_) - moveDragProperty_.originalRect_.width_;
499 maxTranX_ = static_cast<int32_t>(limits_.maxWidth_) - moveDragProperty_.originalRect_.width_;
500 }
501 if (static_cast<uint32_t>(type) & static_cast<uint32_t>(AreaType::TOP)) {
502 minTranY_ = moveDragProperty_.originalRect_.height_ - static_cast<int32_t>(limits_.maxHeight_);
503 maxTranY_ = moveDragProperty_.originalRect_.height_ - static_cast<int32_t>(limits_.minHeight_);
504 } else if (static_cast<uint32_t>(type) & static_cast<uint32_t>(AreaType::BOTTOM)) {
505 minTranY_ = static_cast<int32_t>(limits_.minHeight_) - moveDragProperty_.originalRect_.height_;
506 maxTranY_ = static_cast<int32_t>(limits_.maxHeight_) - moveDragProperty_.originalRect_.height_;
507 }
508 }
509
CalcFixedAspectRatioTranslateLimits(AreaType type,AxisType axis)510 void MoveDragController::CalcFixedAspectRatioTranslateLimits(AreaType type, AxisType axis)
511 {
512 int32_t minW = static_cast<int32_t>(limits_.minWidth_);
513 int32_t maxW = static_cast<int32_t>(limits_.maxWidth_);
514 int32_t minH = static_cast<int32_t>(limits_.minHeight_);
515 int32_t maxH = static_cast<int32_t>(limits_.maxHeight_);
516 if (isDecorEnable_) {
517 if (SessionUtils::ToLayoutWidth(minW, vpr_) < SessionUtils::ToLayoutHeight(minH, vpr_) * aspectRatio_) {
518 minW = SessionUtils::ToWinWidth(SessionUtils::ToLayoutHeight(minH, vpr_) * aspectRatio_, vpr_);
519 } else {
520 minH = SessionUtils::ToWinHeight(SessionUtils::ToLayoutWidth(minW, vpr_) / aspectRatio_, vpr_);
521 }
522 if (SessionUtils::ToLayoutWidth(maxW, vpr_) < SessionUtils::ToLayoutHeight(maxH, vpr_) * aspectRatio_) {
523 maxH = SessionUtils::ToWinHeight(SessionUtils::ToLayoutWidth(maxW, vpr_) * aspectRatio_, vpr_);
524 } else {
525 maxW = SessionUtils::ToWinWidth(SessionUtils::ToLayoutHeight(maxH, vpr_) / aspectRatio_, vpr_);
526 }
527 } else {
528 if (minW < minH * aspectRatio_) {
529 minW = minH * aspectRatio_;
530 } else {
531 minH = minW / aspectRatio_;
532 }
533 if (maxW < maxH * aspectRatio_) {
534 maxH = maxW * aspectRatio_;
535 } else {
536 maxW = maxH / aspectRatio_;
537 }
538 }
539
540 TLOGD(WmsLogTag::WMS_LAYOUT, "areaType:%{public}u, axisType:%{public}d", type, axis);
541 if (axis == AxisType::X_AXIS) {
542 if (static_cast<uint32_t>(type) & static_cast<uint32_t>(AreaType::LEFT)) {
543 minTranX_ = static_cast<int32_t>(moveDragProperty_.originalRect_.width_) - maxW;
544 maxTranX_ = static_cast<int32_t>(moveDragProperty_.originalRect_.width_) - minW;
545 } else if (static_cast<uint32_t>(type) & static_cast<uint32_t>(AreaType::RIGHT)) {
546 minTranX_ = minW - static_cast<int32_t>(moveDragProperty_.originalRect_.width_);
547 maxTranX_ = maxW - static_cast<int32_t>(moveDragProperty_.originalRect_.width_);
548 }
549 } else if (axis == AxisType::Y_AXIS) {
550 if (static_cast<uint32_t>(type) & static_cast<uint32_t>(AreaType::TOP)) {
551 minTranY_ = static_cast<int32_t>(moveDragProperty_.originalRect_.height_) - maxH;
552 maxTranY_ = static_cast<int32_t>(moveDragProperty_.originalRect_.height_) - minH;
553 } else if (static_cast<uint32_t>(type) & static_cast<uint32_t>(AreaType::BOTTOM)) {
554 minTranY_ = minH - static_cast<int32_t>(moveDragProperty_.originalRect_.height_);
555 maxTranY_ = maxH - static_cast<int32_t>(moveDragProperty_.originalRect_.height_);
556 }
557 }
558 }
559
FixTranslateByLimits(int32_t & tranX,int32_t & tranY)560 void MoveDragController::FixTranslateByLimits(int32_t& tranX, int32_t& tranY)
561 {
562 if (tranX < minTranX_) {
563 tranX = minTranX_;
564 } else if (tranX > maxTranX_) {
565 tranX = maxTranX_;
566 }
567 if (tranY < minTranY_) {
568 tranY = minTranY_;
569 } else if (tranY > maxTranY_) {
570 tranY = maxTranY_;
571 }
572 TLOGD(WmsLogTag::WMS_LAYOUT, "tranX:%{public}d, tranY:%{public}d, minTranX:%{public}d, maxTranX:%{public}d, "
573 "minTranY:%{public}d, maxTranY:%{public}d", tranX, tranY, minTranX_, maxTranX_, minTranY_, maxTranY_);
574 }
575
InitMainAxis(AreaType type,int32_t tranX,int32_t tranY)576 bool MoveDragController::InitMainAxis(AreaType type, int32_t tranX, int32_t tranY)
577 {
578 if (type == AreaType::LEFT || type == AreaType::RIGHT) {
579 mainMoveAxis_ = AxisType::X_AXIS;
580 } else if (type == AreaType::TOP || type == AreaType::BOTTOM) {
581 mainMoveAxis_ = AxisType::Y_AXIS;
582 } else if (tranX == 0 && tranY == 0) {
583 return false;
584 } else {
585 mainMoveAxis_ = (std::abs(tranX) > std::abs(tranY)) ? AxisType::X_AXIS : AxisType::Y_AXIS;
586 }
587 CalcFixedAspectRatioTranslateLimits(type, mainMoveAxis_);
588 return true;
589 }
590
ConvertXYByAspectRatio(int32_t & tx,int32_t & ty,float aspectRatio)591 void MoveDragController::ConvertXYByAspectRatio(int32_t& tx, int32_t& ty, float aspectRatio)
592 {
593 if (mainMoveAxis_ == AxisType::X_AXIS) {
594 ty = tx / aspectRatio;
595 } else if (mainMoveAxis_ == AxisType::Y_AXIS) {
596 tx = ty * aspectRatio;
597 }
598 return;
599 }
600
InitDecorValue(const sptr<WindowSessionProperty> property,const SystemSessionConfig & sysConfig)601 void MoveDragController::InitDecorValue(const sptr<WindowSessionProperty> property,
602 const SystemSessionConfig& sysConfig)
603 {
604 auto windowType = property->GetWindowType();
605 bool isMainWindow = WindowHelper::IsMainWindow(windowType);
606 bool isSubWindow = WindowHelper::IsSubWindow(windowType);
607 bool isDialogWindow = WindowHelper::IsDialogWindow(windowType);
608 isDecorEnable_ = (isMainWindow ||
609 ((isSubWindow || isDialogWindow) && property->IsDecorEnable())) &&
610 sysConfig.isSystemDecorEnable_ &&
611 WindowHelper::IsWindowModeSupported(sysConfig.decorWindowModeSupportType_, property->GetWindowMode());
612 }
613
ProcessSessionRectChange(const SizeChangeReason & reason)614 void MoveDragController::ProcessSessionRectChange(const SizeChangeReason& reason)
615 {
616 if (moveDragCallback_) {
617 moveDragCallback_(reason);
618 }
619 }
620
GetVirtualPixelRatio() const621 float MoveDragController::GetVirtualPixelRatio() const
622 {
623 float vpr = 1.5;
624 auto displayInfo = DisplayManager::GetInstance().GetDefaultDisplay();
625 if (displayInfo != nullptr) {
626 vpr = displayInfo->GetVirtualPixelRatio();
627 }
628 WLOGFD("vpr: %{public}f", vpr);
629 return vpr;
630 }
631
UpdateDragType(int32_t startPointPosX,int32_t startPointPosY)632 void MoveDragController::UpdateDragType(int32_t startPointPosX, int32_t startPointPosY)
633 {
634 if (startPointPosX > rectExceptCorner_.posX_ &&
635 (startPointPosX < rectExceptCorner_.posX_ +
636 static_cast<int32_t>(rectExceptCorner_.width_))) {
637 dragType_ = DragType::DRAG_BOTTOM_OR_TOP;
638 } else if (startPointPosY > rectExceptCorner_.posY_ &&
639 (startPointPosY < rectExceptCorner_.posY_ +
640 static_cast<int32_t>(rectExceptCorner_.height_))) {
641 dragType_ = DragType::DRAG_LEFT_OR_RIGHT;
642 } else if ((startPointPosX <= rectExceptCorner_.posX_ && startPointPosY <= rectExceptCorner_.posY_) ||
643 (startPointPosX >= rectExceptCorner_.posX_ + static_cast<int32_t>(rectExceptCorner_.width_) &&
644 startPointPosY >= rectExceptCorner_.posY_ + static_cast<int32_t>(rectExceptCorner_.height_))) {
645 dragType_ = DragType::DRAG_LEFT_TOP_CORNER;
646 } else {
647 dragType_ = DragType::DRAG_RIGHT_TOP_CORNER;
648 }
649 }
650
IsPointInDragHotZone(int32_t startPointPosX,int32_t startPointPosY,int32_t sourceType,const WSRect & winRect)651 bool MoveDragController::IsPointInDragHotZone(int32_t startPointPosX, int32_t startPointPosY,
652 int32_t sourceType, const WSRect& winRect)
653 {
654 // calculate rect with hotzone
655 Rect rectWithHotzone;
656 rectWithHotzone.posX_ = winRect.posX_ - static_cast<int32_t>(HOTZONE_POINTER);
657 rectWithHotzone.posY_ = winRect.posY_ - static_cast<int32_t>(HOTZONE_POINTER);
658 rectWithHotzone.width_ = winRect.width_ + HOTZONE_POINTER * 2u; // double hotZone
659 rectWithHotzone.height_ = winRect.height_ + HOTZONE_POINTER * 2u; // double hotZone
660
661 if (sourceType == MMI::PointerEvent::SOURCE_TYPE_MOUSE &&
662 !WindowHelper::IsPointInTargetRectWithBound(startPointPosX, startPointPosY, rectWithHotzone)) {
663 return false;
664 } else if ((!WindowHelper::IsPointInTargetRect(startPointPosX,
665 startPointPosY, rectExceptFrame_)) ||
666 (!WindowHelper::IsPointInWindowExceptCorner(startPointPosX,
667 startPointPosY, rectExceptCorner_))) {
668 return true;
669 }
670 return false;
671 }
672
CalculateStartRectExceptHotZone(float vpr,const WSRect & winRect)673 void MoveDragController::CalculateStartRectExceptHotZone(float vpr, const WSRect& winRect)
674 {
675 rectExceptFrame_.posX_ = winRect.posX_ +
676 static_cast<int32_t>(WINDOW_FRAME_WIDTH * vpr);
677 rectExceptFrame_.posY_ = winRect.posY_ +
678 static_cast<int32_t>(WINDOW_FRAME_WIDTH * vpr);
679 rectExceptFrame_.width_ = winRect.width_ -
680 static_cast<uint32_t>((WINDOW_FRAME_WIDTH + WINDOW_FRAME_WIDTH) * vpr);
681 rectExceptFrame_.height_ = winRect.height_ -
682 static_cast<uint32_t>((WINDOW_FRAME_WIDTH + WINDOW_FRAME_WIDTH) * vpr);
683
684 rectExceptCorner_.posX_ = winRect.posX_ +
685 static_cast<int32_t>(WINDOW_FRAME_CORNER_WIDTH * vpr);
686 rectExceptCorner_.posY_ = winRect.posY_ +
687 static_cast<int32_t>(WINDOW_FRAME_CORNER_WIDTH * vpr);
688 rectExceptCorner_.width_ = winRect.width_ -
689 static_cast<uint32_t>((WINDOW_FRAME_CORNER_WIDTH + WINDOW_FRAME_CORNER_WIDTH) * vpr);
690 rectExceptCorner_.height_ = winRect.height_ -
691 static_cast<uint32_t>((WINDOW_FRAME_CORNER_WIDTH + WINDOW_FRAME_CORNER_WIDTH) * vpr);
692 }
693
UpdateMoveTempProperty(const std::shared_ptr<MMI::PointerEvent> & pointerEvent)694 WSError MoveDragController::UpdateMoveTempProperty(const std::shared_ptr<MMI::PointerEvent>& pointerEvent)
695 {
696 int32_t pointerId = pointerEvent->GetPointerId();
697 int32_t startPointerId = moveTempProperty_.pointerId_;
698 int32_t pointerType = pointerEvent->GetSourceType();
699 int32_t startPointerType = moveDragProperty_.pointerType_;
700 MMI::PointerEvent::PointerItem pointerItem;
701 int32_t sourceType = pointerEvent->GetSourceType();
702 if (!pointerEvent->GetPointerItem(pointerId, pointerItem) ||
703 (sourceType == MMI::PointerEvent::SOURCE_TYPE_MOUSE &&
704 pointerEvent->GetButtonId() != MMI::PointerEvent::MOUSE_BUTTON_LEFT)) {
705 WLOGFW("invalid pointerEvent");
706 return WSError::WS_ERROR_NULLPTR;
707 }
708
709 int32_t pointerDisplayX = pointerItem.GetDisplayX();
710 int32_t pointerDisplayY = pointerItem.GetDisplayY();
711 switch (pointerEvent->GetPointerAction()) {
712 case MMI::PointerEvent::POINTER_ACTION_BUTTON_DOWN:
713 case MMI::PointerEvent::POINTER_ACTION_DOWN:
714 moveTempProperty_.pointerId_ = pointerId;
715 moveTempProperty_.pointerType_ = pointerType;
716 moveTempProperty_.lastDownPointerPosX_ = pointerDisplayX;
717 moveTempProperty_.lastDownPointerPosY_ = pointerDisplayY;
718 moveTempProperty_.lastMovePointerPosX_ = pointerDisplayX;
719 moveTempProperty_.lastMovePointerPosY_ = pointerDisplayY;
720 moveTempProperty_.lastDownPointerWindowX_ = pointerItem.GetWindowX();
721 moveTempProperty_.lastDownPointerWindowY_ = pointerItem.GetWindowY();
722 break;
723 case MMI::PointerEvent::POINTER_ACTION_MOVE:
724 if ((startPointerId != -1 && startPointerId != pointerId) ||
725 (startPointerType != -1 && pointerType != startPointerType)) {
726 WLOGFI("block unnecessary pointer event inside the window");
727 return WSError::WS_DO_NOTHING;
728 }
729 moveTempProperty_.lastMovePointerPosX_ = pointerDisplayX;
730 moveTempProperty_.lastMovePointerPosY_ = pointerDisplayY;
731 break;
732 case MMI::PointerEvent::POINTER_ACTION_UP:
733 case MMI::PointerEvent::POINTER_ACTION_BUTTON_UP:
734 case MMI::PointerEvent::POINTER_ACTION_CANCEL: {
735 moveTempProperty_ = { -1, -1, -1, -1, -1, -1, -1, -1 };
736 break;
737 }
738 default:
739 break;
740 }
741 return WSError::WS_OK;
742 }
743
CalcFirstMoveTargetRect(const WSRect & windowRect,bool isFullToFloating)744 void MoveDragController::CalcFirstMoveTargetRect(const WSRect& windowRect, bool isFullToFloating)
745 {
746 if (!GetStartMoveFlag() || moveTempProperty_.isEmpty()) {
747 return;
748 }
749
750 WSRect originalRect = {
751 moveTempProperty_.lastDownPointerPosX_ - moveTempProperty_.lastDownPointerWindowX_,
752 moveTempProperty_.lastDownPointerPosY_ - moveTempProperty_.lastDownPointerWindowY_,
753 windowRect.width_,
754 windowRect.height_
755 };
756 if (isFullToFloating) {
757 originalRect.posX_ = windowRect.posX_;
758 originalRect.posY_ = windowRect.posY_;
759 }
760 SetOriginalValue(moveTempProperty_.pointerId_, moveTempProperty_.pointerType_,
761 moveTempProperty_.lastDownPointerPosX_, moveTempProperty_.lastDownPointerPosY_, originalRect);
762
763 int32_t offsetX = moveTempProperty_.lastMovePointerPosX_ - moveTempProperty_.lastDownPointerPosX_;
764 int32_t offsetY = moveTempProperty_.lastMovePointerPosY_ - moveTempProperty_.lastDownPointerPosY_;
765 WSRect targetRect = {
766 originalRect.posX_ + offsetX,
767 originalRect.posY_ + offsetY,
768 originalRect.width_,
769 originalRect.height_
770 };
771 WLOGFD("first move rect: [%{public}d, %{public}d, %{public}u, %{public}u]", targetRect.posX_, targetRect.posY_,
772 targetRect.width_, targetRect.height_);
773 moveDragProperty_.targetRect_ = targetRect;
774 ProcessSessionRectChange(SizeChangeReason::DRAG_MOVE);
775 }
776
CheckDragEventLegal(const std::shared_ptr<MMI::PointerEvent> & pointerEvent,const sptr<WindowSessionProperty> property)777 bool MoveDragController::CheckDragEventLegal(const std::shared_ptr<MMI::PointerEvent>& pointerEvent,
778 const sptr<WindowSessionProperty> property)
779 {
780 if (pointerEvent == nullptr || property == nullptr) {
781 WLOGE("ConsumeDragEvent stop because of nullptr");
782 return false;
783 }
784 if (GetStartMoveFlag()) {
785 WLOGFD("the window is being moved");
786 return false;
787 }
788 if (!GetStartDragFlag() && pointerEvent->GetPointerAction() != MMI::PointerEvent::POINTER_ACTION_DOWN &&
789 pointerEvent->GetPointerAction() != MMI::PointerEvent::POINTER_ACTION_BUTTON_DOWN) {
790 return false;
791 }
792 int32_t pointerId = pointerEvent->GetPointerId();
793 int32_t startPointerId = moveDragProperty_.pointerId_;
794 if (GetStartDragFlag() && startPointerId != -1 && startPointerId != pointerId) {
795 WLOGFI("block unnecessary pointer event inside the window");
796 return false;
797 }
798 return true;
799 }
800
UpdateHotAreaType(const std::shared_ptr<MMI::PointerEvent> & pointerEvent)801 void MoveDragController::UpdateHotAreaType(const std::shared_ptr<MMI::PointerEvent>& pointerEvent)
802 {
803 int32_t pointerId = pointerEvent->GetPointerId();
804 MMI::PointerEvent::PointerItem pointerItem;
805 if (!pointerEvent->GetPointerItem(pointerId, pointerItem)) {
806 WLOGFW("invalid pointerEvent");
807 return;
808 }
809 int32_t pointerDisplayX = pointerItem.GetDisplayX();
810 int32_t pointerDisplayY = pointerItem.GetDisplayY();
811 uint32_t windowDragHotAreaType = SceneSession::GetWindowDragHotAreaType(WINDOW_HOT_AREA_TYPE_UNDEFINED,
812 pointerDisplayX, pointerDisplayY);
813 if (windowDragHotAreaType_ != windowDragHotAreaType) {
814 WLOGFI("the pointerEvent is window drag hot area, old type is: %{public}d, new type is: %{public}d",
815 windowDragHotAreaType_, windowDragHotAreaType);
816 }
817 windowDragHotAreaType_ = windowDragHotAreaType;
818 }
819
GetOriginalPointerPosX()820 int32_t MoveDragController::GetOriginalPointerPosX()
821 {
822 return moveDragProperty_.originalPointerPosX_;
823 }
824
GetOriginalPointerPosY()825 int32_t MoveDragController::GetOriginalPointerPosY()
826 {
827 return moveDragProperty_.originalPointerPosY_;
828 }
829
SetWindowDragHotAreaFunc(const NotifyWindowDragHotAreaFunc & func)830 void MoveDragController::SetWindowDragHotAreaFunc(const NotifyWindowDragHotAreaFunc& func)
831 {
832 windowDragHotAreaFunc_ = func;
833 }
834
OnLostFocus()835 void MoveDragController::OnLostFocus()
836 {
837 if (isStartMove_ || isStartDrag_) {
838 WLOGFI("window id %{public}d lost focus, should stop MoveDrag isMove: %{public}d, isDrag: %{public}d",
839 persistentId_, isStartMove_, isStartDrag_);
840 isStartMove_ = false;
841 isStartDrag_ = false;
842 NotifyWindowInputPidChange(isStartDrag_);
843 if (windowDragHotAreaType_ != WINDOW_HOT_AREA_TYPE_UNDEFINED) {
844 ProcessWindowDragHotAreaFunc(true, SizeChangeReason::DRAG_END);
845 }
846 ProcessSessionRectChange(SizeChangeReason::DRAG_END);
847 }
848 }
849
ResSchedReportData(int32_t type,bool onOffTag)850 void MoveDragController::ResSchedReportData(int32_t type, bool onOffTag)
851 {
852 #ifdef RES_SCHED_ENABLE
853 std::unordered_map<std::string, std::string> payload;
854 // 0 is start, 1 is end
855 if (onOffTag) {
856 OHOS::ResourceSchedule::ResSchedClient::GetInstance().ReportData(type, 0, payload);
857 } else {
858 OHOS::ResourceSchedule::ResSchedClient::GetInstance().ReportData(type, 1, payload);
859 }
860 WLOGFD("ResSchedReportData success type: %{public}d onOffTag: %{public}d", type, onOffTag);
861 #endif
862 }
863 } // namespace OHOS::Rosen
864