我在firefox插件中搜索解决方案,以检测用户工作区何时锁定/释放。在谷歌浏览器中有一个简单的API chrome.idle.onStateChanged.addListener
,它有什么类似的Firefox或任何可能做到这一点,平台独立?
顺便说一句,我使用addon sdk。
我已经尝试过空闲服务了:
Cc["@mozilla.org/widget/idleservice;1"].getService(Ci.nsIIdleService)
但是我只是让我在进入睡眠时访问一些空闲超时或系统而不是仅仅锁定工作空间。
编辑:使用"工作区锁定"我的意思是用户使用 ctrl + alt + delete 锁定工作区。我不知道这在OSX或Linux上是如何工作的。
Edit2:我目前在Windows 8.1工作,但我想chrome.idle
处理程序可以跨平台工作。
Edit3:我目前得出的答案是
1.在chrome和firefox中都没有跨平台解决方案。
chrome.idle.onStateChanged
似乎在windows,linux和osx上有所不同。只有窗户可以处理这个"锁定"行为如预期。我无法测试OSX,在ubuntu 14上它对我不起作用。
2.对于firefox,有一些深入的代码可以让它工作 - 请参阅Noitidart在本主题中的回答。
Edit4:Noitidart找到了Windows的解决方案 - github link。
答案 0 :(得分:1)
我不知道如何检测屏幕锁定,但有这些观察者通知:
https://developer.mozilla.org/en-US/docs/Observer_Notifications#Idle_Service
还有计算机睡眠唤醒通知。我问周围的锁屏是一个有趣的。
关于这个主题的一些有用的聊天,看看谷歌浏览器是如何做到的:
也许他们不是民意调查。[12:33]好的人质疑实际工作。有谁知道如何检测屏幕是否被锁定?显然谷歌浏览器有一个方法:https://developer.chrome.com/extensions/idle#event-onStateChanged
[12:45]有人知道谷歌chromes代码库的MXR或DXR吗?
[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 return ui::IsWorkstationLocked() || IsScreensaverRunning();
54 }
因此,这会导致我们测试屏幕保护程序是否正常运行或工作站已锁定
导致:
http://mxr.mozilla.org/chromium/search?string=IsWorkstationLocked
我们只看到一个实现(它好奇,因为没有linux支持,但它在chrome文档页面上没有这么说,所以也许我找不到它)
窗
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 }
http://mxr.mozilla.org/chromium/search?string=IsScreensaverRunning&find=&findi=&filter= ^%5B ^ \ 0%5D *%24&安培; hitlimit =安培;树=铬
我们在这个搜索结果中看到2个实现,mac和windows 它看起来好像不支持linux,这很好奇,因为chrome.idle页面没有在docs上提到这个,也许我只是找不到它
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 return result != FALSE;
43 return 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:@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 }
所以总结一下:
[13:32]对于Windows,它的蛋糕winapi已经调用测试屏幕是否锁定或scrensaver运行
[13:32]对于mac他们没有屏幕锁定测试。他们只是有屏幕保护程序测试,但它是一个观察者方法
[13:32]对于linux,他们没有屏幕锁定或屏幕保护程序测试。真奇怪。如果他知道他们支持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 // 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 }
导致问我们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 return finder.exists_ && !err_tracker.FoundNewError();
20 }
导致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
我们称他们致电delegate->ShouldStopIterating
,该档案与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 }
导致询问什么是IsWindowVisible
和IsScreensaverWindow
* IsScreensaverWindow
,位于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 }