Skip to content

[Problem/Bug]: NavigationCompleted report failed when custom handling new window request #5257

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

Open
HO-COOH opened this issue May 27, 2025 · 0 comments
Assignees
Labels
bug Something isn't working regression Something used to work but doesn't anymore

Comments

@HO-COOH
Copy link

HO-COOH commented May 27, 2025

What happened?

We used to have a custom error page that is displayed when NavigationCompleted event reports an unsuccessful state. And recently (I think it's from 135->136 this behavior is broken), we found everytime I opened a new custom window in the NewWindowRequested event handler and passing a url to it, the error page is shown, indicating a false positive navigation failed event.

Importance

Important. My app's user experience is significantly compromised.

Runtime Channel

Stable release (WebView2 Runtime)

Runtime Version

136

SDK Version

No response

Framework

Win32

Operating System

Windows 10, Windows 11

OS Version

No response

Repro steps

Use the official WebView2GettingStarted repro, change C++ standard to C++20 for std::format. Replace the code

  1. WebViewWindow.h
#pragma once
#include <tchar.h>
#include <string>
#include <wil/com.h>
#include <WebView2.h>


class WebViewWindow
{
	static void registerIfNeeded();

	// Forward declarations of functions included in this code module:
	static LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);

	// The main window class name.
	constexpr static TCHAR szWindowClass[] = _T("DesktopApp");

	// The string that appears in the application's title bar.
	constexpr static TCHAR szTitle[] = _T("WebView sample");

	HWND m_hwnd{};
	// Pointer to WebViewController
	wil::com_ptr<ICoreWebView2Controller> webviewController;

	// Pointer to WebView window
	wil::com_ptr<ICoreWebView2> webview;

	static inline wil::com_ptr<ICoreWebView2Environment> s_globalEnv;
public:
	WebViewWindow(std::wstring url, ICoreWebView2NewWindowRequestedEventArgs* newWindowArgs = nullptr, wil::com_ptr<ICoreWebView2Deferral> deferral = {});
};
  1. WebViewWindow.cpp
#include <Windows.h>
#include "WebViewWindow.h"
#include <format>
#include <wrl.h>
#include <WebView2.h>
#include <format>


void WebViewWindow::registerIfNeeded()
{
	static bool s_registered = false;
	if (s_registered)
		return;

	WNDCLASSEX wcex{};

	wcex.cbSize = sizeof(WNDCLASSEX);
	wcex.style = CS_HREDRAW | CS_VREDRAW;
	wcex.lpfnWndProc = WndProc;
	wcex.cbClsExtra = 0;
	wcex.cbWndExtra = sizeof(void*);
	wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
	wcex.lpszMenuName = NULL;
	wcex.lpszClassName = szWindowClass;

	if (!RegisterClassEx(&wcex))
	{
		MessageBox(NULL,
			_T("Call to RegisterClassEx failed!"),
			_T("MiLineApi"),
			NULL);
	}
	s_registered = true;
}

LRESULT WebViewWindow::WndProc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam)
{
	switch (msg)
	{
		case WM_CREATE:
		{
			SetWindowLongPtr(hwnd, 0, reinterpret_cast<LONG_PTR>(reinterpret_cast<CREATESTRUCT*>(lparam)->lpCreateParams));
			SetWindowPos(hwnd, NULL, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_FRAMECHANGED);
			break;
		}
		case WM_SIZE:
		{
			auto thisPtr = reinterpret_cast<WebViewWindow*>(GetWindowLongPtr(hwnd, 0));
			if (thisPtr->webviewController)
			{
				RECT bounds;
				GetWindowRect(hwnd, &bounds);
				bounds.right = bounds.right - bounds.left;
				bounds.left = 0;
				bounds.bottom = bounds.bottom - bounds.top;
				bounds.top = 0;
				thisPtr->webviewController->put_Bounds(bounds);
			};
			break;
		}
		case WM_DESTROY:
			PostQuitMessage(0);
			break;
		default:
			return DefWindowProc(hwnd, msg, wparam, lparam);
	}

	return DefWindowProc(hwnd, msg, wparam, lparam);
}

