From 46194a5aa0c1adc29162d46d932a1a87184877c4 Mon Sep 17 00:00:00 2001 From: TrueZhuanjia Date: Thu, 11 Dec 2025 16:40:47 +0800 Subject: [PATCH] fixed: tap to toggle button not release after being cleared reload on-screen widgets only when necessary --- VoidLink/Input/AbsoluteTouchHandler.h | 2 +- VoidLink/Input/AbsoluteTouchHandler.m | 25 ++++++++++++------- VoidLink/Input/OnScreenWidgetView.swift | 7 +++++- VoidLink/Input/StreamView.m | 2 +- .../StreamFrameViewController.m | 12 ++++----- 5 files changed, 30 insertions(+), 18 deletions(-) diff --git a/VoidLink/Input/AbsoluteTouchHandler.h b/VoidLink/Input/AbsoluteTouchHandler.h index 003fdd25..fe6c3010 100644 --- a/VoidLink/Input/AbsoluteTouchHandler.h +++ b/VoidLink/Input/AbsoluteTouchHandler.h @@ -11,7 +11,7 @@ NS_ASSUME_NONNULL_BEGIN @interface AbsoluteTouchHandler : UIResponder -@property (assign,nonatomic) int mouseButtonForCursorMove; +@property (class, nonatomic, assign) int mouseButtonForCursorMove; - (id)initWithView:(StreamView*)view andSettings:(TemporarySettings*)settings; - (void)pauseLeftButtonDrag; diff --git a/VoidLink/Input/AbsoluteTouchHandler.m b/VoidLink/Input/AbsoluteTouchHandler.m index ddd7ebd7..1efa1949 100644 --- a/VoidLink/Input/AbsoluteTouchHandler.m +++ b/VoidLink/Input/AbsoluteTouchHandler.m @@ -26,6 +26,8 @@ // How far the finger can move before it can override the double tap deadzone #define DOUBLE_TAP_DEAD_ZONE_DELTA 0.025f +static int mouseButtonForCursorMove = BUTTON_LEFT; + @implementation AbsoluteTouchHandler { StreamView* streamView; @@ -79,9 +81,7 @@ slideGestureVerticalThreshold = CGRectGetHeight([[UIScreen mainScreen] bounds]) * 0.4; screenWidthWithThreshold = CGRectGetWidth([[UIScreen mainScreen] bounds]) - _edgeTolerance; self->touchPointSpawnedAtUpperScreenEdge = false; - - _mouseButtonForCursorMove = BUTTON_LEFT; - + leftClickDelay = ((CGFloat)settings.leftClickDelayMs.intValue)/1000; return self; @@ -94,7 +94,7 @@ if([self touchDidntMoveOnScreen:movingTouchLocation]){ if(_delayMouseLeftClick){ LiSendMouseButtonEvent(BUTTON_ACTION_RELEASE, BUTTON_LEFT); - if(_mouseButtonForCursorMove!=BUTTON_LEFT) LiSendMouseButtonEvent(BUTTON_ACTION_RELEASE, _mouseButtonForCursorMove); + if(mouseButtonForCursorMove!=BUTTON_LEFT) LiSendMouseButtonEvent(BUTTON_ACTION_RELEASE, mouseButtonForCursorMove); } LiSendMouseButtonEvent(BUTTON_ACTION_PRESS, BUTTON_RIGHT); dispatch_time_t delayShort = dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.01 * NSEC_PER_SEC)); @@ -166,7 +166,7 @@ LiSendMouseButtonEvent(BUTTON_ACTION_RELEASE, BUTTON_LEFT); dispatch_time_t delay = dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.05 * NSEC_PER_SEC)); dispatch_after(delay, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ - LiSendMouseButtonEvent(BUTTON_ACTION_PRESS, self->_mouseButtonForCursorMove); + LiSendMouseButtonEvent(BUTTON_ACTION_PRESS, mouseButtonForCursorMove); }); } } @@ -185,7 +185,7 @@ currentTouchesCount = currentTouches.count; if(currentTouchesCount == 2){ - if(_mouseButtonForCursorMove!=BUTTON_LEFT) LiSendMouseButtonEvent(BUTTON_ACTION_RELEASE, _mouseButtonForCursorMove); + if(mouseButtonForCursorMove!=BUTTON_LEFT) LiSendMouseButtonEvent(BUTTON_ACTION_RELEASE, mouseButtonForCursorMove); if(passthroughGestures) [TouchPadGestureHandler handleGestureIn:streamView with:event]; } @@ -201,10 +201,10 @@ [longPressTimer invalidate]; longPressTimer = nil; - NSTimeInterval dragDelay = _mouseButtonForCursorMove == BUTTON_LEFT ? leftClickTimeThreshold : 0; + NSTimeInterval dragDelay = mouseButtonForCursorMove == BUTTON_LEFT ? leftClickTimeThreshold : 0; if(_delayMouseLeftClick && (CACurrentMediaTime()-touchBeganTimeStamp>dragDelay) && !dragButtonDown){ - LiSendMouseButtonEvent(BUTTON_ACTION_PRESS, _mouseButtonForCursorMove); + LiSendMouseButtonEvent(BUTTON_ACTION_PRESS, mouseButtonForCursorMove); dragButtonDown = true; } } @@ -244,7 +244,7 @@ } else if(!rightButtonClicked){ LiSendMouseButtonEvent(BUTTON_ACTION_RELEASE, BUTTON_LEFT); - if(_mouseButtonForCursorMove!=BUTTON_LEFT) LiSendMouseButtonEvent(BUTTON_ACTION_RELEASE, _mouseButtonForCursorMove); + if(mouseButtonForCursorMove!=BUTTON_LEFT) LiSendMouseButtonEvent(BUTTON_ACTION_RELEASE, mouseButtonForCursorMove); LiSendMouseButtonEvent(BUTTON_ACTION_RELEASE, BUTTON_RIGHT); } } @@ -289,6 +289,13 @@ return isAdjacent; } ++ (int)mouseButtonForCursorMove { + return mouseButtonForCursorMove; +} + ++ (void)setMouseButtonForCursorMove:(int)button { + mouseButtonForCursorMove = button; +} @end diff --git a/VoidLink/Input/OnScreenWidgetView.swift b/VoidLink/Input/OnScreenWidgetView.swift index c6f44799..8288ae16 100644 --- a/VoidLink/Input/OnScreenWidgetView.swift +++ b/VoidLink/Input/OnScreenWidgetView.swift @@ -1967,7 +1967,6 @@ import UIKit case "SOFTKEYBOARD": self.functionalButtonDelegate?.bringUpSoftKeyboard() case "ABSTCHDRAG": - // self.functionalButtonDelegate?.alterAbsTouchDragWith(mouseButton:CommandManager.mouseButtonMappings[self.comboButtonStrings.first ?? "MLEFT"] ?? BUTTON_LEFT) self.functionalButtonDelegate?.alterAbsTouchDragWith(mouseButton:BUTTON_LEFT) default: break @@ -2256,7 +2255,13 @@ import UIKit } if self.motionControlButtonString == "ACCEL" {} if self.motionControlButtonString == "MOTION" {} + + if self.widgetType == WidgetTypeEnum.button && !OnScreenWidgetView.editMode { + self.sendComboButtonsUpEvent(comboStrings: self.comboButtonStrings) + self.functionalButtonDelegate?.alterAbsTouchDragWith(mouseButton:BUTTON_LEFT) + } buttonDownVisualEffectLayer.removeFromSuperlayer() + crossMarkLayer.removeFromSuperlayer() lrudIndicatorBall.removeFromSuperlayer() l3r3Indicator.removeFromSuperlayer() diff --git a/VoidLink/Input/StreamView.m b/VoidLink/Input/StreamView.m index 294494ce..8d767d59 100644 --- a/VoidLink/Input/StreamView.m +++ b/VoidLink/Input/StreamView.m @@ -1388,7 +1388,7 @@ static const double X1_MOUSE_SPEED_DIVISOR = 2.5; - (void)alterAbsTouchDragWith:(int32_t)mouseButton{ if([touchHandler isKindOfClass:[AbsoluteTouchHandler class]]){ AbsoluteTouchHandler* handler = (AbsoluteTouchHandler* )touchHandler; - handler.mouseButtonForCursorMove = mouseButton; + AbsoluteTouchHandler.mouseButtonForCursorMove = mouseButton; [handler pauseLeftButtonDrag]; } else return; diff --git a/VoidLink/ViewControllers/StreamFrameViewController.m b/VoidLink/ViewControllers/StreamFrameViewController.m index d93f0fee..01b8b2bd 100644 --- a/VoidLink/ViewControllers/StreamFrameViewController.m +++ b/VoidLink/ViewControllers/StreamFrameViewController.m @@ -342,11 +342,11 @@ - (void)reConfigStreamViewRealtime { //if(!viewJustLoaded) [self handleViewResize]; - [self reConfigStreamViewRealtimeAndReloadSettings:YES]; + [self reConfigStreamViewRealtimeAndReloadSettings:YES reloadOnscreenWidgets:NO]; } // key implementation of reconfiguring streamview after realtime setting menu is closed. -- (void)reConfigStreamViewRealtimeAndReloadSettings:(BOOL)reloadSettings{ +- (void)reConfigStreamViewRealtimeAndReloadSettings:(BOOL)reloadSettings reloadOnscreenWidgets:(BOOL)reloadOnscreenWidgets{ //[self.view removeGestureRecognizer:] //first, remove all gesture recognizers: for (UIGestureRecognizer *recognizer in _streamView.gestureRecognizers) { @@ -384,7 +384,7 @@ // 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 + if(viewJustLoaded||reloadOnscreenWidgets) [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]; @@ -984,7 +984,7 @@ if (_streamVideoRenderView && _streamView) { [_streamView insertSubview:_streamVideoRenderView atIndex:0]; [self handleViewResize]; // Adjust frames as needed - [self reConfigStreamViewRealtimeAndReloadSettings:YES]; + [self reConfigStreamViewRealtimeAndReloadSettings:YES reloadOnscreenWidgets:YES]; } } NSNotificationCenter* nc = [NSNotificationCenter defaultCenter]; @@ -1518,7 +1518,7 @@ // _settings.enableGraphs = _settings.statsOverlayEnabled; // Reconfigure the UI using the current in-memory settings, without reloading from disk - [self reConfigStreamViewRealtimeAndReloadSettings:NO]; + [self reConfigStreamViewRealtimeAndReloadSettings:NO reloadOnscreenWidgets:NO]; } - (void)toggleMouseCapture{ @@ -1644,7 +1644,7 @@ } dispatch_block_t block = dispatch_block_create(0, ^{ [self handleViewResize]; - [self reConfigStreamViewRealtimeAndReloadSettings:YES]; + [self reConfigStreamViewRealtimeAndReloadSettings:YES reloadOnscreenWidgets:YES]; }); _delayedRemoveExtScreen = block; dispatch_time_t delayTime = dispatch_time(DISPATCH_TIME_NOW, (int64_t)(delayInSeconds * NSEC_PER_SEC));