What OS X events can I access programmatically from Swift? - objective-c

I'd like to find both current running programs (or at least program in the foreground) programmatically - and also key events on OS X.
I found inter-application communication guidelines, but they don't seem to say I can find out what applications are running.
I've found key events, but it seems to imply that the current task in the forefront is the one that gets the key events and only if it doesn't handle them does it go up to event chain. I'd like to programmatically intercept them.
Seems dubious, I know. I'm trying to use key events along with screen captures to try to best learn text on the screen - it's for research.
I'm using swift, but I understand that an obj-c example is pretty helpful since they all use the same libraries.

To get a list of running applications use:
NSWorkspace.sharedWorkspace().runningApplications
You can build a key logger (so to speak) by creating an event monitor (same document you linked, just a different section).

Related

Global events for Show desktop, show notification center, etc. in cocoa

for my program, I need to be able to discriminate between when users are performing some actions using gestures on the trackpad and when using corresponding hotkeys. Typically, I need to know when users show desktop, and if he performed an associated hotkey or associated gesture. Same for switching spaces, etc...
Basically, I have this need for showing notification center, application windows, show desktop, show dashboard,etc... Being able to handle hot corners would even be a plus.
So far I was hoping to be able to investigate global monitors for events, using NSAnyEventMask and slightly reverse engineer to figure out what type is the "Mission control open" event, but this was not a success. In fact, NSAnyEventMask does not seem to work at all as my method is never called (while it is with other masks such as keydown or mousemove).
I also had a look at the accessibility features, hoping I could add a relevant AXObserver notification, but did not find anything neither. I guess this is not surprising since the accessibility API provides a description of basic graphical components such as menus, windows, etc... therefore, virtual spaces and notification centers are not described by it.
Finally, CGevent tap does not seem to handle these events as when I use the function keys for showing desktop, the only events handled by my CGeventTaps are the corresponding keydown and keyup events.
I suspect few possible outcomes.
(1) I have been amazing at trying, but unfortunately this is not possible at all to handle these events ... I seriously doubt this as first I am far from being an amazing programmer, especially in Cocoa, and second, apple prove me that this is possible to access lots of amazing events programmatically and I believe in the power of their API.
(2) I have tried the good methods, but failed because of side factors. It is likely.
(3) other methods could help me to handle these events globally and programmatically (private API?).
Thanks a lot for your help,
Kind regards,
Just saw this, but this is caused by an error in Apple's implementation of NSAnyEventMask. The docs describe NSAnyEventMask as 0xffffffffUyet the implementation of NSAnyEventMask is an NSUIntegerMax which is 0xffffffffffffffffU. This is possibly due to the transition from 32 bit to 64 bit computers which changes NSUInteger's from unsigned int's to unsigned long's. Replacing NSAnyEventMask with '0xffffffffU' fixes the problem. I've already listed this as a bug to apple in hopes they would fix this.

API for intercepting text input in another app?

I was wanting to make an app similar to something like TextExpander, but I am not sure how you would intercept the text. As far as I can tell, I need to start with NSAccessability. Could anyone share some snippets, or at least point me in the right direction?
First off, you should be aware that, because of the sandboxing requirement, this isn't possible at all if you want to sell your app in the App Store.
If you don't intend to sandbox your app, you can use the NSEvent class method addGlobalMonitorForEventsMatchingMask: to create a global key event handler that gets called when keys are pressed in other apps (but not your own app, use addLocalMonitor... for that).
To actually insert snippets, like TextExpander, there are several ways. You can use the accessibility APIs, but that requires that the app(s) you're targeting support accessibility, which isn't always the case.
Another option is to use the Quartz Event Services (CGEvent) APIs which provide (among other things) a low-level method to simulate key events.
Edit: Nevermind. You're asking about Mac OS. I thought you were asking about iOS.
You should look at how TextExpander is used by other apps. The target app has to build in support for TE by making an object provided by TE a delegate of the text field. You can't run your code in someone else's app. They have to compile your code into their app. That's why there's a TextExpander SDK.
Once the TextExpander code is in the target app, the text field delegate gets the shared snippets by looking for snippets put into a shared pasteboard.

How to simulate user input in objective-c?

On windows, and with c#, I was able to capture another window's "screen", use that for processing, and then send user input events to that window. (which were generated by the program).
I would like to do the same with objective-c and within Mac OS X. So! Any resources or even a name for what I'm trying to do would be great. It's very frustrating to try and find information on this when the only ways i can think to phrase my searches are too ambiguous.
Thanks!
EDIT: As a specific example, there might be a particular game that I want to make an AI for. In that case I would need to be able to send mouse and keyboard events to the game.
If you're looking to do automated user interface testing, look at Squish, eggPlant, expect and OS X Accessibility. If you're looking to programmatically control another program, use scripting (if you wrote the program to control, add scripting support; otherwise, see what scripting support the program offers), or try Automator.

Window list ordered by recently used

I'm trying to create a window switching application. Is there any way of getting a list of the windows of other applications, ordered by recently used?
Start with the Accessibility framework. Many of the hooks for screen readers are also useful here. Particularly look at the UIElementInspector sample and the NSAccessiblity protocol.
There's also Quartz Window services, which can easily give you a list of all the windows on screen. Unfortunately, it doesn't tie into concepts like window focus (just level), and I don't know of a way to get notifications back from it when levels change. You might do something like tap into the Quartz Event framework to capture Cmd-Tab and the like, but that's complex and fragile. There is unfortunately no good way to convert a CGWindowID into an AXUIElementRef (the post is for 10.5, but I don't know of anything that was added in 10.6 to improve this). But hopefully you can do everything you need through the Accessibility framework.
You would want to use
[NSWorkspace runningApplications]
to get you a list of all the applications running, and watch
[NSRunningApplication currentApplication]
to know when the user switches to a new application to keep up with which one is used more recently.

In OSX, how do I determine the position of windows, and which window is active?

I'm working on an idea for a type of window manager for OSX, similar to Cinch or SizeUp. In order to do this I need to be able to determine the positions of various windows, and which window is active. Some kind of callback when the active window changes would also be useful, as would how to handle multiple screens and multiple spaces.
I'm resigned to the fact that I'll probably need to learn Objective C for this, but if there is a way to do this type of thing from Java, that would be particularly awesome.
Can anyone point me to the appropriate place in the OSX API for these things?
You'll want to take a look at the Accessibility API, as discussed here.