Skip to content

Add WebView2 implementation for Windows#1192

Open
SyaoranChang wants to merge 8 commits intogree:masterfrom
SyaoranChang:feature/webview2-windows-support
Open

Add WebView2 implementation for Windows#1192
SyaoranChang wants to merge 8 commits intogree:masterfrom
SyaoranChang:feature/webview2-windows-support

Conversation

@SyaoranChang
Copy link

Summary
This implementation was developed with AI assistance, with much of the initial code generated using Cursor AI and then reviewed and adjusted manually.
This PR adds Windows support for Unity WebView using Microsoft WebView2.
It integrates WebView2 to provide a modern Chromium-based webview for Windows builds.


Changes
• Added a WebView2-based implementation for Windows
• Implemented basic webview functionality:
o Load URL
o Execute JavaScript
o Receive messages from JavaScript
o Basic navigation support
• Added conditional compilation for the Windows platform
• Added required initialization for the WebView2 environment


Requirements
This implementation requires Microsoft Edge WebView2 Runtime to be installed on the system.
WebView2 Runtime:
https://developer.microsoft.com/en-us/microsoft-edge/webview2/
Most modern Windows installations already include it, but it may need to be installed on older systems.


Testing
Tested with:
• Unity 6000.0.68f1
• Windows 10
• WebView2 Runtime installed
Verified functionality:
• Loading web pages
• JavaScript execution
• JS → Unity messaging


Limitations
• Only basic functionality is currently implemented
• Some advanced features may not yet be supported
• Requires WebView2 Runtime on the target machine


Notes
This implementation aims to provide a foundation for Windows support using WebView2 while trying to follow the existing architecture of the project as closely as possible. Further improvements and feature parity with other platforms may be added in the future.
Feedback and suggestions are welcome.

…ugin and added entries for user-specific files and downloaded tools
…2 integration. Updated README.md with Windows-specific instructions and added necessary files for building the plugin on Windows. Enhanced WebViewObject.cs to handle Windows platform specifics.
…iguration files and documentation. Adjusted paths in the project files and scripts accordingly to reflect the new version. Updated binary files for both Win32 and x64 builds.
…e package and package-nofragment directories.
Copy link
Member

@KojiNakamaru KojiNakamaru left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you for your great contribution! I've added several comments, so please check them.

if (!inst) return nullptr;
std::string msg;
if (!inst->messages.pop(msg)) return nullptr;
char* buf = (char*)malloc(msg.size() + 1);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should use CoTaskMemAlloc() instead of malloc().
cf. https://www.mono-project.com/docs/advanced/pinvoke/

if (refreshBitmap && inst->hwnd && inst->webview) {
HANDLE ev = CreateEvent(nullptr, FALSE, FALSE, nullptr);
PostMessage(inst->hwnd, WM_WEBVIEW_CAPTURE, 0, (LPARAM)ev);
WaitForSingleObject(ev, 5000);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

To prevent blocking the main thread, we should implement a non-blocking approach. For example
(pseudo code):

    if (refreshBitmap && inst->hwnd && inst->webview) {
        // captureInProgress should be accessed exclusively. We set it to true here and reset
        // it to false when a capture is completed in the STA thread.
        if (!captureInProgress) {
            captureInProgress = true;
            PostMessage(inst->hwnd, WM_WEBVIEW_CAPTURE, ...);
        }
    }

The actual capture logic in the STA thread should utilize double-buffering for bitmapPixels,
similar to the macOS implementation. This allows _CWebViewPlugin_Render() to simply render the
current bitmapPixels without delay.

NOTE: Although the current macOS implementation of update:with: is also incomplete in a different
way (it lacks captureInProgress and triggers takeSnapshotWithConfiguration:completionHandler:
without waiting for previous calls), it avoids blocking the main thread by utilizing
double-buffering.

std::lock_guard<std::mutex> lk(s_instancesMutex);
for (auto it = s_instances.begin(); it != s_instances.end(); ++it) {
if (it->get() == inst) {
s_instances.erase(it);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The inst object is destroyed here immediately after WM_WEBVIEW_DESTROY is sent. However, the STA thread may still be accessing inst at this point.

using UnityEngine.UI;
#endif
#if UNITY_EDITOR_WIN || UNITY_STANDALONE_WIN
using System.IO;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

System.IO doesn't seem to be used.

}
}

// On Windows, CapturePreview is heavy; default 3 = refresh every 3rd frame for better FPS.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The comment should be updated to match the actual definition: 10 instead of 3.

CPU: ARMv7
Any:
enabled: 0
settings:
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The exclude and enabled settings should be corrected.

CPU: ARMv7
Any:
enabled: 0
settings:
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The exclude and enabled settings should be corrected.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants