Hide the home bar when a gamepad is connected and no on-screen controls are visible

Fixes #386
This commit is contained in:
Cameron Gutman
2019-10-22 00:32:56 -04:00
parent 967ddd7d68
commit 5faa8a0b85
4 changed files with 50 additions and 5 deletions

View File

@@ -11,9 +11,15 @@
@class OnScreenControls;
@protocol GamepadPresenceDelegate <NSObject>
- (void) gamepadPresenceChanged;
@end
@interface ControllerSupport : NSObject
-(id) initWithConfig:(StreamConfiguration*)streamConfig;
-(id) initWithConfig:(StreamConfiguration*)streamConfig presenceDelegate:(id<GamepadPresenceDelegate>)delegate;
-(void) initAutoOnScreenControlMode:(OnScreenControls*)osc;
-(void) cleanup;
@@ -36,6 +42,8 @@
+(int) getConnectedGamepadMask:(StreamConfiguration*)streamConfig;
-(NSUInteger) getConnectedGamepadCount;
@property (nonatomic, strong) id connectObserver;
@property (nonatomic, strong) id disconnectObserver;

View File

@@ -21,6 +21,7 @@
NSLock *_controllerStreamLock;
NSMutableDictionary *_controllers;
NSTimer *_rumbleTimer;
id<GamepadPresenceDelegate> _presenceDelegate;
OnScreenControls *_osc;
@@ -464,7 +465,12 @@
}
}
-(id) initWithConfig:(StreamConfiguration*)streamConfig
-(NSUInteger) getConnectedGamepadCount
{
return _controllers.count;
}
-(id) initWithConfig:(StreamConfiguration*)streamConfig presenceDelegate:(id<GamepadPresenceDelegate>)delegate
{
self = [super init];
@@ -472,6 +478,7 @@
_controllers = [[NSMutableDictionary alloc] init];
_controllerNumbers = 0;
_multiController = streamConfig.multiController;
_presenceDelegate = delegate;
_player0osc = [[Controller alloc] init];
_player0osc.playerIndex = 0;
@@ -513,6 +520,9 @@
// Re-evaluate the on-screen control mode
[self updateAutoOnScreenControlMode];
// Notify the delegate
[self->_presenceDelegate gamepadPresenceChanged];
}];
self.disconnectObserver = [[NSNotificationCenter defaultCenter] addObserverForName:GCControllerDidDisconnectNotification object:nil queue:[NSOperationQueue mainQueue] usingBlock:^(NSNotification *note) {
Log(LOG_I, @"Controller disconnected!");
@@ -538,6 +548,9 @@
// Re-evaluate the on-screen control mode
[self updateAutoOnScreenControlMode];
// Notify the delegate
[self->_presenceDelegate gamepadPresenceChanged];
}];
return self;
}

View File

@@ -15,9 +15,9 @@
#if TARGET_OS_TV
@import GameController;
@interface StreamFrameViewController : GCEventViewController <ConnectionCallbacks, EdgeDetectionDelegate>
@interface StreamFrameViewController : GCEventViewController <ConnectionCallbacks, EdgeDetectionDelegate, GamepadPresenceDelegate>
#else
@interface StreamFrameViewController : UIViewController <ConnectionCallbacks, EdgeDetectionDelegate>
@interface StreamFrameViewController : UIViewController <ConnectionCallbacks, EdgeDetectionDelegate, GamepadPresenceDelegate>
#endif
@property (strong, nonatomic) IBOutlet UILabel *stageLabel;
@property (strong, nonatomic) IBOutlet UILabel *tipLabel;

View File

@@ -58,7 +58,7 @@
self.spinner.center = CGPointMake(self.view.frame.size.width / 2, self.view.frame.size.height / 2 - self.stageLabel.frame.size.height - self.spinner.frame.size.height);
[UIApplication sharedApplication].idleTimerDisabled = YES;
_controllerSupport = [[ControllerSupport alloc] initWithConfig:self.streamConfig];
_controllerSupport = [[ControllerSupport alloc] initWithConfig:self.streamConfig presenceDelegate:self];
_inactivityTimer = nil;
_streamView = (StreamView*)self.view;
@@ -335,12 +335,36 @@
// Dispose of any resources that can be recreated.
}
- (void)gamepadPresenceChanged {
#if !TARGET_OS_TV
if (@available(iOS 11.0, *)) {
[self setNeedsUpdateOfHomeIndicatorAutoHidden];
}
#endif
}
#if !TARGET_OS_TV
// Require a confirmation when streaming to activate a system gesture
- (UIRectEdge)preferredScreenEdgesDeferringSystemGestures {
return UIRectEdgeAll;
}
- (BOOL)prefersHomeIndicatorAutoHidden {
if ([_controllerSupport getConnectedGamepadCount] > 0 &&
[_streamView getCurrentOscState] == OnScreenControlsLevelOff) {
// Autohide the home bar when a gamepad is connected
// and the on-screen controls are disabled. We can't
// do this all the time because any touch on the display
// will cause the home indicator to reappear, and our
// preferredScreenEdgesDeferringSystemGestures will also
// be suppressed (leading to possible errant exits of the
// stream).
return YES;
}
return NO;
}
- (BOOL)shouldAutorotate {
return YES;
}