From 7e251eb9f0c28f1afd4117613e05a8c13f3e4bb3 Mon Sep 17 00:00:00 2001 From: l00574490 Date: Tue, 12 Apr 2022 11:29:26 +0800 Subject: [PATCH] support muti_display for drag Signed-off-by: l00574490 Change-Id: I3e1288fb949c92a1d4b152c3468e72c30654f336 --- dmserver/include/abstract_screen.h | 1 + dmserver/include/display_manager_service.h | 1 + .../include/display_manager_service_inner.h | 1 + dmserver/src/abstract_display_controller.cpp | 2 + dmserver/src/abstract_screen.cpp | 5 + dmserver/src/abstract_screen_controller.cpp | 2 +- dmserver/src/display_manager_service.cpp | 12 +- .../src/display_manager_service_inner.cpp | 10 + utils/include/display_change_listener.h | 1 + utils/include/wm_common_inner.h | 6 + .../unittest/avoid_area_controller_test.cpp | 2 +- wm/test/unittest/avoid_area_controller_test.h | 1 + wmserver/include/avoid_area_controller.h | 21 +- wmserver/include/window_layout_policy.h | 49 +-- .../include/window_layout_policy_cascade.h | 55 +-- wmserver/include/window_layout_policy_tile.h | 32 +- wmserver/include/window_node_container.h | 90 ++-- wmserver/include/window_root.h | 15 +- wmserver/src/avoid_area_controller.cpp | 65 ++- wmserver/src/drag_controller.cpp | 2 +- wmserver/src/input_window_monitor.cpp | 14 +- wmserver/src/window_controller.cpp | 14 +- wmserver/src/window_layout_policy.cpp | 109 +++-- wmserver/src/window_layout_policy_cascade.cpp | 333 ++++++++------- wmserver/src/window_layout_policy_tile.cpp | 166 ++++---- wmserver/src/window_manager_service.cpp | 1 + wmserver/src/window_node_container.cpp | 395 ++++++++++++------ wmserver/src/window_root.cpp | 208 +++++---- 28 files changed, 977 insertions(+), 636 deletions(-) diff --git a/dmserver/include/abstract_screen.h b/dmserver/include/abstract_screen.h index 01c73a7b6b..f3e7d6087f 100644 --- a/dmserver/include/abstract_screen.h +++ b/dmserver/include/abstract_screen.h @@ -48,6 +48,7 @@ public: void UpdateRSTree(std::shared_ptr& surfaceNode, bool isAdd); void InitRSDisplayNode(RSDisplayNodeConfig& config, Point& startPoint); + ScreenId GetScreenGroupId() const; // colorspace, gamut DMError GetScreenSupportedColorGamuts(std::vector& colorGamuts); diff --git a/dmserver/include/display_manager_service.h b/dmserver/include/display_manager_service.h index 4299df4840..7a257bec12 100644 --- a/dmserver/include/display_manager_service.h +++ b/dmserver/include/display_manager_service.h @@ -84,6 +84,7 @@ public: void RemoveVirtualScreenFromGroup(std::vector screens) override; sptr GetScreenInfoById(ScreenId screenId) override; sptr GetScreenGroupInfoById(ScreenId screenId) override; + ScreenId GetScreenGroupIdByScreenId(ScreenId screenId); std::vector> GetAllScreenInfos() override; std::vector GetAllDisplayIds() override; diff --git a/dmserver/include/display_manager_service_inner.h b/dmserver/include/display_manager_service_inner.h index ab8a0fc858..ec3bb2f07e 100644 --- a/dmserver/include/display_manager_service_inner.h +++ b/dmserver/include/display_manager_service_inner.h @@ -38,6 +38,7 @@ public: std::vector GetAllDisplayIds() const; ScreenId GetRSScreenId(DisplayId displayId) const; sptr GetScreenInfoByDisplayId(DisplayId displayId) const; + ScreenId GetScreenGroupIdByDisplayId(DisplayId displayId) const; sptr GetScreenModesByDisplayId(DisplayId displayId) const; std::shared_ptr GetDisplaySnapshot(DisplayId) const; void UpdateRSTree(DisplayId displayId, std::shared_ptr& surfaceNode, bool isAdd); diff --git a/dmserver/src/abstract_display_controller.cpp b/dmserver/src/abstract_display_controller.cpp index 7ced297529..3364b0544a 100644 --- a/dmserver/src/abstract_display_controller.cpp +++ b/dmserver/src/abstract_display_controller.cpp @@ -377,6 +377,7 @@ void AbstractDisplayController::BindAloneScreenLocked(sptr realA WLOGI("create display for new screen. screen:%{public}" PRIu64", display:%{public}" PRIu64"", realAbsScreen->dmsId_, display->GetId()); DisplayManagerAgentController::GetInstance().OnDisplayCreate(display->ConvertToDisplayInfo()); + displayStateChangeListener_(display->GetId(), DisplayStateChangeType::CREATE); } else { WLOGI("bind display for new screen. screen:%{public}" PRIu64", display:%{public}" PRIu64"", realAbsScreen->dmsId_, dummyDisplay_->GetId()); @@ -436,6 +437,7 @@ void AbstractDisplayController::AddScreenToExpandLocked(sptr abs WLOGI("create display for new screen. screen:%{public}" PRIu64", display:%{public}" PRIu64"", absScreen->dmsId_, display->GetId()); DisplayManagerAgentController::GetInstance().OnDisplayCreate(display->ConvertToDisplayInfo()); + displayStateChangeListener_(display->GetId(), DisplayStateChangeType::CREATE); } void AbstractDisplayController::SetFreeze(std::vector displayIds, bool toFreeze) diff --git a/dmserver/src/abstract_screen.cpp b/dmserver/src/abstract_screen.cpp index 60694ce335..6e6d9e7adf 100644 --- a/dmserver/src/abstract_screen.cpp +++ b/dmserver/src/abstract_screen.cpp @@ -96,6 +96,11 @@ void AbstractScreen::InitRSDisplayNode(RSDisplayNodeConfig& config, Point& start } } +ScreenId AbstractScreen::GetScreenGroupId() const +{ + return groupDmsId_; +} + DMError AbstractScreen::GetScreenSupportedColorGamuts(std::vector& colorGamuts) { auto ret = RSInterfaces::GetInstance().GetScreenSupportedColorGamuts(rsId_, colorGamuts); diff --git a/dmserver/src/abstract_screen_controller.cpp b/dmserver/src/abstract_screen_controller.cpp index 34086b793c..eb0e64b9e5 100644 --- a/dmserver/src/abstract_screen_controller.cpp +++ b/dmserver/src/abstract_screen_controller.cpp @@ -566,7 +566,7 @@ DMError AbstractScreenController::DestroyVirtualScreen(ScreenId screenId) transactionProxy->FlushImplicitTransaction(); } } - + if (rsScreenId != SCREEN_ID_INVALID && GetAbstractScreen(screenId) != nullptr) { ProcessScreenDisconnected(rsScreenId); } diff --git a/dmserver/src/display_manager_service.cpp b/dmserver/src/display_manager_service.cpp index 434eb1305e..3d5f409dac 100644 --- a/dmserver/src/display_manager_service.cpp +++ b/dmserver/src/display_manager_service.cpp @@ -116,7 +116,7 @@ sptr DisplayManagerService::GetDisplayInfoByScreen(ScreenId screenI } return display->ConvertToDisplayInfo(); } - + ScreenId DisplayManagerService::CreateVirtualScreen(VirtualScreenOption option, const sptr& displayManagerAgent) { @@ -406,6 +406,16 @@ sptr DisplayManagerService::GetScreenGroupInfoById(ScreenId scr return screenGroup->ConvertToScreenGroupInfo(); } +ScreenId DisplayManagerService::GetScreenGroupIdByScreenId(ScreenId screenId) +{ + auto screen = abstractScreenController_->GetAbstractScreen(screenId); + if (screen == nullptr) { + WLOGE("cannot find screenInfo: %{public}" PRIu64"", screenId); + return SCREEN_ID_INVALID; + } + return screen->GetScreenGroupId(); +} + std::vector DisplayManagerService::GetAllDisplayIds() { return abstractDisplayController_->GetAllDisplayIds(); diff --git a/dmserver/src/display_manager_service_inner.cpp b/dmserver/src/display_manager_service_inner.cpp index 44576c5d19..a2a2e5c94c 100644 --- a/dmserver/src/display_manager_service_inner.cpp +++ b/dmserver/src/display_manager_service_inner.cpp @@ -92,6 +92,16 @@ sptr DisplayManagerServiceInner::GetScreenInfoByDisplayId(DisplayId return DisplayManagerService::GetInstance().GetScreenInfoById(displayInfo->GetScreenId()); } +ScreenId DisplayManagerServiceInner::GetScreenGroupIdByDisplayId(DisplayId displayId) const +{ + auto displayInfo = DisplayManagerService::GetInstance().GetDisplayInfoById(displayId); + if (displayInfo == nullptr) { + WLOGFE("can not get display."); + return INVALID_SCREEN_ID; + } + return DisplayManagerService::GetInstance().GetScreenGroupIdByScreenId(displayInfo->GetScreenId()); +} + sptr DisplayManagerServiceInner::GetScreenModesByDisplayId(DisplayId displayId) const { const sptr screenInfo = GetScreenInfoByDisplayId(displayId); diff --git a/utils/include/display_change_listener.h b/utils/include/display_change_listener.h index 83304a3269..01716fd978 100644 --- a/utils/include/display_change_listener.h +++ b/utils/include/display_change_listener.h @@ -25,6 +25,7 @@ enum class DisplayStateChangeType : uint32_t { BEFORE_UNLOCK, UPDATE_ROTATION, SIZE_CHANGE, + CREATE, DESTROY, FREEZE, UNFREEZE, diff --git a/utils/include/wm_common_inner.h b/utils/include/wm_common_inner.h index b76345b2d5..867673cf0c 100644 --- a/utils/include/wm_common_inner.h +++ b/utils/include/wm_common_inner.h @@ -55,6 +55,12 @@ enum class AvoidPosType : uint32_t { AVOID_POS_UNKNOWN }; +enum class WindowRootNodeType : uint32_t { + APP_WINDOW_NODE, + ABOVE_WINDOW_NODE, + BELOW_WINDOW_NODE, +}; + enum class PropertyChangeAction : uint32_t { ACTION_UPDATE_RECT = 1, ACTION_UPDATE_MODE = 1 << 1, diff --git a/wm/test/unittest/avoid_area_controller_test.cpp b/wm/test/unittest/avoid_area_controller_test.cpp index d2564705f2..d213b5f90e 100644 --- a/wm/test/unittest/avoid_area_controller_test.cpp +++ b/wm/test/unittest/avoid_area_controller_test.cpp @@ -344,7 +344,7 @@ HWTEST_F(AvoidAreaControllerTest, UpdateAvoidAreaNode03, Function | SmallTest | HWTEST_F(AvoidAreaControllerTest, GetAvoidAreaByType01, Function | SmallTest | Level2) { sptr avoidAreaController = new AvoidAreaController(0, nullptr); - std::vector avoidArea = avoidAreaController->GetAvoidAreaByType(AvoidAreaType::TYPE_CUTOUT); + std::vector avoidArea = avoidAreaController->GetAvoidAreaByType(AvoidAreaType::TYPE_CUTOUT, displayId_); ASSERT_EQ(4u, static_cast(avoidArea.size())); ASSERT_TRUE(RectEqualToRect(EMPTY_RECT, avoidArea[LEFT])); diff --git a/wm/test/unittest/avoid_area_controller_test.h b/wm/test/unittest/avoid_area_controller_test.h index 040943cfcf..91ed662378 100644 --- a/wm/test/unittest/avoid_area_controller_test.h +++ b/wm/test/unittest/avoid_area_controller_test.h @@ -33,6 +33,7 @@ public: private: static void InitByScreenRect(const Rect& screenRect); + DisplayId displayId_ = 0; }; } // namespace ROSEN } // namespace OHOS diff --git a/wmserver/include/avoid_area_controller.h b/wmserver/include/avoid_area_controller.h index 8dabdb36d6..00039676cb 100644 --- a/wmserver/include/avoid_area_controller.h +++ b/wmserver/include/avoid_area_controller.h @@ -34,27 +34,28 @@ enum class AvoidControlType : uint32_t { AVOID_NODE_UNKNOWN, }; -using UpdateAvoidAreaFunc = std::function& avoidArea)>; +using UpdateAvoidAreaFunc = std::function& avoidArea, DisplayId displayId)>; class AvoidAreaController : public RefBase { public: - AvoidAreaController(DisplayId displayId, UpdateAvoidAreaFunc callback) - : displayId_(displayId), updateAvoidAreaCallBack_(callback) {}; + AvoidAreaController(DisplayId displayId, UpdateAvoidAreaFunc callback); ~AvoidAreaController() = default; WMError AvoidControl(const sptr& node, AvoidControlType type); bool IsAvoidAreaNode(const sptr& node) const; - std::vector GetAvoidArea() const; - std::vector GetAvoidAreaByType(AvoidAreaType avoidAreaType) const; + std::vector GetAvoidArea(DisplayId displayId) const; + std::vector GetAvoidAreaByType(AvoidAreaType avoidAreaType, DisplayId displayId) const; + void UpdateAvoidNodesMap(DisplayId displayId, bool isAdd); private: - DisplayId displayId_ = 0; - std::map> avoidNodes_; // key: windowId - UpdateAvoidAreaFunc updateAvoidAreaCallBack_; - void UseCallbackNotifyAvoidAreaChanged(std::vector& avoidArea) const; + std::map>* GetAvoidNodesByDisplayId(DisplayId displayId); + void UseCallbackNotifyAvoidAreaChanged(std::vector& avoidArea, DisplayId displayId) const; void DumpAvoidArea(const std::vector& avoidArea) const; - AvoidPosType GetAvoidPosType(const Rect& rect) const; + AvoidPosType GetAvoidPosType(const Rect& rect, DisplayId displayId) const; + + std::map>>> avoidNodesMaps_; + UpdateAvoidAreaFunc updateAvoidAreaCallBack_; }; } } diff --git a/wmserver/include/window_layout_policy.h b/wmserver/include/window_layout_policy.h index 6eec2bc74f..42183949aa 100644 --- a/wmserver/include/window_layout_policy.h +++ b/wmserver/include/window_layout_policy.h @@ -25,44 +25,45 @@ namespace OHOS { namespace Rosen { +using WindowNodeMaps = std::map>>>>; class WindowLayoutPolicy : public RefBase { public: WindowLayoutPolicy() = delete; - WindowLayoutPolicy(const Rect& displayRect, const uint64_t& screenId, - sptr& belowAppNode, sptr& appNode, sptr& aboveAppNode); + WindowLayoutPolicy(const std::map& displayRectMap, + WindowNodeMaps& windowNodeMaps); ~WindowLayoutPolicy() = default; virtual void Launch(); virtual void Clean(); virtual void Reset(); virtual void Reorder(); - virtual void UpdateDisplayInfo() = 0; - virtual void AddWindowNode(sptr& node) = 0; - virtual void LayoutWindowTree(); - virtual void RemoveWindowNode(sptr& node); - virtual void UpdateWindowNode(sptr& node, bool isAddWindow = false); - virtual void UpdateLayoutRect(sptr& node) = 0; - float GetVirtualPixelRatio() const; + virtual void UpdateDisplayInfo(const std::map& displayRectMap); + 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; + float GetVirtualPixelRatio(DisplayId displayId) const; protected: - const Rect& displayRect_; - const uint64_t& screenId_; - sptr& belowAppWindowNode_; - sptr& appWindowNode_; - sptr& aboveAppWindowNode_; - Rect limitRect_ = { 0, 0, 0, 0 }; + void UpdateFloatingLayoutRect(Rect& limitRect, Rect& winRect); + void UpdateLimitRect(const sptr& node, Rect& limitRect); + virtual void LayoutWindowNode(const sptr& node); + AvoidPosType GetAvoidPosType(const Rect& rect, DisplayId displayId) const; + void CalcAndSetNodeHotZone(Rect layoutOutRect, const sptr& node) const; + void LimitWindowSize(const sptr& node, const Rect& displayRect, Rect& winRect) const; + void ComputeDecoratedRequestRect(const sptr& node) const; + bool IsVerticalDisplay(DisplayId displayId) const; + bool IsFullScreenRecentWindowExist(const std::vector>& nodeVec) const; + void LayoutWindowNodesByRootType(const std::vector>& nodeVec); + const std::set avoidTypes_ { WindowType::WINDOW_TYPE_STATUS_BAR, WindowType::WINDOW_TYPE_NAVIGATION_BAR, }; - void UpdateFloatingLayoutRect(Rect& limitRect, Rect& winRect); - void UpdateLimitRect(const sptr& node, Rect& limitRect); - virtual void LayoutWindowNode(sptr& node); - AvoidPosType GetAvoidPosType(const Rect& rect) const; - void CalcAndSetNodeHotZone(Rect layoutOutRect, sptr& node) const; - void LimitWindowSize(const sptr& node, const Rect& displayRect, Rect& winRect) const; - void ComputeDecoratedRequestRect(sptr& node) const; - bool IsVertical() const; - bool IsFullScreenRecentWindowExist() const; + mutable std::map displayRectMap_; + mutable std::map limitRectMap_; + WindowNodeMaps& windowNodeMaps_; }; } } diff --git a/wmserver/include/window_layout_policy_cascade.h b/wmserver/include/window_layout_policy_cascade.h index d624d28556..0d2cd497ca 100644 --- a/wmserver/include/window_layout_policy_cascade.h +++ b/wmserver/include/window_layout_policy_cascade.h @@ -29,46 +29,47 @@ namespace Rosen { class WindowLayoutPolicyCascade : public WindowLayoutPolicy { public: WindowLayoutPolicyCascade() = delete; - WindowLayoutPolicyCascade(const Rect& displayRect, const uint64_t& screenId, - sptr& belowAppNode, sptr& appNode, sptr& aboveAppNode); + WindowLayoutPolicyCascade(const std::map& displayRectMap, + WindowNodeMaps& windowNodeMaps); ~WindowLayoutPolicyCascade() = default; void Launch() override; void Clean() override; void Reset() override; void Reorder() override; - void UpdateDisplayInfo() override; - void AddWindowNode(sptr& node) override; - void UpdateWindowNode(sptr& node, bool isAddWindow = false) override; - void UpdateLayoutRect(sptr& node) override; - void RemoveWindowNode(sptr& node) override; + void AddWindowNode(const sptr& node) override; + void UpdateWindowNode(const sptr& node, bool isAddWindow = false) override; + void UpdateLayoutRect(const sptr& node) override; + void RemoveWindowNode(const sptr& node) override; private: - // Rects for split screen - Rect primaryRect_ = {0, 0, 0, 0}; - Rect secondaryRect_ = {0, 0, 0, 0}; - Rect dividerRect_ = {0, 0, 0, 0}; - Rect primaryLimitRect_ = {0, 0, 0, 0}; - Rect secondaryLimitRect_ = {0, 0, 0, 0}; - // cascade mode rect - Rect firstCascadeRect_ = {0, 0, 0, 0}; - - void InitSplitRects(); - void SetSplitRectByRatio(float ratio); - void SetSplitRect(const Rect& rect); + void InitAllRects(); + void InitSplitRects(DisplayId displayId); + void SetSplitRectByRatio(float ratio, DisplayId displayId); + void SetSplitRect(const Rect& rect, DisplayId displayId); void UpdateSplitLimitRect(const Rect& limitRect, Rect& limitSplitRect); - void LayoutWindowNode(sptr& node) override; - void LayoutWindowTree() override; - void InitLimitRects(); - void LimitMoveBounds(Rect& rect) const; - void InitCascadeRect(); + void LayoutWindowNode(const sptr& node) override; + void LayoutWindowTree(DisplayId displayId) override; + void InitLimitRects(DisplayId displayId); + void LimitMoveBounds(Rect& rect, DisplayId displayId) const; + void InitCascadeRect(DisplayId displayId); void SetCascadeRect(const sptr& node); void ApplyWindowRectConstraints(const sptr& node, Rect& winRect) const; Rect GetRectByWindowMode(const WindowMode& mode) const; - Rect GetLimitRect(const WindowMode mode) const; - Rect GetDisplayRect(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; - Rect StepCascadeRect(Rect rect) const; + Rect StepCascadeRect(Rect rect, DisplayId displayId) const; + + struct CascadeRects { + Rect primaryRect_; + Rect secondaryRect_; + Rect primaryLimitRect_; + Rect secondaryLimitRect_; + Rect dividerRect_; + Rect firstCascadeRect_; + }; + mutable std::map cascadeRectsMap_; }; } } diff --git a/wmserver/include/window_layout_policy_tile.h b/wmserver/include/window_layout_policy_tile.h index 656b5e2048..8b44d7b35c 100644 --- a/wmserver/include/window_layout_policy_tile.h +++ b/wmserver/include/window_layout_policy_tile.h @@ -30,27 +30,27 @@ namespace Rosen { class WindowLayoutPolicyTile : public WindowLayoutPolicy { public: WindowLayoutPolicyTile() = delete; - WindowLayoutPolicyTile(const Rect& displayRect, const uint64_t& screenId, - sptr& belowAppNode, sptr& appNode, sptr& aboveAppNode); + WindowLayoutPolicyTile(const std::map& displayRectMap, + WindowNodeMaps& windowNodeMaps); ~WindowLayoutPolicyTile() = default; void Launch() override; - void AddWindowNode(sptr& node) override; - void UpdateWindowNode(sptr& node, bool isAddWindow = false) override; - void RemoveWindowNode(sptr& node) override; - void UpdateLayoutRect(sptr& node) 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; private: - uint32_t maxTileWinNum_ = 1; - std::vector> presetRects_; - std::deque> foregroundNodes_; - void UpdateDisplayInfo() override; - uint32_t GetMaxTileWinNum() const; - void InitTileWindowRects(); - void AssignNodePropertyForTileWindows(); - void LayoutForegroundNodeQueue(); + 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(sptr& node); - void ForegroundNodeQueueRemove(sptr& node); + 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 a95abcb6bc..bc3c7d7ffe 100644 --- a/wmserver/include/window_node_container.h +++ b/wmserver/include/window_node_container.h @@ -29,6 +29,8 @@ namespace OHOS { namespace Rosen { using WindowNodeOperationFunc = std::function)>; // return true indicates to stop traverse +using SysBarNodeMap = std::unordered_map>; +using SysBarTintMap = std::unordered_map; class WindowNodeContainer : public RefBase { public: WindowNodeContainer(DisplayId displayId, uint32_t width, uint32_t height, bool isMinimizedByOther); @@ -50,50 +52,52 @@ public: uint32_t ToOverrideBrightness(float brightness); void UpdateBrightness(uint32_t id, bool byRemoved); void HandleKeepScreenOn(const sptr& node, bool requireLock); - std::vector GetAvoidAreaByType(AvoidAreaType avoidAreaType); + std::vector GetAvoidAreaByType(AvoidAreaType avoidAreaType, DisplayId displayId); WMError MinimizeStructuredAppWindowsExceptSelf(const sptr& node); void TraverseContainer(std::vector>& windowNodes) const; - uint64_t GetScreenId() const; - DisplayId GetDisplayId() const; - Rect GetDisplayRect() const; + uint64_t GetScreenId(DisplayId displayId) const; + Rect GetDisplayRect(DisplayId displayId) const; std::unordered_map GetExpectImmersiveProperty() const; void NotifyAccessibilityWindowInfo(const sptr& windowId, WindowUpdateType type) const; - void UpdateDisplayRect(uint32_t width, uint32_t height); int GetWindowCountByType(WindowType windowType); - void OnAvoidAreaChange(const std::vector& avoidAreas); - bool isVerticalDisplay() const; + void OnAvoidAreaChange(const std::vector& avoidAreas, DisplayId displayId); + bool isVerticalDisplay(DisplayId displayId) const; WMError RaiseZOrderForAppWindow(sptr& node, sptr& parentNode); sptr GetNextFocusableWindow(uint32_t windowId) const; sptr GetNextActiveWindow(uint32_t windowId) const; - void MinimizeAllAppWindows(); + void MinimizeAllAppWindows(DisplayId displayId); void MinimizeOldestAppWindow(); - void NotifyWindowStateChange(WindowState state, WindowStateChangeReason reason); - void NotifySystemBarTints(); + void ProcessWindowStateChange(WindowState state, WindowStateChangeReason reason); + void NotifySystemBarTints(std::vector displayIdVec); void NotifySystemBarDismiss(sptr& node); WMError MinimizeAppNodeExceptOptions(bool fromUser, const std::vector &exceptionalIds = {}, const std::vector &exceptionalModes = {}); - WMError SwitchLayoutPolicy(WindowLayoutMode mode, bool reorder = false); WMError SetWindowMode(sptr& node, WindowMode dstMode); + WMError SwitchLayoutPolicy(WindowLayoutMode mode, DisplayId displayId, bool reorder = false); void RaiseSplitRelatedWindowToTop(sptr& node); - void MoveWindowNode(sptr& container); - float GetVirtualPixelRatio() const; + void MoveWindowNodes(DisplayId displayId, std::vector& windowIds); + float GetVirtualPixelRatio(DisplayId displayId) const; void TraverseWindowTree(const WindowNodeOperationFunc& func, bool isFromTopToBottom = true) const; void UpdateSizeChangeReason(sptr& node, WindowSizeChangeReason reason); void GetWindowList(std::vector>& windowList) const; void DropShowWhenLockedWindowIfNeeded(const sptr& node); + void ProcessDisplayCreate(DisplayId displayId, const Rect& displayRect); + void ProcessDisplayDestroy(DisplayId displayId, std::vector& windowIds); + void ProcessDisplayChange(DisplayId displayId, const Rect& displayRect); private: void TraverseWindowNode(sptr& root, std::vector>& windowNodes) const; sptr FindRoot(WindowType type) const; + std::vector>* FindNodeVectorOfRoot(DisplayId displayId, WindowRootNodeType type); sptr FindWindowNodeById(uint32_t id) const; void UpdateFocusStatus(uint32_t id, bool focused) const; void UpdateActiveStatus(uint32_t id, bool isActive) const; void UpdateWindowTree(sptr& node); bool UpdateRSTree(sptr& node, bool isAdd); - void NotifyIfSystemBarTintChanged(); - void NotifyIfSystemBarRegionChanged(); + void NotifyIfSystemBarTintChanged(DisplayId displayId); + void NotifyIfSystemBarRegionChanged(DisplayId displayId); void TraverseAndUpdateWindowState(WindowState state, int32_t topPriority); void UpdateWindowState(sptr node, int32_t topPriority, WindowState state); void HandleKeepScreenOn(const sptr& node, WindowState state); @@ -107,44 +111,48 @@ private: bool IsSplitImmersiveNode(sptr node) const; bool TraverseFromTopToBottom(sptr node, const WindowNodeOperationFunc& func) const; bool TraverseFromBottomToTop(sptr node, const WindowNodeOperationFunc& func) const; - void RcoveryScreenDefaultOrientationIfNeed(); + void RcoveryScreenDefaultOrientationIfNeed(DisplayId displayId); // cannot determine in case of a window covered by union of several windows or with transparent value void UpdateWindowVisibilityInfos(std::vector>& infos); void RaiseOrderedWindowToTop(std::vector>& orderedNodes, std::vector>& windowNodes); static bool ReadIsWindowAnimationEnabledProperty(); + void DumpScreenWindowTree(); + void RaiseInputMethodWindowPriorityIfNeeded(const sptr& node) const; + void RaiseShowWhenLockedWindowIfNeeded(const sptr& node); + void ReZOrderShowWhenLockedWindows(const sptr& node, bool up); + + void InitSysBarMapForDisplay(DisplayId displayId); + void InitWindowNodeMapForDisplay(DisplayId displayId); + WMError AddWindowNodeOnWindowTree(sptr& node, sptr& parentNode); + void RemoveWindowNodeFromWindowTree(sptr& node); + void AddWindowNodeInRootNodeVector(sptr& node, WindowRootNodeType rootType); + void RemoveWindowNodeFromRootNodeVector(sptr& node, WindowRootNodeType rootType); + void UpdateWindowNodeMaps(); + + float displayBrightness_ = UNDEFINED_BRIGHTNESS; + uint32_t brightnessWindow_ = INVALID_WINDOW_ID; + uint32_t zOrder_ { 0 }; + uint32_t focusedWindow_ { INVALID_WINDOW_ID }; + uint32_t activeWindow_ = INVALID_WINDOW_ID; sptr avoidController_; sptr zorderPolicy_ = new WindowZorderPolicy(); - sptr belowAppWindowNode_ = new WindowNode(); - sptr appWindowNode_ = new WindowNode(); - sptr aboveAppWindowNode_ = new WindowNode(); - std::vector removedIds_; - DisplayId displayId_ = 0; - Rect displayRect_; - std::vector currentCoveredArea_; - std::unordered_map> sysBarNodeMap_ { - { WindowType::WINDOW_TYPE_STATUS_BAR, nullptr }, - { WindowType::WINDOW_TYPE_NAVIGATION_BAR, nullptr }, - }; - std::unordered_map sysBarTintMap_ { - { WindowType::WINDOW_TYPE_STATUS_BAR, SystemBarRegionTint() }, - { WindowType::WINDOW_TYPE_NAVIGATION_BAR, SystemBarRegionTint() }, - }; std::unordered_map> layoutPolicys_; WindowLayoutMode layoutMode_ = WindowLayoutMode::CASCADE; sptr layoutPolicy_; - uint32_t zOrder_ { 0 }; - uint32_t focusedWindow_ { INVALID_WINDOW_ID }; - uint32_t activeWindow_ = INVALID_WINDOW_ID; - float displayBrightness_ = UNDEFINED_BRIGHTNESS; // UNDEFINED_BRIGHTNESS means system default brightness - uint32_t brightnessWindow_ = INVALID_WINDOW_ID; - void DumpScreenWindowTree(); - sptr windowPair_; - void RaiseInputMethodWindowPriorityIfNeeded(const sptr& node) const; - void RaiseShowWhenLockedWindowIfNeeded(const sptr& node); - void ReZOrderShowWhenLockedWindows(const sptr& node, bool up); + std::vector currentCoveredArea_; + std::map sysBarNodeMaps_; + std::map sysBarTintMaps_; + + sptr windowPair_; + std::vector removedIds_; + sptr belowAppWindowNode_ = new WindowNode(); + sptr appWindowNode_ = new WindowNode(); + sptr aboveAppWindowNode_ = new WindowNode(); + std::map displayRectMap_; + WindowNodeMaps windowNodeMaps_; bool isMinimizedByOther_ = true; }; } // namespace Rosen diff --git a/wmserver/include/window_root.h b/wmserver/include/window_root.h index 38f0c48195..6274a5f52c 100644 --- a/wmserver/include/window_root.h +++ b/wmserver/include/window_root.h @@ -36,8 +36,8 @@ public: WindowRoot(std::recursive_mutex& mutex, Callback callback) : mutex_(mutex), callback_(callback) {} ~WindowRoot() = default; - sptr GetOrCreateWindowNodeContainer(DisplayId displayId); - void NotifyDisplayRemoved(DisplayId displayId); + sptr GetWindowNodeContainer(DisplayId displayId); + sptr CreateWindowNodeContainer(DisplayId displayId); sptr GetWindowNode(uint32_t windowId) const; WMError SaveWindow(const sptr& node); @@ -58,9 +58,10 @@ public: WMError MaxmizeWindow(uint32_t windowId); WMError SetWindowLayoutMode(DisplayId displayId, WindowLayoutMode mode); - void NotifyWindowStateChange(WindowState state, WindowStateChangeReason reason); - void NotifyDisplayChange(sptr abstractDisplay); - void NotifyDisplayDestroy(DisplayId displayId); + void ProcessWindowStateChange(WindowState state, WindowStateChangeReason reason); + void ProcessDisplayChange(sptr abstractDisplay); + void ProcessDisplayDestroy(DisplayId displayId); + void ProcessDisplayCreate(DisplayId displayId); void NotifySystemBarTints(); WMError RaiseZOrderForAppWindow(sptr& node); void FocusFaultDetection() const; @@ -85,11 +86,13 @@ private: bool CheckDisplayInfo(const sptr& display); void NotifyKeyboardSizeChangeInfo(const sptr& node, const sptr& container, Rect rect); + ScreenId GetScreenGroupId(DisplayId displayId); std::recursive_mutex& mutex_; - std::map> windowNodeContainerMap_; std::map> windowNodeMap_; std::map, uint32_t> windowIdMap_; + std::map> windowNodeContainerMap_; + std::map> displayIdMap_; bool needCheckFocusWindow = false; bool isMinimizedByOtherWindow_ = true; diff --git a/wmserver/src/avoid_area_controller.cpp b/wmserver/src/avoid_area_controller.cpp index fb2658c3b4..c82093e55d 100644 --- a/wmserver/src/avoid_area_controller.cpp +++ b/wmserver/src/avoid_area_controller.cpp @@ -27,6 +27,22 @@ namespace { const int32_t AVOID_NUM = 4; +AvoidAreaController::AvoidAreaController(DisplayId displayId, UpdateAvoidAreaFunc callback) +{ + UpdateAvoidNodesMap(displayId, true); + updateAvoidAreaCallBack_ = callback; +} + +void AvoidAreaController::UpdateAvoidNodesMap(DisplayId displayId, bool isAdd) +{ + if (isAdd) { + auto avoidNodesMapPtr = std::make_unique>>(); + avoidNodesMaps_.insert(std::make_pair(displayId, std::move(avoidNodesMapPtr))); + } else { + avoidNodesMaps_.erase(displayId); + } +} + bool AvoidAreaController::IsAvoidAreaNode(const sptr& node) const { if (node == nullptr) { @@ -42,11 +58,21 @@ bool AvoidAreaController::IsAvoidAreaNode(const sptr& node) const return true; } -AvoidPosType AvoidAreaController::GetAvoidPosType(const Rect& rect) const +std::map>* AvoidAreaController::GetAvoidNodesByDisplayId( + DisplayId displayId) +{ + if ((const_cast(this)->avoidNodesMaps_).find(displayId) != + (const_cast(this)->avoidNodesMaps_).end()) { + return (const_cast(this)->avoidNodesMaps_)[displayId].get(); + } + return nullptr; +} + +AvoidPosType AvoidAreaController::GetAvoidPosType(const Rect& rect, DisplayId displayId) const { - auto display = DisplayManagerServiceInner::GetInstance().GetDisplayById(displayId_); + auto display = DisplayManagerServiceInner::GetInstance().GetDisplayById(displayId); if (display == nullptr) { - WLOGFE("GetAvoidPosType fail. Get display fail. displayId:%{public}" PRIu64"", displayId_); + WLOGFE("GetAvoidPosType fail. Get display fail. displayId:%{public}" PRIu64"", displayId); return AvoidPosType::AVOID_POS_UNKNOWN; } uint32_t displayWidth = static_cast(display->GetWidth()); @@ -62,30 +88,32 @@ WMError AvoidAreaController::AvoidControl(const sptr& node, AvoidCon WLOGFE("AvoidControl check param Failed. Type: %{public}u", type); return WMError::WM_ERROR_INVALID_PARAM; } + + auto avoidNodes = GetAvoidNodesByDisplayId(node->GetDisplayId()); uint32_t windowId = node->GetWindowId(); - auto iter = avoidNodes_.find(windowId); + auto iter = avoidNodes->find(windowId); // do not add a exist node(the same id) - if (type == AvoidControlType::AVOID_NODE_ADD && iter != avoidNodes_.end()) { + if (type == AvoidControlType::AVOID_NODE_ADD && iter != avoidNodes->end()) { WLOGFE("WinId:%{public}d is added. AvoidControl Add Failed. Type: %{public}u", windowId, type); return WMError::WM_ERROR_INVALID_PARAM; } // do not update or removew a unexist node - if (type != AvoidControlType::AVOID_NODE_ADD && iter == avoidNodes_.end()) { + if (type != AvoidControlType::AVOID_NODE_ADD && iter == avoidNodes->end()) { WLOGFE("WinId:%{public}d not exist. AvoidControl Update or Remove Failed. Type: %{public}u", windowId, type); return WMError::WM_ERROR_INVALID_PARAM; } switch (type) { case AvoidControlType::AVOID_NODE_ADD: - avoidNodes_[windowId] = node; + (*avoidNodes)[windowId] = node; WLOGFI("WinId:%{public}d add. And the windowType is %{public}d", windowId, node->GetWindowType()); break; case AvoidControlType::AVOID_NODE_UPDATE: - avoidNodes_[windowId] = node; + (*avoidNodes)[windowId] = node; WLOGFI("WinId:%{public}d update. And the windowType is %{public}d", windowId, node->GetWindowType()); break; case AvoidControlType::AVOID_NODE_REMOVE: - avoidNodes_.erase(iter); + avoidNodes->erase(iter); WLOGFI("WinId:%{public}d remove. And the windowType is %{public}d", windowId, node->GetWindowType()); break; default: @@ -94,18 +122,19 @@ WMError AvoidAreaController::AvoidControl(const sptr& node, AvoidCon } // get all Area info and notify windowcontainer - std::vector avoidAreas = GetAvoidArea(); + std::vector avoidAreas = GetAvoidArea(node->GetDisplayId()); DumpAvoidArea(avoidAreas); - UseCallbackNotifyAvoidAreaChanged(avoidAreas); + UseCallbackNotifyAvoidAreaChanged(avoidAreas, node->GetDisplayId()); return WMError::WM_OK; } -std::vector AvoidAreaController::GetAvoidArea() const +std::vector AvoidAreaController::GetAvoidArea(DisplayId displayId) const { + auto avoidNodesPtr = const_cast(this)->GetAvoidNodesByDisplayId(displayId); std::vector avoidArea(AVOID_NUM, {0, 0, 0, 0}); // avoid area left, top, right, bottom - for (auto iter = avoidNodes_.begin(); iter != avoidNodes_.end(); ++iter) { + for (auto iter = avoidNodesPtr->begin(); iter != avoidNodesPtr->end(); ++iter) { Rect curRect = iter->second->GetWindowRect(); - auto curPos = GetAvoidPosType(curRect); + auto curPos = GetAvoidPosType(curRect, iter->second->GetDisplayId()); if (curPos == AvoidPosType::AVOID_POS_UNKNOWN) { WLOGFE("GetAvoidArea AVOID_POS_UNKNOWN Rect: x : %{public}d, y: %{public}d, w: %{public}u h: %{public}u", static_cast(curRect.posX_), static_cast(curRect.posY_), @@ -117,7 +146,7 @@ std::vector AvoidAreaController::GetAvoidArea() const return avoidArea; } -std::vector AvoidAreaController::GetAvoidAreaByType(AvoidAreaType avoidAreaType) const +std::vector AvoidAreaController::GetAvoidAreaByType(AvoidAreaType avoidAreaType, DisplayId displayId) const { if (avoidAreaType != AvoidAreaType::TYPE_SYSTEM) { WLOGFE("GetAvoidAreaByType. Support Type is AvoidAreaType::TYPE_SYSTEM. But current type is %{public}u", @@ -126,13 +155,13 @@ std::vector AvoidAreaController::GetAvoidAreaByType(AvoidAreaType avoidAre return avoidArea; } WLOGFI("AvoidAreaController::GetAvoidAreaByType Success"); - return GetAvoidArea(); + return GetAvoidArea(displayId); } -void AvoidAreaController::UseCallbackNotifyAvoidAreaChanged(std::vector& avoidArea) const +void AvoidAreaController::UseCallbackNotifyAvoidAreaChanged(std::vector& avoidArea, DisplayId displayId) const { if (updateAvoidAreaCallBack_) { - updateAvoidAreaCallBack_(avoidArea); + updateAvoidAreaCallBack_(avoidArea, displayId); } } diff --git a/wmserver/src/drag_controller.cpp b/wmserver/src/drag_controller.cpp index 3aad15a5bc..f4ededf041 100644 --- a/wmserver/src/drag_controller.cpp +++ b/wmserver/src/drag_controller.cpp @@ -106,7 +106,7 @@ sptr DragController::GetHitWindow(DisplayId id, PointInfo point) WLOGFE("Get invalid display"); return nullptr; } - sptr container = windowRoot_->GetOrCreateWindowNodeContainer(id); + sptr container = windowRoot_->GetWindowNodeContainer(id); if (container == nullptr) { WLOGFE("get container failed %{public}" PRIu64"", id); return nullptr; diff --git a/wmserver/src/input_window_monitor.cpp b/wmserver/src/input_window_monitor.cpp index b8ac523295..2cc2a45a33 100644 --- a/wmserver/src/input_window_monitor.cpp +++ b/wmserver/src/input_window_monitor.cpp @@ -52,7 +52,7 @@ void InputWindowMonitor::UpdateInputWindowByDisplayId(DisplayId displayId) if (displayId == DISPLAY_ID_INVALID) { return; } - auto container = windowRoot_->GetOrCreateWindowNodeContainer(displayId); + auto container = windowRoot_->GetWindowNodeContainer(displayId); if (container == nullptr) { WLOGFE("can not get window node container."); return; @@ -85,7 +85,7 @@ void InputWindowMonitor::UpdateDisplaysInfo(const sptr& con return; } MMI::PhysicalDisplayInfo physicalDisplayInfo = { - .id = static_cast(container->GetScreenId()), + .id = static_cast(container->GetScreenId(displayId)), .leftDisplayId = static_cast(DISPLAY_ID_INVALID), .upDisplayId = static_cast(DISPLAY_ID_INVALID), .topLeftX = 0, @@ -110,11 +110,11 @@ void InputWindowMonitor::UpdateDisplaysInfo(const sptr& con } MMI::LogicalDisplayInfo logicalDisplayInfo = { - .id = static_cast(container->GetScreenId()), - .topLeftX = container->GetDisplayRect().posX_, - .topLeftY = container->GetDisplayRect().posY_, - .width = static_cast(container->GetDisplayRect().width_), - .height = static_cast(container->GetDisplayRect().height_), + .id = static_cast(container->GetScreenId(displayId)), + .topLeftX = container->GetDisplayRect(displayId).posX_, + .topLeftY = container->GetDisplayRect(displayId).posY_, + .width = static_cast(container->GetDisplayRect(displayId).width_), + .height = static_cast(container->GetDisplayRect(displayId).height_), .name = "logical_display0", .seatId = "seat0", .seatName = "default0", diff --git a/wmserver/src/window_controller.cpp b/wmserver/src/window_controller.cpp index 996d75df5b..8e9e0ebd96 100644 --- a/wmserver/src/window_controller.cpp +++ b/wmserver/src/window_controller.cpp @@ -258,11 +258,11 @@ void WindowController::NotifyDisplayStateChange(DisplayId displayId, DisplayStat WLOGFD("DisplayStateChangeType:%{public}u", type); switch (type) { case DisplayStateChangeType::BEFORE_SUSPEND: { - windowRoot_->NotifyWindowStateChange(WindowState::STATE_FROZEN, WindowStateChangeReason::KEYGUARD); + windowRoot_->ProcessWindowStateChange(WindowState::STATE_FROZEN, WindowStateChangeReason::KEYGUARD); break; } case DisplayStateChangeType::BEFORE_UNLOCK: { - windowRoot_->NotifyWindowStateChange(WindowState::STATE_UNFROZEN, WindowStateChangeReason::KEYGUARD); + windowRoot_->ProcessWindowStateChange(WindowState::STATE_UNFROZEN, WindowStateChangeReason::KEYGUARD); break; } case DisplayStateChangeType::SIZE_CHANGE: @@ -270,8 +270,12 @@ void WindowController::NotifyDisplayStateChange(DisplayId displayId, DisplayStat ProcessDisplayChange(displayId, type); break; } + case DisplayStateChangeType::CREATE: { + windowRoot_->ProcessDisplayCreate(displayId); + break; + } case DisplayStateChangeType::DESTROY: { - windowRoot_->NotifyDisplayDestroy(displayId); + windowRoot_->ProcessDisplayDestroy(displayId); break; } default: { @@ -285,7 +289,7 @@ void WindowController::ProcessDisplayChange(DisplayId displayId, DisplayStateCha { const sptr displayInfo = DisplayManagerServiceInner::GetInstance().GetDisplayById(displayId); if (displayInfo == nullptr) { - WLOGFE("get display failed displayId:%{public}" PRId64 "", displayId); + WLOGFE("get display failed displayId:%{public}" PRIu64 "", displayId); return; } @@ -306,7 +310,7 @@ void WindowController::ProcessDisplayChange(DisplayId displayId, DisplayStateCha = navigationBarNode->GetWindowProperty()->GetWindowRect(); } curDisplayInfo_[displayId] = displayInfo; - windowRoot_->NotifyDisplayChange(displayInfo); + windowRoot_->ProcessDisplayChange(displayInfo); // Remove 'sysBarWinId_' after SystemUI resize 'systembar' uint32_t width = static_cast(displayInfo->GetWidth()); uint32_t height = static_cast(displayInfo->GetHeight() * SYSTEM_BAR_HEIGHT_RATIO); diff --git a/wmserver/src/window_layout_policy.cpp b/wmserver/src/window_layout_policy.cpp index cd698fa279..69c4caec06 100644 --- a/wmserver/src/window_layout_policy.cpp +++ b/wmserver/src/window_layout_policy.cpp @@ -25,10 +25,9 @@ namespace Rosen { namespace { constexpr HiviewDFX::HiLogLabel LABEL = {LOG_CORE, HILOG_DOMAIN_WINDOW, "WindowLayoutPolicy"}; } -WindowLayoutPolicy::WindowLayoutPolicy(const Rect& displayRect, const uint64_t& screenId, - sptr& belowAppNode, sptr& appNode, sptr& aboveAppNode) - : displayRect_(displayRect), screenId_(screenId), - belowAppWindowNode_(belowAppNode), appWindowNode_(appNode), aboveAppWindowNode_(aboveAppNode) +WindowLayoutPolicy::WindowLayoutPolicy(const std::map& displayRectMap, + WindowNodeMaps& windowNodeMaps) + : displayRectMap_(displayRectMap), windowNodeMaps_(windowNodeMaps) { } @@ -47,23 +46,46 @@ void WindowLayoutPolicy::Reorder() WLOGFI("WindowLayoutPolicy::Reorder"); } -void WindowLayoutPolicy::LayoutWindowTree() +void WindowLayoutPolicy::UpdateDisplayInfo(const std::map& displayRectMap) { - limitRect_ = displayRect_; - LayoutWindowNode(aboveAppWindowNode_); // ensure that the avoid area windows are traversed first - if (IsFullScreenRecentWindowExist()) { + displayRectMap_.clear(); + for (auto& displayRect : displayRectMap) { + displayRectMap_.insert(displayRect); + } + Launch(); +} + +void WindowLayoutPolicy::LayoutWindowNodesByRootType(const std::vector>& nodeVec) +{ + if (nodeVec.empty()) { + WLOGE("The node vector is empty!"); + return; + } + for (auto& node : nodeVec) { + LayoutWindowNode(node); + } +} + +void WindowLayoutPolicy::LayoutWindowTree(DisplayId displayId) +{ + auto& windowNodeMap = windowNodeMaps_[displayId]; + limitRectMap_[displayId] = displayRectMap_[displayId]; + // ensure that the avoid area windows are traversed first + LayoutWindowNodesByRootType(*(windowNodeMap[WindowRootNodeType::ABOVE_WINDOW_NODE])); + if (IsFullScreenRecentWindowExist(*(windowNodeMap[WindowRootNodeType::ABOVE_WINDOW_NODE]))) { WLOGFI("recent window on top, early exit layout tree"); return; } - LayoutWindowNode(appWindowNode_); - LayoutWindowNode(belowAppWindowNode_); + LayoutWindowNodesByRootType(*(windowNodeMap[WindowRootNodeType::APP_WINDOW_NODE])); + LayoutWindowNodesByRootType(*(windowNodeMap[WindowRootNodeType::BELOW_WINDOW_NODE])); } -void WindowLayoutPolicy::LayoutWindowNode(sptr& node) +void WindowLayoutPolicy::LayoutWindowNode(const sptr& node) { if (node == nullptr) { 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()); @@ -71,7 +93,7 @@ void WindowLayoutPolicy::LayoutWindowNode(sptr& node) } UpdateLayoutRect(node); if (avoidTypes_.find(node->GetWindowType()) != avoidTypes_.end()) { - UpdateLimitRect(node, limitRect_); + UpdateLimitRect(node, limitRectMap_[node->GetDisplayId()]); } } for (auto& childNode : node->children_) { @@ -79,34 +101,34 @@ void WindowLayoutPolicy::LayoutWindowNode(sptr& node) } } -bool WindowLayoutPolicy::IsVertical() const +bool WindowLayoutPolicy::IsVerticalDisplay(DisplayId displayId) const { - return displayRect_.width_ < displayRect_.height_; + return displayRectMap_[displayId].width_ < displayRectMap_[displayId].height_; } -void WindowLayoutPolicy::RemoveWindowNode(sptr& node) +void WindowLayoutPolicy::RemoveWindowNode(const sptr& node) { WM_FUNCTION_TRACE(); auto type = node->GetWindowType(); // affect other windows, trigger off global layout if (avoidTypes_.find(type) != avoidTypes_.end()) { - LayoutWindowTree(); + LayoutWindowTree(node->GetDisplayId()); } else if (type == WindowType::WINDOW_TYPE_DOCK_SLICE) { // split screen mode - LayoutWindowTree(); + LayoutWindowTree(node->GetDisplayId()); } Rect reqRect = node->GetRequestRect(); node->GetWindowToken()->UpdateWindowRect(reqRect, node->GetDecoStatus(), WindowSizeChangeReason::HIDE); } -void WindowLayoutPolicy::UpdateWindowNode(sptr& node, bool isAddWindow) +void WindowLayoutPolicy::UpdateWindowNode(const sptr& node, bool isAddWindow) { WM_FUNCTION_TRACE(); auto type = node->GetWindowType(); // affect other windows, trigger off global layout if (avoidTypes_.find(type) != avoidTypes_.end()) { - LayoutWindowTree(); + LayoutWindowTree(node->GetDisplayId()); } else if (type == WindowType::WINDOW_TYPE_DOCK_SLICE) { // split screen mode - LayoutWindowTree(); + LayoutWindowTree(node->GetDisplayId()); } else { // layout single window LayoutWindowNode(node); } @@ -126,7 +148,7 @@ void WindowLayoutPolicy::UpdateFloatingLayoutRect(Rect& limitRect, Rect& winRect winRect.posY_); } -void WindowLayoutPolicy::ComputeDecoratedRequestRect(sptr& node) const +void WindowLayoutPolicy::ComputeDecoratedRequestRect(const sptr& node) const { auto property = node->GetWindowProperty(); if (property == nullptr) { @@ -137,7 +159,7 @@ void WindowLayoutPolicy::ComputeDecoratedRequestRect(sptr& node) con if (!property->GetDecorEnable() || property->GetDecoStatus()) { return; } - float virtualPixelRatio = GetVirtualPixelRatio(); + float virtualPixelRatio = GetVirtualPixelRatio(node->GetDisplayId()); uint32_t winFrameW = static_cast(WINDOW_FRAME_WIDTH * virtualPixelRatio); uint32_t winTitleBarH = static_cast(WINDOW_TITLE_BAR_HEIGHT * virtualPixelRatio); @@ -150,10 +172,10 @@ void WindowLayoutPolicy::ComputeDecoratedRequestRect(sptr& node) con property->SetDecoStatus(true); } -void WindowLayoutPolicy::CalcAndSetNodeHotZone(Rect layoutOutRect, sptr& node) const +void WindowLayoutPolicy::CalcAndSetNodeHotZone(Rect layoutOutRect, const sptr& node) const { Rect rect = layoutOutRect; - float virtualPixelRatio = GetVirtualPixelRatio(); + float virtualPixelRatio = GetVirtualPixelRatio(node->GetDisplayId()); uint32_t hotZone = static_cast(HOTZONE * virtualPixelRatio); if (node->GetWindowType() == WindowType::WINDOW_TYPE_DOCK_SLICE) { @@ -165,7 +187,7 @@ void WindowLayoutPolicy::CalcAndSetNodeHotZone(Rect layoutOutRect, sptrGetWindowType() == WindowType::WINDOW_TYPE_LAUNCHER_RECENT) { - rect = displayRect_; + rect = displayRectMap_[node->GetDisplayId()]; } else if (WindowHelper::IsMainFloatingWindow(node->GetWindowType(), node->GetWindowMode())) { rect.posX_ -= hotZone; rect.posY_ -= hotZone; @@ -177,7 +199,7 @@ void WindowLayoutPolicy::CalcAndSetNodeHotZone(Rect layoutOutRect, sptr& node, const Rect& displayRect, Rect& winRect) const { - float virtualPixelRatio = GetVirtualPixelRatio(); + float virtualPixelRatio = GetVirtualPixelRatio(node->GetDisplayId()); uint32_t minVerticalFloatingW = static_cast(MIN_VERTICAL_FLOATING_WIDTH * virtualPixelRatio); uint32_t minVerticalFloatingH = static_cast(MIN_VERTICAL_FLOATING_HEIGHT * virtualPixelRatio); uint32_t windowTitleBarH = static_cast(WINDOW_TITLE_BAR_HEIGHT * virtualPixelRatio); @@ -202,24 +224,25 @@ void WindowLayoutPolicy::LimitWindowSize(const sptr& node, const Rec winRect.height_ = std::min(static_cast(MAX_FLOATING_SIZE * virtualPixelRatio), winRect.height_); } + const Rect& limitRect = limitRectMap_[node->GetDisplayId()]; // limit position of the main floating window(window which support dragging) if (WindowHelper::IsMainFloatingWindow(windowType, windowMode)) { - winRect.posY_ = std::max(limitRect_.posY_, winRect.posY_); - winRect.posY_ = std::min(limitRect_.posY_ + static_cast(limitRect_.height_ - windowTitleBarH), + winRect.posY_ = std::max(limitRect.posY_, winRect.posY_); + winRect.posY_ = std::min(limitRect.posY_ + static_cast(limitRect.height_ - windowTitleBarH), winRect.posY_); - winRect.posX_ = std::max(limitRect_.posX_ + static_cast(windowTitleBarH - winRect.width_), + winRect.posX_ = std::max(limitRect.posX_ + static_cast(windowTitleBarH - winRect.width_), winRect.posX_); - winRect.posX_ = std::min(limitRect_.posX_ + static_cast(limitRect_.width_ - windowTitleBarH), + winRect.posX_ = std::min(limitRect.posX_ + static_cast(limitRect.width_ - windowTitleBarH), winRect.posX_); } } -AvoidPosType WindowLayoutPolicy::GetAvoidPosType(const Rect& rect) const +AvoidPosType WindowLayoutPolicy::GetAvoidPosType(const Rect& rect, DisplayId displayId) const { - auto display = DisplayManagerServiceInner::GetInstance().GetDisplayById(screenId_); + auto display = DisplayManagerServiceInner::GetInstance().GetDisplayById(displayId); if (display == nullptr) { - WLOGFE("GetAvoidPosType fail. Get display fail. displayId:%{public}" PRIu64"", screenId_); + WLOGFE("GetAvoidPosType fail. Get display fail. displayId: %{public}" PRIu64"", displayId); return AvoidPosType::AVOID_POS_UNKNOWN; } uint32_t displayWidth = display->GetWidth(); @@ -237,7 +260,7 @@ void WindowLayoutPolicy::UpdateLimitRect(const sptr& node, Rect& lim int32_t layoutW = static_cast(layoutRect.width_); if (node->GetWindowType() == WindowType::WINDOW_TYPE_STATUS_BAR || node->GetWindowType() == WindowType::WINDOW_TYPE_NAVIGATION_BAR) { - auto avoidPosType = GetAvoidPosType(layoutRect); + auto avoidPosType = GetAvoidPosType(layoutRect, node->GetDisplayId()); int32_t offsetH = 0; int32_t offsetW = 0; switch (avoidPosType) { @@ -273,29 +296,29 @@ void WindowLayoutPolicy::Reset() { } -float WindowLayoutPolicy::GetVirtualPixelRatio() const +float WindowLayoutPolicy::GetVirtualPixelRatio(DisplayId displayId) const { - auto display = DisplayManagerServiceInner::GetInstance().GetDisplayById(screenId_); + auto display = DisplayManagerServiceInner::GetInstance().GetDisplayById(displayId); if (display == nullptr) { - WLOGFE("GetVirtualPixel fail. Get display fail. displayId:%{public}" PRIu64", use Default vpr:1.0", screenId_); + WLOGFE("GetVirtualPixel fail. Get display fail. displayId:%{public}" PRIu64", use Default vpr:1.0", displayId); return 1.0; // Use DefaultVPR 1.0 } float virtualPixelRatio = display->GetVirtualPixelRatio(); if (virtualPixelRatio == 0.0) { - WLOGFE("GetVirtualPixel fail. vpr is 0.0. displayId:%{public}" PRIu64", use Default vpr:1.0", screenId_); + WLOGFE("GetVirtualPixel fail. vpr is 0.0. displayId:%{public}" PRIu64", use Default vpr:1.0", displayId); return 1.0; // Use DefaultVPR 1.0 } - WLOGFI("GetVirtualPixel success. displayId:%{public}" PRIu64", vpr:%{public}f", screenId_, virtualPixelRatio); + WLOGFI("GetVirtualPixel success. displayId:%{public}" PRIu64", vpr:%{public}f", displayId, virtualPixelRatio); return virtualPixelRatio; } -bool WindowLayoutPolicy::IsFullScreenRecentWindowExist() const +bool WindowLayoutPolicy::IsFullScreenRecentWindowExist(const std::vector>& nodeVec) const { - for (auto& childNode : aboveAppWindowNode_->children_) { - if (childNode->GetWindowType() == WindowType::WINDOW_TYPE_LAUNCHER_RECENT && - childNode->GetWindowMode() == WindowMode::WINDOW_MODE_FULLSCREEN) { + for (auto& node : nodeVec) { + if (node->GetWindowType() == WindowType::WINDOW_TYPE_LAUNCHER_RECENT && + node->GetWindowMode() == WindowMode::WINDOW_MODE_FULLSCREEN) { return true; } } diff --git a/wmserver/src/window_layout_policy_cascade.cpp b/wmserver/src/window_layout_policy_cascade.cpp index 83ea89c386..d2540187f0 100644 --- a/wmserver/src/window_layout_policy_cascade.cpp +++ b/wmserver/src/window_layout_policy_cascade.cpp @@ -25,17 +25,26 @@ namespace Rosen { namespace { constexpr HiviewDFX::HiLogLabel LABEL = {LOG_CORE, HILOG_DOMAIN_WINDOW, "WindowLayoutPolicyCascade"}; } -WindowLayoutPolicyCascade::WindowLayoutPolicyCascade(const Rect& displayRect, const uint64_t& screenId, - sptr& belowAppNode, sptr& appNode, sptr& aboveAppNode) - : WindowLayoutPolicy(displayRect, screenId, belowAppNode, appNode, aboveAppNode) +WindowLayoutPolicyCascade::WindowLayoutPolicyCascade(const std::map& displayRectMap, + WindowNodeMaps& windowNodeMaps) + : WindowLayoutPolicy(displayRectMap, windowNodeMaps) { + CascadeRects cascadeRects { + .primaryRect_ = {0, 0, 0, 0}, + .secondaryRect_ = {0, 0, 0, 0}, + .primaryLimitRect_ = {0, 0, 0, 0}, + .secondaryLimitRect_ = {0, 0, 0, 0}, + .dividerRect_ = {0, 0, 0, 0}, + .firstCascadeRect_ = {0, 0, 0, 0}, + }; + for (auto& iter : displayRectMap) { + cascadeRectsMap_.insert(std::make_pair(iter.first, cascadeRects)); + } } void WindowLayoutPolicyCascade::Launch() { - UpdateDisplayInfo(); - LayoutWindowNode(aboveAppWindowNode_); - InitCascadeRect(); + InitAllRects(); WLOGFI("WindowLayoutPolicyCascade::Launch"); } @@ -46,16 +55,27 @@ void WindowLayoutPolicyCascade::Clean() void WindowLayoutPolicyCascade::Reset() { - UpdateDisplayInfo(); + // reset split and limit rects + for (auto& iter : displayRectMap_) { + InitSplitRects(iter.first); + InitLimitRects(iter.first); + } } -void WindowLayoutPolicyCascade::UpdateDisplayInfo() +void WindowLayoutPolicyCascade::InitAllRects() { - InitSplitRects(); - InitLimitRects(); + for (auto& iter : displayRectMap_) { + // init split and limit rects + InitSplitRects(iter.first); + InitLimitRects(iter.first); + // init cascade rect + auto& windowNodeMap = windowNodeMaps_[iter.first]; + LayoutWindowNodesByRootType(*(windowNodeMap[WindowRootNodeType::ABOVE_WINDOW_NODE])); + InitCascadeRect(iter.first); + } } -void WindowLayoutPolicyCascade::LayoutWindowNode(sptr& node) +void WindowLayoutPolicyCascade::LayoutWindowNode(const sptr& node) { if (node == nullptr) { return; @@ -67,13 +87,16 @@ void WindowLayoutPolicyCascade::LayoutWindowNode(sptr& node) } UpdateLayoutRect(node); if (avoidTypes_.find(node->GetWindowType()) != avoidTypes_.end()) { - UpdateLimitRect(node, limitRect_); - UpdateSplitLimitRect(limitRect_, primaryLimitRect_); - UpdateSplitLimitRect(limitRect_, secondaryLimitRect_); + 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); 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_); + "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_); } } for (auto& childNode : node->children_) { @@ -81,57 +104,59 @@ void WindowLayoutPolicyCascade::LayoutWindowNode(sptr& node) } } -void WindowLayoutPolicyCascade::LayoutWindowTree() +void WindowLayoutPolicyCascade::LayoutWindowTree(DisplayId displayId) { - InitLimitRects(); - WindowLayoutPolicy::LayoutWindowTree(); + InitLimitRects(displayId); + WindowLayoutPolicy::LayoutWindowTree(displayId); } -void WindowLayoutPolicyCascade::RemoveWindowNode(sptr& node) +void WindowLayoutPolicyCascade::RemoveWindowNode(const sptr& node) { WM_FUNCTION_TRACE(); auto type = node->GetWindowType(); // affect other windows, trigger off global layout if (avoidTypes_.find(type) != avoidTypes_.end()) { - LayoutWindowTree(); + LayoutWindowTree(node->GetDisplayId()); } else if (type == WindowType::WINDOW_TYPE_DOCK_SLICE) { // split screen mode - InitSplitRects(); - LayoutWindowTree(); + InitSplitRects(node->GetDisplayId()); + LayoutWindowTree(node->GetDisplayId()); } Rect reqRect = node->GetRequestRect(); node->GetWindowToken()->UpdateWindowRect(reqRect, node->GetDecoStatus(), WindowSizeChangeReason::HIDE); } -void WindowLayoutPolicyCascade::UpdateWindowNode(sptr& node, bool isAddWindow) +void WindowLayoutPolicyCascade::UpdateWindowNode(const sptr& node, bool isAddWindow) { WM_FUNCTION_TRACE(); auto type = node->GetWindowType(); + const DisplayId& displayId = node->GetDisplayId(); // affect other windows, trigger off global layout if (avoidTypes_.find(type) != avoidTypes_.end()) { - LayoutWindowTree(); + LayoutWindowTree(displayId); } else if (type == WindowType::WINDOW_TYPE_DOCK_SLICE) { // split screen mode UpdateLayoutRect(node); auto splitDockerRect = node->GetWindowRect(); - SetSplitRect(splitDockerRect); // calculate primary/secondary depend on divider rect + 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) { - for (auto& childNode : appWindowNode_->children_) { // update split node size change reason + const auto& appWindowNodeVec = *(windowNodeMaps_[displayId][WindowRootNodeType::APP_WINDOW_NODE]); + for (auto& childNode : appWindowNodeVec) { // update split node size change reason if (childNode->IsSplitMode()) { childNode->SetWindowSizeChangeReason(WindowSizeChangeReason::DRAG); } } } - LayoutWindowTree(); + LayoutWindowTree(displayId); } else if (node->IsSplitMode()) { - LayoutWindowTree(); + LayoutWindowTree(displayId); } else { // layout single window LayoutWindowNode(node); } } -void WindowLayoutPolicyCascade::AddWindowNode(sptr& node) +void WindowLayoutPolicyCascade::AddWindowNode(const sptr& node) { WM_FUNCTION_TRACE(); auto property = node->GetWindowProperty(); @@ -143,57 +168,59 @@ void WindowLayoutPolicyCascade::AddWindowNode(sptr& node) SetCascadeRect(node); } if (node->GetWindowType() == WindowType::WINDOW_TYPE_DOCK_SLICE) { - node->SetRequestRect(dividerRect_); // init divider bar + node->SetRequestRect(cascadeRectsMap_[node->GetDisplayId()].dividerRect_); // init divider bar } UpdateWindowNode(node, true); // currently, update and add do the same process } -void WindowLayoutPolicyCascade::LimitMoveBounds(Rect& rect) const +void WindowLayoutPolicyCascade::LimitMoveBounds(Rect& rect, DisplayId displayId) const { - float virtualPixelRatio = GetVirtualPixelRatio(); + float virtualPixelRatio = GetVirtualPixelRatio(displayId); uint32_t minHorizontalSplitW = static_cast(MIN_HORIZONTAL_SPLIT_WIDTH * virtualPixelRatio); uint32_t minVerticalSplitH = static_cast(MIN_VERTICAL_SPLIT_HEIGHT * virtualPixelRatio); + const Rect& limitRect = limitRectMap_[displayId]; if (rect.width_ < rect.height_) { - if (rect.posX_ < (limitRect_.posX_ + static_cast(minHorizontalSplitW))) { - rect.posX_ = limitRect_.posX_ + static_cast(minHorizontalSplitW); + if (rect.posX_ < (limitRect.posX_ + static_cast(minHorizontalSplitW))) { + rect.posX_ = limitRect.posX_ + static_cast(minHorizontalSplitW); } else if (rect.posX_ > - (limitRect_.posX_ + limitRect_.width_ - static_cast(minHorizontalSplitW))) { - rect.posX_ = limitRect_.posX_ + static_cast(limitRect_.width_ - minHorizontalSplitW); + (limitRect.posX_ + static_cast(limitRect.width_ - minHorizontalSplitW))) { + rect.posX_ = limitRect.posX_ + static_cast(limitRect.width_ - minHorizontalSplitW); } } else { - if (rect.posY_ < (limitRect_.posY_ + static_cast(minVerticalSplitH))) { - rect.posY_ = limitRect_.posY_ + static_cast(minVerticalSplitH); + if (rect.posY_ < (limitRect.posY_ + static_cast(minVerticalSplitH))) { + rect.posY_ = limitRect.posY_ + static_cast(minVerticalSplitH); } else if (rect.posY_ > - (limitRect_.posY_ + static_cast(limitRect_.height_ - minVerticalSplitH))) { - rect.posY_ = limitRect_.posY_ + static_cast(limitRect_.height_ - minVerticalSplitH); + (limitRect.posY_ + static_cast(limitRect.height_ - minVerticalSplitH))) { + rect.posY_ = limitRect.posY_ + static_cast(limitRect.height_ - minVerticalSplitH); } } WLOGFI("limit divider move bounds:[%{public}d, %{public}d, %{public}u, %{public}u]", rect.posX_, rect.posY_, rect.width_, rect.height_); } -void WindowLayoutPolicyCascade::InitCascadeRect() +void WindowLayoutPolicyCascade::InitCascadeRect(DisplayId displayId) { constexpr uint32_t half = 2; constexpr float ratio = 0.66; // 0.66: default height/width ratio // calculate default H and w - uint32_t defaultW = static_cast(displayRect_.width_ * ratio); - uint32_t defaultH = static_cast(displayRect_.height_ * ratio); + uint32_t defaultW = static_cast(displayRectMap_[displayId].width_ * ratio); + uint32_t defaultH = static_cast(displayRectMap_[displayId].height_ * ratio); // calculate default x and y Rect resRect = {0, 0, defaultW, defaultH}; - if (defaultW <= limitRect_.width_ && defaultH <= limitRect_.height_) { - int32_t centerPosX = limitRect_.posX_ + static_cast(limitRect_.width_ / half); + 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); - int32_t centerPosY = limitRect_.posY_ + static_cast(limitRect_.height_ / half); + int32_t centerPosY = limitRect.posY_ + static_cast(limitRect.height_ / half); resRect.posY_ = centerPosY - static_cast(defaultH / half); } WLOGFI("init CascadeRect :[%{public}d, %{public}d, %{public}d, %{public}d]", resRect.posX_, resRect.posY_, resRect.width_, resRect.height_); - firstCascadeRect_ = resRect; + cascadeRectsMap_[displayId].firstCascadeRect_ = resRect; } void WindowLayoutPolicyCascade::ApplyWindowRectConstraints(const sptr& node, Rect& winRect) const @@ -201,27 +228,27 @@ void WindowLayoutPolicyCascade::ApplyWindowRectConstraints(const sptrGetWindowSizeChangeReason(); - float virtualPixelRatio = GetVirtualPixelRatio(); + float virtualPixelRatio = GetVirtualPixelRatio(node->GetDisplayId()); if (node->GetWindowType() == WindowType::WINDOW_TYPE_DOCK_SLICE) { // if divider, limit position - LimitMoveBounds(winRect); + LimitMoveBounds(winRect, node->GetDisplayId()); } if (reason == WindowSizeChangeReason::DRAG) { // if drag window, limit size and position if (WindowHelper::IsMainFloatingWindow(node->GetWindowType(), node->GetWindowMode())) { const Rect lastRect = node->GetWindowRect(); // fix rect in case of moving window when dragging winRect = WindowHelper::GetFixedWindowRectByLimitSize(winRect, lastRect, - IsVertical(), virtualPixelRatio); + IsVerticalDisplay(node->GetDisplayId()), virtualPixelRatio); winRect = WindowHelper::GetFixedWindowRectByLimitPosition(winRect, lastRect, - virtualPixelRatio, limitRect_); + virtualPixelRatio, limitRectMap_[node->GetDisplayId()]); } } // Limit window to the maximum window size - LimitWindowSize(node, displayRect_, winRect); + LimitWindowSize(node, displayRectMap_[node->GetDisplayId()], winRect); WLOGFI("After apply constraints winRect:[%{public}d, %{public}d, %{public}u, %{public}u]", winRect.posX_, winRect.posY_, winRect.width_, winRect.height_); } -void WindowLayoutPolicyCascade::UpdateLayoutRect(sptr& node) +void WindowLayoutPolicyCascade::UpdateLayoutRect(const sptr& node) { auto type = node->GetWindowType(); auto mode = node->GetWindowMode(); @@ -236,7 +263,7 @@ void WindowLayoutPolicyCascade::UpdateLayoutRect(sptr& node) bool subWindow = WindowHelper::IsSubWindow(type); bool floatingWindow = (mode == WindowMode::WINDOW_MODE_FLOATING); const Rect lastWinRect = node->GetWindowRect(); - Rect displayRect = GetDisplayRect(mode); + Rect displayRect = GetDisplayRect(mode, node->GetDisplayId()); Rect limitRect = displayRect; ComputeDecoratedRequestRect(node); Rect winRect = property->GetRequestRect(); @@ -246,7 +273,7 @@ void WindowLayoutPolicyCascade::UpdateLayoutRect(sptr& node) node->GetWindowId(), needAvoid, parentLimit, floatingWindow, subWindow, property->GetDecorEnable(), static_cast(type), winRect.posX_, winRect.posY_, winRect.width_, winRect.height_); if (needAvoid) { - limitRect = GetLimitRect(mode); + limitRect = GetLimitRect(mode, node->GetDisplayId()); } if (!floatingWindow) { // fullscreen window @@ -274,32 +301,32 @@ void WindowLayoutPolicyCascade::UpdateLayoutRect(sptr& node) } } -void WindowLayoutPolicyCascade::InitLimitRects() +void WindowLayoutPolicyCascade::InitLimitRects(DisplayId displayId) { - limitRect_ = displayRect_; - primaryLimitRect_ = primaryRect_; - secondaryLimitRect_ = secondaryRect_; + limitRectMap_[displayId] = displayRectMap_[displayId]; + cascadeRectsMap_[displayId].primaryLimitRect_ = cascadeRectsMap_[displayId].primaryRect_; + cascadeRectsMap_[displayId].secondaryLimitRect_ = cascadeRectsMap_[displayId].secondaryRect_; } -Rect WindowLayoutPolicyCascade::GetLimitRect(const WindowMode mode) const +Rect WindowLayoutPolicyCascade::GetLimitRect(const WindowMode mode, DisplayId displayId) const { if (mode == WindowMode::WINDOW_MODE_SPLIT_PRIMARY) { - return primaryLimitRect_; + return cascadeRectsMap_[displayId].primaryLimitRect_; } else if (mode == WindowMode::WINDOW_MODE_SPLIT_SECONDARY) { - return secondaryLimitRect_; + return cascadeRectsMap_[displayId].secondaryLimitRect_; } else { - return limitRect_; + return limitRectMap_[displayId]; } } -Rect WindowLayoutPolicyCascade::GetDisplayRect(const WindowMode mode) const +Rect WindowLayoutPolicyCascade::GetDisplayRect(const WindowMode mode, DisplayId displayId) const { if (mode == WindowMode::WINDOW_MODE_SPLIT_PRIMARY) { - return primaryRect_; + return cascadeRectsMap_[displayId].primaryRect_; } else if (mode == WindowMode::WINDOW_MODE_SPLIT_SECONDARY) { - return secondaryRect_; + return cascadeRectsMap_[displayId].secondaryRect_; } else { - return displayRect_; + return displayRectMap_[displayId]; } } @@ -316,100 +343,117 @@ void WindowLayoutPolicyCascade::UpdateSplitLimitRect(const Rect& limitRect, Rect limitSplitRect.posY_; } -void WindowLayoutPolicyCascade::InitSplitRects() +void WindowLayoutPolicyCascade::InitSplitRects(DisplayId displayId) { - float virtualPixelRatio = GetVirtualPixelRatio(); + float virtualPixelRatio = GetVirtualPixelRatio(displayId); uint32_t dividerWidth = static_cast(DIVIDER_WIDTH * virtualPixelRatio); - - if (!IsVertical()) { - dividerRect_ = { static_cast((displayRect_.width_ - dividerWidth) * DEFAULT_SPLIT_RATIO), 0, - dividerWidth, displayRect_.height_ }; + auto& dividerRect = cascadeRectsMap_[displayId].dividerRect_; + auto& displayRect = displayRectMap_[displayId]; + if (!IsVerticalDisplay(displayId)) { + dividerRect = { static_cast((displayRect.width_ - dividerWidth) * DEFAULT_SPLIT_RATIO), 0, + dividerWidth, displayRect.height_ }; } else { - dividerRect_ = { 0, static_cast((displayRect_.height_ - dividerWidth) * DEFAULT_SPLIT_RATIO), - displayRect_.width_, dividerWidth }; + 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_); + dividerRect.posX_, dividerRect.posY_, dividerRect.width_, dividerRect.height_); + SetSplitRect(dividerRect, displayId); } -void WindowLayoutPolicyCascade::SetSplitRectByRatio(float ratio) +void WindowLayoutPolicyCascade::SetSplitRectByRatio(float ratio, DisplayId displayId) { - if (!IsVertical()) { - dividerRect_.posX_ = limitRect_.posX_ + - static_cast((limitRect_.width_ - dividerRect_.width_) * ratio); + auto& dividerRect = cascadeRectsMap_[displayId].dividerRect_; + const Rect& limitRect = limitRectMap_[displayId]; + if (!IsVerticalDisplay(displayId)) { + dividerRect.posX_ = limitRect.posX_ + + static_cast((limitRect.width_ - dividerRect.width_) * ratio); } else { - dividerRect_.posY_ = limitRect_.posY_ + - static_cast((limitRect_.height_ - dividerRect_.height_) * ratio); + dividerRect.posY_ = limitRect.posY_ + + static_cast((limitRect.height_ - dividerRect.height_) * ratio); } WLOGFI("set dividerRect :[%{public}d, %{public}d, %{public}u, %{public}u]", - dividerRect_.posX_, dividerRect_.posY_, dividerRect_.width_, dividerRect_.height_); - SetSplitRect(dividerRect_); + dividerRect.posX_, dividerRect.posY_, dividerRect.width_, dividerRect.height_); + SetSplitRect(dividerRect, displayId); } -void WindowLayoutPolicyCascade::SetSplitRect(const Rect& divRect) +void WindowLayoutPolicyCascade::SetSplitRect(const Rect& divRect, DisplayId displayId) { - dividerRect_.width_ = divRect.width_; - dividerRect_.height_ = divRect.height_; - if (!IsVertical()) { - primaryRect_.posX_ = displayRect_.posX_; - primaryRect_.posY_ = displayRect_.posY_; - primaryRect_.width_ = divRect.posX_; - primaryRect_.height_ = displayRect_.height_; - - secondaryRect_.posX_ = divRect.posX_ + dividerRect_.width_; - secondaryRect_.posY_ = displayRect_.posY_; - secondaryRect_.width_ = displayRect_.width_ - secondaryRect_.posX_; - secondaryRect_.height_ = displayRect_.height_; + auto& dividerRect = cascadeRectsMap_[displayId].dividerRect_; + auto& primaryRect = cascadeRectsMap_[displayId].primaryRect_; + auto& secondaryRect = cascadeRectsMap_[displayId].secondaryRect_; + auto& displayRect = displayRectMap_[displayId]; + + dividerRect.width_ = divRect.width_; + dividerRect.height_ = divRect.height_; + if (!IsVerticalDisplay(displayId)) { + primaryRect.posX_ = displayRect.posX_; + primaryRect.posY_ = displayRect.posY_; + primaryRect.width_ = divRect.posX_; + primaryRect.height_ = displayRect.height_; + + secondaryRect.posX_ = divRect.posX_ + dividerRect.width_; + secondaryRect.posY_ = displayRect.posY_; + secondaryRect.width_ = displayRect.width_ - secondaryRect.posX_; + secondaryRect.height_ = displayRect.height_; } else { - primaryRect_.posX_ = displayRect_.posX_; - primaryRect_.posY_ = displayRect_.posY_; - primaryRect_.height_ = divRect.posY_; - primaryRect_.width_ = displayRect_.width_; - - secondaryRect_.posX_ = displayRect_.posX_; - secondaryRect_.posY_ = divRect.posY_ + dividerRect_.height_; - secondaryRect_.height_ = displayRect_.height_ - secondaryRect_.posY_; - secondaryRect_.width_ = displayRect_.width_; + primaryRect.posX_ = displayRect.posX_; + primaryRect.posY_ = displayRect.posY_; + primaryRect.height_ = divRect.posY_; + primaryRect.width_ = displayRect.width_; + + secondaryRect.posX_ = displayRect.posX_; + secondaryRect.posY_ = divRect.posY_ + dividerRect.height_; + secondaryRect.height_ = displayRect.height_ - secondaryRect.posY_; + secondaryRect.width_ = displayRect.width_; } } void WindowLayoutPolicyCascade::Reorder() { WLOGFI("Cascade reorder start"); - Rect rect = firstCascadeRect_; - bool isFirstReorderedWindow = true; - for (auto iter = appWindowNode_->children_.begin(); iter != appWindowNode_->children_.end(); iter++) { - auto node = *iter; - if (node == nullptr) { - WLOGFI("get node failed."); - continue; - } - if (node->GetWindowType() == WindowType::WINDOW_TYPE_APP_MAIN_WINDOW) { - if (isFirstReorderedWindow) { - isFirstReorderedWindow = false; - } else { - rect = StepCascadeRect(rect); + for (auto& iter : displayRectMap_) { + DisplayId displayId = iter.first; + Rect rect = cascadeRectsMap_[displayId].firstCascadeRect_; + bool isFirstReorderedWindow = true; + const auto& appWindowNodeVec = *(windowNodeMaps_[displayId][WindowRootNodeType::APP_WINDOW_NODE]); + for (auto iter = appWindowNodeVec.begin(); iter != appWindowNodeVec.end(); iter++) { + auto node = *iter; + if (node == nullptr) { + WLOGFI("get node failed."); + continue; } - node->SetRequestRect(rect); - node->SetDecoStatus(true); - if (node->GetWindowMode() != WindowMode::WINDOW_MODE_FLOATING) { - node->SetWindowMode(WindowMode::WINDOW_MODE_FLOATING); - node->GetWindowToken()->UpdateWindowMode(WindowMode::WINDOW_MODE_FLOATING); + if (node->GetWindowType() == WindowType::WINDOW_TYPE_APP_MAIN_WINDOW) { + 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); + 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_); } WLOGFI("Cascade reorder Id: %{public}u, rect:[%{public}d, %{public}d, %{public}d, %{public}d]", node->GetWindowId(), rect.posX_, rect.posY_, rect.width_, rect.height_); } + LayoutWindowTree(displayId); } - LayoutWindowTree(); WLOGFI("Reorder end"); } Rect WindowLayoutPolicyCascade::GetCurCascadeRect(const sptr& node) const { Rect cascadeRect = {0, 0, 0, 0}; - for (auto iter = appWindowNode_->children_.rbegin(); iter != appWindowNode_->children_.rend(); iter++) { - WLOGFI("GetCurCascadeRect id: %{public}u,", (*iter)->GetWindowId()); + const DisplayId& displayId = node->GetDisplayId(); + const auto& appWindowNodeVec = *(const_cast(this)-> + windowNodeMaps_[displayId][WindowRootNodeType::APP_WINDOW_NODE]); + for (auto iter = appWindowNodeVec.rbegin(); iter != appWindowNodeVec.rend(); iter++) { + WLOGFI("GetCurCascadeRect id: %{public}d,", (*iter)->GetWindowId()); if ((*iter)->GetWindowType() != WindowType::WINDOW_TYPE_DOCK_SLICE && (*iter)->GetWindowId() != node->GetWindowId()) { auto property = (*iter)->GetWindowProperty(); @@ -423,27 +467,30 @@ Rect WindowLayoutPolicyCascade::GetCurCascadeRect(const sptr& node) } if (WindowHelper::IsEmptyRect(cascadeRect)) { WLOGFI("cascade rect is empty use first cascade rect"); - return firstCascadeRect_; + return cascadeRectsMap_[displayId].firstCascadeRect_; } - return StepCascadeRect(cascadeRect); + return StepCascadeRect(cascadeRect, displayId); } -Rect WindowLayoutPolicyCascade::StepCascadeRect(Rect rect) const +Rect WindowLayoutPolicyCascade::StepCascadeRect(Rect rect, DisplayId displayId) const { - float virtualPixelRatio = GetVirtualPixelRatio(); + float virtualPixelRatio = GetVirtualPixelRatio(displayId); uint32_t cascadeWidth = static_cast(WINDOW_TITLE_BAR_HEIGHT * virtualPixelRatio); uint32_t cascadeHeight = static_cast(WINDOW_TITLE_BAR_HEIGHT * virtualPixelRatio); + const Rect& limitRect = limitRectMap_[displayId]; Rect cascadeRect = {0, 0, 0, 0}; cascadeRect.width_ = rect.width_; cascadeRect.height_ = rect.height_; - cascadeRect.posX_ = (rect.posX_ + cascadeWidth >= limitRect_.posX_) && - (rect.posX_ + rect.width_ + cascadeWidth <= (limitRect_.width_ + limitRect_.posX_)) ? - (rect.posX_ + cascadeWidth) : limitRect_.posX_; - cascadeRect.posY_ = (rect.posY_ + cascadeHeight >= limitRect_.posY_) && - (rect.posY_ + rect.height_ + cascadeHeight <= (limitRect_.height_ + limitRect_.posY_)) ? - (rect.posY_ + cascadeHeight) : limitRect_.posY_; - WLOGFI("step cascadeRect :[%{public}d, %{public}d, %{public}d, %{public}d]", + cascadeRect.posX_ = (rect.posX_ + static_cast(cascadeWidth) >= limitRect.posX_) && + (rect.posX_ + static_cast(rect.width_ + cascadeWidth) <= + (limitRect.posX_ + static_cast(limitRect.width_))) ? + (rect.posX_ + static_cast(cascadeWidth)) : limitRect.posX_; + cascadeRect.posY_ = (rect.posY_ + static_cast(cascadeHeight) >= limitRect.posY_) && + (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]", cascadeRect.posX_, cascadeRect.posY_, cascadeRect.width_, cascadeRect.height_); return cascadeRect; } @@ -459,7 +506,7 @@ void WindowLayoutPolicyCascade::SetCascadeRect(const sptr& node) } if (WindowHelper::IsAppWindow(property->GetWindowType()) && isFirstAppWindow) { WLOGFI("set first app window cascade rect"); - rect = firstCascadeRect_; + rect = cascadeRectsMap_[node->GetDisplayId()].firstCascadeRect_; isFirstAppWindow = false; } else if (WindowHelper::IsAppWindow(property->GetWindowType()) && !isFirstAppWindow) { WLOGFI("set other app window cascade rect"); @@ -467,7 +514,7 @@ void WindowLayoutPolicyCascade::SetCascadeRect(const sptr& node) } else { // system window WLOGFI("set system window cascade rect"); - rect = firstCascadeRect_; + rect = cascadeRectsMap_[node->GetDisplayId()].firstCascadeRect_; } WLOGFI("set cascadeRect :[%{public}d, %{public}d, %{public}d, %{public}d]", rect.posX_, rect.posY_, rect.width_, rect.height_); diff --git a/wmserver/src/window_layout_policy_tile.cpp b/wmserver/src/window_layout_policy_tile.cpp index 04b74c9685..4330491950 100644 --- a/wmserver/src/window_layout_policy_tile.cpp +++ b/wmserver/src/window_layout_policy_tile.cpp @@ -27,119 +27,137 @@ namespace { constexpr uint32_t EDGE_INTERVAL = 48; constexpr uint32_t MID_INTERVAL = 24; } -WindowLayoutPolicyTile::WindowLayoutPolicyTile(const Rect& displayRect, const uint64_t& screenId, - sptr& belowAppNode, sptr& appNode, sptr& aboveAppNode) - : WindowLayoutPolicy(displayRect, screenId, belowAppNode, appNode, aboveAppNode) +WindowLayoutPolicyTile::WindowLayoutPolicyTile(const std::map& displayRectMap, + WindowNodeMaps& windowNodeMaps) + : WindowLayoutPolicy(displayRectMap, windowNodeMaps) { + for (auto& iter : displayRectMap) { + maxTileWinNumMap_.insert(std::make_pair(iter.first, static_cast(1))); + } } void WindowLayoutPolicyTile::Launch() { // compute limit rect - UpdateDisplayInfo(); + InitAllRects(); // select app min win in queue, and minimize others InitForegroundNodeQueue(); - AssignNodePropertyForTileWindows(); - LayoutForegroundNodeQueue(); - LayoutWindowNode(belowAppWindowNode_); + for (auto& iter : displayRectMap_) { + DisplayId displayId = iter.first; + AssignNodePropertyForTileWindows(displayId); + LayoutForegroundNodeQueue(displayId); + auto& windowNodeMap = windowNodeMaps_[displayId]; + LayoutWindowNodesByRootType(*(windowNodeMap[WindowRootNodeType::BELOW_WINDOW_NODE])); + } WLOGFI("WindowLayoutPolicyTile::Launch"); } -void WindowLayoutPolicyTile::UpdateDisplayInfo() +void WindowLayoutPolicyTile::InitAllRects() { - limitRect_ = displayRect_; - LayoutWindowNode(aboveAppWindowNode_); - InitTileWindowRects(); + for (auto& iter : displayRectMap_) { + DisplayId displayId = iter.first; + limitRectMap_[displayId] = iter.second; + auto& windowNodeMap = windowNodeMaps_[displayId]; + LayoutWindowNodesByRootType(*(windowNodeMap[WindowRootNodeType::ABOVE_WINDOW_NODE])); + InitTileWindowRects(displayId); + } } -uint32_t WindowLayoutPolicyTile::GetMaxTileWinNum() const +uint32_t WindowLayoutPolicyTile::GetMaxTileWinNum(DisplayId displayId) const { - float virtualPixelRatio = GetVirtualPixelRatio(); + float virtualPixelRatio = GetVirtualPixelRatio(displayId); constexpr uint32_t half = 2; uint32_t edgeIntervalVp = static_cast(EDGE_INTERVAL * half * virtualPixelRatio); uint32_t midIntervalVp = static_cast(MID_INTERVAL * virtualPixelRatio); - uint32_t minFloatingW = IsVertical() ? MIN_VERTICAL_FLOATING_WIDTH : MIN_VERTICAL_FLOATING_HEIGHT; + uint32_t minFloatingW = IsVerticalDisplay(displayId) ? MIN_VERTICAL_FLOATING_WIDTH : MIN_VERTICAL_FLOATING_HEIGHT; minFloatingW = static_cast(minFloatingW * virtualPixelRatio); - uint32_t drawableW = limitRect_.width_ - edgeIntervalVp + midIntervalVp; + uint32_t drawableW = limitRectMap_[displayId].width_ - edgeIntervalVp + midIntervalVp; return static_cast(drawableW / (minFloatingW + midIntervalVp)); } -void WindowLayoutPolicyTile::InitTileWindowRects() +void WindowLayoutPolicyTile::InitTileWindowRects(DisplayId displayId) { - float virtualPixelRatio = GetVirtualPixelRatio(); + float virtualPixelRatio = GetVirtualPixelRatio(displayId); uint32_t edgeIntervalVp = static_cast(EDGE_INTERVAL * virtualPixelRatio); uint32_t midIntervalVp = static_cast(MID_INTERVAL * virtualPixelRatio); + const Rect& limitRect = limitRectMap_[displayId]; + const Rect& displayRect = displayRectMap_[displayId]; constexpr float ratio = 0.66; // 0.66: default height/width ratio constexpr int half = 2; - maxTileWinNum_ = GetMaxTileWinNum(); - WLOGFI("set max tile window num %{public}u", maxTileWinNum_); - presetRects_.clear(); - uint32_t w = displayRect_.width_ * ratio; - uint32_t h = displayRect_.height_ * ratio; - w = w > limitRect_.width_ ? limitRect_.width_ : w; - h = h > limitRect_.height_ ? limitRect_.height_ : h; - int x = limitRect_.posX_ + ((limitRect_.width_ - w) / half); - int y = limitRect_.posY_ + ((limitRect_.height_ - h) / half); + maxTileWinNumMap_[displayId] = GetMaxTileWinNum(displayId); + WLOGFI("set max tile window num %{public}u", maxTileWinNumMap_[displayId]); + auto& presetRects = presetRectsMap_[displayId]; + presetRects.clear(); + uint32_t w = displayRect.width_ * ratio; + uint32_t h = displayRect.height_ * ratio; + w = w > limitRect.width_ ? limitRect.width_ : w; + h = h > limitRect.height_ ? limitRect.height_ : h; + int x = limitRect.posX_ + ((limitRect.width_ - w) / half); + int y = limitRect.posY_ + ((limitRect.height_ - h) / half); + std::vector single = {{ x, y, w, h }}; - presetRects_.emplace_back(single); - for (uint32_t num = 2; num <= maxTileWinNum_; num++) { // start calc preset with 2 windows - w = (limitRect_.width_ - edgeIntervalVp * half - midIntervalVp * (num - 1)) / num; + presetRects.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); + 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); curLevel.emplace_back(curRect); } - presetRects_.emplace_back(curLevel); + presetRects.emplace_back(curLevel); } } -void WindowLayoutPolicyTile::AddWindowNode(sptr& node) +void WindowLayoutPolicyTile::AddWindowNode(const sptr& node) { WM_FUNCTION_TRACE(); if (WindowHelper::IsMainWindow(node->GetWindowType())) { - ForegroundNodeQueuePushBack(node); - AssignNodePropertyForTileWindows(); - LayoutForegroundNodeQueue(); + 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(sptr& node, bool isAddWindow) +void WindowLayoutPolicyTile::UpdateWindowNode(const sptr& node, bool isAddWindow) { WM_FUNCTION_TRACE(); WindowLayoutPolicy::UpdateWindowNode(node); if (avoidTypes_.find(node->GetWindowType()) != avoidTypes_.end()) { - InitTileWindowRects(); - AssignNodePropertyForTileWindows(); - LayoutForegroundNodeQueue(); + DisplayId displayId = node->GetDisplayId(); + InitTileWindowRects(displayId); + AssignNodePropertyForTileWindows(displayId); + LayoutForegroundNodeQueue(displayId); } } -void WindowLayoutPolicyTile::RemoveWindowNode(sptr& node) +void WindowLayoutPolicyTile::RemoveWindowNode(const sptr& node) { WM_FUNCTION_TRACE(); 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(); + LayoutWindowTree(displayId); } else { ForegroundNodeQueueRemove(node); - AssignNodePropertyForTileWindows(); - LayoutForegroundNodeQueue(); + AssignNodePropertyForTileWindows(displayId); + LayoutForegroundNodeQueue(displayId); } Rect reqRect = node->GetRequestRect(); node->GetWindowToken()->UpdateWindowRect(reqRect, node->GetDecoStatus(), WindowSizeChangeReason::HIDE); } -void WindowLayoutPolicyTile::LayoutForegroundNodeQueue() +void WindowLayoutPolicyTile::LayoutForegroundNodeQueue(DisplayId displayId) { - for (auto& node : foregroundNodes_) { + for (auto& node : foregroundNodesMap_[displayId]) { Rect lastRect = node->GetWindowRect(); Rect winRect = node->GetRequestRect(); node->SetWindowRect(winRect); @@ -156,59 +174,67 @@ void WindowLayoutPolicyTile::LayoutForegroundNodeQueue() void WindowLayoutPolicyTile::InitForegroundNodeQueue() { - foregroundNodes_.clear(); - for (auto& node : appWindowNode_->children_) { - if (WindowHelper::IsMainWindow(node->GetWindowType())) { - ForegroundNodeQueuePushBack(node); + for (auto& iter : displayRectMap_) { + DisplayId displayId = iter.first; + foregroundNodesMap_[displayId].clear(); + const auto& appWindowNodes = *(windowNodeMaps_[displayId][WindowRootNodeType::APP_WINDOW_NODE]); + for (auto& node : appWindowNodes) { + if (WindowHelper::IsMainWindow(node->GetWindowType())) { + ForegroundNodeQueuePushBack(node, displayId); + } } } } -void WindowLayoutPolicyTile::ForegroundNodeQueuePushBack(sptr& node) +void WindowLayoutPolicyTile::ForegroundNodeQueuePushBack(const sptr& node, DisplayId displayId) { if (node == nullptr) { return; } - WLOGFI("add win in tile for win id: %{public}u", node->GetWindowId()); - while (foregroundNodes_.size() >= maxTileWinNum_) { - auto removeNode = foregroundNodes_.front(); - foregroundNodes_.pop_front(); - WLOGFI("pop win in queue head id: %{public}u, for add new win", removeNode->GetWindowId()); + 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()); if (removeNode->abilityToken_ != nullptr) { WLOGFI("minimize win %{public}u in tile", removeNode->GetWindowId()); AAFwk::AbilityManagerClient::GetInstance()->MinimizeAbility(removeNode->abilityToken_); } } - foregroundNodes_.push_back(node); + foregroundNodes.push_back(node); } -void WindowLayoutPolicyTile::ForegroundNodeQueueRemove(sptr& node) +void WindowLayoutPolicyTile::ForegroundNodeQueueRemove(const sptr& node) { if (node == nullptr) { return; } - auto iter = std::find(foregroundNodes_.begin(), foregroundNodes_.end(), node); - if (iter != foregroundNodes_.end()) { - WLOGFI("remove win in tile for win id: %{public}u", node->GetWindowId()); - foregroundNodes_.erase(iter); + DisplayId displayId = node->GetDisplayId(); + 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()); + foregroundNodes.erase(iter); } } -void WindowLayoutPolicyTile::AssignNodePropertyForTileWindows() +void WindowLayoutPolicyTile::AssignNodePropertyForTileWindows(DisplayId displayId) { // set rect for foreground windows - uint32_t num = foregroundNodes_.size(); - if (num > maxTileWinNum_ || num > presetRects_.size() || num == 0) { + uint32_t num = foregroundNodesMap_[displayId].size(); + auto& presetRects = presetRectsMap_[displayId]; + if (num > maxTileWinNumMap_[displayId] || num > presetRects.size() || num == 0) { WLOGE("invalid tile queue"); return; } - std::vector& presetRect = presetRects_[num - 1]; + std::vector& presetRect = presetRects[num - 1]; if (presetRect.size() != num) { WLOGE("invalid preset rects"); return; } auto rectIt = presetRect.begin(); - for (auto node : foregroundNodes_) { + for (auto node : foregroundNodesMap_[displayId]) { auto& rect = (*rectIt); node->SetWindowMode(WindowMode::WINDOW_MODE_FLOATING); node->GetWindowToken()->UpdateWindowMode(WindowMode::WINDOW_MODE_FLOATING); @@ -220,7 +246,7 @@ void WindowLayoutPolicyTile::AssignNodePropertyForTileWindows() } } -void WindowLayoutPolicyTile::UpdateLayoutRect(sptr& node) +void WindowLayoutPolicyTile::UpdateLayoutRect(const sptr& node) { auto type = node->GetWindowType(); auto mode = node->GetWindowMode(); @@ -236,7 +262,7 @@ void WindowLayoutPolicyTile::UpdateLayoutRect(sptr& node) bool subWindow = WindowHelper::IsSubWindow(type); bool floatingWindow = (mode == WindowMode::WINDOW_MODE_FLOATING); const Rect lastRect = node->GetWindowRect(); - Rect limitRect = displayRect_; + Rect limitRect = displayRectMap_[node->GetDisplayId()]; ComputeDecoratedRequestRect(node); Rect winRect = node->GetRequestRect(); @@ -245,7 +271,7 @@ void WindowLayoutPolicyTile::UpdateLayoutRect(sptr& node) node->GetWindowId(), needAvoid, parentLimit, floatingWindow, subWindow, decorEnbale, static_cast(type), winRect.posX_, winRect.posY_, winRect.width_, winRect.height_); if (needAvoid) { - limitRect = limitRect_; + limitRect = limitRectMap_[node->GetDisplayId()]; } if (!floatingWindow) { // fullscreen window @@ -256,7 +282,7 @@ void WindowLayoutPolicyTile::UpdateLayoutRect(sptr& node) UpdateFloatingLayoutRect(limitRect, winRect); } } - LimitWindowSize(node, displayRect_, winRect); + LimitWindowSize(node, displayRectMap_[node->GetDisplayId()], winRect); node->SetWindowRect(winRect); CalcAndSetNodeHotZone(winRect, node); if (!(lastRect == winRect)) { diff --git a/wmserver/src/window_manager_service.cpp b/wmserver/src/window_manager_service.cpp index 44a51c1ae1..b54aa8d1c1 100644 --- a/wmserver/src/window_manager_service.cpp +++ b/wmserver/src/window_manager_service.cpp @@ -377,6 +377,7 @@ WMError WindowManagerService::GetTopWindowId(uint32_t mainWinId, uint32_t& topWi WMError WindowManagerService::SetWindowLayoutMode(DisplayId displayId, WindowLayoutMode mode) { + WLOGFI("SetWindowLayoutMode, displayId: %{public}" PRIu64", layoutMode: %{public}u", displayId, mode); WM_SCOPED_TRACE("wms:SetWindowLayoutMode"); std::lock_guard lock(mutex_); return windowController_->SetWindowLayoutMode(displayId, mode); diff --git a/wmserver/src/window_node_container.cpp b/wmserver/src/window_node_container.cpp index b4ccdb08b5..5b8f7032b1 100644 --- a/wmserver/src/window_node_container.cpp +++ b/wmserver/src/window_node_container.cpp @@ -46,25 +46,33 @@ namespace { } WindowNodeContainer::WindowNodeContainer(DisplayId displayId, uint32_t width, uint32_t height, bool isMinimizedByOther) - : displayId_(displayId), isMinimizedByOther_(isMinimizedByOther) { - displayRect_ = { + isMinimizedByOther_ = isMinimizedByOther; + Rect displayRect = { .posX_ = 0, .posY_ = 0, .width_ = width, .height_ = height }; - windowPair_ = new WindowPair(displayId_, appWindowNode_); - layoutPolicys_[WindowLayoutMode::CASCADE] = - new WindowLayoutPolicyCascade(displayRect_, displayId_, - belowAppWindowNode_, appWindowNode_, aboveAppWindowNode_); - layoutPolicys_[WindowLayoutMode::TILE] = - new WindowLayoutPolicyTile(displayRect_, displayId_, - belowAppWindowNode_, appWindowNode_, aboveAppWindowNode_); + displayRectMap_.insert(std::make_pair(displayId, displayRect)); + windowPair_ = new WindowPair(displayId, appWindowNode_); + + // init window node maps + InitWindowNodeMapForDisplay(displayId); + + // init layout policy + layoutPolicys_[WindowLayoutMode::CASCADE] = new WindowLayoutPolicyCascade(displayRectMap_, windowNodeMaps_); + layoutPolicys_[WindowLayoutMode::TILE] = new WindowLayoutPolicyTile(displayRectMap_, windowNodeMaps_); layoutPolicy_ = layoutPolicys_[WindowLayoutMode::CASCADE]; layoutPolicy_->Launch(); - UpdateAvoidAreaFunc func = std::bind(&WindowNodeContainer::OnAvoidAreaChange, this, std::placeholders::_1); + + // init avoidAreaController + UpdateAvoidAreaFunc func = std::bind(&WindowNodeContainer::OnAvoidAreaChange, this, + std::placeholders::_1, std::placeholders::_2); avoidController_ = new AvoidAreaController(displayId, func); + + // init systembar map + InitSysBarMapForDisplay(displayId); } WindowNodeContainer::~WindowNodeContainer() @@ -72,16 +80,31 @@ WindowNodeContainer::~WindowNodeContainer() Destroy(); } -void WindowNodeContainer::UpdateDisplayRect(uint32_t width, uint32_t height) +void WindowNodeContainer::InitSysBarMapForDisplay(DisplayId displayId) { - WLOGFI("update display rect, w/h=%{public}u/%{public}u", width, height); - displayRect_ = { - .posX_ = 0, - .posY_ = 0, - .width_ = width, - .height_ = height + SysBarNodeMap sysBarNodeMap { + { WindowType::WINDOW_TYPE_STATUS_BAR, nullptr }, + { WindowType::WINDOW_TYPE_NAVIGATION_BAR, nullptr }, + }; + sysBarNodeMaps_.insert(std::make_pair(displayId, sysBarNodeMap)); + + SysBarTintMap sysBarTintMap { + { WindowType::WINDOW_TYPE_STATUS_BAR, SystemBarRegionTint() }, + { WindowType::WINDOW_TYPE_NAVIGATION_BAR, SystemBarRegionTint() }, }; - layoutPolicy_->LayoutWindowTree(); + sysBarTintMaps_.insert(std::make_pair(displayId, sysBarTintMap)); +} + +void WindowNodeContainer::InitWindowNodeMapForDisplay(DisplayId displayId) +{ + std::map>>> windowRootNodeMap; + windowRootNodeMap.insert(std::make_pair(WindowRootNodeType::APP_WINDOW_NODE, + std::make_unique>>())); + windowRootNodeMap.insert(std::make_pair(WindowRootNodeType::ABOVE_WINDOW_NODE, + std::make_unique>>())); + windowRootNodeMap.insert(std::make_pair(WindowRootNodeType::BELOW_WINDOW_NODE, + std::make_unique>>())); + windowNodeMaps_.insert(std::make_pair(displayId, std::move(windowRootNodeMap))); } int WindowNodeContainer::GetWindowCountByType(WindowType windowType) @@ -103,15 +126,72 @@ WMError WindowNodeContainer::MinimizeStructuredAppWindowsExceptSelf(const sptr& node, sptr& parentNode) +std::vector>* WindowNodeContainer::FindNodeVectorOfRoot(DisplayId displayId, WindowRootNodeType type) { - if (!node->surfaceNode_) { - WLOGFE("surface node is nullptr!"); - return WMError::WM_ERROR_NULLPTR; + if (windowNodeMaps_.find(displayId) != windowNodeMaps_.end()) { + auto& rootNodemap = windowNodeMaps_[displayId]; + if (rootNodemap.find(type) != rootNodemap.end()) { + return rootNodemap[type].get(); + } + } + return nullptr; +} + +void WindowNodeContainer::AddWindowNodeInRootNodeVector(sptr& node, WindowRootNodeType rootType) +{ + std::vector>* rootNodeVectorPtr = FindNodeVectorOfRoot(node->GetDisplayId(), rootType); + if (rootNodeVectorPtr != nullptr) { + rootNodeVectorPtr->push_back(node); + WLOGFI("add node in node vector of root, windowId: %{public}d, rootType: %{public}d", + node->GetWindowId(), rootType); + } else { + WLOGFE("add node failed, rootNode vector is empty, windowId: %{public}d, rootType: %{public}d", + node->GetWindowId(), rootType); + } +} + +void WindowNodeContainer::RemoveWindowNodeFromRootNodeVector(sptr& node, WindowRootNodeType rootType) +{ + std::vector>* rootNodeVectorPtr = FindNodeVectorOfRoot(node->GetDisplayId(), rootType); + if (rootNodeVectorPtr != nullptr) { + auto iter = std::remove(rootNodeVectorPtr->begin(), rootNodeVectorPtr->end(), node); + rootNodeVectorPtr->erase(iter, rootNodeVectorPtr->end()); + WLOGFI("remove node from node vector of root, windowId: %{public}d, rootType: %{public}d", + node->GetWindowId(), rootType); + } else { + WLOGFE("remove node failed, rootNode vector is empty, windowId: %{public}d, rootType: %{public}d", + node->GetWindowId(), rootType); } +} + +void WindowNodeContainer::UpdateWindowNodeMaps() +{ + for (auto& elem : windowNodeMaps_) { + for (auto& nodeVec : elem.second) { + auto emptyVector = std::vector>(); + nodeVec.second->swap(emptyVector); + } + } + + std::vector> rootNodes = { aboveAppWindowNode_, appWindowNode_, belowAppWindowNode_ }; + std::vector rootNodeType = { + WindowRootNodeType::ABOVE_WINDOW_NODE, + WindowRootNodeType::APP_WINDOW_NODE, + WindowRootNodeType::BELOW_WINDOW_NODE + }; + for (size_t index = 0; index < rootNodes.size(); ++index) { + auto rootType = rootNodeType[index]; + for (auto& node : rootNodes[index]->children_) { + AddWindowNodeInRootNodeVector(node, rootType); + } + } +} + +WMError WindowNodeContainer::AddWindowNodeOnWindowTree(sptr& node, sptr& parentNode) +{ sptr root = FindRoot(node->GetWindowType()); if (root == nullptr) { - WLOGFE("root window node is nullptr!"); + WLOGFE("root is nullptr!"); return WMError::WM_ERROR_NULLPTR; } node->requestedVisibility_ = true; @@ -121,18 +201,35 @@ WMError WindowNodeContainer::AddWindowNode(sptr& node, sptrcurrentVisibility_ = parentNode->currentVisibility_; + node->parent_ = parentNode; } else { // mainwindow - parentNode = root; + node->parent_ = root; node->currentVisibility_ = true; for (auto& child : node->children_) { child->currentVisibility_ = child->requestedVisibility_; } if (WindowHelper::IsAvoidAreaWindow(node->GetWindowType())) { - sysBarNodeMap_[node->GetWindowType()] = node; + sysBarNodeMaps_[node->GetDisplayId()][node->GetWindowType()] = node; } } - node->parent_ = parentNode; + return WMError::WM_OK; +} + +WMError WindowNodeContainer::AddWindowNode(sptr& node, sptr& parentNode) +{ + if (!node->surfaceNode_) { + WLOGFE("surface node is nullptr!"); + return WMError::WM_ERROR_NULLPTR; + } + + WMError ret = AddWindowNodeOnWindowTree(node, parentNode); + if (ret != WMError::WM_OK) { + WLOGFE("Add window failed!"); + return ret; + } + windowPair_->UpdateIfSplitRelated(node); + UpdateWindowTree(node); if (node->IsSplitMode() || node->GetWindowType() == WindowType::WINDOW_TYPE_DOCK_SLICE) { RaiseSplitRelatedWindowToTop(node); @@ -142,9 +239,9 @@ WMError WindowNodeContainer::AddWindowNode(sptr& node, sptrAddWindowNode(node); if (WindowHelper::IsAvoidAreaWindow(node->GetWindowType())) { avoidController_->AvoidControl(node, AvoidControlType::AVOID_NODE_ADD); - NotifyIfSystemBarRegionChanged(); + NotifyIfSystemBarRegionChanged(node->GetDisplayId()); } else { - NotifyIfSystemBarTintChanged(); + NotifyIfSystemBarTintChanged(node->GetDisplayId()); } std::vector> infos; UpdateWindowVisibilityInfos(infos); @@ -161,14 +258,14 @@ WMError WindowNodeContainer::UpdateWindowNode(sptr& node, WindowUpda return WMError::WM_ERROR_NULLPTR; } if (WindowHelper::IsMainWindow(node->GetWindowType()) && WindowHelper::IsSwitchCascadeReason(reason)) { - SwitchLayoutPolicy(WindowLayoutMode::CASCADE); + SwitchLayoutPolicy(WindowLayoutMode::CASCADE, node->GetDisplayId()); } layoutPolicy_->UpdateWindowNode(node); if (WindowHelper::IsAvoidAreaWindow(node->GetWindowType())) { avoidController_->AvoidControl(node, AvoidControlType::AVOID_NODE_UPDATE); - NotifyIfSystemBarRegionChanged(); + NotifyIfSystemBarRegionChanged(node->GetDisplayId()); } else { - NotifyIfSystemBarTintChanged(); + NotifyIfSystemBarTintChanged(node->GetDisplayId()); } DumpScreenWindowTree(); WLOGFI("UpdateWindowNode windowId: %{public}u end", node->GetWindowId()); @@ -216,20 +313,20 @@ bool WindowNodeContainer::UpdateRSTree(sptr& node, bool isAdd) { WM_FUNCTION_TRACE(); static const bool IsWindowAnimationEnabled = ReadIsWindowAnimationEnabledProperty(); - + DisplayId displayId = node->GetDisplayId(); auto updateRSTreeFunc = [&]() { auto& dms = DisplayManagerServiceInner::GetInstance(); if (isAdd) { - dms.UpdateRSTree(displayId_, node->surfaceNode_, true); + dms.UpdateRSTree(displayId, node->surfaceNode_, true); for (auto& child : node->children_) { if (child->currentVisibility_) { - dms.UpdateRSTree(displayId_, child->surfaceNode_, true); + dms.UpdateRSTree(displayId, child->surfaceNode_, true); } } } else { - dms.UpdateRSTree(displayId_, node->surfaceNode_, false); + dms.UpdateRSTree(displayId, node->surfaceNode_, false); for (auto& child : node->children_) { - dms.UpdateRSTree(displayId_, child->surfaceNode_, false); + dms.UpdateRSTree(displayId, child->surfaceNode_, false); } } }; @@ -246,6 +343,8 @@ bool WindowNodeContainer::UpdateRSTree(sptr& node, bool isAdd) updateRSTreeFunc(); } + UpdateWindowNodeMaps(); + return true; } @@ -267,28 +366,39 @@ WMError WindowNodeContainer::DestroyWindowNode(sptr& node, std::vect child->surfaceNode_ = nullptr; } } - node->children_.clear(); + auto emptyVector = std::vector>(); + node->children_.swap(emptyVector); return WMError::WM_OK; } +void WindowNodeContainer::RemoveWindowNodeFromWindowTree(sptr& node) +{ + // remove this node from node vector of display + sptr root = FindRoot(node->GetWindowType()); + + // remove this node from parent + auto iter = std::find(node->parent_->children_.begin(), node->parent_->children_.end(), node); + if (iter != node->parent_->children_.end()) { + node->parent_->children_.erase(iter); + } else { + WLOGFE("can't find this node in parent"); + } + node->parent_ = nullptr; +} + WMError WindowNodeContainer::RemoveWindowNode(sptr& node) { if (node == nullptr) { WLOGFE("window node or surface node is nullptr, invalid"); return WMError::WM_ERROR_DESTROYED_OBJECT; } + if (node->parent_ == nullptr) { WLOGFW("can't find parent of this node"); } else { - // remove this node from parent - auto iter = std::find(node->parent_->children_.begin(), node->parent_->children_.end(), node); - if (iter != node->parent_->children_.end()) { - node->parent_->children_.erase(iter); - } else { - WLOGFE("can't find this node in parent"); - } - node->parent_ = nullptr; + RemoveWindowNodeFromWindowTree(node); } + node->requestedVisibility_ = false; node->currentVisibility_ = false; node->isCovered_ = true; @@ -307,30 +417,31 @@ WMError WindowNodeContainer::RemoveWindowNode(sptr& node) windowPair_->HandleRemoveWindow(node); if (WindowHelper::IsAvoidAreaWindow(node->GetWindowType())) { avoidController_->AvoidControl(node, AvoidControlType::AVOID_NODE_REMOVE); - NotifyIfSystemBarRegionChanged(); + NotifyIfSystemBarRegionChanged(node->GetDisplayId()); } else { - NotifyIfSystemBarTintChanged(); + NotifyIfSystemBarTintChanged(node->GetDisplayId()); } UpdateWindowVisibilityInfos(infos); DumpScreenWindowTree(); NotifyAccessibilityWindowInfo(node, WindowUpdateType::WINDOW_UPDATE_REMOVED); - RcoveryScreenDefaultOrientationIfNeed(); + RcoveryScreenDefaultOrientationIfNeed(node->GetDisplayId()); WLOGFI("RemoveWindowNode windowId: %{public}u end", node->GetWindowId()); return WMError::WM_OK; } -void WindowNodeContainer::RcoveryScreenDefaultOrientationIfNeed() +void WindowNodeContainer::RcoveryScreenDefaultOrientationIfNeed(DisplayId displayId) { - if (appWindowNode_->children_.empty()) { - WLOGFI("appWindowNode_ child is empty in display %{public}" PRIu64"", displayId_); + if (windowNodeMaps_[displayId][WindowRootNodeType::APP_WINDOW_NODE]->empty()) { + WLOGFI("appWindowNode_ child is empty in display %{public}" PRIu64"", displayId); DisplayManagerServiceInner::GetInstance(). - SetOrientationFromWindow(displayId_, Orientation::UNSPECIFIED); + SetOrientationFromWindow(displayId, Orientation::UNSPECIFIED); } } const std::vector& WindowNodeContainer::Destroy() { - removedIds_.clear(); + auto emptyVector = std::vector(); + removedIds_.swap(emptyVector); for (auto& node : belowAppWindowNode_->children_) { DestroyWindowNode(node, removedIds_); } @@ -603,43 +714,46 @@ std::unordered_map WindowNodeContainer::GetExpect return sysBarPropMap; } -void WindowNodeContainer::NotifyIfSystemBarTintChanged() +void WindowNodeContainer::NotifyIfSystemBarTintChanged(DisplayId displayId) { WM_FUNCTION_TRACE(); auto expectSystemBarProp = GetExpectImmersiveProperty(); SystemBarRegionTints tints; - for (auto it : sysBarTintMap_) { + SysBarTintMap& sysBarTintMap = sysBarTintMaps_[displayId]; + for (auto it : sysBarTintMap) { auto expectProp = expectSystemBarProp.find(it.first)->second; if (it.second.prop_ == expectProp) { continue; } WLOGFI("System bar prop update, Type: %{public}d, Visible: %{public}d, Color: %{public}x | %{public}x", static_cast(it.first), expectProp.enable_, expectProp.backgroundColor_, expectProp.contentColor_); - sysBarTintMap_[it.first].prop_ = expectProp; - sysBarTintMap_[it.first].type_ = it.first; - tints.emplace_back(sysBarTintMap_[it.first]); + sysBarTintMap[it.first].prop_ = expectProp; + sysBarTintMap[it.first].type_ = it.first; + tints.emplace_back(sysBarTintMap[it.first]); } - WindowManagerAgentController::GetInstance().UpdateSystemBarRegionTints(displayId_, tints); + WindowManagerAgentController::GetInstance().UpdateSystemBarRegionTints(displayId, tints); } -void WindowNodeContainer::NotifyIfSystemBarRegionChanged() +void WindowNodeContainer::NotifyIfSystemBarRegionChanged(DisplayId displayId) { WM_FUNCTION_TRACE(); SystemBarRegionTints tints; - for (auto it : sysBarTintMap_) { // split screen mode not support yet - auto sysNode = sysBarNodeMap_[it.first]; + SysBarTintMap& sysBarTintMap = sysBarTintMaps_[displayId]; + SysBarNodeMap& sysBarNodeMap = sysBarNodeMaps_[displayId]; + for (auto it : sysBarTintMap) { // split screen mode not support yet + auto sysNode = sysBarNodeMap[it.first]; if (sysNode == nullptr || it.second.region_ == sysNode->GetWindowRect()) { continue; } - const auto& newRegion = sysNode->GetWindowRect(); - sysBarTintMap_[it.first].region_ = newRegion; - sysBarTintMap_[it.first].type_ = it.first; - tints.emplace_back(sysBarTintMap_[it.first]); + const Rect& newRegion = sysNode->GetWindowRect(); + sysBarTintMap[it.first].region_ = newRegion; + sysBarTintMap[it.first].type_ = it.first; + tints.emplace_back(sysBarTintMap[it.first]); WLOGFI("system bar region update, type: %{public}d" \ "region: [%{public}d, %{public}d, %{public}d, %{public}d]", static_cast(it.first), newRegion.posX_, newRegion.posY_, newRegion.width_, newRegion.height_); } - WindowManagerAgentController::GetInstance().UpdateSystemBarRegionTints(displayId_, tints); + WindowManagerAgentController::GetInstance().UpdateSystemBarRegionTints(displayId, tints); } void WindowNodeContainer::NotifySystemBarDismiss(sptr& node) @@ -651,36 +765,44 @@ void WindowNodeContainer::NotifySystemBarDismiss(sptr& node) } SystemBarRegionTints tints; auto& sysBarPropMapNode = node->GetSystemBarProperty(); + SysBarTintMap& sysBarTintMap = sysBarTintMaps_[node->GetDisplayId()]; for (auto it : sysBarPropMapNode) { it.second.enable_ = false; node->SetSystemBarProperty(it.first, it.second); WLOGFI("set system bar enable to false, id: %{public}u, type: %{public}d", node->GetWindowId(), static_cast(it.first)); - if (sysBarTintMap_[it.first].prop_.enable_) { - sysBarTintMap_[it.first].prop_.enable_ = false; - tints.emplace_back(sysBarTintMap_[it.first]); + if (sysBarTintMap[it.first].prop_.enable_) { + sysBarTintMap[it.first].prop_.enable_ = false; + tints.emplace_back(sysBarTintMap[it.first]); WLOGFI("notify system bar dismiss, type: %{public}d", static_cast(it.first)); } } - WindowManagerAgentController::GetInstance().UpdateSystemBarRegionTints(displayId_, tints); + WindowManagerAgentController::GetInstance().UpdateSystemBarRegionTints(node->GetDisplayId(), tints); } -void WindowNodeContainer::NotifySystemBarTints() +void WindowNodeContainer::NotifySystemBarTints(std::vector displayIdVec) { WM_FUNCTION_TRACE(); - SystemBarRegionTints tints; - for (auto it : sysBarTintMap_) { - WLOGFD("system bar cur notify, type: %{public}d, " \ - "visible: %{public}d, color: %{public}x | %{public}x, " \ - "region: [%{public}d, %{public}d, %{public}d, %{public}d]", - static_cast(it.first), - sysBarTintMap_[it.first].region_.posX_, sysBarTintMap_[it.first].region_.posY_, - sysBarTintMap_[it.first].region_.width_, sysBarTintMap_[it.first].region_.height_, - sysBarTintMap_[it.first].prop_.enable_, - sysBarTintMap_[it.first].prop_.backgroundColor_, sysBarTintMap_[it.first].prop_.contentColor_); - tints.push_back(sysBarTintMap_[it.first]); + if (displayIdVec.size() != sysBarTintMaps_.size()) { + WLOGE("the number of display is error"); + } + + for (auto displayId : displayIdVec) { + SystemBarRegionTints tints; + SysBarTintMap& sysBarTintMap = sysBarTintMaps_[displayId]; + for (auto it : sysBarTintMap) { + WLOGFI("system bar cur notify, type: %{public}d, " \ + "visible: %{public}d, color: %{public}x | %{public}x, " \ + "region: [%{public}d, %{public}d, %{public}d, %{public}d]", + static_cast(it.first), + sysBarTintMap[it.first].prop_.enable_, + sysBarTintMap[it.first].prop_.backgroundColor_, sysBarTintMap[it.first].prop_.contentColor_, + sysBarTintMap[it.first].region_.posX_, sysBarTintMap[it.first].region_.posY_, + sysBarTintMap[it.first].region_.width_, sysBarTintMap[it.first].region_.height_); + tints.push_back(sysBarTintMap[it.first]); + } + WindowManagerAgentController::GetInstance().UpdateSystemBarRegionTints(displayId, tints); } - WindowManagerAgentController::GetInstance().UpdateSystemBarRegionTints(displayId_, tints); } bool WindowNodeContainer::IsTopWindow(uint32_t windowId, sptr& rootNode) const @@ -831,12 +953,12 @@ void WindowNodeContainer::TraverseWindowNode(sptr& node, std::vector } } -std::vector WindowNodeContainer::GetAvoidAreaByType(AvoidAreaType avoidAreaType) +std::vector WindowNodeContainer::GetAvoidAreaByType(AvoidAreaType avoidAreaType, DisplayId displayId) { - return avoidController_->GetAvoidAreaByType(avoidAreaType); + return avoidController_->GetAvoidAreaByType(avoidAreaType, displayId); } -void WindowNodeContainer::OnAvoidAreaChange(const std::vector& avoidArea) +void WindowNodeContainer::OnAvoidAreaChange(const std::vector& avoidArea, DisplayId displayId) { for (auto& node : appWindowNode_->children_) { if (node->GetWindowMode() == WindowMode::WINDOW_MODE_FULLSCREEN && node->GetWindowToken() != nullptr) { @@ -848,45 +970,41 @@ void WindowNodeContainer::OnAvoidAreaChange(const std::vector& avoidArea) void WindowNodeContainer::DumpScreenWindowTree() { - WLOGFI("-------- display %{public}" PRIu64" dump window info begin---------", displayId_); - WLOGFI("WindowName WinId Type Mode Flag ZOrd Orientation [ x y w h]"); + WLOGFI("-------- dump window info begin---------"); + WLOGFI("WindowName DisplayId WinId Type Mode Flag ZOrd Orientation [ x y w h]"); uint32_t zOrder = zOrder_; WindowNodeOperationFunc func = [&zOrder](sptr node) { Rect rect = node->GetWindowRect(); const std::string& windowName = node->GetWindowName().size() < WINDOW_NAME_MAX_LENGTH ? node->GetWindowName() : node->GetWindowName().substr(0, WINDOW_NAME_MAX_LENGTH); - WLOGI("DumpScreenWindowTree: %{public}10s %{public}5u %{public}4u %{public}4u %{public}4u %{public}4u " \ - "%{public}11u [%{public}4d %{public}4d %{public}4u %{public}4u]", - windowName.c_str(), node->GetWindowId(), node->GetWindowType(), node->GetWindowMode(), + WLOGI("DumpScreenWindowTree: %{public}10s %{public}9" PRIu64" %{public}5u %{public}4u %{public}4u %{public}4u " + "%{public}4u %{public}11u [%{public}4d %{public}4d %{public}4u %{public}4u]", + windowName.c_str(), node->GetDisplayId(), node->GetWindowId(), node->GetWindowType(), node->GetWindowMode(), node->GetWindowFlags(), --zOrder, static_cast(node->GetRequestedOrientation()), rect.posX_, rect.posY_, rect.width_, rect.height_); return false; }; TraverseWindowTree(func, true); - WLOGFI("-------- display %{public}" PRIu64" dump window info end ---------", displayId_); + WLOGFI("-------- dump window info end ---------"); } -uint64_t WindowNodeContainer::GetScreenId() const +uint64_t WindowNodeContainer::GetScreenId(DisplayId displayId) const { - return DisplayManagerServiceInner::GetInstance().GetRSScreenId(displayId_); + return DisplayManagerServiceInner::GetInstance().GetRSScreenId(displayId); } -DisplayId WindowNodeContainer::GetDisplayId() const +Rect WindowNodeContainer::GetDisplayRect(DisplayId displayId) const { - return displayId_; + return const_cast(this)->displayRectMap_[displayId]; } -Rect WindowNodeContainer::GetDisplayRect() const +bool WindowNodeContainer::isVerticalDisplay(DisplayId displayId) const { - return displayRect_; + return const_cast(this)->displayRectMap_[displayId].width_ < + const_cast(this)->displayRectMap_[displayId].height_; } -bool WindowNodeContainer::isVerticalDisplay() const -{ - return displayRect_.width_ < displayRect_.height_; -} - -void WindowNodeContainer::NotifyWindowStateChange(WindowState state, WindowStateChangeReason reason) +void WindowNodeContainer::ProcessWindowStateChange(WindowState state, WindowStateChangeReason reason) { switch (reason) { case WindowStateChangeReason::KEYGUARD: { @@ -1060,10 +1178,10 @@ sptr WindowNodeContainer::GetNextActiveWindow(uint32_t windowId) con return nullptr; } -void WindowNodeContainer::MinimizeAllAppWindows() +void WindowNodeContainer::MinimizeAllAppWindows(DisplayId displayId) { WMError ret = MinimizeAppNodeExceptOptions(true); - SwitchLayoutPolicy(WindowLayoutMode::CASCADE); + SwitchLayoutPolicy(WindowLayoutMode::CASCADE, displayId); if (ret != WMError::WM_OK) { WLOGFE("Minimize all app window failed"); } @@ -1128,10 +1246,10 @@ void WindowNodeContainer::ResetLayoutPolicy() layoutPolicy_->Reset(); } -WMError WindowNodeContainer::SwitchLayoutPolicy(WindowLayoutMode dstMode, bool reorder) +WMError WindowNodeContainer::SwitchLayoutPolicy(WindowLayoutMode dstMode, DisplayId displayId, bool reorder) { - WLOGFI("SwitchLayoutPolicy src: %{public}d dst: %{public}d reorder: %{public}d", - static_cast(layoutMode_), static_cast(dstMode), static_cast(reorder)); + WLOGFI("SwitchLayoutPolicy src: %{public}d dst: %{public}d, reorder: %{public}d, displayId: %{public}" PRIu64"", + static_cast(layoutMode_), static_cast(dstMode), static_cast(reorder), displayId); if (dstMode < WindowLayoutMode::BASE || dstMode >= WindowLayoutMode::END) { WLOGFE("invalid layout mode"); return WMError::WM_ERROR_INVALID_PARAM; @@ -1154,7 +1272,7 @@ WMError WindowNodeContainer::SwitchLayoutPolicy(WindowLayoutMode dstMode, bool r layoutPolicy_->Reorder(); DumpScreenWindowTree(); } - NotifyIfSystemBarTintChanged(); + NotifyIfSystemBarTintChanged(displayId); return WMError::WM_OK; } @@ -1179,6 +1297,7 @@ void WindowNodeContainer::ReZOrderShowWhenLockedWindows(const sptr& std::vector> needReZOrderNodes; auto& srcRoot = up ? appWindowNode_ : aboveAppWindowNode_; auto& dstRoot = up ? aboveAppWindowNode_ : appWindowNode_; + auto dstPriority = up ? zorderPolicy_->GetWindowPriority(WindowType::WINDOW_TYPE_KEYGUARD) + 1 : zorderPolicy_->GetWindowPriority(WindowType::WINDOW_TYPE_APP_MAIN_WINDOW); @@ -1202,6 +1321,7 @@ void WindowNodeContainer::ReZOrderShowWhenLockedWindows(const sptr& break; } } + parentNode->children_.insert(position, needReZOrderNode); WLOGFI("ShowWhenLocked window %{public}u re-zorder when keyguard change %{public}u", needReZOrderNode->GetWindowId(), up); @@ -1241,26 +1361,29 @@ void WindowNodeContainer::DropShowWhenLockedWindowIfNeeded(const sptr& container) +void WindowNodeContainer::MoveWindowNodes(DisplayId displayId, std::vector& windowIds) { - DisplayId from = container->GetDisplayId(); - WLOGFI("disconnect expand display: %{public}" PRId64 ", move window node to display: " - "%{public}" PRId64 "", from, displayId_); - for (auto& node : container->aboveAppWindowNode_->children_) { - WLOGFI("aboveAppWindowNode_: move windowNode: %{public}u", node->GetWindowId()); - aboveAppWindowNode_->children_.push_back(node); - layoutPolicy_->AddWindowNode(node); - } - for (auto& node : container->appWindowNode_->children_) { - WLOGFI("appWindowNode_: move windowNode: %{public}u", node->GetWindowId()); - appWindowNode_->children_.push_back(node); - layoutPolicy_->AddWindowNode(node); - } - for (auto& node : container->belowAppWindowNode_->children_) { - WLOGFI("belowAppWindowNode_: move windowNode: %{public}u", node->GetWindowId()); - belowAppWindowNode_->children_.push_back(node); - layoutPolicy_->AddWindowNode(node); - } + WLOGFI("Move window nodes when destroy display"); +} + +void WindowNodeContainer::ProcessDisplayCreate(DisplayId displayId, const Rect& displayRect) +{ + avoidController_->UpdateAvoidNodesMap(displayId, true); + InitSysBarMapForDisplay(displayId); + InitWindowNodeMapForDisplay(displayId); + displayRectMap_.insert(std::make_pair(displayId, displayRect)); + layoutPolicy_->UpdateDisplayInfo(displayRectMap_); +} + +void WindowNodeContainer::ProcessDisplayDestroy(DisplayId displayId, std::vector& windowIds) +{ + WLOGFI("Process display destroy"); +} + +void WindowNodeContainer::ProcessDisplayChange(DisplayId displayId, const Rect& displayRect) +{ + displayRectMap_[displayId] = displayRect; + layoutPolicy_->UpdateDisplayInfo(displayRectMap_); } void WindowNodeContainer::TraverseWindowTree(const WindowNodeOperationFunc& func, bool isFromTopToBottom) const @@ -1339,17 +1462,19 @@ bool WindowNodeContainer::TraverseFromBottomToTop(sptr node, const W void WindowNodeContainer::UpdateWindowVisibilityInfos(std::vector>& infos) { - currentCoveredArea_.clear(); + auto emptyVector = std::vector(); + currentCoveredArea_.swap(emptyVector); WindowNodeOperationFunc func = [this, &infos](sptr node) { if (node == nullptr) { return false; } Rect layoutRect = node->GetWindowRect(); + const Rect& displayRect = displayRectMap_[node->GetDisplayId()]; int32_t nodeX = std::max(0, layoutRect.posX_); int32_t nodeY = std::max(0, layoutRect.posY_); - int32_t nodeXEnd = std::min(displayRect_.posX_ + static_cast(displayRect_.width_), + int32_t nodeXEnd = std::min(displayRect.posX_ + static_cast(displayRect.width_), layoutRect.posX_ + static_cast(layoutRect.width_)); - int32_t nodeYEnd = std::min(displayRect_.posY_ + static_cast(displayRect_.height_), + int32_t nodeYEnd = std::min(displayRect.posY_ + static_cast(displayRect.height_), layoutRect.posY_ + static_cast(layoutRect.height_)); Rect rectInDisplay = {nodeX, nodeY, @@ -1378,9 +1503,9 @@ void WindowNodeContainer::UpdateWindowVisibilityInfos(std::vectorGetVirtualPixelRatio(); + return layoutPolicy_->GetVirtualPixelRatio(displayId); } bool WindowNodeContainer::ReadIsWindowAnimationEnabledProperty() diff --git a/wmserver/src/window_root.cpp b/wmserver/src/window_root.cpp index c6f0f66a4f..10e3177069 100644 --- a/wmserver/src/window_root.cpp +++ b/wmserver/src/window_root.cpp @@ -28,30 +28,52 @@ namespace Rosen { namespace { constexpr HiviewDFX::HiLogLabel LABEL = {LOG_CORE, HILOG_DOMAIN_WINDOW, "WindowRoot"}; } -sptr WindowRoot::GetOrCreateWindowNodeContainer(DisplayId displayId) + +ScreenId WindowRoot::GetScreenGroupId(DisplayId displayId) { - auto iter = windowNodeContainerMap_.find(displayId); + for (auto iter : displayIdMap_) { + auto displayIdVec = iter.second; + if (std::find(displayIdVec.begin(), displayIdVec.end(), displayId) != displayIdVec.end()) { + return iter.first; + } + } + WLOGFE("This is invalid display, displayId: %{public}" PRIu64 "", displayId); + return INVALID_SCREEN_ID; +} + +sptr WindowRoot::GetWindowNodeContainer(DisplayId displayId) +{ + ScreenId screenGroupId = GetScreenGroupId(displayId); + if (screenGroupId == INVALID_SCREEN_ID) { + return nullptr; + } + auto iter = windowNodeContainerMap_.find(screenGroupId); if (iter != windowNodeContainerMap_.end()) { return iter->second; } + return nullptr; +} + +sptr WindowRoot::CreateWindowNodeContainer(DisplayId displayId) +{ const sptr displayInfo = DisplayManagerServiceInner::GetInstance().GetDisplayById(displayId); - if (displayInfo == nullptr) { - WLOGFE("get display failed displayId:%{public}" PRId64 "", displayId); + if (displayInfo == nullptr || !CheckDisplayInfo(displayInfo)) { + WLOGFE("get display failed or get invailed display info, displayId :%{public}" PRIu64 "", displayId); return nullptr; } - if (!CheckDisplayInfo(displayInfo)) { - WLOGFE("get display invailed infp:%{public}" PRId64 "", displayId); - return nullptr; - } + ScreenId screenGroupId = DisplayManagerServiceInner::GetInstance().GetScreenGroupIdByDisplayId(displayId); + + WLOGFI("create new container for display, width: %{public}d, height: %{public}d, isMinimized:%{public}d, " + "screenGroupId:%{public}" PRIu64", displayId:%{public}" PRIu64"", displayInfo->GetWidth(), + displayInfo->GetHeight(), isMinimizedByOtherWindow_, screenGroupId, displayId); - WLOGFI("create new window node container display width:%{public}d, height:%{public}d, " \ - "isMinimized:%{public}d, screenId:%{public}" PRIu64"", displayInfo->GetWidth(), - displayInfo->GetHeight(), isMinimizedByOtherWindow_, displayInfo->GetDisplayId()); - sptr container = new WindowNodeContainer(displayInfo->GetDisplayId(), + sptr container = new WindowNodeContainer(displayId, static_cast(displayInfo->GetWidth()), static_cast(displayInfo->GetHeight()), isMinimizedByOtherWindow_); - windowNodeContainerMap_.insert(std::make_pair(displayId, container)); + windowNodeContainerMap_.insert(std::make_pair(screenGroupId, container)); + std::vector displayVec = { displayId }; + displayIdMap_.insert(std::make_pair(screenGroupId, displayVec)); return container; } @@ -100,21 +122,6 @@ void WindowRoot::NotifyKeyboardSizeChangeInfo(const sptr& node, WLOGFE("does not have correct callingWindow for input method window"); } -void WindowRoot::NotifyDisplayRemoved(DisplayId displayId) -{ - auto container = GetOrCreateWindowNodeContainer(displayId); - if (container == nullptr) { - WLOGFI("this display does not have any window"); - return; - } - std::vector windowIds = container->Destroy(); - for (auto id : windowIds) { - auto node = GetWindowNode(id); - DestroyWindowInner(node); - } - windowNodeContainerMap_.erase(displayId); -} - sptr WindowRoot::GetWindowNode(uint32_t windowId) const { auto iter = windowNodeMap_.find(windowId); @@ -147,7 +154,7 @@ WMError WindowRoot::SaveWindow(const sptr& node) WMError WindowRoot::MinimizeStructuredAppWindowsExceptSelf(sptr& node) { - auto container = GetOrCreateWindowNodeContainer(node->GetDisplayId()); + auto container = GetWindowNodeContainer(node->GetDisplayId()); if (container == nullptr) { WLOGFE("MinimizeAbility failed, window container could not be found"); return WMError::WM_ERROR_NULLPTR; @@ -163,23 +170,23 @@ std::vector WindowRoot::GetAvoidAreaByType(uint32_t windowId, AvoidAreaTyp WLOGFE("could not find window"); return avoidArea; } - auto container = GetOrCreateWindowNodeContainer(node->GetDisplayId()); + auto container = GetWindowNodeContainer(node->GetDisplayId()); if (container == nullptr) { WLOGFE("add window failed, window container could not be found"); return avoidArea; } - avoidArea = container->GetAvoidAreaByType(avoidAreaType); + avoidArea = container->GetAvoidAreaByType(avoidAreaType, node->GetDisplayId()); return avoidArea; } void WindowRoot::MinimizeAllAppWindows(DisplayId displayId) { - auto container = GetOrCreateWindowNodeContainer(displayId); + auto container = GetWindowNodeContainer(displayId); if (container == nullptr) { WLOGFE("can't find window node container, failed!"); return; } - return container->MinimizeAllAppWindows(); + return container->MinimizeAllAppWindows(displayId); } WMError WindowRoot::MaxmizeWindow(uint32_t windowId) @@ -189,7 +196,7 @@ WMError WindowRoot::MaxmizeWindow(uint32_t windowId) WLOGFE("could not find window"); return WMError::WM_ERROR_NULLPTR; } - auto container = GetOrCreateWindowNodeContainer(node->GetDisplayId()); + auto container = GetWindowNodeContainer(node->GetDisplayId()); if (container == nullptr) { WLOGFE("add window failed, window container could not be found"); return WMError::WM_ERROR_NULLPTR; @@ -208,7 +215,7 @@ WMError WindowRoot::AddWindowNode(uint32_t parentId, sptr& node) return WMError::WM_ERROR_NULLPTR; } - auto container = GetOrCreateWindowNodeContainer(node->GetDisplayId()); + auto container = GetWindowNodeContainer(node->GetDisplayId()); if (container == nullptr) { WLOGFE("add window failed, window container could not be found"); return WMError::WM_ERROR_NULLPTR; @@ -259,7 +266,7 @@ WMError WindowRoot::RemoveWindowNode(uint32_t windowId) WLOGFE("could not find window"); return WMError::WM_ERROR_NULLPTR; } - auto container = GetOrCreateWindowNodeContainer(node->GetDisplayId()); + auto container = GetWindowNodeContainer(node->GetDisplayId()); if (container == nullptr) { WLOGFE("remove window failed, window container could not be found"); return WMError::WM_ERROR_NULLPTR; @@ -284,7 +291,7 @@ WMError WindowRoot::UpdateWindowNode(uint32_t windowId, WindowUpdateReason reaso WLOGFE("could not find window"); return WMError::WM_ERROR_NULLPTR; } - auto container = GetOrCreateWindowNodeContainer(node->GetDisplayId()); + auto container = GetWindowNodeContainer(node->GetDisplayId()); if (container == nullptr) { WLOGFE("update window failed, window container could not be found"); return WMError::WM_ERROR_NULLPTR; @@ -299,7 +306,7 @@ WMError WindowRoot::UpdateSizeChangeReason(uint32_t windowId, WindowSizeChangeRe WLOGFE("could not find window"); return WMError::WM_ERROR_NULLPTR; } - auto container = GetOrCreateWindowNodeContainer(node->GetDisplayId()); + auto container = GetWindowNodeContainer(node->GetDisplayId()); if (container == nullptr) { WLOGFE("update window size change reason failed, window container could not be found"); return WMError::WM_ERROR_NULLPTR; @@ -315,7 +322,7 @@ void WindowRoot::SetBrightness(uint32_t windowId, float brightness) WLOGFE("could not find window"); return; } - auto container = GetOrCreateWindowNodeContainer(node->GetDisplayId()); + auto container = GetWindowNodeContainer(node->GetDisplayId()); if (container == nullptr) { WLOGFE("set brightness failed, window container could not be found"); return; @@ -342,7 +349,7 @@ void WindowRoot::HandleKeepScreenOn(uint32_t windowId, bool requireLock) WLOGFE("could not find window"); return; } - auto container = GetOrCreateWindowNodeContainer(node->GetDisplayId()); + auto container = GetWindowNodeContainer(node->GetDisplayId()); if (container == nullptr) { WLOGFE("handle keep screen on failed, window container could not be found"); return; @@ -357,7 +364,7 @@ void WindowRoot::UpdateFocusableProperty(uint32_t windowId) WLOGFE("could not find window"); return; } - auto container = GetOrCreateWindowNodeContainer(node->GetDisplayId()); + auto container = GetWindowNodeContainer(node->GetDisplayId()); if (container == nullptr) { WLOGFE("handle focusable failed, window container could not be found"); return; @@ -375,7 +382,7 @@ void WindowRoot::UpdateFocusableProperty(uint32_t windowId) WMError WindowRoot::SetWindowMode(sptr& node, WindowMode dstMode) { - auto container = GetOrCreateWindowNodeContainer(node->GetDisplayId()); + auto container = GetWindowNodeContainer(node->GetDisplayId()); if (container == nullptr) { WLOGFE("set window mode failed, window container could not be found"); return WMError::WM_ERROR_NULLPTR; @@ -390,7 +397,7 @@ WMError WindowRoot::DestroyWindow(uint32_t windowId, bool onlySelf) return WMError::WM_ERROR_DESTROYED_OBJECT; } WMError res; - auto container = GetOrCreateWindowNodeContainer(node->GetDisplayId()); + auto container = GetWindowNodeContainer(node->GetDisplayId()); if (container != nullptr) { UpdateFocusWindowWithWindowRemoved(node, container); UpdateActiveWindowWithWindowRemoved(node, container); @@ -544,12 +551,12 @@ void WindowRoot::UpdateBrightnessWithWindowRemoved(uint32_t windowId, const sptr bool WindowRoot::isVerticalDisplay(sptr& node) const { - auto container = const_cast(this)->GetOrCreateWindowNodeContainer(node->GetDisplayId()); + auto container = const_cast(this)->GetWindowNodeContainer(node->GetDisplayId()); if (container == nullptr) { WLOGFE("get display direction failed, window container could not be found"); return false; } - return container->isVerticalDisplay(); + return container->isVerticalDisplay(node->GetDisplayId()); } WMError WindowRoot::RequestFocus(uint32_t windowId) @@ -563,7 +570,7 @@ WMError WindowRoot::RequestFocus(uint32_t windowId) WLOGFE("could not request focus before it does not be shown"); return WMError::WM_ERROR_INVALID_OPERATION; } - auto container = GetOrCreateWindowNodeContainer(node->GetDisplayId()); + auto container = GetWindowNodeContainer(node->GetDisplayId()); if (container == nullptr) { WLOGFE("window container could not be found"); return WMError::WM_ERROR_NULLPTR; @@ -581,7 +588,7 @@ WMError WindowRoot::RequestActiveWindow(uint32_t windowId) WLOGFE("could not find window"); return WMError::WM_ERROR_NULLPTR; } - auto container = GetOrCreateWindowNodeContainer(node->GetDisplayId()); + auto container = GetWindowNodeContainer(node->GetDisplayId()); if (container == nullptr) { WLOGFE("window container could not be found"); return WMError::WM_ERROR_NULLPTR; @@ -610,25 +617,14 @@ std::shared_ptr WindowRoot::GetSurfaceNodeByAbilityToken(const sp return nullptr; } -void WindowRoot::NotifyWindowStateChange(WindowState state, WindowStateChangeReason reason) +void WindowRoot::ProcessWindowStateChange(WindowState state, WindowStateChangeReason reason) { for (auto& elem : windowNodeContainerMap_) { if (elem.second == nullptr) { continue; } - elem.second->NotifyWindowStateChange(state, reason); - } -} - -void WindowRoot::NotifyDisplayChange(sptr displayInfo) -{ - WLOGFD("window should be updated for display changed"); - auto container = GetOrCreateWindowNodeContainer(displayInfo->GetDisplayId()); - if (container == nullptr) { - WLOGFE("can't find window node container, failed!"); - return; + elem.second->ProcessWindowStateChange(state, reason); } - container->UpdateDisplayRect(displayInfo->GetWidth(), displayInfo->GetHeight()); } void WindowRoot::NotifySystemBarTints() @@ -636,7 +632,7 @@ void WindowRoot::NotifySystemBarTints() WLOGFD("notify current system bar tints"); for (auto& it : windowNodeContainerMap_) { if (it.second != nullptr) { - it.second->NotifySystemBarTints(); + it.second->NotifySystemBarTints(displayIdMap_[it.first]); } } } @@ -648,7 +644,7 @@ WMError WindowRoot::RaiseZOrderForAppWindow(sptr& node) return WMError::WM_ERROR_NULLPTR; } if (node->GetWindowType() == WindowType::WINDOW_TYPE_DOCK_SLICE) { - auto container = GetOrCreateWindowNodeContainer(node->GetDisplayId()); + auto container = GetWindowNodeContainer(node->GetDisplayId()); if (container == nullptr) { WLOGFW("window container could not be found"); return WMError::WM_ERROR_NULLPTR; @@ -661,7 +657,7 @@ WMError WindowRoot::RaiseZOrderForAppWindow(sptr& node) WLOGFW("window is not app window"); return WMError::WM_ERROR_INVALID_TYPE; } - auto container = GetOrCreateWindowNodeContainer(node->GetDisplayId()); + auto container = GetWindowNodeContainer(node->GetDisplayId()); if (container == nullptr) { WLOGFW("add window failed, window container could not be found"); return WMError::WM_ERROR_NULLPTR; @@ -705,14 +701,14 @@ WMError WindowRoot::GetTopWindowId(uint32_t mainWinId, uint32_t& topWinId) WMError WindowRoot::SetWindowLayoutMode(DisplayId displayId, WindowLayoutMode mode) { - auto container = GetOrCreateWindowNodeContainer(displayId); + auto container = GetWindowNodeContainer(displayId); if (container == nullptr) { WLOGFE("window container could not be found"); return WMError::WM_ERROR_NULLPTR; } - WMError ret = container->SwitchLayoutPolicy(mode, true); + WMError ret = container->SwitchLayoutPolicy(mode, displayId, true); if (ret != WMError::WM_OK) { - WLOGFW("set window layout mode failed displayId: %{public}" PRId64 ", ret: %{public}d", displayId, ret); + WLOGFW("set window layout mode failed displayId: %{public}" PRIu64 ", ret: %{public}d", displayId, ret); } return ret; } @@ -734,7 +730,10 @@ std::string WindowRoot::GenAllWindowsLogInfo() const if (elem.second == nullptr) { continue; } - os<<"Display "<GetDisplayId()<<":"; + std::vector& displayIdVec = const_cast(this)->displayIdMap_[elem.first]; + for (auto& displayId : displayIdVec) { + os << "Display " << displayId << ":"; + } elem.second->TraverseWindowTree(func, true); } return os.str(); @@ -780,38 +779,73 @@ void WindowRoot::FocusFaultDetection() const } } -void WindowRoot::NotifyDisplayDestroy(DisplayId expandDisplayId) +void WindowRoot::ProcessDisplayCreate(DisplayId displayId) { - WLOGFD("disconnect expand display, get default and expand display container"); - DisplayId defaultDisplayId = DisplayManagerServiceInner::GetInstance().GetDefaultDisplayId(); - // get all windowNode below expand display, and reset its displayId - for (auto iter = windowNodeMap_.begin(); iter != windowNodeMap_.end(); iter++) { - auto node = iter->second; - if (node->GetDisplayId() != expandDisplayId) { - continue; + ScreenId screenGroupId = DisplayManagerServiceInner::GetInstance().GetScreenGroupIdByDisplayId(displayId); + auto iter = windowNodeContainerMap_.find(screenGroupId); + if (iter == windowNodeContainerMap_.end()) { + CreateWindowNodeContainer(displayId); + WLOGFI("[Display Create] Create new container for display, displayId: %{public}" PRIu64"", displayId); + } else { + if (std::find(displayIdMap_[screenGroupId].begin(), displayIdMap_[screenGroupId].end(), displayId) != + displayIdMap_[screenGroupId].end()) { + WLOGFI("[Display Create] Current display is already exist, displayId: %{public}" PRIu64"", displayId); + return; + } + const sptr displayInfo = DisplayManagerServiceInner::GetInstance().GetDisplayById(displayId); + if (displayInfo == nullptr || !CheckDisplayInfo(displayInfo)) { + WLOGFE("get display failed or get invailed display info, displayId :%{public}" PRIu64 "", displayId); + return; } - node->SetDisplayId(defaultDisplayId); - node->GetWindowToken()->UpdateDisplayId(expandDisplayId, defaultDisplayId); - } - // move windowNode from expand display container to default display container - auto expandDisplayContainer = GetOrCreateWindowNodeContainer(expandDisplayId); - auto defaultDisplayContainer = GetOrCreateWindowNodeContainer(defaultDisplayId); - if (expandDisplayContainer == nullptr || defaultDisplayContainer == nullptr) { - WLOGFE("window node container is nullptr!"); + auto container = iter->second; + if (container == nullptr) { + WLOGFE("window node container is nullptr, displayId :%{public}" PRIu64 "", displayId); + } + // add displayId in displayIdMap + displayIdMap_[screenGroupId].push_back(displayId); + Rect displayRect = { 0, 0, displayInfo->GetWidth(), displayInfo->GetHeight() }; + container->ProcessDisplayCreate(displayId, displayRect); + WLOGFI("[Display Create] Container exist, add new display, displayId: %{public}" PRIu64", Rect: [" + "%{public}d, %{public}d, %{public}d, %{public}d]", displayId, displayRect.posX_, displayRect.posY_, + displayRect.width_, displayRect.height_); + } +} + +void WindowRoot::ProcessDisplayDestroy(DisplayId displayId) +{ + WLOGFI("[Display Destroy] displayId: %{public}" PRIu64" ", displayId); +} + +void WindowRoot::ProcessDisplayChange(sptr displayInfo) +{ + DisplayId displayId = displayInfo->GetDisplayId(); + ScreenId screenGroupId = DisplayManagerServiceInner::GetInstance().GetScreenGroupIdByDisplayId(displayId); + auto& displayIdVec = displayIdMap_[screenGroupId]; + auto iter = windowNodeContainerMap_.find(screenGroupId); + if (iter == windowNodeContainerMap_.end() || std::find(displayIdVec.begin(), + displayIdVec.end(), displayId) == displayIdVec.end()) { + WLOGFE("[Display Change] could not find display, change failed, displayId: %{public}" PRIu64"", displayId); return; } - defaultDisplayContainer->MoveWindowNode(expandDisplayContainer); - windowNodeContainerMap_.erase(expandDisplayId); + + // container process display change + auto container = iter->second; + if (container == nullptr) { + WLOGFE("window node container is nullptr, displayId :%{public}" PRIu64 "", displayId); + } + + Rect displayRect = { 0, 0, displayInfo->GetWidth(), displayInfo->GetHeight() }; + container->ProcessDisplayChange(displayId, displayRect); } float WindowRoot::GetVirtualPixelRatio(DisplayId displayId) const { - auto container = const_cast(this)->GetOrCreateWindowNodeContainer(displayId); + auto container = const_cast(this)->GetWindowNodeContainer(displayId); if (container == nullptr) { WLOGFE("window container could not be found"); return 1.0; // Use DefaultVPR 1.0 } - return container->GetVirtualPixelRatio(); + return container->GetVirtualPixelRatio(displayId); } WMError WindowRoot::GetAccessibilityWindowInfo(sptr& windowInfo) -- Gitee