Как получить идентификатор окна и номер вкладки окна терминала с помощью AppleScript через ScriptingBridge?
Я могу открыть вкладку "Терминал", используя следующий AppleScript:
tell application "Terminal"
set myTab to do script "exec sleep 1"
get myTab
end tell
Это возвращает строку как: tab 1 of window id 3263 of application "Terminal"
, Это здорово, я вижу окно с идентификатором 3263 и вкладку № 1 (хотя я не знаю, как запросить myTab, чтобы получить только эти значения).
В Cocoa ScriptingBridge я могу сделать:
SBApplication *terminal;
SBObject *tab;
terminal = [SBApplication applicationWithBundleIdentifier:@"com.apple.terminal"]
tab = [terminal doScript:@"exec sleep 1" in:nil]
Как получить идентификатор окна и номер вкладки из объекта вкладки?
Изменить 2009/4/27 - Почему?
В ответ на вопрос, почему я хочу это сделать - я открываю команду в окне терминала (как указано выше) и возвращаю объект табуляции. Однако я хочу переместить / изменить размер этого окна, поэтому мне нужно получить доступ к объекту "окна" вкладки.
Я использую Objective-C (ну, на самом деле, Objective-C соединился с Perl) и хочу придерживаться стандартных компонентов ОС, поэтому я считаю, что у меня есть только платформы NSAppleScript и ScriptingBridge для игры (все модули perl applecript сломались с 64bit удаление углерода). Я бы попробовал NSAppleScript, но обработка возвращаемых значений кажется чёрным искусством.
Мое текущее решение состоит в том, чтобы получить TTY объекта вкладки (гарантированно уникальный) и перечислять каждую вкладку каждого окна, пока я не найду окно, содержащее вкладку. Я предположил, что это не может быть лучшим способом (это, конечно, не быстро!).
Редактировать 2009/4/30 - Решение
Основываясь на предложениях " has" ниже, я выдержал API NSAppleEventDescriptor. Изначально я смог добраться до этого только с помощью NSAppleScript executeAndReturnError()
вызов. Однако я обнаружил, что NSAppleScript был намного, намного медленнее, чем ScriptingBridge.
После использования ClassDump для извлечения дополнительных вызовов SBObject я обнаружил недокументированные specifierDescription()
а также qualifiedSpecifier()
звонки. Первый дает мне красивую строку "tab X of id окна Y". Последний возвращает дескриптор события apple, который я затем могу декодировать.
Мой окончательный код (в Perl):
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";
3 ответа
Технически вы не можете; лучший вопрос, почему вы хотите?
(Ну, ладно, вы могли бы, если бы вы использовали API Apple Event Manager или objc-appscript, оба из которых могут дать вам сырой AEDesc/NSAppleEventDescriptor, который вы можете рекурсивно разбирать на части. Или вы можете покопаться в SB, чтобы увидеть, есть ли недокументированный API для доступа к базовому AEDesc, но, конечно, предостерегающий emptor. В качестве альтернативы может существовать лучший способ достичь своей реальной цели, не прибегая к хакерским атакам, но вам нужно будет предоставить больше информации.)
Я знаю, что это старый вопрос, но у меня сегодня была эта проблема, и я не нашел хороших ответов в Интернете. Это сработало для меня:
tell application "Terminal"
set newTab to do script "echo hello"
set theWindow to first window of (every window whose tabs contains newTab)
set windowId to theWindow's id
repeat with i from 1 to the count of theWindow's tabs
if item i of theWindow's tabs is newTab then set tabNumber to i
end repeat
get {windowId, tabNumber}
end tell
Как насчет чего-то очень простого, такого как это:
скажите приложению "Терминал", установите new_win для выполнения скрипта "", установите w_id в id переднего окна