!7 cm UserActivityDetector > DynBigNumber { long lastActivity; transient long persistedLastActivity; transient Pt lastMousePosition; start { setDescription("LAST ACTIVITY"); //dm_startKeyLogger(); // crashes on some machines persistedLastActivity = lastActivity; dm_vmBus_onMessages(r activity, 'keyDown, 'javaKeyEvent, 'speechRecognized_raw); dm_doEvery(1.0, r { Pt mouse = toPt(mousePosition()); if (neq(lastMousePosition, mouse)) { lastMousePosition = mouse; activity(); } setValue(lastActivity == 0 ? "NEVER" : iround(secondsSinceLastActivity()) + " s ago"); }); dm_doEvery(5*60.0, r saveIfChanged); } void saveIfChanged enter { if (lastActivity != persistedLastActivity) { persistedLastActivity = lastActivity; change(); } } // API void activity enter { lastActivity = now(); vmBus_send userActivityDetected(); } double secondsSinceLastActivity() { ret lastActivity == 0 ? infinity() : toSeconds(now()-lastActivity); } }