Как получить идентификатор окна и номер вкладки окна терминала с помощью AppleScript через ScriptingBridge? - PullRequest
5 голосов
/ 26 апреля 2010

Я могу открыть вкладку «Терминал», используя следующий 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 - Почему?

В ответ на вопрос, почему я хочу это сделать - я открываю команду в окне терминала (как указано выше) и получаю обратно объект tab . Однако я хочу переместить / изменить размер этого окна, поэтому мне нужно получить доступ к объекту «окна» вкладки.

Я использую Objective-C (ну, на самом деле, Objective-C, соединенный с Perl), и хочу придерживаться стандартных компонентов ОС, поэтому я считаю, что у меня есть только платформы NSAppleScript и ScriptingBridge для игры (все модули Perl AppleScript сломался с 64-битным удалением углерода). Я бы попробовал NSAppleScript, но обработка возвращаемых значений выглядит черным искусством.

Мое текущее решение - получить TTY объекта вкладки (гарантированно уникальный) и перечислять каждую вкладку каждого окна, пока я не найду окно, содержащее вкладку. Я предположил, что это не может быть лучшим способом (это, конечно, не быстро!).


Изменить 2009/4/30 - Решение

Основываясь на предложениях " имеет " ниже, я выдержал NSAppleEventDescriptor API. Изначально я смог достичь этого только с помощью вызова NSAppleScript executeAndReturnError(). Однако я обнаружил, что NSAppleScript намного, намного медленнее, чем ScriptingBridge.

После использования ClassDump для извлечения еще нескольких вызовов SBObject я обнаружил недокументированные вызовы specifierDescription() и qualifiedSpecifier(). Первый дает мне красивую строку " tab X с идентификатором окна 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 ]

3 голосов
/ 17 июля 2015

Я знаю, что это старый вопрос, но у меня была эта проблема сегодня, и я не нашел хороших ответов в Интернете.Это сработало для меня:

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
1 голос
/ 26 апреля 2010

Технически вы не можете; лучше вопрос, почему вы хотите?

(Ну, ладно, вы могли бы, если бы вы использовали API Apple Event Manager или objc-appscript , оба из которых могут дать вам необработанный AEDesc / NSAppleEventDescriptor, который вы можете рекурсивно разделить самостоятельно . Или вы можете покопаться в SB, чтобы посмотреть, есть ли недокументированный API для доступа к базовому AEDesc, но, конечно, будьте осторожны. В качестве альтернативы, может быть лучший способ достичь вашей реальной цели, не прибегая к хакерству, но вам нужно предоставить больше информации.)

0 голосов
/ 14 марта 2012

Как насчет чего-то очень простого, подобного этому:

Расскажите приложение "Терминал" установите new_win для выполнения скрипта "" установить w_id в идентификатор переднего окна конец сказать

...