diff --git a/resources/bg_split_handle.png b/resources/bg_split_handle.png new file mode 100644 index 00000000..16ca892e Binary files /dev/null and b/resources/bg_split_handle.png differ diff --git a/wmserver/BUILD.gn b/wmserver/BUILD.gn index a90a57f2..95d8de54 100644 --- a/wmserver/BUILD.gn +++ b/wmserver/BUILD.gn @@ -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 = [ diff --git a/wmserver/include/window_inner_manager.h b/wmserver/include/window_inner_manager.h index 4dc13984..ee5f4843 100644 --- a/wmserver/include/window_inner_manager.h +++ b/wmserver/include/window_inner_manager.h @@ -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 msg); void HideAndDestroyDivider(std::unique_ptr msg); void DestroyThread(std::unique_ptr msg); - void DrawSurface(const sptr& window, uint32_t color); + void DrawSurface(const sptr& window); sptr 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> messages_; bool hasInitThread_ = false; bool needDestroyThread_ = false; + bool isDeviderImageLoaded = false; + const char *splitIconPath_ = "/etc/window/resources/bg_split_handle.png"; + SkBitmap deviderBitmap; }; } } diff --git a/wmserver/include/window_layout_policy.h b/wmserver/include/window_layout_policy.h index c1f005f5..77625249 100644 --- a/wmserver/include/window_layout_policy.h +++ b/wmserver/include/window_layout_policy.h @@ -49,6 +49,7 @@ public: const sptr& appNode, const sptr& 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& node); void RemoveWindowNode(sptr& node); void UpdateWindowNode(sptr& node); diff --git a/wmserver/include/window_node_container.h b/wmserver/include/window_node_container.h index 74a734fe..fb16b727 100644 --- a/wmserver/include/window_node_container.h +++ b/wmserver/include/window_node_container.h @@ -51,6 +51,7 @@ public: std::shared_ptr GetDisplayNode() const; void LayoutDividerWindow(sptr& node); void UpdateDisplayInfo(); + void UpdateSplitInfo(); bool isVerticalDisplay() const; class DisplayRects : public RefBase { diff --git a/wmserver/src/window_inner_manager.cpp b/wmserver/src/window_inner_manager.cpp index 591db984..5eeaff94 100644 --- a/wmserver/src/window_inner_manager.cpp +++ b/wmserver/src/window_inner_manager.cpp @@ -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, uint32_t color) +bool WindowInnerManager::DecodeImageFile(const char* filename, SkBitmap* bitmap) +{ + sk_sp data(SkData::MakeFromFileName(filename)); + std::unique_ptr 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) { auto surfaceNode = window->GetSurfaceNode(); auto winRect = window->GetRect(); @@ -51,32 +68,35 @@ void WindowInnerManager::DrawSurface(const sptr& window, uint32_t color) rsSurface->SetRenderContext(rc_); #endif auto frame = rsSurface->RequestFrame(width, height); - std::unique_ptr 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(width), static_cast(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(height) / deviderBitmap.width(), + static_cast(width) / deviderBitmap.height()); + matrix.postRotate(-90.0f); // devider shader rotate -90.0 + } else { + matrix.setScale(static_cast(width) / deviderBitmap.width(), + static_cast(height) / deviderBitmap.height()); + } + paint.setShader(deviderBitmap.makeShader(SkTileMode::kRepeat, SkTileMode::kRepeat)); + paint.setShader(paint.getShader()->makeWithLocalMatrix(matrix)); + paintRect.set(0, 0, static_cast(width), static_cast(height)); + canvas->drawRect(paintRect, paint); + } + frame->SetDamageRegion(0, 0, width, height); + rsSurface->FlushFrame(frame); } @@ -137,8 +157,13 @@ void WindowInnerManager::CreateAndShowDivider(std::unique_ptr 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 msg) { hasInitThread_ = false; needDestroyThread_ = true; + isDeviderImageLoaded = false; WLOGFI("DestroyThread success"); } diff --git a/wmserver/src/window_layout_policy.cpp b/wmserver/src/window_layout_policy.cpp index 377cc40f..6f7f7f0a 100644 --- a/wmserver/src/window_layout_policy.cpp +++ b/wmserver/src/window_layout_policy.cpp @@ -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& node) if (avoidTypes_.find(type) != avoidTypes_.end()) { LayoutWindowTree(); } else if (type == WindowType::WINDOW_TYPE_DOCK_SLICE) { // split screen mode - // TODO: change split screen LayoutWindowTree(); } } diff --git a/wmserver/src/window_node_container.cpp b/wmserver/src/window_node_container.cpp index 4b377d35..5256ecaa 100644 --- a/wmserver/src/window_node_container.cpp +++ b/wmserver/src/window_node_container.cpp @@ -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& node) { layoutPolicy_->UpdateLayoutRect(node); @@ -709,7 +717,7 @@ WMError WindowNodeContainer::HandleModeChangeToSplit(sptr& triggerNo displayRects_->SetSplitRect(DEFAULT_SPLIT_RATIO); SendSplitScreenEvent(triggerNode->GetWindowMode()); } - UpdateDisplayInfo(); + UpdateSplitInfo(); return WMError::WM_OK; }