diff --git a/lib/focus/dpad_navigator.dart b/lib/focus/dpad_navigator.dart index 1c19e3de..fed6b658 100644 --- a/lib/focus/dpad_navigator.dart +++ b/lib/focus/dpad_navigator.dart @@ -5,19 +5,22 @@ import 'package:flutter/services.dart'; extension KeyEventActionable on KeyEvent { bool get isActionable => this is KeyDownEvent || this is KeyRepeatEvent; bool get isPhysicalKeyboardEvent => deviceType == ui.KeyEventDeviceType.keyboard; + // Only true keyboard submit keys belong here. LogicalKeyboardKey.select is + // a TV-remote / dpad-center key (Android DPAD_CENTER, tvOS UIPressTypeSelect) + // — USB keyboards never emit it. The custom Flutter tvOS engine reports its + // synthesized Siri Remote presses with deviceType=keyboard, so classifying + // select-with-keyboard-deviceType as a "keyboard enter" would route center + // dpad through TextField submit and skip the TV virtual keyboard. bool get isPhysicalKeyboardEnter => deviceType == ui.KeyEventDeviceType.keyboard && - (logicalKey == LogicalKeyboardKey.enter || - logicalKey == LogicalKeyboardKey.numpadEnter || - logicalKey == LogicalKeyboardKey.select); + (logicalKey == LogicalKeyboardKey.enter || logicalKey == LogicalKeyboardKey.numpadEnter); bool get isTvSelectEvent { - if (isPhysicalKeyboardEvent) return false; + // Dpad-center / gamepad-A are TV-remote-only — always treat as TV select, + // regardless of the deviceType claim from the engine. if (logicalKey == LogicalKeyboardKey.select || logicalKey == LogicalKeyboardKey.gameButtonA) return true; - if (logicalKey == LogicalKeyboardKey.enter || logicalKey == LogicalKeyboardKey.numpadEnter) { - return deviceType != ui.KeyEventDeviceType.keyboard; - } - return false; + if (isPhysicalKeyboardEvent) return false; + return logicalKey == LogicalKeyboardKey.enter || logicalKey == LogicalKeyboardKey.numpadEnter; } } diff --git a/lib/services/apple_tv_remote_touch_service.dart b/lib/services/apple_tv_remote_touch_service.dart index 09eef99d..20e9ecab 100644 --- a/lib/services/apple_tv_remote_touch_service.dart +++ b/lib/services/apple_tv_remote_touch_service.dart @@ -108,12 +108,11 @@ class AppleTvRemoteTouchService { if (position == null) return; _moveTouch(position.$1, position.$2); case 'ended': - final position = _positionFrom(arguments); - if (position == null) { - _resetTouch(); - return; - } - _moveTouch(position.$1, position.$2); + // Drop the lift frame: the final position on touchesEnded is + // unreliable on the Siri Remote — a natural finger pivot during + // lift can register enough delta from the post-last-swipe anchor + // to fire a stray opposite-direction swipe. In-gesture 'move' + // events have already covered any legitimate swipe motion. _resetTouch(); case 'cancelled': _resetTouch(); diff --git a/lib/utils/key_event_simulator.dart b/lib/utils/key_event_simulator.dart index dfe486d2..b23d3bcb 100644 --- a/lib/utils/key_event_simulator.dart +++ b/lib/utils/key_event_simulator.dart @@ -9,6 +9,14 @@ import 'package:flutter/widgets.dart'; /// Used by companion remotes, Apple TV touch input, and gamepad services to /// translate external input into focus-tree key events. void simulateKeyPress(LogicalKeyboardKey logicalKey) { + // The dispatch below is deferred via addPostFrameCallback to ensure the + // focus tree is settled before we walk it. That post-frame callback only + // fires after a frame actually renders — and when Flutter is idle (no + // animations, no rebuilds), the engine will never schedule one on its + // own, so the callback hangs indefinitely. Force a frame so external + // input (gamepad, tvOS remote, companion remote) always advances focus + // immediately rather than batching until something else wakes the engine. + scheduleFrameIfIdle(); SchedulerBinding.instance.addPostFrameCallback((_) { final focusNode = FocusManager.instance.primaryFocus; if (focusNode == null) return; diff --git a/pubspec.yaml b/pubspec.yaml index 660a8df7..3480442b 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -1,7 +1,7 @@ name: plezy description: "A beautiful Plex and Jellyfin client for Flutter" publish_to: "none" -version: 2.0.0+86 +version: 2.0.0+87 environment: sdk: ">=3.10.7 <4.0.0" diff --git a/test/services/apple_tv_remote_touch_service_test.dart b/test/services/apple_tv_remote_touch_service_test.dart index 7a7a0e65..7fa3b544 100644 --- a/test/services/apple_tv_remote_touch_service_test.dart +++ b/test/services/apple_tv_remote_touch_service_test.dart @@ -119,6 +119,21 @@ void main() { expect(harness.keys, [LogicalKeyboardKey.arrowLeft]); }); + test('ended position past threshold opposite of the last move does not fire a reverse swipe', () async { + final harness = _Harness(); + + // User swipes left, then releases the finger. The final lift + // position registers past the swipe threshold from the post-swipe + // anchor in the *opposite* direction — natural finger pivot during + // a lift. The previous implementation called _moveTouch on the + // ended event and re-fired a stray arrowRight here. + await harness.send('started', x: 500, y: 500); + await harness.send('move', x: 380, y: 500); + await harness.send('ended', x: 600, y: 500); + + expect(harness.keys, [LogicalKeyboardKey.arrowLeft]); + }); + test('deduplicates touch tap and click fallback select events', () async { final harness = _Harness(); diff --git a/test/widgets/focusable_text_field_test.dart b/test/widgets/focusable_text_field_test.dart index fa945267..64b10580 100644 --- a/test/widgets/focusable_text_field_test.dart +++ b/test/widgets/focusable_text_field_test.dart @@ -126,8 +126,16 @@ void main() { expect(find.byType(Dialog), findsOneWidget); }); - testWidgets('tvOS keyboard-mapped select submits without opening virtual keyboard', (tester) async { + testWidgets('tvOS engine-synthesized select opens the virtual keyboard', (tester) async { + // The custom Flutter tvOS engine emits Siri Remote center-dpad presses + // as `LogicalKeyboardKey.select` with `deviceType=keyboard` (via the + // legacy `flutter/keyevent` Android DPAD_CENTER path). On Apple TV this + // must open the on-screen keyboard, not submit the form. Previously + // `isPhysicalKeyboardEnter` matched select+keyboard and routed through + // `_submitTextInput`, which silently triggered form submit on every + // dpad center press (e.g. immediate validation error on empty fields). TvDetectionService.debugSetAppleTVOverride(true); + await _setTvSurfaceSize(tester); final controller = TextEditingController(text: 'query'); final fieldFocusNode = FocusNode(debugLabel: 'search_field'); String? submitted; @@ -151,8 +159,8 @@ void main() { await tester.sendKeyEvent(LogicalKeyboardKey.select); await tester.pumpAndSettle(); - expect(submitted, 'query'); - expect(find.byType(Dialog), findsNothing); + expect(submitted, isNull); + expect(find.byType(Dialog), findsOneWidget); }); testWidgets('tvOS text field handles physical keyboard text editing without opening virtual keyboard', ( diff --git a/tvos/Runner.xcodeproj/project.pbxproj b/tvos/Runner.xcodeproj/project.pbxproj index 2780d2ac..27d4f1bf 100644 --- a/tvos/Runner.xcodeproj/project.pbxproj +++ b/tvos/Runner.xcodeproj/project.pbxproj @@ -7,25 +7,25 @@ objects = { /* Begin PBXBuildFile section */ - 0A4E3554C5AD1373495F5434 /* messages.g.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0C8E3486BF50440024D81B1E /* messages.g.swift */; }; - 24753D6DD9098E97989137A6 /* PackageInfoPlusPlugin.swift in Sources */ = {isa = PBXBuildFile; fileRef = 83C51CAD792E5C69AA4F971A /* PackageInfoPlusPlugin.swift */; }; - 31477C4FBA7BF70CAFCDC566 /* DeviceInfoPlusPlugin.swift in Sources */ = {isa = PBXBuildFile; fileRef = 98ED539F08FAE8E8B964C7BE /* DeviceInfoPlusPlugin.swift */; }; + 055E465F9095D0B6E9B91D46 /* PathProviderPlugin.swift in Sources */ = {isa = PBXBuildFile; fileRef = D41AA251EF365516E2AC5287 /* PathProviderPlugin.swift */; }; + 35DB0C8FEF635A3BCA0B722A /* PackageInfoPlusPlugin.swift in Sources */ = {isa = PBXBuildFile; fileRef = F9426EFA282CDA8E0E98EEE9 /* PackageInfoPlusPlugin.swift */; }; 3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */ = {isa = PBXBuildFile; fileRef = 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */; }; - 4E9365FA67E94D8A289FE862 /* PathMonitorConnectivityProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = AA12E2C6063C5799C38CAA95 /* PathMonitorConnectivityProvider.swift */; }; 5C71F5F7B33075F2B007825B /* MpvPlayerPluginShared.swift in Sources */ = {isa = PBXBuildFile; fileRef = 73645904F226A24585A092CE /* MpvPlayerPluginShared.swift */; }; 691577F0EB3F4EB1A5160280 /* MpvPlayerCoreBase.swift in Sources */ = {isa = PBXBuildFile; fileRef = D52A3BDA46E79969EA1DF3AC /* MpvPlayerCoreBase.swift */; }; 6F3C0DD6F2F8DA14E7E2F386 /* MpvPlayerCore.swift in Sources */ = {isa = PBXBuildFile; fileRef = A12B8610AE5D580077264851 /* MpvPlayerCore.swift */; }; 74858FAF1ED2DC5600515810 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 74858FAE1ED2DC5600515810 /* AppDelegate.swift */; }; + 81325C1CD13794375A81AC02 /* messages.g.swift in Sources */ = {isa = PBXBuildFile; fileRef = 34CD411CCD84E381C4BF4C1B /* messages.g.swift */; }; + 81F08E404EBEB19B00FF148D /* ConnectivityPlusPlugin.swift in Sources */ = {isa = PBXBuildFile; fileRef = 67C3193A50DFDECE2B92D075 /* ConnectivityPlusPlugin.swift */; }; 8E5EED3DDAC9455D4DAA9776 /* MpvPlayerPlugin.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9D7A998830EDC8F77BF521D1 /* MpvPlayerPlugin.swift */; }; - 937279397427A0E8ECC70A3A /* PathProviderPlugin.swift in Sources */ = {isa = PBXBuildFile; fileRef = 217BA48DC884CB7ADD43CF88 /* PathProviderPlugin.swift */; }; 97C146FC1CF9000F007C117D /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FA1CF9000F007C117D /* Main.storyboard */; }; 97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FD1CF9000F007C117D /* Assets.xcassets */; }; 97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */; }; + A7596F780E93AF0BE3838A26 /* ConnectivityProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3CCA7E80F3A99D8759F2E59F /* ConnectivityProvider.swift */; }; AA34E3E5872B3792D6959EAA /* MpvPipController.swift in Sources */ = {isa = PBXBuildFile; fileRef = A2635E12EB9322B151EE5127 /* MpvPipController.swift */; }; - AFCEB532D567638EF6707333 /* ConnectivityProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3C9575190150A93F97270FC0 /* ConnectivityProvider.swift */; }; C6A15611158B29B0FF43A960 /* Pods_Runner.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 824D2C68D1F1206932E118C2 /* Pods_Runner.framework */; }; - C94CC73C8037BAA385B7ED5C /* SharedPreferencesPlugin.swift in Sources */ = {isa = PBXBuildFile; fileRef = 35FB5275C65B7F4CC7DD45DF /* SharedPreferencesPlugin.swift */; }; - F85DEBB1878182EEE1DC542A /* ConnectivityPlusPlugin.swift in Sources */ = {isa = PBXBuildFile; fileRef = 936A41610C7269D52E5E51FF /* ConnectivityPlusPlugin.swift */; }; + CD1C0534948840272E58248E /* PathMonitorConnectivityProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6AEF79DFBD1D80F00AB39CDA /* PathMonitorConnectivityProvider.swift */; }; + E3DEAD2AAFC347A2E55AC0F7 /* SharedPreferencesPlugin.swift in Sources */ = {isa = PBXBuildFile; fileRef = C0455EBA0EF4A61D3B71D2D7 /* SharedPreferencesPlugin.swift */; }; + E79A4474D308631AFA59CAE7 /* DeviceInfoPlusPlugin.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5E1F41676FEF1AB57076F8B9 /* DeviceInfoPlusPlugin.swift */; }; /* End PBXBuildFile section */ /* Begin PBXCopyFilesBuildPhase section */ @@ -44,19 +44,18 @@ /* Begin PBXFileReference section */ 04DD35536DEE7C27FFA53862 /* Pods-Runner.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.release.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig"; sourceTree = ""; }; 0C25F4F2367A30B47E945AD6 /* Pods-Runner.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.debug.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig"; sourceTree = ""; }; - 0C8E3486BF50440024D81B1E /* messages.g.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = messages.g.swift; sourceTree = ""; }; - 217BA48DC884CB7ADD43CF88 /* PathProviderPlugin.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = PathProviderPlugin.swift; sourceTree = ""; }; - 35FB5275C65B7F4CC7DD45DF /* SharedPreferencesPlugin.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = SharedPreferencesPlugin.swift; sourceTree = ""; }; + 34CD411CCD84E381C4BF4C1B /* messages.g.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = messages.g.swift; sourceTree = ""; }; 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = AppFrameworkInfo.plist; path = Flutter/AppFrameworkInfo.plist; sourceTree = ""; }; - 3C9575190150A93F97270FC0 /* ConnectivityProvider.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = ConnectivityProvider.swift; sourceTree = ""; }; + 3CCA7E80F3A99D8759F2E59F /* ConnectivityProvider.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = ConnectivityProvider.swift; sourceTree = ""; }; 420881FB6A648A2AFD39FFF2 /* Pods-Runner.profile.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.profile.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.profile.xcconfig"; sourceTree = ""; }; + 5E1F41676FEF1AB57076F8B9 /* DeviceInfoPlusPlugin.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = DeviceInfoPlusPlugin.swift; sourceTree = ""; }; + 67C3193A50DFDECE2B92D075 /* ConnectivityPlusPlugin.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = ConnectivityPlusPlugin.swift; sourceTree = ""; }; + 6AEF79DFBD1D80F00AB39CDA /* PathMonitorConnectivityProvider.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = PathMonitorConnectivityProvider.swift; sourceTree = ""; }; 73645904F226A24585A092CE /* MpvPlayerPluginShared.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = MpvPlayerPluginShared.swift; path = ../shared/apple/MpvPlayer/MpvPlayerPluginShared.swift; sourceTree = ""; }; 74858FAD1ED2DC5600515810 /* Runner-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "Runner-Bridging-Header.h"; sourceTree = ""; }; 74858FAE1ED2DC5600515810 /* AppDelegate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; 7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = Release.xcconfig; path = Flutter/Release.xcconfig; sourceTree = ""; }; 824D2C68D1F1206932E118C2 /* Pods_Runner.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Runner.framework; sourceTree = BUILT_PRODUCTS_DIR; }; - 83C51CAD792E5C69AA4F971A /* PackageInfoPlusPlugin.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = PackageInfoPlusPlugin.swift; sourceTree = ""; }; - 936A41610C7269D52E5E51FF /* ConnectivityPlusPlugin.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = ConnectivityPlusPlugin.swift; sourceTree = ""; }; 9740EEB21CF90195004384FC /* Debug.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Debug.xcconfig; path = Flutter/Debug.xcconfig; sourceTree = ""; }; 9740EEB31CF90195004384FC /* Generated.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Generated.xcconfig; path = Flutter/Generated.xcconfig; sourceTree = ""; }; 97C146EE1CF9000F007C117D /* Runner.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Runner.app; sourceTree = BUILT_PRODUCTS_DIR; }; @@ -64,12 +63,13 @@ 97C146FD1CF9000F007C117D /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; 97C147001CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; 97C147021CF9000F007C117D /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; - 98ED539F08FAE8E8B964C7BE /* DeviceInfoPlusPlugin.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = DeviceInfoPlusPlugin.swift; sourceTree = ""; }; 9D7A998830EDC8F77BF521D1 /* MpvPlayerPlugin.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = MpvPlayerPlugin.swift; path = ../ios/Runner/MpvPlayer/MpvPlayerPlugin.swift; sourceTree = ""; }; A12B8610AE5D580077264851 /* MpvPlayerCore.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = MpvPlayerCore.swift; path = ../ios/Runner/MpvPlayer/MpvPlayerCore.swift; sourceTree = ""; }; A2635E12EB9322B151EE5127 /* MpvPipController.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = MpvPipController.swift; path = ../ios/Runner/MpvPlayer/MpvPipController.swift; sourceTree = ""; }; - AA12E2C6063C5799C38CAA95 /* PathMonitorConnectivityProvider.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = PathMonitorConnectivityProvider.swift; sourceTree = ""; }; + C0455EBA0EF4A61D3B71D2D7 /* SharedPreferencesPlugin.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = SharedPreferencesPlugin.swift; sourceTree = ""; }; + D41AA251EF365516E2AC5287 /* PathProviderPlugin.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = PathProviderPlugin.swift; sourceTree = ""; }; D52A3BDA46E79969EA1DF3AC /* MpvPlayerCoreBase.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = MpvPlayerCoreBase.swift; path = ../shared/apple/MpvPlayer/MpvPlayerCoreBase.swift; sourceTree = ""; }; + F9426EFA282CDA8E0E98EEE9 /* PackageInfoPlusPlugin.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = PackageInfoPlusPlugin.swift; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ @@ -84,26 +84,36 @@ /* End PBXFrameworksBuildPhase section */ /* Begin PBXGroup section */ - 0BB116AB9B63B9251A577795 /* connectivity_plus */ = { + 02A6A190E05475F583874D9C /* package_info_plus */ = { isa = PBXGroup; children = ( - 936A41610C7269D52E5E51FF /* ConnectivityPlusPlugin.swift */, - 3C9575190150A93F97270FC0 /* ConnectivityProvider.swift */, - AA12E2C6063C5799C38CAA95 /* PathMonitorConnectivityProvider.swift */, - ); - name = connectivity_plus; - path = connectivity_plus; - sourceTree = ""; - }; - 5167AAFF7134262A07EBBC7C /* package_info_plus */ = { - isa = PBXGroup; - children = ( - 83C51CAD792E5C69AA4F971A /* PackageInfoPlusPlugin.swift */, + F9426EFA282CDA8E0E98EEE9 /* PackageInfoPlusPlugin.swift */, ); name = package_info_plus; path = package_info_plus; sourceTree = ""; }; + 24CE237B5ECBF841DDDAD2D1 /* shared_preferences_foundation */ = { + isa = PBXGroup; + children = ( + C0455EBA0EF4A61D3B71D2D7 /* SharedPreferencesPlugin.swift */, + 34CD411CCD84E381C4BF4C1B /* messages.g.swift */, + ); + name = shared_preferences_foundation; + path = shared_preferences_foundation; + sourceTree = ""; + }; + 25FB49FF35E9FB1E7A2040EF /* connectivity_plus */ = { + isa = PBXGroup; + children = ( + 67C3193A50DFDECE2B92D075 /* ConnectivityPlusPlugin.swift */, + 3CCA7E80F3A99D8759F2E59F /* ConnectivityProvider.swift */, + 6AEF79DFBD1D80F00AB39CDA /* PathMonitorConnectivityProvider.swift */, + ); + name = connectivity_plus; + path = connectivity_plus; + sourceTree = ""; + }; 53CDD29681161166962B9FA5 /* Pods */ = { isa = PBXGroup; children = ( @@ -122,23 +132,10 @@ name = Frameworks; sourceTree = ""; }; - 6C18DC1E07D29FCDF63F3159 /* Plugins */ = { + 6B0884FDB3DBCBC1E7F0CBAD /* device_info_plus */ = { isa = PBXGroup; children = ( - ACB880260B35BB030208DF38 /* shared_preferences_foundation */, - 5167AAFF7134262A07EBBC7C /* package_info_plus */, - 9DF350B3C8D3FFF46CF8FEF7 /* path_provider */, - 7CEBB3A4438717E61CFCBA1E /* device_info_plus */, - 0BB116AB9B63B9251A577795 /* connectivity_plus */, - ); - name = Plugins; - path = Plugins; - sourceTree = ""; - }; - 7CEBB3A4438717E61CFCBA1E /* device_info_plus */ = { - isa = PBXGroup; - children = ( - 98ED539F08FAE8E8B964C7BE /* DeviceInfoPlusPlugin.swift */, + 5E1F41676FEF1AB57076F8B9 /* DeviceInfoPlusPlugin.swift */, ); name = device_info_plus; path = device_info_plus; @@ -184,30 +181,11 @@ 74858FAE1ED2DC5600515810 /* AppDelegate.swift */, 74858FAD1ED2DC5600515810 /* Runner-Bridging-Header.h */, BF0B7DFE378943E9D7865D18 /* MpvPlayer */, - 6C18DC1E07D29FCDF63F3159 /* Plugins */, + D58B788B11920D95BC7D750C /* Plugins */, ); path = Runner; sourceTree = ""; }; - 9DF350B3C8D3FFF46CF8FEF7 /* path_provider */ = { - isa = PBXGroup; - children = ( - 217BA48DC884CB7ADD43CF88 /* PathProviderPlugin.swift */, - ); - name = path_provider; - path = path_provider; - sourceTree = ""; - }; - ACB880260B35BB030208DF38 /* shared_preferences_foundation */ = { - isa = PBXGroup; - children = ( - 35FB5275C65B7F4CC7DD45DF /* SharedPreferencesPlugin.swift */, - 0C8E3486BF50440024D81B1E /* messages.g.swift */, - ); - name = shared_preferences_foundation; - path = shared_preferences_foundation; - sourceTree = ""; - }; BF0B7DFE378943E9D7865D18 /* MpvPlayer */ = { isa = PBXGroup; children = ( @@ -221,6 +199,28 @@ path = Runner/MpvPlayer; sourceTree = ""; }; + D58B788B11920D95BC7D750C /* Plugins */ = { + isa = PBXGroup; + children = ( + 24CE237B5ECBF841DDDAD2D1 /* shared_preferences_foundation */, + 02A6A190E05475F583874D9C /* package_info_plus */, + DF39F6BC85D449736C737F18 /* path_provider */, + 6B0884FDB3DBCBC1E7F0CBAD /* device_info_plus */, + 25FB49FF35E9FB1E7A2040EF /* connectivity_plus */, + ); + name = Plugins; + path = Plugins; + sourceTree = ""; + }; + DF39F6BC85D449736C737F18 /* path_provider */ = { + isa = PBXGroup; + children = ( + D41AA251EF365516E2AC5287 /* PathProviderPlugin.swift */, + ); + name = path_provider; + path = path_provider; + sourceTree = ""; + }; /* End PBXGroup section */ /* Begin PBXNativeTarget section */ @@ -380,14 +380,14 @@ 6F3C0DD6F2F8DA14E7E2F386 /* MpvPlayerCore.swift in Sources */, 8E5EED3DDAC9455D4DAA9776 /* MpvPlayerPlugin.swift in Sources */, AA34E3E5872B3792D6959EAA /* MpvPipController.swift in Sources */, - C94CC73C8037BAA385B7ED5C /* SharedPreferencesPlugin.swift in Sources */, - 0A4E3554C5AD1373495F5434 /* messages.g.swift in Sources */, - 24753D6DD9098E97989137A6 /* PackageInfoPlusPlugin.swift in Sources */, - 937279397427A0E8ECC70A3A /* PathProviderPlugin.swift in Sources */, - 31477C4FBA7BF70CAFCDC566 /* DeviceInfoPlusPlugin.swift in Sources */, - F85DEBB1878182EEE1DC542A /* ConnectivityPlusPlugin.swift in Sources */, - AFCEB532D567638EF6707333 /* ConnectivityProvider.swift in Sources */, - 4E9365FA67E94D8A289FE862 /* PathMonitorConnectivityProvider.swift in Sources */, + E3DEAD2AAFC347A2E55AC0F7 /* SharedPreferencesPlugin.swift in Sources */, + 81325C1CD13794375A81AC02 /* messages.g.swift in Sources */, + 35DB0C8FEF635A3BCA0B722A /* PackageInfoPlusPlugin.swift in Sources */, + 055E465F9095D0B6E9B91D46 /* PathProviderPlugin.swift in Sources */, + E79A4474D308631AFA59CAE7 /* DeviceInfoPlusPlugin.swift in Sources */, + 81F08E404EBEB19B00FF148D /* ConnectivityPlusPlugin.swift in Sources */, + A7596F780E93AF0BE3838A26 /* ConnectivityProvider.swift in Sources */, + CD1C0534948840272E58248E /* PathMonitorConnectivityProvider.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; diff --git a/tvos/engine.version b/tvos/engine.version index 81f36e77..89666ed4 100644 --- a/tvos/engine.version +++ b/tvos/engine.version @@ -1 +1 @@ -3.41.6+5 +3.41.6+6 diff --git a/tvos/scripts/wire_plugins.rb b/tvos/scripts/wire_plugins.rb index 589934d4..b6ea1cf3 100755 --- a/tvos/scripts/wire_plugins.rb +++ b/tvos/scripts/wire_plugins.rb @@ -78,5 +78,23 @@ plugins.each do |plugin_name, files| end end +# Remove stale Runner/-level Swift refs from earlier engine workarounds. +# Currently nothing needs to live directly under tvos/Runner/ besides +# AppDelegate.swift (which the Xcode project tracks on its own); the +# SiriRemoteDpadBridge.swift workaround was removed once the engine patch +# took over dpad click handling. +STALE_RUNNER_LOCAL_SOURCES = %w[SiriRemoteDpadBridge.swift] + +project.files.select { |f| STALE_RUNNER_LOCAL_SOURCES.include?(f.display_name) }.each do |f| + f.remove_from_project + puts "[rm ] stale ref: #{f.display_name}" +end +project.targets.each do |t| + t.build_phases.each do |phase| + next unless phase.respond_to?(:files) + phase.files.delete_if { |bf| bf.file_ref.nil? } + end +end + project.save puts "Saved"