From 34417de0994641402afc1958707995e296f5dbb6 Mon Sep 17 00:00:00 2001 From: Kristen Schau Date: Tue, 22 Feb 2022 12:55:08 -0800 Subject: [PATCH 01/10] Align WebView2Tests.cs with WinUI 3 --- dev/WebView2/InteractionTests/WebView2Tests.cs | 9 ++------- dev/WebView2/TestUI/WebView2BasicPage.xaml | 2 +- 2 files changed, 3 insertions(+), 8 deletions(-) diff --git a/dev/WebView2/InteractionTests/WebView2Tests.cs b/dev/WebView2/InteractionTests/WebView2Tests.cs index 6f98836ae6..513f1c8cbc 100644 --- a/dev/WebView2/InteractionTests/WebView2Tests.cs +++ b/dev/WebView2/InteractionTests/WebView2Tests.cs @@ -880,7 +880,7 @@ public void MultipleWebviews_FocusTest() Log.Comment("Focus on tabstop1"); x1.SetFocus(); Wait.ForIdle(); - Verify.IsTrue(x1.HasKeyboardFocus); + Verify.IsTrue(x1.HasKeyboardFocus, "TabStopButton1 has keyboard focus"); Log.Comment("Tab tabstop1 -> MyWebView2"); KeyboardHelper.PressKey(Key.Tab); @@ -1167,13 +1167,11 @@ public void MouseCaptureTest() PointerInput.Press(PointerButtons.Primary); PointerInput.Move(outsidePoint); PointerInput.Release(PointerButtons.Primary); - Wait.ForIdle(); // Move mouse back across text // If the WebView did not correctly handle captured mouse input then the text will be deselected // due to the WebView still thinking that the mouse's left-button is pressed. PointerInput.Move(startPoint); - Wait.ForIdle(); using (var pasteTestWaiter = new ValueChangedEventWaiter(CopyPasteTextBox2, "MouseCaptureResult")) { @@ -1338,7 +1336,6 @@ public void ResizeTest() [TestMethod] [TestProperty("Ignore", "True")] // Task 31708332: WebView2 Touch Tests still failing on Helix - [TestProperty("Ignore", "True")] //Task 31704068: Unreliable tests: WebView2 BasicTapTouchTest, BasicFlingTouchTest, BasicLongPressTouchTest [TestProperty("TestSuite", "B")] public void BasicTapTouchTest() { @@ -1366,7 +1363,6 @@ public void BasicTapTouchTest() [TestMethod] [TestProperty("Ignore", "True")] // Task 31708332: WebView2 Touch Tests still failing on Helix - [TestProperty("Ignore", "True")] //Task 31704068: Unreliable tests: WebView2 BasicTapTouchTest, BasicFlingTouchTest, BasicLongPressTouchTest [TestProperty("TestSuite", "B")] public void BasicFlingTouchTest() { @@ -1553,7 +1549,6 @@ public void ReparentElementTest() CompleteTestAndWaitForResult("ReparentElementTest"); // Ensure that the moved WebView is still visible - Log.Comment("ReparentElementTest Test App Result ignored due to RTB issues with the test. Verifying from the test runner."); WebView2Temporary.WebView2RenderingVerifier.VerifyInstances("ReparentElementTest"); } } @@ -2013,7 +2008,7 @@ public void CloseThenDPIChangeTest() [TestMethod] // Test fails because .NET UWP doesn't support Object -> VARIANT marshalling. [TestProperty("TestSuite", "D")] - [TestProperty("Ignore", "True")] // 32510465 + [TestProperty("Ignore", "True")] public void AddHostObjectToScriptTest() { if (!PlatformConfiguration.IsOsVersionGreaterThanOrEqual(OSVersion.Redstone5)) diff --git a/dev/WebView2/TestUI/WebView2BasicPage.xaml b/dev/WebView2/TestUI/WebView2BasicPage.xaml index fe01d5005d..9e7648e38d 100644 --- a/dev/WebView2/TestUI/WebView2BasicPage.xaml +++ b/dev/WebView2/TestUI/WebView2BasicPage.xaml @@ -175,7 +175,7 @@ - + From 035fbf1e5e01dd4f688716c0b4144f723fb67cc9 Mon Sep 17 00:00:00 2001 From: Kristen Schau Date: Tue, 22 Feb 2022 14:34:42 -0800 Subject: [PATCH 02/10] Add HiddenThenVisibleTest and ParentHiddentThenVisibleTest --- .../InteractionTests/WebView2Tests.cs | 34 ++++- dev/WebView2/TestUI/WebView2BasicPage.xaml | 2 + dev/WebView2/TestUI/WebView2BasicPage.xaml.cs | 117 ++++++++++++++++-- 3 files changed, 140 insertions(+), 13 deletions(-) diff --git a/dev/WebView2/InteractionTests/WebView2Tests.cs b/dev/WebView2/InteractionTests/WebView2Tests.cs index 513f1c8cbc..9abc96de2b 100644 --- a/dev/WebView2/InteractionTests/WebView2Tests.cs +++ b/dev/WebView2/InteractionTests/WebView2Tests.cs @@ -2144,10 +2144,42 @@ public void HtmlDropdownTest() } } + [TestMethod] + [TestProperty("TestSuite", "D")] + public void HiddenThenVisibleTest() + { + using (var setup = new WebView2TestSetupHelper(new[] { "WebView2 Tests", "navigateToBasicWebView2" })) + { + ChooseTest("HiddenThenVisibleTest"); + CompleteTestAndWaitForResult("HiddenThenVisibleTest"); + + // Clear the cache so we can find the new webview + ElementCache.Clear(); + var webview = FindElement.ById("MyWebView2"); + Verify.IsTrue(webview.IsOffscreen == false); + } + } + + [TestMethod] + [TestProperty("TestSuite", "D")] + public void ParentHiddenThenVisibleTest() + { + using (var setup = new WebView2TestSetupHelper(new[] { "WebView2 Tests", "navigateToBasicWebView2" })) + { + ChooseTest("ParentHiddenThenVisibleTest"); + CompleteTestAndWaitForResult("ParentHiddenThenVisibleTest"); + + // Clear the cache so we can find the new webview + ElementCache.Clear(); + var webview = FindElement.ById("MyWebView2"); + Verify.IsTrue(webview.IsOffscreen == false); + } + } + private static void BeginSubTest(string testName, string testDescription) { Log.Comment(Environment.NewLine + testName + ": " + testDescription); - + Log.Comment("Resetting event and exception counts..."); Button resetCounts_Button = new Button(FindElement.ById("ResetCounts_Button")); resetCounts_Button.Invoke(); diff --git a/dev/WebView2/TestUI/WebView2BasicPage.xaml b/dev/WebView2/TestUI/WebView2BasicPage.xaml index 9e7648e38d..b2e7fc2cd7 100644 --- a/dev/WebView2/TestUI/WebView2BasicPage.xaml +++ b/dev/WebView2/TestUI/WebView2BasicPage.xaml @@ -42,6 +42,7 @@ Focus_MouseActivateTest Focus_ReverseTabTest GoBackAndForwardTest + HiddenThenVisibleTest HostNameToFolderMappingTest HtmlDropdownTest MouseCaptureTest @@ -63,6 +64,7 @@ NavigationStartingTest NonAsciiUriTest OffTreeWebViewInputTest + ParentHiddenThenVisibleTest ParentVisibilityHiddenTest ParentVisibilityTurnedOnTest PointerReleaseWithoutPressTest diff --git a/dev/WebView2/TestUI/WebView2BasicPage.xaml.cs b/dev/WebView2/TestUI/WebView2BasicPage.xaml.cs index 472772b557..ccdef80195 100644 --- a/dev/WebView2/TestUI/WebView2BasicPage.xaml.cs +++ b/dev/WebView2/TestUI/WebView2BasicPage.xaml.cs @@ -197,6 +197,8 @@ enum TestList NonAsciiUriTest, OffTreeWebViewInputTest, HtmlDropdownTest, + HiddenThenVisibleTest, + ParentHiddenThenVisibleTest }; // Map of TestList entry to its webpage (index in TestPageNames[]) @@ -260,6 +262,8 @@ enum TestList { TestList.NonAsciiUriTest, 7 }, { TestList.OffTreeWebViewInputTest, 1 }, { TestList.HtmlDropdownTest, 5 }, + { TestList.HiddenThenVisibleTest, 0 }, + { TestList.ParentHiddenThenVisibleTest, 0 }, }; readonly string[] TestPageNames = @@ -565,9 +569,7 @@ private void TestNameComboBox_SelectionChanged(object sender, SelectionChangedEv case TestList.SourceBeforeLoadTest: { // Remove existing WebView, we're going to replace it - RemoveWebViewEventHandlers(MyWebView2); - Border parentBorder = MyWebView2.Parent as Border; - parentBorder.Child = null; + Border parentBorder = RemoveExistingWebViewControl(MyWebView2); Uri uri = WebView2Common.GetTestPageUri("SimplePageWithButton.html"); var newWebView2 = new WebView2() { @@ -612,9 +614,7 @@ private void TestNameComboBox_SelectionChanged(object sender, SelectionChangedEv case TestList.WindowlessPopupTest: { // Remove existing WebView so it doesn't get confused with the one in the popup - RemoveWebViewEventHandlers(MyWebView2); - Border parentBorder = MyWebView2.Parent as Border; - parentBorder.Child = null; + _ = RemoveExistingWebViewControl(MyWebView2); // Create popup contents: a new webview var webviewInPopup = new WebView2() { @@ -662,9 +662,7 @@ private void TestNameComboBox_SelectionChanged(object sender, SelectionChangedEv case TestList.CursorUpdateTest: { // Remove existing WebView, we're going to replace it - RemoveWebViewEventHandlers(MyWebView2); - Border parentBorder = MyWebView2.Parent as Border; - parentBorder.Child = null; + Border parentBorder = RemoveExistingWebViewControl(MyWebView2); // Insert webview with public ProtectedCursor var newWebView2 = new WebView2WithCursor() { @@ -691,12 +689,69 @@ private void TestNameComboBox_SelectionChanged(object sender, SelectionChangedEv case TestList.OffTreeWebViewInputTest: { // Remove existing webview - RemoveWebViewEventHandlers(MyWebView2); - Border parentBorder = MyWebView2.Parent as Border; - parentBorder.Child = null; + Border parentBorder = RemoveExistingWebViewControl(MyWebView2); parentBorder.BorderBrush = new SolidColorBrush(Colors.Pink); } break; + case TestList.HiddenThenVisibleTest: + { + // Remove existing WebView, we're going to replace it with a hidden one + Border parentBorder = RemoveExistingWebViewControl(MyWebView2); + var parentStackPanel = parentBorder.Parent as StackPanel; + parentStackPanel.Children.Remove(parentBorder); + + // Create a new border that gets its size from the webview + var newBorder = new Border() { + BorderBrush = new SolidColorBrush(Colors.Red), + BorderThickness = new Thickness(5) + }; + + // Add a new, collapsed WebView2 into the tree + var uri = WebView2Common.GetTestPageUri("SimplePage.html"); + var newWebView2 = new WebView2() { + Name = "MyWebView2", + Margin = new Thickness(8, 8, 8, 8), + Width = 670, + Height = 370, + Source = uri, + Visibility = Visibility.Collapsed, + }; + AutomationProperties.SetName(newWebView2, "MyWebView2"); + newBorder.Child = newWebView2; + parentStackPanel.Children.Add(newBorder); + AddWebViewEventHandlers(newWebView2); + } + break; + case TestList.ParentHiddenThenVisibleTest: + { + // Remove existing WebView, we're going to replace it with a hidden one + Border parentBorder = RemoveExistingWebViewControl(MyWebView2); + var parentStackPanel = parentBorder.Parent as StackPanel; + parentStackPanel.Children.Remove(parentBorder); + + // Create a new, collapsed border that gets its size from the webview + var newBorder = new Border() { + BorderBrush = new SolidColorBrush(Colors.Red), + BorderThickness = new Thickness(5), + Visibility = Visibility.Collapsed + }; + + // Add a new WebView2 into the tree + var uri = WebView2Common.GetTestPageUri("SimplePage.html"); + var newWebView2 = new WebView2() { + Name = "MyWebView2", + Margin = new Thickness(8, 8, 8, 8), + Width = 670, + Height = 370, + Source = uri, + Visibility = Visibility.Visible, + }; + AutomationProperties.SetName(newWebView2, "MyWebView2"); + newBorder.Child = newWebView2; + parentStackPanel.Children.Add(newBorder); + AddWebViewEventHandlers(newWebView2); + } + break; default: WebView2Common.LoadWebPage(MyWebView2, TestPageNames[TestInfoDictionary[test]]); break; @@ -903,6 +958,14 @@ void MoveWebViewControl(string webviewName, WebView2 webView2) WebView2Collection.Children.Add(stackPanel); } + Border RemoveExistingWebViewControl(WebView2 webview) + { + RemoveWebViewEventHandlers(webview); + Border parentBorder = webview.Parent as Border; + parentBorder.Child = null; + return parentBorder; + } + void AddWebViewEventHandlers(WebView2 webview) { webview.NavigationStarting += OnNavigationStarting; @@ -1807,6 +1870,36 @@ async public void CompleteCurrentTest(object sender, RoutedEventArgs args) selectedTest, selctedOption));; } break; + case TestList.HiddenThenVisibleTest: + { + logger.Verify(MyWebView2.Visibility == Visibility.Collapsed, + string.Format("Test {0}: Incorrect setup, Expected MyWebView2.Visibility to be Collapsed, was {1}", + selectedTest, MyWebView2.Visibility)); + + // Make WebView2 visible + MyWebView2.Visibility = Visibility.Visible; + + logger.Verify(MyWebView2.IsHitTestVisible, + string.Format("Test {0}: Failed, Expected MyWebView2.IsHitTestVisible to be true, was {1}", + selectedTest, MyWebView2.IsHitTestVisible)); + } + break; + case TestList.ParentHiddenThenVisibleTest: + { + var parentBorder = MyWebView2.Parent as Border; + + logger.Verify(parentBorder.Visibility == Visibility.Collapsed, + string.Format("Test {0}: Incorrect setup, Expected MyWebView2.Visibility to be Collapsed, was {1}", + selectedTest, parentBorder.Visibility)); + + // Make WebView2's parent Border visible + parentBorder.Visibility = Visibility.Visible; + + logger.Verify(MyWebView2.IsHitTestVisible, + string.Format("Test {0}: Failed, Expected MyWebView2.IsHitTestVisible to be true, was {1}", + selectedTest, MyWebView2.IsHitTestVisible)); + } + break; default: break; From 0a48c722c61dfaadead4caf3197a4f1d3224e4d3 Mon Sep 17 00:00:00 2001 From: Kristen Schau Date: Tue, 22 Feb 2022 12:58:16 -0800 Subject: [PATCH 03/10] Add Panel content to WebView2 --- dev/WebView2/WebView2.cpp | 37 +++++++++++++++++++++++++++++++++---- dev/WebView2/WebView2.h | 3 +++ 2 files changed, 36 insertions(+), 4 deletions(-) diff --git a/dev/WebView2/WebView2.cpp b/dev/WebView2/WebView2.cpp index 2d97376b23..0d75a84c76 100644 --- a/dev/WebView2/WebView2.cpp +++ b/dev/WebView2/WebView2.cpp @@ -1505,6 +1505,38 @@ void WebView2::TryCompleteInitialization() [this](auto&&, auto&&) { UpdateDefaultBackgroundColor(); }); } + AddChildPanel(); + CreateAndSetVisual(); + + // If we were recreating the webview after a core process failure, indicate that we have now recovered + m_isCoreFailure_BrowserExited_State = false; +} + +void WebView2::AddChildPanel() +{ + auto panelContent = winrt::Grid(); + panelContent.Background(winrt::SolidColorBrush(winrt::Colors::Transparent())); + panelContent.Height(this->ActualHeight()); + panelContent.Width(this->ActualWidth()); + Content(panelContent); +} + +void WebView2::ResizeChildPanel() +{ + auto content = this->Content(); + if (content) + { + auto panelContent = content.as(); + if (panelContent) + { + panelContent.Height(this->ActualHeight()); + panelContent.Width(this->ActualWidth()); + } + } +} + +void WebView2::CreateAndSetVisual() +{ #ifdef WINUI3 if (!m_systemVisualBridge) { @@ -1534,10 +1566,6 @@ void WebView2::TryCompleteInitialization() auto coreWebView2CompositionControllerInterop = m_coreWebViewCompositionController.as(); winrt::check_hresult(coreWebView2CompositionControllerInterop->put_RootVisualTarget(m_visual.as<::IUnknown>().get())); #endif - - - // If we were recreating the webview after a core process failure, indicate that we have now recovered - m_isCoreFailure_BrowserExited_State = false; } winrt::IAsyncOperation WebView2::ExecuteScriptAsync(winrt::hstring javascriptCode) @@ -1730,6 +1758,7 @@ void WebView2::HandleXamlRootChanged() void WebView2::HandleSizeChanged(const winrt::IInspectable& /*sender*/, const winrt::SizeChangedEventArgs& args) { SetCoreWebViewAndVisualSize(args.NewSize().Width, args.NewSize().Height); + ResizeChildPanel(); } void WebView2::HandleRendered(const winrt::IInspectable& /*sender*/, const winrt::IInspectable& /*args*/) diff --git a/dev/WebView2/WebView2.h b/dev/WebView2/WebView2.h index dfa4a69d21..c6ee8d0c72 100644 --- a/dev/WebView2/WebView2.h +++ b/dev/WebView2/WebView2.h @@ -155,6 +155,9 @@ class WebView2 : void XamlRootChangedHelper(bool forceUpdate); void TryCompleteInitialization(); void DisconnectFromRootVisualTarget(); + void CreateAndSetVisual(); + void AddChildPanel(); + void ResizeChildPanel(); void CheckAndUpdateWebViewPosition(); void CheckAndUpdateWindowPosition(); From 6058585e25b3eb5096c7146e2be20bef0be2de4f Mon Sep 17 00:00:00 2001 From: Kristen Schau Date: Tue, 22 Feb 2022 15:28:27 -0800 Subject: [PATCH 04/10] Add IAutomationPeerOverrides GetBoundingRectangleCore() --- dev/WebView2/WebView2.cpp | 10 ++++++++++ dev/WebView2/WebView2.h | 2 ++ dev/WebView2/WebView2AutomationPeer.cpp | 6 ++++++ dev/WebView2/WebView2AutomationPeer.h | 1 + 4 files changed, 19 insertions(+) diff --git a/dev/WebView2/WebView2.cpp b/dev/WebView2/WebView2.cpp index 0d75a84c76..98195a47e3 100644 --- a/dev/WebView2/WebView2.cpp +++ b/dev/WebView2/WebView2.cpp @@ -1816,6 +1816,16 @@ void WebView2::CheckAndUpdateWebViewPosition() (m_webViewScaledSize.Y) }); } +winrt::Rect WebView2::GetBoundingRectangle() +{ + return winrt::Rect({ + (m_webViewScaledPosition.X), + (m_webViewScaledPosition.Y), + (m_webViewScaledSize.X), + (m_webViewScaledSize.Y) }); + } +} + void WebView2::SetCoreWebViewAndVisualSize(const float width, const float height) { #ifdef WINUI3 diff --git a/dev/WebView2/WebView2.h b/dev/WebView2/WebView2.h index c6ee8d0c72..984fd5cd3f 100644 --- a/dev/WebView2/WebView2.h +++ b/dev/WebView2/WebView2.h @@ -99,6 +99,8 @@ class WebView2 : winrt::CoreWebView2 CoreWebView2(); // Getter for CoreWebView2 property (read-only) + winrt::Rect GetBoundingRectangle(); + private: bool ShouldNavigate(const winrt::Uri& uri); winrt::IAsyncAction OnSourceChanged(winrt::Uri providedUri); diff --git a/dev/WebView2/WebView2AutomationPeer.cpp b/dev/WebView2/WebView2AutomationPeer.cpp index fe53510c38..8e81b06f40 100644 --- a/dev/WebView2/WebView2AutomationPeer.cpp +++ b/dev/WebView2/WebView2AutomationPeer.cpp @@ -36,6 +36,12 @@ winrt::AutomationControlType WebView2AutomationPeer::GetAutomationControlTypeCor return winrt::AutomationControlType::Pane; } +winrt::Rect WebView2AutomationPeer::GetBoundingRectangleCore() +{ + winrt::Rect boundingRect = GetImpl()->GetBoundingRectangle(); + return boundingRect; +} + #if WINUI3 HRESULT WebView2AutomationPeer::GetRawElementProviderSimple(_Outptr_opt_ IRawElementProviderSimple** value) { diff --git a/dev/WebView2/WebView2AutomationPeer.h b/dev/WebView2/WebView2AutomationPeer.h index 93383b302f..51aa2e5bfb 100644 --- a/dev/WebView2/WebView2AutomationPeer.h +++ b/dev/WebView2/WebView2AutomationPeer.h @@ -20,6 +20,7 @@ class WebView2AutomationPeer : // IAutomationPeerOverrides winrt::hstring GetClassNameCore(); winrt::AutomationControlType GetAutomationControlTypeCore(); + winrt::Rect GetBoundingRectangleCore(); winrt::IInspectable GetFocusedElementCore(); winrt::IInspectable NavigateCore(winrt::AutomationNavigationDirection direction); From c15a2cb9f4138620a3c92535d6ddd06f866e285b Mon Sep 17 00:00:00 2001 From: Kristen Schau Date: Tue, 22 Feb 2022 15:24:10 -0800 Subject: [PATCH 05/10] Don't set Bounds on CoreWebView2 Controller when nothing has changed --- dev/WebView2/WebView2.cpp | 30 ++++++++++++++++++++---------- 1 file changed, 20 insertions(+), 10 deletions(-) diff --git a/dev/WebView2/WebView2.cpp b/dev/WebView2/WebView2.cpp index 98195a47e3..316c8d5336 100644 --- a/dev/WebView2/WebView2.cpp +++ b/dev/WebView2/WebView2.cpp @@ -1792,7 +1792,8 @@ void WebView2::CheckAndUpdateWebViewPosition() return; } - // Check if the position of the WebView within the window has changed + // Check if the position of the WebView2 within the window has changed + bool changed = false; auto transform = TransformToVisual(nullptr); auto topLeft = transform.TransformPoint(winrt::Point(0, 0)); @@ -1803,17 +1804,27 @@ void WebView2::CheckAndUpdateWebViewPosition() { m_webViewScaledPosition.X = scaledTopLeftX; m_webViewScaledPosition.Y = scaledTopLeftY; + changed = true; } - m_webViewScaledSize.X = ceil(static_cast(ActualWidth()) * m_rasterizationScale); - m_webViewScaledSize.Y = ceil(static_cast(ActualHeight()) * m_rasterizationScale); + auto scaledSizeX = ceil(static_cast(ActualWidth()) * m_rasterizationScale); + auto scaledSizeY = ceil(static_cast(ActualHeight()) * m_rasterizationScale); + if (scaledSizeX != m_webViewScaledSize.X || scaledSizeY != m_webViewScaledSize.Y) + { + m_webViewScaledSize.X = scaledSizeX; + m_webViewScaledSize.Y = scaledSizeY; + changed = true; + } - // We create the Bounds using X, Y, width, and height - m_coreWebViewController.Bounds({ - (m_webViewScaledPosition.X), - (m_webViewScaledPosition.Y), - (m_webViewScaledSize.X), - (m_webViewScaledSize.Y) }); + if (changed) + { + // We create the Bounds using X, Y, width, and height + m_coreWebViewController.Bounds({ + (m_webViewScaledPosition.X), + (m_webViewScaledPosition.Y), + (m_webViewScaledSize.X), + (m_webViewScaledSize.Y) }); + } } winrt::Rect WebView2::GetBoundingRectangle() @@ -1823,7 +1834,6 @@ winrt::Rect WebView2::GetBoundingRectangle() (m_webViewScaledPosition.Y), (m_webViewScaledSize.X), (m_webViewScaledSize.Y) }); - } } void WebView2::SetCoreWebViewAndVisualSize(const float width, const float height) From db519144a51cced8ea6a81b83e0e797b60ac485b Mon Sep 17 00:00:00 2001 From: Kristen Schau Date: Tue, 22 Feb 2022 15:57:56 -0800 Subject: [PATCH 06/10] Add click to tests --- .../InteractionTests/WebView2Tests.cs | 26 +++++++++++++++++++ dev/WebView2/TestUI/WebView2BasicPage.xaml.cs | 9 +++++-- 2 files changed, 33 insertions(+), 2 deletions(-) diff --git a/dev/WebView2/InteractionTests/WebView2Tests.cs b/dev/WebView2/InteractionTests/WebView2Tests.cs index 9abc96de2b..e4944ade48 100644 --- a/dev/WebView2/InteractionTests/WebView2Tests.cs +++ b/dev/WebView2/InteractionTests/WebView2Tests.cs @@ -2157,6 +2157,19 @@ public void HiddenThenVisibleTest() ElementCache.Clear(); var webview = FindElement.ById("MyWebView2"); Verify.IsTrue(webview.IsOffscreen == false); + + // Click in the webview to ensure we can interact with it + Rectangle bounds = webview.BoundingRectangle; + Log.Comment("Bounds = X:{0}, Y:{1}, Width:{2}, Height:{3}", bounds.X, bounds.Y, bounds.Width, bounds.Height); + var point = new Point(bounds.X + 20, bounds.Y + 20); + Log.Comment("Move mouse to ({0}, {1})", bounds.X + 20, bounds.Y + 20); + PointerInput.Move(point); + + PointerInput.Press(PointerButtons.Primary); + PointerInput.Release(PointerButtons.Primary); + Wait.ForIdle(); + + WaitForWebMessageResult("HiddenThenVisibleTest"); } } @@ -2173,6 +2186,19 @@ public void ParentHiddenThenVisibleTest() ElementCache.Clear(); var webview = FindElement.ById("MyWebView2"); Verify.IsTrue(webview.IsOffscreen == false); + + // Click in the webview to ensure we can interact with it + Rectangle bounds = webview.BoundingRectangle; + Log.Comment("Bounds = X:{0}, Y:{1}, Width:{2}, Height:{3}", bounds.X, bounds.Y, bounds.Width, bounds.Height); + var point = new Point(bounds.X + 20, bounds.Y + 20); + Log.Comment("Move mouse to ({0}, {1})", bounds.X + 20, bounds.Y + 20); + PointerInput.Move(point); + + PointerInput.Press(PointerButtons.Primary); + PointerInput.Release(PointerButtons.Primary); + Wait.ForIdle(); + + WaitForWebMessageResult("ParentHiddenThenVisibleTest"); } } diff --git a/dev/WebView2/TestUI/WebView2BasicPage.xaml.cs b/dev/WebView2/TestUI/WebView2BasicPage.xaml.cs index ccdef80195..48c9ee617d 100644 --- a/dev/WebView2/TestUI/WebView2BasicPage.xaml.cs +++ b/dev/WebView2/TestUI/WebView2BasicPage.xaml.cs @@ -262,8 +262,8 @@ enum TestList { TestList.NonAsciiUriTest, 7 }, { TestList.OffTreeWebViewInputTest, 1 }, { TestList.HtmlDropdownTest, 5 }, - { TestList.HiddenThenVisibleTest, 0 }, - { TestList.ParentHiddenThenVisibleTest, 0 }, + { TestList.HiddenThenVisibleTest, 1 }, + { TestList.ParentHiddenThenVisibleTest, 1 }, }; readonly string[] TestPageNames = @@ -1182,6 +1182,11 @@ public void VerifyWebMessageBasedTest(string stringResult, string jsonResult) expectedStringResult = "Left mouse button clicked."; break; + case TestList.HiddenThenVisibleTest: + case TestList.ParentHiddenThenVisibleTest: + expectedStringResult = "Left mouse button clicked."; + break; + default: { logger.LogError("Unexpected test type in VerifyWebMessageBasedTest(), got message: " + stringResult); From 063c48e49e5776fdd1d6ba7dbcaa8b70a80e7e05 Mon Sep 17 00:00:00 2001 From: Kristen Schau Date: Tue, 22 Feb 2022 17:18:51 -0800 Subject: [PATCH 07/10] Replace hardcoded test page names --- dev/WebView2/TestUI/WebView2BasicPage.xaml.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/dev/WebView2/TestUI/WebView2BasicPage.xaml.cs b/dev/WebView2/TestUI/WebView2BasicPage.xaml.cs index 48c9ee617d..c84cd9f8d1 100644 --- a/dev/WebView2/TestUI/WebView2BasicPage.xaml.cs +++ b/dev/WebView2/TestUI/WebView2BasicPage.xaml.cs @@ -541,7 +541,7 @@ private void TestNameComboBox_SelectionChanged(object sender, SelectionChangedEv { AddWebViewControl("MyWebView2B"); AddWebViewControl("MyWebView2C"); - WebView2Common.LoadWebPage(MyWebView2, TestPageNames[0]); + WebView2Common.LoadWebPage(MyWebView2, TestPageNames[TestInfoDictionary[test]]); } break; case TestList.MultipleWebviews_FocusTest: @@ -707,7 +707,7 @@ private void TestNameComboBox_SelectionChanged(object sender, SelectionChangedEv }; // Add a new, collapsed WebView2 into the tree - var uri = WebView2Common.GetTestPageUri("SimplePage.html"); + var uri = WebView2Common.GetTestPageUri(TestPageNames[TestInfoDictionary[test]]); var newWebView2 = new WebView2() { Name = "MyWebView2", Margin = new Thickness(8, 8, 8, 8), @@ -737,7 +737,7 @@ private void TestNameComboBox_SelectionChanged(object sender, SelectionChangedEv }; // Add a new WebView2 into the tree - var uri = WebView2Common.GetTestPageUri("SimplePage.html"); + var uri = WebView2Common.GetTestPageUri(TestPageNames[TestInfoDictionary[test]]); var newWebView2 = new WebView2() { Name = "MyWebView2", Margin = new Thickness(8, 8, 8, 8), From 12fc0743bbab0ef59ec08dc4ffec274e34fa250d Mon Sep 17 00:00:00 2001 From: Kristen Schau Date: Thu, 24 Feb 2022 12:17:07 -0800 Subject: [PATCH 08/10] Add comment for AddChildPanel --- dev/WebView2/WebView2.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/dev/WebView2/WebView2.cpp b/dev/WebView2/WebView2.cpp index 316c8d5336..e322d71f7a 100644 --- a/dev/WebView2/WebView2.cpp +++ b/dev/WebView2/WebView2.cpp @@ -1505,7 +1505,13 @@ void WebView2::TryCompleteInitialization() [this](auto&&, auto&&) { UpdateDefaultBackgroundColor(); }); } + // WebView2 in WinUI 2 is a ContentControl that either renders its web content to a SpriteVisual, or in the case that + // the WebView2 Runtime is not installed, renders a message to that effect as its Content. In the case where the + // WebView2 starts with Visibility.Collapsed, hit testing code has trouble seeing the WebView2 if it does not have + // Content. To work around this, give the WebView2 a transparent Grid as Content that hit testing can find. The size + // of this Grid must be kept in sync with the size of the WebView2 (see ResizeChildPanel()). AddChildPanel(); + CreateAndSetVisual(); // If we were recreating the webview after a core process failure, indicate that we have now recovered From 6fdd8750ba33f0581d26ae82592ce7e845017002 Mon Sep 17 00:00:00 2001 From: Kristen Schau Date: Fri, 25 Feb 2022 08:37:33 -0800 Subject: [PATCH 09/10] resize child panel via measure/arrange pass --- dev/WebView2/WebView2.cpp | 41 +++++++++++++-------------------------- dev/WebView2/WebView2.h | 1 - 2 files changed, 14 insertions(+), 28 deletions(-) diff --git a/dev/WebView2/WebView2.cpp b/dev/WebView2/WebView2.cpp index e322d71f7a..c33b89298d 100644 --- a/dev/WebView2/WebView2.cpp +++ b/dev/WebView2/WebView2.cpp @@ -833,24 +833,28 @@ void WebView2::CreateMissingAnaheimWarning() Content(warning); } -// We could have a child TextBlock (see CreateMissingAnaheimWarning), make sure it is visited by Measure pass. +// We could have a child Grid (see AddChildPanel) or a child TextBlock (see CreateMissingAnaheimWarning). +// Make sure it is visited by the Measure pass. winrt::Size WebView2::MeasureOverride(winrt::Size const& availableSize) { - //if (auto child = Content().try_as()) - //{ - // Content().Measure(availableSize); - //} + if (auto child = Content().try_as()) + { + child.Measure(availableSize); + return availableSize; + } return __super::MeasureOverride(availableSize); } -// We could have a child TextBlock (see CreateMissingAnaheimWarning), make sure it is visited by Arrange pass. +// We could have a child Grid (see AddChildPanel) or a child TextBlock (see CreateMissingAnaheimWarning). +// Make sure it is visited by the Arrange pass. winrt::Size WebView2::ArrangeOverride(winrt::Size const& finalSize) { - //if (auto child = Content().try_as()) - //{ - // Content().Arrange(winrt::Rect{ winrt::Point{0,0}, finalSize }); - //} + if (auto child = Content().try_as()) + { + child.Arrange(winrt::Rect{ winrt::Point{0,0}, finalSize }); + return finalSize; + } return __super::ArrangeOverride(finalSize); } @@ -1522,25 +1526,9 @@ void WebView2::AddChildPanel() { auto panelContent = winrt::Grid(); panelContent.Background(winrt::SolidColorBrush(winrt::Colors::Transparent())); - panelContent.Height(this->ActualHeight()); - panelContent.Width(this->ActualWidth()); Content(panelContent); } -void WebView2::ResizeChildPanel() -{ - auto content = this->Content(); - if (content) - { - auto panelContent = content.as(); - if (panelContent) - { - panelContent.Height(this->ActualHeight()); - panelContent.Width(this->ActualWidth()); - } - } -} - void WebView2::CreateAndSetVisual() { #ifdef WINUI3 @@ -1764,7 +1752,6 @@ void WebView2::HandleXamlRootChanged() void WebView2::HandleSizeChanged(const winrt::IInspectable& /*sender*/, const winrt::SizeChangedEventArgs& args) { SetCoreWebViewAndVisualSize(args.NewSize().Width, args.NewSize().Height); - ResizeChildPanel(); } void WebView2::HandleRendered(const winrt::IInspectable& /*sender*/, const winrt::IInspectable& /*args*/) diff --git a/dev/WebView2/WebView2.h b/dev/WebView2/WebView2.h index 984fd5cd3f..d485fb5404 100644 --- a/dev/WebView2/WebView2.h +++ b/dev/WebView2/WebView2.h @@ -159,7 +159,6 @@ class WebView2 : void DisconnectFromRootVisualTarget(); void CreateAndSetVisual(); void AddChildPanel(); - void ResizeChildPanel(); void CheckAndUpdateWebViewPosition(); void CheckAndUpdateWindowPosition(); From 435dcdb348b8bc9a2e1727ddffb19a4c32fc6b96 Mon Sep 17 00:00:00 2001 From: Kristen Schau Date: Tue, 1 Mar 2022 13:31:55 -0800 Subject: [PATCH 10/10] Let default implementation handle child Measure --- dev/WebView2/WebView2.cpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/dev/WebView2/WebView2.cpp b/dev/WebView2/WebView2.cpp index c33b89298d..d1c8cba750 100644 --- a/dev/WebView2/WebView2.cpp +++ b/dev/WebView2/WebView2.cpp @@ -837,11 +837,11 @@ void WebView2::CreateMissingAnaheimWarning() // Make sure it is visited by the Measure pass. winrt::Size WebView2::MeasureOverride(winrt::Size const& availableSize) { - if (auto child = Content().try_as()) - { - child.Measure(availableSize); - return availableSize; - } + //if (auto child = Content().try_as()) + //{ + // child.Measure(availableSize); + // return child.DesiredSize; + //} return __super::MeasureOverride(availableSize); }