diff --git a/src/modules/peek/Peek.FilePreviewer/Controls/BrowserControl.xaml b/src/modules/peek/Peek.FilePreviewer/Controls/BrowserControl.xaml
index f462aeaef6..1ddfee1c6f 100644
--- a/src/modules/peek/Peek.FilePreviewer/Controls/BrowserControl.xaml
+++ b/src/modules/peek/Peek.FilePreviewer/Controls/BrowserControl.xaml
@@ -12,9 +12,15 @@
mc:Ignorable="d">
-
+
+
diff --git a/src/modules/peek/Peek.FilePreviewer/Controls/BrowserControl.xaml.cs b/src/modules/peek/Peek.FilePreviewer/Controls/BrowserControl.xaml.cs
index 5030f2f69f..39f94af55e 100644
--- a/src/modules/peek/Peek.FilePreviewer/Controls/BrowserControl.xaml.cs
+++ b/src/modules/peek/Peek.FilePreviewer/Controls/BrowserControl.xaml.cs
@@ -3,11 +3,13 @@
// See the LICENSE file in the project root for more information.
using System;
+using System.Threading.Tasks;
using Microsoft.UI.Xaml;
using Microsoft.UI.Xaml.Controls;
using Microsoft.Web.WebView2.Core;
using Peek.Common.Constants;
using Peek.Common.Helpers;
+using Windows.ApplicationModel.DataTransfer;
using Windows.System;
using Windows.UI;
@@ -96,6 +98,7 @@ namespace Peek.FilePreviewer.Controls
private void SourcePropertyChanged()
{
+ OpenUriDialog.Hide();
Navigate();
}
@@ -135,6 +138,7 @@ namespace Peek.FilePreviewer.Controls
}
PreviewBrowser.CoreWebView2.DOMContentLoaded += CoreWebView2_DOMContentLoaded;
+ PreviewBrowser.CoreWebView2.NewWindowRequested += CoreWebView2_NewWindowRequested;
}
catch (Exception ex)
{
@@ -149,6 +153,16 @@ namespace Peek.FilePreviewer.Controls
DOMContentLoaded?.Invoke(sender, args);
}
+ private async void CoreWebView2_NewWindowRequested(CoreWebView2 sender, CoreWebView2NewWindowRequestedEventArgs args)
+ {
+ // Monaco opens URI in a new window. We open the URI in the default web browser.
+ if (args.Uri != null && args.IsUserInitiated)
+ {
+ args.Handled = true;
+ await ShowOpenUriDialogAsync(new Uri(args.Uri));
+ }
+ }
+
private async void PreviewBrowser_NavigationStarting(WebView2 sender, Microsoft.Web.WebView2.Core.CoreWebView2NavigationStartingEventArgs args)
{
if (_navigatedUri == null)
@@ -157,10 +171,11 @@ namespace Peek.FilePreviewer.Controls
}
// In case user starts or tries to navigate from within the HTML file we launch default web browser for navigation.
- if (args.Uri != null && args.Uri != _navigatedUri?.ToString() && args.IsUserInitiated)
+ // TODO: && args.IsUserInitiated - always false for PDF files, revert the workaround when fixed in WebView2: https://github.com/microsoft/PowerToys/issues/27403
+ if (args.Uri != null && args.Uri != _navigatedUri?.ToString())
{
args.Cancel = true;
- await Launcher.LaunchUriAsync(new Uri(args.Uri));
+ await ShowOpenUriDialogAsync(new Uri(args.Uri));
}
}
@@ -171,7 +186,29 @@ namespace Peek.FilePreviewer.Controls
_navigatedUri = Source;
}
- NavigationCompleted?.Invoke(sender, args);
+ // Don't raise NavigationCompleted event if NavigationStarting has been cancelled
+ if (args.WebErrorStatus != CoreWebView2WebErrorStatus.OperationCanceled)
+ {
+ NavigationCompleted?.Invoke(sender, args);
+ }
+ }
+
+ private async Task ShowOpenUriDialogAsync(Uri uri)
+ {
+ OpenUriDialog.Content = uri.ToString();
+ var result = await OpenUriDialog.ShowAsync();
+
+ if (result == ContentDialogResult.Primary)
+ {
+ await Launcher.LaunchUriAsync(uri);
+ }
+ }
+
+ private void OpenUriDialog_SecondaryButtonClick(ContentDialog sender, ContentDialogButtonClickEventArgs args)
+ {
+ var dataPackage = new DataPackage();
+ dataPackage.SetText(sender.Content.ToString());
+ Clipboard.SetContent(dataPackage);
}
}
}
diff --git a/src/modules/peek/Peek.UI/Strings/en-us/Resources.resw b/src/modules/peek/Peek.UI/Strings/en-us/Resources.resw
index 756be0a1b4..d8df22b84a 100644
--- a/src/modules/peek/Peek.UI/Strings/en-us/Resources.resw
+++ b/src/modules/peek/Peek.UI/Strings/en-us/Resources.resw
@@ -237,4 +237,20 @@
{0} bytes
Abbreviation for the size bytes
+
+ Cancel
+ Dialog showed when an URI is clicked. Button to close the dialog.
+
+
+ Open
+ Dialog showed when an URI is clicked. Button to open the URI.
+
+
+ Copy
+ Dialog showed when an URI is clicked. Button to copy the URI.
+
+
+ Do you want Peek to open the external application?
+ Title of the dialog showed when an URI is clicked,"Peek" is the name of the utility.
+
\ No newline at end of file
diff --git a/src/modules/previewpane/MonacoPreviewHandler/MonacoPreviewHandlerControl.cs b/src/modules/previewpane/MonacoPreviewHandler/MonacoPreviewHandlerControl.cs
index f137d67883..ca16bcc835 100644
--- a/src/modules/previewpane/MonacoPreviewHandler/MonacoPreviewHandlerControl.cs
+++ b/src/modules/previewpane/MonacoPreviewHandler/MonacoPreviewHandlerControl.cs
@@ -157,6 +157,7 @@ namespace Microsoft.PowerToys.PreviewHandler.Monaco
_webView.NavigationCompleted += WebView2Init;
_webView.Height = this.Height;
_webView.Width = this.Width;
+ _webView.CoreWebView2.NewWindowRequested += CoreWebView2_NewWindowRequested;
Controls.Add(_webView);
_webView.SendToBack();
_loadingBar.Value = 100;
@@ -218,6 +219,16 @@ namespace Microsoft.PowerToys.PreviewHandler.Monaco
}
}
+ private async void CoreWebView2_NewWindowRequested(object sender, CoreWebView2NewWindowRequestedEventArgs e)
+ {
+ // Monaco opens URI in a new window. We open the URI in the default web browser.
+ if (e.Uri != null && e.IsUserInitiated)
+ {
+ e.Handled = true;
+ await Launcher.LaunchUriAsync(new Uri(e.Uri));
+ }
+ }
+
///
/// This event sets the height and width of the webview to the size of the form
///