From b0bac8574620636f58877fb2c6022ecfcc5c811e Mon Sep 17 00:00:00 2001 From: l00574490 Date: Sat, 15 Jan 2022 18:42:24 +0800 Subject: [PATCH] support vertical screen Change-Id: Ibdb7978961ca2d9ae04eee5e74ce97ed58a5f707 Signed-off-by: l00574490 --- wmserver/include/window_layout_policy.h | 5 ++ wmserver/include/window_node_container.h | 4 ++ wmserver/include/window_root.h | 1 + wmserver/src/window_controller.cpp | 8 ++- wmserver/src/window_layout_policy.cpp | 73 +++++++++++++++++++----- wmserver/src/window_node_container.cpp | 51 +++++++++++++---- wmserver/src/window_root.cpp | 10 ++++ 7 files changed, 127 insertions(+), 25 deletions(-) diff --git a/wmserver/include/window_layout_policy.h b/wmserver/include/window_layout_policy.h index a9dc89d352..b83d5f0c3c 100644 --- a/wmserver/include/window_layout_policy.h +++ b/wmserver/include/window_layout_policy.h @@ -53,6 +53,7 @@ public: void RemoveWindowNode(sptr& node); void UpdateWindowNode(sptr& node); void UpdateLayoutRect(sptr& node); + Rect GetDependDisplayRects() const; private: LayoutDependRects dependRects; @@ -63,6 +64,9 @@ private: WindowType::WINDOW_TYPE_STATUS_BAR, WindowType::WINDOW_TYPE_NAVIGATION_BAR, }; + + void UpdateFloatingLayoutRect(Rect& limitRect, Rect& winRect); + void UpdateSplitLimitRect(const Rect& limitRect, Rect& limitSplitRect); void UpdateLimitRect(const sptr& node, Rect& limitRect); void LayoutWindowTree(); void LayoutWindowNode(sptr& node); @@ -70,6 +74,7 @@ private: void InitLimitRects(); Rect& GetLimitRect(const WindowMode mode); Rect& GetDisplayRect(const WindowMode mode); + void LimitMoveBounds(Rect& rect); }; } } diff --git a/wmserver/include/window_node_container.h b/wmserver/include/window_node_container.h index 6e22a2256c..b6a335ac51 100644 --- a/wmserver/include/window_node_container.h +++ b/wmserver/include/window_node_container.h @@ -60,6 +60,7 @@ public: std::shared_ptr GetDisplayNode() const; void LayoutDividerWindow(sptr& node); void UpdateDisplayInfo(); + bool isVerticalDisplay() const; class DisplayRects : public RefBase { public: @@ -71,6 +72,9 @@ public: void SetSplitRect(const Rect& rect); Rect GetRectByWindowMode(const WindowMode& mode) const; Rect GetDividerRect() const; + bool isVertical_ = false; + Rect displayDependRect_ = {0, 0, 0, 0}; + private: Rect primaryRect_ = {0, 0, 0, 0}; Rect secondaryRect_ = {0, 0, 0, 0}; diff --git a/wmserver/include/window_root.h b/wmserver/include/window_root.h index f8c6145355..0054e99e2f 100644 --- a/wmserver/include/window_root.h +++ b/wmserver/include/window_root.h @@ -66,6 +66,7 @@ public: WMError DestroyWindow(uint32_t windowId); WMError UpdateWindowNode(uint32_t windowId); WMError LayoutDividerWindow(sptr& node); + bool isVerticalDisplay(sptr& node) const; WMError RequestFocus(uint32_t windowId); WMError MinimizeOtherFullScreenAbility(sptr& node); diff --git a/wmserver/src/window_controller.cpp b/wmserver/src/window_controller.cpp index b3dd567983..963bb30517 100644 --- a/wmserver/src/window_controller.cpp +++ b/wmserver/src/window_controller.cpp @@ -105,13 +105,17 @@ WMError WindowController::MoveTo(uint32_t windowId, int32_t x, int32_t y) WLOGFE("could not find window"); return WMError::WM_ERROR_NULLPTR; } + auto property = node->GetWindowProperty(); Rect lastRect = property->GetWindowRect(); Rect newRect; WMError res; if (node->GetWindowType() == WindowType::WINDOW_TYPE_DOCK_SLICE) { - WLOGFI("Moving divider"); - newRect = { x, lastRect.posY_, lastRect.width_, lastRect.height_ }; + if (windowRoot_->isVerticalDisplay(node)) { + newRect = { lastRect.posX_, y, lastRect.width_, lastRect.height_ }; + } else { + newRect = { x, lastRect.posY_, lastRect.width_, lastRect.height_ }; + } property->SetWindowRect(newRect); res = windowRoot_->LayoutDividerWindow(node); if (res != WMError::WM_OK) { diff --git a/wmserver/src/window_layout_policy.cpp b/wmserver/src/window_layout_policy.cpp index 92fe42c7c5..8b67bcd9db 100644 --- a/wmserver/src/window_layout_policy.cpp +++ b/wmserver/src/window_layout_policy.cpp @@ -63,9 +63,9 @@ void WindowLayoutPolicy::LayoutWindowNode(sptr& node) } UpdateLayoutRect(node); if (avoidTypes_.find(node->GetWindowType()) != avoidTypes_.end()) { - UpdateLimitRect(node, dependRects.limitPriRect_); - UpdateLimitRect(node, dependRects.limitSecRect_); UpdateLimitRect(node, dependRects.limitFullRect_); + UpdateSplitLimitRect(dependRects.limitFullRect_, dependRects.limitPriRect_); + UpdateSplitLimitRect(dependRects.limitFullRect_, dependRects.limitSecRect_); } } for (auto& childNode : node->children_) { @@ -100,7 +100,6 @@ void WindowLayoutPolicy::UpdateWindowNode(sptr& node) if (avoidTypes_.find(type) != avoidTypes_.end()) { LayoutWindowTree(); } else if (type == WindowType::WINDOW_TYPE_DOCK_SLICE) { // split screen mode - // TODO: change split screen LayoutWindowTree(); } else { // layout single window LayoutWindowNode(node); @@ -112,6 +111,36 @@ static bool IsLayoutChanged(const Rect& l, const Rect& r) return !((l.posX_ == r.posX_) && (l.posY_ == r.posY_) && (l.width_ == r.width_) && (l.height_ == r.height_)); } +void WindowLayoutPolicy::LimitMoveBounds(Rect& rect) +{ + Rect curRect = rect; + rect.posX_ = std::max(curRect.posX_, dependRects.limitFullRect_.posX_); + rect.posY_ = std::max(curRect.posY_, dependRects.limitFullRect_.posY_); + if (rect.width_ < rect.height_) { + rect.posX_ = std::min(curRect.posX_ + rect.width_, + dependRects.limitFullRect_.posX_ + dependRects.limitFullRect_.width_) - rect.width_; + rect.height_ = curRect.posY_ + curRect.height_ - rect.posY_; + } else { + rect.posY_ = std::min(curRect.posY_ + rect.height_, + dependRects.limitFullRect_.posY_ + dependRects.limitFullRect_.height_) - rect.height_; + rect.width_ = curRect.posX_ + curRect.width_ - rect.posX_; + } +} + +void WindowLayoutPolicy::UpdateFloatingLayoutRect(Rect& limitRect, Rect& winRect) +{ + winRect.width_ = std::min(limitRect.width_, winRect.width_); + winRect.height_ = std::min(limitRect.height_, winRect.height_); + winRect.posX_ = std::max(limitRect.posX_, winRect.posX_); + winRect.posY_ = std::max(limitRect.posY_, winRect.posY_); + winRect.posX_ = std::min( + limitRect.posX_ + static_cast(limitRect.width_) - static_cast(winRect.width_), + winRect.posX_); + winRect.posY_ = std::min( + limitRect.posY_ + static_cast(limitRect.height_) - static_cast(winRect.height_), + winRect.posY_); +} + void WindowLayoutPolicy::UpdateLayoutRect(sptr& node) { auto type = node->GetWindowType(); @@ -140,16 +169,7 @@ void WindowLayoutPolicy::UpdateLayoutRect(sptr& node) } else { // floating window if (subWindow && parentLimit) { // subwidow and limited by parent limitRect = node->parent_->GetLayoutRect(); - winRect.width_ = std::min(limitRect.width_, winRect.width_); - winRect.height_ = std::min(limitRect.height_, winRect.height_); - winRect.posX_ = std::max(limitRect.posX_, winRect.posX_); - winRect.posY_ = std::max(limitRect.posY_, winRect.posY_); - winRect.posX_ = std::min( - limitRect.posX_ + static_cast(limitRect.width_) - static_cast(winRect.width_), - winRect.posX_); - winRect.posY_ = std::min( - limitRect.posY_ + static_cast(limitRect.height_) - static_cast(winRect.height_), - winRect.posY_); + UpdateFloatingLayoutRect(limitRect, winRect); } } // Limit window to the maximum window size @@ -158,6 +178,10 @@ void WindowLayoutPolicy::UpdateLayoutRect(sptr& node) winRect.width_ = std::max(1u, winRect.width_); winRect.height_ = std::max(1u, winRect.height_); + if (node->GetWindowType() == WindowType::WINDOW_TYPE_DOCK_SLICE) { + LimitMoveBounds(winRect); + } + node->SetLayoutRect(winRect); if (IsLayoutChanged(lastRect, winRect)) { node->GetWindowToken()->UpdateWindowRect(winRect); @@ -212,6 +236,29 @@ Rect& WindowLayoutPolicy::GetDisplayRect(const WindowMode mode) } } +Rect WindowLayoutPolicy::GetDependDisplayRects() const +{ + Rect displayRect = dependRects.fullRect_; + Rect limitDisplayRect = dependRects.limitFullRect_; + if (IsLayoutChanged(displayRect, limitDisplayRect)) { + return limitDisplayRect; + } + return displayRect; +} + +void WindowLayoutPolicy::UpdateSplitLimitRect(const Rect& limitRect, Rect& limitSplitRect) +{ + Rect curLimitRect = limitSplitRect; + limitSplitRect.posX_ = std::max(limitRect.posX_, curLimitRect.posX_); + limitSplitRect.posY_ = std::max(limitRect.posY_, curLimitRect.posY_); + limitSplitRect.width_ = std::min(limitRect.posX_ + limitRect.width_, + curLimitRect.posX_ + curLimitRect.width_) - + limitSplitRect.posX_; + limitSplitRect.height_ = std::min(limitRect.posY_ + limitRect.height_, + curLimitRect.posY_ + curLimitRect.height_) - + limitSplitRect.posY_; +} + void WindowLayoutPolicy::UpdateLimitRect(const sptr& node, Rect& limitRect) { auto& layoutRect = node->GetLayoutRect(); diff --git a/wmserver/src/window_node_container.cpp b/wmserver/src/window_node_container.cpp index f367683fd5..fb771bc996 100644 --- a/wmserver/src/window_node_container.cpp +++ b/wmserver/src/window_node_container.cpp @@ -495,18 +495,32 @@ void WindowNodeContainer::LayoutDividerWindow(sptr& node) void WindowNodeContainer::DisplayRects::InitRect(Rect& oriDisplayRect) { + if (oriDisplayRect.width_ < oriDisplayRect.height_) { + isVertical_ = true; + } displayRect_ = oriDisplayRect; - const uint32_t dividerWidth = 50; - dividerRect_ = { static_cast((displayRect_.width_ - dividerWidth) * DEFAULT_SPLIT_RATIO), 0, - dividerWidth, displayRect_.height_ }; - + if (!isVertical_) { + 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 }; + } + WLOGFI("init dividerRect :[%{public}d, %{public}d, %{public}d, %{public}d]", + dividerRect_.posX_, dividerRect_.posY_, dividerRect_.width_, dividerRect_.height_); SetSplitRect(dividerRect_); } void WindowNodeContainer::DisplayRects::SetSplitRect(float ratio) { - dividerRect_.posX_ = static_cast((displayRect_.width_ - dividerRect_.width_) * ratio); + if (!isVertical_) { + dividerRect_.posX_ = displayDependRect_.posX_ + static_cast(displayDependRect_.width_ * ratio); + } else { + dividerRect_.posY_ = displayDependRect_.posY_ + static_cast(displayDependRect_.height_ * ratio); + } + WLOGFI("set dividerRect :[%{public}d, %{public}d, %{public}d, %{public}d]", + dividerRect_.posX_, dividerRect_.posY_, dividerRect_.width_, dividerRect_.height_); SetSplitRect(dividerRect_); } @@ -514,13 +528,21 @@ void WindowNodeContainer::DisplayRects::SetSplitRect(const Rect& divRect) { dividerRect_.width_ = divRect.width_; dividerRect_.height_ = divRect.height_; + if (!isVertical_) { + primaryRect_.width_ = divRect.posX_; + primaryRect_.height_ = displayRect_.height_; - primaryRect_.width_ = divRect.posX_; - primaryRect_.height_ = displayRect_.height_; + secondaryRect_.posX_ = divRect.posX_ + dividerRect_.width_; + secondaryRect_.width_ = displayRect_.width_ - secondaryRect_.posX_; + secondaryRect_.height_ = displayRect_.height_; + } else { + primaryRect_.height_ = divRect.posY_; + primaryRect_.width_ = displayRect_.width_; - secondaryRect_.posX_ = divRect.posX_ + dividerRect_.width_; - secondaryRect_.width_ = displayRect_.width_ - secondaryRect_.posX_; - secondaryRect_.height_ = displayRect_.height_; + secondaryRect_.posY_ = divRect.posY_ + dividerRect_.height_; + secondaryRect_.height_ = displayRect_.height_ - secondaryRect_.posY_; + secondaryRect_.width_ = displayRect_.width_; + } } Rect WindowNodeContainer::DisplayRects::GetDividerRect() const @@ -585,6 +607,11 @@ std::shared_ptr WindowNodeContainer::GetDisplayNode() const return displayNode_; } +bool WindowNodeContainer::isVerticalDisplay() const +{ + return displayRects_->isVertical_; +} + void WindowNodeContainer::SendSplitScreenEvent(WindowMode mode) { // should define in common_event_support.h and @ohos.commonEvent.d.ts @@ -626,6 +653,10 @@ WMError WindowNodeContainer::HandleModeChangeToSplit(sptr& triggerNo WM_FUNCTION_TRACE(); WLOGFI("HandleModeChangeToSplit %{public}d", triggerNode->GetWindowId()); auto pairNode = FindSplitPairNode(triggerNode); + displayRects_->displayDependRect_ = layoutPolicy_->GetDependDisplayRects(); // get depend display rect for split + WLOGFI("displayDependRect :[%{public}d, %{public}d, %{public}d, %{public}d]", + displayRects_->displayDependRect_.posX_, displayRects_->displayDependRect_.posY_, + displayRects_->displayDependRect_.width_, displayRects_->displayDependRect_.height_); if (pairNode != nullptr) { WLOGFI("Window %{public}d find pair %{public}d", triggerNode->GetWindowId(), pairNode->GetWindowId()); WMError ret = UpdateWindowPairInfo(triggerNode, pairNode); diff --git a/wmserver/src/window_root.cpp b/wmserver/src/window_root.cpp index a3abc4f104..6b226a6963 100644 --- a/wmserver/src/window_root.cpp +++ b/wmserver/src/window_root.cpp @@ -269,6 +269,16 @@ WMError WindowRoot::LayoutDividerWindow(sptr& node) return WMError::WM_OK; } +bool WindowRoot::isVerticalDisplay(sptr& node) const +{ + auto container = const_cast(this)->GetOrCreateWindowNodeContainer(node->GetDisplayId()); + if (container == nullptr) { + WLOGFE("get display direction failed, window container could not be found"); + return false; + } + return container->isVerticalDisplay(); +} + WMError WindowRoot::RequestFocus(uint32_t windowId) { auto node = GetWindowNode(windowId); -- Gitee