Подтвердить что ты не робот

OSX: Как определить, работает ли управление миссией?

Когда запускается Mission Control, он не позволяет приложениям получать события клавиатуры и мыши. Это также оставляет последнее приложение запущенным, думая, что оно все еще имеет фокус. Это проблема для меня, потому что я не получаю события keyUp или mouseUp, если я запускаю Mission Control, удерживая кнопку мыши или клавишу нажатой, и мое приложение будет вести себя так, как будто эта кнопка мыши или кнопка удерживается нажатой.

Я хотел бы либо прочитать события клавиатуры и мыши, даже когда контроль миссии активен, либо способ определить, что контроль миссии активен. В идеале я хотел бы иметь возможность сделать последнее, так как я фактически не могу использовать свое приложение во время работы Mission Control.

Я попробовал пару вещей без удачи:

  1. Используйте addGlobalMonitorForEventsMatchingMask, чтобы зарегистрировать глобальный монитор для событий клавиатуры и мыши. Это захватывает события мыши (но не события клавиатуры, хотя в документации сказано, что события keyDown должны отправляться на глобальный монитор), когда я переключаюсь на другое приложение, но, похоже, Mission Control не позволяет событиям распространяться на глобальные мониторы.
  2. Проверьте [[NSRunningApplication currentApplication] {isActive, ownsMenuBar}]. По-видимому, мое приложение активно, хотя оно не получает события!
  3. Проверьте [NSApp keyWindow] != nil. Видимо, одно из моих окон должно получать ключевые события. Ни один из них не является.
  4. Проверьте, является ли Mission Control одним из запущенных приложений, возвращаемых [NSWorkspace runningApplications]. Mission Control не отображается в этом списке при запуске.

Редактировать:

Я наконец-то решил эту проблему (хотя и не очень удовлетворительно). Для мыши оказывается, что вы можете запросить состояние нажатых кнопок с помощью [NSEvent pressedMouseButtons]. Я просто отслеживаю то, что, по моему мнению, должно быть состояние мыши из событий NSLeftMouseDown и NSLeftMouseUp, и сравниваю это с [NSEvent pressedMouseButtons] от времени, чтобы убедиться, что они согласованы. Если это не так, то я знаю, что что-то похитило мое событие NSLeftMouseUp и действую соответственно.

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

4b9b3361

Ответ 1

Как минимум в OS X 10.10 вы можете использовать этот код, чтобы проверить, активен ли контроль миссии:

func missionControlIsActive() -> Bool
{
    var result: Bool = false
    let windowInfosRef = CGWindowListCopyWindowInfo(CGWindowListOption(kCGWindowListOptionOnScreenOnly), CGWindowID(0)) // CGWindowID(0) is equal to kCGNullWindowID
    let windowList: NSArray = windowInfosRef.takeRetainedValue() // We own the returned CFArrayRef
    for entry in windowList
    {
        if (entry.objectForKey("kCGWindowOwnerName") as! String) == "Dock"
        {
            var bounds: NSDictionary = entry.objectForKey("kCGWindowBounds") as! NSDictionary
            if (bounds.objectForKey("Y") as! NSNumber) == -1
            {
                result = true
            }
        }
    }
    return result
}

В двух словах код проверяет, отображается ли на экране определенное окно, принадлежащее процессу док-станции OS X, и если оно находится в определенной позиции. Если оба условия будут выполнены, Mission Control будет активен прямо сейчас. Код будет работать в изолированном приложении, и никаких привилегий для вспомогательных устройств не требуется.

Ответ 2

Пробовал ли вы уровень bash с помощью NSTask? Что-то вроде ps -faxU <username> должно содержать список всех запущенных процессов, а затем вы могли бы анализировать выходные данные, или вы могли бы использовать ps -faxU <username> | grep -i "mission control" (Наверху я не уверен, как процесс может быть вызван, но sth вроде "управление миссией" " выглядит вполне законно). Возможно, это не самое элегантное решение, но если ничего не работает, это может стоить того.

Ответ 3

Может быть, я что-то пропустил, но вы пытались использовать метки событий вместо глобального мониторинга?

Ответ 4

Похоже, что DTrace имеет некоторую способность видеть, что управление миссией активировано. Попробуйте запустить:

sudo fs_usage -filesys | Миссия Grep

из командной строки, а затем запускает приложение управления миссиями из папки /Application.

Вы должны увидеть много результатов, связанных с запуском Mission Control. К сожалению, этот же вывод не появился с помощью короткого выреза или прокрутки клавиатуры. Конечно, использование DTrace в производственном коде не является тем, что я бы рекомендовал.