2010-04-26 24 views
5

tôi có thể mở một tab ga sử dụng AppleScript sau:Làm cách nào để nhận được số cửa sổ và số tab của cửa sổ Terminal bằng AppleScript thông qua ScriptingBridge?

tell application "Terminal" 
    set myTab to do script "exec sleep 1" 
    get myTab 
end tell 

này trả về một chuỗi như: tab 1 of window id 3263 of application "Terminal". Điều này thật tuyệt, tôi có thể thấy id cửa sổ và số tab (mặc dù tôi không biết cách truy vấn myTab để chỉ nhận các giá trị này).

Trong ScriptingBridge Cocoa, tôi có thể làm:

SBApplication *terminal; 
SBObject  *tab; 

terminal = [SBApplication applicationWithBundleIdentifier:@"com.apple.terminal"] 
tab = [terminal doScript:@"exec sleep 1" in:nil] 

Làm thế nào để tôi nhận được id cửa sổ và số tab từ đối tượng tab?


Chỉnh sửa 2009/4/27 - Tại sao?

Để trả lời lý do tại sao tôi muốn thực hiện điều này - tôi đang mở lệnh trong cửa sổ Terminal (như trên), và đang nhận lại đối tượng tab. Tuy nhiên tôi muốn di chuyển/thay đổi kích thước cửa sổ này, vì vậy tôi cần truy cập vào đối tượng "cửa sổ" của tab.

Tôi đang sử dụng Objective-C (thực ra, Objective-C được bắc cầu từ Perl) và muốn gắn vào các thành phần OS chuẩn, vì vậy tôi tin rằng tôi chỉ có các khung công tác NSAppleScript và ScriptingBridge để chơi (tất cả mô-đun đã phá vỡ với loại bỏ carbon 64bit). Tôi sẽ thử NSAppleScript, nhưng việc xử lý các giá trị trả về có vẻ là một nghệ thuật đen.

Giải pháp hiện tại của tôi là lấy TTY đối tượng tab (được đảm bảo duy nhất) và liệt kê mọi tab của mỗi cửa sổ cho đến khi tôi tìm thấy cửa sổ chứa tab. Tôi cho rằng đây không phải là cách tốt nhất (chắc chắn là không nhanh!).


Sửa 2009/04/30 - Giải pháp

Dựa trên những đề nghị của "has" dưới đây, tôi bất chấp NSAppleEventDescriptor API. Ban đầu, tôi chỉ có thể thực hiện điều này với cuộc gọi executeAndReturnError() của NSAppleScript. Tuy nhiên tôi thấy rằng NSAppleScript là nhiều, chậm hơn nhiều so với ScriptingBridge.

Sau khi sử dụng ClassDump để trích xuất một số cuộc gọi SBObject khác, tôi đã tìm thấy các cuộc gọi không được yêu cầu specifierDescription()qualifiedSpecifier(). Cái cũ mang đến cho tôi "tab X của cửa sổ id Y" chuỗi. Cái sau trả về bộ mô tả sự kiện của Apple, cái mà tôi có thể giải mã.

mã cuối cùng của tôi (trong perl) là:

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"; 

Trả lời

1

Về mặt kỹ thuật, bạn có thể không; một câu hỏi hay hơn là tại sao muốn?

(Tốt, được rồi, bạn có thể nếu bạn sử dụng API Trình quản lý sự kiện Apple hoặc objc-appscript, cả hai đều có thể cung cấp cho bạn AEDesc/NSAppleEventDescriptor thô mà bạn có thể đệ quy pull apart yourself.Hoặc bạn có thể poke xung quanh trong SB để xem nếu có một API không có giấy tờ để có được tại AEDesc cơ bản, nhưng caveat emptor, tất nhiên. Ngoài ra, có thể có một cách tốt hơn để đạt được mục tiêu thực tế của bạn mà không cần đến hackery, nhưng bạn cần phải cung cấp thêm thông tin)

+0

Cảm ơn nhận xét. Tôi đã cập nhật câu hỏi để thêm phần "tại sao". Tôi nghi ngờ tôi có thể sẽ kết thúc với AppleEvents. Điều này có thể thực hiện được trong NSAppleScript không? Tôi đang cố gắng làm việc chỉ với những thứ được cài đặt lại trên máy. –

+0

Vâng, cũng nên nghĩ đến NSAppleScript. Nếu bạn chạy lệnh 'do script' trong AppleScript bằng cách sử dụng - [NSAppleScript executeAppleEvent: error:] (giả sử bạn cũng muốn truyền tham số) và trả về tham chiếu, bạn sẽ nhận được NSAppleEventDescriptor chứa đối tượng specifier của bạn. Bit lộn xộn, nhưng nếu bạn không ở trong [Obj-] C và không thể đủ khả năng phụ thuộc bên ngoài thì đó thực sự là lựa chọn duy nhất của bạn. Để đóng gói và giải nén AEDescs, nó không quá khó khi bạn biết chúng được cấu trúc như thế nào. ví dụ. Hãy xem lớp AEMCodecs của objc-appscript để biết các mẹo. – has

+0

Cảm ơn - có vẻ như NSAppleEventDescriptor là con đường để đi. Vì tôi không thích hiệu suất của NSAppleScript, tôi đã tìm thấy một cuộc gọi ScriptingBridge không có giấy tờ đã trả về bộ mô tả. Tôi đã thêm mã của mình vào cuối câu hỏi. –

0

Làm thế nào về một cái gì đó rất đơn giản như thế này:.

ứng dụng tell "Terminal" bộ new_win để làm kịch bản "" bộ w_id đến id của phía trước cửa sổ cuối nói

+1

Có, tôi đã sử dụng nó một thời gian, nhưng có một điều kiện chủng tộc nếu người dùng chuyển đổi giữa các cửa sổ giữa "do script" và "set id", điều này xảy ra nhiều hơn bạn mong đợi ban đầu. –

2

tôi biết đây là một câu hỏi cũ, nhưng tôi chỉ có vấn đề này ngày hôm nay, và tôi không tìm thấy câu trả lời tốt trên mạng. Điều này làm việc cho tôi:

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 
Các vấn đề liên quan