1e0dac50fSopenharmony_ci/* 2e0dac50fSopenharmony_ci * Copyright (c) 2021-2023 Huawei Device Co., Ltd. 3e0dac50fSopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License"); 4e0dac50fSopenharmony_ci * you may not use this file except in compliance with the License. 5e0dac50fSopenharmony_ci * You may obtain a copy of the License at 6e0dac50fSopenharmony_ci * 7e0dac50fSopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0 8e0dac50fSopenharmony_ci * 9e0dac50fSopenharmony_ci * Unless required by applicable law or agreed to in writing, software 10e0dac50fSopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS, 11e0dac50fSopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12e0dac50fSopenharmony_ci * See the License for the specific language governing permissions and 13e0dac50fSopenharmony_ci * limitations under the License. 14e0dac50fSopenharmony_ci */ 15e0dac50fSopenharmony_ci#include "drag_controller.h" 16e0dac50fSopenharmony_ci 17e0dac50fSopenharmony_ci#include <vector> 18e0dac50fSopenharmony_ci 19e0dac50fSopenharmony_ci#include "display.h" 20e0dac50fSopenharmony_ci#include "window_helper.h" 21e0dac50fSopenharmony_ci#include "window_inner_manager.h" 22e0dac50fSopenharmony_ci#include "window_manager_hilog.h" 23e0dac50fSopenharmony_ci#include "window_manager_service.h" 24e0dac50fSopenharmony_ci#include "window_node.h" 25e0dac50fSopenharmony_ci#include "window_node_container.h" 26e0dac50fSopenharmony_ci#include "window_property.h" 27e0dac50fSopenharmony_ci#include "wm_common.h" 28e0dac50fSopenharmony_ci#include "wm_math.h" 29e0dac50fSopenharmony_ci#include "xcollie/watchdog.h" 30e0dac50fSopenharmony_ci 31e0dac50fSopenharmony_cinamespace OHOS { 32e0dac50fSopenharmony_cinamespace Rosen { 33e0dac50fSopenharmony_cinamespace { 34e0dac50fSopenharmony_ciconstexpr HiviewDFX::HiLogLabel LABEL = {LOG_CORE, HILOG_DOMAIN_WINDOW, "DragController"}; 35e0dac50fSopenharmony_ci} 36e0dac50fSopenharmony_ci 37e0dac50fSopenharmony_civoid DragController::UpdateDragInfo(uint32_t windowId) 38e0dac50fSopenharmony_ci{ 39e0dac50fSopenharmony_ci PointInfo point; 40e0dac50fSopenharmony_ci if (!GetHitPoint(windowId, point)) { 41e0dac50fSopenharmony_ci return; 42e0dac50fSopenharmony_ci } 43e0dac50fSopenharmony_ci sptr<WindowNode> dragNode = windowRoot_->GetWindowNode(windowId); 44e0dac50fSopenharmony_ci if (dragNode == nullptr) { 45e0dac50fSopenharmony_ci return; 46e0dac50fSopenharmony_ci } 47e0dac50fSopenharmony_ci sptr<WindowNode> hitWindowNode = GetHitWindow(dragNode->GetDisplayId(), point); 48e0dac50fSopenharmony_ci if (hitWindowNode == nullptr) { 49e0dac50fSopenharmony_ci WLOGFE("Get point failed %{public}d %{public}d", point.x, point.y); 50e0dac50fSopenharmony_ci return; 51e0dac50fSopenharmony_ci } 52e0dac50fSopenharmony_ci auto token = hitWindowNode->GetWindowToken(); 53e0dac50fSopenharmony_ci if (token) { 54e0dac50fSopenharmony_ci if (hitWindowNode->GetWindowId() == hitWindowId_) { 55e0dac50fSopenharmony_ci token->UpdateWindowDragInfo(point, DragEvent::DRAG_EVENT_MOVE); 56e0dac50fSopenharmony_ci return; 57e0dac50fSopenharmony_ci } 58e0dac50fSopenharmony_ci token->UpdateWindowDragInfo(point, DragEvent::DRAG_EVENT_IN); 59e0dac50fSopenharmony_ci } 60e0dac50fSopenharmony_ci sptr<WindowNode> oldHitWindow = windowRoot_->GetWindowNode(hitWindowId_); 61e0dac50fSopenharmony_ci if (oldHitWindow != nullptr && oldHitWindow->GetWindowToken()) { 62e0dac50fSopenharmony_ci oldHitWindow->GetWindowToken()->UpdateWindowDragInfo(point, DragEvent::DRAG_EVENT_OUT); 63e0dac50fSopenharmony_ci } 64e0dac50fSopenharmony_ci hitWindowId_ = hitWindowNode->GetWindowId(); 65e0dac50fSopenharmony_ci} 66e0dac50fSopenharmony_ci 67e0dac50fSopenharmony_civoid DragController::StartDrag(uint32_t windowId) 68e0dac50fSopenharmony_ci{ 69e0dac50fSopenharmony_ci PointInfo point; 70e0dac50fSopenharmony_ci if (!GetHitPoint(windowId, point)) { 71e0dac50fSopenharmony_ci WLOGFE("Get hit point failed"); 72e0dac50fSopenharmony_ci return; 73e0dac50fSopenharmony_ci } 74e0dac50fSopenharmony_ci sptr<WindowNode> dragNode = windowRoot_->GetWindowNode(windowId); 75e0dac50fSopenharmony_ci if (dragNode == nullptr) { 76e0dac50fSopenharmony_ci return; 77e0dac50fSopenharmony_ci } 78e0dac50fSopenharmony_ci sptr<WindowNode> hitWindow = GetHitWindow(dragNode->GetDisplayId(), point); 79e0dac50fSopenharmony_ci if (hitWindow == nullptr) { 80e0dac50fSopenharmony_ci WLOGFE("Get point failed %{public}d %{public}d", point.x, point.y); 81e0dac50fSopenharmony_ci return; 82e0dac50fSopenharmony_ci } 83e0dac50fSopenharmony_ci if (hitWindow->GetWindowToken()) { 84e0dac50fSopenharmony_ci hitWindow->GetWindowToken()->UpdateWindowDragInfo(point, DragEvent::DRAG_EVENT_IN); 85e0dac50fSopenharmony_ci } 86e0dac50fSopenharmony_ci hitWindowId_ = windowId; 87e0dac50fSopenharmony_ci WLOGI("start Drag"); 88e0dac50fSopenharmony_ci} 89e0dac50fSopenharmony_ci 90e0dac50fSopenharmony_civoid DragController::FinishDrag(uint32_t windowId) 91e0dac50fSopenharmony_ci{ 92e0dac50fSopenharmony_ci sptr<WindowNode> node = windowRoot_->GetWindowNode(windowId); 93e0dac50fSopenharmony_ci if (node == nullptr) { 94e0dac50fSopenharmony_ci WLOGFE("get node failed"); 95e0dac50fSopenharmony_ci return; 96e0dac50fSopenharmony_ci } 97e0dac50fSopenharmony_ci if (node->GetWindowType() != WindowType::WINDOW_TYPE_DRAGGING_EFFECT) { 98e0dac50fSopenharmony_ci return; 99e0dac50fSopenharmony_ci } 100e0dac50fSopenharmony_ci 101e0dac50fSopenharmony_ci sptr<WindowNode> hitWindow = windowRoot_->GetWindowNode(hitWindowId_); 102e0dac50fSopenharmony_ci if (hitWindow != nullptr) { 103e0dac50fSopenharmony_ci auto property = node->GetWindowProperty(); 104e0dac50fSopenharmony_ci PointInfo point = {property->GetWindowRect().posX_ + property->GetHitOffset().x, 105e0dac50fSopenharmony_ci property->GetWindowRect().posY_ + property->GetHitOffset().y}; 106e0dac50fSopenharmony_ci if (hitWindow->GetWindowToken()) { 107e0dac50fSopenharmony_ci hitWindow->GetWindowToken()->UpdateWindowDragInfo(point, DragEvent::DRAG_EVENT_END); 108e0dac50fSopenharmony_ci } 109e0dac50fSopenharmony_ci } 110e0dac50fSopenharmony_ci WLOGI("end drag"); 111e0dac50fSopenharmony_ci} 112e0dac50fSopenharmony_ci 113e0dac50fSopenharmony_cisptr<WindowNode> DragController::GetHitWindow(DisplayId id, PointInfo point) 114e0dac50fSopenharmony_ci{ 115e0dac50fSopenharmony_ci // Need get display by point 116e0dac50fSopenharmony_ci if (id == DISPLAY_ID_INVALID) { 117e0dac50fSopenharmony_ci WLOGFE("Get invalid display"); 118e0dac50fSopenharmony_ci return nullptr; 119e0dac50fSopenharmony_ci } 120e0dac50fSopenharmony_ci sptr<WindowNodeContainer> container = windowRoot_->GetOrCreateWindowNodeContainer(id); 121e0dac50fSopenharmony_ci if (container == nullptr) { 122e0dac50fSopenharmony_ci WLOGFE("get container failed %{public}" PRIu64"", id); 123e0dac50fSopenharmony_ci return nullptr; 124e0dac50fSopenharmony_ci } 125e0dac50fSopenharmony_ci 126e0dac50fSopenharmony_ci std::vector<sptr<WindowNode>> windowNodes; 127e0dac50fSopenharmony_ci container->TraverseContainer(windowNodes); 128e0dac50fSopenharmony_ci for (auto windowNode : windowNodes) { 129e0dac50fSopenharmony_ci if (windowNode->GetWindowType() >= WindowType::WINDOW_TYPE_PANEL) { 130e0dac50fSopenharmony_ci continue; 131e0dac50fSopenharmony_ci } 132e0dac50fSopenharmony_ci if (WindowHelper::IsPointInTargetRect(point.x, point.y, windowNode->GetWindowRect())) { 133e0dac50fSopenharmony_ci return windowNode; 134e0dac50fSopenharmony_ci } 135e0dac50fSopenharmony_ci } 136e0dac50fSopenharmony_ci return nullptr; 137e0dac50fSopenharmony_ci} 138e0dac50fSopenharmony_ci 139e0dac50fSopenharmony_cibool DragController::GetHitPoint(uint32_t windowId, PointInfo& point) 140e0dac50fSopenharmony_ci{ 141e0dac50fSopenharmony_ci sptr<WindowNode> windowNode = windowRoot_->GetWindowNode(windowId); 142e0dac50fSopenharmony_ci if (windowNode == nullptr || windowNode->GetWindowType() != WindowType::WINDOW_TYPE_DRAGGING_EFFECT) { 143e0dac50fSopenharmony_ci WLOGFE("Get hit point failed"); 144e0dac50fSopenharmony_ci return false; 145e0dac50fSopenharmony_ci } 146e0dac50fSopenharmony_ci sptr<WindowProperty> property = windowNode->GetWindowProperty(); 147e0dac50fSopenharmony_ci point.x = property->GetWindowRect().posX_ + property->GetHitOffset().x; 148e0dac50fSopenharmony_ci point.y = property->GetWindowRect().posY_ + property->GetHitOffset().y; 149e0dac50fSopenharmony_ci return true; 150e0dac50fSopenharmony_ci} 151e0dac50fSopenharmony_ci 152e0dac50fSopenharmony_civoid DragInputEventListener::OnInputEvent(std::shared_ptr<MMI::KeyEvent> keyEvent) const 153e0dac50fSopenharmony_ci{ 154e0dac50fSopenharmony_ci if (keyEvent == nullptr) { 155e0dac50fSopenharmony_ci WLOGFE("KeyEvent is nullptr"); 156e0dac50fSopenharmony_ci return; 157e0dac50fSopenharmony_ci } 158e0dac50fSopenharmony_ci uint32_t windowId = static_cast<uint32_t>(keyEvent->GetAgentWindowId()); 159e0dac50fSopenharmony_ci WLOGFD("[WMS] Receive keyEvent, windowId: %{public}u", windowId); 160e0dac50fSopenharmony_ci keyEvent->MarkProcessed(); 161e0dac50fSopenharmony_ci} 162e0dac50fSopenharmony_ci 163e0dac50fSopenharmony_civoid DragInputEventListener::OnInputEvent(std::shared_ptr<MMI::AxisEvent> axisEvent) const 164e0dac50fSopenharmony_ci{ 165e0dac50fSopenharmony_ci if (axisEvent == nullptr) { 166e0dac50fSopenharmony_ci WLOGFE("AxisEvent is nullptr"); 167e0dac50fSopenharmony_ci return; 168e0dac50fSopenharmony_ci }; 169e0dac50fSopenharmony_ci WLOGFD("[WMS] Receive axisEvent, windowId: %{public}u", axisEvent->GetAgentWindowId()); 170e0dac50fSopenharmony_ci axisEvent->MarkProcessed(); 171e0dac50fSopenharmony_ci} 172e0dac50fSopenharmony_ci 173e0dac50fSopenharmony_civoid DragInputEventListener::OnInputEvent(std::shared_ptr<MMI::PointerEvent> pointerEvent) const 174e0dac50fSopenharmony_ci{ 175e0dac50fSopenharmony_ci if (pointerEvent == nullptr) { 176e0dac50fSopenharmony_ci WLOGFE("PointerEvent is nullptr"); 177e0dac50fSopenharmony_ci return; 178e0dac50fSopenharmony_ci } 179e0dac50fSopenharmony_ci uint32_t windowId = static_cast<uint32_t>(pointerEvent->GetAgentWindowId()); 180e0dac50fSopenharmony_ci WLOGFD("[WMS] Receive pointerEvent, windowId: %{public}u", windowId); 181e0dac50fSopenharmony_ci 182e0dac50fSopenharmony_ci WindowInnerManager::GetInstance().ConsumePointerEvent(pointerEvent); 183e0dac50fSopenharmony_ci} 184e0dac50fSopenharmony_ci 185e0dac50fSopenharmony_civoid MoveDragController::SetInputEventConsumer() 186e0dac50fSopenharmony_ci{ 187e0dac50fSopenharmony_ci if (!inputListener_ || !inputEventHandler_) { 188e0dac50fSopenharmony_ci WLOGFE("InputListener or inputEventHandler is nullptr"); 189e0dac50fSopenharmony_ci return; 190e0dac50fSopenharmony_ci } 191e0dac50fSopenharmony_ci MMI::InputManager::GetInstance()->SetWindowInputEventConsumer(inputListener_, inputEventHandler_); 192e0dac50fSopenharmony_ci} 193e0dac50fSopenharmony_ci 194e0dac50fSopenharmony_civoid MoveDragController::SetWindowRoot(const sptr<WindowRoot>& windowRoot) 195e0dac50fSopenharmony_ci{ 196e0dac50fSopenharmony_ci windowRoot_ = windowRoot; 197e0dac50fSopenharmony_ci} 198e0dac50fSopenharmony_ci 199e0dac50fSopenharmony_cibool MoveDragController::Init() 200e0dac50fSopenharmony_ci{ 201e0dac50fSopenharmony_ci // create handler for input event 202e0dac50fSopenharmony_ci inputEventHandler_ = std::make_shared<AppExecFwk::EventHandler>( 203e0dac50fSopenharmony_ci AppExecFwk::EventRunner::Create(INNER_WM_INPUT_THREAD_NAME)); 204e0dac50fSopenharmony_ci if (inputEventHandler_ == nullptr) { 205e0dac50fSopenharmony_ci return false; 206e0dac50fSopenharmony_ci } 207e0dac50fSopenharmony_ci int ret = HiviewDFX::Watchdog::GetInstance().AddThread(INNER_WM_INPUT_THREAD_NAME, inputEventHandler_); 208e0dac50fSopenharmony_ci if (ret != 0) { 209e0dac50fSopenharmony_ci WLOGFE("Add watchdog thread failed"); 210e0dac50fSopenharmony_ci } 211e0dac50fSopenharmony_ci inputListener_ = std::make_shared<DragInputEventListener>(DragInputEventListener()); 212e0dac50fSopenharmony_ci SetInputEventConsumer(); 213e0dac50fSopenharmony_ci return true; 214e0dac50fSopenharmony_ci} 215e0dac50fSopenharmony_ci 216e0dac50fSopenharmony_civoid MoveDragController::Stop() 217e0dac50fSopenharmony_ci{ 218e0dac50fSopenharmony_ci if (inputEventHandler_ != nullptr) { 219e0dac50fSopenharmony_ci inputEventHandler_.reset(); 220e0dac50fSopenharmony_ci } 221e0dac50fSopenharmony_ci} 222e0dac50fSopenharmony_ci 223e0dac50fSopenharmony_civoid MoveDragController::HandleReadyToMoveOrDrag(uint32_t windowId, sptr<WindowProperty>& windowProperty, 224e0dac50fSopenharmony_ci sptr<MoveDragProperty>& moveDragProperty) 225e0dac50fSopenharmony_ci{ 226e0dac50fSopenharmony_ci SetActiveWindowId(windowId); 227e0dac50fSopenharmony_ci SetWindowProperty(windowProperty); 228e0dac50fSopenharmony_ci SetDragProperty(moveDragProperty); 229e0dac50fSopenharmony_ci} 230e0dac50fSopenharmony_ci 231e0dac50fSopenharmony_civoid MoveDragController::HandleEndUpMovingOrDragging(uint32_t windowId) 232e0dac50fSopenharmony_ci{ 233e0dac50fSopenharmony_ci if (activeWindowId_ != windowId) { 234e0dac50fSopenharmony_ci WLOGFE("end up moving or dragging failed, windowId: %{public}u", windowId); 235e0dac50fSopenharmony_ci return; 236e0dac50fSopenharmony_ci } 237e0dac50fSopenharmony_ci ResetMoveOrDragState(); 238e0dac50fSopenharmony_ci} 239e0dac50fSopenharmony_ci 240e0dac50fSopenharmony_civoid MoveDragController::HandleWindowRemovedOrDestroyed(uint32_t windowId) 241e0dac50fSopenharmony_ci{ 242e0dac50fSopenharmony_ci if (GetMoveDragProperty() == nullptr) { 243e0dac50fSopenharmony_ci return; 244e0dac50fSopenharmony_ci } 245e0dac50fSopenharmony_ci if (!(GetMoveDragProperty()->startMoveFlag_ || GetMoveDragProperty()->startDragFlag_)) { 246e0dac50fSopenharmony_ci return; 247e0dac50fSopenharmony_ci } 248e0dac50fSopenharmony_ci 249e0dac50fSopenharmony_ci { 250e0dac50fSopenharmony_ci std::lock_guard<std::mutex> lock(mtx_); 251e0dac50fSopenharmony_ci auto iter = vsyncStationMap_.find(windowId); 252e0dac50fSopenharmony_ci if (iter != vsyncStationMap_.end()) { 253e0dac50fSopenharmony_ci auto vsyncStation = iter->second; 254e0dac50fSopenharmony_ci vsyncStation->RemoveCallback(); 255e0dac50fSopenharmony_ci vsyncStationMap_.erase(windowId); 256e0dac50fSopenharmony_ci } 257e0dac50fSopenharmony_ci } 258e0dac50fSopenharmony_ci 259e0dac50fSopenharmony_ci ResetMoveOrDragState(); 260e0dac50fSopenharmony_ci} 261e0dac50fSopenharmony_ci 262e0dac50fSopenharmony_civoid MoveDragController::ConvertPointerPosToDisplayGroupPos(DisplayId displayId, int32_t& posX, int32_t& posY) 263e0dac50fSopenharmony_ci{ 264e0dac50fSopenharmony_ci auto displayRect = DisplayGroupInfo::GetInstance().GetDisplayRect(displayId); 265e0dac50fSopenharmony_ci posX += displayRect.posX_; 266e0dac50fSopenharmony_ci posY += displayRect.posY_; 267e0dac50fSopenharmony_ci} 268e0dac50fSopenharmony_ci 269e0dac50fSopenharmony_civoid MoveDragController::HandleDisplayLimitRectChange(const std::map<DisplayId, Rect>& limitRectMap) 270e0dac50fSopenharmony_ci{ 271e0dac50fSopenharmony_ci limitRectMap_.clear(); 272e0dac50fSopenharmony_ci for (auto& elem : limitRectMap) { 273e0dac50fSopenharmony_ci limitRectMap_.insert(elem); 274e0dac50fSopenharmony_ci } 275e0dac50fSopenharmony_ci} 276e0dac50fSopenharmony_ci 277e0dac50fSopenharmony_civoid MoveDragController::ConsumePointerEvent(const std::shared_ptr<MMI::PointerEvent>& pointerEvent) 278e0dac50fSopenharmony_ci{ 279e0dac50fSopenharmony_ci if (pointerEvent == nullptr) { 280e0dac50fSopenharmony_ci WLOGFE("pointerEvent is nullptr or is handling pointer event"); 281e0dac50fSopenharmony_ci return; 282e0dac50fSopenharmony_ci } 283e0dac50fSopenharmony_ci if (pointerEvent->GetPointerAction() == MMI::PointerEvent::POINTER_ACTION_MOVE) { 284e0dac50fSopenharmony_ci moveEvent_ = pointerEvent; 285e0dac50fSopenharmony_ci uint32_t windowId = static_cast<uint32_t>(pointerEvent->GetAgentWindowId()); 286e0dac50fSopenharmony_ci auto vsyncStation = GetVsyncStationByWindowId(windowId); 287e0dac50fSopenharmony_ci if (vsyncStation != nullptr) { 288e0dac50fSopenharmony_ci vsyncStation->RequestVsync(vsyncCallback_); 289e0dac50fSopenharmony_ci } 290e0dac50fSopenharmony_ci } else { 291e0dac50fSopenharmony_ci WLOGFD("[WMS] Dispatch non-move event, action: %{public}d", pointerEvent->GetPointerAction()); 292e0dac50fSopenharmony_ci HandlePointerEvent(pointerEvent); 293e0dac50fSopenharmony_ci pointerEvent->MarkProcessed(); 294e0dac50fSopenharmony_ci } 295e0dac50fSopenharmony_ci} 296e0dac50fSopenharmony_ci 297e0dac50fSopenharmony_civoid MoveDragController::OnReceiveVsync(int64_t timeStamp) 298e0dac50fSopenharmony_ci{ 299e0dac50fSopenharmony_ci if (moveEvent_ == nullptr) { 300e0dac50fSopenharmony_ci WLOGFE("moveEvent is nullptr"); 301e0dac50fSopenharmony_ci return; 302e0dac50fSopenharmony_ci } 303e0dac50fSopenharmony_ci WLOGFD("[OnReceiveVsync] receive move event, action: %{public}d", moveEvent_->GetPointerAction()); 304e0dac50fSopenharmony_ci HandlePointerEvent(moveEvent_); 305e0dac50fSopenharmony_ci moveEvent_->MarkProcessed(); 306e0dac50fSopenharmony_ci} 307e0dac50fSopenharmony_ci 308e0dac50fSopenharmony_ciRect MoveDragController::GetHotZoneRect() 309e0dac50fSopenharmony_ci{ 310e0dac50fSopenharmony_ci auto startPointPosX = moveDragProperty_->startPointPosX_; 311e0dac50fSopenharmony_ci auto startPointPosY = moveDragProperty_->startPointPosY_; 312e0dac50fSopenharmony_ci ConvertPointerPosToDisplayGroupPos(moveDragProperty_->targetDisplayId_, startPointPosX, startPointPosY); 313e0dac50fSopenharmony_ci 314e0dac50fSopenharmony_ci Rect hotZoneRect; 315e0dac50fSopenharmony_ci const auto& startRectExceptCorner = moveDragProperty_->startRectExceptCorner_; 316e0dac50fSopenharmony_ci const auto& startRectExceptFrame = moveDragProperty_->startRectExceptFrame_; 317e0dac50fSopenharmony_ci if ((startPointPosX > startRectExceptCorner.posX_ && 318e0dac50fSopenharmony_ci (startPointPosX < startRectExceptCorner.posX_ + 319e0dac50fSopenharmony_ci static_cast<int32_t>(startRectExceptCorner.width_))) && 320e0dac50fSopenharmony_ci (startPointPosY > startRectExceptCorner.posY_ && 321e0dac50fSopenharmony_ci (startPointPosY < startRectExceptCorner.posY_ + 322e0dac50fSopenharmony_ci static_cast<int32_t>(startRectExceptCorner.height_)))) { 323e0dac50fSopenharmony_ci hotZoneRect = startRectExceptFrame; // drag type: left/right/top/bottom 324e0dac50fSopenharmony_ci } else { 325e0dac50fSopenharmony_ci hotZoneRect = startRectExceptCorner; // drag type: left_top/right_top/left_bottom/right_bottom 326e0dac50fSopenharmony_ci } 327e0dac50fSopenharmony_ci return hotZoneRect; 328e0dac50fSopenharmony_ci} 329e0dac50fSopenharmony_ci 330e0dac50fSopenharmony_cibool MoveDragController::CheckWindowRect(DisplayId displayId, float vpr, const Rect& rect) 331e0dac50fSopenharmony_ci{ 332e0dac50fSopenharmony_ci uint32_t titleBarHeight = static_cast<uint32_t>(WINDOW_TITLE_BAR_HEIGHT * vpr); 333e0dac50fSopenharmony_ci auto iter = limitRectMap_.find(displayId); 334e0dac50fSopenharmony_ci Rect limitRect; 335e0dac50fSopenharmony_ci if (iter != limitRectMap_.end()) { 336e0dac50fSopenharmony_ci limitRect = iter->second; 337e0dac50fSopenharmony_ci } 338e0dac50fSopenharmony_ci if (WindowHelper::IsEmptyRect(limitRect) || MathHelper::NearZero(vpr)) { 339e0dac50fSopenharmony_ci return true; // If limitRect is empty, we can't use limitRect to check window rect 340e0dac50fSopenharmony_ci } 341e0dac50fSopenharmony_ci 342e0dac50fSopenharmony_ci if ((rect.posX_ > static_cast<int32_t>(limitRect.posX_ + limitRect.width_ - titleBarHeight)) || 343e0dac50fSopenharmony_ci (rect.posX_ + static_cast<int32_t>(rect.width_) < 344e0dac50fSopenharmony_ci static_cast<int32_t>(limitRect.posX_ + titleBarHeight)) || 345e0dac50fSopenharmony_ci (rect.posY_ < limitRect.posY_) || 346e0dac50fSopenharmony_ci (rect.posY_ > static_cast<int32_t>(limitRect.posY_ + limitRect.height_ - titleBarHeight))) { 347e0dac50fSopenharmony_ci WLOGFD("[WMS] Invalid window rect, id: %{public}u, rect: [%{public}d, %{public}d, %{public}d, %{public}d]", 348e0dac50fSopenharmony_ci windowProperty_->GetWindowId(), rect.posX_, rect.posY_, rect.width_, rect.height_); 349e0dac50fSopenharmony_ci return false; 350e0dac50fSopenharmony_ci } 351e0dac50fSopenharmony_ci return true; 352e0dac50fSopenharmony_ci} 353e0dac50fSopenharmony_ci 354e0dac50fSopenharmony_civoid MoveDragController::CalculateNewWindowRect(Rect& newRect, DisplayId displayId, int32_t posX, int32_t posY) 355e0dac50fSopenharmony_ci{ 356e0dac50fSopenharmony_ci auto startPointPosX = moveDragProperty_->startPointPosX_; 357e0dac50fSopenharmony_ci auto startPointPosY = moveDragProperty_->startPointPosY_; 358e0dac50fSopenharmony_ci ConvertPointerPosToDisplayGroupPos(moveDragProperty_->targetDisplayId_, startPointPosX, startPointPosY); 359e0dac50fSopenharmony_ci const auto& startPointRect = moveDragProperty_->startPointRect_; 360e0dac50fSopenharmony_ci Rect hotZoneRect = GetHotZoneRect(); 361e0dac50fSopenharmony_ci int32_t diffX = posX - startPointPosX; 362e0dac50fSopenharmony_ci int32_t diffY = posY - startPointPosY; 363e0dac50fSopenharmony_ci 364e0dac50fSopenharmony_ci float vpr = DisplayGroupInfo::GetInstance().GetDisplayVirtualPixelRatio(displayId); 365e0dac50fSopenharmony_ci if (MathHelper::NearZero(vpr)) { 366e0dac50fSopenharmony_ci return; 367e0dac50fSopenharmony_ci } 368e0dac50fSopenharmony_ci uint32_t minWidth = static_cast<uint32_t>(MIN_FLOATING_WIDTH * vpr); 369e0dac50fSopenharmony_ci uint32_t minHeight = static_cast<uint32_t>(MIN_FLOATING_HEIGHT * vpr); 370e0dac50fSopenharmony_ci if (startPointPosX <= hotZoneRect.posX_) { 371e0dac50fSopenharmony_ci if (diffX > static_cast<int32_t>(startPointRect.width_ - minWidth)) { 372e0dac50fSopenharmony_ci diffX = static_cast<int32_t>(startPointRect.width_ - minWidth); 373e0dac50fSopenharmony_ci } 374e0dac50fSopenharmony_ci newRect.posX_ += diffX; 375e0dac50fSopenharmony_ci newRect.width_ = static_cast<uint32_t>(static_cast<int32_t>(newRect.width_) - diffX); 376e0dac50fSopenharmony_ci } else if (startPointPosX >= hotZoneRect.posX_ + static_cast<int32_t>(hotZoneRect.width_)) { 377e0dac50fSopenharmony_ci if (diffX < 0 && (-diffX > static_cast<int32_t>(startPointRect.width_ - minWidth))) { 378e0dac50fSopenharmony_ci diffX = -(static_cast<int32_t>(startPointRect.width_ - minWidth)); 379e0dac50fSopenharmony_ci } 380e0dac50fSopenharmony_ci newRect.width_ = static_cast<uint32_t>(static_cast<int32_t>(newRect.width_) + diffX); 381e0dac50fSopenharmony_ci } 382e0dac50fSopenharmony_ci if (startPointPosY <= hotZoneRect.posY_) { 383e0dac50fSopenharmony_ci if (diffY > static_cast<int32_t>(startPointRect.height_ - minHeight)) { 384e0dac50fSopenharmony_ci diffY = static_cast<int32_t>(startPointRect.height_ - minHeight); 385e0dac50fSopenharmony_ci } 386e0dac50fSopenharmony_ci newRect.posY_ += diffY; 387e0dac50fSopenharmony_ci newRect.height_ = static_cast<uint32_t>(static_cast<int32_t>(newRect.height_) - diffY); 388e0dac50fSopenharmony_ci } else if (startPointPosY >= hotZoneRect.posY_ + static_cast<int32_t>(hotZoneRect.height_)) { 389e0dac50fSopenharmony_ci if (diffY < 0 && (-diffY > static_cast<int32_t>(startPointRect.height_ - minHeight))) { 390e0dac50fSopenharmony_ci diffY = -(static_cast<int32_t>(startPointRect.height_ - minHeight)); 391e0dac50fSopenharmony_ci } 392e0dac50fSopenharmony_ci newRect.height_ = static_cast<uint32_t>(static_cast<int32_t>(newRect.height_) + diffY); 393e0dac50fSopenharmony_ci } 394e0dac50fSopenharmony_ci} 395e0dac50fSopenharmony_ci 396e0dac50fSopenharmony_civoid MoveDragController::HandleDragEvent(DisplayId displayId, int32_t posX, int32_t posY, 397e0dac50fSopenharmony_ci int32_t pointId, int32_t sourceType) 398e0dac50fSopenharmony_ci{ 399e0dac50fSopenharmony_ci if (moveDragProperty_ == nullptr || !moveDragProperty_->startDragFlag_ || 400e0dac50fSopenharmony_ci (pointId != moveDragProperty_->startPointerId_) || (sourceType != moveDragProperty_->sourceType_)) { 401e0dac50fSopenharmony_ci return; 402e0dac50fSopenharmony_ci } 403e0dac50fSopenharmony_ci 404e0dac50fSopenharmony_ci Rect newRect = moveDragProperty_->startPointRect_; 405e0dac50fSopenharmony_ci CalculateNewWindowRect(newRect, displayId, posX, posY); 406e0dac50fSopenharmony_ci 407e0dac50fSopenharmony_ci if (!CheckWindowRect(displayId, DisplayGroupInfo::GetInstance().GetDisplayVirtualPixelRatio(displayId), newRect)) { 408e0dac50fSopenharmony_ci return; 409e0dac50fSopenharmony_ci } 410e0dac50fSopenharmony_ci 411e0dac50fSopenharmony_ci WLOGFD("[WMS] HandleDragEvent, id: %{public}u, newRect: [%{public}d, %{public}d, %{public}d, %{public}d]", 412e0dac50fSopenharmony_ci windowProperty_->GetWindowId(), newRect.posX_, newRect.posY_, newRect.width_, newRect.height_); 413e0dac50fSopenharmony_ci windowProperty_->SetRequestRect(newRect); 414e0dac50fSopenharmony_ci windowProperty_->SetWindowSizeChangeReason(WindowSizeChangeReason::DRAG); 415e0dac50fSopenharmony_ci windowProperty_->SetDragType(moveDragProperty_->dragType_); 416e0dac50fSopenharmony_ci WindowManagerService::GetInstance().UpdateProperty(windowProperty_, PropertyChangeAction::ACTION_UPDATE_RECT, true); 417e0dac50fSopenharmony_ci} 418e0dac50fSopenharmony_ci 419e0dac50fSopenharmony_civoid MoveDragController::HandleMoveEvent(DisplayId displayId, int32_t posX, int32_t posY, 420e0dac50fSopenharmony_ci int32_t pointId, int32_t sourceType) 421e0dac50fSopenharmony_ci{ 422e0dac50fSopenharmony_ci if (moveDragProperty_ == nullptr) { 423e0dac50fSopenharmony_ci return; 424e0dac50fSopenharmony_ci } 425e0dac50fSopenharmony_ci if (!moveDragProperty_->startMoveFlag_ || 426e0dac50fSopenharmony_ci (pointId != moveDragProperty_->startPointerId_) || 427e0dac50fSopenharmony_ci (sourceType != moveDragProperty_->sourceType_)) { 428e0dac50fSopenharmony_ci return; 429e0dac50fSopenharmony_ci } 430e0dac50fSopenharmony_ci auto startPointPosX = moveDragProperty_->startPointPosX_; 431e0dac50fSopenharmony_ci auto startPointPosY = moveDragProperty_->startPointPosY_; 432e0dac50fSopenharmony_ci ConvertPointerPosToDisplayGroupPos(moveDragProperty_->targetDisplayId_, startPointPosX, startPointPosY); 433e0dac50fSopenharmony_ci int32_t targetX = moveDragProperty_->startPointRect_.posX_ + (posX - startPointPosX); 434e0dac50fSopenharmony_ci int32_t targetY = moveDragProperty_->startPointRect_.posY_ + (posY - startPointPosY); 435e0dac50fSopenharmony_ci 436e0dac50fSopenharmony_ci const Rect& oriRect = moveDragProperty_->startPointRect_; 437e0dac50fSopenharmony_ci Rect newRect = { targetX, targetY, oriRect.width_, oriRect.height_ }; 438e0dac50fSopenharmony_ci if (limitRectMap_.find(displayId) != limitRectMap_.end()) { 439e0dac50fSopenharmony_ci newRect.posY_ = std::max(newRect.posY_, limitRectMap_[displayId].posY_); 440e0dac50fSopenharmony_ci } 441e0dac50fSopenharmony_ci WLOGFD("[WMS] HandleMoveEvent, id: %{public}u, newRect: [%{public}d, %{public}d, %{public}d, %{public}d]", 442e0dac50fSopenharmony_ci windowProperty_->GetWindowId(), newRect.posX_, newRect.posY_, newRect.width_, newRect.height_); 443e0dac50fSopenharmony_ci windowProperty_->SetRequestRect(newRect); 444e0dac50fSopenharmony_ci windowProperty_->SetWindowSizeChangeReason(WindowSizeChangeReason::MOVE); 445e0dac50fSopenharmony_ci WindowManagerService::GetInstance().UpdateProperty(windowProperty_, PropertyChangeAction::ACTION_UPDATE_RECT, true); 446e0dac50fSopenharmony_ci} 447e0dac50fSopenharmony_ci 448e0dac50fSopenharmony_civoid MoveDragController::HandlePointerEvent(const std::shared_ptr<MMI::PointerEvent>& pointerEvent) 449e0dac50fSopenharmony_ci{ 450e0dac50fSopenharmony_ci if (windowProperty_) { 451e0dac50fSopenharmony_ci windowProperty_->UpdatePointerEvent(pointerEvent); 452e0dac50fSopenharmony_ci } 453e0dac50fSopenharmony_ci MMI::PointerEvent::PointerItem pointerItem; 454e0dac50fSopenharmony_ci int32_t pointId = pointerEvent->GetPointerId(); 455e0dac50fSopenharmony_ci int32_t sourceType = pointerEvent->GetSourceType(); 456e0dac50fSopenharmony_ci if (!pointerEvent->GetPointerItem(pointId, pointerItem) || 457e0dac50fSopenharmony_ci (sourceType == MMI::PointerEvent::SOURCE_TYPE_MOUSE && 458e0dac50fSopenharmony_ci pointerEvent->GetButtonId() != MMI::PointerEvent::MOUSE_BUTTON_LEFT)) { 459e0dac50fSopenharmony_ci WLOGFW("invalid pointerEvent"); 460e0dac50fSopenharmony_ci return; 461e0dac50fSopenharmony_ci } 462e0dac50fSopenharmony_ci 463e0dac50fSopenharmony_ci int32_t pointPosX = pointerItem.GetDisplayX(); 464e0dac50fSopenharmony_ci int32_t pointPosY = pointerItem.GetDisplayY(); 465e0dac50fSopenharmony_ci int32_t action = pointerEvent->GetPointerAction(); 466e0dac50fSopenharmony_ci int32_t targetDisplayId = pointerEvent->GetTargetDisplayId(); 467e0dac50fSopenharmony_ci ConvertPointerPosToDisplayGroupPos(targetDisplayId, pointPosX, pointPosY); 468e0dac50fSopenharmony_ci switch (action) { 469e0dac50fSopenharmony_ci case MMI::PointerEvent::POINTER_ACTION_DOWN: 470e0dac50fSopenharmony_ci case MMI::PointerEvent::POINTER_ACTION_BUTTON_DOWN: { 471e0dac50fSopenharmony_ci if (pointId == moveDragProperty_->startPointerId_ && sourceType == moveDragProperty_->sourceType_) { 472e0dac50fSopenharmony_ci moveDragProperty_->startMoveFlag_ = false; 473e0dac50fSopenharmony_ci moveDragProperty_->startDragFlag_ = false; 474e0dac50fSopenharmony_ci } 475e0dac50fSopenharmony_ci TLOGD(WmsLogTag::WMS_EVENT, "windowId:%{public}u, pointId:%{public}d, sourceType:%{public}d, " 476e0dac50fSopenharmony_ci "hasPointStarted:%{public}d, startMove:%{public}d, startDrag:%{public}d, targetDisplayId:" 477e0dac50fSopenharmony_ci "%{public}d, pointPos:[%{private}d, %{private}d]", activeWindowId_, pointId, sourceType, 478e0dac50fSopenharmony_ci moveDragProperty_->pointEventStarted_, moveDragProperty_->startMoveFlag_, 479e0dac50fSopenharmony_ci moveDragProperty_->startDragFlag_, targetDisplayId, pointPosX, pointPosY); 480e0dac50fSopenharmony_ci break; 481e0dac50fSopenharmony_ci } 482e0dac50fSopenharmony_ci // ready to move or drag 483e0dac50fSopenharmony_ci case MMI::PointerEvent::POINTER_ACTION_MOVE: { 484e0dac50fSopenharmony_ci HandleMoveEvent(targetDisplayId, pointPosX, pointPosY, pointId, sourceType); 485e0dac50fSopenharmony_ci HandleDragEvent(targetDisplayId, pointPosX, pointPosY, pointId, sourceType); 486e0dac50fSopenharmony_ci break; 487e0dac50fSopenharmony_ci } 488e0dac50fSopenharmony_ci // End move or drag 489e0dac50fSopenharmony_ci case MMI::PointerEvent::POINTER_ACTION_UP: 490e0dac50fSopenharmony_ci case MMI::PointerEvent::POINTER_ACTION_BUTTON_UP: 491e0dac50fSopenharmony_ci case MMI::PointerEvent::POINTER_ACTION_CANCEL: { 492e0dac50fSopenharmony_ci WindowManagerService::GetInstance().NotifyWindowClientPointUp(activeWindowId_, pointerEvent); 493e0dac50fSopenharmony_ci WLOGFD("[Server Point Up/Cancel]: windowId: %{public}u, action: %{public}d, sourceType: %{public}d", 494e0dac50fSopenharmony_ci activeWindowId_, action, sourceType); 495e0dac50fSopenharmony_ci break; 496e0dac50fSopenharmony_ci } 497e0dac50fSopenharmony_ci default: 498e0dac50fSopenharmony_ci break; 499e0dac50fSopenharmony_ci } 500e0dac50fSopenharmony_ci} 501e0dac50fSopenharmony_ci 502e0dac50fSopenharmony_civoid MoveDragController::SetDragProperty(const sptr<MoveDragProperty>& moveDragProperty) 503e0dac50fSopenharmony_ci{ 504e0dac50fSopenharmony_ci moveDragProperty_->CopyFrom(moveDragProperty); 505e0dac50fSopenharmony_ci} 506e0dac50fSopenharmony_ci 507e0dac50fSopenharmony_civoid MoveDragController::SetWindowProperty(const sptr<WindowProperty>& windowProperty) 508e0dac50fSopenharmony_ci{ 509e0dac50fSopenharmony_ci windowProperty_->CopyFrom(windowProperty); 510e0dac50fSopenharmony_ci} 511e0dac50fSopenharmony_ci 512e0dac50fSopenharmony_ciconst sptr<MoveDragProperty>& MoveDragController::GetMoveDragProperty() const 513e0dac50fSopenharmony_ci{ 514e0dac50fSopenharmony_ci return moveDragProperty_; 515e0dac50fSopenharmony_ci} 516e0dac50fSopenharmony_ci 517e0dac50fSopenharmony_ciconst sptr<WindowProperty>& MoveDragController::GetWindowProperty() const 518e0dac50fSopenharmony_ci{ 519e0dac50fSopenharmony_ci return windowProperty_; 520e0dac50fSopenharmony_ci} 521e0dac50fSopenharmony_ci 522e0dac50fSopenharmony_civoid MoveDragController::ResetMoveOrDragState() 523e0dac50fSopenharmony_ci{ 524e0dac50fSopenharmony_ci activeWindowId_ = INVALID_WINDOW_ID; 525e0dac50fSopenharmony_ci auto moveDragProperty = new MoveDragProperty(); 526e0dac50fSopenharmony_ci SetDragProperty(moveDragProperty); 527e0dac50fSopenharmony_ci} 528e0dac50fSopenharmony_ci 529e0dac50fSopenharmony_civoid MoveDragController::SetActiveWindowId(uint32_t activeWindowId) 530e0dac50fSopenharmony_ci{ 531e0dac50fSopenharmony_ci activeWindowId_ = activeWindowId; 532e0dac50fSopenharmony_ci} 533e0dac50fSopenharmony_ci 534e0dac50fSopenharmony_ciuint32_t MoveDragController::GetActiveWindowId() const 535e0dac50fSopenharmony_ci{ 536e0dac50fSopenharmony_ci return activeWindowId_; 537e0dac50fSopenharmony_ci} 538e0dac50fSopenharmony_ci 539e0dac50fSopenharmony_cistd::shared_ptr<VsyncStation> MoveDragController::GetVsyncStationByWindowId(uint32_t windowId) 540e0dac50fSopenharmony_ci{ 541e0dac50fSopenharmony_ci { 542e0dac50fSopenharmony_ci std::lock_guard<std::mutex> lock(mtx_); 543e0dac50fSopenharmony_ci auto iter = vsyncStationMap_.find(windowId); 544e0dac50fSopenharmony_ci if (iter != vsyncStationMap_.end()) { 545e0dac50fSopenharmony_ci return iter->second; 546e0dac50fSopenharmony_ci } 547e0dac50fSopenharmony_ci } 548e0dac50fSopenharmony_ci 549e0dac50fSopenharmony_ci if (windowRoot_ == nullptr) { 550e0dac50fSopenharmony_ci TLOGE(WmsLogTag::WMS_MAIN, "Get vsync station failed, windowRoot is nullptr"); 551e0dac50fSopenharmony_ci return nullptr; 552e0dac50fSopenharmony_ci } 553e0dac50fSopenharmony_ci 554e0dac50fSopenharmony_ci sptr<WindowNode> node = windowRoot_->GetWindowNode(windowId); 555e0dac50fSopenharmony_ci if (node == nullptr || node->surfaceNode_ == nullptr) { 556e0dac50fSopenharmony_ci TLOGE(WmsLogTag::WMS_MAIN, "Get vsync station failed, surfaceNode is nullptr"); 557e0dac50fSopenharmony_ci return nullptr; 558e0dac50fSopenharmony_ci } 559e0dac50fSopenharmony_ci 560e0dac50fSopenharmony_ci auto vsyncStation = std::make_shared<VsyncStation>(node->surfaceNode_->GetId(), inputEventHandler_); 561e0dac50fSopenharmony_ci if (vsyncStation == nullptr) { 562e0dac50fSopenharmony_ci TLOGE(WmsLogTag::WMS_MAIN, "Get vsync station failed, create vsyncStation is nullptr"); 563e0dac50fSopenharmony_ci return nullptr; 564e0dac50fSopenharmony_ci } 565e0dac50fSopenharmony_ci 566e0dac50fSopenharmony_ci { 567e0dac50fSopenharmony_ci std::lock_guard<std::mutex> lock(mtx_); 568e0dac50fSopenharmony_ci vsyncStationMap_.emplace(windowId, vsyncStation); 569e0dac50fSopenharmony_ci } 570e0dac50fSopenharmony_ci 571e0dac50fSopenharmony_ci return vsyncStation; 572e0dac50fSopenharmony_ci} 573e0dac50fSopenharmony_ci} 574e0dac50fSopenharmony_ci} 575