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)
{