node-mac-recorder 2.21.45 → 2.21.48
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/src/cursor_tracker.mm +68 -22
package/package.json
CHANGED
package/src/cursor_tracker.mm
CHANGED
|
@@ -1223,43 +1223,90 @@ static void LoadCursorMappingOverrides(void) {
|
|
|
1223
1223
|
|
|
1224
1224
|
// Runtime seed mapping - built dynamically on first use
|
|
1225
1225
|
// Seeds change between app launches, so we build the mapping at runtime by querying NSCursor objects
|
|
1226
|
+
// SAFETY: Protected with try-catch to prevent crashes in Electron environments
|
|
1227
|
+
static BOOL g_enableSeedLearning = YES; // Runtime seed learning enabled with crash protection
|
|
1226
1228
|
static NSMutableDictionary<NSNumber*, NSString*> *g_seedToTypeMap = nil;
|
|
1227
1229
|
static dispatch_once_t g_seedMapInitToken;
|
|
1228
1230
|
|
|
1229
1231
|
static void buildRuntimeSeedMapping() {
|
|
1230
1232
|
dispatch_once(&g_seedMapInitToken, ^{
|
|
1231
|
-
|
|
1233
|
+
@try {
|
|
1234
|
+
@autoreleasepool {
|
|
1235
|
+
g_seedToTypeMap = [[NSMutableDictionary alloc] init];
|
|
1232
1236
|
|
|
1233
|
-
|
|
1234
|
-
|
|
1235
|
-
|
|
1237
|
+
// Instead of trying to build mapping upfront (which crashes),
|
|
1238
|
+
// we'll build it lazily as we encounter cursors during actual usage
|
|
1239
|
+
// For now, just initialize the empty map
|
|
1236
1240
|
|
|
1237
|
-
|
|
1241
|
+
NSLog(@"✅ Runtime seed mapping initialized (will build lazily)");
|
|
1242
|
+
}
|
|
1243
|
+
} @catch (NSException *exception) {
|
|
1244
|
+
NSLog(@"⚠️ Failed to initialize runtime seed mapping: %@", exception.reason);
|
|
1245
|
+
g_seedToTypeMap = nil;
|
|
1246
|
+
}
|
|
1238
1247
|
});
|
|
1239
1248
|
}
|
|
1240
1249
|
|
|
1241
1250
|
// Add a cursor seed to the runtime mapping
|
|
1242
|
-
|
|
1243
|
-
|
|
1251
|
+
// NOTE: We don't pass cursor object to avoid potential crashes - we only need seed and type
|
|
1252
|
+
static void addCursorToSeedMap(NSString *detectedType, int seed) {
|
|
1253
|
+
// Safety: Check if learning is enabled
|
|
1254
|
+
if (!g_enableSeedLearning) return;
|
|
1255
|
+
|
|
1256
|
+
if (seed <= 0 || !detectedType || [detectedType length] == 0) return;
|
|
1244
1257
|
|
|
1245
|
-
|
|
1258
|
+
@try {
|
|
1259
|
+
@autoreleasepool {
|
|
1260
|
+
buildRuntimeSeedMapping(); // Ensure map is initialized
|
|
1261
|
+
|
|
1262
|
+
// If initialization failed, don't proceed
|
|
1263
|
+
if (!g_seedToTypeMap) return;
|
|
1264
|
+
|
|
1265
|
+
NSNumber *key = @(seed);
|
|
1246
1266
|
|
|
1247
|
-
|
|
1248
|
-
|
|
1249
|
-
|
|
1250
|
-
|
|
1251
|
-
|
|
1252
|
-
|
|
1267
|
+
// Only add if we don't have this seed yet
|
|
1268
|
+
if (![g_seedToTypeMap objectForKey:key]) {
|
|
1269
|
+
[g_seedToTypeMap setObject:detectedType forKey:key];
|
|
1270
|
+
// Log only first 10 learned mappings to avoid spam
|
|
1271
|
+
if ([g_seedToTypeMap count] <= 10) {
|
|
1272
|
+
NSLog(@"📝 Learned seed mapping: %d -> %@", seed, detectedType);
|
|
1273
|
+
}
|
|
1274
|
+
}
|
|
1253
1275
|
}
|
|
1276
|
+
} @catch (NSException *exception) {
|
|
1277
|
+
// Silently fail - don't crash the app for cursor learning
|
|
1278
|
+
NSLog(@"⚠️ Failed to add cursor seed mapping: %@", exception.reason);
|
|
1279
|
+
} @catch (...) {
|
|
1280
|
+
NSLog(@"⚠️ Failed to add cursor seed mapping (unknown exception)");
|
|
1254
1281
|
}
|
|
1255
1282
|
}
|
|
1256
1283
|
|
|
1257
1284
|
static NSString* cursorTypeFromSeed(int seed) {
|
|
1258
1285
|
if (seed > 0) {
|
|
1259
|
-
|
|
1260
|
-
|
|
1261
|
-
|
|
1262
|
-
|
|
1286
|
+
@try {
|
|
1287
|
+
@autoreleasepool {
|
|
1288
|
+
NSNumber *key = @(seed);
|
|
1289
|
+
NSString *override = [g_seedOverrides objectForKey:key];
|
|
1290
|
+
if (override) {
|
|
1291
|
+
return override;
|
|
1292
|
+
}
|
|
1293
|
+
|
|
1294
|
+
// Only check runtime mappings if learning is enabled
|
|
1295
|
+
if (g_enableSeedLearning) {
|
|
1296
|
+
buildRuntimeSeedMapping();
|
|
1297
|
+
if (g_seedToTypeMap) {
|
|
1298
|
+
NSString *runtime = [g_seedToTypeMap objectForKey:key];
|
|
1299
|
+
if (runtime) {
|
|
1300
|
+
return runtime;
|
|
1301
|
+
}
|
|
1302
|
+
}
|
|
1303
|
+
}
|
|
1304
|
+
}
|
|
1305
|
+
} @catch (NSException *exception) {
|
|
1306
|
+
// Silently fail - don't crash for cursor lookup
|
|
1307
|
+
NSLog(@"⚠️ Exception in cursorTypeFromSeed: %@", exception.reason);
|
|
1308
|
+
} @catch (...) {
|
|
1309
|
+
NSLog(@"⚠️ Unknown exception in cursorTypeFromSeed");
|
|
1263
1310
|
}
|
|
1264
1311
|
}
|
|
1265
1312
|
switch(seed) {
|
|
@@ -1710,10 +1757,9 @@ static NSString* detectSystemCursorType(void) {
|
|
|
1710
1757
|
dispatch_sync(dispatch_get_main_queue(), fetchCursorBlock);
|
|
1711
1758
|
}
|
|
1712
1759
|
|
|
1713
|
-
|
|
1714
|
-
|
|
1715
|
-
|
|
1716
|
-
// }
|
|
1760
|
+
if (cursorType && ![cursorType isEqualToString:@"default"] && cursorSeed > 0) {
|
|
1761
|
+
addCursorToSeedMap(cursorType, cursorSeed);
|
|
1762
|
+
}
|
|
1717
1763
|
|
|
1718
1764
|
return cursorType;
|
|
1719
1765
|
}
|