Skip to content
This repository was archived by the owner on Jun 5, 2023. It is now read-only.
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .idea/.gitignore

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 5 additions & 0 deletions src/WebWindow.Native/Exports.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -134,4 +134,9 @@ extern "C"
{
instance->SetIconFile(filename);
}

EXPORTED void WebWindow_SetUriChangeCallback(WebWindow* instance, UriChangeCallback callback)
{
instance->SetUriChangeCallback(callback);
}
}
16 changes: 16 additions & 0 deletions src/WebWindow.Native/WebWindow.Linux.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,21 @@ void HandleWebMessage(WebKitUserContentManager* contentManager, WebKitJavascript
webkit_javascript_result_unref(jsResult);
}

void HandleUriChange(GObject* object, WebKitLoadEvent event, gpointer user_data)
{
WebKitWebView *web_view;

const gchar *uri;

if (event == WEBKIT_LOAD_FINISHED) {
web_view = WEBKIT_WEB_VIEW(object);
uri = webkit_web_view_get_uri(web_view);

UriChangeCallback callback = (UriChangeCallback)user_data;
callback(AutoString(uri));
}
}

void WebWindow::Show()
{
if (!_webview)
Expand All @@ -99,6 +114,7 @@ void WebWindow::Show()

g_signal_connect(contentManager, "script-message-received::webwindowinterop",
G_CALLBACK(HandleWebMessage), (void*)_webMessageReceivedCallback);
g_signal_connect(_webview, "load-changed", G_CALLBACK(HandleUriChange), (void*)_uriChangeCallback);
webkit_user_content_manager_register_script_message_handler(contentManager, "webwindowinterop");
}

Expand Down
13 changes: 13 additions & 0 deletions src/WebWindow.Native/WebWindow.Mac.NavigationDelegate.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
#import <Cocoa/Cocoa.h>
#import <WebKit/WebKit.h>
#include "WebWindow.h"

typedef void (*UriChangedCallback) (char* message);

@interface MyNavigationDelegate : NSObject <WKNavigationDelegate> {
@public
NSWindow * window;
WebWindow * webWindow;
UriChangedCallback uriChangedCallback;
}
@end
26 changes: 26 additions & 0 deletions src/WebWindow.Native/WebWindow.Mac.NavigationDelegate.mm
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
#import "WebWindow.Mac.NavigationDelegate.h"

@implementation MyNavigationDelegate : NSObject

- (void)webView:(WKWebView *)webView didStartProvisionalNavigation:(WKNavigation *)navigation;
{
[self callUriChangedCallback:webView.URL.absoluteString];
}

- (void)webView:(WKWebView *)webView didFailNavigation:(WKNavigation *)navigation withError:(NSError *)error;
{
[self callUriChangedCallback:webView.URL.absoluteString];
}

- (void)webView:(WKWebView *)webView
didReceiveServerRedirectForProvisionalNavigation:(WKNavigation *)navigation;
{
[self callUriChangedCallback:webView.URL.absoluteString];
}

- (void) callUriChangedCallback: (NSString *) uri;
{
char* writableUri = (char*)[uri UTF8String];
uriChangedCallback(writableUri);
}
@end
11 changes: 9 additions & 2 deletions src/WebWindow.Native/WebWindow.Mac.mm
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
#import "WebWindow.Mac.AppDelegate.h"
#import "WebWindow.Mac.UiDelegate.h"
#import "WebWindow.Mac.UrlSchemeHandler.h"
#import "WebWindow.Mac.NavigationDelegate.h"
#include <cstdio>
#include <map>
#import <Cocoa/Cocoa.h>
Expand Down Expand Up @@ -69,6 +70,8 @@
MyUiDelegate *uiDelegate = [[[MyUiDelegate alloc] init] autorelease];
uiDelegate->webWindow = this;

MyNavigationDelegate *navDelegate = [[[MyNavigationDelegate alloc] init] autorelease];

NSString *initScriptSource = @"window.__receiveMessageCallbacks = [];"
"window.__dispatchMessageCallback = function(message) {"
" window.__receiveMessageCallbacks.forEach(function(callback) { callback(message); });"
Expand All @@ -92,13 +95,17 @@
[webView setAutoresizingMask:NSViewWidthSizable | NSViewHeightSizable];
[window.contentView addSubview:webView];
[window.contentView setAutoresizesSubviews:YES];

uiDelegate->window = window;
webView.UIDelegate = uiDelegate;

uiDelegate->webMessageReceivedCallback = _webMessageReceivedCallback;
[userContentController addScriptMessageHandler:uiDelegate name:@"webwindowinterop"];

