From fbff90ed8f9fb8652093b8cc44125207800f74f6 Mon Sep 17 00:00:00 2001 From: Justin Ashworth Date: Thu, 2 Jan 2020 14:37:01 -0500 Subject: [PATCH 1/8] Linux Additions and functional --- src/WebWindow.Native/Exports.cpp | 5 +++++ src/WebWindow.Native/WebWindow.Linux.cpp | 19 +++++++++++++++++++ src/WebWindow.Native/WebWindow.h | 4 ++++ src/WebWindow/WebWindow.cs | 14 ++++++++++++++ src/WebWindow/WebWindowOptions.cs | 1 + 5 files changed, 43 insertions(+) diff --git a/src/WebWindow.Native/Exports.cpp b/src/WebWindow.Native/Exports.cpp index 1b62fbd..e517f13 100644 --- a/src/WebWindow.Native/Exports.cpp +++ b/src/WebWindow.Native/Exports.cpp @@ -134,4 +134,9 @@ extern "C" { instance->SetIconFile(filename); } + + EXPORTED void WebWindow_SetUriChangeCallback(WebWindow* instance, UriChangeCallback callback) + { + instance->SetUriChangeCallback(callback); + } } diff --git a/src/WebWindow.Native/WebWindow.Linux.cpp b/src/WebWindow.Native/WebWindow.Linux.cpp index 8ec24c1..845ccca 100644 --- a/src/WebWindow.Native/WebWindow.Linux.cpp +++ b/src/WebWindow.Native/WebWindow.Linux.cpp @@ -73,6 +73,23 @@ 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_STARTED) { + 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) @@ -99,6 +116,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"); } @@ -155,6 +173,7 @@ void WebWindow::ShowMessage(AutoString title, AutoString body, unsigned int type gtk_widget_destroy(dialog); } + void WebWindow::NavigateToUrl(AutoString url) { webkit_web_view_load_uri(WEBKIT_WEB_VIEW(_webview), url); diff --git a/src/WebWindow.Native/WebWindow.h b/src/WebWindow.Native/WebWindow.h index f5cf4f7..3fe4669 100644 --- a/src/WebWindow.Native/WebWindow.h +++ b/src/WebWindow.Native/WebWindow.h @@ -31,6 +31,7 @@ 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 { @@ -38,6 +39,7 @@ class WebWindow WebMessageReceivedCallback _webMessageReceivedCallback; MovedCallback _movedCallback; ResizedCallback _resizedCallback; + UriChangeCallback _uriChangeCallback; #ifdef _WIN32 static HINSTANCE _hInstance; HWND _hWnd; @@ -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); }; diff --git a/src/WebWindow/WebWindow.cs b/src/WebWindow/WebWindow.cs index 49e3b5a..dcd348d 100644 --- a/src/WebWindow/WebWindow.cs +++ b/src/WebWindow/WebWindow.cs @@ -56,6 +56,9 @@ public class WebWindow [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(); @@ -83,6 +86,9 @@ public class WebWindow [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 _gcHandlesToFree = new List(); private readonly List _hGlobalToFree = new List(); private readonly IntPtr _nativeWebWindow; @@ -145,6 +151,10 @@ public WebWindow(string title, Action 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(); @@ -237,6 +247,10 @@ public void SendMessage(string message) } public event EventHandler OnWebMessageReceived; + + private void UriChanged(string uri) => OnUriChange?.Invoke(this, uri); + + public event EventHandler OnUriChange; private void WriteTitleField(string value) { diff --git a/src/WebWindow/WebWindowOptions.cs b/src/WebWindow/WebWindowOptions.cs index 17b96cd..b49a75d 100644 --- a/src/WebWindow/WebWindowOptions.cs +++ b/src/WebWindow/WebWindowOptions.cs @@ -9,6 +9,7 @@ public class WebWindowOptions public IDictionary SchemeHandlers { get; } = new Dictionary(); + } public delegate Stream ResolveWebResourceDelegate(string url, out string contentType); From 9d3e4d340832cff34a4017bf8c01a21cc781ef3e Mon Sep 17 00:00:00 2001 From: Justin Ashworth Date: Thu, 2 Jan 2020 14:50:53 -0500 Subject: [PATCH 2/8] Windows change to add uri change callback --- src/WebWindow.Native/WebWindow.Windows.cpp | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/src/WebWindow.Native/WebWindow.Windows.cpp b/src/WebWindow.Native/WebWindow.Windows.cpp index f56db8c..00ae19e 100644 --- a/src/WebWindow.Native/WebWindow.Windows.cpp +++ b/src/WebWindow.Native/WebWindow.Windows.cpp @@ -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 + _webviewWindow->add_NavigationStarting(Callback( + [](IWebView2WebView* webview, IWebView2NavigationStartingEventArgs * args) -> HRESULT { + PWSTR uri; + args->get_Uri(&uri); + _uriChangeCallback(uri); + CoTaskMemFree(uri); + 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); From 7a50d9d60d94ba4fb78d8d9cdf73dfa98ddccc8b Mon Sep 17 00:00:00 2001 From: Justin Date: Thu, 2 Jan 2020 16:08:55 -0500 Subject: [PATCH 3/8] Corrections for Windows testing --- src/WebWindow.Native/WebWindow.Windows.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/WebWindow.Native/WebWindow.Windows.cpp b/src/WebWindow.Native/WebWindow.Windows.cpp index 00ae19e..8e01b2b 100644 --- a/src/WebWindow.Native/WebWindow.Windows.cpp +++ b/src/WebWindow.Native/WebWindow.Windows.cpp @@ -226,15 +226,15 @@ void WebWindow::AttachWebView() Settings->put_AreDefaultScriptDialogsEnabled(TRUE); Settings->put_IsWebMessageEnabled(TRUE); // Add a navigation change event handler + /* EventRegistrationToken token; _webviewWindow->add_NavigationStarting(Callback( - [](IWebView2WebView* webview, IWebView2NavigationStartingEventArgs * args) -> HRESULT { + [this](IWebView2WebView* webview, IWebView2NavigationStartingEventArgs * args) -> HRESULT { PWSTR uri; args->get_Uri(&uri); _uriChangeCallback(uri); CoTaskMemFree(uri); return S_OK; - } - ).Get(), &token); + }).Get(), &token);*/ // Register interop APIs From 822800e5be3c7b423532d803f7125d798f94b569 Mon Sep 17 00:00:00 2001 From: Justin Date: Thu, 2 Jan 2020 16:26:38 -0500 Subject: [PATCH 4/8] Updated windows and testasset --- src/WebWindow.Native/WebWindow.Windows.cpp | 4 ++-- testassets/HelloWorldApp/Program.cs | 5 ++++- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/src/WebWindow.Native/WebWindow.Windows.cpp b/src/WebWindow.Native/WebWindow.Windows.cpp index 8e01b2b..7a55286 100644 --- a/src/WebWindow.Native/WebWindow.Windows.cpp +++ b/src/WebWindow.Native/WebWindow.Windows.cpp @@ -226,7 +226,7 @@ void WebWindow::AttachWebView() Settings->put_AreDefaultScriptDialogsEnabled(TRUE); Settings->put_IsWebMessageEnabled(TRUE); // Add a navigation change event handler - /* EventRegistrationToken token; + EventRegistrationToken token; _webviewWindow->add_NavigationStarting(Callback( [this](IWebView2WebView* webview, IWebView2NavigationStartingEventArgs * args) -> HRESULT { PWSTR uri; @@ -234,7 +234,7 @@ void WebWindow::AttachWebView() _uriChangeCallback(uri); CoTaskMemFree(uri); return S_OK; - }).Get(), &token);*/ + }).Get(), &token); // Register interop APIs diff --git a/testassets/HelloWorldApp/Program.cs b/testassets/HelloWorldApp/Program.cs index c5fbf29..1baeb9e 100644 --- a/testassets/HelloWorldApp/Program.cs +++ b/testassets/HelloWorldApp/Program.cs @@ -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(); } From 0f79179f11e2b2585f5ad843f2ab3b74b0e0acd4 Mon Sep 17 00:00:00 2001 From: Justin Ashworth Date: Thu, 2 Jan 2020 17:02:23 -0500 Subject: [PATCH 5/8] fixed issue where update was coming before uri changed --- src/WebWindow.Native/WebWindow.Linux.cpp | 2 +- testassets/HelloWorldApp/Program.cs | 3 ++- testassets/HelloWorldApp/wwwroot/index.html | 4 ++++ 3 files changed, 7 insertions(+), 2 deletions(-) diff --git a/src/WebWindow.Native/WebWindow.Linux.cpp b/src/WebWindow.Native/WebWindow.Linux.cpp index 845ccca..217bbdf 100644 --- a/src/WebWindow.Native/WebWindow.Linux.cpp +++ b/src/WebWindow.Native/WebWindow.Linux.cpp @@ -80,7 +80,7 @@ void HandleUriChange(GObject* object, WebKitLoadEvent event, gpointer user_data) const gchar *uri; - if (event == WEBKIT_LOAD_STARTED) { + if (event == WEBKIT_LOAD_FINISHED) { web_view = WEBKIT_WEB_VIEW(object); uri = webkit_web_view_get_uri(web_view); diff --git a/testassets/HelloWorldApp/Program.cs b/testassets/HelloWorldApp/Program.cs index 1baeb9e..f42b7db 100644 --- a/testassets/HelloWorldApp/Program.cs +++ b/testassets/HelloWorldApp/Program.cs @@ -26,7 +26,8 @@ static void Main(string[] args) { Console.WriteLine($"New URI: {uri}"); }; - window.NavigateToLocalFile("wwwroot/index.html"); + //window.NavigateToLocalFile("wwwroot/index.html"); + window.NavigateToUrl("https://oauth.dev.valididcloud.com/connect/authorize?response_type=code&nonce=zZYFw7ZYTj5xZkqON95gnA&state=-nQotCEKDeCyw5OCFBdDUw&code_challenge=xarZMRurKMtd4vW3a0meG4PKmlGfzBO-UwmTIw_uYfw&code_challenge_method=S256&client_id=00175971-74a5-42af-9946-a21a6c09a93f&scope=https%3A%2F%2Fcap.dev.valididcloud.com%2F&redirect_uri=http%3A%2F%2Flocalhost%3A8080%2Fuser%2Fmobile"); window.WaitForExit(); } } diff --git a/testassets/HelloWorldApp/wwwroot/index.html b/testassets/HelloWorldApp/wwwroot/index.html index bda55ce..a7a0d7c 100644 --- a/testassets/HelloWorldApp/wwwroot/index.html +++ b/testassets/HelloWorldApp/wwwroot/index.html @@ -7,6 +7,10 @@

