Изменение размера Windows незашифрованных приложений в AppleScript - PullRequest
3 голосов
/ 29 мая 2011

Я работаю над приложением, которое перемещает и изменяет размеры окон других приложений в OSX.Основное приложение написано на Какао, но часть изменения размера выполняется на AppleScript, поскольку у Какао, похоже, нет такой функции.

Вот результат регулярного вызова ActionScript (переданного как строка в NSAppleScript):

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

Идентификатор окна получен с использованием API CGWindowListCopyWindowInfo, представленного в OSX 10.6.

Этот подход работает нормально для большинства окон, но не работает для приложений, которые не являются приемлемымиНаиболее ярким примером является собственный предварительный просмотр 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

Я дважды проверил, что окно существует, и идентификатор окна правильный.

Как правильно изменить размер неподписанных окон в OSX?Я вижу, что это возможно из таких приложений, как moom .

Любой совет - будь то на основе какао или AppleScript или что-то еще - более чем приветствуется.

Ответы [ 3 ]

2 голосов
/ 29 мая 2011

К сожалению, AppleScripting windows для приложения зависит от разработчика приложения - нет никакого чистого способа сделать это в целом. Посмотрите на этот сценарий, который я написал несколько лет назад для всех особых случаев:

    -- 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 голос
/ 29 мая 2011

Вы упомянули 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, поэтому вы не можете получить доступ к окнам таким образом. Нет свойства "bounds", поэтому вы не можете устанавливать границы. Также обратите внимание, что вы должны получить окна от «процесса» в вызове системных событий. Поэтому, если вы хотите использовать системные события, ваш код довольно далек.

Лучше всего было бы найти название окна, на которое вы хотите настроить таргетинг. Затем в appleScript вы получаете окна, как у меня выше, затем просматриваете их, проверяя их имя. Когда вы найдете правильное имя, вы нашли соответствующее окно. Затем вы можете установить свойства "size" и "position" этого окна.

Удачи, потому что ваша задача большая!

0 голосов
/ 27 января 2017

У меня возникла та же проблема, когда я пытался изменить размер приложения, используя логику, аналогичную используемой вами.

В моем случае мне нужно было изменить размер приложения в соответствии с размером экрана, и я обнаружил, что вы можете использовать «Системные события», если вы предоставите редактору сценариев вспомогательный доступ . Если вы сохраните сценарий как приложение , вам потребуется вместо этого предоставить ему доступ.

Следующий скрипт просто захватывает размер экрана, снова открывает приложение, чтобы убедиться, что оно открыто, а затем использует «Системные события», чтобы установить размер переднего окна.

ПРИМЕЧАНИЕ: Я нацеливаюсь на приложение под названием "cefclient" ниже

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
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...