!10083 add moveWindowToGlobal

Merge pull request !10083 from qiwenchao/master
This commit is contained in:
openharmony_ci 2024-10-31 09:30:46 +00:00 committed by Gitee
commit 5674d74841
No known key found for this signature in database
GPG Key ID: 173E9B9CA92EEF8F
14 changed files with 183 additions and 8 deletions

View File

@ -898,6 +898,14 @@ public:
* @return WMError
*/
virtual WMError MoveToAsync(int32_t x, int32_t y) { return WMError::WM_ERROR_DEVICE_NOT_SUPPORT; }
/**
* @brief move the window to global (x, y)
*
* @param x
* @param y
* @return WMError
*/
virtual WMError MoveWindowToGlobal(int32_t x, int32_t y) { return WMError::WM_ERROR_DEVICE_NOT_SUPPORT; }
/**
* @brief Get window global scaled rect.
*

View File

@ -195,6 +195,14 @@ napi_value JsWindow::MoveWindowToAsync(napi_env env, napi_callback_info info)
return (me != nullptr) ? me->OnMoveWindowToAsync(env, info) : nullptr;
}
/** @note @window.layout */
napi_value JsWindow::MoveWindowToGlobal(napi_env env, napi_callback_info info)
{
TLOGI(WmsLogTag::WMS_LAYOUT, "MoveWindowToGlobal");
JsWindow* me = CheckParamsAndGetThis<JsWindow>(env, info);
return (me != nullptr) ? me->OnMoveWindowToGlobal(env, info) : nullptr;
}
/** @note @window.layout */
napi_value JsWindow::GetGlobalScaledRect(napi_env env, napi_callback_info info)
{
@ -1600,6 +1608,80 @@ napi_value JsWindow::OnMoveWindowToAsync(napi_env env, napi_callback_info info)
return result;
}
static void SetMoveWindowToGlobalAsyncTask(NapiAsyncTask::ExecuteCallback &execute,
NapiAsyncTask::CompleteCallback &complete, wptr<Window> weakToken, int32_t x, int32_t y)
{
std::shared_ptr<WmErrorCode> errCodePtr = std::make_shared<WmErrorCode>(WmErrorCode::WM_OK);
execute = [weakToken, errCodePtr, x, y] {
if (errCodePtr == nullptr) {
return;
}
if (*errCodePtr != WmErrorCode::WM_OK) {
return;
}
auto weakWindow = weakToken.promote();
if (weakWindow == nullptr) {
TLOGE(WmsLogTag::WMS_LAYOUT, "window is nullptr");
*errCodePtr = WmErrorCode::WM_ERROR_STATE_ABNORMALLY;
return;
}
*errCodePtr = WM_JS_TO_ERROR_CODE_MAP.at(weakWindow->MoveWindowToGlobal(x, y));
TLOGI(WmsLogTag::WMS_LAYOUT, "Window [%{public}u, %{public}s] move end, err = %{public}d",
weakWindow->GetWindowId(), weakWindow->GetWindowName().c_str(), *errCodePtr);
};
complete = [weakToken, errCodePtr](napi_env env, NapiAsyncTask& task, int32_t status) {
if (errCodePtr == nullptr) {
task.Reject(env, JsErrUtils::CreateJsError(env, WmErrorCode::WM_ERROR_STATE_ABNORMALLY));
return;
}
if (*errCodePtr == WmErrorCode::WM_OK) {
task.Resolve(env, NapiGetUndefined(env));
} else {
task.Reject(env, JsErrUtils::CreateJsError(
env, *errCodePtr, "JsWindow::OnMoveWindowToGlobal failed"));
}
};
}
/** @note @window.layout */
napi_value JsWindow::OnMoveWindowToGlobal(napi_env env, napi_callback_info info)
{
WmErrorCode errCode = WmErrorCode::WM_OK;
size_t argc = 4;
napi_value argv[4] = {nullptr};
napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr);
if (argc < 2) { // 2:minimum param num
WLOGFE("Argc is invalid: %{public}zu", argc);
errCode = WmErrorCode::WM_ERROR_INVALID_PARAM;
}
int32_t x = 0;
if (errCode == WmErrorCode::WM_OK && !ConvertFromJsValue(env, argv[0], x)) {
WLOGFE("Failed to convert parameter to x");
errCode = WmErrorCode::WM_ERROR_INVALID_PARAM;
}
int32_t y = 0;
if (errCode == WmErrorCode::WM_OK && !ConvertFromJsValue(env, argv[1], y)) {
WLOGFE("Failed to convert parameter to y");
errCode = WmErrorCode::WM_ERROR_INVALID_PARAM;
}
if (errCode == WmErrorCode::WM_ERROR_INVALID_PARAM) {
return NapiThrowError(env, WmErrorCode::WM_ERROR_INVALID_PARAM);
}
wptr<Window> weakToken(windowToken_);
NapiAsyncTask::ExecuteCallback execute;
NapiAsyncTask::CompleteCallback complete;
SetMoveWindowToGlobalAsyncTask(execute, complete, weakToken, x, y);
// 2: params num; 2: index of callback
napi_value lastParam = (argc <= 2) ? nullptr :
((argv[2] != nullptr && GetType(env, argv[2]) == napi_function) ? argv[2] : nullptr);
napi_value result = nullptr;
NapiAsyncTask::Schedule("JsWindow::OnMoveWindowToGlobal",
env, CreateAsyncTaskWithLastParam(env, lastParam, std::move(execute), std::move(complete), &result));
return result;
}
/** @note @window.layout */
napi_value JsWindow::OnGetGlobalScaledRect(napi_env env, napi_callback_info info)
{
@ -6980,6 +7062,7 @@ void BindFunctions(napi_env env, napi_value object, const char* moduleName)
BindNativeFunction(env, object, "moveTo", moduleName, JsWindow::MoveTo);
BindNativeFunction(env, object, "moveWindowTo", moduleName, JsWindow::MoveWindowTo);
BindNativeFunction(env, object, "moveWindowToAsync", moduleName, JsWindow::MoveWindowToAsync);
BindNativeFunction(env, object, "moveWindowToGlobal", moduleName, JsWindow::MoveWindowToGlobal);
BindNativeFunction(env, object, "getGlobalRect", moduleName, JsWindow::GetGlobalScaledRect);
BindNativeFunction(env, object, "resetSize", moduleName, JsWindow::Resize);
BindNativeFunction(env, object, "resize", moduleName, JsWindow::ResizeWindow);

View File

@ -57,6 +57,7 @@ public:
static napi_value MoveTo(napi_env env, napi_callback_info info);
static napi_value MoveWindowTo(napi_env env, napi_callback_info info);
static napi_value MoveWindowToAsync(napi_env env, napi_callback_info info);
static napi_value MoveWindowToGlobal(napi_env env, napi_callback_info info);
static napi_value GetGlobalScaledRect(napi_env env, napi_callback_info info);
static napi_value Resize(napi_env env, napi_callback_info info);
static napi_value ResizeWindow(napi_env env, napi_callback_info info);
@ -204,6 +205,7 @@ private:
napi_value OnMoveTo(napi_env env, napi_callback_info info);
napi_value OnMoveWindowTo(napi_env env, napi_callback_info info);
napi_value OnMoveWindowToAsync(napi_env env, napi_callback_info info);
napi_value OnMoveWindowToGlobal(napi_env env, napi_callback_info info);
napi_value OnGetGlobalScaledRect(napi_env env, napi_callback_info info);
napi_value OnResize(napi_env env, napi_callback_info info);
napi_value OnResizeWindow(napi_env env, napi_callback_info info);

View File

@ -173,6 +173,7 @@ public:
virtual WMError Hide(uint32_t reason = 0, bool withAnimation = false, bool isFromInnerkits = true) = 0;
virtual WMError MoveTo(int32_t x, int32_t y, bool isMoveToGlobal = false) = 0;
virtual WMError MoveToAsync(int32_t x, int32_t y) { return WMError::WM_ERROR_DEVICE_NOT_SUPPORT; }
virtual WMError MoveWindowToGlobal(int32_t x, int32_t y) { return WMError::WM_OK; }
virtual WMError GetGlobalScaledRect(Rect& globalScaledRect) { return WMError::WM_ERROR_DEVICE_NOT_SUPPORT; }
virtual WMError Resize(uint32_t width, uint32_t height) = 0;
virtual WMError ResizeAsync(uint32_t width, uint32_t height) { return WMError::WM_ERROR_DEVICE_NOT_SUPPORT; }

View File

@ -193,7 +193,8 @@ public:
bool isKeyboardShow, bool isRotating) {};
WSError UpdateRect(const WSRect& rect, SizeChangeReason reason,
const std::string& updateReason, const std::shared_ptr<RSTransaction>& rsTransaction = nullptr) override;
WSError UpdateSessionRect(const WSRect& rect, const SizeChangeReason reason, bool isGlobal = false) override;
WSError UpdateSessionRect(const WSRect& rect, const SizeChangeReason reason,
bool isGlobal = false, bool isFromMoveToGlobal = false) override;
WSError UpdateClientRect(const WSRect& rect) override;
WSError ChangeSessionVisibilityWithStatusBar(const sptr<AAFwk::SessionInfo> info, bool visible) override;
WSError PendingSessionActivation(const sptr<AAFwk::SessionInfo> info) override;

