How to mark the NSEvent as handled? - swift

I handle pressing of letter keys on keyboard with the following code.
NSEvent.addGlobalMonitorForEvents(matching: NSEvent.EventTypeMask.keyDown) { event in
// code
}
How do I then mark the NSEvent as handled, not allowing it to be handled again by system and another apps? For example do not allow the input of a pressed letter in the opened text editor?

You can't do that with NSEvent. As the docs note:
Events are delivered asynchronously to your app and you can only observe the event; you cannot modify or otherwise prevent the event from being delivered to its original target application.
You're not part of the event-generation system; you're just getting notifications as part of your runloop.
If you want to become part of the event system, below the app layer, you need to use CGEvent. See tapCreate(tap:place:options:eventsOfInterest:callback:userInfo:). The callback can return NULL to indicate it's consumed the event.

Related

swift - how to prevent two touches at the same time

For example, I have 2 buttons Change email and Change password, and each of them call functions with Alamofire request, and responce data should reload both the UI and data scheme.
The point is that this PUT requests change not only servers's data, but generate new token and get updated user's profile.
And when pressing buttons at the same time, at the same moment touches begin and end, app crash after parsing requests.
I'm blocking another UI elements(like textfields), I was trying to block another button, but when press it together, it's not works.
So how can I prevent the same time touch? I'm not good at OperationQueue, maybe thats'the way? Is there an option to check if operation not first at the queue and kill it?
Set isExclusiveTouch of your UIButton to true in order to trigger only one button action in a specific time.
This code will get all the buttons contained in the view and set the exclusiveTouch to true:
self.view.subviewsRecursive()
.filter { $0 is UIButton }
.forEach { $0.isExclusiveTouch = true }
This problem with the UIResponder object is very usual. However, your problem description is not clear and your implementation seems not so good.
Here, to resolve this quick touch event problem:
Your solution is debouncing the action event of UIButton.
Debouncing also helps to prevent multiple executions when a user mistakenly pressed a button (or any UIResponder object) multiple times so quickly that even the UI was not blocked till then. Following article may guide you more regarding the same:
Debouncing to tackle repeating user action

Handling key events in OS X with Swift and Cocoa

I have a very basic OS X that has a few different elements.
A text field, a table view and a file contents view.
I have a single ViewController.
I'd like to be able to intercept specific key events for each of these elements in the storyboard in my ViewController and change the focus between the different elements.
For example, if the cursor is currently in the file contents view, and I hit ESCAPE, I'd like for the focus to be transferred to the text field.
Or, if the focus is currently on the table view and I hit ENTER, that the cursor/focus is moved to the file contents view.
What's the best way to handle this?
I have tried overriding the keyDown method in the ViewController but with things such as autocomplete getting in the way, I'm not having much luck. I have added a print statement to keyDown to check if the function is receiving events, but it's not always fired.
Update
Except for the specific keys that I want to intercept, I want all other key events to behave as normal. For example, typing in the file contents view, or the text field.
I would highly recommend watching the WWDC talk #145 from 2010, Key Event Handling in Cocoa Applications. It gives an overview of the event delivery mechanism, and several ways of handling events:
Make a menu item or button whose keyEquivalent is the escape key.
Override cancelOperation(_:) or complete(_:), which are the two NSResponder methods which can get invoked by default when the escape key is pressed. (There are other methods for the enter/return key.)
Override sendEvent(_:) in NSApplication or NSWindow to intercept all events and bypass the default behavior.

Is keeping the key pressed equal to pressing the key many times quickly

I'm not sure if this is the right place to ask this question. It's not an application specific question nor it is about any concrete problem. However, to make it more application specific, I'll take the example of Photoshop.
The shortcut to reduce the brush size is [. When I keep it pressed, the brush size reduces quickly with some inertia. I wanted to know how this is implemented. Does it send the keypress event multiple times or does it send the keypress event along with the key down duration, to which the application responds according to the duration?
I suppose this also depends on the OS? I want to know more specifically OSX.
I don't know what's the behavior on OS X, but this article shows some ways how you can find it out by yourself (without reading the developer manuals):
Super User: Mouse button and keypress counter for Mac OS X
On Windows and .NET and "Windows Forms" as the development platform, the behavior would be
MSDN: System.Windows.Forms → KeyPressEventArgs Class
...A KeyPress event occurs when the user presses a key. Two events that are closely related to the KeyPress event are KeyUp and KeyDown. The KeyDown event precedes each KeyPress event when the user presses a key, and a KeyUp event occurs when the user releases a key. When the user holds down a key, duplicate KeyDown and KeyPress events occur each time the character repeats. One KeyUp event is generated upon release...
See also:
MSDN: System.Windows.Input → Keyboard Attached Events
Application code typically handles all three events, while the KeyPress is actually computed from the down/up signals. Because it mimics the signals received from hardware (see http://wiki.osdev.org/Keyboard for more details) which is OS-neutral I'd expect the OS-APIs to be conceptually very similar

Xcode/iPhone -- break when the next event enters my code?

I am working on a large (>30k lines) event-driven app. I have a sequence of inputs that produces a bug. What I want to do is to break as soon as the final input enters my code.
Is there a general way to do that?
I understand that for any specific sequence of inputs, I can find out where that last input is going to enter my code, then set a breakpoint there. What I would like to do is take out the step of "find out where that last input enters my code." In other words, I am running the app in the simulator, and I want to set a flag somewhere that says "break the next time you are going to enter non-system Objective C code." Then I send the event that causes the problem.
I understand what you are asking, but have you tried using an Exception Breakpoint? This will basically act like an auto-inserted breakpoint on the piece of code that throws the exception. If that doesn't work for you, try a symbolic breakpoint
If you want to intercept UI events, you can try subclassing UIWindow and overriding its sendEvent: method, then setting this class as the class of the UIWindow object in your main XIB file. sendEvent: will be called each time the user generates a touch event. Unfortunately, at this point you cannot yet know which UI object will finally consume the event (read: which event handler code will be ultimately called) since that depends on the actual state of the responder chain. But anyway, you can use this method to inject events into the system.

RichEdit control: Determine when text is changed?

I'm trying to count the number of times that text is changed in a given RichEdit control. I considered using events like key down, but that gets messy when you consider keys that don't change the text (like arrows, page up, etc). And how do you make sure you get all of those keys?
It seems it would be simpler to register a callback for a onTextChanged event, if one exists. Is there any way to do something like that?
Well you need to listen to the EN_CHANGE message if your using C++. Note that you also have to call SetEventMask with ENM_CHANGE to receive these notifications unlike a normal edit control will sends these messages by default.