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
[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
[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
[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)
{
#if NET
IntPtr r;
return CreateTap (processSerialNumber, place, options, mask, cback, data);
}
public static CFMachPort? CreateTap (IntPtr processSerialNumber, CGEventTapPlacement place, CGEventTapOptions options, CGEventMask mask, CGEventTapCallback cback, IntPtr data)
{
unsafe {
var psnPtr = new IntPtr (&processSerialNumber);
#if NET
var tapData = new TapData (cback, data);
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
var r = CGEventTapCreateForPSN (processSerialNumber, location, place, options, mask, cback, data);
var r = CGEventTapCreateForPSN (psnPtr, place, options, mask, cback, data);
#endif
if (r == IntPtr.Zero)
return null;
return new CFMachPort (r, true);
if (r == IntPtr.Zero)
return null;
return new CFMachPort (r, true);
}
}
[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
}
}