View File

@ -114,7 +114,10 @@ public:
* @return Returns WSError::WS_OK if called success, otherwise failed.
*/
virtual WSError UpdateSessionRect(
const WSRect& rect, const SizeChangeReason reason, bool isGlobal = false) { return WSError::WS_OK; }
const WSRect &rect, const SizeChangeReason reason, bool isGlobal = false, bool isFromMoveToGlobal = false)
{
return WSError::WS_OK;
}
virtual WSError UpdateClientRect(const WSRect& rect) { return WSError::WS_OK; }
virtual WMError GetGlobalScaledRect(Rect& globalScaledRect) { return WMError::WM_OK; }
virtual WSError OnNeedAvoid(bool status) { return WSError::WS_OK; }

View File

@ -52,7 +52,8 @@ public:
WSError OnTitleAndDockHoverShowChange(bool isTitleHoverShown = true,
bool isDockHoverShown = true) override;
WSError RaiseToAppTop() override;
WSError UpdateSessionRect(const WSRect& rect, const SizeChangeReason reason, bool isGlobal = false) override;
WSError UpdateSessionRect(const WSRect &rect, const SizeChangeReason reason, bool isGlobal = false,
bool isFromMoveToGlobal = false) override;
WMError GetGlobalScaledRect(Rect& globalScaledRect) override;
WSError UpdateClientRect(const WSRect& rect) override;
WSError OnNeedAvoid(bool status) override;

