diff --git a/resources/config/other/window_manager_config.xml b/resources/config/other/window_manager_config.xml index 24bbe538..a9f31b0c 100644 --- a/resources/config/other/window_manager_config.xml +++ b/resources/config/other/window_manager_config.xml @@ -18,4 +18,8 @@ + + 0.1 + + 0.5 0.33 0.67 diff --git a/resources/config/rk3568/window_manager_config.xml b/resources/config/rk3568/window_manager_config.xml index d64616c7..2d47bdc1 100644 --- a/resources/config/rk3568/window_manager_config.xml +++ b/resources/config/rk3568/window_manager_config.xml @@ -24,4 +24,8 @@ 50 50 50 + + 0.1 + + 0.5 0.33 0.67 \ No newline at end of file diff --git a/utils/include/wm_common_inner.h b/utils/include/wm_common_inner.h index 92cd84b4..517d383e 100644 --- a/utils/include/wm_common_inner.h +++ b/utils/include/wm_common_inner.h @@ -103,6 +103,11 @@ struct ModeChangeHotZones { Rect secondary_; }; +struct SplitRatioConfig { + float exitSplitRatio; + std::vector splitRatios; +}; + enum class DragType : uint32_t { DRAG_UNDEFINED, DRAG_WIDTH, diff --git a/wm/test/systemtest/window_split_test.cpp b/wm/test/systemtest/window_split_test.cpp index 36bbc8a4..e72721fc 100644 --- a/wm/test/systemtest/window_split_test.cpp +++ b/wm/test/systemtest/window_split_test.cpp @@ -206,11 +206,11 @@ HWTEST_F(WindowSplitTest, SplitScreen04, Function | MediumTest | Level3) } /** - * @tc.name: SplitCreen05 - * @tc.desc: forbid dock slive to move test + * @tc.name: SplitScreen05 + * @tc.desc: forbid dock slice to move test * @tc.type: FUNC */ -HWTEST_F(WindowSplitTest, SplitCreen05, Function | MediumTest | Level3) +HWTEST_F(WindowSplitTest, SplitScreen05, Function | MediumTest | Level3) { fullInfo_.name = "fullscreen.5"; splitInfo_.name = "primary.5"; diff --git a/wmserver/include/minimize_app.h b/wmserver/include/minimize_app.h index ec8bc4ac..ba14975e 100644 --- a/wmserver/include/minimize_app.h +++ b/wmserver/include/minimize_app.h @@ -31,6 +31,7 @@ enum class MinimizeReason : uint32_t { LAYOUT_TILE, MAX_APP_COUNT, SPLIT_REPLACE, + SPLIT_QUIT, OTHER_WINDOW, }; @@ -50,7 +51,7 @@ private: { return (reason == MinimizeReason::MINIMIZE_ALL || reason == MinimizeReason::MINIMIZE_BUTTOM || reason == MinimizeReason::MAX_APP_COUNT || reason == MinimizeReason::LAYOUT_TILE || - reason == MinimizeReason::SPLIT_REPLACE); + reason == MinimizeReason::SPLIT_REPLACE || reason == MinimizeReason::SPLIT_QUIT); } static std::map>> needMinimizeAppNodes_; diff --git a/wmserver/include/window_layout_policy.h b/wmserver/include/window_layout_policy.h index dd5522cb..6fefc27a 100644 --- a/wmserver/include/window_layout_policy.h +++ b/wmserver/include/window_layout_policy.h @@ -53,6 +53,7 @@ public: virtual void UpdateLayoutRect(const sptr& node) = 0; virtual void SetSplitDividerWindowRects(std::map dividerWindowRects) {}; virtual Rect GetInitalDividerRect(DisplayId displayId) const; + virtual std::vector GetExitSplitPoints(DisplayId displayId) const; float GetVirtualPixelRatio(DisplayId displayId) const; void UpdateClientRectAndResetReason(const sptr& node, const Rect& lastLayoutRect, const Rect& winRect); Rect GetDisplayGroupRect() const; @@ -61,6 +62,7 @@ public: void ProcessDisplayDestroy(DisplayId displayId, const std::map& displayRectMap); void ProcessDisplaySizeChangeOrRotation(DisplayId displayId, const std::map& displayRectMap); void SetFloatingWindowLimitsConfig(const FloatingWindowLimitsConfig& floatingWindowLimitsConfig); + void SetSplitRatioConfig(SplitRatioConfig splitRatioConfig); protected: void UpdateFloatingLayoutRect(Rect& limitRect, Rect& winRect); @@ -111,6 +113,8 @@ protected: Rect secondaryLimitRect_; Rect dividerRect_; Rect firstCascadeRect_; + std::vector exitSplitPoints_; // 2 element, first elment < second element + std::vector splitRatioPoints_; }; sptr displayGroupInfo_; mutable std::map limitRectMap_; @@ -119,6 +123,7 @@ protected: Rect displayGroupLimitRect_; bool isMultiDisplay_ = false; FloatingWindowLimitsConfig floatingWindowLimitsConfig_; + SplitRatioConfig splitRatioConfig_; }; } } diff --git a/wmserver/include/window_layout_policy_cascade.h b/wmserver/include/window_layout_policy_cascade.h index cc89f440..45a5f47b 100644 --- a/wmserver/include/window_layout_policy_cascade.h +++ b/wmserver/include/window_layout_policy_cascade.h @@ -42,13 +42,16 @@ public: void SetSplitDividerWindowRects(std::map dividerWindowRects) override; void RemoveWindowNode(const sptr& node) override; Rect GetInitalDividerRect(DisplayId displayId) const override; + std::vector GetExitSplitPoints(DisplayId displayId) const override; private: void InitAllRects(); void InitSplitRects(DisplayId displayId); - void SetSplitRectByRatio(float ratio, DisplayId displayId); + int32_t GetSplitRatioPoint(float ratio, DisplayId displayId); void SetSplitRect(const Rect& rect, DisplayId displayId); void UpdateSplitLimitRect(const Rect& limitRect, Rect& limitSplitRect); + void UpdateSplitRatioPoints(DisplayId displayId); + void UpdateDockSlicePosition(DisplayId displayId, int32_t& origin) const; void LayoutWindowNode(const sptr& node) override; void LayoutWindowTree(DisplayId displayId) override; void InitLimitRects(DisplayId displayId); diff --git a/wmserver/include/window_manager_service.h b/wmserver/include/window_manager_service.h index d0448d09..26051654 100644 --- a/wmserver/include/window_manager_service.h +++ b/wmserver/include/window_manager_service.h @@ -109,6 +109,7 @@ private: void NotifyDisplayStateChange(DisplayId id, DisplayStateChangeType type); WMError GetFocusWindowInfo(sptr& abilityToken); void ConfigureWindowManagerService(); + void ConfigFloatWindowLimits(); static inline SingletonDelegator delegator; sptr windowRoot_; diff --git a/wmserver/include/window_node_container.h b/wmserver/include/window_node_container.h index b4b7901c..54417e7b 100644 --- a/wmserver/include/window_node_container.h +++ b/wmserver/include/window_node_container.h @@ -65,6 +65,8 @@ public: void NotifyAccessibilityWindowInfo(const sptr& windowId, WindowUpdateType type) const; int GetWindowCountByType(WindowType windowType); bool IsForbidDockSliceMove(DisplayId displayId) const; + bool IsDockSliceInExitSplitModeArea(DisplayId displayId) const; + void ExitSplitMode(DisplayId displayId); void OnAvoidAreaChange(const std::vector& avoidAreas, DisplayId displayId); bool isVerticalDisplay(DisplayId displayId) const; diff --git a/wmserver/include/window_pair.h b/wmserver/include/window_pair.h index f61a314b..22311203 100644 --- a/wmserver/include/window_pair.h +++ b/wmserver/include/window_pair.h @@ -160,6 +160,17 @@ public: */ bool IsForbidDockSliceMove() const; + /** + * when dock slice in exit split screen mode area, + * exit split screen mode. + */ + void ExitSplitMode(); + + /** + * whether dock slice in exit split screen mode area + */ + bool IsDockSliceInExitSplitModeArea(const std::vector& exitSplitPoints); + /** * Set all app windows are restoring. * diff --git a/wmserver/include/window_root.h b/wmserver/include/window_root.h index 5c73eda8..cea1d329 100644 --- a/wmserver/include/window_root.h +++ b/wmserver/include/window_root.h @@ -49,6 +49,8 @@ public: WMError UpdateWindowNode(uint32_t windowId, WindowUpdateReason reason); bool isVerticalDisplay(sptr& node) const; bool IsForbidDockSliceMove(DisplayId displayId) const; + bool IsDockSliceInExitSplitModeArea(DisplayId displayId) const; + void ExitSplitMode(DisplayId displayId); WMError RequestFocus(uint32_t windowId); WMError RequestActiveWindow(uint32_t windowId); @@ -86,6 +88,8 @@ public: sptr GetWindowForDumpAceHelpInfo() const; void DestroyLeakStartingWindow(); void SetFloatingWindowLimitsConfig(const FloatingWindowLimitsConfig& floatingWindowLimitsConfig); + void SetSplitRatios(const std::vector& splitRatioNumbers); + void SetExitSplitRatio(float exitSplitRatio); private: void OnRemoteDied(const sptr& remoteObject); WMError DestroyWindowInner(sptr& node); @@ -119,6 +123,7 @@ private: Callback callback_; int maxAppWindowNumber_ = 100; FloatingWindowLimitsConfig floatingWindowLimitsConfig_; + SplitRatioConfig splitRatioConfig_ = {0.1, {}}; }; } } diff --git a/wmserver/src/window_controller.cpp b/wmserver/src/window_controller.cpp index abe759ca..e582997f 100644 --- a/wmserver/src/window_controller.cpp +++ b/wmserver/src/window_controller.cpp @@ -616,6 +616,20 @@ WMError WindowController::ProcessPointUp(uint32_t windowId) WLOGFW("could not find window"); return WMError::WM_ERROR_NULLPTR; } + if (node->GetWindowType() == WindowType::WINDOW_TYPE_DOCK_SLICE) { + DisplayId displayId = node->GetDisplayId(); + if (windowRoot_->IsDockSliceInExitSplitModeArea(displayId)) { + windowRoot_->ExitSplitMode(displayId); + } else { + auto property = node->GetWindowProperty(); + node->SetWindowSizeChangeReason(WindowSizeChangeReason::DRAG_END); + property->SetRequestRect(property->GetWindowRect()); + WMError res = windowRoot_->UpdateWindowNode(windowId, WindowUpdateReason::UPDATE_RECT); + if (res == WMError::WM_OK) { + FlushWindowInfo(windowId); + } + } + } WMError res = windowRoot_->UpdateSizeChangeReason(windowId, WindowSizeChangeReason::DRAG_END); if (res != WMError::WM_OK) { return res; diff --git a/wmserver/src/window_layout_policy.cpp b/wmserver/src/window_layout_policy.cpp index e12c6c4d..9f154b3a 100644 --- a/wmserver/src/window_layout_policy.cpp +++ b/wmserver/src/window_layout_policy.cpp @@ -47,6 +47,11 @@ void WindowLayoutPolicy::Reorder() WLOGFI("WindowLayoutPolicy::Reorder"); } +std::vector WindowLayoutPolicy::GetExitSplitPoints(DisplayId displayId) const +{ + return {}; +} + void WindowLayoutPolicy::LimitWindowToBottomRightCorner(const sptr& node) { Rect windowRect = node->GetRequestRect(); @@ -342,7 +347,8 @@ void WindowLayoutPolicy::UpdateClientRectAndResetReason(const sptr& "%{public}u", node->GetWindowId(), winRect.posX_, winRect.posY_, winRect.width_, winRect.height_, reason); node->GetWindowToken()->UpdateWindowRect(winRect, node->GetDecoStatus(), reason); } - if (reason == WindowSizeChangeReason::DRAG || reason == WindowSizeChangeReason::DRAG_END) { + if ((reason == WindowSizeChangeReason::DRAG || reason == WindowSizeChangeReason::DRAG_END) && + (node->GetWindowType() != WindowType::WINDOW_TYPE_DOCK_SLICE)) { node->ResetWindowSizeChangeReason(); } } @@ -968,6 +974,11 @@ Rect WindowLayoutPolicy::GetDisplayGroupRect() const return displayGroupRect_; } +void WindowLayoutPolicy::SetSplitRatioConfig(SplitRatioConfig splitRatioConfig) +{ + splitRatioConfig_ = splitRatioConfig; +} + void WindowLayoutPolicy::SetFloatingWindowLimitsConfig(const FloatingWindowLimitsConfig& floatingWindowLimitsConfig) { floatingWindowLimitsConfig_ = floatingWindowLimitsConfig; diff --git a/wmserver/src/window_layout_policy_cascade.cpp b/wmserver/src/window_layout_policy_cascade.cpp index 64c9f5d5..dc1336ac 100644 --- a/wmserver/src/window_layout_policy_cascade.cpp +++ b/wmserver/src/window_layout_policy_cascade.cpp @@ -99,6 +99,7 @@ void WindowLayoutPolicyCascade::LayoutWindowNode(const sptr& node) UpdateLimitRect(node, limitRectMap_[displayId]); UpdateSplitLimitRect(limitRectMap_[displayId], primaryLimitRect); UpdateSplitLimitRect(limitRectMap_[displayId], secondaryLimitRect); + UpdateSplitRatioPoints(displayId); UpdateDisplayGroupLimitRect_(); WLOGFI("priLimitRect: %{public}d %{public}d %{public}u %{public}u, " \ "secLimitRect: %{public}d %{public}d %{public}u %{public}u", primaryLimitRect.posX_, @@ -134,6 +135,11 @@ void WindowLayoutPolicyCascade::RemoveWindowNode(const sptr& node) } } +std::vector WindowLayoutPolicyCascade::GetExitSplitPoints(DisplayId displayId) const +{ + return cascadeRectsMap_[displayId].exitSplitPoints_; +} + void WindowLayoutPolicyCascade::UpdateWindowNode(const sptr& node, bool isAddWindow) { WM_FUNCTION_TRACE(); @@ -247,10 +253,16 @@ void WindowLayoutPolicyCascade::ApplyWindowRectConstraints(const sptrGetWindowType() == WindowType::WINDOW_TYPE_DOCK_SLICE) { // if divider, limit position - LimitMoveBounds(winRect, node->GetDisplayId()); + auto reason = node->GetWindowSizeChangeReason(); + if (node->GetWindowType() == WindowType::WINDOW_TYPE_DOCK_SLICE && + reason == WindowSizeChangeReason::DRAG_END) { + DisplayId displayId = node->GetDisplayId(); + if (!IsVerticalDisplay(displayId)) { + UpdateDockSlicePosition(displayId, winRect.posX_); + } else { + UpdateDockSlicePosition(displayId, winRect.posY_); + } } - LimitFloatingWindowSize(node, displayGroupInfo_->GetDisplayRect(node->GetDisplayId()), winRect); LimitMainFloatingWindowPosition(node, winRect); @@ -309,6 +321,7 @@ void WindowLayoutPolicyCascade::InitLimitRects(DisplayId displayId) limitRectMap_[displayId] = displayGroupInfo_->GetDisplayRect(displayId); cascadeRectsMap_[displayId].primaryLimitRect_ = cascadeRectsMap_[displayId].primaryRect_; cascadeRectsMap_[displayId].secondaryLimitRect_ = cascadeRectsMap_[displayId].secondaryRect_; + UpdateSplitRatioPoints(displayId); } Rect WindowLayoutPolicyCascade::GetLimitRect(const WindowMode mode, DisplayId displayId) const @@ -333,6 +346,36 @@ Rect WindowLayoutPolicyCascade::GetDisplayRect(const WindowMode mode, DisplayId } } +void WindowLayoutPolicyCascade::UpdateSplitRatioPoints(DisplayId displayId) +{ + LayoutRects& cascadeRects = cascadeRectsMap_[displayId]; + cascadeRects.exitSplitPoints_.clear(); + cascadeRects.splitRatioPoints_.clear(); + cascadeRects.exitSplitPoints_.push_back(GetSplitRatioPoint(splitRatioConfig_.exitSplitRatio, displayId)); + cascadeRects.exitSplitPoints_.push_back(GetSplitRatioPoint(1 - splitRatioConfig_.exitSplitRatio, displayId)); + for (const auto& ratio : splitRatioConfig_.splitRatios) { + cascadeRects.splitRatioPoints_.push_back(GetSplitRatioPoint(ratio, displayId)); + } +} + +void WindowLayoutPolicyCascade::UpdateDockSlicePosition(DisplayId displayId, int32_t& origin) const +{ + const LayoutRects& cascadeRects = cascadeRectsMap_[displayId]; + if (cascadeRects.splitRatioPoints_.size() == 0) { + return; + } + uint32_t minDiff = std::max(limitRectMap_[displayId].width_, limitRectMap_[displayId].height_); + int32_t closestPoint = origin; + for (const auto& elem : cascadeRects.splitRatioPoints_) { + uint32_t diff = (origin > elem) ? (origin - elem) : (elem - origin); + if (diff < minDiff) { + closestPoint = elem; + minDiff = diff; + } + } + origin = closestPoint; +} + void WindowLayoutPolicyCascade::UpdateSplitLimitRect(const Rect& limitRect, Rect& limitSplitRect) { Rect curLimitRect = limitSplitRect; @@ -364,20 +407,17 @@ void WindowLayoutPolicyCascade::InitSplitRects(DisplayId displayId) SetSplitRect(dividerRect, displayId); } -void WindowLayoutPolicyCascade::SetSplitRectByRatio(float ratio, DisplayId displayId) +int32_t WindowLayoutPolicyCascade::GetSplitRatioPoint(float ratio, DisplayId displayId) { - auto& dividerRect = cascadeRectsMap_[displayId].dividerRect_; - const Rect& limitRect = limitRectMap_[displayId]; + const auto& dividerRect = cascadeRectsMap_[displayId].dividerRect_; + const auto& limitRect = limitRectMap_[displayId]; if (!IsVerticalDisplay(displayId)) { - dividerRect.posX_ = limitRect.posX_ + + return limitRect.posX_ + static_cast((limitRect.width_ - dividerRect.width_) * ratio); } else { - dividerRect.posY_ = limitRect.posY_ + + return limitRect.posY_ + static_cast((limitRect.height_ - dividerRect.height_) * ratio); } - WLOGFI("set dividerRect :[%{public}d, %{public}d, %{public}u, %{public}u]", - dividerRect.posX_, dividerRect.posY_, dividerRect.width_, dividerRect.height_); - SetSplitRect(dividerRect, displayId); } void WindowLayoutPolicyCascade::SetSplitRect(const Rect& divRect, DisplayId displayId) diff --git a/wmserver/src/window_manager_config.cpp b/wmserver/src/window_manager_config.cpp index bcf4cdb5..15f23b3b 100644 --- a/wmserver/src/window_manager_config.cpp +++ b/wmserver/src/window_manager_config.cpp @@ -64,7 +64,9 @@ bool WindowManagerConfig::LoadConfigXml(const std::string& configFilePath) continue; } - if (!xmlStrcmp(nodeName, reinterpret_cast("floatingWindowLimitRatio"))) { + if (!xmlStrcmp(nodeName, reinterpret_cast("floatingWindowLimitRatio")) || + !xmlStrcmp(nodeName, reinterpret_cast("splitRatios")) || + !xmlStrcmp(nodeName, reinterpret_cast("exitSplitRatio"))) { ReadFloatNumbersConfigInfo(curNodePtr); continue; } diff --git a/wmserver/src/window_manager_service.cpp b/wmserver/src/window_manager_service.cpp index 5187e6d4..fb0c569b 100644 --- a/wmserver/src/window_manager_service.cpp +++ b/wmserver/src/window_manager_service.cpp @@ -192,6 +192,33 @@ int WindowManagerService::Dump(int fd, const std::vector& args) }).get(); } +void WindowManagerService::ConfigFloatWindowLimits() +{ + const auto& intNumbersConfig = WindowManagerConfig::GetIntNumbersConfig(); + const auto& floatNumbersConfig = WindowManagerConfig::GetFloatNumbersConfig(); + + FloatingWindowLimitsConfig floatingWindowLimitsConfig; + if (intNumbersConfig.count("floatingWindowLimitSize") != 0) { + auto numbers = intNumbersConfig.at("floatingWindowLimitSize"); + if (numbers.size() == 4) { // 4, limitSize + floatingWindowLimitsConfig.maxWidth_ = static_cast(numbers[0]); // 0 max width + floatingWindowLimitsConfig.maxHeight_ = static_cast(numbers[1]); // 1 max height + floatingWindowLimitsConfig.minWidth_ = static_cast(numbers[2]); // 2 min width + floatingWindowLimitsConfig.minHeight_ = static_cast(numbers[3]); // 3 min height + floatingWindowLimitsConfig.isFloatingWindowLimitsConfigured_ = true; + } + } + if (floatNumbersConfig.count("floatingWindowLimitRatio") != 0) { + auto numbers = floatNumbersConfig.at("floatingWindowLimitRatio"); + if (numbers.size() == 2) { // 2, limitRatio + floatingWindowLimitsConfig.maxRatio_ = static_cast(numbers[0]); // 0 max ratio + floatingWindowLimitsConfig.minRatio_ = static_cast(numbers[1]); // 1 min ratio + floatingWindowLimitsConfig.isFloatingWindowLimitsConfigured_ = true; + } + } + windowRoot_->SetFloatingWindowLimitsConfig(floatingWindowLimitsConfig); +} + void WindowManagerService::ConfigureWindowManagerService() { const auto& enableConfig = WindowManagerConfig::GetEnableConfig(); @@ -227,29 +254,18 @@ void WindowManagerService::ConfigureWindowManagerService() } } - FloatingWindowLimitsConfig floatingWindowLimitsConfig; + ConfigFloatWindowLimits(); - if (intNumbersConfig.count("floatingWindowLimitSize") != 0) { - auto numbers = intNumbersConfig.at("floatingWindowLimitSize"); - if (numbers.size() == 4) { // 4, limitSize - floatingWindowLimitsConfig.maxWidth_ = static_cast(numbers[0]); // 0 max width - floatingWindowLimitsConfig.maxHeight_ = static_cast(numbers[1]); // 1 max height - floatingWindowLimitsConfig.minWidth_ = static_cast(numbers[2]); // 2 min width - floatingWindowLimitsConfig.minHeight_ = static_cast(numbers[3]); // 3 min height - floatingWindowLimitsConfig.isFloatingWindowLimitsConfigured_ = true; - } + if (floatNumbersConfig.count("splitRatios") != 0) { + windowRoot_->SetSplitRatios(floatNumbersConfig.at("splitRatios")); } - if (floatNumbersConfig.count("floatingWindowLimitRatio") != 0) { - auto numbers = floatNumbersConfig.at("floatingWindowLimitRatio"); - if (numbers.size() == 2) { // 2, limitRatio - floatingWindowLimitsConfig.maxRatio_ = static_cast(numbers[0]); // 0 max ratio - floatingWindowLimitsConfig.minRatio_ = static_cast(numbers[1]); // 1 min ratio - floatingWindowLimitsConfig.isFloatingWindowLimitsConfigured_ = true; + if (floatNumbersConfig.count("exitSplitRatio") != 0) { + auto numbers = floatNumbersConfig.at("exitSplitRatio"); + if ((numbers.size() == 1) && numbers[0] > 0 && numbers[0] < 0.5) { // valid range (0, 0.5) + windowRoot_->SetExitSplitRatio(numbers[0]); } } - - windowRoot_->SetFloatingWindowLimitsConfig(floatingWindowLimitsConfig); } void WindowManagerService::OnStop() diff --git a/wmserver/src/window_node_container.cpp b/wmserver/src/window_node_container.cpp index 09bf31a9..9acee352 100644 --- a/wmserver/src/window_node_container.cpp +++ b/wmserver/src/window_node_container.cpp @@ -42,6 +42,7 @@ namespace { const char DISABLE_WINDOW_ANIMATION_PATH[] = "/etc/disable_window_animation"; constexpr uint32_t MAX_BRIGHTNESS = 255; constexpr uint32_t SPLIT_WINDOWS_CNT = 2; + constexpr uint32_t EXIT_SPLIT_POINTS_NUMBER = 2; } WindowNodeContainer::WindowNodeContainer(const sptr& displayInfo, ScreenId displayGroupId) @@ -1289,6 +1290,30 @@ bool WindowNodeContainer::IsForbidDockSliceMove(DisplayId displayId) const return false; } +bool WindowNodeContainer::IsDockSliceInExitSplitModeArea(DisplayId displayId) const +{ + auto windowPair = displayGroupController_->GetWindowPairByDisplayId(displayId); + if (windowPair == nullptr) { + WLOGFE("window pair is nullptr"); + return false; + } + std::vector exitSplitPoints = layoutPolicy_->GetExitSplitPoints(displayId); + if (exitSplitPoints.size() != EXIT_SPLIT_POINTS_NUMBER) { + return false; + } + return windowPair->IsDockSliceInExitSplitModeArea(exitSplitPoints); +} + +void WindowNodeContainer::ExitSplitMode(DisplayId displayId) +{ + auto windowPair = displayGroupController_->GetWindowPairByDisplayId(displayId); + if (windowPair == nullptr) { + WLOGFE("window pair is nullptr"); + return; + } + windowPair->ExitSplitMode(); +} + void WindowNodeContainer::MinimizeAllAppWindows(DisplayId displayId) { WMError ret = MinimizeAppNodeExceptOptions(MinimizeReason::MINIMIZE_ALL); diff --git a/wmserver/src/window_pair.cpp b/wmserver/src/window_pair.cpp index 61000e6d..c6a45cb8 100644 --- a/wmserver/src/window_pair.cpp +++ b/wmserver/src/window_pair.cpp @@ -149,6 +149,49 @@ bool WindowPair::IsForbidDockSliceMove() const return true; } +bool WindowPair::IsDockSliceInExitSplitModeArea(const std::vector& exitSplitPoints) +{ + if (!IsPaired()) { + return false; + } + int32_t dividerOrigin; + Rect rect = divider_->GetWindowRect(); + if (rect.width_ < rect.height_) { + dividerOrigin = rect.posX_; + } else { + dividerOrigin = rect.posY_; // vertical display + } + if (dividerOrigin < exitSplitPoints[0] || dividerOrigin > exitSplitPoints[1]) { + return true; + } + return false; +} + +void WindowPair::ExitSplitMode() +{ + if (!IsPaired()) { + return; + } + Rect dividerRect = divider_->GetWindowRect(); + sptr hideWindow, fullScreenWindow; + bool isVertical = (dividerRect.height_ < dividerRect.width_) ? true : false; + if ((isVertical && (primary_->GetWindowRect().height_ < secondary_->GetWindowRect().height_)) || + (!isVertical && (primary_->GetWindowRect().width_ < secondary_->GetWindowRect().width_))) { + hideWindow = primary_; + fullScreenWindow = secondary_; + } else { + hideWindow = secondary_; + fullScreenWindow = primary_; + } + if (WindowHelper::IsWindowModeSupported(fullScreenWindow->GetModeSupportInfo(), + WindowMode::WINDOW_MODE_FULLSCREEN)) { + fullScreenWindow->GetWindowProperty()->SetLastWindowMode(WindowMode::WINDOW_MODE_FULLSCREEN); + } + MinimizeApp::AddNeedMinimizeApp(hideWindow, MinimizeReason::SPLIT_QUIT); + MinimizeApp::ExecuteMinimizeTargetReason(MinimizeReason::SPLIT_QUIT); + WLOGFI("Exit Split Mode, Minimize Window %{public}u", hideWindow->GetWindowId()); +} + void WindowPair::Clear() { WLOGI("Clear window pair."); diff --git a/wmserver/src/window_root.cpp b/wmserver/src/window_root.cpp index 9b223c61..ba2d9ced 100644 --- a/wmserver/src/window_root.cpp +++ b/wmserver/src/window_root.cpp @@ -102,6 +102,7 @@ sptr WindowRoot::CreateWindowNodeContainer(DisplayId displa return nullptr; } container->GetLayoutPolicy()->SetFloatingWindowLimitsConfig(floatingWindowLimitsConfig_); + container->GetLayoutPolicy()->SetSplitRatioConfig(splitRatioConfig_); return container; } @@ -247,6 +248,26 @@ bool WindowRoot::IsForbidDockSliceMove(DisplayId displayId) const return container->IsForbidDockSliceMove(displayId); } +bool WindowRoot::IsDockSliceInExitSplitModeArea(DisplayId displayId) const +{ + auto container = const_cast(this)->GetOrCreateWindowNodeContainer(displayId); + if (container == nullptr) { + WLOGFE("can't find container"); + return false; + } + return container->IsDockSliceInExitSplitModeArea(displayId); +} + +void WindowRoot::ExitSplitMode(DisplayId displayId) +{ + auto container = GetOrCreateWindowNodeContainer(displayId); + if (container == nullptr) { + WLOGFE("can't find container"); + return; + } + container->ExitSplitMode(displayId); +} + std::vector WindowRoot::GetAvoidAreaByType(uint32_t windowId, AvoidAreaType avoidAreaType) { std::vector avoidArea; @@ -1155,6 +1176,28 @@ void WindowRoot::SetMaxAppWindowNumber(int windowNum) maxAppWindowNumber_ = windowNum; } +void WindowRoot::SetSplitRatios(const std::vector& splitRatioNumbers) +{ + auto& splitRatios = splitRatioConfig_.splitRatios; + splitRatios.clear(); + splitRatios = splitRatioNumbers; + for (auto iter = splitRatios.begin(); iter != splitRatios.end();) { + if (*iter > 0 && *iter < 1) { // valid ratio range (0, 1) + iter++; + } else { + iter = splitRatios.erase(iter); + } + } + std::sort(splitRatios.begin(), splitRatios.end()); + auto iter = std::unique(splitRatios.begin(), splitRatios.end()); + splitRatios.erase(iter, splitRatios.end()); // remove duplitcate ratios +} + +void WindowRoot::SetExitSplitRatio(float exitSplitRatio) +{ + splitRatioConfig_.exitSplitRatio = exitSplitRatio; +} + WMError WindowRoot::GetModeChangeHotZones(DisplayId displayId, ModeChangeHotZones& hotZones, const ModeChangeHotZonesConfig& config) {