2011-05-28 81 views
3

我正在处理一个应用程序,用于在OSX上移动和调整其他应用程序的窗口大小。 主要应用程序是用Cocoa编写的,但调整大小的部分是在AppleScript中完成的,因为Cocoa似乎没有这种功能。在AppleScript中调整Windows中Unscriptable应用程序的大小

下面是ActionScript中的常规呼叫(作为字符串NSAppleScript传递)的结果:

tell application "TextEdit" 
    set currentWindow to the window id 5184 
    set bounds of the currentWindow to {2855, 218, 3790, 578} 
end tell 

使用在OSX 10.6引入的CGWindowListCopyWindowInfo API获得的窗口ID。

此方法适用于大多数窗口,但不适用于无法编写脚本的应用程序。 最显着的例子是OSX自己的预览。

我试图“告诉”系统事件,而不是这个代码

tell application "System Events" 
    set bounds of window 5184 to {1920, -502, 2855, 578} 
end tell 

但预览使用的变化,OSX给我一个错误信息:当只是想

"System Events got an error: Can’t set bounds of window 5184 to {1920, -502, 2855, 578}." 

同样的情况,得到一个参考窗口:

tell application "System Events" 
    get window 5184 
end tell 

我已经doublechecked,windo存在w并且窗口ID是正确的。

在OSX上以编程方式调整不可编程窗口的正确方式是什么? 我可以看到它可以从应用程序,如moom

任何建议 - 不管是基于Cocoa还是基于AppleScript的或其他的东西 - 都是值得欢迎的。

回答

2

不幸的是,AppleScripting应用程序的窗口取决于应用程序的开发人员 - 一般来说,没有干净的方法来完成它。看这个剧本我写了几年前对所有的特殊情况:

-- Get screen bounds and origins 
set f to (path to preferences from local domain as Unicode text) & "com.apple.windowserver.plist" 
tell application "System Events" to set {{|Width|:w1, |Height|:h1, |OriginX|:OX1, |OriginY|:OY1}, {|Width|:w2, |Height|:h2, |OriginX|:OX2, |OriginY|:OY2}} to value of property list items of property list item 1 of property list item "DisplaySets" of property list file f 
set SecondaryScreenBounds to {OX2, OY2, OX2 + w2, OY2 + h2} 
set RHedge to OX1 
set BOTedge to OY1 

tell application "Finder" 
    -- Get the running apps (excluding those with special windows) 
    set |running| to name of processes whose visible is true and name is not "Finder" and name is not "QuickSilver" and name is not "CopyPaste" and name is not "DropCopy" and name is not "iPulse" 
    repeat with anApp in |running| 
     try -- for a scriptable App with window bounds property 
      tell application anApp 
       set allWindows to (every window) 
       repeat with aWindow in allWindows 
        set Wbounds to (get bounds of aWindow) 
        if item 1 of Wbounds > RHE or item 2 of Wbounds > BoE then my moveWindows(contents of anApp) 
       end repeat 
      end tell 
     on error -- for an App with window position & size properties 
      tell application "System Events" 
       tell application process anApp 
        set allWindows to (every window) 
        repeat with aWindow in allWindows 
         set {p1, p2} to aWindow's position 
         if p1 ≥ RHedge or p2 ≥ BOTedge then my moveWindows(contents of anApp) 
        end repeat 
       end tell 
      end tell 
     end try 
    end repeat 
    -- for the Finder 
    set allWindows to (every window whose visible is true) 
    repeat with aWindow in allWindows 
     set Wbounds to bounds of aWindow 
     if (item 1 of Wbounds) > RHedge or (item 2 of Wbounds) > BOTedge then 
      set bounds of aWindow to {200, 200, 1200, 800} 
     end if 
    end repeat 
end tell 
-- for Safari 
if "Safari" is in |running| then tell application "Safari" 
    set Wind to name of windows 
    set Wbounds to bounds of windows 
    repeat with k from 1 to count Wind 
     set W to item k of Wind 
     set B to item k of Wbounds 
     if (item 1 of B) ≥ RHedge or (item 2 of B) ≥ BOTedge then 
      set bounds of window W to {200, 200, 1200, 800} 
     end if 
    end repeat 
end tell 
-- for HoudahSpot 
if "HoudahSpot" is in |running| then tell application "System Events" to tell process "HoudahSpot" 
    set W to name of windows 
    set B to position of windows 
    repeat with k from 1 to count W 
     if item k of W is not missing value and (item 1 of item k of B) ≥ RHedge then set position of window (item k of W) to {100, 100} 
    end repeat 
