diff --git a/utils/include/window_helper.h b/utils/include/window_helper.h index 1747da81..9b47e315 100644 --- a/utils/include/window_helper.h +++ b/utils/include/window_helper.h @@ -122,6 +122,11 @@ public: return false; } + static inline bool IsSwitchCascadeReason(WindowUpdateReason reason) + { + return (reason >= NEED_SWITCH_CASCADE_BASE) && (reason < NEED_SWITCH_CASCADE_END); + } + WindowHelper() = default; ~WindowHelper() = default; }; diff --git a/utils/include/wm_common_inner.h b/utils/include/wm_common_inner.h index 8e8daf12..279a74d6 100644 --- a/utils/include/wm_common_inner.h +++ b/utils/include/wm_common_inner.h @@ -37,11 +37,13 @@ enum class WindowStateChangeReason : uint32_t { }; enum class WindowUpdateReason : uint32_t { - UPDATE_ALL, + NEED_SWITCH_CASCADE_BASE, + UPDATE_ALL = NEED_SWITCH_CASCADE_BASE, UPDATE_MODE, UPDATE_RECT, UPDATE_FLAGS, UPDATE_TYPE, + NEED_SWITCH_CASCADE_END, UPDATE_OTHER_PROPS, }; namespace { diff --git a/wmserver/include/window_layout_policy_tile.h b/wmserver/include/window_layout_policy_tile.h index 19c76fcc..5b367c8d 100644 --- a/wmserver/include/window_layout_policy_tile.h +++ b/wmserver/include/window_layout_policy_tile.h @@ -39,9 +39,8 @@ public: void UpdateLayoutRect(sptr& node) override; private: - Rect singleRect_ = { 0, 0, 0, 0 }; - std::vector doubleRects_ = std::vector(2); - std::vector tripleRects_ = std::vector(3); + uint32_t maxTileWinNum_ = 1; + std::vector> presetRects_; std::deque> foregroundNodes_; void UpdateDisplayInfo() override; void InitTileWindowRects(); diff --git a/wmserver/src/window_layout_policy.cpp b/wmserver/src/window_layout_policy.cpp index d6ef8e29..9da70d2c 100644 --- a/wmserver/src/window_layout_policy.cpp +++ b/wmserver/src/window_layout_policy.cpp @@ -269,10 +269,6 @@ void WindowLayoutPolicy::LimitWindowSize(const sptr& node, const Rec WindowType windowType = node->GetWindowType(); WindowMode windowMode = node->GetWindowMode(); bool isVertical = (displayRect.height_ > displayRect.width_) ? true : false; - if (!WindowHelper::IsMainFloatingWindow(windowType, windowMode)) { - winRect.width_ = std::min(displayRect.width_ - winRect.posX_, winRect.width_); - winRect.height_ = std::min(displayRect.height_ - winRect.posY_, winRect.height_); - } if ((windowMode == WindowMode::WINDOW_MODE_FLOATING) && !WindowHelper::IsSystemWindow(windowType)) { if (isVertical) { winRect.width_ = std::max(minVerticalFloatingW, winRect.width_); diff --git a/wmserver/src/window_layout_policy_tile.cpp b/wmserver/src/window_layout_policy_tile.cpp index 1e091dec..28350383 100644 --- a/wmserver/src/window_layout_policy_tile.cpp +++ b/wmserver/src/window_layout_policy_tile.cpp @@ -36,9 +36,7 @@ WindowLayoutPolicyTile::WindowLayoutPolicyTile(const Rect& displayRect, const ui void WindowLayoutPolicyTile::Launch() { // compute limit rect - limitRect_ = displayRect_; - LayoutWindowNode(aboveAppWindowNode_); - InitTileWindowRects(); + UpdateDisplayInfo(); // select app min win in queue, and minimize others InitForegroundNodeQueue(); AssignNodePropertyForTileWindows(); @@ -61,24 +59,26 @@ void WindowLayoutPolicyTile::InitTileWindowRects() constexpr float ratio = 0.75; // 0.75: default height/width ratio constexpr float edgeRatio = 0.125; constexpr int half = 2; + maxTileWinNum_ = IsVertical() ? MAX_WIN_NUM_VERTICAL : MAX_WIN_NUM_HORIZONTAL; + presetRects_.clear(); 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 * half - midInterval) / half; - // 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 * half - midInterval * half) / MAX_WIN_NUM_HORIZONTAL; - tripleRects_[0] = {x, y, w, h}; - tripleRects_[1] = {x + w + midInterval, y, w, h}; - tripleRects_[2] = {x + w * half + midInterval * half, y, w, h}; // 2 is third index - WLOGFI("tripleRects_: %{public}d %{public}d %{public}d %{public}d", x, y, w, h); + 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_ - edgeInterval * half - midInterval * (num - 1)) / num; + std::vector curLevel; + for (uint32_t i = 0; i < num; i++) { + int curX = limitRect_.posX_ + edgeInterval + i * (w + midInterval); + Rect curRect = { curX, y, w, h }; + WLOGFI("presetRects: level %{public}d, id %{public}d, [%{public}d %{public}d %{public}d %{public}d]", + num, i, curX, y, w, h); + curLevel.emplace_back(curRect); + } + presetRects_.emplace_back(curLevel); + } } void WindowLayoutPolicyTile::AddWindowNode(sptr& node) @@ -143,8 +143,7 @@ void WindowLayoutPolicyTile::ForegroundNodeQueuePushBack(sptr& node) 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; - while (foregroundNodes_.size() >= maxTileWinNum) { + while (foregroundNodes_.size() >= maxTileWinNum_) { auto removeNode = foregroundNodes_.front(); foregroundNodes_.pop_front(); WLOGFI("pop win in queue head id: %{public}d, for add new win", removeNode->GetWindowId()); @@ -171,30 +170,26 @@ void WindowLayoutPolicyTile::ForegroundNodeQueueRemove(sptr& node) void WindowLayoutPolicyTile::AssignNodePropertyForTileWindows() { // set rect for foreground windows - int num = foregroundNodes_.size(); - if (num == 1) { - WLOGFI("set rect for win id: %{public}d", foregroundNodes_.front()->GetWindowMode()); - foregroundNodes_.front()->SetWindowMode(WindowMode::WINDOW_MODE_FLOATING); - foregroundNodes_.front()->GetWindowToken()->UpdateWindowMode(WindowMode::WINDOW_MODE_FLOATING); - foregroundNodes_.front()->SetWindowRect(singleRect_); - foregroundNodes_.front()->hasDecorated_ = true; - WLOGFI("set rect for win id: %{public}d [%{public}d %{public}d %{public}d %{public}d]", - foregroundNodes_.front()->GetWindowId(), - singleRect_.posX_, singleRect_.posY_, singleRect_.width_, singleRect_.height_); - } else if (num <= MAX_WIN_NUM_HORIZONTAL) { - auto rit = (num == MAX_WIN_NUM_HORIZONTAL) ? tripleRects_.begin() : doubleRects_.begin(); - for (auto it : foregroundNodes_) { - auto& rect = (*rit); - it->SetWindowMode(WindowMode::WINDOW_MODE_FLOATING); - it->GetWindowToken()->UpdateWindowMode(WindowMode::WINDOW_MODE_FLOATING); - it->SetWindowRect(rect); - it->hasDecorated_ = true; - WLOGFI("set rect for qwin id: %{public}d [%{public}d %{public}d %{public}d %{public}d]", - it->GetWindowId(), rect.posX_, rect.posY_, rect.width_, rect.height_); - rit++; - } - } else { - WLOGE("too many window node in tile queue"); + uint32_t num = foregroundNodes_.size(); + if (num > maxTileWinNum_ || num > presetRects_.size() || num == 0) { + WLOGE("invalid tile queue"); + return; + } + std::vector& presetRect = presetRects_[num - 1]; + if (presetRect.size() != num) { + WLOGE("invalid preset rects"); + return; + } + auto rectIt = presetRect.begin(); + for (auto node : foregroundNodes_) { + auto& rect = (*rectIt); + node->SetWindowMode(WindowMode::WINDOW_MODE_FLOATING); + node->GetWindowToken()->UpdateWindowMode(WindowMode::WINDOW_MODE_FLOATING); + node->SetWindowRect(rect); + node->hasDecorated_ = true; + WLOGFI("set rect for qwin id: %{public}d [%{public}d %{public}d %{public}d %{public}d]", + node->GetWindowId(), rect.posX_, rect.posY_, rect.width_, rect.height_); + rectIt++; } } diff --git a/wmserver/src/window_node_container.cpp b/wmserver/src/window_node_container.cpp index 95862bdb..6972c21c 100644 --- a/wmserver/src/window_node_container.cpp +++ b/wmserver/src/window_node_container.cpp @@ -149,7 +149,7 @@ WMError WindowNodeContainer::UpdateWindowNode(sptr& node, WindowUpda WLOGFE("surface node is nullptr!"); return WMError::WM_ERROR_NULLPTR; } - if (WindowHelper::IsMainWindow(node->GetWindowType()) && reason != WindowUpdateReason::UPDATE_OTHER_PROPS) { + if (WindowHelper::IsMainWindow(node->GetWindowType()) && WindowHelper::IsSwitchCascadeReason(reason)) { SwitchLayoutPolicy(WindowLayoutMode::CASCADE); } layoutPolicy_->UpdateWindowNode(node);