From 5faa8a0b852e4d97ee394c539228286239d0ba47 Mon Sep 17 00:00:00 2001 From: Cameron Gutman Date: Tue, 22 Oct 2019 00:32:56 -0400 Subject: [PATCH] Hide the home bar when a gamepad is connected and no on-screen controls are visible Fixes #386 --- Limelight/Input/ControllerSupport.h | 10 ++++++- Limelight/Input/ControllerSupport.m | 15 ++++++++++- .../StreamFrameViewController.h | 4 +-- .../StreamFrameViewController.m | 26 ++++++++++++++++++- 4 files changed, 50 insertions(+), 5 deletions(-) diff --git a/Limelight/Input/ControllerSupport.h b/Limelight/Input/ControllerSupport.h index 15bb1ad2..96890e6f 100644 --- a/Limelight/Input/ControllerSupport.h +++ b/Limelight/Input/ControllerSupport.h @@ -11,9 +11,15 @@ @class OnScreenControls; +@protocol GamepadPresenceDelegate + +- (void) gamepadPresenceChanged; + +@end + @interface ControllerSupport : NSObject --(id) initWithConfig:(StreamConfiguration*)streamConfig; +-(id) initWithConfig:(StreamConfiguration*)streamConfig presenceDelegate:(id)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; diff --git a/Limelight/Input/ControllerSupport.m b/Limelight/Input/ControllerSupport.m index 2e4ccde2..5cbac015 100644 --- a/Limelight/Input/ControllerSupport.m +++ b/Limelight/Input/ControllerSupport.m @@ -21,6 +21,7 @@ NSLock *_controllerStreamLock; NSMutableDictionary *_controllers; NSTimer *_rumbleTimer; + id _presenceDelegate; OnScreenControls *_osc; @@ -464,7 +465,12 @@ } } --(id) initWithConfig:(StreamConfiguration*)streamConfig +-(NSUInteger) getConnectedGamepadCount +{ + return _controllers.count; +} + +-(id) initWithConfig:(StreamConfiguration*)streamConfig presenceDelegate:(id)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; } diff --git a/Limelight/ViewControllers/StreamFrameViewController.h b/Limelight/ViewControllers/StreamFrameViewController.h index 94b765d4..d8a52246 100644 --- a/Limelight/ViewControllers/StreamFrameViewController.h +++ b/Limelight/ViewControllers/StreamFrameViewController.h @@ -15,9 +15,9 @@ #if TARGET_OS_TV @import GameController; -@interface StreamFrameViewController : GCEventViewController +@interface StreamFrameViewController : GCEventViewController #else -@interface StreamFrameViewController : UIViewController +@interface StreamFrameViewController : UIViewController #endif @property (strong, nonatomic) IBOutlet UILabel *stageLabel; @property (strong, nonatomic) IBOutlet UILabel *tipLabel; diff --git a/Limelight/ViewControllers/StreamFrameViewController.m b/Limelight/ViewControllers/StreamFrameViewController.m index 71abba20..3caf5989 100644 --- a/Limelight/ViewControllers/StreamFrameViewController.m +++ b/Limelight/ViewControllers/StreamFrameViewController.m @@ -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; }