WebViewWindow::WebViewWindow(std::wstring url, ICoreWebView2NewWindowRequestedEventArgs* args, wil::com_ptr<ICoreWebView2Deferral> deferral)
{
	using namespace Microsoft::WRL;
	registerIfNeeded();
	m_hwnd = CreateWindowExW(0L, szWindowClass, szTitle, (0x00000000L | 0x00C00000L | 0x00080000L | 0x00040000L | 0x00020000L | 0x00010000L), ((int)0x80000000), ((int)0x80000000), 1200, 900, 0, 0, 0, this);
	if (!m_hwnd)
	{
		MessageBox(NULL,
			_T("Call to CreateWindow failed!"),
			_T("MiLineApi"),
			NULL);
		return;
	}

	ShowWindow(m_hwnd, SW_SHOW);
	UpdateWindow(m_hwnd);

	auto handler = [this, url = std::move(url), args = wil::com_ptr{ args }, deferral = std::move(deferral)](HRESULT result, ICoreWebView2Environment* env) -> HRESULT {
		if (!s_globalEnv)
			s_globalEnv = env;

		// Create a CoreWebView2Controller and get the associated CoreWebView2 whose parent is the main window hWnd
		env->CreateCoreWebView2Controller(m_hwnd, Callback<ICoreWebView2CreateCoreWebView2ControllerCompletedHandler>(
			[this, url = std::move(url), deferral = std::move(deferral), args = std::move(args)](HRESULT result, ICoreWebView2Controller* controller) -> HRESULT {
				if (controller != nullptr) {
					webviewController = controller;
					webviewController->get_CoreWebView2(&webview);
				}
				webview->OpenDevToolsWindow();

				if (args)
				{
					args->put_NewWindow(webview.get());
					args->put_Handled(true);
					deferral->Complete();
				}

				// Add a few settings for the webview
				// The demo step is redundant since the values are the default settings
				wil::com_ptr<ICoreWebView2Settings> settings;
				webview->get_Settings(&settings);
				settings->put_IsScriptEnabled(TRUE);
				settings->put_AreDefaultScriptDialogsEnabled(TRUE);
				settings->put_IsWebMessageEnabled(TRUE);

				auto settings_4 = settings.query<ICoreWebView2Settings4>();
				settings_4->put_IsGeneralAutofillEnabled(true);
				settings_4->put_IsPasswordAutosaveEnabled(true);

				// Resize WebView to fit the bounds of the parent window
				RECT bounds;
				GetClientRect(m_hwnd, &bounds);
				webviewController->put_Bounds(bounds);


				webview->Navigate(url.data());


				EventRegistrationToken token;


				webview->add_NavigationCompleted(Callback<ICoreWebView2NavigationCompletedEventHandler>([](ICoreWebView2* sender, ICoreWebView2NavigationCompletedEventArgs* args)
					{
						BOOL isSuccess = true;
						if (args->get_IsSuccess(&isSuccess) == S_OK && isSuccess == false)
						{
							wil::com_ptr<ICoreWebView2NavigationCompletedEventArgs2> args_2;
							args->QueryInterface(args_2.put());

							int code{};
							args_2->get_HttpStatusCode(&code);

							MessageBox(NULL, std::format(L"Failed, code: {}", code).data(), L"", 0);
						}
						return S_OK;
					}).Get(), &token);


				webview->add_NewWindowRequested(Callback<ICoreWebView2NewWindowRequestedEventHandler>(
					[](ICoreWebView2* core, ICoreWebView2NewWindowRequestedEventArgs* args)
					{
						wil::unique_cotaskmem_string uri;
						args->get_Uri(&uri);

						wil::com_ptr<ICoreWebView2Deferral> deferral;
						if (args)
						{
							args->GetDeferral(deferral.put());
						}
						new WebViewWindow{ uri.get(), args, deferral };

						return S_OK;
					}
				).Get(), &token);

				return S_OK;
			}).Get());
		return S_OK;
		};

	CreateCoreWebView2EnvironmentWithOptions(nullptr, nullptr, nullptr,Callback<ICoreWebView2CreateCoreWebView2EnvironmentCompletedHandler>(handler).Get());

}
  1. main.cpp
#include <windows.h>
#include <stdlib.h>
#include "WebViewWindow.h"


int CALLBACK WinMain(
	_In_ HINSTANCE hInstance,
	_In_ HINSTANCE hPrevInstance,
	_In_ LPSTR     lpCmdLine,
	_In_ int       nCmdShow
)
{

	WebViewWindow window{ L"https://www.google.com" };

	// Main message loop:
	MSG msg;
	while (GetMessage(&msg, NULL, 0, 0))
	{
		TranslateMessage(&msg);
		DispatchMessage(&msg);
	}

	return (int)msg.wParam;
}
  1. Build and run. Open DevTool, type window.open("https://www.google.com") to trigger this. The messagebox will popup.

Repros in Edge Browser

No, issue does not reproduce in the corresponding Edge version

Regression

Regression in newer Runtime

Last working version (if regression)

134 or 135 maybe.

@HO-COOH HO-COOH added the bug Something isn't working label May 27, 2025
@github-actions github-actions bot added the regression Something used to work but doesn't anymore label May 27, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working regression Something used to work but doesn't anymore
Projects
None yet
Development

No branches or pull requests

2 participants