mirror of
https://github.com/microsoft/PowerToys.git
synced 2024-12-04 03:49:07 +08:00
[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:
parent
1253ed6607
commit
c22e78870b
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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}" />
|
||||
|
||||
|
@ -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)
|
||||
|
@ -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; }
|
||||
}
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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)
|
||||
|
@ -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;
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
|
Loading…
Reference in New Issue
Block a user