Browse Source

[MONOMAC] Dispatcher changes

Nikita Tsukanov 8 years ago
parent
commit
5027248bd4

+ 6 - 0
src/Avalonia.Base/Threading/Dispatcher.cs

@@ -72,6 +72,12 @@ namespace Avalonia.Threading
             _jobRunner?.RunJobs(null);
         }
 
+        /// <summary>
+        /// Use this method to ensure that more prioritized tasks are executed
+        /// </summary>
+        /// <param name="minimumPriority"></param>
+        public void RunJobs(DispatcherPriority minimumPriority) => _jobRunner.RunJobs(minimumPriority);
+
         /// <inheritdoc/>
         public Task InvokeTaskAsync(Action action, DispatcherPriority priority = DispatcherPriority.Normal)
         {

+ 22 - 10
src/OSX/Avalonia.MonoMac/PlatformThreadingInterface.cs

@@ -3,14 +3,18 @@ using System.Threading;
 using Avalonia.Platform;
 using Avalonia.Threading;
 using MonoMac.AppKit;
+using MonoMac.CoreFoundation;
 using MonoMac.CoreGraphics;
 using MonoMac.Foundation;
+using MonoMac.ObjCRuntime;
 
 namespace Avalonia.MonoMac
 {
-    class PlatformThreadingInterface : IPlatformThreadingInterface
+    class PlatformThreadingInterface : NSObject, IPlatformThreadingInterface
     {
         private bool _signaled;
+        private const string SignaledSelectorName = "avaloniauiSignaled";
+        private readonly Selector _signaledSelector = new Selector(SignaledSelectorName);
         public static PlatformThreadingInterface Instance { get; } = new PlatformThreadingInterface();
         public bool CurrentThreadIsLoopThread => NSThread.Current.IsMainThread;
 
@@ -27,18 +31,25 @@ namespace Avalonia.MonoMac
                     return;
                 _signaled = true;
             }
-            NSApplication.SharedApplication.BeginInvokeOnMainThread(() =>
-            {
-                lock (this)
+            PerformSelector(_signaledSelector, NSThread.MainThread, this, false,
+                new[]
                 {
-                    if (!_signaled)
-                        return;
-                    _signaled = false;
-                }
-                Signaled?.Invoke(null);
-            });
+                    NSRunLoop.NSDefaultRunLoopMode, NSRunLoop.NSRunLoopEventTracking, NSRunLoop.NSRunLoopModalPanelMode,
+                    NSRunLoop.NSRunLoopCommonModes, NSRunLoop.NSRunLoopConnectionReplyMode
+                });
         }
 
+        [Export(SignaledSelectorName)]
+        public void CallSignaled()
+        {
+            lock (this)
+            {
+                if (!_signaled)
+                    return;
+                _signaled = false;
+            }
+            Signaled?.Invoke(null);
+        }
 
 
         public void RunLoop(CancellationToken cancellationToken)
@@ -55,6 +66,7 @@ namespace Avalonia.MonoMac
                 var ev = app.NextEvent(NSEventMask.AnyEvent, NSDate.DistantFuture, NSRunLoop.NSDefaultRunLoopMode, true);
                 if (ev != null)
                 {
+                    Console.WriteLine("NSEVENT");
                     app.SendEvent(ev);
                     ev.Dispose();
                 }

+ 0 - 36
src/OSX/Avalonia.MonoMac/ThreadingUtils.cs

@@ -1,36 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Text;
-using MonoMac.AppKit;
-using MonoMac.ObjCRuntime;
-
-namespace Avalonia.MonoMac
-{
-    public static class ThreadingUtils
-    {
-        private static readonly IntPtr selUnlockFocusHandle = Selector.GetHandle("unlockFocus");
-        private static readonly IntPtr selLockFocusIfCanDrawHandle = Selector.GetHandle("lockFocusIfCanDraw");
-        private static readonly IntPtr selWindowHandle = Selector.GetHandle("window");
-        private static readonly IntPtr selCanDrawHandle = Selector.GetHandle("canDraw");
-
-        public static bool NonUILockFocusIfCanDraw(this NSView view)
-        {
-            return Messaging.bool_objc_msgSend(view.Handle, selLockFocusIfCanDrawHandle);
-        }
-
-        public static void NonUIUnlockFocus(this NSView view)
-        {
-            Messaging.void_objc_msgSend(view.Handle, selUnlockFocusHandle);
-        }
-
-        public static NSWindow NonUIGetWindow(this NSView view)
-        {
-            return (NSWindow) Runtime.GetNSObject(Messaging.IntPtr_objc_msgSendSuper(view.Handle, selWindowHandle));
-        }
-
-        public static bool BaseCanDraw(this NSView view)
-        {
-            return Messaging.bool_objc_msgSendSuper(view.SuperHandle, selCanDrawHandle);
-        }
-    }
-}

+ 2 - 0
src/OSX/Avalonia.MonoMac/TopLevelImpl.cs

@@ -25,6 +25,7 @@ namespace Avalonia.MonoMac
 
         protected virtual void OnInput(RawInputEventArgs args)
         {
+            Dispatcher.UIThread.RunJobs(DispatcherPriority.Input + 1);
             Input?.Invoke(args);
         }
 
@@ -75,6 +76,7 @@ namespace Avalonia.MonoMac
             {
                 lock (SyncRoot)
                     _nonUiRedrawQueued = false;
+                Dispatcher.UIThread.RunJobs(DispatcherPriority.Render);
                 lock (SyncRoot)
                 {
                     if (_backBuffer != null)