Skip to content

Commit

Permalink
Move CompositionSwitcher to Experimental namespace (#12960) (#12971)
Browse files Browse the repository at this point in the history
* Move CompositionSwitcher to Experimental namespace

* Change files

* fix

* fix

* fix

* format

* fix

* fix

* format

Co-authored-by: Jon Thysell <jthysell@microsoft.com>
  • Loading branch information
acoates-ms and jonthysell committed Apr 23, 2024
1 parent b8fcbff commit 377d16d
Show file tree
Hide file tree
Showing 63 changed files with 744 additions and 532 deletions.
@@ -0,0 +1,7 @@
{
"type": "prerelease",
"comment": "Move CompositionSwitcher to Experimental namespace",
"packageName": "react-native-windows",
"email": "30809111+acoates-ms@users.noreply.github.com",
"dependentChangeType": "patch"
}
Expand Up @@ -99,11 +99,7 @@ winrt::Microsoft::ReactNative::ReactNativeHost CreateReactNativeHost(
winrt::Microsoft::ReactNative::ReactCoreInjection::SetTopLevelWindowId(
host.InstanceSettings().Properties(), reinterpret_cast<uint64_t>(hwnd));

// By using the MicrosoftCompositionContextHelper here, React Native Windows will use Lifted Visuals for its
// tree.
winrt::Microsoft::ReactNative::Composition::CompositionUIService::SetCompositionContext(
host.InstanceSettings().Properties(),
winrt::Microsoft::ReactNative::Composition::MicrosoftCompositionContextHelper::CreateContext(compositor));
winrt::Microsoft::ReactNative::Composition::CompositionUIService::SetCompositor(host.InstanceSettings(), compositor);

return host;
}
Expand Down Expand Up @@ -170,8 +166,6 @@ _Use_decl_annotations_ int CALLBACK WinMain(HINSTANCE instance, HINSTANCE, PSTR
bridge.Connect(rootView.Island());
bridge.ResizePolicy(winrt::Microsoft::UI::Content::ContentSizePolicy::ResizeContentToParentWindow);

auto invScale = 1.0f / scaleFactor;
rootView.RootVisual().Scale({invScale, invScale, invScale});
rootView.ScaleFactor(scaleFactor);

// Set the intialSize of the root view
Expand Down Expand Up @@ -380,8 +374,7 @@ winrt::Windows::Data::Json::JsonObject DumpVisualTreeRecurse(
winrt::Windows::Data::Json::JsonObject DumpVisualTreeHelper(winrt::Windows::Data::Json::JsonObject payloadObj) {
auto accessibilityId = payloadObj.GetNamedString(L"accessibilityId");
winrt::Windows::Data::Json::JsonObject visualTree;
auto root = winrt::Microsoft::ReactNative::Composition::MicrosoftCompositionContextHelper::InnerVisual(
global_rootView->RootVisual());
auto root = global_rootView->RootVisual();
visualTree = DumpVisualTreeRecurse(root, accessibilityId, false);
return visualTree;
}
Expand Down
2 changes: 1 addition & 1 deletion packages/playground/windows/ExperimentalFeatures.props
Expand Up @@ -3,7 +3,6 @@

<PropertyGroup Label="Microsoft.ReactNative Experimental Features">
<UseHermes>true</UseHermes>
<UseFabric>true</UseFabric>
<UseWinUI3>false</UseWinUI3>
<UseExperimentalWinUI3>false</UseExperimentalWinUI3>
<EnableSourceLink>true</EnableSourceLink>
Expand All @@ -20,6 +19,7 @@
</PropertyGroup>

<PropertyGroup Label="WinUI3 for fabric" Condition="'$(SolutionName)'=='playground-composition'">
<UseFabric>true</UseFabric>
<UseWinUI3>true</UseWinUI3>
</PropertyGroup>

Expand Down
Expand Up @@ -100,7 +100,7 @@ struct CustomComponent : CustomComponentT<CustomComponent> {
base_type::FinalizeUpdates(updateMask);
}

winrt::Microsoft::ReactNative::Composition::IVisual CreateVisual() noexcept {
winrt::Microsoft::UI::Composition::Visual CreateVisual() noexcept {
#ifdef USE_EXPERIMENTAL_WINUI3

m_xamlIsland = winrt::Microsoft::UI::Xaml::XamlIsland{};
Expand All @@ -109,19 +109,15 @@ struct CustomComponent : CustomComponentT<CustomComponent> {
m_contentIsland = m_xamlIsland.ContentIsland();
#endif

m_visual = CompositionContext().CreateSpriteVisual();
m_visual = Compositor().CreateSpriteVisual();
// m_visual.Brush(CompositionContext().CreateColorBrush({255, 255, 0, 255}));
#ifdef USE_EXPERIMENTAL_WINUI3

auto parentSystemVisual =
winrt::Microsoft::ReactNative::Composition::SystemCompositionContextHelper::InnerVisual(m_visual)
.as<winrt::Windows::UI::Composition::ContainerVisual>();

auto hwnd = reinterpret_cast<HWND>(
winrt::Microsoft::ReactNative::ReactCoreInjection::GetTopLevelWindowId(ReactContext().Properties()));

m_siteBridge = winrt::Microsoft::UI::Content::SystemVisualSiteBridge::Create(
m_contentIsland.Compositor(), parentSystemVisual, winrt::Microsoft::UI::GetWindowIdFromWindow(hwnd));
m_contentIsland.Compositor(), m_visual, winrt::Microsoft::UI::GetWindowIdFromWindow(hwnd));
m_siteBridge.Connect(m_contentIsland);

auto rootXamlVisualSize = m_contentIsland.Root().Size();
Expand Down Expand Up @@ -171,7 +167,7 @@ struct CustomComponent : CustomComponentT<CustomComponent> {
const bool m_nativeLayout;
winrt::Microsoft::UI::Xaml::Controls::TextBlock m_buttonLabelTextBlock{nullptr};
winrt::Microsoft::ReactNative::IComponentState m_state;
winrt::Microsoft::ReactNative::Composition::ISpriteVisual m_visual{nullptr};
winrt::Microsoft::UI::Composition::Visual m_visual{nullptr};
#ifdef USE_EXPERIMENTAL_WINUI3
winrt::Microsoft::UI::Xaml::XamlIsland m_xamlIsland{nullptr};
winrt::Microsoft::UI::Content::ContentIsland m_contentIsland{nullptr};
Expand Down
Expand Up @@ -16,6 +16,7 @@
#include <UIAutomation.h>
#include <windows.ui.composition.interop.h>

#include <winrt/Microsoft.ReactNative.Composition.Experimental.h>
#include <winrt/Microsoft.ReactNative.Composition.h>
#include <winrt/Windows.UI.Composition.Desktop.h>
#include <winrt/Windows.UI.Composition.h>
Expand Down Expand Up @@ -176,32 +177,15 @@ struct WindowData {
}

if (windowData->m_useLiftedComposition) {
// By using the MicrosoftCompositionContextHelper here, React Native Windows will use Lifted Visuals for
// its tree.
winrt::Microsoft::ReactNative::Composition::CompositionUIService::SetCompositionContext(
InstanceSettings().Properties(),
winrt::Microsoft::ReactNative::Composition::MicrosoftCompositionContextHelper::CreateContext(
g_liftedCompositor));
// By setting the compositor here we opt into using the new architecture.
winrt::Microsoft::ReactNative::Composition::CompositionUIService::SetCompositor(
InstanceSettings(), g_liftedCompositor);

auto bridge = winrt::Microsoft::UI::Content::DesktopChildSiteBridge::Create(
g_liftedCompositor, winrt::Microsoft::UI::GetWindowIdFromWindow(hwnd));

auto appContent = m_compRootView.Island();

auto invScale = 1.0f / ScaleFactor(hwnd);
m_compRootView.RootVisual().Scale({invScale, invScale, invScale});

/*
// Future versions of WinAppSDK will have more capabilities around scale and size
auto site = bridge.Site();
auto siteWindow = site.Environment();
auto displayScale = siteWindow.DisplayScale();
site.ParentScale(displayScale);
site.ActualSize({m_width / displayScale, m_height / displayScale});
site.ClientSize({m_width / displayScale, m_height / displayScale});
*/

bridge.Connect(appContent);
bridge.Show();

Expand All @@ -211,12 +195,16 @@ struct WindowData {
bridge.ResizePolicy(winrt::Microsoft::UI::Content::ContentSizePolicy::ResizeContentToParentWindow);

} else if (!m_target) {
// By using the SystemCompositionContextHelper here, React Native Windows will use System Visuals for its
// tree.
winrt::Microsoft::ReactNative::Composition::CompositionUIService::SetCompositionContext(
InstanceSettings().Properties(),
winrt::Microsoft::ReactNative::Composition::SystemCompositionContextHelper::CreateContext(
g_compositor));
// General users of RNW should never set CompositionContext - this is an advanced usage to inject another
// composition implementation. By using the SystemCompositionContextHelper here, React Native Windows will
// use System Visuals for its tree.
winrt::Microsoft::ReactNative::ReactPropertyBag(InstanceSettings().Properties())
.Set(
winrt::Microsoft::ReactNative::ReactPropertyId<
winrt::Microsoft::ReactNative::Composition::Experimental::ICompositionContext>{
L"ReactNative.Composition", L"CompositionContext"},
winrt::Microsoft::ReactNative::Composition::Experimental::SystemCompositionContextHelper::
CreateContext(g_compositor));

auto interop = g_compositor.as<ABI::Windows::UI::Composition::Desktop::ICompositorDesktopInterop>();
winrt::Windows::UI::Composition::Desktop::DesktopWindowTarget target{nullptr};
Expand All @@ -231,9 +219,13 @@ struct WindowData {
root.RelativeSizeAdjustment({1.0f, 1.0f});
root.Offset({0, 0, 0});
m_target.Root(root);
m_compRootView.SetWindow(reinterpret_cast<uint64_t>(hwnd));
m_compRootView.RootVisual(
winrt::Microsoft::ReactNative::Composition::SystemCompositionContextHelper::CreateVisual(root));
m_compRootView
.as<winrt::Microsoft::ReactNative::Composition::Experimental::IInternalCompositionRootView>()
.SetWindow(reinterpret_cast<uint64_t>(hwnd));
m_compRootView
.as<winrt::Microsoft::ReactNative::Composition::Experimental::IInternalCompositionRootView>()
.InternalRootVisual(winrt::Microsoft::ReactNative::Composition::Experimental::
SystemCompositionContextHelper::CreateVisual(root));
m_compRootView.ScaleFactor(ScaleFactor(hwnd));
m_compRootView.Size({m_width / ScaleFactor(hwnd), m_height / ScaleFactor(hwnd)});
}
Expand Down Expand Up @@ -307,7 +299,9 @@ struct WindowData {

LRESULT TranslateMessage(HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam) noexcept {
if (!m_useLiftedComposition && m_compRootView) {
return static_cast<LRESULT>(m_compRootView.SendMessage(message, wparam, lparam));
return static_cast<LRESULT>(
m_compRootView.as<winrt::Microsoft::ReactNative::Composition::Experimental::IInternalCompositionRootView>()
.SendMessage(message, wparam, lparam));
}
return 0;
}
Expand Down
1 change: 1 addition & 0 deletions vnext/Desktop/React.Windows.Desktop.vcxproj
Expand Up @@ -53,6 +53,7 @@
<V8AppPlatform>win32</V8AppPlatform>
<HermesCompileRtti>false</HermesCompileRtti>
<IncludeFabricInterface Condition="'$(IncludeFabricInterface)' == ''">true</IncludeFabricInterface>
<UseWinUI3 Condition="'$(UseWinUI3)' == ''">true</UseWinUI3>
</PropertyGroup>
<PropertyGroup Label="Permissive">
<ENABLEPermissive>true</ENABLEPermissive>
Expand Down
12 changes: 6 additions & 6 deletions vnext/Desktop/module.g.cpp
Expand Up @@ -8,9 +8,9 @@
void* winrt_make_Microsoft_Internal_TestController();
void* winrt_make_Microsoft_ReactNative_CompositionRootView();
#ifdef USE_WINUI3
void *winrt_make_Microsoft_ReactNative_Composition_MicrosoftCompositionContextHelper();
void *winrt_make_Microsoft_ReactNative_Composition_Experimental_MicrosoftCompositionContextHelper();
#endif
void *winrt_make_Microsoft_ReactNative_Composition_SystemCompositionContextHelper();
void *winrt_make_Microsoft_ReactNative_Composition_Experimental_SystemCompositionContextHelper();
void *winrt_make_Microsoft_ReactNative_Composition_CompositionUIService();
void* winrt_make_Microsoft_ReactNative_JsiRuntime();
void* winrt_make_Microsoft_ReactNative_ReactCoreInjection();
Expand Down Expand Up @@ -50,12 +50,12 @@ void* __stdcall winrt_get_activation_factory([[maybe_unused]] std::wstring_view
return winrt_make_Microsoft_ReactNative_CompositionRootView();
}
#ifdef USE_WINUI3
if (requal(name, L"Microsoft.ReactNative.Composition.MicrosoftCompositionContextHelper")) {
return winrt_make_Microsoft_ReactNative_Composition_MicrosoftCompositionContextHelper();
if (requal(name, L"Microsoft.ReactNative.Composition.Experimental.MicrosoftCompositionContextHelper")) {
return winrt_make_Microsoft_ReactNative_Composition_Experimental_MicrosoftCompositionContextHelper();
}
#endif
if (requal(name, L"Microsoft.ReactNative.Composition.SystemCompositionContextHelper")) {
return winrt_make_Microsoft_ReactNative_Composition_SystemCompositionContextHelper();
if (requal(name, L"Microsoft.ReactNative.Composition.Experimental.SystemCompositionContextHelper")) {
return winrt_make_Microsoft_ReactNative_Composition_Experimental_SystemCompositionContextHelper();
}
if (requal(name, L"Microsoft.ReactNative.Composition.CompositionUIService")) {
return winrt_make_Microsoft_ReactNative_Composition_CompositionUIService();
Expand Down
6 changes: 3 additions & 3 deletions vnext/Microsoft.ReactNative.Cxx/AutoDraw.h
Expand Up @@ -3,14 +3,14 @@

#include <winrt/Microsoft.ReactNative.Composition.h>

#include <CompositionSwitcher.interop.h>
#include <CompositionSwitcher.Experimental.interop.h>

namespace Microsoft::ReactNative::Composition {

class AutoDrawDrawingSurface {
public:
AutoDrawDrawingSurface(
winrt::Microsoft::ReactNative::Composition::IDrawingSurfaceBrush &drawingSurface,
winrt::Microsoft::ReactNative::Composition::Experimental::IDrawingSurfaceBrush &drawingSurface,
POINT *offset) noexcept {
drawingSurface.as(m_drawingSurfaceInterop);
m_drawingSurfaceInterop->BeginDraw(m_d2dDeviceContext.put(), offset);
Expand All @@ -31,7 +31,7 @@ class AutoDrawDrawingSurface {
}

private:
winrt::com_ptr<ICompositionDrawingSurfaceInterop> m_drawingSurfaceInterop;
winrt::com_ptr<Experimental::ICompositionDrawingSurfaceInterop> m_drawingSurfaceInterop;
winrt::com_ptr<ID2D1DeviceContext> m_d2dDeviceContext;
};

Expand Down
Expand Up @@ -12,7 +12,7 @@
#include <winrt/Microsoft.ReactNative.Composition.h>
#include <winrt/Windows.Graphics.DirectX.Direct3D11.h>

namespace Microsoft::ReactNative::Composition {
namespace Microsoft::ReactNative::Composition::Experimental {

struct __declspec(uuid("941FDD90-ED27-49CE-A1CD-86ECB2D4A0FA")) ICompositionDrawingSurfaceInterop : public IUnknown {
virtual HRESULT BeginDraw(ID2D1DeviceContext **deviceContextOut, POINT *offset) noexcept = 0;
Expand All @@ -31,4 +31,4 @@ struct __declspec(uuid("4742F122-3EE0-48AA-9EA9-44A00147B55F")) ICompositionCont
virtual void D2DFactory(ID2D1Factory1 **outD2DFactory) noexcept = 0;
};

} // namespace Microsoft::ReactNative::Composition
} // namespace Microsoft::ReactNative::Composition::Experimental
21 changes: 18 additions & 3 deletions vnext/Microsoft.ReactNative/CompositionComponentView.idl
Expand Up @@ -6,6 +6,7 @@ import "Theme.idl";
import "ViewProps.idl";
import "Composition.Input.idl";
import "CompositionSwitcher.idl";
import "IReactContext.idl";

#include "DocString.h"

Expand All @@ -28,7 +29,7 @@ namespace Microsoft.ReactNative.Composition
[experimental]
[webhosthidden]
runtimeclass CreateCompositionComponentViewArgs : Microsoft.ReactNative.CreateComponentViewArgs {
ICompositionContext CompositionContext { get; };
Microsoft.UI.Composition.Compositor Compositor { get; };
ComponentViewFeatures Features;
};

Expand All @@ -37,21 +38,35 @@ namespace Microsoft.ReactNative.Composition
unsealed runtimeclass ComponentView : Microsoft.ReactNative.ComponentView {
ComponentView(CreateCompositionComponentViewArgs args);

ICompositionContext CompositionContext { get; };
Microsoft.UI.Composition.Compositor Compositor { get; };
Theme Theme;
overridable void OnThemeChanged();
Boolean CapturePointer(Microsoft.ReactNative.Composition.Input.Pointer pointer);
void ReleasePointerCapture(Microsoft.ReactNative.Composition.Input.Pointer pointer);
};

namespace Experimental {
[webhosthidden]
[experimental]
DOC_STRING("Custom ViewComponents need to implement this interface to be able to provide a custom"
" visual using the composition context that allows custom compositors. This is only required for"
" custom components that need to support running in RNW instances with custom compositors. Most"
" custom components can just override CreateVisual on ViewComponentView."
" This will be removed in a future version")
interface IInternalCreateVisual
{
Microsoft.ReactNative.Composition.Experimental.IVisual CreateInternalVisual();
}
}

[experimental]
[webhosthidden]
unsealed runtimeclass ViewComponentView : ComponentView {
ViewComponentView(CreateCompositionComponentViewArgs args);

Microsoft.ReactNative.ViewProps ViewProps { get; };

overridable IVisual CreateVisual();
overridable Microsoft.UI.Composition.Visual CreateVisual();
};

[experimental]
Expand Down
10 changes: 5 additions & 5 deletions vnext/Microsoft.ReactNative/CompositionContext.idl
Expand Up @@ -5,17 +5,17 @@
#include "DocString.h"
import "CompositionSwitcher.idl";

namespace Microsoft.ReactNative.Composition
namespace Microsoft.ReactNative.Composition.Experimental
{
[webhosthidden]
[default_interface]
[experimental]
DOC_STRING("A helper static class for to create a @ICompositionContext based on Windows.Composition Visuals. And to access the underlying Windows.Composition objects from the abstraction.")
DOC_STRING("A helper static class to create a @ICompositionContext based on Windows.Composition Visuals. This is not for general consumption and is expected to be removed in a future release.")
static runtimeclass SystemCompositionContextHelper
{
DOC_STRING(
"Creates a @ICompositionContext from a Compositor")
static ICompositionContext CreateContext(Windows.UI.Composition.Compositor compositor);
static Microsoft.ReactNative.Composition.Experimental.ICompositionContext CreateContext(Windows.UI.Composition.Compositor compositor);

DOC_STRING(
"Creates a @IVisual from a Visual")
Expand All @@ -32,12 +32,12 @@ namespace Microsoft.ReactNative.Composition
[webhosthidden]
[default_interface]
[experimental]
DOC_STRING("A helper static class for to create a @ICompositionContext based on Microsoft.Composition Visuals. And to access the underlying Microsoft.Composition objects from the abstraction.")
DOC_STRING("A helper static class to create a @ICompositionContext based on Microsoft.Composition Visuals. Generally it should not be required to call this directly. Instead you should call @CompositionUIService.SetCompositor. This is not for general consumption and is expected to be removed in a future release.")
static runtimeclass MicrosoftCompositionContextHelper
{
DOC_STRING(
"Creates a @ICompositionContext from a Compositor")
static ICompositionContext CreateContext(Microsoft.UI.Composition.Compositor compositor);
static Microsoft.ReactNative.Composition.Experimental.ICompositionContext CreateContext(Microsoft.UI.Composition.Compositor compositor);

DOC_STRING(
"Creates a @IVisual from a Visual")
Expand Down

0 comments on commit 377d16d

Please sign in to comment.