mirror of
https://github.com/openharmony/windowmanager.git
synced 2026-07-21 04:25:28 -04:00
@@ -142,8 +142,10 @@ namespace {
|
||||
constexpr uint32_t DIVIDER_WIDTH = 8;
|
||||
constexpr uint32_t INVALID_WINDOW_ID = 0;
|
||||
constexpr uint32_t HOTZONE = 40;
|
||||
constexpr uint32_t MIN_VERTICAL_FLOATING_WIDTH = 360;
|
||||
constexpr uint32_t MIN_VERTICAL_FLOATING_WIDTH = 240;
|
||||
constexpr uint32_t MIN_VERTICAL_FLOATING_HEIGHT = 480;
|
||||
constexpr uint32_t MIN_VERTICAL_SPLIT_HEIGHT = 426;
|
||||
constexpr uint32_t MIN_HORIZONTAL_SPLIT_WIDTH = 426;
|
||||
}
|
||||
|
||||
struct SystemBarProperty {
|
||||
|
||||
@@ -48,7 +48,7 @@ public:
|
||||
virtual void LayoutWindowTree();
|
||||
virtual void RemoveWindowNode(sptr<WindowNode>& node);
|
||||
virtual void UpdateWindowNode(sptr<WindowNode>& node);
|
||||
virtual void UpdateLayoutRect(sptr<WindowNode>& node);
|
||||
virtual void UpdateLayoutRect(sptr<WindowNode>& node) = 0;
|
||||
void UpdateDefaultFoatingRect();
|
||||
|
||||
protected:
|
||||
|
||||
@@ -34,6 +34,7 @@ public:
|
||||
~WindowLayoutPolicyTile() = default;
|
||||
void Launch() override;
|
||||
void AddWindowNode(sptr<WindowNode>& node) override;
|
||||
void UpdateLayoutRect(sptr<WindowNode>& node) override;
|
||||
|
||||
private:
|
||||
Rect singleRect_ = { 0, 0, 0, 0 };
|
||||
|
||||
@@ -130,17 +130,20 @@ static bool IsLayoutChanged(const Rect& l, const Rect& r)
|
||||
|
||||
void WindowLayoutPolicyCascade::LimitMoveBounds(Rect& rect)
|
||||
{
|
||||
Rect curRect = rect;
|
||||
rect.posX_ = std::max(curRect.posX_, limitRect_.posX_);
|
||||
rect.posY_ = std::max(curRect.posY_, limitRect_.posY_);
|
||||
if (rect.width_ < rect.height_) {
|
||||
rect.posX_ = std::min(curRect.posX_ + rect.width_,
|
||||
limitRect_.posX_ + limitRect_.width_) - rect.width_;
|
||||
rect.height_ = curRect.posY_ + curRect.height_ - rect.posY_;
|
||||
if (rect.posX_ < (limitRect_.posX_ + static_cast<int32_t>(MIN_HORIZONTAL_SPLIT_WIDTH))) {
|
||||
rect.posX_ = limitRect_.posX_ + static_cast<int32_t>(MIN_HORIZONTAL_SPLIT_WIDTH);
|
||||
} else if (rect.posX_ >
|
||||
(limitRect_.posX_ + limitRect_.width_ - static_cast<int32_t>(MIN_HORIZONTAL_SPLIT_WIDTH))) {
|
||||
rect.posX_ = limitRect_.posX_ + static_cast<int32_t>(limitRect_.width_ - MIN_HORIZONTAL_SPLIT_WIDTH);
|
||||
}
|
||||
} else {
|
||||
rect.posY_ = std::min(curRect.posY_ + rect.height_,
|
||||
limitRect_.posY_ + limitRect_.height_) - rect.height_;
|
||||
rect.width_ = curRect.posX_ + curRect.width_ - rect.posX_;
|
||||
if (rect.posY_ < (limitRect_.posY_ + static_cast<int32_t>(MIN_VERTICAL_SPLIT_HEIGHT))) {
|
||||
rect.posY_ = limitRect_.posY_ + static_cast<int32_t>(MIN_VERTICAL_SPLIT_HEIGHT);
|
||||
} else if (rect.posY_ >
|
||||
(limitRect_.posY_ + static_cast<int32_t>(limitRect_.height_ - MIN_VERTICAL_SPLIT_HEIGHT))) {
|
||||
rect.posY_ = limitRect_.posY_ + static_cast<int32_t>(limitRect_.height_ - MIN_VERTICAL_SPLIT_HEIGHT);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -205,7 +208,7 @@ void WindowLayoutPolicyCascade::UpdateLayoutRect(sptr<WindowNode>& node)
|
||||
}
|
||||
}
|
||||
// Limit window to the maximum window size
|
||||
LimitWindowSize(node, displayRect, winRect);
|
||||
LimitWindowSize(node, displayRect_, winRect);
|
||||
|
||||
if (node->GetWindowType() == WindowType::WINDOW_TYPE_DOCK_SLICE) {
|
||||
LimitMoveBounds(winRect);
|
||||
|
||||
@@ -114,7 +114,9 @@ void WindowLayoutPolicyTile::InitForegroundNodeQueue()
|
||||
foregroundNodes_.clear();
|
||||
lastForegroundNodeId_ = 0;
|
||||
for (auto& node : appWindowNode_->children_) {
|
||||
UpdateForegroundNodeQueue(node);
|
||||
if (WindowHelper::IsMainWindow(node->GetWindowType())) {
|
||||
UpdateForegroundNodeQueue(node);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -123,11 +125,13 @@ void WindowLayoutPolicyTile::UpdateForegroundNodeQueue(sptr<WindowNode>& node)
|
||||
if (node == nullptr) {
|
||||
return;
|
||||
}
|
||||
WLOGFI("add win in tile for win id: %{public}d", node->GetWindowId());
|
||||
uint32_t maxTileWinNum = IsVertical() ? MAX_WIN_NUM_VERTICAL : MAX_WIN_NUM_HORIZONTAL;
|
||||
if (foregroundNodes_.size() < maxTileWinNum) {
|
||||
foregroundNodes_.push_back(node);
|
||||
lastForegroundNodeId_ = ((++lastForegroundNodeId_) % maxTileWinNum);
|
||||
} else {
|
||||
WLOGFI("minimize win %{public}d in tile", foregroundNodes_[lastForegroundNodeId_]->GetWindowId());
|
||||
AAFwk::AbilityManagerClient::GetInstance()->
|
||||
MinimizeAbility(foregroundNodes_[lastForegroundNodeId_]->abilityToken_);
|
||||
foregroundNodes_[lastForegroundNodeId_] = node;
|
||||
@@ -142,7 +146,9 @@ void WindowLayoutPolicyTile::AssignNodePropertyForTileWindows()
|
||||
if (num == 1) {
|
||||
WLOGFI("set rect for win id: %{public}d", foregroundNodes_[0]->GetWindowMode());
|
||||
foregroundNodes_[0]->SetWindowMode(WindowMode::WINDOW_MODE_FLOATING);
|
||||
foregroundNodes_[0]->GetWindowToken()->UpdateWindowMode(WindowMode::WINDOW_MODE_FLOATING);
|
||||
foregroundNodes_[0]->SetWindowRect(singleRect_);
|
||||
foregroundNodes_[0]->hasDecorated_ = true;
|
||||
WLOGFI("set rect for win id: %{public}d [%{public}d %{public}d %{public}d %{public}d]",
|
||||
foregroundNodes_[0]->GetWindowId(),
|
||||
singleRect_.posX_, singleRect_.posY_, singleRect_.width_, singleRect_.height_);
|
||||
@@ -150,12 +156,58 @@ void WindowLayoutPolicyTile::AssignNodePropertyForTileWindows()
|
||||
auto& rects = (num == MAX_WIN_NUM_HORIZONTAL) ? tripleRects_ : doubleRects_;
|
||||
for (uint32_t i = 0; i < foregroundNodes_.size(); i++) {
|
||||
foregroundNodes_[(lastForegroundNodeId_ + i) % num]->SetWindowMode(WindowMode::WINDOW_MODE_FLOATING);
|
||||
foregroundNodes_[(lastForegroundNodeId_ + i) % num]->GetWindowToken()->
|
||||
UpdateWindowMode(WindowMode::WINDOW_MODE_FLOATING);
|
||||
foregroundNodes_[(lastForegroundNodeId_ + i) % num]->SetWindowRect(rects[i]);
|
||||
foregroundNodes_[(lastForegroundNodeId_ + i) % num]->hasDecorated_ = true;
|
||||
WLOGFI("set rect for qwin id: %{public}d [%{public}d %{public}d %{public}d %{public}d]",
|
||||
foregroundNodes_[(lastForegroundNodeId_ + i) % num]->GetWindowId(),
|
||||
rects[i].posX_, rects[i].posY_, rects[i].width_, rects[i].height_);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void WindowLayoutPolicyTile::UpdateLayoutRect(sptr<WindowNode>& node)
|
||||
{
|
||||
auto type = node->GetWindowType();
|
||||
auto mode = node->GetWindowMode();
|
||||
auto flags = node->GetWindowFlags();
|
||||
auto decorEnbale = node->GetWindowProperty()->GetDecorEnable();
|
||||
bool needAvoid = (flags & static_cast<uint32_t>(WindowFlag::WINDOW_FLAG_NEED_AVOID));
|
||||
bool parentLimit = (flags & static_cast<uint32_t>(WindowFlag::WINDOW_FLAG_PARENT_LIMIT));
|
||||
bool subWindow = WindowHelper::IsSubWindow(type);
|
||||
bool floatingWindow = (mode == WindowMode::WINDOW_MODE_FLOATING);
|
||||
const Rect& layoutRect = node->GetLayoutRect();
|
||||
Rect lastRect = layoutRect;
|
||||
Rect displayRect = displayRect_;
|
||||
Rect limitRect = displayRect;
|
||||
Rect winRect = node->GetWindowProperty()->GetWindowRect();
|
||||
|
||||
WLOGFI("Id:%{public}d, avoid:%{public}d parLimit:%{public}d floating:%{public}d, sub:%{public}d, " \
|
||||
"deco:%{public}d, type:%{public}d, requestRect:[%{public}d, %{public}d, %{public}d, %{public}d]",
|
||||
node->GetWindowId(), needAvoid, parentLimit, floatingWindow, subWindow, decorEnbale,
|
||||
static_cast<uint32_t>(type), winRect.posX_, winRect.posY_, winRect.width_, winRect.height_);
|
||||
if (needAvoid) {
|
||||
limitRect = limitRect_;
|
||||
}
|
||||
|
||||
if (!floatingWindow) { // fullscreen window
|
||||
winRect = limitRect;
|
||||
} else { // floating window
|
||||
if (node->GetWindowProperty()->GetDecorEnable()) { // is decorable
|
||||
winRect = ComputeDecoratedWindowRect(winRect);
|
||||
}
|
||||
if (subWindow && parentLimit) { // subwidow and limited by parent
|
||||
limitRect = node->parent_->GetLayoutRect();
|
||||
UpdateFloatingLayoutRect(limitRect, winRect);
|
||||
}
|
||||
}
|
||||
LimitWindowSize(node, displayRect, winRect);
|
||||
node->SetLayoutRect(winRect);
|
||||
if (!(lastRect == winRect)) {
|
||||
node->GetWindowToken()->UpdateWindowRect(winRect, node->GetWindowSizeChangeReason());
|
||||
node->surfaceNode_->SetBounds(winRect.posX_, winRect.posY_, winRect.width_, winRect.height_);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -920,20 +920,29 @@ WMError WindowNodeContainer::UpdateWindowPairInfo(sptr<WindowNode>& triggerNode,
|
||||
return WMError::WM_OK;
|
||||
}
|
||||
|
||||
WMError WindowNodeContainer::SwitchLayoutPolicy(WindowLayoutMode mode, bool reorder)
|
||||
WMError WindowNodeContainer::SwitchLayoutPolicy(WindowLayoutMode dstMode, bool reorder)
|
||||
{
|
||||
WLOGFI("SwitchLayoutPolicy src: %{public}d dst: %{public}d reorder: %{public}d",
|
||||
static_cast<uint32_t>(layoutMode_), static_cast<uint32_t>(mode), static_cast<uint32_t>(reorder));
|
||||
if (layoutMode_ != mode) {
|
||||
layoutMode_ = mode;
|
||||
static_cast<uint32_t>(layoutMode_), static_cast<uint32_t>(dstMode), static_cast<uint32_t>(reorder));
|
||||
if (layoutMode_ != dstMode) {
|
||||
if (layoutMode_ == WindowLayoutMode::CASCADE && !pairedWindowMap_.empty()) {
|
||||
pairedWindowMap_.clear();
|
||||
SingletonContainer::Get<WindowInnerManager>().SendMessage(INNER_WM_DESTROY_DIVIDER, displayId_);
|
||||
}
|
||||
layoutMode_ = dstMode;
|
||||
layoutPolicy_->Clean();
|
||||
layoutPolicy_ = layoutPolicys_[mode];
|
||||
layoutPolicy_ = layoutPolicys_[dstMode];
|
||||
layoutPolicy_->Launch();
|
||||
DumpScreenWindowTree();
|
||||
} else {
|
||||
WLOGFI("Curret layout mode is allready: %{public}d", static_cast<uint32_t>(mode));
|
||||
WLOGFI("Curret layout mode is allready: %{public}d", static_cast<uint32_t>(dstMode));
|
||||
}
|
||||
if (reorder) {
|
||||
if (!pairedWindowMap_.empty()) {
|
||||
// exit divider window when reorder
|
||||
pairedWindowMap_.clear();
|
||||
SingletonContainer::Get<WindowInnerManager>().SendMessage(INNER_WM_DESTROY_DIVIDER, displayId_);
|
||||
}
|
||||
layoutPolicy_->Reorder();
|
||||
DumpScreenWindowTree();
|
||||
}
|
||||
|
||||
@@ -405,7 +405,7 @@ WMError WindowRoot::SetWindowLayoutMode(DisplayId displayId, WindowLayoutMode mo
|
||||
}
|
||||
WMError ret = container->SwitchLayoutPolicy(mode, true);
|
||||
if (ret != WMError::WM_OK) {
|
||||
WLOGFW("set windoe layout mode failed displayId: %{public}" PRId64 ", ret: %{public}d", displayId, ret);
|
||||
WLOGFW("set window layout mode failed displayId: %{public}" PRId64 ", ret: %{public}d", displayId, ret);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user