Управление окнами OSX - PullRequest
       8

Управление окнами OSX

12 голосов
/ 13 ноября 2009

Я пытаюсь управлять окнами сторонних приложений OSX из моего приложения. мне бы хотелось в 1. переместить окна на экране 2. изменить размер окна на экране 3. изменить текущее активное окно приложения 4. получить текущее активное окно.

(И я хотел бы сделать это либо через ObjC / C / C ++ apis).

Какие вызовы API я должен искать, учитывая, что у меня есть CGWindowIDs окон, которыми я хочу управлять? То есть я ожидал бы найти функции с подписями чего-то вроде: MoveWindow(CGWindowID winId, int x, int y), ResizeWindow(CGWindowID winId, int width, int height), Activatewindow(CGWindowID winId), CGWindowID GetCurrentlyActivatedWindow().

Для 3 я уже использую SetFrontProcess, чтобы вывести процесс на передний план, но это не позволяет мне выбрать конкретное окно процесса, если оно имеет несколько значений.

Ответы [ 6 ]

11 голосов
/ 14 ноября 2009

Один из способов сделать это - использовать API специальных возможностей.

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

Я делаю это через AppleScript. Иногда это может быть неуклюжим, но, похоже, довольно надежным. Я использую AppScript для отправки AppleScript из моего приложения Какао. Он безопасен для потоков и более стабилен, чем альтернативы - либо Scripting Bridge, либо NSAppleScript.

Сложным битом будет идентификация окна по его идентификатору окна в AppleScript - кажется, что у AppleScript нет свойства идентификатора окна, которое соответствует CGWindowID. Тем не менее, вы можете получить любое окно, которое вы хотите, используя AppleScript.

  1. Переместить самое переднее окно на 100, 100

    tell application "System Events"
     set theprocess to the first process whose frontmost is true
     set thewindow to the value of attribute "AXFocusedWindow" of theprocess
        set position of thewindow to {100, 100}
    end tell
    
  2. Изменить размер переднего окна до 200, 300

    tell application "System Events"
      set theprocess to the first process whose frontmost is true
      set thewindow to the value of attribute "AXFocusedWindow" of theprocess
         set size of thewindow to {200, 300}
    end tell
    
  3. Изменить текущее окно самого переднего приложения

    tell application "System Events"
      set theprocess to the first process whose frontmost is true
      set thewindow to the value of attribute "AXFocusedWindow" of theprocess
         set size of thewindow to {200, 300}
         windows of theprocess
         -- Code to get ID of window you want to activate
         tell window 2 of theprocess -- assuming it's window 2
               perform action "AXRaise"
         end tell
    end tell
    
  4. Активное окно

    tell application "System Events"
     set theprocess to the first process whose frontmost is true
     set thewindow to the value of attribute "AXFocusedWindow" of theprocess
    end tell
    

Для AppScript доступно приложение под названием ASTranslate , которое превратит этот AppleScript в код Objective C, который вызывает соответствующие команды в AppScript.

Для получения дополнительной информации о том, как получить размер и границы окон (насколько я знаю, они доступны только для чтения), см. Пример приложения Сын Грабя .

2 голосов
/ 26 августа 2010

Используйте CGWindowListCopyWindowInfo, чтобы получить kCGWindowOwnerPID каждого окна. Затем вы можете использовать «распределенные объекты», если вам нужен доступ к ObjectiveC, или Mach RPC для других вещей. Все это задокументировано на http://developer.apple.com

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

1 голос
/ 14 ноября 2009

Доступность должна быть включена в Системных настройках, чтобы это работало. Это яблочный скрипт, но его можно использовать в target-c с мостом сценариев.

-- Moves safari window by deltaposition
tell application "System Events"
    tell application "Safari"
        set win to first window
        set b to bounds of win
        set deltaposition to {50, 0}
        set bounds of first window to {(item 1 of b) + (item 1 of deltaposition), (item 2 of b) + (item 2 of deltaposition), (item 3 of b) + (item 1 of deltaposition), (item 4 of b) + (item 2 of deltaposition)}
    end tell
end tell
1 голос
/ 13 ноября 2009

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

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

0 голосов
/ 13 ноября 2009

Я новичок здесь, так что это должно быть представлено как ответ, а не комментарий. Я написал .NET-приложение ( PlaceMint ) делает именно это в Windows и совсем не подозрительно. PlaceMint помогает вам организовать ваши окна в структурированном виде, определяемом пользователем. Все, что он делает, это делает такие вещи, как перемещение или изменение размеров окон на основе правил, определенных пользователем. Кто-то спросил меня, могу ли я сделать порт для OSX, но я никогда не заходил слишком далеко, потому что я не мог найти определение API, подобное тому, которое предоставлено в Windows (маршалинг вызовов dll для user32.dll, например SetWindowPos ()).

0 голосов
/ 13 ноября 2009

Я думаю, вы должны объяснить, почему вы хотите это сделать. Единственные известные мне утилиты, которые перемещают окна всех других приложений, - это Spaces и Expose, которые поставляются Apple. Если вы хотите захватить весь экран, для этого есть общедоступный API, но перемещение окон других приложений звучит подозрительно.

...