diff --git a/src/Avalonia.Windowing/Bindings/EventNotifier.cs b/src/Avalonia.Windowing/Bindings/EventNotifier.cs index f35e2eef67..5f38bfa707 100644 --- a/src/Avalonia.Windowing/Bindings/EventNotifier.cs +++ b/src/Avalonia.Windowing/Bindings/EventNotifier.cs @@ -9,7 +9,8 @@ namespace Avalonia.Windowing.Bindings public delegate void KeyboardEventCallback(WindowId windowId, KeyboardEvent keyboardEvent); public delegate void CharacterEventCallback(WindowId windowId, CharacterEvent characterEvent); public delegate void AwakenedEventCallback(); - + public delegate byte ShouldExitEventLoopCallback(WindowId windowId); + [StructLayout(LayoutKind.Sequential)] public struct EventNotifier { @@ -18,5 +19,6 @@ namespace Avalonia.Windowing.Bindings public ResizeEventCallback OnResized; public KeyboardEventCallback OnKeyboardEvent; public CharacterEventCallback OnCharacterEvent; + public ShouldExitEventLoopCallback OnShouldExitEventLoop; } } diff --git a/src/Avalonia.Windowing/Bindings/EventsLoop.cs b/src/Avalonia.Windowing/Bindings/EventsLoop.cs index 5c181fb985..b5f128cdf1 100644 --- a/src/Avalonia.Windowing/Bindings/EventsLoop.cs +++ b/src/Avalonia.Windowing/Bindings/EventsLoop.cs @@ -18,15 +18,6 @@ namespace Avalonia.Windowing.Bindings EventNotifier notifier ); - [UnmanagedFunctionPointer(CallingConvention.Cdecl)] - public delegate void TimerDel(); - - [DllImport("winit_wrapper")] - private static extern void winit_events_loop_timer - ( - TimerDel del2 - ); - public IntPtr Handle { get; private set; } private readonly EventsLoopProxy _eventsLoopProxy; private readonly EventNotifier _notifier; @@ -36,6 +27,7 @@ namespace Avalonia.Windowing.Bindings public event MouseEventCallback OnMouseEvent; public event AwakenedEventCallback OnAwakened; public event ResizeEventCallback OnResized; + public event ShouldExitEventLoopCallback OnShouldExitEventLoop; public EventsLoop() { @@ -47,7 +39,8 @@ namespace Avalonia.Windowing.Bindings OnKeyboardEvent = (windowId, keyboardEvent) => OnKeyboardEvent?.Invoke(windowId, keyboardEvent), OnCharacterEvent = (windowId, characterEvent) => OnCharacterEvent?.Invoke(windowId, characterEvent), OnResized = (windowId, resizeEvent) => OnResized?.Invoke(windowId, resizeEvent), - OnAwakened = () => OnAwakened?.Invoke() + OnAwakened = () => OnAwakened?.Invoke(), + OnShouldExitEventLoop = (windowId) => (byte)OnShouldExitEventLoop?.Invoke(windowId) }; } @@ -59,11 +52,6 @@ namespace Avalonia.Windowing.Bindings ); } - public void RunTimer(TimerDel del) - { - winit_events_loop_timer(del); - } - public void Wakeup() { _eventsLoopProxy.Wakeup(); diff --git a/src/Avalonia.Windowing/Bindings/GlWindow.cs b/src/Avalonia.Windowing/Bindings/GlWindow.cs index 404432cc38..a4775a9eea 100644 --- a/src/Avalonia.Windowing/Bindings/GlWindow.cs +++ b/src/Avalonia.Windowing/Bindings/GlWindow.cs @@ -71,44 +71,56 @@ namespace Avalonia.Windowing.Bindings _handle = winit_gl_window_new(EventsLoop.Handle); } + private bool disposed = false; public void Dispose() { - winit_gl_window_destroy(_handle); + if (!disposed) + { + winit_gl_window_destroy(_handle); + disposed = true; + } } public void SetTitle(string title) { + Contract.Requires(disposed != true); winit_gl_window_set_title(_handle, title); } public void SetSize(double width, double height) { + Contract.Requires(disposed != true); winit_gl_window_set_size(_handle, width, height); } public void SetPosition(double x, double y) { + Contract.Requires(disposed != true); var position = new LogicalPosition { X = x, Y = y }; winit_gl_window_set_position(_handle, position); } public void Present() { + Contract.Requires(disposed != true); winit_gl_window_present(_handle); } public IntPtr GetProcAddress(string symbol) { + Contract.Requires(disposed != true); return winit_gl_window_get_proc_addr(_handle, symbol); } public (double, double) GetSize() { + Contract.Requires(disposed != true); var size = winit_gl_window_get_size(_handle); return (size.Width, size.Height); } public double GetScaleFactor () { + Contract.Requires(disposed != true); return winit_gl_window_get_dpi_scale_factor(_handle); } @@ -119,27 +131,32 @@ namespace Avalonia.Windowing.Bindings public (double, double) GetPosition() { + Contract.Requires(disposed != true); var position = winit_gl_window_get_position(_handle); return (position.X, position.Y); } public void Show() { + Contract.Requires(disposed != true); winit_gl_window_show(_handle); } public void ResizeContext(double width, double height) { + Contract.Requires(disposed != true); winit_gl_window_resize_context(_handle, width, height); } public void ToggleDecorations(bool visible) { + Contract.Requires(disposed != true); winit_gl_window_set_decorations(_handle, visible ? 1 : 0); } public void Hide() { + Contract.Requires(disposed != true); winit_gl_window_hide(_handle); } diff --git a/src/Avalonia.Windowing/WIndowingPlatform.cs b/src/Avalonia.Windowing/WIndowingPlatform.cs index 4318d5ed31..c5f11c4de9 100644 --- a/src/Avalonia.Windowing/WIndowingPlatform.cs +++ b/src/Avalonia.Windowing/WIndowingPlatform.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; using System.Diagnostics; +using System.Linq; using System.Reactive.Disposables; using System.Runtime.InteropServices; using System.Threading; @@ -42,9 +43,18 @@ namespace Avalonia.Windowing _eventsLoop.OnCharacterEvent += _eventsLoop_OnCharacterEvent; _eventsLoop.OnAwakened += _eventsLoop_Awakened; _eventsLoop.OnResized += _eventsLoop_Resized; + _eventsLoop.OnShouldExitEventLoop += _eventsLoop_OnShouldExitEventLoop; _windows = new Dictionary(); } + byte _eventsLoop_OnShouldExitEventLoop(WindowId windowId) + { + if (_windows.ContainsKey(windowId)) + _windows.Remove(windowId); + + return _windows.Any() ? (byte)0 : (byte)1; + } + void _eventsLoop_Resized(WindowId windowId, ResizeEvent resizeEvent) { Dispatcher.UIThread.RunJobs(DispatcherPriority.Layout); @@ -159,8 +169,6 @@ namespace Avalonia.Windowing _eventsLoop.Wakeup(); } - private IList timerTickers = new List(); - public IDisposable StartTimer(DispatcherPriority priority, TimeSpan interval, Action tick) { // TODO: Need a way to cancel a timer when Dispose is called. diff --git a/src/Avalonia.Windowing/WindowImpl.cs b/src/Avalonia.Windowing/WindowImpl.cs index aecc7ffe4b..45b3cf612a 100644 --- a/src/Avalonia.Windowing/WindowImpl.cs +++ b/src/Avalonia.Windowing/WindowImpl.cs @@ -131,7 +131,7 @@ namespace Avalonia.Windowing public Point PointToClient(Point point) { var position = Position; - return new Point(point.X + position.X, point.Y + position.Y); + return new Point(point.X - position.X, point.Y - position.Y); } public Point PointToScreen(Point point)