mirror of
https://gitee.com/openharmony/window_window_manager
synced 2025-02-17 06:19:31 +00:00
!10738 悬停态抛滑新增PcFoldScreenManager
Merge pull request !10738 from slarkwayne/remote_throwSlipFix
This commit is contained in:
commit
13faeff5ec
@ -16,9 +16,9 @@
|
||||
#ifndef OHOS_ROSEN_WM_MATH_H
|
||||
#define OHOS_ROSEN_WM_MATH_H
|
||||
|
||||
#include <chrono>
|
||||
#include <cmath>
|
||||
#include <limits>
|
||||
#include <chrono>
|
||||
|
||||
namespace OHOS::Rosen {
|
||||
namespace MathHelper {
|
||||
|
@ -3580,17 +3580,18 @@ napi_value JsSceneSessionManager::OnUpdatePcFoldScreenStatus(napi_env env, napi_
|
||||
return NapiGetUndefined(env);
|
||||
}
|
||||
|
||||
ScreenFoldStatus status = ScreenFoldStatus::UNKNOWN;
|
||||
if (!ConvertFromJsValue(env, argv[ARG_INDEX_ONE], status)) {
|
||||
TLOGE(WmsLogTag::WMS_LAYOUT, "[NAPI]Failed to convert parameter to type");
|
||||
uint32_t statusNum;
|
||||
if (!ConvertFromJsValue(env, argv[ARG_INDEX_ONE], statusNum)) {
|
||||
TLOGE(WmsLogTag::WMS_LAYOUT, "[NAPI]Failed to convert parameter to status");
|
||||
napi_throw(env, CreateJsError(env, static_cast<int32_t>(WSErrorCode::WS_ERROR_INVALID_PARAM),
|
||||
"Input parameter is missing or invalid"));
|
||||
return NapiGetUndefined(env);
|
||||
}
|
||||
ScreenFoldStatus status = static_cast<ScreenFoldStatus>(statusNum);
|
||||
|
||||
WSRect defaultDisplayRect;
|
||||
if (argv[ARG_INDEX_TWO] == nullptr || !ConvertRectInfoFromJs(env, argv[ARG_INDEX_TWO], defaultDisplayRect)) {
|
||||
TLOGE(WmsLogTag::WMS_LAYOUT, "[NAPI]Failed to convert parameter to rect");
|
||||
TLOGE(WmsLogTag::WMS_LAYOUT, "[NAPI]Failed to convert parameter to display rect");
|
||||
napi_throw(env, CreateJsError(env, static_cast<int32_t>(WSErrorCode::WS_ERROR_INVALID_PARAM),
|
||||
"Input parameter is missing or invalid"));
|
||||
return NapiGetUndefined(env);
|
||||
@ -3598,7 +3599,7 @@ napi_value JsSceneSessionManager::OnUpdatePcFoldScreenStatus(napi_env env, napi_
|
||||
|
||||
WSRect virtualDisplayRect;
|
||||
if (argv[ARG_INDEX_THREE] == nullptr || !ConvertRectInfoFromJs(env, argv[ARG_INDEX_THREE], virtualDisplayRect)) {
|
||||
TLOGE(WmsLogTag::WMS_LAYOUT, "[NAPI]Failed to convert parameter to rect");
|
||||
TLOGE(WmsLogTag::WMS_LAYOUT, "[NAPI]Failed to convert parameter to virtual rect");
|
||||
napi_throw(env, CreateJsError(env, static_cast<int32_t>(WSErrorCode::WS_ERROR_INVALID_PARAM),
|
||||
"Input parameter is missing or invalid"));
|
||||
return NapiGetUndefined(env);
|
||||
@ -3606,17 +3607,14 @@ napi_value JsSceneSessionManager::OnUpdatePcFoldScreenStatus(napi_env env, napi_
|
||||
|
||||
WSRect foldCreaseRect;
|
||||
if (argv[ARG_INDEX_FOUR] == nullptr || !ConvertRectInfoFromJs(env, argv[ARG_INDEX_FOUR], foldCreaseRect)) {
|
||||
TLOGE(WmsLogTag::WMS_LAYOUT, "[NAPI]Failed to convert parameter to rect");
|
||||
TLOGE(WmsLogTag::WMS_LAYOUT, "[NAPI]Failed to convert parameter to fold crease rect");
|
||||
napi_throw(env, CreateJsError(env, static_cast<int32_t>(WSErrorCode::WS_ERROR_INVALID_PARAM),
|
||||
"Input parameter is missing or invalid"));
|
||||
return NapiGetUndefined(env);
|
||||
}
|
||||
|
||||
PcFoldScreenController::UpdateFoldScreenStatus(displayId, status);
|
||||
PcFoldScreenController::SetDefaultDisplayRect(defaultDisplayRect);
|
||||
PcFoldScreenController::SetVirtualDisplayRect(virtualDisplayRect);
|
||||
PcFoldScreenController::SetFoldCreaseRect(foldCreaseRect);
|
||||
|
||||
PcFoldScreenManager::GetInstance().UpdateFoldScreenStatus(displayId, status,
|
||||
defaultDisplayRect, virtualDisplayRect, foldCreaseRect);
|
||||
return NapiGetUndefined(env);
|
||||
}
|
||||
|
||||
@ -3641,8 +3639,7 @@ napi_value JsSceneSessionManager::OnResetPcFoldScreenArrangeRule(napi_env env, n
|
||||
return NapiGetUndefined(env);
|
||||
}
|
||||
|
||||
PcFoldScreenController::ResetArrangeRule(rect);
|
||||
|
||||
PcFoldScreenManager::GetInstance().ResetArrangeRule(rect);
|
||||
return NapiGetUndefined(env);
|
||||
}
|
||||
|
||||
|
@ -17,10 +17,15 @@
|
||||
#define PC_FOLD_SCREEN_CONTROLLER_H
|
||||
|
||||
#include <chrono>
|
||||
#include "interfaces/include/ws_common.h"
|
||||
#include "dm_common.h"
|
||||
#include <mutex>
|
||||
#include <shared_mutex>
|
||||
#include <tuple>
|
||||
|
||||
#include "animation/rs_animation_timing_curve.h"
|
||||
#include "animation/rs_animation_timing_protocol.h"
|
||||
#include "dm_common.h"
|
||||
#include "interfaces/include/ws_common.h"
|
||||
#include "wm_single_instance.h"
|
||||
|
||||
|
||||
namespace OHOS::Rosen {
|
||||
@ -29,96 +34,114 @@ class SceneSession;
|
||||
using RectRecordsVector =
|
||||
std::vector<std::pair<std::chrono::time_point<std::chrono::high_resolution_clock>, WSRect>>;
|
||||
|
||||
enum class ScreenFoldStatus {
|
||||
enum class ScreenFoldStatus : uint8_t {
|
||||
UNKNOWN = 0,
|
||||
COVER_CLOSE = 1,
|
||||
HALF_FOLDED = 2,
|
||||
HALF_FOLDED_PHYSICAL_KEYBOARD = 3,
|
||||
FLATTENED = 4,
|
||||
EXPANDED = 1,
|
||||
FOLDED = 2,
|
||||
HALF_FOLDED = 3,
|
||||
HALF_FOLDED_KEYBOARD = 4,
|
||||
};
|
||||
|
||||
enum class ScreenSide {
|
||||
enum class ScreenSide : uint8_t {
|
||||
EXPAND = 0,
|
||||
FOLD_B = 1,
|
||||
FOLD_C = 2,
|
||||
};
|
||||
|
||||
class PcFoldScreenController : public RefBase {
|
||||
class PcFoldScreenManager {
|
||||
WM_DECLARE_SINGLE_INSTANCE(PcFoldScreenManager);
|
||||
public:
|
||||
explicit PcFoldScreenController(wptr<SceneSession> weak);
|
||||
static bool IsHalfFolded() { return screenFoldStatus_.load() == ScreenFoldStatus::HALF_FOLDED; }
|
||||
void UpdateFoldScreenStatus(DisplayId displayId, ScreenFoldStatus status,
|
||||
const WSRect& defaultDisplayRect, const WSRect& virtualDisplayRect, const WSRect& foldCreaseRect);
|
||||
bool IsHalfFolded(DisplayId displayId);
|
||||
|
||||
// screen property
|
||||
static WSError UpdateFoldScreenStatus(DisplayId displayId, ScreenFoldStatus status);
|
||||
static inline ScreenFoldStatus GetScreenFoldStatus() { return screenFoldStatus_.load(); }
|
||||
static inline WSRect GetDefaultDisplayRect() { return defaultDisplayRect_.load(); }
|
||||
static inline WSRect GetVirtualDisplayRect() { return virtualDisplayRect_.load(); }
|
||||
static inline WSRect GetFoldCreaseRect() { return foldCreaseRect_.load(); }
|
||||
static inline void SetDefaultDisplayRect(const WSRect& rect) { defaultDisplayRect_.store(rect); }
|
||||
static inline void SetVirtualDisplayRect(const WSRect& rect) { virtualDisplayRect_.store(rect); }
|
||||
static inline void SetFoldCreaseRect(const WSRect& rect) { foldCreaseRect_.store(rect); }
|
||||
std::tuple<WSRect, WSRect, WSRect> GetDisplayRects();
|
||||
|
||||
// animation parameters
|
||||
static RSAnimationTimingProtocol GetMovingTimingProtocol();
|
||||
static RSAnimationTimingCurve GetMovingTimingCurve();
|
||||
static RSAnimationTimingProtocol GetThrowSlipTimingProtocol();
|
||||
static RSAnimationTimingCurve GetThrowSlipTimingCurve();
|
||||
RSAnimationTimingProtocol GetMovingTimingProtocol();
|
||||
RSAnimationTimingCurve GetMovingTimingCurve();
|
||||
RSAnimationTimingProtocol GetThrowSlipTimingProtocol();
|
||||
RSAnimationTimingCurve GetThrowSlipTimingCurve();
|
||||
|
||||
void RecordStartRect(const WSRect& rect, bool isStartFullScreen);
|
||||
void RecordMoveRects(const WSRect& rect);
|
||||
bool ThrowSlip(DisplayId displayId, WSRect& rect, int32_t topAvoidHeight, int32_t botAvoidHeight);
|
||||
static void ResetArrangeRule(const WSRect& rect);
|
||||
bool IsStartFullScreen() const;
|
||||
static void ResizeToFullScreen(WSRect& rect, int32_t topAvoidHeight, int32_t botAvoidHeight);
|
||||
ScreenSide CalculateScreenSide(const WSRect& rect);
|
||||
|
||||
private:
|
||||
int32_t GetPersistentId() const;
|
||||
int32_t GetTitleHeight() const;
|
||||
WSRectF CalculateMovingVelocity();
|
||||
void RemoveMoveRects();
|
||||
void ResetArrangeRule();
|
||||
void ResetArrangeRule(ScreenSide side);
|
||||
void ResetArrangeRule(const WSRect& rect);
|
||||
|
||||
static ScreenSide CalculateScreenSide(const WSRect& rect);
|
||||
static bool NeedDoThrowSlip(ScreenSide startSide, WSRectF velocity);
|
||||
void ResizeToFullScreen(WSRect& rect, int32_t topAvoidHeight, int32_t botAvoidHeight);
|
||||
|
||||
bool NeedDoThrowSlip(ScreenSide startSide, const WSRectF& velocity);
|
||||
bool ThrowSlipToOppositeSide(ScreenSide startSide, WSRect& rect,
|
||||
int32_t topAvoidHeight, int32_t botAvoidHeight);
|
||||
static void MappingRectInScreenSide(ScreenSide side, WSRect& rect,
|
||||
int32_t topAvoidHeight, int32_t botAvoidHeight, int32_t titleHeight);
|
||||
void MappingRectInScreenSide(ScreenSide side, WSRect& rect,
|
||||
int32_t topAvoidHeight, int32_t botAvoidHeight);
|
||||
void MappingRectInScreenSideWithArrangeRule(ScreenSide side, WSRect& rect,
|
||||
int32_t topAvoidHeight, int32_t botAvoidHeight);
|
||||
int32_t topAvoidHeight, int32_t botAvoidHeight, int32_t titleHeight);
|
||||
|
||||
static void ApplyInitArrangeRule(WSRect& rect, std::atomic<WSRect>& lastArrangedRect,
|
||||
void ApplyInitArrangeRule(WSRect& rect, WSRect& lastArrangedRect,
|
||||
const WSRect& limitRect, int32_t titleHeight);
|
||||
static void ApplyArrangeRule(WSRect& rect, std::atomic<WSRect>& lastArrangedRect,
|
||||
void ApplyArrangeRule(WSRect& rect, WSRect& lastArrangedRect,
|
||||
const WSRect& limitRect, int32_t titleHeight);
|
||||
static void ResetArrangeRule();
|
||||
static void ResetArrangeRule(ScreenSide side);
|
||||
|
||||
wptr<SceneSession> weakSceneSession_ = nullptr;
|
||||
private:
|
||||
void SetDisplayInfo(DisplayId displayId, ScreenFoldStatus status);
|
||||
void SetDisplayRects(
|
||||
const WSRect& defaultDisplayRect, const WSRect& virtualDisplayRect, const WSRect& foldCreaseRect);
|
||||
float GetVpr();
|
||||
|
||||
/*
|
||||
* fold screen property
|
||||
* if need, use map for multi fold screen
|
||||
*/
|
||||
static std::atomic<DisplayId> displayId_;
|
||||
static std::atomic<float> vpr_; // display vp ratio
|
||||
static std::atomic<ScreenFoldStatus> screenFoldStatus_;
|
||||
static std::atomic<WSRect> defaultDisplayRect_;
|
||||
static std::atomic<WSRect> virtualDisplayRect_;
|
||||
static std::atomic<WSRect> foldCreaseRect_;
|
||||
|
||||
// use queue to calculate velocity
|
||||
WSRect startRect_;
|
||||
bool isStartFullScreen_ { false };
|
||||
RectRecordsVector movingRectRecords_;
|
||||
std::shared_mutex displayInfoMutex_; // protect display infos
|
||||
DisplayId displayId_ { SCREEN_ID_INVALID };
|
||||
float vpr_ { 1.5f }; // display vp ratio
|
||||
ScreenFoldStatus screenFoldStatus_ { ScreenFoldStatus::UNKNOWN };
|
||||
std::shared_mutex rectsMutex_; // protect rects
|
||||
WSRect defaultDisplayRect_;
|
||||
WSRect virtualDisplayRect_;
|
||||
WSRect foldCreaseRect_;
|
||||
|
||||
/*
|
||||
* arranged rect
|
||||
* x,y: last arranged position
|
||||
* w,h: offset for next arranged position
|
||||
*/
|
||||
static std::atomic<WSRect> defaultArrangedRect_;
|
||||
static std::atomic<WSRect> virtualArrangedRect_;
|
||||
std::mutex arrangedRectsMutex_;
|
||||
WSRect defaultArrangedRect_;
|
||||
WSRect virtualArrangedRect_;
|
||||
};
|
||||
|
||||
class PcFoldScreenController : public RefBase {
|
||||
public:
|
||||
explicit PcFoldScreenController(wptr<SceneSession> weakSession);
|
||||
bool IsHalfFolded(DisplayId displayId);
|
||||
void RecordStartMoveRect(const WSRect& rect, bool isStartFullScreen);
|
||||
void RecordMoveRects(const WSRect& rect);
|
||||
bool ThrowSlip(DisplayId displayId, WSRect& rect, int32_t topAvoidHeight, int32_t botAvoidHeight);
|
||||
bool IsStartFullScreen() const;
|
||||
void ResizeToFullScreen(WSRect& rect, int32_t topAvoidHeight, int32_t botAvoidHeight);
|
||||
|
||||
// animation parameters
|
||||
RSAnimationTimingProtocol GetMovingTimingProtocol();
|
||||
RSAnimationTimingCurve GetMovingTimingCurve();
|
||||
RSAnimationTimingProtocol GetThrowSlipTimingProtocol();
|
||||
RSAnimationTimingCurve GetThrowSlipTimingCurve();
|
||||
|
||||
private:
|
||||
int32_t GetPersistentId() const;
|
||||
int32_t GetTitleHeight() const;
|
||||
WSRectF CalculateMovingVelocity();
|
||||
|
||||
wptr<SceneSession> weakSceneSession_ = nullptr;
|
||||
|
||||
// use queue to calculate velocity
|
||||
std::mutex moveMutex_;
|
||||
WSRect startMoveRect_;
|
||||
bool isStartFullScreen_ { false };
|
||||
RectRecordsVector movingRectRecords_;
|
||||
};
|
||||
} // namespace OHOS::Rosen
|
||||
|
||||
#endif // PC_FOLD_SCREEN_CONTROLLER_H
|
||||
#endif // PC_FOLD_SCREEN_CONTROLLER_H
|
@ -175,7 +175,7 @@ public:
|
||||
|
||||
WSError UpdateActiveStatus(bool isActive) override;
|
||||
WSError OnSessionEvent(SessionEvent event) override;
|
||||
WSError OnSessionEvent(SessionEvent event, SessionEventParam param);
|
||||
WSError OnSessionEvent(SessionEvent event, const SessionEventParam& param);
|
||||
WSError SyncSessionEvent(SessionEvent event) override;
|
||||
WSError OnLayoutFullScreenChange(bool isLayoutFullScreen) override;
|
||||
WSError OnDefaultDensityEnabled(bool isDefaultDensityEnabled) override;
|
||||
@ -605,7 +605,7 @@ protected:
|
||||
ClearCallbackMapFunc clearCallbackMapFunc_;
|
||||
|
||||
/*
|
||||
* pc fold screen
|
||||
* PC Fold Screen
|
||||
*/
|
||||
sptr<PcFoldScreenController> pcFoldScreenController_ = nullptr;
|
||||
|
||||
@ -672,12 +672,6 @@ private:
|
||||
bool SaveAspectRatio(float ratio);
|
||||
void NotifyPropertyWhenConnect();
|
||||
WSError RaiseAppMainWindowToTop() override;
|
||||
void SetSurfaceBoundsWithAnimation(
|
||||
std::pair<RSAnimationTimingProtocol, RSAnimationTimingCurve> animationParam,
|
||||
const WSRect& rect, std::function<void()>&& finishCallback = nullptr,
|
||||
bool isGlobal = false, bool needFlush = true
|
||||
);
|
||||
void SetSurfaceBounds(const WSRect& rect, bool isGlobal, bool needFlush = true);
|
||||
void UpdateWinRectForSystemBar(WSRect& rect);
|
||||
bool UpdateInputMethodSessionRect(const WSRect& rect, WSRect& newWinRect, WSRect& newRequestRect);
|
||||
bool IsMovableWindowType();
|
||||
@ -851,6 +845,11 @@ private:
|
||||
/**
|
||||
* Window Layout
|
||||
*/
|
||||
void SetSurfaceBoundsWithAnimation(
|
||||
const std::pair<RSAnimationTimingProtocol, RSAnimationTimingCurve>& animationParam,
|
||||
const WSRect& rect, const std::function<void()>& finishCallback = nullptr,
|
||||
bool isGlobal = false, bool needFlush = true);
|
||||
void SetSurfaceBounds(const WSRect& rect, bool isGlobal, bool needFlush = true);
|
||||
NotifyLayoutFullScreenChangeFunc onLayoutFullScreenChangeFunc_;
|
||||
|
||||
/**
|
||||
|
@ -48,107 +48,398 @@ constexpr int32_t MAX_DECOR_HEIGHT = 112;
|
||||
const WSRect RECT_ZERO = { 0, 0, 0, 0 };
|
||||
} // namespace
|
||||
|
||||
std::atomic<DisplayId> PcFoldScreenController::displayId_ = DEFAULT_SCREEN_ID;
|
||||
std::atomic<float> PcFoldScreenController::vpr_ = 1.5f;
|
||||
std::atomic<ScreenFoldStatus> PcFoldScreenController::screenFoldStatus_ = ScreenFoldStatus::UNKNOWN;
|
||||
std::atomic<WSRect> PcFoldScreenController::defaultDisplayRect_ = RECT_ZERO;
|
||||
std::atomic<WSRect> PcFoldScreenController::virtualDisplayRect_ = RECT_ZERO;
|
||||
std::atomic<WSRect> PcFoldScreenController::foldCreaseRect_ = RECT_ZERO;
|
||||
std::atomic<WSRect> PcFoldScreenController::defaultArrangedRect_ = RECT_ZERO;
|
||||
std::atomic<WSRect> PcFoldScreenController::virtualArrangedRect_ = RECT_ZERO;
|
||||
WM_IMPLEMENT_SINGLE_INSTANCE(PcFoldScreenManager);
|
||||
|
||||
PcFoldScreenController::PcFoldScreenController(wptr<SceneSession> weak) : weakSceneSession_(weak) {}
|
||||
|
||||
WSError PcFoldScreenController::UpdateFoldScreenStatus(DisplayId displayId, ScreenFoldStatus status)
|
||||
void PcFoldScreenManager::UpdateFoldScreenStatus(DisplayId displayId, ScreenFoldStatus status,
|
||||
const WSRect& defaultDisplayRect, const WSRect& virtualDisplayRect, const WSRect& foldCreaseRect)
|
||||
{
|
||||
if (displayId_.load() == displayId && screenFoldStatus_.load() == status) {
|
||||
return WSError::WS_DO_NOTHING;
|
||||
SetDisplayInfo(displayId, status);
|
||||
SetDisplayRects(defaultDisplayRect, virtualDisplayRect, foldCreaseRect);
|
||||
}
|
||||
|
||||
void PcFoldScreenManager::SetDisplayInfo(DisplayId displayId, ScreenFoldStatus status)
|
||||
{
|
||||
std::unique_lock<std::shared_mutex> lock(displayInfoMutex_);
|
||||
if (displayId_ == displayId && screenFoldStatus_ == status) {
|
||||
return;
|
||||
}
|
||||
TLOGI(WmsLogTag::WMS_MAIN, "display: %{public}" PRIu64", fold status: %{public}d",
|
||||
displayId, static_cast<int32_t>(status));
|
||||
screenFoldStatus_.store(status);
|
||||
screenFoldStatus_ = status;
|
||||
ResetArrangeRule();
|
||||
displayId_.store(displayId);
|
||||
displayId_ = displayId;
|
||||
auto display = DisplayManager::GetInstance().GetDisplayById(displayId);
|
||||
if (display == nullptr) {
|
||||
TLOGE(WmsLogTag::WMS_MAIN, "Failed to get display");
|
||||
return WSError::WS_OK;
|
||||
return;
|
||||
}
|
||||
vpr_.store(display->GetVirtualPixelRatio());
|
||||
TLOGI(WmsLogTag::WMS_MAIN, "vpr: %{public}f", vpr_.load());
|
||||
return WSError::WS_OK;
|
||||
vpr_ = display->GetVirtualPixelRatio();
|
||||
TLOGI(WmsLogTag::WMS_MAIN, "vpr: %{public}f", vpr_);
|
||||
}
|
||||
|
||||
RSAnimationTimingProtocol PcFoldScreenController::GetMovingTimingProtocol()
|
||||
void PcFoldScreenManager::SetDisplayRects(
|
||||
const WSRect& defaultDisplayRect, const WSRect& virtualDisplayRect, const WSRect& foldCreaseRect)
|
||||
{
|
||||
std::unique_lock<std::shared_mutex> lock(rectsMutex_);
|
||||
defaultDisplayRect_ = defaultDisplayRect;
|
||||
virtualDisplayRect_ = virtualDisplayRect;
|
||||
foldCreaseRect_ = foldCreaseRect;
|
||||
}
|
||||
|
||||
bool PcFoldScreenManager::IsHalfFolded(DisplayId displayId)
|
||||
{
|
||||
std::shared_lock<std::shared_mutex> lock(displayInfoMutex_);
|
||||
return screenFoldStatus_ == ScreenFoldStatus::HALF_FOLDED && displayId_ == displayId;
|
||||
}
|
||||
|
||||
float PcFoldScreenManager::GetVpr()
|
||||
{
|
||||
std::unique_lock<std::shared_mutex> lock(displayInfoMutex_);
|
||||
return vpr_;
|
||||
}
|
||||
|
||||
std::tuple<WSRect, WSRect, WSRect> PcFoldScreenManager::GetDisplayRects()
|
||||
{
|
||||
std::shared_lock<std::shared_mutex> lock(rectsMutex_);
|
||||
return { defaultDisplayRect_, virtualDisplayRect_, foldCreaseRect_ };
|
||||
}
|
||||
|
||||
RSAnimationTimingProtocol PcFoldScreenManager::GetMovingTimingProtocol()
|
||||
{
|
||||
return MOVING_TIMING_PROTOCOL;
|
||||
}
|
||||
|
||||
RSAnimationTimingCurve PcFoldScreenController::GetMovingTimingCurve()
|
||||
RSAnimationTimingCurve PcFoldScreenManager::GetMovingTimingCurve()
|
||||
{
|
||||
return MOVING_CURVE;
|
||||
}
|
||||
|
||||
RSAnimationTimingProtocol PcFoldScreenController::GetThrowSlipTimingProtocol()
|
||||
RSAnimationTimingProtocol PcFoldScreenManager::GetThrowSlipTimingProtocol()
|
||||
{
|
||||
return THROW_SLIP_TIMING_PROTOCOL;
|
||||
}
|
||||
|
||||
RSAnimationTimingCurve PcFoldScreenController::GetThrowSlipTimingCurve()
|
||||
RSAnimationTimingCurve PcFoldScreenManager::GetThrowSlipTimingCurve()
|
||||
{
|
||||
return THROW_SLIP_CURVE;
|
||||
}
|
||||
|
||||
void PcFoldScreenController::RecordStartRect(const WSRect& rect, bool isStartFullScreen)
|
||||
ScreenSide PcFoldScreenManager::CalculateScreenSide(const WSRect& rect)
|
||||
{
|
||||
int32_t midPosY = rect.height_ / 2 + rect.posY_; // 2: center
|
||||
const auto& [defaultDisplayRect, virtualDisplayRect, foldCreaseRect] = GetDisplayRects();
|
||||
return midPosY <= (defaultDisplayRect.posY_ + defaultDisplayRect.height_) ?
|
||||
ScreenSide::FOLD_B : ScreenSide::FOLD_C;
|
||||
}
|
||||
|
||||
void PcFoldScreenManager::ResetArrangeRule()
|
||||
{
|
||||
std::unique_lock<std::mutex> arrangedRectsMutex_;
|
||||
defaultArrangedRect_ = RECT_ZERO;
|
||||
virtualArrangedRect_ = RECT_ZERO;
|
||||
}
|
||||
|
||||
void PcFoldScreenManager::ResetArrangeRule(const WSRect& rect)
|
||||
{
|
||||
ResetArrangeRule(CalculateScreenSide(rect));
|
||||
}
|
||||
|
||||
void PcFoldScreenManager::ResetArrangeRule(ScreenSide side)
|
||||
{
|
||||
if (side != ScreenSide::FOLD_B && side != ScreenSide::FOLD_C) {
|
||||
TLOGD(WmsLogTag::WMS_LAYOUT, "invalid side: %{public}d", static_cast<int32_t>(side));
|
||||
return;
|
||||
}
|
||||
std::unique_lock<std::mutex> arrangedRectsMutex_;
|
||||
if (side == ScreenSide::FOLD_B) {
|
||||
defaultArrangedRect_ = RECT_ZERO;
|
||||
} else { // FOLD_C
|
||||
virtualArrangedRect_ = RECT_ZERO;
|
||||
}
|
||||
}
|
||||
|
||||
void PcFoldScreenManager::ResizeToFullScreen(WSRect& rect, int32_t topAvoidHeight, int32_t botAvoidHeight)
|
||||
{
|
||||
ScreenSide side = CalculateScreenSide(rect);
|
||||
TLOGD(WmsLogTag::WMS_LAYOUT, "side: %{public}d, rect: %{public}s",
|
||||
static_cast<int32_t>(side), rect.ToString().c_str());
|
||||
if (side != ScreenSide::FOLD_B && side != ScreenSide::FOLD_C) {
|
||||
TLOGW(WmsLogTag::WMS_LAYOUT, "rule not avaliable, side %{public}d", static_cast<int32_t>(side));
|
||||
return;
|
||||
}
|
||||
|
||||
ResetArrangeRule(side);
|
||||
// calculate limit rect
|
||||
const auto& [defaultDisplayRect, virtualDisplayRect, foldCreaseRect] = GetDisplayRects();
|
||||
WSRect limitRect = RECT_ZERO;
|
||||
if (side == ScreenSide::FOLD_B) {
|
||||
limitRect.posX_ = defaultDisplayRect.posX_;
|
||||
limitRect.posY_ = defaultDisplayRect.posY_ + topAvoidHeight;
|
||||
limitRect.width_ = defaultDisplayRect.width_;
|
||||
limitRect.height_ = foldCreaseRect.posY_ - limitRect.posY_;
|
||||
} else { // FOLD_C
|
||||
limitRect.posX_ = virtualDisplayRect.posX_;
|
||||
limitRect.posY_ = foldCreaseRect.posY_ + foldCreaseRect.height_;
|
||||
limitRect.width_ = virtualDisplayRect.width_;
|
||||
limitRect.height_ = virtualDisplayRect.posY_ + virtualDisplayRect.height_ - botAvoidHeight - limitRect.posY_;
|
||||
}
|
||||
|
||||
rect = limitRect;
|
||||
}
|
||||
|
||||
bool PcFoldScreenManager::NeedDoThrowSlip(ScreenSide startSide, const WSRectF& velocity)
|
||||
{
|
||||
TLOGD(WmsLogTag::WMS_LAYOUT, "side: %{public}d, velocity: %{public}s",
|
||||
static_cast<int32_t>(startSide), velocity.ToString().c_str());
|
||||
float vpr = GetVpr();
|
||||
if (startSide == ScreenSide::FOLD_B && velocity.posY_ > VEL_THRESHOLD * vpr &&
|
||||
std::abs(velocity.posX_ / MathHelper::NonZero(velocity.posY_)) < TAN_25_DEG) {
|
||||
return true;
|
||||
}
|
||||
if (startSide == ScreenSide::FOLD_C && velocity.posY_ < -VEL_THRESHOLD * vpr &&
|
||||
std::abs(velocity.posX_ / MathHelper::NonZero(velocity.posY_)) < TAN_25_DEG) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/*
|
||||
* move rect to other side
|
||||
* @param rect: current side, moved to other side
|
||||
* @param titleHeight: used in arrange rule to avoid title bar
|
||||
*/
|
||||
bool PcFoldScreenManager::ThrowSlipToOppositeSide(ScreenSide startSide, WSRect& rect,
|
||||
int32_t topAvoidHeight, int32_t botAvoidHeight, int32_t titleHeight)
|
||||
{
|
||||
if (startSide != ScreenSide::FOLD_B && startSide != ScreenSide::FOLD_C) {
|
||||
return false;
|
||||
}
|
||||
ScreenSide endSide = (startSide == ScreenSide::FOLD_B) ? ScreenSide::FOLD_C : ScreenSide::FOLD_B;
|
||||
MappingRectInScreenSideWithArrangeRule(endSide, rect, topAvoidHeight, botAvoidHeight, titleHeight);
|
||||
return true;
|
||||
}
|
||||
|
||||
void PcFoldScreenManager::MappingRectInScreenSide(ScreenSide side, WSRect& rect,
|
||||
int32_t topAvoidHeight, int32_t botAvoidHeight)
|
||||
{
|
||||
TLOGD(WmsLogTag::WMS_LAYOUT, "side: %{public}d, rect: %{public}s, avoid heights: [%{public}d,%{public}d]",
|
||||
static_cast<int32_t>(side), rect.ToString().c_str(), topAvoidHeight, botAvoidHeight);
|
||||
WSRect topLeftLimit = RECT_ZERO;
|
||||
WSRect botRightLimit = RECT_ZERO;
|
||||
const auto& [defaultDisplayRect, virtualDisplayRect, foldCreaseRect] = GetDisplayRects();
|
||||
float vpr = GetVpr();
|
||||
switch (side) {
|
||||
case ScreenSide::FOLD_B:
|
||||
topLeftLimit.posX_ = MathHelper::Ceil(RULE_TRANS_X * vpr) - rect.width_;
|
||||
topLeftLimit.posY_ = topAvoidHeight;
|
||||
botRightLimit.posX_ = std::max(0,
|
||||
MathHelper::Floor(defaultDisplayRect.width_ - RULE_TRANS_X * vpr));
|
||||
botRightLimit.posY_ = std::max(0, foldCreaseRect.posY_ - rect.height_);
|
||||
botRightLimit.width_ = defaultDisplayRect.width_;
|
||||
botRightLimit.height_ = std::max(0, foldCreaseRect.posY_ - topLeftLimit.posY_);
|
||||
break;
|
||||
case ScreenSide::FOLD_C:
|
||||
topLeftLimit.posX_ = MathHelper::Ceil(RULE_TRANS_X * vpr) - rect.width_;
|
||||
topLeftLimit.posY_ = foldCreaseRect.posY_ + foldCreaseRect.height_;
|
||||
botRightLimit.posX_ = std::max(0,
|
||||
MathHelper::Floor(virtualDisplayRect.width_ - RULE_TRANS_X * vpr));
|
||||
botRightLimit.posY_ = std::max(foldCreaseRect.posY_ + foldCreaseRect.height_,
|
||||
MathHelper::Floor(virtualDisplayRect.posY_ + virtualDisplayRect.height_ -
|
||||
botAvoidHeight - MIN_DECOR_HEIGHT * vpr));
|
||||
botRightLimit.width_ = virtualDisplayRect.width_;
|
||||
botRightLimit.height_ = std::max(0,
|
||||
virtualDisplayRect.posY_ + virtualDisplayRect.height_ - topLeftLimit.posY_ - botAvoidHeight);
|
||||
break;
|
||||
default:
|
||||
TLOGW(WmsLogTag::WMS_LAYOUT, "invalid side: %{public}d", static_cast<int32_t>(side));
|
||||
return;
|
||||
}
|
||||
rect.posX_ = std::max(rect.posX_, topLeftLimit.posX_);
|
||||
rect.posY_ = std::max(rect.posY_, topLeftLimit.posY_);
|
||||
rect.posX_ = std::min(rect.posX_, botRightLimit.posX_);
|
||||
rect.posY_ = std::min(rect.posY_, botRightLimit.posY_);
|
||||
rect.width_ = std::min(rect.width_, botRightLimit.width_);
|
||||
rect.height_ = std::min(rect.height_, botRightLimit.height_);
|
||||
TLOGD(WmsLogTag::WMS_LAYOUT, "limit rects: [%{public}s,%{public}s], mapped rect: %{public}s",
|
||||
topLeftLimit.ToString().c_str(), botRightLimit.ToString().c_str(), rect.ToString().c_str());
|
||||
}
|
||||
|
||||
void PcFoldScreenManager::MappingRectInScreenSideWithArrangeRule(ScreenSide side, WSRect& rect,
|
||||
int32_t topAvoidHeight, int32_t botAvoidHeight, int32_t titleHeight)
|
||||
{
|
||||
TLOGD(WmsLogTag::WMS_LAYOUT, "side: %{public}d, rect: %{public}s",
|
||||
static_cast<int32_t>(side), rect.ToString().c_str());
|
||||
if (side != ScreenSide::FOLD_B && side != ScreenSide::FOLD_C) {
|
||||
TLOGW(WmsLogTag::WMS_LAYOUT, "rule not avaliable, side %{public}d", static_cast<int32_t>(side));
|
||||
return;
|
||||
}
|
||||
|
||||
// calculate limit rect
|
||||
const auto& [defaultDisplayRect, virtualDisplayRect, foldCreaseRect] = GetDisplayRects();
|
||||
WSRect limitRect = RECT_ZERO;
|
||||
if (side == ScreenSide::FOLD_B) {
|
||||
limitRect.posX_ = defaultDisplayRect.posX_;
|
||||
limitRect.posY_ = defaultDisplayRect.posY_ + topAvoidHeight;
|
||||
limitRect.width_ = defaultDisplayRect.width_;
|
||||
limitRect.height_ = foldCreaseRect.posY_ - limitRect.posY_;
|
||||
} else { // FOLD_C
|
||||
limitRect.posX_ = virtualDisplayRect.posX_;
|
||||
limitRect.posY_ = foldCreaseRect.posY_ + foldCreaseRect.height_;
|
||||
limitRect.width_ = virtualDisplayRect.width_;
|
||||
limitRect.height_ = virtualDisplayRect.posY_ + virtualDisplayRect.height_ - botAvoidHeight - limitRect.posY_;
|
||||
}
|
||||
|
||||
{
|
||||
std::unique_lock<std::mutex> lock(arrangedRectsMutex_);
|
||||
WSRect& lastArrangedRect = (side == ScreenSide::FOLD_B) ? defaultArrangedRect_ : virtualArrangedRect_;
|
||||
if (lastArrangedRect.IsEmpty()) {
|
||||
ApplyInitArrangeRule(rect, lastArrangedRect, limitRect, titleHeight);
|
||||
TLOGD(WmsLogTag::WMS_LAYOUT, "init rule, limit: %{public}s, arranged: %{public}s, rect: %{public}s",
|
||||
limitRect.ToString().c_str(), lastArrangedRect.ToString().c_str(), rect.ToString().c_str());
|
||||
return;
|
||||
}
|
||||
|
||||
ApplyArrangeRule(rect, lastArrangedRect, limitRect, titleHeight);
|
||||
TLOGD(WmsLogTag::WMS_LAYOUT, "apply rule, limit: %{public}s, arranged: %{public}s, rect: %{public}s",
|
||||
limitRect.ToString().c_str(), lastArrangedRect.ToString().c_str(), rect.ToString().c_str());
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* init rule: move rect to center of display
|
||||
* @param titleHeight: in vp
|
||||
*/
|
||||
void PcFoldScreenManager::ApplyInitArrangeRule(WSRect& rect, WSRect& lastArrangedRect,
|
||||
const WSRect& limitRect, int32_t titleHeight)
|
||||
{
|
||||
rect.posX_ = std::max(limitRect.posX_, limitRect.posX_ + (limitRect.width_ - rect.width_) / 2); // 2: center align
|
||||
rect.posY_ = std::max(limitRect.posY_, limitRect.posY_ + (limitRect.height_ - rect.height_) / 2); // 2: center align
|
||||
float vpr = GetVpr();
|
||||
lastArrangedRect = { rect.posX_, rect.posY_, RULE_TRANS_X * vpr, titleHeight * vpr };
|
||||
}
|
||||
|
||||
/*
|
||||
* init rule: move rect to bottom-right of last arranged position
|
||||
* @param titleHeight: in vp
|
||||
*/
|
||||
void PcFoldScreenManager::ApplyArrangeRule(WSRect& rect, WSRect& lastArrangedRect,
|
||||
const WSRect& limitRect, int32_t titleHeight)
|
||||
{
|
||||
rect.posX_ = lastArrangedRect.posX_ + lastArrangedRect.width_;
|
||||
rect.posY_ = lastArrangedRect.posY_ + lastArrangedRect.height_;
|
||||
// new column
|
||||
if (rect.posY_ + rect.height_ > limitRect.posY_ + limitRect.height_) {
|
||||
rect.posY_ = limitRect.posY_;
|
||||
}
|
||||
// reset to top-left
|
||||
if (rect.posX_ + rect.width_ > limitRect.posX_ + limitRect.width_) {
|
||||
rect.posX_ = limitRect.posX_;
|
||||
rect.posY_ = limitRect.posY_;
|
||||
}
|
||||
float vpr = GetVpr();
|
||||
lastArrangedRect = { rect.posX_, rect.posY_, RULE_TRANS_X * vpr, titleHeight * vpr};
|
||||
}
|
||||
|
||||
PcFoldScreenController::PcFoldScreenController(wptr<SceneSession> weakSession)
|
||||
: weakSceneSession_(std::move(weakSession)) {}
|
||||
|
||||
bool PcFoldScreenController::IsHalfFolded(DisplayId displayId)
|
||||
{
|
||||
return PcFoldScreenManager::GetInstance().IsHalfFolded(displayId);
|
||||
}
|
||||
|
||||
void PcFoldScreenController::RecordStartMoveRect(const WSRect& rect, bool isStartFullScreen)
|
||||
{
|
||||
TLOGI(WmsLogTag::WMS_LAYOUT, "rect: %{public}s, isStartFullScreen: %{public}d",
|
||||
rect.ToString().c_str(), isStartFullScreen);
|
||||
startRect_ = rect;
|
||||
std::unique_lock<std::mutex> moveMutex_;
|
||||
startMoveRect_ = rect;
|
||||
isStartFullScreen_ = isStartFullScreen;
|
||||
}
|
||||
|
||||
bool PcFoldScreenController::IsStartFullScreen() const
|
||||
{
|
||||
std::unique_lock<std::mutex> moveMutex_;
|
||||
return isStartFullScreen_;
|
||||
}
|
||||
|
||||
void PcFoldScreenController::RecordMoveRects(const WSRect& rect)
|
||||
{
|
||||
auto time = std::chrono::high_resolution_clock::now();
|
||||
std::unique_lock<std::mutex> moveMutex_;
|
||||
movingRectRecords_.push_back(std::make_pair(time, rect));
|
||||
TLOGD(WmsLogTag::WMS_LAYOUT, "id: %{public}d, rect: %{public}s", GetPersistentId(), rect.ToString().c_str());
|
||||
// pop useless record
|
||||
while (movingRectRecords_.size() > MOVING_RECORDS_SIZE_LIMIT ||
|
||||
TimeHelper::GetDuration(movingRectRecords_[0].first, time) > MOVING_RECORDS_TIME_LIMIT) {
|
||||
TimeHelper::GetDuration(movingRectRecords_[0].first, time) > MOVING_RECORDS_TIME_LIMIT) {
|
||||
movingRectRecords_.erase(movingRectRecords_.begin());
|
||||
}
|
||||
TLOGD(WmsLogTag::WMS_LAYOUT, "records size: %{public}d, duration: %{public}d", movingRectRecords_.size(),
|
||||
TLOGD(WmsLogTag::WMS_LAYOUT, "records size: %{public}zu, duration: %{public}d", movingRectRecords_.size(),
|
||||
TimeHelper::GetDuration(movingRectRecords_[0].first, movingRectRecords_[movingRectRecords_.size() - 1].first));
|
||||
}
|
||||
|
||||
/*
|
||||
* if move fast, window can be throwed to other side
|
||||
* @param rect: current rect. if throwed, move it to other side
|
||||
* @param topAvoidHeight: avoid status bar
|
||||
* @param botAvoidHeight: avoid dock
|
||||
*/
|
||||
bool PcFoldScreenController::ThrowSlip(DisplayId displayId, WSRect& rect,
|
||||
int32_t topAvoidHeight, int32_t botAvoidHeight)
|
||||
{
|
||||
if (!IsHalfFolded() || displayId != displayId_.load()) {
|
||||
ResetArrangeRule();
|
||||
auto& manager = PcFoldScreenManager::GetInstance();
|
||||
if (!manager.IsHalfFolded(displayId)) {
|
||||
manager.ResetArrangeRule();
|
||||
return false;
|
||||
}
|
||||
ResetArrangeRule(CalculateScreenSide(startRect_));
|
||||
{
|
||||
std::unique_lock<std::mutex> moveMutex_;
|
||||
manager.ResetArrangeRule(startMoveRect_);
|
||||
}
|
||||
WSRect titleRect = { rect.posX_, rect.posY_, rect.width_, GetTitleHeight() };
|
||||
ScreenSide startSide = CalculateScreenSide(titleRect);
|
||||
ScreenSide startSide = manager.CalculateScreenSide(titleRect);
|
||||
WSRectF velocity = CalculateMovingVelocity();
|
||||
if (!NeedDoThrowSlip(startSide, velocity)) {
|
||||
ResetArrangeRule(startSide);
|
||||
if (!manager.NeedDoThrowSlip(startSide, velocity)) {
|
||||
manager.ResetArrangeRule(startSide);
|
||||
TLOGI(WmsLogTag::WMS_LAYOUT, "no throw rect: %{public}s", rect.ToString().c_str());
|
||||
return false;
|
||||
}
|
||||
|
||||
ThrowSlipToOppositeSide(startSide, rect, topAvoidHeight, botAvoidHeight);
|
||||
ResetArrangeRule(startSide);
|
||||
manager.ThrowSlipToOppositeSide(startSide, rect, topAvoidHeight, botAvoidHeight, GetTitleHeight());
|
||||
manager.ResetArrangeRule(startSide);
|
||||
TLOGI(WmsLogTag::WMS_LAYOUT, "throw to rect: %{public}s", rect.ToString().c_str());
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
* resize to fullscreen in one side considering avoid area
|
||||
* @param rect: resize in its side
|
||||
*/
|
||||
void PcFoldScreenController::ResizeToFullScreen(WSRect& rect, int32_t topAvoidHeight, int32_t botAvoidHeight)
|
||||
{
|
||||
PcFoldScreenManager::GetInstance().ResizeToFullScreen(rect, topAvoidHeight, botAvoidHeight);
|
||||
}
|
||||
|
||||
RSAnimationTimingProtocol PcFoldScreenController::GetMovingTimingProtocol()
|
||||
{
|
||||
return PcFoldScreenManager::GetInstance().GetMovingTimingProtocol();
|
||||
}
|
||||
|
||||
RSAnimationTimingCurve PcFoldScreenController::GetMovingTimingCurve()
|
||||
{
|
||||
return PcFoldScreenManager::GetInstance().GetMovingTimingCurve();
|
||||
}
|
||||
|
||||
RSAnimationTimingProtocol PcFoldScreenController::GetThrowSlipTimingProtocol()
|
||||
{
|
||||
return PcFoldScreenManager::GetInstance().GetThrowSlipTimingProtocol();
|
||||
}
|
||||
|
||||
RSAnimationTimingCurve PcFoldScreenController::GetThrowSlipTimingCurve()
|
||||
{
|
||||
return PcFoldScreenManager::GetInstance().GetThrowSlipTimingCurve();
|
||||
}
|
||||
|
||||
int32_t PcFoldScreenController::GetPersistentId() const
|
||||
{
|
||||
auto sceneSession = weakSceneSession_.promote();
|
||||
@ -174,6 +465,7 @@ int32_t PcFoldScreenController::GetTitleHeight() const
|
||||
WSRectF PcFoldScreenController::CalculateMovingVelocity()
|
||||
{
|
||||
WSRectF velocity = { 0.0f, 0.0f, 0.0f, 0.0f };
|
||||
std::unique_lock<std::mutex> moveMutex_;
|
||||
int32_t recordsSize = movingRectRecords_.size();
|
||||
if (recordsSize <= 1) {
|
||||
return velocity;
|
||||
@ -195,221 +487,4 @@ WSRectF PcFoldScreenController::CalculateMovingVelocity()
|
||||
}
|
||||
return velocity;
|
||||
}
|
||||
|
||||
void PcFoldScreenController::RemoveMoveRects()
|
||||
{
|
||||
RectRecordsVector vec;
|
||||
movingRectRecords_.swap(vec);
|
||||
}
|
||||
|
||||
ScreenSide PcFoldScreenController::CalculateScreenSide(const WSRect& rect)
|
||||
{
|
||||
int32_t midPosY = rect.height_ / 2 + rect.posY_; // 2: center
|
||||
WSRect defaultDisplayRect = PcFoldScreenController::GetDefaultDisplayRect();
|
||||
WSRect virtualDisplayRect = PcFoldScreenController::GetVirtualDisplayRect();
|
||||
return midPosY <= (defaultDisplayRect.posY_ + defaultDisplayRect.height_) ?
|
||||
ScreenSide::FOLD_B : ScreenSide::FOLD_C;
|
||||
}
|
||||
|
||||
bool PcFoldScreenController::NeedDoThrowSlip(ScreenSide startSide, WSRectF velocity)
|
||||
{
|
||||
TLOGD(WmsLogTag::WMS_LAYOUT, "side: %{public}d, velocity: %{public}s", startSide, velocity.ToString().c_str());
|
||||
if (startSide == ScreenSide::FOLD_B && velocity.posY_ > VEL_THRESHOLD * vpr_.load() &&
|
||||
std::abs(velocity.posX_ / MathHelper::NonZero(velocity.posY_)) < TAN_25_DEG) {
|
||||
return true;
|
||||
}
|
||||
if (startSide == ScreenSide::FOLD_C && velocity.posY_ < -VEL_THRESHOLD * vpr_.load() &&
|
||||
std::abs(velocity.posX_ / MathHelper::NonZero(velocity.posY_)) < TAN_25_DEG) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool PcFoldScreenController::ThrowSlipToOppositeSide(ScreenSide startSide, WSRect& rect,
|
||||
int32_t topAvoidHeight, int32_t botAvoidHeight)
|
||||
{
|
||||
if (startSide != ScreenSide::FOLD_B && startSide != ScreenSide::FOLD_C) {
|
||||
return false;
|
||||
}
|
||||
ScreenSide endSide = (startSide == ScreenSide::FOLD_B) ? ScreenSide::FOLD_C : ScreenSide::FOLD_B;
|
||||
MappingRectInScreenSideWithArrangeRule(endSide, rect, topAvoidHeight, botAvoidHeight);
|
||||
return true;
|
||||
}
|
||||
|
||||
void PcFoldScreenController::MappingRectInScreenSide(ScreenSide side, WSRect& rect,
|
||||
int32_t topAvoidHeight, int32_t botAvoidHeight)
|
||||
{
|
||||
TLOGD(WmsLogTag::WMS_LAYOUT, "side: %{public}d, rect: %{public}s, avoid heights: [%{public}d,%{public}d]",
|
||||
static_cast<int32_t>(side), rect.ToString().c_str(), topAvoidHeight, botAvoidHeight);
|
||||
WSRect topLeftLimit = RECT_ZERO;
|
||||
WSRect botRightLimit = RECT_ZERO;
|
||||
WSRect defaultDisplayRect = PcFoldScreenController::GetDefaultDisplayRect();
|
||||
WSRect virtualDisplayRect = PcFoldScreenController::GetVirtualDisplayRect();
|
||||
WSRect foldCreaseRect = PcFoldScreenController::GetFoldCreaseRect();
|
||||
switch (side) {
|
||||
case ScreenSide::FOLD_B:
|
||||
topLeftLimit.posX_ = MathHelper::Ceil(RULE_TRANS_X * vpr_.load()) - rect.width_;
|
||||
topLeftLimit.posY_ = topAvoidHeight;
|
||||
botRightLimit.posX_ = std::max(0,
|
||||
MathHelper::Floor(defaultDisplayRect.width_ - RULE_TRANS_X * vpr_.load()));
|
||||
botRightLimit.posY_ = std::max(0, foldCreaseRect.posY_ - rect.height_);
|
||||
botRightLimit.width_ = defaultDisplayRect.width_;
|
||||
botRightLimit.height_ = std::max(0, foldCreaseRect.posY_ - topLeftLimit.posY_);
|
||||
break;
|
||||
case ScreenSide::FOLD_C:
|
||||
topLeftLimit.posX_ = MathHelper::Ceil(RULE_TRANS_X * vpr_.load()) - rect.width_;
|
||||
topLeftLimit.posY_ = foldCreaseRect.posY_ + foldCreaseRect.height_;
|
||||
botRightLimit.posX_ = std::max(0,
|
||||
MathHelper::Floor(virtualDisplayRect.width_ - RULE_TRANS_X * vpr_.load()));
|
||||
botRightLimit.posY_ = std::max(foldCreaseRect.posY_ + foldCreaseRect.height_,
|
||||
MathHelper::Floor(virtualDisplayRect.posY_ + virtualDisplayRect.height_ -
|
||||
botAvoidHeight - MIN_DECOR_HEIGHT * vpr_.load()));
|
||||
botRightLimit.width_ = virtualDisplayRect.width_;
|
||||
botRightLimit.height_ = std::max(0,
|
||||
virtualDisplayRect.posY_ + virtualDisplayRect.height_ - topLeftLimit.posY_ - botAvoidHeight);
|
||||
break;
|
||||
default:
|
||||
TLOGW(WmsLogTag::WMS_LAYOUT, "invalid side: %{public}d", static_cast<int32_t>(side));
|
||||
return;
|
||||
}
|
||||
rect.posX_ = std::max(rect.posX_, topLeftLimit.posX_);
|
||||
rect.posY_ = std::max(rect.posY_, topLeftLimit.posY_);
|
||||
rect.posX_ = std::min(rect.posX_, botRightLimit.posX_);
|
||||
rect.posY_ = std::min(rect.posY_, botRightLimit.posY_);
|
||||
rect.width_ = std::min(rect.width_, botRightLimit.width_);
|
||||
rect.height_ = std::min(rect.height_, botRightLimit.height_);
|
||||
TLOGD(WmsLogTag::WMS_LAYOUT, "limit rects: [%{public}s,%{public}s], mapped rect: %{public}s",
|
||||
topLeftLimit.ToString().c_str(), botRightLimit.ToString().c_str(), rect.ToString().c_str());
|
||||
}
|
||||
|
||||
void PcFoldScreenController::ResizeToFullScreen(WSRect& rect, int32_t topAvoidHeight, int32_t botAvoidHeight)
|
||||
{
|
||||
ScreenSide side = CalculateScreenSide(rect);
|
||||
TLOGD(WmsLogTag::WMS_LAYOUT, "side: %{public}d, rect: %{public}s",
|
||||
static_cast<int32_t>(side), rect.ToString().c_str());
|
||||
if (side != ScreenSide::FOLD_B && side != ScreenSide::FOLD_C) {
|
||||
TLOGW(WmsLogTag::WMS_LAYOUT, "rule not avaliable, side %{public}d", static_cast<int32_t>(side));
|
||||
return;
|
||||
}
|
||||
|
||||
ResetArrangeRule(side);
|
||||
// calculate limit rect
|
||||
WSRect defaultDisplayRect = PcFoldScreenController::GetDefaultDisplayRect();
|
||||
WSRect virtualDisplayRect = PcFoldScreenController::GetVirtualDisplayRect();
|
||||
WSRect foldCreaseRect = PcFoldScreenController::GetFoldCreaseRect();
|
||||
WSRect limitRect = RECT_ZERO;
|
||||
if (side == ScreenSide::FOLD_B) {
|
||||
limitRect.posX_ = defaultDisplayRect.posX_;
|
||||
limitRect.posY_ = defaultDisplayRect.posY_ + topAvoidHeight;
|
||||
limitRect.width_ = defaultDisplayRect.width_;
|
||||
limitRect.height_ = foldCreaseRect.posY_ - limitRect.posY_;
|
||||
} else { // FOLD_C
|
||||
limitRect.posX_ = virtualDisplayRect.posX_;
|
||||
limitRect.posY_ = foldCreaseRect.posY_ + foldCreaseRect.height_;
|
||||
limitRect.width_ = virtualDisplayRect.width_;
|
||||
limitRect.height_ = virtualDisplayRect.posY_ + virtualDisplayRect.height_ - botAvoidHeight - limitRect.posY_;
|
||||
}
|
||||
|
||||
rect = limitRect;
|
||||
}
|
||||
|
||||
void PcFoldScreenController::MappingRectInScreenSideWithArrangeRule(ScreenSide side, WSRect& rect,
|
||||
int32_t topAvoidHeight, int32_t botAvoidHeight)
|
||||
{
|
||||
TLOGD(WmsLogTag::WMS_LAYOUT, "side: %{public}d, rect: %{public}s",
|
||||
static_cast<int32_t>(side), rect.ToString().c_str());
|
||||
if (side != ScreenSide::FOLD_B && side != ScreenSide::FOLD_C) {
|
||||
TLOGW(WmsLogTag::WMS_LAYOUT, "rule not avaliable, side %{public}d", static_cast<int32_t>(side));
|
||||
return;
|
||||
}
|
||||
|
||||
// calculate limit rect
|
||||
WSRect defaultDisplayRect = PcFoldScreenController::GetDefaultDisplayRect();
|
||||
WSRect virtualDisplayRect = PcFoldScreenController::GetVirtualDisplayRect();
|
||||
WSRect foldCreaseRect = PcFoldScreenController::GetFoldCreaseRect();
|
||||
WSRect limitRect = RECT_ZERO;
|
||||
if (side == ScreenSide::FOLD_B) {
|
||||
limitRect.posX_ = defaultDisplayRect.posX_;
|
||||
limitRect.posY_ = defaultDisplayRect.posY_ + topAvoidHeight;
|
||||
limitRect.width_ = defaultDisplayRect.width_;
|
||||
limitRect.height_ = foldCreaseRect.posY_ - limitRect.posY_;
|
||||
} else { // FOLD_C
|
||||
limitRect.posX_ = virtualDisplayRect.posX_;
|
||||
limitRect.posY_ = foldCreaseRect.posY_ + foldCreaseRect.height_;
|
||||
limitRect.width_ = virtualDisplayRect.width_;
|
||||
limitRect.height_ = virtualDisplayRect.posY_ + virtualDisplayRect.height_ - botAvoidHeight - limitRect.posY_;
|
||||
}
|
||||
|
||||
std::atomic<WSRect>& lastArrangedRect = (side == ScreenSide::FOLD_B) ?
|
||||
defaultArrangedRect_ : virtualArrangedRect_;
|
||||
if (lastArrangedRect.load().IsEmpty()) {
|
||||
ApplyInitArrangeRule(rect, lastArrangedRect, limitRect, GetTitleHeight());
|
||||
TLOGD(WmsLogTag::WMS_LAYOUT, "init rule, limit: %{public}s, arranged: %{public}s, rect: %{public}s",
|
||||
limitRect.ToString().c_str(), lastArrangedRect.load().ToString().c_str(), rect.ToString().c_str());
|
||||
return;
|
||||
}
|
||||
|
||||
ApplyArrangeRule(rect, lastArrangedRect, limitRect, GetTitleHeight());
|
||||
TLOGD(WmsLogTag::WMS_LAYOUT, "apply rule, limit: %{public}s, arranged: %{public}s, rect: %{public}s",
|
||||
limitRect.ToString().c_str(), lastArrangedRect.load().ToString().c_str(), rect.ToString().c_str());
|
||||
}
|
||||
|
||||
/*
|
||||
* init rule: move rect to center of display
|
||||
* @param titleHeight: in vp
|
||||
*/
|
||||
void PcFoldScreenController::ApplyInitArrangeRule(WSRect& rect, std::atomic<WSRect>& lastArrangedRect,
|
||||
const WSRect& limitRect, int32_t titleHeight)
|
||||
{
|
||||
rect.posX_ = std::max(limitRect.posX_, limitRect.posX_ + (limitRect.width_ - rect.width_) / 2); // 2: center align
|
||||
rect.posY_ = std::max(limitRect.posY_, limitRect.posY_ + (limitRect.height_ - rect.height_) / 2); // 2: center align
|
||||
lastArrangedRect.store({ rect.posX_, rect.posY_,
|
||||
RULE_TRANS_X * vpr_.load(), titleHeight * vpr_.load()});
|
||||
}
|
||||
|
||||
/*
|
||||
* init rule: move rect to bottom-right of last arranged position
|
||||
* @param titleHeight: in vp
|
||||
*/
|
||||
void PcFoldScreenController::ApplyArrangeRule(WSRect& rect, std::atomic<WSRect>& lastArrangedRect,
|
||||
const WSRect& limitRect, int32_t titleHeight)
|
||||
{
|
||||
rect.posX_ = lastArrangedRect.load().posX_ + lastArrangedRect.load().width_;
|
||||
rect.posY_ = lastArrangedRect.load().posY_ + lastArrangedRect.load().height_;
|
||||
// new column
|
||||
if (rect.posY_ + rect.height_ > limitRect.posY_ + limitRect.height_) {
|
||||
rect.posY_ = limitRect.posY_;
|
||||
}
|
||||
// reset to top-left
|
||||
if (rect.posX_ + rect.width_ > limitRect.posX_ + limitRect.width_) {
|
||||
rect.posX_ = limitRect.posX_;
|
||||
rect.posY_ = limitRect.posY_;
|
||||
}
|
||||
lastArrangedRect.store({ rect.posX_, rect.posY_,
|
||||
RULE_TRANS_X * vpr_.load(), titleHeight * vpr_.load()});
|
||||
}
|
||||
|
||||
void PcFoldScreenController::ResetArrangeRule()
|
||||
{
|
||||
defaultArrangedRect_.store(RECT_ZERO);
|
||||
virtualArrangedRect_.store(RECT_ZERO);
|
||||
}
|
||||
|
||||
void PcFoldScreenController::ResetArrangeRule(const WSRect& rect)
|
||||
{
|
||||
ResetArrangeRule(CalculateScreenSide(rect));
|
||||
}
|
||||
|
||||
void PcFoldScreenController::ResetArrangeRule(ScreenSide side)
|
||||
{
|
||||
if (side != ScreenSide::FOLD_B && side != ScreenSide::FOLD_C) {
|
||||
TLOGD(WmsLogTag::WMS_LAYOUT, "invalid side: %{public}d", static_cast<int32_t>(side));
|
||||
return;
|
||||
}
|
||||
if (side == ScreenSide::FOLD_B) {
|
||||
defaultArrangedRect_.store(RECT_ZERO);
|
||||
} else { // FOLD_C
|
||||
virtualArrangedRect_.store(RECT_ZERO);
|
||||
}
|
||||
}
|
||||
} // namespace OHOS::Rosen
|
||||
} // namespace OHOS::Rosen
|
@ -525,7 +525,7 @@ WSError SceneSession::OnSessionEvent(SessionEvent event)
|
||||
session->InitializeCrossMoveDrag();
|
||||
session->moveDragController_->InitMoveDragProperty();
|
||||
if (session->pcFoldScreenController_) {
|
||||
session->pcFoldScreenController_->RecordStartRect(session->GetSessionRect(),
|
||||
session->pcFoldScreenController_->RecordStartMoveRect(session->GetSessionRect(),
|
||||
session->IsFullScreenMovable());
|
||||
}
|
||||
if (session->IsFullScreenMovable()) {
|
||||
@ -555,25 +555,24 @@ WSError SceneSession::OnSessionEvent(SessionEvent event)
|
||||
return WSError::WS_OK;
|
||||
}
|
||||
|
||||
WSError SceneSession::OnSessionEvent(SessionEvent event, SessionEventParam param)
|
||||
WSError SceneSession::OnSessionEvent(SessionEvent event, const SessionEventParam& param)
|
||||
{
|
||||
const char* const where = __func__;
|
||||
auto task = [weakThis = wptr(this), event, param, where]() {
|
||||
auto task = [weakThis = wptr(this), event, param, where] {
|
||||
auto session = weakThis.promote();
|
||||
if (!session) {
|
||||
TLOGNE(WmsLogTag::WMS_MAIN, "%{public}s session is null", where);
|
||||
return WSError::WS_ERROR_DESTROYED_OBJECT;
|
||||
return;
|
||||
}
|
||||
if (!(session->sessionChangeCallback_ && session->sessionChangeCallback_->OnSessionEvent_)) {
|
||||
TLOGNE(WmsLogTag::WMS_MAIN, "%{public}s invalid callback", where);
|
||||
return WSError::WS_DO_NOTHING;
|
||||
return;
|
||||
}
|
||||
TLOGNI(WmsLogTag::WMS_MAIN,
|
||||
"%{public}s event: %{public}d, param:[%{public}d,%{public}d,%{public}d,%{public}d]",
|
||||
where, static_cast<int32_t>(event),
|
||||
param.pointerX_, param.pointerY_, param.sessionWidth_, param.sessionHeight_);
|
||||
session->sessionChangeCallback_->OnSessionEvent_(static_cast<uint32_t>(event), param);
|
||||
return WSError::WS_OK;
|
||||
};
|
||||
PostTask(task, "OnSessionEvent:" + std::to_string(static_cast<uint32_t>(event)));
|
||||
return WSError::WS_OK;
|
||||
@ -2526,14 +2525,10 @@ void SceneSession::InitializeCrossMoveDrag()
|
||||
void SceneSession::HandleMoveDragSurfaceBounds(WSRect& rect, WSRect& globalRect, SizeChangeReason reason,
|
||||
bool isGlobal, bool needFlush)
|
||||
{
|
||||
const char* const funcName = __func__;
|
||||
if (pcFoldScreenController_ && pcFoldScreenController_->IsHalfFolded()) {
|
||||
SetSurfaceBoundsWithAnimation(
|
||||
std::make_pair(
|
||||
pcFoldScreenController_->GetMovingTimingProtocol(),
|
||||
pcFoldScreenController_->GetMovingTimingCurve()
|
||||
),
|
||||
globalRect, nullptr, isGlobal, needFlush);
|
||||
if (pcFoldScreenController_ && pcFoldScreenController_->IsHalfFolded(GetScreenId())) {
|
||||
auto movingPair = std::make_pair(pcFoldScreenController_->GetMovingTimingProtocol(),
|
||||
pcFoldScreenController_->GetMovingTimingCurve());
|
||||
SetSurfaceBoundsWithAnimation(movingPair, globalRect, nullptr, isGlobal, needFlush);
|
||||
if (reason == SizeChangeReason::MOVE) {
|
||||
pcFoldScreenController_->RecordMoveRects(rect);
|
||||
}
|
||||
@ -2610,23 +2605,20 @@ bool SceneSession::MoveUnderInteriaAndNotifyRectChange(WSRect& rect, SizeChangeR
|
||||
bool needSetFullScreen = pcFoldScreenController_->IsStartFullScreen();
|
||||
if (needSetFullScreen) {
|
||||
// maximize end rect and notify last rect
|
||||
PcFoldScreenController::ResizeToFullScreen(endRect, GetStatusBarHeight(), GetDockHeight());
|
||||
finishCallback = [weakThis = wptr(this), rect]() {
|
||||
pcFoldScreenController_->ResizeToFullScreen(endRect, GetStatusBarHeight(), GetDockHeight());
|
||||
finishCallback = [weakThis = wptr(this), rect] {
|
||||
auto session = weakThis.promote();
|
||||
if (session == nullptr) {
|
||||
TLOGW(WmsLogTag::WMS_LAYOUT, "session is nullptr");
|
||||
TLOGNW(WmsLogTag::WMS_LAYOUT, "session is nullptr");
|
||||
return;
|
||||
}
|
||||
session->OnSessionEvent(SessionEvent::EVENT_MAXIMIZE_WITHOUT_ANIMATION,
|
||||
SessionEventParam {rect.posX_, rect.posY_, rect.width_, rect.height_});
|
||||
};
|
||||
}
|
||||
SetSurfaceBoundsWithAnimation(
|
||||
std::make_pair(
|
||||
pcFoldScreenController_->GetThrowSlipTimingProtocol(),
|
||||
pcFoldScreenController_->GetThrowSlipTimingCurve()
|
||||
),
|
||||
endRect, std::move(finishCallback));
|
||||
auto throwSlipPair = std::make_pair(pcFoldScreenController_->GetThrowSlipTimingProtocol(),
|
||||
pcFoldScreenController_->GetThrowSlipTimingCurve());
|
||||
SetSurfaceBoundsWithAnimation(throwSlipPair, endRect, finishCallback);
|
||||
return needSetFullScreen;
|
||||
}
|
||||
|
||||
@ -2758,19 +2750,18 @@ void SceneSession::UpdateWinRectForSystemBar(WSRect& rect)
|
||||
}
|
||||
|
||||
void SceneSession::SetSurfaceBoundsWithAnimation(
|
||||
std::pair<RSAnimationTimingProtocol, RSAnimationTimingCurve> animationParam,
|
||||
const WSRect& rect, std::function<void()>&& finishCallback, bool isGlobal, bool needFlush)
|
||||
const std::pair<RSAnimationTimingProtocol, RSAnimationTimingCurve>& animationParam,
|
||||
const WSRect& rect, const std::function<void()>& finishCallback, bool isGlobal, bool needFlush)
|
||||
{
|
||||
auto weakThis = wptr(this);
|
||||
auto interiaFunc = [weakThis, rect, isGlobal, needFlush]() {
|
||||
auto interiaFunc = [weakThis = wptr(this), rect, isGlobal, needFlush]() {
|
||||
auto session = weakThis.promote();
|
||||
if (session == nullptr) {
|
||||
TLOGW(WmsLogTag::WMS_EVENT, "session is nullptr");
|
||||
TLOGNW(WmsLogTag::WMS_LAYOUT, "session is nullptr");
|
||||
return;
|
||||
}
|
||||
session->SetSurfaceBounds(rect, isGlobal, needFlush);
|
||||
};
|
||||
RSNode::Animate(animationParam.first, animationParam.second, interiaFunc, std::move(finishCallback));
|
||||
RSNode::Animate(animationParam.first, animationParam.second, interiaFunc, finishCallback);
|
||||
}
|
||||
|
||||
void SceneSession::SetSurfaceBounds(const WSRect& rect, bool isGlobal, bool needFlush)
|
||||
@ -5212,9 +5203,11 @@ int32_t SceneSession::GetDockHeight()
|
||||
std::vector<sptr<SceneSession>> dockVector = specificCallback_->onGetSceneSessionVectorByType_(
|
||||
WindowType::WINDOW_TYPE_LAUNCHER_DOCK, GetSessionProperty()->GetDisplayId());
|
||||
for (auto& dock : dockVector) {
|
||||
if (dock != nullptr && dock->IsVisible() && dock->GetSessionRect().height_ > height &&
|
||||
dock->GetWindowName().find("SCBSmartDock") != std::string::npos) {
|
||||
height = dock->GetSessionRect().height_;
|
||||
if (dock != nullptr && dock->IsVisible() && dock->GetWindowName().find("SCBSmartDock") != std::string::npos) {
|
||||
int32_t dockHeight = dock->GetSessionRect().height_;
|
||||
if (dockHeight > height) {
|
||||
height = dockHeight;
|
||||
}
|
||||
}
|
||||
}
|
||||
return height;
|
||||
|
Loading…
x
Reference in New Issue
Block a user