From 73dbc77c53e63b32a604eb63515cffdcef577b73 Mon Sep 17 00:00:00 2001 From: xiaojianfeng Date: Wed, 6 Jul 2022 16:27:52 +0800 Subject: [PATCH] resize float calling window when call soft input Signed-off-by: xiaojianfeng Change-Id: I816cda27a3e1ec9f3f7ddc0470198dd4b606afaf --- wmserver/include/window_controller.h | 4 ++ wmserver/src/avoid_area_controller.cpp | 5 +- wmserver/src/window_controller.cpp | 79 +++++++++++++++++++++++++- wmserver/src/window_node_container.cpp | 2 +- 4 files changed, 83 insertions(+), 7 deletions(-) diff --git a/wmserver/include/window_controller.h b/wmserver/include/window_controller.h index 83526c1f..beb2a566 100644 --- a/wmserver/include/window_controller.h +++ b/wmserver/include/window_controller.h @@ -78,6 +78,8 @@ private: WMError ResizeRect(uint32_t windowId, const Rect& rect, WindowSizeChangeReason reason); WMError SetWindowMode(uint32_t windowId, WindowMode dstMode); void ResizeSystemBarPropertySizeIfNeed(const sptr& node); + void ResizeSoftInputCallingWindowIfNeed(const sptr& node); + void RestoreCallingWindowSizeIfNeed(); void HandleTurnScreenOn(const sptr& node); void ProcessSystemBarChange(const sptr& displayInfo); WMError UpdateTouchHotAreas(const sptr& node, const std::vector& rects); @@ -93,6 +95,8 @@ private: { WindowType::WINDOW_TYPE_NAVIGATION_BAR, INVALID_WINDOW_ID }, }; bool isScreenLocked_ { false }; + Rect callingWindowRestoringRect_ { 0, 0, 0, 0 }; + uint32_t callingWindowId_ = 0u; }; } // Rosen } // OHOS diff --git a/wmserver/src/avoid_area_controller.cpp b/wmserver/src/avoid_area_controller.cpp index 40a8869f..b5c3d5c8 100644 --- a/wmserver/src/avoid_area_controller.cpp +++ b/wmserver/src/avoid_area_controller.cpp @@ -122,7 +122,7 @@ void AvoidAreaController::AddOrRemoveKeyboard(const sptr& keyboardNo if (lastKeyboardAreaUpdatedWindow != nullptr && lastKeyboardAreaUpdatedWindow != callingWindow) { const WindowMode windowMode = lastKeyboardAreaUpdatedWindow->GetWindowMode(); if (windowMode == WindowMode::WINDOW_MODE_FULLSCREEN || windowMode == WindowMode::WINDOW_MODE_SPLIT_PRIMARY || - windowMode == WindowMode::WINDOW_MODE_SPLIT_SECONDARY || windowMode == WindowMode::WINDOW_MODE_FLOATING) { + windowMode == WindowMode::WINDOW_MODE_SPLIT_SECONDARY) { auto avoidArea = GetAvoidAreaByType(lastKeyboardAreaUpdatedWindow, AvoidAreaType::TYPE_KEYBOARD); UpdateAvoidAreaIfNeed(avoidArea, lastKeyboardAreaUpdatedWindow, AvoidAreaType::TYPE_KEYBOARD); } @@ -135,8 +135,7 @@ void AvoidAreaController::AddOrRemoveKeyboard(const sptr& keyboardNo const WindowMode callingWindowMode = callingWindow->GetWindowMode(); if (callingWindowMode == WindowMode::WINDOW_MODE_FULLSCREEN || callingWindowMode == WindowMode::WINDOW_MODE_SPLIT_PRIMARY || - callingWindowMode == WindowMode::WINDOW_MODE_SPLIT_SECONDARY || - callingWindowMode == WindowMode::WINDOW_MODE_FLOATING) { + callingWindowMode == WindowMode::WINDOW_MODE_SPLIT_SECONDARY) { auto avoidArea = GetAvoidAreaByType(callingWindow, AvoidAreaType::TYPE_KEYBOARD); bool res = UpdateAvoidAreaIfNeed(avoidArea, callingWindow, AvoidAreaType::TYPE_KEYBOARD); if (res) { diff --git a/wmserver/src/window_controller.cpp b/wmserver/src/window_controller.cpp index 12379fe7..bcfe6aac 100644 --- a/wmserver/src/window_controller.cpp +++ b/wmserver/src/window_controller.cpp @@ -235,11 +235,67 @@ WMError WindowController::AddWindowNode(sptr& property) sysBarWinId_[node->GetWindowType()] = node->GetWindowId(); ResizeSystemBarPropertySizeIfNeed(node); } + if (node->GetWindowType() == WindowType::WINDOW_TYPE_INPUT_METHOD_FLOAT) { + ResizeSoftInputCallingWindowIfNeed(node); + } StopBootAnimationIfNeed(node->GetWindowType()); MinimizeApp::ExecuteMinimizeAll(); return WMError::WM_OK; } +void WindowController::ResizeSoftInputCallingWindowIfNeed(const sptr& node) +{ + auto callingWindowId = node->GetCallingWindow(); + auto callingWindow = windowRoot_->GetWindowNode(callingWindowId); + if (callingWindow == nullptr) { + auto windowNodeContainer = windowRoot_->GetOrCreateWindowNodeContainer(node->GetDisplayId()); + if (windowNodeContainer == nullptr) { + WLOGFE("windowNodeContainer is null, displayId:%{public}" PRIu64"", node->GetDisplayId()); + return; + } + callingWindowId = windowNodeContainer->GetFocusWindow(); + callingWindow = windowRoot_->GetWindowNode(callingWindowId); + } + if (callingWindow == nullptr || !callingWindow->currentVisibility_ || + callingWindow->GetWindowMode() != WindowMode::WINDOW_MODE_FLOATING) { + WLOGFE("callingWindow is null or invisible or not float window, callingWindowId:%{public}u", callingWindowId); + return; + } + Rect softInputWindowRect = node->GetWindowRect(); + Rect callingWindowRect = callingWindow->GetWindowRect(); + Rect rect = WindowHelper::GetOverlap(softInputWindowRect, callingWindowRect, 0, 0); + if (WindowHelper::IsEmptyRect(rect)) { + WLOGFE("there is no overlap"); + return; + } + Rect requestedRect = callingWindowRect; + requestedRect.posY_ = softInputWindowRect.posY_ - static_cast(requestedRect.height_); + Rect statusBarWindowRect = { 0, 0, 0, 0 }; + auto statusbarWindow = windowRoot_->GetWindowNode(sysBarWinId_[WindowType::WINDOW_TYPE_STATUS_BAR]); + if (statusbarWindow != nullptr && statusbarWindow->parent_ != nullptr) { + statusBarWindowRect = statusbarWindow->GetWindowRect(); + } + int32_t posY = std::max(requestedRect.posY_, static_cast(statusBarWindowRect.height_)); + if (posY != requestedRect.posY_) { + requestedRect.height_ = softInputWindowRect.posY_ - posY; + requestedRect.posY_ = posY; + } + callingWindowRestoringRect_ = callingWindowRect; + callingWindowId_ = callingWindow->GetWindowId(); + ResizeRect(callingWindowId_, requestedRect, WindowSizeChangeReason::DRAG); +} + +void WindowController::RestoreCallingWindowSizeIfNeed() +{ + auto callingWindow = windowRoot_->GetWindowNode(callingWindowId_); + if (!WindowHelper::IsEmptyRect(callingWindowRestoringRect_) && callingWindow != nullptr && + callingWindow->GetWindowMode() == WindowMode::WINDOW_MODE_FLOATING) { + ResizeRect(callingWindowId_, callingWindowRestoringRect_, WindowSizeChangeReason::DRAG); + } + callingWindowRestoringRect_ = { 0, 0, 0, 0 }; + callingWindowId_ = 0u; +} + void WindowController::ResizeSystemBarPropertySizeIfNeed(const sptr& node) { auto displayInfo = DisplayManagerServiceInner::GetInstance().GetDisplayById(node->GetDisplayId()); @@ -292,14 +348,20 @@ WMError WindowController::RemoveWindowNode(uint32_t windowId) return res; }; auto windowNode = windowRoot_->GetWindowNode(windowId); + WMError res = WMError::WM_ERROR_NO_REMOTE_ANIMATION; if (windowNode && windowNode->GetWindowType() == WindowType::WINDOW_TYPE_KEYGUARD) { if (RemoteAnimation::NotifyAnimationScreenUnlock(removeFunc) == WMError::WM_OK) { WLOGFI("NotifyAnimationScreenUnlock with remote animation"); - return WMError::WM_OK; + res = WMError::WM_OK; } } - - return removeFunc(); + if (res != WMError::WM_OK) { + res = removeFunc(); + } + if (windowNode->GetWindowType() == WindowType::WINDOW_TYPE_INPUT_METHOD_FLOAT) { + RestoreCallingWindowSizeIfNeed(); + } + return res; } WMError WindowController::DestroyWindow(uint32_t windowId, bool onlySelf) @@ -746,6 +808,17 @@ WMError WindowController::UpdateProperty(sptr& property, Propert node->SetOriginRect(property->GetOriginRect()); node->SetDragType(property->GetDragType()); ret = ResizeRect(windowId, property->GetRequestRect(), property->GetWindowSizeChangeReason()); + if (node->GetWindowMode() == WindowMode::WINDOW_MODE_FLOATING && ret == WMError::WM_OK && + callingWindowId_ != 0u && !WindowHelper::IsEmptyRect(callingWindowRestoringRect_)) { + if (property->GetWindowSizeChangeReason() != WindowSizeChangeReason::MOVE) { + callingWindowId_ = 0u; + callingWindowRestoringRect_ = { 0, 0, 0, 0 }; + } else { + auto windowRect = node->GetWindowRect(); + callingWindowRestoringRect_.posX_ = windowRect.posX_; + callingWindowRestoringRect_.posY_ = windowRect.posY_; + } + } break; } case PropertyChangeAction::ACTION_UPDATE_MODE: { diff --git a/wmserver/src/window_node_container.cpp b/wmserver/src/window_node_container.cpp index cb94d529..8b545c9e 100644 --- a/wmserver/src/window_node_container.cpp +++ b/wmserver/src/window_node_container.cpp @@ -1398,7 +1398,7 @@ WMError WindowNodeContainer::ToggleShownStateForAllAppWindows( if (node->GetWindowType() == WindowType::WINDOW_TYPE_LAUNCHER_RECENT) { recentWindowNode = node; if (node->GetWindowMode() == WindowMode::WINDOW_MODE_FULLSCREEN) { - return WMError::WM_OK; + return WMError::WM_DO_NOTHING; } } }