diff --git a/dmserver/include/display_manager_config.h b/dmserver/include/display_manager_config.h index fdb11dee5362675cfa79e85bb5cc8f8dadf0966b..55217c0e165a0e0f19afcd9a3c43807ddc044cc9 100644 --- a/dmserver/include/display_manager_config.h +++ b/dmserver/include/display_manager_config.h @@ -31,14 +31,14 @@ public: ~DisplayManagerConfig() = default; static bool LoadConfigXml(const std::string& configFilePath); - static const std::map>& GetNumbersConfig(); + static const std::map>& GetIntNumbersConfig(); static void DumpConfig(); private: - static std::map> numbersConfig_; + static std::map> intNumbersConfig_; static bool IsValidNode(const xmlNode& currNode); - static void ReadNumbersConfigInfo(const xmlNodePtr& currNode); + static void ReadIntNumbersConfigInfo(const xmlNodePtr& currNode); static std::vector Split(std::string str, std::string pattern); static inline bool IsNumber(std::string str); diff --git a/dmserver/src/display_manager_config.cpp b/dmserver/src/display_manager_config.cpp index 28fb3fc5cf4a3574b29aa6368597fe92018e0a30..d31756158a911af7eae71da0125eb4d256458f3e 100644 --- a/dmserver/src/display_manager_config.cpp +++ b/dmserver/src/display_manager_config.cpp @@ -22,7 +22,7 @@ namespace { constexpr HiviewDFX::HiLogLabel LABEL = {LOG_CORE, HILOG_DOMAIN_WINDOW, "DisplayManagerConfig"}; } -std::map> DisplayManagerConfig::numbersConfig_; +std::map> DisplayManagerConfig::intNumbersConfig_; std::vector DisplayManagerConfig::Split(std::string str, std::string pattern) { @@ -76,7 +76,7 @@ bool DisplayManagerConfig::LoadConfigXml(const std::string& configFilePath) auto nodeName = curNodePtr->name; if (!xmlStrcmp(nodeName, reinterpret_cast("dpi"))) { - ReadNumbersConfigInfo(curNodePtr); + ReadIntNumbersConfigInfo(curNodePtr); continue; } } @@ -92,7 +92,7 @@ bool DisplayManagerConfig::IsValidNode(const xmlNode& currNode) return true; } -void DisplayManagerConfig::ReadNumbersConfigInfo(const xmlNodePtr& currNode) +void DisplayManagerConfig::ReadIntNumbersConfigInfo(const xmlNodePtr& currNode) { xmlChar* context = xmlNodeGetContent(currNode); if (context == nullptr) { @@ -113,18 +113,18 @@ void DisplayManagerConfig::ReadNumbersConfigInfo(const xmlNodePtr& currNode) } std::string nodeName = reinterpret_cast(currNode->name); - numbersConfig_[nodeName] = numbersVec; + intNumbersConfig_[nodeName] = numbersVec; xmlFree(context); } -const std::map>& DisplayManagerConfig::GetNumbersConfig() +const std::map>& DisplayManagerConfig::GetIntNumbersConfig() { - return numbersConfig_; + return intNumbersConfig_; } void DisplayManagerConfig::DumpConfig() { - for (auto& numbers : numbersConfig_) { + for (auto& numbers : intNumbersConfig_) { WLOGFI("[DmConfig] Numbers: %{public}s %{public}zu", numbers.first.c_str(), numbers.second.size()); for (auto& num : numbers.second) { WLOGFI("[DmConfig] Num: %{public}d", num); diff --git a/dmserver/src/display_manager_service.cpp b/dmserver/src/display_manager_service.cpp index 36d17c237a9af47fada5fa2de4702a5323d49a4a..354e96c9caf9ae5c72c28fe709858a8ccfd1744f 100644 --- a/dmserver/src/display_manager_service.cpp +++ b/dmserver/src/display_manager_service.cpp @@ -80,7 +80,7 @@ bool DisplayManagerService::Init() void DisplayManagerService::ConfigureDisplayManagerService() { - auto numbersConfig = DisplayManagerConfig::GetNumbersConfig(); + auto numbersConfig = DisplayManagerConfig::GetIntNumbersConfig(); if (numbersConfig.count("dpi") != 0) { uint32_t densityDpi = static_cast(numbersConfig["dpi"][0]); if (densityDpi == 0) { diff --git a/utils/include/window_helper.h b/utils/include/window_helper.h index e91b446b25e5dff4fc1ec47bcbefa7146f56c3a3..21515367b14df9c6655fbc38d409cca3f7d0768e 100644 --- a/utils/include/window_helper.h +++ b/utils/include/window_helper.h @@ -171,43 +171,6 @@ public: return dstRect; } - static Rect GetFixedWindowRectByLimitPosition(const Rect& oriDstRect, const Rect& lastRect, - float virtualPixelRatio, const Rect& displayLimitRect) - { - Rect dstRect = oriDstRect; - uint32_t windowTitleBarH = static_cast(WINDOW_TITLE_BAR_HEIGHT * virtualPixelRatio); - // minimum (x + width) - if (dstRect.posX_ < (displayLimitRect.posX_ + static_cast(windowTitleBarH - oriDstRect.width_))) { - if (oriDstRect.width_ != lastRect.width_) { - dstRect.width_ = static_cast(displayLimitRect.posX_ - oriDstRect.posX_) + windowTitleBarH; - } - } - // maximum position x - if (dstRect.posX_ > (displayLimitRect.posX_ + - static_cast(displayLimitRect.width_ - windowTitleBarH))) { - dstRect.posX_ = displayLimitRect.posX_ + static_cast(displayLimitRect.width_ - windowTitleBarH); - if (oriDstRect.width_ != lastRect.width_) { - dstRect.width_ = lastRect.width_; - } - } - // minimum position y - if (oriDstRect.posY_ < displayLimitRect.posY_) { - dstRect.posY_ = displayLimitRect.posY_; - if (oriDstRect.height_ != lastRect.height_) { - dstRect.height_ = lastRect.height_; - } - } - // maximum position y - if (dstRect.posY_ > (displayLimitRect.posY_ + - static_cast(displayLimitRect.height_ - windowTitleBarH))) { - dstRect.posY_ = displayLimitRect.posY_ + static_cast(displayLimitRect.height_ - windowTitleBarH); - if (oriDstRect.height_ != lastRect.height_) { - dstRect.height_ = lastRect.height_; - } - } - return dstRect; - } - static bool IsPointInTargetRect(int32_t pointPosX, int32_t pointPosY, const Rect& targetRect) { if ((pointPosX > targetRect.posX_) && @@ -265,6 +228,17 @@ public: return true; } + static inline bool IsFloatingNumber(std::string str) + { + for (int32_t i = 0; i < static_cast(str.size()); i++) { + if ((str.at(i) < '0' || str.at(i) > '9') && + (str.at(i) != '.' || std::count(str.begin(), str.end(), '.') > 1)) { + return false; + } + } + return true; + } + static std::vector Split(std::string str, std::string pattern) { int32_t position; diff --git a/utils/include/window_property.h b/utils/include/window_property.h index 6580330c085ca0f539fac04618152e48c328d3b4..9683d9a21afedd0199f27927a5e7aa2153962065 100644 --- a/utils/include/window_property.h +++ b/utils/include/window_property.h @@ -24,6 +24,7 @@ #include "class_var_definition.h" #include "dm_common.h" #include "wm_common.h" +#include "wm_common_inner.h" namespace OHOS { namespace Rosen { @@ -67,6 +68,7 @@ public: void SetWindowSizeChangeReason(WindowSizeChangeReason reason); void SetTokenState(bool hasToken); void SetModeSupportInfo(uint32_t modeSupportInfo); + void SetDragType(DragType dragType); WindowSizeChangeReason GetWindowSizeChangeReason() const; const std::string& GetWindowName() const; @@ -98,6 +100,7 @@ public: const PointInfo& GetHitOffset() const; uint32_t GetAnimationFlag() const; uint32_t GetModeSupportInfo() const; + DragType GetDragType() const; virtual bool Marshalling(Parcel& parcel) const override; static WindowProperty* Unmarshalling(Parcel& parcel); @@ -137,6 +140,7 @@ private: { WindowType::WINDOW_TYPE_NAVIGATION_BAR, SystemBarProperty() }, }; bool isDecorEnable_ { false }; + DragType dragType_ = DragType::DRAG_UNDEFINED; DEFINE_VAR_DEFAULT_FUNC_GET_SET(Orientation, RequestedOrientation, requestedOrientation, Orientation::UNSPECIFIED); }; } diff --git a/utils/include/wm_common_inner.h b/utils/include/wm_common_inner.h index 83b6f223a978acb5102d39103214c6dbcac747d2..ed7ea9b0be4374a33d59ccc4d3dc08e29f520029 100644 --- a/utils/include/wm_common_inner.h +++ b/utils/include/wm_common_inner.h @@ -85,12 +85,31 @@ struct ModeChangeHotZonesConfig { uint32_t secondaryRange_; }; +struct FloatingWindowLimitsConfig { + bool isFloatingWindowLimitsConfigured_; + uint32_t maxWidth_; + uint32_t maxHeight_; + uint32_t minWidth_; + uint32_t minHeight_; + float maxRatio_; + float minRatio_; + FloatingWindowLimitsConfig() : isFloatingWindowLimitsConfigured_(false), maxWidth_(0), maxHeight_(0), minWidth_(0), + minHeight_(0), maxRatio_(0.0f), minRatio_(0.0f) {} +}; + struct ModeChangeHotZones { Rect fullscreen_; Rect primary_; Rect secondary_; }; +enum class DragType : uint32_t { + DRAG_UNDEFINED, + DRAG_WIDTH, + DRAG_HEIGHT, + DRAG_CORNER, +}; + namespace { constexpr float DEFAULT_SPLIT_RATIO = 0.5; constexpr float DEFAULT_ASPECT_RATIO = 0.66; diff --git a/utils/src/window_property.cpp b/utils/src/window_property.cpp index 7c2b13442c819aa8597ddf4bf3fb2719f34a2f38..59d7360de417f17dd5ee44c63cb7b33290593be9 100644 --- a/utils/src/window_property.cpp +++ b/utils/src/window_property.cpp @@ -165,6 +165,11 @@ void WindowProperty::SetWindowSizeChangeReason(WindowSizeChangeReason reason) windowSizeChangeReason_ = reason; } +void WindowProperty::SetDragType(DragType dragType) +{ + dragType_ = dragType; +} + WindowSizeChangeReason WindowProperty::GetWindowSizeChangeReason() const { return windowSizeChangeReason_; @@ -335,6 +340,11 @@ bool WindowProperty::GetTokenState() const return tokenState_; } +DragType WindowProperty::GetDragType() const +{ + return dragType_; +} + bool WindowProperty::MapMarshalling(Parcel& parcel) const { auto size = sysBarPropMap_.size(); @@ -384,7 +394,7 @@ bool WindowProperty::Marshalling(Parcel& parcel) const parcel.WriteUint32(static_cast(windowSizeChangeReason_)) && parcel.WriteBool(tokenState_) && parcel.WriteUint32(callingWindow_) && parcel.WriteUint32(static_cast(requestedOrientation_)) && parcel.WriteBool(turnScreenOn_) && parcel.WriteBool(keepScreenOn_) && - parcel.WriteUint32(modeSupportInfo_); + parcel.WriteUint32(modeSupportInfo_) && parcel.WriteUint32(static_cast(dragType_)); } WindowProperty* WindowProperty::Unmarshalling(Parcel& parcel) @@ -426,6 +436,7 @@ WindowProperty* WindowProperty::Unmarshalling(Parcel& parcel) property->SetTurnScreenOn(parcel.ReadBool()); property->SetKeepScreenOn(parcel.ReadBool()); property->SetModeSupportInfo(parcel.ReadUint32()); + property->SetDragType(static_cast(parcel.ReadUint32())); return property; } @@ -461,6 +472,7 @@ void WindowProperty::CopyFrom(const sptr& property) turnScreenOn_ = property->turnScreenOn_; keepScreenOn_ = property->keepScreenOn_; modeSupportInfo_ = property->modeSupportInfo_; + dragType_ = property->dragType_; } } } diff --git a/wm/include/window_impl.h b/wm/include/window_impl.h index bd264bfc5943867beb877e7c5e999655de39f29d..45803d60290de8ebd50d5a078cbfb6677c5f5385 100644 --- a/wm/include/window_impl.h +++ b/wm/include/window_impl.h @@ -276,6 +276,7 @@ private: void HandleModeChangeHotZones(int32_t posX, int32_t posY); WMError NotifyWindowTransition(TransitionReason reason); void UpdatePointerEventForStretchableWindow(std::shared_ptr& pointerEvent); + void UpdateDragType(); // colorspace, gamut using ColorSpaceConvertMap = struct { @@ -321,6 +322,7 @@ private: Rect startPointRect_ = { 0, 0, 0, 0 }; Rect startRectExceptFrame_ = { 0, 0, 0, 0 }; Rect startRectExceptCorner_ = { 0, 0, 0, 0 }; + DragType dragType_ = DragType::DRAG_UNDEFINED; Rect originRect_ = {0, 0, 0, 0}; bool isAppDecorEnbale_ = true; SystemConfig windowSystemConfig_ ; diff --git a/wm/src/window_impl.cpp b/wm/src/window_impl.cpp index dd1ea579e67dcc3521ebe118cbdb885f970af1f8..d66cab823d072e6481b913d40c6a7709a8f8711c 100644 --- a/wm/src/window_impl.cpp +++ b/wm/src/window_impl.cpp @@ -1059,6 +1059,7 @@ WMError WindowImpl::Drag(const Rect& rect) Rect requestRect = rect; property_->SetRequestRect(requestRect); property_->SetWindowSizeChangeReason(WindowSizeChangeReason::DRAG); + property_->SetDragType(dragType_); return UpdateProperty(PropertyChangeAction::ACTION_UPDATE_RECT); } @@ -1636,6 +1637,23 @@ void WindowImpl::EndMoveOrDragWindow(int32_t posX, int32_t posY, int32_t pointId pointEventStarted_ = false; } +void WindowImpl::UpdateDragType() +{ + if (!startDragFlag_) { + dragType_ = DragType::DRAG_UNDEFINED; + return; + } + if (startPointPosX_ > startRectExceptCorner_.posX_ && + (startPointPosX_ < startRectExceptCorner_.posX_ + static_cast(startRectExceptCorner_.width_))) { + dragType_ = DragType::DRAG_HEIGHT; + } else if (startPointPosY_ > startRectExceptCorner_.posY_ && + (startPointPosY_ < startRectExceptCorner_.posY_ + static_cast(startRectExceptCorner_.height_))) { + dragType_ = DragType::DRAG_WIDTH; + } else { + dragType_ = DragType::DRAG_CORNER; + } +} + void WindowImpl::ReadyToMoveOrDragWindow(int32_t globalX, int32_t globalY, int32_t pointId, const Rect& rect) { if (pointEventStarted_) { @@ -1683,6 +1701,9 @@ void WindowImpl::ReadyToMoveOrDragWindow(int32_t globalX, int32_t globalY, int32 startDragFlag_ = true; SingletonContainer::Get().ProcessPointDown(property_->GetWindowId(), true); } + + UpdateDragType(); + return; } diff --git a/wm/test/systemtest/window_layout_test.cpp b/wm/test/systemtest/window_layout_test.cpp index 0737ac8d662deb69bcb067af120461212737aa1f..0e1ca1322620339db9e731530d22edf08e03d197 100644 --- a/wm/test/systemtest/window_layout_test.cpp +++ b/wm/test/systemtest/window_layout_test.cpp @@ -33,6 +33,8 @@ public: std::vector> activeWindows_; static vector fullScreenExpecteds_; static inline float virtualPixelRatio_ = 0.0; +private: + static constexpr uint32_t WAIT_SYANC_US = 100000; }; vector WindowLayoutTest::fullScreenExpecteds_; @@ -371,31 +373,34 @@ HWTEST_F(WindowLayoutTest, LayoutTile01, Function | MediumTest | Level3) utils::InitTileWindowRects(window); ASSERT_TRUE(utils::RectEqualTo(window, expect)); WindowManager::GetInstance().SetWindowLayoutMode(WindowLayoutMode::TILE); + usleep(WAIT_SYANC_US); ASSERT_TRUE(utils::RectEqualTo(window, utils::singleTileRect_)); info.name = "test1"; const sptr& test1 = utils::CreateTestWindow(info); activeWindows_.push_back(test1); ASSERT_EQ(WMError::WM_OK, test1->Show()); + usleep(WAIT_SYANC_US); ASSERT_TRUE(utils::RectEqualTo(window, utils::doubleTileRects_[0])); ASSERT_TRUE(utils::RectEqualTo(test1, utils::doubleTileRects_[1])); info.name = "test2"; const sptr& test2 = utils::CreateTestWindow(info); activeWindows_.push_back(test2); ASSERT_EQ(WMError::WM_OK, test2->Show()); + usleep(WAIT_SYANC_US); if (utils::isVerticalDisplay_) { ASSERT_TRUE(utils::RectEqualTo(test1, utils::doubleTileRects_[0])); ASSERT_TRUE(utils::RectEqualTo(test2, utils::doubleTileRects_[1])); WindowManager::GetInstance().SetWindowLayoutMode(WindowLayoutMode::CASCADE); return; - } else { - ASSERT_TRUE(utils::RectEqualTo(window, utils::tripleTileRects_[0])); - ASSERT_TRUE(utils::RectEqualTo(test1, utils::tripleTileRects_[1])); - ASSERT_TRUE(utils::RectEqualTo(test2, utils::tripleTileRects_[2])); // 2 is second rect idx } + ASSERT_TRUE(utils::RectEqualTo(window, utils::tripleTileRects_[0])); + ASSERT_TRUE(utils::RectEqualTo(test1, utils::tripleTileRects_[1])); + ASSERT_TRUE(utils::RectEqualTo(test2, utils::tripleTileRects_[2])); // 2 is second rect idx info.name = "test3"; const sptr& test3 = utils::CreateTestWindow(info); activeWindows_.push_back(test3); ASSERT_EQ(WMError::WM_OK, test3->Show()); + usleep(WAIT_SYANC_US); ASSERT_TRUE(utils::RectEqualTo(test1, utils::tripleTileRects_[0])); ASSERT_TRUE(utils::RectEqualTo(test2, utils::tripleTileRects_[1])); ASSERT_TRUE(utils::RectEqualTo(test3, utils::tripleTileRects_[2])); // 2 is second rect idx @@ -423,17 +428,20 @@ HWTEST_F(WindowLayoutTest, LayoutTileNegative01, Function | MediumTest | Level3) ASSERT_EQ(WMError::WM_OK, window->Show()); utils::InitTileWindowRects(window); WindowManager::GetInstance().SetWindowLayoutMode(WindowLayoutMode::TILE); + usleep(WAIT_SYANC_US); ASSERT_TRUE(utils::RectEqualTo(window, utils::singleTileRect_)); info.name = "test1"; const sptr& test1 = utils::CreateTestWindow(info); activeWindows_.push_back(test1); ASSERT_EQ(WMError::WM_OK, test1->Show()); + usleep(WAIT_SYANC_US); ASSERT_TRUE(utils::RectEqualTo(window, utils::doubleTileRects_[0])); ASSERT_TRUE(utils::RectEqualTo(test1, utils::doubleTileRects_[1])); info.name = "test2"; const sptr& test2 = utils::CreateTestWindow(info); activeWindows_.push_back(test2); ASSERT_EQ(WMError::WM_OK, test2->Show()); + usleep(WAIT_SYANC_US); if (utils::isVerticalDisplay_) { ASSERT_TRUE(utils::RectEqualTo(test1, utils::doubleTileRects_[0])); ASSERT_TRUE(utils::RectEqualTo(test2, utils::doubleTileRects_[1])); @@ -448,6 +456,7 @@ HWTEST_F(WindowLayoutTest, LayoutTileNegative01, Function | MediumTest | Level3) const sptr& test3 = utils::CreateTestWindow(info); activeWindows_.push_back(test3); ASSERT_EQ(WMError::WM_OK, test3->Show()); + usleep(WAIT_SYANC_US); ASSERT_TRUE(utils::RectEqualTo(test1, utils::tripleTileRects_[0])); ASSERT_TRUE(utils::RectEqualTo(test2, utils::tripleTileRects_[1])); ASSERT_TRUE(utils::RectEqualTo(test3, utils::tripleTileRects_[2])); // 2 is second rect idx @@ -474,6 +483,7 @@ HWTEST_F(WindowLayoutTest, LayoutNegative01, Function | MediumTest | Level3) activeWindows_.push_back(window); Rect expect = utils::GetDefaultFloatingRect(window); ASSERT_EQ(WMError::WM_OK, window->Show()); + usleep(WAIT_SYANC_US); ASSERT_TRUE(utils::RectEqualTo(window, expect)); } @@ -499,8 +509,10 @@ HWTEST_F(WindowLayoutTest, LayoutNegative02, Function | MediumTest | Level3) activeWindows_.push_back(window); Rect expect = utils::GetDefaultFloatingRect(window); ASSERT_EQ(WMError::WM_OK, window->Show()); + usleep(WAIT_SYANC_US); ASSERT_TRUE(utils::RectEqualTo(window, expect)); window->Resize(negativeW, negativeH); + usleep(WAIT_SYANC_US); Rect expect2 = {expect.posX_, expect.posY_, negativeW, negativeH}; expect2 = utils::CalcLimitedRect(expect2, virtualPixelRatio_); ASSERT_TRUE(utils::RectEqualTo(window, expect2)); diff --git a/wmserver/include/window_layout_policy.h b/wmserver/include/window_layout_policy.h index 3cb0470e8f1cb1fec46ae5762b31775491c1fb4d..924515fc2f5f5dc559b773474bb9b397fae92228 100644 --- a/wmserver/include/window_layout_policy.h +++ b/wmserver/include/window_layout_policy.h @@ -59,27 +59,23 @@ public: void ProcessDisplayCreate(DisplayId displayId, const std::map& displayRectMap); void ProcessDisplayDestroy(DisplayId displayId, const std::map& displayRectMap); void ProcessDisplaySizeChangeOrRotation(DisplayId displayId, const std::map& displayRectMap); + void SetFloatingWindowLimitsConfig(const FloatingWindowLimitsConfig& floatingWindowLimitsConfig); protected: void UpdateFloatingLayoutRect(Rect& limitRect, Rect& winRect); void UpdateLimitRect(const sptr& node, Rect& limitRect); virtual void LayoutWindowNode(const sptr& node); AvoidPosType GetAvoidPosType(const Rect& rect, DisplayId displayId) const; - void CalcAndSetNodeHotZone(Rect layoutOutRect, const sptr& node) const; - void LimitFloatingWindowSize(const sptr& node, const Rect& displayRect, Rect& winRect) const; - void LimitMainFloatingWindowPositionWithDrag(const sptr& node, Rect& winRect) const; - void LimitMainFloatingWindowPosition(const sptr& node, Rect& winRect) const; + void CalcAndSetNodeHotZone(const Rect& winRect, const sptr& node) const; void ComputeDecoratedRequestRect(const sptr& node) const; bool IsVerticalDisplay(DisplayId displayId) const; bool IsFullScreenRecentWindowExist(const std::vector>& nodeVec) const; void LayoutWindowNodesByRootType(const std::vector>& nodeVec); void UpdateSurfaceBounds(const sptr& node, const Rect& winRect); void UpdateRectInDisplayGroupForAllNodes(DisplayId displayId, - const Rect& oriDisplayRect, - const Rect& newDisplayRect); + const Rect& oriDisplayRect, const Rect& newDisplayRect); void UpdateRectInDisplayGroup(const sptr& node, - const Rect& oriDisplayRect, - const Rect& newDisplayRect); + const Rect& oriDisplayRect, const Rect& newDisplayRect); void LimitWindowToBottomRightCorner(const sptr& node); void UpdateDisplayGroupRect(); void UpdateDisplayGroupLimitRect_(); @@ -87,6 +83,19 @@ protected: void PostProcessWhenDisplayChange(); void UpdateDisplayRectAndDisplayGroupInfo(const std::map& displayRectMap); DockWindowShowState GetDockWindowShowState(DisplayId displayId, Rect& dockWinRect) const; + void LimitFloatingWindowSize(const sptr& node, const Rect& displayRect, Rect& winRect) const; + void LimitMainFloatingWindowPosition(const sptr& node, Rect& winRect) const; + + void UpdateFloatingWindowSizeByCustomizedLimits(const sptr& node, + const Rect& displayRect, Rect& winRect) const; + void UpdateFloatingWindowSizeBySystemLimits(const sptr& node, + const Rect& displayRect, Rect& winRect) const; + void LimitWindowPositionWhenInitRectOrMove(const sptr& node, Rect& winRect) const; + void LimitWindowPositionWhenDrag(const sptr& node, Rect& winRect) const; + void FixWindowSizeByRatioIfDragBeyondLimitRegion(const sptr& node, Rect& winRect, + const FloatingWindowLimitsConfig& limitConfig); + FloatingWindowLimitsConfig GetCustomizedLimitsConfig(const Rect& displayRect, float virtualPixelRatio); + FloatingWindowLimitsConfig GetSystemLimitsConfig(const Rect& displayRect, float virtualPixelRatio); const std::set avoidTypes_ { WindowType::WINDOW_TYPE_STATUS_BAR, @@ -98,6 +107,7 @@ protected: Rect displayGroupRect_; Rect displayGroupLimitRect_; bool isMultiDisplay_ = false; + FloatingWindowLimitsConfig floatingWindowLimitsConfig_; }; } } diff --git a/wmserver/include/window_manager_config.h b/wmserver/include/window_manager_config.h index 7efe7f3df8f4c69c6a5891605ff2cc588b2a57dd..52604ff5227ddc0cb1b8126adb0ffab1f57dbb47 100644 --- a/wmserver/include/window_manager_config.h +++ b/wmserver/include/window_manager_config.h @@ -33,16 +33,19 @@ public: static bool LoadConfigXml(const std::string& configFilePath); static const std::map& GetEnableConfig(); - static const std::map>& GetNumbersConfig(); + static const std::map>& GetIntNumbersConfig(); + static const std::map>& GetFloatNumbersConfig(); static void DumpConfig(); private: static std::map enableConfig_; - static std::map> numbersConfig_; + static std::map> intNumbersConfig_; + static std::map> floatNumbersConfig_; static bool IsValidNode(const xmlNode& currNode); static void ReadEnableConfigInfo(const xmlNodePtr& currNode); - static void ReadNumbersConfigInfo(const xmlNodePtr& currNode); + static void ReadIntNumbersConfigInfo(const xmlNodePtr& currNode); + static void ReadFloatNumbersConfigInfo(const xmlNodePtr& currNode); }; } // namespace Rosen } // namespace OHOS diff --git a/wmserver/include/window_node.h b/wmserver/include/window_node.h index 71601c5f754893a131977cd8d7d4878c18a09e29..de5904d2a5a784d593d0e282feffcb6f8669473a 100644 --- a/wmserver/include/window_node.h +++ b/wmserver/include/window_node.h @@ -69,6 +69,8 @@ public: void SetRequestedOrientation(Orientation orientation); void SetShowingDisplays(const std::vector& displayIdVec); void SetModeSupportInfo(uint32_t modeSupportInfo); + void SetDragType(DragType dragType); + const sptr& GetWindowToken() const; uint32_t GetWindowId() const; uint32_t GetParentId() const; @@ -95,6 +97,7 @@ public: Orientation GetRequestedOrientation() const; std::vector GetShowingDisplays() const; uint32_t GetModeSupportInfo() const; + DragType GetDragType() const; void ResetWindowSizeChangeReason(); sptr parent_; diff --git a/wmserver/include/window_root.h b/wmserver/include/window_root.h index d6af874b7193dd17d0b576fd1f2144f65689cd4d..7a9bf4a18824d6c1ad6a26d4b1ea8f3a2d22f45f 100644 --- a/wmserver/include/window_root.h +++ b/wmserver/include/window_root.h @@ -85,6 +85,7 @@ public: uint32_t GetWindowIdByObject(const sptr& remoteObject); sptr GetWindowForDumpAceHelpInfo() const; void DestroyLeakStartingWindow(); + void SetFloatingWindowLimitsConfig(const FloatingWindowLimitsConfig& floatingWindowLimitsConfig); private: void OnRemoteDied(const sptr& remoteObject); WMError DestroyWindowInner(sptr& node); @@ -98,7 +99,7 @@ private: void NotifyKeyboardSizeChangeInfo(const sptr& node, const sptr& container, Rect rect); ScreenId GetScreenGroupId(DisplayId displayId, bool& isRecordedDisplay); - void ProcessExpandDisplayCreate(DisplayId displayId, ScreenId screenGroupId); + void ProcessExpandDisplayCreate(DisplayId displayId, ScreenId displayGroupId); std::map> GetAllDisplayInfos(const std::vector& displayIdVec); std::map GetAllDisplayRects(const std::vector& displayIdVec); void MoveNotShowingWindowToDefaultDisplay(DisplayId displayId); @@ -117,6 +118,7 @@ private: this, std::placeholders::_1)); Callback callback_; int maxAppWindowNumber_ = 100; + FloatingWindowLimitsConfig floatingWindowLimitsConfig_; }; } } diff --git a/wmserver/src/window_controller.cpp b/wmserver/src/window_controller.cpp index eef7c5857085f0ad36ee605e0f2c226fd3834ece..dd8b15276ab1bf91d0f29a76e37c1b58f2296683 100644 --- a/wmserver/src/window_controller.cpp +++ b/wmserver/src/window_controller.cpp @@ -723,6 +723,7 @@ WMError WindowController::UpdateProperty(sptr& property, Propert switch (action) { case PropertyChangeAction::ACTION_UPDATE_RECT: { node->SetDecoStatus(property->GetDecoStatus()); + node->SetDragType(property->GetDragType()); return ResizeRect(windowId, property->GetRequestRect(), property->GetWindowSizeChangeReason()); } case PropertyChangeAction::ACTION_UPDATE_MODE: { diff --git a/wmserver/src/window_layout_policy.cpp b/wmserver/src/window_layout_policy.cpp index 0e252e57dbab545822f9f2f136c347632cae4da3..8c680c8a7b893d305be15cb078b1564114e359ee 100644 --- a/wmserver/src/window_layout_policy.cpp +++ b/wmserver/src/window_layout_policy.cpp @@ -415,9 +415,9 @@ void WindowLayoutPolicy::ComputeDecoratedRequestRect(const sptr& nod property->SetDecoStatus(true); } -void WindowLayoutPolicy::CalcAndSetNodeHotZone(Rect layoutOutRect, const sptr& node) const +void WindowLayoutPolicy::CalcAndSetNodeHotZone(const Rect& winRect, const sptr& node) const { - Rect rect = layoutOutRect; + Rect rect = winRect; float virtualPixelRatio = GetVirtualPixelRatio(node->GetDisplayId()); uint32_t hotZone = static_cast(HOTZONE * virtualPixelRatio); @@ -440,104 +440,320 @@ void WindowLayoutPolicy::CalcAndSetNodeHotZone(Rect layoutOutRect, const sptrSetHotZoneRect(rect); } +void WindowLayoutPolicy::FixWindowSizeByRatioIfDragBeyondLimitRegion(const sptr& node, Rect& winRect, + const FloatingWindowLimitsConfig& limitConfig) +{ + if (limitConfig.maxWidth_ == limitConfig.minWidth_ && + limitConfig.maxHeight_ == limitConfig.minHeight_) { + WLOGFI("window rect can not be changed"); + return; + } + float curRatio = static_cast(winRect.width_) / static_cast(winRect.height_); + if (limitConfig.minRatio_ <= curRatio && curRatio <= limitConfig.maxRatio_) { + WLOGFI("window ratio is satisfied with limit ratio, curRatio: %{public}f", curRatio); + return; + } + + float virtualPixelRatio = GetVirtualPixelRatio(node->GetDisplayId()); + uint32_t windowTitleBarH = static_cast(WINDOW_TITLE_BAR_HEIGHT * virtualPixelRatio); + Rect limitRect = isMultiDisplay_ ? displayGroupLimitRect_ : limitRectMap_[node->GetDisplayId()]; + int32_t limitMinPosX = limitRect.posX_ + static_cast(windowTitleBarH); + int32_t limitMaxPosX = limitRect.posX_ + static_cast(limitRect.width_ - windowTitleBarH); + int32_t limitMinPosY = limitRect.posY_; + int32_t limitMaxPosY = limitRect.posY_ + static_cast(limitRect.height_ - windowTitleBarH); + + Rect dockWinRect; + DockWindowShowState dockShownState = GetDockWindowShowState(node->GetDisplayId(), dockWinRect); + if (dockShownState == DockWindowShowState::SHOWN_IN_BOTTOM) { + WLOGFD("dock window show in bottom"); + limitMaxPosY = dockWinRect.posY_ - static_cast(windowTitleBarH); + } else if (dockShownState == DockWindowShowState::SHOWN_IN_LEFT) { + WLOGFD("dock window show in left"); + limitMinPosX = dockWinRect.posX_ + static_cast(dockWinRect.width_ + windowTitleBarH); + } else if (dockShownState == DockWindowShowState::SHOWN_IN_RIGHT) { + WLOGFD("dock window show in right"); + limitMaxPosX = dockWinRect.posX_ - static_cast(windowTitleBarH); + } + + float newRatio = curRatio < limitConfig.minRatio_ ? limitConfig.minRatio_ : limitConfig.maxRatio_; + if ((winRect.posX_ + static_cast(winRect.width_) == limitMinPosX) || (winRect.posX_ == limitMaxPosX)) { + // height can not be changed + if (limitConfig.maxHeight_ == limitConfig.minHeight_) { + return; + } + winRect.height_ = static_cast(static_cast(winRect.width_) / newRatio); + } + + if ((winRect.posY_ == limitMinPosY) || (winRect.posX_ == limitMaxPosY)) { + // width can not be changed + if (limitConfig.maxWidth_ == limitConfig.minWidth_) { + return; + } + winRect.width_ = static_cast(static_cast(winRect.height_) * newRatio); + } + WLOGFI("After limit by ratio if beyond limit region, winRect: %{public}d %{public}d %{public}u %{public}u", + winRect.posX_, winRect.posY_, winRect.width_, winRect.height_); +} + +FloatingWindowLimitsConfig WindowLayoutPolicy::GetSystemLimitsConfig(const Rect& displayRect, float virtualPixelRatio) +{ + FloatingWindowLimitsConfig limitConfig; + limitConfig.maxWidth_ = static_cast(MAX_FLOATING_SIZE * virtualPixelRatio); + limitConfig.maxHeight_ = static_cast(MAX_FLOATING_SIZE * virtualPixelRatio); + limitConfig.minWidth_ = static_cast(MIN_VERTICAL_FLOATING_WIDTH * virtualPixelRatio); + limitConfig.minHeight_ = static_cast(MIN_VERTICAL_FLOATING_HEIGHT * virtualPixelRatio); + if (displayRect.width_ > displayRect.height_) { + std::swap(limitConfig.minWidth_, limitConfig.minHeight_); + } + WLOGFI("maxWidth: %{public}u, maxHeight: %{public}u, minWidth: %{public}u, minHeight: %{public}u " + "maxRatio: %{public}f, minRatio: %{public}f", limitConfig.maxWidth_, limitConfig.maxHeight_, + limitConfig.minWidth_, limitConfig.minHeight_, limitConfig.maxRatio_, limitConfig.minRatio_); + return limitConfig; +} + +FloatingWindowLimitsConfig WindowLayoutPolicy::GetCustomizedLimitsConfig(const Rect& displayRect, + float virtualPixelRatio) +{ + const auto& systemLimits = GetSystemLimitsConfig(displayRect, virtualPixelRatio); + FloatingWindowLimitsConfig newLimitConfig = systemLimits; + // configured limits of floating window + uint32_t configuredMaxWidth = static_cast(floatingWindowLimitsConfig_.maxWidth_ * virtualPixelRatio); + uint32_t configuredMaxHeight = static_cast(floatingWindowLimitsConfig_.maxHeight_ * virtualPixelRatio); + uint32_t configuredMinWidth = static_cast(floatingWindowLimitsConfig_.minWidth_ * virtualPixelRatio); + uint32_t configuredMinHeight = static_cast(floatingWindowLimitsConfig_.minHeight_ * virtualPixelRatio); + float configuerdMaxRatio = floatingWindowLimitsConfig_.maxRatio_; + float configuerdMinRatio = floatingWindowLimitsConfig_.minRatio_; + + // calculate new limit size + if (systemLimits.minWidth_ <= configuredMaxWidth && configuredMaxWidth <= systemLimits.maxWidth_) { + newLimitConfig.maxWidth_ = configuredMaxWidth; + } + if (systemLimits.minHeight_ <= configuredMaxHeight && configuredMaxHeight <= systemLimits.maxHeight_) { + newLimitConfig.maxHeight_ = configuredMaxHeight; + } + if (systemLimits.minWidth_ <= configuredMinWidth && configuredMinWidth <= newLimitConfig.maxWidth_) { + newLimitConfig.minWidth_ = configuredMinWidth; + } + if (systemLimits.minHeight_ <= configuredMinHeight && configuredMinHeight <= newLimitConfig.maxHeight_) { + newLimitConfig.minHeight_ = configuredMinHeight; + } + + // calculate new limit ratio + newLimitConfig.maxRatio_ = static_cast(newLimitConfig.maxWidth_) / + static_cast(newLimitConfig.minHeight_); + newLimitConfig.minRatio_ = static_cast(newLimitConfig.minWidth_) / + static_cast(newLimitConfig.maxHeight_); + if (newLimitConfig.minRatio_ <= configuerdMaxRatio && configuerdMaxRatio <= newLimitConfig.maxRatio_) { + newLimitConfig.maxRatio_ = configuerdMaxRatio; + } + if (newLimitConfig.minRatio_ <= configuerdMinRatio && configuerdMinRatio <= newLimitConfig.maxRatio_) { + newLimitConfig.minRatio_ = configuerdMinRatio; + } + + // recalculate limit size by new ratio + uint32_t newMaxWidth = static_cast(static_cast(newLimitConfig.maxHeight_) * + newLimitConfig.maxRatio_); + newLimitConfig.maxWidth_ = std::min(newMaxWidth, newLimitConfig.maxWidth_); + uint32_t newMinWidth = static_cast(static_cast(newLimitConfig.minHeight_) * + newLimitConfig.minRatio_); + newLimitConfig.minWidth_ = std::max(newMinWidth, newLimitConfig.minWidth_); + uint32_t newMaxHeight = static_cast(static_cast(newLimitConfig.maxWidth_) / + newLimitConfig.minRatio_); + newLimitConfig.maxHeight_ = std::min(newMaxHeight, newLimitConfig.maxHeight_); + uint32_t newMinHeight = static_cast(static_cast(newLimitConfig.minWidth_) / + newLimitConfig.maxRatio_); + newLimitConfig.minHeight_ = std::max(newMinHeight, newLimitConfig.minHeight_); + + WLOGFI("maxWidth: %{public}u, maxHeight: %{public}u, minWidth: %{public}u, minHeight: %{public}u, " + "maxRatio: %{public}f, minRatio: %{public}f", newLimitConfig.maxWidth_, newLimitConfig.maxHeight_, + newLimitConfig.minWidth_, newLimitConfig.minHeight_, newLimitConfig.maxRatio_, newLimitConfig.minRatio_); + return newLimitConfig; +} + +void WindowLayoutPolicy::UpdateFloatingWindowSizeByCustomizedLimits(const sptr& node, + const Rect& displayRect, Rect& winRect) const +{ + // get new limit config with the settings of system and app + const auto& customizedLimits = const_cast(this)-> + GetCustomizedLimitsConfig(displayRect, GetVirtualPixelRatio(node->GetDisplayId())); + + // limit minimum and maximum size of floating (not system type) window + winRect.width_ = std::max(customizedLimits.minWidth_, winRect.width_); + winRect.height_ = std::max(customizedLimits.minHeight_, winRect.height_); + winRect.width_ = std::min(customizedLimits.maxWidth_, winRect.width_); + winRect.height_ = std::min(customizedLimits.maxHeight_, winRect.height_); + WLOGFD("After limit by size, winRect: %{public}d %{public}d %{public}u %{public}u", + winRect.posX_, winRect.posY_, winRect.width_, winRect.height_); + + // width and height can not be changed + if (customizedLimits.maxWidth_ == customizedLimits.minWidth_ && + customizedLimits.maxHeight_ == customizedLimits.minHeight_) { + winRect.width_ = customizedLimits.maxWidth_; + winRect.height_ = customizedLimits.maxHeight_; + WLOGFD("window rect can not be changed"); + return; + } + + float curRatio = static_cast(winRect.width_) / static_cast(winRect.height_); + if ((customizedLimits.minWidth_ <= winRect.width_ && winRect.width_ <= customizedLimits.maxWidth_) && + (customizedLimits.minHeight_ <= winRect.height_ && winRect.height_ <= customizedLimits.maxHeight_) && + (customizedLimits.minRatio_ <= curRatio && curRatio <= customizedLimits.maxRatio_)) { + WLOGFD("window size and ratio is satisfied with limit ratio, curSize: [%{public}d, %{public}d], " + "curRatio: %{public}f", winRect.width_, winRect.height_, curRatio); + return; + } + + float newRatio = curRatio < customizedLimits.minRatio_ ? customizedLimits.minRatio_ : customizedLimits.maxRatio_; + if (customizedLimits.maxWidth_ == customizedLimits.minWidth_) { + winRect.height_ = static_cast(static_cast(winRect.width_) / newRatio); + return; + } + if (customizedLimits.maxHeight_ == customizedLimits.minHeight_) { + winRect.width_ = static_cast(static_cast(winRect.height_) * newRatio); + return; + } + + auto dragType = node->GetDragType(); + if (dragType == DragType::DRAG_HEIGHT) { + // if drag height, use height to fix size. + winRect.width_ = static_cast(static_cast(winRect.height_) * newRatio); + } else { + // if drag width or corner, use width to fix size. + winRect.height_ = static_cast(static_cast(winRect.width_) / newRatio); + } + WLOGFI("After limit by customize config, winRect: %{public}d %{public}d %{public}u %{public}u", + winRect.posX_, winRect.posY_, winRect.width_, winRect.height_); +} + +void WindowLayoutPolicy::UpdateFloatingWindowSizeBySystemLimits(const sptr& node, + const Rect& displayRect, Rect& winRect) const +{ + const auto& systemLimits = const_cast(this)-> + GetSystemLimitsConfig(displayRect, GetVirtualPixelRatio(node->GetDisplayId())); + + // limit minimum size of floating (not system type) window + if (!WindowHelper::IsSystemWindow(node->GetWindowType())) { + winRect.width_ = std::max(systemLimits.minWidth_, winRect.width_); + winRect.height_ = std::max(systemLimits.minHeight_, winRect.height_); + } + // limit maximum size of all floating window + winRect.width_ = std::min(systemLimits.maxWidth_, winRect.width_); + winRect.height_ = std::min(systemLimits.maxHeight_, winRect.height_); + WLOGFI("After limit by system config, winRect: %{public}d %{public}d %{public}u %{public}u", + winRect.posX_, winRect.posY_, winRect.width_, winRect.height_); +} + void WindowLayoutPolicy::LimitFloatingWindowSize(const sptr& node, const Rect& displayRect, Rect& winRect) const { - float virtualPixelRatio = GetVirtualPixelRatio(node->GetDisplayId()); - uint32_t minVerticalFloatingW = static_cast(MIN_VERTICAL_FLOATING_WIDTH * virtualPixelRatio); - uint32_t minVerticalFloatingH = static_cast(MIN_VERTICAL_FLOATING_HEIGHT * virtualPixelRatio); - - WindowType windowType = node->GetWindowType(); - WindowMode windowMode = node->GetWindowMode(); - bool isVertical = (displayRect.height_ > displayRect.width_) ? true : false; - - if (windowMode == WindowMode::WINDOW_MODE_FLOATING) { - // limit minimum size of floating (not system type) window - if (!WindowHelper::IsSystemWindow(windowType)) { - if (isVertical) { - winRect.width_ = std::max(minVerticalFloatingW, winRect.width_); - winRect.height_ = std::max(minVerticalFloatingH, winRect.height_); - } else { - winRect.width_ = std::max(minVerticalFloatingH, winRect.width_); - winRect.height_ = std::max(minVerticalFloatingW, winRect.height_); - } + if (node->GetWindowMode() != WindowMode::WINDOW_MODE_FLOATING) { + return; + } + Rect oriWinRect = winRect; + if (floatingWindowLimitsConfig_.isFloatingWindowLimitsConfigured_ && + (WindowHelper::IsMainFloatingWindow(node->GetWindowType(), node->GetWindowMode()))) { + UpdateFloatingWindowSizeByCustomizedLimits(node, displayRect, winRect); + } else { + UpdateFloatingWindowSizeBySystemLimits(node, displayRect, winRect); + } + + // fix size in case of moving window when dragging + const auto& lastWinRect = node->GetWindowRect(); + if (node->GetWindowSizeChangeReason() == WindowSizeChangeReason::DRAG) { + if (oriWinRect.posX_ != lastWinRect.posX_) { + winRect.posX_ = oriWinRect.posX_ + static_cast(oriWinRect.width_) - + static_cast(winRect.width_); + } + if (oriWinRect.posY_ != lastWinRect.posY_) { + winRect.posY_ = oriWinRect.posY_ + static_cast(oriWinRect.height_) - + static_cast(winRect.height_); } - // limit maximum size of all floating window - winRect.width_ = std::min(static_cast(MAX_FLOATING_SIZE * virtualPixelRatio), winRect.width_); - winRect.height_ = std::min(static_cast(MAX_FLOATING_SIZE * virtualPixelRatio), winRect.height_); } } -DockWindowShowState WindowLayoutPolicy::GetDockWindowShowState(DisplayId displayId, Rect& dockWinRect) const +void WindowLayoutPolicy::LimitMainFloatingWindowPosition(const sptr& node, Rect& winRect) const { - auto& displayWindowTree = displayGroupWindowTree_[displayId]; - auto& nodeVec = *(displayWindowTree[WindowRootNodeType::ABOVE_WINDOW_NODE]); - for (auto& node : nodeVec) { - if (node->GetWindowType() != WindowType::WINDOW_TYPE_LAUNCHER_DOCK) { - continue; - } + if (!WindowHelper::IsMainFloatingWindow(node->GetWindowType(), node->GetWindowMode())) { + return; + } - dockWinRect = node->GetWindowRect(); - auto displayRect = displayGroupInfo_->GetDisplayRect(displayId); - WLOGFI("begin dockWinRect :[%{public}d, %{public}d, %{public}u, %{public}u]", - dockWinRect.posX_, dockWinRect.posY_, dockWinRect.width_, dockWinRect.height_); - if (dockWinRect.height_ < dockWinRect.width_) { - if (static_cast(dockWinRect.posY_) + dockWinRect.height_ == displayRect.height_) { - return DockWindowShowState::SHOWN_IN_BOTTOM; - } else { - return DockWindowShowState::NOT_SHOWN; - } - } else { - if (dockWinRect.posX_ == 0) { - return DockWindowShowState::SHOWN_IN_LEFT; - } else if (static_cast(dockWinRect.posX_) + dockWinRect.width_ == displayRect.width_) { - return DockWindowShowState::SHOWN_IN_RIGHT; - } else { - return DockWindowShowState::NOT_SHOWN; - } + auto reason = node->GetWindowSizeChangeReason(); + // if drag or move window, limit size and position + if (reason == WindowSizeChangeReason::DRAG) { + LimitWindowPositionWhenDrag(node, winRect); + if (floatingWindowLimitsConfig_.isFloatingWindowLimitsConfigured_ && + (WindowHelper::IsMainFloatingWindow(node->GetWindowType(), node->GetWindowMode()))) { + const auto& limitConfig = const_cast(this)-> GetCustomizedLimitsConfig( + displayGroupInfo_->GetDisplayRect(node->GetDisplayId()), GetVirtualPixelRatio(node->GetDisplayId())); + const_cast(this)-> + FixWindowSizeByRatioIfDragBeyondLimitRegion(node, winRect, limitConfig); } + } else { + // Limit window position, such as init window rect when show + LimitWindowPositionWhenInitRectOrMove(node, winRect); } - return DockWindowShowState::NOT_SHOWN; } -void WindowLayoutPolicy::LimitMainFloatingWindowPositionWithDrag(const sptr& node, Rect& winRect) const +void WindowLayoutPolicy::LimitWindowPositionWhenDrag(const sptr& node, + Rect& winRect) const { - if (WindowHelper::IsMainFloatingWindow(node->GetWindowType(), node->GetWindowMode())) { - float virtualPixelRatio = GetVirtualPixelRatio(node->GetDisplayId()); - uint32_t windowTitleBarH = static_cast(WINDOW_TITLE_BAR_HEIGHT * virtualPixelRatio); - const Rect lastRect = node->GetWindowRect(); - // fix rect in case of moving window when dragging - winRect = WindowHelper::GetFixedWindowRectByLimitSize(winRect, lastRect, - IsVerticalDisplay(node->GetDisplayId()), virtualPixelRatio); - - // if is mutiDisplay, the limit rect should be full limitRect when move or drag - Rect limitRect; - if (isMultiDisplay_) { - limitRect = displayGroupLimitRect_; - } else { - limitRect = limitRectMap_[node->GetDisplayId()]; + float virtualPixelRatio = GetVirtualPixelRatio(node->GetDisplayId()); + uint32_t windowTitleBarH = static_cast(WINDOW_TITLE_BAR_HEIGHT * virtualPixelRatio); + const Rect& lastRect = node->GetWindowRect(); + Rect oriWinRect = winRect; + + Rect limitRect = isMultiDisplay_ ? displayGroupLimitRect_ : limitRectMap_[node->GetDisplayId()]; + int32_t limitMinPosX = limitRect.posX_ + static_cast(windowTitleBarH); + int32_t limitMaxPosX = limitRect.posX_ + static_cast(limitRect.width_ - windowTitleBarH); + int32_t limitMinPosY = limitRect.posY_; + int32_t limitMaxPosY = limitRect.posY_ + static_cast(limitRect.height_ - windowTitleBarH); + + Rect dockWinRect; + DockWindowShowState dockShownState = GetDockWindowShowState(node->GetDisplayId(), dockWinRect); + if (dockShownState == DockWindowShowState::SHOWN_IN_BOTTOM) { + WLOGFD("dock window show in bottom"); + limitMaxPosY = dockWinRect.posY_ - static_cast(windowTitleBarH); + } else if (dockShownState == DockWindowShowState::SHOWN_IN_LEFT) { + WLOGFD("dock window show in left"); + limitMinPosX = dockWinRect.posX_ + static_cast(dockWinRect.width_ + windowTitleBarH); + } else if (dockShownState == DockWindowShowState::SHOWN_IN_RIGHT) { + WLOGFD("dock window show in right"); + limitMaxPosX = dockWinRect.posX_ - static_cast(windowTitleBarH); + } + + // limitMinPosX is minimum (x + width) + if (oriWinRect.posX_ + static_cast(oriWinRect.width_) < limitMinPosX) { + if (oriWinRect.width_ != lastRect.width_) { + winRect.width_ = static_cast(limitMinPosX - oriWinRect.posX_); } - winRect = WindowHelper::GetFixedWindowRectByLimitPosition(winRect, lastRect, - virtualPixelRatio, limitRect); - Rect dockWinRect; - DockWindowShowState dockShownState = GetDockWindowShowState(node->GetDisplayId(), dockWinRect); - if (dockShownState == DockWindowShowState::SHOWN_IN_BOTTOM) { - WLOGFI("dock window show in bottom"); - winRect.posY_ = std::min(dockWinRect.posY_ - static_cast(windowTitleBarH), winRect.posY_); - } else if (dockShownState == DockWindowShowState::SHOWN_IN_LEFT) { - WLOGFI("dock window show in left"); - winRect.posX_ = std::max(static_cast(dockWinRect.width_ + windowTitleBarH - winRect.width_), - winRect.posX_); - } else if (dockShownState == DockWindowShowState::SHOWN_IN_RIGHT) { - WLOGFI("dock window show in right"); - winRect.posX_ = std::min(dockWinRect.posX_ - static_cast(windowTitleBarH), - winRect.posX_); + } + // maximum position x + if (oriWinRect.posX_ > limitMaxPosX) { + winRect.posX_ = limitMaxPosX; + if (oriWinRect.width_ != lastRect.width_) { + winRect.width_ = oriWinRect.posX_ + static_cast(oriWinRect.width_) - winRect.posX_; + } + } + // minimum position y + if (oriWinRect.posY_ < limitMinPosY) { + winRect.posY_ = limitMinPosY; + if (oriWinRect.height_ != lastRect.height_) { + winRect.height_ = oriWinRect.posY_ + static_cast(oriWinRect.height_) - winRect.posY_; + } + } + // maximum position y + if (winRect.posY_ > limitMaxPosY) { + winRect.posY_ = limitMaxPosY; + if (oriWinRect.height_ != lastRect.height_) { + winRect.height_ = oriWinRect.posY_ + static_cast(oriWinRect.height_) - winRect.posY_; } } + WLOGFI("After limit by position, winRect: %{public}d %{public}d %{public}u %{public}u", + winRect.posX_, winRect.posY_, winRect.width_, winRect.height_); } -void WindowLayoutPolicy::LimitMainFloatingWindowPosition(const sptr& node, Rect& winRect) const +void WindowLayoutPolicy::LimitWindowPositionWhenInitRectOrMove(const sptr& node, Rect& winRect) const { float virtualPixelRatio = GetVirtualPixelRatio(node->GetDisplayId()); uint32_t windowTitleBarH = static_cast(WINDOW_TITLE_BAR_HEIGHT * virtualPixelRatio); @@ -558,25 +774,59 @@ void WindowLayoutPolicy::LimitMainFloatingWindowPosition(const sptr& winRect.posY_ = std::min(limitRect.posY_ + static_cast(limitRect.height_ - windowTitleBarH), winRect.posY_); if (dockShownState == DockWindowShowState::SHOWN_IN_BOTTOM) { - WLOGFI("dock window show in bottom"); + WLOGFD("dock window show in bottom"); winRect.posY_ = std::min(dockWinRect.posY_ + static_cast(dockWinRect.height_ - windowTitleBarH), winRect.posY_); } winRect.posX_ = std::max(limitRect.posX_ + static_cast(windowTitleBarH - winRect.width_), winRect.posX_); if (dockShownState == DockWindowShowState::SHOWN_IN_LEFT) { - WLOGFI("dock window show in left"); + WLOGFD("dock window show in left"); winRect.posX_ = std::max(static_cast(dockWinRect.width_ + windowTitleBarH - winRect.width_), winRect.posX_); } winRect.posX_ = std::min(limitRect.posX_ + static_cast(limitRect.width_ - windowTitleBarH), winRect.posX_); if (dockShownState == DockWindowShowState::SHOWN_IN_RIGHT) { - WLOGFI("dock window show in right"); + WLOGFD("dock window show in right"); winRect.posX_ = std::min(dockWinRect.posX_ - static_cast(windowTitleBarH), winRect.posX_); } } + WLOGFI("After limit by position if init or move, winRect: %{public}d %{public}d %{public}u %{public}u", + winRect.posX_, winRect.posY_, winRect.width_, winRect.height_); +} + +DockWindowShowState WindowLayoutPolicy::GetDockWindowShowState(DisplayId displayId, Rect& dockWinRect) const +{ + auto& displayWindowTree = displayGroupWindowTree_[displayId]; + auto& nodeVec = *(displayWindowTree[WindowRootNodeType::ABOVE_WINDOW_NODE]); + for (auto& node : nodeVec) { + if (node->GetWindowType() != WindowType::WINDOW_TYPE_LAUNCHER_DOCK) { + continue; + } + + dockWinRect = node->GetWindowRect(); + auto displayRect = displayGroupInfo_->GetDisplayRect(displayId); + WLOGFI("begin dockWinRect :[%{public}d, %{public}d, %{public}u, %{public}u]", + dockWinRect.posX_, dockWinRect.posY_, dockWinRect.width_, dockWinRect.height_); + if (dockWinRect.height_ < dockWinRect.width_) { + if (static_cast(dockWinRect.posY_) + dockWinRect.height_ == displayRect.height_) { + return DockWindowShowState::SHOWN_IN_BOTTOM; + } else { + return DockWindowShowState::NOT_SHOWN; + } + } else { + if (dockWinRect.posX_ == 0) { + return DockWindowShowState::SHOWN_IN_LEFT; + } else if (static_cast(dockWinRect.posX_) + dockWinRect.width_ == displayRect.width_) { + return DockWindowShowState::SHOWN_IN_RIGHT; + } else { + return DockWindowShowState::NOT_SHOWN; + } + } + } + return DockWindowShowState::NOT_SHOWN; } AvoidPosType WindowLayoutPolicy::GetAvoidPosType(const Rect& rect, DisplayId displayId) const @@ -676,5 +926,10 @@ Rect WindowLayoutPolicy::GetDisplayGroupRect() const { return displayGroupRect_; } + +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 6f99e74bbe34da9ca36b62a9897dbcab555ffaa9..d0bbba6011df4509b1a61ae8afb8f16758b43c87 100644 --- a/wmserver/src/window_layout_policy_cascade.cpp +++ b/wmserver/src/window_layout_policy_cascade.cpp @@ -247,20 +247,12 @@ void WindowLayoutPolicyCascade::ApplyWindowRectConstraints(const sptrGetWindowSizeChangeReason(); - if (node->GetWindowType() == WindowType::WINDOW_TYPE_DOCK_SLICE) { // if divider, limit position LimitMoveBounds(winRect, node->GetDisplayId()); } - // if drag or move window, limit size and position - if (reason == WindowSizeChangeReason::DRAG || reason == WindowSizeChangeReason::MOVE) { - LimitMainFloatingWindowPositionWithDrag(node, winRect); - } else { - // Limit window to the maximum window size if size change is other reason, such as init window rect when show - LimitFloatingWindowSize(node, displayGroupInfo_->GetDisplayRect(node->GetDisplayId()), winRect); - LimitMainFloatingWindowPosition(node, winRect); - } + LimitFloatingWindowSize(node, displayGroupInfo_->GetDisplayRect(node->GetDisplayId()), winRect); + LimitMainFloatingWindowPosition(node, winRect); WLOGFI("After apply constraints winRect:[%{public}d, %{public}d, %{public}u, %{public}u]", winRect.posX_, winRect.posY_, winRect.width_, winRect.height_); diff --git a/wmserver/src/window_manager_config.cpp b/wmserver/src/window_manager_config.cpp index dbfdf44b1790a4156f377bd382aae47eea0538d0..bcf4cdb5e2672b51bb3423762f38723f7034d60f 100644 --- a/wmserver/src/window_manager_config.cpp +++ b/wmserver/src/window_manager_config.cpp @@ -24,7 +24,8 @@ namespace { } std::map WindowManagerConfig::enableConfig_; -std::map> WindowManagerConfig::numbersConfig_; +std::map> WindowManagerConfig::intNumbersConfig_; +std::map> WindowManagerConfig::floatNumbersConfig_; bool WindowManagerConfig::LoadConfigXml(const std::string& configFilePath) { @@ -57,8 +58,14 @@ bool WindowManagerConfig::LoadConfigXml(const std::string& configFilePath) continue; } if (!xmlStrcmp(nodeName, reinterpret_cast("maxAppWindowNumber")) || - !xmlStrcmp(nodeName, reinterpret_cast("modeChangeHotZones"))) { - ReadNumbersConfigInfo(curNodePtr); + !xmlStrcmp(nodeName, reinterpret_cast("modeChangeHotZones")) || + !xmlStrcmp(nodeName, reinterpret_cast("floatingWindowLimitSize"))) { + ReadIntNumbersConfigInfo(curNodePtr); + continue; + } + + if (!xmlStrcmp(nodeName, reinterpret_cast("floatingWindowLimitRatio"))) { + ReadFloatNumbersConfigInfo(curNodePtr); continue; } } @@ -91,7 +98,7 @@ void WindowManagerConfig::ReadEnableConfigInfo(const xmlNodePtr& currNode) xmlFree(enable); } -void WindowManagerConfig::ReadNumbersConfigInfo(const xmlNodePtr& currNode) +void WindowManagerConfig::ReadIntNumbersConfigInfo(const xmlNodePtr& currNode) { xmlChar* context = xmlNodeGetContent(currNode); if (context == nullptr) { @@ -104,15 +111,41 @@ void WindowManagerConfig::ReadNumbersConfigInfo(const xmlNodePtr& currNode) auto numbers = WindowHelper::Split(numbersStr, " "); for (auto& num : numbers) { if (!WindowHelper::IsNumber(num)) { - WLOGFE("[WmConfig] read number error: nodeName:(%{public}s)", currNode->name); + WLOGFE("[WmConfig] read int number error: nodeName:(%{public}s)", currNode->name); xmlFree(context); return; } + numbersVec.emplace_back(std::stoi(num)); } std::string nodeName = reinterpret_cast(currNode->name); - numbersConfig_[nodeName] = numbersVec; + intNumbersConfig_[nodeName] = numbersVec; + xmlFree(context); +} + +void WindowManagerConfig::ReadFloatNumbersConfigInfo(const xmlNodePtr& currNode) +{ + xmlChar* context = xmlNodeGetContent(currNode); + if (context == nullptr) { + WLOGFE("[WmConfig] read xml node error: nodeName:(%{public}s)", currNode->name); + return; + } + + std::vector numbersVec; + std::string numbersStr = reinterpret_cast(context); + auto numbers = WindowHelper::Split(numbersStr, " "); + for (auto& num : numbers) { + if (!WindowHelper::IsFloatingNumber(num)) { + WLOGFE("[WmConfig] read float number error: nodeName:(%{public}s)", currNode->name); + xmlFree(context); + return; + } + numbersVec.emplace_back(std::stof(num)); + } + + std::string nodeName = reinterpret_cast(currNode->name); + floatNumbersConfig_[nodeName] = numbersVec; xmlFree(context); } @@ -121,9 +154,14 @@ const std::map& WindowManagerConfig::GetEnableConfig() return enableConfig_; } -const std::map>& WindowManagerConfig::GetNumbersConfig() +const std::map>& WindowManagerConfig::GetIntNumbersConfig() { - return numbersConfig_; + return intNumbersConfig_; +} + +const std::map>& WindowManagerConfig::GetFloatNumbersConfig() +{ + return floatNumbersConfig_; } void WindowManagerConfig::DumpConfig() @@ -132,12 +170,19 @@ void WindowManagerConfig::DumpConfig() WLOGFI("[WmConfig] Enable: %{public}s %{public}u", enable.first.c_str(), enable.second); } - for (auto& numbers : numbersConfig_) { - WLOGFI("[WmConfig] Numbers: %{public}s %{public}zu", numbers.first.c_str(), numbers.second.size()); + for (auto& numbers : intNumbersConfig_) { + WLOGFI("[WmConfig] Int numbers: %{public}s %{public}zu", numbers.first.c_str(), numbers.second.size()); for (auto& num : numbers.second) { WLOGFI("[WmConfig] Num: %{public}d", num); } } + + for (auto& numbers : floatNumbersConfig_) { + WLOGFI("[WmConfig] Float numbers: %{public}s %{public}zu", numbers.first.c_str(), numbers.second.size()); + for (auto& num : numbers.second) { + WLOGFI("[WmConfig] Num: %{public}f", num); + } + } } } // namespace Rosen } // namespace OHOS diff --git a/wmserver/src/window_manager_service.cpp b/wmserver/src/window_manager_service.cpp index a782832420f4d556ed240113a669035c7579a45f..1c4d8127554a6e595f4524dbb2bcd8e8f2da9b39 100644 --- a/wmserver/src/window_manager_service.cpp +++ b/wmserver/src/window_manager_service.cpp @@ -195,7 +195,8 @@ int WindowManagerService::Dump(int fd, const std::vector& args) void WindowManagerService::ConfigureWindowManagerService() { const auto& enableConfig = WindowManagerConfig::GetEnableConfig(); - const auto& numbersConfig = WindowManagerConfig::GetNumbersConfig(); + const auto& intNumbersConfig = WindowManagerConfig::GetIntNumbersConfig(); + const auto& floatNumbersConfig = WindowManagerConfig::GetFloatNumbersConfig(); if (enableConfig.count("decor") != 0) { systemConfig_.isSystemDecorEnable_ = enableConfig.at("decor"); @@ -209,15 +210,15 @@ void WindowManagerService::ConfigureWindowManagerService() systemConfig_.isStretchable_ = enableConfig.at("stretchable"); } - if (numbersConfig.count("maxAppWindowNumber") != 0) { - auto numbers = numbersConfig.at("maxAppWindowNumber"); + if (intNumbersConfig.count("maxAppWindowNumber") != 0) { + auto numbers = intNumbersConfig.at("maxAppWindowNumber"); if (numbers.size() == 1) { windowRoot_->SetMaxAppWindowNumber(numbers[0]); } } - if (numbersConfig.count("modeChangeHotZones") != 0) { - auto numbers = numbersConfig.at("modeChangeHotZones"); + if (intNumbersConfig.count("modeChangeHotZones") != 0) { + auto numbers = intNumbersConfig.at("modeChangeHotZones"); if (numbers.size() == 3) { // 3 hot zones hotZonesConfig_.fullscreenRange_ = static_cast(numbers[0]); // 0 fullscreen hotZonesConfig_.primaryRange_ = static_cast(numbers[1]); // 1 primary @@ -225,6 +226,30 @@ void WindowManagerService::ConfigureWindowManagerService() hotZonesConfig_.isModeChangeHotZoneConfigured_ = true; } } + + 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::OnStop() diff --git a/wmserver/src/window_node.cpp b/wmserver/src/window_node.cpp index 496874f797e3d63cafdb5490dae5946a87974f05..faf3026d27bd546b72f651667e4b1c41347f245e 100644 --- a/wmserver/src/window_node.cpp +++ b/wmserver/src/window_node.cpp @@ -188,6 +188,16 @@ void WindowNode::SetCallingUid(int32_t uid) callingUid_ = uid; } +void WindowNode::SetDragType(DragType dragType) +{ + property_->SetDragType(dragType); +} + +DragType WindowNode::GetDragType() const +{ + return property_->GetDragType(); +} + DisplayId WindowNode::GetDisplayId() const { return property_->GetDisplayId(); diff --git a/wmserver/src/window_root.cpp b/wmserver/src/window_root.cpp index be8679cfda4111419b0b268cab55997c0972df0a..48220113828193101f98962dfa51e0e9323d6237 100644 --- a/wmserver/src/window_root.cpp +++ b/wmserver/src/window_root.cpp @@ -97,6 +97,11 @@ sptr WindowRoot::CreateWindowNodeContainer(DisplayId displa windowNodeContainerMap_.insert(std::make_pair(displayGroupId, container)); std::vector displayVec = { displayId }; displayIdMap_.insert(std::make_pair(displayGroupId, displayVec)); + if (container == nullptr) { + WLOGFE("create container failed, displayId :%{public}" PRIu64 "", displayId); + return nullptr; + } + container->GetLayoutPolicy()->SetFloatingWindowLimitsConfig(floatingWindowLimitsConfig_); return container; } @@ -1157,5 +1162,10 @@ WMError WindowRoot::GetModeChangeHotZones(DisplayId displayId, container->GetModeChangeHotZones(displayId, hotZones, config); return WMError::WM_OK; } + +void WindowRoot::SetFloatingWindowLimitsConfig(const FloatingWindowLimitsConfig& floatingWindowLimitsConfig) +{ + floatingWindowLimitsConfig_ = floatingWindowLimitsConfig; +} } // namespace Rosen } // namespace OHOS