Page 1 of 1
NSEvent otherEventWithType too many parameters?
Posted: Tue Dec 24, 2019 7:55 am
by Rinzwind
Code: Select all
#NSSystemDefined = 14
#KMUTE = 7 ;#define NX_KEYTYPE_MUTE 7
Procedure MediaKeyPress(k1)
Protected p.NSPoint, flags, data1, data2
flags = $a00 ;down
data1 = (k1 << 16) | ($a << 8) ;down
CocoaMessage(0, 0, "NSEvent otherEventWithType:", NSSystemDefined, "location:@", @p, "modifierFlags:", flags, "timestamp:", 0, "windowNumber:", 0, "context:", 0, "subtype:", 8, "data1:", data1, "data2:", -1)
flags = $b00 ;up
data1 = (k1 << 16) | ($b << 8) ;up
CocoaMessage(0, 0, "NSEvent otherEventWithType:", NSSystemDefined, "location:@", @p, "modifierFlags:", flags, "timestamp:", 0, "windowNumber:", 0, "context:", 0, "subtype:", 8, "data1:", data1, "data2:", -1)
EndProcedure
MediaKeyPress(#KMUTE)
Nogo... too many parameters for CocoaMessage because it has a buildin max of 7 in total.. (need 9 here...)
https://developer.apple.com/documentati ... guage=objc
I guess not possible then. Just asking to be sure... Just playing around with media keys...
Re: NSEvent otherEventWithType too many parameters?
Posted: Tue Dec 24, 2019 10:36 am
by wilbert
Rinzwind wrote:I guess not possible then. Just asking to be sure... Just playing around with media keys...
No, not possible with CocoaMessage.
If you really need the functionality you can work around it but that's less easy.
Re: NSEvent otherEventWithType too many parameters?
Posted: Tue Dec 24, 2019 3:35 pm
by Justin
Once I had to use that function and I did something like this, I am on a VM so I don't know if it really works although the function returns a value.
Code: Select all
EnableExplicit
PrototypeC NSEventOtherEventWithTypeProto(class.i, sel.i, type.i, locx.f, locy.f, flags.i, time.d, wNum.i, gctx.i, subtype.w, data1.i, data2.i)
Global.i NSEventClass, NSEventOtherEventWithTypeSel
Global.NSEventOtherEventWithTypeProto NSEventOtherEventWithTypeImp
Macro NSEventOtherEventWithType(iType, ptLocation, iFlags, dTime, iWinNum, iGctx, wSubtype, iData1, iData2)
NSEventOtherEventWithTypeImp(NSEventClass, NSEventOtherEventWithTypeSel, iType, ptLocation\x, ptLocation\y, iFlags, dTime, iWinNum, iGctx, wSubtype, iData1, iData2)
EndMacro
Procedure LoadNSEventFunctions()
NSEventClass = CocoaMessage(0, 0, "NSEvent class")
NSEventOtherEventWithTypeSel = sel_registerName_("otherEventWithType:location:modifierFlags:timestamp:windowNumber:context:subtype:data1:data2:")
NSEventOtherEventWithTypeImp = method_getImplementation_(class_getClassMethod_(NSEventClass, NSEventOtherEventWithTypeSel))
EndProcedure
;- START
#NSSystemDefined = 14
#KMUTE = 7
Procedure MediaKeyPress(k1)
Protected p.NSPoint, flags, data1, data2
flags = $a00 ;down
data1 = (k1 << 16) | ($a << 8) ;down
NSEventOtherEventWithType(#NSSystemDefined, @p, flags, 0, 0, 0, 8, data1, -1)
flags = $b00 ;up
data1 = (k1 << 16) | ($b << 8) ;up
NSEventOtherEventWithType(#NSSystemDefined, @p, flags, 0, 0, 0, 8, data1, -1)
EndProcedure
LoadNSEventFunctions()
MediaKeyPress(#KMUTE)
Re: NSEvent otherEventWithType too many parameters?
Posted: Tue Dec 24, 2019 4:22 pm
by wilbert
Justin wrote:Once I had to use that function and I did something like this
Using a method implementation pointer with a prototype is indeed a way to do it.
But inside the prototype, it's best to type locx and locy as CGFloat.
For the x64 version of PureBasic, .f is wrong since CGFloat is a double .d on x64.
Re: NSEvent otherEventWithType too many parameters?
Posted: Tue Dec 24, 2019 4:45 pm
by Justin
Ok i will change it when i can. Does the Media function acrually work? Is there another way to do it?
Re: NSEvent otherEventWithType too many parameters?
Posted: Wed Dec 25, 2019 8:53 am
by wilbert
Justin wrote:Does the Media function acrually work?
If it is supposed to mute all sounds system wide, I can't get it to work so far
Besides creating an event, you also have to post the event but even that doesn't seem to help.
Another way to call the function is yo use NSInvocation, which is what CocoaMessage does internally.
But that's a lot more work.
Re: NSEvent otherEventWithType too many parameters?
Posted: Thu Dec 26, 2019 10:58 am
by Justin
Just translated this code to simulate system hot keys from stack overflow and it works. Like I said I can't test the mute key.
https://stackoverflow.com/questions/107 ... de-hotkeys
Code: Select all
;https://stackoverflow.com/questions/10734349/simulate-keypress-for-system-wide-hotkeys
;Simulate keypress for system wide hotkeys
;Brings spotlight search.
EnableExplicit
#kCGEventFlagMaskCommand = $00100000
Define.i src, cmdd, cmdu, spcd, spcu, loc
src = CGEventsourceCreate_(#kCGEventSourceStateHIDSystemState)
cmdd = CGEventCreateKeyboardEvent_(src, $38, #True)
cmdu = CGEventCreateKeyboardEvent_(src, $38, #False)
spcd = CGEventCreateKeyboardEvent_(src, $31, #True)
spcu = CGEventCreateKeyboardEvent_(src, $31, #False)
CGEventSetFlags_(spcd, #kCGEventFlagMaskCommand)
CGEventSetFlags_(spcu, #kCGEventFlagMaskCommand)
loc = #kCGHIDEventTap ;kCGSessionEventTap also works
CGEventPost_(loc, cmdd)
CGEventPost_(loc, spcd)
CGEventPost_(loc, spcu)
CGEventPost_(loc, cmdu)
;Put a delay, spotlight search disapears when losing focus after program exits.
Delay(2000)
CFRelease_(cmdd)
CFRelease_(cmdu)
CFRelease_(spcd)
CFRelease_(spcu)
CFRelease_(src)
Re: NSEvent otherEventWithType too many parameters?
Posted: Thu Dec 26, 2019 11:13 am
by wilbert
Justin wrote:Just translated this code to simulate system hot keys from stack overflow and it works.
Nothing happens if I run your code (macOS 10.15.2)
Re: NSEvent otherEventWithType too many parameters?
Posted: Thu Dec 26, 2019 11:50 am
by Justin
Does the spotlight search appear if you press cmd+space?
Maybe the shortcuts change from Mac OS version, try the code with a shortcut that works on your system.
Re: NSEvent otherEventWithType too many parameters?
Posted: Thu Dec 26, 2019 12:01 pm
by wilbert
Justin wrote:Does the spotlight search appear if you press cmd+space?
Yes, it does.
But not with the code you posted.
Maybe something has changed when it comes to permissions.
Re: NSEvent otherEventWithType too many parameters?
Posted: Thu Dec 26, 2019 1:41 pm
by Justin
The cmd key code was wrong from SO but not sure is the problem, try this one, pressing the test button simulates cmd+tab to switch to the next app, the pb ide in my case.
Code: Select all
;https://stackoverflow.com/questions/10734349/simulate-keypress-for-system-wide-hotkeys
;Simulate keypress for system wide hotkeys
EnableExplicit
#kCGEventFlagMaskCommand = $00100000
#kVK_Tab = $30
#kVK_Space = $31
#kVK_Command = $37
#kVK_ANSI_Comma = $2B
#kVK_Return = $24
#kVK_ANSI_G = $05
Define.i src, cmdd, cmdu, spcd, spcu, loc, keyd, keyu, retd, retu, ev, btn
src = CGEventsourceCreate_(#kCGEventSourceStateHIDSystemState)
cmdd = CGEventCreateKeyboardEvent_(src, #kVK_Command, #True)
cmdu = CGEventCreateKeyboardEvent_(src, #kVK_Command, #False)
keyd = CGEventCreateKeyboardEvent_(src, #kVK_Tab, #True)
keyu = CGEventCreateKeyboardEvent_(src, #kVK_Tab, #False)
; retd = CGEventCreateKeyboardEvent_(src, #kVK_Return, #True)
; retu = CGEventCreateKeyboardEvent_(src, #kVK_Return, #False)
CGEventSetFlags_(keyd, #kCGEventFlagMaskCommand)
CGEventSetFlags_(keyu, #kCGEventFlagMaskCommand)
;kCGSessionEventTap
loc = #kCGHIDEventTap
OpenWindow(0, 10, 10, 500, 400, "", #PB_Window_SystemMenu)
btn = ButtonGadget(0, 10, 10, 80, 30, "Test")
Repeat
ev = WaitWindowEvent()
Select ev
Case #PB_Event_Gadget
;cmd+tab to switch app
CGEventPost_(loc, keyd)
CGEventPost_(loc, keyu)
CGEventPost_(loc, cmdu)
EndSelect
Until ev = #PB_Event_CloseWindow
; CFRelease_(cmdd)
; CFRelease_(cmdu)
; CFRelease_(keyd)
; CFRelease_(keyu)
; CFRelease_(src)
Re: NSEvent otherEventWithType too many parameters?
Posted: Thu Dec 26, 2019 2:20 pm
by wilbert
No difference.
After some reading ...
On macOS 10.15 it seems you have to give an app permission to monitor system wide keyboard input in system preferences > privacy settings.
Re: NSEvent otherEventWithType too many parameters?
Posted: Thu Dec 26, 2019 8:01 pm
by Justin
I upgraded to Catalina and after pressing the button a message showed up to let the app grant access, in
System Preferences - Security & Privacy - Privacy - Accessibility add the app to the list and works as expected.
Re: NSEvent otherEventWithType too many parameters?
Posted: Fri Dec 27, 2019 8:04 am
by wilbert
Justin wrote:I upgraded to Catalina and after pressing the button a message showed up to let the app grant access, in
System Preferences - Security & Privacy - Privacy - Accessibility add the app to the list and works as expected.
You are right. Simulating mute also works fine now.
Code: Select all
PrototypeC NSEventOtherEventWithTypeProto(obj, sel, type, locx.CGFloat, locy.CGFloat, flags, time.d, wNum, ctx, subtype.w, d1, d2)
Global NSEventClass, NSEventOtherEventWithTypeSel, NSEventOtherEventWithTypeImp.NSEventOtherEventWithTypeProto
NSEventClass = CocoaMessage(0, 0, "NSEvent class")
NSEventOtherEventWithTypeSel = sel_registerName_("otherEventWithType:location:modifierFlags:timestamp:windowNumber:context:subtype:data1:data2:")
NSEventOtherEventWithTypeImp = method_getImplementation_(class_getClassMethod_(NSEventClass, NSEventOtherEventWithTypeSel))
#NSEventTypeSystemDefined = 14
#NX_KEYTYPE_MUTE = 7
Procedure MediaKeyPress(k)
Protected NSEvent
NSEvent = NSEventOtherEventWithTypeImp(NSEventClass, NSEventOtherEventWithTypeSel, #NSEventTypeSystemDefined, 0, 0,
$a00, 0, 0, 0, 8, (k << 16) | $a00, -1)
CGEventPost_(0, CocoaMessage(0, NSEvent, "CGEvent"))
NSEvent = NSEventOtherEventWithTypeImp(NSEventClass, NSEventOtherEventWithTypeSel, #NSEventTypeSystemDefined, 0, 0,
$b00, 0, 0, 0, 8, (k << 16) | $b00, -1)
CGEventPost_(0, CocoaMessage(0, NSEvent, "CGEvent"))
EndProcedure
MediaKeyPress(#NX_KEYTYPE_MUTE)