diff --git a/interfaces/kits/napi/window_runtime/window_napi/js_window.cpp b/interfaces/kits/napi/window_runtime/window_napi/js_window.cpp index da6a1d663b2c34f2a29281ca96a4872bb9be44ea..161f1de464e970aaba3b75cc6234d88a9d5ed6e4 100644 --- a/interfaces/kits/napi/window_runtime/window_napi/js_window.cpp +++ b/interfaces/kits/napi/window_runtime/window_napi/js_window.cpp @@ -6899,8 +6899,8 @@ napi_value JsWindow::OnSetSubWindowModal(napi_env env, napi_callback_info info) return result; } -static std::function SetFollowParentMultiScreenPolicyTask(const wptr& weakToken, bool enabled, - napi_env env, std::shared_ptr napiAsyncTask) +static std::function GetFollowParentMultiScreenPolicyTask(const wptr& weakToken, bool enabled, + napi_env env, std::shared_ptr& napiAsyncTask) { return [weakToken, enabled, env, task = napiAsyncTask] { auto window = weakToken.promote(); @@ -6955,7 +6955,7 @@ napi_value JsWindow::OnSetFollowParentMultiScreenPolicy(napi_env env, napi_callb } napi_value result = nullptr; std::shared_ptr napiAsyncTask = CreateEmptyAsyncTask(env, nullptr, &result); - auto asyncTask = SetFollowParentMultiScreenPolicyTask(wptr(windowToken_), enabled, env, napiAsyncTask); + auto asyncTask = GetFollowParentMultiScreenPolicyTask(wptr(windowToken_), enabled, env, napiAsyncTask); if (napi_status::napi_ok != napi_send_event(env, asyncTask, napi_eprio_high)) { napiAsyncTask->Reject(env, CreateJsError(env, static_cast(WmErrorCode::WM_ERROR_STATE_ABNORMALLY), "send event failed")); diff --git a/window_scene/common/src/window_session_property.cpp b/window_scene/common/src/window_session_property.cpp index ddfadd37a783d29bab540c6bc7eed382dba61cd2..7ba18515176109fbca492f431f669a838e0c0505 100755 --- a/window_scene/common/src/window_session_property.cpp +++ b/window_scene/common/src/window_session_property.cpp @@ -1042,6 +1042,9 @@ bool WindowSessionProperty::MarshallingSessionInfo(Parcel& parcel) const if (hasWant && !parcel.WriteParcelable(want.get())) { return false; } + if (!parcel.WriteBool(sessionInfo_.isFollowParentMultiScreenPolicy)) { + return false; + } return true; } @@ -1080,6 +1083,12 @@ bool WindowSessionProperty::UnmarshallingSessionInfo(Parcel& parcel, WindowSessi } info.want = want; } + bool isFollowParentMultiScreenPolicy = false; + if (!parcel.ReadBool(isFollowParentMultiScreenPolicy)) { + TLOGE(WmsLogTag::DEFAULT, "Failed to read isFollowParentMultiScreenPolicy!"); + return false; + } + info.isFollowParentMultiScreenPolicy = isFollowParentMultiScreenPolicy; property->SetSessionInfo(info); return true; } diff --git a/window_scene/interfaces/include/ws_common.h b/window_scene/interfaces/include/ws_common.h index 3e283e2e85f33a1ca85c09c8ec6a4aef17fea827..3b483cd77cbffa217045b77a1498e3cb115fc754 100644 --- a/window_scene/interfaces/include/ws_common.h +++ b/window_scene/interfaces/include/ws_common.h @@ -427,6 +427,7 @@ struct SessionInfo { */ std::vector supportedWindowModes; WindowSizeLimits windowSizeLimits; + bool isFollowParentMultiScreenPolicy = false; /* * Window Rotation diff --git a/window_scene/session/host/include/scene_session.h b/window_scene/session/host/include/scene_session.h index b4beaa345935f168be73e51e16ebe23afc77531b..325795adf0a2db85b4c79b496755cc9aff114772 100644 --- a/window_scene/session/host/include/scene_session.h +++ b/window_scene/session/host/include/scene_session.h @@ -836,6 +836,7 @@ protected: std::mutex registerNotifySurfaceBoundsChangeMutex_; std::unordered_map notifySurfaceBoundsChangeFuncMap_; bool isFollowParentLayout_ = false; + int32_t cloneNodeCount_ = 0; virtual void NotifySessionRectChange(const WSRect& rect, SizeChangeReason reason = SizeChangeReason::UNDEFINED, DisplayId displayId = DISPLAY_ID_INVALID, @@ -850,6 +851,8 @@ protected: WSRect ConvertRelativeRectToGlobal(const WSRect& relativeRect, DisplayId currentDisplayId) const override; WSRect ConvertGlobalRectToRelative(const WSRect& globalRect, DisplayId targetDisplayId) const override; bool IsNeedConvertToRelativeRect(SizeChangeReason reason = SizeChangeReason::UNDEFINED) const override; + void SetRequestMoveConfiguration(const MoveConfiguration& config) { requestMoveConfiguration_ = config; } + MoveConfiguration GetRequestMoveConfiguration() const { return requestMoveConfiguration_; } /* * Window Lifecycle @@ -1078,7 +1081,7 @@ private: void UpdateSessionRectPosYFromClient(SizeChangeReason reason, DisplayId& configDisplayId, WSRect& rect); void HandleSubSessionSurfaceNode(bool isAdd); virtual void AddSurfaceNodeToScreen() {} - virtual void RemoveSufaceNodeFromScreen() {} + virtual void RemoveSurfaceNodeFromScreen() {} /* * Window Decor @@ -1177,6 +1180,7 @@ private: virtual void UpdateCrossAxisOfLayout(const WSRect& rect); NotifyLayoutFullScreenChangeFunc onLayoutFullScreenChangeFunc_; WSRect requestRectWhenFollowParent_; + MoveConfiguration requestMoveConfiguration_; virtual void NotifySubAndDialogFollowRectChange(const WSRect& rect, bool isGlobal, bool needFlush) {}; std::atomic shouldFollowParentWhenShow_ = true; bool isDragging_ = false; diff --git a/window_scene/session/host/include/sub_session.h b/window_scene/session/host/include/sub_session.h index a014cef07c3fbc4a9ac129327df0d5e2f4cbdefb..8295283caf34340a1e5295ddc7f20d203bdb3961 100644 --- a/window_scene/session/host/include/sub_session.h +++ b/window_scene/session/host/include/sub_session.h @@ -79,7 +79,7 @@ private: * Window Layout */ void AddSurfaceNodeToScreen() override; - void RemoveSufaceNodeFromScreen() override; + void RemoveSurfaceNodeFromScreen() override; }; } // namespace OHOS::Rosen #endif // OHOS_ROSEN_WINDOW_SCENE_SUB_SESSION_H diff --git a/window_scene/session/host/src/scene_session.cpp b/window_scene/session/host/src/scene_session.cpp index 5f94f27003d0410832df5bc88a0660b3a5c38a8a..91de106d21dcc9d3b78535defebf4005acd2154e 100644 --- a/window_scene/session/host/src/scene_session.cpp +++ b/window_scene/session/host/src/scene_session.cpp @@ -744,7 +744,7 @@ WSError SceneSession::InitializeMoveInputBar() bool SceneSession::IsNeedConvertToRelativeRect(SizeChangeReason reason) const { - if (IsDraggingReason(reason)) { + if (reason == SizeChangeReason::DRAG_MOVE) { return true; } if (WindowHelper::IsSubWindow(GetWindowType())) { @@ -768,8 +768,8 @@ WSRect SceneSession::ConvertRelativeRectToGlobal(const WSRect& relativeRect, Dis const ScreenProperty& screenProperty = screenSession->GetScreenProperty(); int32_t currentDisplayOffsetX = static_cast(screenProperty.GetStartX()); int32_t currentDisplayOffsetY = static_cast(screenProperty.GetStartY()); - TLOGI(WmsLogTag::WMS_LAYOUT, "relativeRect:%{public}s, offsetX:%{public}d, offsetY:%{public}d", - relativeRect.ToString().c_str(), currentDisplayOffsetX, currentDisplayOffsetY); + TLOGI(WmsLogTag::WMS_LAYOUT, "id:%{public}d, relativeRect:%{public}s, offsetX:%{public}d, offsetY:%{public}d", + GetPersistentId(), relativeRect.ToString().c_str(), currentDisplayOffsetX, currentDisplayOffsetY); return {relativeRect.posX_ + currentDisplayOffsetX, relativeRect.posY_ + currentDisplayOffsetY, relativeRect.width_, relativeRect.height_}; @@ -790,8 +790,8 @@ WSRect SceneSession::ConvertGlobalRectToRelative(const WSRect& globalRect, Displ const ScreenProperty& screenProperty = screenSession->GetScreenProperty(); int32_t targetDisplayOffsetX = static_cast(screenProperty.GetStartX()); int32_t targetDisplayOffsetY = static_cast(screenProperty.GetStartY()); - TLOGI(WmsLogTag::WMS_LAYOUT, "globalRect:%{public}s, offsetX:%{public}d, offsetY:%{public}d", - globalRect.ToString().c_str(), targetDisplayOffsetX, targetDisplayOffsetY); + TLOGI(WmsLogTag::WMS_LAYOUT, "id:%{public}d, globalRect:%{public}s, offsetX:%{public}d, offsetY:%{public}d", + GetPersistentId(), globalRect.ToString().c_str(), targetDisplayOffsetX, targetDisplayOffsetY); return {globalRect.posX_ - targetDisplayOffsetX, globalRect.posY_ - targetDisplayOffsetY, globalRect.width_, globalRect.height_}; @@ -1724,6 +1724,7 @@ WSError SceneSession::UpdateSessionRect( TLOGNE(WmsLogTag::WMS_LAYOUT, "%{public}s session is null", where); return WSError::WS_ERROR_DESTROYED_OBJECT; } + session->SetRequestMoveConfiguration(newMoveConfiguration); session->UpdateSessionRectInner(newRect, reason, newMoveConfiguration, rectAnimationConfig); return WSError::WS_OK; }, __func__ + GetRectInfo(rect)); @@ -3554,7 +3555,7 @@ void SceneSession::OnMoveDragCallback(SizeChangeReason reason) void SceneSession::HandleSubSessionCrossNode(SizeChangeReason reason) { - if ((reason == SizeChangeReason::DRAG || reason == SizeChangeReason::DRAG_MOVE) && !Session::IsDragStart()) { + if (IsDraggingReason(reason) && !Session::IsDragStart()) { Session::SetDragStart(true); if (Session::GetOriginDisplayId() == DISPLAY_ID_INVALID) { Session::SetOriginDisplayId(moveDragController_->GetMoveDragStartDisplayId()); @@ -3832,7 +3833,8 @@ void SceneSession::HandleSubSessionSurfaceNode(bool isAdd) } } - if (WindowHelper::IsSubWindow(GetWindowType()) && IsFollowParentMultiScreenPolicy()) { + if (WindowHelper::IsSubWindow(GetWindowType()) && + (IsFollowParentMultiScreenPolicy() || (!isAdd && cloneNodeCount_ > 0))) { WSRect targetRect = isAdd ? ConvertRelativeRectToGlobal(winRect_, GetScreenId()) : ConvertGlobalRectToRelative(winRect_, GetScreenId()); TLOGI(WmsLogTag::WMS_LAYOUT, "isAdd:%{public}d targetRect:%{public}s", isAdd, targetRect.ToString().c_str()); @@ -3840,7 +3842,7 @@ void SceneSession::HandleSubSessionSurfaceNode(bool isAdd) AddSurfaceNodeToScreen(); SetSurfaceBounds(targetRect, true, true); } else { - RemoveSufaceNodeFromScreen(); + RemoveSurfaceNodeFromScreen(); SetSurfaceBounds(targetRect, false, false); { std::lock_guard lock(displayIdSetDuringMoveToMutex_); @@ -3850,8 +3852,10 @@ void SceneSession::HandleSubSessionSurfaceNode(bool isAdd) if (lastRect.IsInvalid()) { return; } - NotifySessionRectChange(lastRect, SizeChangeReason::UNDEFINED); + auto moveConfiguration = GetRequestMoveConfiguration(); + NotifySessionRectChange(lastRect, SizeChangeReason::UNDEFINED, moveConfiguration.displayId); SetRequestRectWhenFollowParent({0, 0, 0, 0}); + SetRequestMoveConfiguration({DISPLAY_ID_INVALID}); } } } @@ -3922,8 +3926,8 @@ void SceneSession::SetSurfaceBounds(const WSRect& rect, bool isGlobal, bool need { HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "SceneSession::SetSurfaceBounds id:%d [%d, %d, %d, %d] reason:%u", GetPersistentId(), rect.posX_, rect.posY_, rect.width_, rect.height_, reason_); - TLOGD(WmsLogTag::WMS_LAYOUT, "rect: %{public}s isGlobal: %{public}d needFlush: %{public}d", - rect.ToString().c_str(), isGlobal, needFlush); + TLOGD(WmsLogTag::WMS_LAYOUT, "id: %{public}d, rect: %{public}s isGlobal: %{public}d needFlush: %{public}d", + GetPersistentId(), rect.ToString().c_str(), isGlobal, needFlush); auto rsTransaction = RSTransactionProxy::GetInstance(); if (rsTransaction != nullptr && needFlush) { rsTransaction->Begin(); @@ -7705,8 +7709,8 @@ void SceneSession::UpdateNewSizeForPCWindow() sessionStage_->UpdateRect(winRect, SizeChangeReason::UPDATE_DPI_SYNC); NotifySessionRectChange(winRect, SizeChangeReason::UPDATE_DPI_SYNC); TLOGI(WmsLogTag::WMS_LAYOUT_PC, "left: %{public}d, top: %{public}d, width: %{public}u, " - "height: %{public}u, Id: %{public}u", winRect.posX_, winRect.posY_, winRect.width_, - winRect.height_, GetPersistentId()); + "height: %{public}u, Id: %{public}u, displayId: %{public}" PRIu64, winRect.posX_, winRect.posY_, + winRect.width_, winRect.height_, GetPersistentId(), GetDisplayId()); } } displayChangedByMoveDrag_ = false; diff --git a/window_scene/session/host/src/sub_session.cpp b/window_scene/session/host/src/sub_session.cpp index 97cd53ec3b7d2211a0cf363bbc93dec9d6b02d4e..f8dfea6867e4b12d719ef50de891556cabbcc9c4 100644 --- a/window_scene/session/host/src/sub_session.cpp +++ b/window_scene/session/host/src/sub_session.cpp @@ -392,6 +392,7 @@ void SubSession::HandleCrossMoveToSurfaceNode(WSRect& globalRect) } movedSurfaceNode->SetPositionZ(GetZOrder()); screenSession->GetDisplayNode()->AddCrossScreenChild(movedSurfaceNode, SUFFIX_INDEX, true); + cloneNodeCount_++; movedSurfaceNode->SetIsCrossNode(true); TLOGI(WmsLogTag::WMS_LAYOUT, "Add sub window to display:%{public}" PRIu64 " persistentId:%{public}d", displayId, GetPersistentId()); @@ -441,10 +442,10 @@ void SubSession::AddSurfaceNodeToScreen() originDisplayId = GetScreenId(); Session::SetOriginDisplayId(originDisplayId); } - WSRect currRect = winRect_; + WSRect targetRect = ConvertRelativeRectToGlobal(winRect_, GetScreenId()); TLOGI(WmsLogTag::WMS_LAYOUT, "originDisplayId:%{public}" PRIu64 ", originalPositionZ:%{public}f, " "winRect:%{public}s", GetOriginDisplayId(), originalPositionZ, winRect_.ToString().c_str()); - for (const auto displayId : GetNewDisplayIdsDuringMoveTo(currRect)) { + for (const auto displayId : GetNewDisplayIdsDuringMoveTo(targetRect)) { if (displayId == originDisplayId) { continue; } @@ -463,6 +464,7 @@ void SubSession::AddSurfaceNodeToScreen() } currSurfacedNode->SetPositionZ(GetZOrder()); screenSession->GetDisplayNode()->AddCrossScreenChild(currSurfacedNode, SUFFIX_INDEX, true); + cloneNodeCount_++; currSurfacedNode->SetIsCrossNode(true); TLOGI(WmsLogTag::WMS_LAYOUT, "Add sub window to display:%{public}" PRIu64 " persistentId:%{public}d", displayId, GetPersistentId()); @@ -470,7 +472,7 @@ void SubSession::AddSurfaceNodeToScreen() RSTransaction::FlushImplicitTransaction(); } -void SubSession::RemoveSufaceNodeFromScreen() +void SubSession::RemoveSurfaceNodeFromScreen() { auto currSurfacedNode = GetSurfaceNodeForMoveDrag(); if (currSurfacedNode == nullptr) { @@ -497,6 +499,7 @@ void SubSession::RemoveSufaceNodeFromScreen() } currSurfacedNode->SetPositionZ(moveDragController_->GetOriginalPositionZ()); screenSession->GetDisplayNode()->RemoveCrossScreenChild(currSurfacedNode); + cloneNodeCount_--; currSurfacedNode->SetIsCrossNode(false); TLOGI(WmsLogTag::WMS_LAYOUT, "Remove sub window to display:%{public}" PRIu64 " persistentId:%{public}d", displayId, GetPersistentId()); diff --git a/window_scene/session_manager/src/scene_session_manager.cpp b/window_scene/session_manager/src/scene_session_manager.cpp index a9df604a2a0d0f23e39f5636a11feffd99a51ebc..a88ab932b3e2869ef2a39a3df55facefd530b7d2 100644 --- a/window_scene/session_manager/src/scene_session_manager.cpp +++ b/window_scene/session_manager/src/scene_session_manager.cpp @@ -3574,10 +3574,10 @@ SessionInfo SceneSessionManager::RecoverSessionInfo(const sptrNotifyFollowParentMultiScreenPolicy(info.isFollowParentMultiScreenPolicy); NotifyCreateSpecificSession(sceneSession, property, property->GetWindowType()); CacheSpecificSessionForRecovering(sceneSession, property); NotifySessionUnfocusedToClient(persistentId); diff --git a/window_scene/test/unittest/scene_session_layout_test.cpp b/window_scene/test/unittest/scene_session_layout_test.cpp index ad37ae9884841a6023e6e2a8ce76963710359ae2..048f54c4e4e23e01c27402b6219a6de48e36df9a 100644 --- a/window_scene/test/unittest/scene_session_layout_test.cpp +++ b/window_scene/test/unittest/scene_session_layout_test.cpp @@ -765,7 +765,7 @@ HWTEST_F(SceneSessionLayoutTest, IsNeedConvertToRelativeRect, TestSize.Level1) subSceneSession->parentSession_ = sceneSession; ASSERT_EQ(sceneSession->IsNeedConvertToRelativeRect(SizeChangeReason::MAXIMIZE), false); - ASSERT_EQ(sceneSession->IsNeedConvertToRelativeRect(SizeChangeReason::DRAG_START), true); + ASSERT_EQ(sceneSession->IsNeedConvertToRelativeRect(SizeChangeReason::DRAG_MOVE), true); sceneSession->moveDragController_->isStartMove_ = true; sceneSession->moveDragController_->isStartDrag_ = false; diff --git a/window_scene/test/unittest/sub_session_test.cpp b/window_scene/test/unittest/sub_session_test.cpp index b2a664ba35dfc87c378b3095f93d7f01c785b2f9..65d97be991dd8ea3aef4b72dd55ae457d0103099 100644 --- a/window_scene/test/unittest/sub_session_test.cpp +++ b/window_scene/test/unittest/sub_session_test.cpp @@ -600,18 +600,18 @@ HWTEST_F(SubSessionTest, AddSurfaceNodeToScreen, TestSize.Level1) } /** - * @tc.name: RemoveSufaceNodeFromScreen - * @tc.desc: RemoveSufaceNodeFromScreen + * @tc.name: RemoveSurfaceNodeFromScreen + * @tc.desc: RemoveSurfaceNodeFromScreen * @tc.type: FUNC */ -HWTEST_F(SubSessionTest, RemoveSufaceNodeFromScreen, TestSize.Level1) +HWTEST_F(SubSessionTest, RemoveSurfaceNodeFromScreen, TestSize.Level1) { SessionInfo info; - info.abilityName_ = "RemoveSufaceNodeFromScreen"; - info.bundleName_ = "RemoveSufaceNodeFromScreen"; + info.abilityName_ = "RemoveSurfaceNodeFromScreen"; + info.bundleName_ = "RemoveSurfaceNodeFromScreen"; sptr sceneSession = sptr::MakeSptr(info, nullptr); sceneSession->GetSessionProperty()->SetWindowType(WindowType::WINDOW_TYPE_APP_SUB_WINDOW); - sceneSession->RemoveSufaceNodeFromScreen(); + sceneSession->RemoveSurfaceNodeFromScreen(); struct RSSurfaceNodeConfig rsSurfaceNodeConfig; rsSurfaceNodeConfig.SurfaceNodeName = info.abilityName_; RSSurfaceNodeType rsSurfaceNodeType = RSSurfaceNodeType::DEFAULT; @@ -621,10 +621,10 @@ HWTEST_F(SubSessionTest, RemoveSufaceNodeFromScreen, TestSize.Level1) sceneSession->SetOriginDisplayId(DISPLAY_ID_INVALID); sceneSession->displayIdSetDuringMoveTo_.insert(0); sceneSession->displayIdSetDuringMoveTo_.insert(888); - sceneSession->RemoveSufaceNodeFromScreen(); + sceneSession->RemoveSurfaceNodeFromScreen(); ASSERT_EQ(DISPLAY_ID_INVALID, sceneSession->GetOriginDisplayId()); sceneSession->SetOriginDisplayId(DISPLAY_ID_INVALID); - sceneSession->RemoveSufaceNodeFromScreen(); + sceneSession->RemoveSurfaceNodeFromScreen(); ASSERT_EQ(DISPLAY_ID_INVALID, sceneSession->GetOriginDisplayId()); } diff --git a/wm/src/window_scene_session_impl.cpp b/wm/src/window_scene_session_impl.cpp index 0cf3db9cafc098471750b39b4e6c1b80303fb1a1..29900e38c93cc1ef70a22ba4867fb93012fc4926 100644 --- a/wm/src/window_scene_session_impl.cpp +++ b/wm/src/window_scene_session_impl.cpp @@ -4994,6 +4994,7 @@ WMError WindowSceneSessionImpl::SetFollowParentMultiScreenPolicy(bool enabled) auto hostSession = GetHostSession(); CHECK_HOST_SESSION_RETURN_ERROR_IF_NULL(hostSession, WMError::WM_ERROR_INVALID_WINDOW); hostSession->NotifyFollowParentMultiScreenPolicy(enabled); + property_->EditSessionInfo().isFollowParentMultiScreenPolicy = enabled; return WMError::WM_OK; }