Globally monitoring NSMouseMoved returns NSMouseUp - objective-c

I'm trying to register the NSMouseMoved event globally using this line of code:
[NSEvent addGlobalMonitorForEventsMatchingMask:NSMouseMoved handler:mouseMovedBlock];
However, my mouseMovedBlock only gets called when the mouse gets clicked and not when the mouse is moved. I tried detecting the type of the NSEvent and it returns NSMouseUp, which doesn't really make any sense.
Why is my program acting so strange / what did I miss?

Turns out it was a simple mistake. I just changed "NSMouseMoved" to "NSMouseMovedMask". I simply forgot that it needed to be an event mask instead of a normal event type.

Related

Unreal Engine 4 Blueprint

Im new to unreal
I have a problem with the communication from Hud_Blueprint to Level_Blueprint.
I want to have a slider in the Hud which controls the rotation of a cube in the level.
In the Hud_Blueprint i have the slider I made in a Widget_Blueprint.
Works perfect, printline values from 0 to 1.
I tried to use a Interface_Blueprint, like in the following link without success.
https://answers.unrealengine.com/questions/22126/pass-variable-from-hud-blueprint-to-level-blueprin.html
my Blueprints:
https://www.dropbox.com/s/k30ah9fjuwlff6x/zusammen.jpg?dl=0 (404 response)
Seems like i have no connection between the Blueprints.
The function works just in the Hud_Blueprint.
Well, your problem is maybe solved, but someone can find it helpful:
First, create new WidgetBlueprint and name it "Slider".
In Slider editor create Event Dispatcher called "ValueChanged" with float input. In designer, add slider and add it's OnValueChanged. From that node you must call ValueChanged with obtained Value as parameter.
In level blueprint, on EventBeginPlay create SliderWidget and Add (return value) To Viewport. You must promote Slider to variable to use it in next step - Assign ValueChanged with new event which will cover up rotation login in it's execution. See image at Dropbox
If you select your cube in the level outliner and drag that into your HUD_BP you can obtain a reference to the object that way. You can then drag a pin off the object reference and call SetActorRotation

Can I call a method without triggering its event listeners?

Is there any sort of flag or way to call a method without triggering any event handlers?
FOR EXAMPLE
I'm handling a controlTextDidChange method and checking to see if the character returned by a keystroke is valid. If it's not, I remove it; if it is, I append a word. The problem is that when I change the text while in controlTextDidChange, controlTextDidChange is called again and the program will loop indefinitely. I know I can use an instance variable to get around this, but is there any sort of flag or way to call a method without triggering any event handlers?
To expand the comment into a quick answer.
You have a method that issues a notification by design. You want it to not issue that notification. You don't have an alternative available that does the same thing w/o the notification. If you want it to never issue that notification, and you have access to the code for the method, you could swizzle the method to a version where you've just commented out the notification. Of course, if you had the code, you could just add another method, and call that one. So you don't have the code, and all that's moot.
Can't you just bracket that invocation in code that removes the listener and then restores the listener? In other words, psuedocode like this:
[self.controlThingy removeObserver:self]
[self.controlThingy myMethod]
[self.controlThingy addObserver:self]
You've then made self deaf to notifications for that one invocation of myMethod. I've done similar things with bindings and KVO.

How to change variables between scripts in UnityScript?

I made a game have two objects in the hierarchy panel. One called GameScreen and another called Clock I set up. Each has its own script attached. GameScreen uses game.js and the other uses clock.js.
When I win the game a popup box appears and says, "You've won!" This is caused by the game.js script. However, the clock.js is still running, so my clock is still counting down. When the time is up the clock.js makes a popup box saying, "you lose!"
This causes for a "you win" screen to pop up when you win and then later a you lose screen to appear. As you can probably guess, this is super annoying. If there was a way I could change variables in one script from another,, I could get the clock to stop when you won or I could get the game to stop when the time ran out.
Is there some way to do this??
For example here are two javascript files one on clock and the other on GameScreen . I want the first one to change the variable changeMe in the second to two.
1.js:
function start(){
}
2.js:
var changeMe:int;
When you win the game, you can change clock's variable from game.js this way:
GameObject.Find("Clock").GetComponent("clock.js").variable_name = new_value;
, where [variable_name] and [new_value] obviously depend on your project. variable_name has to be an exposed variable.
You can simply use SendMessage() it will make you able to call a function from another object easily.Basically you need to write a function to destroy the clock after wining the game,let's say your function is called destroyClock so you should add that to your game.js script:
gameobject.Find("here goes the name of your clock obj").sendMessage("destroyClock")

