diff --git a/interfaces/innerkits/wm/wm_common.h b/interfaces/innerkits/wm/wm_common.h index 573ec06e..bffecebd 100644 --- a/interfaces/innerkits/wm/wm_common.h +++ b/interfaces/innerkits/wm/wm_common.h @@ -114,7 +114,7 @@ enum class WMError : int32_t { WM_ERROR_DESTROYED_OBJECT, WM_ERROR_DEATH_RECIPIENT, WM_ERROR_INVALID_WINDOW, - WM_ERROR_INVALID_WINDOW_MODE, + WM_ERROR_INVALID_WINDOW_MODE_OR_SIZE, WM_ERROR_INVALID_OPERATION, WM_ERROR_INVALID_PERMISSION, WM_ERROR_NO_REMOTE_ANIMATION, diff --git a/utils/include/window_transition_info.h b/utils/include/window_transition_info.h index f2424a67..6208672c 100644 --- a/utils/include/window_transition_info.h +++ b/utils/include/window_transition_info.h @@ -21,6 +21,7 @@ #include "ability_info.h" #include "window_info.h" #include "wm_common.h" +#include "wm_common_inner.h" namespace OHOS { namespace Rosen { @@ -61,6 +62,8 @@ public: TransitionReason GetTransitionReason(); void SetIsRecent(bool isRecent); bool GetIsRecent() const; + WindowSizeLimits GetWindowSizeLimits() const; + private: std::string bundleName_; std::string abilityName_; @@ -73,6 +76,7 @@ private: bool isRecent_ = false; TransitionReason reason_ = TransitionReason::ABILITY_TRANSITION; std::vector supportWindowModes_; + WindowSizeLimits sizeLimits_; }; } // Rosen } // OHOS diff --git a/utils/src/window_transition_info.cpp b/utils/src/window_transition_info.cpp index d95cf8b4..f4fad7fd 100644 --- a/utils/src/window_transition_info.cpp +++ b/utils/src/window_transition_info.cpp @@ -35,6 +35,13 @@ WindowTransitionInfo::WindowTransitionInfo(sptr in } else { supportWindowModes_.assign(info->windowModes_.begin(), info->windowModes_.end()); } + + sizeLimits_.maxRatio_ = static_cast(info->maxWindowRatio_); + sizeLimits_.minRatio_ = static_cast(info->minWindowRatio_); + sizeLimits_.maxWidth_ = info->maxWindowWidth_; + sizeLimits_.minWidth_ = info->minWindowWidth_; + sizeLimits_.maxHeight_ = info->maxWindowHeight_; + sizeLimits_.minHeight_ = info->minWindowHeight_; } void WindowTransitionInfo::SetBundleName(std::string name) @@ -122,6 +129,11 @@ std::vector WindowTransitionInfo::GetWindowSuppor return supportWindowModes_; } +WindowSizeLimits WindowTransitionInfo::GetWindowSizeLimits() const +{ + return sizeLimits_; +} + bool WindowTransitionInfo::GetShowFlagWhenLocked() { return isShowWhenLocked_; @@ -191,6 +203,7 @@ bool WindowTransitionInfo::Marshalling(Parcel& parcel) const if (!parcel.WriteUint32(static_cast(reason_))) { return false; } + return true; } diff --git a/wm/include/window_impl.h b/wm/include/window_impl.h index fe8148f4..6f19d664 100644 --- a/wm/include/window_impl.h +++ b/wm/include/window_impl.h @@ -376,6 +376,8 @@ private: void SetModeSupportInfo(uint32_t modeSupportInfo); uint32_t GetModeSupportInfo() const; WMError PreProcessShow(uint32_t reason, bool withAnimation); + bool NeedToStopShowing(); + // colorspace, gamut using ColorSpaceConvertMap = struct { ColorSpace colorSpace; diff --git a/wm/src/window_impl.cpp b/wm/src/window_impl.cpp index 211fd2d6..dc8d7477 100755 --- a/wm/src/window_impl.cpp +++ b/wm/src/window_impl.cpp @@ -708,7 +708,7 @@ void WindowImpl::GetConfigurationFromAbilityInfo() uint32_t modeSupportInfo = 0; WindowHelper::ConvertSupportModesToSupportInfo(modeSupportInfo, abilityInfo->windowModes); if (modeSupportInfo == 0) { - WLOGFI("mode config param is 0, all modes is supported"); + WLOGFD("mode config param is 0, all modes is supported"); modeSupportInfo = WindowModeSupport::WINDOW_MODE_SUPPORT_ALL; } WLOGFI("winId: %{public}u, modeSupportInfo: %{public}u", GetWindowId(), modeSupportInfo); @@ -948,6 +948,22 @@ WMError WindowImpl::Destroy(bool needNotifyServer) return ret; } +bool WindowImpl::NeedToStopShowing() +{ + if (!WindowHelper::IsMainWindow(property_->GetWindowType())) { + return false; + } + // show failed when current mode is not support or window only supports split mode and can show when locked + bool isShowWhenLocked = GetWindowFlags() & static_cast(WindowFlag::WINDOW_FLAG_SHOW_WHEN_LOCKED); + if (!WindowHelper::IsWindowModeSupported(GetModeSupportInfo(), GetMode()) || + WindowHelper::IsOnlySupportSplitAndShowWhenLocked(isShowWhenLocked, GetModeSupportInfo())) { + WLOGFE("current mode is not supported, windowId: %{public}u, modeSupportInfo: %{public}u, winMode: %{public}u", + property_->GetWindowId(), GetModeSupportInfo(), GetMode()); + return true; + } + return false; +} + WMError WindowImpl::UpdateSurfaceNodeAfterCustomAnimation(bool isAdd) { WLOGFI("[Client] Window [name:%{public}s, id:%{public}u] UpdateRsTree, isAdd:%{public}u", @@ -982,15 +998,12 @@ WMError WindowImpl::PreProcessShow(uint32_t reason, bool withAnimation) } SetDefaultOption(); AdjustWindowAnimationFlag(withAnimation); - // show failed when current mode is not support or window only supports split mode and can show when locked - bool isShowWhenLocked = GetWindowFlags() & static_cast(WindowFlag::WINDOW_FLAG_SHOW_WHEN_LOCKED); - if (!WindowHelper::IsWindowModeSupported(GetModeSupportInfo(), GetMode()) || - WindowHelper::IsOnlySupportSplitAndShowWhenLocked(isShowWhenLocked, GetModeSupportInfo())) { - WLOGFE("current mode is not supported, windowId: %{public}u, modeSupportInfo: %{public}u, winMode: %{public}u", - property_->GetWindowId(), GetModeSupportInfo(), GetMode()); + + if (NeedToStopShowing()) { // true means stop showing NotifyForegroundInvalidWindowMode(); - return WMError::WM_ERROR_INVALID_WINDOW_MODE; + return WMError::WM_ERROR_INVALID_WINDOW_MODE_OR_SIZE; } + // update title button visibility when show UpdateTitleButtonVisibility(); return WMError::WM_OK; @@ -1036,7 +1049,7 @@ WMError WindowImpl::Show(uint32_t reason, bool withAnimation) // CustomAnimation is enabled when animationTranistionController_ exists animationTranistionController_->AnimationForShown(); } - } else if (ret == WMError::WM_ERROR_INVALID_WINDOW_MODE) { + } else if (ret == WMError::WM_ERROR_INVALID_WINDOW_MODE_OR_SIZE) { NotifyForegroundInvalidWindowMode(); } else { NotifyForegroundFailed(); diff --git a/wmserver/include/minimize_app.h b/wmserver/include/minimize_app.h index af827c69..a05f77d2 100644 --- a/wmserver/include/minimize_app.h +++ b/wmserver/include/minimize_app.h @@ -49,6 +49,7 @@ public: static void ClearNodesWithReason(MinimizeReason reason); static bool IsNodeNeedMinimize(const sptr& node); static std::vector> GetNeedMinimizeAppNodes(); + static sptr GetRecoverdNodeFromMinimizeList(); private: static inline bool IsFromUser(MinimizeReason reason) { diff --git a/wmserver/include/starting_window.h b/wmserver/include/starting_window.h index 93223a0b..6385e6cd 100644 --- a/wmserver/include/starting_window.h +++ b/wmserver/include/starting_window.h @@ -30,8 +30,7 @@ public: StartingWindow() = delete; ~StartingWindow() = default; - static sptr CreateWindowNode(const sptr& info, - uint32_t winId, WindowLayoutMode layoutMode); + static sptr CreateWindowNode(const sptr& info, uint32_t winId); static void HandleClientWindowCreate(sptr& node, sptr& window, uint32_t& windowId, const std::shared_ptr& surfaceNode, sptr& property, int32_t pid, int32_t uid); @@ -39,11 +38,11 @@ public: bool isColdStart); static void UpdateRSTree(sptr& node); static void ReleaseStartWinSurfaceNode(sptr& node); + static bool NeedToStopStartingWindow(WindowMode winMode, uint32_t modeSupportInfo, + const sptr& info); private: static WMError CreateLeashAndStartingSurfaceNode(sptr& node); - static bool NeedCancelStartingWindow(uint32_t modeSupportInfo, - WindowLayoutMode layoutMode, const sptr& info); static SurfaceDraw surfaceDraw_; static std::recursive_mutex mutex_; }; diff --git a/wmserver/include/window_layout_policy.h b/wmserver/include/window_layout_policy.h index ae69a4da..baaf3698 100644 --- a/wmserver/include/window_layout_policy.h +++ b/wmserver/include/window_layout_policy.h @@ -62,6 +62,7 @@ public: void ProcessDisplayDestroy(DisplayId displayId, const std::map& displayRectMap); void ProcessDisplaySizeChangeOrRotation(DisplayId displayId, const std::map& displayRectMap); void SetSplitRatioConfig(const SplitRatioConfig& splitRatioConfig); + virtual bool IsTileRectSatisfiedWithSizeLimits(const sptr& node); protected: void UpdateFloatingLayoutRect(Rect& limitRect, Rect& winRect); diff --git a/wmserver/include/window_layout_policy_tile.h b/wmserver/include/window_layout_policy_tile.h index 4136f544..7e8da067 100644 --- a/wmserver/include/window_layout_policy_tile.h +++ b/wmserver/include/window_layout_policy_tile.h @@ -38,6 +38,7 @@ public: void UpdateWindowNode(const sptr& node, bool isAddWindow = false) override; void RemoveWindowNode(const sptr& node) override; void UpdateLayoutRect(const sptr& node) override; + bool IsTileRectSatisfiedWithSizeLimits(const sptr& node) override; private: std::map maxTileWinNumMap_; diff --git a/wmserver/include/window_node_container.h b/wmserver/include/window_node_container.h index f4d55f91..8cd68ad1 100644 --- a/wmserver/include/window_node_container.h +++ b/wmserver/include/window_node_container.h @@ -111,6 +111,7 @@ public: void ProcessWindowAvoidAreaChangeWhenDisplayChange() const; WindowLayoutMode GetCurrentLayoutMode() const; void RemoveSingleUserWindowNodes(); + WMError IsTileRectSatisfiedWithSizeLimits(sptr& node); private: void TraverseWindowNode(sptr& root, std::vector>& windowNodes) const; diff --git a/wmserver/include/window_root.h b/wmserver/include/window_root.h index 4fc7e816..b3374e97 100644 --- a/wmserver/include/window_root.h +++ b/wmserver/include/window_root.h @@ -96,7 +96,6 @@ public: void SetSplitRatios(const std::vector& splitRatioNumbers); void SetExitSplitRatios(const std::vector& exitSplitRatios); void MinimizeTargetWindows(std::vector& windowIds); - WindowLayoutMode GetCurrentLayoutMode(DisplayId displayId); void RemoveSingleUserWindowNodes(); WMError UpdateRsTree(uint32_t windowId, bool isAdd); private: @@ -121,6 +120,8 @@ private: sptr& container); std::vector> GetWindowVisibilityChangeInfo( std::shared_ptr occlusionData); + bool NeedToStopAddingNode(sptr& node, const sptr& container); + std::map> windowNodeMap_; std::map, uint32_t> windowIdMap_; std::map> surfaceIdWindowNodeMap_; diff --git a/wmserver/src/minimize_app.cpp b/wmserver/src/minimize_app.cpp index 9875d272..387d0e44 100644 --- a/wmserver/src/minimize_app.cpp +++ b/wmserver/src/minimize_app.cpp @@ -86,6 +86,21 @@ void MinimizeApp::ClearNodesWithReason(MinimizeReason reason) } } +sptr MinimizeApp::GetRecoverdNodeFromMinimizeList() +{ + WLOGFI("[Minimize] RevertMinimizedNodeForTile"); + std::lock_guard lock(mutex_); + if (needMinimizeAppNodes_.find(MinimizeReason::LAYOUT_TILE) != needMinimizeAppNodes_.end()) { + auto& tileNodesForMinimize = needMinimizeAppNodes_.at(MinimizeReason::LAYOUT_TILE); + if (!tileNodesForMinimize.empty()) { + auto recoverNode = tileNodesForMinimize.back().promote(); + tileNodesForMinimize.pop_back(); + return recoverNode; + } + } + return nullptr; +} + bool MinimizeApp::IsNodeNeedMinimize(const sptr& node) { if (node == nullptr) { diff --git a/wmserver/src/remote_animation.cpp b/wmserver/src/remote_animation.cpp index 02ed6e5b..88b2dc47 100644 --- a/wmserver/src/remote_animation.cpp +++ b/wmserver/src/remote_animation.cpp @@ -110,7 +110,7 @@ TransitionEvent RemoteAnimation::GetTransitionEvent(sptr s WMError RemoteAnimation::NotifyAnimationTransition(sptr srcInfo, sptr dstInfo, const sptr& srcNode, - const sptr& dstNode) + const sptr& dstNode) { if (!dstNode || !dstNode->startingWindowShown_) { WLOGFE("RSWindowAnimation: no startingWindow for dst window id:%{public}u!", dstNode->GetWindowId()); diff --git a/wmserver/src/starting_window.cpp b/wmserver/src/starting_window.cpp index 718eaf16..4feb660b 100644 --- a/wmserver/src/starting_window.cpp +++ b/wmserver/src/starting_window.cpp @@ -31,34 +31,28 @@ namespace { std::recursive_mutex StartingWindow::mutex_; -bool StartingWindow::NeedCancelStartingWindow(uint32_t modeSupportInfo, - WindowLayoutMode layoutMode, const sptr& info) +bool StartingWindow::NeedToStopStartingWindow(WindowMode winMode, uint32_t modeSupportInfo, + const sptr& info) { - if ((!WindowHelper::IsWindowModeSupported(modeSupportInfo, info->GetWindowMode())) || - (WindowHelper::IsInvalidWindowInTileLayoutMode(modeSupportInfo, layoutMode)) || + if (!WindowHelper::IsMainWindow(info->GetWindowType())) { + return false; + } + + if ((!WindowHelper::IsWindowModeSupported(modeSupportInfo, winMode)) || (WindowHelper::IsOnlySupportSplitAndShowWhenLocked(info->GetShowFlagWhenLocked(), modeSupportInfo))) { - WLOGFI("window mode is not be supported or not support floating mode in tile, cancel starting window"); + WLOGFE("window mode is not be supported or not support floating mode in tile, cancel starting window"); return true; } return false; } -sptr StartingWindow::CreateWindowNode(const sptr& info, - uint32_t winId, WindowLayoutMode layoutMode) +sptr StartingWindow::CreateWindowNode(const sptr& info, uint32_t winId) { sptr property = new(std::nothrow) WindowProperty(); if (property == nullptr || info == nullptr) { return nullptr; } - // if mode isn't be supported or don't support floating mode in tile mode, create starting window failed - uint32_t modeSupportInfo = 0; - WindowHelper::ConvertSupportModesToSupportInfo(modeSupportInfo, info->GetWindowSupportModes()); - if (NeedCancelStartingWindow(modeSupportInfo, layoutMode, info)) { - WLOGFI("window mode is not be supported or not support floating mode in tile, cancel starting window"); - return nullptr; - } - property->SetRequestRect(info->GetWindowRect()); if (WindowHelper::IsValidWindowMode(info->GetWindowMode())) { property->SetWindowMode(info->GetWindowMode()); @@ -76,6 +70,11 @@ sptr StartingWindow::CreateWindowNode(const sptrabilityToken_ = info->GetAbilityToken(); + node->SetWindowSizeLimits(info->GetWindowSizeLimits()); + + uint32_t modeSupportInfo = 0; + WindowHelper::ConvertSupportModesToSupportInfo(modeSupportInfo, info->GetWindowSupportModes()); + node->SetModeSupportInfo(modeSupportInfo); if (CreateLeashAndStartingSurfaceNode(node) != WMError::WM_OK) { return nullptr; diff --git a/wmserver/src/window_controller.cpp b/wmserver/src/window_controller.cpp index 1799c464..f1b21a47 100644 --- a/wmserver/src/window_controller.cpp +++ b/wmserver/src/window_controller.cpp @@ -53,13 +53,12 @@ void WindowController::StartingWindow(sptr info, sptr(TraceTaskId::STARTING_WINDOW), "wms:async:ShowStartingWindow"); auto node = windowRoot_->FindWindowNodeWithToken(info->GetAbilityToken()); - auto layoutMode = windowRoot_->GetCurrentLayoutMode(info->GetDisplayId()); if (node == nullptr) { if (!isColdStart) { WLOGFE("no windowNode exists but is hot start!"); return; } - node = StartingWindow::CreateWindowNode(info, GenWindowId(), layoutMode); + node = StartingWindow::CreateWindowNode(info, GenWindowId()); if (node == nullptr) { return; } @@ -74,7 +73,6 @@ void WindowController::StartingWindow(sptr info, sptrGetWindowMode()) && (node->GetWindowMode() != info->GetWindowMode())) { WLOGFW("set starting window mode. starting mode is: %{public}u, window mode is:%{public}u.", @@ -82,6 +80,12 @@ void WindowController::StartingWindow(sptr info, sptrSetWindowMode(info->GetWindowMode()); } } + + if (StartingWindow::NeedToStopStartingWindow(node->GetWindowMode(), node->GetModeSupportInfo(), info)) { + WLOGFE("need to cancel starting window"); + return; + } + if (windowRoot_->AddWindowNode(0, node, true) != WMError::WM_OK) { return; } @@ -217,12 +221,6 @@ WMError WindowController::AddWindowNode(sptr& property) return WMError::WM_ERROR_INVALID_OPERATION; } - auto layoutMode = windowRoot_->GetCurrentLayoutMode(property->GetDisplayId()); - if (WindowHelper::IsInvalidWindowInTileLayoutMode(node->GetModeSupportInfo(), layoutMode)) { - WLOGFE("window doesn't support floating mode in tile, windowId: %{public}u", node->GetWindowId()); - return WMError::WM_ERROR_INVALID_WINDOW_MODE; - } - // using starting window rect if client rect is empty if (WindowHelper::IsEmptyRect(property->GetRequestRect()) && node->startingWindowShown_) { // for tile and cascade property->SetRequestRect(node->GetRequestRect()); diff --git a/wmserver/src/window_layout_policy.cpp b/wmserver/src/window_layout_policy.cpp index b88caec3..65416940 100644 --- a/wmserver/src/window_layout_policy.cpp +++ b/wmserver/src/window_layout_policy.cpp @@ -530,9 +530,9 @@ WindowSizeLimits WindowLayoutPolicy::GetSystemSizeLimits(const Rect& displayRect if (displayRect.width_ > displayRect.height_) { std::swap(systemLimits.minWidth_, systemLimits.minHeight_); } - WLOGFI("maxWidth: %{public}u, maxHeight: %{public}u, minWidth: %{public}u, minHeight: %{public}u " - "maxRatio: %{public}f, minRatio: %{public}f", systemLimits.maxWidth_, systemLimits.maxHeight_, - systemLimits.minWidth_, systemLimits.minHeight_, systemLimits.maxRatio_, systemLimits.minRatio_); + WLOGFI("[System SizeLimits] [maxWidth: %{public}u, minWidth: %{public}u, maxHeight: %{public}u, " + "minHeight: %{public}u]", systemLimits.maxWidth_, systemLimits.minWidth_, + systemLimits.maxHeight_, systemLimits.minHeight_); return systemLimits; } @@ -543,7 +543,10 @@ void WindowLayoutPolicy::UpdateWindowSizeLimits(const sptr& node) const auto& systemLimits = GetSystemSizeLimits(displayRect, virtualPixelRatio); const auto& customizedLimits = node->GetWindowSizeLimits(); if (customizedLimits.isSizeLimitsUpdated_) { - WLOGFI("size limits have been updated"); + WLOGFI("[SizeLimits Updated] winId: %{public}u, Width: [max:%{public}u, min:%{public}u], Height: " + "[max:%{public}u, min:%{public}u], Ratio: [max:%{public}f, min:%{public}f]", node->GetWindowId(), + customizedLimits.maxWidth_, customizedLimits.minWidth_, customizedLimits.maxHeight_, + customizedLimits.minHeight_, customizedLimits.maxRatio_, customizedLimits.minRatio_); return; } WindowSizeLimits newLimits = systemLimits; @@ -553,8 +556,6 @@ void WindowLayoutPolicy::UpdateWindowSizeLimits(const sptr& node) uint32_t configuredMaxHeight = static_cast(customizedLimits.maxHeight_ * virtualPixelRatio); uint32_t configuredMinWidth = static_cast(customizedLimits.minWidth_ * virtualPixelRatio); uint32_t configuredMinHeight = static_cast(customizedLimits.minHeight_ * virtualPixelRatio); - float configuerdMaxRatio = customizedLimits.maxRatio_; - float configuerdMinRatio = customizedLimits.minRatio_; // calculate new limit size if (systemLimits.minWidth_ <= configuredMaxWidth && configuredMaxWidth <= systemLimits.maxWidth_) { @@ -573,11 +574,11 @@ void WindowLayoutPolicy::UpdateWindowSizeLimits(const sptr& node) // calculate new limit ratio newLimits.maxRatio_ = static_cast(newLimits.maxWidth_) / static_cast(newLimits.minHeight_); newLimits.minRatio_ = static_cast(newLimits.minWidth_) / static_cast(newLimits.maxHeight_); - if (newLimits.minRatio_ <= configuerdMaxRatio && configuerdMaxRatio <= newLimits.maxRatio_) { - newLimits.maxRatio_ = configuerdMaxRatio; + if (newLimits.minRatio_ <= customizedLimits.maxRatio_ && customizedLimits.maxRatio_ <= newLimits.maxRatio_) { + newLimits.maxRatio_ = customizedLimits.maxRatio_; } - if (newLimits.minRatio_ <= configuerdMinRatio && configuerdMinRatio <= newLimits.maxRatio_) { - newLimits.minRatio_ = configuerdMinRatio; + if (newLimits.minRatio_ <= customizedLimits.minRatio_ && customizedLimits.minRatio_ <= newLimits.maxRatio_) { + newLimits.minRatio_ = customizedLimits.minRatio_; } // recalculate limit size by new ratio @@ -591,9 +592,9 @@ void WindowLayoutPolicy::UpdateWindowSizeLimits(const sptr& node) newLimits.minHeight_ = std::max(newMinHeight, newLimits.minHeight_); newLimits.isSizeLimitsUpdated_ = true; - WLOGFI("maxWidth: %{public}u, maxHeight: %{public}u, minWidth: %{public}u, minHeight: %{public}u, " - "maxRatio: %{public}f, minRatio: %{public}f", newLimits.maxWidth_, newLimits.maxHeight_, - newLimits.minWidth_, newLimits.minHeight_, newLimits.maxRatio_, newLimits.minRatio_); + WLOGFI("[Update SizeLimits] winId: %{public}u, Width: [max:%{public}u, min:%{public}u], Height: [max:%{public}u, " + "min:%{public}u], Ratio: [max:%{public}f, min:%{public}f]", node->GetWindowId(), newLimits.maxWidth_, + newLimits.minWidth_, newLimits.maxHeight_, newLimits.minHeight_, newLimits.maxRatio_, newLimits.minRatio_); node->SetWindowSizeLimits(newLimits); } @@ -980,5 +981,10 @@ Rect WindowLayoutPolicy::GetInitalDividerRect(DisplayId displayId) const { return INVALID_EMPTY_RECT; } + +bool WindowLayoutPolicy::IsTileRectSatisfiedWithSizeLimits(const sptr& node) +{ + return true; +} } } diff --git a/wmserver/src/window_layout_policy_tile.cpp b/wmserver/src/window_layout_policy_tile.cpp index 5a6f4c34..b79636b8 100644 --- a/wmserver/src/window_layout_policy_tile.cpp +++ b/wmserver/src/window_layout_policy_tile.cpp @@ -116,6 +116,26 @@ void WindowLayoutPolicyTile::InitTileWindowRects(DisplayId displayId) } } +bool WindowLayoutPolicyTile::IsTileRectSatisfiedWithSizeLimits(const sptr& node) +{ + if (!WindowHelper::IsMainWindow(node->GetWindowType())) { + return true; + } + UpdateWindowSizeLimits(node); + const auto& displayId = node->GetDisplayId(); + const auto& presetRects = presetRectsMap_[displayId]; + Rect tileRect; + // if size of foreground nodes is equal to or more than max tile window number + if (foregroundNodesMap_[displayId].size() >= maxTileWinNumMap_[displayId]) { + tileRect = *(presetRects[foregroundNodesMap_[displayId].size() - 1].begin()); + } else { // if size of foreground nodes is less than max tile window number + tileRect = *(presetRects[foregroundNodesMap_[displayId].size()].begin()); + } + WLOGFI("id %{public}u, tileRect: [%{public}d %{public}d %{public}u %{public}u]", + node->GetWindowId(), tileRect.posX_, tileRect.posY_, tileRect.width_, tileRect.height_); + return WindowHelper::IsRectSatisfiedWithSizeLimits(tileRect, node->GetWindowSizeLimits()); +} + void WindowLayoutPolicyTile::AddWindowNode(const sptr& node) { HITRACE_METER(HITRACE_TAG_WINDOW_MANAGER); @@ -244,7 +264,8 @@ void WindowLayoutPolicyTile::ForegroundNodeQueueRemove(const sptr& n void WindowLayoutPolicyTile::AssignNodePropertyForTileWindows(DisplayId displayId) { // set rect for foreground windows - uint32_t num = foregroundNodesMap_[displayId].size(); + auto& foregroundNodes = foregroundNodesMap_[displayId]; + uint32_t num = foregroundNodes.size(); auto& presetRects = presetRectsMap_[displayId]; if (num > maxTileWinNumMap_[displayId] || num > presetRects.size() || num == 0) { WLOGE("invalid tile queue"); @@ -256,7 +277,9 @@ void WindowLayoutPolicyTile::AssignNodePropertyForTileWindows(DisplayId displayI return; } auto rectIt = presetRect.begin(); - for (auto node : foregroundNodesMap_[displayId]) { + std::vector> needMinimizeNodes; + std::vector> needRecoverNodes; + for (auto node : foregroundNodes) { auto& rect = (*rectIt); if (WindowHelper::IsWindowModeSupported(node->GetModeSupportInfo(), WindowMode::WINDOW_MODE_FLOATING) && WindowHelper::IsRectSatisfiedWithSizeLimits(rect, node->GetWindowSizeLimits())) { @@ -270,9 +293,29 @@ void WindowLayoutPolicyTile::AssignNodePropertyForTileWindows(DisplayId displayI node->GetWindowId(), rect.posX_, rect.posY_, rect.width_, rect.height_); rectIt++; } else { + // if foreground nodes is equal to max tileWinNum, means need recover one node before minimize cur node + if (num == maxTileWinNumMap_[displayId]) { + auto recoverNode = MinimizeApp::GetRecoverdNodeFromMinimizeList(); + if (recoverNode != nullptr) { + needRecoverNodes.push_back(recoverNode); + } + } + needMinimizeNodes.push_back(node); MinimizeApp::AddNeedMinimizeApp(node, MinimizeReason::LAYOUT_TILE); } } + for (auto& miniNode : needMinimizeNodes) { + auto iter = std::find(foregroundNodes.begin(), foregroundNodes.end(), miniNode); + if (iter != foregroundNodes.end()) { + foregroundNodes.erase(iter); + } + } + needMinimizeNodes.clear(); + + for (auto& recNode : needRecoverNodes) { + foregroundNodes.push_back(recNode); + } + needRecoverNodes.clear(); } void WindowLayoutPolicyTile::UpdateLayoutRect(const sptr& node) diff --git a/wmserver/src/window_node_container.cpp b/wmserver/src/window_node_container.cpp index 2674de12..d32f8feb 100644 --- a/wmserver/src/window_node_container.cpp +++ b/wmserver/src/window_node_container.cpp @@ -121,6 +121,7 @@ WMError WindowNodeContainer::ShowStartingWindow(sptr& node) WLOGFE("current window is visible, windowId: %{public}u", node->GetWindowId()); return WMError::WM_ERROR_INVALID_OPERATION; } + WMError res = AddWindowNodeOnWindowTree(node, nullptr); if (res != WMError::WM_OK) { return res; @@ -139,12 +140,22 @@ WMError WindowNodeContainer::ShowStartingWindow(sptr& node) displayGroupController_->PreProcessWindowNode(node, WindowUpdateType::WINDOW_UPDATE_ADDED); StartingWindow::UpdateRSTree(node); AssignZOrder(); - layoutPolicy_->AddWindowNode(node); WLOGFI("ShowStartingWindow windowId: %{public}u end", node->GetWindowId()); return WMError::WM_OK; } +WMError WindowNodeContainer::IsTileRectSatisfiedWithSizeLimits(sptr& node) +{ + if (layoutMode_ == WindowLayoutMode::TILE && + !layoutPolicy_->IsTileRectSatisfiedWithSizeLimits(node)) { + WLOGFE("layoutMode is tile, default rect is not satisfied with size limits of window, windowId: %{public}u", + node->GetWindowId()); + return WMError::WM_ERROR_INVALID_WINDOW_MODE_OR_SIZE; + } + return WMError::WM_OK; +} + WMError WindowNodeContainer::AddWindowNode(sptr& node, sptr& parentNode) { if (!node->startingWindowShown_) { diff --git a/wmserver/src/window_root.cpp b/wmserver/src/window_root.cpp index 08b859d6..d0cf985a 100644 --- a/wmserver/src/window_root.cpp +++ b/wmserver/src/window_root.cpp @@ -451,6 +451,24 @@ WMError WindowRoot::PostProcessAddWindowNode(sptr& node, sptr& node, const sptr& container) +{ + if (!WindowHelper::IsMainWindow(node->GetWindowType())) { + return false; + } + // intercept the node which doesn't support floating mode at tile mode + if (WindowHelper::IsInvalidWindowInTileLayoutMode(node->GetModeSupportInfo(), container->GetCurrentLayoutMode())) { + WLOGFE("window doesn't support floating mode in tile, windowId: %{public}u", node->GetWindowId()); + return true; + } + // intercept the node that the tile rect can't be applied to + WMError res = container->IsTileRectSatisfiedWithSizeLimits(node); + if (res != WMError::WM_OK) { + return true; + } + return false; +} + WMError WindowRoot::AddWindowNode(uint32_t parentId, sptr& node, bool fromStartingWin) { if (node == nullptr) { @@ -463,6 +481,11 @@ WMError WindowRoot::AddWindowNode(uint32_t parentId, sptr& node, boo WLOGFE("add window failed, window container could not be found"); return WMError::WM_ERROR_NULLPTR; } + + if (NeedToStopAddingNode(node, container)) { // true means stop adding + return WMError::WM_ERROR_INVALID_WINDOW_MODE_OR_SIZE; + } + if (node->GetWindowMode() == WindowMode::WINDOW_MODE_FULLSCREEN && WindowHelper::IsAppWindow(node->GetWindowType()) && !node->isPlayAnimationShow_) { container->NotifyDockWindowStateChanged(node, false); @@ -1310,16 +1333,6 @@ WMError WindowRoot::GetModeChangeHotZones(DisplayId displayId, return WMError::WM_OK; } -WindowLayoutMode WindowRoot::GetCurrentLayoutMode(DisplayId displayId) -{ - auto container = GetOrCreateWindowNodeContainer(displayId); - if (container == nullptr) { - WLOGFE("GetCurrentLayoutMode failed, window container could not be found"); - return WindowLayoutMode::BASE; - } - return container->GetCurrentLayoutMode(); -} - void WindowRoot::RemoveSingleUserWindowNodes() { std::vector displayIds = GetAllDisplayIds();