From 431b32b6805e9d7b6fd220992fc8a8281e9c415a Mon Sep 17 00:00:00 2001 From: TrueZhuanjia Date: Tue, 23 Sep 2025 20:55:15 +0800 Subject: [PATCH] try to fix broken native touch & broken on screen widget layout when orientation is locked on iPhone iOS 16/17 control center --- .../LayoutOnScreenControlsViewController.m | 22 +--- .../ViewControllers/MainFrameViewController.h | 1 + .../ViewControllers/MainFrameViewController.m | 1 - .../ViewControllers/SettingsViewController.m | 116 +++++++++--------- .../StreamFrameViewController.m | 12 +- 5 files changed, 72 insertions(+), 80 deletions(-) diff --git a/VoidLink/ViewControllers/CustomOSCViewControl/LayoutOnScreenControlsViewController.m b/VoidLink/ViewControllers/CustomOSCViewControl/LayoutOnScreenControlsViewController.m index 3f9ca0c6..d9a92c74 100644 --- a/VoidLink/ViewControllers/CustomOSCViewControl/LayoutOnScreenControlsViewController.m +++ b/VoidLink/ViewControllers/CustomOSCViewControl/LayoutOnScreenControlsViewController.m @@ -205,25 +205,14 @@ /* This will animate the toolbar with a subtle up and down motion intended to telegraph to the user that they can hide the toolbar if they wish*/ dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.2 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{ - [UIView animateWithDuration:0.3 + [UIView animateWithDuration:0.2 delay:0.25 - usingSpringWithDamping:0.8 + usingSpringWithDamping:0.9 initialSpringVelocity:0.5 options:UIViewAnimationOptionCurveEaseInOut animations:^{ // Animate toolbar up a a very small distance. Note the 0.35 time delay is necessary to avoid a bug that keeps animations from playing if the animation is presented immediately on a modally presented VC - self.toolbarRootView.frame = CGRectMake(self.toolbarRootView.frame.origin.x, self.toolbarRootView.frame.origin.y - 25, self.toolbarRootView.frame.size.width, self.toolbarRootView.frame.size.height); + self.toolbarRootView.frame = CGRectMake(self.toolbarRootView.frame.origin.x, self.toolbarRootView.frame.origin.y, self.toolbarRootView.frame.size.width, self.toolbarRootView.frame.size.height); } - completion:^(BOOL finished) { - [UIView animateWithDuration:0.3 - delay:0 - usingSpringWithDamping:0.7 - initialSpringVelocity:1.0 - options:UIViewAnimationOptionCurveEaseIn animations:^{ // Animate the toolbar back down that same distance - self.toolbarRootView.frame = CGRectMake(self.toolbarRootView.frame.origin.x, self.toolbarRootView.frame.origin.y + 25, self.toolbarRootView.frame.size.width, self.toolbarRootView.frame.size.height); - } - completion:^(BOOL finished) { - NSLog (@"done"); - }]; - }]; + completion:nil]; }); trashCanStoryBoardColor = trashCanButton.tintColor; self.toolbarRootView.layer.shadowColor = [UIColor blackColor].CGColor; @@ -245,6 +234,7 @@ selectedWidgetView = nil; widgetPanelStoredCenter = self.widgetPanelStack.center; [super viewDidAppear:animated]; + [self profileRefresh]; } - (void)viewWillAppear:(BOOL)animated{ @@ -287,7 +277,7 @@ OnScreenWidgetView.editMode = true; [self handleMissingToolBarIcon:toolbarRootView]; - [self profileRefresh]; + self.widgetPanelStack.hidden = YES; } #pragma mark - Class Helper Functions diff --git a/VoidLink/ViewControllers/MainFrameViewController.h b/VoidLink/ViewControllers/MainFrameViewController.h index 2b6c379e..33cf4d4f 100644 --- a/VoidLink/ViewControllers/MainFrameViewController.h +++ b/VoidLink/ViewControllers/MainFrameViewController.h @@ -39,5 +39,6 @@ #endif - (void)fillResolutionTable:(CGSize*)resolutionTable externalDisplayMode:(NSInteger)externalDisplayMode; - (bool)isIPhone; +- (void)setNeedsUpdateAllowedOrientation; @end diff --git a/VoidLink/ViewControllers/MainFrameViewController.m b/VoidLink/ViewControllers/MainFrameViewController.m index 9f109911..03480b70 100644 --- a/VoidLink/ViewControllers/MainFrameViewController.m +++ b/VoidLink/ViewControllers/MainFrameViewController.m @@ -1208,7 +1208,6 @@ static NSMutableSet* hostList; if (position == FrontViewPositionLeft) { [settingsViewController saveSettings]; - [self setNeedsUpdateAllowedOrientation]; // handle allow portratit on & off _settingsButton.enabled = YES; // make sure these 2 buttons are enabled after closing setting view. _upButton.enabled = YES; // here is the select new host button } diff --git a/VoidLink/ViewControllers/SettingsViewController.m b/VoidLink/ViewControllers/SettingsViewController.m index 5a74ec6c..93b4563f 100644 --- a/VoidLink/ViewControllers/SettingsViewController.m +++ b/VoidLink/ViewControllers/SettingsViewController.m @@ -21,6 +21,9 @@ #import "LocalizationHelper.h" @implementation SettingsViewController { + TemporarySettings* tempSettings; + DataManager* dataMan; + NSLayoutConstraint *parentStackLeadingConstraint; NSLayoutConstraint *parentStackWidthConstraint; @@ -375,11 +378,10 @@ BOOL isCustomResolution(int resolutionSelected) { [self updateResolutionTable]; [self.customResolutionSwitch addTarget:self action:@selector(customResolutionSwitched:) forControlEvents:UIControlEventValueChanged]; - DataManager* dataMan = [[DataManager alloc] init]; - TemporarySettings *currentSettings = [dataMan getSettings]; + tempSettings = [dataMan getSettings]; //CGSize currentResolution = CGSizeMake(currentSettings.width.intValue, currentSettings.height.intValue); - [self.customResolutionSwitch setOn: isCustomResolution(currentSettings.resolutionSelected.intValue)]; + [self.customResolutionSwitch setOn: isCustomResolution(tempSettings.resolutionSelected.intValue)]; [self.resolutionSelector setEnabled:!self.customResolutionSwitch.isOn]; } @@ -391,6 +393,9 @@ BOOL isCustomResolution(int resolutionSelected) { - (void)viewDidDisappear:(BOOL)animated{ [super viewDidDisappear:NO]; [[NSNotificationCenter defaultCenter] postNotificationName:@"SettingsViewClosedNotification" object:self]; // notify other view that settings view just closed + + bool unlockDisplayOrientationFlipped = tempSettings.unlockDisplayOrientation != (_unlockDisplayOrientationSelector.selectedSegmentIndex == 1); + if(unlockDisplayOrientationFlipped) [_mainFrameViewController setNeedsUpdateAllowedOrientation]; // handle allow portratit on & off } @@ -1239,7 +1244,6 @@ BOOL isCustomResolution(int resolutionSelected) { currentSettingsMenuMode = FavoriteSettings; [self initParentStack]; [self updateTheme]; - DataManager* dataMan = [[DataManager alloc] init]; Settings *currentSettings = [dataMan retrieveSettings]; currentSettings.settingsMenuMode = [NSNumber numberWithInteger:currentSettingsMenuMode]; [dataMan saveData]; @@ -1274,7 +1278,6 @@ BOOL isCustomResolution(int resolutionSelected) { [self layoutSections]; [self updateTheme]; //[self doneRemoveSettingItem]; - DataManager* dataMan = [[DataManager alloc] init]; Settings *currentSettings = [dataMan retrieveSettings]; currentSettings.settingsMenuMode = [NSNumber numberWithInteger:currentSettingsMenuMode]; [dataMan saveData]; @@ -1405,15 +1408,15 @@ BOOL isCustomResolution(int resolutionSelected) { self.overrideUserInterfaceStyle = UIUserInterfaceStyleDark; } - DataManager* dataMan = [[DataManager alloc] init]; - TemporarySettings* currentSettings = [dataMan getSettings]; + dataMan = [[DataManager alloc] init]; + tempSettings = [dataMan getSettings]; - currentSettingsMenuMode = currentSettings.settingsMenuMode.intValue; + currentSettingsMenuMode = tempSettings.settingsMenuMode.intValue; [self loadFavoriteSettingStackIdentifiers]; - if(currentSettings.settingsMenuMode.intValue == FavoriteSettings) [self switchToFavoriteSettings]; + if(tempSettings.settingsMenuMode.intValue == FavoriteSettings) [self switchToFavoriteSettings]; // Ensure we pick a bitrate that falls exactly onto a slider notch - _bitrate = bitrateTable[[self getSliderValueForBitrate:[currentSettings.bitrate intValue]]]; + _bitrate = bitrateTable[[self getSliderValueForBitrate:[tempSettings.bitrate intValue]]]; // Get the size of the screen with and without safe area insets // UIWindow *window = UIApplication.sharedApplication.windows.firstObject; @@ -1428,12 +1431,12 @@ BOOL isCustomResolution(int resolutionSelected) { self.resolutionSelector.selectedSegmentIndex = 3; [self.resolutionSelector setNeedsLayout]; - resolutionTable[5] = CGSizeMake([currentSettings.width integerValue], [currentSettings.height integerValue]); // custom initial value + resolutionTable[5] = CGSizeMake([tempSettings.width integerValue], [tempSettings.height integerValue]); // custom initial value [self updateResolutionTable]; NSInteger framerate; - switch ([currentSettings.framerate integerValue]) { + switch ([tempSettings.framerate integerValue]) { case 30: framerate = 0; break; @@ -1446,7 +1449,7 @@ BOOL isCustomResolution(int resolutionSelected) { break; } - NSInteger resolution = currentSettings.resolutionSelected.integerValue; + NSInteger resolution = tempSettings.resolutionSelected.integerValue; if(resolution >= RESOLUTION_TABLE_SIZE){ resolution = 0; } @@ -1476,7 +1479,7 @@ BOOL isCustomResolution(int resolutionSelected) { // they support HEVC decoding (A9 or later). [self.resolutionSelector setEnabled:NO forSegmentAtIndex:2]; } - switch (currentSettings.preferredCodec) { + switch (tempSettings.preferredCodec) { case CODEC_PREF_AUTO: [self.codecSelector setSelectedSegmentIndex:self.codecSelector.numberOfSegments - 1]; break; @@ -1499,39 +1502,39 @@ BOOL isCustomResolution(int resolutionSelected) { [self.hdrSwitch setEnabled:NO]; } else { - [self.hdrSwitch setOn:currentSettings.enableHdr]; + [self.hdrSwitch setOn:tempSettings.enableHdr]; } - [self.yuv444Switch setOn:currentSettings.enableYUV444]; + [self.yuv444Switch setOn:tempSettings.enableYUV444]; - [self.pipSwitch setOn:currentSettings.enablePIP]; + [self.pipSwitch setOn:tempSettings.enablePIP]; if(@available(iOS 15.0, *)) [self.pipSwitch setEnabled:true]; else{ [self.pipSwitch setOn:false]; [self.pipSwitch setEnabled:false]; } - [self.statsOverlaySelector setSelectedSegmentIndex:currentSettings.statsOverlayLevel.intValue]; + [self.statsOverlaySelector setSelectedSegmentIndex:tempSettings.statsOverlayLevel.intValue]; - NSInteger renderingBackend = [currentSettings.renderingBackend integerValue]; + NSInteger renderingBackend = [tempSettings.renderingBackend integerValue]; [self.renderingBackendSelector setSelectedSegmentIndex:renderingBackend]; [self.renderingBackendSelector addTarget:self action:@selector(renderingBackendChanged:) forControlEvents:UIControlEventValueChanged]; - NSInteger framePacingMode = [currentSettings.framePacingMode integerValue]; + NSInteger framePacingMode = [tempSettings.framePacingMode integerValue]; [self.framePacingModeSelector setSelectedSegmentIndex:framePacingMode]; [self.framePacingModeSelector addTarget:self action:@selector(framePacingModeChanged:) forControlEvents:UIControlEventValueChanged]; [self framePacingModeChanged:self.framePacingModeSelector]; [self renderingBackendChanged:self.renderingBackendSelector]; // Update PiP and frame pacing state based on current selection - [self.citrixX1MouseSwitch setOn:currentSettings.btMouseSupport]; - [self.optimizeGamesSwitch setOn: currentSettings.optimizeGames]; - [self.multiControllerSwitch setOn:currentSettings.multiController]; - [self.swapAbxySwitch setOn:currentSettings.swapABXYButtons]; - [self.buttonVisualFeedbackSwitch setOn:currentSettings.buttonVisualFeedback]; + [self.citrixX1MouseSwitch setOn:tempSettings.btMouseSupport]; + [self.optimizeGamesSwitch setOn: tempSettings.optimizeGames]; + [self.multiControllerSwitch setOn:tempSettings.multiController]; + [self.swapAbxySwitch setOn:tempSettings.swapABXYButtons]; + [self.buttonVisualFeedbackSwitch setOn:tempSettings.buttonVisualFeedback]; - [self.gyroModeSelector setSelectedSegmentIndex:currentSettings.gyroMode.intValue]; - [self.gyroSensitivitySlider setValue: (uint16_t)(currentSettings.gyroSensitivity.floatValue * 100) animated:YES]; // Load old setting. + [self.gyroModeSelector setSelectedSegmentIndex:tempSettings.gyroMode.intValue]; + [self.gyroSensitivitySlider setValue: (uint16_t)(tempSettings.gyroSensitivity.floatValue * 100) animated:YES]; // Load old setting. [self.gyroSensitivitySlider addTarget:self action:@selector(gyroSensitivitySliderMoved:) forControlEvents:(UIControlEventValueChanged)]; // Update label display when slider is being moved. [self gyroSensitivitySliderMoved:self.gyroSensitivitySlider]; @@ -1543,14 +1546,14 @@ BOOL isCustomResolution(int resolutionSelected) { CMMotionManager *motionManager = [[CMMotionManager alloc] init]; [self.gyroModeSelector setEnabled:[motionManager isGyroAvailable] forSegmentAtIndex:2]; - [self.emulatedControllerTypeSelector setSelectedSegmentIndex:[self controllerTypeToSegmentIndex:currentSettings.emulatedControllerType.intValue]]; + [self.emulatedControllerTypeSelector setSelectedSegmentIndex:[self controllerTypeToSegmentIndex:tempSettings.emulatedControllerType.intValue]]; [self.emulatedControllerTypeSelector addTarget:self action:@selector(emulatedControllerTypeChanged:) forControlEvents:(UIControlEventValueChanged)]; // Update label display when slider is being moved. [self emulatedControllerTypeChanged:self.emulatedControllerTypeSelector]; - [self.audioOnPcSwitch setOn:currentSettings.playAudioOnPC]; - [self.redirectMicSwitch setOn:currentSettings.redirectMic]; + [self.audioOnPcSwitch setOn:tempSettings.playAudioOnPC]; + [self.redirectMicSwitch setOn:tempSettings.redirectMic]; [self.redirectMicSwitch addTarget:self action:@selector(redirectMicSwitchFlipped:) forControlEvents:UIControlEventValueChanged]; [self redirectMicSwitchFlipped:self.redirectMicSwitch]; @@ -1569,16 +1572,16 @@ BOOL isCustomResolution(int resolutionSelected) { [self.frameQueueSizeSlider setMinimumValue:1]; [self.frameQueueSizeSlider setMaximumValue:5]; - [self.frameQueueSizeSlider setValue:currentSettings.frameQueueSize.intValue]; + [self.frameQueueSizeSlider setValue:tempSettings.frameQueueSize.intValue]; [self.frameQueueSizeSlider addTarget:self action:@selector(frameQueueSizeSliderMoved:) forControlEvents:UIControlEventValueChanged]; [self frameQueueSizeSliderMoved:self.frameQueueSizeSlider]; - [self.enableGraphsSwitch setOn:currentSettings.enableGraphs animated:NO]; // Add this line + [self.enableGraphsSwitch setOn:tempSettings.enableGraphs animated:NO]; // Add this line [self.enableGraphsSwitch addTarget:self action:@selector(enableGraphsChanged:) forControlEvents:UIControlEventValueChanged]; [self enableGraphsChanged:self.enableGraphsSwitch]; [self.graphOpacityStepper setMinimumValue:0]; [self.graphOpacityStepper setMaximumValue:100]; - [self.graphOpacityStepper setValue:(int)currentSettings.graphOpacity.intValue]; + [self.graphOpacityStepper setValue:(int)tempSettings.graphOpacity.intValue]; [self.graphOpacityStepper addTarget:self action:@selector(graphOpacityStepperTapped:) forControlEvents:UIControlEventValueChanged]; [self graphOpacityStepperTapped:self.graphOpacityStepper]; @@ -1588,7 +1591,7 @@ BOOL isCustomResolution(int resolutionSelected) { [self.audioConfigSelector setTitle:[LocalizationHelper localizedStringForKey:@"Stereo (surround sound available for iOS18+)"] forSegmentAtIndex:0]; [self.audioConfigSelector setEnabled:NO]; } - switch ([currentSettings.audioConfig integerValue]) { + switch ([tempSettings.audioConfig integerValue]) { case 2: [self.audioConfigSelector setSelectedSegmentIndex:0]; break; @@ -1602,31 +1605,31 @@ BOOL isCustomResolution(int resolutionSelected) { // Unlock Display Orientation setting bool unlockDisplayOrientationSelectorEnabled = [self isFullScreenRequired] || [self isIPhone];//need "requires fullscreen" enabled in the app bunddle to make runtime orientation limitation working - if(unlockDisplayOrientationSelectorEnabled) [self.unlockDisplayOrientationSelector setSelectedSegmentIndex:currentSettings.unlockDisplayOrientation ? 1 : 0]; + if(unlockDisplayOrientationSelectorEnabled) [self.unlockDisplayOrientationSelector setSelectedSegmentIndex:tempSettings.unlockDisplayOrientation ? 1 : 0]; 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 setValue:(uint32_t)tempSettings.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 + [self.liftStreamViewForKeyboardSelector setSelectedSegmentIndex:tempSettings.liftStreamViewForKeyboard ? 1 : 0];// Load old setting // showkeyboard toolbar setting - [self.softKeyboardToolbarSwitch setOn:currentSettings.showKeyboardToolbar];// Load old setting + [self.softKeyboardToolbarSwitch setOn:tempSettings.showKeyboardToolbar];// Load old setting // reverse mouse wheel direction setting - [self.reverseMouseWheelDirectionSelector setSelectedSegmentIndex:currentSettings.reverseMouseWheelDirection ? 1 : 0];// Load old setting + [self.reverseMouseWheelDirectionSelector setSelectedSegmentIndex:tempSettings.reverseMouseWheelDirection ? 1 : 0];// Load old setting // slide to menu settings - [self.slideToSettingsScreenEdgeSelector setSelectedSegmentIndex:[self getSelectorIndexFromScreenEdge:(uint32_t)currentSettings.slideToSettingsScreenEdge.integerValue]]; + [self.slideToSettingsScreenEdgeSelector setSelectedSegmentIndex:[self getSelectorIndexFromScreenEdge:(uint32_t)tempSettings.slideToSettingsScreenEdge.integerValue]]; // Load old setting [self.slideToToolboxScreenEdgeSelector setEnabled:false]; [self.slideToSettingsScreenEdgeSelector addTarget:self action:@selector(slideToSettingsScreenEdgeChanged) forControlEvents:UIControlEventValueChanged]; [self slideToSettingsScreenEdgeChanged]; - [self.slideToMenuDistanceSlider setValue:currentSettings.slideToSettingsDistance.floatValue]; + [self.slideToMenuDistanceSlider setValue:tempSettings.slideToSettingsDistance.floatValue]; [self.slideToMenuDistanceSlider addTarget:self action:@selector(slideToMenuDistanceSliderMoved:) forControlEvents:(UIControlEventValueChanged)]; // Update label display when slider is being moved. [self slideToMenuDistanceSliderMoved:self.slideToMenuDistanceSlider]; @@ -1635,12 +1638,12 @@ BOOL isCustomResolution(int resolutionSelected) { //TouchMode & OSC Related Settings: // pointer veloc setting, will be enable/disabled by touchMode - [self.pointerVelocityModeDividerSlider setValue: (uint8_t)(currentSettings.pointerVelocityModeDivider.floatValue * 100) animated:YES]; // Load old setting. + [self.pointerVelocityModeDividerSlider setValue: (uint8_t)(tempSettings.pointerVelocityModeDivider.floatValue * 100) animated:YES]; // Load old setting. [self.pointerVelocityModeDividerSlider addTarget:self action:@selector(pointerVelocityModeDividerSliderMoved:) forControlEvents:(UIControlEventValueChanged)]; // Update label display when slider is being moved. [self pointerVelocityModeDividerSliderMoved:self.pointerVelocityModeDividerSlider]; // init pointer veloc setting, will be enable/disabled by touchMode - [self.touchPointerVelocityFactorSlider setValue: [self map_SliderValue_fromVelocFactor: currentSettings.touchPointerVelocityFactor.floatValue] animated:YES]; // Load old setting. + [self.touchPointerVelocityFactorSlider setValue: [self map_SliderValue_fromVelocFactor: tempSettings.touchPointerVelocityFactor.floatValue] animated:YES]; // Load old setting. [self.touchPointerVelocityFactorSlider addTarget:self action:@selector(touchPointerVelocityFactorSliderMoved:) forControlEvents:(UIControlEventValueChanged)]; // Update label display when slider is being moved. [self touchPointerVelocityFactorSliderMoved:self.touchPointerVelocityFactorSlider]; @@ -1649,48 +1652,48 @@ BOOL isCustomResolution(int resolutionSelected) { // [self.asyncNativeTouchPrioritySelector addTarget:self action:@selector(asyncNativeTouchPriorityChanged) forControlEvents:UIControlEventValueChanged]; // init relative touch mouse pointer veloc setting, will be enable/disabled by touchMode - [self.mousePointerVelocityFactorSlider setValue:[self map_SliderValue_fromVelocFactor: currentSettings.mousePointerVelocityFactor.floatValue] animated:YES]; // Load old setting. + [self.mousePointerVelocityFactorSlider setValue:[self map_SliderValue_fromVelocFactor: tempSettings.mousePointerVelocityFactor.floatValue] animated:YES]; // Load old setting. [self.mousePointerVelocityFactorSlider addTarget:self action:@selector(mousePointerVelocityFactorSliderMoved:) forControlEvents:(UIControlEventValueChanged)]; // Update label display when slider is being moved. [self mousePointerVelocityFactorSliderMoved:self.mousePointerVelocityFactorSlider]; // these settings will be affected by onscreenControl & touchMode, must be loaded before them. // NSLog(@"osc tool fingers setting test: %d", currentSettings.oscLayoutToolFingers.intValue); - self->oswLayoutFingers = (uint16_t)currentSettings.oscLayoutToolFingers.intValue; // load old setting of oscLayoutFingers - uint8_t keyboardToggleFingers = currentSettings.keyboardToggleFingers.intValue; + self->oswLayoutFingers = (uint16_t)tempSettings.oscLayoutToolFingers.intValue; // load old setting of oscLayoutFingers + uint8_t keyboardToggleFingers = tempSettings.keyboardToggleFingers.intValue; [self.softKeyboardGestureSelector setSelectedSegmentIndex:keyboardToggleFingers>=5 ? 3 : keyboardToggleFingers-3]; // this setting will be affected by touchMode, must be loaded before them. - NSInteger onscreenControlsLevel = [currentSettings.onscreenControls integerValue]; + NSInteger onscreenControlsLevel = [tempSettings.onscreenControls integerValue]; [self.onScreenWidgetSelector setSelectedSegmentIndex:onscreenControlsLevel]; [self.onScreenWidgetSelector addTarget:self action:@selector(onScreenWidgetChanged) forControlEvents:UIControlEventValueChanged]; [self onScreenWidgetChanged]; // touch move event interval for native-touch. - [self.touchMoveEventIntervalSlider setValue:currentSettings.touchMoveEventInterval.intValue animated:YES]; // Load old setting. + [self.touchMoveEventIntervalSlider setValue:tempSettings.touchMoveEventInterval.intValue animated:YES]; // Load old setting. [self.touchMoveEventIntervalSlider addTarget:self action:@selector(touchMoveEventIntervalSliderMoved:) forControlEvents:(UIControlEventValueChanged)]; // Update label display when slider is being moved. [self touchMoveEventIntervalSliderMoved:self.touchMoveEventIntervalSlider]; // this part will enable/disable oscSelector & the asyncNativeTouchPriority selector - uint8_t touchModeSelectorIndex = currentSettings.touchMode.intValue == NativeTouchOnly ? NativeTouch : currentSettings.touchMode.intValue; + uint8_t touchModeSelectorIndex = tempSettings.touchMode.intValue == NativeTouchOnly ? NativeTouch : tempSettings.touchMode.intValue; [self.touchModeSelector setSelectedSegmentIndex:touchModeSelectorIndex]; //Load old touchMode setting [self.touchModeSelector addTarget:self action:@selector(touchModeChanged:) forControlEvents:UIControlEventValueChanged]; [self touchModeChanged:self.touchModeSelector]; - self.enableOswSwitchStack.hidden = !(currentSettings.touchMode.intValue == NativeTouch || currentSettings.touchMode.intValue == NativeTouchOnly); // do not use setHidden to stack wrapped by a settingStack + self.enableOswSwitchStack.hidden = !(tempSettings.touchMode.intValue == NativeTouch || tempSettings.touchMode.intValue == NativeTouchOnly); // do not use setHidden to stack wrapped by a settingStack - [self.enableOswForNativeTouchSwitch setOn:currentSettings.touchMode.intValue != NativeTouchOnly]; + [self.enableOswForNativeTouchSwitch setOn:tempSettings.touchMode.intValue != NativeTouchOnly]; [self.enableOswForNativeTouchSwitch addTarget:self action:@selector(enableOswForNativeTouchSwitchFlipped:) forControlEvents:UIControlEventValueChanged]; [self enableOswForNativeTouchSwitchFlipped:self.enableOswForNativeTouchSwitch]; - [self.externalDisplayModeSelector setSelectedSegmentIndex:currentSettings.externalDisplayMode.integerValue]; - [self.localMousePointerModeSelector setSelectedSegmentIndex:currentSettings.localMousePointerMode.integerValue]; + [self.externalDisplayModeSelector setSelectedSegmentIndex:tempSettings.externalDisplayMode.integerValue]; + [self.localMousePointerModeSelector setSelectedSegmentIndex:tempSettings.localMousePointerMode.integerValue]; - [self.sendDummyEventSwitch setOn:currentSettings.sendDummyEvent];// Load old setting + [self.sendDummyEventSwitch setOn:tempSettings.sendDummyEvent];// Load old setting settingsViewJustLoaded = false; } @@ -1784,9 +1787,7 @@ BOOL isCustomResolution(int resolutionSelected) { } // Get the current settings to compare with the new selection - DataManager* dataMan = [[DataManager alloc] init]; - TemporarySettings* currentSettings = [dataMan getSettings]; - NSInteger previousBackend = [currentSettings.renderingBackend integerValue]; + NSInteger previousBackend = [tempSettings.renderingBackend integerValue]; // Check if the rendering backend has actually changed if (previousBackend != sender.selectedSegmentIndex) { @@ -2443,7 +2444,6 @@ BOOL isCustomResolution(int resolutionSelected) { - (void) saveSettings { [self preSavingActions]; - DataManager* dataMan = [[DataManager alloc] init]; Settings* currentSettings = [dataMan retrieveSettings]; NSInteger height = self.mainFrameViewController.settingsExpandedInStreamView ? currentSettings.height.intValue : [self getChosenStreamHeight]; diff --git a/VoidLink/ViewControllers/StreamFrameViewController.m b/VoidLink/ViewControllers/StreamFrameViewController.m index 69e105ab..18a1a168 100644 --- a/VoidLink/ViewControllers/StreamFrameViewController.m +++ b/VoidLink/ViewControllers/StreamFrameViewController.m @@ -340,6 +340,7 @@ } - (void)reConfigStreamViewRealtime { + //if(!viewJustLoaded) [self handleViewResize]; [self reConfigStreamViewRealtimeAndReloadSettings:YES]; } @@ -373,15 +374,14 @@ } else [micHandler stopTappingWithStopEngine:false]; - NSLog(@"viewJustloaded: %d, redirectMic:%d", viewJustLoaded, _settings.redirectMic); if(!viewJustLoaded) [_controllerSupport updateControllerSupport:self.streamConfig delegate:self]; - else viewJustLoaded = false; // reload controllerSupport obj, this is mandatory for OSC reload,especially when the stream view is launched without OSC [_streamView setupStreamView:_controllerSupport interactionDelegate:self config:self.streamConfig streamFrameTopLayerView:self.view]; //reinitiate setupStreamView process. // we got self.view passed to streamView class as the topLayerView, will be useful in many cases [self->_streamView reloadOnScreenControlsRealtimeWith:(ControllerSupport*)_controllerSupport andConfig:(StreamConfiguration*)_streamConfig]; //reload OSC here. [self->_streamView reloadOnScreenWidgetViews]; //reload keyboard buttons here. the keyboard widget view will be added to the streamframe view instead streamview, the highest layer, which saves a lot of reengineering + [self reloadAirPlayConfig]; [self mousePresenceChanged]; @@ -451,7 +451,7 @@ - (void)viewDidAppear:(BOOL)animated { [super viewDidAppear:animated]; - + viewJustLoaded = false; _deviceWindow = self.view.window; if (@available(iOS 13.0, *)) { UIScreen *currentScreen = self.view.window.windowScene.screen; @@ -998,6 +998,7 @@ if (_streamVideoRenderView && _streamView) { [_streamView insertSubview:_streamVideoRenderView atIndex:0]; [self handleViewResize]; // Adjust frames as needed + [self reConfigStreamViewRealtimeAndReloadSettings:YES]; } } NSNotificationCenter* nc = [NSNotificationCenter defaultCenter]; @@ -1035,8 +1036,10 @@ - (void) handleViewResize{ viewIsBeingResized = true; + _streamView.bounds = _deviceWindow.bounds; _streamView.frame = _deviceWindow.frame; + if(![self isAirPlaying]){ _streamVideoRenderView.bounds = _deviceWindow.bounds; _streamVideoRenderView.frame = _deviceWindow.frame; @@ -1053,7 +1056,6 @@ NSNotificationCenter* nc = [NSNotificationCenter defaultCenter]; [nc postNotificationName:@"ScreenChanged" object:self]; } - [self reConfigStreamViewRealtime]; } @@ -1528,7 +1530,6 @@ - (void)toggleMouseCapture{ DataManager* dataMan = [[DataManager alloc] init]; Settings *currentSettings = [dataMan retrieveSettings]; - if(currentSettings.localMousePointerMode.intValue == 0){ currentSettings.localMousePointerMode = @1; }else{ @@ -1604,6 +1605,7 @@ } dispatch_block_t block = dispatch_block_create(0, ^{ [self handleViewResize]; + [self reConfigStreamViewRealtimeAndReloadSettings:YES]; }); _delayedRemoveExtScreen = block; dispatch_time_t delayTime = dispatch_time(DISPATCH_TIME_NOW, (int64_t)(delayInSeconds * NSEC_PER_SEC));