mirror of
https://github.com/hrydgard/ppsspp.git
synced 2026-10-13 22:40:29 +02:00
tvOS: Back on the main screen goes to the home screen, like on Android
tvOS only does that with a Back press it gets to see, so the view controller lets controller events through to UIKit while the top screen is top level (the new TOP_LEVEL_CHANGED notification), and passes presses that aren't keyboard keys on to super. Elsewhere Back stays ours. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
5b05b34b4e
commit
625db43746
5 files changed
+45
-4
No files matched your search
@@ -277,6 +277,7 @@ enum class SystemNotification {
|
||||
PAD_STATE_CHANGED,
|
||||
CONFIG_LOADED,
|
||||
BEFORE_CONFIG_SAVE_ON_EXIT,
|
||||
TOP_LEVEL_CHANGED, // NativeIsAtTopLevel() changed. From the render thread.
|
||||
};
|
||||
|
||||
// I guess it's not super great architecturally to centralize this, since it's not general - but same with a lot of
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
#include "Common/System/Display.h"
|
||||
#include "Common/System/System.h"
|
||||
#include "Common/Data/Collections/TinySet.h"
|
||||
#include "Common/UI/ScreenManager.h"
|
||||
#include "Common/UI/Root.h"
|
||||
@@ -133,13 +134,15 @@ void ScreenManager::Update() {
|
||||
overlayScreen_->update();
|
||||
}
|
||||
|
||||
bool topLevel = false;
|
||||
if (!stack_.empty()) {
|
||||
Screen *backScreen = stack_.back().screen;
|
||||
backScreen->update();
|
||||
passInputToMapper_ = backScreen->PassInputToMapper();
|
||||
topIsTopLevel_ = backScreen->isTopLevel();
|
||||
} else {
|
||||
topIsTopLevel_ = false;
|
||||
topLevel = backScreen->isTopLevel();
|
||||
}
|
||||
if (topIsTopLevel_.exchange(topLevel) != topLevel) {
|
||||
System_Notify(SystemNotification::TOP_LEVEL_CHANGED);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -46,6 +46,7 @@
|
||||
- (void)willResignActive;
|
||||
|
||||
- (void)uiStateChanged;
|
||||
- (void)topLevelChanged;
|
||||
- (void)pickPhoto:(NSString *)saveFilename requestId:(int)requestId;
|
||||
- (void)updateResolutionWithView:(UIView *)view;
|
||||
|
||||
|
||||
+30
-1
@@ -202,7 +202,7 @@ static int GetPickerRequestId(id picker) {
|
||||
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(controllerDidDisconnect:) name:GCControllerDidDisconnectNotification object:nil];
|
||||
|
||||
#if PPSSPP_PLATFORM(TVOS)
|
||||
// Already the default. Should become YES at the top level menu, so the Menu button goes home.
|
||||
// Already the default. See topLevelChanged.
|
||||
self.controllerUserInteractionEnabled = NO;
|
||||
#else
|
||||
// Observe orientation changes
|
||||
@@ -392,6 +392,15 @@ static int GetPickerRequestId(id picker) {
|
||||
}
|
||||
}
|
||||
|
||||
// Like Android, Back on the main screen leaves the app. tvOS only does that with a Back press it
|
||||
// gets to see, so let controller events through to UIKit there. They still reach GCController.
|
||||
- (void)topLevelChanged {
|
||||
#if PPSSPP_PLATFORM(TVOS)
|
||||
self.controllerUserInteractionEnabled = NativeIsAtTopLevel() ? YES : NO;
|
||||
INFO_LOG(Log::System, "Controller events to UIKit: %s", self.controllerUserInteractionEnabled ? "yes" : "no");
|
||||
#endif
|
||||
}
|
||||
|
||||
- (void)setupController:(GCController *)controller {
|
||||
self.gameController = controller;
|
||||
if (!InitController(controller)) {
|
||||
@@ -698,16 +707,36 @@ extern float g_safeInsetBottom;
|
||||
return YES;
|
||||
}
|
||||
|
||||
// Presses that aren't keyboard keys, like the remote's buttons, go on up the responder chain. On
|
||||
// tvOS, that's what takes Back on the main screen to the home screen (see topLevelChanged).
|
||||
static NSSet<UIPress *> *NonKeyboardPresses(NSSet<UIPress *> *presses) {
|
||||
return [presses objectsPassingTest:^BOOL(UIPress *press, BOOL *stop) {
|
||||
return press.key == nil;
|
||||
}];
|
||||
}
|
||||
|
||||
- (void)pressesBegan:(NSSet<UIPress *> *)presses withEvent:(UIPressesEvent *)event {
|
||||
KeyboardPressesBegan(presses, event);
|
||||
NSSet<UIPress *> *others = NonKeyboardPresses(presses);
|
||||
if (others.count) {
|
||||
[super pressesBegan:others withEvent:event];
|
||||
}
|
||||
}
|
||||
|
||||
- (void)pressesEnded:(NSSet<UIPress *> *)presses withEvent:(UIPressesEvent *)event {
|
||||
KeyboardPressesEnded(presses, event);
|
||||
NSSet<UIPress *> *others = NonKeyboardPresses(presses);
|
||||
if (others.count) {
|
||||
[super pressesEnded:others withEvent:event];
|
||||
}
|
||||
}
|
||||
|
||||
- (void)pressesCancelled:(NSSet<UIPress *> *)presses withEvent:(UIPressesEvent *)event {
|
||||
KeyboardPressesEnded(presses, event);
|
||||
NSSet<UIPress *> *others = NonKeyboardPresses(presses);
|
||||
if (others.count) {
|
||||
[super pressesCancelled:others withEvent:event];
|
||||
}
|
||||
}
|
||||
|
||||
#pragma mark - Status Bar Control
|
||||
|
||||
@@ -438,6 +438,13 @@ void System_Notify(SystemNotification notification) {
|
||||
}
|
||||
});
|
||||
break;
|
||||
case SystemNotification::TOP_LEVEL_CHANGED:
|
||||
dispatch_async(dispatch_get_main_queue(), ^{
|
||||
if (sharedViewController) {
|
||||
[sharedViewController topLevelChanged];
|
||||
}
|
||||
});
|
||||
break;
|
||||
case SystemNotification::AUDIO_MODE_CHANGED:
|
||||
dispatch_async(dispatch_get_main_queue(), ^{
|
||||
iOSCoreAudioUpdateSession();
|
||||
|
||||
Reference in new issue
Block a user