1 /* 2 * Copyright (c) 2021-2023 Huawei Device Co., Ltd. 3 * Licensed under the Apache License, Version 2.0 (the "License"); 4 * you may not use this file except in compliance with the License. 5 * You may obtain a copy of the License at 6 * 7 * http://www.apache.org/licenses/LICENSE-2.0 8 * 9 * Unless required by applicable law or agreed to in writing, software 10 * distributed under the License is distributed on an "AS IS" BASIS, 11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 * See the License for the specific language governing permissions and 13 * limitations under the License. 14 */ 15 16 #ifndef OHOS_WM_INCLUDE_WM_HELPER_H 17 #define OHOS_WM_INCLUDE_WM_HELPER_H 18 19 #include <unistd.h> 20 #include <vector> 21 #include "ability_info.h" 22 #include "window_transition_info.h" 23 #include "wm_common.h" 24 #include "wm_common_inner.h" 25 #include "wm_math.h" 26 27 namespace OHOS { 28 namespace Rosen { 29 class WindowHelper { 30 public: IsMainWindow(WindowType type)31 static inline bool IsMainWindow(WindowType type) 32 { 33 return (type >= WindowType::APP_MAIN_WINDOW_BASE && type < WindowType::APP_MAIN_WINDOW_END); 34 } 35 IsMainWindowAndNotShown(WindowType type,WindowState state)36 static inline bool IsMainWindowAndNotShown(WindowType type, WindowState state) 37 { 38 return (IsMainWindow(type) && state != WindowState::STATE_SHOWN); 39 } 40 IsModalMainWindow(WindowType type,uint32_t windowFlags)41 static inline bool IsModalMainWindow(WindowType type, uint32_t windowFlags) 42 { 43 return IsMainWindow(type) && (windowFlags & static_cast<uint32_t>(WindowFlag::WINDOW_FLAG_IS_MODAL)); 44 } 45 IsSubWindow(WindowType type)46 static inline bool IsSubWindow(WindowType type) 47 { 48 return (type >= WindowType::APP_SUB_WINDOW_BASE && type < WindowType::APP_SUB_WINDOW_END); 49 } 50 IsNormalSubWindow(WindowType type,uint32_t windowFlags)51 static inline bool IsNormalSubWindow(WindowType type, uint32_t windowFlags) 52 { 53 const uint32_t mask = static_cast<uint32_t>(WindowFlag::WINDOW_FLAG_IS_MODAL) | 54 static_cast<uint32_t>(WindowFlag::WINDOW_FLAG_IS_TOAST) | 55 static_cast<uint32_t>(WindowFlag::WINDOW_FLAG_IS_TEXT_MENU); 56 return ((windowFlags & mask) == 0 && IsSubWindow(type)); 57 } 58 IsModalSubWindow(WindowType type,uint32_t windowFlags)59 static inline bool IsModalSubWindow(WindowType type, uint32_t windowFlags) 60 { 61 return IsSubWindow(type) && (windowFlags & static_cast<uint32_t>(WindowFlag::WINDOW_FLAG_IS_MODAL)); 62 } 63 IsApplicationModalSubWindow(WindowType type,uint32_t windowFlags)64 static inline bool IsApplicationModalSubWindow(WindowType type, uint32_t windowFlags) 65 { 66 return IsModalSubWindow(type, windowFlags) && 67 (windowFlags & static_cast<uint32_t>(WindowFlag::WINDOW_FLAG_IS_APPLICATION_MODAL)); 68 } 69 IsToastSubWindow(WindowType type,uint32_t windowFlags)70 static inline bool IsToastSubWindow(WindowType type, uint32_t windowFlags) 71 { 72 return IsSubWindow(type) && (windowFlags & static_cast<uint32_t>(WindowFlag::WINDOW_FLAG_IS_TOAST)); 73 } 74 IsModalWindow(uint32_t windowFlags)75 static inline bool IsModalWindow(uint32_t windowFlags) 76 { 77 return (windowFlags & static_cast<uint32_t>(WindowFlag::WINDOW_FLAG_IS_APPLICATION_MODAL)) || 78 (windowFlags & static_cast<uint32_t>(WindowFlag::WINDOW_FLAG_IS_MODAL)); 79 } 80 IsTextMenuSubWindow(WindowType type,uint32_t windowFlags)81 static inline bool IsTextMenuSubWindow(WindowType type, uint32_t windowFlags) 82 { 83 return IsSubWindow(type) && (windowFlags & static_cast<uint32_t>(WindowFlag::WINDOW_FLAG_IS_TEXT_MENU)); 84 } 85 IsDialogWindow(WindowType type)86 static inline bool IsDialogWindow(WindowType type) 87 { 88 return type == WindowType::WINDOW_TYPE_DIALOG; 89 } 90 IsAppWindow(WindowType type)91 static inline bool IsAppWindow(WindowType type) 92 { 93 return (IsMainWindow(type) || IsSubWindow(type)); 94 } 95 IsAppFloatingWindow(WindowType type)96 static inline bool IsAppFloatingWindow(WindowType type) 97 { 98 return (type == WindowType::WINDOW_TYPE_FLOAT) || (type == WindowType::WINDOW_TYPE_FLOAT_CAMERA); 99 } 100 IsFloatOrSubWindow(WindowType type)101 static inline bool IsFloatOrSubWindow(WindowType type) 102 { 103 return type == WindowType::WINDOW_TYPE_FLOAT || IsSubWindow(type); 104 } 105 IsPipWindow(WindowType type)106 static inline bool IsPipWindow(WindowType type) 107 { 108 return (type == WindowType::WINDOW_TYPE_PIP); 109 } 110 IsFbWindow(WindowType type)111 static inline bool IsFbWindow(WindowType type) 112 { 113 return (type == WindowType::WINDOW_TYPE_FB); 114 } 115 IsBelowSystemWindow(WindowType type)116 static inline bool IsBelowSystemWindow(WindowType type) 117 { 118 return (type >= WindowType::BELOW_APP_SYSTEM_WINDOW_BASE && type < WindowType::BELOW_APP_SYSTEM_WINDOW_END); 119 } 120 IsAboveSystemWindow(WindowType type)121 static inline bool IsAboveSystemWindow(WindowType type) 122 { 123 return (type >= WindowType::ABOVE_APP_SYSTEM_WINDOW_BASE && type < WindowType::ABOVE_APP_SYSTEM_WINDOW_END); 124 } 125 IsSystemSubWindow(WindowType type)126 static inline bool IsSystemSubWindow(WindowType type) 127 { 128 return (type >= WindowType::SYSTEM_SUB_WINDOW_BASE && type < WindowType::SYSTEM_SUB_WINDOW_END); 129 } 130 IsSystemMainWindow(WindowType type)131 static inline bool IsSystemMainWindow(WindowType type) 132 { 133 return IsBelowSystemWindow(type) || IsAboveSystemWindow(type); 134 } 135 IsSystemWindow(WindowType type)136 static inline bool IsSystemWindow(WindowType type) 137 { 138 return (IsBelowSystemWindow(type) || IsAboveSystemWindow(type) || IsSystemSubWindow(type)); 139 } 140 IsUIExtensionWindow(WindowType type)141 static inline bool IsUIExtensionWindow(WindowType type) 142 { 143 return (type == WindowType::WINDOW_TYPE_UI_EXTENSION); 144 } 145 IsAppComponentWindow(WindowType type)146 static inline bool IsAppComponentWindow(WindowType type) 147 { 148 return (type == WindowType::WINDOW_TYPE_APP_COMPONENT); 149 } 150 IsMainFloatingWindow(WindowType type,WindowMode mode)151 static inline bool IsMainFloatingWindow(WindowType type, WindowMode mode) 152 { 153 return ((IsMainWindow(type)) && (mode == WindowMode::WINDOW_MODE_FLOATING)); 154 } 155 IsMainFullScreenWindow(WindowType type,WindowMode mode)156 static inline bool IsMainFullScreenWindow(WindowType type, WindowMode mode) 157 { 158 return ((IsMainWindow(type)) && (mode == WindowMode::WINDOW_MODE_FULLSCREEN)); 159 } 160 IsFloatingWindow(WindowMode mode)161 static inline bool IsFloatingWindow(WindowMode mode) 162 { 163 return mode == WindowMode::WINDOW_MODE_FLOATING; 164 } 165 IsSystemBarWindow(WindowType type)166 static inline bool IsSystemBarWindow(WindowType type) 167 { 168 return (type == WindowType::WINDOW_TYPE_STATUS_BAR || type == WindowType::WINDOW_TYPE_NAVIGATION_BAR); 169 } 170 IsOverlayWindow(WindowType type)171 static inline bool IsOverlayWindow(WindowType type) 172 { 173 return (type == WindowType::WINDOW_TYPE_STATUS_BAR || 174 type == WindowType::WINDOW_TYPE_NAVIGATION_BAR || 175 type == WindowType::WINDOW_TYPE_INPUT_METHOD_FLOAT); 176 } 177 IsRotatableWindow(WindowType type,WindowMode mode)178 static inline bool IsRotatableWindow(WindowType type, WindowMode mode) 179 { 180 return WindowHelper::IsMainFullScreenWindow(type, mode) || type == WindowType::WINDOW_TYPE_KEYGUARD || 181 type == WindowType::WINDOW_TYPE_DESKTOP || 182 ((type == WindowType::WINDOW_TYPE_LAUNCHER_RECENT) && (mode == WindowMode::WINDOW_MODE_FULLSCREEN)); 183 } 184 IsInputWindow(WindowType type)185 static inline bool IsInputWindow(WindowType type) 186 { 187 return (type == WindowType::WINDOW_TYPE_INPUT_METHOD_FLOAT || 188 type == WindowType::WINDOW_TYPE_INPUT_METHOD_STATUS_BAR); 189 } 190 IsKeyboardWindow(WindowType type)191 static inline bool IsKeyboardWindow(WindowType type) 192 { 193 return type == WindowType::WINDOW_TYPE_KEYBOARD_PANEL || type == WindowType::WINDOW_TYPE_INPUT_METHOD_FLOAT; 194 } 195 IsSystemOrSubWindow(WindowType type)196 static inline bool IsSystemOrSubWindow(WindowType type) 197 { 198 return IsSubWindow(type) || IsSystemWindow(type); 199 } 200 IsNeedWaitAttachStateWindow(WindowType type)201 static inline bool IsNeedWaitAttachStateWindow(WindowType type) 202 { 203 return !IsKeyboardWindow(type) && IsSystemOrSubWindow(type); 204 } 205 IsDynamicWindow(WindowType type)206 static inline bool IsDynamicWindow(WindowType type) 207 { 208 return type == WindowType::WINDOW_TYPE_DYNAMIC; 209 } 210 IsFullScreenWindow(WindowMode mode)211 static inline bool IsFullScreenWindow(WindowMode mode) 212 { 213 return mode == WindowMode::WINDOW_MODE_FULLSCREEN; 214 } 215 IsSplitWindowMode(WindowMode mode)216 static inline bool IsSplitWindowMode(WindowMode mode) 217 { 218 return mode == WindowMode::WINDOW_MODE_SPLIT_PRIMARY || mode == WindowMode::WINDOW_MODE_SPLIT_SECONDARY; 219 } 220 IsPipWindowMode(WindowMode mode)221 static inline bool IsPipWindowMode(WindowMode mode) 222 { 223 return mode == WindowMode::WINDOW_MODE_PIP; 224 } 225 IsAppFullOrSplitWindow(WindowType type,WindowMode mode)226 static inline bool IsAppFullOrSplitWindow(WindowType type, WindowMode mode) 227 { 228 if (!IsAppWindow(type)) { 229 return false; 230 } 231 return IsFullScreenWindow(mode) || IsSplitWindowMode(mode); 232 } 233 IsValidWindowMode(WindowMode mode)234 static inline bool IsValidWindowMode(WindowMode mode) 235 { 236 return mode == WindowMode::WINDOW_MODE_FULLSCREEN || mode == WindowMode::WINDOW_MODE_SPLIT_PRIMARY || 237 mode == WindowMode::WINDOW_MODE_SPLIT_SECONDARY || mode == WindowMode::WINDOW_MODE_FLOATING || 238 mode == WindowMode::WINDOW_MODE_PIP || mode == WindowMode::WINDOW_MODE_FB; 239 } 240 IsEmptyRect(const Rect & r)241 static inline bool IsEmptyRect(const Rect& r) 242 { 243 return (r.posX_ == 0 && r.posY_ == 0 && r.width_ == 0 && r.height_ == 0); 244 } 245 IsLandscapeRect(const Rect & r)246 static inline bool IsLandscapeRect(const Rect& r) 247 { 248 return r.width_ > r.height_; 249 } 250 IsShowWhenLocked(uint32_t flags)251 static inline bool IsShowWhenLocked(uint32_t flags) 252 { 253 return flags & static_cast<uint32_t>(WindowFlag::WINDOW_FLAG_SHOW_WHEN_LOCKED); 254 } 255 GetOverlap(const Rect & rect1,const Rect & rect2,const int offsetX,const int offsetY)256 static Rect GetOverlap(const Rect& rect1, const Rect& rect2, const int offsetX, const int offsetY) 257 { 258 int32_t x_begin = std::max(rect1.posX_, rect2.posX_); 259 int32_t x_end = std::min(rect1.posX_ + static_cast<int32_t>(rect1.width_), 260 rect2.posX_ + static_cast<int32_t>(rect2.width_)); 261 int32_t y_begin = std::max(rect1.posY_, rect2.posY_); 262 int32_t y_end = std::min(rect1.posY_ + static_cast<int32_t>(rect1.height_), 263 rect2.posY_ + static_cast<int32_t>(rect2.height_)); 264 if (y_begin >= y_end || x_begin >= x_end) { 265 return { 0, 0, 0, 0 }; 266 } 267 return { x_begin - offsetX, y_begin - offsetY, 268 static_cast<uint32_t>(x_end - x_begin), static_cast<uint32_t>(y_end - y_begin) }; 269 } 270 IsWindowModeSupported(uint32_t windowModeSupportType,WindowMode mode)271 static bool IsWindowModeSupported(uint32_t windowModeSupportType, WindowMode mode) 272 { 273 switch (mode) { 274 case WindowMode::WINDOW_MODE_FULLSCREEN: 275 return WindowModeSupport::WINDOW_MODE_SUPPORT_FULLSCREEN & windowModeSupportType; 276 case WindowMode::WINDOW_MODE_FLOATING: 277 return WindowModeSupport::WINDOW_MODE_SUPPORT_FLOATING & windowModeSupportType; 278 case WindowMode::WINDOW_MODE_SPLIT_PRIMARY: 279 return WindowModeSupport::WINDOW_MODE_SUPPORT_SPLIT_PRIMARY & windowModeSupportType; 280 case WindowMode::WINDOW_MODE_SPLIT_SECONDARY: 281 return WindowModeSupport::WINDOW_MODE_SUPPORT_SPLIT_SECONDARY & windowModeSupportType; 282 case WindowMode::WINDOW_MODE_PIP: 283 return WindowModeSupport::WINDOW_MODE_SUPPORT_PIP & windowModeSupportType; 284 case WindowMode::WINDOW_MODE_FB: 285 return WindowModeSupport::WINDOW_MODE_SUPPORT_FB & windowModeSupportType; 286 case WindowMode::WINDOW_MODE_UNDEFINED: 287 return false; 288 default: 289 return true; 290 } 291 } 292 GetWindowModeFromWindowModeSupportType(uint32_t windowModeSupportType)293 static WindowMode GetWindowModeFromWindowModeSupportType(uint32_t windowModeSupportType) 294 { 295 // get the binary number consists of the last 1 and 0 behind it 296 uint32_t windowModeSupport = windowModeSupportType & (~windowModeSupportType + 1); 297 298 switch (windowModeSupport) { 299 case WindowModeSupport::WINDOW_MODE_SUPPORT_FULLSCREEN: 300 return WindowMode::WINDOW_MODE_FULLSCREEN; 301 case WindowModeSupport::WINDOW_MODE_SUPPORT_FLOATING: 302 return WindowMode::WINDOW_MODE_FLOATING; 303 case WindowModeSupport::WINDOW_MODE_SUPPORT_SPLIT_PRIMARY: 304 return WindowMode::WINDOW_MODE_SPLIT_PRIMARY; 305 case WindowModeSupport::WINDOW_MODE_SUPPORT_SPLIT_SECONDARY: 306 return WindowMode::WINDOW_MODE_SPLIT_SECONDARY; 307 case WindowModeSupport::WINDOW_MODE_SUPPORT_PIP: 308 return WindowMode::WINDOW_MODE_PIP; 309 case WindowModeSupport::WINDOW_MODE_SUPPORT_FB: 310 return WindowMode::WINDOW_MODE_FB; 311 default: 312 return WindowMode::WINDOW_MODE_UNDEFINED; 313 } 314 } 315 ConvertSupportModesToSupportType(const std::vector<AppExecFwk::SupportWindowMode> & supportModes)316 static uint32_t ConvertSupportModesToSupportType(const std::vector<AppExecFwk::SupportWindowMode>& supportModes) 317 { 318 uint32_t windowModeSupportType = 0; 319 for (auto& mode : supportModes) { 320 if (mode == AppExecFwk::SupportWindowMode::FULLSCREEN) { 321 windowModeSupportType |= WindowModeSupport::WINDOW_MODE_SUPPORT_FULLSCREEN; 322 } else if (mode == AppExecFwk::SupportWindowMode::SPLIT) { 323 windowModeSupportType |= (WindowModeSupport::WINDOW_MODE_SUPPORT_SPLIT_PRIMARY | 324 WindowModeSupport::WINDOW_MODE_SUPPORT_SPLIT_SECONDARY); 325 } else if (mode == AppExecFwk::SupportWindowMode::FLOATING) { 326 windowModeSupportType |= WindowModeSupport::WINDOW_MODE_SUPPORT_FLOATING; 327 } 328 } 329 return windowModeSupportType; 330 } 331 ConvertSupportTypeToSupportModes(uint32_t windowModeSupportType)332 static std::vector<AppExecFwk::SupportWindowMode> ConvertSupportTypeToSupportModes(uint32_t windowModeSupportType) 333 { 334 std::vector<AppExecFwk::SupportWindowMode> supportModes; 335 if ((windowModeSupportType & WindowModeSupport::WINDOW_MODE_SUPPORT_FULLSCREEN) != 0) { 336 supportModes.push_back(AppExecFwk::SupportWindowMode::FULLSCREEN); 337 } 338 if ((windowModeSupportType & (WindowModeSupport::WINDOW_MODE_SUPPORT_SPLIT_PRIMARY | 339 WindowModeSupport::WINDOW_MODE_SUPPORT_SPLIT_SECONDARY)) != 0) { 340 supportModes.push_back(AppExecFwk::SupportWindowMode::SPLIT); 341 } 342 if ((windowModeSupportType & WindowModeSupport::WINDOW_MODE_SUPPORT_FLOATING) != 0) { 343 supportModes.push_back(AppExecFwk::SupportWindowMode::FLOATING); 344 } 345 return supportModes; 346 } 347 IsPointInTargetRect(int32_t pointPosX,int32_t pointPosY,const Rect & targetRect)348 static bool IsPointInTargetRect(int32_t pointPosX, int32_t pointPosY, const Rect& targetRect) 349 { 350 if ((pointPosX > targetRect.posX_) && 351 (pointPosX < (targetRect.posX_ + static_cast<int32_t>(targetRect.width_)) - 1) && 352 (pointPosY > targetRect.posY_) && 353 (pointPosY < (targetRect.posY_ + static_cast<int32_t>(targetRect.height_)) - 1)) { 354 return true; 355 } 356 return false; 357 } 358 IsPointInTargetRectWithBound(int32_t pointPosX,int32_t pointPosY,const Rect & targetRect)359 static bool IsPointInTargetRectWithBound(int32_t pointPosX, int32_t pointPosY, const Rect& targetRect) 360 { 361 if ((pointPosX >= targetRect.posX_) && 362 (pointPosX < (targetRect.posX_ + static_cast<int32_t>(targetRect.width_))) && 363 (pointPosY >= targetRect.posY_) && 364 (pointPosY < (targetRect.posY_ + static_cast<int32_t>(targetRect.height_)))) { 365 return true; 366 } 367 return false; 368 } 369 IsPointInWindowExceptCorner(int32_t pointPosX,int32_t pointPosY,const Rect & rectExceptCorner)370 static bool IsPointInWindowExceptCorner(int32_t pointPosX, int32_t pointPosY, const Rect& rectExceptCorner) 371 { 372 if ((pointPosX > rectExceptCorner.posX_ && 373 pointPosX < (rectExceptCorner.posX_ + static_cast<int32_t>(rectExceptCorner.width_)) - 1) || 374 (pointPosY > rectExceptCorner.posY_ && 375 pointPosY < (rectExceptCorner.posY_ + static_cast<int32_t>(rectExceptCorner.height_)) - 1)) { 376 return true; 377 } 378 return false; 379 } 380 IsSwitchCascadeReason(WindowUpdateReason reason)381 static inline bool IsSwitchCascadeReason(WindowUpdateReason reason) 382 { 383 return (reason >= WindowUpdateReason::NEED_SWITCH_CASCADE_BASE) && 384 (reason < WindowUpdateReason::NEED_SWITCH_CASCADE_END); 385 } 386 GetAvoidPosType(const Rect & rect,const Rect & displayRect)387 static AvoidPosType GetAvoidPosType(const Rect& rect, const Rect& displayRect) 388 { 389 if (rect.width_ == displayRect.width_) { 390 if (rect.posY_ == displayRect.posY_) { 391 return AvoidPosType::AVOID_POS_TOP; 392 } else { 393 return AvoidPosType::AVOID_POS_BOTTOM; 394 } 395 } else if (rect.height_ == displayRect.height_) { 396 if (rect.posX_ == displayRect.posX_) { 397 return AvoidPosType::AVOID_POS_LEFT; 398 } else { 399 return AvoidPosType::AVOID_POS_RIGHT; 400 } 401 } 402 403 return AvoidPosType::AVOID_POS_UNKNOWN; 404 } 405 IsNumber(std::string str)406 static inline bool IsNumber(std::string str) 407 { 408 if (str.size() == 0) { 409 return false; 410 } 411 for (int32_t i = 0; i < static_cast<int32_t>(str.size()); i++) { 412 if (str.at(i) < '0' || str.at(i) > '9') { 413 return false; 414 } 415 } 416 return true; 417 } 418 419 static bool IsFloatingNumber(std::string str, bool allowNeg = false) 420 { 421 if (str.size() == 0) { 422 return false; 423 } 424 425 int32_t i = 0; 426 if (allowNeg && str.at(i) == '-') { 427 i++; 428 } 429 430 for (; i < static_cast<int32_t>(str.size()); i++) { 431 if ((str.at(i) < '0' || str.at(i) > '9') && 432 (str.at(i) != '.' || std::count(str.begin(), str.end(), '.') > 1)) { 433 return false; 434 } 435 } 436 return true; 437 } 438 Split(std::string str,std::string pattern)439 static std::vector<std::string> Split(std::string str, std::string pattern) 440 { 441 int32_t position; 442 std::vector<std::string> result; 443 str += pattern; 444 int32_t length = static_cast<int32_t>(str.size()); 445 for (int32_t i = 0; i < length; i++) { 446 position = static_cast<int32_t>(str.find(pattern, i)); 447 if (position < length) { 448 std::string tmp = str.substr(i, position - i); 449 result.push_back(tmp); 450 i = position + static_cast<int32_t>(pattern.size()) - 1; 451 } 452 } 453 return result; 454 } 455 CalculateOriginPosition(const Rect & rOrigin,const Rect & rActial,const PointInfo & pos)456 static PointInfo CalculateOriginPosition(const Rect& rOrigin, const Rect& rActial, const PointInfo& pos) 457 { 458 PointInfo ret = pos; 459 ret.x += rActial.posX_ - pos.x; 460 ret.y += rActial.posY_ - pos.y; 461 ret.x += rOrigin.posX_ - rActial.posX_; 462 ret.y += rOrigin.posY_ - rActial.posY_; 463 if (rActial.width_ && rActial.height_) { 464 ret.x += (pos.x - rActial.posX_) * rOrigin.width_ / rActial.width_; 465 ret.y += (pos.y - rActial.posY_) * rOrigin.height_ / rActial.height_; 466 } 467 return ret; 468 } 469 470 // Transform a point at screen to its oringin position in 3D world and project to xy plane CalculateOriginPosition(const TransformHelper::Matrix4 & transformMat,const PointInfo & pointPos)471 static PointInfo CalculateOriginPosition(const TransformHelper::Matrix4& transformMat, const PointInfo& pointPos) 472 { 473 TransformHelper::Vector2 p(static_cast<float>(pointPos.x), static_cast<float>(pointPos.y)); 474 TransformHelper::Vector2 originPos = TransformHelper::GetOriginScreenPoint(p, transformMat); 475 return PointInfo { static_cast<uint32_t>(originPos.x_), static_cast<uint32_t>(originPos.y_) }; 476 } 477 478 // This method is used to update transform when rect changed, but world transform matrix should not change. GetTransformFromWorldMat4(const TransformHelper::Matrix4 & inWorldMat,const Rect & rect,Transform & transform)479 static void GetTransformFromWorldMat4(const TransformHelper::Matrix4& inWorldMat, const Rect& rect, 480 Transform& transform) 481 { 482 TransformHelper::Vector3 pivotPos = { rect.posX_ + transform.pivotX_ * rect.width_, 483 rect.posY_ + transform.pivotY_ * rect.height_, 0 }; 484 TransformHelper::Matrix4 worldMat = TransformHelper::CreateTranslation(pivotPos) * inWorldMat * 485 TransformHelper::CreateTranslation(-pivotPos); 486 auto scale = worldMat.GetScale(); 487 auto translation = worldMat.GetTranslation(); 488 transform.scaleX_ = scale.x_; 489 transform.scaleY_ = scale.y_; 490 transform.scaleZ_ = scale.z_; 491 transform.translateX_ = translation.x_; 492 transform.translateY_ = translation.y_; 493 transform.translateZ_ = translation.z_; 494 } 495 ComputeWorldTransformMat4(const Transform & transform)496 static TransformHelper::Matrix4 ComputeWorldTransformMat4(const Transform& transform) 497 { 498 TransformHelper::Matrix4 ret = TransformHelper::Matrix4::Identity; 499 // set scale 500 if (!MathHelper::NearZero(transform.scaleX_ - 1.0f) || !MathHelper::NearZero(transform.scaleY_ - 1.0f) || 501 !MathHelper::NearZero(transform.scaleZ_ - 1.0f)) { 502 ret *= TransformHelper::CreateScale(transform.scaleX_, transform.scaleY_, transform.scaleZ_); 503 } 504 // set rotation 505 if (!MathHelper::NearZero(transform.rotationX_)) { 506 ret *= TransformHelper::CreateRotationX(MathHelper::ToRadians(transform.rotationX_)); 507 } 508 if (!MathHelper::NearZero(transform.rotationY_)) { 509 ret *= TransformHelper::CreateRotationY(MathHelper::ToRadians(transform.rotationY_)); 510 } 511 if (!MathHelper::NearZero(transform.rotationZ_)) { 512 ret *= TransformHelper::CreateRotationZ(MathHelper::ToRadians(transform.rotationZ_)); 513 } 514 // set translation 515 if (!MathHelper::NearZero(transform.translateX_) || !MathHelper::NearZero(transform.translateY_) || 516 !MathHelper::NearZero(transform.translateZ_)) { 517 ret *= TransformHelper::CreateTranslation(TransformHelper::Vector3(transform.translateX_, 518 transform.translateY_, transform.translateZ_)); 519 } 520 return ret; 521 } 522 523 // Transform rect by matrix and get the circumscribed rect TransformRect(const TransformHelper::Matrix4 & transformMat,const Rect & rect)524 static Rect TransformRect(const TransformHelper::Matrix4& transformMat, const Rect& rect) 525 { 526 TransformHelper::Vector3 a = TransformHelper::TransformWithPerspDiv( 527 TransformHelper::Vector3(rect.posX_, rect.posY_, 0), transformMat); 528 TransformHelper::Vector3 b = TransformHelper::TransformWithPerspDiv( 529 TransformHelper::Vector3(rect.posX_ + rect.width_, rect.posY_, 0), transformMat); 530 TransformHelper::Vector3 c = TransformHelper::TransformWithPerspDiv( 531 TransformHelper::Vector3(rect.posX_, rect.posY_ + rect.height_, 0), transformMat); 532 TransformHelper::Vector3 d = TransformHelper::TransformWithPerspDiv( 533 TransformHelper::Vector3(rect.posX_ + rect.width_, rect.posY_ + rect.height_, 0), transformMat); 534 // Return smallest rect involve transformed rect(abcd) 535 int32_t xmin = MathHelper::Min(a.x_, b.x_, c.x_, d.x_); 536 int32_t ymin = MathHelper::Min(a.y_, b.y_, c.y_, d.y_); 537 int32_t xmax = MathHelper::Max(a.x_, b.x_, c.x_, d.x_); 538 int32_t ymax = MathHelper::Max(a.y_, b.y_, c.y_, d.y_); 539 uint32_t w = static_cast<uint32_t>(xmax - xmin); 540 uint32_t h = static_cast<uint32_t>(ymax - ymin); 541 return Rect { xmin, ymin, w, h }; 542 } 543 CalculateHotZoneScale(const TransformHelper::Matrix4 & transformMat)544 static TransformHelper::Vector2 CalculateHotZoneScale(const TransformHelper::Matrix4& transformMat) 545 { 546 TransformHelper::Vector2 hotZoneScale; 547 TransformHelper::Vector3 a = TransformHelper::TransformWithPerspDiv(TransformHelper::Vector3(0, 0, 0), 548 transformMat); 549 TransformHelper::Vector3 b = TransformHelper::TransformWithPerspDiv(TransformHelper::Vector3(1, 0, 0), 550 transformMat); 551 TransformHelper::Vector3 c = TransformHelper::TransformWithPerspDiv(TransformHelper::Vector3(0, 1, 0), 552 transformMat); 553 TransformHelper::Vector2 axy(a.x_, a.y_); 554 TransformHelper::Vector2 bxy(b.x_, b.y_); 555 TransformHelper::Vector2 cxy(c.x_, c.y_); 556 hotZoneScale.x_ = (axy - bxy).Length(); 557 hotZoneScale.y_ = (axy - cxy).Length(); 558 if (std::isnan(hotZoneScale.x_) || std::isnan(hotZoneScale.y_) || 559 MathHelper::NearZero(hotZoneScale.x_) || MathHelper::NearZero(hotZoneScale.y_)) { 560 return TransformHelper::Vector2(1, 1); 561 } else { 562 return hotZoneScale; 563 } 564 } 565 CalculateTouchHotAreas(const Rect & windowRect,const std::vector<Rect> & requestRects,std::vector<Rect> & outRects)566 static bool CalculateTouchHotAreas(const Rect& windowRect, const std::vector<Rect>& requestRects, 567 std::vector<Rect>& outRects) 568 { 569 bool isOk = true; 570 for (const auto& rect : requestRects) { 571 if (rect.posX_ < 0 || rect.posY_ < 0 || rect.width_ == 0 || rect.height_ == 0) { 572 return false; 573 } 574 Rect hotArea; 575 if (rect.posX_ >= static_cast<int32_t>(windowRect.width_) || 576 rect.posY_ >= static_cast<int32_t>(windowRect.height_)) { 577 isOk = false; 578 continue; 579 } 580 hotArea.posX_ = windowRect.posX_ + rect.posX_; 581 hotArea.posY_ = windowRect.posY_ + rect.posY_; 582 hotArea.width_ = static_cast<uint32_t>(std::min(hotArea.posX_ + rect.width_, 583 windowRect.posX_ + windowRect.width_) - hotArea.posX_); 584 hotArea.height_ = static_cast<uint32_t>(std::min(hotArea.posY_ + rect.height_, 585 windowRect.posY_ + windowRect.height_) - hotArea.posY_); 586 outRects.emplace_back(hotArea); 587 } 588 return isOk; 589 } 590 IsRectSatisfiedWithSizeLimits(const Rect & rect,const WindowLimits & sizeLimits)591 static bool IsRectSatisfiedWithSizeLimits(const Rect& rect, const WindowLimits& sizeLimits) 592 { 593 if (rect.height_ == 0) { 594 return false; 595 } 596 auto curRatio = static_cast<float>(rect.width_) / static_cast<float>(rect.height_); 597 if (sizeLimits.minWidth_ <= rect.width_ && rect.width_ <= sizeLimits.maxWidth_ && 598 sizeLimits.minHeight_ <= rect.height_ && rect.height_ <= sizeLimits.maxHeight_ && 599 sizeLimits.minRatio_ <= curRatio && curRatio <= sizeLimits.maxRatio_) { 600 return true; 601 } 602 return false; 603 } 604 IsOnlySupportSplitAndShowWhenLocked(bool isShowWhenLocked,uint32_t windowModeSupportType)605 static bool IsOnlySupportSplitAndShowWhenLocked(bool isShowWhenLocked, uint32_t windowModeSupportType) 606 { 607 uint32_t splitMode = (WindowModeSupport::WINDOW_MODE_SUPPORT_SPLIT_PRIMARY | 608 WindowModeSupport::WINDOW_MODE_SUPPORT_SPLIT_SECONDARY); 609 if (isShowWhenLocked && (splitMode == windowModeSupportType)) { 610 return true; 611 } 612 return false; 613 } 614 IsInvalidWindowInTileLayoutMode(uint32_t supportModeInfo,WindowLayoutMode layoutMode)615 static bool IsInvalidWindowInTileLayoutMode(uint32_t supportModeInfo, WindowLayoutMode layoutMode) 616 { 617 if ((!IsWindowModeSupported(supportModeInfo, WindowMode::WINDOW_MODE_FLOATING)) && 618 (layoutMode == WindowLayoutMode::TILE)) { 619 return true; 620 } 621 return false; 622 } 623 CheckSupportWindowMode(WindowMode winMode,uint32_t windowModeSupportType,const sptr<WindowTransitionInfo> & info)624 static bool CheckSupportWindowMode(WindowMode winMode, uint32_t windowModeSupportType, 625 const sptr<WindowTransitionInfo>& info) 626 { 627 if (!WindowHelper::IsMainWindow(info->GetWindowType())) { 628 return true; 629 } 630 631 if (!IsWindowModeSupported(windowModeSupportType, winMode) || 632 IsOnlySupportSplitAndShowWhenLocked(info->GetShowFlagWhenLocked(), windowModeSupportType)) { 633 return false; 634 } 635 return true; 636 } 637 IsAspectRatioSatisfiedWithSizeLimits(const WindowLimits & sizeLimits,float ratio,float vpr)638 static bool IsAspectRatioSatisfiedWithSizeLimits(const WindowLimits& sizeLimits, float ratio, float vpr) 639 { 640 /* 641 * 1) Usually the size limits won't be empty after show window. 642 * In case of SetAspectRatio is called befor show (size limits may be empty at that time) or the 643 * sizeLimits is empty, there is no need to check ratio (layout will check), return true directly. 644 * 2) ratio : 0.0 means reset aspect ratio 645 */ 646 if (sizeLimits.IsEmpty() || MathHelper::NearZero(ratio)) { 647 return true; 648 } 649 650 uint32_t winFrameW = static_cast<uint32_t>(WINDOW_FRAME_WIDTH * vpr) * 2; // 2 mean double decor width 651 uint32_t winFrameH = static_cast<uint32_t>(WINDOW_FRAME_WIDTH * vpr) + 652 static_cast<uint32_t>(WINDOW_TITLE_BAR_HEIGHT * vpr); // decor height 653 uint32_t maxWidth = sizeLimits.maxWidth_ - winFrameW; 654 uint32_t minWidth = sizeLimits.minWidth_ - winFrameW; 655 uint32_t maxHeight = sizeLimits.maxHeight_ - winFrameH; 656 uint32_t minHeight = sizeLimits.minHeight_ - winFrameH; 657 float maxRatio = static_cast<float>(maxWidth) / static_cast<float>(minHeight); 658 float minRatio = static_cast<float>(minWidth) / static_cast<float>(maxHeight); 659 if (maxRatio < ratio || ratio < minRatio) { 660 return false; 661 } 662 return true; 663 } 664 IsWindowFollowParent(WindowType type)665 static bool IsWindowFollowParent(WindowType type) 666 { 667 if (type == WindowType::WINDOW_TYPE_DIALOG || type == WindowType::WINDOW_TYPE_APP_SUB_WINDOW) { 668 return true; 669 } 670 return false; 671 } 672 CheckButtonStyleValid(const DecorButtonStyle & decorButtonStyle)673 static bool CheckButtonStyleValid(const DecorButtonStyle& decorButtonStyle) 674 { 675 return decorButtonStyle.buttonBackgroundSize >= MIN_BUTTON_BACKGROUND_SIZE && 676 decorButtonStyle.buttonBackgroundSize <= MAX_BUTTON_BACKGROUND_SIZE && 677 decorButtonStyle.closeButtonRightMargin >= MIN_CLOSE_BUTTON_RIGHT_MARGIN && 678 decorButtonStyle.closeButtonRightMargin <= MAX_CLOSE_BUTTON_RIGHT_MARGIN && 679 decorButtonStyle.spacingBetweenButtons >= MIN_SPACING_BETWEEN_BUTTONS && 680 decorButtonStyle.spacingBetweenButtons <= MAX_SPACING_BETWEEN_BUTTONS && 681 decorButtonStyle.colorMode >= MIN_COLOR_MODE && 682 decorButtonStyle.colorMode <= MAX_COLOR_MODE && 683 decorButtonStyle.buttonIconSize >= MIN_BUTTON_ICON_SIZE && 684 decorButtonStyle.buttonIconSize <= MAX_BUTTON_ICON_SIZE && 685 decorButtonStyle.buttonBackgroundCornerRadius >= MIN_BUTTON_BACKGROUND_CORNER_RADIUS && 686 decorButtonStyle.buttonBackgroundCornerRadius <= MAX_BUTTON_BACKGROUND_CORNER_RADIUS; 687 } 688 SplitStringByDelimiter(const std::string & inputStr,const std::string & delimiter,std::unordered_set<std::string> & container)689 static void SplitStringByDelimiter( 690 const std::string& inputStr, const std::string& delimiter, std::unordered_set<std::string>& container) 691 { 692 if (inputStr.empty()) { 693 return; 694 } 695 if (delimiter.empty()) { 696 container.insert(inputStr); 697 return; 698 } 699 std::string::size_type start = 0; 700 std::string::size_type end = 0; 701 while ((end = inputStr.find(delimiter, start)) != std::string::npos) { 702 container.insert(inputStr.substr(start, end - start)); 703 start = end + delimiter.length(); 704 } 705 container.insert(inputStr.substr(start)); 706 } 707 708 /** 709 * @brief Check whether the window has scaling applied. 710 * 711 * This method returns true if scaleX or scaleY is not equal to 1, 712 * meaning the window is currently scaled. 713 * 714 * @param transform The layout transform of the window. 715 * @return true if the window is scaled, false otherwise. 716 */ IsScaled(const Transform & transform)717 static bool IsScaled(const Transform& transform) 718 { 719 auto IsApproximatelyOne = [](float value) { 720 constexpr float EPSILON = 1e-6f; 721 return std::fabs(value - 1.0f) < EPSILON; 722 }; 723 return !IsApproximatelyOne(transform.scaleX_) || !IsApproximatelyOne(transform.scaleY_); 724 } 725 726 private: 727 WindowHelper() = default; 728 ~WindowHelper() = default; 729 }; 730 } // namespace OHOS 731 } // namespace Rosen 732 #endif // OHOS_WM_INCLUDE_WM_HELPER_H 733