-
Notifications
You must be signed in to change notification settings - Fork 692
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Backport WebView2 to WinUI2 #5708
Conversation
/azp run |
Azure Pipelines successfully started running 1 pipeline(s). |
test/MUXControlsReleaseTest/LibraryThatUsesMUX/LibraryThatUsesMUX.csproj
Outdated
Show resolved
Hide resolved
test/MUXControlsReleaseTest/RuntimeComponentThatUsesMUX/packages.config
Outdated
Show resolved
Hide resolved
/azp run |
Azure Pipelines successfully started running 1 pipeline(s). |
/azp run |
Azure Pipelines successfully started running 1 pipeline(s). |
/azp run |
Azure Pipelines successfully started running 1 pipeline(s). |
{ | ||
if (textbox.Value != expectedValue) | ||
{ | ||
return; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
shouldn't this assert/throw/fail the test?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hmmm .. I don't know. This is what it looks like in WinUI3's code as well. @DmitriyKomin ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good catch. This function does two things (1)wait for textbox to attain a new value, and then (2) match that against expectedString (or the negation of it).
In the two places we use it, looks like it mostly just depends on part (1) - if the textbox value, changes then things are good, we don't depend on (2)... I am not sure that's true 100% of the time it's called, and also there could be new usages in the future expecting the matching part to work correctly...
In short, I agree this should be changed to return a bool reflecting the matching result.
public static uint PW_RENDERFULLCONTENT = 2; | ||
[DllImport("user32.dll")] public static extern bool PrintWindow(IntPtr hWnd, IntPtr hdc, uint flags); | ||
[DllImport("user32.dll")] public static extern IntPtr GetDC(IntPtr hWnd); | ||
[DllImport("user32.dll")] public static extern IntPtr ReleaseDC(IntPtr hWnd, IntPtr hdc); | ||
[DllImport("user32.dll", CharSet = CharSet.Unicode)] public static extern IntPtr FindWindowEx(IntPtr parentHandle, IntPtr childAfter, string className, string windowTitle); | ||
[DllImport("user32.dll")] public static extern int GetWindowRect(IntPtr hWnd, ref RECT rectangle); | ||
[DllImport("user32.dll")] public static extern int GetDpiForWindow([In] IntPtr hWnd); | ||
|
||
[StructLayout(LayoutKind.Sequential)] | ||
public struct RECT | ||
{ | ||
public int Left; // x position of upper-left corner | ||
public int Top; // y position of upper-left corner | ||
public int Right; // x position of lower-right corner | ||
public int Bottom; // y position of lower-right corner | ||
} | ||
|
||
[DllImport("gdi32.dll")] public static extern IntPtr CreateCompatibleDC(IntPtr hdc); | ||
[DllImport("gdi32.dll")] public static extern bool DeleteDC(IntPtr hdc); | ||
[DllImport("gdi32.dll")] public static extern IntPtr CreateCompatibleBitmap(IntPtr hdc, int width, int height); | ||
[DllImport("gdi32.dll")] public static extern IntPtr SelectObject(IntPtr hdc, IntPtr obj); | ||
[DllImport("gdi32.dll")] public static extern bool DeleteObject(IntPtr obj); | ||
[DllImport("gdi32.dll")] public static extern uint GetPixel(IntPtr hdc, int x, int y); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit, we could be using win32metadata instead : )
} | ||
} | ||
|
||
private static bool AreEqualIgnoringSpace(string string1, string string2) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit, can probably use Uri.EscapeUriString
instead?
"(async function() { " + | ||
"let result = await window.chrome.webview.hostObjects.bridge.AnotherObject.Prop; " + | ||
"window.chrome.webview.postMessage(result); })();"); | ||
// Listen for WebMessageReceived |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
mark as TODO / file an issue?
public static Uri GetTestPageUri(string testPageName) | ||
{ | ||
string localAppDataPath = AppDataPaths.GetDefault().LocalAppData; | ||
string fullUri = @"file:///" + localAppDataPath + @"/" + testPageName; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit you can make this a little more readable with an interpolated string
string fullUri = @"file:///" + localAppDataPath + @"/" + testPageName; | |
string fullUri = $"file:///{localAppDataPath}/{testPageName}"; |
dev/WebView2/WebView2.cpp
Outdated
#include <winuser.h> | ||
#include <uiautomationclient.h> | ||
|
||
using namespace Microsoft::WRL; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
curious, could we not use wrl and use the cppwinrt winrt::
types instead?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Interesting, I suspect this is stale, since I don't recall seeing any WRL usage in this file. Let me try to remove.
void WebView2::CreateMissingAnaheimWarning() | ||
{ | ||
auto warning = winrt::TextBlock(); | ||
warning.Text(L"A suitable version of Microsoft Edge WebView2 Runtime was not detected. "); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
shouldn't these strings come from resources / be localized?
float leftVal = inputProperties.ContactRect().X * m_rasterizationScale; | ||
float topVal = inputProperties.ContactRect().Y * m_rasterizationScale; | ||
|
||
winrt::Windows::Foundation::Rect outputPt_touchContact(static_cast<float>(leftVal), static_cast<float>(topVal), static_cast<float>(width), static_cast<float>(height)); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
these are already floats, can remove the casts. same below.
LRESULT result = ::SendMessageW(GetActiveInputWindowHwnd(), message, wparam, lparam); | ||
if (!result) | ||
{ | ||
winrt::check_hresult(HRESULT_FROM_WIN32(::GetLastError())); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
noexcept with check_hresult #ByDesign
/azp run |
Azure Pipelines successfully started running 1 pipeline(s). |
/azp run |
Azure Pipelines successfully started running 1 pipeline(s). |
/azp run |
Azure Pipelines successfully started running 1 pipeline(s). |
{ | ||
auto coreWindowInterop = coreWindow.as<ICoreWindowInterop>(); | ||
winrt::check_hresult(coreWindowInterop->get_WindowHandle(&m_xamlHostHwnd)); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What happens in the context of OS Xaml islands / DWXS? I belive the CoreWindow will exist, but is not used for rendering... WebView2 will fail in some way. Should we early out to avoid unsafe behavior? Also, is there an issue/task to track WebView2 in island?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is just to get it working in UWP. We can have a follow-up to figure out how (if at all) to make it work in islands. I suspect there will be other things that need to be done.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
agree with getting it to work on UWP first and figuring out islands post "1.0".
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Having said that, an error message would be good if possible :)
if (m_visual) | ||
{ | ||
winrt::float2 newSize = winrt::float2(width * m_rasterizationScale, height * m_rasterizationScale); | ||
winrt::float3 newScale = winrt::float3(1.0f / m_rasterizationScale, 1.0f / m_rasterizationScale, 1.0); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Extract duplicatd code #WontFix
outputMatrix.m44 = 1.0f; | ||
|
||
return outputMatrix; | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is no longer used (was needed for older input forwarding API). Please remove.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
How about you remove in WinUI3 first and then i can copy those deltas over here?
WebView2::WebView2() | ||
{ | ||
if (HMODULE user32module = LoadLibraryW(L"user32.dll")) | ||
{ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit, GetModuleHandle since user32 will have already been loaded (also gets rid of needing to free the hmodule) #Resolved
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
main remaining thing for me is to please make sure the noexcept/throws are reasonable (i.e. does it make sense to [not] bubble exceptions up to the app)
Per discussion with @jevansaks and @asklar , some of the comments made by @asklar and myself are existing issues in WinUI3 codebase and that are lower priority. I will capture these for fixing in WinUI3 codebase (and porting the changes back to WinUI2). |
/azp run |
Azure Pipelines successfully started running 1 pipeline(s). |
/azp run |
Azure Pipelines successfully started running 1 pipeline(s). |
Congratulations! |
How's the extra dependency going to work for an app that doesn't use |
The dlls are relatively small (~500KB). For now it's getting copied into the consuming apps. We are discussing alternatives, since WinUI3 is already doing this slightly differently by including the WebView2 client-side dlls in the WinAppSDK framework package. |
This is a backport of the WinUI3 control and tests into WinUI2. Notable differences from the experience you get in WinUI3 via WinAppSDK are:
WinUI2 also compiles and supports Arm32, but WebView2 package does not because there is no WebView2 runtime for Arm32. I've asked the WebView2 folks to consider adding at least the type information (with stub implementation), but I don't know if/when that will happen. As such I have made the build conditional so that the Arm32 version does not include WebView2 control. Consumers will need to write conditional code as well if they support Arm32 and want to use WebView2.
Fixes #5610