Skip to content

Commit b289487

Browse files
authored
Merge pull request #120 from wakatime/major/idle-time
Switch from global keylogger to idle time interval
2 parents 5bca444 + 592527e commit b289487

File tree

4 files changed

+21
-62
lines changed

4 files changed

+21
-62
lines changed

electron/watchers/watcher.ts

Lines changed: 19 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,10 @@
1-
import type { IGlobalKeyListener } from "node-global-key-listener";
21
import {
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

109
import { AppsManager } from "../helpers/apps-manager";
1110
import { 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
}

package-lock.json

Lines changed: 0 additions & 14 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,6 @@
3838
"iconutil": "^1.0.2",
3939
"lucide-react": "^0.428.0",
4040
"node-fetch": "^3.3.2",
41-
"node-global-key-listener": "^0.3.0",
4241
"plist": "^3.1.0",
4342
"react": "^18.3.1",
4443
"react-dom": "^18.3.1",
@@ -80,4 +79,4 @@
8079
"vite-plugin-native": "^2.2.1"
8180
},
8281
"main": "dist-electron/main.js"
83-
}
82+
}

vite.config.ts

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -14,11 +14,7 @@ export default defineConfig({
1414
vite: {
1515
build: {
1616
rollupOptions: {
17-
external: [
18-
"@miniben90/x-win",
19-
"node-global-key-listener",
20-
"icon-promise",
21-
],
17+
external: ["@miniben90/x-win", "icon-promise"],
2218
},
2319
minify: false,
2420
},

0 commit comments

Comments
 (0)