From ca69db75057f45d31bc48dad8e112b0d2fb8cb47 Mon Sep 17 00:00:00 2001 From: zhirong <215782872@qq.com> Date: Thu, 7 Jul 2022 19:29:34 +0800 Subject: [PATCH] enable window property transform Signed-off-by: zhirong <215782872@qq.com> Change-Id: I24e1790cefe5d11e29f9e9e2862effb79803603f Signed-off-by: zhirong <215782872@qq.com> --- interfaces/innerkits/wm/wm_common.h | 21 ++ .../window_napi/js_window_utils.cpp | 2 +- .../window_napi/js_window_utils.h | 2 +- utils/BUILD.gn | 1 + utils/include/window_helper.h | 90 +++++ utils/include/window_property.h | 8 + utils/include/wm_common_inner.h | 1 + utils/include/wm_math.h | 222 ++++++++++++ utils/src/window_property.cpp | 27 ++ utils/src/wm_math.cpp | 319 ++++++++++++++++++ wm/include/window_impl.h | 1 + wm/src/window_impl.cpp | 50 ++- wmserver/include/window_controller.h | 1 + wmserver/include/window_node.h | 2 + wmserver/src/input_window_monitor.cpp | 18 +- wmserver/src/window_controller.cpp | 16 + wmserver/src/window_layout_policy.cpp | 28 +- wmserver/src/window_node.cpp | 10 + 18 files changed, 796 insertions(+), 23 deletions(-) create mode 100644 utils/include/wm_math.h create mode 100644 utils/src/wm_math.cpp diff --git a/interfaces/innerkits/wm/wm_common.h b/interfaces/innerkits/wm/wm_common.h index e7b5805b..6763f76f 100644 --- a/interfaces/innerkits/wm/wm_common.h +++ b/interfaces/innerkits/wm/wm_common.h @@ -136,6 +136,7 @@ enum class WindowSizeChangeReason : uint32_t { RESIZE, MOVE, HIDE, + TRANSFORM, }; enum class WindowLayoutMode : uint32_t { @@ -181,6 +182,20 @@ public: translateX_(0.f), translateY_(0.f), translateZ_(0.f) {} ~Transform() {} + + bool operator!=(const Transform& right) const + { + return (pivotX_ - right.pivotX_) || (pivotY_ - right.pivotY_) || (scaleX_ - right.scaleX_) || + (scaleY_ - right.scaleY_) || (rotationX_ - right.rotationX_) || (rotationY_ - right.rotationY_) || + (rotationZ_ - right.rotationZ_) || (translateX_ - right.translateX_) || + (translateY_ - right.translateY_) || (translateZ_ - right.translateZ_); + } + + bool operator==(const Transform& right) const + { + return !(*this != right); + } + float pivotX_; float pivotY_; float scaleX_; @@ -191,6 +206,12 @@ public: float translateX_; float translateY_; float translateZ_; + + static const Transform& Identity() + { + static Transform I; + return I; + } }; struct SystemBarProperty { diff --git a/interfaces/kits/napi/window_runtime/window_napi/js_window_utils.cpp b/interfaces/kits/napi/window_runtime/window_napi/js_window_utils.cpp index 00dd8614..d9104d03 100644 --- a/interfaces/kits/napi/window_runtime/window_napi/js_window_utils.cpp +++ b/interfaces/kits/napi/window_runtime/window_napi/js_window_utils.cpp @@ -528,7 +528,7 @@ bool GetAPI7Ability(NativeEngine& engine, AppExecFwk::Ability* &ability) return true; } -bool ParseJsDoubleValue(NativeObject* jsObject, NativeEngine& engine, const std::string& name, double data) +bool ParseJsDoubleValue(NativeObject* jsObject, NativeEngine& engine, const std::string& name, double& data) { NativeValue* value = jsObject->GetProperty(name.c_str()); if (value->TypeOf() != NATIVE_UNDEFINED) { diff --git a/interfaces/kits/napi/window_runtime/window_napi/js_window_utils.h b/interfaces/kits/napi/window_runtime/window_napi/js_window_utils.h index b8ba7106..9a2fabeb 100644 --- a/interfaces/kits/napi/window_runtime/window_napi/js_window_utils.h +++ b/interfaces/kits/napi/window_runtime/window_napi/js_window_utils.h @@ -166,7 +166,7 @@ const std::map JS_TO_NATIVE_ORIENTATION_MAP { NativeValue* WindowStageEventTypeInit(NativeEngine* engine); NativeValue* WindowLayoutModeInit(NativeEngine* engine); bool GetAPI7Ability(NativeEngine& engine, AppExecFwk::Ability* &ability); - bool ParseJsDoubleValue(NativeObject* jsObject, NativeEngine& engine, const std::string& name, double data); + bool ParseJsDoubleValue(NativeObject* jsObject, NativeEngine& engine, const std::string& name, double& data); template inline bool ConvertNativeValueToVector(NativeEngine& engine, NativeValue* nativeValue, std::vector& out) { diff --git a/utils/BUILD.gn b/utils/BUILD.gn index 657637b7..1a184d87 100644 --- a/utils/BUILD.gn +++ b/utils/BUILD.gn @@ -39,6 +39,7 @@ ohos_shared_library("libwmutil") { "src/surface_reader_handler_impl.cpp", "src/window_property.cpp", "src/window_transition_info.cpp", + "src/wm_math.cpp", ] configs = [ ":libwmutil_private_config" ] diff --git a/utils/include/window_helper.h b/utils/include/window_helper.h index ff3be69c..d24bee50 100644 --- a/utils/include/window_helper.h +++ b/utils/include/window_helper.h @@ -20,6 +20,7 @@ #include "ability_info.h" #include "wm_common.h" #include "wm_common_inner.h" +#include "wm_math.h" namespace OHOS { namespace Rosen { @@ -325,6 +326,95 @@ public: return ret; } + // Transform a point at screen to its oringin position in 3D world and project to xy plane + // A screen point only has x and y component, so we need a plane to calculate its z component. + // | -- -- -- 0 | + // | -- -- -- 0 | + // There is no need to unify w component since the matrix is like | -- -- -- 0 | + // | -- -- -- 1 | + static PointInfo CalculateOriginPosition(const TransformHelper::Matrix4& transformMat, + const TransformHelper::Plane& plane, const PointInfo& pointPos) + { + TransformHelper::Matrix4 invertMat = transformMat; + invertMat.Invert(); + TransformHelper::Vector3 pointAtPlane; + pointAtPlane.x_ = static_cast(pointPos.x); + pointAtPlane.y_ = static_cast(pointPos.y); + pointAtPlane.z_ = plane.ComponentZ(pointAtPlane.x_, pointAtPlane.y_); + TransformHelper::Vector3 originPos = TransformHelper::Transform(pointAtPlane, invertMat); + return PointInfo { static_cast(originPos.x_), static_cast(originPos.y_) }; + } + + static TransformHelper::Matrix4 ComputeRectTransformMat4(const Transform& transform, const Rect& rect) + { + TransformHelper::Vector3 pivotPos = { + rect.posX_ + transform.pivotX_ * rect.width_, rect.posY_ + transform.pivotY_ * rect.height_, 0 }; + // move pivot point to (0,0,0) + TransformHelper::Matrix4 ret = TransformHelper::CreateTranslation(-pivotPos); + // set scale + if ((transform.scaleX_ - 1) || (transform.scaleY_ - 1)) { + ret *= TransformHelper::CreateScale(transform.scaleX_, transform.scaleY_, 1.0f); + } + // set rotation + if (transform.rotationX_) { + ret *= TransformHelper::CreateRotationX(MathHelper::ToRadians(transform.rotationX_)); + } + if (transform.rotationY_) { + ret *= TransformHelper::CreateRotationY(MathHelper::ToRadians(transform.rotationY_)); + } + if (transform.rotationZ_) { + ret *= TransformHelper::CreateRotationZ(MathHelper::ToRadians(transform.rotationZ_)); + } + // set translation + if (transform.translateX_ || transform.translateY_ || transform.translateZ_) { + ret *= TransformHelper::CreateTranslation(TransformHelper::Vector3(transform.translateX_, + transform.translateY_, transform.translateZ_)); + } + // move pivot point to old position + ret *= TransformHelper::CreateTranslation(pivotPos); + return ret; + } + + // Transform rect by matrix and get the circumscribed rect + static Rect TransformRect(const TransformHelper::Matrix4& transformMat, const Rect& rect) + { + TransformHelper::Vector3 a = TransformHelper::Transform( + TransformHelper::Vector3(rect.posX_, rect.posY_, 0), transformMat); + TransformHelper::Vector3 b = TransformHelper::Transform( + TransformHelper::Vector3(rect.posX_ + rect.width_, rect.posY_, 0), transformMat); + TransformHelper::Vector3 c = TransformHelper::Transform( + TransformHelper::Vector3(rect.posX_, rect.posY_ + rect.height_, 0), transformMat); + TransformHelper::Vector3 d = b + c - a; + // Return smallest rect involve transformed rect(abcd) + int32_t xmin = MathHelper::Min(a.x_, b.x_, c.x_, d.x_); + int32_t ymin = MathHelper::Min(a.y_, b.y_, c.y_, d.y_); + int32_t xmax = MathHelper::Max(a.x_, b.x_, c.x_, d.x_); + int32_t ymax = MathHelper::Max(a.y_, b.y_, c.y_, d.y_); + uint32_t w = xmax - xmin; + uint32_t h = ymax - ymin; + return Rect { xmin, ymin, w, h }; + } + + static TransformHelper::Vector2 CalculateHotZoneScale(const TransformHelper::Matrix4& transformMat, + const TransformHelper::Plane& plane) + { + TransformHelper::Vector2 hotZoneScale; + TransformHelper::Vector3 a = TransformHelper::Transform(TransformHelper::Vector3(0, 0, 0), + transformMat); + TransformHelper::Vector3 b = TransformHelper::Transform(TransformHelper::Vector3(1, 0, 0), + transformMat); + TransformHelper::Vector3 c = TransformHelper::Transform(TransformHelper::Vector3(0, 1, 0), + transformMat); + TransformHelper::Vector3 scale = transformMat.GetScale(); + hotZoneScale.x_ = scale.x_ * plane.ParallelDistanceGrad(a, c); + hotZoneScale.y_ = scale.y_ * plane.ParallelDistanceGrad(a, b); + if (std::isnan(hotZoneScale.x_) || std::isnan(hotZoneScale.y_)) { + return TransformHelper::Vector2(1, 1); + } else { + return hotZoneScale; + } + } + static bool CalculateTouchHotAreas(const Rect& windowRect, const std::vector& requestRects, std::vector& outRects) { diff --git a/utils/include/window_property.h b/utils/include/window_property.h index d3716143..dc6fb03a 100644 --- a/utils/include/window_property.h +++ b/utils/include/window_property.h @@ -24,6 +24,7 @@ #include "dm_common.h" #include "wm_common.h" #include "wm_common_inner.h" +#include "wm_math.h" namespace OHOS { namespace Rosen { @@ -76,6 +77,7 @@ public: void SetSizeLimits(const WindowSizeLimits& sizeLimits); WindowSizeChangeReason GetWindowSizeChangeReason() const; void SetTransform(const Transform& trans); + void ComputeTransform(); const std::string& GetWindowName() const; Rect GetRequestRect() const; @@ -114,6 +116,7 @@ public: uint32_t GetAccessTokenId() const; Transform GetTransform() const; WindowSizeLimits GetSizeLimits() const; + const TransformHelper::Matrix4& GetTransformMat() const; virtual bool Marshalling(Parcel& parcel) const override; static WindowProperty* Unmarshalling(Parcel& parcel); @@ -170,8 +173,13 @@ private: DragType dragType_ = DragType::DRAG_UNDEFINED; std::vector touchHotAreas_; // coordinates relative to window. uint32_t accessTokenId_ { 0 }; + // Transform info Transform trans_; + bool recomputeTransformMat_ { false }; + TransformHelper::Matrix4 transformMat_ = TransformHelper::Matrix4::Identity; + DEFINE_VAR_DEFAULT_FUNC_GET_SET(Orientation, RequestedOrientation, requestedOrientation, Orientation::UNSPECIFIED); + DEFINE_VAR_FUNC_GET_SET(TransformHelper::Plane, Plane, windowPlane); WindowSizeLimits sizeLimits_; }; } diff --git a/utils/include/wm_common_inner.h b/utils/include/wm_common_inner.h index 808f4083..0c5694f4 100644 --- a/utils/include/wm_common_inner.h +++ b/utils/include/wm_common_inner.h @@ -55,6 +55,7 @@ enum class WindowUpdateReason : uint32_t { UPDATE_TYPE, NEED_SWITCH_CASCADE_END, UPDATE_OTHER_PROPS, + UPDATE_TRANSFORM, }; enum class AvoidPosType : uint32_t { diff --git a/utils/include/wm_math.h b/utils/include/wm_math.h new file mode 100644 index 00000000..6fab826b --- /dev/null +++ b/utils/include/wm_math.h @@ -0,0 +1,222 @@ +/* + * 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_WM_MATH_H +#define OHOS_ROSEN_WM_MATH_H + +#include +#include + +namespace OHOS { +namespace Rosen { +namespace MathHelper { +constexpr float PI = 3.14159265f; +constexpr float INF = std::numeric_limits::infinity(); +constexpr float NAG_INF = -std::numeric_limits::infinity(); +constexpr float POS_ZERO = 0.001f; +constexpr float NAG_ZERO = -POS_ZERO; +inline bool NearZero(float val) +{ + return val < POS_ZERO && val > NAG_ZERO; +} + +inline float ToRadians(float degrees) +{ + return degrees * PI / 180.0f; +} + +inline float ToDegrees(float radians) +{ + return radians * 180.0f / PI; +} + +template +T Max(const T& a, const T& b) +{ + return (a < b ? b : a); +} + +template +T Max(const T& a, Ts... bs) +{ + T b = Max(bs...); + return (a > b ? a : b); +} + +template +T Min(const T& a, const T& b) +{ + return (a < b ? a : b); +} + +template +T Min(const T& a, Ts... bs) +{ + T b = Min(bs...); + return (a < b ? a : b); +} + +template +T Clamp(const T& value, const T& lower, const T& upper) +{ + return Min(upper, Max(lower, value)); +} +} // namespace MathHelper + +namespace TransformHelper { +struct Vector2 { + float x_, y_; + Vector2() : x_(0.0f), y_(0.0f) {} + Vector2(float inX, float inY) + : x_(inX), y_(inY) {} + friend Vector2 operator-(const Vector2& v) + { + return Vector2 { -v.x_, -v.y_ }; + } + friend Vector2 operator+(const Vector2& a, const Vector2& b) + { + return Vector2 { a.x_ + b.x_, a.y_ + b.y_ }; + } + friend Vector2 operator-(const Vector2& a, const Vector2& b) + { + return Vector2 { a.x_ - b.x_, a.y_ - b.y_ }; + } + float LengthSq() const + { + return (x_ * x_ + y_ * y_); + } + float Length() const + { + return (std::sqrt(LengthSq())); + } +}; + +struct Vector3 { + float x_, y_, z_; + Vector3() : x_(0.0f), y_(0.0f), z_(0.0f) {} + Vector3(float inX, float inY, float inZ) + : x_(inX), y_(inY), z_(inZ) {} + friend Vector3 operator-(const Vector3& v) + { + return Vector3 { -v.x_, -v.y_, -v.z_ }; + } + friend Vector3 operator+(const Vector3& a, const Vector3& b) + { + return Vector3 { a.x_ + b.x_, a.y_ + b.y_, a.z_ + b.z_ }; + } + friend Vector3 operator-(const Vector3& a, const Vector3& b) + { + return Vector3 { a.x_ - b.x_, a.y_ - b.y_, a.z_ - b.z_ }; + } + float LengthSq() const + { + return (x_ * x_ + y_ * y_ + z_ * z_); + } + float Length() const + { + return (std::sqrt(LengthSq())); + } + void Normalize() + { + float length = Length(); + if (length > MathHelper::POS_ZERO) { + x_ /= length; + y_ /= length; + z_ /= length; + } + } + static Vector3 Normalize(const Vector3& vec) + { + Vector3 temp = vec; + temp.Normalize(); + return temp; + } + static float Dot(const Vector3& a, const Vector3& b) + { + return (a.x_ * b.x_ + a.y_ * b.y_ + a.z_ * b.z_); + } + static Vector3 Cross(const Vector3& a, const Vector3& b) + { + Vector3 temp; + temp.x_ = a.y_ * b.z_ - a.z_ * b.y_; + temp.y_ = a.z_ * b.x_ - a.x_ * b.z_; + temp.z_ = a.x_ * b.y_ - a.y_ * b.x_; + return temp; + } +}; + +struct Matrix3 { + float mat_[3][3]; + + friend Matrix3 operator*(const Matrix3& left, const Matrix3& right); + Matrix3& operator*=(const Matrix3& right); + static const Matrix3 Identity; +}; + +struct Matrix4 { + float mat_[4][4]; + + friend Matrix4 operator*(const Matrix4& left, const Matrix4& right); + Matrix4& operator*=(const Matrix4& right); + void SwapRow(int row1, int row2); + // Inverse matrix with Gauss-Jordan method + void Invert(); + // Extract the scale component from the matrix + Vector3 GetScale() const; + static const Matrix4 Identity; + static constexpr int MAT_SIZE = 4; +}; + +struct Plane { + Plane() : normal_ { 0, 0, 1 }, d_ { 0 } {} + Plane(const Vector3& normal, float d); + Plane(const Vector3& a, const Vector3& b, const Vector3& c); + float ComponentZ(float x, float y) const; + // Compute the distance of parallel lines projected from this plane to xy plane + // it is assumed that distance of parallel lines in this plane is 1 + // a, b determine a line in this plane + float ParallelDistanceGrad(const Vector3& a, const Vector3& b) const; + + Vector3 normal_; // Normal vector of plane + float d_; // Signed distance from (0,0,0) to plane +}; +// Create a scale matrix with x and y scales(in xy-plane) +Matrix3 CreateScale(float xScale, float yScale); +// Create a rotation matrix about the Z axis +// theta is in radians +Matrix3 CreateRotation(float theta); +// Create a translation matrix (on the xy-plane) +Matrix3 CreateTranslation(const Vector2& trans); +// Create a scale matrix with x, y, and z scales +Matrix4 CreateScale(float xScale, float yScale, float zScale); +// Create a rotation matrix about X axis +// theta is in radians +Matrix4 CreateRotationX(float theta); +// Create a rotation matrix about Y axis +// theta is in radians +Matrix4 CreateRotationY(float theta); +// Create a rotation matrix about Z axis +// theta is in radians +Matrix4 CreateRotationZ(float theta); +// Create a 3D translation matrix +Matrix4 CreateTranslation(const Vector3& trans); +// Transform a Vector2 in xy-plane by matrix3 +Vector2 Transform(const Vector2& vec, const Matrix3& mat); +// Transform a Vector3 in 3D world by matrix4 +Vector3 Transform(const Vector3& vec, const Matrix4& mat); +} // namespace TransformHelper +} // namespace OHOS +} // namespace Rosen +#endif // OHOS_ROSEN_WM_MATH_H \ No newline at end of file diff --git a/utils/src/window_property.cpp b/utils/src/window_property.cpp index 98b04ef7..1a01e002 100644 --- a/utils/src/window_property.cpp +++ b/utils/src/window_property.cpp @@ -31,6 +31,7 @@ void WindowProperty::SetWindowName(const std::string& name) void WindowProperty::SetWindowRect(const struct Rect& rect) { + recomputeTransformMat_ = true; windowRect_ = rect; } @@ -108,9 +109,30 @@ void WindowProperty::SetAlpha(float alpha) void WindowProperty::SetTransform(const Transform& trans) { + recomputeTransformMat_ = true; trans_ = trans; } +void WindowProperty::ComputeTransform() +{ + if (recomputeTransformMat_ && (trans_ != Transform::Identity())) { + // Update transform matrix + transformMat_ = WindowHelper::ComputeRectTransformMat4(trans_, windowRect_); + // Update window plane + TransformHelper::Vector3 a = TransformHelper::Transform( + TransformHelper::Vector3 { static_cast(windowRect_.posX_), + static_cast(windowRect_.posY_), 0 }, transformMat_); + TransformHelper::Vector3 b = TransformHelper::Transform( + TransformHelper::Vector3 { static_cast(windowRect_.posX_ + windowRect_.width_), + static_cast(windowRect_.posY_), 0 }, transformMat_); + TransformHelper::Vector3 c = TransformHelper::Transform( + TransformHelper::Vector3 { static_cast(windowRect_.posX_), + static_cast(windowRect_.posY_+ windowRect_.height_), 0 }, transformMat_); + windowPlane_ = TransformHelper::Plane(a, b, c); + recomputeTransformMat_ = false; + } +} + void WindowProperty::SetBrightness(float brightness) { brightness_ = brightness; @@ -411,6 +433,11 @@ WindowSizeLimits WindowProperty::GetSizeLimits() const return sizeLimits_; } +const TransformHelper::Matrix4& WindowProperty::GetTransformMat() const +{ + return transformMat_; +} + void WindowProperty::SetTouchHotAreas(const std::vector& rects) { touchHotAreas_ = rects; diff --git a/utils/src/wm_math.cpp b/utils/src/wm_math.cpp new file mode 100644 index 00000000..e46143d5 --- /dev/null +++ b/utils/src/wm_math.cpp @@ -0,0 +1,319 @@ +/* + * 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 "wm_math.h" +#include + +namespace OHOS { +namespace Rosen { +namespace TransformHelper { +const Matrix3 Matrix3::Identity = { { + { 1, 0, 0 }, + { 0, 1, 0 }, + { 0, 0, 1 }, +} }; +const Matrix4 Matrix4::Identity = { { + { 1, 0, 0, 0 }, + { 0, 1, 0, 0 }, + { 0, 0, 1, 0 }, + { 0, 0, 0, 1 }, +} }; + +Matrix3 operator*(const Matrix3& left, const Matrix3& right) +{ + return { { + // row 0 + { left.mat_[0][0] * right.mat_[0][0] + left.mat_[0][1] * right.mat_[1][0] + left.mat_[0][2] * right.mat_[2][0], + left.mat_[0][0] * right.mat_[0][1] + left.mat_[0][1] * right.mat_[1][1] + left.mat_[0][2] * right.mat_[2][1], + left.mat_[0][0] * right.mat_[0][2] + left.mat_[0][1] * right.mat_[1][2] + left.mat_[0][2] * right.mat_[2][2] }, + + // row 1 + { left.mat_[1][0] * right.mat_[0][0] + left.mat_[1][1] * right.mat_[1][0] + left.mat_[1][2] * right.mat_[2][0], + left.mat_[1][0] * right.mat_[0][1] + left.mat_[1][1] * right.mat_[1][1] + left.mat_[1][2] * right.mat_[2][1], + left.mat_[1][0] * right.mat_[0][2] + left.mat_[1][1] * right.mat_[1][2] + left.mat_[1][2] * right.mat_[2][2] }, + + // row 2 + { left.mat_[2][0] * right.mat_[0][0] + left.mat_[2][1] * right.mat_[1][0] + left.mat_[2][2] * right.mat_[2][0], + left.mat_[2][0] * right.mat_[0][1] + left.mat_[2][1] * right.mat_[1][1] + left.mat_[2][2] * right.mat_[2][1], + left.mat_[2][0] * right.mat_[0][2] + left.mat_[2][1] * right.mat_[1][2] + left.mat_[2][2] * right.mat_[2][2] } + } }; +} + +Matrix3& Matrix3::operator*=(const Matrix3& right) +{ + *this = *this * right; + return *this; +} + +Matrix4 operator*(const Matrix4& left, const Matrix4& right) +{ + return { { + // row 0 + { left.mat_[0][0] * right.mat_[0][0] + left.mat_[0][1] * right.mat_[1][0] + + left.mat_[0][2] * right.mat_[2][0] + left.mat_[0][3] * right.mat_[3][0], + left.mat_[0][0] * right.mat_[0][1] + left.mat_[0][1] * right.mat_[1][1] + + left.mat_[0][2] * right.mat_[2][1] + left.mat_[0][3] * right.mat_[3][1], + left.mat_[0][0] * right.mat_[0][2] + left.mat_[0][1] * right.mat_[1][2] + + left.mat_[0][2] * right.mat_[2][2] + left.mat_[0][3] * right.mat_[3][2], + left.mat_[0][0] * right.mat_[0][3] + left.mat_[0][1] * right.mat_[1][3] + + left.mat_[0][2] * right.mat_[2][3] + left.mat_[0][3] * right.mat_[3][3] }, + + // row 1 + { left.mat_[1][0] * right.mat_[0][0] + left.mat_[1][1] * right.mat_[1][0] + + left.mat_[1][2] * right.mat_[2][0] + left.mat_[1][3] * right.mat_[3][0], + left.mat_[1][0] * right.mat_[0][1] + left.mat_[1][1] * right.mat_[1][1] + + left.mat_[1][2] * right.mat_[2][1] + left.mat_[1][3] * right.mat_[3][1], + left.mat_[1][0] * right.mat_[0][2] + left.mat_[1][1] * right.mat_[1][2] + + left.mat_[1][2] * right.mat_[2][2] + left.mat_[1][3] * right.mat_[3][2], + left.mat_[1][0] * right.mat_[0][3] + left.mat_[1][1] * right.mat_[1][3] + + left.mat_[1][2] * right.mat_[2][3] + left.mat_[1][3] * right.mat_[3][3] }, + + // row 2 + { left.mat_[2][0] * right.mat_[0][0] + left.mat_[2][1] * right.mat_[1][0] + + left.mat_[2][2] * right.mat_[2][0] + left.mat_[2][3] * right.mat_[3][0], + left.mat_[2][0] * right.mat_[0][1] + left.mat_[2][1] * right.mat_[1][1] + + left.mat_[2][2] * right.mat_[2][1] + left.mat_[2][3] * right.mat_[3][1], + left.mat_[2][0] * right.mat_[0][2] + left.mat_[2][1] * right.mat_[1][2] + + left.mat_[2][2] * right.mat_[2][2] + left.mat_[2][3] * right.mat_[3][2], + left.mat_[2][0] * right.mat_[0][3] + left.mat_[2][1] * right.mat_[1][3] + + left.mat_[2][2] * right.mat_[2][3] + left.mat_[2][3] * right.mat_[3][3] }, + + // row 3 + { left.mat_[3][0] * right.mat_[0][0] + left.mat_[3][1] * right.mat_[1][0] + + left.mat_[3][2] * right.mat_[2][0] + left.mat_[3][3] * right.mat_[3][0], + left.mat_[3][0] * right.mat_[0][1] + left.mat_[3][1] * right.mat_[1][1] + + left.mat_[3][2] * right.mat_[2][1] + left.mat_[3][3] * right.mat_[3][1], + left.mat_[3][0] * right.mat_[0][2] + left.mat_[3][1] * right.mat_[1][2] + + left.mat_[3][2] * right.mat_[2][2] + left.mat_[3][3] * right.mat_[3][2], + left.mat_[3][0] * right.mat_[0][3] + left.mat_[3][1] * right.mat_[1][3] + + left.mat_[3][2] * right.mat_[2][3] + left.mat_[3][3] * right.mat_[3][3] } + } }; +} + +Matrix4& Matrix4::operator*=(const Matrix4& right) +{ + *this = *this * right; + return *this; +} + +void Matrix4::SwapRow(int row1, int row2) +{ + float *p = mat_[row1]; + float *q = mat_[row2]; + float tmp = p[0]; + p[0] = q[0]; + q[0] = tmp; + + tmp = p[1]; + p[1] = q[1]; + q[1] = tmp; + + tmp = p[2]; + p[2] = q[2]; + q[2] = tmp; + + tmp = p[3]; + p[3] = q[3]; + q[3] = tmp; +} + +void Matrix4::Invert() +{ + // Inverse matrix with Gauss-Jordan method + Matrix4 tmp = Matrix4::Identity; + int i, j, k; + float t, u; + for (k = 0; k < MAT_SIZE; k++) { + t = mat_[k][k]; + if (t < MathHelper::POS_ZERO && t > MathHelper::NAG_ZERO) { + for (i = k + 1; i < MAT_SIZE; i++) { + if (mat_[i][k] < MathHelper::NAG_ZERO || mat_[i][k] > MathHelper::POS_ZERO) { + SwapRow(k, i); + tmp.SwapRow(k, i); + break; + } + } + t = mat_[k][k]; + } + for (j = 0; j <= k; j++) { + tmp.mat_[k][j] /= t; + } + for (; j < MAT_SIZE; j++) { + mat_[k][j] /= t; + tmp.mat_[k][j] /= t; + } + for (i = 0; i < MAT_SIZE; i++) { + if (i == k) { + continue; + } + u = mat_[i][k]; + for (j = 0; j <= k; j++) { + tmp.mat_[i][j] -= tmp.mat_[k][j] * u; + } + for (; j < MAT_SIZE; j++) { + mat_[i][j] -= mat_[k][j] * u; + tmp.mat_[i][j] -= tmp.mat_[k][j] * u; + } + } + } + *this = tmp; +} + +Vector3 Matrix4::GetScale() const +{ + Vector3 retVal; + retVal.x_ = Vector3(mat_[0][0], mat_[0][1], mat_[0][2]).Length(); + retVal.y_ = Vector3(mat_[1][0], mat_[1][1], mat_[1][2]).Length(); + retVal.z_ = Vector3(mat_[2][0], mat_[2][1], mat_[2][2]).Length(); + return retVal; +} + +Plane::Plane(const Vector3& normal, float d) + : normal_(normal), d_(d) +{ +} + +Plane::Plane(const Vector3& a, const Vector3& b, const Vector3& c) +{ + Vector3 ab = b - a; + Vector3 ac = c - a; + normal_ = Vector3::Cross(ab, ac); + normal_.Normalize(); + d_ = -Vector3::Dot(a, normal_); +} + +float Plane::ComponentZ(float x, float y) const +{ + return (-d_ - normal_.x_ * x - normal_.y_ * y) / normal_.z_; +} + +float Plane::ParallelDistanceGrad(const Vector3& a, const Vector3& b) const +{ + Vector2 axy(a.x_, a.y_), bxy(b.x_, b.y_); + return (b - a).Length() * std::abs(normal_.z_) / (bxy - axy).Length(); +} + +// Create a scale matrix with x and y scales +Matrix3 CreateScale(float xScale, float yScale) +{ + return { { + { xScale, 0.0f, 0.0f }, + { 0.0f, yScale, 0.0f }, + { 0.0f, 0.0f, 1.0f }, + } }; +} + +// Create a rotation matrix about the Z axis +// theta is in radians +Matrix3 CreateRotation(float theta) +{ + return { { + { std::cos(theta), std::sin(theta), 0.0f }, + { -std::sin(theta), std::cos(theta), 0.0f }, + { 0.0f, 0.0f, 1.0f }, + } }; +} + +// Create a translation matrix (on the xy-plane) +Matrix3 CreateTranslation(const Vector2& trans) +{ + return { { + { 1.0f, 0.0f, 0.0f }, + { 0.0f, 1.0f, 0.0f }, + { trans.x_, trans.y_, 1.0f }, + } }; +} + +// Create a scale matrix with x, y, and z scales +Matrix4 CreateScale(float xScale, float yScale, float zScale) +{ + return { { + { xScale, 0.0f, 0.0f, 0.0f }, + { 0.0f, yScale, 0.0f, 0.0f }, + { 0.0f, 0.0f, zScale, 0.0f }, + { 0.0f, 0.0f, 0.0f, 1.0f }, + } }; +} + +// Create a rotation matrix about X axis +// theta is in radians +Matrix4 CreateRotationX(float theta) +{ + return { { + { 1.0f, 0.0f, 0.0f, 0.0f }, + { 0.0f, std::cos(theta), std::sin(theta), 0.0f }, + { 0.0f, -std::sin(theta), std::cos(theta), 0.0f }, + { 0.0f, 0.0f, 0.0f, 1.0f }, + } }; +} + +// Create a rotation matrix about Y axis +// theta is in radians +Matrix4 CreateRotationY(float theta) +{ + return { { + { std::cos(theta), 0.0f, -std::sin(theta), 0.0f }, + { 0.0f, 1.0f, 0.0f, 0.0f }, + { std::sin(theta), 0.0f, std::cos(theta), 0.0f }, + { 0.0f, 0.0f, 0.0f, 1.0f }, + } }; +} + +// Create a rotation matrix about Z axis +// theta is in radians +Matrix4 CreateRotationZ(float theta) +{ + return { { + { std::cos(theta), std::sin(theta), 0.0f, 0.0f }, + { -std::sin(theta), std::cos(theta), 0.0f, 0.0f }, + { 0.0f, 0.0f, 1.0f, 0.0f }, + { 0.0f, 0.0f, 0.0f, 1.0f }, + } }; +} + +// Create a 3D translation matrix +Matrix4 CreateTranslation(const Vector3& trans) +{ + return { { + { 1.0f, 0.0f, 0.0f, 0.0f }, + { 0.0f, 1.0f, 0.0f, 0.0f }, + { 0.0f, 0.0f, 1.0f, 0.0f }, + { trans.x_, trans.y_, trans.z_, 1.0f }, + } }; +} + +// Transform a Vector2 in xy-plane by matrix3 +Vector2 Transform(const Vector2& vec, const Matrix3& mat) +{ + Vector2 retVal; + retVal.x_ = vec.x_ * mat.mat_[0][0] + vec.y_ * mat.mat_[1][0] + mat.mat_[2][0]; + retVal.y_ = vec.x_ * mat.mat_[0][1] + vec.y_ * mat.mat_[1][1] + mat.mat_[2][1]; + return retVal; +} + +// Transform a Vector3 in 3D world by matrix4 +Vector3 Transform(const Vector3& vec, const Matrix4& mat) +{ + Vector3 retVal; + retVal.x_ = vec.x_ * mat.mat_[0][0] + vec.y_ * mat.mat_[1][0] + + vec.z_ * mat.mat_[2][0] + mat.mat_[3][0]; + retVal.y_ = vec.x_ * mat.mat_[0][1] + vec.y_ * mat.mat_[1][1] + + vec.z_ * mat.mat_[2][1] + mat.mat_[3][1]; + retVal.z_ = vec.x_ * mat.mat_[0][2] + vec.y_ * mat.mat_[1][2] + + vec.z_ * mat.mat_[2][2] + mat.mat_[3][2]; + return retVal; +} +} // namespace TransformHelper +} // namespace Rosen +} // namespace OHOS diff --git a/wm/include/window_impl.h b/wm/include/window_impl.h index a17d05a6..581ecb71 100644 --- a/wm/include/window_impl.h +++ b/wm/include/window_impl.h @@ -345,6 +345,7 @@ private: Rect GetSystemAlarmWindowDefaultSize(Rect defaultRect); void HandleModeChangeHotZones(int32_t posX, int32_t posY); WMError NotifyWindowTransition(TransitionReason reason); + void UpdatePointerEvent(std::shared_ptr& pointerEvent); void UpdatePointerEventForStretchableWindow(std::shared_ptr& pointerEvent); void UpdateDragType(); void InitListenerHandler(); diff --git a/wm/src/window_impl.cpp b/wm/src/window_impl.cpp index 72ad62d1..95d71e6d 100755 --- a/wm/src/window_impl.cpp +++ b/wm/src/window_impl.cpp @@ -1924,6 +1924,28 @@ void WindowImpl::HandleModeChangeHotZones(int32_t posX, int32_t posY) } } +void WindowImpl::UpdatePointerEvent(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(), property_->GetPlane(), + { 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(std::shared_ptr& pointerEvent) { MMI::PointerEvent::PointerItem pointerItem; @@ -1986,6 +2008,12 @@ void WindowImpl::ReadyToMoveOrDragWindow(int32_t globalX, int32_t globalY, int32 if (pointEventStarted_) { return; } + TransformHelper::Vector2 hotZoneScale(1, 1); + if (property_->GetTransform() != Transform::Identity()) { + property_->ComputeTransform(); + hotZoneScale = WindowHelper::CalculateHotZoneScale(property_->GetTransformMat(), + property_->GetPlane()); + } startPointRect_ = rect; startPointPosX_ = globalX; startPointPosY_ = globalY; @@ -2002,22 +2030,24 @@ void WindowImpl::ReadyToMoveOrDragWindow(int32_t globalX, int32_t globalY, int32 float virtualPixelRatio = display->GetVirtualPixelRatio(); startRectExceptFrame_.posX_ = startPointRect_.posX_ + - static_cast(WINDOW_FRAME_WIDTH * virtualPixelRatio); + static_cast(WINDOW_FRAME_WIDTH * virtualPixelRatio / hotZoneScale.x_); startRectExceptFrame_.posY_ = startPointRect_.posY_ + - static_cast(WINDOW_FRAME_WIDTH * virtualPixelRatio); + static_cast(WINDOW_FRAME_WIDTH * virtualPixelRatio / hotZoneScale.y_); startRectExceptFrame_.width_ = startPointRect_.width_ - - static_cast((WINDOW_FRAME_WIDTH + WINDOW_FRAME_WIDTH) * virtualPixelRatio); + static_cast((WINDOW_FRAME_WIDTH + WINDOW_FRAME_WIDTH) * virtualPixelRatio / hotZoneScale.x_); startRectExceptFrame_.height_ = startPointRect_.height_ - - static_cast((WINDOW_FRAME_WIDTH + WINDOW_FRAME_WIDTH) * virtualPixelRatio); + static_cast((WINDOW_FRAME_WIDTH + WINDOW_FRAME_WIDTH) * virtualPixelRatio / hotZoneScale.y_); startRectExceptCorner_.posX_ = startPointRect_.posX_ + - static_cast(WINDOW_FRAME_CORNER_WIDTH * virtualPixelRatio); + static_cast(WINDOW_FRAME_CORNER_WIDTH * virtualPixelRatio / hotZoneScale.x_); startRectExceptCorner_.posY_ = startPointRect_.posY_ + - static_cast(WINDOW_FRAME_CORNER_WIDTH * virtualPixelRatio); + static_cast(WINDOW_FRAME_CORNER_WIDTH * virtualPixelRatio / hotZoneScale.y_); startRectExceptCorner_.width_ = startPointRect_.width_ - - static_cast((WINDOW_FRAME_CORNER_WIDTH + WINDOW_FRAME_CORNER_WIDTH) * virtualPixelRatio); + static_cast((WINDOW_FRAME_CORNER_WIDTH + WINDOW_FRAME_CORNER_WIDTH) * + virtualPixelRatio / hotZoneScale.x_); startRectExceptCorner_.height_ = startPointRect_.height_ - - static_cast((WINDOW_FRAME_CORNER_WIDTH + WINDOW_FRAME_CORNER_WIDTH) * virtualPixelRatio); + static_cast((WINDOW_FRAME_CORNER_WIDTH + WINDOW_FRAME_CORNER_WIDTH) * + virtualPixelRatio / hotZoneScale.y_); if (GetType() == WindowType::WINDOW_TYPE_DOCK_SLICE) { startMoveFlag_ = true; @@ -2103,6 +2133,10 @@ void WindowImpl::AdjustWindowAnimationFlag(bool withAnimation) void WindowImpl::ConsumePointerEvent(std::shared_ptr& pointerEvent) { + // If windowRect transformed, transform event back to its origin position + if (property_->GetTransform() != Transform::Identity()) { + UpdatePointerEvent(pointerEvent); + } int32_t action = pointerEvent->GetPointerAction(); if (action == MMI::PointerEvent::POINTER_ACTION_DOWN || action == MMI::PointerEvent::POINTER_ACTION_BUTTON_DOWN) { WLOGI("WMS process point down, window: [name:%{public}s, id:%{public}u], action: %{public}d", diff --git a/wmserver/include/window_controller.h b/wmserver/include/window_controller.h index beb2a566..1308713c 100644 --- a/wmserver/include/window_controller.h +++ b/wmserver/include/window_controller.h @@ -83,6 +83,7 @@ private: void HandleTurnScreenOn(const sptr& node); void ProcessSystemBarChange(const sptr& displayInfo); WMError UpdateTouchHotAreas(const sptr& node, const std::vector& rects); + WMError UpdateTransform(uint32_t windowId); void NotifyTouchOutside(const sptr& node); uint32_t GetEmbedNodeId(const std::vector>& windowNodes, const sptr& node); void NotifyWindowPropertyChanged(const sptr& node); diff --git a/wmserver/include/window_node.h b/wmserver/include/window_node.h index 8fb948f1..ade0feea 100644 --- a/wmserver/include/window_node.h +++ b/wmserver/include/window_node.h @@ -72,6 +72,8 @@ public: void SetOriginRect(const Rect& rect); void SetTouchHotAreas(const std::vector& rects); void SetWindowSizeLimits(const WindowSizeLimits& sizeLimits); + void ComputeTransform(); + void SetTransform(const Transform& trans); const sptr& GetWindowToken() const; uint32_t GetWindowId() const; diff --git a/wmserver/src/input_window_monitor.cpp b/wmserver/src/input_window_monitor.cpp index cb53ec26..b971670e 100644 --- a/wmserver/src/input_window_monitor.cpp +++ b/wmserver/src/input_window_monitor.cpp @@ -19,6 +19,7 @@ #include "display_manager_service_inner.h" #include "dm_common.h" +#include "window_helper.h" #include "window_manager_hilog.h" namespace OHOS { @@ -128,13 +129,24 @@ void InputWindowMonitor::TraverseWindowNodes(const std::vector> } std::vector touchHotAreas; windowNode->GetTouchHotAreas(touchHotAreas); - Rect windowRect = windowNode->GetWindowRect(); + Rect areaRect = windowNode->GetWindowRect(); + if (windowNode->GetWindowProperty()->GetTransform() != Transform::Identity()) { + windowNode->ComputeTransform(); + for (Rect& rect : touchHotAreas) { + rect = WindowHelper::TransformRect(windowNode->GetWindowProperty()->GetTransformMat(), rect); + } + WLOGFI("area rect befoe tranform: [%{public}d, %{public}d, %{public}u, %{public}u]", + areaRect.posX_, areaRect.posY_, areaRect.width_, areaRect.height_); + areaRect = WindowHelper::TransformRect(windowNode->GetWindowProperty()->GetTransformMat(), areaRect); + WLOGFI("area rect after tranform: [%{public}d, %{public}d, %{public}u, %{public}u]", + areaRect.posX_, areaRect.posY_, areaRect.width_, areaRect.height_); + } MMI::WindowInfo windowInfo = { .id = static_cast(windowNode->GetWindowId()), .pid = windowNode->GetCallingPid(), .uid = windowNode->GetCallingUid(), - .area = MMI::Rect{ windowRect.posX_, windowRect.posY_, - static_cast(windowRect.width_), static_cast(windowRect.height_) }, + .area = MMI::Rect { areaRect.posX_, areaRect.posY_, + static_cast(areaRect.width_), static_cast(areaRect.height_) }, .agentWindowId = static_cast(windowNode->GetWindowId()), }; convertRectsToMmiRects(touchHotAreas, windowInfo.defaultHotAreas); diff --git a/wmserver/src/window_controller.cpp b/wmserver/src/window_controller.cpp index 04f37893..f62a70d8 100644 --- a/wmserver/src/window_controller.cpp +++ b/wmserver/src/window_controller.cpp @@ -891,6 +891,12 @@ WMError WindowController::UpdateProperty(sptr& property, Propert UpdateWindowAnimation(node); break; } + case PropertyChangeAction::ACTION_UPDATE_TRANSFORM_PROPERTY: { + node->SetTransform(property->GetTransform()); + node->SetWindowSizeChangeReason(WindowSizeChangeReason::TRANSFORM); + ret = UpdateTransform(windowId); + break; + } default: break; } @@ -950,6 +956,16 @@ WMError WindowController::UpdateTouchHotAreas(const sptr& node, cons return WMError::WM_OK; } +WMError WindowController::UpdateTransform(uint32_t windowId) +{ + WMError res = windowRoot_->UpdateWindowNode(windowId, WindowUpdateReason::UPDATE_TRANSFORM); + if (res != WMError::WM_OK) { + return res; + } + FlushWindowInfo(windowId); + return WMError::WM_OK; +} + void WindowController::NotifyTouchOutside(const sptr& node) { auto windowNodeContainer = windowRoot_->GetOrCreateWindowNodeContainer(node->GetDisplayId()); diff --git a/wmserver/src/window_layout_policy.cpp b/wmserver/src/window_layout_policy.cpp index 7bd0f8a4..b88caec3 100644 --- a/wmserver/src/window_layout_policy.cpp +++ b/wmserver/src/window_layout_policy.cpp @@ -422,23 +422,30 @@ void WindowLayoutPolicy::CalcAndSetNodeHotZone(const Rect& winRect, const sptrGetDisplayId()); - uint32_t hotZone = static_cast(HOTZONE * virtualPixelRatio); + TransformHelper::Vector2 hotZoneScale(1, 1); + if (node->GetWindowProperty()->GetTransform() != Transform::Identity()) { + node->ComputeTransform(); + hotZoneScale = WindowHelper::CalculateHotZoneScale(node->GetWindowProperty()->GetTransformMat(), + node->GetWindowProperty()->GetPlane()); + } + uint32_t hotZoneX = static_cast(HOTZONE * virtualPixelRatio / hotZoneScale.x_); + uint32_t hotZoneY = static_cast(HOTZONE * virtualPixelRatio / hotZoneScale.y_); if (node->GetWindowType() == WindowType::WINDOW_TYPE_DOCK_SLICE) { if (rect.width_ < rect.height_) { - rect.posX_ -= hotZone; - rect.width_ += (hotZone + hotZone); + rect.posX_ -= hotZoneX; + rect.width_ += (hotZoneX + hotZoneX); } else { - rect.posY_ -= hotZone; - rect.height_ += (hotZone + hotZone); + rect.posY_ -= hotZoneY; + rect.height_ += (hotZoneY + hotZoneY); } } else if (node->GetWindowType() == WindowType::WINDOW_TYPE_LAUNCHER_RECENT) { rect = displayGroupInfo_->GetDisplayRect(node->GetDisplayId()); } else if (WindowHelper::IsMainFloatingWindow(node->GetWindowType(), node->GetWindowMode())) { - rect.posX_ -= hotZone; - rect.posY_ -= hotZone; - rect.width_ += (hotZone + hotZone); - rect.height_ += (hotZone + hotZone); + rect.posX_ -= hotZoneX; + rect.posY_ -= hotZoneY; + rect.width_ += (hotZoneX + hotZoneX); + rect.height_ += (hotZoneY + hotZoneY); } node->SetFullWindowHotArea(rect); std::vector requestedHotAreas; @@ -938,7 +945,8 @@ bool WindowLayoutPolicy::IsFullScreenRecentWindowExist(const std::vector& node, const Rect& winRect, const Rect& preRect) { - if (node->GetWindowType() == WindowType::WINDOW_TYPE_APP_COMPONENT) { + if (node->GetWindowType() == WindowType::WINDOW_TYPE_APP_COMPONENT || + node->GetWindowSizeChangeReason() == WindowSizeChangeReason::TRANSFORM) { WLOGFI("not need to update bounds"); return; } diff --git a/wmserver/src/window_node.cpp b/wmserver/src/window_node.cpp index d7b87473..5fb8d7c9 100644 --- a/wmserver/src/window_node.cpp +++ b/wmserver/src/window_node.cpp @@ -201,6 +201,16 @@ void WindowNode::SetWindowSizeLimits(const WindowSizeLimits& sizeLimits) property_->SetSizeLimits(sizeLimits); } +void WindowNode::ComputeTransform() +{ + property_->ComputeTransform(); +} + +void WindowNode::SetTransform(const Transform& trans) +{ + property_->SetTransform(trans); +} + WindowSizeLimits WindowNode::GetWindowSizeLimits() const { return property_->GetSizeLimits();