View File

@ -1172,7 +1172,8 @@ void SceneSession::UpdateSessionRectInner(const WSRect& rect, const SizeChangeRe
}
/** @note @window.layout */
WSError SceneSession::UpdateSessionRect(const WSRect& rect, const SizeChangeReason reason, bool isGlobal)
WSError SceneSession::UpdateSessionRect(
const WSRect &rect, const SizeChangeReason reason, bool isGlobal, bool isFromMoveToGlobal)
{
if ((reason == SizeChangeReason::MOVE || reason == SizeChangeReason::RESIZE) &&
GetWindowType() == WindowType::WINDOW_TYPE_PIP) {
@ -1191,6 +1192,17 @@ WSError SceneSession::UpdateSessionRect(const WSRect& rect, const SizeChangeReas
}
}
}
if (isFromMoveToGlobal && WindowHelper::IsSubWindow(Session::GetWindowType()) &&
(systemConfig_.IsPhoneWindow() ||
(systemConfig_.IsPadWindow() && !IsFreeMultiWindowMode()))) {
auto parentSession = GetParentSession();
if (parentSession && parentSession->GetFloatingScale() != 0) {
Rect parentGlobalRect;
WMError errorCode = parentSession->GetGlobalScaledRect(parentGlobalRect);
newRect.posX_ = (newRect.posX_ - parentGlobalRect.posX_) / parentSession->GetFloatingScale();
newRect.posY_ = (newRect.posY_ - parentGlobalRect.posY_) / parentSession->GetFloatingScale();
}
}
Session::RectCheckProcess();
auto task = [weakThis = wptr(this), newRect, reason]() {
auto session = weakThis.promote();

View File

@ -704,7 +704,8 @@ WSError SessionProxy::OnTitleAndDockHoverShowChange(bool isTitleHoverShown, bool
}
/** @note @window.layout */
WSError SessionProxy::UpdateSessionRect(const WSRect& rect, const SizeChangeReason reason, bool isGlobal)
WSError SessionProxy::UpdateSessionRect(const WSRect& rect, const SizeChangeReason reason,
bool isGlobal, bool isFromMoveToGlobal)
{
TLOGI(WmsLogTag::WMS_LAYOUT, "Rect [%{public}d, %{public}d, %{public}u, %{public}u]",
rect.posX_, rect.posY_, rect.width_, rect.height_);
@ -733,6 +734,11 @@ WSError SessionProxy::UpdateSessionRect(const WSRect& rect, const SizeChangeReas
return WSError::WS_ERROR_IPC_FAILED;
}
if (!data.WriteBool(isFromMoveToGlobal)) {
TLOGE(WmsLogTag::WMS_LAYOUT, "Write bool failed");
return WSError::WS_ERROR_IPC_FAILED;
}
sptr<IRemoteObject> remote = Remote();
if (remote == nullptr) {
TLOGE(WmsLogTag::WMS_LAYOUT, "remote is null");

View File

@ -652,7 +652,12 @@ int SessionStub::HandleUpdateSessionRect(MessageParcel& data, MessageParcel& rep
TLOGE(WmsLogTag::WMS_LAYOUT, "read isGlobal failed");
return ERR_INVALID_DATA;
}
WSError errCode = UpdateSessionRect(rect, reason, isGlobal);
auto isFromMoveToGlobal = false;
if (!data.ReadBool(isFromMoveToGlobal)) {
TLOGE(WmsLogTag::WMS_LAYOUT, "read isFromMoveToGlobal failed");
return ERR_INVALID_DATA;
}
WSError errCode = UpdateSessionRect(rect, reason, isGlobal, isFromMoveToGlobal);
reply.WriteUint32(static_cast<uint32_t>(errCode));
return ERR_NONE;
}

View File

@ -45,7 +45,8 @@ public:
: SceneSession(info, specificCallback) {}
~KSSceneSessionMocker() {}
WSError UpdateSessionRect(const WSRect& rect, const SizeChangeReason reason, bool isGlobal = false) override
WSError UpdateSessionRect(const WSRect& rect, const SizeChangeReason reason, bool isGlobal = false,
bool isFromMoveToGlobal = false) override
{
updateRectCallback_(rect, reason);
return WSError::WS_OK;

View File

@ -38,7 +38,8 @@ public:
MOCK_METHOD2(Background, WSError(bool isFromClient, const std::string& identityToken));
MOCK_METHOD2(Disconnect, WSError(bool isFromClient, const std::string& identityToken));
MOCK_METHOD3(UpdateSessionRect, WSError(const WSRect& rect, const SizeChangeReason reason, bool isGlobal));
MOCK_METHOD4(UpdateSessionRect, WSError(const WSRect& rect, const SizeChangeReason reason,
bool isGlobal, bool isFromMoveToGlobal));
MOCK_METHOD1(UpdateClientRect, WSError(const WSRect& rect));
MOCK_METHOD0(Recover, WSError(void));

View File

@ -50,6 +50,7 @@ public:
WindowMode GetMode() const override;
WMError MoveTo(int32_t x, int32_t y, bool isMoveToGlobal = false) override;
WMError MoveToAsync(int32_t x, int32_t y) override;
WMError MoveWindowToGlobal(int32_t x, int32_t y) override;
WMError GetGlobalScaledRect(Rect& globalScaledRect) override;
WMError Resize(uint32_t width, uint32_t height) override;
WMError ResizeAsync(uint32_t width, uint32_t height) override;

View File

@ -1471,6 +1471,56 @@ WMError WindowSceneSessionImpl::MoveTo(int32_t x, int32_t y, bool isMoveToGlobal
return static_cast<WMError>(ret);
}
WMError WindowSceneSessionImpl::MoveWindowToGlobal(int32_t x, int32_t y)
{
TLOGI(WmsLogTag::WMS_LAYOUT, "Id:%{public}d MoveTo %{public}d %{public}d", property_->GetPersistentId(), x, y);
if (IsWindowSessionInvalid()) {
return WMError::WM_ERROR_INVALID_WINDOW;
}
if (GetMode() != WindowMode::WINDOW_MODE_FLOATING) {
TLOGW(WmsLogTag::WMS_LAYOUT, "FullScreen window should not move, winId:%{public}u, mode:%{public}u",
GetWindowId(), GetMode());
return WMError::WM_ERROR_OPER_FULLSCREEN_FAILED;
}
if (property_->GetWindowType() == WindowType::WINDOW_TYPE_PIP) {
TLOGW(WmsLogTag::WMS_LAYOUT, "Unsupported operation for pip window");
return WMError::WM_ERROR_INVALID_OPERATION;
}
const auto& windowRect = GetRect();
const auto& requestRect = GetRequestRect();
Rect newRect = { x, y, requestRect.width_, requestRect.height_ }; // must keep x/y
TLOGI(WmsLogTag::WMS_LAYOUT, "Id:%{public}d, state: %{public}d, type: %{public}d, mode: %{public}d, requestRect: "
"[%{public}d, %{public}d, %{public}d, %{public}d], windowRect: [%{public}d, %{public}d, "
"%{public}d, %{public}d], newRect: [%{public}d, %{public}d, %{public}d, %{public}d]",
property_->GetPersistentId(), state_, GetType(), GetMode(), requestRect.posX_, requestRect.posY_,
requestRect.width_, requestRect.height_, windowRect.posX_, windowRect.posY_,
windowRect.width_, windowRect.height_, newRect.posX_, newRect.posY_,
newRect.width_, newRect.height_);
property_->SetRequestRect(newRect);
WSRect wsRect = { newRect.posX_, newRect.posY_, newRect.width_, newRect.height_ };
auto hostSession = GetHostSession();
CHECK_HOST_SESSION_RETURN_ERROR_IF_NULL(hostSession, WMError::WM_ERROR_INVALID_WINDOW);
auto ret = hostSession->UpdateSessionRect(wsRect, SizeChangeReason::MOVE, false, true);
if (state_ == WindowState::STATE_SHOWN) {
layoutCallback_->ResetMoveToLock();
auto startTime = std::chrono::duration_cast<std::chrono::milliseconds>(
std::chrono::system_clock::now().time_since_epoch()).count();
layoutCallback_->GetMoveToAsyncResult(WINDOW_LAYOUT_TIMEOUT);
auto endTime = std::chrono::duration_cast<std::chrono::milliseconds>(
std::chrono::system_clock::now().time_since_epoch()).count();
auto waitTime = endTime - startTime;
if (waitTime >= WINDOW_LAYOUT_TIMEOUT) {
TLOGW(WmsLogTag::WMS_LAYOUT, "Layout timeout, Id:%{public}d", property_->GetPersistentId());
layoutCallback_->GetMoveToAsyncResult(WINDOW_LAYOUT_TIMEOUT);
}
}
return static_cast<WMError>(ret);
}
WMError WindowSceneSessionImpl::MoveToAsync(int32_t x, int32_t y)
{
if (IsWindowSessionInvalid()) {