Browse Source

Make WindowId FFI safe

repro-window-close
Nelson Carrillo 8 years ago
parent
commit
87dfd105a2
  1. 8
      src/Avalonia.Windowing/Bindings/EventNotifier.cs
  2. 6
      src/Avalonia.Windowing/Bindings/EventsLoop.cs
  3. 19
      src/Avalonia.Windowing/Bindings/GlWindow.cs
  4. 3
      src/Avalonia.Windowing/Bindings/IWindowWrapper.cs
  5. 13
      src/Avalonia.Windowing/KeyTransform.cs
  6. 1
      src/Avalonia.Windowing/PopupImpl.cs
  7. 15
      src/Avalonia.Windowing/WIndowingPlatform.cs
  8. 24
      src/Avalonia.Windowing/WindowImpl.cs

8
src/Avalonia.Windowing/Bindings/EventNotifier.cs

@ -4,10 +4,10 @@ using System.Security;
namespace Avalonia.Windowing.Bindings
{
public delegate void MouseEventCallback(IntPtr windowId, MouseEvent mouseEvent);
public delegate void ResizeEventCallback(IntPtr windowId, ResizeEvent resizeEvent);
public delegate void KeyboardEventCallback(IntPtr windowId, KeyboardEvent keyboardEvent);
public delegate void CharacterEventCallback(IntPtr windowId, CharacterEvent characterEvent);
public delegate void MouseEventCallback(WindowId windowId, MouseEvent mouseEvent);
public delegate void ResizeEventCallback(WindowId windowId, ResizeEvent resizeEvent);
public delegate void KeyboardEventCallback(WindowId windowId, KeyboardEvent keyboardEvent);
public delegate void CharacterEventCallback(WindowId windowId, CharacterEvent characterEvent);
public delegate void AwakenedEventCallback();
[StructLayout(LayoutKind.Sequential)]

6
src/Avalonia.Windowing/Bindings/EventsLoop.cs

@ -43,10 +43,10 @@ namespace Avalonia.Windowing.Bindings
_eventsLoopProxy = new EventsLoopProxy(elpHandle);
_notifier = new EventNotifier()
{
OnMouseEvent = (IntPtr windowId, MouseEvent mouseEvent) => OnMouseEvent?.Invoke(windowId, mouseEvent),
OnKeyboardEvent = (IntPtr windowId, KeyboardEvent keyboardEvent) => OnKeyboardEvent?.Invoke(windowId, keyboardEvent),
OnMouseEvent = (windowId, mouseEvent) => OnMouseEvent?.Invoke(windowId, mouseEvent),
OnKeyboardEvent = (windowId, keyboardEvent) => OnKeyboardEvent?.Invoke(windowId, keyboardEvent),
OnCharacterEvent = (windowId, characterEvent) => OnCharacterEvent?.Invoke(windowId, characterEvent),
OnResized = (IntPtr windowId, ResizeEvent resizeEvent) => OnResized?.Invoke(windowId, resizeEvent),
OnResized = (windowId, resizeEvent) => OnResized?.Invoke(windowId, resizeEvent),
OnAwakened = () => OnAwakened?.Invoke()
};
}

19
src/Avalonia.Windowing/Bindings/GlWindow.cs