navDelegate->window = window;
navDelegate->webWindow = this;
navDelegate->uriChangedCallback = _uriChangeCallback;

webView.navigationDelegate = navDelegate;

// TODO: Remove these observers when the window is closed
[[NSNotificationCenter defaultCenter] addObserver:uiDelegate selector:@selector(windowDidResize:) name:NSWindowDidResizeNotification object:window];
[[NSNotificationCenter defaultCenter] addObserver:uiDelegate selector:@selector(windowDidMove:) name:NSWindowDidMoveNotification object:window];
Expand Down
4 changes: 4 additions & 0 deletions src/WebWindow.Native/WebWindow.Native.vcxproj
Original file line number Diff line number Diff line change
Expand Up @@ -153,10 +153,14 @@
</ItemGroup>
<ItemGroup>
<ClInclude Include="WebWindow.h" />
<ClInclude Include="WebWindow.Mac.NavigationDelegate.h" />
</ItemGroup>
<ItemGroup>
<None Include="packages.config" />
</ItemGroup>
<ItemGroup>
<Content Include="WebWindow.Mac.NavigationDelegate.mm" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
<Import Project="..\..\packages\Microsoft.Web.WebView2.0.8.270\build\native\Microsoft.Web.WebView2.targets" Condition="Exists('..\..\packages\Microsoft.Web.WebView2.0.8.270\build\native\Microsoft.Web.WebView2.targets')" />
Expand Down
13 changes: 12 additions & 1 deletion src/WebWindow.Native/WebWindow.Windows.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -225,7 +225,18 @@ void WebWindow::AttachWebView()
Settings->put_IsScriptEnabled(TRUE);
Settings->put_AreDefaultScriptDialogsEnabled(TRUE);
Settings->put_IsWebMessageEnabled(TRUE);

// Add a navigation change event handler
EventRegistrationToken token;
_webviewWindow->add_NavigationStarting(Callback<IWebView2NavigationStartingEventHandler>(
[this](IWebView2WebView* webview, IWebView2NavigationStartingEventArgs * args) -> HRESULT
{
wil::unique_cotaskmem_string uri;
args->get_Uri(&uri);
_uriChangeCallback(uri.get());
return S_OK;
}
).Get(), &token);

// Register interop APIs
EventRegistrationToken webMessageToken;
_webviewWindow->AddScriptToExecuteOnDocumentCreated(L"window.external = { sendMessage: function(message) { window.chrome.webview.postMessage(message); }, receiveMessage: function(callback) { window.chrome.webview.addEventListener(\'message\', function(e) { callback(e.data); }); } };", nullptr);
Expand Down
4 changes: 4 additions & 0 deletions src/WebWindow.Native/WebWindow.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,13 +31,15 @@ typedef void* (*WebResourceRequestedCallback)(AutoString url, int* outNumBytes,
typedef int (*GetAllMonitorsCallback)(const Monitor* monitor);
typedef void (*ResizedCallback)(int width, int height);
typedef void (*MovedCallback)(int x, int y);
typedef void (*UriChangeCallback)(AutoString url);

class WebWindow
{
private:
WebMessageReceivedCallback _webMessageReceivedCallback;
MovedCallback _movedCallback;
ResizedCallback _resizedCallback;
UriChangeCallback _uriChangeCallback;
#ifdef _WIN32
static HINSTANCE _hInstance;
HWND _hWnd;
Expand Down Expand Up @@ -87,6 +89,8 @@ class WebWindow
void SetPosition(int x, int y);
void SetMovedCallback(MovedCallback callback) { _movedCallback = callback; }
void InvokeMoved(int x, int y) { if (_movedCallback) _movedCallback(x, y); }
void SetUriChangeCallback(UriChangeCallback callback) { _uriChangeCallback = callback; }
void InvokeUriChange(AutoString uri) { if (_uriChangeCallback) _uriChangeCallback(uri); }
void SetTopmost(bool topmost);
void SetIconFile(AutoString filename);
};
Expand Down
11 changes: 10 additions & 1 deletion src/WebWindow/WebWindow.cs
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ public class WebWindow
[UnmanagedFunctionPointer(CallingConvention.Cdecl)] delegate int GetAllMonitorsCallback(in NativeMonitor monitor);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)] delegate void ResizedCallback(int width, int height);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)] delegate void MovedCallback(int x, int y);