end tell 

-- for Activity Monitor 
if "Activity Monitor" is in |running| then tell application "System Events" to tell process "Activity Monitor" 
    set W to name of windows 
    set B to position of windows 
    repeat with k from 1 to count W 
     if item k of W is not missing value and (item 1 of item k of B) ≥ RHedge then set position of window (item k of W) to {100, 100} 
    end repeat 
end tell 
-- for 1Password 
if "1Password" is in |running| then tell application "System Events" to tell process "1Password" 
    set W to name of windows 
    set B to position of windows 
    repeat with k from 1 to count W 
     if item k of W is not missing value and (item 1 of item k of B) ≥ RHedge then set position of window (item k of W) to {100, 100} 
    end repeat 
end tell 
-- for iCal 
if "iCal" is in |running| then tell application "iCal" 
    set iCB to bounds of window "iCal" 
    if item 1 of iCB ≥ RHedge or item 2 of iCB ≥ BOTedge then 
     set bounds of window "iCal" to {100, 100, 1200, 1000} 
    end if 
end tell 
-- for a Help Window 
tell application "System Events" 
    if exists process "Help Viewer" then tell process "Help Viewer" 
     set W to windows 
     repeat with w1 in W 
      set position of w1 to {200, 200} 
     end repeat 
    end tell 
end tell 

to moveWindows(anApp) 
    tell application "System Events" 
     if anApp is "ScriptLight" then 
      tell process "ScriptLight" to set position of window 1 to {200, 200} 
     else if anApp is "PowerKey" then 
      tell process "PowerKey" to set position of window "PowerKey" to {200, 200} 
     else if anApp is "Script Debugger 4" then 
      tell application process "Script Debugger 4" 
       set allWindows to (every window) 
       repeat with aWindow in allWindows 
        set {p1, p2} to aWindow's position 
        if p1 ≥ 1680 or p2 > 1050 then set aWindow's position to {100, 100} 
       end repeat 
      end tell 
     end if 
    end tell 
end moveWindows 
+1

拼写错误'fortunately' – hooleyhoop 2011-05-29 22:54:33

+0

感谢您使用AppleScript完成此任务的复杂脚本和见解。我决定改用Accessibility API。虽然它具有较大的开销,但它可用于跨应用程序以调整大小。 – 0x90 2011-05-30 16:26:16

1

你提到了Preview,所以在Preview中打开一个窗口并运行这个脚本。

tell application "System Events" 
    tell process "Preview" 
     set theWindows to windows 
     return properties of (item 1 of theWindows) 
    end tell 
end tell 

看看返回的属性。没有“id”属性,所以你不能以这种方式访问​​窗口。没有“界限”属性,所以你不能设置界限。另请注意,您必须从系统事件调用中的“进程”中获取窗口。所以如果你想使用系统事件,你的代码是非常遥远的。

最好的办法是找到想要定位的窗口的名称。然后在applescript中,您将获得上面的Windows,然后通过检查其名称来查看它们。当您找到适当的名称时,您已找到相应的窗口。然后你可以设置该窗口的“大小”和“位置”属性。

祝你好运,因为你的任务是一个大的!

+0

针对所谓的“cefclient”的应用程序'没有“边界”属性,因此不能设置边界。 '我尝试了流程“Google Chrome”。没有“边界”属性,但我可以设置边界。 – 2015-05-23 00:56:05

0

我有同样的问题,试图调整使用类似的逻辑应用到你正在使用的东西。

在我的情况下,我需要调整应用程序的大小以匹配屏幕大小,我发现如果您授予脚本编辑器assistive access,则可以使用“系统事件”。如果您使用save the script as an app,则需要授予该应用访问权限。

下面的脚本简单地抓住屏幕大小,重新打开应用程序以确保它是开放的,然后使用“系统事件”来设置前窗的大小。

注:我下面

set theApp to "cefclient" 

tell application "Finder" 
    set screenResolution to bounds of window of desktop 
end tell 

set screenWidth to item 3 of screenResolution 
set screenHeight to item 4 of screenResolution 

tell application theApp 
    activate 
    reopen 
end tell 

tell application "System Events" 
    tell process theApp 
     set the size of front window to {screenWidth, screenHeight} 
    end tell 
end tell 
相关问题