how to continue after calling objc_msgSend

I am doing meta-programming with objective-C and try to automate some of an application functions. Thus, I am not changing the source code files and the view controllers of the application but from another file I am managing to get the UI navigation stack and I am using Objective-C Runtime Reference to find the tappable UI elements and the actions. for example for a button I found the target and action and call objc_msgSend to programatically fire the event.
step = (NSObject *)objc_msgSend(element.target, NSSelectorFromString(element.action));
However I need to be notified when the action was done, or in other word, I need to wait until the action was done and then continue my automation. I was thinking of using NSNotificationCenter
//To raise an event
[[NSNotificationCenter defaultCenter] postNotificationName:FIRE_EVENT_NOTIFICATION object:self];
but doesn't look like working.
I am even thinking of using Categories or
So I am not sure if there is anyway to wait for objc_msgSend and where should I continue.
It isn't entirely clear what you are trying to do and the exact problem that you are having but I'll have a go at answering your question.
If I understand correctly you are trying to fire the action associated with a UI element, presumably something like a button press. You have a reference to the element in element and you want to call the associated action on the elements target. The following assumes the action is an IBAction.
The simplest way to do this would presumably be:
[element.target performSelector:element.action];
Note: element.action almost certainly returns a SEL (a selector) not an NSString so there is no need to run it through NSSelectorFromString().
Normally, an IBAction event would receive the clicked on element as a parameter so I think you might want to do:
[element.target performSelector:element.action withObject:element];
IBAction's have no return value so there is nothing to store when the method returns.
performSelector: and performSelector:withObject: will only return once the called method has run to completion. You shouldn't need to organise some sort of notification of the action completing.
However, if the action you are calling is launching code on another thread then it is possible that the called action will return before the result of pressing the button has completed. This will be difficult to monitor without knowledge of the code that is being run.
If, for some reason, you have to use objc_msgSend then you would use the following:
objc_msgSend(element.target, element.action, element);
Like performSelector:, objc_msgSend will only return when the called method has run to completion.
Hopefully I have understood your question and my answer makes sense, it is entirely possible I'm barking up the wrong tree though.

How to monitor global modifier key state (in any application)?

