From 0167bbb97cabe197de7346aa382113aa1b2a208a Mon Sep 17 00:00:00 2001 From: Dan Walmsley Date: Sun, 29 Jul 2018 20:00:04 +0100 Subject: [PATCH] implement Screens api. --- src/Avalonia.Windowing/Bindings/EventsLoop.cs | 16 ++++++- src/Avalonia.Windowing/Bindings/Monitor.cs | 1 + src/Avalonia.Windowing/Bindings/Monitors.cs | 17 ------- src/Avalonia.Windowing/Bindings/Units.cs | 7 +++ src/Avalonia.Windowing/ScreenImpl.cs | 44 +++++++++++++++++++ src/Avalonia.Windowing/WindowImpl.cs | 2 +- 6 files changed, 67 insertions(+), 20 deletions(-) delete mode 100644 src/Avalonia.Windowing/Bindings/Monitors.cs create mode 100644 src/Avalonia.Windowing/ScreenImpl.cs diff --git a/src/Avalonia.Windowing/Bindings/EventsLoop.cs b/src/Avalonia.Windowing/Bindings/EventsLoop.cs index 956f3f5ffe..cb38a3b8e0 100644 --- a/src/Avalonia.Windowing/Bindings/EventsLoop.cs +++ b/src/Avalonia.Windowing/Bindings/EventsLoop.cs @@ -21,6 +21,13 @@ namespace Avalonia.Windowing.Bindings EventNotifier notifier ); + + [DllImport("winit_wrapper")] + private static extern UInt32 winit_events_loop_get_monitor_count(IntPtr handle); + + [DllImport("winit_wrapper")] + private static extern Monitor winit_monitor_get_monitor(IntPtr handle, UInt32 id); + public IntPtr Handle { get; private set; } private readonly EventsLoopProxy _eventsLoopProxy; @@ -71,9 +78,14 @@ namespace Avalonia.Windowing.Bindings winit_events_loop_destroy(Handle); } - public void GetAvailableMonitors() + public UInt32 GetAvailableMonitors() + { + return winit_events_loop_get_monitor_count(Handle); + } + + public Monitor GetMonitor (UInt32 id) { - // TODO + return winit_monitor_get_monitor(Handle, id); } private class EventsLoopProxy : IDisposable diff --git a/src/Avalonia.Windowing/Bindings/Monitor.cs b/src/Avalonia.Windowing/Bindings/Monitor.cs index c4e01ee333..d7b8578779 100644 --- a/src/Avalonia.Windowing/Bindings/Monitor.cs +++ b/src/Avalonia.Windowing/Bindings/Monitor.cs @@ -8,5 +8,6 @@ namespace Avalonia.Windowing.Bindings { public LogicalSize Size { get; set; } public LogicalPosition Position { get; set; } + public byte IsPrimary { get; set; } } } diff --git a/src/Avalonia.Windowing/Bindings/Monitors.cs b/src/Avalonia.Windowing/Bindings/Monitors.cs deleted file mode 100644 index 0bb0544306..0000000000 --- a/src/Avalonia.Windowing/Bindings/Monitors.cs +++ /dev/null @@ -1,17 +0,0 @@ -using System; -using Avalonia.Platform; - -namespace Avalonia.Windowing.Bindings -{ - - public class Monitors : IScreenImpl - { - public int ScreenCount => 1; - public Screen[] AllScreens => new Screen[] { new Screen(Rect.Empty, Rect.Empty, true) }; - - public Monitors() - { - - } - } -} diff --git a/src/Avalonia.Windowing/Bindings/Units.cs b/src/Avalonia.Windowing/Bindings/Units.cs index dcad04a828..6c42c42fd3 100644 --- a/src/Avalonia.Windowing/Bindings/Units.cs +++ b/src/Avalonia.Windowing/Bindings/Units.cs @@ -3,6 +3,13 @@ using System.Runtime.InteropServices; namespace Avalonia.Windowing.Bindings { + [StructLayout(LayoutKind.Sequential)] + public struct PhysicalSize + { + public double Width { get; set; } + public double Height { get; set; } + } + [StructLayout(LayoutKind.Sequential)] public struct LogicalPosition { diff --git a/src/Avalonia.Windowing/ScreenImpl.cs b/src/Avalonia.Windowing/ScreenImpl.cs new file mode 100644 index 0000000000..aacc3c24f5 --- /dev/null +++ b/src/Avalonia.Windowing/ScreenImpl.cs @@ -0,0 +1,44 @@ +using System; +using Avalonia.Platform; +using Avalonia.Windowing.Bindings; + +namespace Avalonia.Windowing +{ + public class ScreenImpl : IScreenImpl + { + private EventsLoop _loop; + private Screen[] _screens; + + public ScreenImpl(EventsLoop loop) + { + _loop = loop; + } + + public int ScreenCount => (int)_loop.GetAvailableMonitors(); + + private Screen[] _allScreens; + public Screen[] AllScreens + { + get + { + if (_allScreens == null || ScreenCount != _allScreens.Length) + { + Screen[] screens = new Screen[ScreenCount]; + + for (UInt32 i = 0; i < ScreenCount; i++) + { + var monitor = _loop.GetMonitor(i); + + var bounds = new Rect(new Point(monitor.Position.X, monitor.Position.Y), new Size(monitor.Size.Width, monitor.Size.Height)); + + // TODO winit doesnt support the concept of working area. (size minus area used by taskbar. + + screens[i] = new Screen(bounds, bounds, monitor.IsPrimary == 1); + } + + _allScreens = screens; + } + return _allScreens; + } + }} +} diff --git a/src/Avalonia.Windowing/WindowImpl.cs b/src/Avalonia.Windowing/WindowImpl.cs index 36660ecf03..cbfdf11a92 100644 --- a/src/Avalonia.Windowing/WindowImpl.cs +++ b/src/Avalonia.Windowing/WindowImpl.cs @@ -75,7 +75,7 @@ namespace Avalonia.Windowing public Size MaxClientSize => Size.Empty; - public IScreenImpl Screen => new Monitors(); + public IScreenImpl Screen => new ScreenImpl(_windowWrapper.EventsLoop); public Size ClientSize {