From 62ae63d7f6fe6ce48b49d0f302b2fdc7aa709644 Mon Sep 17 00:00:00 2001 From: xzzpig Date: Fri, 29 Nov 2024 23:00:54 +0800 Subject: [PATCH] Allow not capture mouse --- Limelight/Base.lproj/iPad.storyboard | 19 +++ Limelight/Base.lproj/iPhone.storyboard | 19 +++ Limelight/Database/DataManager.h | 3 +- Limelight/Database/DataManager.m | 4 +- Limelight/Database/TemporarySettings.h | 1 + Limelight/Database/TemporarySettings.m | 1 + Limelight/Input/ControllerSupport.m | 33 +++-- Limelight/Input/StreamView.m | 13 +- .../Moonlight v1.10.xcdatamodel/contents | 3 +- Limelight/Stream/StreamConfiguration.h | 1 + .../CustomEdgeSlideGestureRecognizer.m | 2 +- .../ViewControllers/MainFrameViewController.m | 1 + .../ViewControllers/SettingsViewController.h | 1 + .../ViewControllers/SettingsViewController.m | 5 +- .../StreamFrameViewController.m | 3 +- Limelight/mul.lproj/iPad.xcstrings | 120 ++++++++++++++++++ Limelight/mul.lproj/iPhone.xcstrings | 120 ++++++++++++++++++ 17 files changed, 327 insertions(+), 22 deletions(-) diff --git a/Limelight/Base.lproj/iPad.storyboard b/Limelight/Base.lproj/iPad.storyboard index eb385bf3..9923baa9 100644 --- a/Limelight/Base.lproj/iPad.storyboard +++ b/Limelight/Base.lproj/iPad.storyboard @@ -554,6 +554,13 @@ ICAgICAgICAgICAgICA + @@ -564,6 +571,17 @@ ICAgICAgICAgICAgICA + + + + + + + + + + + @@ -585,6 +603,7 @@ ICAgICAgICAgICAgICA + diff --git a/Limelight/Base.lproj/iPhone.storyboard b/Limelight/Base.lproj/iPhone.storyboard index 1cc95c98..943ff049 100644 --- a/Limelight/Base.lproj/iPhone.storyboard +++ b/Limelight/Base.lproj/iPhone.storyboard @@ -580,6 +580,24 @@ ICAgICAgICAgICAgIA + + + + + + + + + + + + @@ -601,6 +619,7 @@ ICAgICAgICAgICAgIA + diff --git a/Limelight/Database/DataManager.h b/Limelight/Database/DataManager.h index d4708696..eeed64e2 100644 --- a/Limelight/Database/DataManager.h +++ b/Limelight/Database/DataManager.h @@ -44,7 +44,8 @@ statsOverlay:(BOOL)statsOverlay allowPortrait:(BOOL)allowPortrait resolutionSelected:(NSInteger)resolutionSelected - externalDisplayMode:(NSInteger)externalDisplayMode; + externalDisplayMode:(NSInteger)externalDisplayMode + mouseMode:(NSInteger)mouseMode; - (NSArray*) getHosts; - (void) updateHost:(TemporaryHost*)host; diff --git a/Limelight/Database/DataManager.m b/Limelight/Database/DataManager.m index ef1de168..bc6e1168 100644 --- a/Limelight/Database/DataManager.m +++ b/Limelight/Database/DataManager.m @@ -83,7 +83,8 @@ statsOverlay:(BOOL)statsOverlay allowPortrait:(BOOL)allowPortrait resolutionSelected:(NSInteger)resolutionSelected - externalDisplayMode:(NSInteger)externalDisplayMode { + externalDisplayMode:(NSInteger)externalDisplayMode + mouseMode:(NSInteger)mouseMode { [_managedObjectContext performBlockAndWait:^{ Settings* settingsToSave = [self retrieveSettings]; @@ -119,6 +120,7 @@ settingsToSave.allowPortrait = allowPortrait; settingsToSave.resolutionSelected = [NSNumber numberWithInteger:resolutionSelected]; settingsToSave.externalDisplayMode = [NSNumber numberWithInteger:externalDisplayMode]; + settingsToSave.mouseMode = [NSNumber numberWithInteger:mouseMode]; [self saveData]; }]; } diff --git a/Limelight/Database/TemporarySettings.h b/Limelight/Database/TemporarySettings.h index b536d596..c01ee84d 100644 --- a/Limelight/Database/TemporarySettings.h +++ b/Limelight/Database/TemporarySettings.h @@ -35,6 +35,7 @@ @property (nonatomic, retain) NSString * uniqueId; @property (nonatomic, retain) NSNumber * resolutionSelected; @property (nonatomic, retain) NSNumber * externalDisplayMode; +@property (nonatomic, retain) NSNumber * mouseMode; @property (nonatomic) enum { CODEC_PREF_AUTO, CODEC_PREF_H264, diff --git a/Limelight/Database/TemporarySettings.m b/Limelight/Database/TemporarySettings.m index 837ebbc6..02f81033 100644 --- a/Limelight/Database/TemporarySettings.m +++ b/Limelight/Database/TemporarySettings.m @@ -101,6 +101,7 @@ self.allowPortrait = settings.allowPortrait; self.resolutionSelected = settings.resolutionSelected; self.externalDisplayMode = settings.externalDisplayMode; + self.mouseMode = settings.mouseMode; #endif self.uniqueId = settings.uniqueId; diff --git a/Limelight/Input/ControllerSupport.m b/Limelight/Input/ControllerSupport.m index e8af49d9..9ceec98f 100644 --- a/Limelight/Input/ControllerSupport.m +++ b/Limelight/Input/ControllerSupport.m @@ -46,6 +46,7 @@ static const double MOUSE_SPEED_DIVISOR = 1.25; char _controllerNumbers; bool _multiController; bool _swapABXYButtons; + bool _captureMouse; } // UPDATE_BUTTON_FLAG(controller, flag, pressed) @@ -864,20 +865,25 @@ static const double MOUSE_SPEED_DIVISOR = 1.25; } -(void) registerMouseCallbacks:(GCMouse*) mouse API_AVAILABLE(ios(14.0)) { - mouse.mouseInput.mouseMovedHandler = ^(GCMouseInput * _Nonnull mouse, float deltaX, float deltaY) { - self->accumulatedDeltaX += deltaX / MOUSE_SPEED_DIVISOR; - self->accumulatedDeltaY += -deltaY / MOUSE_SPEED_DIVISOR; - - short truncatedDeltaX = (short)self->accumulatedDeltaX; - short truncatedDeltaY = (short)self->accumulatedDeltaY; - - if (truncatedDeltaX != 0 || truncatedDeltaY != 0) { - LiSendMouseMoveEvent(truncatedDeltaX, truncatedDeltaY); + if (_captureMouse){ + mouse.mouseInput.mouseMovedHandler = ^(GCMouseInput * _Nonnull mouse, float deltaX, float deltaY) { + self->accumulatedDeltaX += deltaX / MOUSE_SPEED_DIVISOR; + self->accumulatedDeltaY += -deltaY / MOUSE_SPEED_DIVISOR; - self->accumulatedDeltaX -= truncatedDeltaX; - self->accumulatedDeltaY -= truncatedDeltaY; - } - }; + short truncatedDeltaX = (short)self->accumulatedDeltaX; + short truncatedDeltaY = (short)self->accumulatedDeltaY; + + if (truncatedDeltaX != 0 || truncatedDeltaY != 0) { + LiSendMouseMoveEvent(truncatedDeltaX, truncatedDeltaY); + + self->accumulatedDeltaX -= truncatedDeltaX; + self->accumulatedDeltaY -= truncatedDeltaY; + } + }; + } else { + mouse.mouseInput.mouseMovedHandler = nil; + } + mouse.mouseInput.leftButton.pressedChangedHandler = ^(GCControllerButtonInput * _Nonnull button, float value, BOOL pressed) { LiSendMouseButtonEvent(pressed ? BUTTON_ACTION_PRESS : BUTTON_ACTION_RELEASE, BUTTON_LEFT); @@ -1120,6 +1126,7 @@ static const double MOUSE_SPEED_DIVISOR = 1.25; } } + _captureMouse = (streamConfig.mouseMode == 0); if (@available(iOS 14.0, tvOS 14.0, *)) { for (GCMouse* mouse in [GCMouse mice]) { [self registerMouseCallbacks:mouse]; diff --git a/Limelight/Input/StreamView.m b/Limelight/Input/StreamView.m index 70a49db2..ed69488b 100644 --- a/Limelight/Input/StreamView.m +++ b/Limelight/Input/StreamView.m @@ -48,6 +48,8 @@ static const double X1_MOUSE_SPEED_DIVISOR = 2.5; double accumulatedMouseDeltaX; double accumulatedMouseDeltaY; + int mouseMode; + UIResponder* touchHandler; id interactionDelegate; @@ -76,6 +78,8 @@ static const double X1_MOUSE_SPEED_DIVISOR = 2.5; settings = [[[DataManager alloc] init] getSettings]; + mouseMode = streamConfig.mouseMode; + keysDown = [[NSMutableSet alloc] init]; keyInputField = [[KeyboardInputField alloc] initWithFrame:CGRectZero]; [keyInputField setKeyboardType:UIKeyboardTypeDefault]; @@ -869,7 +873,7 @@ static const double X1_MOUSE_SPEED_DIVISOR = 2.5; regionForRequest:(UIPointerRegionRequest *)request defaultRegion:(UIPointerRegion *)defaultRegion API_AVAILABLE(ios(13.4)) { if (@available(iOS 14.0, *)) { - if ([GCMouse current] != nil) { + if ([GCMouse current] != nil && mouseMode == 0) { // We'll handle this with GCMouse. Do nothing here. return nil; } @@ -897,8 +901,11 @@ static const double X1_MOUSE_SPEED_DIVISOR = 2.5; } - (UIPointerStyle *)pointerInteraction:(UIPointerInteraction *)interaction styleForRegion:(UIPointerRegion *)region API_AVAILABLE(ios(13.4)) { - // Always hide the mouse cursor over our stream view - return [UIPointerStyle hiddenPointerStyle]; + if(mouseMode != 2){ + return [UIPointerStyle hiddenPointerStyle]; + }else{ + return nil; + } } - (void)mouseWheelMovedContinuous:(UIPanGestureRecognizer *)gesture { diff --git a/Limelight/Limelight.xcdatamodeld/Moonlight v1.10.xcdatamodel/contents b/Limelight/Limelight.xcdatamodeld/Moonlight v1.10.xcdatamodel/contents index bc7f12b1..7cbb880a 100644 --- a/Limelight/Limelight.xcdatamodeld/Moonlight v1.10.xcdatamodel/contents +++ b/Limelight/Limelight.xcdatamodeld/Moonlight v1.10.xcdatamodel/contents @@ -1,5 +1,5 @@ - + @@ -33,6 +33,7 @@ + diff --git a/Limelight/Stream/StreamConfiguration.h b/Limelight/Stream/StreamConfiguration.h index 3073ea62..ab1aa33d 100644 --- a/Limelight/Stream/StreamConfiguration.h +++ b/Limelight/Stream/StreamConfiguration.h @@ -32,5 +32,6 @@ @property BOOL multiController; @property BOOL useFramePacing; @property NSData* serverCert; +@property int mouseMode; @end diff --git a/Limelight/ViewControllers/CustomEdgeSlideGestureRecognizer.m b/Limelight/ViewControllers/CustomEdgeSlideGestureRecognizer.m index 4703ee4f..0b202d93 100644 --- a/Limelight/ViewControllers/CustomEdgeSlideGestureRecognizer.m +++ b/Limelight/ViewControllers/CustomEdgeSlideGestureRecognizer.m @@ -18,7 +18,7 @@ static CGFloat screenWidthInPoints; - (instancetype)initWithTarget:(nullable id)target action:(nullable SEL)action { self = [super initWithTarget:target action:action]; - screenWidthInPoints = CGRectGetWidth([[UIScreen mainScreen] bounds]); // Get the screen's bounds (in points) + screenWidthInPoints = CGRectGetWidth([UIApplication.sharedApplication.windows.firstObject.screen bounds]); // Get the screen's bounds (in points) _immediateTriggering = false; _EDGE_TOLERANCE = 15.0f; return self; diff --git a/Limelight/ViewControllers/MainFrameViewController.m b/Limelight/ViewControllers/MainFrameViewController.m index fc03be11..2331b8ea 100644 --- a/Limelight/ViewControllers/MainFrameViewController.m +++ b/Limelight/ViewControllers/MainFrameViewController.m @@ -670,6 +670,7 @@ static NSMutableSet* hostList; // multiController must be set before calling getConnectedGamepadMask _streamConfig.multiController = streamSettings.multiController; _streamConfig.gamepadMask = [ControllerSupport getConnectedGamepadMask:_streamConfig]; + _streamConfig.mouseMode = streamSettings.mouseMode.intValue; // Probe for supported channel configurations int physicalOutputChannels = (int)[AVAudioSession sharedInstance].maximumOutputNumberOfChannels; diff --git a/Limelight/ViewControllers/SettingsViewController.h b/Limelight/ViewControllers/SettingsViewController.h index 360d101e..4e1bc240 100644 --- a/Limelight/ViewControllers/SettingsViewController.h +++ b/Limelight/ViewControllers/SettingsViewController.h @@ -58,6 +58,7 @@ @property (nonatomic, strong) MainFrameViewController *mainFrameViewController; @property (strong, nonatomic) IBOutlet UISegmentedControl *externalDisplayModeSelector; +@property (strong, nonatomic) IBOutlet UISegmentedControl *mouseModeSelector; #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wunguarded-availability" diff --git a/Limelight/ViewControllers/SettingsViewController.m b/Limelight/ViewControllers/SettingsViewController.m index 6672229d..3ba5545b 100644 --- a/Limelight/ViewControllers/SettingsViewController.m +++ b/Limelight/ViewControllers/SettingsViewController.m @@ -560,6 +560,7 @@ BOOL isCustomResolution(CGSize res) { } [self.externalDisplayModeSelector setSelectedSegmentIndex:currentSettings.externalDisplayMode.integerValue]; + [self.mouseModeSelector setSelectedSegmentIndex:currentSettings.mouseMode.integerValue]; } - (void)slideToSettingsScreenEdgeChanged{ @@ -1067,6 +1068,7 @@ BOOL isCustomResolution(CGSize res) { BOOL allowPortrait = [self.allowPortraitSelector selectedSegmentIndex] == 1; NSInteger resolutionSelected = [self.resolutionSelector selectedSegmentIndex]; NSInteger externalDisplayMode = [self.externalDisplayModeSelector selectedSegmentIndex]; + NSInteger mouseMode = [self.mouseModeSelector selectedSegmentIndex]; [dataMan saveSettingsWithBitrate:_bitrate framerate:framerate height:height @@ -1098,7 +1100,8 @@ BOOL isCustomResolution(CGSize res) { statsOverlay:statsOverlay allowPortrait:allowPortrait resolutionSelected:resolutionSelected - externalDisplayMode:externalDisplayMode]; + externalDisplayMode:externalDisplayMode + mouseMode:mouseMode]; } - (void)didReceiveMemoryWarning { diff --git a/Limelight/ViewControllers/StreamFrameViewController.m b/Limelight/ViewControllers/StreamFrameViewController.m index 07ff44ba..2ec28416 100644 --- a/Limelight/ViewControllers/StreamFrameViewController.m +++ b/Limelight/ViewControllers/StreamFrameViewController.m @@ -167,6 +167,7 @@ andConfig:(StreamConfiguration*)_streamConfig]; //reload OSC here. [self->_streamView reloadOnScreenButtonViews]; //reload keyboard buttons here. the keyboard button view will be added to the streamframe view instead streamview, the highest layer, which saves a lot of reengineering [self reloadAirPlayConfig]; + [self mousePresenceChanged]; //reconfig statsOverlay self->_statsUpdateTimer = [NSTimer scheduledTimerWithTimeInterval:1.0f @@ -966,7 +967,7 @@ // Pointer lock breaks the UIKit mouse APIs, which is a problem because // GCMouse is horribly broken on iOS 14.0 for certain mice. Only lock // the cursor if there is a GCMouse present. - return [GCMouse mice].count > 0; + return ([GCMouse mice].count > 0) && [_settings mouseMode].intValue == 0; } #endif diff --git a/Limelight/mul.lproj/iPad.xcstrings b/Limelight/mul.lproj/iPad.xcstrings index 2b332554..9d5fead5 100644 --- a/Limelight/mul.lproj/iPad.xcstrings +++ b/Limelight/mul.lproj/iPad.xcstrings @@ -91,6 +91,96 @@ } } }, + "4FU-iP-c6T.segmentTitles[0]" : { + "comment" : "Class = \"UISegmentedControl\"; 4FU-iP-c6T.segmentTitles[0] = \"Capture\"; ObjectID = \"4FU-iP-c6T\";", + "extractionState" : "extracted_with_value", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "new", + "value" : "Capture" + } + }, + "zh-Hans" : { + "stringUnit" : { + "state" : "translated", + "value" : "捕获" + } + }, + "zh-Hant" : { + "stringUnit" : { + "state" : "translated", + "value" : "捕获" + } + }, + "zh-HK" : { + "stringUnit" : { + "state" : "translated", + "value" : "捕获" + } + } + } + }, + "4FU-iP-c6T.segmentTitles[1]" : { + "comment" : "Class = \"UISegmentedControl\"; 4FU-iP-c6T.segmentTitles[1] = \"Hidden\"; ObjectID = \"4FU-iP-c6T\";", + "extractionState" : "extracted_with_value", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "new", + "value" : "Hidden" + } + }, + "zh-Hans" : { + "stringUnit" : { + "state" : "translated", + "value" : "隐藏" + } + }, + "zh-Hant" : { + "stringUnit" : { + "state" : "translated", + "value" : "隐藏" + } + }, + "zh-HK" : { + "stringUnit" : { + "state" : "translated", + "value" : "隐藏" + } + } + } + }, + "4FU-iP-c6T.segmentTitles[2]" : { + "comment" : "Class = \"UISegmentedControl\"; 4FU-iP-c6T.segmentTitles[2] = \"Visible\"; ObjectID = \"4FU-iP-c6T\";", + "extractionState" : "extracted_with_value", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "new", + "value" : "Visible" + } + }, + "zh-Hans" : { + "stringUnit" : { + "state" : "translated", + "value" : "可见" + } + }, + "zh-Hant" : { + "stringUnit" : { + "state" : "translated", + "value" : "可见" + } + }, + "zh-HK" : { + "stringUnit" : { + "state" : "translated", + "value" : "可见" + } + } + } + }, "4Qy-hB-oa5.text" : { "comment" : "Class = \"UILabel\"; text = \"External Display Mode\"; ObjectID = \"4Qy-hB-oa5\";", "extractionState" : "extracted_with_value", @@ -2167,6 +2257,36 @@ } } }, + "tAd-bm-2IO.text" : { + "comment" : "Class = \"UILabel\"; text = \"Mouse Mode\"; ObjectID = \"tAd-bm-2IO\";", + "extractionState" : "extracted_with_value", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "new", + "value" : "Mouse Mode" + } + }, + "zh-Hans" : { + "stringUnit" : { + "state" : "translated", + "value" : "鼠标模式" + } + }, + "zh-Hant" : { + "stringUnit" : { + "state" : "translated", + "value" : "鼠标模式" + } + }, + "zh-HK" : { + "stringUnit" : { + "state" : "translated", + "value" : "鼠标模式" + } + } + } + }, "uSS-ev-IFe.configuration.title" : { "comment" : "Class = \"UIButton\"; configuration.title = \"Go Back to Stream View\"; ObjectID = \"uSS-ev-IFe\";", "extractionState" : "extracted_with_value", diff --git a/Limelight/mul.lproj/iPhone.xcstrings b/Limelight/mul.lproj/iPhone.xcstrings index 26e95e57..2af3742b 100644 --- a/Limelight/mul.lproj/iPhone.xcstrings +++ b/Limelight/mul.lproj/iPhone.xcstrings @@ -961,6 +961,96 @@ } } }, + "F96-Um-Q6t.segmentTitles[0]" : { + "comment" : "Class = \"UISegmentedControl\"; F96-Um-Q6t.segmentTitles[0] = \"Capture\"; ObjectID = \"F96-Um-Q6t\";", + "extractionState" : "extracted_with_value", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "new", + "value" : "Capture" + } + }, + "zh-Hans" : { + "stringUnit" : { + "state" : "translated", + "value" : "捕获" + } + }, + "zh-Hant" : { + "stringUnit" : { + "state" : "translated", + "value" : "捕获" + } + }, + "zh-HK" : { + "stringUnit" : { + "state" : "translated", + "value" : "捕获" + } + } + } + }, + "F96-Um-Q6t.segmentTitles[1]" : { + "comment" : "Class = \"UISegmentedControl\"; F96-Um-Q6t.segmentTitles[1] = \"Hidden\"; ObjectID = \"F96-Um-Q6t\";", + "extractionState" : "extracted_with_value", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "new", + "value" : "Hidden" + } + }, + "zh-Hans" : { + "stringUnit" : { + "state" : "translated", + "value" : "隐藏" + } + }, + "zh-Hant" : { + "stringUnit" : { + "state" : "translated", + "value" : "隐藏" + } + }, + "zh-HK" : { + "stringUnit" : { + "state" : "translated", + "value" : "隐藏" + } + } + } + }, + "F96-Um-Q6t.segmentTitles[2]" : { + "comment" : "Class = \"UISegmentedControl\"; F96-Um-Q6t.segmentTitles[2] = \"Visible\"; ObjectID = \"F96-Um-Q6t\";", + "extractionState" : "extracted_with_value", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "new", + "value" : "Visible" + } + }, + "zh-Hans" : { + "stringUnit" : { + "state" : "translated", + "value" : "可见" + } + }, + "zh-Hant" : { + "stringUnit" : { + "state" : "translated", + "value" : "可见" + } + }, + "zh-HK" : { + "stringUnit" : { + "state" : "translated", + "value" : "可见" + } + } + } + }, "FqF-bM-afQ.configuration.title" : { "comment" : "Class = \"UIButton\"; configuration.title = \"Go Back to Stream View\"; ObjectID = \"FqF-bM-afQ\";", "extractionState" : "extracted_with_value", @@ -2029,6 +2119,36 @@ } } }, + "VGn-Oc-mKc.text" : { + "comment" : "Class = \"UILabel\"; text = \"Mouse Mode\"; ObjectID = \"VGn-Oc-mKc\";", + "extractionState" : "extracted_with_value", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "new", + "value" : "Mouse Mode" + } + }, + "zh-Hans" : { + "stringUnit" : { + "state" : "translated", + "value" : "鼠标模式" + } + }, + "zh-Hant" : { + "stringUnit" : { + "state" : "translated", + "value" : "鼠标模式" + } + }, + "zh-HK" : { + "stringUnit" : { + "state" : "translated", + "value" : "鼠标模式" + } + } + } + }, "VlN-ZW-1gm.text" : { "comment" : "Class = \"UILabel\"; text = \"Touch Pointer Velocity: Scaled on 0% of Right Screen \"; ObjectID = \"VlN-ZW-1gm\";", "extractionState" : "extracted_with_value",