mirror of
https://gitee.com/openharmony/window_window_manager
synced 2024-11-23 06:50:40 +00:00
!10447 悬停态抛滑
Merge pull request !10447 from slarkwayne/remote_throwSlip
This commit is contained in:
commit
7309e0e899
@ -18,6 +18,7 @@
|
||||
|
||||
#include <cmath>
|
||||
#include <limits>
|
||||
#include <chrono>
|
||||
|
||||
namespace OHOS::Rosen {
|
||||
namespace MathHelper {
|
||||
@ -82,8 +83,34 @@ T Clamp(const T& value, const T& lower, const T& upper)
|
||||
{
|
||||
return Min(upper, Max(lower, value));
|
||||
}
|
||||
|
||||
inline float NonZero(float val)
|
||||
{
|
||||
if (!NearZero(val)) {
|
||||
return val;
|
||||
}
|
||||
return val > 0 ? POS_ZERO : NAG_ZERO;
|
||||
}
|
||||
|
||||
inline int32_t Floor(float val)
|
||||
{
|
||||
return static_cast<int32_t>(std::floor(val));
|
||||
}
|
||||
|
||||
inline int32_t Ceil(float val)
|
||||
{
|
||||
return static_cast<int32_t>(std::ceil(val));
|
||||
}
|
||||
} // namespace MathHelper
|
||||
|
||||
namespace TimeHelper {
|
||||
inline int32_t GetDuration(std::chrono::time_point<std::chrono::high_resolution_clock> t0,
|
||||
std::chrono::time_point<std::chrono::high_resolution_clock> t1)
|
||||
{
|
||||
return static_cast<int32_t>(std::chrono::duration_cast<std::chrono::milliseconds>(t1 - t0).count());
|
||||
}
|
||||
}
|
||||
|
||||
namespace TransformHelper {
|
||||
struct Vector2 {
|
||||
float x_, y_;
|
||||
|
@ -412,6 +412,7 @@ enum class SessionEvent : uint32_t {
|
||||
EVENT_SPLIT_SECONDARY,
|
||||
EVENT_DRAG_START,
|
||||
EVENT_DRAG,
|
||||
EVENT_MAXIMIZE_WITHOUT_ANIMATION,
|
||||
};
|
||||
|
||||
enum class BrokerStates: uint32_t {
|
||||
|
@ -21,6 +21,7 @@
|
||||
#include "napi_common_want.h"
|
||||
#include "native_value.h"
|
||||
#include "pixel_map_napi.h"
|
||||
#include "session/host/include/pc_fold_screen_controller.h"
|
||||
#include "session/host/include/scene_persistence.h"
|
||||
#include "session/host/include/scene_persistent_storage.h"
|
||||
#include "session/host/include/session.h"
|
||||
@ -50,6 +51,7 @@ constexpr int DEFAULT_ARG_COUNT = 4;
|
||||
constexpr int ARG_INDEX_ONE = 1;
|
||||
constexpr int ARG_INDEX_TWO = 2;
|
||||
constexpr int ARG_INDEX_THREE = 3;
|
||||
constexpr int ARG_INDEX_FOUR = 4;
|
||||
constexpr int32_t RESTYPE_RECLAIM = 100001;
|
||||
const std::string RES_PARAM_RECLAIM_TAG = "reclaimTag";
|
||||
const std::string CREATE_SYSTEM_SESSION_CB = "createSpecificSession";
|
||||
@ -215,6 +217,10 @@ napi_value JsSceneSessionManager::Init(napi_env env, napi_value exportObj)
|
||||
JsSceneSessionManager::RefreshAppInfo);
|
||||
BindNativeFunction(env, exportObj, "getWindowPid", moduleName,
|
||||
JsSceneSessionManager::GetWindowPid);
|
||||
BindNativeFunction(env, exportObj, "updatePcFoldScreenStatus", moduleName,
|
||||
JsSceneSessionManager::UpdatePcFoldScreenStatus);
|
||||
BindNativeFunction(env, exportObj, "resetPcFoldScreenArrangeRule", moduleName,
|
||||
JsSceneSessionManager::ResetPcFoldScreenArrangeRule);
|
||||
return NapiGetUndefined(env);
|
||||
}
|
||||
|
||||
@ -1117,6 +1123,18 @@ napi_value JsSceneSessionManager::GetWindowPid(napi_env env, napi_callback_info
|
||||
return me->OnGetWindowPid(env, info);
|
||||
}
|
||||
|
||||
napi_value JsSceneSessionManager::UpdatePcFoldScreenStatus(napi_env env, napi_callback_info info)
|
||||
{
|
||||
JsSceneSessionManager* me = CheckParamsAndGetThis<JsSceneSessionManager>(env, info);
|
||||
return (me != nullptr) ? me->OnUpdatePcFoldScreenStatus(env, info) : nullptr;
|
||||
}
|
||||
|
||||
napi_value JsSceneSessionManager::ResetPcFoldScreenArrangeRule(napi_env env, napi_callback_info info)
|
||||
{
|
||||
JsSceneSessionManager* me = CheckParamsAndGetThis<JsSceneSessionManager>(env, info);
|
||||
return (me != nullptr) ? me->OnResetPcFoldScreenArrangeRule(env, info) : nullptr;
|
||||
}
|
||||
|
||||
napi_value JsSceneSessionManager::RefreshPcZOrder(napi_env env, napi_callback_info info)
|
||||
{
|
||||
TLOGD(WmsLogTag::WMS_LAYOUT, "[NAPI]");
|
||||
@ -3525,6 +3543,93 @@ napi_value JsSceneSessionManager::OnGetWindowPid(napi_env env, napi_callback_inf
|
||||
return result;
|
||||
}
|
||||
|
||||
napi_value JsSceneSessionManager::OnUpdatePcFoldScreenStatus(napi_env env, napi_callback_info info)
|
||||
{
|
||||
size_t argc = ARGC_FIVE;
|
||||
napi_value argv[ARGC_FIVE] = {nullptr};
|
||||
napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr);
|
||||
|
||||
if (argc < ARGC_FIVE) {
|
||||
TLOGE(WmsLogTag::WMS_LAYOUT, "[NAPI]Argc is invalid: %{public}zu", argc);
|
||||
napi_throw(env, CreateJsError(env, static_cast<int32_t>(WSErrorCode::WS_ERROR_INVALID_PARAM),
|
||||
"Input parameter is missing or invalid"));
|
||||
return NapiGetUndefined(env);
|
||||
}
|
||||
|
||||
int64_t displayId { INVALID_SCREEN_ID };
|
||||
if (!ConvertFromJsValue(env, argv[0], displayId)) {
|
||||
TLOGE(WmsLogTag::WMS_LAYOUT, "[NAPI]Failed to convert parameter to displayId");
|
||||
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 = ScreenFoldStatus::UNKNOWN;
|
||||
if (!ConvertFromJsValue(env, argv[ARG_INDEX_ONE], status)) {
|
||||
TLOGE(WmsLogTag::WMS_LAYOUT, "[NAPI]Failed to convert parameter to type");
|
||||
napi_throw(env, CreateJsError(env, static_cast<int32_t>(WSErrorCode::WS_ERROR_INVALID_PARAM),
|
||||
"Input parameter is missing or invalid"));
|
||||
return NapiGetUndefined(env);
|
||||
}
|
||||
|
||||
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");
|
||||
napi_throw(env, CreateJsError(env, static_cast<int32_t>(WSErrorCode::WS_ERROR_INVALID_PARAM),
|
||||
"Input parameter is missing or invalid"));
|
||||
return NapiGetUndefined(env);
|
||||
}
|
||||
|
||||
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");
|
||||
napi_throw(env, CreateJsError(env, static_cast<int32_t>(WSErrorCode::WS_ERROR_INVALID_PARAM),
|
||||
"Input parameter is missing or invalid"));
|
||||
return NapiGetUndefined(env);
|
||||
}
|
||||
|
||||
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");
|
||||
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);
|
||||
|
||||
return NapiGetUndefined(env);
|
||||
}
|
||||
|
||||
napi_value JsSceneSessionManager::OnResetPcFoldScreenArrangeRule(napi_env env, napi_callback_info info)
|
||||
{
|
||||
size_t argc = ARGC_FOUR;
|
||||
napi_value argv[ARGC_FOUR] = {nullptr};
|
||||
napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr);
|
||||
|
||||
if (argc < ARGC_ONE) {
|
||||
TLOGE(WmsLogTag::WMS_LAYOUT, "[NAPI]Argc is invalid: %{public}zu", argc);
|
||||
napi_throw(env, CreateJsError(env, static_cast<int32_t>(WSErrorCode::WS_ERROR_INVALID_PARAM),
|
||||
"Input parameter is missing or invalid"));
|
||||
return NapiGetUndefined(env);
|
||||
}
|
||||
|
||||
WSRect rect;
|
||||
if (argv[0] == nullptr || !ConvertRectInfoFromJs(env, argv[0], rect)) {
|
||||
TLOGE(WmsLogTag::WMS_LAYOUT, "[NAPI]Failed to convert parameter to 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::ResetArrangeRule(rect);
|
||||
|
||||
return NapiGetUndefined(env);
|
||||
}
|
||||
|
||||
void JsSceneSessionManager::OnCloseTargetFloatWindow(const std::string& bundleName)
|
||||
{
|
||||
TLOGD(WmsLogTag::WMS_MULTI_WINDOW, "[NAPI]");
|
||||
|
@ -115,6 +115,8 @@ public:
|
||||
static napi_value IsScbCoreEnabled(napi_env env, napi_callback_info info);
|
||||
static napi_value RefreshPcZOrder(napi_env env, napi_callback_info info);
|
||||
static napi_value GetWindowPid(napi_env env, napi_callback_info info);
|
||||
static napi_value UpdatePcFoldScreenStatus(napi_env env, napi_callback_info info);
|
||||
static napi_value ResetPcFoldScreenArrangeRule(napi_env env, napi_callback_info info);
|
||||
|
||||
/*
|
||||
* Multi instance
|
||||
@ -188,6 +190,8 @@ private:
|
||||
napi_value OnIsScbCoreEnabled(napi_env env, napi_callback_info info);
|
||||
napi_value OnRefreshPcZOrder(napi_env env, napi_callback_info info);
|
||||
napi_value OnGetWindowPid(napi_env env, napi_callback_info info);
|
||||
napi_value OnUpdatePcFoldScreenStatus(napi_env env, napi_callback_info info);
|
||||
napi_value OnResetPcFoldScreenArrangeRule(napi_env env, napi_callback_info info);
|
||||
|
||||
/*
|
||||
* multi instance
|
||||
|
@ -51,6 +51,7 @@ ohos_shared_library("scene_session") {
|
||||
"host/src/main_session.cpp",
|
||||
"host/src/move_drag_controller.cpp",
|
||||
"host/src/multi_instance_manager.cpp",
|
||||
"host/src/pc_fold_screen_controller.cpp",
|
||||
"host/src/root_scene_session.cpp",
|
||||
"host/src/scb_system_session.cpp",
|
||||
"host/src/scene_persistence.cpp",
|
||||
@ -89,6 +90,7 @@ ohos_shared_library("scene_session") {
|
||||
"ffrt:libffrt",
|
||||
"graphic_2d:librender_service_base",
|
||||
"graphic_2d:librender_service_client",
|
||||
"graphic_2d:window_animation",
|
||||
"hilog:libhilog",
|
||||
"hisysevent:libhisysevent",
|
||||
"hitrace:hitrace_meter",
|
||||
|
124
window_scene/session/host/include/pc_fold_screen_controller.h
Executable file
124
window_scene/session/host/include/pc_fold_screen_controller.h
Executable file
@ -0,0 +1,124 @@
|
||||
/*
|
||||
* Copyright (c) 2024 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 PC_FOLD_SCREEN_CONTROLLER_H
|
||||
#define PC_FOLD_SCREEN_CONTROLLER_H
|
||||
|
||||
#include <chrono>
|
||||
#include "interfaces/include/ws_common.h"
|
||||
#include "dm_common.h"
|
||||
#include "animation/rs_animation_timing_curve.h"
|
||||
#include "animation/rs_animation_timing_protocol.h"
|
||||
|
||||
|
||||
namespace OHOS::Rosen {
|
||||
|
||||
class SceneSession;
|
||||
using RectRecordsVector =
|
||||
std::vector<std::pair<std::chrono::time_point<std::chrono::high_resolution_clock>, WSRect>>;
|
||||
|
||||
enum class ScreenFoldStatus {
|
||||
UNKNOWN = 0,
|
||||
COVER_CLOSE = 1,
|
||||
HALF_FOLDED = 2,
|
||||
HALF_FOLDED_PHYSICAL_KEYBOARD = 3,
|
||||
FLATTENED = 4,
|
||||
};
|
||||
|
||||
enum class ScreenSide {
|
||||
EXPAND = 0,
|
||||
FOLD_B = 1,
|
||||
FOLD_C = 2,
|
||||
};
|
||||
|
||||
class PcFoldScreenController : public RefBase {
|
||||
public:
|
||||
explicit PcFoldScreenController(wptr<SceneSession> weak);
|
||||
static bool IsHalfFolded() { return screenFoldStatus_.load() == ScreenFoldStatus::HALF_FOLDED; }
|
||||
|
||||
// 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); }
|
||||
|
||||
// animation parameters
|
||||
static RSAnimationTimingProtocol GetMovingTimingProtocol();
|
||||
static RSAnimationTimingCurve GetMovingTimingCurve();
|
||||
static RSAnimationTimingProtocol GetThrowSlipTimingProtocol();
|
||||
static 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);
|
||||
|
||||
private:
|
||||
int32_t GetPersistentId() const;
|
||||
int32_t GetTitleHeight() const;
|
||||
WSRectF CalculateMovingVelocity();
|
||||
void RemoveMoveRects();
|
||||
|
||||
static ScreenSide CalculateScreenSide(const WSRect& rect);
|
||||
static bool NeedDoThrowSlip(ScreenSide startSide, 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);
|
||||
void MappingRectInScreenSideWithArrangeRule(ScreenSide side, WSRect& rect,
|
||||
int32_t topAvoidHeight, int32_t botAvoidHeight);
|
||||
|
||||
static void ApplyInitArrangeRule(WSRect& rect, std::atomic<WSRect>& lastArrangedRect,
|
||||
const WSRect& limitRect, int32_t titleHeight);
|
||||
static void ApplyArrangeRule(WSRect& rect, std::atomic<WSRect>& lastArrangedRect,
|
||||
const WSRect& limitRect, int32_t titleHeight);
|
||||
static void ResetArrangeRule();
|
||||
static void ResetArrangeRule(ScreenSide side);
|
||||
|
||||
wptr<SceneSession> weakSceneSession_ = nullptr;
|
||||
|
||||
/*
|
||||
* 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_;
|
||||
|
||||
/*
|
||||
* arranged rect
|
||||
* x,y: last arranged position
|
||||
* w,h: offset for next arranged position
|
||||
*/
|
||||
static std::atomic<WSRect> defaultArrangedRect_;
|
||||
static std::atomic<WSRect> virtualArrangedRect_;
|
||||
};
|
||||
} // namespace OHOS::Rosen
|
||||
|
||||
#endif // PC_FOLD_SCREEN_CONTROLLER_H
|
@ -18,6 +18,7 @@
|
||||
|
||||
#include "session/host/include/session.h"
|
||||
#include "session/host/include/move_drag_controller.h"
|
||||
#include "session/host/include/pc_fold_screen_controller.h"
|
||||
#include "vsync_station.h"
|
||||
#include "wm_common.h"
|
||||
|
||||
@ -177,6 +178,7 @@ public:
|
||||
|
||||
WSError UpdateActiveStatus(bool isActive) override;
|
||||
WSError OnSessionEvent(SessionEvent event) override;
|
||||
WSError OnSessionEvent(SessionEvent event, SessionEventParam param);
|
||||
WSError SyncSessionEvent(SessionEvent event) override;
|
||||
WSError OnLayoutFullScreenChange(bool isLayoutFullScreen) override;
|
||||
WSError OnDefaultDensityEnabled(bool isDefaultDensityEnabled) override;
|
||||
@ -458,6 +460,7 @@ public:
|
||||
void RemoveUIExtSurfaceNodeId(int32_t persistentId);
|
||||
int32_t GetUIExtPersistentIdBySurfaceNodeId(uint64_t surfaceNodeId) const;
|
||||
int32_t GetStatusBarHeight() override;
|
||||
int32_t GetDockHeight();
|
||||
bool IsFreeMultiWindowMode() const
|
||||
{
|
||||
return systemConfig_.IsFreeMultiWindowMode();
|
||||
@ -591,6 +594,11 @@ protected:
|
||||
NotifyForceHideChangeFunc onForceHideChangeFunc_;
|
||||
ClearCallbackMapFunc clearCallbackMapFunc_;
|
||||
|
||||
/*
|
||||
* pc fold screen
|
||||
*/
|
||||
sptr<PcFoldScreenController> pcFoldScreenController_ = nullptr;
|
||||
|
||||
/**
|
||||
* PC Window
|
||||
*/
|
||||
@ -640,6 +648,7 @@ private:
|
||||
void HandleMoveDragSurfaceBounds(WSRect& rect, WSRect& globalRect, SizeChangeReason reason,
|
||||
bool isGlobal, bool needFlush);
|
||||
void HandleMoveDragEnd(WSRect& rect, SizeChangeReason reason);
|
||||
bool MoveUnderInteriaAndNotifyRectChange(WSRect& rect, SizeChangeReason reason);
|
||||
|
||||
/**
|
||||
* Gesture Back
|
||||
@ -658,6 +667,11 @@ 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);
|
||||
|
@ -210,6 +210,7 @@ public:
|
||||
void GetCloseAbilityWantAndClean(AAFwk::Want& outWant);
|
||||
void SetSessionInfo(const SessionInfo& info);
|
||||
const SessionInfo& GetSessionInfo() const;
|
||||
DisplayId GetScreenId() const;
|
||||
void SetScreenId(uint64_t screenId);
|
||||
WindowType GetWindowType() const;
|
||||
float GetAspectRatio() const;
|
||||
|
@ -31,6 +31,7 @@ MainSession::MainSession(const SessionInfo& info, const sptr<SpecificSessionCall
|
||||
// persistentId changed due to id conflicts. Need to rename the old snapshot if exists
|
||||
scenePersistence_->RenameSnapshotFromOldPersistentId(info.persistentId_);
|
||||
}
|
||||
pcFoldScreenController_ = sptr<PcFoldScreenController>::MakeSptr(wptr(this));
|
||||
moveDragController_ = sptr<MoveDragController>::MakeSptr(GetPersistentId(), GetWindowType());
|
||||
if (specificCallback != nullptr &&
|
||||
specificCallback->onWindowInputPidChangeCallback_ != nullptr) {
|
||||
|
415
window_scene/session/host/src/pc_fold_screen_controller.cpp
Executable file
415
window_scene/session/host/src/pc_fold_screen_controller.cpp
Executable file
@ -0,0 +1,415 @@
|
||||
/*
|
||||
* Copyright (c) 2024 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 "session/host/include/pc_fold_screen_controller.h"
|
||||
#include "display_manager.h"
|
||||
#include "session/host/include/scene_session.h"
|
||||
#include "window_manager_hilog.h"
|
||||
#include "wm_common_inner.h"
|
||||
#include "wm_math.h"
|
||||
|
||||
namespace OHOS::Rosen {
|
||||
|
||||
namespace {
|
||||
// moving
|
||||
constexpr int32_t MOVING_RECORDS_SIZE_LIMIT = 5;
|
||||
constexpr int32_t MOVING_RECORDS_TIME_LIMIT = 100;
|
||||
constexpr int32_t MOVING_RESPONSE = 50;
|
||||
constexpr float MOVING_DAMPING_RATIO = 0.98f;
|
||||
const RSAnimationTimingProtocol MOVING_TIMING_PROTOCOL(MOVING_RESPONSE); // animation time
|
||||
const RSAnimationTimingCurve MOVING_CURVE =
|
||||
RSAnimationTimingCurve::CreateSpring(static_cast<float>(MOVING_RESPONSE / 1000.0f), MOVING_DAMPING_RATIO, 0.0f);
|
||||
|
||||
// throw-slip
|
||||
constexpr float TAN_25_DEG = 0.4663; // throw slip angle = 25 deg
|
||||
constexpr float VEL_THRESHOLD = 0.13445; // 134.45 dp/s
|
||||
constexpr float THROW_SLIP_TIME = 416.0f;
|
||||
constexpr float THROW_SLIP_DAMPING_RATIO = 0.9934f; // stiffness = 228, damping = 30
|
||||
const RSAnimationTimingProtocol THROW_SLIP_TIMING_PROTOCOL(std::round(THROW_SLIP_TIME)); // animation time
|
||||
const RSAnimationTimingCurve THROW_SLIP_CURVE =
|
||||
RSAnimationTimingCurve::CreateSpring(THROW_SLIP_TIME / 1000.0f, THROW_SLIP_DAMPING_RATIO, 0.0f);
|
||||
|
||||
// arrange rule
|
||||
constexpr int32_t RULE_TRANS_X = 48; // dp
|
||||
constexpr int32_t MIN_DECOR_HEIGHT = 37;
|
||||
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;
|
||||
|
||||
PcFoldScreenController::PcFoldScreenController(wptr<SceneSession> weak) : weakSceneSession_(weak) {}
|
||||
|
||||
WSError PcFoldScreenController::UpdateFoldScreenStatus(DisplayId displayId, ScreenFoldStatus status)
|
||||
{
|
||||
if (displayId_.load() == displayId && screenFoldStatus_.load() == status) {
|
||||
return WSError::WS_DO_NOTHING;
|
||||
}
|
||||
TLOGI(WmsLogTag::WMS_MAIN, "display: %{public}" PRIu64", fold status: %{public}d",
|
||||
displayId, static_cast<int32_t>(status));
|
||||
screenFoldStatus_.store(status);
|
||||
ResetArrangeRule();
|
||||
displayId_.store(displayId);
|
||||
auto display = DisplayManager::GetInstance().GetDisplayById(displayId);
|
||||
if (display == nullptr) {
|
||||
TLOGE(WmsLogTag::WMS_MAIN, "Failed to get display");
|
||||
return WSError::WS_OK;
|
||||
}
|
||||
vpr_.store(display->GetVirtualPixelRatio());
|
||||
TLOGI(WmsLogTag::WMS_MAIN, "vpr: %{public}f", vpr_.load());
|
||||
return WSError::WS_OK;
|
||||
}
|
||||
|
||||
RSAnimationTimingProtocol PcFoldScreenController::GetMovingTimingProtocol()
|
||||
{
|
||||
return MOVING_TIMING_PROTOCOL;
|
||||
}
|
||||
|
||||
RSAnimationTimingCurve PcFoldScreenController::GetMovingTimingCurve()
|
||||
{
|
||||
return MOVING_CURVE;
|
||||
}
|
||||
|
||||
RSAnimationTimingProtocol PcFoldScreenController::GetThrowSlipTimingProtocol()
|
||||
{
|
||||
return THROW_SLIP_TIMING_PROTOCOL;
|
||||
}
|
||||
|
||||
RSAnimationTimingCurve PcFoldScreenController::GetThrowSlipTimingCurve()
|
||||
{
|
||||
return THROW_SLIP_CURVE;
|
||||
}
|
||||
|
||||
void PcFoldScreenController::RecordStartRect(const WSRect& rect, bool isStartFullScreen)
|
||||
{
|
||||
TLOGI(WmsLogTag::WMS_LAYOUT, "rect: %{public}s, isStartFullScreen: %{public}d",
|
||||
rect.ToString().c_str(), isStartFullScreen);
|
||||
startRect_ = rect;
|
||||
isStartFullScreen_ = isStartFullScreen;
|
||||
}
|
||||
|
||||
bool PcFoldScreenController::IsStartFullScreen() const
|
||||
{
|
||||
return isStartFullScreen_;
|
||||
}
|
||||
|
||||
void PcFoldScreenController::RecordMoveRects(const WSRect& rect)
|
||||
{
|
||||
auto time = std::chrono::high_resolution_clock::now();
|
||||
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) {
|
||||
movingRectRecords_.erase(movingRectRecords_.begin());
|
||||
}
|
||||
TLOGD(WmsLogTag::WMS_LAYOUT, "records size: %{public}d, duration: %{public}d", movingRectRecords_.size(),
|
||||
TimeHelper::GetDuration(movingRectRecords_[0].first, movingRectRecords_[movingRectRecords_.size() - 1].first));
|
||||
}
|
||||
|
||||
bool PcFoldScreenController::ThrowSlip(DisplayId displayId, WSRect& rect,
|
||||
int32_t topAvoidHeight, int32_t botAvoidHeight)
|
||||
{
|
||||
if (!IsHalfFolded() || displayId != displayId_.load()) {
|
||||
ResetArrangeRule();
|
||||
return false;
|
||||
}
|
||||
ResetArrangeRule(CalculateScreenSide(startRect_));
|
||||
WSRect titleRect = { rect.posX_, rect.posY_, rect.width_, GetTitleHeight() };
|
||||
ScreenSide startSide = CalculateScreenSide(titleRect);
|
||||
WSRectF velocity = CalculateMovingVelocity();
|
||||
if (!NeedDoThrowSlip(startSide, velocity)) {
|
||||
ResetArrangeRule(startSide);
|
||||
TLOGI(WmsLogTag::WMS_LAYOUT, "no throw rect: %{public}s", rect.ToString().c_str());
|
||||
return false;
|
||||
}
|
||||
|
||||
ThrowSlipToOppositeSide(startSide, rect, topAvoidHeight, botAvoidHeight);
|
||||
ResetArrangeRule(startSide);
|
||||
TLOGI(WmsLogTag::WMS_LAYOUT, "throw to rect: %{public}s", rect.ToString().c_str());
|
||||
return true;
|
||||
}
|
||||
|
||||
int32_t PcFoldScreenController::GetPersistentId() const
|
||||
{
|
||||
auto sceneSession = weakSceneSession_.promote();
|
||||
if (sceneSession == nullptr) {
|
||||
return INVALID_SESSION_ID;
|
||||
}
|
||||
return sceneSession->GetPersistentId();
|
||||
}
|
||||
|
||||
/*
|
||||
* get height of title bar
|
||||
* @return: vp
|
||||
*/
|
||||
int32_t PcFoldScreenController::GetTitleHeight() const
|
||||
{
|
||||
auto sceneSession = weakSceneSession_.promote();
|
||||
if (sceneSession == nullptr) {
|
||||
return MIN_DECOR_HEIGHT;
|
||||
}
|
||||
return std::clamp(sceneSession->GetCustomDecorHeight(), MIN_DECOR_HEIGHT, MAX_DECOR_HEIGHT);
|
||||
}
|
||||
|
||||
WSRectF PcFoldScreenController::CalculateMovingVelocity()
|
||||
{
|
||||
WSRectF velocity = { 0.0f, 0.0f, 0.0f, 0.0f };
|
||||
int32_t recordsSize = movingRectRecords_.size();
|
||||
if (recordsSize <= 1) {
|
||||
return velocity;
|
||||
}
|
||||
|
||||
if (recordsSize >= 2) { // temp use 2 points
|
||||
auto rect0 = movingRectRecords_[0].second;
|
||||
auto rect1 = movingRectRecords_[recordsSize - 1].second;
|
||||
int32_t duration = TimeHelper::GetDuration(movingRectRecords_[0].first,
|
||||
movingRectRecords_[recordsSize - 1].first);
|
||||
if (duration <= 1) {
|
||||
return velocity;
|
||||
}
|
||||
velocity.posX_ = static_cast<float>((rect1.posX_ - rect0.posX_) / static_cast<float>(duration));
|
||||
velocity.posY_ = static_cast<float>((rect1.posY_ - rect0.posY_) / static_cast<float>(duration));
|
||||
velocity.width_ = static_cast<float>((rect1.width_ - rect0.width_) / static_cast<float>(duration));
|
||||
velocity.height_ = static_cast<float>((rect1.height_ - rect0.height_) / static_cast<float>(duration));
|
||||
return velocity;
|
||||
}
|
||||
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
|
@ -52,6 +52,7 @@
|
||||
#include "screen.h"
|
||||
#include "fold_screen_state_internel.h"
|
||||
#include "session/host/include/multi_instance_manager.h"
|
||||
#include "session/host/include/pc_fold_screen_controller.h"
|
||||
|
||||
#ifdef POWER_MANAGER_ENABLE
|
||||
#include <power_mgr_client.h>
|
||||
@ -523,6 +524,10 @@ WSError SceneSession::OnSessionEvent(SessionEvent event)
|
||||
HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "SceneSession::StartMove");
|
||||
session->InitializeCrossMoveDrag();
|
||||
session->moveDragController_->InitMoveDragProperty();
|
||||
if (session->pcFoldScreenController_) {
|
||||
session->pcFoldScreenController_->RecordStartRect(session->GetSessionRect(),
|
||||
session->IsFullScreenMovable());
|
||||
}
|
||||
if (session->IsFullScreenMovable()) {
|
||||
WSRect rect = session->moveDragController_->GetFullScreenToFloatingRect(session->winRect_,
|
||||
session->GetSessionRequestRect());
|
||||
@ -550,6 +555,30 @@ WSError SceneSession::OnSessionEvent(SessionEvent event)
|
||||
return WSError::WS_OK;
|
||||
}
|
||||
|
||||
WSError SceneSession::OnSessionEvent(SessionEvent event, SessionEventParam param)
|
||||
{
|
||||
const char* const where = __func__;
|
||||
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;
|
||||
}
|
||||
if (!(session->sessionChangeCallback_ && session->sessionChangeCallback_->OnSessionEvent_)) {
|
||||
TLOGNE(WmsLogTag::WMS_MAIN, "%{public}s invalid callback", where);
|
||||
return WSError::WS_DO_NOTHING;
|
||||
}
|
||||
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;
|
||||
}
|
||||
|
||||
WSError SceneSession::SyncSessionEvent(SessionEvent event)
|
||||
{
|
||||
if (event != SessionEvent::EVENT_START_MOVE) {
|
||||
@ -2464,7 +2493,19 @@ void SceneSession::HandleMoveDragSurfaceBounds(WSRect& rect, WSRect& globalRect,
|
||||
bool isGlobal, bool needFlush)
|
||||
{
|
||||
const char* const funcName = __func__;
|
||||
SetSurfaceBounds(globalRect, isGlobal, needFlush);
|
||||
if (pcFoldScreenController_ && pcFoldScreenController_->IsHalfFolded()) {
|
||||
SetSurfaceBoundsWithAnimation(
|
||||
std::make_pair(
|
||||
pcFoldScreenController_->GetMovingTimingProtocol(),
|
||||
pcFoldScreenController_->GetMovingTimingCurve()
|
||||
),
|
||||
globalRect, nullptr, isGlobal, needFlush);
|
||||
if (reason == SizeChangeReason::MOVE) {
|
||||
pcFoldScreenController_->RecordMoveRects(rect);
|
||||
}
|
||||
} else {
|
||||
SetSurfaceBounds(globalRect, isGlobal, needFlush);
|
||||
}
|
||||
UpdateSizeChangeReason(reason);
|
||||
if (reason != SizeChangeReason::MOVE) {
|
||||
UpdateRectForDrag(rect);
|
||||
@ -2503,16 +2544,58 @@ void SceneSession::HandleMoveDragEnd(WSRect& rect, SizeChangeReason reason)
|
||||
TLOGI(WmsLogTag::WMS_KEYBOARD, "Calling session is moved and reset oriPosYBeforeRaisedByKeyboard");
|
||||
SetOriPosYBeforeRaisedByKeyboard(0);
|
||||
}
|
||||
if (moveDragController_->GetMoveDragEndDisplayId() == moveDragController_->GetMoveDragStartDisplayId() ||
|
||||
WindowHelper::IsSystemWindow(GetWindowType())) {
|
||||
NotifySessionRectChange(rect, reason);
|
||||
} else {
|
||||
NotifySessionRectChange(rect, reason, moveDragController_->GetMoveDragEndDisplayId());
|
||||
if (!MoveUnderInteriaAndNotifyRectChange(rect, reason)) {
|
||||
if (moveDragController_->GetMoveDragEndDisplayId() == moveDragController_->GetMoveDragStartDisplayId() ||
|
||||
WindowHelper::IsSystemWindow(GetWindowType())) {
|
||||
NotifySessionRectChange(rect, reason);
|
||||
} else {
|
||||
NotifySessionRectChange(rect, reason, moveDragController_->GetMoveDragEndDisplayId());
|
||||
}
|
||||
}
|
||||
moveDragController_->ResetCrossMoveDragProperty();
|
||||
OnSessionEvent(SessionEvent::EVENT_END_MOVE);
|
||||
}
|
||||
|
||||
/*
|
||||
* move with init velocity
|
||||
* @return true: rect change notified when move
|
||||
*/
|
||||
bool SceneSession::MoveUnderInteriaAndNotifyRectChange(WSRect& rect, SizeChangeReason reason)
|
||||
{
|
||||
if (pcFoldScreenController_ == nullptr) {
|
||||
return false;
|
||||
}
|
||||
bool ret = pcFoldScreenController_->ThrowSlip(GetScreenId(), rect, GetStatusBarHeight(), GetDockHeight());
|
||||
if (!ret) {
|
||||
TLOGD(WmsLogTag::WMS_LAYOUT, "no throw slip");
|
||||
return false;
|
||||
}
|
||||
|
||||
WSRect endRect = rect;
|
||||
std::function<void()> finishCallback = nullptr;
|
||||
bool needSetFullScreen = pcFoldScreenController_->IsStartFullScreen();
|
||||
if (needSetFullScreen) {
|
||||
// maximize end rect and notify last 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");
|
||||
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));
|
||||
return needSetFullScreen;
|
||||
}
|
||||
|
||||
void SceneSession::OnMoveDragCallback(SizeChangeReason reason)
|
||||
{
|
||||
if (!moveDragController_) {
|
||||
@ -2640,6 +2723,22 @@ void SceneSession::UpdateWinRectForSystemBar(WSRect& rect)
|
||||
rect.posX_, rect.posY_, rect.width_, rect.height_);
|
||||
}
|
||||
|
||||
void SceneSession::SetSurfaceBoundsWithAnimation(
|
||||
std::pair<RSAnimationTimingProtocol, RSAnimationTimingCurve> animationParam,
|
||||
const WSRect& rect, std::function<void()>&& finishCallback, bool isGlobal, bool needFlush)
|
||||
{
|
||||
auto weakThis = wptr(this);
|
||||
auto interiaFunc = [weakThis, rect, isGlobal, needFlush]() {
|
||||
auto session = weakThis.promote();
|
||||
if (session == nullptr) {
|
||||
TLOGW(WmsLogTag::WMS_EVENT, "session is nullptr");
|
||||
return;
|
||||
}
|
||||
session->SetSurfaceBounds(rect, isGlobal, needFlush);
|
||||
};
|
||||
RSNode::Animate(animationParam.first, animationParam.second, interiaFunc, std::move(finishCallback));
|
||||
}
|
||||
|
||||
void SceneSession::SetSurfaceBounds(const WSRect& rect, bool isGlobal, bool needFlush)
|
||||
{
|
||||
TLOGD(WmsLogTag::WMS_LAYOUT, "rect: %{public}s isGlobal: %{public}d needFlush: %{public}d",
|
||||
@ -5072,6 +5171,25 @@ int32_t SceneSession::GetStatusBarHeight()
|
||||
return height;
|
||||
}
|
||||
|
||||
int32_t SceneSession::GetDockHeight()
|
||||
{
|
||||
int32_t height = 0;
|
||||
if (specificCallback_ == nullptr || specificCallback_->onGetSceneSessionVectorByType_ == nullptr ||
|
||||
GetSessionProperty() == nullptr) {
|
||||
TLOGE(WmsLogTag::WMS_LAYOUT, "specificCallback_ or session property is null");
|
||||
return height;
|
||||
}
|
||||
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_;
|
||||
}
|
||||
}
|
||||
return height;
|
||||
}
|
||||
|
||||
bool SceneSession::CheckPermissionWithPropertyAnimation(const sptr<WindowSessionProperty>& property) const
|
||||
{
|
||||
if (property && property->GetAnimationFlag() == static_cast<uint32_t>(WindowAnimation::CUSTOM)) {
|
||||
|
@ -291,6 +291,11 @@ void Session::SetSessionInfo(const SessionInfo& info)
|
||||
sessionInfo_.processOptions = info.processOptions;
|
||||
}
|
||||
|
||||
DisplayId Session::GetScreenId() const
|
||||
{
|
||||
return sessionInfo_.screenId_;
|
||||
}
|
||||
|
||||
void Session::SetScreenId(uint64_t screenId)
|
||||
{
|
||||
sessionInfo_.screenId_ = screenId;
|
||||
|
Loading…
Reference in New Issue
Block a user