I can open a Terminal tab using the following AppleScript:
tell application "Terminal"
set myTab to do script "exec sleep 1"
get myTab
end tell
This returns a string like: tab 1 of window id 3263 of application "Terminal"
. This is great, I can see the window id 3263 and tab number 1 (although I don't know how to query myTab to get only these values).
In the Cocoa ScriptingBridge, I can do:
SBApplication *terminal;
SBObject *tab;
terminal = [SBApplication applicationWithBundleIdentifier:@"com.apple.terminal"]
tab = [terminal doScript:@"exec sleep 1" in:nil]
How do I get the window id and tab number from the tab object?
Edit 2009/4/27 - Why?
In answer to why I want to do this - I am opening a command in a Terminal window (as above), and am getting back the tab object. However I want to move/resize this window, so I need to get access to the tab's "window" object.
I am using Objective-C (well actually, Objective-C bridged from Perl), and want to stick to standard OS components, so I believe I only have the NSAppleScript and ScriptingBridge frameworks to play with (all the perl applescript modules broke with 64bit carbon removal). I would try NSAppleScript, but processing the returned values seems to be a black-art.
My current solution is to get the TTY of the tab object (guaranteed unique) and enumerate every tab of every window until I find the window containing the tab. I assumed that this couldn't be the best way (it sure ain't fast!).
Edit 2009/4/30 - Solution
Based on the suggestions of "has" below, I braved the NSAppleEventDescriptor API. Initially, I was only able to get to this with NSAppleScript's executeAndReturnError()
call. However I found that NSAppleScript was much, much slower than ScriptingBridge.
After using ClassDump to extract some more SBObject calls, I found the undocumented specifierDescription()
and qualifiedSpecifier()
calls. The former gives me the nice "tab X of window id Y" string. The latter returns the apple event descriptor, which I can then decode.
My final code (in perl) is:
use Foundation;
NSBundle->bundleWithPath_('/System/Library/Frameworks/ScriptingBridge.framework')->load;
# Create an OSType (bid endian long) from a string
sub OSType ($) { return unpack('N', $_[0]) }
my $terminal = SBApplication->applicationWithBundleIdentifier_("com.apple.terminal");
my $tab = $terminal->doScript_in_("exec sleep 1", undef);
my $tab_ev_desc = $tab->qualifiedSpecifier;
my $tab_id = $tab_ev_desc->descriptorForKeyword_(OSType 'seld')->int32Value;
my $win_ev_desc = $tab_ev_desc->descriptorForKeyword_(OSType 'from');
my $window_id = $win_ev_desc->descriptorForKeyword_(OSType 'seld')->int32Value;
print "Window:$window_id Tab:$tab_id\n";