@ -4,6 +4,12 @@ using Avalonia.Gpu;
namespace Avalonia.Windowing.Bindings
{
[StructLayout(LayoutKind.Sequential)]
public struct WindowId
{
public long Value { get; set; }
}
/// <summary>
/// A window and GL context pair.
/// Due to platform specific quirks, the ordering of window and context creation must be controlled by winit.
@ -22,6 +28,9 @@ namespace Avalonia.Windowing.Bindings
[DllImport("winit_wrapper")]
private static extern void winit_gl_window_set_size(IntPtr handle, double width, double height);
[DllImport("winit_wrapper")]
private static extern void winit_gl_window_set_position(IntPtr handle, LogicalPosition position);
[DllImport("winit_wrapper")]
private static extern LogicalSize winit_gl_window_get_size(IntPtr handle);
@ -47,13 +56,13 @@ namespace Avalonia.Windowing.Bindings
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 static extern WindowId winit_gl_window_get_id(IntPtr handle);
[DllImport("winit_wrapper")]
private static extern void winit_gl_window_resize_context(IntPtr handle, double width, double height);
private IntPtr _handle;
public IntPtr Id => winit_gl_window_get_id(_handle);
public WindowId Id => winit_gl_window_get_id(_handle);
public EventsLoop EventsLoop { get; }
public GlWindowWrapper(EventsLoop eventsLoop)
@ -77,6 +86,12 @@ namespace Avalonia.Windowing.Bindings
winit_gl_window_set_size(_handle, width, height);
}
public void SetPosition(double x, double y)
{
var position = new LogicalPosition { X = x, Y = y };
winit_gl_window_set_position(_handle, position);
}
public void Present()
{
winit_gl_window_present(_handle);

3
src/Avalonia.Windowing/Bindings/IWindowWrapper.cs

@ -6,11 +6,12 @@ namespace Avalonia.Windowing.Bindings
/// </summary>
public interface IWindowWrapper : IDisposable
{
IntPtr Id { get; }
WindowId Id { get; }
EventsLoop EventsLoop { get; }
void SetTitle(string title);
void SetSize(double width, double height);
void SetPosition(double x, double y);
double GetScaleFactor();
(double, double) GetSize();

13
src/Avalonia.Windowing/KeyTransform.cs

@ -216,7 +216,7 @@ namespace Avalonia.Windowing
[VirtualKeyCode.Left] = Key.Left,
[VirtualKeyCode.Capital] = Key.CapsLock,
[VirtualKeyCode.LAlt]= Key.LeftAlt,
[VirtualKeyCode.LAlt] = Key.LeftAlt,
[VirtualKeyCode.RAlt] = Key.RightAlt,
[VirtualKeyCode.LControl] = Key.LeftCtrl,
[VirtualKeyCode.RControl] = Key.RightCtrl,
@ -226,11 +226,18 @@ namespace Avalonia.Windowing
[VirtualKeyCode.RWin] = Key.RWin,
[VirtualKeyCode.Numlock] = Key.NumLock,
[VirtualKeyCode.Delete] = Key.Delete,
[VirtualKeyCode.LBracket] = Key.OemOpenBrackets,
[VirtualKeyCode.RBracket] = Key.OemCloseBrackets,
[VirtualKeyCode.Add] = Key.OemPlus,
[VirtualKeyCode.Minus] = Key.OemMinus,
[VirtualKeyCode.Subtract] = Key.Subtract,
[VirtualKeyCode.Backslash] = Key.OemBackslash,
[VirtualKeyCode.Colon] = Key.OemSemicolon,
[VirtualKeyCode.Comma] = Key.OemComma,
[VirtualKeyCode.Tab] = Key.Tab,
[VirtualKeyCode.Space] = Key.Space,
[VirtualKeyCode.A] = Key.A,
[VirtualKeyCode.B] = Key.B,
[VirtualKeyCode.C] = Key.C,
@ -255,8 +262,8 @@ namespace Avalonia.Windowing
[VirtualKeyCode.V] = Key.V,
[VirtualKeyCode.W] = Key.W,
[VirtualKeyCode.X] = Key.X,
[VirtualKeyCode.X] = Key.Y,
[VirtualKeyCode.X] = Key.Z,
[VirtualKeyCode.Y] = Key.Y,
[VirtualKeyCode.Z] = Key.Z,
};
public static Key? TransformKeyCode(VirtualKeyCode code)

1
src/Avalonia.Windowing/PopupImpl.cs

@ -13,6 +13,7 @@ namespace Avalonia.Windowing
{
public PopupImpl(IWindowWrapper wrapper) : base(wrapper)
{
this.SetSystemDecorations(false);
}
}
}

