【问题标题】:Detect lock screen or running screensaver with Firefox/OS X使用 Firefox/OS X 检测锁屏或运行屏幕保护程序
【发布时间】:2013-11-01 14:45:20
【问题描述】:

我正在为 Firefox(SDK 插件)创建一个扩展,我需要在其中检测屏幕保护程序和锁屏事件,以便我可以在网络应用中设置用户的可用性状态。

我已经设法为 Windows 做到这一点,现在需要移植到 OS X。对于 Windows 版本,我使用对本机 API 的调用来确定屏幕是否被锁定等。有没有类似的方法从 OS X 上的 Firefox 扩展获取操作系统信息?我试过用谷歌搜索,但没有找到可靠的答案 - 感谢任何帮助!

【问题讨论】:

    标签: javascript macos firefox firefox-addon jsctypes


    【解决方案1】:

    在 OSX 上,您可以使用 CGSessionCopyCurrentDictionary 查询锁定的屏幕/屏幕保护程序,并查找 "CGSSessionScreenIsLocked" 键的存在和值。

    这是平台 API,因此必须再次使用 js-ctypes 并编写一堆代码才能使其正常工作。

    我确实让它工作了:以下代码是一个工作示例,您可以在特权Scratchpad 中运行。要获得特权,请打开一个垫子,例如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);
    

    【讨论】:

    • 非常感谢您的建议。我已经看到这个在 Scratchpad 中工作了——但是,在我的插件中运行的完全相同的代码给出了以下错误:“ctypes.CDataFinalizer 不是一个函数”关于什么可能导致这种情况的任何想法?
    • 哦,不,我的意思是您在上面提供的确切代码。希望这可能是您以前可能遇到过的事情。将继续调查。
    • 好吧,如果你不提供一个独立的、可重现的示例来显示错误,我将无法提供帮助。
    • 天哪,我刚刚写了自己的版本,然后找到了你的。当当真棒的人。我的有点不同,我认为我的更正确! :P 我不使用令人讨厌的终结器,没有保证调用 :P 我做手动,它是一个布尔值。但是你做的不一样,现在我做了我的,看着你的教我很多,非常感谢这个人!这是我的:gist.github.com/Noitidart/ff19ae88500a649c1ef9
    • btw CGSessionScreenLocked 只有在锁定屏幕设置为 true 时才为 1。如果没有设置,我们必须使用 px 或其他东西来测试屏幕保护程序是否打开。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-02-15
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多