diff --git a/samples/AvaloniaVncClient/App.xaml b/samples/AvaloniaVncClient/App.xaml index 78b40ff..ebcf4ed 100644 --- a/samples/AvaloniaVncClient/App.xaml +++ b/samples/AvaloniaVncClient/App.xaml @@ -2,12 +2,12 @@ xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:local="clr-namespace:AvaloniaVncClient" x:Class="AvaloniaVncClient.App"> + - - + diff --git a/samples/AvaloniaVncClient/AvaloniaVncClient.csproj b/samples/AvaloniaVncClient/AvaloniaVncClient.csproj index 36a77e2..e51145b 100644 --- a/samples/AvaloniaVncClient/AvaloniaVncClient.csproj +++ b/samples/AvaloniaVncClient/AvaloniaVncClient.csproj @@ -1,7 +1,7 @@  WinExe - netcoreapp3.1 + net6.0 enable @@ -16,10 +16,10 @@ - - - - + + + + diff --git a/samples/AvaloniaVncClient/ViewLocator.cs b/samples/AvaloniaVncClient/ViewLocator.cs index 7fa8017..f62583a 100644 --- a/samples/AvaloniaVncClient/ViewLocator.cs +++ b/samples/AvaloniaVncClient/ViewLocator.cs @@ -9,7 +9,7 @@ public class ViewLocator : IDataTemplate { public bool SupportsRecycling => false; - public IControl Build(object data) + public Control Build(object data) { var viewName = data.GetType().FullName?.Replace("ViewModel", "View"); if (viewName == null) diff --git a/samples/AvaloniaVncClient/Views/MainWindow.xaml b/samples/AvaloniaVncClient/Views/MainWindow.xaml index 55a7727..208af56 100644 --- a/samples/AvaloniaVncClient/Views/MainWindow.xaml +++ b/samples/AvaloniaVncClient/Views/MainWindow.xaml @@ -50,7 +50,7 @@ IsVisible="{Binding RfbConnection, Converter={x:Static ObjectConverters.IsNotNull}}"> - + @@ -58,7 +58,7 @@ - + diff --git a/src/MarcusW.VncClient.Avalonia/Adapters/Logging/AvaloniaLogger.cs b/src/MarcusW.VncClient.Avalonia/Adapters/Logging/AvaloniaLogger.cs index 2f7ce4e..fe2c825 100644 --- a/src/MarcusW.VncClient.Avalonia/Adapters/Logging/AvaloniaLogger.cs +++ b/src/MarcusW.VncClient.Avalonia/Adapters/Logging/AvaloniaLogger.cs @@ -1,7 +1,7 @@ using System; using System.ComponentModel; +using System.Diagnostics.CodeAnalysis; using Avalonia.Logging; -using JetBrains.Annotations; using Microsoft.Extensions.Logging; namespace MarcusW.VncClient.Avalonia.Adapters.Logging diff --git a/src/MarcusW.VncClient.Avalonia/Clipboard.cs b/src/MarcusW.VncClient.Avalonia/Clipboard.cs new file mode 100644 index 0000000..fb35553 --- /dev/null +++ b/src/MarcusW.VncClient.Avalonia/Clipboard.cs @@ -0,0 +1,30 @@ +using Avalonia; +using Avalonia.Controls; +using Avalonia.Controls.ApplicationLifetimes; +using Avalonia.Input.Platform; +using Avalonia.VisualTree; + +namespace MarcusW.VncClient.Avalonia; + +public static class Clipboard +{ + public static IClipboard Get() + { + //Desktop + if (Application.Current?.ApplicationLifetime is IClassicDesktopStyleApplicationLifetime { MainWindow: { } window }) + { + return window.Clipboard!; + } + //Android (and iOS?) + else if (Application.Current?.ApplicationLifetime is ISingleViewApplicationLifetime { MainView: { } mainView }) + { + var visualRoot = mainView.GetVisualRoot(); + if (visualRoot is TopLevel topLevel) + { + return topLevel.Clipboard!; + } + } + + return null!; + } +} diff --git a/src/MarcusW.VncClient.Avalonia/Conversions.cs b/src/MarcusW.VncClient.Avalonia/Conversions.cs index 91e56ce..91ecb10 100644 --- a/src/MarcusW.VncClient.Avalonia/Conversions.cs +++ b/src/MarcusW.VncClient.Avalonia/Conversions.cs @@ -1,3 +1,4 @@ +using System; using System.ComponentModel; using Avalonia; @@ -28,20 +29,17 @@ public static class Conversions /// Value to convert. /// The conversion result. public static PixelFormat GetPixelFormat(global::Avalonia.Platform.PixelFormat avaloniaPixelFormat) - => avaloniaPixelFormat switch { - // TODO: Actually, the Avalonia PixelFormat is generic and doesn't always refer to Skia. But as long as the pixel representation is identical with Direct2D and others, they can just be renamed. - - // Packed format, component order refers to order in native type (BE): 0xRGB - global::Avalonia.Platform.PixelFormat.Rgb565 => new PixelFormat("Skia kRGB_565_SkColorType", 16, 16, false, true, false, 31, 63, 31, 0, 11, 5, 0, 0), - - // Array format, component order refers to order in memory (LE): ...RGBA... => 0xABGR - global::Avalonia.Platform.PixelFormat.Rgba8888 => new PixelFormat("Skia kRGBA_8888_SkColorType", 32, 32, false, true, true, 0xFF, 0xFF, 0xFF, 0xFF, 0, 8, 16, 24), - - // Array format, component order refers to order in memory (LE): ...BGRA... => 0xARGB - global::Avalonia.Platform.PixelFormat.Bgra8888 => new PixelFormat("Skia kBGRA_8888_SkColorType", 32, 32, false, true, true, 0xFF, 0xFF, 0xFF, 0xFF, 16, 8, 0, 24), - - _ => throw new InvalidEnumArgumentException(nameof(avaloniaPixelFormat), (int)avaloniaPixelFormat, typeof(global::Avalonia.Platform.PixelFormat)) - }; + { + // TODO: Actually, the Avalonia PixelFormat is generic and doesn't always refer to Skia. But as long as the pixel representation is identical with Direct2D and others, they can just be renamed. + if(avaloniaPixelFormat.Equals(global::Avalonia.Platform.PixelFormat.Rgb565)) + return new PixelFormat("Skia kRGB_565_SkColorType", 16, 16, false, true, false, 31, 63, 31, 0, 11, 5, 0, 0); + else if(avaloniaPixelFormat.Equals(global::Avalonia.Platform.PixelFormat.Rgba8888)) + return new PixelFormat("Skia kRGBA_8888_SkColorType", 32, 32, false, true, true, 0xFF, 0xFF, 0xFF, 0xFF, 0, 8, 16, 24); + else if(avaloniaPixelFormat.Equals(global::Avalonia.Platform.PixelFormat.Bgra8888)) + return new PixelFormat("Skia kBGRA_8888_SkColorType", 32, 32, false, true, true, 0xFF, 0xFF, 0xFF, 0xFF, 16, 8, 0, 24); + else + throw new ArgumentException(avaloniaPixelFormat.ToString(), nameof(avaloniaPixelFormat)); + } /// /// Converts a Avalonia to a . diff --git a/src/MarcusW.VncClient.Avalonia/MarcusW.VncClient.Avalonia.csproj b/src/MarcusW.VncClient.Avalonia/MarcusW.VncClient.Avalonia.csproj index 53e2440..db95223 100644 --- a/src/MarcusW.VncClient.Avalonia/MarcusW.VncClient.Avalonia.csproj +++ b/src/MarcusW.VncClient.Avalonia/MarcusW.VncClient.Avalonia.csproj @@ -1,9 +1,17 @@ + + net6.0 + + - - - + + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + + + diff --git a/src/MarcusW.VncClient.Avalonia/RfbRenderTarget.cs b/src/MarcusW.VncClient.Avalonia/RfbRenderTarget.cs index 9a19663..05102e6 100644 --- a/src/MarcusW.VncClient.Avalonia/RfbRenderTarget.cs +++ b/src/MarcusW.VncClient.Avalonia/RfbRenderTarget.cs @@ -99,7 +99,7 @@ public override void Render(DrawingContext context) // Has any bitmap been rendered yet? if (!bitmapSize.HasValue) - return global::Avalonia.Size.Empty; + return default; // Request the size of the current bitmap return bitmapSize.Value; diff --git a/src/MarcusW.VncClient.Avalonia/VncView.cs b/src/MarcusW.VncClient.Avalonia/VncView.cs index 3bd5fb9..857ea7b 100644 --- a/src/MarcusW.VncClient.Avalonia/VncView.cs +++ b/src/MarcusW.VncClient.Avalonia/VncView.cs @@ -93,7 +93,7 @@ public virtual void HandleServerClipboardUpdate(string text) { Dispatcher.UIThread.Post(async () => { // Copy the text to the local clipboard - await Application.Current.Clipboard.SetTextAsync(text).ConfigureAwait(true); + await Clipboard.Get().SetTextAsync(text).ConfigureAwait(true); }); } } diff --git a/src/MarcusW.VncClient/MarcusW.VncClient.csproj b/src/MarcusW.VncClient/MarcusW.VncClient.csproj index 1298acd..f34fc3f 100644 --- a/src/MarcusW.VncClient/MarcusW.VncClient.csproj +++ b/src/MarcusW.VncClient/MarcusW.VncClient.csproj @@ -2,6 +2,7 @@ true + net6.0 diff --git a/tests/MarcusW.VncClient.Tests/MarcusW.VncClient.Tests.csproj b/tests/MarcusW.VncClient.Tests/MarcusW.VncClient.Tests.csproj index bfe0e3e..76e061d 100644 --- a/tests/MarcusW.VncClient.Tests/MarcusW.VncClient.Tests.csproj +++ b/tests/MarcusW.VncClient.Tests/MarcusW.VncClient.Tests.csproj @@ -1,7 +1,7 @@ - netcoreapp3.1 + net6.0 enable false