[UnmanagedFunctionPointer(CallingConvention.Cdecl, CharSet = CharSet.Auto)] delegate void UriChangeCallback(string uri);
const string DllName = "WebWindow.Native";
[DllImport(DllName, CallingConvention = CallingConvention.Cdecl)] static extern IntPtr WebWindow_register_win32(IntPtr hInstance);
[DllImport(DllName, CallingConvention = CallingConvention.Cdecl)] static extern IntPtr WebWindow_register_mac();
Expand All @@ -82,6 +82,7 @@ public class WebWindow
[DllImport(DllName, CallingConvention = CallingConvention.Cdecl)] static extern void WebWindow_SetMovedCallback(IntPtr instance, MovedCallback callback);
[DllImport(DllName, CallingConvention = CallingConvention.Cdecl)] static extern void WebWindow_SetTopmost(IntPtr instance, int topmost);
[DllImport(DllName, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Auto)] static extern void WebWindow_SetIconFile(IntPtr instance, string filename);
[DllImport(DllName, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Auto)] static extern void WebWindow_SetUriChangeCallback(IntPtr instance, UriChangeCallback callback);

private readonly List<GCHandle> _gcHandlesToFree = new List<GCHandle>();
private readonly List<IntPtr> _hGlobalToFree = new List<IntPtr>();
Expand Down Expand Up @@ -145,6 +146,10 @@ public WebWindow(string title, Action<WebWindowOptions> configure)
_gcHandlesToFree.Add(GCHandle.Alloc(onMovedDelegate));
WebWindow_SetMovedCallback(_nativeWebWindow, onMovedDelegate);

var onUriChangeDelegate = (UriChangeCallback)UriChanged;
_gcHandlesToFree.Add(GCHandle.Alloc(onUriChangeDelegate));
WebWindow_SetUriChangeCallback(_nativeWebWindow, onUriChangeDelegate);

// Auto-show to simplify the API, but more importantly because you can't
// do things like navigate until it has been shown
Show();
Expand Down Expand Up @@ -237,6 +242,10 @@ public void SendMessage(string message)
}

public event EventHandler<string> OnWebMessageReceived;

private void UriChanged(string uri) => OnUriChange?.Invoke(this, uri);

public event EventHandler<string> OnUriChange;

private void WriteTitleField(string value)
{
Expand Down
2 changes: 1 addition & 1 deletion src/WebWindow/WebWindow.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
<MakeDir Directories="..\WebWindow.Native\x64\$(Configuration)" />
<Exec Condition="'$(IsMacOS)' == 'true'"
WorkingDirectory="..\WebWindow.Native"
Command="gcc -shared -lstdc++ -DOS_MAC -framework Cocoa -framework WebKit WebWindow.Mac.mm Exports.cpp WebWindow.Mac.AppDelegate.mm WebWindow.Mac.UiDelegate.mm WebWindow.Mac.UrlSchemeHandler.m -o x64/$(Configuration)/WebWindow.Native.dylib" />
Command="gcc -shared -lstdc++ -DOS_MAC -framework Cocoa -framework WebKit WebWindow.Mac.mm Exports.cpp WebWindow.Mac.AppDelegate.mm WebWindow.Mac.UiDelegate.mm WebWindow.Mac.UrlSchemeHandler.m WebWindow.Mac.NavigationDelegate.mm -o x64/$(Configuration)/WebWindow.Native.dylib" />
<Exec Condition="'$(IsMacOS)' != 'true'"
WorkingDirectory="..\WebWindow.Native"
Command="gcc -std=c++11 -shared -DOS_LINUX Exports.cpp WebWindow.Linux.cpp -o x64/$(Configuration)/WebWindow.Native.so `pkg-config --cflags --libs gtk+-3.0 webkit2gtk-4.0` -fPIC" />
Expand Down
1 change: 1 addition & 0 deletions src/WebWindow/WebWindowOptions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ public class WebWindowOptions

public IDictionary<string, ResolveWebResourceDelegate> SchemeHandlers { get; }
= new Dictionary<string, ResolveWebResourceDelegate>();

}

public delegate Stream ResolveWebResourceDelegate(string url, out string contentType);
Expand Down
5 changes: 4 additions & 1 deletion testassets/HelloWorldApp/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,10 @@ static void Main(string[] args)
{
window.SendMessage("Got message: " + message);
};

window.OnUriChange += (sender, uri) =>
{
Console.WriteLine($"New URI: {uri}");
};
window.NavigateToLocalFile("wwwroot/index.html");
window.WaitForExit();
}
Expand Down
4 changes: 4 additions & 0 deletions testassets/HelloWorldApp/wwwroot/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,10 @@ <h1>Hello</h1>
<p>
<button onclick="callDotNet()">Call .NET</button>
</p>

<p>
<a href="http://www.example.com">Link to example.com</a>
</p>

<script src="app://something.js"></script>

Expand Down