Firefox扩展/插件 - 检测工作区锁定 [英] Firefox Extension/Addon - Detect workspace locked

查看:273
本文介绍了Firefox扩展/插件 - 检测工作区锁定的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在我的Firefox插件中寻找解决方案来检测用户工作区何时被锁定/释放。在谷歌浏览器有一个简单的API chrome.idle.onStateChanged.addListener 为它,有没有类似的Firefox或任何可能做到这一点,独立平台?
顺便说一句,我用的是插件sdk。

我已经试过这个空闲服务:

  Cc [@ mozilla.org/widget/idleservice;1\"].getService(Ci.nsIIdleService)

但是我只是让我在进入睡眠状态时进入一些闲置超时或系统,而不是仅仅锁定工作区。



编辑:工作区锁定是指用户用 ctrl + alt + delete 锁定工作区。编辑2:我目前在Windows 8.1中工作,但是我猜是 chrome。闲置处理程序工作跨平台。



Edit3:我目前得到的答案是
1.那里不存在跨平台的解决方案,既不在铬也不在Firefox。
chrome.idle.onStateChanged 似乎在windows,linux和osx上有所不同。只有Windows才能按预期处理锁定行为。我无法测试OSX,在Ubuntu 14它不适合我。

2.对于Firefox有一些深入的代码的东西,试图使它的工作 - 见Noitidart在这个答案主题。



Edit4:Noitidart已经找到了windows的解决方案 - github链接

解决方案

我不知道如何检测屏幕锁定,但有这些观察员通知:



https:/ /developer.mozilla.org/en-US/docs/Observer_Notifications#Idle_Service



计算机睡眠唤醒通知。生病问周围的锁屏这是一个有趣的一个。



一些有用的聊天主题,看看如何谷歌浏览器:


[12:33]好男人对实际工作有疑问。任何人都知道如何检测屏幕被锁定?显然谷歌浏览器有一个方法: https://developer.chrome.com/extensions/idle# event-onStateChanged

[12:45]有人知道MXR或DXR适用于Google Chrome的代码库吗?
$ b $ [12:46] mxr.mozilla.org/chromium

[12:52] Ms2ger:你能帮我看看他们如何测试屏幕锁定。即时通讯在这里看: http:/ /mxr.mozilla.org/chromium/source/src/chrome/browser/extensions/api/idle/idle_api_unittest.cc#84



[12: 56]哦,你看起来像他们投票: http://mxr.mozilla.org/chromium/source/src/chrome/browser/extensions/api/idle/idle_manager.h#118


也许他们没有投票。



检查:

http://mxr.mozilla .org / chromium / source / src / chrome / browser / extensions / api / idle / idle_manager.cc#246

  244 void IdleManager :: UpdateIdleStateCallback(int idle_time){
245 DCHECK(thread_checker_ .CalledOnValidThread());
246 bool locked = idle_time_provider _-> CheckIdleStateIsLocked();
247 int listener_count = 0;

导致: http://mxr.mozilla.org/chromium/source/src/chrome/browser/idle_win.cc#52



  52 bool CheckIdleStateIsLocked(){
53返回ui :: IsWorkstationLocked()|| IsScreensaverRunning();
54




$ p
$ b

这样我们就可以测试屏幕保护程序运行或工作站是否锁定 =http://mxr.mozilla.org/chromium/search?string=IsWorkstationLocked =nofollow> http://mxr.mozilla.org/chromium/search?string=IsWorkstationLocked




  • 我们只看到一个实现(它很好奇,因为没有linux支持,但是在chrome docs页面上没有这么说,所以也许我找不到它) b
    $ b


    • Windows


      • http://mxr.mozilla.org/chromium/source/src/ui/base/win/lock_state.cc#11

          11 bool IsWorkstationLocked(){
        12 bool is_locked = true;
        13 HDESK input_desk = :: OpenInputDesktop(0,0,GENERIC_READ);
        14 if(input_desk){
        15 wchar_t name [256] = {0};
        16 DWORD needed = 0;
        17 if(:: GetUserObjectInformation(
        18 input_desk,UOI_NAME,name,sizeof(name)& needed)){
        19 is_locked = lstrcmpi(name,Ldefault)! = 0;
        20}
        21 :: CloseDesktop(input_desk);
        22}
        23 return is_locked;
        24
        code

        $ b $ li $ $ b

        • 请参阅下面的屏幕保护程序部分,屏幕锁也通过此处理




  • http://mxr.mozilla.org/chromium/search?string=IsScreensaverRunning&find=&findi=&filter= ^% 5B ^ \ 0%5D *%24& hitlimit =& tree = chromium


    • 我们在此搜索结果中看到2 Mac和Windows看起来不支持linux,这很好奇,因为chrome.idle页面没有在文档中提到这个,也许我只是找不到它。




      • windows执行: http://mxr.mozilla.org/chromium/source/src/chrome/browser/idle_win.cc#39

          39 bool IsScreensaverRunning(){
        40 DWORD result = 0;
        41 if(:: SystemParametersInfo(SPI_GETSCREENSAVERRUNNING,0,& result,0))
        42返回结果!= FALSE;
        43返回false;
        44}
        45


      • mac执行: http://mxr.mozilla.org/chromium/source/src/chrome /browser/idle_mac.mm#28

          28  - (id)init {
        29 if( (self = [super init])){
        30 NSDistributedNotificationCenter * distCenter =
        31 [NSDistributedNotificationCenter defaultCenter];
        32 [distCenter addObserver:self
        33选择器:@selector(onScreenSaverStarted :)
        34名称:@com.apple.screensaver.didstart
        35 object:nil];
        36 [distCenter addObserver:self
        37选择器:@selector(onScreenSaverStopped)
        38名称:@com.apple.screensaver.didstop
        39 object:nil];
        40 [distCenter addObserver:self
        41选择器:@selector(onScreenLocked :)
        42名称:@com.apple.screenIsLocked
        43 object:nil];
        44 [distCenter addObserver:self
        45选择器:@selector(onScreenUnlocked :)
        46名称:@com.apple.screenIsUnlocked
        47 object:nil];
        48}
        49自我回报;
        50
        code $


        $ / $> li>


      所以总结一下:


      [13:32]对于windows来说,它的蛋糕winapi已经打电话来测试屏幕是否锁定或scrensaver运行

      [13:32]对于mac他们没有屏幕锁定测试。他们只是有屏幕保护程序测试,但它的观察员方法



      [13:32]对于Linux他们没有屏幕锁定和屏幕保护程序测试。真奇怪。如果他知道哪个os支持chrome.idle,那么请问这个家伙是否在

      编辑:其实我找到了linux的实现。返回搜索结果: CheckIdleStateLocked http://mxr.mozilla.org/chromium/search?string=CheckIdleStateIsLocked




      • http://mxr.mozilla.org/chromium/source/src/ chrome / browser / idle_linux.cc#24

          24 bool CheckIdleStateIsLocked(){
        25 //通常屏幕保护程序是用来锁定屏幕,所以我们不需要
        26 //检查工作站是否被锁定。
        27 #if defined(OS_CHROMEOS)
        28 return false;
        29 #elif defined(USE_OZONE)
        30 return false;
        31 #else
        32 return ScreensaverWindowFinder :: ScreensaverWindowExists();
        33 #endif
        34}


      • ScreensaverWindowExists 我们发现: http://mxr.mozilla.org/chromium/source/src/chrome/browser/screensaver_window_finder_x11.cc

          15 bool ScreensaverWindowFinder :: ScreensaverWindowExists(){
        16 gfx :: X11ErrorTracker err_tracker;
        17 ScreensaverWindowFinder finder;
        18 ui :: EnumerateTopLevelWindows(&finder);
        19返回finder.exists_&& !err_tracker.FoundNewError();



        $ b $ li $ EnumerateTopLevelWindows http:// mxr .mozilla.org / chromium / source / src / ui / base / x / x11_util.cc#1059

          1059 void EnumerateTopLevelWindows(ui :: EnumerateWindowsDelegate * delegate){
        1060 std :: vector< XID>栈;
        1061 if(!ui :: GetXWindowStack(ui :: GetX11RootWindow(),& stack)){
        1062 // Window Manager不支持_NET_CLIENT_LIST_STACKING,所以退回
        1063 / /到老式的所有X窗口列举。一些WMs父级'顶级'
        1064 //窗口在未命名的实际顶级窗口(ion WM)中,因此将
        1065 //搜索深度扩展到顶级窗口的所有子级。
        1066 const int kMaxSearchDepth = 1;
        1067 ui :: EnumerateAllWindows(delegate,kMaxSearchDepth);
        1068回报;
        1069}
        1070 XMenuList :: GetInstance() - > InsertMenuWindowXIDs(& stack);
        1071
        1072 std :: vector< XID> :: iterator iter; (iter = stack.begin(); iter!= stack.end(); iter ++){
        1074 if(delegate-&>; ShouldStopIterating(* iter))
        1075 return ;
        1076}
        1077}
        1078


      • 我们他们称之为委托 - > ShouldStopIterating ,它与 ScreensaverWindowExists http://mxr.mozilla.org/chromium/source/src/chrome/browser/screensaver_window_finder_x11。 cc $
        $ b $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $如果(!ui: :IsWindowVisible(window)||!IsScreensaverWindow(window))
        24 return false;
        25 exists_ = true;
        26返回true;
        27}


  • 需要询问 IsWindowVisible 和 IsScreensaverWindow




  • *在 ScreensaverWindowExists http://mxr.mozilla.org/chromium/source/src/chrome/browser/screensaver_window_finder_x11.cc

      29 bool ScreensaverWindowFinder :: IsScreensaverWindow(XID窗口)const {
    30 //它应该占据整个屏幕。
    31 if(!ui :: IsX11WindowFullScreen(window))
    32返回false;
    33
    34 //对于xscreensaver,窗口应具有_SCREENSAVER_VERSION属性。
    35 if(ui :: PropertyExists(window,_SCREENSAVER_VERSION))
    36 return true;
    37
    38 //对于所有其他的,如gnome-screensaver,窗口的WM_CLASS属性
    39 //应该包含屏幕保护程序。
    40 std :: string value;
    41 if(!ui :: GetStringProperty(window,WM_CLASS,& value))
    42返回false;
    43
    44返回value.find(screensaver)!= std :: string :: npos;
    45
    $ / code>




    • IsWindowVisible http ://mxr.mozilla.org/chromium/source/src/ui/base/x/x11_util.cc#546

        546 bool IsWindowVisible(XID窗口){
      547 TRACE_EVENT0(ui,IsWindowVisible);
      548
      549 XWindowAttributes win_attributes;
      550 if(!XGetWindowAttributes(gfx :: GetXDisplay(),window,& win_attributes))
      551 return false;
      552 if(win_attributes.map_state!= IsViewable)
      553 return false;
      554
      555 //最小化窗口不可见。
      556 std :: vector< XAtom> wm_states;
      557 if(GetAtomArrayProperty(window,_NET_WM_STATE,& wm_states)){
      558 XAtom hidden_​​atom = GetAtom(_ NET_WM_STATE_HIDDEN);
      559 if(std :: find(wm_states.begin(),wm_states.end(),hidden_​​atom)!=
      560 wm_states.end()){
      561 return false;
      562}
      563}



    I'm searching for a solution in my firefox addon to detect when the user workspace has locked/released. In google chrome there is an easy API chrome.idle.onStateChanged.addListener for it, is there something similar in firefox or any possibility to do that, platform independent? By the way, I use the addon sdk.

    I've already tried the idle service:

    Cc["@mozilla.org/widget/idleservice;1"].getService(Ci.nsIIdleService) 
    

    but I just gives me access to some idle timeout or system when go to sleep and not to just workspace locked.

    Edit: With "workspace locked" I mean the user lock the workspace with ctrl + alt + delete. I don't know how this exactly work on OSX or linux.

    Edit2: I working in Windows 8.1 currently, but I guess the chrome.idle handler works cross platform.

    Edit3: What i currently get out of current answers is 1. That there not exist a cross-platform solution, neither in chrome nor in firefox. chrome.idle.onStateChanged seems to work different on windows, linux and osx. Only windows can handle that "locked" behaviour as expected. I can't test OSX, on ubuntu 14 it doesn't work for me.
    2. For firefox there some in-depth code things to try to make it working - see answer bellow from Noitidart in this topic.

    Edit4: Noitidart have found a solution for windows - github link.

    解决方案

    I don't know how to detect screen lock but there are these observer notifications:

    https://developer.mozilla.org/en-US/docs/Observer_Notifications#Idle_Service

    Also the computer sleep wake notifications. ill ask around for lock screen thats an interesting one.

    Some useful chat about the subject, looking at how google chrome does it:

    [12:33] ok guys question about actual work. anyone know how to detect if screen was locked? apparently google chrome has a method: https://developer.chrome.com/extensions/idle#event-onStateChanged

    [12:45] anyone know of a MXR or DXR for google chromes codebase?

    [12:46] mxr.mozilla.org/chromium

    [12:52] Ms2ger: can you help me find how they test screen lock. im looking here: http://mxr.mozilla.org/chromium/source/src/chrome/browser/extensions/api/idle/idle_api_unittest.cc#84

    [12:56] oh yuck it looks like they poll: http://mxr.mozilla.org/chromium/source/src/chrome/browser/extensions/api/idle/idle_manager.h#118

    maybe they arent polling.

    check this out:

    http://mxr.mozilla.org/chromium/source/src/chrome/browser/extensions/api/idle/idle_manager.cc#246

    244 void IdleManager::UpdateIdleStateCallback(int idle_time) {
    245   DCHECK(thread_checker_.CalledOnValidThread());
    246   bool locked = idle_time_provider_->CheckIdleStateIsLocked();
    247   int listener_count = 0;
    

    leads to: http://mxr.mozilla.org/chromium/source/src/chrome/browser/idle_win.cc#52

    52 bool CheckIdleStateIsLocked() {
    53   return ui::IsWorkstationLocked() || IsScreensaverRunning();
    54 }
    

    so this leads us to test if screensaver running or workstation locked

    leads to:

    • http://mxr.mozilla.org/chromium/search?string=IsWorkstationLocked

      • we see just one implementation (its curious because there is no linux support but it doesnt say so on the chrome docs page, so maybe i couldnt find it)

        • Windows

          • http://mxr.mozilla.org/chromium/source/src/ui/base/win/lock_state.cc#11

            11 bool IsWorkstationLocked() {
            12   bool is_locked = true;
            13   HDESK input_desk = ::OpenInputDesktop(0, 0, GENERIC_READ);
            14   if (input_desk) {
            15     wchar_t name[256] = {0};
            16     DWORD needed = 0;
            17     if (::GetUserObjectInformation(
            18             input_desk, UOI_NAME, name, sizeof(name), &needed)) {
            19       is_locked = lstrcmpi(name, L"default") != 0;
            20     }
            21     ::CloseDesktop(input_desk);
            22   }
            23   return is_locked;
            24 }
            

        • Mac
          • see the screensaver section below, the screenlock is handled via there as well
    • http://mxr.mozilla.org/chromium/search?string=IsScreensaverRunning&find=&findi=&filter=^%5B^\0%5D*%24&hitlimit=&tree=chromium

      • we see in this search results 2 implementations, mac and windows it looks like no support for linux, which is curious because the chrome.idle page doesnt mention this on docs, maybe i just couldnt find it

        • windows implementation: http://mxr.mozilla.org/chromium/source/src/chrome/browser/idle_win.cc#39

          39 bool IsScreensaverRunning() {
          40   DWORD result = 0;
          41   if (::SystemParametersInfo(SPI_GETSCREENSAVERRUNNING, 0, &result, 0))
          42     return result != FALSE;
          43   return false;
          44 }
          45 
          

        • mac implementation: http://mxr.mozilla.org/chromium/source/src/chrome/browser/idle_mac.mm#28

          28 - (id)init {
          29   if ((self = [super init])) {
          30     NSDistributedNotificationCenter* distCenter =
          31           [NSDistributedNotificationCenter defaultCenter];
          32     [distCenter addObserver:self
          33                    selector:@selector(onScreenSaverStarted:)
          34                        name:@"com.apple.screensaver.didstart"
          35                      object:nil];
          36     [distCenter addObserver:self
          37                    selector:@selector(onScreenSaverStopped:)
          38                        name:@"com.apple.screensaver.didstop"
          39                      object:nil];
          40     [distCenter addObserver:self
          41                    selector:@selector(onScreenLocked:)
          42                        name:@"com.apple.screenIsLocked"
          43                      object:nil];
          44     [distCenter addObserver:self
          45                    selector:@selector(onScreenUnlocked:)
          46                        name:@"com.apple.screenIsUnlocked"
          47                      object:nil];
          48   }
          49   return self;
          50 }
          

    so to sum this all up:

    [13:32] for windows its peice of cake winapi has call to test if screen is locked or scrensaver running

    [13:32] for mac they dont have screen lock test. they just have screensaver test, but its an observer method

    [13:32] for linux they dont have screen lock nor screen saver test. real odd. ill ask the guy if he knows which os's they support chrome.idle in

    edit: actually i found the linux implementation. back from the search results of: CheckIdleStateLocked: http://mxr.mozilla.org/chromium/search?string=CheckIdleStateIsLocked

    • http://mxr.mozilla.org/chromium/source/src/chrome/browser/idle_linux.cc#24

      24 bool CheckIdleStateIsLocked() {
      25   // Usually the screensaver is used to lock the screen, so we do not need to
      26   // check if the workstation is locked.
      27 #if defined(OS_CHROMEOS)
      28   return false;
      29 #elif defined(USE_OZONE)
      30   return false;
      31 #else
      32   return ScreensaverWindowFinder::ScreensaverWindowExists();
      33 #endif
      34 }
      

    • Leads to ask how is ScreensaverWindowExists we find this: http://mxr.mozilla.org/chromium/source/src/chrome/browser/screensaver_window_finder_x11.cc

      15 bool ScreensaverWindowFinder::ScreensaverWindowExists() {
      16   gfx::X11ErrorTracker err_tracker;
      17   ScreensaverWindowFinder finder;
      18   ui::EnumerateTopLevelWindows(&finder);
      19   return finder.exists_ && !err_tracker.FoundNewError();
      20 }
      

    • Leads to what is EnumerateTopLevelWindows http://mxr.mozilla.org/chromium/source/src/ui/base/x/x11_util.cc#1059:

      1059 void EnumerateTopLevelWindows(ui::EnumerateWindowsDelegate* delegate) {
      1060   std::vector<XID> stack;
      1061   if (!ui::GetXWindowStack(ui::GetX11RootWindow(), &stack)) {
      1062     // Window Manager doesn't support _NET_CLIENT_LIST_STACKING, so fall back
      1063     // to old school enumeration of all X windows.  Some WMs parent 'top-level'
      1064     // windows in unnamed actual top-level windows (ion WM), so extend the
      1065     // search depth to all children of top-level windows.
      1066     const int kMaxSearchDepth = 1;
              1067     ui::EnumerateAllWindows(delegate, kMaxSearchDepth);
      1068     return;
      1069   }
      1070   XMenuList::GetInstance()->InsertMenuWindowXIDs(&stack);
      1071 
      1072   std::vector<XID>::iterator iter;
      1073   for (iter = stack.begin(); iter != stack.end(); iter++) {
      1074     if (delegate->ShouldStopIterating(*iter))
      1075       return;
      1076   }
      1077 }
      1078 
      

    • We say they call delegate->ShouldStopIterating which was seen in same file as ScreensaverWindowExists: http://mxr.mozilla.org/chromium/source/src/chrome/browser/screensaver_window_finder_x11.cc

      22 bool ScreensaverWindowFinder::ShouldStopIterating(XID window) {
      23   if (!ui::IsWindowVisible(window) || !IsScreensaverWindow(window))
      24     return false;
      25   exists_ = true;
      26   return true;
      27 }
      

    • Leads to ask what is IsWindowVisible and IsScreensaverWindow

    *IsScreensaverWindow, in same file of ScreensaverWindowExists: http://mxr.mozilla.org/chromium/source/src/chrome/browser/screensaver_window_finder_x11.cc

        29 bool ScreensaverWindowFinder::IsScreensaverWindow(XID window) const {
        30   // It should occupy the full screen.
        31   if (!ui::IsX11WindowFullScreen(window))
        32     return false;
        33 
        34   // For xscreensaver, the window should have _SCREENSAVER_VERSION property.
        35   if (ui::PropertyExists(window, "_SCREENSAVER_VERSION"))
        36     return true;
        37 
        38   // For all others, like gnome-screensaver, the window's WM_CLASS property
        39   // should contain "screensaver".
        40   std::string value;
        41   if (!ui::GetStringProperty(window, "WM_CLASS", &value))
        42     return false;
        43 
        44   return value.find("screensaver") != std::string::npos;
        45 }
    

    • IsWindowVisible: http://mxr.mozilla.org/chromium/source/src/ui/base/x/x11_util.cc#546

      546 bool IsWindowVisible(XID window) {
      547   TRACE_EVENT0("ui", "IsWindowVisible");
      548 
      549   XWindowAttributes win_attributes;
      550   if (!XGetWindowAttributes(gfx::GetXDisplay(), window, &win_attributes))
      551     return false;
      552   if (win_attributes.map_state != IsViewable)
      553     return false;
      554 
      555   // Minimized windows are not visible.
      556   std::vector<XAtom> wm_states;
      557   if (GetAtomArrayProperty(window, "_NET_WM_STATE", &wm_states)) {
      558     XAtom hidden_atom = GetAtom("_NET_WM_STATE_HIDDEN");
      559     if (std::find(wm_states.begin(), wm_states.end(), hidden_atom) !=
      560             wm_states.end()) {
      561       return false;
      562     }
      563   }
      

    这篇关于Firefox扩展/插件 - 检测工作区锁定的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

    查看全文
    登录 关闭
    扫码关注1秒登录
    发送“验证码”获取 | 15天全站免登陆