Обнаружение экрана блокировки или запущенной заставки с Firefox / OS X

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

Мне удалось сделать это уже для Windows, и теперь мне нужно выполнить перенос на OS X. Для версии для Windows я использовал вызовы собственного API, чтобы узнать, заблокирован ли экран и т. Д. Есть ли аналогичный способ получения информации об ОС из расширения Firefox в OS X? Я пробовал погуглить и не нашел твердого ответа - любая помощь приветствуется!


person BeneGal    schedule 01.11.2013    source источник


Ответы (1)


В OSX вы можете запросить заблокированный экран / заставку, используя CGSessionCopyCurrentDictionary и ища наличие и значение ключа "CGSSessionScreenIsLocked".

Это API платформы, поэтому придется снова использовать js-ctypes и написать кучу кода, чтобы это заработало.

У меня все заработало: следующий код - это рабочий пример, который вы можете запустить в привилегированном Электронный блокнот. Чтобы получить привилегированный, откройте панель, например, about:newtab.

Components.utils.import("resource://gre/modules/ctypes.jsm");

var CoreFoundation = new (function() {
    this.CFNumberRef = ctypes.voidptr_t;
    this.CFStringRef = ctypes.voidptr_t;
    this.CFDictionaryRef = ctypes.voidptr_t;

    var lib = ctypes.open("/System/Library/Frameworks/CoreFoundation.framework/CoreFoundation");
    this.CFRelease = lib.declare(
        "CFRelease",
        ctypes.default_abi,
        ctypes.void_t,
        ctypes.voidptr_t);

    var CFStringCreateWithCharacters = lib.declare(
        "CFStringCreateWithCharacters",
        ctypes.default_abi,
        this.CFStringRef,
        ctypes.voidptr_t,
        ctypes.jschar.ptr,
        ctypes.int32_t);
    this.CFStringCreateWithCharacters = function(str) {
        var rv = CFStringCreateWithCharacters(null, str, str.length);
        if (!rv || rv.isNull()) {
            return null;
        }
        return ctypes.CDataFinalizer(rv, this.CFRelease);
    };


    var CFDictionaryGetValue = lib.declare(
        "CFDictionaryGetValue",
        ctypes.default_abi,
        this.CFNumberRef,
        this.CFDictionaryRef,
        this.CFStringRef);
    this.CFDictionaryGetInt = function(dict, str) {
        var rv = CFDictionaryGetValue(dict, this.CFStringCreateWithCharacters(str));
        if (!rv || rv.isNull()) {
            return null;
        };
        return this.CFNumberGetValue(rv);
    };

    var CFNumberGetValue = lib.declare(
        "CFNumberGetValue",
        ctypes.default_abi,
        ctypes.bool,
        this.CFNumberRef,
        ctypes.int32_t,
        ctypes.int32_t.ptr);
    this.CFNumberGetValue = function(num) {
        var rv = new ctypes.int32_t();
        CFNumberGetValue(num, 3, rv.address());
        console.log("CFNumberGetValue", rv, rv.value);
        return rv.value;
    };
    this.close = function() {
        lib.close();
    };
})();
var ApplicationServices = new (function() {
    var lib = ctypes.open("/System/Library/Frameworks/ApplicationServices.framework/ApplicationServices");

    var CGSessionCopyCurrentDictionary = lib.declare(
        "CGSessionCopyCurrentDictionary",
        ctypes.default_abi,
        CoreFoundation.CFDictionaryRef);
    this.CGSessionCopyCurrentDictionary = function() {
        var rv = CGSessionCopyCurrentDictionary();
        if (!rv || rv.isNull()) {
            return null;
        }
        return ctypes.CDataFinalizer(rv, CoreFoundation.CFRelease);
    };

    this.close = function() {
        lib.close();
    };
})();

setInterval(function() {
    var dict = ApplicationServices.CGSessionCopyCurrentDictionary();
    if (dict) {
        var locked = CoreFoundation.CFDictionaryGetInt(dict, "CGSSessionScreenIsLocked");
        console.log("rv", locked);
        if (locked) {
            // do something;
        }
    }
}, 500);
person nmaier    schedule 05.11.2013
comment
Большое спасибо за ваши предложения. Я видел, как это работает в Scratchpad - однако тот же самый код, работающий внутри моего дополнения, дает следующую ошибку: ctypes.CDataFinalizer не является функцией. Есть идеи относительно того, что может быть причиной этого? - person BeneGal; 03.12.2013
comment
О нет, я имел в виду именно тот код, который вы указали выше. Надеялся, что, возможно, вы сталкивались с этим раньше. Продолжим расследование. - person BeneGal; 03.12.2013
comment
Что ж, без предоставления автономного воспроизводимого примера, показывающего ошибку, я не смогу помочь. - person nmaier; 03.12.2013
comment
Черт возьми, я только что написал свою версию, а потом нашел твою. Черт возьми, такой классный человек. Моя немного другая, я думаю, что моя правильнее !! : P Я не использую мерзкий финализатор, никаких гарантий для звонка: P Я делаю руководство, и это логическое значение. но человек, ты сделал это по-другому, и теперь, когда я сделал свое, глядя на тебя, я так многому меня научился, большое спасибо за этого человека !! вот мой: gist.github.com/Noitidart/ff19ae88500a649c1ef9 - person Noitidart; 17.12.2014
comment
btw CGSessionScreenLocked только 1, если для параметра экрана блокировки установлено значение true. если он не установлен, мы должны использовать px или что-то еще, чтобы проверить, включена ли заставка. - person Noitidart; 17.12.2014
comment
вам нужно CFRelease this.CFStringCreateWithCharacters(str): P, так что ваш тип возврата в CFDictionaryGetValue` очень специфичен, но вам не нужно связываться с красивым приведением: P - person Noitidart; 17.12.2014