Hello

+ +

+ Link to Microsoft +

From 96f33d93f94c28ceed32cacc3b3550458d908ffb Mon Sep 17 00:00:00 2001 From: Justin Ashworth Date: Thu, 2 Jan 2020 17:02:57 -0500 Subject: [PATCH 6/8] wrong Navigate --- testassets/HelloWorldApp/Program.cs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/testassets/HelloWorldApp/Program.cs b/testassets/HelloWorldApp/Program.cs index f42b7db..1baeb9e 100644 --- a/testassets/HelloWorldApp/Program.cs +++ b/testassets/HelloWorldApp/Program.cs @@ -26,8 +26,7 @@ static void Main(string[] args) { Console.WriteLine($"New URI: {uri}"); }; - //window.NavigateToLocalFile("wwwroot/index.html"); - window.NavigateToUrl("https://oauth.dev.valididcloud.com/connect/authorize?response_type=code&nonce=zZYFw7ZYTj5xZkqON95gnA&state=-nQotCEKDeCyw5OCFBdDUw&code_challenge=xarZMRurKMtd4vW3a0meG4PKmlGfzBO-UwmTIw_uYfw&code_challenge_method=S256&client_id=00175971-74a5-42af-9946-a21a6c09a93f&scope=https%3A%2F%2Fcap.dev.valididcloud.com%2F&redirect_uri=http%3A%2F%2Flocalhost%3A8080%2Fuser%2Fmobile"); + window.NavigateToLocalFile("wwwroot/index.html"); window.WaitForExit(); } } From ef0e6e33cfe178e807b385c606d30d9cf6610782 Mon Sep 17 00:00:00 2001 From: Justin Ashworth Date: Thu, 2 Jan 2020 14:37:01 -0500 Subject: [PATCH 7/8] Added EventHandler for UriChanging Update testassets/HelloWorldApp/wwwroot/index.html Co-Authored-By: Steve Sanderson Update src/WebWindow.Native/WebWindow.Mac.mm Co-Authored-By: Steve Sanderson Update src/WebWindow.Native/WebWindow.Mac.mm Co-Authored-By: Steve Sanderson Update src/WebWindow.Native/WebWindow.Mac.NavigationDelegate.mm Co-Authored-By: Steve Sanderson Fixes for formatting typo in mac nav delegate mac callback changes More changes to mac Learning Objective-C as we go! More string manip issues syntax More mac fun UTF not Utf mac stuff Mac More mac mac more mac Added EventHandler for UriChanging Deleted .idea --- .idea/.gitignore | 3 +++ src/WebWindow.Native/Exports.cpp | 5 ++++ src/WebWindow.Native/WebWindow.Linux.cpp | 16 ++++++++++++ .../WebWindow.Mac.NavigationDelegate.h | 13 ++++++++++ .../WebWindow.Mac.NavigationDelegate.mm | 26 +++++++++++++++++++ src/WebWindow.Native/WebWindow.Mac.mm | 11 ++++++-- src/WebWindow.Native/WebWindow.Native.vcxproj | 4 +++ src/WebWindow.Native/WebWindow.Windows.cpp | 14 +++++++++- src/WebWindow.Native/WebWindow.h | 4 +++ src/WebWindow/WebWindow.cs | 11 +++++++- src/WebWindow/WebWindow.csproj | 2 +- testassets/HelloWorldApp/Program.cs | 5 +++- testassets/HelloWorldApp/wwwroot/index.html | 4 +++ 13 files changed, 112 insertions(+), 6 deletions(-) create mode 100644 .idea/.gitignore create mode 100644 src/WebWindow.Native/WebWindow.Mac.NavigationDelegate.h create mode 100644 src/WebWindow.Native/WebWindow.Mac.NavigationDelegate.mm diff --git a/.idea/.gitignore b/.idea/.gitignore new file mode 100644 index 0000000..c0cef7a --- /dev/null +++ b/.idea/.gitignore @@ -0,0 +1,3 @@ + +# Default ignored files +/.idea.WebWindow.Dev/.idea/workspace.xml \ No newline at end of file diff --git a/src/WebWindow.Native/Exports.cpp b/src/WebWindow.Native/Exports.cpp index 1b62fbd..e517f13 100644 --- a/src/WebWindow.Native/Exports.cpp +++ b/src/WebWindow.Native/Exports.cpp @@ -134,4 +134,9 @@ extern "C" { instance->SetIconFile(filename); } + + EXPORTED void WebWindow_SetUriChangeCallback(WebWindow* instance, UriChangeCallback callback) + { + instance->SetUriChangeCallback(callback); + } } diff --git a/src/WebWindow.Native/WebWindow.Linux.cpp b/src/WebWindow.Native/WebWindow.Linux.cpp index 8ec24c1..900d9f7 100644 --- a/src/WebWindow.Native/WebWindow.Linux.cpp +++ b/src/WebWindow.Native/WebWindow.Linux.cpp @@ -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) @@ -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"); } diff --git a/src/WebWindow.Native/WebWindow.Mac.NavigationDelegate.h b/src/WebWindow.Native/WebWindow.Mac.NavigationDelegate.h new file mode 100644 index 0000000..046c29e --- /dev/null +++ b/src/WebWindow.Native/WebWindow.Mac.NavigationDelegate.h @@ -0,0 +1,13 @@ +#import +#import +#include "WebWindow.h" + +typedef void (*UriChangedCallback) (char* message); + +@interface MyNavigationDelegate : NSObject { + @public + NSWindow * window; + WebWindow * webWindow; + UriChangedCallback uriChangedCallback; +} +@end \ No newline at end of file diff --git a/src/WebWindow.Native/WebWindow.Mac.NavigationDelegate.mm b/src/WebWindow.Native/WebWindow.Mac.NavigationDelegate.mm new file mode 100644 index 0000000..1498d99 --- /dev/null +++ b/src/WebWindow.Native/WebWindow.Mac.NavigationDelegate.mm @@ -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 diff --git a/src/WebWindow.Native/WebWindow.Mac.mm b/src/WebWindow.Native/WebWindow.Mac.mm index cdee0bf..0e20bc0 100644 --- a/src/WebWindow.Native/WebWindow.Mac.mm +++ b/src/WebWindow.Native/WebWindow.Mac.mm @@ -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 #include #import @@ -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); });" @@ -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]; diff --git a/src/WebWindow.Native/WebWindow.Native.vcxproj b/src/WebWindow.Native/WebWindow.Native.vcxproj index 3c5ef82..c9ccff4 100644 --- a/src/WebWindow.Native/WebWindow.Native.vcxproj +++ b/src/WebWindow.Native/WebWindow.Native.vcxproj @@ -153,10 +153,14 @@ + + + + diff --git a/src/WebWindow.Native/WebWindow.Windows.cpp b/src/WebWindow.Native/WebWindow.Windows.cpp index f56db8c..c1192bf 100644 --- a/src/WebWindow.Native/WebWindow.Windows.cpp +++ b/src/WebWindow.Native/WebWindow.Windows.cpp @@ -225,7 +225,19 @@ 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( + [this](IWebView2WebView* webview, IWebView2NavigationStartingEventArgs * args) -> HRESULT + { + PWSTR uri; + args->get_Uri(&uri); + _uriChangeCallback(uri); + CoTaskMemFree(uri); + 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); diff --git a/src/WebWindow.Native/WebWindow.h b/src/WebWindow.Native/WebWindow.h index f5cf4f7..3fe4669 100644 --- a/src/WebWindow.Native/WebWindow.h +++ b/src/WebWindow.Native/WebWindow.h @@ -31,6 +31,7 @@ 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 { @@ -38,6 +39,7 @@ class WebWindow WebMessageReceivedCallback _webMessageReceivedCallback; MovedCallback _movedCallback; ResizedCallback _resizedCallback; + UriChangeCallback _uriChangeCallback; #ifdef _WIN32 static HINSTANCE _hInstance; HWND _hWnd; @@ -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); }; diff --git a/src/WebWindow/WebWindow.cs b/src/WebWindow/WebWindow.cs index 49e3b5a..fa62061 100644 --- a/src/WebWindow/WebWindow.cs +++ b/src/WebWindow/WebWindow.cs @@ -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(); @@ -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 _gcHandlesToFree = new List(); private readonly List _hGlobalToFree = new List(); @@ -145,6 +146,10 @@ public WebWindow(string title, Action 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(); @@ -237,6 +242,10 @@ public void SendMessage(string message) } public event EventHandler OnWebMessageReceived; + + private void UriChanged(string uri) => OnUriChange?.Invoke(this, uri); + + public event EventHandler OnUriChange; private void WriteTitleField(string value) { diff --git a/src/WebWindow/WebWindow.csproj b/src/WebWindow/WebWindow.csproj index f2a56da..dfffaaf 100644 --- a/src/WebWindow/WebWindow.csproj +++ b/src/WebWindow/WebWindow.csproj @@ -20,7 +20,7 @@ + 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" /> diff --git a/testassets/HelloWorldApp/Program.cs b/testassets/HelloWorldApp/Program.cs index c5fbf29..1baeb9e 100644 --- a/testassets/HelloWorldApp/Program.cs +++ b/testassets/HelloWorldApp/Program.cs @@ -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(); } diff --git a/testassets/HelloWorldApp/wwwroot/index.html b/testassets/HelloWorldApp/wwwroot/index.html index bda55ce..e37c78e 100644 --- a/testassets/HelloWorldApp/wwwroot/index.html +++ b/testassets/HelloWorldApp/wwwroot/index.html @@ -7,6 +7,10 @@

Hello

+ +

+ Link to example.com +

From 9a2c452e8438ebdc651d4db6ce11f4fabd8ed038 Mon Sep 17 00:00:00 2001 From: Justin Date: Fri, 10 Jan 2020 13:17:30 -0500 Subject: [PATCH 8/8] Changed to unique_cotaskmem_string instead of PWSTR --- src/WebWindow.Native/WebWindow.Windows.cpp | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/WebWindow.Native/WebWindow.Windows.cpp b/src/WebWindow.Native/WebWindow.Windows.cpp index c1192bf..2980038 100644 --- a/src/WebWindow.Native/WebWindow.Windows.cpp +++ b/src/WebWindow.Native/WebWindow.Windows.cpp @@ -230,10 +230,9 @@ void WebWindow::AttachWebView() _webviewWindow->add_NavigationStarting(Callback( [this](IWebView2WebView* webview, IWebView2NavigationStartingEventArgs * args) -> HRESULT { - PWSTR uri; + wil::unique_cotaskmem_string uri; args->get_Uri(&uri); - _uriChangeCallback(uri); - CoTaskMemFree(uri); + _uriChangeCallback(uri.get()); return S_OK; } ).Get(), &token);