15
src/Avalonia.Windowing/WIndowingPlatform.cs

@ -32,7 +32,7 @@ namespace Avalonia.Windowing
{
internal static WindowingPlatform Instance { get; private set; }
private readonly EventsLoop _eventsLoop;
private readonly Dictionary<IntPtr, WindowImpl> _windows;
private readonly Dictionary<WindowId, WindowImpl> _windows;
public WindowingPlatform()
{
@ -42,10 +42,10 @@ namespace Avalonia.Windowing
_eventsLoop.OnCharacterEvent += _eventsLoop_OnCharacterEvent;
_eventsLoop.OnAwakened += _eventsLoop_Awakened;
_eventsLoop.OnResized += _eventsLoop_Resized;
_windows = new Dictionary<IntPtr, WindowImpl>();
_windows = new Dictionary<WindowId, WindowImpl>();
}
void _eventsLoop_Resized(IntPtr windowId, ResizeEvent resizeEvent)
void _eventsLoop_Resized(WindowId windowId, ResizeEvent resizeEvent)
{
Dispatcher.UIThread.RunJobs(DispatcherPriority.Layout);
if (_windows.ContainsKey(windowId))
@ -55,7 +55,7 @@ namespace Avalonia.Windowing
}
private void _eventsLoop_MouseEvent(IntPtr windowId, MouseEvent mouseEvent)
private void _eventsLoop_MouseEvent(WindowId windowId, MouseEvent mouseEvent)
{
if (_windows.ContainsKey(windowId))
{
@ -63,7 +63,7 @@ namespace Avalonia.Windowing
}
}
void _eventsLoop_OnCharacterEvent(IntPtr windowId, CharacterEvent characterEvent)
void _eventsLoop_OnCharacterEvent(WindowId windowId, CharacterEvent characterEvent)
{
if (_windows.ContainsKey(windowId))
{
@ -72,7 +72,7 @@ namespace Avalonia.Windowing
}
void _eventsLoop_OnKeyboardEvent(IntPtr windowId, KeyboardEvent keyboardEvent)
void _eventsLoop_OnKeyboardEvent(WindowId windowId, KeyboardEvent keyboardEvent)
{
if(_windows.ContainsKey(windowId))
{
@ -136,7 +136,8 @@ namespace Avalonia.Windowing
{
var windowWrapper = new GlWindowWrapper(_eventsLoop);
var window = new WindowImpl(windowWrapper);
_windows.Add(windowWrapper.Id, window);
var id = windowWrapper.Id;
_windows.Add(id, window);
return window;
}

24
src/Avalonia.Windowing/WindowImpl.cs

@ -32,11 +32,14 @@ namespace Avalonia.Windowing
.SubscribeOn(AvaloniaScheduler.Instance)
.Subscribe((x) =>
{
// Dont schedule a paint for empty invalidations.
if (coalescedRect != Rect.Empty) {
Dispatcher.UIThread.Post(() => Paint(coalescedRect), DispatcherPriority.Render);
coalescedRect = Rect.Empty;
}
// Dont schedule a paint for empty invalidations.
if (coalescedRect != Rect.Empty) {
Dispatcher.UIThread.Post(() =>
{
Paint(coalescedRect);
coalescedRect = Rect.Empty;
}, DispatcherPriority.Render);
}
});
}
@ -52,17 +55,10 @@ namespace Avalonia.Windowing
}
set
{
// TODO: SetPosition
var x = value;
_windowWrapper.SetPosition(value.X, value.Y);
}
}
public bool timeToPaint = false;
public void Test() {
timeToPaint = true;
}
public Action<Point> PositionChanged { get; set; }
public Action Deactivated { get; set; }
public Action Activated { get; set; }
@ -141,7 +137,7 @@ namespace Avalonia.Windowing
public Point PointToScreen(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 void Resize(Size clientSize)

Loading…
Cancel
Save