node-mac-recorder 2.21.46 → 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 +66 -25
package/package.json
CHANGED
package/src/cursor_tracker.mm
CHANGED
|
@@ -1223,49 +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;
|
|
1244
1255
|
|
|
1245
|
-
|
|
1256
|
+
if (seed <= 0 || !detectedType || [detectedType length] == 0) return;
|
|
1246
1257
|
|
|
1247
|
-
|
|
1248
|
-
|
|
1249
|
-
|
|
1250
|
-
|
|
1251
|
-
|
|
1252
|
-
|
|
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);
|
|
1266
|
+
|
|
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
|
-
|
|
1263
|
-
|
|
1286
|
+
@try {
|
|
1287
|
+
@autoreleasepool {
|
|
1288
|
+
NSNumber *key = @(seed);
|
|
1289
|
+
NSString *override = [g_seedOverrides objectForKey:key];
|
|
1290
|
+
if (override) {
|
|
1291
|
+
return override;
|
|
1292
|
+
}
|
|
1264
1293
|
|
|
1265
|
-
|
|
1266
|
-
|
|
1267
|
-
|
|
1268
|
-
|
|
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");
|
|
1269
1310
|
}
|
|
1270
1311
|
}
|
|
1271
1312
|
switch(seed) {
|
|
@@ -1716,8 +1757,8 @@ static NSString* detectSystemCursorType(void) {
|
|
|
1716
1757
|
dispatch_sync(dispatch_get_main_queue(), fetchCursorBlock);
|
|
1717
1758
|
}
|
|
1718
1759
|
|
|
1719
|
-
if (cursorType && ![cursorType isEqualToString:@"default"] && cursorSeed > 0
|
|
1720
|
-
addCursorToSeedMap(
|
|
1760
|
+
if (cursorType && ![cursorType isEqualToString:@"default"] && cursorSeed > 0) {
|
|
1761
|
+
addCursorToSeedMap(cursorType, cursorSeed);
|
|
1721
1762
|
}
|
|
1722
1763
|
|
|
1723
1764
|
return cursorType;
|