diff --git a/VoidLink/HostCardView.h b/VoidLink/HostCardView.h index b78f2e07..a7c903a2 100644 --- a/VoidLink/HostCardView.h +++ b/VoidLink/HostCardView.h @@ -16,6 +16,7 @@ - (void)wakeupButtonTappedForHost:(TemporaryHost *)host; - (void)pairButtonTappedForHost:(TemporaryHost *)host; - (void)hostCardLongPressed:(TemporaryHost *)host view:(UIView *)view; +- (bool)isStreaming; @end diff --git a/VoidLink/HostCardView.m b/VoidLink/HostCardView.m index 3a1b1d0e..85ed5a21 100644 --- a/VoidLink/HostCardView.m +++ b/VoidLink/HostCardView.m @@ -509,10 +509,12 @@ static const float REFRESH_CYCLE = 2.0f; return; } + NSLog(@"hostCard update loop %f", CACurrentMediaTime()); + [self updateContentsForHost:_host]; // Queue the next refresh cycle - [self performSelector:@selector(updateLoop) withObject:self afterDelay:REFRESH_CYCLE]; + if(![self.delegate isStreaming]) [self performSelector:@selector(updateLoop) withObject:self afterDelay:REFRESH_CYCLE]; } - (void) updateContentsForHost:(TemporaryHost*)host { diff --git a/VoidLink/Images.xcassets/speaker.wave.2.imageset/Contents.json b/VoidLink/Images.xcassets/speaker.wave.2.imageset/Contents.json new file mode 100644 index 00000000..2a082ab7 --- /dev/null +++ b/VoidLink/Images.xcassets/speaker.wave.2.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "speaker.wave.2.svg", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/VoidLink/Images.xcassets/speaker.wave.2.imageset/speaker.wave.2.svg b/VoidLink/Images.xcassets/speaker.wave.2.imageset/speaker.wave.2.svg new file mode 100644 index 00000000..3f993019 --- /dev/null +++ b/VoidLink/Images.xcassets/speaker.wave.2.imageset/speaker.wave.2.svg @@ -0,0 +1,13 @@ + + + + + + + + + + + diff --git a/VoidLink/Input/NativeTouchHandler.m b/VoidLink/Input/NativeTouchHandler.m index 0c82e10b..b5871fb5 100644 --- a/VoidLink/Input/NativeTouchHandler.m +++ b/VoidLink/Input/NativeTouchHandler.m @@ -35,6 +35,7 @@ NSMutableSet *pointerIdPool; //pre-defined pool of pointerIds. NSMutableSet *unassignedPointerIds; NSMutableSet *blacklistedTouches; + bool doNotBlockTouchEvents; NSMutableDictionary *pointerObjDict; @@ -60,6 +61,7 @@ } self->activePointerIds = [NSMutableSet set]; self->blacklistedTouches = [NSMutableSet set]; + doNotBlockTouchEvents = true; self->asyncNativeTouch = settings.asyncNativeTouchPriority.intValue != AsyncNativeTouchOff; @@ -165,7 +167,8 @@ //check if touch point is spawned on the left or right upper half screen edges, event to remote PC. this is for better handling in-stream slide gesture CGPoint initialPoint = [touch locationInView:self->streamView]; if(initialPoint.y < slideGestureVerticalThreshold && (initialPoint.x < EDGE_TOLERANCE || initialPoint.x > screenWidthWithThreshold)) { - [blacklistedTouches addObject:touchAddrObj]; + doNotBlockTouchEvents = false; + // [blacklistedTouches addObject:touchAddrObj]; } } @@ -189,8 +192,8 @@ - (void)sendTouchEvent:(UITouch*)touch withTouchtype:(uint8_t)touchType{ //if(touchPointSpawnedAtUpperScreenEdge && touchType != LI_TOUCH_EVENT_UP) return; // we're done here. this touch event will not be sent to the remote PC. and this must be checked after coord selector finishes populating new relative coords, or the app will crash - if([blacklistedTouches containsObject:@((uintptr_t)touch)]) return; - + // if([blacklistedTouches containsObject:@((uintptr_t)touch)]) return; + CGPoint targetCoords; //NSLog(@"selecting coords: %d", touch.phase == UITouchPhaseMoved); // NSLog(@"excluded count: %d", (uint32_t)[excludedPointerIds count]); @@ -236,7 +239,7 @@ // continue to the next loop if current touch is already captured by OSC. works only in regular native touch if([OnScreenControls.touchAddrsCapturedByOnScreenControls containsObject:@((uintptr_t)touch)]) continue; if(self->activateCoordSelector) [self updatePointerObjInDict:touch]; - [self sendTouchEvent:touch withTouchtype:LI_TOUCH_EVENT_MOVE]; + if(self->doNotBlockTouchEvents) [self sendTouchEvent:touch withTouchtype:LI_TOUCH_EVENT_MOVE]; [[self getPointerObjFromDict:touch] doesNeedResetCoords]; // execute the judging of doesReachBoundary for current pointer instance. (happens after the event is sent to Sunshine service) usleep(self->touchMoveEventIntervalUs); } @@ -262,8 +265,9 @@ [self sendTouchEvent:touch withTouchtype:LI_TOUCH_EVENT_UP]; //send touch event before remove pointerId [self removePointerId:touch]; //then remove pointerId if(self->activateCoordSelector) [self removePointerObjFromDict:touch]; - [self->blacklistedTouches removeObject:@((uintptr_t)touch)]; + //[self->blacklistedTouches removeObject:@((uintptr_t)touch)]; } + self->doNotBlockTouchEvents = true; //if(self->touchPointSpawnedAtUpperScreenEdge && [[event allTouches] count] == [touches count]) }); else{ diff --git a/VoidLink/UIAppView.m b/VoidLink/UIAppView.m index 5975b34f..abe6d208 100644 --- a/VoidLink/UIAppView.m +++ b/VoidLink/UIAppView.m @@ -236,7 +236,7 @@ static UIImage* noImage; _appImage.layer.opacity = 0.5f; } - (void) buttonDeselected:(id)sender { - _appImage.layer.opacity = 1.0f; + _appImage.layer.opacity = [self isCurrentApp] ? 0.75 : 1.0f; } - (void) positionSubviews { @@ -252,7 +252,8 @@ static UIImage* noImage; if (_appOverlay != nil) { _appOverlay.frame = [self isCurrentApp] ? CGRectMake(0, 0, frameSize.width / 2.39, frameSize.width / 2.39) : CGRectMake(0, 0, frameSize.width / 2, frameSize.width / 2); _appOverlay.center = CGPointMake(frameSize.width/2, frameSize.height/2 - 2 * verticalPadding); - + if([self isCurrentApp]) _appImage.layer.opacity = 0.75f; + //[_appLabel setFrame:CGRectMake(padding, _appOverlay.frame.size.height + padding, frameSize.width - 2 * padding, frameSize.height - _appOverlay.frame.size.height - 2 * padding)]; } } diff --git a/VoidLink/ViewControllers/CustomOSCViewControl/LayoutOnScreenControlsViewController.m b/VoidLink/ViewControllers/CustomOSCViewControl/LayoutOnScreenControlsViewController.m index 35e425d4..1e881a1c 100644 --- a/VoidLink/ViewControllers/CustomOSCViewControl/LayoutOnScreenControlsViewController.m +++ b/VoidLink/ViewControllers/CustomOSCViewControl/LayoutOnScreenControlsViewController.m @@ -621,12 +621,14 @@ } } -- (void)autoFitView:(UIView* )view{ - CGSize fittingSize = [view systemLayoutSizeFittingSize:UILayoutFittingCompressedSize]; - CGRect newFrame = view.frame; +- (void)autoFitStack:(UIStackView* )stack{ + CGSize fittingSize = [stack systemLayoutSizeFittingSize:UILayoutFittingCompressedSize]; + CGRect newFrame = stack.frame; newFrame.size = fittingSize; - view.frame = newFrame; - if([self isIPhone]) [self updateClippedMaskForView:view]; + stack.frame = newFrame; + [self updateClippedMaskForView:stack]; + if (@available(iOS 14, *)) nil; + else [self applyShadowForiOS13:stack]; } - (void)enableCommonWidgetTools{ @@ -681,7 +683,7 @@ self.mouseDownButtonStack.hidden = !([selectedWidgetView.cmdString containsString:@"MOUSEPAD"] && selectedWidgetView.widgetType == WidgetTypeEnumTouchPad); self.decelerationRateStack.hidden = !([selectedWidgetView.cmdString containsString:@"TRACKBALL"] && selectedWidgetView.widgetType == WidgetTypeEnumTouchPad); - [self autoFitView:self.widgetPanelStack]; + [self autoFitStack:self.widgetPanelStack]; if(showSensitivityFactorStack){ [self.sensitivityXSlider setValue:self->selectedWidgetView.sensitivityFactorX]; @@ -719,12 +721,11 @@ [self.decelerationRateLabel setText:[LocalizationHelper localizedStringForKey:@"Deceleration Rate: %.3f ", selectedWidgetView.trackballDecelerationRate]]; self.mouseButtonDownSelector.selectedSegmentIndex = selectedWidgetView.mouseButtonAction; - if([self isIPhone]){ self.vibrationStyleStack.hidden = [widgetView.cmdString containsString:@"MOUSEPAD"] || [widgetView.cmdString containsString:@"TRACKBALL"]; - [self autoFitView:self.widgetPanelStack]; + [self autoFitStack:self.widgetPanelStack]; self.vibrationStyleSelector.selectedSegmentIndex = self->selectedWidgetView.vibrationStyle; } } @@ -769,7 +770,7 @@ NSNumber *style = [OnScreenControls.layerVibrationStyleDic objectForKey:selectedControllerLayer.name]; self.vibrationStyleSelector.selectedSegmentIndex = [style unsignedCharValue]; } - [self autoFitView:_widgetPanelStack]; + [self autoFitStack:_widgetPanelStack]; } - (void)widgetSizeSliderMoved:(UISlider* )sender{ @@ -995,7 +996,7 @@ self.widgetPanelStack.frame = frame; - [self autoFitView:self.widgetPanelStack]; + [self autoFitStack:self.widgetPanelStack]; if([self isIPhone]) { for(UIView* view in _widgetPanelStack.arrangedSubviews){ @@ -1020,13 +1021,48 @@ } } +- (void)applyShadowForiOS13:(UIStackView* )stack { + stack.backgroundColor = [UIColor clearColor]; + + for(UIView* view in stack.arrangedSubviews){ + if([view isKindOfClass:[UIStackView class]]){ + UIStackView* subStack = (UIStackView* )view; + for(UIView* view in subStack.arrangedSubviews){ + if([view isKindOfClass:[UILabel class]]){ + view.backgroundColor = [[UIColor blackColor] colorWithAlphaComponent:0.5]; + view.layer.cornerRadius = 6; + view.clipsToBounds = YES; + UILabel* label = (UILabel* )view; + label.textAlignment = NSTextAlignmentCenter; + } + else{ + view.tintColor= [UIColor systemTealColor]; + view.layer.shadowColor = [[UIColor blackColor] colorWithAlphaComponent:0.9].CGColor; + //view.layer.shadowColor = [UIColor blackColor].CGColor; + view.layer.shadowOffset = CGSizeMake(1, 1); + view.layer.shadowOpacity = 1; + view.layer.shadowRadius = 5; + } + } + } + else{ + view.layer.cornerRadius = 10; + view.clipsToBounds = YES; + view.backgroundColor = [[UIColor blackColor] colorWithAlphaComponent:0.5]; + } + } +} + + - (void)updateClippedMaskForView:(UIView* )view{ - CAShapeLayer *maskLayer = [CAShapeLayer layer]; - view.layer.mask = nil; - CGRect visibleRect = CGRectInset(view.bounds, 40, 0); // 左右各裁掉 20pt - UIBezierPath *path = [UIBezierPath bezierPathWithRoundedRect:visibleRect cornerRadius:12]; - maskLayer.path = path.CGPath; - view.layer.mask = maskLayer; + if([self isIPhone]){ + CAShapeLayer *maskLayer = [CAShapeLayer layer]; + view.layer.mask = nil; + CGRect visibleRect = CGRectInset(view.bounds, 40, 0); // 左右各裁掉 20pt + UIBezierPath *path = [UIBezierPath bezierPathWithRoundedRect:visibleRect cornerRadius:12]; + maskLayer.path = path.CGPath; + view.layer.mask = maskLayer; + } } - (BOOL)isIPhone{ diff --git a/VoidLink/ViewControllers/MainFrameViewController.m b/VoidLink/ViewControllers/MainFrameViewController.m index e1da333c..36f84212 100644 --- a/VoidLink/ViewControllers/MainFrameViewController.m +++ b/VoidLink/ViewControllers/MainFrameViewController.m @@ -69,6 +69,7 @@ NSCache* _boxArtCache; bool _background; bool _enteredAppView; + bool _settingsViewExpanded; UIView* menuSeparator; UIView* snapshot; SettingsViewController* settingsViewController; @@ -1118,6 +1119,7 @@ static NSMutableSet* hostList; - (void)revealController:(SWRevealViewController *)revealController willMoveToPosition:(FrontViewPosition)position { settingsViewController = (SettingsViewController*)[revealController rearViewController]; revealController.navBarMenuDelegate = settingsViewController; + _settingsViewExpanded = position != FrontViewPositionLeft; if (position == FrontViewPositionLeft) { self.navigationItem.leftBarButtonItems = @[_settingsButton]; } @@ -1787,10 +1789,12 @@ static NSMutableSet* hostList; [super viewWillAppear:NO]; /* this makes background color works*/ - for (UIView *subview in self.view.subviews) { - [subview removeFromSuperview]; // 暂时移除所有子视图 + + if(!_settingsViewExpanded){ + for (UIView *subview in self.view.subviews) { + [subview removeFromSuperview]; // 暂时移除所有子视图 + } } - // We can get here on home press while streaming // since the stream view segues to us just before @@ -2006,6 +2010,10 @@ static NSMutableSet* hostList; return !self.revealViewController.isStreaming && _enteredAppView; } +- (bool)isStreaming{ + return self.revealViewController.isStreaming; +} + - (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath { UICollectionViewCell* cell = [collectionView dequeueReusableCellWithReuseIdentifier:@"AppCell" forIndexPath:indexPath]; diff --git a/VoidLink/ViewControllers/SettingsViewController.m b/VoidLink/ViewControllers/SettingsViewController.m index d9c9e89b..90e68dbd 100644 --- a/VoidLink/ViewControllers/SettingsViewController.m +++ b/VoidLink/ViewControllers/SettingsViewController.m @@ -581,7 +581,7 @@ BOOL isCustomResolution(CGSize res) { audioSection.delegate = self; audioSection.sectionTitle = [LocalizationHelper localizedStringForKey:@"Audio"]; if (@available(iOS 13.0, *)) { - [audioSection setSectionWithIcon:[UIImage systemImageNamed:@"speaker.wave.2"] andSize:23]; + [audioSection setSectionWithIcon:[UIImage imageNamed:@"speaker.wave.2"] andSize:20]; } [self addSetting:self.audioOnPcStack ofId:@"audioOnPcStack" withInfoTag:NO withDynamicLabel:NO to:audioSection];