I'm using some Carbon code in my Cocoa project for handling global key events (shortcuts) from other applications. Currently I have setup a kEventHotKeyReleased event handler and I can successfully obtain hot keys when my application is not active. That triggers some operation in my application.
The problem I have with the behavior of kEventHotKeyReleased is:
Say for example I press the Cmd-Shift-P key combination. As soon as I release the "P" key the hot key event is triggered. I need to be able to trigger the event (or manually trigger it) when all of the keys are unpressed (i.e: the Cmd and Shift keys are released too).
It is easy to monitor for hot keys but I have seen nothing for monitoring individual keystrokes. If I could monitor the modifier key states I would be in business.
Any hints on how to do this?
Thanks in advance!
UPDATE:
I've tried using kEventRawKeyUp and kEventRawKeyModifiersChanged but while kEventHotKeyReleased works those two don't even though I set them up in the exact same way as kEventHotKeyReleased.
EventTypeSpec eventTypes[] = {{kEventClassKeyboard, kEventHotKeyReleased}, {kEventClassKeyboard, kEventRawKeyUp}};
// Changing the order in the list does not help, nor does removing kEventHotKeyReleased
OSStatus err = InstallApplicationEventHandler(&globalHotkeyHandler, GetEventTypeCount(eventTypes), eventTypes, NULL, NULL);
// err == noErr after this line
The globalHotKeyHandler method is called for kEventHotKeyReleased, but not for kEventRawKeyUp for some reason I can't seem to grasp. Here's what my globalHotKeyHandler method looks like:
OSStatus globalHotkeyHandler(EventHandlerCallRef nextHandler, EventRef anEvent, void *userData) {
NSLog(#"Something happened!");
}
Is there an additional call that needs to be made or something else I forgot?
N.B: At first glance, it seems like it could be that Access for Assistive Devices is disabled but it is not. So I'm pretty clueless.
UPDATE 2:
I investigated a bit on the CGEventTap Leibowitzn suggested and I came up with this setup:
CFMachPortRef keyUpEventTap = CGEventTapCreate(kCGHIDEventTap,kCGHeadInsertEventTap,kCGEventTapOptionListenOnly,kCGEventKeyUp,&keyUpCallback,NULL);
CFRunLoopSourceRef keyUpRunLoopSourceRef = CFMachPortCreateRunLoopSource(NULL, keyUpEventTap, 0);
CFRelease(keyUpEventTap);
CFRunLoopAddSource(CFRunLoopGetCurrent(), keyUpRunLoopSourceRef, kCFRunLoopDefaultMode);
CFRelease(keyUpRunLoopSourceRef);
... and the callback:
CGEventRef keyUpCallback (CGEventTapProxy proxy, CGEventType type, CGEventRef event, void *refcon) {
NSLog(#"KeyUp event tapped!");
return event;
}
As you can see I'm using kCGEventKeyUp as the mask for the event tap but somehow I'm receiving mouse down events ??!??
UPDATE 3:
Ok forget that, I overlooked the line in the doc that said to use CGEventMaskBit(kCGEventKeyUp) for this parameter, so the correct call is:
CGEventTapCreate(kCGHIDEventTap,kCGHeadInsertEventTap,kCGEventTapOptionListenOnly,CGEventMaskBit(kCGEventKeyUp),&keyUpCallback,NULL);
I'm still having a problem though: modifier keys do not trigger the kCGEventKeyUp...
UPDATE 4:
Ok forget that again... I'm bound to answer to my own questions 5 minutes after asking them today huh!
To intercept modifier keys, use kCGEventFlagsChanged:
CGEventTapCreate(kCGHIDEventTap,kCGHeadInsertEventTap,kCGEventTapOptionListenOnly,CGEventMaskBit(kCGEventFlagsChanged),&callbackFunction,NULL);
So in essence I got the key and modifier key state detection working, but I'm still interested in knowing why kEventRawKeyUp doesn't work...
N.B: Also note that I'm developing on Tiger with the goal of having support for new and older versions of the OS as much as possible. CGEventTap is 10.4+ only so I'll be using this for now but a backwards-compatible solution would be welcome.
One option is to use EventTaps. This lets you monitor all keyboard events. See:
http://developer.apple.com/mac/library/documentation/Carbon/Reference/QuartzEventServicesRef/Reference/reference.html#//apple_ref/c/func/CGEventTapCreate
Unfortunately event taps will stop working if an application is requesting secure input. For example Quicken.
OSStatus err = InstallApplicationEventHandler(&globalHotkeyHandler, GetEventTypeCount(eventTypes), eventTypes, NULL, NULL);
This is not global. This installs the handler only when your own application is active, and (I believe) after the Carbon Event Manager's own event filters.
You need to use InstallEventHandler, which takes an event target as its first parameter (InstallApplicationEventHandler is a macro that passes the application event target).
For events that occur while your application is not active, the target you want is GetEventMonitorTarget(). For events that occur while your application is active, the target you want is GetEventDispatcherTarget(). To catch events no matter what application is active, install your handler on both targets.
Nowadays, though, I'd just use CGEventTaps, as Leibowitzn suggested.