mirror of
https://github.com/openharmony/windowmanager.git
synced 2026-07-18 16:24:27 -04:00
!161 单应用分屏支持layout避让
Merge pull request !161 from liuqi/master Signed-off-by: xingyanan <xingyanan2@huawei.com> Change-Id: I9ce8f0154e451c349f62a78b4cd81666b3af68ab
This commit is contained in:
Binary file not shown.
|
After Width: | Height: | Size: 342 B |
@@ -37,6 +37,13 @@ config("libwms_config") {
|
||||
}
|
||||
}
|
||||
|
||||
ohos_prebuilt_etc("window_devider_image") {
|
||||
source = "//foundation/windowmanager/resources/bg_split_handle.png"
|
||||
part_name = "window_manager"
|
||||
subsystem_name = "window"
|
||||
relative_install_dir = "window/resources"
|
||||
}
|
||||
|
||||
ohos_shared_library("libwms") {
|
||||
sources = [
|
||||
"../dm/src/zidl/display_manager_agent_proxy.cpp",
|
||||
@@ -77,6 +84,7 @@ ohos_shared_library("libwms") {
|
||||
"//foundation/graphic/standard/rosen/modules/render_service_client:librender_service_client",
|
||||
"//foundation/windowmanager/utils:libwmutil",
|
||||
"//foundation/windowmanager/wm:libwm",
|
||||
":window_devider_image"
|
||||
]
|
||||
|
||||
public_deps = [
|
||||
|
||||
@@ -24,6 +24,7 @@
|
||||
#ifdef ACE_ENABLE_GL
|
||||
#include "render_context/render_context.h"
|
||||
#endif
|
||||
#include "include/core/SkBitmap.h"
|
||||
#include "single_instance.h"
|
||||
#include "singleton_delegator.h"
|
||||
#include "window.h"
|
||||
@@ -57,8 +58,9 @@ private:
|
||||
void CreateAndShowDivider(std::unique_ptr<WindowMessage> msg);
|
||||
void HideAndDestroyDivider(std::unique_ptr<WindowMessage> msg);
|
||||
void DestroyThread(std::unique_ptr<WindowMessage> msg);
|
||||
void DrawSurface(const sptr<Window>& window, uint32_t color);
|
||||
void DrawSurface(const sptr<Window>& window);
|
||||
sptr<Window> GetDividerWindow(uint32_t displayId) const;
|
||||
bool DecodeImageFile(const char* filename, SkBitmap* bitmap);
|
||||
|
||||
std::mutex mutex_;
|
||||
std::condition_variable conVar_;
|
||||
@@ -70,6 +72,9 @@ private:
|
||||
std::vector<std::unique_ptr<WindowMessage>> messages_;
|
||||
bool hasInitThread_ = false;
|
||||
bool needDestroyThread_ = false;
|
||||
bool isDeviderImageLoaded = false;
|
||||
const char *splitIconPath_ = "/etc/window/resources/bg_split_handle.png";
|
||||
SkBitmap deviderBitmap;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -49,6 +49,7 @@ public:
|
||||
const sptr<WindowNode>& appNode, const sptr<WindowNode>& aboveAppNode);
|
||||
~WindowLayoutPolicy() = default;
|
||||
void UpdateDisplayInfo(const Rect& primaryRect, const Rect& secondaryRect, const Rect& displayRect);
|
||||
void UpdateSplitInfo(const Rect& primaryRect, const Rect& secondaryRect);
|
||||
void AddWindowNode(sptr<WindowNode>& node);
|
||||
void RemoveWindowNode(sptr<WindowNode>& node);
|
||||
void UpdateWindowNode(sptr<WindowNode>& node);
|
||||
|
||||
@@ -51,6 +51,7 @@ public:
|
||||
std::shared_ptr<RSDisplayNode> GetDisplayNode() const;
|
||||
void LayoutDividerWindow(sptr<WindowNode>& node);
|
||||
void UpdateDisplayInfo();
|
||||
void UpdateSplitInfo();
|
||||
bool isVerticalDisplay() const;
|
||||
|
||||
class DisplayRects : public RefBase {
|
||||
|
||||
@@ -16,7 +16,9 @@
|
||||
#include "window_inner_manager.h"
|
||||
|
||||
#include "include/core/SkCanvas.h"
|
||||
#include "include/core/SkImageInfo.h"
|
||||
#include "include/codec/SkCodec.h"
|
||||
#include "include/core/SkData.h"
|
||||
#include "include/core/SkImage.h"
|
||||
#include "transaction/rs_transaction.h"
|
||||
#include "ui/rs_surface_extractor.h"
|
||||
|
||||
@@ -32,7 +34,22 @@ namespace {
|
||||
|
||||
WM_IMPLEMENT_SINGLE_INSTANCE(WindowInnerManager)
|
||||
|
||||
void WindowInnerManager::DrawSurface(const sptr<Window>& window, uint32_t color)
|
||||
bool WindowInnerManager::DecodeImageFile(const char* filename, SkBitmap* bitmap)
|
||||
{
|
||||
sk_sp<SkData> data(SkData::MakeFromFileName(filename));
|
||||
std::unique_ptr<SkCodec> codec = SkCodec::MakeFromData(std::move(data));
|
||||
if (codec == nullptr) {
|
||||
return false;
|
||||
}
|
||||
SkColorType colorType = kN32_SkColorType;
|
||||
SkImageInfo info = codec->getInfo().makeColorType(colorType);
|
||||
if (!bitmap->tryAllocPixels(info)) {
|
||||
return false;
|
||||
}
|
||||
return SkCodec::kSuccess == codec->getPixels(info, bitmap->getPixels(), bitmap->rowBytes());
|
||||
}
|
||||
|
||||
void WindowInnerManager::DrawSurface(const sptr<Window>& window)
|
||||
{
|
||||
auto surfaceNode = window->GetSurfaceNode();
|
||||
auto winRect = window->GetRect();
|
||||
@@ -51,32 +68,35 @@ void WindowInnerManager::DrawSurface(const sptr<Window>& window, uint32_t color)
|
||||
rsSurface->SetRenderContext(rc_);
|
||||
#endif
|
||||
auto frame = rsSurface->RequestFrame(width, height);
|
||||
std::unique_ptr<RSSurfaceFrame> framePtr = std::move(frame);
|
||||
if (!framePtr) {
|
||||
if (!frame) {
|
||||
WLOGFE("DrawSurface frameptr is nullptr");
|
||||
return;
|
||||
}
|
||||
auto canvas = framePtr->GetCanvas();
|
||||
auto canvas = frame->GetCanvas();
|
||||
if (!canvas) {
|
||||
WLOGFE("DrawSurface canvas is nullptr");
|
||||
return;
|
||||
}
|
||||
SkPaint paint;
|
||||
paint.setAntiAlias(true);
|
||||
paint.setStyle(SkPaint::kFill_Style);
|
||||
const SkScalar skWidth = 20;
|
||||
paint.setStrokeWidth(skWidth);
|
||||
paint.setStrokeJoin(SkPaint::kRound_Join);
|
||||
paint.setColor(color);
|
||||
|
||||
SkPoint rectPts[] = { {0, 0}, {static_cast<int>(width), static_cast<int>(height)} };
|
||||
SkRect rect;
|
||||
rect.set(rectPts[0], rectPts[1]);
|
||||
|
||||
canvas->drawRect(rect, paint);
|
||||
framePtr->SetDamageRegion(0, 0, width, height);
|
||||
auto framPtr1 = std::move(framePtr);
|
||||
rsSurface->FlushFrame(framPtr1);
|
||||
if (!deviderBitmap.isNull()) {
|
||||
SkPaint paint;
|
||||
SkMatrix matrix;
|
||||
SkRect paintRect;
|
||||
if (width < height) {
|
||||
// rotate when devider is hozizon
|
||||
matrix.setScale(static_cast<float>(height) / deviderBitmap.width(),
|
||||
static_cast<float>(width) / deviderBitmap.height());
|
||||
matrix.postRotate(-90.0f); // devider shader rotate -90.0
|
||||
} else {
|
||||
matrix.setScale(static_cast<float>(width) / deviderBitmap.width(),
|
||||
static_cast<float>(height) / deviderBitmap.height());
|
||||
}
|
||||
paint.setShader(deviderBitmap.makeShader(SkTileMode::kRepeat, SkTileMode::kRepeat));
|
||||
paint.setShader(paint.getShader()->makeWithLocalMatrix(matrix));
|
||||
paintRect.set(0, 0, static_cast<int>(width), static_cast<int>(height));
|
||||
canvas->drawRect(paintRect, paint);
|
||||
}
|
||||
frame->SetDamageRegion(0, 0, width, height);
|
||||
rsSurface->FlushFrame(frame);
|
||||
}
|
||||
|
||||
|
||||
@@ -137,8 +157,13 @@ void WindowInnerManager::CreateAndShowDivider(std::unique_ptr<WindowMessage> msg
|
||||
}
|
||||
}
|
||||
#endif
|
||||
const uint32_t colorGrey = 0xff808080;
|
||||
DrawSurface(window, colorGrey);
|
||||
if (!isDeviderImageLoaded) {
|
||||
isDeviderImageLoaded = DecodeImageFile(splitIconPath_, &deviderBitmap);
|
||||
if (!isDeviderImageLoaded) {
|
||||
WLOGFE("Decode devider image failed");
|
||||
}
|
||||
}
|
||||
DrawSurface(window);
|
||||
WLOGFI("CreateAndShowDivider success");
|
||||
}
|
||||
|
||||
@@ -162,6 +187,7 @@ void WindowInnerManager::DestroyThread(std::unique_ptr<WindowMessage> msg)
|
||||
{
|
||||
hasInitThread_ = false;
|
||||
needDestroyThread_ = true;
|
||||
isDeviderImageLoaded = false;
|
||||
WLOGFI("DestroyThread success");
|
||||
}
|
||||
|
||||
|
||||
@@ -47,6 +47,17 @@ void WindowLayoutPolicy::UpdateDisplayInfo(const Rect& primaryRect,
|
||||
UpdateDefaultFoatingRect();
|
||||
}
|
||||
|
||||
void WindowLayoutPolicy::UpdateSplitInfo(const Rect& primaryRect, const Rect& secondaryRect)
|
||||
{
|
||||
dependRects.priRect_ = primaryRect;
|
||||
dependRects.secRect_ = secondaryRect;
|
||||
dependRects.limitPriRect_ = dependRects.priRect_;
|
||||
dependRects.limitSecRect_ = dependRects.secRect_;
|
||||
|
||||
UpdateSplitLimitRect(dependRects.limitFullRect_, dependRects.limitPriRect_);
|
||||
UpdateSplitLimitRect(dependRects.limitFullRect_, dependRects.limitSecRect_);
|
||||
}
|
||||
|
||||
void WindowLayoutPolicy::LayoutWindowTree()
|
||||
{
|
||||
InitLimitRects();
|
||||
@@ -131,7 +142,6 @@ void WindowLayoutPolicy::RemoveWindowNode(sptr<WindowNode>& node)
|
||||
if (avoidTypes_.find(type) != avoidTypes_.end()) {
|
||||
LayoutWindowTree();
|
||||
} else if (type == WindowType::WINDOW_TYPE_DOCK_SLICE) { // split screen mode
|
||||
// TODO: change split screen
|
||||
LayoutWindowTree();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -517,6 +517,14 @@ void WindowNodeContainer::UpdateDisplayInfo()
|
||||
layoutPolicy_->UpdateDisplayInfo(primaryRect, secondaryRect, displayRect);
|
||||
}
|
||||
|
||||
void WindowNodeContainer::UpdateSplitInfo()
|
||||
{
|
||||
// update for split
|
||||
const Rect& primaryRect = displayRects_->GetRectByWindowMode(WindowMode::WINDOW_MODE_SPLIT_PRIMARY);
|
||||
const Rect& secondaryRect = displayRects_->GetRectByWindowMode(WindowMode::WINDOW_MODE_SPLIT_SECONDARY);
|
||||
layoutPolicy_->UpdateSplitInfo(primaryRect, secondaryRect);
|
||||
}
|
||||
|
||||
void WindowNodeContainer::LayoutDividerWindow(sptr<WindowNode>& node)
|
||||
{
|
||||
layoutPolicy_->UpdateLayoutRect(node);
|
||||
@@ -709,7 +717,7 @@ WMError WindowNodeContainer::HandleModeChangeToSplit(sptr<WindowNode>& triggerNo
|
||||
displayRects_->SetSplitRect(DEFAULT_SPLIT_RATIO);
|
||||
SendSplitScreenEvent(triggerNode->GetWindowMode());
|
||||
}
|
||||
UpdateDisplayInfo();
|
||||
UpdateSplitInfo();
|
||||
return WMError::WM_OK;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user