From 4282a629efd296e56b1a1ea4aa2d4001139a17bf Mon Sep 17 00:00:00 2001 From: l00574490 Date: Tue, 27 Sep 2022 14:54:55 +0800 Subject: [PATCH] modify layout Signed-off-by: l00574490 Change-Id: Ib14f71f59de6af9147bd09ed9bacf11166d7fd2c --- wmserver/include/display_group_controller.h | 7 +- wmserver/include/window_controller.h | 1 - wmserver/include/window_layout_policy.h | 105 +-- .../include/window_layout_policy_cascade.h | 56 +- wmserver/include/window_layout_policy_tile.h | 37 +- wmserver/include/window_node_container.h | 5 +- wmserver/include/window_pair.h | 28 + wmserver/src/display_group_controller.cpp | 102 ++- wmserver/src/window_controller.cpp | 34 +- wmserver/src/window_layout_policy.cpp | 209 ++---- wmserver/src/window_layout_policy_cascade.cpp | 617 +++++++----------- wmserver/src/window_layout_policy_tile.cpp | 343 +++++----- wmserver/src/window_node_container.cpp | 54 +- wmserver/src/window_pair.cpp | 37 ++ wmserver/src/window_root.cpp | 11 +- 15 files changed, 777 insertions(+), 869 deletions(-) diff --git a/wmserver/include/display_group_controller.h b/wmserver/include/display_group_controller.h index 85d9bb8c77..807136a2ea 100644 --- a/wmserver/include/display_group_controller.h +++ b/wmserver/include/display_group_controller.h @@ -54,7 +54,7 @@ public: const std::map& displayRectMap, DisplayStateChangeType type); sptr GetWindowPairByDisplayId(DisplayId displayId); - void SetDividerRect(DisplayId displayId, const Rect& rect); + void SetSplitRatioConfig(const SplitRatioConfig& splitRatioConfig); DisplayGroupWindowTree displayGroupWindowTree_; std::map sysBarNodeMaps_; @@ -74,7 +74,10 @@ private: void UpdateWindowDisplayId(const sptr& node, DisplayId newDisplayId); void ClearMapOfDestroyedDisplay(DisplayId displayId); void ChangeToRectInDisplayGroup(const sptr& node, DisplayId displayId); - void UpdateNodeSizeChangeReasonWithRotation(DisplayId displayId); + void UpdateNodeSizeChangeReasonWithRotation(DisplayId displayId, const std::map& displayRectMap); + void ProcessWindowPairWhenDisplayChange(bool rotateDisplay = false); + void UpdateSplitRatioPoints(DisplayId displayId); + void ProcessSystemBarRotation(const sptr& node, const std::map& displayRectMap); sptr windowNodeContainer_; sptr displayGroupInfo_; diff --git a/wmserver/include/window_controller.h b/wmserver/include/window_controller.h index f39307529e..2c37fe5b74 100644 --- a/wmserver/include/window_controller.h +++ b/wmserver/include/window_controller.h @@ -99,7 +99,6 @@ private: 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); WMError UpdateTransform(uint32_t windowId); void NotifyTouchOutside(const sptr& node); diff --git a/wmserver/include/window_layout_policy.h b/wmserver/include/window_layout_policy.h index cece88969d..e6bc88d244 100644 --- a/wmserver/include/window_layout_policy.h +++ b/wmserver/include/window_layout_policy.h @@ -43,53 +43,60 @@ public: WindowLayoutPolicy(const sptr& displayGroupInfo, DisplayGroupWindowTree& displayGroupWindowTree); ~WindowLayoutPolicy() = default; virtual void Launch(); - virtual void Clean(); - virtual void Reset(); virtual void Reorder(); - virtual void AddWindowNode(const sptr& node) = 0; - virtual void LayoutWindowTree(DisplayId displayId); - virtual void RemoveWindowNode(const sptr& node); - virtual void UpdateWindowNode(const sptr& node, bool isAddWindow = false); - virtual void UpdateLayoutRect(const sptr& node) = 0; - virtual void SetSplitDividerWindowRects(std::map dividerWindowRects) {}; - virtual Rect GetDividerRect(DisplayId displayId) const; - virtual std::vector GetExitSplitPoints(DisplayId displayId) const; - float GetVirtualPixelRatio(DisplayId displayId) const; - void UpdateClientRectAndResetReason(const sptr& node, const Rect& winRect); - void UpdateClientRect(const Rect& rect, const sptr& node, WindowSizeChangeReason reason); - Rect GetDisplayGroupRect() const; - bool IsMultiDisplay(); + virtual void PerformWindowLayout(const sptr& node, WindowUpdateType type) = 0; void ProcessDisplayCreate(DisplayId displayId, const std::map& displayRectMap); void ProcessDisplayDestroy(DisplayId displayId, const std::map& displayRectMap); void ProcessDisplaySizeChangeOrRotation(DisplayId displayId, const std::map& displayRectMap); - void SetSplitRatioConfig(const SplitRatioConfig& splitRatioConfig); + void ProcessDisplayVprChange(DisplayId displayId); + + virtual void SetSplitDividerWindowRects(std::map dividerWindowRects) {}; + virtual Rect GetDividerRect(DisplayId displayId) const; virtual bool IsTileRectSatisfiedWithSizeLimits(const sptr& node); + bool IsMultiDisplay(); + Rect GetDisplayGroupRect() const; + void SetSplitRatioPoints(DisplayId displayId, const std::vector& splitRatioPoints); + void NotifyClientAndAnimation(const sptr& node, const Rect& winRect, WindowSizeChangeReason reason); protected: - void UpdateFloatingLayoutRect(Rect& limitRect, Rect& winRect); - void UpdateLimitRect(const sptr& node, Rect& limitRect); - virtual void LayoutWindowNode(const sptr& node); + /* + * methods for calculate window rect + */ + virtual void UpdateLayoutRect(const sptr& node) = 0; + void LayoutWindowTree(DisplayId displayId); + void LayoutWindowNode(const sptr& node); + void LayoutWindowNodesByRootType(const std::vector>& nodeVec); + + /* + * methods for get/update display information or limit information + */ AvoidPosType GetAvoidPosType(const Rect& rect, DisplayId displayId) const; - void CalcAndSetNodeHotZone(const Rect& winRect, const sptr& node) const; - void ComputeDecoratedRequestRect(const sptr& node) const; + void UpdateDisplayLimitRect(const sptr& node, Rect& limitRect); bool IsVerticalDisplay(DisplayId displayId) const; bool IsFullScreenRecentWindowExist(const std::vector>& nodeVec) const; - void LayoutWindowNodesByRootType(const std::vector>& nodeVec); - virtual void UpdateSurfaceBounds(const sptr& node, const Rect& winRect, const Rect& preRect); - void UpdateRectInDisplayGroupForAllNodes(DisplayId displayId, - const Rect& oriDisplayRect, const Rect& newDisplayRect); - void UpdateRectInDisplayGroup(const sptr& node, - const Rect& oriDisplayRect, const Rect& newDisplayRect); - void LimitWindowToBottomRightCorner(const sptr& node); + void UpdateWindowSizeLimits(const sptr& node); + WindowSizeLimits GetSystemSizeLimits(const sptr& node, const Rect& displayRect, float vpr); + + /* + * methods for multiDisplay + */ + void UpdateMultiDisplayFlag(); void UpdateDisplayGroupRect(); void UpdateDisplayGroupLimitRect(); - void UpdateMultiDisplayFlag(); void PostProcessWhenDisplayChange(); + void LimitWindowToBottomRightCorner(const sptr& node); + void UpdateRectInDisplayGroupForAllNodes(DisplayId displayId, const Rect& oriDisplayRect, + const Rect& newDisplayRect); + void UpdateRectInDisplayGroup(const sptr& node, const Rect& oriDisplayRect, + const Rect& newDisplayRect); void UpdateDisplayRectAndDisplayGroupInfo(const std::map& displayRectMap); + + /* + * methods for floating window limitSize and position + */ DockWindowShowState GetDockWindowShowState(DisplayId displayId, Rect& dockWinRect) const; void LimitFloatingWindowSize(const sptr& node, const Rect& displayRect, Rect& winRect) const; void LimitMainFloatingWindowPosition(const sptr& node, Rect& winRect) const; - void UpdateFloatingWindowSizeForStretchableWindow(const sptr& node, const Rect& displayRect, Rect& winRect) const; void UpdateFloatingWindowSizeBySizeLimits(const sptr& node, @@ -97,33 +104,27 @@ protected: void LimitWindowPositionWhenInitRectOrMove(const sptr& node, Rect& winRect) const; void LimitWindowPositionWhenDrag(const sptr& node, Rect& winRect) const; void FixWindowSizeByRatioIfDragBeyondLimitRegion(const sptr& node, Rect& winRect); - void UpdateWindowSizeLimits(const sptr& node); - WindowSizeLimits GetSystemSizeLimits(const sptr& node, - const Rect& displayRect, float virtualPixelRatio); + + /* + * methods for update node latest information, include: + * 1. notify client and animation + * 2. update hot zone + * 3. update surface bounds + */ + void NotifyAnimationSizeChangeIfNeeded(); + void CalcAndSetNodeHotZone(const Rect& winRect, const sptr& node) const; Rect CalcEntireWindowHotZone(const sptr& node, const Rect& winRect, uint32_t hotZone, float vpr, TransformHelper::Vector2 hotZoneScale) const; - void NotifyAnimationSizeChangeIfNeeded(); - const std::set avoidTypes_ { - WindowType::WINDOW_TYPE_STATUS_BAR, - WindowType::WINDOW_TYPE_NAVIGATION_BAR, - }; - struct LayoutRects { - Rect primaryRect_; - Rect secondaryRect_; - Rect primaryLimitRect_; - Rect secondaryLimitRect_; - Rect dividerRect_; - Rect firstCascadeRect_; - std::vector exitSplitPoints_; // 2 element, first element < second element - std::vector splitRatioPoints_; - }; - sptr displayGroupInfo_; - mutable std::map limitRectMap_; - DisplayGroupWindowTree& displayGroupWindowTree_; + void UpdateSurfaceBounds(const sptr& node, const Rect& winRect, const Rect& preRect); + Rect displayGroupRect_; Rect displayGroupLimitRect_; bool isMultiDisplay_ = false; - SplitRatioConfig splitRatioConfig_; + sptr displayGroupInfo_; + mutable std::map limitRectMap_; + DisplayGroupWindowTree& displayGroupWindowTree_; + std::map restoringDividerWindowRects_; + mutable std::map> splitRatioPointsMap_; }; } } diff --git a/wmserver/include/window_layout_policy_cascade.h b/wmserver/include/window_layout_policy_cascade.h index 48bd4ef2e7..758ac2e88c 100644 --- a/wmserver/include/window_layout_policy_cascade.h +++ b/wmserver/include/window_layout_policy_cascade.h @@ -33,50 +33,46 @@ public: DisplayGroupWindowTree& displayGroupWindowTree); ~WindowLayoutPolicyCascade() = default; void Launch() override; - void Clean() override; - void Reset() override; void Reorder() override; - void AddWindowNode(const sptr& node) override; - void UpdateWindowNode(const sptr& node, bool isAddWindow = false) override; - void UpdateLayoutRect(const sptr& node) override; - void SetSplitDividerWindowRects(std::map dividerWindowRects) override; - void RemoveWindowNode(const sptr& node) override; Rect GetDividerRect(DisplayId displayId) const override; - std::vector GetExitSplitPoints(DisplayId displayId) const override; + void SetSplitDividerWindowRects(std::map dividerWindowRects) override; + void PerformWindowLayout(const sptr& node, WindowUpdateType updateType) override; private: + /* + * methods for calculate cascadeRect and splitRect + */ void InitAllRects(); void InitSplitRects(DisplayId displayId); - int32_t GetSplitRatioPoint(float ratio, DisplayId displayId); - void SetSplitRect(const Rect& rect, DisplayId displayId); - void UpdateSplitLimitRect(const Rect& limitRect, Rect& limitSplitRect); - void UpdateSplitRatioPoints(DisplayId displayId); - void UpdateDockSlicePosition(DisplayId displayId, int32_t& origin) const; - void LayoutWindowNode(const sptr& node) override; - void LayoutWindowTree(DisplayId displayId) override; - void InitLimitRects(DisplayId displayId); - void LimitDividerMoveBounds(Rect& rect, DisplayId displayId) const; + void SetSplitRectByDivider(const Rect& divRect, DisplayId displayId); + void SetInitialDividerRect(const sptr& node, DisplayId displayId); void InitCascadeRect(DisplayId displayId); - void SetCascadeRect(const sptr& node); - void ApplyWindowRectConstraints(const sptr& node, Rect& winRect) const; - void UpdateWindowNodeRectOffset(const sptr& node) const; - bool SpecialReasonProcess(const sptr& node) const; - - Rect GetRectByWindowMode(const WindowMode& mode) const; - Rect GetLimitRect(const WindowMode mode, DisplayId displayId) const; - Rect GetDisplayRect(const WindowMode mode, DisplayId displayId) const; - Rect GetCurCascadeRect(const sptr& node) const; + void SetDefaultCascadeRect(const sptr& node); Rect StepCascadeRect(Rect rect, DisplayId displayId) const; + Rect GetCurCascadeRect(const sptr& node) const; + + // methods for limit divider position by display and split ratio + void UpdateDividerPosition(const sptr& node) const; + void LimitDividerInDisplayRegion(Rect& rect, DisplayId displayId) const; + void LimitDividerPositionBySplitRatio(DisplayId displayId, Rect& winRect) const; + + /* + * methods for calculate window rect + */ + void LayoutDivider(const sptr& node, WindowUpdateType type); + void LayoutSplitNodes(DisplayId displayId, WindowUpdateType type, bool layoutByDivider = false); + void UpdateLayoutRect(const sptr& node) override; + void FixWindowRectWithinDisplay(const sptr& node) const; + void ComputeDecoratedRequestRect(const sptr& node) const; + void ApplyWindowRectConstraints(const sptr& node, Rect& winRect) const; struct CascadeRects { Rect primaryRect_; Rect secondaryRect_; - Rect primaryLimitRect_; - Rect secondaryLimitRect_; Rect dividerRect_; - Rect firstCascadeRect_; + Rect defaultCascadeRect_; }; - mutable std::map cascadeRectsMap_; + mutable std::map cascadeRectsMap_; std::map restoringDividerWindowRects_; }; } diff --git a/wmserver/include/window_layout_policy_tile.h b/wmserver/include/window_layout_policy_tile.h index 7e8da0675f..093b4b6ff5 100644 --- a/wmserver/include/window_layout_policy_tile.h +++ b/wmserver/include/window_layout_policy_tile.h @@ -34,24 +34,37 @@ public: DisplayGroupWindowTree& displayGroupWindowTree); ~WindowLayoutPolicyTile() = default; void Launch() override; - void AddWindowNode(const sptr& node) override; - void UpdateWindowNode(const sptr& node, bool isAddWindow = false) override; - void RemoveWindowNode(const sptr& node) override; - void UpdateLayoutRect(const sptr& node) override; bool IsTileRectSatisfiedWithSizeLimits(const sptr& node) override; + void PerformWindowLayout(const sptr& node, WindowUpdateType type) override; private: + /* + * methods for calculate maxTileNum and preset tileRects + */ + void InitTileRects(DisplayId displayId); + uint32_t GetMaxTileWinNum(DisplayId displayId) const; + + /* + * methods for update tile queue + */ + void InitTileQueue(DisplayId displayId); + void LayoutTileQueue(DisplayId displayId); + void RefreshTileQueue(DisplayId displayId, std::vector>& needMinimizeNodes, + std::vector>& needRecoverNodes); + void PushBackNodeInTileQueue(const sptr& node, DisplayId displayId); + void RemoveNodeFromTileQueue(const sptr& node); + + /* + * methods for calculate tile window rect + */ + void ApplyPresetRectForTileWindows(DisplayId displayId); + void UpdateLayoutRect(const sptr& node) override; + bool IsWindowAlreadyInTileQueue(const sptr& node); + bool IsValidTileQueueAndPresetRects(DisplayId displayId); + std::map maxTileWinNumMap_; std::map>> presetRectsMap_; std::map>> foregroundNodesMap_; - void InitAllRects(); - uint32_t GetMaxTileWinNum(DisplayId displayId) const; - void InitTileWindowRects(DisplayId displayId); - void AssignNodePropertyForTileWindows(DisplayId displayId); - void LayoutForegroundNodeQueue(DisplayId displayId); - void InitForegroundNodeQueue(); - void ForegroundNodeQueuePushBack(const sptr& node, DisplayId displayId); - void ForegroundNodeQueueRemove(const sptr& node); }; } } diff --git a/wmserver/include/window_node_container.h b/wmserver/include/window_node_container.h index eab4da0af5..9997eed89b 100644 --- a/wmserver/include/window_node_container.h +++ b/wmserver/include/window_node_container.h @@ -83,7 +83,6 @@ public: WMError SetWindowMode(sptr& node, WindowMode dstMode); WMError SwitchLayoutPolicy(WindowLayoutMode mode, DisplayId displayId, bool reorder = false); void RaiseSplitRelatedWindowToTop(sptr& node); - float GetVirtualPixelRatio(DisplayId displayId) const; Rect GetDisplayGroupRect() const; void TraverseWindowTree(const WindowNodeOperationFunc& func, bool isFromTopToBottom = true) const; void UpdateSizeChangeReason(sptr& node, WindowSizeChangeReason reason); @@ -106,7 +105,7 @@ public: sptr GetLayoutPolicy() const; sptr GetAvoidController() const; - sptr GetMultiDisplayController() const; + sptr GetDisplayGroupController() const; sptr GetRootNode(WindowRootNodeType type) const; void NotifyDockWindowStateChanged(sptr& node, bool isEnable); void UpdateCameraFloatWindowStatus(const sptr& node, bool isShowing); @@ -140,7 +139,6 @@ private: bool IsTopWindow(uint32_t windowId, sptr& rootNode) const; sptr FindDividerNode() const; void RaiseWindowToTop(uint32_t windowId, std::vector>& windowNodes); - void ResetLayoutPolicy(); bool IsAboveSystemBarNode(sptr node) const; bool IsSplitImmersiveNode(sptr node) const; bool TraverseFromTopToBottom(sptr node, const WindowNodeOperationFunc& func) const; @@ -172,6 +170,7 @@ private: std::map backupWindowMode_; std::map backupDividerWindowRect_; std::map> backupDisplaySplitWindowMode_; + sptr zorderPolicy_ = new WindowZorderPolicy(); std::unordered_map> layoutPolicies_; WindowLayoutMode layoutMode_ = WindowLayoutMode::CASCADE; diff --git a/wmserver/include/window_pair.h b/wmserver/include/window_pair.h index 1d4606ca6a..d00e520c7f 100644 --- a/wmserver/include/window_pair.h +++ b/wmserver/include/window_pair.h @@ -179,6 +179,26 @@ public: */ void ClearPairSnapshot(); + /** + * @brief Set split ratio config. + */ + void SetSplitRatioConfig(const SplitRatioConfig& splitRatioConfig); + + /** + * @brief Calculate split ratio points. + */ + void CalculateSplitRatioPoints(const Rect& displayRect); + + /** + * @brief Get exit split points. + */ + std::vector GetExitSplitPoints(); + + /** + * @brief Get split ratio points. + */ + std::vector GetSplitRatioPoints(); + private: /** * @brief Gets whether the window is related to split window. @@ -242,6 +262,11 @@ private: */ void NotifyCreateOrDestroyDivider(sptr node, bool isDestroy); + /** + * @brief Calculate and Get split ratio point + */ + int32_t GetSplitRatioPoint(float ratio, const Rect& displayRect); + private: float ratio_ = DEFAULT_SPLIT_RATIO; DisplayId displayId_; @@ -250,6 +275,9 @@ private: sptr divider_; WindowPairStatus status_ = {WindowPairStatus::STATUS_EMPTY}; Rect dividerRect_ {0, 0, 0, 0}; + std::vector exitSplitPoints_; // 2 element, first element < second element + std::vector splitRatioPoints_; + SplitRatioConfig splitRatioConfig_; DEFINE_VAR_DEFAULT_FUNC_SET(bool, AllSplitAppWindowsRestoring, isAllSplitAppWindowsRestoring, false) }; } // namespace Rosen diff --git a/wmserver/src/display_group_controller.cpp b/wmserver/src/display_group_controller.cpp index 1ecd47b0fa..0f766243ad 100644 --- a/wmserver/src/display_group_controller.cpp +++ b/wmserver/src/display_group_controller.cpp @@ -14,6 +14,7 @@ */ #include "display_group_controller.h" +#include "window_helper.h" #include "window_inner_manager.h" #include "window_manager_hilog.h" #include "window_node_container.h" @@ -393,9 +394,11 @@ void DisplayGroupController::ProcessDisplayCreate(DisplayId defaultDisplayId, sp ProcessCrossNodes(defaultDisplayId, DisplayStateChangeType::CREATE); UpdateDisplayGroupWindowTree(); const auto& layoutPolicy = windowNodeContainer_->GetLayoutPolicy(); + if (layoutPolicy == nullptr) { + return; + } layoutPolicy->ProcessDisplayCreate(displayId, displayRectMap); - Rect initialDividerRect = layoutPolicy->GetDividerRect(displayId); - SetDividerRect(displayId, initialDividerRect); + ProcessWindowPairWhenDisplayChange(); } void DisplayGroupController::ProcessDisplayDestroy(DisplayId defaultDisplayId, sptr displayInfo, @@ -412,9 +415,31 @@ void DisplayGroupController::ProcessDisplayDestroy(DisplayId defaultDisplayId, s UpdateDisplayGroupWindowTree(); ClearMapOfDestroyedDisplay(displayId); windowNodeContainer_->GetLayoutPolicy()->ProcessDisplayDestroy(displayId, displayRectMap); + ProcessWindowPairWhenDisplayChange(); +} + +void DisplayGroupController::ProcessSystemBarRotation(const sptr& node, + const std::map& displayRectMap) +{ + auto rect = node->GetWindowRect(); + auto displayId = node->GetDisplayId(); + auto iter = displayRectMap.find(displayId); + if (iter == displayRectMap.end()) { + return; + } + auto displayRect = iter->second; + if (node->GetWindowType() == WindowType::WINDOW_TYPE_STATUS_BAR) { + rect.width_ = displayRect.width_; + } else if (node->GetWindowType() == WindowType::WINDOW_TYPE_NAVIGATION_BAR) { + rect.posY_ = static_cast(displayRect.height_ - rect.height_); + rect.width_ = displayRect.width_; + } + + node->SetRequestRect(rect); } -void DisplayGroupController::UpdateNodeSizeChangeReasonWithRotation(DisplayId displayId) +void DisplayGroupController::UpdateNodeSizeChangeReasonWithRotation(DisplayId displayId, + const std::map& displayRectMap) { std::vector rootNodeType = { WindowRootNodeType::ABOVE_WINDOW_NODE, @@ -432,6 +457,9 @@ void DisplayGroupController::UpdateNodeSizeChangeReasonWithRotation(DisplayId di if (node->GetWindowType() == WindowType::WINDOW_TYPE_DOCK_SLICE) { continue; } + if (WindowHelper::IsSystemBarWindow(node->GetWindowType())) { + ProcessSystemBarRotation(node, displayRectMap); + } node->SetWindowSizeChangeReason(WindowSizeChangeReason::ROTATION); } } @@ -456,7 +484,7 @@ void DisplayGroupController::ProcessDisplayChange(DisplayId defaultDisplayId, sp } case DisplayStateChangeType::VIRTUAL_PIXEL_RATIO_CHANGE: { displayGroupInfo_->SetDisplayVirtualPixelRatio(displayId, displayInfo->GetVirtualPixelRatio()); - windowNodeContainer_->GetLayoutPolicy()->LayoutWindowTree(displayId); + windowNodeContainer_->GetLayoutPolicy()->ProcessDisplayVprChange(displayId); break; } default: { @@ -471,17 +499,14 @@ void DisplayGroupController::ProcessDisplaySizeChangeOrRotation(DisplayId defaul // modify RSTree and window tree of displayGroup for cross-display nodes ProcessCrossNodes(defaultDisplayId, type); UpdateDisplayGroupWindowTree(); + // update reason after process cross Nodes to get correct display attribution + UpdateNodeSizeChangeReasonWithRotation(displayId, displayRectMap); const auto& layoutPolicy = windowNodeContainer_->GetLayoutPolicy(); if (layoutPolicy == nullptr) { return; } - // update reason after process cross Nodes to get correct display attribution - UpdateNodeSizeChangeReasonWithRotation(displayId); layoutPolicy->ProcessDisplaySizeChangeOrRotation(displayId, displayRectMap); - Rect curDividerRect = layoutPolicy->GetDividerRect(displayId); - if (windowPairMap_[displayId] != nullptr) { - windowPairMap_[displayId]->RotateDividerWindow(curDividerRect); - } + ProcessWindowPairWhenDisplayChange(true); } void DisplayGroupController::ClearMapOfDestroyedDisplay(DisplayId displayId) @@ -501,11 +526,62 @@ sptr DisplayGroupController::GetWindowPairByDisplayId(DisplayId disp return nullptr; } -void DisplayGroupController::SetDividerRect(DisplayId displayId, const Rect& rect) +void DisplayGroupController::ProcessWindowPairWhenDisplayChange(bool rotateDisplay) { - if (windowPairMap_.find(displayId) != windowPairMap_.end()) { - windowPairMap_[displayId]->SetDividerRect(rect); + for (auto& elem : displayGroupInfo_->GetAllDisplayRects()) { + const auto& displayId = elem.first; + const auto& windowPair = GetWindowPairByDisplayId(displayId); + if (windowPair == nullptr) { + WLOGFE("WindowPair is nullptr, displayId: %{public}" PRIu64"", displayId); + return; + } + const auto& layoutPolicy = windowNodeContainer_->GetLayoutPolicy(); + if (layoutPolicy == nullptr) { + WLOGFE("LayoutPolicy is nullptr, displayId: %{public}" PRIu64"", displayId); + return; + } + Rect divRect = layoutPolicy->GetDividerRect(displayId); + if (rotateDisplay) { + windowPair->RotateDividerWindow(divRect); + } else { + windowPair->SetDividerRect(divRect); + } + UpdateSplitRatioPoints(displayId); + } +} + +void DisplayGroupController::SetSplitRatioConfig(const SplitRatioConfig& splitRatioConfig) +{ + for (auto& elem : displayGroupInfo_->GetAllDisplayRects()) { + const auto& displayId = elem.first; + const auto& windowPair = GetWindowPairByDisplayId(displayId); + if (windowPair == nullptr) { + WLOGFE("WindowPair is nullptr, displayId: %{public}" PRIu64"", displayId); + continue; + } + windowPair->SetSplitRatioConfig(splitRatioConfig); + UpdateSplitRatioPoints(displayId); + } +} + +void DisplayGroupController::UpdateSplitRatioPoints(DisplayId displayId) +{ + const auto& windowPair = GetWindowPairByDisplayId(displayId); + if (windowPair == nullptr) { + WLOGFE("WindowPair is nullptr, displayId: %{public}" PRIu64"", displayId); + return; + } + auto displayRects = displayGroupInfo_->GetAllDisplayRects(); + if (displayRects.find(displayId) == displayRects.end()) { + return; + } + windowPair->CalculateSplitRatioPoints(displayRects[displayId]); + const auto& layoutPolicy = windowNodeContainer_->GetLayoutPolicy(); + if (layoutPolicy == nullptr) { + WLOGFE("LayoutPolicy is nullptr, displayId: %{public}" PRIu64"", displayId); + return; } + layoutPolicy->SetSplitRatioPoints(displayId, windowPair->GetSplitRatioPoints()); } } // namespace Rosen } // namespace OHOS diff --git a/wmserver/src/window_controller.cpp b/wmserver/src/window_controller.cpp index fd57efc9be..d98add7f77 100644 --- a/wmserver/src/window_controller.cpp +++ b/wmserver/src/window_controller.cpp @@ -457,6 +457,15 @@ WMError WindowController::ResizeRect(uint32_t windowId, const Rect& rect, Window WLOGFE("fullscreen window could not resize"); return WMError::WM_ERROR_INVALID_OPERATION; } + /* + * if requestRect of systemBar equals to winRect, not need to resize. This may happen when rotate display + */ + if (WindowHelper::IsSystemBarWindow(node->GetWindowType())) { + if ((reason== WindowSizeChangeReason::MOVE || reason == WindowSizeChangeReason::RESIZE) && + rect == node->GetWindowRect()) { + return WMError::WM_OK; + } + } auto property = node->GetWindowProperty(); node->SetWindowSizeChangeReason(reason); Rect lastRect = property->GetWindowRect(); @@ -475,7 +484,7 @@ WMError WindowController::ResizeRect(uint32_t windowId, const Rect& rect, Window } } else if (reason == WindowSizeChangeReason::RESIZE) { newRect = { lastRect.posX_, lastRect.posY_, rect.width_, rect.height_ }; - } else if (reason == WindowSizeChangeReason::DRAG || reason == WindowSizeChangeReason::ROTATION) { + } else if (reason == WindowSizeChangeReason::DRAG) { newRect = rect; } property->SetRequestRect(newRect); @@ -589,25 +598,6 @@ void WindowController::SetDefaultDisplayInfo(DisplayId defaultDisplayId, sptr& displayInfo) -{ - DisplayId displayId = displayInfo->GetDisplayId(); - auto width = static_cast(displayInfo->GetWidth()); - auto height = static_cast(displayInfo->GetHeight()); - const auto& statusBarNode = windowRoot_->GetWindowNode(sysBarWinId_[WindowType::WINDOW_TYPE_STATUS_BAR]); - if (statusBarNode != nullptr && statusBarNode->GetDisplayId() == displayId) { - auto statusBarHeight = statusBarNode->GetWindowRect().height_; - Rect newRect = { 0, 0, width, statusBarHeight }; - ResizeRect(sysBarWinId_[WindowType::WINDOW_TYPE_STATUS_BAR], newRect, WindowSizeChangeReason::ROTATION); - } - const auto& naviBarNode = windowRoot_->GetWindowNode(sysBarWinId_[WindowType::WINDOW_TYPE_NAVIGATION_BAR]); - if (naviBarNode != nullptr && naviBarNode->GetDisplayId() == displayId) { - auto naviBarHeight = naviBarNode->GetWindowRect().height_; - Rect newRect = { 0, static_cast(height - naviBarHeight), width, naviBarHeight }; - ResizeRect(sysBarWinId_[WindowType::WINDOW_TYPE_NAVIGATION_BAR], newRect, WindowSizeChangeReason::ROTATION); - } -} - void WindowController::ProcessDisplayChange(DisplayId defaultDisplayId, sptr displayInfo, const std::map>& displayInfoMap, DisplayStateChangeType type) { @@ -626,9 +616,6 @@ void WindowController::ProcessDisplayChange(DisplayId defaultDisplayId, sptrProcessDisplayChange(defaultDisplayId, displayInfo, displayInfoMap, type); - ProcessSystemBarChange(displayInfo); - break; case DisplayStateChangeType::VIRTUAL_PIXEL_RATIO_CHANGE: { windowRoot_->ProcessDisplayChange(defaultDisplayId, displayInfo, displayInfoMap, type); break; @@ -959,6 +946,7 @@ WMError WindowController::RecoverInputEventToClient(uint32_t windowId) WLOGFD("There is no need to recover input event to client"); return WMError::WM_OK; } + node->SetInputEventCallingPid(node->GetCallingPid()); RecoverDefaultMouseStyle(windowId); AsyncFlushInputInfo(windowId); diff --git a/wmserver/src/window_layout_policy.cpp b/wmserver/src/window_layout_policy.cpp index d91edd5153..3b1ded13b7 100644 --- a/wmserver/src/window_layout_policy.cpp +++ b/wmserver/src/window_layout_policy.cpp @@ -37,21 +37,11 @@ void WindowLayoutPolicy::Launch() WLOGFI("WindowLayoutPolicy::Launch"); } -void WindowLayoutPolicy::Clean() -{ - WLOGFI("WindowLayoutPolicy::Clean"); -} - void WindowLayoutPolicy::Reorder() { WLOGFI("WindowLayoutPolicy::Reorder"); } -std::vector WindowLayoutPolicy::GetExitSplitPoints(DisplayId displayId) const -{ - return {}; -} - void WindowLayoutPolicy::LimitWindowToBottomRightCorner(const sptr& node) { Rect windowRect = node->GetRequestRect(); @@ -95,7 +85,7 @@ void WindowLayoutPolicy::UpdateDisplayGroupRect() newDisplayGroupRect.height_ = maxHeight - newDisplayGroupRect.posY_; } displayGroupRect_ = newDisplayGroupRect; - WLOGFI("displayGroupRect_: [ %{public}d, %{public}d, %{public}d, %{public}d]", + WLOGFI("Update displayGroupRect: [%{public}d, %{public}d, %{public}d, %{public}d]", displayGroupRect_.posX_, displayGroupRect_.posY_, displayGroupRect_.width_, displayGroupRect_.height_); } @@ -118,7 +108,7 @@ void WindowLayoutPolicy::UpdateDisplayGroupLimitRect() newDisplayGroupLimitRect.height_ = maxHeight - newDisplayGroupLimitRect.posY_; } displayGroupLimitRect_ = newDisplayGroupLimitRect; - WLOGFI("displayGroupLimitRect_: [ %{public}d, %{public}d, %{public}d, %{public}d]", + WLOGFI("Update displayGroupLimitRect: [%{public}d, %{public}d, %{public}d, %{public}d]", displayGroupLimitRect_.posX_, displayGroupLimitRect_.posY_, displayGroupLimitRect_.width_, displayGroupLimitRect_.height_); } @@ -196,7 +186,6 @@ void WindowLayoutPolicy::PostProcessWhenDisplayChange() { displayGroupInfo_->UpdateLeftAndRightDisplayId(); UpdateMultiDisplayFlag(); - UpdateDisplayGroupRect(); Launch(); } @@ -281,10 +270,15 @@ void WindowLayoutPolicy::ProcessDisplaySizeChangeOrRotation(DisplayId displayId, WLOGFI("Process display change, displayId: %{public}" PRIu64"", displayId); } +void WindowLayoutPolicy::ProcessDisplayVprChange(DisplayId displayId) +{ + Launch(); +} + void WindowLayoutPolicy::LayoutWindowNodesByRootType(const std::vector>& nodeVec) { if (nodeVec.empty()) { - WLOGE("The node vector is empty!"); + WLOGW("The node vector is empty!"); return; } for (auto& node : nodeVec) { @@ -322,12 +316,15 @@ void WindowLayoutPolicy::NotifyAnimationSizeChangeIfNeeded() void WindowLayoutPolicy::LayoutWindowTree(DisplayId displayId) { - auto& displayWindowTree = displayGroupWindowTree_[displayId]; + // reset limit rect limitRectMap_[displayId] = displayGroupInfo_->GetDisplayRect(displayId); + displayGroupLimitRect_ = displayGroupRect_; + // ensure that the avoid area windows are traversed first + auto& displayWindowTree = displayGroupWindowTree_[displayId]; LayoutWindowNodesByRootType(*(displayWindowTree[WindowRootNodeType::ABOVE_WINDOW_NODE])); if (IsFullScreenRecentWindowExist(*(displayWindowTree[WindowRootNodeType::ABOVE_WINDOW_NODE]))) { - WLOGFI("recent window on top, early exit layout tree"); + WLOGFD("recent window on top, early exit layout tree"); return; } LayoutWindowNodesByRootType(*(displayWindowTree[WindowRootNodeType::APP_WINDOW_NODE])); @@ -336,20 +333,23 @@ void WindowLayoutPolicy::LayoutWindowTree(DisplayId displayId) void WindowLayoutPolicy::LayoutWindowNode(const sptr& node) { - if (node == nullptr) { + if (node == nullptr || node->parent_ == nullptr) { + WLOGFE("Node or it's parent is nullptr, windowId: [%{public}u]", node->GetWindowId()); return; } - WLOGFI("LayoutWindowNode, window[%{public}u]", node->GetWindowId()); - if (node->parent_ != nullptr) { // isn't root node - if (!node->currentVisibility_) { - WLOGFI("window[%{public}u] currently not visible, no need layout", node->GetWindowId()); - return; - } - UpdateLayoutRect(node); - if (avoidTypes_.find(node->GetWindowType()) != avoidTypes_.end()) { - UpdateLimitRect(node, limitRectMap_[node->GetDisplayId()]); - UpdateDisplayGroupLimitRect(); - } + if (!node->currentVisibility_) { + WLOGFD("window[%{public}u] currently not visible, no need to layout", node->GetWindowId()); + return; + } + + /* + * 1. update window rect + * 2. update diplayLimitRect and displayGroupRect if this is avoidNode + */ + UpdateLayoutRect(node); + if (WindowHelper::IsSystemBarWindow(node->GetWindowType())) { + UpdateDisplayLimitRect(node, limitRectMap_[node->GetDisplayId()]); + UpdateDisplayGroupLimitRect(); } for (auto& childNode : node->children_) { LayoutWindowNode(childNode); @@ -361,87 +361,18 @@ bool WindowLayoutPolicy::IsVerticalDisplay(DisplayId displayId) const return displayGroupInfo_->GetDisplayRect(displayId).width_ < displayGroupInfo_->GetDisplayRect(displayId).height_; } -void WindowLayoutPolicy::UpdateClientRect(const Rect& rect, const sptr& node, WindowSizeChangeReason reason) +void WindowLayoutPolicy::NotifyClientAndAnimation(const sptr& node, + const Rect& winRect, WindowSizeChangeReason reason) { if (node->GetWindowToken()) { - WLOGFI("notify client id: %{public}d, windowRect:[%{public}d, %{public}d, %{public}u, %{public}u], reason: " - "%{public}u", node->GetWindowId(), rect.posX_, rect.posY_, rect.width_, rect.height_, reason); - node->GetWindowToken()->UpdateWindowRect(rect, node->GetDecoStatus(), reason); + node->GetWindowToken()->UpdateWindowRect(winRect, node->GetDecoStatus(), reason); + WLOGFI("notify client id: %{public}d, winRect:[%{public}d, %{public}d, %{public}u, %{public}u], reason: " + "%{public}u", node->GetWindowId(), winRect.posX_, winRect.posY_, winRect.width_, winRect.height_, reason); } - NotifyAnimationSizeChangeIfNeeded(); -} - -void WindowLayoutPolicy::UpdateClientRectAndResetReason(const sptr& node, const Rect& winRect) -{ - auto reason = node->GetWindowSizeChangeReason(); - UpdateClientRect(winRect, node, reason); if ((reason != WindowSizeChangeReason::MOVE) && (node->GetWindowType() != WindowType::WINDOW_TYPE_DOCK_SLICE)) { node->ResetWindowSizeChangeReason(); } -} - -void WindowLayoutPolicy::RemoveWindowNode(const sptr& node) -{ - auto type = node->GetWindowType(); - // affect other windows, trigger off global layout - if (avoidTypes_.find(type) != avoidTypes_.end()) { - LayoutWindowTree(node->GetDisplayId()); - } else if (type == WindowType::WINDOW_TYPE_DOCK_SLICE) { // split screen mode - LayoutWindowTree(node->GetDisplayId()); - } - UpdateClientRect(node->GetRequestRect(), node, WindowSizeChangeReason::HIDE); -} - -void WindowLayoutPolicy::UpdateWindowNode(const sptr& node, bool isAddWindow) -{ - auto type = node->GetWindowType(); - // affect other windows, trigger off global layout - if (avoidTypes_.find(type) != avoidTypes_.end()) { - LayoutWindowTree(node->GetDisplayId()); - } else if (type == WindowType::WINDOW_TYPE_DOCK_SLICE) { // split screen mode - LayoutWindowTree(node->GetDisplayId()); - } else { // layout single window - LayoutWindowNode(node); - } -} - -void WindowLayoutPolicy::UpdateFloatingLayoutRect(Rect& limitRect, Rect& winRect) -{ - winRect.width_ = std::min(limitRect.width_, winRect.width_); - winRect.height_ = std::min(limitRect.height_, winRect.height_); - winRect.posX_ = std::max(limitRect.posX_, winRect.posX_); - winRect.posY_ = std::max(limitRect.posY_, winRect.posY_); - winRect.posX_ = std::min( - limitRect.posX_ + static_cast(limitRect.width_) - static_cast(winRect.width_), - winRect.posX_); - winRect.posY_ = std::min( - limitRect.posY_ + static_cast(limitRect.height_) - static_cast(winRect.height_), - winRect.posY_); -} - -void WindowLayoutPolicy::ComputeDecoratedRequestRect(const sptr& node) const -{ - auto property = node->GetWindowProperty(); - if (property == nullptr) { - WLOGE("window property is nullptr"); - return; - } - auto reqRect = property->GetRequestRect(); - if (!property->GetDecorEnable() || property->GetDecoStatus() || - node->GetWindowSizeChangeReason() == WindowSizeChangeReason::MOVE) { - return; - } - float virtualPixelRatio = GetVirtualPixelRatio(node->GetDisplayId()); - uint32_t winFrameW = static_cast(WINDOW_FRAME_WIDTH * virtualPixelRatio); - uint32_t winTitleBarH = static_cast(WINDOW_TITLE_BAR_HEIGHT * virtualPixelRatio); - - Rect rect; - rect.posX_ = reqRect.posX_; - rect.posY_ = reqRect.posY_; - rect.width_ = reqRect.width_ + winFrameW + winFrameW; - rect.height_ = reqRect.height_ + winTitleBarH + winFrameW; - property->SetRequestRect(rect); - property->SetDecoStatus(true); + NotifyAnimationSizeChangeIfNeeded(); } Rect WindowLayoutPolicy::CalcEntireWindowHotZone(const sptr& node, const Rect& winRect, uint32_t hotZone, @@ -472,7 +403,7 @@ Rect WindowLayoutPolicy::CalcEntireWindowHotZone(const sptr& node, c void WindowLayoutPolicy::CalcAndSetNodeHotZone(const Rect& winRect, const sptr& node) const { - float virtualPixelRatio = GetVirtualPixelRatio(node->GetDisplayId()); + float virtualPixelRatio = displayGroupInfo_->GetDisplayVirtualPixelRatio(node->GetDisplayId()); TransformHelper::Vector2 hotZoneScale(1, 1); if (node->GetWindowProperty()->isNeedComputerTransform()) { node->ComputeTransform(); @@ -507,7 +438,7 @@ void WindowLayoutPolicy::FixWindowSizeByRatioIfDragBeyondLimitRegion(const sptr< const auto& sizeLimits = node->GetWindowUpdatedSizeLimits(); if (sizeLimits.maxWidth_ == sizeLimits.minWidth_ && sizeLimits.maxHeight_ == sizeLimits.minHeight_) { - WLOGFI("window rect can not be changed"); + WLOGFD("window rect can not be changed"); return; } if (winRect.height_ == 0) { @@ -516,13 +447,13 @@ void WindowLayoutPolicy::FixWindowSizeByRatioIfDragBeyondLimitRegion(const sptr< } float curRatio = static_cast(winRect.width_) / static_cast(winRect.height_); if (sizeLimits.minRatio_ <= curRatio && curRatio <= sizeLimits.maxRatio_) { - WLOGFI("window ratio is satisfied with limit ratio, curRatio: %{public}f", curRatio); + WLOGFD("window ratio is satisfied with limit ratio, curRatio: %{public}f", curRatio); return; } - float virtualPixelRatio = GetVirtualPixelRatio(node->GetDisplayId()); + float virtualPixelRatio = displayGroupInfo_->GetDisplayVirtualPixelRatio(node->GetDisplayId()); uint32_t windowTitleBarH = static_cast(WINDOW_TITLE_BAR_HEIGHT * virtualPixelRatio); - Rect limitRect = isMultiDisplay_ ? displayGroupLimitRect_ : limitRectMap_[node->GetDisplayId()]; + Rect limitRect = (node->isShowingOnMultiDisplays_) ? displayGroupLimitRect_ : limitRectMap_[node->GetDisplayId()]; int32_t limitMinPosX = limitRect.posX_ + static_cast(windowTitleBarH); int32_t limitMaxPosX = limitRect.posX_ + static_cast(limitRect.width_ - windowTitleBarH); int32_t limitMinPosY = limitRect.posY_; @@ -557,16 +488,16 @@ void WindowLayoutPolicy::FixWindowSizeByRatioIfDragBeyondLimitRegion(const sptr< } winRect.width_ = static_cast(static_cast(winRect.height_) * newRatio); } - WLOGFI("After limit by ratio if beyond limit region, winRect: %{public}d %{public}d %{public}u %{public}u", + WLOGFD("After limit by ratio if beyond limit region, winRect: %{public}d %{public}d %{public}u %{public}u", winRect.posX_, winRect.posY_, winRect.width_, winRect.height_); } WindowSizeLimits WindowLayoutPolicy::GetSystemSizeLimits(const sptr& node, - const Rect& displayRect, float virtualPixelRatio) + const Rect& displayRect, float vpr) { WindowSizeLimits systemLimits; - systemLimits.maxWidth_ = static_cast(MAX_FLOATING_SIZE * virtualPixelRatio); - systemLimits.maxHeight_ = static_cast(MAX_FLOATING_SIZE * virtualPixelRatio); + systemLimits.maxWidth_ = static_cast(MAX_FLOATING_SIZE * vpr); + systemLimits.maxHeight_ = static_cast(MAX_FLOATING_SIZE * vpr); // Float camera window has a special limit: // if display sw <= 600dp, portrait: min width = display sw * 30%, landscape: min width = sw * 50% @@ -574,7 +505,7 @@ WindowSizeLimits WindowLayoutPolicy::GetSystemSizeLimits(const sptr& if (node->GetWindowType() == WindowType::WINDOW_TYPE_FLOAT_CAMERA) { uint32_t smallWidth = displayRect.height_ <= displayRect.width_ ? displayRect.height_ : displayRect.width_; float hwRatio = static_cast(displayRect.height_) / static_cast(displayRect.width_); - if (smallWidth <= static_cast(600 * virtualPixelRatio)) { // sw <= 600dp + if (smallWidth <= static_cast(600 * vpr)) { // sw <= 600dp if (displayRect.width_ <= displayRect.height_) { systemLimits.minWidth_ = static_cast(smallWidth * 0.3); // min width = display sw * 0.3 } else { @@ -589,8 +520,8 @@ WindowSizeLimits WindowLayoutPolicy::GetSystemSizeLimits(const sptr& } systemLimits.minHeight_ = static_cast(systemLimits.minWidth_ * hwRatio); } else { - systemLimits.minWidth_ = static_cast(MIN_FLOATING_WIDTH * virtualPixelRatio); - systemLimits.minHeight_ = static_cast(MIN_FLOATING_HEIGHT * virtualPixelRatio); + systemLimits.minWidth_ = static_cast(MIN_FLOATING_WIDTH * vpr); + systemLimits.minHeight_ = static_cast(MIN_FLOATING_HEIGHT * vpr); } WLOGFD("[System SizeLimits] [maxWidth: %{public}u, minWidth: %{public}u, maxHeight: %{public}u, " "minHeight: %{public}u]", systemLimits.maxWidth_, systemLimits.minWidth_, @@ -601,7 +532,7 @@ WindowSizeLimits WindowLayoutPolicy::GetSystemSizeLimits(const sptr& void WindowLayoutPolicy::UpdateWindowSizeLimits(const sptr& node) { const auto& displayRect = displayGroupInfo_->GetDisplayRect(node->GetDisplayId()); - const auto& virtualPixelRatio = GetVirtualPixelRatio(node->GetDisplayId()); + const auto& virtualPixelRatio = displayGroupInfo_->GetDisplayVirtualPixelRatio(node->GetDisplayId()); const auto& systemLimits = GetSystemSizeLimits(node, displayRect, virtualPixelRatio); const auto& customizedLimits = node->GetWindowSizeLimits(); @@ -647,7 +578,7 @@ void WindowLayoutPolicy::UpdateWindowSizeLimits(const sptr& node) uint32_t newMinHeight = static_cast(static_cast(newLimits.minWidth_) / newLimits.maxRatio_); newLimits.minHeight_ = std::max(newMinHeight, newLimits.minHeight_); - WLOGFI("[Update SizeLimits] winId: %{public}u, Width: [max:%{public}u, min:%{public}u], Height: [max:%{public}u, " + WLOGFD("[Update SizeLimits] winId: %{public}u, Width: [max:%{public}u, min:%{public}u], Height: [max:%{public}u, " "min:%{public}u], Ratio: [max:%{public}f, min:%{public}f]", node->GetWindowId(), newLimits.maxWidth_, newLimits.minWidth_, newLimits.maxHeight_, newLimits.minHeight_, newLimits.maxRatio_, newLimits.minRatio_); node->SetWindowUpdatedSizeLimits(newLimits); @@ -795,12 +726,12 @@ void WindowLayoutPolicy::LimitMainFloatingWindowPosition(const sptr& void WindowLayoutPolicy::LimitWindowPositionWhenDrag(const sptr& node, Rect& winRect) const { - float virtualPixelRatio = GetVirtualPixelRatio(node->GetDisplayId()); + float virtualPixelRatio = displayGroupInfo_->GetDisplayVirtualPixelRatio(node->GetDisplayId()); uint32_t windowTitleBarH = static_cast(WINDOW_TITLE_BAR_HEIGHT * virtualPixelRatio); const Rect& lastRect = node->GetWindowRect(); Rect oriWinRect = winRect; - Rect limitRect = isMultiDisplay_ ? displayGroupLimitRect_ : limitRectMap_[node->GetDisplayId()]; + Rect limitRect = (node->isShowingOnMultiDisplays_) ? displayGroupLimitRect_ : limitRectMap_[node->GetDisplayId()]; int32_t limitMinPosX = limitRect.posX_ + static_cast(windowTitleBarH); int32_t limitMaxPosX = limitRect.posX_ + static_cast(limitRect.width_ - windowTitleBarH); int32_t limitMinPosY = limitRect.posY_; @@ -852,16 +783,11 @@ void WindowLayoutPolicy::LimitWindowPositionWhenDrag(const sptr& nod void WindowLayoutPolicy::LimitWindowPositionWhenInitRectOrMove(const sptr& node, Rect& winRect) const { - float virtualPixelRatio = GetVirtualPixelRatio(node->GetDisplayId()); + float virtualPixelRatio = displayGroupInfo_->GetDisplayVirtualPixelRatio(node->GetDisplayId()); uint32_t windowTitleBarH = static_cast(WINDOW_TITLE_BAR_HEIGHT * virtualPixelRatio); - Rect limitRect; // if is cross-display window, the limit rect should be full limitRect - if (node->isShowingOnMultiDisplays_) { - limitRect = displayGroupLimitRect_; - } else { - limitRect = limitRectMap_[node->GetDisplayId()]; - } + Rect limitRect = (node->isShowingOnMultiDisplays_) ? displayGroupLimitRect_ : limitRectMap_[node->GetDisplayId()]; // limit position of the main floating window(window which support dragging) if (WindowHelper::IsMainFloatingWindow(node->GetWindowType(), node->GetWindowMode())) { @@ -937,7 +863,7 @@ AvoidPosType WindowLayoutPolicy::GetAvoidPosType(const Rect& rect, DisplayId dis return WindowHelper::GetAvoidPosType(rect, displayRect); } -void WindowLayoutPolicy::UpdateLimitRect(const sptr& node, Rect& limitRect) +void WindowLayoutPolicy::UpdateDisplayLimitRect(const sptr& node, Rect& limitRect) { const auto& layoutRect = node->GetWindowRect(); int32_t limitH = static_cast(limitRect.height_); @@ -974,19 +900,10 @@ void WindowLayoutPolicy::UpdateLimitRect(const sptr& node, Rect& lim } limitRect.height_ = static_cast(limitH < 0 ? 0 : limitH); limitRect.width_ = static_cast(limitW < 0 ? 0 : limitW); - WLOGFI("Type: %{public}d, limitRect: %{public}d %{public}d %{public}u %{public}u", - node->GetWindowType(), limitRect.posX_, limitRect.posY_, limitRect.width_, limitRect.height_); -} - -void WindowLayoutPolicy::Reset() -{ -} - -float WindowLayoutPolicy::GetVirtualPixelRatio(DisplayId displayId) const -{ - float virtualPixelRatio = displayGroupInfo_->GetDisplayVirtualPixelRatio(displayId); - WLOGFI("GetVirtualPixel success. displayId:%{public}" PRIu64", vpr:%{public}f", displayId, virtualPixelRatio); - return virtualPixelRatio; + WLOGFI("[Update limit displayRect], avoidNodeId: %{public}d, avoidNodeRect: [%{public}d %{public}d " + "%{public}u %{public}u], limitDisplayRect: [%{public}d %{public}d, %{public}u %{public}u]", + node->GetWindowId(), layoutRect.posX_, layoutRect.posY_, layoutRect.width_, layoutRect.height_, + limitRect.posX_, limitRect.posY_, limitRect.width_, limitRect.height_); } bool WindowLayoutPolicy::IsFullScreenRecentWindowExist(const std::vector>& nodeVec) const @@ -1019,11 +936,9 @@ static void SetBounds(const sptr& node, const Rect& winRect, const R node->surfaceNode_->SetFrameGravity(Gravity::TOP_LEFT); } } - WLOGFD("name:%{public}s id:%{public}u preRect:[x:%{public}d, y:%{public}d, w:%{public}d, h:%{public}d]", - node->GetWindowName().c_str(), node->GetWindowId(), - preRect.posX_, preRect.posY_, preRect.width_, preRect.height_); - WLOGFD("name:%{public}s id:%{public}u winRect:[x:%{public}d, y:%{public}d, w:%{public}d, h:%{public}d]", - node->GetWindowName().c_str(), node->GetWindowId(), + WLOGFD("[Set Bounds] name:%{public}s id:%{public}u preRect: [%{public}d, %{public}d, %{public}d, %{public}d], " + "winRect: [%{public}d, %{public}d, %{public}d, %{public}d]", node->GetWindowName().c_str(), + node->GetWindowId(), preRect.posX_, preRect.posY_, preRect.width_, preRect.height_, winRect.posX_, winRect.posY_, winRect.width_, winRect.height_); if (node->leashWinSurfaceNode_) { if (winRect != preRect) { @@ -1086,9 +1001,9 @@ Rect WindowLayoutPolicy::GetDisplayGroupRect() const return displayGroupRect_; } -void WindowLayoutPolicy::SetSplitRatioConfig(const SplitRatioConfig& splitRatioConfig) +void WindowLayoutPolicy::SetSplitRatioPoints(DisplayId displayId, const std::vector& splitRatioPoints) { - splitRatioConfig_ = splitRatioConfig; + splitRatioPointsMap_[displayId] = splitRatioPoints; } Rect WindowLayoutPolicy::GetDividerRect(DisplayId displayId) const diff --git a/wmserver/src/window_layout_policy_cascade.cpp b/wmserver/src/window_layout_policy_cascade.cpp index 729c9be294..bab5d0173c 100644 --- a/wmserver/src/window_layout_policy_cascade.cpp +++ b/wmserver/src/window_layout_policy_cascade.cpp @@ -32,13 +32,11 @@ WindowLayoutPolicyCascade::WindowLayoutPolicyCascade(const sptrGetAllDisplayRects()) { cascadeRectsMap_.insert(std::make_pair(iter.first, cascadeRects)); @@ -48,182 +46,138 @@ WindowLayoutPolicyCascade::WindowLayoutPolicyCascade(const sptrGetAllDisplayRects()) { - DisplayId displayId = iter.first; - auto& displayWindowTree = displayGroupWindowTree_[displayId]; - LayoutWindowNodesByRootType(*(displayWindowTree[WindowRootNodeType::APP_WINDOW_NODE])); - LayoutWindowNodesByRootType(*(displayWindowTree[WindowRootNodeType::BELOW_WINDOW_NODE])); - } WLOGFI("WindowLayoutPolicyCascade::Launch"); } -void WindowLayoutPolicyCascade::Clean() -{ - WLOGFI("WindowLayoutPolicyCascade::Clean"); -} - -void WindowLayoutPolicyCascade::Reset() +void WindowLayoutPolicyCascade::Reorder() { - const auto& displayRectMap = displayGroupInfo_->GetAllDisplayRects(); - // reset split and limit rects - for (auto& iter : displayRectMap) { - InitSplitRects(iter.first); - InitLimitRects(iter.first); + WLOGFD("Cascade reorder start"); + for (auto& iter : displayGroupInfo_->GetAllDisplayRects()) { + DisplayId displayId = iter.first; + Rect rect = cascadeRectsMap_[displayId].defaultCascadeRect_; + bool isFirstReorderedWindow = true; + const auto& appWindowNodeVec = *(displayGroupWindowTree_[displayId][WindowRootNodeType::APP_WINDOW_NODE]); + for (auto nodeIter = appWindowNodeVec.begin(); nodeIter != appWindowNodeVec.end(); nodeIter++) { + auto node = *nodeIter; + if (node == nullptr || node->GetWindowType() != WindowType::WINDOW_TYPE_APP_MAIN_WINDOW) { + WLOGFW("get node failed or not app window."); + continue; + } + // if window don't support floating mode, or default rect of cascade is not satisfied with limits + if (!WindowHelper::IsWindowModeSupported(node->GetModeSupportInfo(), WindowMode::WINDOW_MODE_FLOATING) || + !WindowHelper::IsRectSatisfiedWithSizeLimits(rect, node->GetWindowUpdatedSizeLimits())) { + MinimizeApp::AddNeedMinimizeApp(node, MinimizeReason::LAYOUT_CASCADE); + continue; + } + if (isFirstReorderedWindow) { + isFirstReorderedWindow = false; + } else { + rect = StepCascadeRect(rect, displayId); + } + node->SetRequestRect(rect); + node->SetDecoStatus(true); + if (node->GetWindowMode() != WindowMode::WINDOW_MODE_FLOATING) { + node->SetWindowMode(WindowMode::WINDOW_MODE_FLOATING); + if (node->GetWindowToken()) { + node->GetWindowToken()->UpdateWindowMode(WindowMode::WINDOW_MODE_FLOATING); + } + } + WLOGFD("Cascade reorder Id: %{public}d, rect:[%{public}d, %{public}d, %{public}d, %{public}d]", + node->GetWindowId(), rect.posX_, rect.posY_, rect.width_, rect.height_); + } + LayoutWindowTree(displayId); } - displayGroupLimitRect_ = displayGroupRect_; + WLOGFI("Cascade Reorder end"); } void WindowLayoutPolicyCascade::InitAllRects() { - const auto& displayRectMap = displayGroupInfo_->GetAllDisplayRects(); - for (auto& iter : displayRectMap) { - // init split and limit rects - InitSplitRects(iter.first); - InitLimitRects(iter.first); - // init full displayRect - displayGroupLimitRect_ = displayGroupRect_; - // init cascade rect - auto& displayWindowTree = displayGroupWindowTree_[iter.first]; - LayoutWindowNodesByRootType(*(displayWindowTree[WindowRootNodeType::ABOVE_WINDOW_NODE])); - InitCascadeRect(iter.first); + UpdateDisplayGroupRect(); + for (auto& iter : displayGroupInfo_->GetAllDisplayRects()) { + auto displayId = iter.first; + InitSplitRects(displayId); + LayoutWindowTree(displayId); + InitCascadeRect(displayId); } } -void WindowLayoutPolicyCascade::LayoutWindowNode(const sptr& node) +void WindowLayoutPolicyCascade::LayoutSplitNodes(DisplayId displayId, WindowUpdateType type, bool layoutByDivider) { - if (node == nullptr) { - return; - } - if (node->parent_ != nullptr) { // isn't root node - if (!node->currentVisibility_) { - WLOGFI("window[%{public}u] currently not visible, no need layout", node->GetWindowId()); - return; - } - UpdateLayoutRect(node); - if (avoidTypes_.find(node->GetWindowType()) != avoidTypes_.end()) { - const DisplayId& displayId = node->GetDisplayId(); - Rect& primaryLimitRect = cascadeRectsMap_[displayId].primaryLimitRect_; - Rect& secondaryLimitRect = cascadeRectsMap_[displayId].secondaryLimitRect_; - UpdateLimitRect(node, limitRectMap_[displayId]); - UpdateSplitLimitRect(limitRectMap_[displayId], primaryLimitRect); - UpdateSplitLimitRect(limitRectMap_[displayId], secondaryLimitRect); - UpdateSplitRatioPoints(displayId); - UpdateDisplayGroupLimitRect(); - WLOGFI("priLimitRect: %{public}d %{public}d %{public}u %{public}u, " \ - "secLimitRect: %{public}d %{public}d %{public}u %{public}u", primaryLimitRect.posX_, - primaryLimitRect.posY_, primaryLimitRect.width_, primaryLimitRect.height_, secondaryLimitRect.posX_, - secondaryLimitRect.posY_, secondaryLimitRect.width_, secondaryLimitRect.height_); + const auto& appWindowNodeVec = *(displayGroupWindowTree_[displayId][WindowRootNodeType::APP_WINDOW_NODE]); + for (auto& childNode : appWindowNodeVec) { + if (type == WindowUpdateType::WINDOW_UPDATE_REMOVED) { + /* + * If updateType is remove we need to layout all appNodes, cause remove split node or + * divider means exit split mode, split node may change to other mode + */ + LayoutWindowNode(childNode); + } else if (childNode->IsSplitMode()) { // add or update type, layout split node + if (layoutByDivider && type == WindowUpdateType::WINDOW_UPDATE_ACTIVE) { + childNode->SetWindowSizeChangeReason(WindowSizeChangeReason::DRAG); + } + LayoutWindowNode(childNode); } } - for (auto& childNode : node->children_) { - LayoutWindowNode(childNode); - } -} - -void WindowLayoutPolicyCascade::LayoutWindowTree(DisplayId displayId) -{ - InitLimitRects(displayId); - WindowLayoutPolicy::LayoutWindowTree(displayId); -} - -void WindowLayoutPolicyCascade::RemoveWindowNode(const sptr& node) -{ - HITRACE_METER(HITRACE_TAG_WINDOW_MANAGER); - auto type = node->GetWindowType(); - // affect other windows, trigger off global layout - if (avoidTypes_.find(type) != avoidTypes_.end()) { - LayoutWindowTree(node->GetDisplayId()); - } else if (type == WindowType::WINDOW_TYPE_DOCK_SLICE) { // split screen mode - InitSplitRects(node->GetDisplayId()); - LayoutWindowTree(node->GetDisplayId()); - } - UpdateClientRect(node->GetRequestRect(), node, WindowSizeChangeReason::HIDE); -} - -std::vector WindowLayoutPolicyCascade::GetExitSplitPoints(DisplayId displayId) const -{ - return cascadeRectsMap_[displayId].exitSplitPoints_; } -bool WindowLayoutPolicyCascade::SpecialReasonProcess(const sptr& node) const +void WindowLayoutPolicyCascade::LayoutDivider(const sptr& node, WindowUpdateType type) { - const DisplayId& displayId = node->GetDisplayId(); - if ((node->GetWindowSizeChangeReason() == WindowSizeChangeReason::MOVE) || - (node->GetWindowSizeChangeReason() == WindowSizeChangeReason::RESIZE)) { - if (node->GetRequestRect() == node->GetWindowRect()) { - return false; - } - } - if (node->GetWindowSizeChangeReason() == WindowSizeChangeReason::ROTATION) { - const auto& windowNodeVecSptrs = displayGroupWindowTree_[displayId]; - for (const auto& windowNodeVecSptr : windowNodeVecSptrs) { - const auto& windowNodeVec = *(windowNodeVecSptr.second); - for (auto& childNode : windowNodeVec) { - childNode->SetWindowSizeChangeReason(WindowSizeChangeReason::ROTATION); - } - } + auto displayId = node->GetDisplayId(); + switch (type) { + case WindowUpdateType::WINDOW_UPDATE_ADDED: + SetInitialDividerRect(node, displayId); + [[fallthrough]]; + case WindowUpdateType::WINDOW_UPDATE_ACTIVE: + UpdateDividerPosition(node); + LayoutWindowNode(node); + SetSplitRectByDivider(node->GetWindowRect(), displayId); // set splitRect by divider + break; + case WindowUpdateType::WINDOW_UPDATE_REMOVED: + InitSplitRects(displayId); // reinit split rects when remove divider + break; + default: + WLOGFW("Unknown update type, type: %{public}u", type); } - return true; + LayoutSplitNodes(displayId, type, true); } -void WindowLayoutPolicyCascade::UpdateWindowNode(const sptr& node, bool isAddWindow) +void WindowLayoutPolicyCascade::PerformWindowLayout(const sptr& node, WindowUpdateType updateType) { HITRACE_METER(HITRACE_TAG_WINDOW_MANAGER); - auto type = node->GetWindowType(); - const DisplayId& displayId = node->GetDisplayId(); - UpdateWindowNodeRectOffset(node); - // affect other windows, trigger off global layout - if (avoidTypes_.find(type) != avoidTypes_.end()) { - bool ret = SpecialReasonProcess(node); - if (ret != true) { - return; - } - LayoutWindowTree(displayId); - } else if (type == WindowType::WINDOW_TYPE_DOCK_SLICE) { // split screen mode - UpdateLayoutRect(node); - auto splitDockerRect = node->GetWindowRect(); - SetSplitRect(splitDockerRect, displayId); // calculate primary/secondary depend on divider rect - WLOGFI("UpdateDividerRects WinId: %{public}u, Rect: %{public}d %{public}d %{public}u %{public}u", - node->GetWindowId(), splitDockerRect.posX_, splitDockerRect.posY_, - splitDockerRect.width_, splitDockerRect.height_); - if (!isAddWindow) { - const auto& appWindowNodeVec = *(displayGroupWindowTree_[displayId][WindowRootNodeType::APP_WINDOW_NODE]); - for (auto& childNode : appWindowNodeVec) { // update split node size change reason - if (childNode->IsSplitMode()) { - childNode->SetWindowSizeChangeReason(WindowSizeChangeReason::DRAG); - } + const auto& windowType = node->GetWindowType(); + const auto& requestRect = node->GetRequestRect(); + WLOGFI("[PerformWindowLayout] windowId: %{public}u, windowType: %{public}u, updateType: %{public}u, requestRect: " + "requestRect: [%{public}d, %{public}d, %{public}u, %{public}u]", node->GetWindowId(), windowType, updateType, + requestRect.posX_, requestRect.posY_, requestRect.width_, requestRect.height_); + SetDefaultCascadeRect(node); + FixWindowRectWithinDisplay(node); + switch (windowType) { + case WindowType::WINDOW_TYPE_DOCK_SLICE: + LayoutDivider(node, updateType); + break; + case WindowType::WINDOW_TYPE_STATUS_BAR: + case WindowType::WINDOW_TYPE_NAVIGATION_BAR: + LayoutWindowTree(node->GetDisplayId()); + break; + default: + if (node->IsSplitMode()) { + LayoutSplitNodes(node->GetDisplayId(), updateType); + } else { + LayoutWindowNode(node); } - } - LayoutWindowTree(displayId); - } else if (node->IsSplitMode()) { - LayoutWindowTree(displayId); - } else { // layout single window - LayoutWindowNode(node); + } + if (updateType == WindowUpdateType::WINDOW_UPDATE_REMOVED) { + NotifyClientAndAnimation(node, node->GetRequestRect(), WindowSizeChangeReason::HIDE); } } -void WindowLayoutPolicyCascade::AddWindowNode(const sptr& node) +void WindowLayoutPolicyCascade::SetInitialDividerRect(const sptr& node, DisplayId displayId) { - HITRACE_METER(HITRACE_TAG_WINDOW_MANAGER); - auto property = node->GetWindowProperty(); - if (property == nullptr) { - WLOGFE("window property is nullptr."); - return; - } - - if (WindowHelper::IsEmptyRect(property->GetRequestRect())) { - SetCascadeRect(node); - } - UpdateWindowNodeRectOffset(node); - if (node->GetWindowType() == WindowType::WINDOW_TYPE_DOCK_SLICE) { - node->SetRequestRect(cascadeRectsMap_[node->GetDisplayId()].dividerRect_); // init divider bar - DisplayId displayId = node->GetDisplayId(); - if (!WindowHelper::IsEmptyRect(restoringDividerWindowRects_[displayId])) { - node->SetRequestRect(restoringDividerWindowRects_[displayId]); - } - restoringDividerWindowRects_.erase(displayId); - } - UpdateWindowNode(node, true); // currently, update and add do the same process + const auto& restoredRect = restoringDividerWindowRects_[displayId]; + const auto& presetRect = cascadeRectsMap_[node->GetDisplayId()].dividerRect_; + auto divRect = WindowHelper::IsEmptyRect(restoredRect) ? presetRect : restoredRect; + node->SetRequestRect(divRect); + restoringDividerWindowRects_.erase(displayId); } void WindowLayoutPolicyCascade::SetSplitDividerWindowRects(std::map dividerWindowRects) @@ -231,7 +185,7 @@ void WindowLayoutPolicyCascade::SetSplitDividerWindowRects(std::map(limitRect.height_ - rect.height_); } } - WLOGFI("limit divider move bounds:[%{public}d, %{public}d, %{public}u, %{public}u]", + WLOGFD("limit divider move bounds: [%{public}d, %{public}d, %{public}u, %{public}u]", rect.posX_, rect.posY_, rect.width_, rect.height_); } +void WindowLayoutPolicyCascade::UpdateDividerPosition(const sptr& node) const +{ + auto rect = node->GetRequestRect(); + auto displayId = node->GetDisplayId(); + LimitDividerInDisplayRegion(rect, displayId); + if (node->GetWindowSizeChangeReason() == WindowSizeChangeReason::DRAG_END) { + LimitDividerPositionBySplitRatio(displayId, rect); + } + /* + * use the layout orientation of the window and the layout orientation of the screen + * to determine whether the screen is rotating + */ + if ((!WindowHelper::IsLandscapeRect(rect) && IsVerticalDisplay(displayId)) || + (WindowHelper::IsLandscapeRect(rect) && !IsVerticalDisplay(displayId))) { + // resets the rect of the divider window when the screen is rotating + WLOGFD("Reset divider when display rotate rect: [%{public}d, %{public}d, %{public}u, %{public}u]", + rect.posX_, rect.posY_, rect.width_, rect.height_); + rect = cascadeRectsMap_[displayId].dividerRect_; + } + node->SetRequestRect(rect); +} + void WindowLayoutPolicyCascade::InitCascadeRect(DisplayId displayId) { constexpr uint32_t half = 2; @@ -267,172 +243,124 @@ void WindowLayoutPolicyCascade::InitCascadeRect(DisplayId displayId) Rect resRect = {0, 0, defaultW, defaultH}; const Rect& limitRect = limitRectMap_[displayId]; if (defaultW <= limitRect.width_ && defaultH <= limitRect.height_) { - int32_t centerPosX = limitRect.posX_ + static_cast(limitRect.width_ / half); - resRect.posX_ = centerPosX - static_cast(defaultW / half); + resRect.posX_ = limitRect.posX_ + static_cast((limitRect.width_ - defaultW) / half); - int32_t centerPosY = limitRect.posY_ + static_cast(limitRect.height_ / half); - resRect.posY_ = centerPosY - static_cast(defaultH / half); + resRect.posY_ = limitRect.posY_ + static_cast((limitRect.height_ - defaultH) / half); } - WLOGFI("init CascadeRect :[%{public}d, %{public}d, %{public}d, %{public}d]", + WLOGFI("Init CascadeRect :[%{public}d, %{public}d, %{public}d, %{public}d]", resRect.posX_, resRect.posY_, resRect.width_, resRect.height_); - cascadeRectsMap_[displayId].firstCascadeRect_ = resRect; + cascadeRectsMap_[displayId].defaultCascadeRect_ = resRect; } -void WindowLayoutPolicyCascade::ApplyWindowRectConstraints(const sptr& node, Rect& winRect) const +void WindowLayoutPolicyCascade::ComputeDecoratedRequestRect(const sptr& node) const { - WLOGFI("Before apply constraints winRect:[%{public}d, %{public}d, %{public}u, %{public}u]", - winRect.posX_, winRect.posY_, winRect.width_, winRect.height_); - auto reason = node->GetWindowSizeChangeReason(); - DisplayId displayId = node->GetDisplayId(); - if (node->GetWindowType() == WindowType::WINDOW_TYPE_DOCK_SLICE) { - // make sure the divider is entirely within display - LimitDividerMoveBounds(winRect, displayId); - if (reason == WindowSizeChangeReason::DRAG_END) { - if (!IsVerticalDisplay(displayId)) { - UpdateDockSlicePosition(displayId, winRect.posX_); - } else { - UpdateDockSlicePosition(displayId, winRect.posY_); - } - } - /* - * use the layout orientation of the window and the layout orientation of the screen - * to determine whether the screen is rotating - */ - if ((!WindowHelper::IsLandscapeRect(winRect) && IsVerticalDisplay(displayId)) || - (WindowHelper::IsLandscapeRect(winRect) && !IsVerticalDisplay(displayId))) { - // resets the rect of the divider window when the screen is rotating - WLOGFD("Reset divider when display rotate rect:[%{public}d, %{public}d, %{public}u, %{public}u]", - winRect.posX_, winRect.posY_, winRect.width_, winRect.height_); - winRect = cascadeRectsMap_[displayId].dividerRect_; - node->SetRequestRect(winRect); - } + auto property = node->GetWindowProperty(); + if (property == nullptr) { + WLOGE("window property is nullptr"); + return; } + + if (!property->GetDecorEnable() || property->GetDecoStatus() || + node->GetWindowSizeChangeReason() == WindowSizeChangeReason::MOVE) { + return; + } + float virtualPixelRatio = displayGroupInfo_->GetDisplayVirtualPixelRatio(node->GetDisplayId()); + uint32_t winFrameW = static_cast(WINDOW_FRAME_WIDTH * virtualPixelRatio); + uint32_t winTitleBarH = static_cast(WINDOW_TITLE_BAR_HEIGHT * virtualPixelRatio); + + auto oriRect = property->GetRequestRect(); + Rect dstRect; + dstRect.posX_ = oriRect.posX_; + dstRect.posY_ = oriRect.posY_; + dstRect.width_ = oriRect.width_ + winFrameW + winFrameW; + dstRect.height_ = oriRect.height_ + winTitleBarH + winFrameW; + property->SetRequestRect(dstRect); + property->SetDecoStatus(true); +} + +void WindowLayoutPolicyCascade::ApplyWindowRectConstraints(const sptr& node, Rect& winRect) const +{ + WLOGFD("[Before constraints] windowId: %{public}u, winRect:[%{public}d, %{public}d, %{public}u, %{public}u]", + node->GetWindowId(), winRect.posX_, winRect.posY_, winRect.width_, winRect.height_); LimitFloatingWindowSize(node, displayGroupInfo_->GetDisplayRect(node->GetDisplayId()), winRect); LimitMainFloatingWindowPosition(node, winRect); - WLOGFI("After apply constraints winRect:[%{public}d, %{public}d, %{public}u, %{public}u]", - winRect.posX_, winRect.posY_, winRect.width_, winRect.height_); + WLOGFD("[After constraints] windowId: %{public}u, winRect:[%{public}d, %{public}d, %{public}u, %{public}u]", + node->GetWindowId(), winRect.posX_, winRect.posY_, winRect.width_, winRect.height_); } void WindowLayoutPolicyCascade::UpdateLayoutRect(const sptr& node) { - auto type = node->GetWindowType(); - auto mode = node->GetWindowMode(); auto property = node->GetWindowProperty(); if (property == nullptr) { WLOGFE("window property is nullptr."); return; } - UpdateWindowSizeLimits(node); - bool needAvoid = (node->GetWindowFlags() & static_cast(WindowFlag::WINDOW_FLAG_NEED_AVOID)); - bool parentLimit = (node->GetWindowFlags() & static_cast(WindowFlag::WINDOW_FLAG_PARENT_LIMIT)); - bool subWindow = WindowHelper::IsSubWindow(type) || WindowHelper::IsSystemSubWindow(type); - bool floatingWindow = (mode == WindowMode::WINDOW_MODE_FLOATING); - const Rect lastWinRect = node->GetWindowRect(); - Rect displayRect = GetDisplayRect(mode, node->GetDisplayId()); - Rect limitRect = displayRect; - ComputeDecoratedRequestRect(node); + auto mode = node->GetWindowMode(); Rect winRect = property->GetRequestRect(); - - WLOGFI("Id:%{public}u, avoid:%{public}d parLimit:%{public}d floating:%{public}d, sub:%{public}d, " \ - "deco:%{public}d, type:%{public}d, requestRect:[%{public}d, %{public}d, %{public}u, %{public}u]", - node->GetWindowId(), needAvoid, parentLimit, floatingWindow, subWindow, property->GetDecorEnable(), - static_cast(type), winRect.posX_, winRect.posY_, winRect.width_, winRect.height_); - if (needAvoid) { - limitRect = GetLimitRect(mode, node->GetDisplayId()); - } - - if (!floatingWindow) { // fullscreen window - winRect = limitRect; - } else { // floating window - if (subWindow && parentLimit && node->parent_) { // subwindow and limited by parent - limitRect = node->parent_->GetWindowRect(); - UpdateFloatingLayoutRect(limitRect, winRect); + auto displayId = node->GetDisplayId(); + WLOGFI("[Before CascadeLayout] windowId: %{public}u, mode: %{public}u, type: %{public}u requestRect: [%{public}d, " + "%{public}d, %{public}u, %{public}u]", node->GetWindowId(), mode, node->GetWindowType(), winRect.posX_, + winRect.posY_, winRect.width_, winRect.height_); + switch (mode) { + case WindowMode::WINDOW_MODE_SPLIT_PRIMARY: + winRect = cascadeRectsMap_[displayId].primaryRect_; + break; + case WindowMode::WINDOW_MODE_SPLIT_SECONDARY: + winRect = cascadeRectsMap_[displayId].secondaryRect_; + break; + case WindowMode::WINDOW_MODE_FULLSCREEN: { + bool needAvoid = (node->GetWindowFlags() & static_cast(WindowFlag::WINDOW_FLAG_NEED_AVOID)); + winRect = needAvoid ? limitRectMap_[displayId] : displayGroupInfo_->GetDisplayRect(displayId); + break; + } + case WindowMode::WINDOW_MODE_FLOATING: { + if (node->GetWindowType() == WindowType::WINDOW_TYPE_DOCK_SLICE) { + break; + } + UpdateWindowSizeLimits(node); + ComputeDecoratedRequestRect(node); + winRect = property->GetRequestRect(); + ApplyWindowRectConstraints(node, winRect); + break; } + default: + WLOGFW("Layout invalid mode, winId: %{public}u, mode: %{public}u", node->GetWindowId(), mode); } - ApplyWindowRectConstraints(node, winRect); + WLOGFI("[After CascadeLayout] windowId: %{public}u, isDecor: %{public}u, winRect: [%{public}d, %{public}d, " + "%{public}u, %{public}u]", node->GetWindowId(), node->GetDecoStatus(), winRect.posX_, winRect.posY_, + winRect.width_, winRect.height_); + + const Rect& lastWinRect = node->GetWindowRect(); node->SetWindowRect(winRect); + + // postProcess after update winRect CalcAndSetNodeHotZone(winRect, node); - // update node bounds before reset reason UpdateSurfaceBounds(node, winRect, lastWinRect); - UpdateClientRectAndResetReason(node, winRect); -} - -void WindowLayoutPolicyCascade::InitLimitRects(DisplayId displayId) -{ - limitRectMap_[displayId] = displayGroupInfo_->GetDisplayRect(displayId); - cascadeRectsMap_[displayId].primaryLimitRect_ = cascadeRectsMap_[displayId].primaryRect_; - cascadeRectsMap_[displayId].secondaryLimitRect_ = cascadeRectsMap_[displayId].secondaryRect_; - UpdateSplitRatioPoints(displayId); + NotifyClientAndAnimation(node, winRect, node->GetWindowSizeChangeReason()); } -Rect WindowLayoutPolicyCascade::GetLimitRect(const WindowMode mode, DisplayId displayId) const +void WindowLayoutPolicyCascade::LimitDividerPositionBySplitRatio(DisplayId displayId, Rect& winRect) const { - if (mode == WindowMode::WINDOW_MODE_SPLIT_PRIMARY) { - return cascadeRectsMap_[displayId].primaryLimitRect_; - } else if (mode == WindowMode::WINDOW_MODE_SPLIT_SECONDARY) { - return cascadeRectsMap_[displayId].secondaryLimitRect_; - } else { - return limitRectMap_[displayId]; - } -} - -Rect WindowLayoutPolicyCascade::GetDisplayRect(const WindowMode mode, DisplayId displayId) const -{ - if (mode == WindowMode::WINDOW_MODE_SPLIT_PRIMARY) { - return cascadeRectsMap_[displayId].primaryRect_; - } else if (mode == WindowMode::WINDOW_MODE_SPLIT_SECONDARY) { - return cascadeRectsMap_[displayId].secondaryRect_; - } else { - return displayGroupInfo_->GetDisplayRect(displayId); - } -} - -void WindowLayoutPolicyCascade::UpdateSplitRatioPoints(DisplayId displayId) -{ - LayoutRects& cascadeRects = cascadeRectsMap_[displayId]; - cascadeRects.exitSplitPoints_.clear(); - cascadeRects.splitRatioPoints_.clear(); - cascadeRects.exitSplitPoints_.push_back(GetSplitRatioPoint(splitRatioConfig_.exitSplitStartRatio, displayId)); - cascadeRects.exitSplitPoints_.push_back(GetSplitRatioPoint(splitRatioConfig_.exitSplitEndRatio, displayId)); - for (const auto& ratio : splitRatioConfig_.splitRatios) { - cascadeRects.splitRatioPoints_.push_back(GetSplitRatioPoint(ratio, displayId)); - } -} - -void WindowLayoutPolicyCascade::UpdateDockSlicePosition(DisplayId displayId, int32_t& origin) const -{ - const LayoutRects& cascadeRects = cascadeRectsMap_[displayId]; - if (cascadeRects.splitRatioPoints_.size() == 0) { + int32_t oriPos = IsVerticalDisplay(displayId) ? winRect.posY_ : winRect.posX_; + int32_t& dstPos = IsVerticalDisplay(displayId) ? winRect.posY_ : winRect.posX_; + if (splitRatioPointsMap_[displayId].size() == 0) { return; } uint32_t minDiff = std::max(limitRectMap_[displayId].width_, limitRectMap_[displayId].height_); - int32_t closestPoint = origin; - for (const auto& elem : cascadeRects.splitRatioPoints_) { - uint32_t diff = (origin > elem) ? (origin - elem) : (elem - origin); + int32_t closestPoint = oriPos; + for (const auto& elem : splitRatioPointsMap_[displayId]) { + uint32_t diff = (oriPos > elem) ? (oriPos - elem) : (elem - oriPos); if (diff < minDiff) { closestPoint = elem; minDiff = diff; } } - origin = closestPoint; -} - -void WindowLayoutPolicyCascade::UpdateSplitLimitRect(const Rect& limitRect, Rect& limitSplitRect) -{ - Rect curLimitRect = limitSplitRect; - limitSplitRect.posX_ = std::max(limitRect.posX_, curLimitRect.posX_); - limitSplitRect.posY_ = std::max(limitRect.posY_, curLimitRect.posY_); - limitSplitRect.width_ = std::min(limitRect.posX_ + limitRect.width_, - curLimitRect.posX_ + curLimitRect.width_) - - limitSplitRect.posX_; - limitSplitRect.height_ = std::min(limitRect.posY_ + limitRect.height_, - curLimitRect.posY_ + curLimitRect.height_) - - limitSplitRect.posY_; + dstPos = closestPoint; } void WindowLayoutPolicyCascade::InitSplitRects(DisplayId displayId) { - float virtualPixelRatio = GetVirtualPixelRatio(displayId); + float virtualPixelRatio = displayGroupInfo_->GetDisplayVirtualPixelRatio(displayId); uint32_t dividerWidth = static_cast(DIVIDER_WIDTH * virtualPixelRatio); auto& dividerRect = cascadeRectsMap_[displayId].dividerRect_; const auto& displayRect = displayGroupInfo_->GetDisplayRect(displayId); @@ -443,25 +371,10 @@ void WindowLayoutPolicyCascade::InitSplitRects(DisplayId displayId) dividerRect = { 0, static_cast((displayRect.height_ - dividerWidth) * DEFAULT_SPLIT_RATIO), displayRect.width_, dividerWidth }; } - WLOGFI("init dividerRect :[%{public}d, %{public}d, %{public}u, %{public}u]", - dividerRect.posX_, dividerRect.posY_, dividerRect.width_, dividerRect.height_); - SetSplitRect(dividerRect, displayId); -} - -int32_t WindowLayoutPolicyCascade::GetSplitRatioPoint(float ratio, DisplayId displayId) -{ - auto dividerRect = cascadeRectsMap_[displayId].dividerRect_; - auto displayRect = displayGroupInfo_->GetDisplayRect(displayId); - if (!IsVerticalDisplay(displayId)) { - return displayRect.posX_ + - static_cast((displayRect.width_ - dividerRect.width_) * ratio); - } else { - return displayRect.posY_ + - static_cast((displayRect.height_ - dividerRect.height_) * ratio); - } + SetSplitRectByDivider(dividerRect, displayId); } -void WindowLayoutPolicyCascade::SetSplitRect(const Rect& divRect, DisplayId displayId) +void WindowLayoutPolicyCascade::SetSplitRectByDivider(const Rect& divRect, DisplayId displayId) { auto& dividerRect = cascadeRectsMap_[displayId].dividerRect_; auto& primaryRect = cascadeRectsMap_[displayId].primaryRect_; @@ -491,47 +404,12 @@ void WindowLayoutPolicyCascade::SetSplitRect(const Rect& divRect, DisplayId disp secondaryRect.height_ = displayRect.height_ - secondaryRect.posY_; secondaryRect.width_ = displayRect.width_; } -} - -void WindowLayoutPolicyCascade::Reorder() -{ - WLOGFI("Cascade reorder start"); - for (auto& iter : displayGroupInfo_->GetAllDisplayRects()) { - DisplayId displayId = iter.first; - Rect rect = cascadeRectsMap_[displayId].firstCascadeRect_; - bool isFirstReorderedWindow = true; - const auto& appWindowNodeVec = *(displayGroupWindowTree_[displayId][WindowRootNodeType::APP_WINDOW_NODE]); - for (auto nodeIter = appWindowNodeVec.begin(); nodeIter != appWindowNodeVec.end(); nodeIter++) { - auto node = *nodeIter; - if (node == nullptr || node->GetWindowType() != WindowType::WINDOW_TYPE_APP_MAIN_WINDOW) { - WLOGFI("get node failed or not app window."); - continue; - } - // if window don't support floating mode, or default rect of cascade is not satisfied with limits - if (!WindowHelper::IsWindowModeSupported(node->GetModeSupportInfo(), WindowMode::WINDOW_MODE_FLOATING) || - !WindowHelper::IsRectSatisfiedWithSizeLimits(rect, node->GetWindowUpdatedSizeLimits())) { - MinimizeApp::AddNeedMinimizeApp(node, MinimizeReason::LAYOUT_CASCADE); - continue; - } - if (isFirstReorderedWindow) { - isFirstReorderedWindow = false; - } else { - rect = StepCascadeRect(rect, displayId); - } - node->SetRequestRect(rect); - node->SetDecoStatus(true); - if (node->GetWindowMode() != WindowMode::WINDOW_MODE_FLOATING) { - node->SetWindowMode(WindowMode::WINDOW_MODE_FLOATING); - if (node->GetWindowToken()) { - node->GetWindowToken()->UpdateWindowMode(WindowMode::WINDOW_MODE_FLOATING); - } - } - WLOGFI("Cascade reorder Id: %{public}d, rect:[%{public}d, %{public}d, %{public}d, %{public}d]", - node->GetWindowId(), rect.posX_, rect.posY_, rect.width_, rect.height_); - } - LayoutWindowTree(displayId); - } - WLOGFI("Reorder end"); + WLOGFD("DividerRect: [%{public}d %{public}d %{public}u %{public}u] " + "PrimaryRect: [%{public}d %{public}d %{public}u %{public}u] " + "SecondaryRect: [%{public}d %{public}d %{public}u %{public}u]", + dividerRect.posX_, dividerRect.posY_, dividerRect.width_, dividerRect.height_, + primaryRect.posX_, primaryRect.posY_, primaryRect.width_, primaryRect.height_, + secondaryRect.posX_, secondaryRect.posY_, secondaryRect.width_, secondaryRect.height_); } Rect WindowLayoutPolicyCascade::GetCurCascadeRect(const sptr& node) const @@ -553,7 +431,7 @@ Rect WindowLayoutPolicyCascade::GetCurCascadeRect(const sptr& node) cascadeRect = ((*iter)->GetWindowMode() == WindowMode::WINDOW_MODE_FLOATING ? property->GetWindowRect() : property->GetRequestRect()); } - WLOGFI("Get current cascadeRect: %{public}u [%{public}d, %{public}d, %{public}u, %{public}u]", + WLOGFD("Get current cascadeRect: %{public}u [%{public}d, %{public}d, %{public}u, %{public}u]", (*iter)->GetWindowId(), cascadeRect.posX_, cascadeRect.posY_, cascadeRect.width_, cascadeRect.height_); break; @@ -562,15 +440,15 @@ Rect WindowLayoutPolicyCascade::GetCurCascadeRect(const sptr& node) } if (WindowHelper::IsEmptyRect(cascadeRect)) { - WLOGFI("cascade rect is empty use first cascade rect"); - return cascadeRectsMap_[displayId].firstCascadeRect_; + WLOGFD("cascade rect is empty use first cascade rect"); + return cascadeRectsMap_[displayId].defaultCascadeRect_; } return StepCascadeRect(cascadeRect, displayId); } Rect WindowLayoutPolicyCascade::StepCascadeRect(Rect rect, DisplayId displayId) const { - float virtualPixelRatio = GetVirtualPixelRatio(displayId); + float virtualPixelRatio = displayGroupInfo_->GetDisplayVirtualPixelRatio(displayId); uint32_t cascadeWidth = static_cast(WINDOW_TITLE_BAR_HEIGHT * virtualPixelRatio); uint32_t cascadeHeight = static_cast(WINDOW_TITLE_BAR_HEIGHT * virtualPixelRatio); @@ -586,37 +464,42 @@ Rect WindowLayoutPolicyCascade::StepCascadeRect(Rect rect, DisplayId displayId) (rect.posY_ + static_cast(rect.height_ + cascadeHeight) <= (limitRect.posY_ + static_cast(limitRect.height_))) ? (rect.posY_ + static_cast(cascadeHeight)) : limitRect.posY_; - WLOGFI("step cascadeRect :[%{public}d, %{public}d, %{public}u, %{public}u]", + WLOGFD("Step cascadeRect :[%{public}d, %{public}d, %{public}u, %{public}u]", cascadeRect.posX_, cascadeRect.posY_, cascadeRect.width_, cascadeRect.height_); return cascadeRect; } -void WindowLayoutPolicyCascade::SetCascadeRect(const sptr& node) +void WindowLayoutPolicyCascade::SetDefaultCascadeRect(const sptr& node) { - static bool isFirstAppWindow = true; - Rect rect; auto property = node->GetWindowProperty(); if (property == nullptr) { WLOGFE("window property is nullptr."); return; } + if (!WindowHelper::IsEmptyRect(property->GetRequestRect())) { + return; + } + + static bool isFirstAppWindow = true; + Rect rect; if (WindowHelper::IsAppWindow(property->GetWindowType()) && isFirstAppWindow) { - WLOGFI("set first app window cascade rect"); - rect = cascadeRectsMap_[node->GetDisplayId()].firstCascadeRect_; + WLOGFD("Set first app window cascade rect"); + rect = cascadeRectsMap_[node->GetDisplayId()].defaultCascadeRect_; isFirstAppWindow = false; } else if (WindowHelper::IsAppWindow(property->GetWindowType()) && !isFirstAppWindow) { - WLOGFI("set other app window cascade rect"); + WLOGFD("Set other app window cascade rect"); rect = GetCurCascadeRect(node); } else { // system window - WLOGFI("set system window cascade rect"); - rect = cascadeRectsMap_[node->GetDisplayId()].firstCascadeRect_; + WLOGFD("Set system window cascade rect"); + rect = cascadeRectsMap_[node->GetDisplayId()].defaultCascadeRect_; } - WLOGFI("set cascadeRect :[%{public}d, %{public}d, %{public}u, %{public}u]", + WLOGFD("Set cascadeRect :[%{public}d, %{public}d, %{public}u, %{public}u]", rect.posX_, rect.posY_, rect.width_, rect.height_); node->SetRequestRect(rect); node->SetDecoStatus(true); } + Rect WindowLayoutPolicyCascade::GetDividerRect(DisplayId displayId) const { Rect dividerRect = {0, 0, 0, 0}; @@ -626,39 +509,31 @@ Rect WindowLayoutPolicyCascade::GetDividerRect(DisplayId displayId) const return dividerRect; } -void WindowLayoutPolicyCascade::UpdateWindowNodeRectOffset(const sptr& node) const +void WindowLayoutPolicyCascade::FixWindowRectWithinDisplay(const sptr& node) const { - WLOGFD("UpdateWindowNodeRectOffset, windowId: %{public}u", node->GetWindowId()); auto displayId = node->GetDisplayId(); const Rect& displayRect = displayGroupInfo_->GetDisplayRect(displayId); auto displayInfo = displayGroupInfo_->GetDisplayInfo(displayId); auto type = node->GetWindowType(); Rect rect = node->GetRequestRect(); - WLOGFD("RequestRect before, width: %{public}u, height: %{public}u, posX:%{public}d, posY:%{public}d", - rect.width_, rect.height_, rect.posX_, rect.posY_); switch (type) { - case WindowType::WINDOW_TYPE_STATUS_BAR: { + case WindowType::WINDOW_TYPE_STATUS_BAR: rect.posY_ = displayRect.posY_; break; - } - case WindowType::WINDOW_TYPE_NAVIGATION_BAR: { + case WindowType::WINDOW_TYPE_NAVIGATION_BAR: rect.posY_ = static_cast(displayRect.height_) + displayRect.posY_ - static_cast(rect.height_); break; - } - default: { - if (displayInfo->GetWaterfallDisplayCompressionStatus()) { - if (rect.posY_ < displayRect.posY_) { - rect.posY_ = displayRect.posY_; - } else if (rect.posY_ > displayRect.posY_ + static_cast(displayRect.height_)) { - rect.posY_ = displayRect.posY_ + static_cast(displayRect.height_); - } + default: + if (!displayInfo->GetWaterfallDisplayCompressionStatus()) { + return; } - } + rect.posY_ = std::max(rect.posY_, displayRect.posY_); + rect.posY_ = std::min(rect.posY_, displayRect.posY_ + static_cast(displayRect.height_)); } node->SetRequestRect(rect); - WLOGFD("RequestRect after, width: %{public}u, height: %{public}u, posX:%{public}d, posY:%{public}d", - rect.width_, rect.height_, rect.posX_, rect.posY_); + WLOGFD("[After fix rect], winId: %{public}d, requestRect: [%{public}d, %{public}d, %{public}u, %{public}u]", + node->GetWindowId(), rect.posX_, rect.posY_, rect.width_, rect.height_); } } // Rosen } // OHOS diff --git a/wmserver/src/window_layout_policy_tile.cpp b/wmserver/src/window_layout_policy_tile.cpp index 1937d09c34..bf862f570d 100644 --- a/wmserver/src/window_layout_policy_tile.cpp +++ b/wmserver/src/window_layout_policy_tile.cpp @@ -34,42 +34,23 @@ WindowLayoutPolicyTile::WindowLayoutPolicyTile(const sptr& dis DisplayGroupWindowTree& displayGroupWindowTree) : WindowLayoutPolicy(displayGroupInfo, displayGroupWindowTree) { - for (auto& iter : displayGroupInfo_->GetAllDisplayRects()) { - maxTileWinNumMap_.insert(std::make_pair(iter.first, static_cast(1))); - } } void WindowLayoutPolicyTile::Launch() { - // compute limit rect - InitAllRects(); - // select app min win in queue, and minimize others - InitForegroundNodeQueue(); - for (auto& iter : displayGroupInfo_->GetAllDisplayRects()) { - DisplayId displayId = iter.first; - AssignNodePropertyForTileWindows(displayId); - LayoutForegroundNodeQueue(displayId); - auto& displayWindowTree = displayGroupWindowTree_[displayId]; - LayoutWindowNodesByRootType(*(displayWindowTree[WindowRootNodeType::BELOW_WINDOW_NODE])); - } - WLOGFI("WindowLayoutPolicyTile::Launch"); -} - -void WindowLayoutPolicyTile::InitAllRects() -{ - displayGroupLimitRect_ = displayGroupRect_; for (auto& iter : displayGroupInfo_->GetAllDisplayRects()) { - DisplayId displayId = iter.first; - limitRectMap_[displayId] = iter.second; - auto& displayWindowTree = displayGroupWindowTree_[displayId]; - LayoutWindowNodesByRootType(*(displayWindowTree[WindowRootNodeType::ABOVE_WINDOW_NODE])); - InitTileWindowRects(displayId); + const auto& displayId = iter.first; + InitTileRects(displayId); + InitTileQueue(displayId); + LayoutTileQueue(displayId); + WLOGFD("[Launch TileLayout], displayId: %{public}" PRIu64"", displayId); } + WLOGFI("[Launch TileLayout Finished]"); } uint32_t WindowLayoutPolicyTile::GetMaxTileWinNum(DisplayId displayId) const { - float virtualPixelRatio = GetVirtualPixelRatio(displayId); + float virtualPixelRatio = displayGroupInfo_->GetDisplayVirtualPixelRatio(displayId); constexpr uint32_t half = 2; uint32_t edgeIntervalVp = static_cast(EDGE_INTERVAL * half * virtualPixelRatio); uint32_t midIntervalVp = static_cast(MID_INTERVAL * virtualPixelRatio); @@ -78,20 +59,27 @@ uint32_t WindowLayoutPolicyTile::GetMaxTileWinNum(DisplayId displayId) const return static_cast(drawableW / (minFloatingW + midIntervalVp)); } -void WindowLayoutPolicyTile::InitTileWindowRects(DisplayId displayId) +void WindowLayoutPolicyTile::InitTileRects(DisplayId displayId) { - float virtualPixelRatio = GetVirtualPixelRatio(displayId); + // TileLayout don't consider limitRect yet, limitDisplay equals to displayRect + const auto& displayRect = displayGroupInfo_->GetDisplayRect(displayId); + if (WindowHelper::IsEmptyRect(displayRect)) { + WLOGFE("DisplayRect is empty, displayRect: %{public}" PRIu64"", displayId); + return; + } + + limitRectMap_[displayId] = displayRect; + float virtualPixelRatio = displayGroupInfo_->GetDisplayVirtualPixelRatio(displayId); uint32_t edgeIntervalVp = static_cast(EDGE_INTERVAL * virtualPixelRatio); uint32_t midIntervalVp = static_cast(MID_INTERVAL * virtualPixelRatio); constexpr float ratio = DEFAULT_ASPECT_RATIO; const Rect& limitRect = limitRectMap_[displayId]; - const Rect& displayRect = displayGroupInfo_->GetDisplayRect(displayId); constexpr int half = 2; - maxTileWinNumMap_[displayId] = GetMaxTileWinNum(displayId); - WLOGFI("set max tile window num %{public}u", maxTileWinNumMap_[displayId]); - auto& presetRects = presetRectsMap_[displayId]; - presetRects.clear(); + maxTileWinNumMap_[displayId] = GetMaxTileWinNum(displayId); + WLOGFD("set max tile window num %{public}u", maxTileWinNumMap_[displayId]); + auto& presetRectsForAllLevel = presetRectsMap_[displayId]; + presetRectsForAllLevel.clear(); uint32_t w = displayRect.width_ * ratio; uint32_t h = displayRect.height_ * ratio; w = w > limitRect.width_ ? limitRect.width_ : w; @@ -100,18 +88,29 @@ void WindowLayoutPolicyTile::InitTileWindowRects(DisplayId displayId) int y = limitRect.posY_ + ((limitRect.height_ - h) / half); std::vector single = {{ x, y, w, h }}; - presetRects.emplace_back(single); + presetRectsForAllLevel.emplace_back(single); for (uint32_t num = 2; num <= maxTileWinNumMap_[displayId]; num++) { // start calc preset with 2 windows w = (limitRect.width_ - edgeIntervalVp * half - midIntervalVp * (num - 1)) / num; std::vector curLevel; for (uint32_t i = 0; i < num; i++) { int curX = limitRect.posX_ + edgeIntervalVp + i * (w + midIntervalVp); Rect curRect = { curX, y, w, h }; - WLOGFI("presetRects: level %{public}u, id %{public}u, [%{public}d %{public}d %{public}u %{public}u]", - num, i, curX, y, w, h); + WLOGFD("presetRectsForAllLevel: level %{public}u, id %{public}u, tileRect: [%{public}d %{public}d " + "%{public}u %{public}u]", num, i, curX, y, w, h); curLevel.emplace_back(curRect); } - presetRects.emplace_back(curLevel); + presetRectsForAllLevel.emplace_back(curLevel); + } +} + +void WindowLayoutPolicyTile::InitTileQueue(DisplayId displayId) +{ + foregroundNodesMap_[displayId].clear(); + const auto& appWindowNodes = *(displayGroupWindowTree_[displayId][WindowRootNodeType::APP_WINDOW_NODE]); + for (auto& node : appWindowNodes) { + if (WindowHelper::IsMainWindow(node->GetWindowType())) { + PushBackNodeInTileQueue(node, displayId); + } } } @@ -127,132 +126,106 @@ bool WindowLayoutPolicyTile::IsTileRectSatisfiedWithSizeLimits(const sptr foregroundNode) { - return foregroundNode->GetWindowId() == node->GetWindowId(); - }); - if (iter != foregroundNodes.end()) { + if (IsWindowAlreadyInTileQueue(node)) { return true; } - const auto& presetRects = presetRectsMap_[displayId]; + UpdateWindowSizeLimits(node); + const auto& presetRectsForAllLevel = presetRectsMap_[displayId]; Rect tileRect; // if size of foreground nodes is equal to or more than max tile window number if (num == maxTileWinNumMap_[displayId]) { - tileRect = *(presetRects[num - 1].begin()); + tileRect = *(presetRectsForAllLevel[num - 1].begin()); } else { // if size of foreground nodes is less than max tile window number - tileRect = *(presetRects[num].begin()); + tileRect = *(presetRectsForAllLevel[num].begin()); } - WLOGFI("id %{public}u, tileRect: [%{public}d %{public}d %{public}u %{public}u]", + WLOGFD("id %{public}u, tileRect: [%{public}d %{public}d %{public}u %{public}u]", node->GetWindowId(), tileRect.posX_, tileRect.posY_, tileRect.width_, tileRect.height_); return WindowHelper::IsRectSatisfiedWithSizeLimits(tileRect, node->GetWindowUpdatedSizeLimits()); } -void WindowLayoutPolicyTile::AddWindowNode(const sptr& node) +void WindowLayoutPolicyTile::PerformWindowLayout(const sptr& node, WindowUpdateType updateType) { HITRACE_METER(HITRACE_TAG_WINDOW_MANAGER); - - if (WindowHelper::IsMainWindow(node->GetWindowType())) { - DisplayId displayId = node->GetDisplayId(); - ForegroundNodeQueuePushBack(node, displayId); - AssignNodePropertyForTileWindows(displayId); - LayoutForegroundNodeQueue(displayId); - } else { - UpdateWindowNode(node); // currently, update and add do the same process - } -} - -void WindowLayoutPolicyTile::UpdateWindowNode(const sptr& node, bool isAddWindow) -{ - HITRACE_METER(HITRACE_TAG_WINDOW_MANAGER); - WindowLayoutPolicy::UpdateWindowNode(node); - if (avoidTypes_.find(node->GetWindowType()) != avoidTypes_.end()) { - DisplayId displayId = node->GetDisplayId(); - InitTileWindowRects(displayId); - AssignNodePropertyForTileWindows(displayId); - LayoutForegroundNodeQueue(displayId); - } -} - -void WindowLayoutPolicyTile::RemoveWindowNode(const sptr& node) -{ - HITRACE_METER(HITRACE_TAG_WINDOW_MANAGER); - WLOGFI("RemoveWindowNode %{public}u in tile", node->GetWindowId()); - auto type = node->GetWindowType(); - auto displayId = node->GetDisplayId(); - // affect other windows, trigger off global layout - if (avoidTypes_.find(type) != avoidTypes_.end()) { - LayoutWindowTree(displayId); - } else { - ForegroundNodeQueueRemove(node); - AssignNodePropertyForTileWindows(displayId); - LayoutForegroundNodeQueue(displayId); + const auto& windowType = node->GetWindowType(); + const auto& requestRect = node->GetRequestRect(); + WLOGFI("[PerformWindowLayout] windowId: %{public}u, windowType: %{public}u, updateType: %{public}u, requestRect: " + "requestRect: [%{public}d, %{public}d, %{public}u, %{public}u]", node->GetWindowId(), windowType, updateType, + requestRect.posX_, requestRect.posY_, requestRect.width_, requestRect.height_); + switch (updateType) { + case WindowUpdateType::WINDOW_UPDATE_ADDED: { + if (WindowHelper::IsMainWindow(windowType)) { + PushBackNodeInTileQueue(node, node->GetDisplayId()); + LayoutTileQueue(node->GetDisplayId()); + return; + } + break; + } + case WindowUpdateType::WINDOW_UPDATE_REMOVED: { + if (WindowHelper::IsMainWindow(windowType)) { + RemoveNodeFromTileQueue(node); + LayoutTileQueue(node->GetDisplayId()); + } + NotifyClientAndAnimation(node, node->GetRequestRect(), WindowSizeChangeReason::HIDE); + return; + } + default: + WLOGFD("Update type is not add or remove"); } - UpdateClientRect(node->GetRequestRect(), node, WindowSizeChangeReason::HIDE); + LayoutWindowNode(node); } -void WindowLayoutPolicyTile::LayoutForegroundNodeQueue(DisplayId displayId) +void WindowLayoutPolicyTile::LayoutTileQueue(DisplayId displayId) { + ApplyPresetRectForTileWindows(displayId); for (auto& node : foregroundNodesMap_[displayId]) { - Rect winRect = node->GetRequestRect(); - Rect lastRect = node->GetWindowRect(); - node->SetWindowRect(winRect); - CalcAndSetNodeHotZone(winRect, node); - UpdateClientRect(winRect, node, node->GetWindowSizeChangeReason()); - UpdateSurfaceBounds(node, winRect, lastRect); - for (auto& childNode : node->children_) { - LayoutWindowNode(childNode); - } + LayoutWindowNode(node); } } -void WindowLayoutPolicyTile::InitForegroundNodeQueue() +bool WindowLayoutPolicyTile::IsWindowAlreadyInTileQueue(const sptr& node) { - for (auto& iter : displayGroupInfo_->GetAllDisplayRects()) { - DisplayId displayId = iter.first; - foregroundNodesMap_[displayId].clear(); - const auto& appWindowNodes = *(displayGroupWindowTree_[displayId][WindowRootNodeType::APP_WINDOW_NODE]); - for (auto& node : appWindowNodes) { - if (WindowHelper::IsMainWindow(node->GetWindowType())) { - ForegroundNodeQueuePushBack(node, displayId); - } - } + auto& foregroundNodes = foregroundNodesMap_[node->GetDisplayId()]; + auto iter = std::find_if(foregroundNodes.begin(), foregroundNodes.end(), + [node](sptr foregroundNode) { + return foregroundNode->GetWindowId() == node->GetWindowId(); + }); + if (iter != foregroundNodes.end()) { + WLOGFD("Window is already in tile queue, windowId: %{public}d", node->GetWindowId()); + return true; } + return false; } -void WindowLayoutPolicyTile::ForegroundNodeQueuePushBack(const sptr& node, DisplayId displayId) +void WindowLayoutPolicyTile::PushBackNodeInTileQueue(const sptr& node, DisplayId displayId) { if (node == nullptr) { return; } - auto& foregroundNodes = foregroundNodesMap_[displayId]; - auto iter = std::find_if(foregroundNodes.begin(), foregroundNodes.end(), - [node](sptr foregroundNode) { - return foregroundNode->GetWindowId() == node->GetWindowId(); - }); - if (iter != foregroundNodes.end()) { + if (IsWindowAlreadyInTileQueue(node)) { return; } if (!WindowHelper::IsWindowModeSupported(node->GetModeSupportInfo(), WindowMode::WINDOW_MODE_FLOATING)) { - WLOGFD("window don't support tile mode, winId: %{public}d", node->GetWindowId()); + WLOGFD("Window don't support floating mode that should be minimized, winId: %{public}u, " + "modeSupportInfo: %{public}u", node->GetWindowId(), node->GetModeSupportInfo()); MinimizeApp::AddNeedMinimizeApp(node, MinimizeReason::LAYOUT_TILE); return; } - WLOGFI("add win in tile, displayId: %{public}" PRIu64", winId: %{public}d", displayId, node->GetWindowId()); + auto& foregroundNodes = foregroundNodesMap_[displayId]; while (foregroundNodes.size() >= maxTileWinNumMap_[displayId]) { auto removeNode = foregroundNodes.front(); foregroundNodes.pop_front(); - WLOGFI("pop win in queue head for add new win, windowId: %{public}d", removeNode->GetWindowId()); + WLOGFD("Minimize win in queue head for add new win, windowId: %{public}d", removeNode->GetWindowId()); MinimizeApp::AddNeedMinimizeApp(removeNode, MinimizeReason::LAYOUT_TILE); } foregroundNodes.push_back(node); + WLOGFD("Pusk back win in tile queue, displayId: %{public}" PRIu64", winId: %{public}d", + displayId, node->GetWindowId()); } -void WindowLayoutPolicyTile::ForegroundNodeQueueRemove(const sptr& node) +void WindowLayoutPolicyTile::RemoveNodeFromTileQueue(const sptr& node) { if (node == nullptr) { return; @@ -261,114 +234,128 @@ void WindowLayoutPolicyTile::ForegroundNodeQueueRemove(const sptr& n auto& foregroundNodes = foregroundNodesMap_[displayId]; auto iter = std::find(foregroundNodes.begin(), foregroundNodes.end(), node); if (iter != foregroundNodes.end()) { - WLOGFI("remove win in tile for win id: %{public}d", node->GetWindowId()); + WLOGFD("Remove win in tile for win id: %{public}d", node->GetWindowId()); foregroundNodes.erase(iter); } } -void WindowLayoutPolicyTile::AssignNodePropertyForTileWindows(DisplayId displayId) +bool WindowLayoutPolicyTile::IsValidTileQueueAndPresetRects(DisplayId displayId) { - // set rect for foreground windows auto& foregroundNodes = foregroundNodesMap_[displayId]; uint32_t num = foregroundNodes.size(); - auto& presetRects = presetRectsMap_[displayId]; - if (num > maxTileWinNumMap_[displayId] || num > presetRects.size() || num == 0) { - WLOGE("invalid tile queue"); - return; + auto& presetRectsForAllLevel = presetRectsMap_[displayId]; + if (num > maxTileWinNumMap_[displayId] || num > presetRectsForAllLevel.size() || num == 0) { + WLOGE("Invalid tile queue, foreground tileNum: %{public}u, maxTileNum: %{public}u, presetRectsForAllLevel: " + "%{public}u", num, maxTileWinNumMap_[displayId], static_cast(presetRectsForAllLevel.size())); + return false; } - std::vector& presetRect = presetRects[num - 1]; + auto& presetRect = presetRectsForAllLevel[num - 1]; if (presetRect.size() != num) { - WLOGE("invalid preset rects"); + WLOGE("Invalid preset rects, foreground tileNum: %{public}u, presetRect.size(): %{public}u", + num, static_cast(presetRect.size())); + return false; + } + return true; +} + +void WindowLayoutPolicyTile::RefreshTileQueue(DisplayId displayId, + std::vector>& needMinimizeNodes, std::vector>& needRecoverNodes) +{ + /* + * Usually, needMinimizeNodes and needRecoverNodes will be empty, there is no need to refresh tile queue + */ + auto& foregroundNodes = foregroundNodesMap_[displayId]; + if (needMinimizeNodes.empty() && needRecoverNodes.empty()) { + WLOGD("No need to refresh tileQueue"); return; } - auto rectIt = presetRect.begin(); + + WLOGD("Update tile queue for the nodes which should be minimized or recovered"); + for (auto& miniNode : needMinimizeNodes) { + auto iter = std::find(foregroundNodes.begin(), foregroundNodes.end(), miniNode); + if (iter != foregroundNodes.end()) { + foregroundNodes.erase(iter); + } + } + for (auto& recNode : needRecoverNodes) { + auto iter = std::find(foregroundNodes.begin(), foregroundNodes.end(), recNode); + if (iter == foregroundNodes.end()) { + foregroundNodes.push_back(recNode); + } + } + ApplyPresetRectForTileWindows(displayId); + needMinimizeNodes.clear(); + needRecoverNodes.clear(); +} + +void WindowLayoutPolicyTile::ApplyPresetRectForTileWindows(DisplayId displayId) +{ + if (!(IsValidTileQueueAndPresetRects(displayId))) { + return; + } + + auto& foregroundNodes = foregroundNodesMap_[displayId]; + uint32_t num = foregroundNodes.size(); + auto rectIt = presetRectsMap_[displayId][num - 1].begin(); std::vector> needMinimizeNodes; std::vector> needRecoverNodes; for (auto node : foregroundNodes) { auto& rect = (*rectIt); - if (WindowHelper::IsWindowModeSupported(node->GetModeSupportInfo(), WindowMode::WINDOW_MODE_FLOATING) && - WindowHelper::IsRectSatisfiedWithSizeLimits(rect, node->GetWindowUpdatedSizeLimits())) { + if (WindowHelper::IsRectSatisfiedWithSizeLimits(rect, node->GetWindowUpdatedSizeLimits())) { node->SetWindowMode(WindowMode::WINDOW_MODE_FLOATING); if (node->GetWindowToken()) { node->GetWindowToken()->UpdateWindowMode(WindowMode::WINDOW_MODE_FLOATING); } node->SetRequestRect(rect); node->SetDecoStatus(true); - WLOGFI("set rect for qwin id: %{public}d [%{public}d %{public}d %{public}d %{public}d]", - node->GetWindowId(), rect.posX_, rect.posY_, rect.width_, rect.height_); rectIt++; + WLOGFD("Set preset rect for tileWin, id: %{public}d [%{public}d %{public}d %{public}d %{public}d]", + node->GetWindowId(), rect.posX_, rect.posY_, rect.width_, rect.height_); } else { - // if foreground nodes is equal to max tileWinNum, means need recover one node before minimize cur node + WLOGFD("Minimize node which can't be applied to tileRect, winId: %{public}u", node->GetWindowId()); if (num == maxTileWinNumMap_[displayId]) { + // if foreground nodes equal to max tileWinNum, means need to recover one node before minimize curNode auto recoverNode = MinimizeApp::GetRecoverdNodeFromMinimizeList(); if (recoverNode != nullptr) { needRecoverNodes.push_back(recoverNode); + WLOGFD("Cancel minimize node from minimizeList, winId: %{public}u", node->GetWindowId()); } } needMinimizeNodes.push_back(node); MinimizeApp::AddNeedMinimizeApp(node, MinimizeReason::LAYOUT_TILE); + break; } } - for (auto& miniNode : needMinimizeNodes) { - auto iter = std::find(foregroundNodes.begin(), foregroundNodes.end(), miniNode); - if (iter != foregroundNodes.end()) { - foregroundNodes.erase(iter); - } - } - needMinimizeNodes.clear(); - for (auto& recNode : needRecoverNodes) { - foregroundNodes.push_back(recNode); - } - needRecoverNodes.clear(); + RefreshTileQueue(displayId, needMinimizeNodes, needRecoverNodes); } void WindowLayoutPolicyTile::UpdateLayoutRect(const sptr& node) { - auto type = node->GetWindowType(); - auto mode = node->GetWindowMode(); - auto flags = node->GetWindowFlags(); - auto property = node->GetWindowProperty(); - if (property == nullptr) { - WLOGFE("window property is nullptr."); - return; - } UpdateWindowSizeLimits(node); - auto decorEnable = property->GetDecorEnable(); - bool needAvoid = (flags & static_cast(WindowFlag::WINDOW_FLAG_NEED_AVOID)); - bool parentLimit = (flags & static_cast(WindowFlag::WINDOW_FLAG_PARENT_LIMIT)); - bool subWindow = WindowHelper::IsSubWindow(type) || WindowHelper::IsSystemSubWindow(type); - bool floatingWindow = (mode == WindowMode::WINDOW_MODE_FLOATING); - const Rect lastRect = node->GetWindowRect(); - Rect limitRect = displayGroupInfo_->GetDisplayRect(node->GetDisplayId()); - ComputeDecoratedRequestRect(node); + bool floatingWindow = (node->GetWindowMode() == WindowMode::WINDOW_MODE_FLOATING); + bool needAvoid = (node->GetWindowFlags() & static_cast(WindowFlag::WINDOW_FLAG_NEED_AVOID)); + Rect lastRect = node->GetWindowRect(); Rect winRect = node->GetRequestRect(); - - WLOGFI("Id:%{public}u, avoid:%{public}d parLimit:%{public}d floating:%{public}d, sub:%{public}d, " \ - "deco:%{public}d, type:%{public}u, requestRect:[%{public}d, %{public}d, %{public}u, %{public}u]", - node->GetWindowId(), needAvoid, parentLimit, floatingWindow, subWindow, decorEnable, - static_cast(type), winRect.posX_, winRect.posY_, winRect.width_, winRect.height_); - if (needAvoid) { - limitRect = limitRectMap_[node->GetDisplayId()]; - } + WLOGFI("[Before TileLayout] windowId: %{public}u, mode: %{public}u, type: %{public}u requestRect: [%{public}d, " + "%{public}d, %{public}u, %{public}u]", node->GetWindowId(), node->GetWindowMode(), node->GetWindowType(), + winRect.posX_, winRect.posY_, winRect.width_, winRect.height_); if (!floatingWindow) { // fullscreen window - winRect = limitRect; - } else { // floating window - if (subWindow && parentLimit && node->parent_) { // subwindow and limited by parent - limitRect = node->parent_->GetWindowRect(); - UpdateFloatingLayoutRect(limitRect, winRect); - } + const auto& displayRect = displayGroupInfo_->GetDisplayRect(node->GetDisplayId()); + const auto& limitDisplayRect = limitRectMap_[node->GetDisplayId()]; + winRect = needAvoid ? limitDisplayRect : displayRect; } - LimitFloatingWindowSize(node, displayGroupInfo_->GetDisplayRect(node->GetDisplayId()), winRect); - LimitMainFloatingWindowPosition(node, winRect); - + WLOGFI("[After TileLayout] windowId: %{public}u, isDecor: %{public}u, winRect: [%{public}d, %{public}d, " + "%{public}u, %{public}u]", node->GetWindowId(), node->GetDecoStatus(), winRect.posX_, winRect.posY_, + winRect.width_, winRect.height_); node->SetWindowRect(winRect); + + // postProcess after update winRect CalcAndSetNodeHotZone(winRect, node); - // update Node Bounds before reset Reason UpdateSurfaceBounds(node, winRect, lastRect); - UpdateClientRectAndResetReason(node, winRect); + NotifyClientAndAnimation(node, winRect, node->GetWindowSizeChangeReason()); } } // Rosen } // OHOS diff --git a/wmserver/src/window_node_container.cpp b/wmserver/src/window_node_container.cpp index 8211e7e682..2b8ae6bdfb 100644 --- a/wmserver/src/window_node_container.cpp +++ b/wmserver/src/window_node_container.cpp @@ -70,8 +70,13 @@ WindowNodeContainer::WindowNodeContainer(const sptr& displayInfo, S layoutPolicy_ = layoutPolicies_[WindowLayoutMode::CASCADE]; layoutPolicy_->Launch(); - Rect initalDividerRect = layoutPolicies_[WindowLayoutMode::CASCADE]->GetDividerRect(displayId); - displayGroupController_->SetDividerRect(displayId, initalDividerRect); + // set initial divider rect in windowPair + Rect initialDivRect = layoutPolicies_[WindowLayoutMode::CASCADE]->GetDividerRect(displayId); + auto windowPair = displayGroupController_->GetWindowPairByDisplayId(displayId); + if (windowPair != nullptr) { + windowPair->SetDividerRect(initialDivRect); + } + // init avoidAreaController avoidController_ = new AvoidAreaController(focusedWindow_); } @@ -150,7 +155,7 @@ WMError WindowNodeContainer::ShowStartingWindow(sptr& node) displayGroupController_->PreProcessWindowNode(node, WindowUpdateType::WINDOW_UPDATE_ADDED); StartingWindow::AddNodeOnRSTree(node, animationConfig_, layoutPolicy_->IsMultiDisplay()); AssignZOrder(); - layoutPolicy_->AddWindowNode(node); + layoutPolicy_->PerformWindowLayout(node, WindowUpdateType::WINDOW_UPDATE_ADDED); WLOGFI("ShowStartingWindow windowId: %{public}u end", node->GetWindowId()); return WMError::WM_OK; } @@ -174,7 +179,7 @@ AnimationConfig& WindowNodeContainer::GetAnimationConfigRef() void WindowNodeContainer::LayoutWhenAddWindowNode(sptr& node, bool afterAnimation) { if (afterAnimation) { - layoutPolicy_->AddWindowNode(node); + layoutPolicy_->PerformWindowLayout(node, WindowUpdateType::WINDOW_UPDATE_ADDED); return; } WLOGFI("AddWindowNode windowId:%{public}u, name:%{public}s currState:%{public}u", @@ -187,16 +192,16 @@ void WindowNodeContainer::LayoutWhenAddWindowNode(sptr& node, bool a auto winRect = node->GetWindowRect(); if (node->surfaceNode_) { node->surfaceNode_->SetBounds(0, 0, winRect.width_, winRect.height_); - WLOGFI("notify client and SetBounds id:%{public}u, rect:[%{public}d, %{public}d, %{public}u, %{public}u]", + WLOGFI("SetBounds id:%{public}u, rect:[%{public}d, %{public}d, %{public}u, %{public}u]", node->GetWindowId(), winRect.posX_, winRect.posY_, winRect.width_, winRect.height_); - layoutPolicy_->UpdateClientRect(node->GetWindowRect(), node, WindowSizeChangeReason::UNDEFINED); + layoutPolicy_->NotifyClientAndAnimation(node, winRect, WindowSizeChangeReason::UNDEFINED); } } else { if (node->GetWindowProperty()->GetAnimationFlag() == static_cast(WindowAnimation::CUSTOM) && WindowHelper::IsSystemWindow(node->GetWindowType())) { node->SetWindowSizeChangeReason(WindowSizeChangeReason::CUSTOM_ANIMATION_SHOW); } - layoutPolicy_->AddWindowNode(node); + layoutPolicy_->PerformWindowLayout(node, WindowUpdateType::WINDOW_UPDATE_ADDED); } } @@ -284,7 +289,7 @@ WMError WindowNodeContainer::UpdateWindowNode(sptr& node, WindowUpda if (WindowHelper::IsMainWindow(node->GetWindowType()) && WindowHelper::IsSwitchCascadeReason(reason)) { SwitchLayoutPolicy(WindowLayoutMode::CASCADE, node->GetDisplayId()); } - layoutPolicy_->UpdateWindowNode(node); + layoutPolicy_->PerformWindowLayout(node, WindowUpdateType::WINDOW_UPDATE_ACTIVE); displayGroupController_->PostProcessWindowNode(node); // Get current displayId and showing displays, update RSTree and displayGroupWindowTree UpdateRSTreeWhenShowingDisplaysChange(node, lastShowingDisplays); @@ -339,8 +344,7 @@ WMError WindowNodeContainer::RemoveWindowNode(sptr& node, bool fromA node->currentVisibility_ = false; RemoveFromRsTreeWhenRemoveWindowNode(node, fromAnimation); displayGroupController_->UpdateDisplayGroupWindowTree(); - - layoutPolicy_->RemoveWindowNode(node); + layoutPolicy_->PerformWindowLayout(node, WindowUpdateType::WINDOW_UPDATE_REMOVED); WindowMode lastMode = node->GetWindowMode(); if (HandleRemoveWindow(node) != WMError::WM_OK) { return WMError::WM_ERROR_NULLPTR; @@ -415,17 +419,15 @@ void WindowNodeContainer::UpdateSizeChangeReason(sptr& node, WindowS return; } if (node->GetWindowType() == WindowType::WINDOW_TYPE_DOCK_SLICE) { - for (auto& childNode : appWindowNode_->children_) { - if (childNode->IsSplitMode()) { - layoutPolicy_->UpdateClientRect(childNode->GetWindowRect(), childNode, reason); - childNode->ResetWindowSizeChangeReason(); - WLOGFI("Notify split window that the drag action is start or end, windowId: %{public}d, " - "reason: %{public}u", childNode->GetWindowId(), reason); + for (auto& child : appWindowNode_->children_) { + if (child->IsSplitMode() && child->GetWindowToken()) { + layoutPolicy_->NotifyClientAndAnimation(child, child->GetWindowRect(), reason); + WLOGFI("Notify split window that the drag action is start or end, windowId: " + "%{public}d, reason: %{public}u", child->GetWindowId(), reason); } } } else { - layoutPolicy_->UpdateClientRect(node->GetWindowRect(), node, reason); - node->ResetWindowSizeChangeReason(); + layoutPolicy_->NotifyClientAndAnimation(node, node->GetWindowRect(), reason); WLOGFI("Notify window that the drag action is start or end, windowId: %{public}d, " "reason: %{public}u", node->GetWindowId(), reason); } @@ -799,7 +801,7 @@ sptr WindowNodeContainer::GetAvoidController() const return avoidController_; } -sptr WindowNodeContainer::GetMultiDisplayController() const +sptr WindowNodeContainer::GetDisplayGroupController() const { return displayGroupController_; } @@ -1428,7 +1430,7 @@ bool WindowNodeContainer::IsDockSliceInExitSplitModeArea(DisplayId displayId) co WLOGFE("window pair is nullptr"); return false; } - std::vector exitSplitPoints = layoutPolicy_->GetExitSplitPoints(displayId); + std::vector exitSplitPoints = windowPair->GetExitSplitPoints(); if (exitSplitPoints.size() != EXIT_SPLIT_POINTS_NUMBER) { return false; } @@ -1630,11 +1632,6 @@ WMError WindowNodeContainer::MinimizeStructuredAppWindowsExceptSelf(const sptrReset(); -} - WMError WindowNodeContainer::SwitchLayoutPolicy(WindowLayoutMode dstMode, DisplayId displayId, bool reorder) { WLOGFI("SwitchLayoutPolicy src: %{public}d dst: %{public}d, reorder: %{public}d, displayId: %{public}" PRIu64"", @@ -1650,11 +1647,9 @@ WMError WindowNodeContainer::SwitchLayoutPolicy(WindowLayoutMode dstMode, Displa } if (layoutMode_ != dstMode) { if (layoutMode_ == WindowLayoutMode::CASCADE) { - layoutPolicy_->Reset(); windowPair->Clear(); } layoutMode_ = dstMode; - layoutPolicy_->Clean(); layoutPolicy_ = layoutPolicies_[dstMode]; layoutPolicy_->Launch(); DumpScreenWindowTree(); @@ -1869,11 +1864,6 @@ bool WindowNodeContainer::TraverseFromBottomToTop(sptr node, const W return false; } -float WindowNodeContainer::GetVirtualPixelRatio(DisplayId displayId) const -{ - return layoutPolicy_->GetVirtualPixelRatio(displayId); -} - Rect WindowNodeContainer::GetDisplayGroupRect() const { return layoutPolicy_->GetDisplayGroupRect(); diff --git a/wmserver/src/window_pair.cpp b/wmserver/src/window_pair.cpp index 5399a2ec37..85dfccb87a 100644 --- a/wmserver/src/window_pair.cpp +++ b/wmserver/src/window_pair.cpp @@ -496,5 +496,42 @@ void WindowPair::ClearPairSnapshot() secondary_->SetSnapshot(nullptr); } } + +int32_t WindowPair::GetSplitRatioPoint(float ratio, const Rect& displayRect) +{ + if (displayRect.width_ > displayRect.height_) { + return displayRect.posX_ + + static_cast((displayRect.width_ - dividerRect_.width_) * ratio); + } else { + return displayRect.posY_ + + static_cast((displayRect.height_ - dividerRect_.height_) * ratio); + } +} + +void WindowPair::CalculateSplitRatioPoints(const Rect& displayRect) +{ + exitSplitPoints_.clear(); + splitRatioPoints_.clear(); + exitSplitPoints_.push_back(GetSplitRatioPoint(splitRatioConfig_.exitSplitStartRatio, displayRect)); + exitSplitPoints_.push_back(GetSplitRatioPoint(splitRatioConfig_.exitSplitEndRatio, displayRect)); + for (const auto& ratio : splitRatioConfig_.splitRatios) { + splitRatioPoints_.push_back(GetSplitRatioPoint(ratio, displayRect)); + } +} + +void WindowPair::SetSplitRatioConfig(const SplitRatioConfig& splitRatioConfig) +{ + splitRatioConfig_ = splitRatioConfig; +} + +std::vector WindowPair::GetExitSplitPoints() +{ + return exitSplitPoints_; +} + +std::vector WindowPair::GetSplitRatioPoints() +{ + return splitRatioPoints_; +} } // namespace Rosen } // namespace OHOS \ No newline at end of file diff --git a/wmserver/src/window_root.cpp b/wmserver/src/window_root.cpp index 42e7ff3958..5cad7b278c 100644 --- a/wmserver/src/window_root.cpp +++ b/wmserver/src/window_root.cpp @@ -119,7 +119,7 @@ sptr WindowRoot::CreateWindowNodeContainer(sptrGetLayoutPolicy()->SetSplitRatioConfig(splitRatioConfig_); + container->GetDisplayGroupController()->SetSplitRatioConfig(splitRatioConfig_); return container; } @@ -257,7 +257,7 @@ std::vector> WindowRoot::GetSplitScreenWindowNodes(DisplayId di if (container == nullptr) { return {}; } - auto displayGroupController = container->GetMultiDisplayController(); + auto displayGroupController = container->GetDisplayGroupController(); if (displayGroupController == nullptr) { return {}; } @@ -1280,7 +1280,8 @@ void WindowRoot::ProcessExpandDisplayCreate(DisplayId defaultDisplayId, sptrGetMultiDisplayController()->ProcessDisplayCreate(defaultDisplayId, displayInfo, displayRectMap); + container->GetDisplayGroupController()->ProcessDisplayCreate(defaultDisplayId, displayInfo, displayRectMap); + container->GetDisplayGroupController()->SetSplitRatioConfig(splitRatioConfig_); WLOGFI("[Display Create] Container exist, add new display, displayId: %{public}" PRIu64"", displayId); } @@ -1400,7 +1401,7 @@ void WindowRoot::ProcessDisplayDestroy(DisplayId defaultDisplayId, sptrGetMultiDisplayController()->ProcessDisplayDestroy( + container->GetDisplayGroupController()->ProcessDisplayDestroy( defaultDisplayId, displayInfo, displayRectMap, needDestroyWindows); for (auto id : needDestroyWindows) { auto node = GetWindowNode(id); @@ -1437,7 +1438,7 @@ void WindowRoot::ProcessDisplayChange(DisplayId defaultDisplayId, sptrGetMultiDisplayController()->ProcessDisplayChange(defaultDisplayId, displayInfo, displayRectMap, type); + container->GetDisplayGroupController()->ProcessDisplayChange(defaultDisplayId, displayInfo, displayRectMap, type); } float WindowRoot::GetVirtualPixelRatio(DisplayId displayId) const -- Gitee