Skip to content

Commit fcc4fbd

Browse files
committed
load x-win async to prevent windows 11 arm crashes on startup
1 parent d90dbd8 commit fcc4fbd

File tree

4 files changed

+72
-15
lines changed

4 files changed

+72
-15
lines changed

package-lock.json

Lines changed: 2 additions & 2 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 & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "solidtime",
3-
"version": "0.0.56-beta",
3+
"version": "0.0.57-beta",
44
"description": "Desktop App for solidtime - the modern open-source time tracker",
55
"main": "./out/main/index.js",
66
"author": "solidtime.io",

src/main/activityTracker.ts

Lines changed: 44 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,42 @@
1-
import {
2-
activeWindowAsync,
3-
subscribeActiveWindow,
4-
unsubscribeAllActiveWindow,
5-
} from '@miniben90/x-win'
61
import { db } from './db/client'
72
import { windowActivities, validateNewWindowActivity } from './db/schema'
83
import { getAppSettings } from './settings'
94
import { hasScreenRecordingPermission } from './permissions'
105
import { ipcMain } from 'electron'
116
import { logger } from './logger'
127

8+
// Lazy-load x-win module with detailed error reporting
9+
let xWinModule: any = null
10+
let xWinLoadError: Error | null = null
11+
12+
async function loadXWinModule() {
13+
if (xWinModule) return xWinModule
14+
if (xWinLoadError) throw xWinLoadError
15+
16+
try {
17+
console.log('=== ATTEMPTING TO LOAD @miniben90/x-win ===')
18+
console.log('Process platform:', process.platform)
19+
console.log('Process arch:', process.arch)
20+
console.log('Process versions:', JSON.stringify(process.versions, null, 2))
21+
console.log('__dirname:', __dirname)
22+
console.log('process.cwd():', process.cwd())
23+
console.log('app.isPackaged:', require('electron').app.isPackaged)
24+
25+
xWinModule = await import('@miniben90/x-win')
26+
console.log('=== @miniben90/x-win LOADED SUCCESSFULLY ===')
27+
return xWinModule
28+
} catch (error) {
29+
console.error('=== FAILED TO LOAD @miniben90/x-win ===')
30+
console.error('Error name:', error instanceof Error ? error.name : 'Unknown')
31+
console.error('Error message:', error instanceof Error ? error.message : String(error))
32+
console.error('Error stack:', error instanceof Error ? error.stack : 'No stack')
33+
console.error('Full error:', JSON.stringify(error, Object.getOwnPropertyNames(error), 2))
34+
35+
xWinLoadError = error instanceof Error ? error : new Error(String(error))
36+
throw xWinLoadError
37+
}
38+
}
39+
1340
interface WindowInfo {
1441
id: number
1542
title: string
@@ -114,9 +141,17 @@ export async function startActivityTracking(): Promise<void> {
114141

115142
logger.info('Starting activity tracking...')
116143

144+
let xWin
145+
try {
146+
xWin = await loadXWinModule()
147+
} catch (error) {
148+
logger.error('Cannot start activity tracking - x-win module failed to load:', error)
149+
return
150+
}
151+
117152
try {
118153
// Get initial window state
119-
const initialWindow = await activeWindowAsync()
154+
const initialWindow = await xWin.activeWindowAsync()
120155
if (initialWindow) {
121156
lastWindowInfo = initialWindow as WindowInfo
122157
currentActivityStartTime = new Date()
@@ -128,7 +163,7 @@ export async function startActivityTracking(): Promise<void> {
128163
}
129164

130165
// Subscribe to window changes
131-
subscriptionId = subscribeActiveWindow(async (error, windowInfo) => {
166+
subscriptionId = xWin.subscribeActiveWindow(async (error, windowInfo) => {
132167
if (error) {
133168
logger.error('Error in window subscription:', error)
134169
return
@@ -254,8 +289,8 @@ export async function stopActivityTracking(): Promise<void> {
254289
await saveCurrentActivityIfNeeded()
255290

256291
// Unsubscribe from window changes
257-
if (subscriptionId !== null) {
258-
unsubscribeAllActiveWindow()
292+
if (subscriptionId !== null && xWinModule) {
293+
xWinModule.unsubscribeAllActiveWindow()
259294
subscriptionId = null
260295
}
261296

src/main/appIcons.ts

Lines changed: 25 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,28 @@
11
import { ipcMain, app } from 'electron'
2-
import { openWindowsAsync } from '@miniben90/x-win'
32
import * as fs from 'fs/promises'
43
import * as path from 'path'
54

5+
// Lazy-load x-win module with detailed error reporting
6+
let xWinModule: any = null
7+
let xWinLoadError: Error | null = null
8+
9+
async function loadXWinModule() {
10+
if (xWinModule) return xWinModule
11+
if (xWinLoadError) throw xWinLoadError
12+
13+
try {
14+
console.log('=== appIcons: ATTEMPTING TO LOAD @miniben90/x-win ===')
15+
xWinModule = await import('@miniben90/x-win')
16+
console.log('=== appIcons: @miniben90/x-win LOADED SUCCESSFULLY ===')
17+
return xWinModule
18+
} catch (error) {
19+
console.error('=== appIcons: FAILED TO LOAD @miniben90/x-win ===')
20+
console.error('Error:', error instanceof Error ? error.message : String(error))
21+
xWinLoadError = error instanceof Error ? error : new Error(String(error))
22+
throw xWinLoadError
23+
}
24+
}
25+
626
const ICON_CACHE_DIR = path.join(app.getPath('userData'), 'app-icons')
727
const ICON_CACHE_EXPIRY_DAYS = 30 // Expire icons after 30 days
828

@@ -116,7 +136,8 @@ export async function getAppIcon(appName: string): Promise<string | null> {
116136
*/
117137
async function fetchIconForApp(appName: string): Promise<string | null> {
118138
try {
119-
const windows = await openWindowsAsync()
139+
const xWin = await loadXWinModule()
140+
const windows = await xWin.openWindowsAsync()
120141
const matchingWindow = windows.find(
121142
(win) => win.info.name === appName || win.info.execName === appName
122143
)
@@ -165,7 +186,8 @@ async function getAppIcons(appNames: string[]): Promise<Record<string, string |
165186

166187
// Fetch all open windows once for all uncached apps
167188
try {
168-
const windows = await openWindowsAsync()
189+
const xWin = await loadXWinModule()
190+
const windows = await xWin.openWindowsAsync()
169191

170192
// Process each app that needs fetching
171193
await Promise.all(

0 commit comments

Comments
 (0)