diff --git a/VoidLink/Base.lproj/iPad.storyboard b/VoidLink/Base.lproj/iPad.storyboard
index 4bd30eb5..561911a1 100644
--- a/VoidLink/Base.lproj/iPad.storyboard
+++ b/VoidLink/Base.lproj/iPad.storyboard
@@ -60,7 +60,7 @@
-
+
@@ -969,16 +969,38 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
+
+
@@ -1076,7 +1098,7 @@
-
+
diff --git a/VoidLink/Base.lproj/iPhone.storyboard b/VoidLink/Base.lproj/iPhone.storyboard
index 5294dce9..3ec54b5e 100644
--- a/VoidLink/Base.lproj/iPhone.storyboard
+++ b/VoidLink/Base.lproj/iPhone.storyboard
@@ -1541,6 +1541,25 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -1551,6 +1570,8 @@
+
+
diff --git a/VoidLink/Database/DataManager.h b/VoidLink/Database/DataManager.h
index 8648762b..dcf52f0a 100644
--- a/VoidLink/Database/DataManager.h
+++ b/VoidLink/Database/DataManager.h
@@ -79,6 +79,7 @@ typedef NS_ENUM(NSInteger, SettingsMenuMode) {
useFramePacing:(BOOL)useFramePacing
enableHdr:(BOOL)enableHdr
btMouseSupport:(BOOL)btMouseSupport
+ // absoluteTouchMode:(BOOL)absoluteTouchMode
touchMode:(NSInteger)touchMode
statsOverlayLevel:(NSInteger)statsOverlayLevel
statsOverlayEnabled:(BOOL)statsOverlayEnabled
@@ -90,6 +91,7 @@ typedef NS_ENUM(NSInteger, SettingsMenuMode) {
enableGraphs:(BOOL)enableGraphs
graphOpacity:(NSInteger)graphOpacity
renderingBackend:(NSInteger)renderingBackend;
+ backgroundSessionTimer:(NSInteger)backgroundSessionTimer;
- (NSArray*) getHosts;
- (void) updateHost:(TemporaryHost*)host;
diff --git a/VoidLink/Database/DataManager.m b/VoidLink/Database/DataManager.m
index e92c9215..15fe83e5 100644
--- a/VoidLink/Database/DataManager.m
+++ b/VoidLink/Database/DataManager.m
@@ -97,7 +97,8 @@
enableGraphs:(BOOL)enableGraphs
graphOpacity:(NSInteger)graphOpacity
renderingBackend:(NSInteger)renderingBackend
-{
+ backgroundSessionTimer:(NSInteger)backgroundSessionTimer{
+
[_managedObjectContext performBlockAndWait:^{
Settings* settingsToSave = [self retrieveSettings];
settingsToSave.framerate = [NSNumber numberWithInteger:framerate];
@@ -137,6 +138,7 @@
settingsToSave.resolutionSelected = [NSNumber numberWithInteger:resolutionSelected];
settingsToSave.externalDisplayMode = [NSNumber numberWithInteger:externalDisplayMode];
settingsToSave.localMousePointerMode = [NSNumber numberWithInteger:localMousePointerMode];
+ settingsToSave.backroundSessionTimer = [NSNumber numberWithInteger:backgroundSessionTimer];
settingsToSave.frameQueueSize = [NSNumber numberWithInteger:frameQueueSize];
settingsToSave.enableGraphs = enableGraphs;
diff --git a/VoidLink/Database/TemporarySettings.h b/VoidLink/Database/TemporarySettings.h
index a4f5c966..08105bc8 100644
--- a/VoidLink/Database/TemporarySettings.h
+++ b/VoidLink/Database/TemporarySettings.h
@@ -39,6 +39,7 @@
@property (nonatomic, retain) NSNumber * resolutionSelected;
@property (nonatomic, retain) NSNumber * externalDisplayMode;
@property (nonatomic, retain) NSNumber * localMousePointerMode;
+@property (nonatomic, retain) NSNumber * backgroundSessionTimer;
@property (nonatomic) enum {
CODEC_PREF_AUTO,
CODEC_PREF_H264,
diff --git a/VoidLink/Database/TemporarySettings.m b/VoidLink/Database/TemporarySettings.m
index 469c0fc1..ac1a87ff 100644
--- a/VoidLink/Database/TemporarySettings.m
+++ b/VoidLink/Database/TemporarySettings.m
@@ -120,6 +120,7 @@
self.enableGraphs = settings.enableGraphs;
self.graphOpacity = settings.graphOpacity;
self.renderingBackend = settings.renderingBackend;
+ self.backgroundSessionTimer = settings.backroundSessionTimer;
#endif
self.uniqueId = settings.uniqueId;
diff --git a/VoidLink/Limelight.xcdatamodeld/VoidLink v1.0.xcdatamodel/contents b/VoidLink/Limelight.xcdatamodeld/VoidLink v1.0.xcdatamodel/contents
index 1aae1e21..6bfa5d3c 100644
--- a/VoidLink/Limelight.xcdatamodeld/VoidLink v1.0.xcdatamodel/contents
+++ b/VoidLink/Limelight.xcdatamodeld/VoidLink v1.0.xcdatamodel/contents
@@ -23,12 +23,13 @@
+
-
+
diff --git a/VoidLink/Localization/Localizable.xcstrings b/VoidLink/Localization/Localizable.xcstrings
index 730e22b9..ab4b6d92 100644
--- a/VoidLink/Localization/Localizable.xcstrings
+++ b/VoidLink/Localization/Localizable.xcstrings
@@ -47,6 +47,75 @@
}
}
},
+ " disconnect " : {
+ "extractionState" : "manual",
+ "localizations" : {
+ "zh-Hans" : {
+ "stringUnit" : {
+ "state" : "translated",
+ "value" : " 断开 "
+ }
+ },
+ "zh-Hant" : {
+ "stringUnit" : {
+ "state" : "translated",
+ "value" : " 斷開 "
+ }
+ },
+ "zh-HK" : {
+ "stringUnit" : {
+ "state" : "translated",
+ "value" : " 斷開 "
+ }
+ }
+ }
+ },
+ " keep %d min " : {
+ "extractionState" : "manual",
+ "localizations" : {
+ "zh-Hans" : {
+ "stringUnit" : {
+ "state" : "translated",
+ "value" : " 保持%d分钟 "
+ }
+ },
+ "zh-Hant" : {
+ "stringUnit" : {
+ "state" : "translated",
+ "value" : " 保持%d分鐘 "
+ }
+ },
+ "zh-HK" : {
+ "stringUnit" : {
+ "state" : "translated",
+ "value" : " 保持%d分鐘 "
+ }
+ }
+ }
+ },
+ " keep alive " : {
+ "extractionState" : "manual",
+ "localizations" : {
+ "zh-Hans" : {
+ "stringUnit" : {
+ "state" : "translated",
+ "value" : " 保活 "
+ }
+ },
+ "zh-Hant" : {
+ "stringUnit" : {
+ "state" : "translated",
+ "value" : " 保持連線 "
+ }
+ },
+ "zh-HK" : {
+ "stringUnit" : {
+ "state" : "translated",
+ "value" : " 保持連線 "
+ }
+ }
+ }
+ },
" Launch" : {
"extractionState" : "manual",
"localizations" : {
diff --git a/VoidLink/ViewControllers/MainFrameViewController.m b/VoidLink/ViewControllers/MainFrameViewController.m
index 3ed807bd..8d229f7e 100644
--- a/VoidLink/ViewControllers/MainFrameViewController.m
+++ b/VoidLink/ViewControllers/MainFrameViewController.m
@@ -74,6 +74,7 @@
SettingsViewController* settingsViewController;
StreamFrameViewController* streamFrameViewController;
id navBarAppearanceStandard;
+bool _viewJustAppeared;
NSTimer *_foregroundHostUpdateTimer;
@@ -207,7 +208,7 @@ static NSMutableSet* hostList;
AppListResponse* appListResp = [ConnectionHelper getAppListForHost:host];
[self->_discMan resumeDiscoveryForHost:host];
-
+
if (![appListResp isStatusOk] || [appListResp getAppList] == nil) {
Log(LOG_W, @"Failed to get applist: %@", appListResp.statusMessage);
dispatch_async(dispatch_get_main_queue(), ^{
@@ -230,7 +231,7 @@ static NSMutableSet* hostList;
} else {
dispatch_async(dispatch_get_main_queue(), ^{
[self updateApplist:[appListResp getAppList] forHost:host];
-
+
if (host != self->_selectedHost) {
[self hideLoadingFrame: nil];
return;
@@ -248,7 +249,7 @@ static NSMutableSet* hostList;
- (void) updateAppEntry:(TemporaryApp*)app forHost:(TemporaryHost*)host {
DataManager* database = [[DataManager alloc] init];
NSMutableSet* newHostAppList = [NSMutableSet setWithSet:host.appList];
-
+
for (TemporaryApp* savedApp in newHostAppList) {
if ([app.id isEqualToString:savedApp.id]) {
savedApp.name = app.name;
@@ -256,7 +257,7 @@ static NSMutableSet* hostList;
savedApp.hidden = app.hidden;
host.appList = newHostAppList;
-
+
[database updateAppsForExistingHost:host];
return;
}
@@ -315,7 +316,7 @@ static NSMutableSet* hostList;
} while (appWasRemoved);
host.appList = newHostAppList;
-
+
[database updateAppsForExistingHost:host];
// This host may be eligible for a shortcut now that the app list
@@ -573,11 +574,11 @@ static NSMutableSet* hostList;
- (UIViewController*) activeViewController {
UIViewController *topController = [UIApplication sharedApplication].keyWindow.rootViewController;
-
+
while (topController.presentedViewController) {
topController = topController.presentedViewController;
}
-
+
return topController;
}
@@ -605,7 +606,7 @@ static NSMutableSet* hostList;
message = [LocalizationHelper localizedStringForKey:@"Online - Not Paired"];
}
break;
-
+
case StateUnknown:
message = [LocalizationHelper localizedStringForKey:@"Connecting"];
break;
@@ -816,12 +817,12 @@ static NSMutableSet* hostList;
_streamConfig.asyncNativeTouchPriority = streamSettings.asyncNativeTouchPriority; // new streamConfig segment
_streamConfig.gyroMode = [streamSettings.gyroMode intValue];
//NSLog(@"gyroMode from settings: %ld", _streamConfig.gyroMode);
-
+
// multiController must be set before calling getConnectedGamepadMask
_streamConfig.multiController = streamSettings.multiController;
_streamConfig.gamepadMask = [ControllerSupport getConnectedGamepadMask:_streamConfig];
_streamConfig.localMousePointerMode = streamSettings.localMousePointerMode.intValue;
-
+
// Probe for supported channel configurations
int physicalOutputChannels = (int)[AVAudioSession sharedInstance].maximumOutputNumberOfChannels;
Log(LOG_I, @"Audio device supports %d channels", physicalOutputChannels);
@@ -841,7 +842,7 @@ static NSMutableSet* hostList;
else {
_streamConfig.audioConfiguration = AUDIO_CONFIGURATION_STEREO;
}
-
+
switch (streamSettings.preferredCodec) {
case CODEC_PREF_AV1:
@@ -1209,7 +1210,7 @@ static NSMutableSet* hostList;
- (BOOL)isFullScreenRequired {
NSDictionary *infoDictionary = [[NSBundle mainBundle] infoDictionary];
NSNumber *requiresFullScreen = infoDictionary[@"UIRequiresFullScreen"];
-
+
if (requiresFullScreen != nil) {
return [requiresFullScreen boolValue];
}
@@ -1229,7 +1230,7 @@ static NSMutableSet* hostList;
self->waterMark.text = [LocalizationHelper localizedStringForKey:@"waterMarkText"];
CGFloat labelHeight = 60;
// the app is unable to automatically lock screen orientation in app window resizable mode(aka. not require fullscreen)
-
+
// if(![self isFullScreenRequired]){
if(false){
NSString* screenRotationTip = [LocalizationHelper localizedStringForKey:@"screenRotationTIp"];
@@ -1238,7 +1239,7 @@ static NSMutableSet* hostList;
self->waterMark.font = [UIFont systemFontOfSize:19];
labelHeight = 80;
}
-
+
self->waterMark.textColor = UIColor.blackColor;
self->waterMark.alpha = 0.35;
self->waterMark.textAlignment = NSTextAlignmentCenter;
@@ -1451,7 +1452,7 @@ static NSMutableSet* hostList;
self.settingsExpandedInStreamView = false; // init this flag
self.revealViewController.isStreaming = false; //init this flag for rvlVC
self.revealViewController.mainFrameIsInHostView = true;
-
+
[self setupNavBar];
// Set the gesture
@@ -1515,15 +1516,16 @@ static NSMutableSet* hostList;
// [self.view addSubview:hostScrollView];
// if ([hostList count] == 1) [self hostClicked:[hostList anyObject] view:nil]; // auto click for single host
+
//if([SettingsViewController isLandscapeNow] != _streamConfig.width > _streamConfig.height)
//[self simulateSettingsButtonPress]; //force expand setting view if orientation changed since last quit from app.
//[self simulateSettingsButtonPress]; //force expand setting view if orientation changed since last quit from app.
//[self updateResolutionAccordingly];
-
+
// SettingsViewController* settingsViewController = (SettingsViewController*)[self.revealViewController rearViewController];
// [settingsViewController updateResolutionTable];
-
+
UILongPressGestureRecognizer *longPress = [[UILongPressGestureRecognizer alloc] initWithTarget:self action:@selector(handleMenuResize:)];
[self.view addGestureRecognizer:longPress];
@@ -1542,7 +1544,7 @@ static NSMutableSet* hostList;
// this will also be called back when device orientation changes
//- (void)viewWillTransitionToSize:(CGSize)size withTransitionCoordinator:(id)coordinator {
// [super viewWillTransitionToSize:size withTransitionCoordinator:coordinator];
-//
+//
// double delayInSeconds = 0.7;
// // Convert the delay into a dispatch_time_t value
// dispatch_time_t delayTime = dispatch_time(DISPATCH_TIME_NOW, (int64_t)(delayInSeconds * NSEC_PER_SEC));
@@ -1561,7 +1563,7 @@ static NSMutableSet* hostList;
CGFloat appWindowHeight = CGRectGetHeight(window.frame) * screenScale;
CGFloat screenWidthInPoints = CGRectGetWidth([[UIScreen mainScreen] bounds]);
CGFloat screenHeightInPoints = CGRectGetHeight([[UIScreen mainScreen] bounds]);
-
+
if(currentSettings.externalDisplayMode.intValue == 1 && UIScreen.screens.count > 1){
CGRect bounds = [UIScreen.screens.lastObject bounds];
screenScale = [UIScreen.screens.lastObject scale];
@@ -1570,7 +1572,7 @@ static NSMutableSet* hostList;
}
bool needSwap = false;
-
+
if([self isFullScreenRequired]){ // if force fullscreen is enabled in app bundle, we use screen bounds to tell if a swap between width & height is needed
needSwap = (currentSettings.width.floatValue - currentSettings.height.floatValue) * (screenWidthInPoints - screenHeightInPoints) < 0; //update the current resolution accordingly
NSLog(@"need to swap width & height (non-app window mode): %d", needSwap);
@@ -1623,15 +1625,19 @@ static NSMutableSet* hostList;
-(void)beginForegroundRefresh
{
- if (!_background) {
+ if (!_background || _viewJustAppeared) {
// This will kick off box art caching
+ _viewJustAppeared = false;
+ [_foregroundHostUpdateTimer invalidate];
+ _foregroundHostUpdateTimer = nil;
+
_foregroundHostUpdateTimer = [NSTimer scheduledTimerWithTimeInterval:5 repeats:YES block:^(NSTimer *timer) {
[self updateHosts];
}];
-
+
[_discMan startDiscovery];
// This will refresh the applist when a paired host is selected
@@ -1692,6 +1698,10 @@ static NSMutableSet* hostList;
{
[super viewDidAppear:NO];
+ _viewJustAppeared = true;
+
+ [self beginForegroundRefresh];
+
// [self setupHostViewTitle];
// [self reloadScrollHostView]; //remove this for proper test
[self attachWaterMark];
@@ -1701,7 +1711,7 @@ static NSMutableSet* hostList;
selector:@selector(handleOrientationChange) // //force expand settings view to update resolution table, and all setting includes current fullscreen resolution will be updated.
name:UIDeviceOrientationDidChangeNotification
object:nil];
-
+
[[self revealViewController] setPrimaryViewController:self];
self.revealViewController.isStreaming = false; // tell the revealViewController streaming is finished
//[self.settingsButton setEnabled:![self isIPhonePortrait]]; //make sure settings button is disabled in iphone portrait mode.
@@ -1772,8 +1782,6 @@ static NSMutableSet* hostList;
[self retrieveSavedHosts];
_discMan = [[DiscoveryManager alloc] initWithHosts:[hostList allObjects] andCallback:self];
-
- [self beginForegroundRefresh];
}
- (void)viewDidDisappear:(BOOL)animated
@@ -1863,26 +1871,7 @@ static NSMutableSet* hostList;
NSArray* sortedHostList = [[hostList allObjects] sortedArrayUsingSelector:@selector(compareName:)];
for (TemporaryHost* comp in sortedHostList) {
-if(comp.state == StateOnline || comp.pairState == PairStatePaired || comp.pairState == PairStateUnknown) [self.hostCollectionVC addHost:comp];
-
- // new host card test
- // if([comp.name isEqualToString: @"ASRockPC"]) {
- /*
- if([comp.name isEqualToString: @"ASRockPC"]) {
- //if([comp.name isEqualToString: @"PianoServer"]) {
- //if([comp.name isEqualToString: @"TrueZj"]) {
- HostCardView *testCard = [[HostCardView alloc] initWithHost:comp];
-
- [self.view addSubview:testCard];
- // [testCard resizeBySizeFactor:3];
- [NSLayoutConstraint activateConstraints:@[
- [testCard.centerXAnchor constraintEqualToAnchor:self.view.centerXAnchor constant:0],
- [testCard.centerYAnchor constraintEqualToAnchor:self.view.centerYAnchor constant:150],
- ]];
-
- }*/
- //
-
+ if(comp.state == StateOnline || comp.pairState == PairStatePaired || comp.pairState == PairStateUnknown) [self.hostCollectionVC addHost:comp];
// Start jobs to decode the box art in advance
for (TemporaryApp* app in comp.appList) {
@@ -1898,7 +1887,7 @@ if(comp.state == StateOnline || comp.pairState == PairStatePaired || comp.pairSt
// Update the title in case we now have a PC
[self updateTitle];
-
+
// Reset state first so we can rediscover hosts that were deleted before
[_discMan resetDiscoveryState];
}
diff --git a/VoidLink/ViewControllers/SettingsViewController.h b/VoidLink/ViewControllers/SettingsViewController.h
index af4150d6..ae9cec6b 100644
--- a/VoidLink/ViewControllers/SettingsViewController.h
+++ b/VoidLink/ViewControllers/SettingsViewController.h
@@ -119,6 +119,9 @@
@property (strong, nonatomic) IBOutlet UIStepper *graphOpacityStepper;
@property (strong, nonatomic) IBOutlet UISegmentedControl *renderingBackendSelector;
+@property (strong, nonatomic) IBOutlet UIStackView *backgroundSessionTimerStack;
+@property (strong, nonatomic) IBOutlet UISlider *backgroundSessionTimerSlider;
+
#pragma clang diagnostic push
diff --git a/VoidLink/ViewControllers/SettingsViewController.m b/VoidLink/ViewControllers/SettingsViewController.m
index 800756a6..778d8299 100644
--- a/VoidLink/ViewControllers/SettingsViewController.m
+++ b/VoidLink/ViewControllers/SettingsViewController.m
@@ -557,6 +557,7 @@ BOOL isCustomResolution(CGSize res) {
}
[self addSetting:self.statsOverlayStack ofId:@"statsOverlayStack" withInfoTag:NO withDynamicLabel:NO to:otherSection];
[self addSetting:self.unlockDisplayOrientationStack ofId:@"unlockDisplayOrientationStack" withInfoTag:YES withDynamicLabel:NO to:otherSection];
+ [self addSetting:self.backgroundSessionTimerStack ofId:@"backgroundSessionTimerStack" withInfoTag:NO withDynamicLabel:YES to:otherSection];
[self addSetting:self.optimizeGamesStack ofId:@"optimizeGamesStack" withInfoTag:YES withDynamicLabel:NO to:otherSection];
[self addSetting:self.multiControllerStack ofId:@"multiControllerStack" withInfoTag:YES withDynamicLabel:NO to:otherSection];
[self addSetting:self.softKeyboardToolbarStack ofId:@"softKeyboardToolbarStack" withInfoTag:YES withDynamicLabel:NO to:otherSection];
@@ -1328,6 +1329,9 @@ BOOL isCustomResolution(CGSize res) {
else [self.unlockDisplayOrientationSelector setSelectedSegmentIndex:1]; // can't lock screen orientation in this mode = Display Orientation always unlocked
[self.unlockDisplayOrientationSelector setEnabled:unlockDisplayOrientationSelectorEnabled];
+ [self.backgroundSessionTimerSlider setValue:(uint32_t)currentSettings.backgroundSessionTimer.floatValue];
+ [self.backgroundSessionTimerSlider addTarget:self action:@selector(backgroundSessionTimerSliderMoved:) forControlEvents:UIControlEventValueChanged];
+ [self backgroundSessionTimerSliderMoved:self.backgroundSessionTimerSlider];
// lift streamview setting
[self.liftStreamViewForKeyboardSelector setSelectedSegmentIndex:currentSettings.liftStreamViewForKeyboard ? 1 : 0];// Load old setting
@@ -1542,6 +1546,14 @@ BOOL isCustomResolution(CGSize res) {
[self findDynamicLabelFromStack:self.gyroSensitivityStack].text = [NSString stringWithFormat:@" %d%% ", (uint16_t)sender.value]; // Update label display
}
+- (void) backgroundSessionTimerSliderMoved:(UISlider* )sender {
+ NSString* labelString;
+ labelString = [LocalizationHelper localizedStringForKey:@" keep %d min ", (uint16_t)sender.value];
+ if(sender.value == 0) labelString = [LocalizationHelper localizedStringForKey:@" disconnect "];
+ if(sender.value == sender.maximumValue) labelString = [LocalizationHelper localizedStringForKey:@" keep alive "];
+ [self findDynamicLabelFromStack:self.backgroundSessionTimerStack].text = labelString; // Update label display
+}
+
// veloc factor upto 700%
- (uint16_t) map_velocFactorDisplay_fromSliderValue:(CGFloat)sliderValue{
@@ -2024,6 +2036,7 @@ BOOL isCustomResolution(CGSize res) {
NSInteger resolutionSelected = [self.resolutionSelector selectedSegmentIndex];
NSInteger externalDisplayMode = [self.externalDisplayModeSelector selectedSegmentIndex];
NSInteger localMousePointerMode = [self.localMousePointerModeSelector selectedSegmentIndex];
+ NSInteger backgroundSessionTimer = self.backgroundSessionTimerSlider.value == self.backgroundSessionTimerSlider.maximumValue ? (uint32_t) INT16_MAX : (uint32_t)self.backgroundSessionTimerSlider.value;
[dataMan saveSettingsWithBitrate:_bitrate
framerate:framerate
height:height
@@ -2065,6 +2078,7 @@ BOOL isCustomResolution(CGSize res) {
enableGraphs:enableGraphs
graphOpacity:_graphOpacity
renderingBackend:renderingBackend];
+ backgroundSessionTimer:backgroundSessionTimer];
}
- (void)didReceiveMemoryWarning {
diff --git a/VoidLink/ViewControllers/StreamFrameViewController.m b/VoidLink/ViewControllers/StreamFrameViewController.m
index 1c4e44dd..708325e3 100644
--- a/VoidLink/ViewControllers/StreamFrameViewController.m
+++ b/VoidLink/ViewControllers/StreamFrameViewController.m
@@ -118,7 +118,7 @@
self.imguiView.mtkView.hidden = NO;
Log(LOG_I, @"Showing ImGui view after PiP stop.");
}
-
+
if (!_isRestoringFromPiP) {
[self returnToMainFrame];
}
@@ -361,7 +361,7 @@
if (self.imguiView && self.imguiView.mtkView.superview) {
[self.view bringSubviewToFront:self.imguiView.mtkView];
}
-
+
NSLog(@"frameview gestures: %d", (uint32_t)[self.view.gestureRecognizers count]);
NSLog(@"streamview gestures: %d", (uint32_t)[_streamView.gestureRecognizers count]);
}
@@ -819,7 +819,7 @@
[_statsUpdateTimer invalidate];
_statsUpdateTimer = nil;
-
+
[self.navigationController popToRootViewControllerAnimated:YES];
_extWindow = nil;
@@ -901,21 +901,8 @@
//[self.pipController startPictureInPicture];
//sleep(1);
-
- if (_inactivityTimer != nil) {
- [_inactivityTimer invalidate];
- _inactivityTimer = nil;
- }
-
-
+
#if !TARGET_OS_TV
- // Terminate the stream if the app is inactive for 60 seconds
- Log(LOG_I, @"Starting inactivity termination timer");
- _inactivityTimer = [NSTimer scheduledTimerWithTimeInterval:18000
- target:self
- selector:@selector(inactiveTimerExpired:)
- userInfo:nil
- repeats:NO];
#endif
}
@@ -928,13 +915,13 @@
}
- (void)applicationDidBecomeActive:(NSNotification *)notification {
- // Stop the background timer
+ // Stop the background timer, since we're foregrounded again
if (_inactivityTimer != nil) {
Log(LOG_I, @"Stopping inactivity timer after becoming active again");
[_inactivityTimer invalidate];
_inactivityTimer = nil;
}
-
+
// Check if we were in PiP
if (self.pipController && self.pipController.isPictureInPictureActive) {
[self.pipController stopPictureInPicture];
@@ -943,7 +930,7 @@
if (_isRestoringFromPiP) {
[self->_streamMan.videoRenderer resetFramePacing];
}
-
+
_isRestoringFromPiP = NO;
}
@@ -952,10 +939,22 @@
NSLog(@"did enter background, %d, %@, %d", _settings.enablePIP, self.pipController, self.pipController.isPictureInPictureActive);
if (_settings.enablePIP && self.pipController && self.pipController.isPictureInPictureActive) {
- Log(LOG_I, @"PIP is active, not terminating stream");
- return;
+ //Log(LOG_I, @"PIP is active, not terminating stream");
}
+ if (_inactivityTimer != nil) {
+ [_inactivityTimer invalidate];
+ _inactivityTimer = nil;
+ }
+
+ // Terminate the stream if the app is inactive for ...
+ Log(LOG_I, @"Starting inactivity termination timer with %d min", _settings.backgroundSessionTimer.intValue);
+ _inactivityTimer = [NSTimer scheduledTimerWithTimeInterval:60*(double)_settings.backgroundSessionTimer.intValue
+ target:self
+ selector:@selector(inactiveTimerExpired:)
+ userInfo:nil
+ repeats:NO];
+
#if !TARGET_OS_TV
#endif
@@ -1204,7 +1203,7 @@
if (@available(tvOS 11.2, *)) {
UIWindow* window = [[[UIApplication sharedApplication] delegate] window];
AVDisplayManager* displayManager = [window avDisplayManager];
-
+
// This logic comes from Kodi and MrMC
if (streamActive) {
int dynamicRange;
@@ -1215,7 +1214,7 @@
else {
dynamicRange = 0; // SDR
}
-
+
AVDisplayCriteria* displayCriteria = [[AVDisplayCriteria alloc] initWithRefreshRate:[_settings.framerate floatValue]
videoDynamicRange:dynamicRange];
displayManager.preferredDisplayCriteria = displayCriteria;
@@ -1392,7 +1391,7 @@
Log(LOG_I, @"View size changed during PiP restore, skipping redundant reconfiguration.");
return;
}
-
+
Log(LOG_I, @"View size changed, terminating stream");
double delayInSeconds = 0.2;
diff --git a/VoidLink/mul.lproj/iPad.xcstrings b/VoidLink/mul.lproj/iPad.xcstrings
index 053fc628..0870c224 100644
--- a/VoidLink/mul.lproj/iPad.xcstrings
+++ b/VoidLink/mul.lproj/iPad.xcstrings
@@ -349,6 +349,36 @@
}
}
},
+ "9pX-93-bC2.text" : {
+ "comment" : "Class = \"UILabel\"; text = \"Background Session\"; ObjectID = \"9pX-93-bC2\";",
+ "extractionState" : "extracted_with_value",
+ "localizations" : {
+ "en" : {
+ "stringUnit" : {
+ "state" : "new",
+ "value" : "Background Session"
+ }
+ },
+ "zh-Hans" : {
+ "stringUnit" : {
+ "state" : "translated",
+ "value" : "后台会话"
+ }
+ },
+ "zh-Hant" : {
+ "stringUnit" : {
+ "state" : "translated",
+ "value" : "背景執行"
+ }
+ },
+ "zh-HK" : {
+ "stringUnit" : {
+ "state" : "translated",
+ "value" : "背景執行"
+ }
+ }
+ }
+ },
"9XL-xt-Q57.text" : {
"comment" : "Class = \"UILabel\"; text = \"Gyro Sensitivity\"; ObjectID = \"9XL-xt-Q57\";",
"extractionState" : "extracted_with_value",
diff --git a/VoidLink/mul.lproj/iPhone.xcstrings b/VoidLink/mul.lproj/iPhone.xcstrings
index 49375568..d7694217 100644
--- a/VoidLink/mul.lproj/iPhone.xcstrings
+++ b/VoidLink/mul.lproj/iPhone.xcstrings
@@ -727,6 +727,36 @@
}
}
},
+ "9et-1g-y3D.text" : {
+ "comment" : "Class = \"UILabel\"; text = \"Background Session\"; ObjectID = \"9et-1g-y3D\";",
+ "extractionState" : "extracted_with_value",
+ "localizations" : {
+ "en" : {
+ "stringUnit" : {
+ "state" : "new",
+ "value" : "Background Session"
+ }
+ },
+ "zh-Hans" : {
+ "stringUnit" : {
+ "state" : "translated",
+ "value" : "后台会话"
+ }
+ },
+ "zh-Hant" : {
+ "stringUnit" : {
+ "state" : "translated",
+ "value" : "背景執行"
+ }
+ },
+ "zh-HK" : {
+ "stringUnit" : {
+ "state" : "translated",
+ "value" : "背景執行"
+ }
+ }
+ }
+ },
"9Gg-66-UdB.text" : {
"comment" : "Class = \"UILabel\"; text = \"Tap any widget to load configuration (per widget)\"; ObjectID = \"9Gg-66-UdB\";",
"extractionState" : "extracted_with_value",