CGEventCreate fixed broken call, added tests (#17805)

Fixes https://github.com/xamarin/xamarin-macios/issues/17656
This commit is contained in:
Steve Hawley 2023-03-16 11:00:12 -04:00 коммит произвёл GitHub
Родитель b941563bbc
Коммит 61ad2a9dec
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
2 изменённых файлов: 63 добавлений и 10 удалений

Просмотреть файл

@ -103,27 +103,33 @@ namespace CoreGraphics {
#if NET #if NET
[DllImport (Constants.ApplicationServicesCoreGraphicsLibrary)] [DllImport (Constants.ApplicationServicesCoreGraphicsLibrary)]
extern static unsafe IntPtr CGEventTapCreateForPSN (IntPtr processSerialNumer, CGEventTapLocation location, CGEventTapPlacement place, CGEventTapOptions options, CGEventMask mask, delegate* unmanaged<IntPtr, CGEventType, IntPtr, IntPtr, IntPtr> cback, IntPtr data); extern static unsafe IntPtr CGEventTapCreateForPSN (IntPtr processSerialNumer, CGEventTapPlacement place, CGEventTapOptions options, CGEventMask mask, delegate* unmanaged<IntPtr, CGEventType, IntPtr, IntPtr, IntPtr> cback, IntPtr data);
#else #else
[DllImport (Constants.ApplicationServicesCoreGraphicsLibrary)] [DllImport (Constants.ApplicationServicesCoreGraphicsLibrary)]
extern static IntPtr CGEventTapCreateForPSN (IntPtr processSerialNumer, CGEventTapLocation location, CGEventTapPlacement place, CGEventTapOptions options, CGEventMask mask, CGEventTapCallback cback, IntPtr data); extern static IntPtr CGEventTapCreateForPSN (IntPtr processSerialNumer, CGEventTapPlacement place, CGEventTapOptions options, CGEventMask mask, CGEventTapCallback cback, IntPtr data);
#endif #endif
[Obsolete ("The location parameter is not used. Consider using the overload without the location parameter.", false)]
public static CFMachPort? CreateTap (IntPtr processSerialNumber, CGEventTapLocation location, CGEventTapPlacement place, CGEventTapOptions options, CGEventMask mask, CGEventTapCallback cback, IntPtr data) public static CFMachPort? CreateTap (IntPtr processSerialNumber, CGEventTapLocation location, CGEventTapPlacement place, CGEventTapOptions options, CGEventMask mask, CGEventTapCallback cback, IntPtr data)
{ {
#if NET return CreateTap (processSerialNumber, place, options, mask, cback, data);
IntPtr r; }
public static CFMachPort? CreateTap (IntPtr processSerialNumber, CGEventTapPlacement place, CGEventTapOptions options, CGEventMask mask, CGEventTapCallback cback, IntPtr data)
{
unsafe { unsafe {
var psnPtr = new IntPtr (&processSerialNumber);
#if NET
var tapData = new TapData (cback, data); var tapData = new TapData (cback, data);
var gch = GCHandle.Alloc (tapData); var gch = GCHandle.Alloc (tapData);
r = CGEventTapCreateForPSN (processSerialNumber, location, place, options, mask, &TapCallback, GCHandle.ToIntPtr (gch)); var r = CGEventTapCreateForPSN (psnPtr, place, options, mask, &TapCallback, GCHandle.ToIntPtr (gch));
}
#else #else
var r = CGEventTapCreateForPSN (processSerialNumber, location, place, options, mask, cback, data); var r = CGEventTapCreateForPSN (psnPtr, place, options, mask, cback, data);
#endif #endif
if (r == IntPtr.Zero) if (r == IntPtr.Zero)
return null; return null;
return new CFMachPort (r, true); return new CFMachPort (r, true);
}
} }
[DllImport (Constants.ApplicationServicesCoreGraphicsLibrary)] [DllImport (Constants.ApplicationServicesCoreGraphicsLibrary)]

Просмотреть файл

@ -0,0 +1,47 @@
using System;
using Foundation;
#if MONOMAC
using AppKit;
#else
using UIKit;
#endif
using CoreGraphics;
using NUnit.Framework;
namespace MonoTouchFixtures.CoreGraphics {
[TestFixture]
[Preserve (AllMembers = true)]
public class CGEventTests {
#if MONOMAC
bool tapCalled = false;
IntPtr callBack (IntPtr tapProxyEvent, CGEventType eventType,
IntPtr eventRef, IntPtr userInfo)
{
tapCalled = true;
return eventRef;
}
[Test]
public void CreateTap ()
{
tapCalled = false;
var psn = (IntPtr) 2; // kCurrentProcess
var tapPort = CGEvent.CreateTap (CGEventTapLocation.AnnotatedSession, CGEventTapPlacement.HeadInsert, CGEventTapOptions.Default, CGEventMask.KeyDown, callBack, IntPtr.Zero);
Assert.IsNull (tapPort, "magically created tap port when not root");
Assert.IsFalse (tapCalled, "tap was mistakenly called.");
}
[Test]
public void CreateTapPSN ()
{
tapCalled = false;
var psn = (IntPtr) 2; // kCurrentProcess
var tapPort = CGEvent.CreateTap (psn, CGEventTapPlacement.HeadInsert, CGEventTapOptions.Default, CGEventMask.KeyDown, callBack, IntPtr.Zero);
Assert.IsNull (tapPort, "magically created tap port with OSN when not root");
Assert.IsFalse (tapCalled, "tap was mistakenly called.");
}
#endif
}
}