diff --git a/interfaces/innerkits/wm/wm_common.h b/interfaces/innerkits/wm/wm_common.h index 96314a2d..54b853c8 100644 --- a/interfaces/innerkits/wm/wm_common.h +++ b/interfaces/innerkits/wm/wm_common.h @@ -142,8 +142,10 @@ namespace { constexpr uint32_t DIVIDER_WIDTH = 8; constexpr uint32_t INVALID_WINDOW_ID = 0; constexpr uint32_t HOTZONE = 40; - constexpr uint32_t MIN_VERTICAL_FLOATING_WIDTH = 360; + constexpr uint32_t MIN_VERTICAL_FLOATING_WIDTH = 240; constexpr uint32_t MIN_VERTICAL_FLOATING_HEIGHT = 480; + constexpr uint32_t MIN_VERTICAL_SPLIT_HEIGHT = 426; + constexpr uint32_t MIN_HORIZONTAL_SPLIT_WIDTH = 426; } struct SystemBarProperty { diff --git a/wmserver/include/window_layout_policy.h b/wmserver/include/window_layout_policy.h index 3866dc46..d2b0fc7a 100644 --- a/wmserver/include/window_layout_policy.h +++ b/wmserver/include/window_layout_policy.h @@ -48,7 +48,7 @@ public: virtual void LayoutWindowTree(); virtual void RemoveWindowNode(sptr& node); virtual void UpdateWindowNode(sptr& node); - virtual void UpdateLayoutRect(sptr& node); + virtual void UpdateLayoutRect(sptr& node) = 0; void UpdateDefaultFoatingRect(); protected: diff --git a/wmserver/include/window_layout_policy_tile.h b/wmserver/include/window_layout_policy_tile.h index f2cc80ac..37e02e1b 100644 --- a/wmserver/include/window_layout_policy_tile.h +++ b/wmserver/include/window_layout_policy_tile.h @@ -34,6 +34,7 @@ public: ~WindowLayoutPolicyTile() = default; void Launch() override; void AddWindowNode(sptr& node) override; + void UpdateLayoutRect(sptr& node) override; private: Rect singleRect_ = { 0, 0, 0, 0 }; diff --git a/wmserver/src/window_layout_policy_cascade.cpp b/wmserver/src/window_layout_policy_cascade.cpp index e40cd12f..cc3e213a 100644 --- a/wmserver/src/window_layout_policy_cascade.cpp +++ b/wmserver/src/window_layout_policy_cascade.cpp @@ -130,17 +130,20 @@ static bool IsLayoutChanged(const Rect& l, const Rect& r) void WindowLayoutPolicyCascade::LimitMoveBounds(Rect& rect) { - Rect curRect = rect; - rect.posX_ = std::max(curRect.posX_, limitRect_.posX_); - rect.posY_ = std::max(curRect.posY_, limitRect_.posY_); if (rect.width_ < rect.height_) { - rect.posX_ = std::min(curRect.posX_ + rect.width_, - limitRect_.posX_ + limitRect_.width_) - rect.width_; - rect.height_ = curRect.posY_ + curRect.height_ - rect.posY_; + if (rect.posX_ < (limitRect_.posX_ + static_cast(MIN_HORIZONTAL_SPLIT_WIDTH))) { + rect.posX_ = limitRect_.posX_ + static_cast(MIN_HORIZONTAL_SPLIT_WIDTH); + } else if (rect.posX_ > + (limitRect_.posX_ + limitRect_.width_ - static_cast(MIN_HORIZONTAL_SPLIT_WIDTH))) { + rect.posX_ = limitRect_.posX_ + static_cast(limitRect_.width_ - MIN_HORIZONTAL_SPLIT_WIDTH); + } } else { - rect.posY_ = std::min(curRect.posY_ + rect.height_, - limitRect_.posY_ + limitRect_.height_) - rect.height_; - rect.width_ = curRect.posX_ + curRect.width_ - rect.posX_; + if (rect.posY_ < (limitRect_.posY_ + static_cast(MIN_VERTICAL_SPLIT_HEIGHT))) { + rect.posY_ = limitRect_.posY_ + static_cast(MIN_VERTICAL_SPLIT_HEIGHT); + } else if (rect.posY_ > + (limitRect_.posY_ + static_cast(limitRect_.height_ - MIN_VERTICAL_SPLIT_HEIGHT))) { + rect.posY_ = limitRect_.posY_ + static_cast(limitRect_.height_ - MIN_VERTICAL_SPLIT_HEIGHT); + } } } @@ -205,7 +208,7 @@ void WindowLayoutPolicyCascade::UpdateLayoutRect(sptr& node) } } // Limit window to the maximum window size - LimitWindowSize(node, displayRect, winRect); + LimitWindowSize(node, displayRect_, winRect); if (node->GetWindowType() == WindowType::WINDOW_TYPE_DOCK_SLICE) { LimitMoveBounds(winRect); diff --git a/wmserver/src/window_layout_policy_tile.cpp b/wmserver/src/window_layout_policy_tile.cpp index 2c12ab05..073ada6a 100644 --- a/wmserver/src/window_layout_policy_tile.cpp +++ b/wmserver/src/window_layout_policy_tile.cpp @@ -114,7 +114,9 @@ void WindowLayoutPolicyTile::InitForegroundNodeQueue() foregroundNodes_.clear(); lastForegroundNodeId_ = 0; for (auto& node : appWindowNode_->children_) { - UpdateForegroundNodeQueue(node); + if (WindowHelper::IsMainWindow(node->GetWindowType())) { + UpdateForegroundNodeQueue(node); + } } } @@ -123,11 +125,13 @@ void WindowLayoutPolicyTile::UpdateForegroundNodeQueue(sptr& node) if (node == nullptr) { return; } + WLOGFI("add win in tile for win id: %{public}d", node->GetWindowId()); uint32_t maxTileWinNum = IsVertical() ? MAX_WIN_NUM_VERTICAL : MAX_WIN_NUM_HORIZONTAL; if (foregroundNodes_.size() < maxTileWinNum) { foregroundNodes_.push_back(node); lastForegroundNodeId_ = ((++lastForegroundNodeId_) % maxTileWinNum); } else { + WLOGFI("minimize win %{public}d in tile", foregroundNodes_[lastForegroundNodeId_]->GetWindowId()); AAFwk::AbilityManagerClient::GetInstance()-> MinimizeAbility(foregroundNodes_[lastForegroundNodeId_]->abilityToken_); foregroundNodes_[lastForegroundNodeId_] = node; @@ -142,7 +146,9 @@ void WindowLayoutPolicyTile::AssignNodePropertyForTileWindows() if (num == 1) { WLOGFI("set rect for win id: %{public}d", foregroundNodes_[0]->GetWindowMode()); foregroundNodes_[0]->SetWindowMode(WindowMode::WINDOW_MODE_FLOATING); + foregroundNodes_[0]->GetWindowToken()->UpdateWindowMode(WindowMode::WINDOW_MODE_FLOATING); foregroundNodes_[0]->SetWindowRect(singleRect_); + foregroundNodes_[0]->hasDecorated_ = true; 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_); @@ -150,12 +156,58 @@ void WindowLayoutPolicyTile::AssignNodePropertyForTileWindows() auto& rects = (num == MAX_WIN_NUM_HORIZONTAL) ? tripleRects_ : doubleRects_; for (uint32_t i = 0; i < foregroundNodes_.size(); i++) { foregroundNodes_[(lastForegroundNodeId_ + i) % num]->SetWindowMode(WindowMode::WINDOW_MODE_FLOATING); + foregroundNodes_[(lastForegroundNodeId_ + i) % num]->GetWindowToken()-> + UpdateWindowMode(WindowMode::WINDOW_MODE_FLOATING); foregroundNodes_[(lastForegroundNodeId_ + i) % num]->SetWindowRect(rects[i]); + foregroundNodes_[(lastForegroundNodeId_ + i) % num]->hasDecorated_ = true; 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_); } } } + +void WindowLayoutPolicyTile::UpdateLayoutRect(sptr& node) +{ + auto type = node->GetWindowType(); + auto mode = node->GetWindowMode(); + auto flags = node->GetWindowFlags(); + auto decorEnbale = node->GetWindowProperty()->GetDecorEnable(); + bool needAvoid = (flags & static_cast(WindowFlag::WINDOW_FLAG_NEED_AVOID)); + bool parentLimit = (flags & static_cast(WindowFlag::WINDOW_FLAG_PARENT_LIMIT)); + bool subWindow = WindowHelper::IsSubWindow(type); + bool floatingWindow = (mode == WindowMode::WINDOW_MODE_FLOATING); + const Rect& layoutRect = node->GetLayoutRect(); + Rect lastRect = layoutRect; + Rect displayRect = displayRect_; + Rect limitRect = displayRect; + Rect winRect = node->GetWindowProperty()->GetWindowRect(); + + WLOGFI("Id:%{public}d, avoid:%{public}d parLimit:%{public}d floating:%{public}d, sub:%{public}d, " \ + "deco:%{public}d, type:%{public}d, requestRect:[%{public}d, %{public}d, %{public}d, %{public}d]", + node->GetWindowId(), needAvoid, parentLimit, floatingWindow, subWindow, decorEnbale, + static_cast(type), winRect.posX_, winRect.posY_, winRect.width_, winRect.height_); + if (needAvoid) { + limitRect = limitRect_; + } + + if (!floatingWindow) { // fullscreen window + winRect = limitRect; + } else { // floating window + if (node->GetWindowProperty()->GetDecorEnable()) { // is decorable + winRect = ComputeDecoratedWindowRect(winRect); + } + if (subWindow && parentLimit) { // subwidow and limited by parent + limitRect = node->parent_->GetLayoutRect(); + UpdateFloatingLayoutRect(limitRect, winRect); + } + } + LimitWindowSize(node, displayRect, winRect); + node->SetLayoutRect(winRect); + if (!(lastRect == winRect)) { + node->GetWindowToken()->UpdateWindowRect(winRect, node->GetWindowSizeChangeReason()); + node->surfaceNode_->SetBounds(winRect.posX_, winRect.posY_, winRect.width_, winRect.height_); + } +} } } diff --git a/wmserver/src/window_node_container.cpp b/wmserver/src/window_node_container.cpp index 11124272..b32d2ed8 100644 --- a/wmserver/src/window_node_container.cpp +++ b/wmserver/src/window_node_container.cpp @@ -920,20 +920,29 @@ WMError WindowNodeContainer::UpdateWindowPairInfo(sptr& triggerNode, return WMError::WM_OK; } -WMError WindowNodeContainer::SwitchLayoutPolicy(WindowLayoutMode mode, bool reorder) +WMError WindowNodeContainer::SwitchLayoutPolicy(WindowLayoutMode dstMode, bool reorder) { WLOGFI("SwitchLayoutPolicy src: %{public}d dst: %{public}d reorder: %{public}d", - static_cast(layoutMode_), static_cast(mode), static_cast(reorder)); - if (layoutMode_ != mode) { - layoutMode_ = mode; + static_cast(layoutMode_), static_cast(dstMode), static_cast(reorder)); + if (layoutMode_ != dstMode) { + if (layoutMode_ == WindowLayoutMode::CASCADE && !pairedWindowMap_.empty()) { + pairedWindowMap_.clear(); + SingletonContainer::Get().SendMessage(INNER_WM_DESTROY_DIVIDER, displayId_); + } + layoutMode_ = dstMode; layoutPolicy_->Clean(); - layoutPolicy_ = layoutPolicys_[mode]; + layoutPolicy_ = layoutPolicys_[dstMode]; layoutPolicy_->Launch(); DumpScreenWindowTree(); } else { - WLOGFI("Curret layout mode is allready: %{public}d", static_cast(mode)); + WLOGFI("Curret layout mode is allready: %{public}d", static_cast(dstMode)); } if (reorder) { + if (!pairedWindowMap_.empty()) { + // exit divider window when reorder + pairedWindowMap_.clear(); + SingletonContainer::Get().SendMessage(INNER_WM_DESTROY_DIVIDER, displayId_); + } layoutPolicy_->Reorder(); DumpScreenWindowTree(); } diff --git a/wmserver/src/window_root.cpp b/wmserver/src/window_root.cpp index 5f6d51d2..c422479c 100644 --- a/wmserver/src/window_root.cpp +++ b/wmserver/src/window_root.cpp @@ -405,7 +405,7 @@ WMError WindowRoot::SetWindowLayoutMode(DisplayId displayId, WindowLayoutMode mo } 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); + WLOGFW("set window layout mode failed displayId: %{public}" PRId64 ", ret: %{public}d", displayId, ret); } return ret; }