[Peek] add WV2 improvements (behavior and UX) (#22685)

* [Peek] added logic to get max monitor size for opening WebView2

* Removed ununsed dependency property

* Added workaround for cases where the web page would not finish navigating in a quick timing, for example google.com.

* Remove window extensions from common and use nullable size argument instead

Co-authored-by: Samuel Chapleau <sachaple@microsoft.com>
This commit is contained in:
Robson 2022-12-13 21:37:17 -08:00 committed by GitHub
parent 1253ed6607
commit c22e78870b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
10 changed files with 66 additions and 30 deletions

View File

@ -10,7 +10,7 @@ namespace Peek.FilePreviewer.Controls
using Microsoft.Web.WebView2.Core;
using Windows.System;
public sealed partial class BrowserControl : UserControl
public sealed partial class BrowserControl : UserControl, IDisposable
{
/// <summary>
/// Helper private Uri where we cache the last navigated page
@ -21,37 +21,37 @@ namespace Peek.FilePreviewer.Controls
public delegate void NavigationCompletedHandler(WebView2? sender, CoreWebView2NavigationCompletedEventArgs? args);
public delegate void DOMContentLoadedHandler(CoreWebView2? sender, CoreWebView2DOMContentLoadedEventArgs? args);
public event NavigationCompletedHandler? NavigationCompleted;
public event DOMContentLoadedHandler? DOMContentLoaded;
public static readonly DependencyProperty SourceProperty = DependencyProperty.Register(
nameof(Source),
typeof(Uri),
typeof(BrowserControl),
new PropertyMetadata(null, new PropertyChangedCallback((d, e) => ((BrowserControl)d).SourcePropertyChanged())));
public static readonly DependencyProperty IsNavigationCompletedProperty = DependencyProperty.Register(
nameof(IsNavigationCompleted),
typeof(bool),
typeof(BrowserControl),
new PropertyMetadata(false));
public Uri? Source
{
get { return (Uri)GetValue(SourceProperty); }
set { SetValue(SourceProperty, value); }
}
public bool IsNavigationCompleted
{
get { return (bool)GetValue(IsNavigationCompletedProperty); }
set { SetValue(IsNavigationCompletedProperty, value); }
}
public BrowserControl()
{
this.InitializeComponent();
}
public void Dispose()
{
if (PreviewBrowser.CoreWebView2 != null)
{
PreviewBrowser.CoreWebView2.DOMContentLoaded -= CoreWebView2_DOMContentLoaded;
}
}
/// <summary>
/// Navigate to the to the <see cref="Uri"/> set in <see cref="Source"/>.
/// Calling <see cref="Navigate"/> will always trigger a navigation/refresh
@ -59,7 +59,8 @@ namespace Peek.FilePreviewer.Controls
/// </summary>
public void Navigate()
{
IsNavigationCompleted = false;
var value = Environment.GetEnvironmentVariable("WEBVIEW2_ADDITIONAL_BROWSER_ARGUMENTS");
_navigatedUri = null;
if (Source != null)
@ -89,6 +90,8 @@ namespace Peek.FilePreviewer.Controls
PreviewBrowser.CoreWebView2.Settings.IsPasswordAutosaveEnabled = false;
PreviewBrowser.CoreWebView2.Settings.IsScriptEnabled = false;
PreviewBrowser.CoreWebView2.Settings.IsWebMessageEnabled = false;
PreviewBrowser.CoreWebView2.DOMContentLoaded += CoreWebView2_DOMContentLoaded;
}
catch
{
@ -96,6 +99,11 @@ namespace Peek.FilePreviewer.Controls
}
}
private void CoreWebView2_DOMContentLoaded(CoreWebView2 sender, CoreWebView2DOMContentLoadedEventArgs args)
{
DOMContentLoaded?.Invoke(sender, args);
}
private async void PreviewBrowser_NavigationStarting(WebView2 sender, Microsoft.Web.WebView2.Core.CoreWebView2NavigationStartingEventArgs args)
{
if (_navigatedUri == null)
@ -115,8 +123,6 @@ namespace Peek.FilePreviewer.Controls
{
if (args.IsSuccess)
{
IsNavigationCompleted = true;
_navigatedUri = Source;
}

View File

@ -28,6 +28,7 @@
x:Name="BrowserPreview"
x:Load="True"
NavigationCompleted="PreviewBrowser_NavigationCompleted"
DOMContentLoaded="BrowserPreview_DOMContentLoaded"
Source="{x:Bind BrowserPreviewer.Preview, Mode=OneWay}"
Visibility="{x:Bind IsPreviewVisible(BrowserPreviewer, Previewer.State), Mode=OneWay, FallbackValue=Collapsed}" />

View File

@ -153,15 +153,43 @@ namespace Peek.FilePreviewer
}
}
private void PreviewBrowser_NavigationCompleted(WebView2 sender, CoreWebView2NavigationCompletedEventArgs args)
private void BrowserPreview_DOMContentLoaded(Microsoft.Web.WebView2.Core.CoreWebView2 sender, Microsoft.Web.WebView2.Core.CoreWebView2DOMContentLoadedEventArgs args)
{
// Once browser has completed navigation it is ready to be visible
/*
* There is an odd behavior where the WebView2 would not raise the NavigationCompleted event
* for certain HTML files, even though it has already been loaded. Probably related to certain
* extra module that require more time to load. One example is saving and opening google.com locally.
*
* So to address this, we will make the Browser visible and display it as "Loaded" as soon the HTML document
* has been parsed and loaded with the DOMContentLoaded event.
*
* Similar issue: https://github.com/MicrosoftEdge/WebView2Feedback/issues/998
*/
if (BrowserPreviewer != null)
{
BrowserPreviewer.State = PreviewState.Loaded;
}
}
private void PreviewBrowser_NavigationCompleted(WebView2 sender, CoreWebView2NavigationCompletedEventArgs args)
{
/*
* In theory most of navigation should work after DOM is loaded.
* But in case something fails we check NavigationCompleted event
* for failure and switch visibility accordingly.
*
* As an alternative, in the future, the preview Browser control
* could also display error content.
*/
if (!args.IsSuccess)
{
if (BrowserPreviewer != null)
{
BrowserPreviewer.State = PreviewState.Error;
}
}
}
private async void KeyboardAccelerator_CtrlC_Invoked(KeyboardAccelerator sender, KeyboardAcceleratorInvokedEventArgs args)
{
if (Previewer != null)

View File

@ -14,13 +14,13 @@ namespace Peek.FilePreviewer.Models
public class PreviewSizeChangedArgs
{
public PreviewSizeChangedArgs(Size windowSizeRequested, SizeFormat sizeFormat = SizeFormat.Pixels)
public PreviewSizeChangedArgs(Size? windowSizeRequested, SizeFormat sizeFormat = SizeFormat.Pixels)
{
WindowSizeRequested = windowSizeRequested;
WindowSizeFormat = sizeFormat;
}
public Size WindowSizeRequested { get; init; }
public Size? WindowSizeRequested { get; init; }
public SizeFormat WindowSizeFormat { get; init; }
}

View File

@ -16,7 +16,7 @@ namespace Peek.FilePreviewer.Previewers
public static bool IsFileTypeSupported(string fileExt) => throw new NotImplementedException();
public Task<Size> GetPreviewSizeAsync(CancellationToken cancellationToken);
public Task<Size?> GetPreviewSizeAsync(CancellationToken cancellationToken);
Task LoadPreviewAsync(CancellationToken cancellationToken);

View File

@ -57,7 +57,7 @@ namespace Peek.FilePreviewer.Previewers
GC.SuppressFinalize(this);
}
public async Task<Size> GetPreviewSizeAsync(CancellationToken cancellationToken)
public async Task<Size?> GetPreviewSizeAsync(CancellationToken cancellationToken)
{
cancellationToken.ThrowIfCancellationRequested();
var propertyImageSize = await PropertyHelper.GetImageSize(File.Path);

View File

@ -56,7 +56,7 @@ namespace Peek.FilePreviewer.Previewers
GC.SuppressFinalize(this);
}
public async Task<Size> GetPreviewSizeAsync(CancellationToken cancellationToken)
public async Task<Size?> GetPreviewSizeAsync(CancellationToken cancellationToken)
{
var propertyImageSize = await PropertyHelper.GetImageSize(File.Path);
if (propertyImageSize != Size.Empty)

View File

@ -80,11 +80,12 @@ namespace Peek.FilePreviewer.Previewers
GC.SuppressFinalize(this);
}
public Task<Size> GetPreviewSizeAsync(CancellationToken cancellationToken)
public Task<Size?> GetPreviewSizeAsync(CancellationToken cancellationToken)
{
return Task.Run(() =>
{
return new Size(UnsupportedFileWidthPercent, UnsupportedFileHeightPercent);
Size? size = new Size(UnsupportedFileWidthPercent, UnsupportedFileHeightPercent);
return size;
});
}

View File

@ -45,10 +45,9 @@ namespace Peek.FilePreviewer.Previewers
private DispatcherQueue Dispatcher { get; }
public Task<Size> GetPreviewSizeAsync(CancellationToken cancellationToken)
public Task<Size?> GetPreviewSizeAsync(CancellationToken cancellationToken)
{
// TODO: define how to proper window size on HTML content.
var size = new Size(1280, 720);
Size? size = null;
return Task.FromResult(size);
}

View File

@ -94,10 +94,11 @@ namespace Peek.UI
/// <param name="e">PreviewSizeChangedArgs</param>
private void FilePreviewer_PreviewSizeChanged(object sender, PreviewSizeChangedArgs e)
{
// TODO: Use design-defined rules for adjusted window size
var requestedSize = e.WindowSizeRequested;
var monitorSize = this.GetMonitorSize();
// If no size is requested, try to fit to the monitor size.
Size requestedSize = e.WindowSizeRequested ?? monitorSize;
var titleBarHeight = TitleBarControl.ActualHeight;
var maxContentSize = new Size(0, 0);