mirror of
https://github.com/openharmony/windowmanager.git
synced 2026-07-19 17:08:11 -04:00
分屏重构
Signed-off-by: xingyanan <xingyanan2@huawei.com> Change-Id: Ia5446fb6134c98c8dcab9a7b29108b9bd062554d Signed-off-by: xingyanan <xingyanan2@huawei.com>
This commit is contained in:
@@ -67,6 +67,7 @@ ohos_shared_library("libwms") {
|
||||
"src/window_manager_stub.cpp",
|
||||
"src/window_node.cpp",
|
||||
"src/window_node_container.cpp",
|
||||
"src/window_pair.cpp",
|
||||
"src/window_root.cpp",
|
||||
"src/window_snapshot/snapshot_controller.cpp",
|
||||
"src/window_snapshot/snapshot_proxy.cpp",
|
||||
|
||||
@@ -40,6 +40,7 @@ public:
|
||||
void AddWindowNode(sptr<WindowNode>& node) override;
|
||||
void UpdateWindowNode(sptr<WindowNode>& node, bool isAddWindow = false) override;
|
||||
void UpdateLayoutRect(sptr<WindowNode>& node) override;
|
||||
void RemoveWindowNode(sptr<WindowNode>& node) override;
|
||||
|
||||
private:
|
||||
// Rects for split screen
|
||||
|
||||
@@ -24,6 +24,7 @@
|
||||
#include "window_zorder_policy.h"
|
||||
#include "wm_common.h"
|
||||
#include "wm_common_inner.h"
|
||||
#include "window_pair.h"
|
||||
|
||||
namespace OHOS {
|
||||
namespace Rosen {
|
||||
@@ -70,9 +71,8 @@ public:
|
||||
void NotifySystemBarDismiss(sptr<WindowNode>& node);
|
||||
WMError MinimizeAppNodeExceptOptions(bool fromUser, const std::vector<uint32_t> &exceptionalIds = {},
|
||||
const std::vector<WindowMode> &exceptionalModes = {});
|
||||
WMError EnterSplitWindowMode(sptr<WindowNode>& node);
|
||||
WMError ExitSplitWindowMode(sptr<WindowNode>& node);
|
||||
WMError SwitchLayoutPolicy(WindowLayoutMode mode, bool reorder = false);
|
||||
WMError SetWindowMode(sptr<WindowNode>& node, WindowMode dstMode);
|
||||
void RaiseSplitRelatedWindowToTop(sptr<WindowNode>& node);
|
||||
void MoveWindowNode(sptr<WindowNodeContainer>& container);
|
||||
float GetVirtualPixelRatio() const;
|
||||
@@ -90,9 +90,6 @@ private:
|
||||
void UpdateWindowTree(sptr<WindowNode>& node);
|
||||
bool UpdateRSTree(sptr<WindowNode>& node, bool isAdd);
|
||||
|
||||
void SendSplitScreenEvent(sptr<WindowNode>& node);
|
||||
sptr<WindowNode> FindSplitPairNode(sptr<WindowNode>& node) const;
|
||||
WMError UpdateWindowPairInfo(sptr<WindowNode>& triggerNode, sptr<WindowNode>& pairNode);
|
||||
void NotifyIfSystemBarTintChanged();
|
||||
void NotifyIfSystemBarRegionChanged();
|
||||
void TraverseAndUpdateWindowState(WindowState state, int32_t topPriority);
|
||||
@@ -111,7 +108,8 @@ private:
|
||||
void RcoveryScreenDefaultOrientationIfNeed();
|
||||
// cannot determine in case of a window covered by union of several windows or with transparent value
|
||||
void UpdateWindowVisibilityInfos(std::vector<sptr<WindowVisibilityInfo>>& infos);
|
||||
void RaiseOrderedWindowToTop(std::vector<uint32_t> orderedIds, std::vector<sptr<WindowNode>>& windowNodes);
|
||||
void RaiseOrderedWindowToTop(std::vector<sptr<WindowNode>>& orderedNodes,
|
||||
std::vector<sptr<WindowNode>>& windowNodes);
|
||||
static bool ReadIsWindowAnimationEnabledProperty();
|
||||
|
||||
sptr<AvoidAreaController> avoidController_;
|
||||
@@ -140,12 +138,7 @@ private:
|
||||
float displayBrightness_ = UNDEFINED_BRIGHTNESS; // UNDEFINED_BRIGHTNESS means system default brightness
|
||||
uint32_t brightnessWindow_ = INVALID_WINDOW_ID;
|
||||
void DumpScreenWindowTree();
|
||||
|
||||
struct WindowPairInfo {
|
||||
sptr<WindowNode> pairNode_;
|
||||
float splitRatio_;
|
||||
};
|
||||
std::unordered_map<uint32_t, WindowPairInfo> pairedWindowMap_;
|
||||
sptr<WindowPair> windowPair_;
|
||||
void RaiseInputMethodWindowPriorityIfNeeded(const sptr<WindowNode>& node) const;
|
||||
void RaiseShowWhenLockedWindowIfNeeded(const sptr<WindowNode>& node);
|
||||
void ReZOrderShowWhenLockedWindows(const sptr<WindowNode>& node, bool up);
|
||||
|
||||
@@ -0,0 +1,237 @@
|
||||
/*
|
||||
* Copyright (c) 2022 Huawei Device Co., Ltd.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef OHOS_ROSEN_WINDOW_PAIR_H
|
||||
#define OHOS_ROSEN_WINDOW_PAIR_H
|
||||
|
||||
#include <refbase.h>
|
||||
#include "window_inner_manager.h"
|
||||
#include "window_node.h"
|
||||
#include "wm_common_inner.h"
|
||||
#include "wm_common.h"
|
||||
|
||||
namespace OHOS {
|
||||
namespace Rosen {
|
||||
/**
|
||||
* Enumerates the status of window pair.
|
||||
*/
|
||||
enum class WindowPairStatus : uint32_t {
|
||||
STATUS_EMPTY,
|
||||
STATUS_SINGLE_PRIMARY,
|
||||
STATUS_SINGLE_SECONDARY,
|
||||
STATUS_PAIRING,
|
||||
STATUS_PAIRED_DONE
|
||||
};
|
||||
|
||||
/**
|
||||
* Enumerates the message of split event.
|
||||
*/
|
||||
enum class SplitBroadcastMsg : uint32_t {
|
||||
MSG_NONE,
|
||||
MSG_START_PRIMARY,
|
||||
MSG_START_SECONDARY,
|
||||
MSG_START_DIVIDER
|
||||
};
|
||||
|
||||
class WindowPair : public RefBase {
|
||||
public:
|
||||
/**
|
||||
* Constructor used to create an empty WindowPair instance.
|
||||
*
|
||||
* @param displayId the disply of window pair
|
||||
* @param appNode the window root of app window
|
||||
*/
|
||||
WindowPair(const DisplayId& displayId, sptr<WindowNode>& appNode);
|
||||
|
||||
/**
|
||||
* Deconstructor used to deconstruct.
|
||||
*
|
||||
*/
|
||||
~WindowPair();
|
||||
|
||||
/**
|
||||
* Clear window pair.
|
||||
*
|
||||
*/
|
||||
void Clear();
|
||||
|
||||
/**
|
||||
* Set split ratio.
|
||||
*
|
||||
* @param ratio split ratio
|
||||
*/
|
||||
void SetSplitRatio(float ratio);
|
||||
|
||||
/**
|
||||
* Get split ratio.
|
||||
*
|
||||
* @return split ratio
|
||||
*/
|
||||
float GetSplitRatio() const;
|
||||
|
||||
/**
|
||||
* Get whether the window pair is paired..
|
||||
*
|
||||
* @return the pair state of window pair
|
||||
*/
|
||||
bool IsPaired() const;
|
||||
|
||||
/**
|
||||
* Handle changes in the state of the window pair
|
||||
*
|
||||
* @param node trigger window node
|
||||
*/
|
||||
void UpdateIfSplitRelated(sptr<WindowNode>& node);
|
||||
|
||||
/**
|
||||
* Handle remove window from pair.
|
||||
*
|
||||
* @param node target node
|
||||
*/
|
||||
void HandleRemoveWindow(sptr<WindowNode>& node);
|
||||
|
||||
/**
|
||||
* Find window node from window pair.
|
||||
*
|
||||
* @param node target window node
|
||||
* @return window node
|
||||
*/
|
||||
sptr<WindowNode> Find(sptr<WindowNode>& node);
|
||||
|
||||
/**
|
||||
* Get primary window node.
|
||||
*
|
||||
* @return primary window node
|
||||
*/
|
||||
sptr<WindowNode> GetPrimaryWindow() const;
|
||||
|
||||
/**
|
||||
* Get secondary window node.
|
||||
*
|
||||
* @return secondary window node
|
||||
*/
|
||||
sptr<WindowNode> GetSecondaryWindow() const;
|
||||
|
||||
/**
|
||||
* Get divider window node.
|
||||
*
|
||||
* @return divider window node
|
||||
*/
|
||||
sptr<WindowNode> GetDividerWindow() const;
|
||||
|
||||
/**
|
||||
* Get pair status.
|
||||
*
|
||||
* @return the pair status of window pair
|
||||
*/
|
||||
WindowPairStatus GetPairStatus() const;
|
||||
|
||||
/**
|
||||
* Get all window node form pair in Z order.
|
||||
*
|
||||
* @return the list window form pair
|
||||
*/
|
||||
std::vector<sptr<WindowNode>> GetOrderedPair(sptr<WindowNode>& node);
|
||||
|
||||
/**
|
||||
* Get all window node form pair.
|
||||
*
|
||||
* @return the list window form pair
|
||||
*/
|
||||
std::vector<sptr<WindowNode>> GetPairedWindows();
|
||||
|
||||
private:
|
||||
/**
|
||||
* Gets whether the window is related to split window.
|
||||
*
|
||||
* @param node target node
|
||||
* @return Whether target node is related to the split window
|
||||
*/
|
||||
bool IsSplitRelated(sptr<WindowNode>& node) const;
|
||||
|
||||
/**
|
||||
* Replace paired window.
|
||||
*
|
||||
* @param node current node
|
||||
*/
|
||||
void Insert(sptr<WindowNode>& node);
|
||||
|
||||
/**
|
||||
* Update paired window node
|
||||
*
|
||||
*/
|
||||
void HandlePairedNodesChange();
|
||||
|
||||
/**
|
||||
* Update pair status
|
||||
*
|
||||
*/
|
||||
void UpdateWindowPairStatus();
|
||||
|
||||
/**
|
||||
* Switch the position of two paired window.
|
||||
*
|
||||
*/
|
||||
void SwitchPosition();
|
||||
|
||||
/**
|
||||
* Dump the info of pair.
|
||||
*
|
||||
*/
|
||||
void DumpPairInfo();
|
||||
|
||||
/**
|
||||
* Send inner window message.
|
||||
*
|
||||
* @param cmd the message of inner window manager
|
||||
* @param displayId the id of target display
|
||||
*/
|
||||
void SendInnerMessage(InnerWMCmd cmd, DisplayId displayId);
|
||||
|
||||
/**
|
||||
* Find pairable window frome window trees.
|
||||
*
|
||||
* @param node the node waiting to be paired
|
||||
* @return window node
|
||||
*/
|
||||
sptr<WindowNode> FindPairableWindow(sptr<WindowNode>& node);
|
||||
|
||||
/**
|
||||
* Get pairable node from trees or send split broadcast.
|
||||
*
|
||||
* @param node the node waiting to be paired
|
||||
* @return pairable node
|
||||
*/
|
||||
sptr<WindowNode> GetPairableWindow(sptr<WindowNode>& node);
|
||||
|
||||
/**
|
||||
* Send brodcast message of split event.
|
||||
*
|
||||
* @param node trigger node
|
||||
*/
|
||||
void SendBroadcastMsg(sptr<WindowNode>& node);
|
||||
|
||||
private:
|
||||
float ratio_ = DEFAULT_SPLIT_RATIO;
|
||||
DisplayId displayId_;
|
||||
sptr<WindowNode> appWindowNode_;
|
||||
sptr<WindowNode> primary_;
|
||||
sptr<WindowNode> secondary_;
|
||||
sptr<WindowNode> divider_;
|
||||
WindowPairStatus status_ = {WindowPairStatus::STATUS_EMPTY};
|
||||
};
|
||||
} // namespace Rosen
|
||||
} // namespace OHOS
|
||||
#endif // OHOS_ROSEN_WINDOW_PAIR_H
|
||||
@@ -51,8 +51,7 @@ public:
|
||||
WMError RequestActiveWindow(uint32_t windowId);
|
||||
WMError MinimizeStructuredAppWindowsExceptSelf(sptr<WindowNode>& node);
|
||||
std::vector<Rect> GetAvoidAreaByType(uint32_t windowId, AvoidAreaType avoidAreaType);
|
||||
WMError EnterSplitWindowMode(sptr<WindowNode>& node);
|
||||
WMError ExitSplitWindowMode(sptr<WindowNode>& node);
|
||||
WMError SetWindowMode(sptr<WindowNode>& node, WindowMode dstMode);
|
||||
std::shared_ptr<RSSurfaceNode> GetSurfaceNodeByAbilityToken(const sptr<IRemoteObject>& abilityToken) const;
|
||||
WMError GetTopWindowId(uint32_t mainWinId, uint32_t& topWinId);
|
||||
void MinimizeAllAppWindows(DisplayId displayId);
|
||||
|
||||
@@ -219,47 +219,10 @@ WMError WindowController::SetWindowMode(uint32_t windowId, WindowMode dstMode)
|
||||
WLOGFE("could not find window");
|
||||
return WMError::WM_ERROR_NULLPTR;
|
||||
}
|
||||
WindowMode srcMode = node->GetWindowMode();
|
||||
if (srcMode == dstMode) {
|
||||
return WMError::WM_OK;
|
||||
WMError ret = windowRoot_->SetWindowMode(node, dstMode);
|
||||
if (ret != WMError::WM_OK) {
|
||||
return ret;
|
||||
}
|
||||
WMError res = WMError::WM_OK;
|
||||
if ((srcMode == WindowMode::WINDOW_MODE_FULLSCREEN) && (dstMode == WindowMode::WINDOW_MODE_FLOATING)) {
|
||||
node->SetWindowSizeChangeReason(WindowSizeChangeReason::RECOVER);
|
||||
} else if (dstMode == WindowMode::WINDOW_MODE_FULLSCREEN) {
|
||||
node->SetWindowSizeChangeReason(WindowSizeChangeReason::MAXIMIZE);
|
||||
} else {
|
||||
node->SetWindowSizeChangeReason(WindowSizeChangeReason::RESIZE);
|
||||
}
|
||||
if (WindowHelper::IsSplitWindowMode(srcMode)) {
|
||||
// change split mode to other
|
||||
res = windowRoot_->ExitSplitWindowMode(node);
|
||||
node->SetWindowMode(dstMode);
|
||||
} else if (!WindowHelper::IsSplitWindowMode(srcMode) && WindowHelper::IsSplitWindowMode(dstMode)) {
|
||||
// change other mode to split
|
||||
node->SetWindowMode(dstMode);
|
||||
res = windowRoot_->EnterSplitWindowMode(node);
|
||||
} else {
|
||||
node->SetWindowMode(dstMode);
|
||||
}
|
||||
if (res != WMError::WM_OK) {
|
||||
node->GetWindowProperty()->ResumeLastWindowMode();
|
||||
return res;
|
||||
}
|
||||
if (node->GetWindowMode() == WindowMode::WINDOW_MODE_FULLSCREEN &&
|
||||
WindowHelper::IsAppWindow(node->GetWindowType())) {
|
||||
// minimize other app window
|
||||
res = windowRoot_->MinimizeStructuredAppWindowsExceptSelf(node);
|
||||
if (res != WMError::WM_OK) {
|
||||
return res;
|
||||
}
|
||||
}
|
||||
res = windowRoot_->UpdateWindowNode(windowId, WindowUpdateReason::UPDATE_MODE);
|
||||
if (res != WMError::WM_OK) {
|
||||
WLOGFE("Set window mode failed, update node failed");
|
||||
return res;
|
||||
}
|
||||
node->GetWindowToken()->UpdateWindowMode(node->GetWindowMode());
|
||||
FlushWindowInfo(windowId);
|
||||
return WMError::WM_OK;
|
||||
}
|
||||
|
||||
@@ -87,6 +87,21 @@ void WindowLayoutPolicyCascade::LayoutWindowTree()
|
||||
WindowLayoutPolicy::LayoutWindowTree();
|
||||
}
|
||||
|
||||
void WindowLayoutPolicyCascade::RemoveWindowNode(sptr<WindowNode>& node)
|
||||
{
|
||||
WM_FUNCTION_TRACE();
|
||||
auto type = node->GetWindowType();
|
||||
// affect other windows, trigger off global layout
|
||||
if (avoidTypes_.find(type) != avoidTypes_.end()) {
|
||||
LayoutWindowTree();
|
||||
} else if (type == WindowType::WINDOW_TYPE_DOCK_SLICE) { // split screen mode
|
||||
InitSplitRects();
|
||||
LayoutWindowTree();
|
||||
}
|
||||
Rect reqRect = node->GetRequestRect();
|
||||
node->GetWindowToken()->UpdateWindowRect(reqRect, node->GetDecoStatus(), WindowSizeChangeReason::HIDE);
|
||||
}
|
||||
|
||||
void WindowLayoutPolicyCascade::UpdateWindowNode(sptr<WindowNode>& node, bool isAddWindow)
|
||||
{
|
||||
WM_FUNCTION_TRACE();
|
||||
@@ -109,6 +124,8 @@ void WindowLayoutPolicyCascade::UpdateWindowNode(sptr<WindowNode>& node, bool is
|
||||
}
|
||||
}
|
||||
LayoutWindowTree();
|
||||
} else if (node->IsSplitMode()) {
|
||||
LayoutWindowTree();
|
||||
} else { // layout single window
|
||||
LayoutWindowNode(node);
|
||||
}
|
||||
@@ -159,7 +176,7 @@ void WindowLayoutPolicyCascade::LimitMoveBounds(Rect& rect) const
|
||||
void WindowLayoutPolicyCascade::InitCascadeRect()
|
||||
{
|
||||
constexpr uint32_t half = 2;
|
||||
constexpr float ratio = 0.75; // 0.75: default height/width ratio
|
||||
constexpr float ratio = 0.66; // 0.66: default height/width ratio
|
||||
|
||||
// calculate default H and w
|
||||
uint32_t defaultW = static_cast<uint32_t>(displayRect_.width_ * ratio);
|
||||
|
||||
@@ -272,4 +272,4 @@ void WindowLayoutPolicyTile::UpdateLayoutRect(sptr<WindowNode>& node)
|
||||
}
|
||||
}
|
||||
} // Rosen
|
||||
} // OHOS
|
||||
} // OHOS
|
||||
|
||||
@@ -53,6 +53,7 @@ WindowNodeContainer::WindowNodeContainer(DisplayId displayId, uint32_t width, ui
|
||||
.width_ = width,
|
||||
.height_ = height
|
||||
};
|
||||
windowPair_ = new WindowPair(displayId_, appWindowNode_);
|
||||
layoutPolicys_[WindowLayoutMode::CASCADE] =
|
||||
new WindowLayoutPolicyCascade(displayRect_, displayId_,
|
||||
belowAppWindowNode_, appWindowNode_, aboveAppWindowNode_);
|
||||
@@ -118,14 +119,7 @@ WMError WindowNodeContainer::AddWindowNode(sptr<WindowNode>& node, sptr<WindowNo
|
||||
}
|
||||
}
|
||||
node->parent_ = parentNode;
|
||||
|
||||
if (node->IsSplitMode()) {
|
||||
WMError ret = EnterSplitWindowMode(node);
|
||||
if (ret != WMError::WM_OK) {
|
||||
WLOGFE("Add split window failed!");
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
windowPair_->UpdateIfSplitRelated(node);
|
||||
UpdateWindowTree(node);
|
||||
if (node->IsSplitMode() || node->GetWindowType() == WindowType::WINDOW_TYPE_DOCK_SLICE) {
|
||||
RaiseSplitRelatedWindowToTop(node);
|
||||
@@ -295,17 +289,9 @@ WMError WindowNodeContainer::RemoveWindowNode(sptr<WindowNode>& node)
|
||||
child->GetCallingUid(), false));
|
||||
}
|
||||
}
|
||||
|
||||
if (node->IsSplitMode()) {
|
||||
WMError ret = ExitSplitWindowMode(node);
|
||||
if (ret != WMError::WM_OK) {
|
||||
WLOGFE("Remove split window failed!");
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
UpdateRSTree(node, false);
|
||||
layoutPolicy_->RemoveWindowNode(node);
|
||||
windowPair_->HandleRemoveWindow(node);
|
||||
if (WindowHelper::IsAvoidAreaWindow(node->GetWindowType())) {
|
||||
avoidController_->AvoidControl(node, AvoidControlType::AVOID_NODE_REMOVE);
|
||||
NotifyIfSystemBarRegionChanged();
|
||||
@@ -706,23 +692,22 @@ bool WindowNodeContainer::IsTopWindow(uint32_t windowId, sptr<WindowNode>& rootN
|
||||
return node->GetWindowId() == windowId;
|
||||
}
|
||||
|
||||
void WindowNodeContainer::RaiseOrderedWindowToTop(std::vector<uint32_t> orderedIds,
|
||||
void WindowNodeContainer::RaiseOrderedWindowToTop(std::vector<sptr<WindowNode>>& orderedNodes,
|
||||
std::vector<sptr<WindowNode>>& windowNodes)
|
||||
{
|
||||
for (auto iter = appWindowNode_->children_.begin(); iter != appWindowNode_->children_.end();) {
|
||||
uint32_t wid = (*iter)->GetWindowId();
|
||||
auto idIter = std::find_if(orderedIds.begin(), orderedIds.end(),
|
||||
[wid] (uint32_t id) { return id == wid; });
|
||||
if (idIter != orderedIds.end()) {
|
||||
orderedIds.erase(idIter);
|
||||
sptr<WindowNode> node = *iter;
|
||||
auto orderedIter = std::find_if(orderedNodes.begin(), orderedNodes.end(),
|
||||
[wid] (sptr<WindowNode> orderedNode) { return orderedNode->GetWindowId() == wid; });
|
||||
if (orderedIter != orderedNodes.end()) {
|
||||
iter = windowNodes.erase(iter);
|
||||
UpdateWindowTree(node);
|
||||
WLOGFI("raise group window to top %{public}u", node->GetWindowId());
|
||||
} else {
|
||||
iter++;
|
||||
}
|
||||
}
|
||||
for (auto iter = orderedNodes.begin(); iter != orderedNodes.end(); iter++) {
|
||||
UpdateWindowTree(*iter);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -956,36 +941,8 @@ void WindowNodeContainer::RaiseSplitRelatedWindowToTop(sptr<WindowNode>& node)
|
||||
if (node == nullptr) {
|
||||
return;
|
||||
}
|
||||
if (!node->IsSplitMode() && node->GetWindowType() != WindowType::WINDOW_TYPE_DOCK_SLICE) {
|
||||
return;
|
||||
}
|
||||
if (node->GetWindowType() == WindowType::WINDOW_TYPE_DOCK_SLICE && !pairedWindowMap_.empty()) {
|
||||
std::vector<uint32_t> raiseNodeIds;
|
||||
for (auto& splitInfo : pairedWindowMap_) {
|
||||
auto pairNode = splitInfo.second.pairNode_;
|
||||
if (pairNode != nullptr) {
|
||||
raiseNodeIds.push_back(pairNode->GetWindowId());
|
||||
}
|
||||
}
|
||||
// raise primary and secondary window to top, keep raw zorder
|
||||
RaiseOrderedWindowToTop(raiseNodeIds, appWindowNode_->children_);
|
||||
// raise divider final, keep divider on top
|
||||
RaiseWindowToTop(node->GetWindowId(), appWindowNode_->children_);
|
||||
} else if (!pairedWindowMap_.empty()) {
|
||||
if (pairedWindowMap_.count(node->GetWindowId())) {
|
||||
auto pairNode = pairedWindowMap_.at(node->GetWindowId()).pairNode_;
|
||||
RaiseWindowToTop(pairNode->GetWindowId(), appWindowNode_->children_);
|
||||
}
|
||||
RaiseWindowToTop(node->GetWindowId(), appWindowNode_->children_);
|
||||
sptr<WindowNode> deviderNode = FindDividerNode();
|
||||
if (deviderNode != nullptr) {
|
||||
// raise divider final, keep divider on top
|
||||
RaiseWindowToTop(deviderNode->GetWindowId(), appWindowNode_->children_);
|
||||
}
|
||||
} else {
|
||||
// raise self if not paired
|
||||
RaiseWindowToTop(node->GetWindowId(), appWindowNode_->children_);
|
||||
}
|
||||
std::vector<sptr<WindowNode>> orderedPair = windowPair_->GetOrderedPair(node);
|
||||
RaiseOrderedWindowToTop(orderedPair, appWindowNode_->children_);
|
||||
AssignZOrder();
|
||||
return;
|
||||
}
|
||||
@@ -1100,46 +1057,6 @@ void WindowNodeContainer::MinimizeAllAppWindows()
|
||||
return;
|
||||
}
|
||||
|
||||
void WindowNodeContainer::SendSplitScreenEvent(sptr<WindowNode>& node)
|
||||
{
|
||||
// reset ipc identity
|
||||
std::string identity = IPCSkeleton::ResetCallingIdentity();
|
||||
AAFwk::Want want;
|
||||
want.SetAction(SPLIT_SCREEN_EVENT_NAME);
|
||||
std::string modeData = (node->GetWindowMode() == WindowMode::WINDOW_MODE_SPLIT_PRIMARY) ? "Secondary" : "Primary";
|
||||
int32_t missionId = -1;
|
||||
AAFwk::AbilityManagerClient::GetInstance()->GetMissionIdByToken(node->abilityToken_, missionId);
|
||||
WLOGFI("split window missionId is: %{public}d", missionId);
|
||||
want.SetParam("windowMode", modeData);
|
||||
want.SetParam("missionId", missionId);
|
||||
EventFwk::CommonEventData commonEventData;
|
||||
commonEventData.SetWant(want);
|
||||
EventFwk::CommonEventManager::PublishCommonEvent(commonEventData);
|
||||
// set ipc identity to raw
|
||||
IPCSkeleton::SetCallingIdentity(identity);
|
||||
WLOGFI("send split sceen event finish.");
|
||||
}
|
||||
|
||||
sptr<WindowNode> WindowNodeContainer::FindSplitPairNode(sptr<WindowNode>& triggerNode) const
|
||||
{
|
||||
auto triggerMode = triggerNode->GetWindowMode();
|
||||
for (auto iter = appWindowNode_->children_.rbegin(); iter != appWindowNode_->children_.rend(); iter++) {
|
||||
if ((*iter)->GetWindowId() == triggerNode->GetWindowId()) {
|
||||
continue;
|
||||
}
|
||||
// Find Top FullScreen main winodow or top paired split mode app main window
|
||||
if ((*iter)->GetWindowMode() == WindowMode::WINDOW_MODE_FULLSCREEN ||
|
||||
(triggerMode == WindowMode::WINDOW_MODE_SPLIT_PRIMARY &&
|
||||
(*iter)->GetWindowMode() == WindowMode::WINDOW_MODE_SPLIT_SECONDARY) ||
|
||||
(triggerMode == WindowMode::WINDOW_MODE_SPLIT_SECONDARY &&
|
||||
(*iter)->GetWindowMode() == WindowMode::WINDOW_MODE_SPLIT_PRIMARY)) {
|
||||
WLOGFI("Find pair node mode is: %{public}d", static_cast<uint32_t>((*iter)->GetWindowMode()));
|
||||
return *iter;
|
||||
}
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void WindowNodeContainer::MinimizeWindowFromAbility(const sptr<WindowNode>& node, bool fromUser)
|
||||
{
|
||||
if (node->abilityToken_ == nullptr) {
|
||||
@@ -1170,105 +1087,11 @@ WMError WindowNodeContainer::MinimizeAppNodeExceptOptions(bool fromUser, const s
|
||||
return WMError::WM_OK;
|
||||
}
|
||||
|
||||
WMError WindowNodeContainer::EnterSplitWindowMode(sptr<WindowNode>& node)
|
||||
{
|
||||
WM_FUNCTION_TRACE();
|
||||
WLOGFI("Enter split window mode: %{public}u", node->GetWindowId());
|
||||
SwitchLayoutPolicy(WindowLayoutMode::CASCADE); // window split mode is belong to cascade
|
||||
auto pairNode = FindSplitPairNode(node);
|
||||
if (pairNode != nullptr) {
|
||||
WLOGFI("Window %{public}d find pair %{public}u", node->GetWindowId(), pairNode->GetWindowId());
|
||||
WMError ret = UpdateWindowPairInfo(node, pairNode);
|
||||
if (ret != WMError::WM_OK) {
|
||||
return ret;
|
||||
}
|
||||
SingletonContainer::Get<WindowInnerManager>().SendMessage(InnerWMCmd::INNER_WM_CREATE_DIVIDER, displayId_);
|
||||
std::vector<uint32_t> exceptionalIds;
|
||||
for (auto iter = pairedWindowMap_.begin(); iter != pairedWindowMap_.end(); iter++) {
|
||||
exceptionalIds.emplace_back(iter->first);
|
||||
}
|
||||
std::vector<WindowMode> exceptionalModes = { WindowMode::WINDOW_MODE_FLOATING, WindowMode::WINDOW_MODE_PIP };
|
||||
ret = MinimizeAppNodeExceptOptions(false, exceptionalIds, exceptionalModes);
|
||||
if (ret != WMError::WM_OK) {
|
||||
return ret;
|
||||
}
|
||||
} else {
|
||||
SendSplitScreenEvent(node);
|
||||
}
|
||||
return WMError::WM_OK;
|
||||
}
|
||||
|
||||
void WindowNodeContainer::ResetLayoutPolicy()
|
||||
{
|
||||
layoutPolicy_->Reset();
|
||||
}
|
||||
|
||||
WMError WindowNodeContainer::ExitSplitWindowMode(sptr<WindowNode>& node)
|
||||
{
|
||||
WM_FUNCTION_TRACE();
|
||||
WLOGFI("exit split window mode %{public}u", node->GetWindowId());
|
||||
node->GetWindowProperty()->ResumeLastWindowMode();
|
||||
node->GetWindowToken()->UpdateWindowMode(node->GetWindowMode());
|
||||
if (pairedWindowMap_.count(node->GetWindowId()) != 0) {
|
||||
auto pairNode = pairedWindowMap_.at(node->GetWindowId()).pairNode_;
|
||||
pairNode->GetWindowProperty()->ResumeLastWindowMode();
|
||||
pairNode->GetWindowToken()->UpdateWindowMode(pairNode->GetWindowMode());
|
||||
pairedWindowMap_.erase(pairNode->GetWindowId());
|
||||
pairedWindowMap_.erase(node->GetWindowId());
|
||||
WLOGFI("resume pair node mode, Id[%{public}u, %{public}u], Mode[%{public}d, %{public}d]", node->GetWindowId(),
|
||||
pairNode->GetWindowId(), node->GetWindowMode(), pairNode->GetWindowMode());
|
||||
}
|
||||
if (pairedWindowMap_.empty()) {
|
||||
WLOGFI("send destroy msg to divider, Id: %{public}u", node->GetWindowId());
|
||||
SingletonContainer::Get<WindowInnerManager>().SendMessage(InnerWMCmd::INNER_WM_DESTROY_DIVIDER, displayId_);
|
||||
}
|
||||
ResetLayoutPolicy();
|
||||
return WMError::WM_OK;
|
||||
}
|
||||
|
||||
WMError WindowNodeContainer::UpdateWindowPairInfo(sptr<WindowNode>& triggerNode, sptr<WindowNode>& pairNode)
|
||||
{
|
||||
float splitRatio = DEFAULT_SPLIT_RATIO;
|
||||
WindowMode triggerMode = triggerNode->GetWindowMode();
|
||||
WindowMode pairSrcMode = pairNode->GetWindowMode();
|
||||
if (pairSrcMode == WindowMode::WINDOW_MODE_FULLSCREEN) {
|
||||
WindowMode pairDstMode = (triggerMode == WindowMode::WINDOW_MODE_SPLIT_PRIMARY) ?
|
||||
WindowMode::WINDOW_MODE_SPLIT_SECONDARY : WindowMode::WINDOW_MODE_SPLIT_PRIMARY;
|
||||
pairNode->SetWindowMode(pairDstMode);
|
||||
pairNode->GetWindowToken()->UpdateWindowMode(pairDstMode);
|
||||
WMError ret = UpdateWindowNode(pairNode, WindowUpdateReason::UPDATE_MODE);
|
||||
if (ret != WMError::WM_OK) {
|
||||
WLOGFE("Update window pair info failed");
|
||||
return ret;
|
||||
}
|
||||
WLOGFI("Pair FullScreen [%{public}u, %{public}u], Mode[%{public}d, %{public}d], splitRatio = %{public}f",
|
||||
triggerNode->GetWindowId(), pairNode->GetWindowId(), triggerMode, pairDstMode, splitRatio);
|
||||
} else {
|
||||
if (pairedWindowMap_.count(pairNode->GetWindowId()) != 0) {
|
||||
WindowPairInfo info = pairedWindowMap_.at(pairNode->GetWindowId());
|
||||
auto prevPairNode = info.pairNode_;
|
||||
WLOGFI("%{public}d node is paird , pre paired id is %{public}d,",
|
||||
pairNode->GetWindowId(), prevPairNode->GetWindowId());
|
||||
prevPairNode->GetWindowProperty()->ResumeLastWindowMode();
|
||||
prevPairNode->GetWindowToken()->UpdateWindowMode(prevPairNode->GetWindowMode());
|
||||
|
||||
pairedWindowMap_.erase(prevPairNode->GetWindowId());
|
||||
pairedWindowMap_.erase(pairNode->GetWindowId());
|
||||
|
||||
splitRatio = info.splitRatio_;
|
||||
WLOGFI("Pair Split [%{public}d, %{public}d], Mode[%{public}d, %{public}d], splitRatio = %{public}f",
|
||||
triggerNode->GetWindowId(), pairNode->GetWindowId(), triggerMode, pairSrcMode, splitRatio);
|
||||
} else {
|
||||
WLOGFI("%{public}d node is not paird", pairNode->GetWindowId());
|
||||
}
|
||||
}
|
||||
pairedWindowMap_.insert(std::pair<uint32_t, WindowPairInfo>(triggerNode->GetWindowId(),
|
||||
{pairNode, splitRatio}));
|
||||
pairedWindowMap_.insert(std::pair<uint32_t, WindowPairInfo>(pairNode->GetWindowId(),
|
||||
{triggerNode, 1 - splitRatio}));
|
||||
return WMError::WM_OK;
|
||||
}
|
||||
|
||||
WMError WindowNodeContainer::SwitchLayoutPolicy(WindowLayoutMode dstMode, bool reorder)
|
||||
{
|
||||
WLOGFI("SwitchLayoutPolicy src: %{public}d dst: %{public}d reorder: %{public}d",
|
||||
@@ -1278,9 +1101,9 @@ WMError WindowNodeContainer::SwitchLayoutPolicy(WindowLayoutMode dstMode, bool r
|
||||
return WMError::WM_ERROR_INVALID_PARAM;
|
||||
}
|
||||
if (layoutMode_ != dstMode) {
|
||||
if (layoutMode_ == WindowLayoutMode::CASCADE && !pairedWindowMap_.empty()) {
|
||||
pairedWindowMap_.clear();
|
||||
SingletonContainer::Get<WindowInnerManager>().SendMessage(InnerWMCmd::INNER_WM_DESTROY_DIVIDER, displayId_);
|
||||
if (layoutMode_ == WindowLayoutMode::CASCADE) {
|
||||
layoutPolicy_->Reset();
|
||||
windowPair_->Clear();
|
||||
}
|
||||
layoutMode_ = dstMode;
|
||||
layoutPolicy_->Clean();
|
||||
@@ -1291,11 +1114,7 @@ WMError WindowNodeContainer::SwitchLayoutPolicy(WindowLayoutMode dstMode, bool r
|
||||
WLOGFI("Current layout mode is already: %{public}d", static_cast<uint32_t>(dstMode));
|
||||
}
|
||||
if (reorder) {
|
||||
if (!pairedWindowMap_.empty()) {
|
||||
// exit divider window when reorder
|
||||
pairedWindowMap_.clear();
|
||||
SingletonContainer::Get<WindowInnerManager>().SendMessage(InnerWMCmd::INNER_WM_DESTROY_DIVIDER, displayId_);
|
||||
}
|
||||
windowPair_->Clear();
|
||||
layoutPolicy_->Reorder();
|
||||
DumpScreenWindowTree();
|
||||
}
|
||||
@@ -1535,5 +1354,44 @@ bool WindowNodeContainer::ReadIsWindowAnimationEnabledProperty()
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
WMError WindowNodeContainer::SetWindowMode(sptr<WindowNode>& node, WindowMode dstMode)
|
||||
{
|
||||
if (node == nullptr) {
|
||||
WLOGFE("could not find window");
|
||||
return WMError::WM_ERROR_NULLPTR;
|
||||
}
|
||||
WindowMode srcMode = node->GetWindowMode();
|
||||
if (srcMode == dstMode) {
|
||||
return WMError::WM_OK;
|
||||
}
|
||||
WMError res = WMError::WM_OK;
|
||||
if ((srcMode == WindowMode::WINDOW_MODE_FULLSCREEN) && (dstMode == WindowMode::WINDOW_MODE_FLOATING)) {
|
||||
node->SetWindowSizeChangeReason(WindowSizeChangeReason::RECOVER);
|
||||
} else if (dstMode == WindowMode::WINDOW_MODE_FULLSCREEN) {
|
||||
node->SetWindowSizeChangeReason(WindowSizeChangeReason::MAXIMIZE);
|
||||
} else {
|
||||
node->SetWindowSizeChangeReason(WindowSizeChangeReason::RESIZE);
|
||||
}
|
||||
node->SetWindowMode(dstMode);
|
||||
windowPair_->UpdateIfSplitRelated(node);
|
||||
if (node->GetWindowMode() == WindowMode::WINDOW_MODE_FULLSCREEN &&
|
||||
WindowHelper::IsAppWindow(node->GetWindowType())) {
|
||||
// minimize other app window
|
||||
res = MinimizeStructuredAppWindowsExceptSelf(node);
|
||||
if (res != WMError::WM_OK) {
|
||||
return res;
|
||||
}
|
||||
}
|
||||
if (node->GetWindowToken() != nullptr) {
|
||||
node->GetWindowToken()->UpdateWindowMode(node->GetWindowMode());
|
||||
}
|
||||
res = UpdateWindowNode(node, WindowUpdateReason::UPDATE_MODE);
|
||||
if (res != WMError::WM_OK) {
|
||||
WLOGFE("Set window mode failed, update node failed");
|
||||
return res;
|
||||
}
|
||||
return WMError::WM_OK;
|
||||
}
|
||||
} // namespace Rosen
|
||||
} // namespace OHOS
|
||||
|
||||
@@ -0,0 +1,431 @@
|
||||
/*
|
||||
* Copyright (c) 2022 Huawei Device Co., Ltd.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include "window_pair.h"
|
||||
|
||||
#include <ability_manager_client.h>
|
||||
#include "common_event_manager.h"
|
||||
#include "window_manager_hilog.h"
|
||||
#include "window_helper.h"
|
||||
#include "wm_trace.h"
|
||||
|
||||
namespace OHOS {
|
||||
namespace Rosen {
|
||||
namespace {
|
||||
constexpr HiviewDFX::HiLogLabel LABEL = {LOG_CORE, HILOG_DOMAIN_WINDOW, "WindowPair"};
|
||||
const std::string SPLIT_SCREEN_EVENT_NAME = "common.event.SPLIT_SCREEN";
|
||||
}
|
||||
|
||||
WindowPair::WindowPair(const DisplayId& displayId, sptr<WindowNode>& appNode)
|
||||
: displayId_(displayId), appWindowNode_(appNode) {
|
||||
}
|
||||
|
||||
WindowPair::~WindowPair()
|
||||
{
|
||||
WLOGI("~WindowPair");
|
||||
Clear();
|
||||
}
|
||||
|
||||
void WindowPair::SendInnerMessage(InnerWMCmd cmd, DisplayId displayId)
|
||||
{
|
||||
WLOGI("Send inner message cmd id: %{public}u display id: %{public}u.", static_cast<uint32_t>(cmd),
|
||||
static_cast<uint32_t>(displayId));
|
||||
SingletonContainer::Get<WindowInnerManager>().SendMessage(cmd, displayId);
|
||||
}
|
||||
|
||||
void WindowPair::SendBroadcastMsg(sptr<WindowNode>& node)
|
||||
{
|
||||
if (node == nullptr) {
|
||||
return;
|
||||
}
|
||||
// reset ipc identity
|
||||
std::string identity = IPCSkeleton::ResetCallingIdentity();
|
||||
AAFwk::Want want;
|
||||
want.SetAction(SPLIT_SCREEN_EVENT_NAME);
|
||||
int32_t missionId = -1;
|
||||
AAFwk::AbilityManagerClient::GetInstance()->GetMissionIdByToken(node->abilityToken_, missionId);
|
||||
std::string modeData = "";
|
||||
auto msg = (node->GetWindowMode() == WindowMode::WINDOW_MODE_SPLIT_SECONDARY) ?
|
||||
SplitBroadcastMsg::MSG_START_PRIMARY : SplitBroadcastMsg::MSG_START_SECONDARY;
|
||||
switch (msg) {
|
||||
case SplitBroadcastMsg::MSG_START_PRIMARY :
|
||||
modeData = "Primary";
|
||||
break;
|
||||
case SplitBroadcastMsg::MSG_START_SECONDARY :
|
||||
modeData = "Secondary";
|
||||
break;
|
||||
case SplitBroadcastMsg::MSG_START_DIVIDER :
|
||||
modeData = "Divider";
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
want.SetParam("windowMode", modeData);
|
||||
want.SetParam("missionId", missionId);
|
||||
EventFwk::CommonEventData commonEventData;
|
||||
commonEventData.SetWant(want);
|
||||
EventFwk::CommonEventManager::PublishCommonEvent(commonEventData);
|
||||
// set ipc identity to raw
|
||||
IPCSkeleton::SetCallingIdentity(identity);
|
||||
WLOGI("Send broadcast msg: %{public}s", modeData.c_str());
|
||||
}
|
||||
|
||||
sptr<WindowNode> WindowPair::Find(sptr<WindowNode>& node)
|
||||
{
|
||||
if (node == nullptr) {
|
||||
return nullptr;
|
||||
}
|
||||
if (primary_ != nullptr && primary_->GetWindowId() == node->GetWindowId()) {
|
||||
return primary_;
|
||||
} else if (secondary_ != nullptr && secondary_->GetWindowId() == node->GetWindowId()) {
|
||||
return secondary_;
|
||||
} else if (divider_ != nullptr && divider_->GetWindowId() == node->GetWindowId()) {
|
||||
return divider_;
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
bool WindowPair::IsPaired() const
|
||||
{
|
||||
if (primary_ == nullptr || secondary_ == nullptr) {
|
||||
return false;
|
||||
}
|
||||
if (primary_->GetWindowMode() == WindowMode::WINDOW_MODE_SPLIT_PRIMARY &&
|
||||
secondary_->GetWindowMode() == WindowMode::WINDOW_MODE_SPLIT_SECONDARY &&
|
||||
divider_ != nullptr) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void WindowPair::SetSplitRatio(float ratio)
|
||||
{
|
||||
ratio_ = ratio;
|
||||
}
|
||||
|
||||
float WindowPair::GetSplitRatio() const
|
||||
{
|
||||
return ratio_;
|
||||
}
|
||||
|
||||
WindowPairStatus WindowPair::GetPairStatus() const
|
||||
{
|
||||
return status_;
|
||||
}
|
||||
|
||||
sptr<WindowNode> WindowPair::GetDividerWindow() const
|
||||
{
|
||||
return divider_;
|
||||
}
|
||||
|
||||
sptr<WindowNode> WindowPair::GetPrimaryWindow() const
|
||||
{
|
||||
return primary_;
|
||||
}
|
||||
|
||||
sptr<WindowNode> WindowPair::GetSecondaryWindow() const
|
||||
{
|
||||
return secondary_;
|
||||
}
|
||||
|
||||
void WindowPair::Clear()
|
||||
{
|
||||
WLOGI("Clear window pair.");
|
||||
DumpPairInfo();
|
||||
if (primary_ != nullptr && primary_->GetWindowProperty() != nullptr &&
|
||||
primary_->GetWindowToken() != nullptr) {
|
||||
primary_->GetWindowProperty()->ResumeLastWindowMode();
|
||||
primary_->GetWindowToken()->UpdateWindowMode(primary_->GetWindowMode());
|
||||
}
|
||||
if (secondary_ != nullptr && secondary_->GetWindowProperty() != nullptr &&
|
||||
secondary_->GetWindowToken() != nullptr) {
|
||||
secondary_->GetWindowProperty()->ResumeLastWindowMode();
|
||||
secondary_->GetWindowToken()->UpdateWindowMode(secondary_->GetWindowMode());
|
||||
}
|
||||
primary_ = nullptr;
|
||||
secondary_ = nullptr;
|
||||
if (divider_ != nullptr) {
|
||||
SendInnerMessage(InnerWMCmd::INNER_WM_DESTROY_DIVIDER, displayId_);
|
||||
divider_ = nullptr;
|
||||
}
|
||||
status_ = WindowPairStatus::STATUS_EMPTY;
|
||||
}
|
||||
|
||||
bool WindowPair::IsSplitRelated(sptr<WindowNode>& node) const
|
||||
{
|
||||
if (node == nullptr) {
|
||||
return false;
|
||||
}
|
||||
return WindowHelper::IsSplitWindowMode((node->GetWindowMode())) ||
|
||||
(node->GetWindowType() == WindowType::WINDOW_TYPE_DOCK_SLICE);
|
||||
}
|
||||
|
||||
std::vector<sptr<WindowNode>> WindowPair::GetOrderedPair(sptr<WindowNode>& node)
|
||||
{
|
||||
WLOGI("Get piared node in Z order");
|
||||
std::vector<sptr<WindowNode>> orderedPair;
|
||||
if (node == nullptr || Find(node) == nullptr) {
|
||||
return orderedPair;
|
||||
}
|
||||
if (node->GetWindowMode() == WindowMode::WINDOW_MODE_SPLIT_SECONDARY ||
|
||||
node->GetWindowType() == WindowType::WINDOW_TYPE_DOCK_SLICE) {
|
||||
// primary secondary
|
||||
if (primary_ != nullptr && WindowHelper::IsAppWindow(primary_->GetWindowType())) {
|
||||
orderedPair.push_back(primary_);
|
||||
}
|
||||
if (secondary_ != nullptr && WindowHelper::IsAppWindow(secondary_->GetWindowType())) {
|
||||
orderedPair.push_back(secondary_);
|
||||
}
|
||||
} else if (node->GetWindowMode() == WindowMode::WINDOW_MODE_SPLIT_PRIMARY) {
|
||||
// secondary primary divider
|
||||
if (secondary_ != nullptr && WindowHelper::IsAppWindow(secondary_->GetWindowType())) {
|
||||
orderedPair.push_back(secondary_);
|
||||
}
|
||||
if (primary_ != nullptr && WindowHelper::IsAppWindow(primary_->GetWindowType())) {
|
||||
orderedPair.push_back(primary_);
|
||||
}
|
||||
}
|
||||
if (divider_ != nullptr) {
|
||||
orderedPair.push_back(divider_);
|
||||
}
|
||||
return orderedPair;
|
||||
}
|
||||
|
||||
std::vector<sptr<WindowNode>> WindowPair::GetPairedWindows()
|
||||
{
|
||||
WLOGI("Get all node of window pair");
|
||||
std::vector<sptr<WindowNode>> orderedPair;
|
||||
if (primary_ != nullptr) {
|
||||
orderedPair.push_back(primary_);
|
||||
}
|
||||
if (secondary_ != nullptr) {
|
||||
orderedPair.push_back(secondary_);
|
||||
}
|
||||
if (divider_ != nullptr) {
|
||||
orderedPair.push_back(divider_);
|
||||
}
|
||||
return orderedPair;
|
||||
}
|
||||
|
||||
sptr<WindowNode> WindowPair::FindPairableWindow(sptr<WindowNode>& node)
|
||||
{
|
||||
if (node == nullptr) {
|
||||
return nullptr;
|
||||
}
|
||||
if (!node->IsSplitMode()) {
|
||||
return nullptr;
|
||||
}
|
||||
for (auto iter = appWindowNode_->children_.rbegin(); iter != appWindowNode_->children_.rend(); iter++) {
|
||||
auto pairNode = *iter;
|
||||
if (pairNode == nullptr) {
|
||||
continue;
|
||||
}
|
||||
if (pairNode->GetWindowMode() == WindowMode::WINDOW_MODE_FULLSCREEN) {
|
||||
WindowMode dstMode = (node->GetWindowMode() == WindowMode::WINDOW_MODE_SPLIT_PRIMARY ?
|
||||
WindowMode::WINDOW_MODE_SPLIT_SECONDARY : WindowMode::WINDOW_MODE_SPLIT_PRIMARY);
|
||||
pairNode->SetWindowMode(dstMode);
|
||||
if (pairNode->GetWindowToken() != nullptr) {
|
||||
pairNode->GetWindowToken()->UpdateWindowMode(pairNode->GetWindowMode());
|
||||
}
|
||||
WLOGFI("Find full screen pair window: %{public}u", static_cast<uint32_t>(pairNode->GetWindowId()));
|
||||
return pairNode;
|
||||
}
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
sptr<WindowNode> WindowPair::GetPairableWindow(sptr<WindowNode>& node)
|
||||
{
|
||||
if (node == nullptr) {
|
||||
return nullptr;
|
||||
}
|
||||
// get pairable window from window tree or send broadcast msg to start pair window
|
||||
sptr<WindowNode> pairableNode = FindPairableWindow(node);
|
||||
if (pairableNode == nullptr) {
|
||||
WLOGFI("Can not find pairable window from current tree.");
|
||||
SendBroadcastMsg(node);
|
||||
return nullptr;
|
||||
}
|
||||
WLOGFI("Find pairable window id: %{public}u", pairableNode->GetWindowId());
|
||||
return pairableNode;
|
||||
}
|
||||
|
||||
|
||||
void WindowPair::UpdateIfSplitRelated(sptr<WindowNode>& node)
|
||||
{
|
||||
if (node == nullptr) {
|
||||
WLOGI("Window is nullptr.");
|
||||
return;
|
||||
}
|
||||
if (Find(node) == nullptr && !IsSplitRelated(node)) {
|
||||
WLOGI("Window id: %{public}u is not split related and paired.", node->GetWindowId());
|
||||
return;
|
||||
}
|
||||
WLOGI("Current status: %{public}u, window id: %{public}u mode: %{public}u",
|
||||
status_, node->GetWindowId(), node->GetWindowMode());
|
||||
if (status_ == WindowPairStatus::STATUS_EMPTY) {
|
||||
Insert(node);
|
||||
// find pairable window from trees or send broadcast
|
||||
sptr<WindowNode> pairableNode = GetPairableWindow(node);
|
||||
// insert pairable node
|
||||
Insert(pairableNode);
|
||||
} else {
|
||||
if (Find(node) == nullptr) {
|
||||
// add new split related node to pair
|
||||
Insert(node);
|
||||
} else {
|
||||
// handle paired nodes change
|
||||
HandlePairedNodesChange();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void WindowPair::UpdateWindowPairStatus()
|
||||
{
|
||||
WLOGI("Update window pair status.");
|
||||
WindowPairStatus prevStatus = status_;
|
||||
if (primary_ != nullptr && secondary_ != nullptr && divider_ != nullptr) {
|
||||
status_ = WindowPairStatus::STATUS_PAIRED_DONE;
|
||||
} else if (primary_ != nullptr && secondary_ != nullptr && divider_ == nullptr) {
|
||||
status_ = WindowPairStatus::STATUS_PAIRING;
|
||||
} else if (primary_ != nullptr && secondary_ == nullptr) {
|
||||
status_ = WindowPairStatus::STATUS_SINGLE_PRIMARY;
|
||||
} else if (primary_ == nullptr && secondary_ != nullptr) {
|
||||
status_ = WindowPairStatus::STATUS_SINGLE_SECONDARY;
|
||||
} else {
|
||||
status_ = WindowPairStatus::STATUS_EMPTY;
|
||||
}
|
||||
if ((prevStatus == WindowPairStatus::STATUS_SINGLE_PRIMARY ||
|
||||
prevStatus == WindowPairStatus::STATUS_SINGLE_SECONDARY || prevStatus == WindowPairStatus::STATUS_EMPTY) &&
|
||||
status_ == WindowPairStatus::STATUS_PAIRING) {
|
||||
// create divider
|
||||
SendInnerMessage(InnerWMCmd::INNER_WM_CREATE_DIVIDER, displayId_);
|
||||
} else if ((prevStatus == WindowPairStatus::STATUS_PAIRED_DONE || prevStatus == WindowPairStatus::STATUS_PAIRING) &&
|
||||
(status_ != WindowPairStatus::STATUS_PAIRED_DONE && status_ != WindowPairStatus::STATUS_PAIRING)) {
|
||||
// clear pair
|
||||
Clear();
|
||||
}
|
||||
DumpPairInfo();
|
||||
}
|
||||
|
||||
void WindowPair::SwitchPosition()
|
||||
{
|
||||
if (primary_ == nullptr || secondary_ == nullptr) {
|
||||
return;
|
||||
}
|
||||
WLOGFI("Switch the pair pos, pri: %{public}u pri-mode: %{public}u, sec: %{public}u sec-mode: %{public}u,",
|
||||
primary_->GetWindowId(), primary_->GetWindowMode(), secondary_->GetWindowId(), secondary_->GetWindowMode());
|
||||
if (primary_->GetWindowMode() == secondary_->GetWindowMode() &&
|
||||
primary_->GetWindowMode() == WindowMode::WINDOW_MODE_SPLIT_PRIMARY) {
|
||||
primary_->SetWindowMode(WindowMode::WINDOW_MODE_SPLIT_SECONDARY);
|
||||
if (primary_->GetWindowToken() != nullptr) {
|
||||
primary_->GetWindowToken()->UpdateWindowMode(WindowMode::WINDOW_MODE_SPLIT_SECONDARY);
|
||||
}
|
||||
std::swap(primary_, secondary_);
|
||||
} else if (primary_->GetWindowMode() == secondary_->GetWindowMode() &&
|
||||
primary_->GetWindowMode() == WindowMode::WINDOW_MODE_SPLIT_SECONDARY) {
|
||||
secondary_->SetWindowMode(WindowMode::WINDOW_MODE_SPLIT_PRIMARY);
|
||||
if (secondary_->GetWindowToken() != nullptr) {
|
||||
secondary_->GetWindowToken()->UpdateWindowMode(WindowMode::WINDOW_MODE_SPLIT_PRIMARY);
|
||||
}
|
||||
std::swap(primary_, secondary_);
|
||||
}
|
||||
}
|
||||
|
||||
void WindowPair::HandlePairedNodesChange()
|
||||
{
|
||||
WLOGI("Update pair node.");
|
||||
if (primary_ != nullptr && !primary_->IsSplitMode()) {
|
||||
primary_ = nullptr;
|
||||
}
|
||||
if (secondary_ != nullptr && !secondary_->IsSplitMode()) {
|
||||
secondary_ = nullptr;
|
||||
}
|
||||
// paired node mode change
|
||||
if (primary_ != nullptr && secondary_ == nullptr &&
|
||||
primary_->GetWindowMode() == WindowMode::WINDOW_MODE_SPLIT_SECONDARY) {
|
||||
std::swap(primary_, secondary_);
|
||||
} else if (primary_ == nullptr && secondary_ != nullptr &&
|
||||
secondary_->GetWindowMode() == WindowMode::WINDOW_MODE_SPLIT_PRIMARY) {
|
||||
std::swap(primary_, secondary_);
|
||||
} else if (primary_ != nullptr && secondary_ != nullptr &&
|
||||
primary_->GetWindowMode() == secondary_->GetWindowMode()) {
|
||||
// switch position
|
||||
SwitchPosition();
|
||||
}
|
||||
UpdateWindowPairStatus();
|
||||
}
|
||||
|
||||
void WindowPair::Insert(sptr<WindowNode>& node)
|
||||
{
|
||||
if (node == nullptr) {
|
||||
return;
|
||||
}
|
||||
WLOGI("Insert a window to pair id: %{public}u", node->GetWindowId());
|
||||
sptr<WindowNode> pairedNode;
|
||||
if (node->GetWindowMode() == WindowMode::WINDOW_MODE_SPLIT_PRIMARY) {
|
||||
pairedNode = primary_;
|
||||
primary_ = node;
|
||||
} else if (node->GetWindowMode() == WindowMode::WINDOW_MODE_SPLIT_SECONDARY) {
|
||||
pairedNode = secondary_;
|
||||
secondary_ = node;
|
||||
} else if (node->GetWindowType() == WindowType::WINDOW_TYPE_DOCK_SLICE) {
|
||||
pairedNode = divider_;
|
||||
divider_ = node;
|
||||
}
|
||||
// minimize invalid paired window
|
||||
if (pairedNode != nullptr && pairedNode->abilityToken_ != nullptr) {
|
||||
AAFwk::AbilityManagerClient::GetInstance()->MinimizeAbility(pairedNode->abilityToken_, false);
|
||||
}
|
||||
UpdateWindowPairStatus();
|
||||
}
|
||||
|
||||
void WindowPair::DumpPairInfo()
|
||||
{
|
||||
if (primary_ != nullptr) {
|
||||
WLOGI("[DumpPairInfo] primary id: %{public}u mode: %{public}u", primary_->GetWindowId(),
|
||||
primary_->GetWindowMode());
|
||||
}
|
||||
if (secondary_ != nullptr) {
|
||||
WLOGI("[DumpPairInfo] secondary id: %{public}u mode: %{public}u", secondary_->GetWindowId(),
|
||||
secondary_->GetWindowMode());
|
||||
}
|
||||
if (divider_ != nullptr) {
|
||||
WLOGI("[DumpPairInfo] divider id: %{public}u mode: %{public}u", divider_->GetWindowId(),
|
||||
divider_->GetWindowMode());
|
||||
}
|
||||
WLOGI("[DumpPairInfo] pair status %{public}u", status_);
|
||||
}
|
||||
|
||||
void WindowPair::HandleRemoveWindow(sptr<WindowNode>& node)
|
||||
{
|
||||
if (node == nullptr) {
|
||||
return;
|
||||
}
|
||||
if (Find(node) == nullptr && node->IsSplitMode()) {
|
||||
WLOGI("Resume unpaired split related window id: %{public}u", node->GetWindowId());
|
||||
if (node->GetWindowProperty() != nullptr && node->GetWindowToken() != nullptr) {
|
||||
node->GetWindowProperty()->ResumeLastWindowMode();
|
||||
node->GetWindowToken()->UpdateWindowMode(node->GetWindowMode());
|
||||
}
|
||||
// target node is not in window pair, need resume mode when remove
|
||||
return;
|
||||
} else if (Find(node) != nullptr) {
|
||||
WLOGI("Pairing window id: %{public}u is remove, clear window pair", node->GetWindowId());
|
||||
Clear();
|
||||
}
|
||||
}
|
||||
} // namespace Rosen
|
||||
} // namespace OHOS
|
||||
@@ -361,24 +361,14 @@ void WindowRoot::UpdateFocusableProperty(uint32_t windowId)
|
||||
}
|
||||
}
|
||||
|
||||
WMError WindowRoot::EnterSplitWindowMode(sptr<WindowNode>& node)
|
||||
WMError WindowRoot::SetWindowMode(sptr<WindowNode>& node, WindowMode dstMode)
|
||||
{
|
||||
auto container = GetOrCreateWindowNodeContainer(node->GetDisplayId());
|
||||
if (container == nullptr) {
|
||||
WLOGFE("Enter split window mode failed, window container could not be found");
|
||||
WLOGFE("set window mode failed, window container could not be found");
|
||||
return WMError::WM_ERROR_NULLPTR;
|
||||
}
|
||||
return container->EnterSplitWindowMode(node);
|
||||
}
|
||||
|
||||
WMError WindowRoot::ExitSplitWindowMode(sptr<WindowNode>& node)
|
||||
{
|
||||
auto container = GetOrCreateWindowNodeContainer(node->GetDisplayId());
|
||||
if (container == nullptr) {
|
||||
WLOGFE("Exit split window mode failed, window container could not be found");
|
||||
return WMError::WM_ERROR_NULLPTR;
|
||||
}
|
||||
return container->ExitSplitWindowMode(node);
|
||||
return container->SetWindowMode(node, dstMode);
|
||||
}
|
||||
|
||||
WMError WindowRoot::DestroyWindow(uint32_t windowId, bool onlySelf)
|
||||
|
||||
Reference in New Issue
Block a user