Getting process list and hiding a specific app - objective-c

How do I get a process list (in a popup button), and then when the user selects the application, can I hide/kill/minimize/quit the application?

-[NSWorkspace runningApplications] will give you an NSArray of NSRunningApplication instances representing currently-running processes. I'm not exactly sure what causes a program to be excluded from that list, but it does include any application that the user has launched from the Finder. It also includes a couple of things (the Finder itself, and the loginwindow process) that you don't want to mess with, as well as faceless applications.
You can filter those out using filteredArrayWithPredicate:; the objects you want to keep have an activationPolicy of NSApplicationActivationPolicyRegular.
Once the array is filtered, you can search it, using bundleIdentifier, bundleURL, or localizedName to find the app you want. Then send hide or terminate as you like to that NSRunningApplication instance.
Apple has a sample project that demos all this, called AppList.

Related

Get the list of windows for running application on Mac

I used samples from CGWindow API and SonOfGrab samples to get the windows list and grab them, in particularly I used CGWindowListCopyWindowInfo for retrieving the list of windows along with CGWindowListOption specified. However I have a problem here. The thing is that I only want to see the list of windows which belong to a running applications, i.e. I don't want to get windows for dock, system menu etc.
I tried to set kCGWindowListExcludeDesktopElements and kCGWindowListOptionOnScreenOnly flags, they removed some windows I'm not interested in, however even with these options set, I still have 'Dropbox icon in menu bar' window, dock window, system panel window etc. Is there a way to filter them out?
I also tried to request [[NSWorkspace sharedWorkspace] runningApps] to get the list of running applications. My idea was to get the process identifiers from runningApps and remove from the list of windows those ones who don't have process identifiers from the runningApps list. Unfortunately it didn't work out, since the list of running applications is way bigger than I expected and it also contains dashboard applications and other things. I tried to find a property or something like this to distinguish between these 'system apps' and 'real apps', however I wasn't able to achieve this.
Does anyone know how to solve this?
Thanks.
you could:
get the bundle for a running application
check its plist for if it is has a UIElement key -> those wouldn't be in the dock
=> then filter the windows against the remaining PIDs

Icons in Activity Monitor?

In the above image some processes have "icons" beside their names. What characteristic must a process meet to have an "icon" beside its name? Note the defining characteristic is not simply being in the Applications folder since several processes location in the Applications folder don't have the icon.
In addition how can I check if a PID meets the defining criteria in Objective-C? (Using Cocoa on OSX)
I think only applications that appear with their icon in the dock when you open them do have an icon in the activity monitor.
Applications that have "checked in" with Launch Services as a UI app get icons. Technically speaking, anything that ends up calling LSApplicationCheckIn will get one, but that's not a call you can make yourself.
If you run a standard NSRunLoop, or even initialize NSApplication ([NSApplication sharedApplication]) you should get it.
My question is: what are you doing that you're not getting it?

How can I organize the "Window" menu?

I have a document based application. Every document can have multiple windows. Every window is automatically added to the "Window" menu. However, they are added in a more or less random and useless order. I would like the window titles to be organized according to the NSDocument they belong to, similar to how XCode or Photoshop do it.
How can I best do that? How can I prevent the default behaviour of AppKit to add all windows to this special menu, and where should I put the code that adds the menu items in the "correct" manner? I don't want to put handlers into every window controller!
It sure does seem like this is something Cocoa should do automatically. I don't know whether it does, but the first thing to check is whether the window controllers are properly connected to their documents. Does your document subclass's windowControllers property contain all the right objects?
If that's no good, then from NSWindow's reference it looks like the only way to prevent a window whose title has been set from being added to the Windows menu is -[NSWindow setExcludedFromWindowsMenu:]. It looks like you'll want to call that on all your windows, then set up an object (perhaps in the MainMenu nib) that takes care of all the windows' positions and grouping in the Windows menu (via NSApplication's methods). You may need to put in special disabled items and the like to get the grouping to look right. I would hope that windows could still be manually added even if you've previously asked them to be excluded.

Create new document programmatically in Cocoa

I'm wondering if it is possible to send a message (programmatically) to a document-based application to create a new document with some special content inside it. I'm creating two applications and the first has to call the second one sending it some data.
I've tried with the Apple Events but it doesn't seem to work.
There are a number of ways to do this. If you control both applications, probably the simplest is to post a notification to the global notification center from one application, and have the other app listen for it. AppleScript is another way, but requires a bit more work to set up.

Locking a screen in 10.6

How would I go about locking a screen like Keychain does, meaning preventing all access to Dock, menubar, desktop, etc. Basically just a black screen that I can add a password field to, for the user to return to the desktop? I am well aware of the Carbon method, but I want the NSApplication method because this is an all Cocoa application.
Thanks~
If you can get away with not writing this code yourself, all for the better. It is usually a terrible idea to write your own code to lock the screen, considering the number of vulnerabilities that have been found in screen locking code over the years. If you have a Carbon call that can do it, go ahead and use that... don't worry about the "purity" of your Cocoa code.
However, if you decide to write this yourself, here's what you do:
First, capture all the screens using CoreGraphics. See: http://developer.apple.com/mac/library/documentation/GraphicsImaging/Conceptual/QuartzDisplayServicesConceptual/Articles/DisplayCapture.html
Next, create a new NSWindow and put it in front of the window that's used for capturing the screens. You'll have to call a CG function to get the "order" of the black window covering each screen, and order the new window in front of that. Normally, the black window has an order so far forward that everything is behind it. Put a password field in the window. Do NOT use an ordinary text field or write your own code for password input. The password input field has a ton of special code in it so you can't copy text out of it, and other programs can't listen to keystrokes while you're typing into a password field. So use the one that Apple provides.
Last, put the computer in "kiosk mode". This mode allows you to disable alt-tab, user switching, the menubar and dock, and even the ability to force quit. See: http://developer.apple.com/mac/library/technotes/KioskMode/Introduction/Introduction.html
It's not a lot of code, it just uses a few different APIs so you'll spend most of your time bouncing between API docs. I suggest writing the screen lock code as its own application (just add a new application target to your Xcode project) and then put the screen locker inside your application bundle. This used to be (as of 10.4) how Apple Remote Desktop implemented the "Lock Screen" functionality, but I can't find the app anymore.
I believe the Cocoa replacement to the SetSystemUIMode API was not introduced until 10.6.
If you can live with Snow-Leopard-only code, the answer is - setPresentationOptions: on NSApplication.