From 2c81526af13cd830a35f1a7f749d86817e9b9e32 Mon Sep 17 00:00:00 2001 From: wlj Date: Mon, 29 Aug 2022 11:15:44 +0800 Subject: [PATCH] display zoom Signed-off-by: wlj Change-Id: I03785db7199688fa2365e8be9ebc6fc3fa600f0b --- .../wm/window_accessibility_controller.h | 1 + interfaces/innerkits/wm/wm_common.h | 24 ++ .../window_runtime/window_napi/js_window.cpp | 27 -- previewer/mock/pointer_event.h | 51 +++ test/fuzztest/wms/windowipc_fuzzer/BUILD.gn | 1 + test/systemtest/wms/BUILD.gn | 1 + .../wms/window_display_zoom_test.cpp | 33 +- test/systemtest/wms/window_rotation_test.cpp | 38 ++ utils/BUILD.gn | 6 +- utils/include/window_property.h | 17 + utils/include/wm_common_inner.h | 3 + utils/src/window_property.cpp | 129 ++++++- wm/include/window_adapter.h | 3 + wm/include/window_agent.h | 1 + wm/include/window_impl.h | 4 +- wm/include/zidl/window_interface.h | 2 + wm/include/zidl/window_proxy.h | 1 + wm/src/window_accessibility_controller.cpp | 4 + wm/src/window_adapter.cpp | 18 + wm/src/window_agent.cpp | 9 + wm/src/window_impl.cpp | 66 ++-- wm/src/zidl/window_proxy.cpp | 23 ++ wm/src/zidl/window_stub.cpp | 8 + wmserver/BUILD.gn | 1 + wmserver/include/display_zoom_controller.h | 62 +++ wmserver/include/window_controller.h | 8 +- wmserver/include/window_manager_service.h | 3 + wmserver/include/window_node.h | 2 + wmserver/include/window_node_container.h | 1 + wmserver/include/window_root.h | 1 + .../include/zidl/window_manager_interface.h | 6 + wmserver/include/zidl/window_manager_proxy.h | 3 + wmserver/src/display_zoom_controller.cpp | 353 ++++++++++++++++++ wmserver/src/drag_controller.cpp | 3 + wmserver/src/input_window_monitor.cpp | 2 +- wmserver/src/window_controller.cpp | 26 ++ wmserver/src/window_layout_policy.cpp | 2 +- wmserver/src/window_manager_service.cpp | 25 +- wmserver/src/window_node.cpp | 14 + wmserver/src/window_node_container.cpp | 14 + wmserver/src/window_root.cpp | 17 + wmserver/src/zidl/window_manager_proxy.cpp | 65 ++++ wmserver/src/zidl/window_manager_stub.cpp | 17 + .../unittest/avoid_area_controller_test.cpp | 1 + wmserver/test/unittest/window_node_test.cpp | 1 + 45 files changed, 1017 insertions(+), 80 deletions(-) create mode 100644 wmserver/include/display_zoom_controller.h create mode 100644 wmserver/src/display_zoom_controller.cpp diff --git a/interfaces/innerkits/wm/window_accessibility_controller.h b/interfaces/innerkits/wm/window_accessibility_controller.h index a0b77715dc..66683db805 100644 --- a/interfaces/innerkits/wm/window_accessibility_controller.h +++ b/interfaces/innerkits/wm/window_accessibility_controller.h @@ -23,6 +23,7 @@ namespace OHOS::Rosen { class WindowAccessibilityController { WM_DECLARE_SINGLE_INSTANCE_BASE(WindowAccessibilityController); public: + // below three interfaces only take effect for the main display void SetAnchorAndScale(int32_t x, int32_t y, float scale); void SetAnchorOffset(int32_t deltaX, int32_t deltaY); void OffWindowZoom(); diff --git a/interfaces/innerkits/wm/wm_common.h b/interfaces/innerkits/wm/wm_common.h index d6e60d1cfb..40f8cfad30 100644 --- a/interfaces/innerkits/wm/wm_common.h +++ b/interfaces/innerkits/wm/wm_common.h @@ -240,6 +240,30 @@ public: static Transform I; return I; } + + bool Marshalling(Parcel& parcel) const + { + return parcel.WriteFloat(pivotX_) && parcel.WriteFloat(pivotY_) && + parcel.WriteFloat(scaleX_) && parcel.WriteFloat(scaleY_) && parcel.WriteFloat(scaleZ_) && + parcel.WriteFloat(rotationX_) && parcel.WriteFloat(rotationY_) && + parcel.WriteFloat(rotationZ_) && parcel.WriteFloat(translateX_) && + parcel.WriteFloat(translateY_) && parcel.WriteFloat(translateZ_); + } + + void Unmarshalling(Parcel& parcel) + { + pivotX_ = parcel.ReadFloat(); + pivotY_ = parcel.ReadFloat(); + scaleX_ = parcel.ReadFloat(); + scaleY_ = parcel.ReadFloat(); + scaleZ_ = parcel.ReadFloat(); + rotationX_ = parcel.ReadFloat(); + rotationY_ = parcel.ReadFloat(); + rotationZ_ = parcel.ReadFloat(); + translateX_ = parcel.ReadFloat(); + translateY_ = parcel.ReadFloat(); + translateZ_ = parcel.ReadFloat(); + } private: static inline bool NearZero(float val) { 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 d728d65bc4..4847c20340 100644 --- a/interfaces/kits/napi/window_runtime/window_napi/js_window.cpp +++ b/interfaces/kits/napi/window_runtime/window_napi/js_window.cpp @@ -2065,38 +2065,29 @@ static bool IsScaleValid(double data) bool JsWindow::ParseScaleOption(NativeEngine& engine, NativeObject* jsObject, Transform& trans) { - auto surfaceNode = windowToken_->GetSurfaceNode(); - if (surfaceNode == nullptr) { - WLOGFE("[NAPI] surfaceNode is nullptr"); - return false; - } double data = 0.0f; if (ParseJsDoubleValue(jsObject, engine, "pivotX", data)) { if (!IsPivotValid(data)) { return false; } - surfaceNode->SetPivotX(data); trans.pivotX_ = data; } if (ParseJsDoubleValue(jsObject, engine, "pivotY", data)) { if (!IsPivotValid(data)) { return false; } - surfaceNode->SetPivotY(data); trans.pivotY_ = data; } if (ParseJsDoubleValue(jsObject, engine, "x", data)) { if (!IsScaleValid(data)) { return false; } - surfaceNode->SetScaleX(data); trans.scaleX_ = data; } if (ParseJsDoubleValue(jsObject, engine, "y", data)) { if (!IsScaleValid(data)) { return false; } - surfaceNode->SetScaleY(data); trans.scaleY_ = data; } return true; @@ -2132,36 +2123,26 @@ NativeValue* JsWindow::OnScale(NativeEngine& engine, NativeCallbackInfo& info) bool JsWindow::ParseRotateOption(NativeEngine& engine, NativeObject* jsObject, Transform& trans) { - auto surfaceNode = windowToken_->GetSurfaceNode(); - if (surfaceNode == nullptr) { - WLOGFE("[NAPI] surfaceNode is nullptr"); - return false; - } double data = 0.0f; if (ParseJsDoubleValue(jsObject, engine, "pivotX", data)) { if (!IsPivotValid(data)) { return false; } - surfaceNode->SetPivotX(data); trans.pivotX_ = data; } if (ParseJsDoubleValue(jsObject, engine, "pivotY", data)) { if (!IsPivotValid(data)) { return false; } - surfaceNode->SetPivotY(data); trans.pivotY_ = data; } if (ParseJsDoubleValue(jsObject, engine, "x", data)) { - surfaceNode->SetRotationX(data); trans.rotationX_ = data; } if (ParseJsDoubleValue(jsObject, engine, "y", data)) { - surfaceNode->SetRotationY(data); trans.rotationY_ = data; } if (ParseJsDoubleValue(jsObject, engine, "z", data)) { - surfaceNode->SetRotation(data); trans.rotationZ_ = data; } return true; @@ -2199,22 +2180,14 @@ NativeValue* JsWindow::OnRotate(NativeEngine& engine, NativeCallbackInfo& info) bool JsWindow::ParseTranslateOption(NativeEngine& engine, NativeObject* jsObject, Transform& trans) { - auto surfaceNode = windowToken_->GetSurfaceNode(); - if (surfaceNode == nullptr) { - WLOGFE("[NAPI] surfaceNode is nullptr"); - return false; - } double data = 0.0f; if (ParseJsDoubleValue(jsObject, engine, "x", data)) { - surfaceNode->SetTranslateX(data); trans.translateX_ = data; } if (ParseJsDoubleValue(jsObject, engine, "y", data)) { - surfaceNode->SetTranslateY(data); trans.translateY_ = data; } if (ParseJsDoubleValue(jsObject, engine, "z", data)) { - surfaceNode->SetTranslateZ(data); trans.translateZ_ = data; } return true; diff --git a/previewer/mock/pointer_event.h b/previewer/mock/pointer_event.h index 4a4cb5036e..9e3e04cd1c 100644 --- a/previewer/mock/pointer_event.h +++ b/previewer/mock/pointer_event.h @@ -46,6 +46,57 @@ public: { return 0; } + + class PointerItem { + public: + int32_t pointerId_ {}; + int32_t GetDisplayX() const + { + return 0; + } + + int32_t GetDisplayY() const + { + return 0; + } + + void SetDisplayY(int32_t y) + { + pointerId_ = y; + } + + void SetDisplayX(int32_t x) + { + pointerId_ = x; + } + + void SetWindowY(int32_t y) + { + pointerId_ = y; + } + + void SetWindowX(int32_t x) + { + pointerId_ = x; + } + }; + + bool GetPointerItem(int32_t pointerId, PointerItem &pointerItem) + { + pointerItem = PointerItem(); + pointerItem.pointerId_ = pointerId; + return true; + } + + void UpdatePointerItem(int32_t pointerId, PointerItem &pointerItem) + { + pointerItem.pointerId_ = pointerId; + } + + int32_t GetPointerId() const + { + return 0; + } }; } // namespace MMI } // namespace OHOS diff --git a/test/fuzztest/wms/windowipc_fuzzer/BUILD.gn b/test/fuzztest/wms/windowipc_fuzzer/BUILD.gn index e61727bbe3..4164bfc0ad 100644 --- a/test/fuzztest/wms/windowipc_fuzzer/BUILD.gn +++ b/test/fuzztest/wms/windowipc_fuzzer/BUILD.gn @@ -42,6 +42,7 @@ ohos_fuzztest("WindowIPCFuzzTest") { external_deps = [ "ability_runtime:ability_manager", + "input:libmmi-client", "samgr:samgr_proxy", ] } diff --git a/test/systemtest/wms/BUILD.gn b/test/systemtest/wms/BUILD.gn index 07d4bd0689..e54fe0d05b 100644 --- a/test/systemtest/wms/BUILD.gn +++ b/test/systemtest/wms/BUILD.gn @@ -23,6 +23,7 @@ group("systemtest") { ":wms_window_animation_transition_test", ":wms_window_app_floating_window_test", ":wms_window_dialogwindow_test", + ":wms_window_display_zoom_test", ":wms_window_drag_test", ":wms_window_effect_test", ":wms_window_focus_test", diff --git a/test/systemtest/wms/window_display_zoom_test.cpp b/test/systemtest/wms/window_display_zoom_test.cpp index ec8b5b1f89..0d96827524 100644 --- a/test/systemtest/wms/window_display_zoom_test.cpp +++ b/test/systemtest/wms/window_display_zoom_test.cpp @@ -226,6 +226,7 @@ HWTEST_F(WindowDisplayZoomTest, DisplayZoom05, Function | MediumTest | Level3) Transform animate; animate.translateX_ = -100; + animate.translateZ_ = 100; window->SetTransform(animate); sleep(1); @@ -233,8 +234,36 @@ HWTEST_F(WindowDisplayZoomTest, DisplayZoom05, Function | MediumTest | Level3) Rect rect = window->GetRect(); expect.pivotX_ = (0 - rect.posX_) * 1.0 / rect.width_; expect.pivotY_ = (0 - rect.posY_) * 1.0 / rect.height_; - expect.scaleX_ = expect.scaleY_ = 2; - expect.translateX_ = -200; + expect.scaleX_ = expect.scaleY_ = 1.7; + expect.translateX_ = -146; + expect.translateY_ = 93.6; + expect.translateZ_ = 0; + ASSERT_EQ(expect, implPtr->GetWindowProperty()->GetZoomTransform()); + + WindowAccessibilityController::GetInstance().OffWindowZoom(); + window->Destroy(); +} + +/** + * @tc.name: DisplayZoom06 + * @tc.desc: test speical window type + * @tc.type: FUNC + * @tc.require: issueI5NGWL + */ +HWTEST_F(WindowDisplayZoomTest, DisplayZoom06, Function | MediumTest | Level3) +{ + WindowAccessibilityController::GetInstance().SetAnchorAndScale(0, 0, 2); + sleep(1); + + windowInfo_.name = "DisplayZoom06"; + windowInfo_.type = WindowType::WINDOW_TYPE_INPUT_METHOD_FLOAT; + sptr window = Utils::CreateTestWindow(windowInfo_); + Window* ptr = window.GetRefPtr(); + WindowImpl* implPtr = (WindowImpl*)ptr; + ASSERT_EQ(WMError::WM_OK, window->Show()); + sleep(1); + + Transform expect; ASSERT_EQ(expect, implPtr->GetWindowProperty()->GetZoomTransform()); WindowAccessibilityController::GetInstance().OffWindowZoom(); diff --git a/test/systemtest/wms/window_rotation_test.cpp b/test/systemtest/wms/window_rotation_test.cpp index b7689df207..9eaf1f0481 100644 --- a/test/systemtest/wms/window_rotation_test.cpp +++ b/test/systemtest/wms/window_rotation_test.cpp @@ -21,6 +21,8 @@ #include "future.h" #include "screen_manager.h" #include "window_manager.h" +#include "window_accessibility_controller.h" +#include "window_impl.h" using namespace testing; using namespace testing::ext; @@ -285,6 +287,42 @@ HWTEST_F(WindowRotationTest, WindowRotationTest5, Function | MediumTest | Level3 defaultScreen->SetOrientation(Orientation::UNSPECIFIED); sleep(SPLIT_TEST_SLEEP_S); } + +/** +* @tc.name: WindowRotationTest6 +* @tc.desc: test window rotation when display is zoomed. +* @tc.type: FUNC +* @tc.require: issueI5NGWL +*/ +HWTEST_F(WindowRotationTest, WindowRotationTest6, Function | MediumTest | Level3) +{ + WindowAccessibilityController::GetInstance().SetAnchorAndScale(0, 0, 2); + sleep(SPLIT_TEST_SLEEP_S); + + fullInfo_.name = "fullscreen.2"; + fullInfo_.orientation_ = Orientation::REVERSE_HORIZONTAL; + const sptr& fullWindow = Utils::CreateTestWindow(fullInfo_); + activeWindows_.push_back(fullWindow); + ASSERT_EQ(WMError::WM_OK, fullWindow->Show()); + + DisplayId displayId = displayListener_->changeFuture_.GetResult(FUTURE_GET_RESULT_TIMEOUT); + ScreenId screenId = screenListener_->changeFuture_.GetResult(FUTURE_GET_RESULT_TIMEOUT); + auto screen = ScreenManager::GetInstance().GetScreenById(screenId); + auto display = DisplayManager::GetInstance().GetDisplayById(displayId); + ASSERT_EQ(Orientation::REVERSE_HORIZONTAL, screen->GetOrientation()); + ASSERT_EQ(Orientation::REVERSE_HORIZONTAL, display->GetOrientation()); + sleep(SPLIT_TEST_SLEEP_S); + + Window* ptr = fullWindow.GetRefPtr(); + WindowImpl* implPtr = (WindowImpl*)ptr; + Transform expect; + ASSERT_NE(expect, implPtr->GetWindowProperty()->GetZoomTransform()); + + WindowAccessibilityController::GetInstance().OffWindowZoom(); + ASSERT_EQ(WMError::WM_OK, fullWindow->Hide()); + screen->SetOrientation(Orientation::UNSPECIFIED); + sleep(SPLIT_TEST_SLEEP_S); +} } } // namespace Rosen } // namespace OHOS diff --git a/utils/BUILD.gn b/utils/BUILD.gn index 80961fb60f..373a7fa7cb 100644 --- a/utils/BUILD.gn +++ b/utils/BUILD.gn @@ -22,7 +22,10 @@ config("libwmutil_private_config") { } config("libwmutil_public_config") { - include_dirs = [ "//foundation/window/window_manager/utils/include" ] + include_dirs = [ + "//foundation/window/window_manager/utils/include", + "//foundation/multimodalinput/input/interfaces/native/innerkits/event/include", + ] } ## Build libwmutil.so @@ -69,6 +72,7 @@ ohos_shared_library("libwmutil") { "graphic_standard:surface", "hilog_native:libhilog", "hisysevent_native:libhisysevent", + "input:libmmi-client", "ipc:ipc_core", "multimedia_image_standard:image_native", "safwk:system_ability_fwk", diff --git a/utils/include/window_property.h b/utils/include/window_property.h index 7d6140c335..e8318ae3f9 100644 --- a/utils/include/window_property.h +++ b/utils/include/window_property.h @@ -21,6 +21,7 @@ #include #include #include "class_var_definition.h" +#include "pointer_event.h" #include "dm_common.h" #include "wm_common.h" #include "wm_common_inner.h" @@ -79,6 +80,12 @@ public: WindowSizeChangeReason GetWindowSizeChangeReason() const; void SetTransform(const Transform& trans); void ComputeTransform(); + void SetZoomTransform(const Transform& trans); + void SetDisplayZoomState(bool isDisplayZoomOn); + void SetAnimateWindowFlag(bool isAnimateWindow); + void UpdatePointerEvent(const std::shared_ptr& pointerEvent); + bool isNeedComputerTransform(); + void ClearTransformZAxisOffset(Transform& trans); const std::string& GetWindowName() const; Rect GetRequestRect() const; @@ -116,6 +123,9 @@ public: void GetTouchHotAreas(std::vector& rects) const; uint32_t GetAccessTokenId() const; const Transform& GetTransform() const; + Transform GetZoomTransform() const; + bool IsDisplayZoomOn() const; + bool IsAnimateWindow() const; WindowSizeLimits GetSizeLimits() const; WindowSizeLimits GetUpdatedSizeLimits() const; const TransformHelper::Matrix4& GetTransformMat() const; @@ -135,6 +145,7 @@ private: static void UnmarshallingTransform(Parcel& parcel, WindowProperty* property); bool MarshallingWindowSizeLimits(Parcel& parcel) const; static void UnmarshallingWindowSizeLimits(Parcel& parcel, WindowProperty* property); + void HandleComputeTransform(const Transform& trans); std::string windowName_; Rect requestRect_ { 0, 0, 0, 0 }; // window rect requested by the client (without decoration size) @@ -181,6 +192,12 @@ private: bool recomputeTransformMat_ { false }; TransformHelper::Matrix4 transformMat_ = TransformHelper::Matrix4::Identity; TransformHelper::Matrix4 worldTransformMat_ = TransformHelper::Matrix4::Identity; + // Display Zoom transform info + Transform zoomTrans_; // Compared with original window rect, including class member trans_ + bool reCalcuZoomTransformMat_ {true}; + // if scale of trans_ is less than 1.0, zoomTrans_ may be an identity matrix + bool isDisplayZoomOn_ {false}; + bool isAnimateWindow_ {false}; DEFINE_VAR_DEFAULT_FUNC_GET_SET(Orientation, RequestedOrientation, requestedOrientation, Orientation::UNSPECIFIED); WindowSizeLimits sizeLimits_; diff --git a/utils/include/wm_common_inner.h b/utils/include/wm_common_inner.h index 813649befd..dce507beed 100644 --- a/utils/include/wm_common_inner.h +++ b/utils/include/wm_common_inner.h @@ -322,6 +322,9 @@ struct AbilityInfo { namespace { constexpr float DEFAULT_SPLIT_RATIO = 0.5; constexpr float DEFAULT_ASPECT_RATIO = 0.66; + constexpr float DISPLAY_ZOOM_OFF_SCALE = 1.0; + constexpr float DISPLAY_ZOOM_MIN_SCALE = 2.0; + constexpr float DISPLAY_ZOOM_MAX_SCALE = 8.0; constexpr int32_t IVALID_DIALOG_WINDOW_ID = -1; constexpr uint32_t DIVIDER_WIDTH = 8; constexpr uint32_t WINDOW_TITLE_BAR_HEIGHT = 37; diff --git a/utils/src/window_property.cpp b/utils/src/window_property.cpp index f2b2924a77..d04333981f 100644 --- a/utils/src/window_property.cpp +++ b/utils/src/window_property.cpp @@ -33,9 +33,6 @@ void WindowProperty::SetWindowRect(const struct Rect& rect) { ComputeTransform(); windowRect_ = rect; - if (trans_ != Transform::Identity()) { - WindowHelper::GetTransformFromWorldMat4(worldTransformMat_, windowRect_, trans_); - } } void WindowProperty::SetDecoStatus(bool decoStatus) @@ -113,27 +110,113 @@ void WindowProperty::SetTransform(const Transform& trans) trans_ = trans; } +void WindowProperty::HandleComputeTransform(const Transform& trans) +{ + TransformHelper::Vector3 pivotPos = { windowRect_.posX_ + trans.pivotX_ * windowRect_.width_, + windowRect_.posY_ + trans.pivotY_ * windowRect_.height_, 0 }; + worldTransformMat_ = TransformHelper::CreateTranslation(-pivotPos) * + WindowHelper::ComputeWorldTransformMat4(trans) * + TransformHelper::CreateTranslation(pivotPos); + // transformMat = worldTransformMat * viewProjectionMat + transformMat_ = worldTransformMat_; + // Z component of camera position is constant value + constexpr float cameraZ = -576.f; + TransformHelper::Vector3 cameraPos(pivotPos.x_ + trans.translateX_, pivotPos.y_ + trans.translateY_, cameraZ); + // Concatenate with view projection matrix + transformMat_ *= TransformHelper::CreateLookAt(cameraPos, + TransformHelper::Vector3(cameraPos.x_, cameraPos.y_, 0), TransformHelper::Vector3(0, 1, 0)) * + TransformHelper::CreatePerspective(cameraPos); +} + void WindowProperty::ComputeTransform() { - if (recomputeTransformMat_) { - TransformHelper::Vector3 pivotPos = { windowRect_.posX_ + trans_.pivotX_ * windowRect_.width_, - windowRect_.posY_ + trans_.pivotY_ * windowRect_.height_, 0 }; - worldTransformMat_ = TransformHelper::CreateTranslation(-pivotPos) * - WindowHelper::ComputeWorldTransformMat4(trans_) * - TransformHelper::CreateTranslation(pivotPos); - // transformMat = worldTransformMat * viewProjectionMat - transformMat_ = worldTransformMat_; - // Z component of camera position is constant value - constexpr float cameraZ = -576.f; - TransformHelper::Vector3 cameraPos(pivotPos.x_ + trans_.translateX_, pivotPos.y_ + trans_.translateY_, cameraZ); - // Concatenate with view projection matrix - transformMat_ *= TransformHelper::CreateLookAt(cameraPos, - TransformHelper::Vector3(cameraPos.x_, cameraPos.y_, 0), TransformHelper::Vector3(0, 1, 0)) * - TransformHelper::CreatePerspective(cameraPos); + if (isDisplayZoomOn_) { + if (reCalcuZoomTransformMat_) { + HandleComputeTransform(zoomTrans_); + reCalcuZoomTransformMat_ = false; + } + } else if (recomputeTransformMat_) { + HandleComputeTransform(trans_); recomputeTransformMat_ = false; } } +void WindowProperty::SetZoomTransform(const Transform& trans) +{ + zoomTrans_ = trans; + reCalcuZoomTransformMat_ = true; +} + +void WindowProperty::ClearTransformZAxisOffset(Transform& trans) +{ + // replace Z axis translation by scaling + TransformHelper::Matrix4 preTransformMat = transformMat_; + HandleComputeTransform(trans); + Rect rect = WindowHelper::TransformRect(transformMat_, windowRect_); + float translateZ = trans.translateZ_; + trans.translateZ_ = 0.f; + HandleComputeTransform(trans); + Rect rectWithoutZAxisOffset = WindowHelper::TransformRect(transformMat_, windowRect_); + if (rectWithoutZAxisOffset.width_ == 0) { + trans.translateZ_ = translateZ; + return; + } + float scale = rect.width_ * 1.0f / rectWithoutZAxisOffset.width_; + trans.scaleX_ *= scale; + trans.scaleY_ *= scale; + transformMat_ = preTransformMat; +} + +void WindowProperty::UpdatePointerEvent(const std::shared_ptr& pointerEvent) +{ + if (trans_ == Transform::Identity() && zoomTrans_ == Transform::Identity()) { + return; + } + ComputeTransform(); + MMI::PointerEvent::PointerItem pointerItem; + if (!pointerEvent->GetPointerItem(pointerEvent->GetPointerId(), pointerItem)) { + return; + } + PointInfo originPos = + WindowHelper::CalculateOriginPosition(transformMat_, + { pointerItem.GetDisplayX(), pointerItem.GetDisplayY() }); + pointerItem.SetDisplayX(originPos.x); + pointerItem.SetDisplayY(originPos.y); + pointerItem.SetWindowX(originPos.x - windowRect_.posX_); + pointerItem.SetWindowY(originPos.y - windowRect_.posY_); + pointerEvent->UpdatePointerItem(pointerEvent->GetPointerId(), pointerItem); +} + +bool WindowProperty::isNeedComputerTransform() +{ + return ((!isDisplayZoomOn_ && trans_ != Transform::Identity()) || zoomTrans_ != Transform::Identity()); +} + +void WindowProperty::SetAnimateWindowFlag(bool isAnimateWindow) +{ + isAnimateWindow_ = isAnimateWindow; +} + +void WindowProperty::SetDisplayZoomState(bool isDisplayZoomOn) +{ + isDisplayZoomOn_ = isDisplayZoomOn; +} + +bool WindowProperty::IsDisplayZoomOn() const +{ + return isDisplayZoomOn_; +} + +bool WindowProperty::IsAnimateWindow() const +{ + return isAnimateWindow_; +} + +Transform WindowProperty::GetZoomTransform() const +{ + return zoomTrans_; +} + void WindowProperty::SetBrightness(float brightness) { brightness_ = brightness; @@ -588,7 +671,8 @@ bool WindowProperty::Marshalling(Parcel& parcel) const parcel.WriteUint32(static_cast(dragType_)) && parcel.WriteUint32(originRect_.width_) && parcel.WriteUint32(originRect_.height_) && parcel.WriteBool(isStretchable_) && MarshallingTouchHotAreas(parcel) && parcel.WriteUint32(accessTokenId_) && - MarshallingTransform(parcel) && MarshallingWindowSizeLimits(parcel); + MarshallingTransform(parcel) && MarshallingWindowSizeLimits(parcel) && zoomTrans_.Marshalling(parcel) && + parcel.WriteBool(isDisplayZoomOn_); } WindowProperty* WindowProperty::Unmarshalling(Parcel& parcel) @@ -639,6 +723,10 @@ WindowProperty* WindowProperty::Unmarshalling(Parcel& parcel) property->SetAccessTokenId(parcel.ReadUint32()); UnmarshallingTransform(parcel, property); UnmarshallingWindowSizeLimits(parcel, property); + Transform zoomTrans; + zoomTrans.Unmarshalling(parcel); + property->SetZoomTransform(zoomTrans); + property->SetDisplayZoomState(parcel.ReadBool()); return property; } @@ -806,6 +894,9 @@ void WindowProperty::CopyFrom(const sptr& property) accessTokenId_ = property->accessTokenId_; trans_ = property->trans_; sizeLimits_ = property->sizeLimits_; + zoomTrans_ = property->zoomTrans_; + isDisplayZoomOn_ = property->isDisplayZoomOn_; + reCalcuZoomTransformMat_ = true; } } } diff --git a/wm/include/window_adapter.h b/wm/include/window_adapter.h index b32f1d5458..8cc19c9cbf 100644 --- a/wm/include/window_adapter.h +++ b/wm/include/window_adapter.h @@ -68,6 +68,9 @@ public: virtual WMError GetAccessibilityWindowInfo(std::vector>& infos); virtual void MinimizeWindowsByLauncher(std::vector windowIds, bool isAnimated, sptr& finishCallback); + virtual void SetAnchorAndScale(int32_t x, int32_t y, float scale); + virtual void SetAnchorOffset(int32_t deltaX, int32_t deltaY); + virtual void OffWindowZoom(); private: static inline SingletonDelegator delegator; bool InitWMSProxy(); diff --git a/wm/include/window_agent.h b/wm/include/window_agent.h index c5dcc04e96..9aeef815f0 100644 --- a/wm/include/window_agent.h +++ b/wm/include/window_agent.h @@ -43,6 +43,7 @@ public: void DumpInfo(const std::vector& params, std::vector& info) override; void NotifyDestroy(void) override; void NotifyWindowClientPointUp(const std::shared_ptr& pointerEvent) override; + void UpdateZoomTransform(const Transform& trans, bool isDisplayZoomOn) override; private: sptr window_; }; diff --git a/wm/include/window_impl.h b/wm/include/window_impl.h index c20edaa82b..f97d1c3994 100644 --- a/wm/include/window_impl.h +++ b/wm/include/window_impl.h @@ -136,6 +136,7 @@ public: virtual WMError SetLayoutFullScreen(bool status) override; virtual WMError SetFullScreen(bool status) override; virtual const Transform& GetTransform() const override; + virtual const Transform& GetZoomTransform() const; virtual WMError UpdateSurfaceNodeAfterCustomAnimation(bool isAdd) override; inline void SetWindowState(WindowState state) { @@ -230,6 +231,7 @@ public: void NotifyScreenshot(); void NotifyTouchDialogTarget() override; void NotifyDestroy(); + void UpdateZoomTransform(const Transform& trans, bool isDisplayZoomOn); virtual WMError SetUIContent(const std::string& contentInfo, NativeEngine* engine, NativeValue* storage, bool isdistributed, AppExecFwk::Ability* ability) override; @@ -382,7 +384,6 @@ private: Rect GetSystemAlarmWindowDefaultSize(Rect defaultRect); void HandleModeChangeHotZones(int32_t posX, int32_t posY); WMError NotifyWindowTransition(TransitionReason reason); - void UpdatePointerEvent(const std::shared_ptr& pointerEvent); void UpdatePointerEventForStretchableWindow(const std::shared_ptr& pointerEvent); void UpdateDragType(int32_t startPointPosX, int32_t startPointPosY); void InitListenerHandler(); @@ -396,6 +397,7 @@ private: bool NeedToStopShowing(); void CalculateStartRectExceptHotZone(float virtualPixelRatio, const TransformHelper::Vector2& hotZoneScale); void SetSystemConfig(); + void TransformSurfaceNode(const Transform& trans); bool IsAppMainOrSunOrFloatingWindow(); void SetWindowCornerRadiusAccordingToSystemConfig(); bool IsAppMainOrSubOrFloatingWindow(); diff --git a/wm/include/zidl/window_interface.h b/wm/include/zidl/window_interface.h index a0d8dd52e4..930c33439d 100644 --- a/wm/include/zidl/window_interface.h +++ b/wm/include/zidl/window_interface.h @@ -45,6 +45,7 @@ public: TRANS_ID_DUMP_INFO, TRANS_ID_NOTIFY_DESTROY, TRANS_ID_NOTIFY_CLIENT_POINT_UP, + TRANS_ID_UPDATE_ZOOM_TRANSFORM, }; virtual void UpdateWindowRect(const struct Rect& rect, bool decoStatus, WindowSizeChangeReason reason) = 0; @@ -63,6 +64,7 @@ public: virtual void DumpInfo(const std::vector& params, std::vector& info) = 0; virtual void NotifyDestroy(void) = 0; virtual void NotifyWindowClientPointUp(const std::shared_ptr& pointerEvent) = 0; + virtual void UpdateZoomTransform(const Transform& trans, bool isDisplayZoomOn) = 0; }; } // namespace Rosen } // namespace OHOS diff --git a/wm/include/zidl/window_proxy.h b/wm/include/zidl/window_proxy.h index 14a20a2686..f28775e7b2 100644 --- a/wm/include/zidl/window_proxy.h +++ b/wm/include/zidl/window_proxy.h @@ -44,6 +44,7 @@ public: void DumpInfo(const std::vector& params, std::vector& info) override; void NotifyDestroy(void) override; void NotifyWindowClientPointUp(const std::shared_ptr& pointerEvent) override; + void UpdateZoomTransform(const Transform& trans, bool isDisplayZoomOn) override; private: static inline BrokerDelegator delegator_; }; diff --git a/wm/src/window_accessibility_controller.cpp b/wm/src/window_accessibility_controller.cpp index 8e5ca3c4dd..1420351403 100644 --- a/wm/src/window_accessibility_controller.cpp +++ b/wm/src/window_accessibility_controller.cpp @@ -14,6 +14,7 @@ */ #include "window_accessibility_controller.h" +#include "window_adapter.h" namespace OHOS::Rosen { WM_IMPLEMENT_SINGLE_INSTANCE(WindowAccessibilityController) @@ -23,13 +24,16 @@ WindowAccessibilityController::WindowAccessibilityController() void WindowAccessibilityController::SetAnchorAndScale(int32_t x, int32_t y, float scale) { + SingletonContainer::Get().SetAnchorAndScale(x, y, scale); } void WindowAccessibilityController::SetAnchorOffset(int32_t deltaX, int32_t deltaY) { + SingletonContainer::Get().SetAnchorOffset(deltaX, deltaY); } void WindowAccessibilityController::OffWindowZoom() { + SingletonContainer::Get().OffWindowZoom(); } } // namespace OHOS::Rosen \ No newline at end of file diff --git a/wm/src/window_adapter.cpp b/wm/src/window_adapter.cpp index 0e2624a21b..6edc5c7ccd 100644 --- a/wm/src/window_adapter.cpp +++ b/wm/src/window_adapter.cpp @@ -269,5 +269,23 @@ WMError WindowAdapter::BindDialogTarget(uint32_t& windowId, sptr INIT_PROXY_CHECK_RETURN(WMError::WM_ERROR_SAMGR); return windowManagerServiceProxy_->BindDialogTarget(windowId, targetToken); } + +void WindowAdapter::SetAnchorAndScale(int32_t x, int32_t y, float scale) +{ + INIT_PROXY_CHECK_RETURN(); + windowManagerServiceProxy_->SetAnchorAndScale(x, y, scale); +} + +void WindowAdapter::SetAnchorOffset(int32_t deltaX, int32_t deltaY) +{ + INIT_PROXY_CHECK_RETURN(); + windowManagerServiceProxy_->SetAnchorOffset(deltaX, deltaY); +} + +void WindowAdapter::OffWindowZoom() +{ + INIT_PROXY_CHECK_RETURN(); + windowManagerServiceProxy_->OffWindowZoom(); +} } // namespace Rosen } // namespace OHOS \ No newline at end of file diff --git a/wm/src/window_agent.cpp b/wm/src/window_agent.cpp index e2ef09a041..8fba39a778 100644 --- a/wm/src/window_agent.cpp +++ b/wm/src/window_agent.cpp @@ -156,6 +156,15 @@ void WindowAgent::DumpInfo(const std::vector& params, std::vectorDumpInfo(params, info); } +void WindowAgent::UpdateZoomTransform(const Transform& trans, bool isDisplayZoomOn) +{ + if (window_ == nullptr) { + WLOGFE("window_ is nullptr"); + return; + } + window_->UpdateZoomTransform(trans, isDisplayZoomOn); +} + void WindowAgent::NotifyDestroy(void) { if (window_ == nullptr) { diff --git a/wm/src/window_impl.cpp b/wm/src/window_impl.cpp index 93ed9167ff..cc9da05a1f 100755 --- a/wm/src/window_impl.cpp +++ b/wm/src/window_impl.cpp @@ -400,6 +400,11 @@ void WindowImpl::SetTransform(const Transform& trans) static_cast(ret), property_->GetWindowId()); property_->SetTransform(oriTrans); // reset to ori transform when update failed } + if (property_->IsDisplayZoomOn()) { + TransformSurfaceNode(property_->GetZoomTransform()); + } else { + TransformSurfaceNode(trans); + } } const Transform& WindowImpl::GetTransform() const @@ -407,6 +412,11 @@ const Transform& WindowImpl::GetTransform() const return property_->GetTransform(); } +const Transform& WindowImpl::GetZoomTransform() const +{ + return property_->GetZoomTransform(); +} + WMError WindowImpl::AddWindowFlag(WindowFlag flag) { if (flag == WindowFlag::WINDOW_FLAG_SHOW_WHEN_LOCKED && state_ != WindowState::STATE_CREATED) { @@ -2156,28 +2166,6 @@ void WindowImpl::HandleModeChangeHotZones(int32_t posX, int32_t posY) } } -void WindowImpl::UpdatePointerEvent(const std::shared_ptr& pointerEvent) -{ - property_->ComputeTransform(); - MMI::PointerEvent::PointerItem pointerItem; - if (!pointerEvent->GetPointerItem(pointerEvent->GetPointerId(), pointerItem)) { - WLOGFW("Point item is invalid"); - return; - } - Rect winRect = GetRect(); - PointInfo originPos = - WindowHelper::CalculateOriginPosition(property_->GetTransformMat(), - { pointerItem.GetDisplayX(), pointerItem.GetDisplayY() }); - WLOGI("Pointer event has been updated,window id:%{public}u, before->now:" - "[%{public}d,%{public}d]->[%{public}d,%{public}d]", - property_->GetWindowId(), pointerItem.GetDisplayX(), pointerItem.GetDisplayY(), originPos.x, originPos.y); - pointerItem.SetDisplayX(originPos.x); - pointerItem.SetDisplayY(originPos.y); - pointerItem.SetWindowX(originPos.x - winRect.posX_); - pointerItem.SetWindowY(originPos.y - winRect.posY_); - pointerEvent->UpdatePointerItem(pointerEvent->GetPointerId(), pointerItem); -} - void WindowImpl::UpdatePointerEventForStretchableWindow(const std::shared_ptr& pointerEvent) { MMI::PointerEvent::PointerItem pointerItem; @@ -2275,7 +2263,7 @@ void WindowImpl::ReadyToMoveOrDragWindow(int32_t globalX, int32_t globalY, int32 return; } TransformHelper::Vector2 hotZoneScale(1, 1); - if (property_->GetTransform() != Transform::Identity()) { + if (property_->isNeedComputerTransform()) { property_->ComputeTransform(); hotZoneScale = WindowHelper::CalculateHotZoneScale(property_->GetTransformMat()); } @@ -2387,8 +2375,8 @@ void WindowImpl::AdjustWindowAnimationFlag(bool withAnimation) void WindowImpl::ConsumePointerEvent(const std::shared_ptr& pointerEvent) { // If windowRect transformed, transform event back to its origin position - if (property_->GetTransform() != Transform::Identity()) { - UpdatePointerEvent(pointerEvent); + if (property_) { + property_->UpdatePointerEvent(pointerEvent); } int32_t action = pointerEvent->GetPointerAction(); if (action == MMI::PointerEvent::POINTER_ACTION_DOWN || action == MMI::PointerEvent::POINTER_ACTION_BUTTON_DOWN) { @@ -2648,6 +2636,34 @@ void WindowImpl::NotifyDestroy() }); } +void WindowImpl::TransformSurfaceNode(const Transform& trans) +{ + if (surfaceNode_ == nullptr) { + return; + } + surfaceNode_->SetPivotX(trans.pivotX_); + surfaceNode_->SetPivotY(trans.pivotY_); + surfaceNode_->SetScaleX(trans.scaleX_); + surfaceNode_->SetScaleY(trans.scaleY_); + surfaceNode_->SetTranslateX(trans.translateX_); + surfaceNode_->SetTranslateY(trans.translateY_); + surfaceNode_->SetTranslateZ(trans.translateZ_); + surfaceNode_->SetRotationX(trans.rotationX_); + surfaceNode_->SetRotationY(trans.rotationY_); + surfaceNode_->SetRotation(trans.rotationZ_); +} + +void WindowImpl::UpdateZoomTransform(const Transform& trans, bool isDisplayZoomOn) +{ + WLOGFD("%{public}s zoomTrans, pivotX:%{public}f, pivotY:%{public}f, scaleX:%{public}f, scaleY:%{public}f" + ", transX:%{public}f, transY:%{public}f, transZ:%{public}f, rotateX:%{public}f, rotateY:%{public}f " + "rotateZ:%{public}f", property_->GetWindowName().c_str(), trans.pivotX_, trans.pivotY_, trans.scaleX_, + trans.scaleY_, trans.translateX_, trans.translateY_, trans.translateZ_, trans.rotationX_, + trans.rotationY_, trans.rotationZ_); + property_->SetZoomTransform(trans); + property_->SetDisplayZoomState(isDisplayZoomOn); +} + void WindowImpl::NotifySizeChange(Rect rect, WindowSizeChangeReason reason) { std::vector> windowChangeListeners; diff --git a/wm/src/zidl/window_proxy.cpp b/wm/src/zidl/window_proxy.cpp index 801959e086..30fc9fdd3f 100644 --- a/wm/src/zidl/window_proxy.cpp +++ b/wm/src/zidl/window_proxy.cpp @@ -316,6 +316,29 @@ void WindowProxy::DumpInfo(const std::vector& params, std::vectorSendRequest(static_cast(WindowMessage::TRANS_ID_UPDATE_ZOOM_TRANSFORM), + data, reply, option) != ERR_NONE) { + WLOGFE("SendRequest failed"); + } +} + void WindowProxy::NotifyDestroy(void) { MessageParcel data; diff --git a/wm/src/zidl/window_stub.cpp b/wm/src/zidl/window_stub.cpp index 9df53d30c0..d13385f2bf 100644 --- a/wm/src/zidl/window_stub.cpp +++ b/wm/src/zidl/window_stub.cpp @@ -126,6 +126,14 @@ int WindowStub::OnRemoteRequest(uint32_t code, MessageParcel &data, MessageParce return -1; } NotifyWindowClientPointUp(pointerEvent); + break; + } + case WindowMessage::TRANS_ID_UPDATE_ZOOM_TRANSFORM: { + Transform trans; + trans.Unmarshalling(data); + bool isDisplayZoomOn = data.ReadBool(); + UpdateZoomTransform(trans, isDisplayZoomOn); + break; } default: break; diff --git a/wmserver/BUILD.gn b/wmserver/BUILD.gn index 16418ef821..85a130823f 100644 --- a/wmserver/BUILD.gn +++ b/wmserver/BUILD.gn @@ -36,6 +36,7 @@ ohos_shared_library("libwms") { "src/avoid_area_controller.cpp", "src/display_group_controller.cpp", "src/display_group_info.cpp", + "src/display_zoom_controller.cpp", "src/drag_controller.cpp", "src/freeze_controller.cpp", "src/inner_window.cpp", diff --git a/wmserver/include/display_zoom_controller.h b/wmserver/include/display_zoom_controller.h new file mode 100644 index 0000000000..1f29718171 --- /dev/null +++ b/wmserver/include/display_zoom_controller.h @@ -0,0 +1,62 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef OHOS_ROSEN_DISPLAY_ZOOM_CONTROLLER_H +#define OHOS_ROSEN_DISPLAY_ZOOM_CONTROLLER_H + +#include + +#include "window_node.h" +#include "window_root.h" +#include "window_node_container.h" +#include "wm_common.h" + +namespace OHOS::Rosen { +class DisplayZoomController : public RefBase { +public: + explicit DisplayZoomController(sptr& root) : windowRoot_(root) {} + ~DisplayZoomController() = default; + void SetAnchorAndScale(int32_t x, int32_t y, float scale); + void SetAnchorOffset(int32_t deltaX, int32_t deltaY); + void OffWindowZoom(); + void UpdateAllWindowsZoomInfo(DisplayId displayId); + void UpdateWindowZoomInfo(uint32_t windowId); + void ClearZoomTransform(std::vector> nodes); +private: + struct DisplayZoomInfo { + int32_t pivotX; + int32_t pivotY; + float scale; + int32_t translateX; + int32_t translateY; + }; + sptr windowRoot_; + void ClearZoomTransformInner(sptr node); + bool UpdateZoomTranslateInfo(sptr windowNodeContainer, DisplayId displayId, + int32_t& deltaX, int32_t& deltaY); + Transform CalcuAnimateZoomTrans(sptr node); + Transform CalcuZoomTransByZoomInfo(sptr node); + Transform CalcuZoomTrans(sptr node, const DisplayZoomInfo& zoomInfo); + void UpdateClientAndSurfaceZoomInfo(sptr node, const Transform& zoomTrans); + void HandleUpdateWindowZoomInfo(sptr node); + void TransformSurfaceNode(std::shared_ptr surfaceNode, const Transform& trans); + DisplayZoomInfo zoomInfo_ = {0, 0, 1.0, 0, 0}; // compared with original window rect + std::unordered_set displayZoomWindowTypeSkipped_ { + WindowType::WINDOW_TYPE_NAVIGATION_BAR, + WindowType::WINDOW_TYPE_INPUT_METHOD_FLOAT, + }; +}; +} +#endif // OHOS_ROSEN_DISPLAY_ZOOM_CONTROLLER_H diff --git a/wmserver/include/window_controller.h b/wmserver/include/window_controller.h index 133a766c31..76efed1db9 100644 --- a/wmserver/include/window_controller.h +++ b/wmserver/include/window_controller.h @@ -20,6 +20,7 @@ #include #include "accessibility_connection.h" +#include "display_zoom_controller.h" #include "input_window_monitor.h" #include "zidl/window_manager_agent_interface.h" #include "window_root.h" @@ -32,7 +33,8 @@ namespace Rosen { class WindowController : public RefBase { public: WindowController(sptr& root, sptr inputWindowMonitor) : windowRoot_(root), - inputWindowMonitor_(inputWindowMonitor), accessibilityConnection_(new AccessibilityConnection(windowRoot_)) {} + inputWindowMonitor_(inputWindowMonitor), accessibilityConnection_(new AccessibilityConnection(windowRoot_)), + displayZoomController_(new DisplayZoomController(root)) {} ~WindowController() = default; WMError CreateWindow(sptr& window, sptr& property, @@ -68,6 +70,9 @@ public: Orientation GetWindowPreferredOrientation(DisplayId displayId); void OnScreenshot(DisplayId displayId); WMError GetAccessibilityWindowInfo(std::vector>& infos) const; + void SetAnchorAndScale(int32_t x, int32_t y, float scale); + void SetAnchorOffset(int32_t deltaX, int32_t deltaY); + void OffWindowZoom(); WMError BindDialogTarget(uint32_t& windowId, sptr targetToken); WMError InterceptInputEventToServer(uint32_t windowId); WMError RecoverInputEventToClient(uint32_t windowId); @@ -102,6 +107,7 @@ private: sptr windowRoot_; sptr inputWindowMonitor_; sptr accessibilityConnection_; + sptr displayZoomController_; std::atomic windowId_ { INVALID_WINDOW_ID }; // Remove 'sysBarWinId_' after SystemUI resize 'systembar', systemBar only exist on default display currently std::unordered_map sysBarWinId_ { diff --git a/wmserver/include/window_manager_service.h b/wmserver/include/window_manager_service.h index 99c19f9187..dc9893ddf1 100644 --- a/wmserver/include/window_manager_service.h +++ b/wmserver/include/window_manager_service.h @@ -127,6 +127,9 @@ public: void HasPrivateWindow(DisplayId displayId, bool& hasPrivateWindow); void NotifyWindowClientPointUp(uint32_t windowId, const std::shared_ptr& pointerEvent); + void SetAnchorAndScale(int32_t x, int32_t y, float scale) override; + void SetAnchorOffset(int32_t deltaX, int32_t deltaY) override; + void OffWindowZoom() override; protected: WindowManagerService(); virtual ~WindowManagerService() = default; diff --git a/wmserver/include/window_node.h b/wmserver/include/window_node.h index 32810e43c6..6fe21e14c0 100644 --- a/wmserver/include/window_node.h +++ b/wmserver/include/window_node.h @@ -92,6 +92,8 @@ public: void SetTransform(const Transform& trans); void SetSnapshot(std::shared_ptr pixelMap); std::shared_ptr GetSnapshot(); + Transform GetZoomTransform() const; + void UpdateZoomTransform(const Transform& trans, bool isDisplayZoomOn); const sptr& GetWindowToken() const; uint32_t GetWindowId() const; diff --git a/wmserver/include/window_node_container.h b/wmserver/include/window_node_container.h index 72bd67eafb..36c7d41857 100644 --- a/wmserver/include/window_node_container.h +++ b/wmserver/include/window_node_container.h @@ -118,6 +118,7 @@ public: void RemoveSingleUserWindowNodes(int accountId); WMError IsTileRectSatisfiedWithSizeLimits(sptr& node); bool HasPrivateWindow(); + sptr GetDeskTopWindow(); static AnimationConfig& GetAnimationConfigRef(); bool TakeWindowPairSnapshot(DisplayId displayId); void ClearWindowPairSnapshot(DisplayId displayId); diff --git a/wmserver/include/window_root.h b/wmserver/include/window_root.h index 33b07a9041..7cab66cbc9 100644 --- a/wmserver/include/window_root.h +++ b/wmserver/include/window_root.h @@ -95,6 +95,7 @@ public: sptr GetWindowForDumpAceHelpInfo() const; void DestroyLeakStartingWindow(); void SetSplitRatios(const std::vector& splitRatioNumbers); + std::vector> GetSplitScreenWindowNodes(DisplayId displayId); void SetExitSplitRatios(const std::vector& exitSplitRatios); void MinimizeTargetWindows(std::vector& windowIds); WMError UpdateRsTree(uint32_t windowId, bool isAdd); diff --git a/wmserver/include/zidl/window_manager_interface.h b/wmserver/include/zidl/window_manager_interface.h index 39ed6f0281..4e43f66adb 100644 --- a/wmserver/include/zidl/window_manager_interface.h +++ b/wmserver/include/zidl/window_manager_interface.h @@ -63,6 +63,9 @@ public: TRANS_ID_UPDATE_RS_TREE, TRANS_ID_BIND_DIALOG_TARGET, TRANS_ID_NOTIFY_READY_MOVE_OR_DRAG, + TRANS_ID_SET_ANCHOR_AND_SCALE, + TRANS_ID_SET_ANCHOR_OFFSET, + TRANS_ID_OFF_WINDOW_ZOOM, }; virtual WMError CreateWindow(sptr& window, sptr& property, const std::shared_ptr& surfaceNode, @@ -97,6 +100,9 @@ public: virtual WMError UpdateAvoidAreaListener(uint32_t windowId, bool haveListener) = 0; virtual WMError UpdateRsTree(uint32_t windowId, bool isAdd) = 0; virtual WMError BindDialogTarget(uint32_t& windowId, sptr targetToken) = 0; + virtual void SetAnchorAndScale(int32_t x, int32_t y, float scale) = 0; + virtual void SetAnchorOffset(int32_t deltaX, int32_t deltaY) = 0; + virtual void OffWindowZoom() = 0; }; } } diff --git a/wmserver/include/zidl/window_manager_proxy.h b/wmserver/include/zidl/window_manager_proxy.h index bf0bb666d6..c099e42da1 100644 --- a/wmserver/include/zidl/window_manager_proxy.h +++ b/wmserver/include/zidl/window_manager_proxy.h @@ -61,6 +61,9 @@ public: WMError UpdateAvoidAreaListener(uint32_t windowId, bool haveListener) override; WMError UpdateRsTree(uint32_t windowId, bool isAdd) override; WMError BindDialogTarget(uint32_t& windowId, sptr targetToken) override; + void SetAnchorAndScale(int32_t x, int32_t y, float scale) override; + void SetAnchorOffset(int32_t deltaX, int32_t deltaY) override; + void OffWindowZoom() override; private: static inline BrokerDelegator delegator_; }; diff --git a/wmserver/src/display_zoom_controller.cpp b/wmserver/src/display_zoom_controller.cpp new file mode 100644 index 0000000000..9d67c0e8bc --- /dev/null +++ b/wmserver/src/display_zoom_controller.cpp @@ -0,0 +1,353 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include "display_zoom_controller.h" +#include "window_helper.h" + +namespace OHOS::Rosen { +namespace { + constexpr HiviewDFX::HiLogLabel LABEL = {LOG_CORE, HILOG_DOMAIN_WINDOW, "DisplayZoomController"}; +} + +void DisplayZoomController::SetAnchorAndScale(int32_t x, int32_t y, float scale) +{ + WLOGFD("DisplayZoom: On, anchor x:%{public}d, y:%{public}d, scale:%{public}f", x, y, scale); + if (scale <= 0) { + return; + } else if (zoomInfo_.scale * scale < DISPLAY_ZOOM_MIN_SCALE) { + scale = DISPLAY_ZOOM_MIN_SCALE / zoomInfo_.scale; + } else if (zoomInfo_.scale * scale > DISPLAY_ZOOM_MAX_SCALE) { + scale = DISPLAY_ZOOM_MAX_SCALE / zoomInfo_.scale; + } + DisplayId displayId = DisplayManagerServiceInner::GetInstance().GetDefaultDisplayId(); + sptr windowNodeContainer = windowRoot_->GetOrCreateWindowNodeContainer(displayId); + if (windowNodeContainer == nullptr) { + return; + } + std::vector> windowNodes; + windowNodeContainer->TraverseContainer(windowNodes); + bool isAlreadyCalcu = false; + for (auto& node : windowNodes) { + if (displayZoomWindowTypeSkipped_.find(node->GetWindowProperty()->GetWindowType()) != + displayZoomWindowTypeSkipped_.end()) { + continue; + } + Transform zoomTrans; + if (!isAlreadyCalcu) { + zoomTrans = CalcuZoomTrans(node, {x, y, scale, 0, 0}); + zoomInfo_.scale *= scale; + Rect rect = node->GetWindowRect(); + zoomInfo_.pivotX = rect.posX_ + zoomTrans.pivotX_ * rect.width_; + zoomInfo_.pivotY = rect.posY_ + zoomTrans.pivotY_ * rect.height_; + zoomInfo_.translateX = zoomTrans.translateX_; + zoomInfo_.translateY = zoomTrans.translateY_; + isAlreadyCalcu = true; + } else { + zoomTrans = CalcuZoomTransByZoomInfo(node); + } + UpdateClientAndSurfaceZoomInfo(node, zoomTrans); + } +} + +void DisplayZoomController::SetAnchorOffset(int32_t deltaX, int32_t deltaY) +{ + WLOGFD("DisplayZoom: SetAnchorOffset"); + DisplayId displayId = DisplayManagerServiceInner::GetInstance().GetDefaultDisplayId(); + sptr windowNodeContainer = windowRoot_->GetOrCreateWindowNodeContainer(displayId); + if (windowNodeContainer == nullptr) { + return; + } + if (!UpdateZoomTranslateInfo(windowNodeContainer, displayId, deltaX, deltaY)) { + return; + } + WindowNodeOperationFunc translateFunc = [this, deltaX, deltaY](sptr node) { + if (displayZoomWindowTypeSkipped_.find(node->GetWindowProperty()->GetWindowType()) != + displayZoomWindowTypeSkipped_.end()) { + return false; + } + Transform zoomTrans = node->GetZoomTransform(); + zoomTrans.translateX_ += static_cast(deltaX); + zoomTrans.translateY_ += static_cast(deltaY); + UpdateClientAndSurfaceZoomInfo(node, zoomTrans); + return false; + }; + windowNodeContainer->TraverseWindowTree(translateFunc, false); +} + +void DisplayZoomController::OffWindowZoom() +{ + WLOGFD("DisplayZoom: Off"); + DisplayId displayId = DisplayManagerServiceInner::GetInstance().GetDefaultDisplayId(); + sptr windowNodeContainer = windowRoot_->GetOrCreateWindowNodeContainer(displayId); + if (windowNodeContainer == nullptr) { + return; + } + zoomInfo_ = {0, 0, 1.0, 0, 0}; + std::vector> windowNodes; + windowNodeContainer->TraverseContainer(windowNodes); + for (auto& node : windowNodes) { + if (displayZoomWindowTypeSkipped_.find(node->GetWindowProperty()->GetWindowType()) != + displayZoomWindowTypeSkipped_.end()) { + continue; + } + ClearZoomTransformInner(node); + } +} + +void DisplayZoomController::UpdateAllWindowsZoomInfo(DisplayId displayId) +{ + if (zoomInfo_.scale == DISPLAY_ZOOM_OFF_SCALE) { + return; + } + DisplayId defaultDisplayId = DisplayManagerServiceInner::GetInstance().GetDefaultDisplayId(); + if (defaultDisplayId != displayId) { + return; + } + sptr windowNodeContainer = windowRoot_->GetOrCreateWindowNodeContainer(displayId); + if (windowNodeContainer == nullptr) { + return; + } + int32_t deltaX, deltaY; + deltaX = deltaY = 0; + if (UpdateZoomTranslateInfo(windowNodeContainer, displayId, deltaX, deltaY)) { + WLOGFD("Change ZoomInfo translation, deltaX:%{public}d, deltaY:%{public}d", deltaX, deltaY); + } + std::vector> windowNodes; + windowNodeContainer->TraverseContainer(windowNodes); + for (auto& node: windowNodes) { + HandleUpdateWindowZoomInfo(node); + } +} + +void DisplayZoomController::UpdateWindowZoomInfo(uint32_t windowId) +{ + if (zoomInfo_.scale == DISPLAY_ZOOM_OFF_SCALE) { + return; + } + auto node = windowRoot_->GetWindowNode(windowId); + if (node == nullptr) { + return; + } + if (!node->currentVisibility_) { + return; + } + DisplayId displayId = DisplayManagerServiceInner::GetInstance().GetDefaultDisplayId(); + if (node->GetDisplayId() != displayId) { + return; + } + std::vector> windowNodes; + windowNodes.push_back(node); + if (node->GetWindowType() == WindowType::WINDOW_TYPE_DOCK_SLICE) { + windowNodes = windowRoot_->GetSplitScreenWindowNodes(node->GetDisplayId()); + } + for (auto& node: windowNodes) { + HandleUpdateWindowZoomInfo(node); + } +} + +void DisplayZoomController::ClearZoomTransform(std::vector> nodes) +{ + if (zoomInfo_.scale == DISPLAY_ZOOM_OFF_SCALE) { + return; + } + for (auto& node: nodes) { + ClearZoomTransformInner(node); + } +} + +void DisplayZoomController::ClearZoomTransformInner(sptr node) +{ + Transform recoverTrans; + node->UpdateZoomTransform(recoverTrans, false); + auto surfaceNode = node->leashWinSurfaceNode_ ? node->leashWinSurfaceNode_ : node->surfaceNode_; + if (!node->GetWindowProperty()->IsAnimateWindow()) { + TransformSurfaceNode(surfaceNode, recoverTrans); + } +} + +bool DisplayZoomController::UpdateZoomTranslateInfo(sptr windowNodeContainer, + DisplayId displayId, int32_t& deltaX, int32_t& deltaY) +{ + sptr deskTop = windowNodeContainer->GetDeskTopWindow(); + if (deskTop == nullptr) { + WLOGFE("DisplayZoom: can't find deskTop windowNode"); + return false; + } + Transform zoomTrans = deskTop->GetZoomTransform(); + Rect originalRect = deskTop->GetWindowRect(); + Rect zoomRect = originalRect; + if (zoomTrans != Transform::Identity()) { + deskTop->ComputeTransform(); + zoomRect = WindowHelper::TransformRect(deskTop->GetWindowProperty()->GetTransformMat(), originalRect); + } + sptr displayInfo = windowNodeContainer->GetDisplayInfo(displayId); + if (displayInfo == nullptr) { + WLOGFE("DisplayZoom: can't get displayInfo"); + return false; + } + int32_t deltaXMax = displayInfo->GetOffsetX() - zoomRect.posX_; + int32_t deltaXMin = displayInfo->GetOffsetX() + displayInfo->GetWidth() - zoomRect.posX_ + - static_cast(zoomRect.width_); + int32_t deltaYMax = displayInfo->GetOffsetY() - zoomRect.posY_; + int32_t deltaYMin = displayInfo->GetOffsetY() + displayInfo->GetHeight() - zoomRect.posY_ + - static_cast(zoomRect.height_); + deltaX = MathHelper::Clamp(deltaX, deltaXMin, deltaXMax); + deltaY = MathHelper::Clamp(deltaY, deltaYMin, deltaYMax); + if (deltaX == 0 && deltaY == 0) { + return false; + } + zoomInfo_.translateX += deltaX; + zoomInfo_.translateY += deltaY; + return true; +} + +Transform DisplayZoomController::CalcuAnimateZoomTrans(sptr node) +{ + Rect rect = node->GetWindowRect(); + if (rect.width_ == 0 || rect.height_ == 0) { + return Transform::Identity(); + } + Transform lastZoomTrans = CalcuZoomTransByZoomInfo(node); + TransformHelper::Vector3 lastPivotPos = { rect.posX_ + lastZoomTrans.pivotX_ * rect.width_, + rect.posY_ + lastZoomTrans.pivotY_ * rect.height_, 0 }; + TransformHelper::Matrix4 lastWorldMat = TransformHelper::CreateTranslation(-lastPivotPos) * + WindowHelper::ComputeWorldTransformMat4(lastZoomTrans) * + TransformHelper::CreateTranslation(lastPivotPos); + + Transform animateTrans = node->GetWindowProperty()->GetTransform(); + if (animateTrans.translateZ_ != 0.f) { + node->GetWindowProperty()->ClearTransformZAxisOffset(animateTrans); + } + TransformHelper::Vector3 animatePivotPos = { rect.posX_ + animateTrans.pivotX_ * rect.width_, + rect.posY_ + animateTrans.pivotY_ * rect.height_, 0 }; + TransformHelper::Matrix4 animateWorldMat = TransformHelper::CreateTranslation(-animatePivotPos) * + WindowHelper::ComputeWorldTransformMat4(animateTrans) * + TransformHelper::CreateTranslation(animatePivotPos); + + TransformHelper::Matrix4 finalWorldMat = animateWorldMat * lastWorldMat; + Transform finalZoomTrans; + finalZoomTrans.pivotX_ = (0 - rect.posX_) * 1.0 / rect.width_; + finalZoomTrans.pivotY_ = (0 - rect.posY_) * 1.0 / rect.height_; + TransformHelper::Vector3 scale = finalWorldMat.GetScale(); + TransformHelper::Vector3 translation = finalWorldMat.GetTranslation(); + finalZoomTrans.scaleX_ = scale.x_; + finalZoomTrans.scaleY_ = scale.y_; + finalZoomTrans.translateX_ = translation.x_; + finalZoomTrans.translateY_ = translation.y_; + finalZoomTrans.translateZ_ = translation.z_; + finalZoomTrans.rotationX_ = animateTrans.rotationX_; + finalZoomTrans.rotationY_ = animateTrans.rotationY_; + finalZoomTrans.rotationZ_ = animateTrans.rotationZ_; + + return finalZoomTrans; +} + +Transform DisplayZoomController::CalcuZoomTransByZoomInfo(sptr node) +{ + Transform zoomTrans; + Rect rect = node->GetWindowRect(); + if (rect.width_ == 0 || rect.height_ == 0) { + return zoomTrans; + } + zoomTrans.pivotX_ = (zoomInfo_.pivotX - rect.posX_) * 1.0 / rect.width_; + zoomTrans.pivotY_ = (zoomInfo_.pivotY - rect.posY_) * 1.0 / rect.height_; + zoomTrans.scaleX_ = zoomTrans.scaleY_ = zoomInfo_.scale; + zoomTrans.translateX_ = zoomInfo_.translateX; + zoomTrans.translateY_ = zoomInfo_.translateY; + return zoomTrans; +} + +Transform DisplayZoomController::CalcuZoomTrans(sptr node, const DisplayZoomInfo& zoomInfo) +{ + Rect rect = node->GetWindowRect(); + if (rect.width_ == 0 || rect.height_ == 0) { + return Transform::Identity(); + } + Transform lastZoomTrans = node->GetZoomTransform(); + TransformHelper::Vector3 lastPivotPos = { rect.posX_ + lastZoomTrans.pivotX_ * rect.width_, + rect.posY_ + lastZoomTrans.pivotY_ * rect.height_, 0 }; + TransformHelper::Matrix4 lastWorldMat = TransformHelper::CreateTranslation(-lastPivotPos) * + WindowHelper::ComputeWorldTransformMat4(lastZoomTrans) * + TransformHelper::CreateTranslation(lastPivotPos); + + Transform zoomTrans; + zoomTrans.scaleX_ = zoomTrans.scaleY_ = zoomInfo.scale; + zoomTrans.translateX_ = zoomInfo.translateX; + zoomTrans.translateY_ = zoomInfo.translateY; + TransformHelper::Vector3 pivotPos = { zoomInfo.pivotX, zoomInfo.pivotY, 0 }; + TransformHelper::Matrix4 worldMat = TransformHelper::CreateTranslation(-pivotPos) * + WindowHelper::ComputeWorldTransformMat4(zoomTrans) * + TransformHelper::CreateTranslation(pivotPos); + + TransformHelper::Matrix4 finalWorldMat = lastWorldMat * worldMat; + Transform finalZoomTrans; + finalZoomTrans.pivotX_ = (0 - rect.posX_) * 1.0 / rect.width_; + finalZoomTrans.pivotY_ = (0 - rect.posY_) * 1.0 / rect.height_; + TransformHelper::Vector3 scale = finalWorldMat.GetScale(); + TransformHelper::Vector3 translation = finalWorldMat.GetTranslation(); + finalZoomTrans.scaleX_ = scale.x_; + finalZoomTrans.scaleY_ = scale.y_; + finalZoomTrans.translateX_ = translation.x_; + finalZoomTrans.translateY_ = translation.y_; + + return finalZoomTrans; +} + +void DisplayZoomController::UpdateClientAndSurfaceZoomInfo(sptr node, const Transform& zoomTrans) +{ + node->UpdateZoomTransform(zoomTrans, true); + auto surfaceNode = node->leashWinSurfaceNode_ ? node->leashWinSurfaceNode_ : node->surfaceNode_; + if (!node->GetWindowProperty()->IsAnimateWindow()) { + TransformSurfaceNode(surfaceNode, zoomTrans); + } + WLOGFD("%{public}s zoomTrans, pivotX:%{public}f, pivotY:%{public}f, scaleX:%{public}f, scaleY:%{public}f" + ", transX:%{public}f, transY:%{public}f, transZ:%{public}f, rotateX:%{public}f, rotateY:%{public}f " + "rotateZ:%{public}f", node->GetWindowName().c_str(), zoomTrans.pivotX_, zoomTrans.pivotY_, zoomTrans.scaleX_, + zoomTrans.scaleY_, zoomTrans.translateX_, zoomTrans.translateY_, zoomTrans.translateZ_, zoomTrans.rotationX_, + zoomTrans.rotationY_, zoomTrans.rotationZ_); +} + +void DisplayZoomController::HandleUpdateWindowZoomInfo(sptr node) +{ + if (displayZoomWindowTypeSkipped_.find(node->GetWindowProperty()->GetWindowType()) != + displayZoomWindowTypeSkipped_.end()) { + return; + } + Transform zoomTrans; + Transform animateTrans = node->GetWindowProperty()->GetTransform(); + if (node->GetWindowProperty()->IsAnimateWindow()) { + zoomTrans = CalcuAnimateZoomTrans(node); + } else { + zoomTrans = CalcuZoomTransByZoomInfo(node); + } + UpdateClientAndSurfaceZoomInfo(node, zoomTrans); +} + +void DisplayZoomController::TransformSurfaceNode(std::shared_ptr surfaceNode, const Transform& trans) +{ + if (surfaceNode == nullptr) { + return; + } + surfaceNode->SetPivotX(trans.pivotX_); + surfaceNode->SetPivotY(trans.pivotY_); + surfaceNode->SetScaleX(trans.scaleX_); + surfaceNode->SetScaleY(trans.scaleY_); + surfaceNode->SetTranslateX(trans.translateX_); + surfaceNode->SetTranslateY(trans.translateY_); + surfaceNode->SetTranslateZ(trans.translateZ_); + surfaceNode->SetRotationX(trans.rotationX_); + surfaceNode->SetRotationY(trans.rotationY_); + surfaceNode->SetRotation(trans.rotationZ_); +} +} \ No newline at end of file diff --git a/wmserver/src/drag_controller.cpp b/wmserver/src/drag_controller.cpp index 9ce793a88e..1983370b09 100644 --- a/wmserver/src/drag_controller.cpp +++ b/wmserver/src/drag_controller.cpp @@ -371,6 +371,9 @@ void MoveDragController::HandleMoveEvent(int32_t posX, int32_t posY, int32_t poi void MoveDragController::HandlePointerEvent(const std::shared_ptr& pointerEvent) { + if (windowProperty_) { + windowProperty_->UpdatePointerEvent(pointerEvent); + } MMI::PointerEvent::PointerItem pointerItem; int32_t pointId = pointerEvent->GetPointerId(); if (!pointerEvent->GetPointerItem(pointId, pointerItem)) { diff --git a/wmserver/src/input_window_monitor.cpp b/wmserver/src/input_window_monitor.cpp index 9ffac0d481..21868b9328 100644 --- a/wmserver/src/input_window_monitor.cpp +++ b/wmserver/src/input_window_monitor.cpp @@ -132,7 +132,7 @@ void InputWindowMonitor::UpdateDisplayInfo(const std::vector>& void InputWindowMonitor::TransformWindowRects(const sptr& windowNode, Rect& areaRect, std::vector& touchHotAreas, std::vector& pointerHotAreas) { - if (windowNode->GetWindowProperty()->GetTransform() != Transform::Identity()) { + if (windowNode->GetWindowProperty()->isNeedComputerTransform()) { windowNode->ComputeTransform(); for (Rect& rect : touchHotAreas) { rect = WindowHelper::TransformRect(windowNode->GetWindowProperty()->GetTransformMat(), rect); diff --git a/wmserver/src/window_controller.cpp b/wmserver/src/window_controller.cpp index 8feadddc63..3ba783a0fb 100644 --- a/wmserver/src/window_controller.cpp +++ b/wmserver/src/window_controller.cpp @@ -363,6 +363,7 @@ WMError WindowController::RemoveWindowNode(uint32_t windowId) for (auto& child : windowNode->children_) { nodes.emplace_back(child); } + displayZoomController_->ClearZoomTransform(nodes); accessibilityConnection_->NotifyAccessibilityWindowInfo(windowNode->GetDisplayId(), nodes, WindowUpdateType::WINDOW_UPDATE_REMOVED); return res; @@ -580,6 +581,7 @@ void WindowController::ProcessDisplayChange(DisplayId defaultDisplayId, sptrGetDisplayId(); + displayZoomController_->UpdateAllWindowsZoomInfo(displayId); FlushWindowInfoWithDisplayId(displayId); accessibilityConnection_->NotifyAccessibilityWindowInfo(displayId, WindowUpdateType::WINDOW_UPDATE_PROPERTY); if (windowNodeContainer != nullptr) { @@ -875,6 +877,7 @@ WMError WindowController::GetTopWindowId(uint32_t mainWinId, uint32_t& topWinId) void WindowController::FlushWindowInfo(uint32_t windowId) { WLOGFD("FlushWindowInfo"); + displayZoomController_->UpdateWindowZoomInfo(windowId); RSTransaction::FlushImplicitTransaction(); inputWindowMonitor_->UpdateInputWindow(windowId); } @@ -928,6 +931,7 @@ WMError WindowController::SetWindowLayoutMode(WindowLayoutMode mode) if (res != WMError::WM_OK) { return res; } + displayZoomController_->UpdateAllWindowsZoomInfo(displayId); FlushWindowInfoWithDisplayId(displayId); accessibilityConnection_->NotifyAccessibilityWindowInfo(displayId, WindowUpdateType::WINDOW_UPDATE_PROPERTY); } @@ -1042,6 +1046,7 @@ WMError WindowController::UpdateProperty(sptr& property, Propert case PropertyChangeAction::ACTION_UPDATE_TRANSFORM_PROPERTY: { node->SetTransform(property->GetTransform()); node->SetWindowSizeChangeReason(WindowSizeChangeReason::TRANSFORM); + node->GetWindowProperty()->SetAnimateWindowFlag(true); ret = UpdateTransform(windowId); break; } @@ -1213,6 +1218,27 @@ void WindowController::OnScreenshot(DisplayId displayId) windowToken->NotifyScreenshot(); } +void WindowController::SetAnchorOffset(int32_t deltaX, int32_t deltaY) +{ + displayZoomController_->SetAnchorOffset(deltaX, deltaY); + DisplayId displayId = DisplayManagerServiceInner::GetInstance().GetDefaultDisplayId(); + FlushWindowInfoWithDisplayId(displayId); +} + +void WindowController::OffWindowZoom() +{ + displayZoomController_->OffWindowZoom(); + DisplayId displayId = DisplayManagerServiceInner::GetInstance().GetDefaultDisplayId(); + FlushWindowInfoWithDisplayId(displayId); +} + +void WindowController::SetAnchorAndScale(int32_t x, int32_t y, float scale) +{ + displayZoomController_->SetAnchorAndScale(x, y, scale); + DisplayId displayId = DisplayManagerServiceInner::GetInstance().GetDefaultDisplayId(); + FlushWindowInfoWithDisplayId(displayId); +} + WMError WindowController::BindDialogTarget(uint32_t& windowId, sptr targetToken) { auto node = windowRoot_->GetWindowNode(windowId); diff --git a/wmserver/src/window_layout_policy.cpp b/wmserver/src/window_layout_policy.cpp index cbc3e27fdf..9b8805d229 100644 --- a/wmserver/src/window_layout_policy.cpp +++ b/wmserver/src/window_layout_policy.cpp @@ -479,7 +479,7 @@ void WindowLayoutPolicy::CalcAndSetNodeHotZone(const Rect& winRect, const sptrGetDisplayId()); TransformHelper::Vector2 hotZoneScale(1, 1); - if (node->GetWindowProperty()->GetTransform() != Transform::Identity()) { + if (node->GetWindowProperty()->isNeedComputerTransform()) { node->ComputeTransform(); hotZoneScale = WindowHelper::CalculateHotZoneScale(node->GetWindowProperty()->GetTransformMat()); } diff --git a/wmserver/src/window_manager_service.cpp b/wmserver/src/window_manager_service.cpp index 028a6827e6..3b81df6ba7 100644 --- a/wmserver/src/window_manager_service.cpp +++ b/wmserver/src/window_manager_service.cpp @@ -931,10 +931,10 @@ WMError WindowManagerService::UpdateProperty(sptr& windowPropert } if (action == PropertyChangeAction::ACTION_UPDATE_TRANSFORM_PROPERTY) { - PostAsyncTask([this, windowProperty, action]() mutable { + return PostSyncTask([this, windowProperty, action]() mutable { windowController_->UpdateProperty(windowProperty, action); + return WMError::WM_OK; }); - return WMError::WM_OK; } if (isAsyncTask) { @@ -1015,6 +1015,27 @@ WMError WindowManagerService::UpdateAvoidAreaListener(uint32_t windowId, bool ha }); } +void WindowManagerService::SetAnchorAndScale(int32_t x, int32_t y, float scale) +{ + PostAsyncTask([this, x, y, scale]() { + windowController_->SetAnchorAndScale(x, y, scale); + }); +} + +void WindowManagerService::SetAnchorOffset(int32_t deltaX, int32_t deltaY) +{ + PostAsyncTask([this, deltaX, deltaY]() { + windowController_->SetAnchorOffset(deltaX, deltaY); + }); +} + +void WindowManagerService::OffWindowZoom() +{ + PostAsyncTask([this]() { + windowController_->OffWindowZoom(); + }); +} + WMError WindowManagerService::UpdateRsTree(uint32_t windowId, bool isAdd) { return PostSyncTask([this, windowId, isAdd]() { diff --git a/wmserver/src/window_node.cpp b/wmserver/src/window_node.cpp index 59e6573558..0cee69b918 100644 --- a/wmserver/src/window_node.cpp +++ b/wmserver/src/window_node.cpp @@ -200,6 +200,20 @@ void WindowNode::SetTransform(const Transform& trans) property_->SetTransform(trans); } +Transform WindowNode::GetZoomTransform() const +{ + return property_->GetZoomTransform(); +} + +void WindowNode::UpdateZoomTransform(const Transform& trans, bool isDisplayZoomOn) +{ + property_->SetZoomTransform(trans); + property_->SetDisplayZoomState(isDisplayZoomOn); + if (windowToken_) { + windowToken_->UpdateZoomTransform(trans, isDisplayZoomOn); + } +} + WindowSizeLimits WindowNode::GetWindowSizeLimits() const { return property_->GetSizeLimits(); diff --git a/wmserver/src/window_node_container.cpp b/wmserver/src/window_node_container.cpp index f40b2d34bc..24c0f1eec0 100644 --- a/wmserver/src/window_node_container.cpp +++ b/wmserver/src/window_node_container.cpp @@ -1400,6 +1400,20 @@ void WindowNodeContainer::MinimizeAllAppWindows(DisplayId displayId) return; } +sptr WindowNodeContainer::GetDeskTopWindow() +{ + sptr deskTop; + WindowNodeOperationFunc findDeskTopFunc = [this, &deskTop](sptr node) { + if (node->GetWindowProperty()->GetWindowType() == WindowType::WINDOW_TYPE_DESKTOP) { + deskTop = node; + return true; + } + return false; + }; + TraverseWindowTree(findDeskTopFunc, false); + return deskTop; +} + bool WindowNodeContainer::HasPrivateWindow() { std::vector> windowNodes; diff --git a/wmserver/src/window_root.cpp b/wmserver/src/window_root.cpp index 72d72ac8bd..9a2cff743a 100644 --- a/wmserver/src/window_root.cpp +++ b/wmserver/src/window_root.cpp @@ -250,6 +250,23 @@ void WindowRoot::MinimizeTargetWindows(std::vector& windowIds) } } +std::vector> WindowRoot::GetSplitScreenWindowNodes(DisplayId displayId) +{ + auto container = GetOrCreateWindowNodeContainer(displayId); + if (container == nullptr) { + return {}; + } + auto displayGroupController = container->GetMultiDisplayController(); + if (displayGroupController == nullptr) { + return {}; + } + auto windowPair = displayGroupController->GetWindowPairByDisplayId(displayId); + if (windowPair == nullptr) { + return {}; + } + return windowPair->GetPairedWindows(); +} + bool WindowRoot::IsForbidDockSliceMove(DisplayId displayId) const { auto container = const_cast(this)->GetOrCreateWindowNodeContainer(displayId); diff --git a/wmserver/src/zidl/window_manager_proxy.cpp b/wmserver/src/zidl/window_manager_proxy.cpp index 9e93ba8005..d397dec95f 100644 --- a/wmserver/src/zidl/window_manager_proxy.cpp +++ b/wmserver/src/zidl/window_manager_proxy.cpp @@ -690,5 +690,70 @@ WMError WindowManagerProxy::BindDialogTarget(uint32_t& windowId, sptr(ret); } + +void WindowManagerProxy::SetAnchorAndScale(int32_t x, int32_t y, float scale) +{ + MessageParcel data; + MessageParcel reply; + MessageOption option; + if (!data.WriteInterfaceToken(GetDescriptor())) { + WLOGFE("WriteInterfaceToken failed"); + return; + } + if (!data.WriteInt32(x)) { + WLOGFE("Write anchor x failed"); + return; + } + if (!data.WriteInt32(y)) { + WLOGFE("Write anchor y failed"); + return; + } + if (!data.WriteFloat(scale)) { + WLOGFE("Write scale failed"); + return; + } + if (Remote()->SendRequest(static_cast(WindowManagerMessage::TRANS_ID_SET_ANCHOR_AND_SCALE), + data, reply, option) != ERR_NONE) { + WLOGFE("SendRequest failed"); + } +} + +void WindowManagerProxy::SetAnchorOffset(int32_t deltaX, int32_t deltaY) +{ + MessageParcel data; + MessageParcel reply; + MessageOption option; + if (!data.WriteInterfaceToken(GetDescriptor())) { + WLOGFE("WriteInterfaceToken failed"); + return; + } + if (!data.WriteInt32(deltaX)) { + WLOGFE("Write anchor delatX failed"); + return; + } + if (!data.WriteInt32(deltaY)) { + WLOGFE("Write anchor deltaY failed"); + return; + } + if (Remote()->SendRequest(static_cast(WindowManagerMessage::TRANS_ID_SET_ANCHOR_OFFSET), + data, reply, option) != ERR_NONE) { + WLOGFE("SendRequest failed"); + } +} + +void WindowManagerProxy::OffWindowZoom() +{ + MessageParcel data; + MessageParcel reply; + MessageOption option; + if (!data.WriteInterfaceToken(GetDescriptor())) { + WLOGFE("WriteInterfaceToken failed"); + return; + } + if (Remote()->SendRequest(static_cast(WindowManagerMessage::TRANS_ID_OFF_WINDOW_ZOOM), + data, reply, option) != ERR_NONE) { + WLOGFE("SendRequest failed"); + } +} } // namespace Rosen } // namespace OHOS \ No newline at end of file diff --git a/wmserver/src/zidl/window_manager_stub.cpp b/wmserver/src/zidl/window_manager_stub.cpp index 2f26743e93..aa3c97f891 100644 --- a/wmserver/src/zidl/window_manager_stub.cpp +++ b/wmserver/src/zidl/window_manager_stub.cpp @@ -242,6 +242,23 @@ int32_t WindowManagerStub::OnRemoteRequest(uint32_t code, MessageParcel &data, M reply.WriteInt32(static_cast(errCode)); break; } + case WindowManagerMessage::TRANS_ID_SET_ANCHOR_AND_SCALE : { + int32_t x = data.ReadInt32(); + int32_t y = data.ReadInt32(); + float scale = data.ReadFloat(); + SetAnchorAndScale(x, y, scale); + break; + } + case WindowManagerMessage::TRANS_ID_SET_ANCHOR_OFFSET: { + int32_t deltaX = data.ReadInt32(); + int32_t deltaY = data.ReadInt32(); + SetAnchorOffset(deltaX, deltaY); + break; + } + case WindowManagerMessage::TRANS_ID_OFF_WINDOW_ZOOM: { + OffWindowZoom(); + break; + } default: WLOGFW("unknown transaction code %{public}d", code); return IPCObjectStub::OnRemoteRequest(code, data, reply, option); diff --git a/wmserver/test/unittest/avoid_area_controller_test.cpp b/wmserver/test/unittest/avoid_area_controller_test.cpp index 285b4de9c3..0b1562547d 100644 --- a/wmserver/test/unittest/avoid_area_controller_test.cpp +++ b/wmserver/test/unittest/avoid_area_controller_test.cpp @@ -86,6 +86,7 @@ public: void NotifyTouchOutside() override {} void NotifyScreenshot() override {} void NotifyDestroy(void) override {} + void UpdateZoomTransform(const Transform& trans, bool isDisplayZoomOn) override {} void DumpInfo(const std::vector& params, std::vector& info) override {} void NotifyWindowClientPointUp(const std::shared_ptr& pointerEvent) override {} RunnableFuture statusBarAvoidAreaFuture_; diff --git a/wmserver/test/unittest/window_node_test.cpp b/wmserver/test/unittest/window_node_test.cpp index ec4fded356..ad227c89dc 100644 --- a/wmserver/test/unittest/window_node_test.cpp +++ b/wmserver/test/unittest/window_node_test.cpp @@ -71,6 +71,7 @@ public: virtual void DumpInfo(const std::vector& params, std::vector& info) override {}; virtual void NotifyDestroy(void) override {}; virtual void NotifyWindowClientPointUp(const std::shared_ptr& pointerEvent) override {}; + void UpdateZoomTransform(const Transform& trans, bool isDisplayZoomOn) override {}; virtual sptr AsObject() override { -- Gitee