+ _continousOutputs = [[NSMutableArray alloc] initWithCapacity:32];
+
+ NSArray *expanded = [NSUserDefaults.standardUserDefaults objectForKey:@"expanded rows"];
+ if (![expanded isKindOfClass:NSArray.class])
+ expanded = @[];
+ _expanded = [[NSMutableArray alloc] initWithCapacity:MAX(16, _expanded.count)];
+ [_expanded addObjectsFromArray:expanded];
+
+ _hidManager = [[NJHIDManager alloc] initWithCriteria:@[
+ @{ NSSTR(kIOHIDDeviceUsagePageKey) : @(kHIDPage_GenericDesktop),
+ NSSTR(kIOHIDDeviceUsageKey) : @(kHIDUsage_GD_Joystick) },
+ @{ NSSTR(kIOHIDDeviceUsagePageKey) : @(kHIDPage_GenericDesktop),
+ NSSTR(kIOHIDDeviceUsageKey) : @(kHIDUsage_GD_GamePad) },
+ @{ NSSTR(kIOHIDDeviceUsagePageKey) : @(kHIDPage_GenericDesktop),
+ NSSTR(kIOHIDDeviceUsageKey) : @(kHIDUsage_GD_MultiAxisController) }
+ ]
+ delegate:self];
+
+ [NSNotificationCenter.defaultCenter
+ addObserver:self
+ selector:@selector(startHid)
+ name:NSApplicationDidFinishLaunchingNotification
+ object:nil];
+
+ // The HID manager uses 5-10ms per second doing basically
+ // nothing if a noisy device is plugged in (the % of that
+ // spent in input_callback is negligible, so it's not
+ // something we can make faster). I don't really think that's
+ // acceptable, CPU/power wise. So if simulation is disabled
+ // and the window is closed, just switch off the HID manager
+ // entirely. This probably also has some marginal benefits for
+ // compatibility with other applications that want exclusive
+ // grabs.
+ [NSNotificationCenter.defaultCenter
+ addObserver:self
+ selector:@selector(stopHidIfDisabled:)
+ name:NSApplicationDidResignActiveNotification
+ object:nil];
+ [NSNotificationCenter.defaultCenter
+ addObserver:self
+ selector:@selector(startHid)
+ name:NSApplicationDidBecomeActiveNotification
+ object:nil];