Objective equivalent to AppleScript : Opening directory without bringing every finder window to from - objective-c

There this AppleScript
tell application "Google Chrome" to set index of window 1 to 1
do shell script "open /Volumes"
Which opens a directory in Finder without bringing every onther Finder windows to the front.
Currently I'm using :
[[NSWorkspace sharedWorkspace] openURL:fileURL];
But it has the flaw to bring every Finder windows on the top of others.
Any idea how I could achieve the same behaviour as the AppleScript ?

You can always use NSAppleScript to run applescript code in Objective-C if Cocoa doesn't provide the functionality you want.

At a guess, -[NSWorkspace openURL:] also sends the application an activate event whereas the open process does not.
I'd recommend looking into the LaunchServices API. It's what both NSWorkspace and open use behind the scenes, but gives you more control than NSWorkspace's limited API.
--
p.s. If you do have to call out to open (or any other command line tool) from ObjC, you should use Cocoa's NSTask. (AppleScript's do shell script command is just its [crappy] equivalent of NSTask.)

Related

How to show the NSUserNotification in command-line-tool program?

I want to write a command-line-tool program that only shows the NSUserNotification. I've found out, that in order to show the NSUserNotification I need to create a Cocoa App and is not what I want.
I want to run my program at log-in in background, so that my notification is always visible. How can I do that without creating a Cocoa App?
These are the options I found...
Trick Mac OS X into allowing a notification from a command-line tool.
Trigger the notification using Applescript or a helper application.
Create an Automator workflow & execute it using the automator command.
Automator provides a better experience than Applescript. Didn't try the helper.

Porting CLI/GUI Windows program to OS X

I have a Windows program that has a GUI which also uses a command line interface (a cmd Window) as a debugging console. Basically, when it is double clicked, it launches a command line window and then the program creates all the GUI windows. Then you'd have two Windows: the main GUI and a debugging console.
I'm trying to port this pogram to OS X. Because OS X (and all Unix OSs for that matter) doesn't automatically launch a command line window when you run a command line application. So, I obviously need another way to port this application.
My initial thought was simply to import the source code into a XCode project, redirect standard input and output and then port the GUI. The GUI and console would run side by side just like in Windows. I don't think this is the most optimal solution since that would mean I'd essentially have to write a terminal emulator.
My other thought would be to port the application as a command line application which creates its GUI just like in Windows. The application would then have to be run from Terminal.app which could handle all the I/O. Unfortunately, I don't think you can use the Cocoa framework without using a NSApplication loop.
Any ideas how I could approach this?
You can of course create a run loop from a terminal-launched app. But that generally isn't what you want to do.
It sounds like on Windows, the CLI is just being used as a shortcut to creating a real debugging console window. So the simplest answer is to create a debugging console window. It's pretty easy to create a window which contains just a multi-line text or list view. (If you want something fancier, consider borrowing code from iTerm2 or other open source projects instead of trying to build a complete terminal.) If your debug information is being printed with some fancy macros, just change the macros to log to your list view.
If you're directly doing something like fprintf or syslog to do your logging, it might be simpler to create a wrapper app that launches the main app, and the wrapper creates the debugging console window and displays the main app's stdout and/or stderr. (This might be as simple as using popen.)

In OS X Lion, asking the Finder for the current selection, returns the wrong file

I've confirmed that this is only happening in Lion. I've uncovered what appears to be a bug where you need to focus a window twice in order for Finder to return the correct result over the scripting bridge or AppleScript. This only happens when opening a folder from the desktop or another space.
Here's how to duplicate:
Close, hide or minimize all windows until the desktop is showing.
Open any folder on the desktop, a new finder window will appear. Select any file in that finder window by clicking on it once.
Open your AppleScript Editor and run the following script:
tell application "Finder"
return selection
end tell
The script will return only the path to the folder on the desktop, not the selected file in the finder window.
If you refocus the window, or click on the file again, everything works as expected and the script returns the correct path.
This seems like a bug in Lion. Snow Leopard returns the correct path 100% of the time.
I've tried the following methods with no success:
Using the scripting bridge and https://github.com/davedelong/BetterInfo/blob/master/Finder.h
Using "System Events" apple script to click "Edit"->"Copy"
Using AppleScript to get the current selection from the finder.
All seem to have have the same issue.
Am I missing something obvious or is this truly a problem with Lion?
Wow, I can confirm (at least through applescript) most of what you describe. I was getting an empty list returned, not even the desktop path you mention. I was testing this using a script in the applescript menu. The only way I could get the selection from a fresh Finder window was like this...
tell application "System Events" to activate
tell application "Finder"
activate
set a to (get selection) as text
display dialog a
end tell

possible to modifer the properties of windows in Objective C?

These are windows besides those that belong to the application. For example, how could I change the title of an open application, for example, TextEdit
You could use mach_inject and mach_override to load code into the target application and then simply use the Objective-C API's to access the window.
You could also try using applescript, but no idea if or how that is done.

Why do AppleScript "tell" commands run a non-GUI instance of my GUI application in the background?

I'm writing a standard Cocoa application, and I've just started implementing AppleScript support for it. I've defined and implemented a property called testprop for my top-level application scripting class, and accessing it works just fine: if I launch an instance of my app and run the following AppleScript in Script Editor, I get the output I expect:
tell application "MyApp"
testprop
end tell
However if I run this very same AppleScript in the Script Editor when my app is not running, it returns the last known value for this property, and continues to return it for subsequent calls. I don't see an instance of my app getting started anywhere in the GUI.
After I noticed this, I ran "ps xawww | grep MyApp" in the shell, which told me that a process had been created using my app's main executable, with an argument that looks something like this: -psn_0_323663 (the number at the end changes each time this process is started -- I gather that it's the "process serial number" that AppleScript (among others) uses to keep track of and control processes).
What is going on here? How can I prevent this from happening (i.e. launch my app as a full, proper GUI-enabled instance when AppleScript "tell" commands for it are run)?
Edit:
The above seems to occur only on my laptop. When I try exactly the same thing on my Mac Mini (the OS version is the same on both: 10.5.8), I simply get an error message:
$ osascript -e "tell application \"MyApp\"" -e "testprop" -e "end tell"
26:40: execution error: The variable testprop is not defined. (-2753)
I don't think it's running a "non-GUI" instance, it just hides the app. You could add the line "activate" to the applescript to get the app to become active, in which case you'll see the windows and menu.