From 52bf8699e89d5d6690c0ca7ad34d6425356b6f35 Mon Sep 17 00:00:00 2001 From: Nelson Carrillo Date: Sun, 22 Jul 2018 14:04:18 -0400 Subject: [PATCH] Fix more DPI issues. --- src/Avalonia.Windowing/Bindings/EventsLoop.cs | 30 +++++++++++++++---- src/Avalonia.Windowing/Bindings/GlWindow.cs | 4 +++ .../Bindings/IWindowWrapper.cs | 1 + src/Avalonia.Windowing/Bindings/Window.cs | 3 ++ src/Avalonia.Windowing/WIndowingPlatform.cs | 29 +++++++++++++++++- src/Avalonia.Windowing/WindowImpl.cs | 24 ++++++++------- src/Skia/Avalonia.Skia/GlRenderTarget.cs | 10 ++++--- 7 files changed, 79 insertions(+), 22 deletions(-) diff --git a/src/Avalonia.Windowing/Bindings/EventsLoop.cs b/src/Avalonia.Windowing/Bindings/EventsLoop.cs index c2eb028aa7..5ef8d97d3d 100644 --- a/src/Avalonia.Windowing/Bindings/EventsLoop.cs +++ b/src/Avalonia.Windowing/Bindings/EventsLoop.cs @@ -30,6 +30,7 @@ namespace Avalonia.Windowing.Bindings } public delegate void MouseEventCallback(IntPtr windowId, MouseEvent mouseEvent); + public delegate void AwakenedEventCallback(); public class EventsLoop : IDisposable { @@ -40,11 +41,19 @@ namespace Avalonia.Windowing.Bindings private static extern void winit_events_loop_destroy(IntPtr handle); [DllImport("winit_wrapper")] - private static extern void winit_events_loop_run(IntPtr handle, MouseEventCallback callback); + private static extern void winit_events_loop_run + ( + IntPtr handle, + MouseEventCallback callback, + AwakenedEventCallback awakenedEventCallback + ); public IntPtr Handle { get; private set; } private readonly EventsLoopProxy _eventsLoopProxy; + public event MouseEventCallback MouseEvent; + public event AwakenedEventCallback Awakened; + public EventsLoop() { Handle = winit_events_loop_new(out var elpHandle); @@ -55,10 +64,16 @@ namespace Avalonia.Windowing.Bindings { // We need a delegate callback here to support talking back to the C# code. // Send an event type enum and then unsafely construct the event - winit_events_loop_run(Handle, (windowId, mouseEvent) => { - var (x, y) = (mouseEvent.Position.X, mouseEvent.Position.Y); - System.Diagnostics.Debug.WriteLine("Got evt {0} ({1}, {2})", mouseEvent.EventType, x, y); - }); + winit_events_loop_run( + Handle, + (windowId, mouseEvent) => { + MouseEvent?.Invoke(windowId, mouseEvent); + }, + () => + { + Awakened?.Invoke(); + } + ); } public void Wakeup() @@ -77,6 +92,9 @@ namespace Avalonia.Windowing.Bindings [DllImport("winit_wrapper")] private static extern void winit_events_loop_proxy_destroy(IntPtr handle); + [DllImport("winit_wrapper")] + private static extern void winit_events_loop_proxy_wakeup(IntPtr handle); + private readonly IntPtr _handle; public EventsLoopProxy(IntPtr handle) { @@ -85,7 +103,7 @@ namespace Avalonia.Windowing.Bindings public void Wakeup() { - + winit_events_loop_proxy_wakeup(_handle); } public void Dispose() diff --git a/src/Avalonia.Windowing/Bindings/GlWindow.cs b/src/Avalonia.Windowing/Bindings/GlWindow.cs index 82cbc978e0..3fa1a8553e 100644 --- a/src/Avalonia.Windowing/Bindings/GlWindow.cs +++ b/src/Avalonia.Windowing/Bindings/GlWindow.cs @@ -37,7 +37,11 @@ namespace Avalonia.Windowing.Bindings [DllImport("winit_wrapper")] private static extern IntPtr winit_gl_window_get_proc_addr(IntPtr handle, string symbol); + [DllImport("winit_wrapper")] + private static extern IntPtr winit_gl_window_get_id(IntPtr handle); + private IntPtr _handle; + public IntPtr Id => winit_gl_window_get_id(_handle); public GlWindowWrapper(EventsLoop eventsLoop) { _handle = winit_gl_window_new(eventsLoop.Handle); diff --git a/src/Avalonia.Windowing/Bindings/IWindowWrapper.cs b/src/Avalonia.Windowing/Bindings/IWindowWrapper.cs index 53181ad2fa..777e8937fe 100644 --- a/src/Avalonia.Windowing/Bindings/IWindowWrapper.cs +++ b/src/Avalonia.Windowing/Bindings/IWindowWrapper.cs @@ -6,6 +6,7 @@ namespace Avalonia.Windowing.Bindings /// public interface IWindowWrapper : IDisposable { + IntPtr Id { get; } void SetTitle(string title); void SetSize(double width, double height); (double, double) GetSize(); diff --git a/src/Avalonia.Windowing/Bindings/Window.cs b/src/Avalonia.Windowing/Bindings/Window.cs index a7a45c6696..43a19f83cb 100644 --- a/src/Avalonia.Windowing/Bindings/Window.cs +++ b/src/Avalonia.Windowing/Bindings/Window.cs @@ -12,6 +12,9 @@ namespace Avalonia.Windowing.Bindings private static extern IntPtr winit_window_destroy(IntPtr handle); private IntPtr _handle; + + public IntPtr Id => IntPtr.Zero; + public WindowWrapper(EventsLoop eventsLoop) { _handle = winit_window_new(eventsLoop.Handle); diff --git a/src/Avalonia.Windowing/WIndowingPlatform.cs b/src/Avalonia.Windowing/WIndowingPlatform.cs index 6b85713c50..f78414a1d4 100644 --- a/src/Avalonia.Windowing/WIndowingPlatform.cs +++ b/src/Avalonia.Windowing/WIndowingPlatform.cs @@ -1,4 +1,5 @@ using System; +using System.Collections.Generic; using System.Reactive.Disposables; using System.Runtime.InteropServices; using System.Threading; @@ -39,12 +40,30 @@ namespace Avalonia.Windowing { internal static WindowingPlatform Instance { get; private set; } private readonly EventsLoop _eventsLoop; + private readonly Dictionary _windows; public WindowingPlatform() { _eventsLoop = new EventsLoop(); + _eventsLoop.MouseEvent += _eventsLoop_MouseEvent; + _eventsLoop.Awakened += _eventsLoop_Awakened; + _windows = new Dictionary(); } + private void _eventsLoop_MouseEvent(IntPtr windowId, MouseEvent mouseEvent) + { + if (_windows.ContainsKey(windowId)) + { + _windows[windowId].OnMouseEvent(mouseEvent); + } + } + + private void _eventsLoop_Awakened() + { + Signaled?.Invoke(DispatcherPriority.Normal); + } + + public static void Initialize() { Instance = new WindowingPlatform(); @@ -55,6 +74,7 @@ namespace Avalonia.Windowing { AvaloniaLocator.CurrentMutable .Bind().ToConstant(this) + .Bind().ToConstant(new MouseDevice()) .Bind().ToConstant(new IconLoader()) .Bind().ToConstant(new CursorFactory()) .Bind().ToConstant(this); @@ -73,7 +93,14 @@ namespace Avalonia.Windowing throw new NotImplementedException(); } - public IWindowImpl CreateWindow() => new Window(new GlWindowWrapper(_eventsLoop)); + public IWindowImpl CreateWindow() + { + var windowWrapper = new GlWindowWrapper(_eventsLoop); + var window = new Window(windowWrapper); + _windows.Add(windowWrapper.Id, window); + + return window; + } public void RunLoop(CancellationToken cancellationToken) { diff --git a/src/Avalonia.Windowing/WindowImpl.cs b/src/Avalonia.Windowing/WindowImpl.cs index 8434609f3c..2fa5ce979a 100644 --- a/src/Avalonia.Windowing/WindowImpl.cs +++ b/src/Avalonia.Windowing/WindowImpl.cs @@ -48,7 +48,7 @@ namespace Avalonia.Windowing get { var (width, height) = _windowWrapper.GetSize(); - return new Size(width * 2, height * 2); + return new Size(width, height); } } @@ -62,7 +62,7 @@ namespace Avalonia.Windowing public Action ScalingChanged { get; set; } public Action Closed { get; set; } - public IMouseDevice MouseDevice => throw new NotImplementedException(); + public IMouseDevice MouseDevice => new MouseDevice(); public void Activate() { @@ -101,14 +101,14 @@ namespace Avalonia.Windowing public Point PointToClient(Point point) { - point = point.WithY(ClientSize.Height - point.Y); + // point = point.WithY(ClientSize.Height - point.Y); var (x, y) = _windowWrapper.GetPosition(); return new Point(point.X + x, point.Y + y); } public Point PointToScreen(Point point) { - point = point.WithY(ClientSize.Height - point.Y); + // point = point.WithY(ClientSize.Height - point.Y); var (x, y) = _windowWrapper.GetPosition(); return new Point(point.X - x, point.Y - y);; } @@ -116,10 +116,7 @@ namespace Avalonia.Windowing public void Resize(Size clientSize) { // This is where we size the window accordingly.. - _windowWrapper.SetSize(clientSize.Width / Scaling, clientSize.Height / Scaling); - - // TODO: Move this to when we receive the Resized message. - Resized(clientSize); + _windowWrapper.SetSize(clientSize.Width, clientSize.Height); } public void SetCursor(IPlatformHandle cursor) @@ -130,9 +127,8 @@ namespace Avalonia.Windowing { } - public void SetInputRoot(IInputRoot inputRoot) - { - } + private IInputRoot _inputRoot; + public void SetInputRoot(IInputRoot inputRoot) => _inputRoot = inputRoot; public void SetMinMaxSize(Size minSize, Size maxSize) { @@ -164,5 +160,11 @@ namespace Avalonia.Windowing public void ShowTaskbarIcon(bool value) { } + + public void OnMouseEvent(MouseEvent evt) + { + Input(new RawMouseEventArgs(MouseDevice, (uint)Environment.TickCount, _inputRoot, RawMouseEventType.Move, new Point(evt.Position.X, evt.Position.Y), InputModifiers.None)); + Paint?.Invoke(Rect.Empty); + } } } diff --git a/src/Skia/Avalonia.Skia/GlRenderTarget.cs b/src/Skia/Avalonia.Skia/GlRenderTarget.cs index 7561c98e0f..67015e9367 100644 --- a/src/Skia/Avalonia.Skia/GlRenderTarget.cs +++ b/src/Skia/Avalonia.Skia/GlRenderTarget.cs @@ -31,8 +31,8 @@ namespace Avalonia.Skia { // TODO: These are hard coded for now. Don't do that. // TODO: Recreate the surface when the size changes. - if (_surface == null) - { + // if (_surface == null) + { var (width, height) = _context.GetFramebufferSize(); _surface = SKSurface.Create(_grContext, new GRBackendRenderTargetDesc @@ -49,9 +49,10 @@ namespace Avalonia.Skia _canvas = _surface.Canvas; } - _canvas.RestoreToCount(-1); - _canvas.ResetMatrix(); + // _canvas.RestoreToCount(-1); + // _canvas.ResetMatrix(); + _canvas.Scale(2); var createInfo = new DrawingContextImpl.CreateInfo { Canvas = _canvas, @@ -62,6 +63,7 @@ namespace Avalonia.Skia return new DrawingContextImpl(createInfo, Disposable.Create(() => { + _canvas.Flush(); _grContext.Flush(); _context.Present(); // Swap Buffers }));