diff --git a/utils/include/window_helper.h b/utils/include/window_helper.h index 7d8afdb3..bca9272f 100644 --- a/utils/include/window_helper.h +++ b/utils/include/window_helper.h @@ -64,6 +64,11 @@ public: mode == WindowMode::WINDOW_MODE_PIP; } + static inline bool IsEmptyRect(const Rect& r) + { + return (r.posX_ == 0 && r.posY_ == 0 && r.width_ == 0 && r.height_ == 0); + } + WindowHelper() = default; ~WindowHelper() = default; }; diff --git a/wm/src/window_impl.cpp b/wm/src/window_impl.cpp index 2fccd1e0..378fecf7 100644 --- a/wm/src/window_impl.cpp +++ b/wm/src/window_impl.cpp @@ -213,11 +213,6 @@ WMError WindowImpl::SetUIContent(const std::string& contentInfo, WLOGFE("fail to SetUIContent id: %{public}d", property_->GetWindowId()); return WMError::WM_ERROR_NULLPTR; } - if (WindowHelper::IsMainWindow(property_->GetWindowType())) { - property_->SetDecorEnable(true); - } else { - property_->SetDecorEnable(false); - } if (isdistributed) { uiContent_->Restore(this, contentInfo, storage); } else { @@ -281,6 +276,12 @@ WMError WindowImpl::Create(const std::string& parentName, const std::shared_ptr< } } + if (WindowHelper::IsMainWindow(property_->GetWindowType())) { + property_->SetDecorEnable(true); + } else { + property_->SetDecorEnable(false); + } + sptr window(this); sptr windowAgent(new WindowAgent(window)); uint32_t windowId = 0; diff --git a/wmserver/include/window_layout_policy.h b/wmserver/include/window_layout_policy.h index c63ee4b0..c1f005f5 100644 --- a/wmserver/include/window_layout_policy.h +++ b/wmserver/include/window_layout_policy.h @@ -54,6 +54,7 @@ public: void UpdateWindowNode(sptr& node); void UpdateLayoutRect(sptr& node); Rect GetDependDisplayRects() const; + void UpdateDefaultFoatingRect(); private: LayoutDependRects dependRects; @@ -78,6 +79,9 @@ private: Rect& GetLimitRect(const WindowMode mode); Rect& GetDisplayRect(const WindowMode mode); void LimitMoveBounds(Rect& rect); + void LimitWindowSize(const sptr& node, const Rect& displayRect, Rect& winRect); + void SetRectForFloating(const sptr& node); + Rect defaultFloatingRect_ = { 0, 0, 0, 0 }; }; } } diff --git a/wmserver/include/window_node.h b/wmserver/include/window_node.h index 4dc76246..e7f18bbb 100644 --- a/wmserver/include/window_node.h +++ b/wmserver/include/window_node.h @@ -42,6 +42,7 @@ public: void SetDisplayId(int32_t displayId); void SetLayoutRect(const Rect& rect); + void SetWindowRect(const Rect& rect); void SetWindowProperty(const sptr& property); void SetSystemBarProperty(WindowType type, const SystemBarProperty& property); void SetWindowMode(WindowMode mode); diff --git a/wmserver/src/window_layout_policy.cpp b/wmserver/src/window_layout_policy.cpp index a6a78cd2..619d30a0 100644 --- a/wmserver/src/window_layout_policy.cpp +++ b/wmserver/src/window_layout_policy.cpp @@ -24,6 +24,8 @@ namespace { constexpr HiviewDFX::HiLogLabel LABEL = {LOG_CORE, 0, "WindowLayoutPolicy"}; constexpr uint32_t WINDOW_TITLE_BAR_HEIGHT = 48; constexpr uint32_t WINDOW_FRAME_WIDTH = 4; + constexpr uint32_t MIN_VERTICAL_FLOATING_WIDTH = 360; + constexpr uint32_t MIN_VERTICAL_FLOATING_HEIGHT = 480; } WindowLayoutPolicy::WindowLayoutPolicy(const sptr& belowAppNode, @@ -42,6 +44,7 @@ void WindowLayoutPolicy::UpdateDisplayInfo(const Rect& primaryRect, dependRects.secRect_ = secondaryRect; dependRects.fullRect_ = displayRect; InitLimitRects(); + UpdateDefaultFoatingRect(); } void WindowLayoutPolicy::LayoutWindowTree() @@ -78,9 +81,48 @@ void WindowLayoutPolicy::LayoutWindowNode(sptr& node) void WindowLayoutPolicy::AddWindowNode(sptr& node) { WM_FUNCTION_TRACE(); + if (WindowHelper::IsEmptyRect(node->GetWindowProperty()->GetWindowRect())) { + SetRectForFloating(node); + } UpdateWindowNode(node); // currently, update and add do the same process } +void WindowLayoutPolicy::UpdateDefaultFoatingRect() +{ + constexpr uint32_t half = 2; + constexpr float ratio = 0.75; // 0.75: default height/width ratio + + // calculate default H and w + Rect displayRect = GetDisplayRect(WindowMode::WINDOW_MODE_FLOATING); + uint32_t defaultW = static_cast(displayRect.width_ * ratio); + uint32_t defaultH = static_cast(displayRect.height_ * ratio); + + // calculate default x and y + Rect limitRect = GetLimitRect(WindowMode::WINDOW_MODE_FLOATING); + Rect resRect = {0, 0, defaultW, defaultH}; + 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); + resRect.posY_ = centerPosY - static_cast(defaultH / half); + } + + defaultFloatingRect_ = resRect; +} + +void WindowLayoutPolicy::SetRectForFloating(const sptr& node) +{ + // deduct decor size + Rect rect = defaultFloatingRect_; + if (node->GetWindowProperty()->GetDecorEnable()) { + rect.width_ -= (WINDOW_FRAME_WIDTH + WINDOW_FRAME_WIDTH); + rect.height_ -= (WINDOW_TITLE_BAR_HEIGHT + WINDOW_FRAME_WIDTH); + } + + node->SetWindowRect(rect); +} + void WindowLayoutPolicy::RemoveWindowNode(sptr& node) { WM_FUNCTION_TRACE(); @@ -158,6 +200,7 @@ void WindowLayoutPolicy::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); @@ -168,9 +211,9 @@ void WindowLayoutPolicy::UpdateLayoutRect(sptr& node) Rect limitRect = displayRect; Rect winRect = node->GetWindowProperty()->GetWindowRect(); - WLOGFI("Id:%{public}d, avoid:%{public}d parLimit:%{public}d floating:%{public}d, sub:%{public}d," \ - "type:%{public}d, requestRect:[%{public}d, %{public}d, %{public}d, %{public}d]", - node->GetWindowId(), needAvoid, parentLimit, floatingWindow, subWindow, + 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 = GetLimitRect(mode); @@ -188,10 +231,7 @@ void WindowLayoutPolicy::UpdateLayoutRect(sptr& node) } } // Limit window to the maximum window size - winRect.width_ = std::min(displayRect.width_, winRect.width_); - winRect.height_ = std::min(displayRect.height_, winRect.height_); - winRect.width_ = std::max(1u, winRect.width_); - winRect.height_ = std::max(1u, winRect.height_); + LimitWindowSize(node, displayRect, winRect); if (node->GetWindowType() == WindowType::WINDOW_TYPE_DOCK_SLICE) { LimitMoveBounds(winRect); @@ -204,6 +244,28 @@ void WindowLayoutPolicy::UpdateLayoutRect(sptr& node) } } +void WindowLayoutPolicy::LimitWindowSize(const sptr& node, const Rect& displayRect, Rect& winRect) +{ + bool floatingWindow = (node->GetWindowMode() == WindowMode::WINDOW_MODE_FLOATING); + + winRect.width_ = std::min(displayRect.width_, winRect.width_); + winRect.height_ = std::min(displayRect.height_, winRect.height_); + bool isVertical = (displayRect.height_ > displayRect.width_) ? true : false; + WindowType windowType = node->GetWindowProperty()->GetWindowType(); + if (floatingWindow && !WindowHelper::IsSystemWindow(windowType)) { + if (isVertical) { + winRect.width_ = std::max(MIN_VERTICAL_FLOATING_WIDTH, winRect.width_); + winRect.height_ = std::max(MIN_VERTICAL_FLOATING_HEIGHT, winRect.height_); + } else { + winRect.width_ = std::max(MIN_VERTICAL_FLOATING_HEIGHT, winRect.width_); + winRect.height_ = std::max(MIN_VERTICAL_FLOATING_WIDTH, winRect.height_); + } + } else { + winRect.width_ = std::max(1u, winRect.width_); + winRect.height_ = std::max(1u, winRect.height_); + } +} + AvoidPosType WindowLayoutPolicy::GetAvoidPosType(const Rect& rect) { if (rect.width_ >= rect.height_) { diff --git a/wmserver/src/window_node.cpp b/wmserver/src/window_node.cpp index c7abd188..4c4f8916 100644 --- a/wmserver/src/window_node.cpp +++ b/wmserver/src/window_node.cpp @@ -28,6 +28,11 @@ void WindowNode::SetLayoutRect(const Rect& rect) layoutRect_ = rect; } +void WindowNode::SetWindowRect(const Rect& rect) +{ + property_->SetWindowRect(rect); +} + void WindowNode::SetWindowProperty(const sptr& property) { property_ = property; diff --git a/wmserver/src/window_node_container.cpp b/wmserver/src/window_node_container.cpp index 739c7064..bec4694b 100644 --- a/wmserver/src/window_node_container.cpp +++ b/wmserver/src/window_node_container.cpp @@ -602,6 +602,7 @@ std::vector WindowNodeContainer::GetAvoidAreaByType(AvoidAreaType avoidAre void WindowNodeContainer::OnAvoidAreaChange(const std::vector& avoidArea) { + layoutPolicy_->UpdateDefaultFoatingRect(); for (auto& node : appWindowNode_->children_) { if (node->GetWindowMode() == WindowMode::WINDOW_MODE_FULLSCREEN && node->GetWindowToken() != nullptr) { // notify client