1- import type { IGlobalKeyListener } from "node-global-key-listener" ;
21import {
32 activeWindow ,
43 subscribeActiveWindow ,
54 unsubscribeActiveWindow ,
65 WindowInfo ,
76} from "@miniben90/x-win" ;
8- import { GlobalKeyboardListener } from "node-global-key-listener " ;
7+ import { powerMonitor } from "electron " ;
98
109import { AppsManager } from "../helpers/apps-manager" ;
1110import { MonitoredApp } from "../helpers/monitored-app" ;
@@ -17,23 +16,21 @@ export class Watcher {
1716 wakatime : Wakatime ;
1817 activeWindow ?: WindowInfo ;
1918 private activeWindowSubscription : number | null ;
20- private gkl : GlobalKeyboardListener ;
21- private isWatchingForKeyboardEvents = false ;
19+ private interval : NodeJS . Timeout | null ;
2220
2321 constructor ( wakatime : Wakatime ) {
2422 this . wakatime = wakatime ;
2523 this . activeWindowSubscription = null ;
26- this . gkl = new GlobalKeyboardListener ( ) ;
24+ this . interval = null ;
2725 }
2826
29- private globalKeyListener : IGlobalKeyListener = ( event ) => {
30- if ( event . state !== "DOWN" ) {
31- return ;
32- }
33-
27+ private handleActivity ( ) {
3428 try {
35- // To ensure we always retrieve the most current window information, including the updated URL and title, we use the activeWindow function instead of relying on the previously stored this.activeApp. This approach addresses the issue where switching tabs in your browser does not trigger a window change event, leading to activeApp retaining outdated URL and title information.
3629 const window = activeWindow ( ) ;
30+ if ( ! MonitoringManager . isMonitored ( window . info . path ) ) {
31+ return ;
32+ }
33+
3734 const app = AppsManager . instance ( ) . getApp ( window . info . path ) ;
3835 const heartbeatData = MonitoredApp . heartbeatData ( window , app ) ;
3936 if ( ! heartbeatData ) {
@@ -53,58 +50,39 @@ export class Watcher {
5350 } catch ( error ) {
5451 Logging . instance ( ) . log ( ( error as Error ) . message , LogLevel . ERROR , true ) ;
5552 }
56- } ;
57-
58- private watchKeyboardEvents ( ) {
59- this . isWatchingForKeyboardEvents = true ;
60- this . gkl . addListener ( this . globalKeyListener ) ;
61- }
62-
63- private unwatchKeyboardEvents ( ) {
64- this . isWatchingForKeyboardEvents = false ;
65- this . gkl . removeListener ( this . globalKeyListener ) ;
6653 }
6754
6855 start ( ) {
56+ this . stop ( ) ;
6957 this . activeWindowSubscription = subscribeActiveWindow (
7058 ( windowInfo : WindowInfo ) => {
7159 if ( ! windowInfo . info . processId ) return ;
7260 if ( this . activeWindow ?. info . processId === windowInfo . info . processId ) {
7361 return ;
7462 }
7563
76- if ( this . isWatchingForKeyboardEvents ) {
77- this . unwatchKeyboardEvents ( ) ;
78- }
79-
8064 Logging . instance ( ) . log (
8165 `App changed from ${ this . activeWindow ?. info . name || "nil" } to ${ windowInfo . info . name } ` ,
8266 ) ;
83-
8467 this . activeWindow = windowInfo ;
85- if ( this . activeWindow . info . path ) {
86- const isMonitored = MonitoringManager . isMonitored (
87- this . activeWindow . info . path ,
88- ) ;
8968
90- if ( isMonitored ) {
91- Logging . instance ( ) . log (
92- `Monitoring ${ windowInfo . info . name } : ${ this . activeWindow . info . path } ` ,
93- ) ;
94- this . watchKeyboardEvents ( ) ;
95- } else {
96- Logging . instance ( ) . log (
97- `Not monitoring ${ windowInfo . info . name } : ${ this . activeWindow . info . path } ` ,
98- ) ;
99- }
100- }
69+ this . handleActivity ( ) ;
10170 } ,
10271 ) ;
72+ this . interval = setInterval ( ( ) => {
73+ const idleState = powerMonitor . getSystemIdleState ( 10 ) ;
74+ if ( idleState === "active" ) {
75+ this . handleActivity ( ) ;
76+ }
77+ } , 5000 ) ;
10378 }
10479
10580 stop ( ) {
10681 if ( this . activeWindowSubscription !== null ) {
10782 unsubscribeActiveWindow ( this . activeWindowSubscription ) ;
10883 }
84+ if ( this . interval !== null ) {
85+ clearInterval ( this . interval ) ;
86+ }
10987 }
11088}
0 commit comments