From d92ed666f912d262de0006abe8922865a770510c Mon Sep 17 00:00:00 2001 From: jincanran Date: Thu, 10 Feb 2022 15:40:42 +0800 Subject: [PATCH] add tile window layout mode Signed-off-by: jincanran Change-Id: I9839d7b25a77d10fc9713c2a62de66a6761d62a5 --- wm/include/window_adapter.h | 1 + wm/src/window_adapter.cpp | 9 ++ wmserver/include/window_controller.h | 1 + wmserver/include/window_layout_policy.h | 10 +- .../include/window_layout_policy_cascade.h | 3 +- wmserver/include/window_layout_policy_tile.h | 17 ++- wmserver/include/window_manager_interface.h | 4 +- wmserver/include/window_manager_proxy.h | 1 + wmserver/include/window_manager_service.h | 1 + wmserver/include/window_node_container.h | 4 + wmserver/include/window_root.h | 1 + wmserver/src/window_controller.cpp | 11 ++ wmserver/src/window_layout_policy.cpp | 12 +- wmserver/src/window_layout_policy_cascade.cpp | 7 +- wmserver/src/window_layout_policy_tile.cpp | 144 +++++++++++++++++- wmserver/src/window_manager_proxy.cpp | 25 +++ wmserver/src/window_manager_service.cpp | 7 + wmserver/src/window_manager_stub.cpp | 7 + wmserver/src/window_node_container.cpp | 14 +- wmserver/src/window_root.cpp | 14 ++ 20 files changed, 275 insertions(+), 18 deletions(-) diff --git a/wm/include/window_adapter.h b/wm/include/window_adapter.h index 0255f7e1e6..baaa470435 100644 --- a/wm/include/window_adapter.h +++ b/wm/include/window_adapter.h @@ -54,6 +54,7 @@ public: virtual WMError GetTopWindowId(uint32_t mainWinId, uint32_t& topWinId); virtual void ProcessWindowTouchedEvent(uint32_t windowId); virtual void MinimizeAllAppWindows(DisplayId displayId); + virtual WMError SetWindowLayoutMode(DisplayId displayId, WindowLayoutMode mode); // colorspace, gamut virtual bool IsSupportWideGamut(uint32_t windowId); diff --git a/wm/src/window_adapter.cpp b/wm/src/window_adapter.cpp index 12852af325..34658df50d 100644 --- a/wm/src/window_adapter.cpp +++ b/wm/src/window_adapter.cpp @@ -312,5 +312,14 @@ WMError WindowAdapter::GetTopWindowId(uint32_t mainWinId, uint32_t& topWinId) } return windowManagerServiceProxy_->GetTopWindowId(mainWinId, topWinId); } + +WMError WindowAdapter::SetWindowLayoutMode(DisplayId displayId, WindowLayoutMode mode) +{ + std::lock_guard lock(mutex_); + if (!InitWMSProxyLocked()) { + return WMError::WM_ERROR_SAMGR; + } + return windowManagerServiceProxy_->SetWindowLayoutMode(displayId, mode); +} } // namespace Rosen } // namespace OHOS \ No newline at end of file diff --git a/wmserver/include/window_controller.h b/wmserver/include/window_controller.h index 756acd3683..aa9a670cba 100644 --- a/wmserver/include/window_controller.h +++ b/wmserver/include/window_controller.h @@ -51,6 +51,7 @@ public: void NotifyDisplayStateChange(DisplayStateChangeType type); WMError ProcessWindowTouchedEvent(uint32_t windowId); void MinimizeAllAppWindows(DisplayId displayId); + WMError SetWindowLayoutMode(DisplayId displayId, WindowLayoutMode mode); private: uint32_t GenWindowId(); diff --git a/wmserver/include/window_layout_policy.h b/wmserver/include/window_layout_policy.h index 768a151489..981e208e28 100644 --- a/wmserver/include/window_layout_policy.h +++ b/wmserver/include/window_layout_policy.h @@ -37,11 +37,12 @@ class WindowLayoutPolicy : public RefBase { public: WindowLayoutPolicy() = delete; WindowLayoutPolicy(const Rect& displayRect, const uint64_t& screenId, - const sptr& belowAppNode, const sptr& appNode, const sptr& aboveAppNode); + sptr& belowAppNode, sptr& appNode, sptr& aboveAppNode); ~WindowLayoutPolicy() = default; virtual void Launch(); virtual void Clean(); virtual void Reset(); + virtual void Reorder(); virtual void UpdateDisplayInfo(); virtual void AddWindowNode(sptr& node); virtual void RemoveWindowNode(sptr& node); @@ -52,9 +53,9 @@ public: protected: const Rect& displayRect_; const uint64_t& screenId_; - const sptr& belowAppWindowNode_; - const sptr& appWindowNode_; - const sptr& aboveAppWindowNode_; + sptr& belowAppWindowNode_; + sptr& appWindowNode_; + sptr& aboveAppWindowNode_; Rect limitRect_ = { 0, 0, 0, 0 }; const std::set avoidTypes_ { WindowType::WINDOW_TYPE_STATUS_BAR, @@ -68,6 +69,7 @@ protected: void LimitWindowSize(const sptr& node, const Rect& displayRect, Rect& winRect); void SetRectForFloating(const sptr& node); Rect ComputeDecoratedWindowRect(const Rect& winRect); + bool IsVertical() const; Rect defaultFloatingRect_ = { 0, 0, 0, 0 }; }; } diff --git a/wmserver/include/window_layout_policy_cascade.h b/wmserver/include/window_layout_policy_cascade.h index 3e0a42ba67..088c940537 100644 --- a/wmserver/include/window_layout_policy_cascade.h +++ b/wmserver/include/window_layout_policy_cascade.h @@ -30,7 +30,7 @@ class WindowLayoutPolicyCascade : public WindowLayoutPolicy { public: WindowLayoutPolicyCascade() = delete; WindowLayoutPolicyCascade(const Rect& displayRect, const uint64_t& screenId, - const sptr& belowAppNode, const sptr& appNode, const sptr& aboveAppNode); + sptr& belowAppNode, sptr& appNode, sptr& aboveAppNode); ~WindowLayoutPolicyCascade() = default; void Launch() override; void Clean() override; @@ -59,7 +59,6 @@ private: Rect GetLimitRect(const WindowMode mode) const; Rect GetDisplayRect(const WindowMode mode) const; void LimitMoveBounds(Rect& rect); - bool IsVertical() const; }; } } diff --git a/wmserver/include/window_layout_policy_tile.h b/wmserver/include/window_layout_policy_tile.h index 435f6cd69a..f2cc80acbe 100644 --- a/wmserver/include/window_layout_policy_tile.h +++ b/wmserver/include/window_layout_policy_tile.h @@ -30,8 +30,23 @@ class WindowLayoutPolicyTile : public WindowLayoutPolicy { public: WindowLayoutPolicyTile() = delete; WindowLayoutPolicyTile(const Rect& displayRect, const uint64_t& screenId, - const sptr& belowAppNode, const sptr& appNode, const sptr& aboveAppNode); + sptr& belowAppNode, sptr& appNode, sptr& aboveAppNode); ~WindowLayoutPolicyTile() = default; + void Launch() override; + void AddWindowNode(sptr& node) override; + +private: + Rect singleRect_ = { 0, 0, 0, 0 }; + std::vector doubleRects_ = std::vector(2); + std::vector tripleRects_ = std::vector(3); + std::vector> foregroundNodes_; + uint32_t lastForegroundNodeId_ = 0; + void UpdateDisplayInfo() override; + void InitTileWindowRects(); + void AssignNodePropertyForTileWindows(); + void LayoutForegroundNodeQueue(); + void InitForegroundNodeQueue(); + void UpdateForegroundNodeQueue(sptr& node); }; } } diff --git a/wmserver/include/window_manager_interface.h b/wmserver/include/window_manager_interface.h index ad07b4e3b0..effd4130c0 100644 --- a/wmserver/include/window_manager_interface.h +++ b/wmserver/include/window_manager_interface.h @@ -54,7 +54,8 @@ public: TRANS_ID_SET_COLOR_SPACE, // set color space TRANS_ID_GET_COLOR_SPACE, // get color space TRANS_ID_SET_BACKGROUND_BLUR, - TRANS_ID_SET_APLPHA + TRANS_ID_SET_APLPHA, + TRANS_ID_UPDATE_LAYOUT_MODE, }; virtual WMError CreateWindow(sptr& window, sptr& property, const std::shared_ptr& surfaceNode, uint32_t& windowId) = 0; @@ -78,6 +79,7 @@ public: virtual WMError GetTopWindowId(uint32_t mainWinId, uint32_t& topWinId) = 0; virtual void ProcessWindowTouchedEvent(uint32_t windowId) = 0; virtual void MinimizeAllAppWindows(DisplayId displayId) = 0; + virtual WMError SetWindowLayoutMode(DisplayId displayId, WindowLayoutMode mode) = 0; // colorspace, gamut virtual bool IsSupportWideGamut(uint32_t windowId) = 0; diff --git a/wmserver/include/window_manager_proxy.h b/wmserver/include/window_manager_proxy.h index af1e2d675e..f0c8f48ea6 100644 --- a/wmserver/include/window_manager_proxy.h +++ b/wmserver/include/window_manager_proxy.h @@ -49,6 +49,7 @@ public: WMError GetTopWindowId(uint32_t mainWinId, uint32_t& topWinId) override; void ProcessWindowTouchedEvent(uint32_t windowId) override; void MinimizeAllAppWindows(DisplayId displayId) override; + WMError SetWindowLayoutMode(DisplayId displayId, WindowLayoutMode mode) override; // colorspace, gamut virtual bool IsSupportWideGamut(uint32_t windowId) override; diff --git a/wmserver/include/window_manager_service.h b/wmserver/include/window_manager_service.h index 731865085c..5b016a8c6c 100644 --- a/wmserver/include/window_manager_service.h +++ b/wmserver/include/window_manager_service.h @@ -69,6 +69,7 @@ public: void ProcessWindowTouchedEvent(uint32_t windowId) override; WMError GetTopWindowId(uint32_t mainWinId, uint32_t& topWinId) override; void MinimizeAllAppWindows(DisplayId displayId) override; + WMError SetWindowLayoutMode(DisplayId displayId, WindowLayoutMode mode) override; // colorspace, gamut virtual bool IsSupportWideGamut(uint32_t windowId) override; diff --git a/wmserver/include/window_node_container.h b/wmserver/include/window_node_container.h index 568c135edc..86a6caf379 100644 --- a/wmserver/include/window_node_container.h +++ b/wmserver/include/window_node_container.h @@ -59,6 +59,7 @@ public: const std::vector &exceptionalModes = {}); WMError EnterSplitWindowMode(sptr& node); WMError ExitSplitWindowMode(sptr& node); + WMError SwitchLayoutPolicy(WindowLayoutMode mode, bool reorder = false); private: void AssignZOrder(sptr& node); @@ -72,8 +73,11 @@ private: void SendSplitScreenEvent(WindowMode mode); sptr FindSplitPairNode(sptr& node) const; WMError UpdateWindowPairInfo(sptr& triggerNode, sptr& pairNode); +<<<<<<< HEAD WMError SwitchLayoutPolicy(WindowLayoutMode mode); +======= +>>>>>>> add tile window layout mode void NotifyIfSystemBarTintChanged(); void NotifyIfSystemBarRegionChanged(); void TraverseAndUpdateWindowState(WindowState state, int32_t topPriority); diff --git a/wmserver/include/window_root.h b/wmserver/include/window_root.h index 2439db50ab..5d64323567 100644 --- a/wmserver/include/window_root.h +++ b/wmserver/include/window_root.h @@ -55,6 +55,7 @@ public: std::shared_ptr GetSurfaceNodeByAbilityToken(const sptr& abilityToken) const; WMError GetTopWindowId(uint32_t mainWinId, uint32_t& topWinId); void MinimizeAllAppWindows(DisplayId displayId); + WMError SetWindowLayoutMode(DisplayId displayId, WindowLayoutMode mode); void NotifyWindowStateChange(WindowState state, WindowStateChangeReason reason); WMError RaiseZOrderForAppWindow(sptr& node); diff --git a/wmserver/src/window_controller.cpp b/wmserver/src/window_controller.cpp index b16b8367f0..3b16f08dd4 100644 --- a/wmserver/src/window_controller.cpp +++ b/wmserver/src/window_controller.cpp @@ -388,5 +388,16 @@ void WindowController::FlushWindowInfoWithDisplayId(DisplayId displayId) RSTransaction::FlushImplicitTransaction(); inputWindowMonitor_->UpdateInputWindowByDisplayId(displayId); } + +WMError WindowController::SetWindowLayoutMode(DisplayId displayId, WindowLayoutMode mode) +{ + WMError res = windowRoot_->SetWindowLayoutMode(displayId, mode); + if (res != WMError::WM_OK) { + return res; + } + RSTransaction::FlushImplicitTransaction(); + inputWindowMonitor_->UpdateInputWindowByDisplayId(displayId); + return res; +} } } \ No newline at end of file diff --git a/wmserver/src/window_layout_policy.cpp b/wmserver/src/window_layout_policy.cpp index 38d72e15ef..cc829d5020 100644 --- a/wmserver/src/window_layout_policy.cpp +++ b/wmserver/src/window_layout_policy.cpp @@ -26,7 +26,7 @@ namespace { constexpr uint32_t WINDOW_FRAME_WIDTH = 4; } WindowLayoutPolicy::WindowLayoutPolicy(const Rect& displayRect, const uint64_t& screenId, - const sptr& belowAppNode, const sptr& appNode, const sptr& aboveAppNode) + sptr& belowAppNode, sptr& appNode, sptr& aboveAppNode) : displayRect_(displayRect), screenId_(screenId), belowAppWindowNode_(belowAppNode), appWindowNode_(appNode), aboveAppWindowNode_(aboveAppNode) { @@ -49,6 +49,11 @@ void WindowLayoutPolicy::Clean() WLOGFI("WindowLayoutPolicy::Clean"); } +void WindowLayoutPolicy::Reorder() +{ + WLOGFI("WindowLayoutPolicy::Reorder"); +} + void WindowLayoutPolicy::LayoutWindowTree() { limitRect_ = displayRect_; @@ -120,6 +125,11 @@ void WindowLayoutPolicy::SetRectForFloating(const sptr& node) node->SetWindowRect(rect); } +bool WindowLayoutPolicy::IsVertical() const +{ + return displayRect_.width_ < displayRect_.height_; +} + void WindowLayoutPolicy::RemoveWindowNode(sptr& node) { WM_FUNCTION_TRACE(); diff --git a/wmserver/src/window_layout_policy_cascade.cpp b/wmserver/src/window_layout_policy_cascade.cpp index e25b052543..917d2e189e 100644 --- a/wmserver/src/window_layout_policy_cascade.cpp +++ b/wmserver/src/window_layout_policy_cascade.cpp @@ -25,7 +25,7 @@ namespace { constexpr HiviewDFX::HiLogLabel LABEL = {LOG_CORE, HILOG_DOMAIN_WINDOW, "WindowLayoutPolicyCascade"}; } WindowLayoutPolicyCascade::WindowLayoutPolicyCascade(const Rect& displayRect, const uint64_t& screenId, - const sptr& belowAppNode, const sptr& appNode, const sptr& aboveAppNode) + sptr& belowAppNode, sptr& appNode, sptr& aboveAppNode) : WindowLayoutPolicy(displayRect, screenId, belowAppNode, appNode, aboveAppNode) { } @@ -250,11 +250,6 @@ void WindowLayoutPolicyCascade::InitSplitRects() SetSplitRect(dividerRect_); } -bool WindowLayoutPolicyCascade::IsVertical() const -{ - return displayRect_.width_ < displayRect_.height_; -} - void WindowLayoutPolicyCascade::SetSplitRectByRatio(float ratio) { if (!IsVertical()) { diff --git a/wmserver/src/window_layout_policy_tile.cpp b/wmserver/src/window_layout_policy_tile.cpp index cb4d36c8bb..aeb0e11a44 100644 --- a/wmserver/src/window_layout_policy_tile.cpp +++ b/wmserver/src/window_layout_policy_tile.cpp @@ -14,6 +14,7 @@ */ #include "window_layout_policy_tile.h" +#include #include "window_helper.h" #include "window_inner_manager.h" #include "window_manager_hilog.h" @@ -21,10 +22,151 @@ namespace OHOS { namespace Rosen { +namespace { + constexpr HiviewDFX::HiLogLabel LABEL = {LOG_CORE, 0, "WindowLayoutPolicyTile"}; + constexpr uint32_t MAX_WIN_NUM_VERTICAL = 3; + constexpr uint32_t MAX_WIN_NUM_HORIZONTAL = 3; +} WindowLayoutPolicyTile::WindowLayoutPolicyTile(const Rect& displayRect, const uint64_t& screenId, - const sptr& belowAppNode, const sptr& appNode, const sptr& aboveAppNode) + sptr& belowAppNode, sptr& appNode, sptr& aboveAppNode) : WindowLayoutPolicy(displayRect, screenId, belowAppNode, appNode, aboveAppNode) { } + +void WindowLayoutPolicyTile::Launch() +{ + // compute limit rect + limitRect_ = displayRect_; + LayoutWindowNode(aboveAppWindowNode_); + InitTileWindowRects(); + // select app min win in queue, and minimize others + InitForegroundNodeQueue(); + LayoutForegroundNodeQueue(); + LayoutWindowNode(belowAppWindowNode_); + WLOGFI("WindowLayoutPolicyTile::Launch"); +} + +void WindowLayoutPolicyTile::UpdateDisplayInfo() +{ + limitRect_ = displayRect_; + LayoutWindowNode(aboveAppWindowNode_); + InitTileWindowRects(); +} + +void WindowLayoutPolicyTile::InitTileWindowRects() +{ + constexpr uint32_t edgeInterval = 48; + constexpr uint32_t midInterval = 24; + constexpr float ratio = 0.75; // 0.75: default height/width ratio + constexpr float edgeRatio = 0.125; + int x = limitRect_.posX_ + (limitRect_.width_ * edgeRatio); + int y = limitRect_.posY_ + (limitRect_.height_ * edgeRatio); + uint32_t w = limitRect_.width_ * ratio; + uint32_t h = limitRect_.height_ * ratio; + singleRect_ = { x, y, w, h }; + WLOGFI("singleRect_: %{public}d %{public}d %{public}d %{public}d", x, y, w, h); + x = edgeInterval; + w = (limitRect_.width_ - edgeInterval * 2 - midInterval) / 2; + // calc doubleRect + doubleRects_[0] = {x, y, w, h}; + doubleRects_[1] = {x + w + midInterval, y, w, h}; + WLOGFI("doubleRects_: %{public}d %{public}d %{public}d %{public}d", x, y, w, h); + // calc tripleRect + w = (limitRect_.width_ - edgeInterval * 2 - midInterval * 2) / 3; + tripleRects_[0] = {x, y, w, h}; + tripleRects_[1] = {x + w + midInterval, y, w, h}; + tripleRects_[2] = {x + w * 2 + midInterval * 2, y, w, h}; + WLOGFI("tripleRects_: %{public}d %{public}d %{public}d %{public}d", x, y, w, h); +} + +void WindowLayoutPolicyTile::AddWindowNode(sptr& node) +{ + WM_FUNCTION_TRACE(); + WLOGFI("AddWindowNode"); + if (WindowHelper::IsMainWindow(node->GetWindowType())) { + WLOGFI("AddWindowNode1"); + UpdateForegroundNodeQueue(node); + LayoutForegroundNodeQueue(); + } else { + WLOGFI("AddWindowNode2"); + UpdateWindowNode(node); // currently, update and add do the same process + } +} + +void WindowLayoutPolicyTile::LayoutForegroundNodeQueue() +{ + for (auto& node : foregroundNodes_) { + Rect lastRect = node->GetLayoutRect(); + Rect winRect = node->GetWindowProperty()->GetWindowRect(); + node->SetLayoutRect(winRect); + if (!(lastRect == winRect)) { + node->GetWindowToken()->UpdateWindowRect(winRect); + node->surfaceNode_->SetBounds(winRect.posX_, winRect.posY_, winRect.width_, winRect.height_); + } + for (auto& childNode : node->children_) { + LayoutWindowNode(childNode); + } + } +} + +void WindowLayoutPolicyTile::InitForegroundNodeQueue() +{ + foregroundNodes_.clear(); + uint32_t maxTileWinNum = IsVertical() ? MAX_WIN_NUM_VERTICAL : MAX_WIN_NUM_HORIZONTAL; + for (auto& node : appWindowNode_->children_) { + if (WindowHelper::IsMainWindow(node->GetWindowType())) { + if (foregroundNodes_.size() < maxTileWinNum) { + foregroundNodes_.push_back(node); + lastForegroundNodeId_ = ((++lastForegroundNodeId_) % maxTileWinNum); + } else { + AAFwk::AbilityManagerClient::GetInstance()-> + MinimizeAbility(node->abilityToken_); + } + } + } + AssignNodePropertyForTileWindows(); +} + +void WindowLayoutPolicyTile::UpdateForegroundNodeQueue(sptr& node) +{ + if (node == nullptr) { + return; + } + uint32_t maxTileWinNum = IsVertical() ? MAX_WIN_NUM_VERTICAL : MAX_WIN_NUM_HORIZONTAL; + if (foregroundNodes_.size() < maxTileWinNum) { + foregroundNodes_.push_back(node); + lastForegroundNodeId_ = ((++lastForegroundNodeId_) % maxTileWinNum); + } else { + AAFwk::AbilityManagerClient::GetInstance()-> + MinimizeAbility(foregroundNodes_[lastForegroundNodeId_]->abilityToken_); + foregroundNodes_[lastForegroundNodeId_] = node; + lastForegroundNodeId_ = ((++lastForegroundNodeId_) % maxTileWinNum); + } + AssignNodePropertyForTileWindows(); +} + +void WindowLayoutPolicyTile::AssignNodePropertyForTileWindows() +{ + // set rect for foreground windows + int num = foregroundNodes_.size(); + if (num == 1) { + WLOGFI("set rect for win id: %{public}d", foregroundNodes_[0]->GetWindowMode()); + foregroundNodes_[0]->SetWindowMode(WindowMode::WINDOW_MODE_FLOATING); + foregroundNodes_[0]->SetWindowRect(singleRect_); + WLOGFI("set rect for win id: %{public}d", foregroundNodes_[0]->GetWindowMode()); + WLOGFI("set rect for win id: %{public}d [%{public}d %{public}d %{public}d %{public}d]", + foregroundNodes_[0]->GetWindowId(), + singleRect_.posX_, singleRect_.posY_, singleRect_.width_, singleRect_.height_); + } else { + auto& rects = (num == MAX_WIN_NUM_HORIZONTAL) ? tripleRects_ : doubleRects_; + for (int i = 0; i < foregroundNodes_.size(); i++) { + foregroundNodes_[(lastForegroundNodeId_ + i) % num]->SetWindowMode(WindowMode::WINDOW_MODE_FLOATING); + foregroundNodes_[(lastForegroundNodeId_ + i) % num]->SetWindowRect(rects[i]); + WLOGFI("set rect for qwin id: %{public}d [%{public}d %{public}d %{public}d %{public}d]", + foregroundNodes_[(lastForegroundNodeId_ + i) % num]->GetWindowId(), + rects[i].posX_, rects[i].posY_, rects[i].width_, rects[i].height_); + } + } +} } } diff --git a/wmserver/src/window_manager_proxy.cpp b/wmserver/src/window_manager_proxy.cpp index d9a3dab049..28c87c1d2f 100644 --- a/wmserver/src/window_manager_proxy.cpp +++ b/wmserver/src/window_manager_proxy.cpp @@ -620,6 +620,31 @@ ColorSpace WindowManagerProxy::GetColorSpace(uint32_t windowId) return static_cast(ret); } +WMError WindowManagerProxy::SetWindowLayoutMode(DisplayId displayId, WindowLayoutMode mode) +{ + MessageParcel data; + MessageParcel reply; + MessageOption option; + if (!data.WriteInterfaceToken(GetDescriptor())) { + WLOGFE("WriteInterfaceToken failed"); + return WMError::WM_ERROR_IPC_FAILED; + } + if (!data.WriteUint64(displayId)) { + WLOGFE("Write displayId failed"); + return WMError::WM_ERROR_IPC_FAILED; + } + if (!data.WriteUint32(static_cast(mode))) { + WLOGFE("Write mode failed"); + return WMError::WM_ERROR_IPC_FAILED; + } + if (Remote()->SendRequest(TRANS_ID_UPDATE_LAYOUT_MODE, data, reply, option) != ERR_NONE) { + return WMError::WM_ERROR_IPC_FAILED; + } + + int32_t ret = reply.ReadInt32(); + return static_cast(ret); +} + WMError WindowManagerProxy::GetTopWindowId(uint32_t mainWinId, uint32_t& topWinId) { MessageParcel data; diff --git a/wmserver/src/window_manager_service.cpp b/wmserver/src/window_manager_service.cpp index 0156cadef9..0c23524b00 100644 --- a/wmserver/src/window_manager_service.cpp +++ b/wmserver/src/window_manager_service.cpp @@ -344,5 +344,12 @@ WMError WindowManagerService::GetTopWindowId(uint32_t mainWinId, uint32_t& topWi std::lock_guard lock(mutex_); return windowController_->GetTopWindowId(mainWinId, topWinId); } + +WMError WindowManagerService::SetWindowLayoutMode(DisplayId displayId, WindowLayoutMode mode) +{ + WM_SCOPED_TRACE("wms:SetWindowLayoutNode"); + std::lock_guard lock(mutex_); + return windowController_->SetWindowLayoutMode(displayId, mode); +} } } \ No newline at end of file diff --git a/wmserver/src/window_manager_stub.cpp b/wmserver/src/window_manager_stub.cpp index cab8c31153..fc59b709d7 100644 --- a/wmserver/src/window_manager_stub.cpp +++ b/wmserver/src/window_manager_stub.cpp @@ -206,6 +206,13 @@ int32_t WindowManagerStub::OnRemoteRequest(uint32_t code, MessageParcel &data, M reply.WriteUint32(static_cast(colorSpace)); break; } + case TRANS_ID_UPDATE_LAYOUT_MODE: { + DisplayId displayId = data.ReadUint64(); + WindowLayoutMode mode = static_cast(data.ReadUint32()); + WMError errCode = SetWindowLayoutMode(displayId, mode); + reply.WriteInt32(static_cast(errCode)); + break; + } default: WLOGFW("unknown transaction code"); return IPCObjectStub::OnRemoteRequest(code, data, reply, option); diff --git a/wmserver/src/window_node_container.cpp b/wmserver/src/window_node_container.cpp index bfb9470e2e..fe947c0342 100644 --- a/wmserver/src/window_node_container.cpp +++ b/wmserver/src/window_node_container.cpp @@ -129,6 +129,7 @@ WMError WindowNodeContainer::UpdateWindowNode(sptr& node) WLOGFE("surface node or display node is nullptr!"); return WMError::WM_ERROR_NULLPTR; } + SwitchLayoutPolicy(WindowLayoutMode::CASCADE); layoutPolicy_->UpdateWindowNode(node); if (avoidController_->IsAvoidAreaNode(node)) { avoidController_->UpdateAvoidAreaNode(node); @@ -207,7 +208,7 @@ WMError WindowNodeContainer::RemoveWindowNode(sptr& node) WLOGFE("window node or surface node is nullptr, invalid"); return WMError::WM_ERROR_DESTROYED_OBJECT; } - + SwitchLayoutPolicy(WindowLayoutMode::CASCADE); if (node->parent_ == nullptr) { WLOGFW("can't find parent of this node"); } else { @@ -867,7 +868,7 @@ WMError WindowNodeContainer::UpdateWindowPairInfo(sptr& triggerNode, return WMError::WM_OK; } -WMError WindowNodeContainer::SwitchLayoutPolicy(WindowLayoutMode mode) +WMError WindowNodeContainer::SwitchLayoutPolicy(WindowLayoutMode mode, bool reorder) { if (mode == layoutMode_) { WLOGFI("curret layout mode is allready: %{public}d", static_cast(mode)); @@ -875,10 +876,19 @@ WMError WindowNodeContainer::SwitchLayoutPolicy(WindowLayoutMode mode) } WLOGFI("SwitchLayoutPolicy src: %{public}d dst: %{public}d", static_cast(layoutMode_), static_cast(mode)); + if (layoutMode_ == mode) { + if (reorder) { + layoutPolicy_->Reorder(); + } + return WMError::WM_OK; + } layoutMode_ = mode; layoutPolicy_->Clean(); layoutPolicy_ = layoutPolicys_[mode]; layoutPolicy_->Launch(); + if (reorder) { + layoutPolicy_->Reorder(); + } return WMError::WM_OK; } diff --git a/wmserver/src/window_root.cpp b/wmserver/src/window_root.cpp index 3d8cc30aab..bcb712a276 100644 --- a/wmserver/src/window_root.cpp +++ b/wmserver/src/window_root.cpp @@ -384,5 +384,19 @@ WMError WindowRoot::GetTopWindowId(uint32_t mainWinId, uint32_t& topWinId) topWinId = mainWinId; return WMError::WM_OK; } + +WMError WindowRoot::SetWindowLayoutMode(DisplayId displayId, WindowLayoutMode mode) +{ + auto container = GetOrCreateWindowNodeContainer(displayId); + if (container == nullptr) { + WLOGFE("window container could not be found"); + return WMError::WM_ERROR_NULLPTR; + } + WMError ret = container->SwitchLayoutPolicy(mode, true); + if (ret != WMError::WM_OK) { + WLOGFW("set windoe layout mode failed displayId: %{public}" PRId64 ", ret: %{public}d", displayId, ret); + } + return ret; +} } } -- Gitee