Carbon Accessibility API - Получение информации о Windows через пробелы - PullRequest
2 голосов
/ 20 апреля 2010

У меня есть следующая (незначительная) проблема, которую я хочу решить программно. Всякий раз, когда я отсоединяю свой дополнительный монитор от моего ноутбука, все окна перемещаются, чтобы быть видимыми в теперь меньшем разрешении. Когда я подключаю свой внешний монитор обратно, мне нужно вручную заменить окна в их правильное положение. Я должен делать это каждое утро ( вздох ).

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

Мне удалось сделать что-то, что отлично работает, с помощью API-интерфейса Accessibility, который позволяет мне контролировать окна, которые не являются частью моего пространства процесса. У меня проблема, хотя: программа может только видеть окна, которые находятся в моем текущем пространстве (я говорю о функции OSX Spaces здесь).

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

Некоторые подробности о моей программе:

  • Он проходит по всем запущенным процессам и получает их PID.
  • Создает элементы приложения из этих PID (AXUIElementCreateApplication)
  • Получает окна, связанные с этим приложением, а затем их позиции

При получении элементов windows из элемента application, AXUIElementCopyAttributeValues возвращает мне только окна текущего пространства.

Теперь, есть ли способ управления какими-либо окнами (в разных местах)? В противном случае я не возражаю против изменения пробелов программно, чтобы получить все окна, но это кажется невозможным.

Любая помощь будет оценена!

Ответы [ 2 ]

1 голос
/ 21 апреля 2010

Мне неизвестен документированный способ переключения пробелов.

Возможно, вы хотите CGSPrivate.h - CGSSetWorkspace и др. Просто помните, что эти функции являются SPI и могут выходить из строя без предупреждения даже в версии 10.6.x.

0 голосов
/ 20 августа 2013

Если вы хотите избежать использования частных API, вы можете воспользоваться тем, что у Mission Control есть сочетания клавиш для перемещения в различные области, и вы можете программно отправлять коды клавиш для их активации. Я написал об этом в блоге (http://ianyh.com/blog/2013/06/05/accessibility/) для оконного менеджера листов, над которым я работал, под названием Amethyst , в котором есть пример кода, который вы можете проверить в -[AMWindow moveToSpace:].

Короткая версия для перемещения в пробел выглядит как использование по умолчанию ctrl + arrow key для перемещения в соседние пробелы:

CGEventRef keyboardDownEvent = CGEventCreateKeyboardEvent(NULL, kVK_RightArrow, true);
CGEventRef keyboardUpEvent = CGEventCreateKeyboardEvent(NULL, kVK_RightArrow, false);

CGEventSetFlags(keyboardDownEvent, kCGEventFlagMaskControl);
CGEventSetFlags(keyboardUpEvent, 0);

CGEventPost(kCGHIDEventTap, keyboardDownEvent);
CGEventPost(kCGHIDEventTap, keyboardUpEvent);

CFRelease(keyboardEvent);
CFRelease(keyboardEventUp);

Вы можете объединить это с NSWorkspaceActiveSpaceDidChangeNotification для обхода всех пробелов и сбора данных окна.

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

...