From 459d7fa81935d68e5e57fb5ab3746557747d73ea Mon Sep 17 00:00:00 2001 From: Andrew Coates <30809111+acoates-ms@users.noreply.github.com> Date: Wed, 11 Oct 2023 12:47:50 -0700 Subject: [PATCH 1/6] Initial Islands support --- .../CustomComponent.cpp | 123 ++++++ .../DeviceInfoModule.cpp | 46 ++ .../Playground-Composition.cpp | 406 +++++++++--------- .../Playground-Composition.rc | 2 +- .../Playground-Composition.vcxproj | 2 + .../windows/playground-composition/resource.h | 2 +- .../CompositionRootView.idl | 8 + .../Fabric/Composition/Composition.Input.cpp | 195 +++++++-- .../Fabric/Composition/Composition.Input.h | 20 +- .../Composition/CompositionEventHandler.cpp | 118 ++++- .../Composition/CompositionEventHandler.h | 1 - .../Composition/CompositionRootView.cpp | 33 ++ .../Fabric/Composition/CompositionRootView.h | 10 + .../Microsoft.ReactNative/packages.lock.json | 112 +++-- 14 files changed, 794 insertions(+), 284 deletions(-) create mode 100644 packages/playground/windows/playground-composition/CustomComponent.cpp create mode 100644 packages/playground/windows/playground-composition/DeviceInfoModule.cpp diff --git a/packages/playground/windows/playground-composition/CustomComponent.cpp b/packages/playground/windows/playground-composition/CustomComponent.cpp new file mode 100644 index 00000000000..3517c11cc72 --- /dev/null +++ b/packages/playground/windows/playground-composition/CustomComponent.cpp @@ -0,0 +1,123 @@ +#include "pch.h" + +#include +#include +#include +#include + +/* + * Custom Properties can be passed from JS to this native component + * This struct will eventually be codegen'd from the JS spec file + */ +struct CustomProps : winrt::implements { + CustomProps(winrt::Microsoft::ReactNative::ViewProps props) : m_props(props) {} + + void SetProp(uint32_t hash, winrt::hstring propName, winrt::Microsoft::ReactNative::IJSValueReader value) noexcept { + if (propName == L"label") { + if (!value) { + label.clear(); + } else { + label = winrt::to_string(value.GetString()); + } + } + } + + std::string label; + winrt::Microsoft::ReactNative::ViewProps m_props; +}; + +struct CustomComponent : winrt::implements { + CustomComponent( + winrt::Microsoft::ReactNative::IReactContext reactContext, + winrt::Microsoft::ReactNative::Composition::ICompositionContext compContext) + : m_compContext(compContext) {} + + void UpdateProps(winrt::Microsoft::ReactNative::IComponentProps props) noexcept { + auto customProps = props.as(); + } + + void UpdateLayoutMetrics(winrt::Microsoft::ReactNative::Composition::LayoutMetrics metrics) noexcept { + m_visual.Size({metrics.Frame.Width, metrics.Frame.Height}); + } + + winrt::Microsoft::ReactNative::Composition::IVisual CreateVisual() noexcept { + m_visual = m_compContext.CreateSpriteVisual(); + m_visual.Brush(m_compContext.CreateColorBrush(winrt::Windows::UI::Colors::White())); + + auto compositor = + winrt::Microsoft::ReactNative::Composition::WindowsCompositionContextHelper::InnerCompositor(m_compContext); + + m_spotlight = compositor.CreateSpotLight(); + m_spotlight.InnerConeAngleInDegrees(50.0f); + m_spotlight.InnerConeColor(winrt::Windows::UI::Colors::FloralWhite()); + m_spotlight.InnerConeIntensity(5.0f); + m_spotlight.OuterConeAngleInDegrees(0.0f); + m_spotlight.ConstantAttenuation(1.0f); + m_spotlight.LinearAttenuation(0.253f); + m_spotlight.QuadraticAttenuation(0.58f); + m_spotlight.CoordinateSpace( + winrt::Microsoft::ReactNative::Composition::WindowsCompositionContextHelper::InnerVisual(m_visual)); + m_spotlight.Targets().Add( + winrt::Microsoft::ReactNative::Composition::WindowsCompositionContextHelper::InnerVisual(m_visual)); + + auto animation = compositor.CreateVector3KeyFrameAnimation(); + auto easeIn = compositor.CreateCubicBezierEasingFunction({0.5f, 0.0f}, {1.0f, 1.0f}); + animation.InsertKeyFrame(0.00f, {100.0f, 100.0f, 35.0f}); + animation.InsertKeyFrame(0.25f, {300.0f, 200.0f, 75.0f}, easeIn); + animation.InsertKeyFrame(0.50f, {050.0f, 300.0f, 15.0f}, easeIn); + animation.InsertKeyFrame(0.75f, {300.0f, 050.0f, 75.0f}, easeIn); + animation.InsertKeyFrame(1.00f, {100.0f, 100.0f, 35.0f}, easeIn); + animation.Duration(std::chrono::milliseconds(4000)); + animation.IterationBehavior(winrt::Windows::UI::Composition::AnimationIterationBehavior::Forever); + + m_spotlight.StartAnimation(L"Offset", animation); + + return m_visual; + } + + // TODO - Once we get more complete native eventing we can move spotlight based on pointer position + void OnPointerMove() noexcept { + // m_spotlight.Offset({(float)x, (float)y, 15.0f}); + + // m_propSet.InsertVector2(L"Position", {x, y}); + // TODO expose coordinate translation methods + // TODO convert x/y into local coordinates + } + + static void RegisterViewComponent(winrt::Microsoft::ReactNative::IReactPackageBuilder const &packageBuilder) { + packageBuilder.as().AddViewComponent( + L"MyCustomComponent", [](winrt::Microsoft::ReactNative::IReactViewComponentBuilder const &builder) noexcept { + builder.SetCreateProps( + [](winrt::Microsoft::ReactNative::ViewProps props) noexcept { return winrt::make(props); }); + auto compBuilder = + builder.as(); + compBuilder.SetCreateView( + [](winrt::Microsoft::ReactNative::IReactContext reactContext, + winrt::Microsoft::ReactNative::Composition::ICompositionContext context) noexcept { + return winrt::make(reactContext, context); + }); + compBuilder.SetPropsUpdater([](winrt::Windows::Foundation::IInspectable handle, + winrt::Microsoft::ReactNative::IComponentProps props) noexcept { + handle.as()->UpdateProps(props); + }); + compBuilder.SetLayoutMetricsUpdater( + [](winrt::Windows::Foundation::IInspectable handle, + winrt::Microsoft::ReactNative::Composition::LayoutMetrics metrics) noexcept { + handle.as()->UpdateLayoutMetrics(metrics); + }); + compBuilder.SetVisualCreator([](winrt::Windows::Foundation::IInspectable handle) noexcept { + return handle.as()->CreateVisual(); + }); + }); + } + + private: + winrt::Windows::UI::Composition::SpotLight m_spotlight{nullptr}; + + winrt::Microsoft::ReactNative::Composition::ISpriteVisual m_visual{nullptr}; + winrt::Microsoft::ReactNative::Composition::ICompositionContext m_compContext; +}; + +void RegisterCustomComponent(winrt::Microsoft::ReactNative::IReactPackageBuilder const &packageBuilder) noexcept { + CustomComponent::RegisterViewComponent(packageBuilder); +} diff --git a/packages/playground/windows/playground-composition/DeviceInfoModule.cpp b/packages/playground/windows/playground-composition/DeviceInfoModule.cpp new file mode 100644 index 00000000000..7956f497303 --- /dev/null +++ b/packages/playground/windows/playground-composition/DeviceInfoModule.cpp @@ -0,0 +1,46 @@ +#include "pch.h" + +#include "../../../../vnext/codegen/NativeDeviceInfoSpec.g.h" + +#include "NativeModules.h" + +// Temporary Work around crash in DeviceInfo when running outside of XAML environment +// TODO rework built-in DeviceInfo to allow it to be driven without use of HWNDs or XamlApps +REACT_MODULE(DeviceInfo) +struct DeviceInfo { + using ModuleSpec = Microsoft::ReactNativeSpecs::DeviceInfoSpec; + + REACT_INIT(Initialize) + void Initialize(React::ReactContext const &reactContext) noexcept { + m_context = reactContext; + } + + REACT_GET_CONSTANTS(GetConstants) + Microsoft::ReactNativeSpecs::DeviceInfoSpec_DeviceInfoConstants GetConstants() noexcept { + Microsoft::ReactNativeSpecs::DeviceInfoSpec_DeviceInfoConstants constants; + Microsoft::ReactNativeSpecs::DeviceInfoSpec_DisplayMetrics screenDisplayMetrics; + screenDisplayMetrics.fontScale = 1; + screenDisplayMetrics.height = 1024; + screenDisplayMetrics.width = 1024; + screenDisplayMetrics.scale = 1; + constants.Dimensions.screen = screenDisplayMetrics; + constants.Dimensions.window = screenDisplayMetrics; + return constants; + } + + private: + winrt::Microsoft::ReactNative::ReactContext m_context; +}; + +// Have to use TurboModules to override built in modules.. so the standard attributed package provider doesn't work. +struct StubDeviceInfoReactPackageProvider + : winrt::implements { + public: // IReactPackageProvider + void CreatePackage(winrt::Microsoft::ReactNative::IReactPackageBuilder const &packageBuilder) noexcept { + AddAttributedModules(packageBuilder, true); + } +}; + +winrt::Microsoft::ReactNative::IReactPackageProvider CreateStubDeviceInfoPackageProvider() noexcept { + return winrt::make(); +} diff --git a/packages/playground/windows/playground-composition/Playground-Composition.cpp b/packages/playground/windows/playground-composition/Playground-Composition.cpp index 30b3f214407..fae2b02b8c7 100644 --- a/packages/playground/windows/playground-composition/Playground-Composition.cpp +++ b/packages/playground/windows/playground-composition/Playground-Composition.cpp @@ -5,6 +5,7 @@ #include #include +#include // Disabled until we have a 3rd party story for custom components // #include "AutolinkedNativeModules.g.h" @@ -24,198 +25,55 @@ #include "NativeModules.h" #include "ReactPropertyBag.h" -struct CustomProps : winrt::implements { - CustomProps(winrt::Microsoft::ReactNative::ViewProps props) : m_props(props) {} - - void SetProp(uint32_t hash, winrt::hstring propName, winrt::Microsoft::ReactNative::IJSValueReader value) noexcept { - if (propName == L"label") { - if (!value) { - label.clear(); - } else { - label = winrt::to_string(value.GetString()); - } - } - } - - std::string label; - winrt::Microsoft::ReactNative::ViewProps m_props; -}; - -struct CustomComponent : winrt::implements { - CustomComponent( - winrt::Microsoft::ReactNative::IReactContext reactContext, - winrt::Microsoft::ReactNative::Composition::ICompositionContext compContext) - : m_compContext(compContext) {} - - void UpdateProps(winrt::Microsoft::ReactNative::IComponentProps props) noexcept { - auto customProps = props.as(); - } - - void UpdateLayoutMetrics(winrt::Microsoft::ReactNative::Composition::LayoutMetrics metrics) noexcept { - m_visual.Size({metrics.Frame.Width, metrics.Frame.Height}); - } - - winrt::Microsoft::ReactNative::Composition::IVisual CreateVisual() noexcept { - m_visual = m_compContext.CreateSpriteVisual(); - m_visual.Brush(m_compContext.CreateColorBrush(winrt::Windows::UI::Colors::White())); - - auto compositor = - winrt::Microsoft::ReactNative::Composition::WindowsCompositionContextHelper::InnerCompositor(m_compContext); - - m_spotlight = compositor.CreateSpotLight(); - m_spotlight.InnerConeAngleInDegrees(50.0f); - m_spotlight.InnerConeColor(winrt::Windows::UI::Colors::FloralWhite()); - m_spotlight.InnerConeIntensity(5.0f); - m_spotlight.OuterConeAngleInDegrees(0.0f); - m_spotlight.ConstantAttenuation(1.0f); - m_spotlight.LinearAttenuation(0.253f); - m_spotlight.QuadraticAttenuation(0.58f); - m_spotlight.CoordinateSpace( - winrt::Microsoft::ReactNative::Composition::WindowsCompositionContextHelper::InnerVisual(m_visual)); - m_spotlight.Targets().Add( - winrt::Microsoft::ReactNative::Composition::WindowsCompositionContextHelper::InnerVisual(m_visual)); - - auto animation = compositor.CreateVector3KeyFrameAnimation(); - auto easeIn = compositor.CreateCubicBezierEasingFunction({0.5f, 0.0f}, {1.0f, 1.0f}); - animation.InsertKeyFrame(0.00f, {100.0f, 100.0f, 35.0f}); - animation.InsertKeyFrame(0.25f, {300.0f, 200.0f, 75.0f}, easeIn); - animation.InsertKeyFrame(0.50f, {050.0f, 300.0f, 15.0f}, easeIn); - animation.InsertKeyFrame(0.75f, {300.0f, 050.0f, 75.0f}, easeIn); - animation.InsertKeyFrame(1.00f, {100.0f, 100.0f, 35.0f}, easeIn); - animation.Duration(std::chrono::milliseconds(4000)); - animation.IterationBehavior(winrt::Windows::UI::Composition::AnimationIterationBehavior::Forever); - - m_spotlight.StartAnimation(L"Offset", animation); - - return m_visual; - } - - // TODO - Once we get more complete native eventing we can move spotlight based on pointer position - int64_t SendMessage(uint32_t msg, uint64_t wParam, int64_t lParam) noexcept { - if (msg == WM_MOUSEMOVE) { - auto x = GET_X_LPARAM(lParam); - auto y = GET_Y_LPARAM(lParam); - - m_spotlight.Offset({(float)x, (float)y, 15.0f}); - - // m_propSet.InsertVector2(L"Position", {x, y}); - // TODO expose coordinate translation methods - // TODO convert x/y into local coordinates - } - - return 0; - } - - static void RegisterViewComponent(winrt::Microsoft::ReactNative::IReactPackageBuilder const &packageBuilder) { - packageBuilder.as().AddViewComponent( - L"MyCustomComponent", [](winrt::Microsoft::ReactNative::IReactViewComponentBuilder const &builder) noexcept { - builder.SetCreateProps( - [](winrt::Microsoft::ReactNative::ViewProps props) noexcept { return winrt::make(props); }); - auto compBuilder = - builder.as(); - compBuilder.SetCreateView( - [](winrt::Microsoft::ReactNative::IReactContext reactContext, - winrt::Microsoft::ReactNative::Composition::ICompositionContext context) noexcept { - return winrt::make(reactContext, context); - }); - compBuilder.SetPropsUpdater([](winrt::Windows::Foundation::IInspectable handle, - winrt::Microsoft::ReactNative::IComponentProps props) noexcept { - handle.as()->UpdateProps(props); - }); - compBuilder.SetLayoutMetricsUpdater( - [](winrt::Windows::Foundation::IInspectable handle, - winrt::Microsoft::ReactNative::Composition::LayoutMetrics metrics) noexcept { - handle.as()->UpdateLayoutMetrics(metrics); - }); - compBuilder.SetVisualCreator([](winrt::Windows::Foundation::IInspectable handle) noexcept { - return handle.as()->CreateVisual(); - }); - compBuilder.SetMessageHandler( - [](winrt::Windows::Foundation::IInspectable handle, - uint32_t Msg, - uint64_t WParam, - int64_t LParam) noexcept { return handle.as()->SendMessage(Msg, WParam, LParam); }); - }); - } - - private: - winrt::Windows::UI::Composition::SpotLight m_spotlight{nullptr}; - - winrt::Microsoft::ReactNative::Composition::ISpriteVisual m_visual{nullptr}; - winrt::Microsoft::ReactNative::Composition::ICompositionContext m_compContext; -}; +#if USE_WINUI3 +#include +#include +#include +#include +#include +#endif -// Work around crash in DeviceInfo when running outside of XAML environment -// TODO rework built-in DeviceInfo to allow it to be driven without use of HWNDs or XamlApps -REACT_MODULE(DeviceInfo) -struct DeviceInfo { - using ModuleSpec = Microsoft::ReactNativeSpecs::DeviceInfoSpec; +#if USE_WINUI3 +winrt::Microsoft::UI::Dispatching::DispatcherQueueController g_liftedDispatcherQueueController{nullptr}; +winrt::Microsoft::UI::Composition::Compositor g_liftedCompositor{nullptr}; - REACT_INIT(Initialize) - void Initialize(React::ReactContext const &reactContext) noexcept { - m_context = reactContext; - } +#endif - REACT_GET_CONSTANTS(GetConstants) - Microsoft::ReactNativeSpecs::DeviceInfoSpec_DeviceInfoConstants GetConstants() noexcept { - Microsoft::ReactNativeSpecs::DeviceInfoSpec_DeviceInfoConstants constants; - Microsoft::ReactNativeSpecs::DeviceInfoSpec_DisplayMetrics screenDisplayMetrics; - screenDisplayMetrics.fontScale = 1; - screenDisplayMetrics.height = 1024; - screenDisplayMetrics.width = 1024; - screenDisplayMetrics.scale = 1; - constants.Dimensions.screen = screenDisplayMetrics; - constants.Dimensions.window = screenDisplayMetrics; - return constants; - } +HWND g_hwndTopLevel; - private: - winrt::Microsoft::ReactNative::ReactContext m_context; -}; +void RegisterCustomComponent(winrt::Microsoft::ReactNative::IReactPackageBuilder const &packageBuilder) noexcept; // Have to use TurboModules to override built in modules.. so the standard attributed package provider doesn't work. struct CompReactPackageProvider : winrt::implements { public: // IReactPackageProvider void CreatePackage(winrt::Microsoft::ReactNative::IReactPackageBuilder const &packageBuilder) noexcept { - AddAttributedModules(packageBuilder, true); - - CustomComponent::RegisterViewComponent(packageBuilder); + RegisterCustomComponent(packageBuilder); } }; -#ifdef USE_WINUI3 -winrt::Microsoft::UI::Dispatching::DispatcherQueueController g_liftedDispatcherQueueController{nullptr}; -#endif winrt::Windows::System::DispatcherQueueController g_dispatcherQueueController{nullptr}; winrt::Windows::UI::Composition::Compositor g_compositor{nullptr}; constexpr auto WindowDataProperty = L"WindowData"; int RunPlayground(int showCmd, bool useWebDebugger); +winrt::Microsoft::ReactNative::IReactPackageProvider CreateStubDeviceInfoPackageProvider() noexcept; struct WindowData { static HINSTANCE s_instance; static constexpr uint16_t defaultDebuggerPort = 9229; std::wstring m_bundleFile; - bool m_windowInited{false}; - winrt::Microsoft::ReactNative::CompositionHwndHost m_CompositionHwndHost{nullptr}; + winrt::Microsoft::ReactNative::CompositionRootView m_compRootView{nullptr}; winrt::Microsoft::ReactNative::ReactNativeHost m_host{nullptr}; winrt::Microsoft::ReactNative::ReactInstanceSettings m_instanceSettings{nullptr}; + bool m_useLiftedComposition{true}; + winrt::Windows::UI::Composition::Desktop::DesktopWindowTarget m_target{nullptr}; + LONG m_height{0}; + LONG m_width{0}; - bool m_useWebDebugger{false}; - bool m_fastRefreshEnabled{true}; - bool m_useDirectDebugger{false}; - bool m_breakOnNextLine{false}; - uint16_t m_debuggerPort{defaultDebuggerPort}; - xaml::ElementTheme m_theme{xaml::ElementTheme::Default}; - - WindowData(const winrt::Microsoft::ReactNative::CompositionHwndHost &compHost) : m_CompositionHwndHost(compHost) { - winrt::Microsoft::ReactNative::Composition::CompositionUIService::SetCompositionContext( - InstanceSettings().Properties(), - winrt::Microsoft::ReactNative::Composition::WindowsCompositionContextHelper::CreateContext(g_compositor)); - } + WindowData() {} static WindowData *GetFromWindow(HWND hwnd) { auto data = reinterpret_cast(GetProp(hwnd, WindowDataProperty)); @@ -233,11 +91,50 @@ struct WindowData { winrt::Microsoft::ReactNative::ReactInstanceSettings InstanceSettings() noexcept { if (!m_instanceSettings) { m_instanceSettings = winrt::Microsoft::ReactNative::ReactInstanceSettings(); + m_instanceSettings.UseFastRefresh(true); } return m_instanceSettings; } + winrt::Microsoft::UI::WindowId + CreateChildWindow(winrt::Microsoft::UI::WindowId parentWindowId, LPCWSTR title, int x, int y, int w, int h) { + LPCWSTR childWindowClassName = L"TestChildWindowClass"; + + // Register child window class + static std::once_flag onceFlag; + std::call_once(onceFlag, [&childWindowClassName]() { + WNDCLASSEX childWindowClass = {}; + + childWindowClass.cbSize = sizeof(WNDCLASSEX); + childWindowClass.style = CS_HREDRAW | CS_VREDRAW; + childWindowClass.lpfnWndProc = ::DefWindowProc; + childWindowClass.hInstance = GetModuleHandle(nullptr); + childWindowClass.lpszClassName = childWindowClassName; + + RegisterClassEx(&childWindowClass); + }); + + HWND parentHwnd; + parentHwnd = winrt::Microsoft::UI::GetWindowFromWindowId(parentWindowId); + + HWND childHwnd = ::CreateWindowEx( + 0 /* dwExStyle */, + childWindowClassName, + title, + WS_CHILD | WS_CLIPSIBLINGS | WS_VISIBLE, + x, + y, + w, + h, + parentHwnd /* hWndParent */, + nullptr /* hMenu */, + GetModuleHandle(nullptr), + nullptr /* lpParam */); + + return winrt::Microsoft::UI::GetWindowIdFromWindow(childHwnd); + } + LRESULT OnCommand(HWND hwnd, int id, HWND /* hwndCtl*/, UINT) { switch (id) { case IDM_OPENJSFILE: { @@ -255,15 +152,11 @@ struct WindowData { host.InstanceSettings().JavaScriptBundleFile(m_bundleFile); - host.InstanceSettings().UseWebDebugger(m_useWebDebugger); - host.InstanceSettings().UseDirectDebugger(m_useDirectDebugger); host.InstanceSettings().BundleRootPath( std::wstring(L"file:").append(workingDir).append(L"\\Bundle\\").c_str()); - host.InstanceSettings().DebuggerBreakOnNextLine(m_breakOnNextLine); - host.InstanceSettings().UseFastRefresh(m_fastRefreshEnabled); - host.InstanceSettings().DebuggerPort(m_debuggerPort); host.InstanceSettings().UseDeveloperSupport(true); + host.PackageProviders().Append(CreateStubDeviceInfoPackageProvider()); host.PackageProviders().Append(winrt::make()); winrt::Microsoft::ReactNative::ReactCoreInjection::SetTopLevelWindowId( host.InstanceSettings().Properties(), reinterpret_cast(hwnd)); @@ -273,13 +166,86 @@ struct WindowData { winrt::Microsoft::ReactNative::ReactViewOptions viewOptions; viewOptions.ComponentName(appName); - m_CompositionHwndHost.ReactViewHost( + auto windowData = WindowData::GetFromWindow(hwnd); + + if (!m_compRootView) { + if (windowData->m_useLiftedComposition) { + m_compRootView = winrt::Microsoft::ReactNative::CompositionRootView(g_liftedCompositor); + } else { + m_compRootView = winrt::Microsoft::ReactNative::CompositionRootView(); + } + } + + m_compRootView.ReactViewHost( winrt::Microsoft::ReactNative::ReactCoreInjection::MakeViewHost(host, viewOptions)); - auto windowData = WindowData::GetFromWindow(hwnd); - if (!windowData->m_windowInited) { - m_CompositionHwndHost.Initialize((uint64_t)hwnd); - windowData->m_windowInited = true; + 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)); + + auto bridge = winrt::Microsoft::UI::Content::DesktopChildSiteBridge::Create( + g_liftedCompositor, winrt::Microsoft::UI::GetWindowIdFromWindow(hwnd)); + + auto appContent = m_compRootView.Island(); + + //auto invScale = static_cast(1.0 / ScaleFactor(hwnd)); + //m_compRootView.RootVisual().Scale({invScale, invScale, 1}); + + /* + // Future versions of WinAppSDK will have more capabilities around scale and size + auto site = bridge.Site(); + auto siteWindow = site.Environment(); + auto displayScale = siteWindow.DisplayScale(); + + // Size the island to be half the size of the custom component, to more easily test behavior across the island + site.ParentScale(displayScale); + site.ActualSize({metrics.Frame.Width / 2, metrics.Frame.Height / 2}); + site.ClientSize( + {static_cast(metrics.Frame.Width / 2 * metrics.PointScaleFactor), + static_cast(metrics.Frame.Height / 2 * metrics.PointScaleFactor)}); + */ + + //bridge.OverrideScale(static_cast(ScaleFactor(hwnd))); + bridge.Connect(appContent); + bridge.Show(); + + m_compRootView.ScaleFactor(ScaleFactor(hwnd)); + //m_compRootView.ScaleFactor(1); + m_compRootView.Size( + {static_cast(m_width / ScaleFactor(hwnd)), static_cast(m_height / ScaleFactor(hwnd))}); + + bridge.ResizePolicy(winrt::Microsoft::UI::Content::ContentSizePolicy::ResizeContentToParentWindow); + + } else if (!m_target) { + // By using the WindowsCompositionContextHelper here, React Native Windows will use System Visuals for its + // tree. + winrt::Microsoft::ReactNative::Composition::CompositionUIService::SetCompositionContext( + InstanceSettings().Properties(), + winrt::Microsoft::ReactNative::Composition::WindowsCompositionContextHelper::CreateContext( + g_compositor)); + + auto interop = g_compositor.as(); + winrt::Windows::UI::Composition::Desktop::DesktopWindowTarget target{nullptr}; + winrt::check_hresult(interop->CreateDesktopWindowTarget( + hwnd, + false, + reinterpret_cast( + winrt::put_abi(target)))); + m_target = target; + + auto root = g_compositor.CreateContainerVisual(); + root.RelativeSizeAdjustment({1.0f, 1.0f}); + root.Offset({0, 0, 0}); + m_target.Root(root); + m_compRootView.RootVisual( + winrt::Microsoft::ReactNative::Composition::WindowsCompositionContextHelper::CreateVisual(root)); + m_compRootView.ScaleFactor(ScaleFactor(hwnd)); + m_compRootView.Size( + {static_cast(m_width / ScaleFactor(hwnd)), static_cast(m_height / ScaleFactor(hwnd))}); } } @@ -311,9 +277,30 @@ struct WindowData { return 0; } - LRESULT TranslateMessage(UINT message, WPARAM wparam, LPARAM lparam) noexcept { - if (m_CompositionHwndHost) { - return static_cast(m_CompositionHwndHost.TranslateMessage(message, wparam, lparam)); + double ScaleFactor(HWND hwnd) noexcept { + return GetDpiForWindow(hwnd) / 96.0; + } + + void UpdateSize(HWND hwnd) noexcept { + RECT rc; + if (GetClientRect(hwnd, &rc)) { + if (m_height != (rc.bottom - rc.top) || m_width != (rc.right - rc.left)) { + m_height = rc.bottom - rc.top; + m_width = rc.right - rc.left; + + if (m_compRootView) { + winrt::Windows::Foundation::Size size{ + static_cast(m_width / ScaleFactor(hwnd)), static_cast(m_height / ScaleFactor(hwnd))}; + m_compRootView.Arrange(size); + m_compRootView.Size(size); + } + } + } + } + + LRESULT TranslateMessage(HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam) noexcept { + if (m_compRootView) { + return static_cast(m_compRootView.SendMessage(message, wparam, lparam)); } return 0; } @@ -393,39 +380,33 @@ struct WindowData { case WM_INITDIALOG: { auto boolToCheck = [](bool b) { return b ? BST_CHECKED : BST_UNCHECKED; }; auto self = reinterpret_cast(lparam); - CheckDlgButton(hwnd, IDC_WEBDEBUGGER, boolToCheck(self->m_useWebDebugger)); - CheckDlgButton(hwnd, IDC_FASTREFRESH, boolToCheck(self->m_fastRefreshEnabled)); - CheckDlgButton(hwnd, IDC_DIRECTDEBUGGER, boolToCheck(self->m_useDirectDebugger)); - CheckDlgButton(hwnd, IDC_BREAKONNEXTLINE, boolToCheck(self->m_breakOnNextLine)); + CheckDlgButton(hwnd, IDC_LIFTEDCOMPOSITION, boolToCheck(self->m_useLiftedComposition)); + CheckDlgButton(hwnd, IDC_FASTREFRESH, boolToCheck(self->InstanceSettings().UseFastRefresh())); + CheckDlgButton(hwnd, IDC_DIRECTDEBUGGER, boolToCheck(self->InstanceSettings().UseDirectDebugger())); + CheckDlgButton(hwnd, IDC_BREAKONNEXTLINE, boolToCheck(self->InstanceSettings().DebuggerBreakOnNextLine())); auto portEditControl = GetDlgItem(hwnd, IDC_DEBUGGERPORT); - SetWindowTextW(portEditControl, std::to_wstring(self->m_debuggerPort).c_str()); + SetWindowTextW(portEditControl, std::to_wstring(self->InstanceSettings().DebuggerPort()).c_str()); SendMessageW(portEditControl, (UINT)EM_SETLIMITTEXT, (WPARAM)5, (LPARAM)0); auto cmbEngines = GetDlgItem(hwnd, IDC_JSENGINE); SendMessageW(cmbEngines, (UINT)CB_ADDSTRING, (WPARAM)0, (LPARAM)TEXT("Chakra")); SendMessageW(cmbEngines, (UINT)CB_ADDSTRING, (WPARAM)0, (LPARAM)TEXT("Hermes")); SendMessageW(cmbEngines, (UINT)CB_ADDSTRING, (WPARAM)0, (LPARAM)TEXT("V8")); + // Fabric only supports Hermes right now - So dont actually set JS engine override // SendMessageW(cmbEngines, CB_SETCURSEL, (WPARAM) static_cast(self->m_jsEngine), (LPARAM)0); - auto cmbTheme = GetDlgItem(hwnd, IDC_THEME); - SendMessageW(cmbTheme, CB_ADDSTRING, 0, (LPARAM)L"Default"); - SendMessageW(cmbTheme, CB_ADDSTRING, 0, (LPARAM)L"Light"); - SendMessageW(cmbTheme, CB_ADDSTRING, 0, (LPARAM)L"Dark"); - ComboBox_SetCurSel(cmbTheme, static_cast(self->m_theme)); - return TRUE; } case WM_COMMAND: { switch (LOWORD(wparam)) { case IDOK: { auto self = GetFromWindow(GetParent(hwnd)); - self->m_useWebDebugger = IsDlgButtonChecked(hwnd, IDC_WEBDEBUGGER) == BST_CHECKED; - self->m_fastRefreshEnabled = IsDlgButtonChecked(hwnd, IDC_FASTREFRESH) == BST_CHECKED; - self->m_useDirectDebugger = IsDlgButtonChecked(hwnd, IDC_DIRECTDEBUGGER) == BST_CHECKED; - self->m_breakOnNextLine = IsDlgButtonChecked(hwnd, IDC_BREAKONNEXTLINE) == BST_CHECKED; - - auto themeComboBox = GetDlgItem(hwnd, IDC_THEME); + self->m_useLiftedComposition = (IsDlgButtonChecked(hwnd, IDC_LIFTEDCOMPOSITION) == BST_CHECKED); + self->InstanceSettings().UseFastRefresh(IsDlgButtonChecked(hwnd, IDC_FASTREFRESH) == BST_CHECKED); + self->InstanceSettings().UseDirectDebugger(IsDlgButtonChecked(hwnd, IDC_DIRECTDEBUGGER) == BST_CHECKED); + self->InstanceSettings().DebuggerBreakOnNextLine( + IsDlgButtonChecked(hwnd, IDC_BREAKONNEXTLINE) == BST_CHECKED); WCHAR buffer[6] = {}; auto portEditControl = GetDlgItem(hwnd, IDC_DEBUGGERPORT); @@ -435,14 +416,15 @@ struct WindowData { auto port = std::stoi(buffer); if (port > UINT16_MAX) port = defaultDebuggerPort; - self->m_debuggerPort = static_cast(port); + self->InstanceSettings().DebuggerPort(static_cast(port)); } catch (const std::out_of_range &) { - self->m_debuggerPort = defaultDebuggerPort; + self->InstanceSettings().DebuggerPort(defaultDebuggerPort); } catch (const std::invalid_argument &) { // Don't update the debugger port if the new value can't be parsed // (E.g. includes letters or symbols). } + // Fabric only supports Hermes right now - So dont actually set JS engine override // auto cmbEngines = GetDlgItem(hwnd, IDC_JSENGINE); // int itemIndex = (int)SendMessageW(cmbEngines, (UINT)CB_GETCURSEL, (WPARAM)0, (LPARAM)0); // self->m_jsEngine = static_cast(itemIndex); @@ -466,7 +448,7 @@ HINSTANCE WindowData::s_instance = reinterpret_cast(&__ImageBase); LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam) noexcept { auto windowData = WindowData::GetFromWindow(hwnd); if (windowData) { - auto result = WindowData::GetFromWindow(hwnd)->TranslateMessage(message, wparam, lparam); + auto result = WindowData::GetFromWindow(hwnd)->TranslateMessage(hwnd, message, wparam, lparam); if (result) return result; } @@ -492,18 +474,23 @@ LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam) case WM_GETOBJECT: { if (lparam == UiaRootObjectId) { auto windowData = WindowData::GetFromWindow(hwnd); - if (windowData == nullptr || !windowData->m_windowInited) + if (windowData == nullptr || !windowData->m_compRootView) break; - auto hwndHost = windowData->m_CompositionHwndHost; + auto rootView = windowData->m_compRootView; winrt::com_ptr spReps; - if (!hwndHost.UiaProvider().try_as(spReps)) { + if (!rootView.GetUiaProvider().try_as(spReps)) { break; } LRESULT lResult = UiaReturnRawElementProvider(hwnd, wparam, lparam, spReps.get()); return lResult; } } + case WM_WINDOWPOSCHANGED: { + auto windowData = WindowData::GetFromWindow(hwnd); + windowData->UpdateSize(hwnd); + break; + } } return DefWindowProc(hwnd, message, wparam, lparam); @@ -514,7 +501,7 @@ constexpr PCWSTR c_windowClassName = L"MS_REACTNATIVE_PLAYGROUND_COMPOSITION"; int RunPlayground(int showCmd, bool useWebDebugger) { constexpr PCWSTR appName = L"React Native Playground (Composition)"; - auto windowData = std::make_unique(winrt::Microsoft::ReactNative::CompositionHwndHost()); + auto windowData = std::make_unique(); HWND hwnd = CreateWindow( c_windowClassName, appName, @@ -530,6 +517,8 @@ int RunPlayground(int showCmd, bool useWebDebugger) { WINRT_VERIFY(hwnd); + g_hwndTopLevel = hwnd; // Temporary for prototyping + windowData.release(); ShowWindow(hwnd, showCmd); @@ -539,11 +528,21 @@ int RunPlayground(int showCmd, bool useWebDebugger) { HACCEL hAccelTable = LoadAccelerators(WindowData::s_instance, MAKEINTRESOURCE(IDC_PLAYGROUND_COMPOSITION)); MSG msg = {}; + + // This would be the same as the loop below. - Using the lower loop right now for easier debugging. + // g_liftedDispatcherQueueController.DispatcherQueue().RunEventLoop(); + while (GetMessage(&msg, nullptr, 0, 0)) { +#if USE_WINUI3 + // if (!ContentPreTranslateMessage(&msg)) { +#endif if (!TranslateAccelerator(hwnd, hAccelTable, &msg)) { TranslateMessage(&msg); DispatchMessage(&msg); } +#if USE_WINUI3 + // } +#endif } return static_cast(msg.wParam); @@ -577,12 +576,15 @@ _Use_decl_annotations_ int CALLBACK WinMain(HINSTANCE instance, HINSTANCE, PSTR options, reinterpret_cast( winrt::put_abi(g_dispatcherQueueController)))); + g_compositor = winrt::Windows::UI::Composition::Compositor(); #ifdef USE_WINUI3 + // Create a Lifted (WinAppSDK) DispatcherQueue for this thread. This is needed for + // Microsoft.UI.Composition, Content, and Input APIs. g_liftedDispatcherQueueController = winrt::Microsoft::UI::Dispatching::DispatcherQueueController::CreateOnCurrentThread(); + g_liftedCompositor = winrt::Microsoft::UI::Composition::Compositor(); #endif - g_compositor = winrt::Windows::UI::Composition::Compositor(); return RunPlayground(showCmd, false); } diff --git a/packages/playground/windows/playground-composition/Playground-Composition.rc b/packages/playground/windows/playground-composition/Playground-Composition.rc index ab8352c99de..c354aacac30 100644 --- a/packages/playground/windows/playground-composition/Playground-Composition.rc +++ b/packages/playground/windows/playground-composition/Playground-Composition.rc @@ -105,7 +105,7 @@ STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION | WS_SYSM CAPTION "Settings" FONT 8, "MS Shell Dlg", 400, 0, 0x1 BEGIN - CONTROL "&Web Debugger",IDC_WEBDEBUGGER,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,8,8,104,10 + CONTROL "&Lifted Composition",IDC_LIFTEDCOMPOSITION,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,8,8,104,10 CONTROL "&Fast Refresh",IDC_FASTREFRESH,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,8,26,104,10 CONTROL "&Direct Debugger",IDC_DIRECTDEBUGGER,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,8,44,104,10 CONTROL "&Break On Next Line",IDC_BREAKONNEXTLINE,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,8,63,104,10 diff --git a/packages/playground/windows/playground-composition/Playground-Composition.vcxproj b/packages/playground/windows/playground-composition/Playground-Composition.vcxproj index a556872eaa3..03ae7b3ecee 100644 --- a/packages/playground/windows/playground-composition/Playground-Composition.vcxproj +++ b/packages/playground/windows/playground-composition/Playground-Composition.vcxproj @@ -116,6 +116,8 @@ Create + + diff --git a/packages/playground/windows/playground-composition/resource.h b/packages/playground/windows/playground-composition/resource.h index c6a21456087..917cfeeaf37 100644 --- a/packages/playground/windows/playground-composition/resource.h +++ b/packages/playground/windows/playground-composition/resource.h @@ -4,7 +4,7 @@ // #define IDC_PLAYGROUND_COMPOSITION 100 #define IDD_ABOUTBOX 100 -#define IDC_WEBDEBUGGER 100 +#define IDC_LIFTEDCOMPOSITION 100 #define IDC_JSBUNDLELIST 100 #define IDM_ABOUT 100 #define IDD_SETTINGSBOX 101 diff --git a/vnext/Microsoft.ReactNative/CompositionRootView.idl b/vnext/Microsoft.ReactNative/CompositionRootView.idl index 54ba69979ab..c40e073406a 100644 --- a/vnext/Microsoft.ReactNative/CompositionRootView.idl +++ b/vnext/Microsoft.ReactNative/CompositionRootView.idl @@ -49,6 +49,10 @@ namespace Microsoft.ReactNative DOC_STRING("Creates a new instance of @CompositionRootView.") CompositionRootView(); +#ifdef USE_WINUI3 + CompositionRootView(Microsoft.UI.Composition.Compositor compositor); +#endif + DOC_STRING( "A ReactViewHost specifies the root UI component and initial properties to render in this RootView" "It must be set to show any React UI elements.") @@ -71,6 +75,10 @@ namespace Microsoft.ReactNative Int64 SendMessage(UInt32 Msg, UInt64 WParam, Int64 LParam); Object GetUiaProvider(); + +#ifdef USE_WINUI3 + Microsoft.UI.Content.ContentIsland Island { get; }; +#endif } } // namespace Microsoft.ReactNative diff --git a/vnext/Microsoft.ReactNative/Fabric/Composition/Composition.Input.cpp b/vnext/Microsoft.ReactNative/Fabric/Composition/Composition.Input.cpp index 12d4ecf0c9d..980a695da26 100644 --- a/vnext/Microsoft.ReactNative/Fabric/Composition/Composition.Input.cpp +++ b/vnext/Microsoft.ReactNative/Fabric/Composition/Composition.Input.cpp @@ -33,6 +33,19 @@ KeyRoutedEventArgs::KeyRoutedEventArgs(facebook::react::Tag tag, uint32_t msg, u m_key = static_cast(wParam); } +#ifdef USE_WINUI3 +KeyRoutedEventArgs::KeyRoutedEventArgs(facebook::react::Tag tag, winrt::Microsoft::UI::Input::KeyEventArgs const& args) : m_tag(tag) { + auto keyStatus = args.KeyStatus(); + m_keyStatus.RepeatCount = keyStatus.RepeatCount; + m_keyStatus.ScanCode = keyStatus.ScanCode; + m_keyStatus.IsExtendedKey = keyStatus.IsExtendedKey; + m_keyStatus.IsMenuKeyDown = keyStatus.IsMenuKeyDown; + m_keyStatus.WasKeyDown = keyStatus.WasKeyDown; + m_keyStatus.IsKeyReleased = keyStatus.IsKeyReleased; + m_key = args.VirtualKey(); +} +#endif + int32_t KeyRoutedEventArgs::OriginalSource() noexcept { return m_tag; } @@ -61,8 +74,10 @@ winrt::Windows::System::VirtualKey KeyRoutedEventArgs::OriginalKey() noexcept { return m_key; } -PointerPointProperties::PointerPointProperties(const winrt::Windows::UI::Input::PointerPointProperties &ppp) +#ifdef USE_WINUI3 +PointerPointProperties::PointerPointProperties(const winrt::Microsoft::UI::Input::PointerPointProperties &ppp) : m_sysPointerPointProps(ppp) {} +#endif PointerPointProperties::PointerPointProperties( bool isBarrelButtonPressed, @@ -107,92 +122,198 @@ PointerPointProperties::PointerPointProperties( m_yTilt(yTilt) {} winrt::Windows::Foundation::Rect PointerPointProperties::ContactRect() noexcept { +#ifdef USE_WINUI3 return m_sysPointerPointProps.ContactRect(); +#else + assert(false); + return {}; +#endif } bool PointerPointProperties::IsBarrelButtonPressed() noexcept { - return m_sysPointerPointProps ? m_sysPointerPointProps.IsBarrelButtonPressed() : m_isBarrelButtonPressed; +#ifdef USE_WINUI3 + if (m_sysPointerPointProps) { + return m_sysPointerPointProps.IsBarrelButtonPressed(); + } +#endif + return m_isBarrelButtonPressed; } bool PointerPointProperties::IsCanceled() noexcept { - return m_sysPointerPointProps ? m_sysPointerPointProps.IsCanceled() : m_isCanceled; +#ifdef USE_WINUI3 + if (m_sysPointerPointProps) { + return m_sysPointerPointProps.IsCanceled(); + } +#endif + return m_isCanceled; } bool PointerPointProperties::IsEraser() noexcept { - return m_sysPointerPointProps ? m_sysPointerPointProps.IsEraser() : m_isEraser; +#ifdef USE_WINUI3 + if (m_sysPointerPointProps) { + return m_sysPointerPointProps.IsEraser(); + } +#endif + return m_isEraser; } bool PointerPointProperties::IsHorizontalMouseWheel() noexcept { - return m_sysPointerPointProps ? m_sysPointerPointProps.IsHorizontalMouseWheel() : m_isHorizontalMouseWheel; +#ifdef USE_WINUI3 + if (m_sysPointerPointProps) { + return m_sysPointerPointProps.IsHorizontalMouseWheel(); + } +#endif + return m_isHorizontalMouseWheel; } bool PointerPointProperties::IsInRange() noexcept { - return m_sysPointerPointProps ? m_sysPointerPointProps.IsInRange() : m_isInRange; +#ifdef USE_WINUI3 + if (m_sysPointerPointProps) { + return m_sysPointerPointProps.IsInRange(); + } +#endif + return m_isInRange; } bool PointerPointProperties::IsInverted() noexcept { - return m_sysPointerPointProps ? m_sysPointerPointProps.IsInverted() : m_isInverted; +#ifdef USE_WINUI3 + if (m_sysPointerPointProps) { + return m_sysPointerPointProps.IsInverted(); + } +#endif + return m_isInverted; } bool PointerPointProperties::IsLeftButtonPressed() noexcept { - return m_sysPointerPointProps ? m_sysPointerPointProps.IsLeftButtonPressed() : m_isLeftButtonPressed; +#ifdef USE_WINUI3 + if (m_sysPointerPointProps) { + return m_sysPointerPointProps.IsLeftButtonPressed(); + } +#endif + return m_isLeftButtonPressed; } bool PointerPointProperties::IsMiddleButtonPressed() noexcept { - return m_sysPointerPointProps ? m_sysPointerPointProps.IsMiddleButtonPressed() : m_isMiddleButtonPressed; +#ifdef USE_WINUI3 + if (m_sysPointerPointProps) { + return m_sysPointerPointProps.IsMiddleButtonPressed(); + } +#endif + return m_isMiddleButtonPressed; } bool PointerPointProperties::IsPrimary() noexcept { - return m_sysPointerPointProps ? m_sysPointerPointProps.IsPrimary() : m_isPrimary; +#ifdef USE_WINUI3 + if (m_sysPointerPointProps) { + return m_sysPointerPointProps.IsPrimary(); + } +#endif + return m_isPrimary; } bool PointerPointProperties::IsRightButtonPressed() noexcept { - return m_sysPointerPointProps ? m_sysPointerPointProps.IsRightButtonPressed() : m_isRightButtonPressed; +#ifdef USE_WINUI3 + if (m_sysPointerPointProps) { + return m_sysPointerPointProps.IsRightButtonPressed(); + } +#endif + return m_isRightButtonPressed; } bool PointerPointProperties::IsXButton1Pressed() noexcept { - return m_sysPointerPointProps ? m_sysPointerPointProps.IsXButton1Pressed() : m_isXButton1Pressed; +#ifdef USE_WINUI3 + if (m_sysPointerPointProps) { + return m_sysPointerPointProps.IsXButton1Pressed(); + } +#endif + return m_isXButton1Pressed; } bool PointerPointProperties::IsXButton2Pressed() noexcept { - return m_sysPointerPointProps ? m_sysPointerPointProps.IsXButton2Pressed() : m_isXButton2Pressed; +#ifdef USE_WINUI3 + if (m_sysPointerPointProps) { + return m_sysPointerPointProps.IsXButton2Pressed(); + } +#endif + return m_isXButton2Pressed; } int32_t PointerPointProperties::MouseWheelDelta() noexcept { - return m_sysPointerPointProps ? m_sysPointerPointProps.MouseWheelDelta() : m_mouseWheelDelta; +#ifdef USE_WINUI3 + if (m_sysPointerPointProps) { + return m_sysPointerPointProps.MouseWheelDelta(); + } +#endif + return m_mouseWheelDelta; } float PointerPointProperties::Orientation() noexcept { - return m_sysPointerPointProps ? m_sysPointerPointProps.Orientation() : m_orientation; +#ifdef USE_WINUI3 + if (m_sysPointerPointProps) { + return m_sysPointerPointProps.Orientation(); + } +#endif + return m_orientation; } PointerUpdateKind PointerPointProperties::PointerUpdateKind() noexcept { - return m_sysPointerPointProps ? static_cast( - m_sysPointerPointProps.PointerUpdateKind()) - : m_pointerUpdateKind; +#ifdef USE_WINUI3 + if (m_sysPointerPointProps) { + return static_cast( + m_sysPointerPointProps.PointerUpdateKind()); + } +#endif + return m_pointerUpdateKind; } float PointerPointProperties::Pressure() noexcept { - return m_sysPointerPointProps ? m_sysPointerPointProps.Pressure() : m_pressure; +#ifdef USE_WINUI3 + if (m_sysPointerPointProps) { + return m_sysPointerPointProps.Pressure(); + } +#endif + return m_pressure; } bool PointerPointProperties::TouchConfidence() noexcept { - return m_sysPointerPointProps ? m_sysPointerPointProps.TouchConfidence() : m_touchConfidence; +#ifdef USE_WINUI3 + if (m_sysPointerPointProps) { + return m_sysPointerPointProps.TouchConfidence(); + } +#endif + return m_touchConfidence; } float PointerPointProperties::Twist() noexcept { - return m_sysPointerPointProps ? m_sysPointerPointProps.Twist() : m_twist; +#ifdef USE_WINUI3 + if (m_sysPointerPointProps) { + return m_sysPointerPointProps.Twist(); + } +#endif + return m_twist; } float PointerPointProperties::XTilt() noexcept { - return m_sysPointerPointProps ? m_sysPointerPointProps.XTilt() : m_xTilt; +#ifdef USE_WINUI3 + if (m_sysPointerPointProps) { + return m_sysPointerPointProps.XTilt(); + } +#endif + return m_xTilt; } float PointerPointProperties::YTilt() noexcept { - return m_sysPointerPointProps ? m_sysPointerPointProps.YTilt() : m_yTilt; +#ifdef USE_WINUI3 + if (m_sysPointerPointProps) { + return m_sysPointerPointProps.YTilt(); + } +#endif + return m_yTilt; } -PointerPoint::PointerPoint(const winrt::Windows::UI::Input::PointerPoint &pp) : m_sysPointerPoint(pp) {} +#ifdef USE_WINUI3 +PointerPoint::PointerPoint(const winrt::Microsoft::UI::Input::PointerPoint &pp) : m_sysPointerPoint(pp) {} +#endif PointerPoint::PointerPoint(uint32_t msg, uint64_t wParam, int64_t lParam) { m_msg = msg; @@ -206,19 +327,30 @@ PointerPoint::PointerPoint(uint32_t msg, uint64_t wParam, int64_t lParam) { } uint32_t PointerPoint::FrameId() noexcept { - return m_sysPointerPoint ? m_sysPointerPoint.FrameId() : m_pi.frameId; +#ifdef USE_WINUI3 +if (m_sysPointerPoint) { + return m_sysPointerPoint.FrameId(); +} +#endif + return m_pi.frameId; } bool PointerPoint::IsInContact() noexcept { - return m_sysPointerPoint ? m_sysPointerPoint.IsInContact() - : ((m_pi.pointerFlags & POINTER_FLAG_INCONTACT) == POINTER_FLAG_INCONTACT); +#ifdef USE_WINUI3 + if (m_sysPointerPoint) { + return m_sysPointerPoint.IsInContact(); + } +#endif + return ((m_pi.pointerFlags & POINTER_FLAG_INCONTACT) == POINTER_FLAG_INCONTACT); } winrt::Microsoft::ReactNative::Composition::Input::PointerDeviceType PointerPoint::PointerDeviceType() noexcept { +#ifdef USE_WINUI3 if (m_sysPointerPoint) { return static_cast( - m_sysPointerPoint.PointerDevice().PointerDeviceType()); + m_sysPointerPoint.PointerDeviceType()); } +#endif if (m_pi.pointerId) { switch (m_pi.pointerType) { @@ -239,7 +371,12 @@ winrt::Microsoft::ReactNative::Composition::Input::PointerDeviceType PointerPoin } uint32_t PointerPoint::PointerId() noexcept { - return m_sysPointerPoint ? m_sysPointerPoint.PointerId() : (m_pi.pointerId ? m_pi.pointerId : 1 /* MOUSE */); +#ifdef USE_WINUI3 + if (m_sysPointerPoint) { + return m_sysPointerPoint.PointerId(); + } +#endif + return (m_pi.pointerId ? m_pi.pointerId : 1 /* MOUSE */); } winrt::Windows::Foundation::Point PointerPoint::Position() noexcept { diff --git a/vnext/Microsoft.ReactNative/Fabric/Composition/Composition.Input.h b/vnext/Microsoft.ReactNative/Fabric/Composition/Composition.Input.h index 62c207bd646..2befedaff67 100644 --- a/vnext/Microsoft.ReactNative/Fabric/Composition/Composition.Input.h +++ b/vnext/Microsoft.ReactNative/Fabric/Composition/Composition.Input.h @@ -9,6 +9,9 @@ #include #include #include +#ifdef USE_WINUI3 +#include +#endif namespace winrt::Microsoft::ReactNative::Composition::Input::implementation { @@ -17,6 +20,9 @@ struct KeyRoutedEventArgs : winrt::implements< winrt::Microsoft::ReactNative::Composition::Input::KeyRoutedEventArgs, winrt::Microsoft::ReactNative::Composition::Input::RoutedEventArgs> { KeyRoutedEventArgs(facebook::react::Tag tag, uint32_t msg, uint64_t wParam, int64_t lParam); +#ifdef USE_WINUI3 + KeyRoutedEventArgs(facebook::react::Tag tag, winrt::Microsoft::UI::Input::KeyEventArgs const& args); +#endif int32_t OriginalSource() noexcept; winrt::hstring DeviceId() noexcept; @@ -34,7 +40,9 @@ struct KeyRoutedEventArgs : winrt::implements< }; struct PointerPointProperties : PointerPointPropertiesT { - PointerPointProperties(const winrt::Windows::UI::Input::PointerPointProperties &ppp); +#ifdef USE_WINUI3 + PointerPointProperties(const winrt::Microsoft::UI::Input::PointerPointProperties &ppp); +#endif PointerPointProperties( bool isBarrelButtonPressed, @@ -81,7 +89,9 @@ struct PointerPointProperties : PointerPointPropertiesT float YTilt() noexcept; private: - winrt::Windows::UI::Input::PointerPointProperties m_sysPointerPointProps{nullptr}; +#ifdef USE_WINUI3 + winrt::Microsoft::UI::Input::PointerPointProperties m_sysPointerPointProps{nullptr}; +#endif // When not using m_sysPointerPointProps bool m_isBarrelButtonPressed : 1; @@ -107,7 +117,7 @@ struct PointerPointProperties : PointerPointPropertiesT }; struct PointerPoint : PointerPointT { - PointerPoint(const winrt::Windows::UI::Input::PointerPoint &pp); + PointerPoint(const winrt::Microsoft::UI::Input::PointerPoint &pp); PointerPoint(uint32_t msg, uint64_t wParam, int64_t lParam); uint32_t FrameId() noexcept; @@ -124,7 +134,9 @@ struct PointerPoint : PointerPointT { bool IsPointerMessage(uint32_t message) noexcept; // Windows::Input - winrt::Windows::UI::Input::PointerPoint m_sysPointerPoint{nullptr}; +#ifdef USE_WINUI3 + winrt::Microsoft::UI::Input::PointerPoint m_sysPointerPoint{nullptr}; +#endif // WM_POINTER* POINTER_INFO m_pi = {0}; // WM_*MOUSE diff --git a/vnext/Microsoft.ReactNative/Fabric/Composition/CompositionEventHandler.cpp b/vnext/Microsoft.ReactNative/Fabric/Composition/CompositionEventHandler.cpp index 9860ab6af3c..03810d4f26d 100644 --- a/vnext/Microsoft.ReactNative/Fabric/Composition/CompositionEventHandler.cpp +++ b/vnext/Microsoft.ReactNative/Fabric/Composition/CompositionEventHandler.cpp @@ -18,6 +18,10 @@ #include "CompositionViewComponentView.h" #include "RootComponentView.h" +#ifdef USE_WINUI3 +#include +#endif + namespace Microsoft::ReactNative { const PointerId MOUSE_POINTER_ID = 1; @@ -98,17 +102,119 @@ struct CompositionKeyboardSource } private: - CompositionEventHandler *m_outer; + CompositionEventHandler* m_outer { nullptr }; }; -CompositionEventHandler::CompositionEventHandler(const winrt::Microsoft::ReactNative::ReactContext &context) - : m_context(context) {} + +#ifdef USE_WINUI3 +struct CompositionInputKeyboardSource + : winrt::implements +{ + CompositionInputKeyboardSource(winrt::Microsoft::UI::Input::InputKeyboardSource source) : m_source(source) + { + } + + winrt::Windows::UI::Core::CoreVirtualKeyStates GetKeyState(winrt::Windows::System::VirtualKey key) noexcept + { + if (!m_source) + return winrt::Windows::UI::Core::CoreVirtualKeyStates::None; + + static_assert(static_cast(winrt::Microsoft::UI::Input::VirtualKeyStates::Down) == winrt::Windows::UI::Core::CoreVirtualKeyStates::Down); + static_assert(static_cast(winrt::Microsoft::UI::Input::VirtualKeyStates::Locked) == winrt::Windows::UI::Core::CoreVirtualKeyStates::Locked); + static_assert(static_cast(winrt::Microsoft::UI::Input::VirtualKeyStates::None) == winrt::Windows::UI::Core::CoreVirtualKeyStates::None); + return static_cast(m_source.GetKeyState(key)); + } + + void Disconnect() noexcept + { + m_source = nullptr; + } + +private: + winrt::Microsoft::UI::Input::InputKeyboardSource m_source { nullptr }; +}; +#endif CompositionEventHandler::CompositionEventHandler( const winrt::Microsoft::ReactNative::ReactContext &context, const winrt::Microsoft::ReactNative::CompositionRootView &CompositionRootView) - : CompositionEventHandler(context) { + : m_context(context) { m_compRootView = CompositionRootView; + +#ifdef USE_WINUI3 + if (auto island = m_compRootView.Island()) { + auto pointerSource = winrt::Microsoft::UI::Input::InputPointerSource::GetForIsland(island); + + pointerSource.PointerPressed([this]( + winrt::Microsoft::UI::Input::InputPointerSource const &, + winrt::Microsoft::UI::Input::PointerEventArgs const &args) { + + auto pp = winrt::make( + args.CurrentPoint()); + onPointerPressed(pp, args.KeyModifiers()); + }); + + pointerSource.PointerReleased([this]( + winrt::Microsoft::UI::Input::InputPointerSource const&, + winrt::Microsoft::UI::Input::PointerEventArgs const& args) + { + auto pp = winrt::make( + args.CurrentPoint()); + onPointerReleased(pp, args.KeyModifiers()); + }); + + pointerSource.PointerMoved([this]( + winrt::Microsoft::UI::Input::InputPointerSource const&, + winrt::Microsoft::UI::Input::PointerEventArgs const& args) + { + auto pp = winrt::make( + args.CurrentPoint()); + onPointerMoved(pp, args.KeyModifiers()); + }); + + pointerSource.PointerWheelChanged([this]( + winrt::Microsoft::UI::Input::InputPointerSource const&, + winrt::Microsoft::UI::Input::PointerEventArgs const& args) + { + auto pp = winrt::make( + args.CurrentPoint()); + onPointerWheelChanged(pp, args.KeyModifiers()); + }); + + auto keyboardSource = winrt::Microsoft::UI::Input::InputKeyboardSource::GetForIsland(island); + + keyboardSource.KeyDown([this](winrt::Microsoft::UI::Input::InputKeyboardSource const& source, winrt::Microsoft::UI::Input::KeyEventArgs const& args) + { + auto focusedComponent = RootComponentView().GetFocusedComponent(); + auto keyArgs = winrt::make( + focusedComponent + ? focusedComponent->tag() + : static_cast( + winrt::get_self(m_compRootView) + ->GetTag()), + args); + auto keyboardSource = winrt::make(source); + onKeyDown(keyboardSource, keyArgs); + winrt::get_self(keyboardSource)->Disconnect(); + }); + + keyboardSource.KeyUp([this](winrt::Microsoft::UI::Input::InputKeyboardSource const& source, winrt::Microsoft::UI::Input::KeyEventArgs const& args) + { + auto focusedComponent = RootComponentView().GetFocusedComponent(); + auto keyArgs = winrt::make( + focusedComponent + ? focusedComponent->tag() + : static_cast( + winrt::get_self(m_compRootView) + ->GetTag()), + args); + auto keyboardSource = winrt::make(source); + onKeyUp(keyboardSource, keyArgs); + winrt::get_self(keyboardSource)->Disconnect(); + }); + + } +#endif }; CompositionEventHandler::~CompositionEventHandler() {} @@ -511,6 +617,10 @@ facebook::react::PointerEvent CreatePointerEventFromIncompleteHoverData( void CompositionEventHandler::onPointerMoved( const winrt::Microsoft::ReactNative::Composition::Input::PointerPoint &pointerPoint, winrt::Windows::System::VirtualKeyModifiers keyModifiers) noexcept { + + if (SurfaceId() == -1) + return; + int pointerId = pointerPoint.PointerId(); auto position = pointerPoint.Position(); diff --git a/vnext/Microsoft.ReactNative/Fabric/Composition/CompositionEventHandler.h b/vnext/Microsoft.ReactNative/Fabric/Composition/CompositionEventHandler.h index 7e5b7f81e2b..1e986ef40b3 100644 --- a/vnext/Microsoft.ReactNative/Fabric/Composition/CompositionEventHandler.h +++ b/vnext/Microsoft.ReactNative/Fabric/Composition/CompositionEventHandler.h @@ -28,7 +28,6 @@ typedef int PointerId; class CompositionEventHandler { public: - CompositionEventHandler(const winrt::Microsoft::ReactNative::ReactContext &context); CompositionEventHandler( const winrt::Microsoft::ReactNative::ReactContext &context, const winrt::Microsoft::ReactNative::CompositionRootView &CompositionRootView); diff --git a/vnext/Microsoft.ReactNative/Fabric/Composition/CompositionRootView.cpp b/vnext/Microsoft.ReactNative/Fabric/Composition/CompositionRootView.cpp index 6413aeb6ce8..a6dbcb78ca2 100644 --- a/vnext/Microsoft.ReactNative/Fabric/Composition/CompositionRootView.cpp +++ b/vnext/Microsoft.ReactNative/Fabric/Composition/CompositionRootView.cpp @@ -21,6 +21,10 @@ #include "ReactNativeHost.h" #include "RootComponentView.h" +#ifdef USE_WINUI3 +#include +#endif + namespace winrt::Microsoft::ReactNative::implementation { //! This class ensures that we access ReactRootView from UI thread. @@ -98,6 +102,10 @@ inline Mso::Future CompositionReactViewInstance::PostInUIQueue(TAction &&a CompositionRootView::CompositionRootView() noexcept {} +#ifdef USE_WINUI3 +CompositionRootView::CompositionRootView(winrt::Microsoft::UI::Composition::Compositor compositor) noexcept : m_compositor(compositor) {} +#endif + ReactNative::IReactViewHost CompositionRootView::ReactViewHost() noexcept { return m_reactViewHost; } @@ -356,6 +364,31 @@ winrt::Windows::Foundation::Size CompositionRootView::Arrange(winrt::Windows::Fo return finalSize; } +#ifdef USE_WINUI3 +winrt::Microsoft::UI::Content::ContentIsland CompositionRootView::Island() noexcept { + if (!m_compositor) { + return nullptr; + } + + if (!m_island) { + auto testBrush = m_compositor.CreateColorBrush(winrt::Windows::UI::Colors::Red()); // TODO remove + auto rootVisual = m_compositor.CreateSpriteVisual(); + rootVisual.RelativeSizeAdjustment({1, 1}); + + // Display a border around the root to help debug sizing of island + auto nine = m_compositor.CreateNineGridBrush(); // TODO remove + nine.SetInsets(10); + nine.IsCenterHollow(true); + nine.Source(testBrush); + rootVisual.Brush(nine); + + RootVisual(winrt::Microsoft::ReactNative::Composition::MicrosoftCompositionContextHelper::CreateVisual(rootVisual)); + m_island = winrt::Microsoft::UI::Content::ContentIsland::Create(rootVisual); + } + return m_island; +} +#endif + ::Microsoft::ReactNative::RootComponentView *CompositionRootView::GetComponentView() noexcept { if (!m_context || m_context.Handle().LoadingState() != winrt::Microsoft::ReactNative::LoadingState::Loaded) return nullptr; diff --git a/vnext/Microsoft.ReactNative/Fabric/Composition/CompositionRootView.h b/vnext/Microsoft.ReactNative/Fabric/Composition/CompositionRootView.h index 15806b902a5..d6239b8a46b 100644 --- a/vnext/Microsoft.ReactNative/Fabric/Composition/CompositionRootView.h +++ b/vnext/Microsoft.ReactNative/Fabric/Composition/CompositionRootView.h @@ -43,6 +43,11 @@ struct FocusNavigationResult : FocusNavigationResultT { struct CompositionRootView : CompositionRootViewT, ::Microsoft::ReactNative::ICompositionRootView { CompositionRootView() noexcept; +#ifdef USE_WINUI3 + CompositionRootView(winrt::Microsoft::UI::Composition::Compositor compositor) noexcept; + winrt::Microsoft::UI::Content::ContentIsland Island() noexcept; +#endif + // property ReactViewHost ReactNative::IReactViewHost ReactViewHost() noexcept; void ReactViewHost(ReactNative::IReactViewHost const &value) noexcept; @@ -89,6 +94,11 @@ struct CompositionRootView : CompositionRootViewT, ::Micros void UninitRootView() noexcept; private: +#ifdef USE_WINUI3 + winrt::Microsoft::UI::Composition::Compositor m_compositor{nullptr}; + winrt::Microsoft::UI::Content::ContentIsland m_island{nullptr}; +#endif + bool m_isInitialized{false}; bool m_isJSViewAttached{false}; IReactDispatcher m_uiDispatcher{nullptr}; diff --git a/vnext/Microsoft.ReactNative/packages.lock.json b/vnext/Microsoft.ReactNative/packages.lock.json index 0f5612becc6..05b42f0576e 100644 --- a/vnext/Microsoft.ReactNative/packages.lock.json +++ b/vnext/Microsoft.ReactNative/packages.lock.json @@ -24,21 +24,21 @@ "Microsoft.SourceLink.Common": "1.1.1" } }, - "Microsoft.UI.Xaml": { - "type": "Direct", - "requested": "[2.8.0, )", - "resolved": "2.8.0", - "contentHash": "vxdHxTr63s5KVtNddMFpgvjBjUH50z7seq/5jLWmmSuf8poxg+sXrywkofUdE8ZstbpO9y3FL/IXXUcPYbeesA==", - "dependencies": { - "Microsoft.Web.WebView2": "1.0.1264.42" - } - }, "Microsoft.Windows.CppWinRT": { "type": "Direct", "requested": "[2.0.211028.7, )", "resolved": "2.0.211028.7", "contentHash": "JBGI0c3WLoU6aYJRy9Qo0MLDQfObEp+d4nrhR95iyzf7+HOgjRunHDp/6eGFREd7xq3OI1mll9ecJrMfzBvlyg==" }, + "Microsoft.WindowsAppSDK": { + "type": "Direct", + "requested": "[1.4.230913002, )", + "resolved": "1.4.230913002", + "contentHash": "l+9RshN4TsTuxL0ijFp5smbs3Y07RO7CxKBHNM/RsrsGtWvuk6edITMp4oqL9C3ufEAmpYk3dqOZRSf+sFH4Zg==", + "dependencies": { + "Microsoft.Windows.SDK.BuildTools": "10.0.22621.1" + } + }, "Microsoft.Build.Tasks.Git": { "type": "Transitive", "resolved": "1.1.1", @@ -49,10 +49,10 @@ "resolved": "1.1.1", "contentHash": "WMcGpWKrmJmzrNeuaEb23bEMnbtR/vLmvZtkAP5qWu7vQsY59GqfRJd65sFpBszbd2k/bQ8cs8eWawQKAabkVg==" }, - "Microsoft.Web.WebView2": { + "Microsoft.Windows.SDK.BuildTools": { "type": "Transitive", - "resolved": "1.0.1264.42", - "contentHash": "7OBUTkzQ5VI/3gb0ufi5U4zjuCowAJwQg2li0zXXzqkM+S1kmOlivTy1R4jAW+gY5Vyg510M+qMAESCQUjrfgA==" + "resolved": "10.0.22621.1", + "contentHash": "Sp1DkYvg7yxuhamwxv+qFC66KC3paKQpwK8Q1J6XuAh6nzXIInmsDcpJ3szr0XGud4ysXojqwTfGdW01gvZ/0g==" }, "common": { "type": "Project" @@ -63,8 +63,8 @@ "folly": { "type": "Project", "dependencies": { - "Fmt": "[1.0.0, )", - "boost": "[1.76.0, )" + "boost": "[1.76.0, )", + "fmt": "[1.0.0, )" } }, "reactcommon": { @@ -76,52 +76,80 @@ } }, "native,Version=v0.0/win10-arm": { - "Microsoft.Web.WebView2": { - "type": "Transitive", - "resolved": "1.0.1264.42", - "contentHash": "7OBUTkzQ5VI/3gb0ufi5U4zjuCowAJwQg2li0zXXzqkM+S1kmOlivTy1R4jAW+gY5Vyg510M+qMAESCQUjrfgA==" + "Microsoft.WindowsAppSDK": { + "type": "Direct", + "requested": "[1.4.230913002, )", + "resolved": "1.4.230913002", + "contentHash": "l+9RshN4TsTuxL0ijFp5smbs3Y07RO7CxKBHNM/RsrsGtWvuk6edITMp4oqL9C3ufEAmpYk3dqOZRSf+sFH4Zg==", + "dependencies": { + "Microsoft.Windows.SDK.BuildTools": "10.0.22621.1" + } } }, "native,Version=v0.0/win10-arm-aot": { - "Microsoft.Web.WebView2": { - "type": "Transitive", - "resolved": "1.0.1264.42", - "contentHash": "7OBUTkzQ5VI/3gb0ufi5U4zjuCowAJwQg2li0zXXzqkM+S1kmOlivTy1R4jAW+gY5Vyg510M+qMAESCQUjrfgA==" + "Microsoft.WindowsAppSDK": { + "type": "Direct", + "requested": "[1.4.230913002, )", + "resolved": "1.4.230913002", + "contentHash": "l+9RshN4TsTuxL0ijFp5smbs3Y07RO7CxKBHNM/RsrsGtWvuk6edITMp4oqL9C3ufEAmpYk3dqOZRSf+sFH4Zg==", + "dependencies": { + "Microsoft.Windows.SDK.BuildTools": "10.0.22621.1" + } } }, "native,Version=v0.0/win10-arm64-aot": { - "Microsoft.Web.WebView2": { - "type": "Transitive", - "resolved": "1.0.1264.42", - "contentHash": "7OBUTkzQ5VI/3gb0ufi5U4zjuCowAJwQg2li0zXXzqkM+S1kmOlivTy1R4jAW+gY5Vyg510M+qMAESCQUjrfgA==" + "Microsoft.WindowsAppSDK": { + "type": "Direct", + "requested": "[1.4.230913002, )", + "resolved": "1.4.230913002", + "contentHash": "l+9RshN4TsTuxL0ijFp5smbs3Y07RO7CxKBHNM/RsrsGtWvuk6edITMp4oqL9C3ufEAmpYk3dqOZRSf+sFH4Zg==", + "dependencies": { + "Microsoft.Windows.SDK.BuildTools": "10.0.22621.1" + } } }, "native,Version=v0.0/win10-x64": { - "Microsoft.Web.WebView2": { - "type": "Transitive", - "resolved": "1.0.1264.42", - "contentHash": "7OBUTkzQ5VI/3gb0ufi5U4zjuCowAJwQg2li0zXXzqkM+S1kmOlivTy1R4jAW+gY5Vyg510M+qMAESCQUjrfgA==" + "Microsoft.WindowsAppSDK": { + "type": "Direct", + "requested": "[1.4.230913002, )", + "resolved": "1.4.230913002", + "contentHash": "l+9RshN4TsTuxL0ijFp5smbs3Y07RO7CxKBHNM/RsrsGtWvuk6edITMp4oqL9C3ufEAmpYk3dqOZRSf+sFH4Zg==", + "dependencies": { + "Microsoft.Windows.SDK.BuildTools": "10.0.22621.1" + } } }, "native,Version=v0.0/win10-x64-aot": { - "Microsoft.Web.WebView2": { - "type": "Transitive", - "resolved": "1.0.1264.42", - "contentHash": "7OBUTkzQ5VI/3gb0ufi5U4zjuCowAJwQg2li0zXXzqkM+S1kmOlivTy1R4jAW+gY5Vyg510M+qMAESCQUjrfgA==" + "Microsoft.WindowsAppSDK": { + "type": "Direct", + "requested": "[1.4.230913002, )", + "resolved": "1.4.230913002", + "contentHash": "l+9RshN4TsTuxL0ijFp5smbs3Y07RO7CxKBHNM/RsrsGtWvuk6edITMp4oqL9C3ufEAmpYk3dqOZRSf+sFH4Zg==", + "dependencies": { + "Microsoft.Windows.SDK.BuildTools": "10.0.22621.1" + } } }, "native,Version=v0.0/win10-x86": { - "Microsoft.Web.WebView2": { - "type": "Transitive", - "resolved": "1.0.1264.42", - "contentHash": "7OBUTkzQ5VI/3gb0ufi5U4zjuCowAJwQg2li0zXXzqkM+S1kmOlivTy1R4jAW+gY5Vyg510M+qMAESCQUjrfgA==" + "Microsoft.WindowsAppSDK": { + "type": "Direct", + "requested": "[1.4.230913002, )", + "resolved": "1.4.230913002", + "contentHash": "l+9RshN4TsTuxL0ijFp5smbs3Y07RO7CxKBHNM/RsrsGtWvuk6edITMp4oqL9C3ufEAmpYk3dqOZRSf+sFH4Zg==", + "dependencies": { + "Microsoft.Windows.SDK.BuildTools": "10.0.22621.1" + } } }, "native,Version=v0.0/win10-x86-aot": { - "Microsoft.Web.WebView2": { - "type": "Transitive", - "resolved": "1.0.1264.42", - "contentHash": "7OBUTkzQ5VI/3gb0ufi5U4zjuCowAJwQg2li0zXXzqkM+S1kmOlivTy1R4jAW+gY5Vyg510M+qMAESCQUjrfgA==" + "Microsoft.WindowsAppSDK": { + "type": "Direct", + "requested": "[1.4.230913002, )", + "resolved": "1.4.230913002", + "contentHash": "l+9RshN4TsTuxL0ijFp5smbs3Y07RO7CxKBHNM/RsrsGtWvuk6edITMp4oqL9C3ufEAmpYk3dqOZRSf+sFH4Zg==", + "dependencies": { + "Microsoft.Windows.SDK.BuildTools": "10.0.22621.1" + } } } } From 699309d8bc2df1669e666b7996cadf2be88e062c Mon Sep 17 00:00:00 2001 From: Andrew Coates <30809111+acoates-ms@users.noreply.github.com> Date: Wed, 11 Oct 2023 13:21:48 -0700 Subject: [PATCH 2/6] Hook up AutomationProvider when running as an island --- .../CustomComponent.cpp | 8 +- .../Playground-Composition.cpp | 9 +- .../Fabric/Composition/Composition.Input.cpp | 13 +- .../Fabric/Composition/Composition.Input.h | 2 +- .../Composition/CompositionEventHandler.cpp | 152 +++++++++--------- .../CompositionRootAutomationProvider.cpp | 16 ++ .../CompositionRootAutomationProvider.h | 6 + .../Composition/CompositionRootView.cpp | 19 ++- 8 files changed, 132 insertions(+), 93 deletions(-) diff --git a/packages/playground/windows/playground-composition/CustomComponent.cpp b/packages/playground/windows/playground-composition/CustomComponent.cpp index 3517c11cc72..94265a0fb1a 100644 --- a/packages/playground/windows/playground-composition/CustomComponent.cpp +++ b/packages/playground/windows/playground-composition/CustomComponent.cpp @@ -1,9 +1,9 @@ #include "pch.h" -#include -#include -#include #include +#include +#include +#include /* * Custom Properties can be passed from JS to this native component @@ -119,5 +119,5 @@ struct CustomComponent : winrt::implements }; void RegisterCustomComponent(winrt::Microsoft::ReactNative::IReactPackageBuilder const &packageBuilder) noexcept { - CustomComponent::RegisterViewComponent(packageBuilder); + CustomComponent::RegisterViewComponent(packageBuilder); } diff --git a/packages/playground/windows/playground-composition/Playground-Composition.cpp b/packages/playground/windows/playground-composition/Playground-Composition.cpp index fae2b02b8c7..3c1259cfc15 100644 --- a/packages/playground/windows/playground-composition/Playground-Composition.cpp +++ b/packages/playground/windows/playground-composition/Playground-Composition.cpp @@ -192,8 +192,8 @@ struct WindowData { auto appContent = m_compRootView.Island(); - //auto invScale = static_cast(1.0 / ScaleFactor(hwnd)); - //m_compRootView.RootVisual().Scale({invScale, invScale, 1}); + // auto invScale = static_cast(1.0 / ScaleFactor(hwnd)); + // m_compRootView.RootVisual().Scale({invScale, invScale, 1}); /* // Future versions of WinAppSDK will have more capabilities around scale and size @@ -201,7 +201,6 @@ struct WindowData { auto siteWindow = site.Environment(); auto displayScale = siteWindow.DisplayScale(); - // Size the island to be half the size of the custom component, to more easily test behavior across the island site.ParentScale(displayScale); site.ActualSize({metrics.Frame.Width / 2, metrics.Frame.Height / 2}); site.ClientSize( @@ -209,12 +208,12 @@ struct WindowData { static_cast(metrics.Frame.Height / 2 * metrics.PointScaleFactor)}); */ - //bridge.OverrideScale(static_cast(ScaleFactor(hwnd))); + // bridge.OverrideScale(static_cast(ScaleFactor(hwnd))); bridge.Connect(appContent); bridge.Show(); m_compRootView.ScaleFactor(ScaleFactor(hwnd)); - //m_compRootView.ScaleFactor(1); + // m_compRootView.ScaleFactor(1); m_compRootView.Size( {static_cast(m_width / ScaleFactor(hwnd)), static_cast(m_height / ScaleFactor(hwnd))}); diff --git a/vnext/Microsoft.ReactNative/Fabric/Composition/Composition.Input.cpp b/vnext/Microsoft.ReactNative/Fabric/Composition/Composition.Input.cpp index 980a695da26..8468ef47eed 100644 --- a/vnext/Microsoft.ReactNative/Fabric/Composition/Composition.Input.cpp +++ b/vnext/Microsoft.ReactNative/Fabric/Composition/Composition.Input.cpp @@ -34,7 +34,8 @@ KeyRoutedEventArgs::KeyRoutedEventArgs(facebook::react::Tag tag, uint32_t msg, u } #ifdef USE_WINUI3 -KeyRoutedEventArgs::KeyRoutedEventArgs(facebook::react::Tag tag, winrt::Microsoft::UI::Input::KeyEventArgs const& args) : m_tag(tag) { +KeyRoutedEventArgs::KeyRoutedEventArgs(facebook::react::Tag tag, winrt::Microsoft::UI::Input::KeyEventArgs const &args) + : m_tag(tag) { auto keyStatus = args.KeyStatus(); m_keyStatus.RepeatCount = keyStatus.RepeatCount; m_keyStatus.ScanCode = keyStatus.ScanCode; @@ -160,7 +161,7 @@ bool PointerPointProperties::IsEraser() noexcept { bool PointerPointProperties::IsHorizontalMouseWheel() noexcept { #ifdef USE_WINUI3 if (m_sysPointerPointProps) { - return m_sysPointerPointProps.IsHorizontalMouseWheel(); + return m_sysPointerPointProps.IsHorizontalMouseWheel(); } #endif return m_isHorizontalMouseWheel; @@ -260,7 +261,7 @@ PointerUpdateKind PointerPointProperties::PointerUpdateKind() noexcept { #ifdef USE_WINUI3 if (m_sysPointerPointProps) { return static_cast( - m_sysPointerPointProps.PointerUpdateKind()); + m_sysPointerPointProps.PointerUpdateKind()); } #endif return m_pointerUpdateKind; @@ -328,9 +329,9 @@ PointerPoint::PointerPoint(uint32_t msg, uint64_t wParam, int64_t lParam) { uint32_t PointerPoint::FrameId() noexcept { #ifdef USE_WINUI3 -if (m_sysPointerPoint) { - return m_sysPointerPoint.FrameId(); -} + if (m_sysPointerPoint) { + return m_sysPointerPoint.FrameId(); + } #endif return m_pi.frameId; } diff --git a/vnext/Microsoft.ReactNative/Fabric/Composition/Composition.Input.h b/vnext/Microsoft.ReactNative/Fabric/Composition/Composition.Input.h index 2befedaff67..4075f9efd9c 100644 --- a/vnext/Microsoft.ReactNative/Fabric/Composition/Composition.Input.h +++ b/vnext/Microsoft.ReactNative/Fabric/Composition/Composition.Input.h @@ -21,7 +21,7 @@ struct KeyRoutedEventArgs : winrt::implements< winrt::Microsoft::ReactNative::Composition::Input::RoutedEventArgs> { KeyRoutedEventArgs(facebook::react::Tag tag, uint32_t msg, uint64_t wParam, int64_t lParam); #ifdef USE_WINUI3 - KeyRoutedEventArgs(facebook::react::Tag tag, winrt::Microsoft::UI::Input::KeyEventArgs const& args); + KeyRoutedEventArgs(facebook::react::Tag tag, winrt::Microsoft::UI::Input::KeyEventArgs const &args); #endif int32_t OriginalSource() noexcept; diff --git a/vnext/Microsoft.ReactNative/Fabric/Composition/CompositionEventHandler.cpp b/vnext/Microsoft.ReactNative/Fabric/Composition/CompositionEventHandler.cpp index 03810d4f26d..9f643d804f9 100644 --- a/vnext/Microsoft.ReactNative/Fabric/Composition/CompositionEventHandler.cpp +++ b/vnext/Microsoft.ReactNative/Fabric/Composition/CompositionEventHandler.cpp @@ -102,117 +102,118 @@ struct CompositionKeyboardSource } private: - CompositionEventHandler* m_outer { nullptr }; + CompositionEventHandler *m_outer{nullptr}; }; - #ifdef USE_WINUI3 -struct CompositionInputKeyboardSource - : winrt::implements -{ - CompositionInputKeyboardSource(winrt::Microsoft::UI::Input::InputKeyboardSource source) : m_source(source) - { - } +struct CompositionInputKeyboardSource : winrt::implements< + CompositionInputKeyboardSource, + winrt::Microsoft::ReactNative::Composition::Input::KeyboardSource> { + CompositionInputKeyboardSource(winrt::Microsoft::UI::Input::InputKeyboardSource source) : m_source(source) {} - winrt::Windows::UI::Core::CoreVirtualKeyStates GetKeyState(winrt::Windows::System::VirtualKey key) noexcept - { + winrt::Windows::UI::Core::CoreVirtualKeyStates GetKeyState(winrt::Windows::System::VirtualKey key) noexcept { if (!m_source) return winrt::Windows::UI::Core::CoreVirtualKeyStates::None; - static_assert(static_cast(winrt::Microsoft::UI::Input::VirtualKeyStates::Down) == winrt::Windows::UI::Core::CoreVirtualKeyStates::Down); - static_assert(static_cast(winrt::Microsoft::UI::Input::VirtualKeyStates::Locked) == winrt::Windows::UI::Core::CoreVirtualKeyStates::Locked); - static_assert(static_cast(winrt::Microsoft::UI::Input::VirtualKeyStates::None) == winrt::Windows::UI::Core::CoreVirtualKeyStates::None); + static_assert( + static_cast( + winrt::Microsoft::UI::Input::VirtualKeyStates::Down) == + winrt::Windows::UI::Core::CoreVirtualKeyStates::Down); + static_assert( + static_cast( + winrt::Microsoft::UI::Input::VirtualKeyStates::Locked) == + winrt::Windows::UI::Core::CoreVirtualKeyStates::Locked); + static_assert( + static_cast( + winrt::Microsoft::UI::Input::VirtualKeyStates::None) == + winrt::Windows::UI::Core::CoreVirtualKeyStates::None); return static_cast(m_source.GetKeyState(key)); } - void Disconnect() noexcept - { + void Disconnect() noexcept { m_source = nullptr; } -private: - winrt::Microsoft::UI::Input::InputKeyboardSource m_source { nullptr }; + private: + winrt::Microsoft::UI::Input::InputKeyboardSource m_source{nullptr}; }; #endif CompositionEventHandler::CompositionEventHandler( const winrt::Microsoft::ReactNative::ReactContext &context, const winrt::Microsoft::ReactNative::CompositionRootView &CompositionRootView) - : m_context(context) { + : m_context(context) { m_compRootView = CompositionRootView; #ifdef USE_WINUI3 if (auto island = m_compRootView.Island()) { - auto pointerSource = winrt::Microsoft::UI::Input::InputPointerSource::GetForIsland(island); - - pointerSource.PointerPressed([this]( - winrt::Microsoft::UI::Input::InputPointerSource const &, - winrt::Microsoft::UI::Input::PointerEventArgs const &args) { + auto pointerSource = winrt::Microsoft::UI::Input::InputPointerSource::GetForIsland(island); - auto pp = winrt::make( + pointerSource.PointerPressed([this]( + winrt::Microsoft::UI::Input::InputPointerSource const &, + winrt::Microsoft::UI::Input::PointerEventArgs const &args) { + auto pp = winrt::make( args.CurrentPoint()); onPointerPressed(pp, args.KeyModifiers()); - }); + }); - pointerSource.PointerReleased([this]( - winrt::Microsoft::UI::Input::InputPointerSource const&, - winrt::Microsoft::UI::Input::PointerEventArgs const& args) - { - auto pp = winrt::make( + pointerSource.PointerReleased([this]( + winrt::Microsoft::UI::Input::InputPointerSource const &, + winrt::Microsoft::UI::Input::PointerEventArgs const &args) { + auto pp = winrt::make( args.CurrentPoint()); - onPointerReleased(pp, args.KeyModifiers()); - }); - - pointerSource.PointerMoved([this]( - winrt::Microsoft::UI::Input::InputPointerSource const&, - winrt::Microsoft::UI::Input::PointerEventArgs const& args) - { - auto pp = winrt::make( + onPointerReleased(pp, args.KeyModifiers()); + }); + + pointerSource.PointerMoved([this]( + winrt::Microsoft::UI::Input::InputPointerSource const &, + winrt::Microsoft::UI::Input::PointerEventArgs const &args) { + auto pp = winrt::make( args.CurrentPoint()); - onPointerMoved(pp, args.KeyModifiers()); - }); - - pointerSource.PointerWheelChanged([this]( - winrt::Microsoft::UI::Input::InputPointerSource const&, - winrt::Microsoft::UI::Input::PointerEventArgs const& args) - { - auto pp = winrt::make( + onPointerMoved(pp, args.KeyModifiers()); + }); + + pointerSource.PointerWheelChanged([this]( + winrt::Microsoft::UI::Input::InputPointerSource const &, + winrt::Microsoft::UI::Input::PointerEventArgs const &args) { + auto pp = winrt::make( args.CurrentPoint()); - onPointerWheelChanged(pp, args.KeyModifiers()); - }); + onPointerWheelChanged(pp, args.KeyModifiers()); + }); - auto keyboardSource = winrt::Microsoft::UI::Input::InputKeyboardSource::GetForIsland(island); + auto keyboardSource = winrt::Microsoft::UI::Input::InputKeyboardSource::GetForIsland(island); - keyboardSource.KeyDown([this](winrt::Microsoft::UI::Input::InputKeyboardSource const& source, winrt::Microsoft::UI::Input::KeyEventArgs const& args) - { - auto focusedComponent = RootComponentView().GetFocusedComponent(); - auto keyArgs = winrt::make( + keyboardSource.KeyDown([this]( + winrt::Microsoft::UI::Input::InputKeyboardSource const &source, + winrt::Microsoft::UI::Input::KeyEventArgs const &args) { + auto focusedComponent = RootComponentView().GetFocusedComponent(); + auto keyArgs = winrt::make( focusedComponent - ? focusedComponent->tag() - : static_cast( - winrt::get_self(m_compRootView) - ->GetTag()), + ? focusedComponent->tag() + : static_cast( + winrt::get_self(m_compRootView) + ->GetTag()), args); - auto keyboardSource = winrt::make(source); - onKeyDown(keyboardSource, keyArgs); - winrt::get_self(keyboardSource)->Disconnect(); - }); - - keyboardSource.KeyUp([this](winrt::Microsoft::UI::Input::InputKeyboardSource const& source, winrt::Microsoft::UI::Input::KeyEventArgs const& args) - { - auto focusedComponent = RootComponentView().GetFocusedComponent(); - auto keyArgs = winrt::make( + auto keyboardSource = winrt::make(source); + onKeyDown(keyboardSource, keyArgs); + winrt::get_self(keyboardSource)->Disconnect(); + }); + + keyboardSource.KeyUp([this]( + winrt::Microsoft::UI::Input::InputKeyboardSource const &source, + winrt::Microsoft::UI::Input::KeyEventArgs const &args) { + auto focusedComponent = RootComponentView().GetFocusedComponent(); + auto keyArgs = winrt::make( focusedComponent - ? focusedComponent->tag() - : static_cast( - winrt::get_self(m_compRootView) - ->GetTag()), + ? focusedComponent->tag() + : static_cast( + winrt::get_self(m_compRootView) + ->GetTag()), args); - auto keyboardSource = winrt::make(source); - onKeyUp(keyboardSource, keyArgs); - winrt::get_self(keyboardSource)->Disconnect(); - }); - + auto keyboardSource = winrt::make(source); + onKeyUp(keyboardSource, keyArgs); + winrt::get_self(keyboardSource)->Disconnect(); + }); } #endif }; @@ -617,7 +618,6 @@ facebook::react::PointerEvent CreatePointerEventFromIncompleteHoverData( void CompositionEventHandler::onPointerMoved( const winrt::Microsoft::ReactNative::Composition::Input::PointerPoint &pointerPoint, winrt::Windows::System::VirtualKeyModifiers keyModifiers) noexcept { - if (SurfaceId() == -1) return; diff --git a/vnext/Microsoft.ReactNative/Fabric/Composition/CompositionRootAutomationProvider.cpp b/vnext/Microsoft.ReactNative/Fabric/Composition/CompositionRootAutomationProvider.cpp index f0dd6e35880..de6c5769c7d 100644 --- a/vnext/Microsoft.ReactNative/Fabric/Composition/CompositionRootAutomationProvider.cpp +++ b/vnext/Microsoft.ReactNative/Fabric/Composition/CompositionRootAutomationProvider.cpp @@ -3,6 +3,10 @@ #include #include "UiaHelpers.h" +#ifdef USE_WINUI3 +#include +#endif + namespace winrt::Microsoft::ReactNative::implementation { CompositionRootAutomationProvider::CompositionRootAutomationProvider( @@ -56,6 +60,14 @@ HRESULT __stdcall CompositionRootAutomationProvider::get_HostRawElementProvider( if (pRetVal == nullptr) return E_POINTER; +#ifdef USE_WINUI3 + if (m_island) { + winrt::Windows::Foundation::IInspectable host = m_island.GetAutomationHostProvider(); + *pRetVal = host.as().detach(); + return S_OK; + } +#endif + // TODO: assumes windowed if (!IsWindow(m_hwnd)) return UIA_E_ELEMENTNOTAVAILABLE; @@ -172,6 +184,10 @@ void CompositionRootAutomationProvider::SetHwnd(HWND hwnd) noexcept { m_hwnd = hwnd; } +void CompositionRootAutomationProvider::SetIsland(winrt::Microsoft::UI::Content::ContentIsland &island) noexcept { + m_island = island; +} + HRESULT __stdcall CompositionRootAutomationProvider::Navigate( NavigateDirection direction, IRawElementProviderFragment **pRetVal) { diff --git a/vnext/Microsoft.ReactNative/Fabric/Composition/CompositionRootAutomationProvider.h b/vnext/Microsoft.ReactNative/Fabric/Composition/CompositionRootAutomationProvider.h index 8ba2f23a4e4..aafe93559e9 100644 --- a/vnext/Microsoft.ReactNative/Fabric/Composition/CompositionRootAutomationProvider.h +++ b/vnext/Microsoft.ReactNative/Fabric/Composition/CompositionRootAutomationProvider.h @@ -43,6 +43,9 @@ class CompositionRootAutomationProvider : public winrt::implements< const std::shared_ptr<::Microsoft::ReactNative::RootComponentView> &componentView) noexcept; void SetHwnd(HWND hwnd) noexcept; +#ifdef USE_WINUI3 + void SetIsland(winrt::Microsoft::UI::Content::ContentIsland &island) noexcept; +#endif bool WasPropertyAdvised(PROPERTYID prop) noexcept; bool WasEventAdvised(EVENTID event) noexcept; @@ -70,6 +73,9 @@ class CompositionRootAutomationProvider : public winrt::implements< std::vector m_advisedProperties{}; ::Microsoft::ReactNative::ReactTaggedView m_view; HWND m_hwnd{nullptr}; +#ifdef USE_WINUI3 + winrt::Microsoft::UI::Content::ContentIsland m_island{nullptr}; +#endif }; } // namespace winrt::Microsoft::ReactNative::implementation diff --git a/vnext/Microsoft.ReactNative/Fabric/Composition/CompositionRootView.cpp b/vnext/Microsoft.ReactNative/Fabric/Composition/CompositionRootView.cpp index a6dbcb78ca2..911daa003d2 100644 --- a/vnext/Microsoft.ReactNative/Fabric/Composition/CompositionRootView.cpp +++ b/vnext/Microsoft.ReactNative/Fabric/Composition/CompositionRootView.cpp @@ -23,6 +23,7 @@ #ifdef USE_WINUI3 #include +#include "CompositionRootAutomationProvider.h" #endif namespace winrt::Microsoft::ReactNative::implementation { @@ -103,7 +104,8 @@ inline Mso::Future CompositionReactViewInstance::PostInUIQueue(TAction &&a CompositionRootView::CompositionRootView() noexcept {} #ifdef USE_WINUI3 -CompositionRootView::CompositionRootView(winrt::Microsoft::UI::Composition::Compositor compositor) noexcept : m_compositor(compositor) {} +CompositionRootView::CompositionRootView(winrt::Microsoft::UI::Composition::Compositor compositor) noexcept + : m_compositor(compositor) {} #endif ReactNative::IReactViewHost CompositionRootView::ReactViewHost() noexcept { @@ -384,6 +386,21 @@ winrt::Microsoft::UI::Content::ContentIsland CompositionRootView::Island() noexc RootVisual(winrt::Microsoft::ReactNative::Composition::MicrosoftCompositionContextHelper::CreateVisual(rootVisual)); m_island = winrt::Microsoft::UI::Content::ContentIsland::Create(rootVisual); + + m_island.AutomationProviderRequested( + [this]( + winrt::Microsoft::UI::Content::ContentIsland const &, + winrt::Microsoft::UI::Content::ContentIslandAutomationProviderRequestedEventArgs const &args) { + auto provider = GetUiaProvider(); + auto pRootProvider = + static_cast( + provider.as().get()); + if (pRootProvider != nullptr) { + pRootProvider->SetIsland(m_island); + } + args.AutomationProvider(std::move(provider)); + args.Handled(true); + }); } return m_island; } From 8171c77cd4622a941d2ac70ccd3e0f989ed38a72 Mon Sep 17 00:00:00 2001 From: Andrew Coates <30809111+acoates-ms@users.noreply.github.com> Date: Wed, 11 Oct 2023 14:12:14 -0700 Subject: [PATCH 3/6] Input args from window message should be translated to scaled coords --- .../Playground-Composition.cpp | 19 ++++++------- .../CompositionRootView.idl | 2 +- .../Fabric/Composition/Composition.Input.cpp | 23 +++++++++------ .../Fabric/Composition/Composition.Input.h | 3 +- .../Composition/CompositionEventHandler.cpp | 28 +++++++------------ .../Composition/CompositionHwndHost.cpp | 4 +-- .../Fabric/Composition/CompositionHwndHost.h | 2 +- .../Composition/CompositionRootView.cpp | 12 ++------ .../Fabric/Composition/CompositionRootView.h | 6 ++-- .../CompositionRootView_emptyimpl.cpp | 4 +-- .../Fabric/FabricUIManagerModule.cpp | 4 +-- .../Views/ICompositionRootView.h | 2 +- 12 files changed, 49 insertions(+), 60 deletions(-) diff --git a/packages/playground/windows/playground-composition/Playground-Composition.cpp b/packages/playground/windows/playground-composition/Playground-Composition.cpp index 3c1259cfc15..b7f19f28ebb 100644 --- a/packages/playground/windows/playground-composition/Playground-Composition.cpp +++ b/packages/playground/windows/playground-composition/Playground-Composition.cpp @@ -192,8 +192,8 @@ struct WindowData { auto appContent = m_compRootView.Island(); - // auto invScale = static_cast(1.0 / ScaleFactor(hwnd)); - // m_compRootView.RootVisual().Scale({invScale, invScale, 1}); + 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 @@ -208,14 +208,13 @@ struct WindowData { static_cast(metrics.Frame.Height / 2 * metrics.PointScaleFactor)}); */ - // bridge.OverrideScale(static_cast(ScaleFactor(hwnd))); + // bridge.OverrideScale(ScaleFactor(hwnd)); bridge.Connect(appContent); bridge.Show(); m_compRootView.ScaleFactor(ScaleFactor(hwnd)); // m_compRootView.ScaleFactor(1); - m_compRootView.Size( - {static_cast(m_width / ScaleFactor(hwnd)), static_cast(m_height / ScaleFactor(hwnd))}); + m_compRootView.Size({m_width / ScaleFactor(hwnd), m_height / ScaleFactor(hwnd)}); bridge.ResizePolicy(winrt::Microsoft::UI::Content::ContentSizePolicy::ResizeContentToParentWindow); @@ -243,8 +242,7 @@ struct WindowData { m_compRootView.RootVisual( winrt::Microsoft::ReactNative::Composition::WindowsCompositionContextHelper::CreateVisual(root)); m_compRootView.ScaleFactor(ScaleFactor(hwnd)); - m_compRootView.Size( - {static_cast(m_width / ScaleFactor(hwnd)), static_cast(m_height / ScaleFactor(hwnd))}); + m_compRootView.Size({m_width / ScaleFactor(hwnd), m_height / ScaleFactor(hwnd)}); } } @@ -276,8 +274,8 @@ struct WindowData { return 0; } - double ScaleFactor(HWND hwnd) noexcept { - return GetDpiForWindow(hwnd) / 96.0; + float ScaleFactor(HWND hwnd) noexcept { + return GetDpiForWindow(hwnd) / 96.0f; } void UpdateSize(HWND hwnd) noexcept { @@ -288,8 +286,7 @@ struct WindowData { m_width = rc.right - rc.left; if (m_compRootView) { - winrt::Windows::Foundation::Size size{ - static_cast(m_width / ScaleFactor(hwnd)), static_cast(m_height / ScaleFactor(hwnd))}; + winrt::Windows::Foundation::Size size{m_width / ScaleFactor(hwnd), m_height / ScaleFactor(hwnd)}; m_compRootView.Arrange(size); m_compRootView.Size(size); } diff --git a/vnext/Microsoft.ReactNative/CompositionRootView.idl b/vnext/Microsoft.ReactNative/CompositionRootView.idl index c40e073406a..a7b15732305 100644 --- a/vnext/Microsoft.ReactNative/CompositionRootView.idl +++ b/vnext/Microsoft.ReactNative/CompositionRootView.idl @@ -64,7 +64,7 @@ namespace Microsoft.ReactNative Windows.Foundation.Size Size {get; set; }; DOC_STRING("ScaleFactor for this windows (DPI/96)") - Double ScaleFactor {get; set;}; + Single ScaleFactor {get; set;}; DOC_STRING("Move focus to this @CompositionRootView") FocusNavigationResult NavigateFocus(FocusNavigationRequest request); diff --git a/vnext/Microsoft.ReactNative/Fabric/Composition/Composition.Input.cpp b/vnext/Microsoft.ReactNative/Fabric/Composition/Composition.Input.cpp index 8468ef47eed..1f30a275765 100644 --- a/vnext/Microsoft.ReactNative/Fabric/Composition/Composition.Input.cpp +++ b/vnext/Microsoft.ReactNative/Fabric/Composition/Composition.Input.cpp @@ -316,10 +316,11 @@ float PointerPointProperties::YTilt() noexcept { PointerPoint::PointerPoint(const winrt::Microsoft::UI::Input::PointerPoint &pp) : m_sysPointerPoint(pp) {} #endif -PointerPoint::PointerPoint(uint32_t msg, uint64_t wParam, int64_t lParam) { +PointerPoint::PointerPoint(uint32_t msg, uint64_t wParam, int64_t lParam, float scaleFactor) { m_msg = msg; m_wParam = wParam; m_lParam = lParam; + m_scaleFactor = scaleFactor; if (IsPointerMessage(msg)) { const unsigned int pointerId = GET_POINTERID_WPARAM(wParam); bool result = ::GetPointerInfo(pointerId, &m_pi); @@ -381,19 +382,25 @@ uint32_t PointerPoint::PointerId() noexcept { } winrt::Windows::Foundation::Point PointerPoint::Position() noexcept { - return m_sysPointerPoint - ? m_sysPointerPoint.Position() - : (m_pi.pointerId - ? winrt::Windows::Foundation:: - Point{static_cast(m_pi.ptPixelLocation.x), static_cast(m_pi.ptPixelLocation.y)} - : winrt::Windows::Foundation::Point{ - static_cast(GET_X_LPARAM(m_lParam)), static_cast(GET_Y_LPARAM(m_lParam))}); +#ifdef USE_WINUI3 + if (m_sysPointerPoint) { + return m_sysPointerPoint.Position(); + } +#endif + return m_pi.pointerId + ? winrt::Windows::Foundation:: + Point{static_cast(m_pi.ptPixelLocation.x / m_scaleFactor), static_cast(m_pi.ptPixelLocation.y / m_scaleFactor)} + : winrt::Windows::Foundation::Point{ + static_cast(GET_X_LPARAM(m_lParam) / m_scaleFactor), + static_cast(GET_Y_LPARAM(m_lParam) / m_scaleFactor)}; } winrt::Microsoft::ReactNative::Composition::Input::PointerPointProperties PointerPoint::Properties() noexcept { +#ifdef USE_WINUI3 if (m_sysPointerPoint) { return winrt::make(m_sysPointerPoint.Properties()); } +#endif if (m_pi.pointerId) { auto pointerUpdateKind = winrt::Microsoft::ReactNative::Composition::Input::PointerUpdateKind::Other; diff --git a/vnext/Microsoft.ReactNative/Fabric/Composition/Composition.Input.h b/vnext/Microsoft.ReactNative/Fabric/Composition/Composition.Input.h index 4075f9efd9c..8f9a30c9345 100644 --- a/vnext/Microsoft.ReactNative/Fabric/Composition/Composition.Input.h +++ b/vnext/Microsoft.ReactNative/Fabric/Composition/Composition.Input.h @@ -118,7 +118,7 @@ struct PointerPointProperties : PointerPointPropertiesT struct PointerPoint : PointerPointT { PointerPoint(const winrt::Microsoft::UI::Input::PointerPoint &pp); - PointerPoint(uint32_t msg, uint64_t wParam, int64_t lParam); + PointerPoint(uint32_t msg, uint64_t wParam, int64_t lParam, float scaleFactor); uint32_t FrameId() noexcept; bool IsInContact() noexcept; @@ -143,6 +143,7 @@ struct PointerPoint : PointerPointT { uint32_t m_msg; uint64_t m_wParam; int64_t m_lParam; + float m_scaleFactor; }; struct PointerRoutedEventArgs : PointerRoutedEventArgsT { diff --git a/vnext/Microsoft.ReactNative/Fabric/Composition/CompositionEventHandler.cpp b/vnext/Microsoft.ReactNative/Fabric/Composition/CompositionEventHandler.cpp index 9f643d804f9..e4409a2f53c 100644 --- a/vnext/Microsoft.ReactNative/Fabric/Composition/CompositionEventHandler.cpp +++ b/vnext/Microsoft.ReactNative/Fabric/Composition/CompositionEventHandler.cpp @@ -240,9 +240,7 @@ void CompositionEventHandler::onPointerWheelChanged( auto position = pointerPoint.Position(); facebook::react::Point ptLocal; - facebook::react::Point ptScaled = { - static_cast(position.X / m_compRootView.ScaleFactor()), - static_cast(position.Y / m_compRootView.ScaleFactor())}; + facebook::react::Point ptScaled = {static_cast(position.X), static_cast(position.Y)}; auto tag = RootComponentView().hitTest(ptScaled, ptLocal); @@ -293,37 +291,37 @@ int64_t CompositionEventHandler::SendMessage(uint32_t msg, uint64_t wParam, int6 switch (msg) { case WM_LBUTTONDOWN: { auto pp = winrt::make( - msg, wParam, lParam); + msg, wParam, lParam, m_compRootView.ScaleFactor()); onPointerPressed(pp, GetKeyModifiers(wParam)); return 0; } case WM_POINTERDOWN: { auto pp = winrt::make( - msg, wParam, lParam); + msg, wParam, lParam, m_compRootView.ScaleFactor()); onPointerPressed(pp, GetKeyModifiers(wParam)); return 0; } case WM_LBUTTONUP: { auto pp = winrt::make( - msg, wParam, lParam); + msg, wParam, lParam, m_compRootView.ScaleFactor()); onPointerReleased(pp, GetKeyModifiers(wParam)); return 0; } case WM_POINTERUP: { auto pp = winrt::make( - msg, wParam, lParam); + msg, wParam, lParam, m_compRootView.ScaleFactor()); onPointerReleased(pp, GetKeyModifiers(wParam)); return 0; } case WM_MOUSEMOVE: { auto pp = winrt::make( - msg, wParam, lParam); + msg, wParam, lParam, m_compRootView.ScaleFactor()); onPointerMoved(pp, GetKeyModifiers(wParam)); return 0; } case WM_MOUSEWHEEL: { auto pp = winrt::make( - msg, wParam, lParam); + msg, wParam, lParam, m_compRootView.ScaleFactor()); onPointerWheelChanged(pp, GetKeyModifiers(wParam)); } case WM_CHAR: @@ -629,9 +627,7 @@ void CompositionEventHandler::onPointerMoved( ::Microsoft::ReactNative::FabricUIManager::FromProperties(m_context.Properties())) { facebook::react::Point ptLocal; - facebook::react::Point ptScaled = { - static_cast(position.X / m_compRootView.ScaleFactor()), - static_cast(position.Y / m_compRootView.ScaleFactor())}; + facebook::react::Point ptScaled = {position.X, position.Y}; auto tag = RootComponentView().hitTest(ptScaled, ptLocal); if (tag == -1) @@ -685,9 +681,7 @@ void CompositionEventHandler::onPointerPressed( ::Microsoft::ReactNative::FabricUIManager::FromProperties(m_context.Properties())) { facebook::react::Point ptLocal; - facebook::react::Point ptScaled = { - static_cast(position.X / m_compRootView.ScaleFactor()), - static_cast(position.Y / m_compRootView.ScaleFactor())}; + facebook::react::Point ptScaled = {position.X, position.Y}; auto tag = RootComponentView().hitTest(ptScaled, ptLocal); if (tag == -1) @@ -750,9 +744,7 @@ void CompositionEventHandler::onPointerReleased( ::Microsoft::ReactNative::FabricUIManager::FromProperties(m_context.Properties())) { facebook::react::Point ptLocal; - facebook::react::Point ptScaled = { - static_cast(position.X / m_compRootView.ScaleFactor()), - static_cast(position.Y / m_compRootView.ScaleFactor())}; + facebook::react::Point ptScaled = {position.X, position.Y}; auto tag = RootComponentView().hitTest(ptScaled, ptLocal); if (tag == -1) diff --git a/vnext/Microsoft.ReactNative/Fabric/Composition/CompositionHwndHost.cpp b/vnext/Microsoft.ReactNative/Fabric/Composition/CompositionHwndHost.cpp index a9746c9955d..ae09c2c76e2 100644 --- a/vnext/Microsoft.ReactNative/Fabric/Composition/CompositionHwndHost.cpp +++ b/vnext/Microsoft.ReactNative/Fabric/Composition/CompositionHwndHost.cpp @@ -67,8 +67,8 @@ void CompositionHwndHost::Initialize(uint64_t hwnd) noexcept { UpdateSize(); } -double CompositionHwndHost::ScaleFactor() noexcept { - return GetDpiForWindow(m_hwnd) / 96.0; +float CompositionHwndHost::ScaleFactor() noexcept { + return GetDpiForWindow(m_hwnd) / 96.0f; } void CompositionHwndHost::UpdateSize() noexcept { diff --git a/vnext/Microsoft.ReactNative/Fabric/Composition/CompositionHwndHost.h b/vnext/Microsoft.ReactNative/Fabric/Composition/CompositionHwndHost.h index 33fd872826b..bf2890b40e3 100644 --- a/vnext/Microsoft.ReactNative/Fabric/Composition/CompositionHwndHost.h +++ b/vnext/Microsoft.ReactNative/Fabric/Composition/CompositionHwndHost.h @@ -38,7 +38,7 @@ struct CompositionHwndHost : CompositionHwndHostT { void CreateDesktopWindowTarget(HWND window); void CreateCompositionRoot(); void UpdateSize() noexcept; - double ScaleFactor() noexcept; + float ScaleFactor() noexcept; HWND m_hwnd; winrt::Microsoft::ReactNative::CompositionRootView m_compRootView{nullptr}; diff --git a/vnext/Microsoft.ReactNative/Fabric/Composition/CompositionRootView.cpp b/vnext/Microsoft.ReactNative/Fabric/Composition/CompositionRootView.cpp index 911daa003d2..7e984a171aa 100644 --- a/vnext/Microsoft.ReactNative/Fabric/Composition/CompositionRootView.cpp +++ b/vnext/Microsoft.ReactNative/Fabric/Composition/CompositionRootView.cpp @@ -148,11 +148,11 @@ void CompositionRootView::Size(winrt::Windows::Foundation::Size value) noexcept m_size = value; } -double CompositionRootView::ScaleFactor() noexcept { +float CompositionRootView::ScaleFactor() noexcept { return m_scaleFactor; } -void CompositionRootView::ScaleFactor(double value) noexcept { +void CompositionRootView::ScaleFactor(float value) noexcept { m_scaleFactor = value; } @@ -373,17 +373,9 @@ winrt::Microsoft::UI::Content::ContentIsland CompositionRootView::Island() noexc } if (!m_island) { - auto testBrush = m_compositor.CreateColorBrush(winrt::Windows::UI::Colors::Red()); // TODO remove auto rootVisual = m_compositor.CreateSpriteVisual(); rootVisual.RelativeSizeAdjustment({1, 1}); - // Display a border around the root to help debug sizing of island - auto nine = m_compositor.CreateNineGridBrush(); // TODO remove - nine.SetInsets(10); - nine.IsCenterHollow(true); - nine.Source(testBrush); - rootVisual.Brush(nine); - RootVisual(winrt::Microsoft::ReactNative::Composition::MicrosoftCompositionContextHelper::CreateVisual(rootVisual)); m_island = winrt::Microsoft::UI::Content::ContentIsland::Create(rootVisual); diff --git a/vnext/Microsoft.ReactNative/Fabric/Composition/CompositionRootView.h b/vnext/Microsoft.ReactNative/Fabric/Composition/CompositionRootView.h index d6239b8a46b..247e6048033 100644 --- a/vnext/Microsoft.ReactNative/Fabric/Composition/CompositionRootView.h +++ b/vnext/Microsoft.ReactNative/Fabric/Composition/CompositionRootView.h @@ -61,8 +61,8 @@ struct CompositionRootView : CompositionRootViewT, ::Micros void Size(winrt::Windows::Foundation::Size value) noexcept; // ScaleFactor (DPI) - double ScaleFactor() noexcept; - void ScaleFactor(double value) noexcept; + float ScaleFactor() noexcept; + void ScaleFactor(float value) noexcept; winrt::Windows::Foundation::Size Measure(winrt::Windows::Foundation::Size const &availableSize) const; winrt::Windows::Foundation::Size Arrange(winrt::Windows::Foundation::Size finalSize) const; @@ -103,7 +103,7 @@ struct CompositionRootView : CompositionRootViewT, ::Micros bool m_isJSViewAttached{false}; IReactDispatcher m_uiDispatcher{nullptr}; int64_t m_rootTag{-1}; - double m_scaleFactor{1.0}; + float m_scaleFactor{1.0}; winrt::Windows::Foundation::Size m_size; winrt::Microsoft::ReactNative::ReactContext m_context; winrt::Microsoft::ReactNative::IReactViewHost m_reactViewHost; diff --git a/vnext/Microsoft.ReactNative/Fabric/Composition/CompositionRootView_emptyimpl.cpp b/vnext/Microsoft.ReactNative/Fabric/Composition/CompositionRootView_emptyimpl.cpp index 6bb2bbf0fd4..24635c8936a 100644 --- a/vnext/Microsoft.ReactNative/Fabric/Composition/CompositionRootView_emptyimpl.cpp +++ b/vnext/Microsoft.ReactNative/Fabric/Composition/CompositionRootView_emptyimpl.cpp @@ -47,11 +47,11 @@ winrt::Windows::Foundation::Size CompositionRootView::Size() noexcept { void CompositionRootView::Size(winrt::Windows::Foundation::Size) noexcept {} -double CompositionRootView::ScaleFactor() noexcept { +float CompositionRootView::ScaleFactor() noexcept { return 0; } -void CompositionRootView::ScaleFactor(double) noexcept {} +void CompositionRootView::ScaleFactor(float) noexcept {} winrt::IInspectable CompositionRootView::GetUiaProvider() noexcept { return nullptr; diff --git a/vnext/Microsoft.ReactNative/Fabric/FabricUIManagerModule.cpp b/vnext/Microsoft.ReactNative/Fabric/FabricUIManagerModule.cpp index 780194cb936..39e422bcd24 100644 --- a/vnext/Microsoft.ReactNative/Fabric/FabricUIManagerModule.cpp +++ b/vnext/Microsoft.ReactNative/Fabric/FabricUIManagerModule.cpp @@ -183,8 +183,8 @@ void FabricUIManager::startSurface( facebook::react::LayoutContext context; facebook::react::LayoutConstraints constraints; - context.pointScaleFactor = static_cast(CompositionRootView->ScaleFactor()); - context.fontSizeMultiplier = static_cast(CompositionRootView->ScaleFactor()); + context.pointScaleFactor = CompositionRootView->ScaleFactor(); + context.fontSizeMultiplier = CompositionRootView->ScaleFactor(); constraints.minimumSize.height = static_cast(CompositionRootView->GetActualHeight()); constraints.minimumSize.width = static_cast(CompositionRootView->GetActualWidth()); constraints.maximumSize.height = static_cast(CompositionRootView->GetActualHeight()); diff --git a/vnext/Microsoft.ReactNative/Views/ICompositionRootView.h b/vnext/Microsoft.ReactNative/Views/ICompositionRootView.h index 09a1dacb8ab..c97fae29a50 100644 --- a/vnext/Microsoft.ReactNative/Views/ICompositionRootView.h +++ b/vnext/Microsoft.ReactNative/Views/ICompositionRootView.h @@ -13,7 +13,7 @@ namespace Microsoft::ReactNative { struct ICompositionRootView : public facebook::react::IReactRootView { virtual winrt::Microsoft::ReactNative::Composition::IVisual GetVisual() const noexcept = 0; - virtual double ScaleFactor() noexcept = 0; + virtual float ScaleFactor() noexcept = 0; }; } // namespace Microsoft::ReactNative From cd69118249a28f4244c1e055db489526f372bd9e Mon Sep 17 00:00:00 2001 From: Andrew Coates <30809111+acoates-ms@users.noreply.github.com> Date: Wed, 11 Oct 2023 14:12:42 -0700 Subject: [PATCH 4/6] Change files --- ...ative-windows-085557aa-eea4-4220-9665-4c1cb7386536.json | 7 +++++++ 1 file changed, 7 insertions(+) create mode 100644 change/react-native-windows-085557aa-eea4-4220-9665-4c1cb7386536.json diff --git a/change/react-native-windows-085557aa-eea4-4220-9665-4c1cb7386536.json b/change/react-native-windows-085557aa-eea4-4220-9665-4c1cb7386536.json new file mode 100644 index 00000000000..8259cc6ef9a --- /dev/null +++ b/change/react-native-windows-085557aa-eea4-4220-9665-4c1cb7386536.json @@ -0,0 +1,7 @@ +{ + "type": "prerelease", + "comment": "[Fabric] Support hosting in ContentIsland", + "packageName": "react-native-windows", + "email": "30809111+acoates-ms@users.noreply.github.com", + "dependentChangeType": "patch" +} From d0cc5af12d7a511d438face29f22bf7ec8193d5c Mon Sep 17 00:00:00 2001 From: Andrew Coates <30809111+acoates-ms@users.noreply.github.com> Date: Wed, 11 Oct 2023 14:27:33 -0700 Subject: [PATCH 5/6] revert packages.lock --- .../Microsoft.ReactNative/packages.lock.json | 112 +++++++----------- 1 file changed, 42 insertions(+), 70 deletions(-) diff --git a/vnext/Microsoft.ReactNative/packages.lock.json b/vnext/Microsoft.ReactNative/packages.lock.json index 05b42f0576e..0f5612becc6 100644 --- a/vnext/Microsoft.ReactNative/packages.lock.json +++ b/vnext/Microsoft.ReactNative/packages.lock.json @@ -24,21 +24,21 @@ "Microsoft.SourceLink.Common": "1.1.1" } }, + "Microsoft.UI.Xaml": { + "type": "Direct", + "requested": "[2.8.0, )", + "resolved": "2.8.0", + "contentHash": "vxdHxTr63s5KVtNddMFpgvjBjUH50z7seq/5jLWmmSuf8poxg+sXrywkofUdE8ZstbpO9y3FL/IXXUcPYbeesA==", + "dependencies": { + "Microsoft.Web.WebView2": "1.0.1264.42" + } + }, "Microsoft.Windows.CppWinRT": { "type": "Direct", "requested": "[2.0.211028.7, )", "resolved": "2.0.211028.7", "contentHash": "JBGI0c3WLoU6aYJRy9Qo0MLDQfObEp+d4nrhR95iyzf7+HOgjRunHDp/6eGFREd7xq3OI1mll9ecJrMfzBvlyg==" }, - "Microsoft.WindowsAppSDK": { - "type": "Direct", - "requested": "[1.4.230913002, )", - "resolved": "1.4.230913002", - "contentHash": "l+9RshN4TsTuxL0ijFp5smbs3Y07RO7CxKBHNM/RsrsGtWvuk6edITMp4oqL9C3ufEAmpYk3dqOZRSf+sFH4Zg==", - "dependencies": { - "Microsoft.Windows.SDK.BuildTools": "10.0.22621.1" - } - }, "Microsoft.Build.Tasks.Git": { "type": "Transitive", "resolved": "1.1.1", @@ -49,10 +49,10 @@ "resolved": "1.1.1", "contentHash": "WMcGpWKrmJmzrNeuaEb23bEMnbtR/vLmvZtkAP5qWu7vQsY59GqfRJd65sFpBszbd2k/bQ8cs8eWawQKAabkVg==" }, - "Microsoft.Windows.SDK.BuildTools": { + "Microsoft.Web.WebView2": { "type": "Transitive", - "resolved": "10.0.22621.1", - "contentHash": "Sp1DkYvg7yxuhamwxv+qFC66KC3paKQpwK8Q1J6XuAh6nzXIInmsDcpJ3szr0XGud4ysXojqwTfGdW01gvZ/0g==" + "resolved": "1.0.1264.42", + "contentHash": "7OBUTkzQ5VI/3gb0ufi5U4zjuCowAJwQg2li0zXXzqkM+S1kmOlivTy1R4jAW+gY5Vyg510M+qMAESCQUjrfgA==" }, "common": { "type": "Project" @@ -63,8 +63,8 @@ "folly": { "type": "Project", "dependencies": { - "boost": "[1.76.0, )", - "fmt": "[1.0.0, )" + "Fmt": "[1.0.0, )", + "boost": "[1.76.0, )" } }, "reactcommon": { @@ -76,80 +76,52 @@ } }, "native,Version=v0.0/win10-arm": { - "Microsoft.WindowsAppSDK": { - "type": "Direct", - "requested": "[1.4.230913002, )", - "resolved": "1.4.230913002", - "contentHash": "l+9RshN4TsTuxL0ijFp5smbs3Y07RO7CxKBHNM/RsrsGtWvuk6edITMp4oqL9C3ufEAmpYk3dqOZRSf+sFH4Zg==", - "dependencies": { - "Microsoft.Windows.SDK.BuildTools": "10.0.22621.1" - } + "Microsoft.Web.WebView2": { + "type": "Transitive", + "resolved": "1.0.1264.42", + "contentHash": "7OBUTkzQ5VI/3gb0ufi5U4zjuCowAJwQg2li0zXXzqkM+S1kmOlivTy1R4jAW+gY5Vyg510M+qMAESCQUjrfgA==" } }, "native,Version=v0.0/win10-arm-aot": { - "Microsoft.WindowsAppSDK": { - "type": "Direct", - "requested": "[1.4.230913002, )", - "resolved": "1.4.230913002", - "contentHash": "l+9RshN4TsTuxL0ijFp5smbs3Y07RO7CxKBHNM/RsrsGtWvuk6edITMp4oqL9C3ufEAmpYk3dqOZRSf+sFH4Zg==", - "dependencies": { - "Microsoft.Windows.SDK.BuildTools": "10.0.22621.1" - } + "Microsoft.Web.WebView2": { + "type": "Transitive", + "resolved": "1.0.1264.42", + "contentHash": "7OBUTkzQ5VI/3gb0ufi5U4zjuCowAJwQg2li0zXXzqkM+S1kmOlivTy1R4jAW+gY5Vyg510M+qMAESCQUjrfgA==" } }, "native,Version=v0.0/win10-arm64-aot": { - "Microsoft.WindowsAppSDK": { - "type": "Direct", - "requested": "[1.4.230913002, )", - "resolved": "1.4.230913002", - "contentHash": "l+9RshN4TsTuxL0ijFp5smbs3Y07RO7CxKBHNM/RsrsGtWvuk6edITMp4oqL9C3ufEAmpYk3dqOZRSf+sFH4Zg==", - "dependencies": { - "Microsoft.Windows.SDK.BuildTools": "10.0.22621.1" - } + "Microsoft.Web.WebView2": { + "type": "Transitive", + "resolved": "1.0.1264.42", + "contentHash": "7OBUTkzQ5VI/3gb0ufi5U4zjuCowAJwQg2li0zXXzqkM+S1kmOlivTy1R4jAW+gY5Vyg510M+qMAESCQUjrfgA==" } }, "native,Version=v0.0/win10-x64": { - "Microsoft.WindowsAppSDK": { - "type": "Direct", - "requested": "[1.4.230913002, )", - "resolved": "1.4.230913002", - "contentHash": "l+9RshN4TsTuxL0ijFp5smbs3Y07RO7CxKBHNM/RsrsGtWvuk6edITMp4oqL9C3ufEAmpYk3dqOZRSf+sFH4Zg==", - "dependencies": { - "Microsoft.Windows.SDK.BuildTools": "10.0.22621.1" - } + "Microsoft.Web.WebView2": { + "type": "Transitive", + "resolved": "1.0.1264.42", + "contentHash": "7OBUTkzQ5VI/3gb0ufi5U4zjuCowAJwQg2li0zXXzqkM+S1kmOlivTy1R4jAW+gY5Vyg510M+qMAESCQUjrfgA==" } }, "native,Version=v0.0/win10-x64-aot": { - "Microsoft.WindowsAppSDK": { - "type": "Direct", - "requested": "[1.4.230913002, )", - "resolved": "1.4.230913002", - "contentHash": "l+9RshN4TsTuxL0ijFp5smbs3Y07RO7CxKBHNM/RsrsGtWvuk6edITMp4oqL9C3ufEAmpYk3dqOZRSf+sFH4Zg==", - "dependencies": { - "Microsoft.Windows.SDK.BuildTools": "10.0.22621.1" - } + "Microsoft.Web.WebView2": { + "type": "Transitive", + "resolved": "1.0.1264.42", + "contentHash": "7OBUTkzQ5VI/3gb0ufi5U4zjuCowAJwQg2li0zXXzqkM+S1kmOlivTy1R4jAW+gY5Vyg510M+qMAESCQUjrfgA==" } }, "native,Version=v0.0/win10-x86": { - "Microsoft.WindowsAppSDK": { - "type": "Direct", - "requested": "[1.4.230913002, )", - "resolved": "1.4.230913002", - "contentHash": "l+9RshN4TsTuxL0ijFp5smbs3Y07RO7CxKBHNM/RsrsGtWvuk6edITMp4oqL9C3ufEAmpYk3dqOZRSf+sFH4Zg==", - "dependencies": { - "Microsoft.Windows.SDK.BuildTools": "10.0.22621.1" - } + "Microsoft.Web.WebView2": { + "type": "Transitive", + "resolved": "1.0.1264.42", + "contentHash": "7OBUTkzQ5VI/3gb0ufi5U4zjuCowAJwQg2li0zXXzqkM+S1kmOlivTy1R4jAW+gY5Vyg510M+qMAESCQUjrfgA==" } }, "native,Version=v0.0/win10-x86-aot": { - "Microsoft.WindowsAppSDK": { - "type": "Direct", - "requested": "[1.4.230913002, )", - "resolved": "1.4.230913002", - "contentHash": "l+9RshN4TsTuxL0ijFp5smbs3Y07RO7CxKBHNM/RsrsGtWvuk6edITMp4oqL9C3ufEAmpYk3dqOZRSf+sFH4Zg==", - "dependencies": { - "Microsoft.Windows.SDK.BuildTools": "10.0.22621.1" - } + "Microsoft.Web.WebView2": { + "type": "Transitive", + "resolved": "1.0.1264.42", + "contentHash": "7OBUTkzQ5VI/3gb0ufi5U4zjuCowAJwQg2li0zXXzqkM+S1kmOlivTy1R4jAW+gY5Vyg510M+qMAESCQUjrfgA==" } } } From 51a3232d455a837e7cc3b1e85bc268cf04630b80 Mon Sep 17 00:00:00 2001 From: Andrew Coates <30809111+acoates-ms@users.noreply.github.com> Date: Wed, 11 Oct 2023 15:29:35 -0700 Subject: [PATCH 6/6] fix --- .../Fabric/Composition/Composition.Input.cpp | 14 ++++++++++++-- .../Fabric/Composition/Composition.Input.h | 2 ++ .../CompositionRootAutomationProvider.cpp | 2 ++ 3 files changed, 16 insertions(+), 2 deletions(-) diff --git a/vnext/Microsoft.ReactNative/Fabric/Composition/Composition.Input.cpp b/vnext/Microsoft.ReactNative/Fabric/Composition/Composition.Input.cpp index 1f30a275765..ded94c74847 100644 --- a/vnext/Microsoft.ReactNative/Fabric/Composition/Composition.Input.cpp +++ b/vnext/Microsoft.ReactNative/Fabric/Composition/Composition.Input.cpp @@ -518,12 +518,22 @@ winrt::Microsoft::ReactNative::Composition::Input::PointerPointProperties Pointe } uint64_t PointerPoint::Timestamp() noexcept { - return m_sysPointerPoint ? m_sysPointerPoint.Timestamp() : m_pi.dwTime; +#ifdef USE_WINUI3 + if (m_sysPointerPoint) { + return m_sysPointerPoint.Timestamp(); + } +#endif + return m_pi.dwTime; } winrt::Microsoft::ReactNative::Composition::Input::PointerPoint PointerPoint::GetTransformedPoint( const IPointerPointTransform &transform) noexcept { - return winrt::make(m_sysPointerPoint); +#ifdef USE_WINUI3 + if (m_sysPointerPoint) { + return winrt::make(m_sysPointerPoint); + } +#endif + return winrt::make(m_msg, m_wParam, m_lParam, m_scaleFactor); } bool PointerPoint::IsPointerMessage(uint32_t message) noexcept { diff --git a/vnext/Microsoft.ReactNative/Fabric/Composition/Composition.Input.h b/vnext/Microsoft.ReactNative/Fabric/Composition/Composition.Input.h index 8f9a30c9345..7b69ec809c1 100644 --- a/vnext/Microsoft.ReactNative/Fabric/Composition/Composition.Input.h +++ b/vnext/Microsoft.ReactNative/Fabric/Composition/Composition.Input.h @@ -117,7 +117,9 @@ struct PointerPointProperties : PointerPointPropertiesT }; struct PointerPoint : PointerPointT { +#ifdef USE_WINUI3 PointerPoint(const winrt::Microsoft::UI::Input::PointerPoint &pp); +#endif PointerPoint(uint32_t msg, uint64_t wParam, int64_t lParam, float scaleFactor); uint32_t FrameId() noexcept; diff --git a/vnext/Microsoft.ReactNative/Fabric/Composition/CompositionRootAutomationProvider.cpp b/vnext/Microsoft.ReactNative/Fabric/Composition/CompositionRootAutomationProvider.cpp index de6c5769c7d..1518d364615 100644 --- a/vnext/Microsoft.ReactNative/Fabric/Composition/CompositionRootAutomationProvider.cpp +++ b/vnext/Microsoft.ReactNative/Fabric/Composition/CompositionRootAutomationProvider.cpp @@ -184,9 +184,11 @@ void CompositionRootAutomationProvider::SetHwnd(HWND hwnd) noexcept { m_hwnd = hwnd; } +#ifdef USE_WINUI3 void CompositionRootAutomationProvider::SetIsland(winrt::Microsoft::UI::Content::ContentIsland &island) noexcept { m_island = island; } +#endif HRESULT __stdcall CompositionRootAutomationProvider::Navigate( NavigateDirection direction,