Introduce an experimental island

This commit is contained in:
Venkata Sharath Chandra Manchala 2024-05-15 12:53:59 -07:00
Родитель 480b6ac379
Коммит a092212d47
10 изменённых файлов: 214 добавлений и 62 удалений

Просмотреть файл

@ -9,8 +9,8 @@
},
"Microsoft.JavaScript.Hermes": {
"type": "Transitive",
"resolved": "0.1.18",
"contentHash": "5K8rRihGwIs2XNOTP2Jsw3T6cegxCBQXcpPS4optONU/AmFElGAfnA6XBQJ4UqlCFCl9Nf9zQrgvCUPBWYHiag=="
"resolved": "0.1.21",
"contentHash": "5njCh+3eXTLOv7+8nOnp6nJ5C0r6it5ze54c0nuWleeDptuK8t3dEDB79XTU4D5DKNvAPlqJpgXRDOak5nYIug=="
},
"Microsoft.VCRTForwarders.140": {
"type": "Transitive",
@ -51,7 +51,7 @@
"dependencies": {
"Common": "[1.0.0, )",
"Folly": "[1.0.0, )",
"Microsoft.JavaScript.Hermes": "[0.1.18, )",
"Microsoft.JavaScript.Hermes": "[0.1.21, )",
"Microsoft.WindowsAppSDK": "[1.5.240227000, )",
"ReactCommon": "[1.0.0, )",
"boost": "[1.76.0, )"
@ -67,7 +67,7 @@
"sampleappfabric": {
"type": "Project",
"dependencies": {
"Microsoft.JavaScript.Hermes": "[0.1.18, )",
"Microsoft.JavaScript.Hermes": "[0.1.21, )",
"Microsoft.ReactNative": "[1.0.0, )",
"Microsoft.VCRTForwarders.140": "[1.0.2-rc, )",
"Microsoft.WindowsAppSDK": "[1.5.240227000, )",

Просмотреть файл

@ -24,21 +24,6 @@ float ScaleFactor(HWND hwnd) noexcept {
return GetDpiForWindow(hwnd) / static_cast<float>(USER_DEFAULT_SCREEN_DPI);
}
void UpdateRootViewSizeToAppWindow(
winrt::Microsoft::ReactNative::CompositionRootView const &rootView,
winrt::Microsoft::UI::Windowing::AppWindow const &window) {
auto hwnd = winrt::Microsoft::UI::GetWindowFromWindowId(window.Id());
auto scaleFactor = ScaleFactor(hwnd);
winrt::Windows::Foundation::Size size{
window.ClientSize().Width / scaleFactor, window.ClientSize().Height / scaleFactor};
// Do not relayout when minimized
if (window.Presenter().as<winrt::Microsoft::UI::Windowing::OverlappedPresenter>().State() !=
winrt::Microsoft::UI::Windowing::OverlappedPresenterState::Minimized) {
rootView.Arrange(size);
rootView.Size(size);
}
}
// Create and configure the ReactNativeHost
winrt::Microsoft::ReactNative::ReactNativeHost CreateReactNativeHost(
HWND hwnd,
@ -106,19 +91,17 @@ _Use_decl_annotations_ int CALLBACK WinMain(HINSTANCE instance, HINSTANCE, PSTR
// Start the react-native instance, which will create a JavaScript runtime and load the applications bundle
host.ReloadInstance();
// Create a RootView which will present a react-native component
winrt::Microsoft::ReactNative::ReactViewOptions viewOptions;
viewOptions.ComponentName(mainComponentName);
auto rootView = winrt::Microsoft::ReactNative::CompositionRootView(compositor);
rootView.ReactViewHost(winrt::Microsoft::ReactNative::ReactCoreInjection::MakeViewHost(host, viewOptions));
// Create a ReactNative Island
auto reactNativeIsland =
winrt::Microsoft::ReactNative::ReactNativeIsland::Create(compositor, window, host, mainComponentName);
// Update the size of the RootView when the AppWindow changes size
window.Changed([wkRootView = winrt::make_weak(rootView)](
window.Changed([wkreactNativeIsland = winrt::make_weak(reactNativeIsland)](
winrt::Microsoft::UI::Windowing::AppWindow const &window,
winrt::Microsoft::UI::Windowing::AppWindowChangedEventArgs const &args) {
if (args.DidSizeChange() || args.DidVisibilityChange()) {
if (auto rootView = wkRootView.get()) {
UpdateRootViewSizeToAppWindow(rootView, window);
if (auto reactNativeIsland = wkreactNativeIsland.get()) {
reactNativeIsland.UpdateRootViewSizeToAppWindow(window);
}
}
});
@ -137,14 +120,9 @@ _Use_decl_annotations_ int CALLBACK WinMain(HINSTANCE instance, HINSTANCE, PSTR
// DesktopChildSiteBridge create a ContentSite that can host the RootView ContentIsland
auto bridge = winrt::Microsoft::UI::Content::DesktopChildSiteBridge::Create(compositor, window.Id());
bridge.Connect(rootView.Island());
bridge.Connect(reactNativeIsland.Island());
bridge.ResizePolicy(winrt::Microsoft::UI::Content::ContentSizePolicy::ResizeContentToParentWindow);
rootView.ScaleFactor(scaleFactor);
// Set the intialSize of the root view
UpdateRootViewSizeToAppWindow(rootView, window);
bridge.Show();
// Run the main application event loop

Просмотреть файл

@ -10,9 +10,9 @@
},
"Microsoft.JavaScript.Hermes": {
"type": "Direct",
"requested": "[0.1.18, )",
"resolved": "0.1.18",
"contentHash": "5K8rRihGwIs2XNOTP2Jsw3T6cegxCBQXcpPS4optONU/AmFElGAfnA6XBQJ4UqlCFCl9Nf9zQrgvCUPBWYHiag=="
"requested": "[0.1.21, )",
"resolved": "0.1.21",
"contentHash": "5njCh+3eXTLOv7+8nOnp6nJ5C0r6it5ze54c0nuWleeDptuK8t3dEDB79XTU4D5DKNvAPlqJpgXRDOak5nYIug=="
},
"Microsoft.VCRTForwarders.140": {
"type": "Direct",
@ -61,7 +61,7 @@
"dependencies": {
"Common": "[1.0.0, )",
"Folly": "[1.0.0, )",
"Microsoft.JavaScript.Hermes": "[0.1.18, )",
"Microsoft.JavaScript.Hermes": "[0.1.21, )",
"Microsoft.WindowsAppSDK": "[1.5.240227000, )",
"ReactCommon": "[1.0.0, )",
"boost": "[1.76.0, )"

Просмотреть файл

@ -310,6 +310,10 @@
<DependentUpon>ReactNativeHost.idl</DependentUpon>
<SubType>Code</SubType>
</ClInclude>
<ClInclude Include="ReactNativeIsland.h">
<DependentUpon>ReactNativeIsland.idl</DependentUpon>
<SubType>Code</SubType>
</ClInclude>
<ClInclude Include="Timer.h">
<DependentUpon>Timer.idl</DependentUpon>
<SubType>Code</SubType>

Просмотреть файл

@ -77,3 +77,10 @@
#include <activeObject/activeObject.h>
#include <functional/functorRef.h>
#include <future/future.h>
#include <winrt/Microsoft.ReactNative.h>
#include <winrt/Microsoft.ReactNative.Composition.h>
#include <winrt/Microsoft.UI.Composition.h>
#include <winrt/Microsoft.UI.Input.h>
#include <winrt/Microsoft.UI.Windowing.h>
#include <winrt/Microsoft.UI.h>

Просмотреть файл

@ -0,0 +1,96 @@
#include "pch.h"
#include "ReactNativeIsland.h"
#include "ReactNativeIsland.g.cpp"
#include <winrt/Microsoft.UI.Interop.h>
namespace winrt::ReactNative
{
using namespace winrt::Microsoft::ReactNative;
using namespace winrt::Microsoft::ReactNative::Composition;
}
namespace winrt::UI
{
using namespace winrt::Microsoft::UI::Composition;
using namespace winrt::Microsoft::UI::Content;
using namespace winrt::Microsoft::UI::Input;
using namespace winrt::Microsoft::UI::Windowing;
}
float ScaleFactor(HWND hwnd) noexcept {
return GetDpiForWindow(hwnd) / static_cast<float>(USER_DEFAULT_SCREEN_DPI);
}
namespace winrt::Microsoft::ReactNative::implementation
{
winrt::ReactNative::ReactNativeIsland ReactNativeIsland::Create(
winrt::UI::Compositor const& compositor,
winrt::UI::AppWindow const& window,
winrt::ReactNative::ReactNativeHost const& host,
winrt::hstring const& mainComponentName)
{
return winrt::make<ReactNativeIsland>(compositor, window, host, mainComponentName);
}
ReactNativeIsland::~ReactNativeIsland()
{
m_island.Close();
}
void ReactNativeIsland::ApplyScaleFactor(winrt::UI::AppWindow const& window)
{
auto hwnd = winrt::Microsoft::UI::GetWindowFromWindowId(window.Id());
m_scaleFactor = ScaleFactor(hwnd);
}
ReactNativeIsland::ReactNativeIsland(
winrt::UI::Compositor const& compositor,
winrt::UI::AppWindow const& window,
winrt::ReactNative::ReactNativeHost const& host,
winrt::hstring const& mainComponentName)
: m_compositor(compositor)
{
ApplyScaleFactor(window);
winrt::ReactNative::ReactViewOptions viewOptions;
viewOptions.ComponentName(mainComponentName);
// Create a RootView (creates a spriteVisual) and associates it with an island
m_rootView = winrt::ReactNative::CompositionRootView(m_compositor);
m_rootView.ReactViewHost(
winrt::ReactNative::ReactCoreInjection::MakeViewHost(host, viewOptions));
// Create a contentIsland
m_island = m_rootView.Island();
auto invScale = 1.0f / m_scaleFactor;
m_rootView.RootVisual().Scale({ invScale, invScale, invScale });
m_rootView.ScaleFactor(m_scaleFactor);
// Set the intialSize of the root view
UpdateRootViewSizeToAppWindow(window);
// Lifted input base setup.
m_mouseInput = winrt::UI::InputPointerSource::GetForIsland(m_island);
m_keyboardInput = winrt::UI::InputKeyboardSource::GetForIsland(m_island);
}
void ReactNativeIsland::InitalizeInputHandlers()
{
throw winrt::hresult_not_implemented();
}
void ReactNativeIsland::UpdateRootViewSizeToAppWindow(
winrt::Microsoft::UI::Windowing::AppWindow const& window) {
winrt::Windows::Foundation::Size size{
window.ClientSize().Width / m_scaleFactor, window.ClientSize().Height / m_scaleFactor };
// Do not relayout when minimized
if (window.Presenter().as<winrt::UI::OverlappedPresenter>().State() !=
winrt::UI::OverlappedPresenterState::Minimized) {
m_rootView.Arrange(size);
m_rootView.Size(size);
}
}
}

Просмотреть файл

@ -0,0 +1,54 @@
#pragma once
#include "ReactNativeIsland.g.h"
namespace winrt::Microsoft::ReactNative::implementation
{
struct ReactNativeIsland : ReactNativeIslandT<ReactNativeIsland>
{
ReactNativeIsland() = default;
ReactNativeIsland(
const winrt::Microsoft::UI::Composition::Compositor& compositor,
winrt::Microsoft::UI::Windowing::AppWindow const& window,
winrt::Microsoft::ReactNative::ReactNativeHost const& host,
winrt::hstring const& mainComponentName);
~ReactNativeIsland();
static winrt::Microsoft::ReactNative::ReactNativeIsland Create(
winrt::Microsoft::UI::Composition::Compositor const& compositor,
winrt::Microsoft::UI::Windowing::AppWindow const& window,
winrt::Microsoft::ReactNative::ReactNativeHost const& host,
winrt::hstring const& mainComponentName);
winrt::Microsoft::UI::Content::ContentIsland Island() const
{
return m_island;
}
void UpdateRootViewSizeToAppWindow(
winrt::Microsoft::UI::Windowing::AppWindow const& window);
private:
void ApplyScaleFactor(winrt::Microsoft::UI::Windowing::AppWindow const& window);
// Initialize Mouse and Keyboard input handlers
void InitalizeInputHandlers();
winrt::Microsoft::UI::Composition::Compositor m_compositor{nullptr};
winrt::Microsoft::ReactNative::CompositionRootView m_rootView { nullptr };
winrt::Microsoft::UI::Content::ContentIsland m_island{ nullptr };
float m_scaleFactor{ 0 };
// Input objects.
winrt::Microsoft::UI::Input::InputPointerSource m_mouseInput{ nullptr };
winrt::Microsoft::UI::Input::InputKeyboardSource m_keyboardInput{ nullptr };
};
}
namespace winrt::Microsoft::ReactNative::factory_implementation
{
struct ReactNativeIsland : ReactNativeIslandT<ReactNativeIsland, implementation::ReactNativeIsland>
{
};
}

Просмотреть файл

@ -0,0 +1,29 @@
import "CompositionSwitcher.idl";
import "CompositionRootView.idl";
import "ReactNativeHost.idl";
namespace Microsoft.ReactNative
{
#ifdef USE_WINUI3
runtimeclass ReactNativeIsland
{
// Create the ReactNativeIsland which sets up the contentIsland and the
// CompositionRootView
// This Island makes the assumption that we have:
// One ReactNativeHost that is mapped to one JSBundle with one JsApp(rootview) in the bundle.
static ReactNativeIsland Create(
Microsoft.UI.Composition.Compositor compositor,
Microsoft.UI.Windowing.AppWindow window,
Microsoft.ReactNative.ReactNativeHost host,
String mainComponentName);
// Each RNIsland has one ContentIsland and the ContentIsland is associated to single JsApp.
Microsoft.UI.Content.ContentIsland Island{ get; };
// Updates Root view size with respect to AppWindow size change
void UpdateRootViewSizeToAppWindow(
Microsoft.UI.Windowing.AppWindow window);
}
#endif
}

Просмотреть файл

@ -10,19 +10,9 @@
},
"Microsoft.JavaScript.Hermes": {
"type": "Direct",
"requested": "[0.1.18, )",
"resolved": "0.1.18",
"contentHash": "5K8rRihGwIs2XNOTP2Jsw3T6cegxCBQXcpPS4optONU/AmFElGAfnA6XBQJ4UqlCFCl9Nf9zQrgvCUPBWYHiag=="
},
"Microsoft.SourceLink.GitHub": {
"type": "Direct",
"requested": "[1.1.1, )",
"resolved": "1.1.1",
"contentHash": "IaJGnOv/M7UQjRJks7B6p7pbPnOwisYGOIzqCz5ilGFTApZ3ktOR+6zJ12ZRPInulBmdAf1SrGdDG2MU8g6XTw==",
"dependencies": {
"Microsoft.Build.Tasks.Git": "1.1.1",
"Microsoft.SourceLink.Common": "1.1.1"
}
"requested": "[0.1.21, )",
"resolved": "0.1.21",
"contentHash": "5njCh+3eXTLOv7+8nOnp6nJ5C0r6it5ze54c0nuWleeDptuK8t3dEDB79XTU4D5DKNvAPlqJpgXRDOak5nYIug=="
},
"Microsoft.Windows.CppWinRT": {
"type": "Direct",
@ -39,16 +29,6 @@
"Microsoft.Windows.SDK.BuildTools": "10.0.22621.756"
}
},
"Microsoft.Build.Tasks.Git": {
"type": "Transitive",
"resolved": "1.1.1",
"contentHash": "AT3HlgTjsqHnWpBHSNeR0KxbLZD7bztlZVj7I8vgeYG9SYqbeFGh0TM/KVtC6fg53nrWHl3VfZFvb5BiQFcY6Q=="
},
"Microsoft.SourceLink.Common": {
"type": "Transitive",
"resolved": "1.1.1",
"contentHash": "WMcGpWKrmJmzrNeuaEb23bEMnbtR/vLmvZtkAP5qWu7vQsY59GqfRJd65sFpBszbd2k/bQ8cs8eWawQKAabkVg=="
},
"Microsoft.Windows.SDK.BuildTools": {
"type": "Transitive",
"resolved": "10.0.22621.756",
@ -66,8 +46,8 @@
"folly": {
"type": "Project",
"dependencies": {
"Fmt": "[1.0.0, )",
"boost": "[1.76.0, )"
"boost": "[1.76.0, )",
"fmt": "[1.0.0, )"
}
},
"reactcommon": {

Просмотреть файл

@ -335,6 +335,9 @@
<ClCompile Include="$(MSBuildThisFileDirectory)..\Microsoft.ReactNative\ReactNativeHost.cpp">
<DependentUpon>$(MSBuildThisFileDirectory)..\Microsoft.ReactNative\ReactNativeHost.idl</DependentUpon>
</ClCompile>
<ClCompile Include="$(MSBuildThisFileDirectory)..\Microsoft.ReactNative\ReactNativeIsland.cpp">
<DependentUpon>$(MSBuildThisFileDirectory)..\Microsoft.ReactNative\ReactNativeIsland.idl</DependentUpon>
</ClCompile>
<ClCompile Include="$(MSBuildThisFileDirectory)..\Microsoft.ReactNative\RedBoxHandler.cpp">
<DependentUpon>$(MSBuildThisFileDirectory)..\Microsoft.ReactNative\RedBoxHandler.idl</DependentUpon>
</ClCompile>
@ -637,6 +640,7 @@
<Midl Include="$(MSBuildThisFileDirectory)..\Microsoft.ReactNative\ReactNativeHost.idl" />
<Midl Include="$(MSBuildThisFileDirectory)..\Microsoft.ReactNative\RedBoxHandler.idl" />
<Midl Include="$(MSBuildThisFileDirectory)..\Microsoft.ReactNative\Timer.idl" />
<Midl Include="$(MSBuildThisFileDirectory)..\Microsoft.ReactNative\ReactNativeIsland.idl" />
</ItemGroup>
<ItemGroup Condition="'$(UseFabric)' == 'true' OR '$(IncludeFabricInterface)' == 'true'">
<Midl Condition="'$(UseFabric)' == 'true' OR '$(IncludeFabricInterface)' == 'true'" Include="$(ReactNativeWindowsDir)Microsoft.ReactNative\ComponentView.idl" />