diff --git a/CefGlue.Avalonia/AvaloniaBrowserProcessHandler.cs b/CefGlue.Avalonia/AvaloniaBrowserProcessHandler.cs
index ec64113d..744fb349 100644
--- a/CefGlue.Avalonia/AvaloniaBrowserProcessHandler.cs
+++ b/CefGlue.Avalonia/AvaloniaBrowserProcessHandler.cs
@@ -1,6 +1,6 @@
-using System;
+using System;
using System.Reactive.Linq;
-using Avalonia.ReactiveUI;
+using ReactiveUI.Avalonia;
using Xilium.CefGlue.Common.Handlers;
namespace Xilium.CefGlue.Avalonia
diff --git a/CefGlue.Avalonia/CefGlue.Avalonia.csproj b/CefGlue.Avalonia/CefGlue.Avalonia.csproj
index 90db6b3b..50bfd5cc 100644
--- a/CefGlue.Avalonia/CefGlue.Avalonia.csproj
+++ b/CefGlue.Avalonia/CefGlue.Avalonia.csproj
@@ -20,8 +20,8 @@
-
-
+
+
diff --git a/CefGlue.Avalonia/InputExtensions.cs b/CefGlue.Avalonia/InputExtensions.cs
index 933af370..6bec569f 100644
--- a/CefGlue.Avalonia/InputExtensions.cs
+++ b/CefGlue.Avalonia/InputExtensions.cs
@@ -1,4 +1,4 @@
-using System.IO;
+using System.IO;
using Avalonia;
using Avalonia.Input;
using Avalonia.VisualTree;
@@ -200,21 +200,23 @@ public static CefDragData GetDragData(this DragEventArgs e)
{
var dragData = CefDragData.Create();
- // Files
- if (e.Data.Contains(DataFormats.FileNames))
+ // Avalonia 12 uses DataTransfer.TryGetFiles for asynchronous strongly-typed file extraction
+ var files = e.DataTransfer.TryGetFiles();
+ if (files != null)
{
- var files = (string[])e.Data.GetFileNames();
- foreach (var filePath in files)
+ foreach (var file in files)
{
- var displayName = Path.GetFileName(filePath);
+ var filePath = file.Path.LocalPath;
+ var displayName = file.Name;
dragData.AddFile(filePath.Replace("\\", "/"), displayName);
}
}
- // Text
- if (e.Data.Contains(DataFormats.Text))
+ // Avalonia 12 Using DataTransfer.TryGetText for Strongly-Typed Text Extraction
+ var text = e.DataTransfer.TryGetText();
+ if (!string.IsNullOrWhiteSpace(text))
{
- dragData.SetFragmentText(e.Data.GetText());
+ dragData.SetFragmentText(text);
}
return dragData;
diff --git a/CefGlue.Avalonia/Platform/AvaloniaControl.cs b/CefGlue.Avalonia/Platform/AvaloniaControl.cs
index 4ae258d8..e2f3b7b1 100644
--- a/CefGlue.Avalonia/Platform/AvaloniaControl.cs
+++ b/CefGlue.Avalonia/Platform/AvaloniaControl.cs
@@ -45,7 +45,7 @@ private void OnLayoutUpdated(object sender, EventArgs e)
SizeChanged?.Invoke(new CefSize((int)_control.Bounds.Width, (int)_control.Bounds.Height));
}
- private void OnGotFocus(object sender, GotFocusEventArgs e)
+ private void OnGotFocus(object sender, FocusChangedEventArgs e)
{
GotFocus?.Invoke();
}
@@ -128,7 +128,7 @@ public void OpenContextMenu(IEnumerable menuEntries, int x, int y, Ce
menu.PlacementAnchor = PopupAnchor.TopLeft;
menu.PlacementGravity = PopupGravity.BottomRight;
- menu.PlacementMode = PlacementMode.AnchorAndGravity;
+ menu.Placement = PlacementMode.AnchorAndGravity;
menu.PlacementRect = new Rect(x, y, 1, 1);
menu.Open(_control);
},
diff --git a/CefGlue.Avalonia/Platform/AvaloniaOffScreenControlHost.cs b/CefGlue.Avalonia/Platform/AvaloniaOffScreenControlHost.cs
index c2142a5b..346cc72a 100644
--- a/CefGlue.Avalonia/Platform/AvaloniaOffScreenControlHost.cs
+++ b/CefGlue.Avalonia/Platform/AvaloniaOffScreenControlHost.cs
@@ -1,4 +1,4 @@
-using System;
+using System;
using System.Threading.Tasks;
using Avalonia;
using Avalonia.Collections;
@@ -173,7 +173,7 @@ private void OnPointerMoved(object sender, PointerEventArgs e)
MouseMoved?.Invoke(e.AsCefMouseEvent(MousePositionReferential));
}
- private void OnLostFocus(object sender, RoutedEventArgs e)
+ private void OnLostFocus(object sender, FocusChangedEventArgs e)
{
LostFocus?.Invoke();
}
@@ -190,13 +190,16 @@ private void OnDetachedFromVisualTree(object sender, VisualTreeAttachmentEventAr
private void OnAttachedToVisualTree(object sender, VisualTreeAttachmentEventArgs e)
{
VisibilityChanged?.Invoke(true);
- if (e.Root is Window newWindow)
+ if (e.RootVisual is Window newWindow)
{
_windowStateChangedObservable = newWindow.GetPropertyChangedObservable(Window.WindowStateProperty).Subscribe(OnHostWindowStateChanged);
}
- if (e.Root.RenderScaling != RenderSurface.DeviceScaleFactor)
+
+ // In Avalonia 12, safely read the current window's scaling factor through TopLevel
+ var topLevel = TopLevel.GetTopLevel(_control);
+ if (topLevel != null && topLevel.RenderScaling != RenderSurface.DeviceScaleFactor)
{
- RenderSurface.DeviceScaleFactor = (float)e.Root.RenderScaling;
+ RenderSurface.DeviceScaleFactor = (float)topLevel.RenderScaling;
ScreenInfoChanged?.Invoke(RenderSurface.DeviceScaleFactor);
}
}
@@ -268,10 +271,19 @@ public async Task StartDrag(CefDragData dragData, CefDrag
var lastPointerEvent = this._lastPointerEvent; // story a copy, since this might be other thread
if (lastPointerEvent != null)
{
- var dataObject = new DataObject();
- dataObject.Set(DataFormats.Text, dragData.FragmentText);
+ // Replace the deprecated DataObject with the officially recommended DataTransfer
+ var dataObject = new DataTransfer();
+ if (!string.IsNullOrEmpty(dragData.FragmentText))
+ {
+ var item = new DataTransferItem();
+ item.SetText(dragData.FragmentText);
+ dataObject.Add(item);
+ }
+
+ // Use asynchronous DoDragDropAsync to trigger the OS's native drag-and-drop action
+ var result = await Dispatcher.UIThread.InvokeAsync(() =>
+ DragDrop.DoDragDropAsync(lastPointerEvent, dataObject, allowedOps.AsDragDropEffects()));
- var result = await Dispatcher.UIThread.InvokeAsync(() => DragDrop.DoDragDrop(lastPointerEvent, dataObject, allowedOps.AsDragDropEffects()));
this._lastPointerEvent = null;
_previousCursor = null;
_currentDragCursor = null;
diff --git a/CefGlue.Avalonia/Platform/AvaloniaPopup.cs b/CefGlue.Avalonia/Platform/AvaloniaPopup.cs
index 320c9fe5..331daa8b 100644
--- a/CefGlue.Avalonia/Platform/AvaloniaPopup.cs
+++ b/CefGlue.Avalonia/Platform/AvaloniaPopup.cs
@@ -45,7 +45,8 @@ public void Open()
{
Dispatcher.UIThread.Post(() =>
{
- _popup.Show(_popup.PlacementTarget.GetVisualRoot() as Window);
+ // Use TopLevel.GetTopLevel to dynamically get ownership of the current rendering root window
+ _popup.Show(TopLevel.GetTopLevel(_popup.PlacementTarget) as Window);
});
}
diff --git a/CefGlue.Avalonia/Platform/ExtendedAvaloniaPopup.cs b/CefGlue.Avalonia/Platform/ExtendedAvaloniaPopup.cs
index 6d5b73b6..047b2be5 100644
--- a/CefGlue.Avalonia/Platform/ExtendedAvaloniaPopup.cs
+++ b/CefGlue.Avalonia/Platform/ExtendedAvaloniaPopup.cs
@@ -15,7 +15,7 @@ internal class ExtendedAvaloniaPopup : Window
public ExtendedAvaloniaPopup()
{
CanResize = false;
- SystemDecorations = SystemDecorations.None;
+ WindowDecorations = WindowDecorations.None;
Focusable = false;
Topmost = true;
ShowActivated = false;
diff --git a/CefGlue.Demo.Avalonia/CefGlue.Demo.Avalonia.csproj b/CefGlue.Demo.Avalonia/CefGlue.Demo.Avalonia.csproj
index 96af4d77..404e32e6 100644
--- a/CefGlue.Demo.Avalonia/CefGlue.Demo.Avalonia.csproj
+++ b/CefGlue.Demo.Avalonia/CefGlue.Demo.Avalonia.csproj
@@ -31,8 +31,9 @@
+
+
-
diff --git a/CefGlue.Tests/Events/EventsTests.cs b/CefGlue.Tests/Events/EventsTests.cs
index adecbe6f..d01b87b2 100644
--- a/CefGlue.Tests/Events/EventsTests.cs
+++ b/CefGlue.Tests/Events/EventsTests.cs
@@ -50,7 +50,7 @@ void OnBrowserLoadError(object sender, LoadErrorEventArgs e)
taskCompletionSource.SetResult(true);
}
Browser.LoadError += OnBrowserLoadError;
- Browser.Address = "http://0.0.0.0"; // navigate to an invalid url
+ Browser.Address = "http://invalidurl"; // navigate to an invalid url
await taskCompletionSource.Task;
}
diff --git a/CefGlue.Tests/Javascript/JavascriptEvaluationTests.cs b/CefGlue.Tests/Javascript/JavascriptEvaluationTests.cs
index 6c52fb50..130b01d9 100644
--- a/CefGlue.Tests/Javascript/JavascriptEvaluationTests.cs
+++ b/CefGlue.Tests/Javascript/JavascriptEvaluationTests.cs
@@ -46,7 +46,8 @@ public async Task DateTimeReturn()
{
var expected = DateTime.Parse("2022-12-20T15:50:21.817Z");
var result = await EvaluateJavascript($"return new Date('{expected.ToString("o", CultureInfo.InvariantCulture)}');");
- Assert.AreEqual(expected, result);
+ // Align to UTC before comparison to eliminate local Ticks deviation
+ Assert.AreEqual(expected.ToUniversalTime(), result.ToUniversalTime());
}
[Test]
diff --git a/CefGlue.Tests/Javascript/NativeObjectInteropTests.cs b/CefGlue.Tests/Javascript/NativeObjectInteropTests.cs
index 2b8c5041..c582fa43 100644
--- a/CefGlue.Tests/Javascript/NativeObjectInteropTests.cs
+++ b/CefGlue.Tests/Javascript/NativeObjectInteropTests.cs
@@ -208,7 +208,7 @@ public async Task MethodParamsArePassed()
Assert.AreEqual(4, result.Length);
Assert.AreEqual(Arg1, result[0]);
Assert.AreEqual(Arg2, result[1]);
- Assert.AreEqual(DateTime.Parse(Date), result[2]);
+ Assert.AreEqual(DateTime.Parse(Date).ToUniversalTime(), ((DateTime)result[2]).ToUniversalTime());
Assert.AreEqual(true, result[3]);
}
@@ -297,7 +297,7 @@ public async Task MethodWithObjectParamIsPassed()
var arg = (Person) result[0];
Assert.AreEqual("cef", arg.Name);
Assert.AreEqual(10, arg.Age);
- Assert.AreEqual(DateTime.Parse(Date), arg.BirthDate);
+ Assert.AreEqual(DateTime.Parse(Date).ToUniversalTime(), arg.BirthDate.ToUniversalTime());
}
[Test]
@@ -407,7 +407,7 @@ public async Task NativeObjectMethodDateTimeResultIsReturned()
var result = await nativeObject.ResultTask;
// Assert
- Assert.AreEqual(nativeObject.MethodWithDateTimeReturn(), result);
+ Assert.AreEqual(nativeObject.MethodWithDateTimeReturn().ToUniversalTime(), ((DateTime)result).ToUniversalTime());
}
[Test]
@@ -420,7 +420,7 @@ public async Task NativeObjectMethodObjectResultIsReturned()
var expected = nativeObject.MethodWithObjectReturn();
Assert.AreEqual(expected.Name, result.Name);
Assert.AreEqual(expected.Age, result.Age);
- Assert.AreEqual(expected.BirthDate, result.BirthDate);
+ Assert.AreEqual(expected.BirthDate.ToUniversalTime(), result.BirthDate.ToUniversalTime());
Assert.AreEqual(expected.Photo, result.Photo);
}
diff --git a/Directory.Build.props b/Directory.Build.props
index 53034066..776c87a6 100644
--- a/Directory.Build.props
+++ b/Directory.Build.props
@@ -4,7 +4,7 @@
net8.0
latest
120.1.8
- 11.0.9
+ 12.1.0
120.1.8
120.1.8
x64;ARM64
diff --git a/Directory.Packages.props b/Directory.Packages.props
index d4afe4c8..0a1307d5 100644
--- a/Directory.Packages.props
+++ b/Directory.Packages.props
@@ -1,49 +1,43 @@
-
- true
-
-
+
+ true
+
+
-
- $(PrivateAssets);compile
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+ $(PrivateAssets);compile
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file