From 760369174d1ab6b21dd263d4fe9ebbeccc5ae204 Mon Sep 17 00:00:00 2001 From: CoyAce Date: Tue, 10 Mar 2026 16:42:09 +0800 Subject: [PATCH] app: [iOS] fix focus event for iOS 13.0+ with backward compatibility UIScene notifications are the correct way to track window focus on iOS 13.0+, because the Key Window API is scene-level on iOS 13.0+, but we need to maintain support for iOS 12 and earlier. Implementation strategy: - iOS 13.0+: Use UIScene notifications (DidActivate/WillDeactivate) - iOS 12 and earlier: Keep existing UIWindow notifications as fallback - Add runtime version checks to select the appropriate API Key changes in os_ios.m: - Add @available(iOS 13.0, *) checks - Register both notification types with conditional logic - Ensure proper cleanup of observers when moving between windows See: https://developer.apple.com/documentation/uikit/uiscene?language=objc Fixes: https://lists.sr.ht/~eliasnaur/gio/%3CCAMAFT9Uyh_JWrkQQt+AmekJWFBqhZPsP_3ZxC1fUNB+=VGGorw@mail.gmail.com%3E Signed-off-by: CoyAce Signed-off-by: Elias Naur --- app/os.go | 2 +- app/os_ios.m | 58 ++++++++++++++++++++++++++++++++++++++++++---------- 2 files changed, 48 insertions(+), 12 deletions(-) diff --git a/app/os.go b/app/os.go index d35e6de7..6da6d34b 100644 --- a/app/os.go +++ b/app/os.go @@ -47,7 +47,7 @@ type Config struct { Decorated bool // TopMost windows render above all other non-top-most windows. TopMost bool - // Focused reports whether has the keyboard focus. + // Focused reports whether the window is focused. Focused bool // decoHeight is the height of the fallback decoration for platforms such // as Wayland that may need fallback client-side decorations. diff --git a/app/os_ios.m b/app/os_ios.m index 26ae7301..c9555cfd 100644 --- a/app/os_ios.m +++ b/app/os_ios.m @@ -134,23 +134,59 @@ NSArray *_keyCommands; return gio_layerClass(); } - (void)willMoveToWindow:(UIWindow *)newWindow { + self.contentScaleFactor = newWindow.screen.nativeScale; + if (@available(iOS 13.0, *)) { + [self registerSceneNotifications:newWindow]; + }else{ + [self registerWindowNotifications:newWindow]; + } +} + +- (void)registerSceneNotifications:(UIWindow *)newWindow { + if (self.window != nil) { + [[NSNotificationCenter defaultCenter] removeObserver:self + name:UISceneDidActivateNotification + object:self.window.windowScene]; + [[NSNotificationCenter defaultCenter] removeObserver:self + name:UISceneWillDeactivateNotification + object:self.window.windowScene]; + } + [[NSNotificationCenter defaultCenter] addObserver:self + selector:@selector(onSceneDidActivate:) + name:UISceneDidActivateNotification + object:newWindow.windowScene]; + + [[NSNotificationCenter defaultCenter] addObserver:self + selector:@selector(onSceneWillDeactivate:) + name:UISceneWillDeactivateNotification + object:newWindow.windowScene]; +} + +- (void)onSceneDidActivate:(NSNotification *)note API_AVAILABLE(ios(13.0)){ + onFocus(self.handle, YES); +} + +- (void)onSceneWillDeactivate:(NSNotification *)note API_AVAILABLE(ios(13.0)){ + onFocus(self.handle, NO); +} + +- (void)registerWindowNotifications:(UIWindow *)newWindow { if (self.window != nil) { [[NSNotificationCenter defaultCenter] removeObserver:self - name:UIWindowDidBecomeKeyNotification - object:self.window]; + name:UIWindowDidBecomeKeyNotification + object:self.window]; [[NSNotificationCenter defaultCenter] removeObserver:self - name:UIWindowDidResignKeyNotification - object:self.window]; + name:UIWindowDidResignKeyNotification + object:self.window]; } - self.contentScaleFactor = newWindow.screen.nativeScale; [[NSNotificationCenter defaultCenter] addObserver:self - selector:@selector(onWindowDidBecomeKey:) - name:UIWindowDidBecomeKeyNotification - object:newWindow]; + selector:@selector(onWindowDidBecomeKey:) + name:UIWindowDidBecomeKeyNotification + object:newWindow]; [[NSNotificationCenter defaultCenter] addObserver:self - selector:@selector(onWindowDidResignKey:) - name:UIWindowDidResignKeyNotification - object:newWindow]; + selector:@selector(onWindowDidResignKey:) + name:UIWindowDidResignKeyNotification + object:newWindow]; } - (void)onWindowDidBecomeKey:(NSNotification *)note {