From bebdac3c71a2ce5db31b65cb88d729f3bf20643c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jesu=CC=81s=20A=2E=20A=CC=81lvarez?= Date: Sun, 31 Mar 2024 14:29:57 +0200 Subject: [PATCH] clean up UIKit watchOS stuff --- .../InterfaceController.m | 65 +++++++++---------- Mini vMac WatchKit Extension/UIKit+Watch.h | 58 +++++++++++++++++ Mini vMac.xcodeproj/project.pbxproj | 2 + Mini vMac/EmulatorProtocol.h | 7 +- Mini vMac/TrackPad.m | 7 +- 5 files changed, 98 insertions(+), 41 deletions(-) diff --git a/Mini vMac WatchKit Extension/InterfaceController.m b/Mini vMac WatchKit Extension/InterfaceController.m index 2f96e5b..27cdd67 100644 --- a/Mini vMac WatchKit Extension/InterfaceController.m +++ b/Mini vMac WatchKit Extension/InterfaceController.m @@ -17,27 +17,10 @@ #import "EmulatorProtocol.h" #import "TrackPad.h" -@interface NSObject (fs_override) -+(id)sharedApplication; --(id)keyWindow; --(id)rootViewController; --(NSArray *)viewControllers; --(id)view; --(NSArray *)subviews; --(id)timeLabel; --(id)layer; --(void)addSubview:(id)subview; --(CGPoint)center; --(NSString*)timeText; --(id)sharedPUICApplication; --(void)_setStatusBarTimeHidden:(BOOL)hidden animated:(BOOL)animated completion:(void (^)(void))completion; --(void)setAffineTransform:(CGAffineTransform)transform; --(void)setContentsScale:(CGFloat)value; --(void)setContentsGravity:(NSString*)gravity; --(void)setMinificationFilter:(NSString*)filter; --(void)addTarget:(nullable id)target action:(SEL)action forControlEvents:(NSUInteger)controlEvents; --(void)setIdleTimerDisabled:(BOOL)disabled; --(BOOL)prefersStatusBarHidden; +@interface NSObject () +@property(nonatomic, copy) NSArray<__kindof UIViewController *> *viewControllers; +- (UIView*)timeLabel; +- (NSString*)timeText; @end @interface InterfaceController () @@ -77,22 +60,24 @@ static NSObject *sharedEmulator = nil; - (void)hideTimeLabel { /* Hack to make the digital time overlay disappear (on watchOS 5) */ - id fullScreenView = [self fullScreenView]; + UIView *fullScreenView = [self fullScreenView]; if ([fullScreenView respondsToSelector:@selector(timeLabel)]) { - [[[fullScreenView timeLabel] layer] setOpacity:0]; + fullScreenView.timeLabel.layer.opacity = 0.0; } /* Hack to make the digital time overlay disappear (on watchOS 7 and 8) */ - Class PUICApplication = NSClassFromString(@"PUICApplication"); - if ([PUICApplication instancesRespondToSelector:@selector(_setStatusBarTimeHidden:animated:completion:)]) { - [[PUICApplication sharedApplication] _setStatusBarTimeHidden:YES animated:NO completion:nil]; + Class clsPUICApplication = NSClassFromString(@"PUICApplication"); + if ([clsPUICApplication instancesRespondToSelector:@selector(_setStatusBarTimeHidden:animated:completion:)]) { + PUICApplication *app = (PUICApplication*)[clsPUICApplication sharedApplication]; + [app _setStatusBarTimeHidden:YES animated:NO completion:nil]; } } - (UIView*)fullScreenView { - id parentView = [[[[[[NSClassFromString(@"UIApplication") sharedApplication] keyWindow] rootViewController] viewControllers] firstObject] view]; - id view = [self findDescendantViewOfClass:NSClassFromString(@"SPFullScreenView") inView:parentView]; // watchOS 5 + UIApplication *app = [NSClassFromString(@"UIApplication") sharedApplication]; + UIView *parentView = app.keyWindow.rootViewController.viewControllers.firstObject.view; + UIView *view = [self findDescendantViewOfClass:NSClassFromString(@"SPFullScreenView") inView:parentView]; // watchOS 5 if (view == nil) { view = [self findDescendantViewOfClass:NSClassFromString(@"SPInterfaceRemoteView") inView:parentView]; // watchOS 6 } @@ -176,15 +161,25 @@ static NSObject *sharedEmulator = nil; } } sharedEmulator.dataPath = documentsPath; - sharedEmulator.screenLayer = fullScreenView.layer; - sharedEmulator.speed = sharedEmulator.initialSpeed; - [sharedEmulator.screenLayer setContentsGravity:@"CAGravityResizeAspectFill"]; - CGFloat scale = [self bestScaleForScreen]; - [sharedEmulator.screenLayer setAffineTransform:CGAffineTransformScale(CGAffineTransformMakeRotation(M_PI_2), scale, scale)]; - [sharedEmulator.screenLayer setMinificationFilter:@"CAFilterTrilinear"]; - TrackPad *trackpad = [[TrackPad alloc] initWithFrame:fullScreenView.bounds]; + // screen + CALayer *screenLayer = [NSClassFromString(@"CALayer") layer]; + [fullScreenView.layer addSublayer:screenLayer]; + screenLayer.frame = fullScreenView.layer.bounds; + sharedEmulator.screenLayer = screenLayer; + sharedEmulator.speed = sharedEmulator.initialSpeed; + [screenLayer setContentsGravity:@"CAGravityResizeAspectFill"]; + CGFloat scale = [self bestScaleForScreen]; + [screenLayer setAffineTransform:CGAffineTransformScale(CGAffineTransformMakeRotation(M_PI_2), scale, scale)]; + [screenLayer setMinificationFilter:@"CAFilterTrilinear"]; + + // trackpad + TrackPad *trackpad = [[TrackPad alloc] initWithFrame:CGRectMake(0, 0, 512, 342)]; [fullScreenView addSubview:trackpad]; + trackpad.center = fullScreenView.center; + [trackpad.layer setAffineTransform:CGAffineTransformScale(CGAffineTransformMakeRotation(M_PI_2), 0.5, 0.5)]; + trackpad.layer.masksToBounds = YES; + fullScreenView.clipsToBounds = NO; [self startRuntimeSession]; } diff --git a/Mini vMac WatchKit Extension/UIKit+Watch.h b/Mini vMac WatchKit Extension/UIKit+Watch.h index 3b37af0..3ab2756 100644 --- a/Mini vMac WatchKit Extension/UIKit+Watch.h +++ b/Mini vMac WatchKit Extension/UIKit+Watch.h @@ -13,6 +13,29 @@ NS_ASSUME_NONNULL_BEGIN +typedef NSString *CALayerContentsFilter; +typedef NSString *CALayerContentsGravity; + +@interface CALayer : NSObject + +@property(strong) id contents; +@property CGRect contentsRect; +@property CGRect contentsCenter; +@property(copy) CALayerContentsFilter minificationFilter; +@property(copy) CALayerContentsGravity contentsGravity; +@property float opacity; +@property BOOL hidden; +@property CGRect bounds; +@property CGRect frame; +@property CGPoint position; +@property CGPoint anchorPoint; +@property BOOL masksToBounds; + ++ (instancetype)layer; +- (void)addSublayer:(CALayer *)layer; +- (void)setAffineTransform:(CGAffineTransform)m; + +@end @interface UIResponder : NSObject @@ -21,8 +44,15 @@ NS_ASSUME_NONNULL_BEGIN @interface UIView : UIResponder @property(nonatomic,getter=isMultipleTouchEnabled) BOOL multipleTouchEnabled; @property(nonatomic) CGRect bounds; +@property(nullable, nonatomic, copy) UIColor *backgroundColor; +@property(nullable, readonly, unsafe_unretained) UIView *superview; +@property(nonatomic, readonly, copy) NSArray<__kindof UIView *> *subviews; +@property(nonatomic, readonly, strong) CALayer *layer; +@property(nonatomic) CGPoint center; +@property(nonatomic) BOOL clipsToBounds; - (instancetype)initWithFrame:(CGRect)frame NS_DESIGNATED_INITIALIZER; +- (void)addSubview:(UIView *)subview; @end @@ -49,6 +79,34 @@ NS_ASSUME_NONNULL_BEGIN @end +@interface UIViewController : UIResponder + +@property(nonatomic, strong) UIView *view; + +-(BOOL)prefersStatusBarHidden; + +@end + +@interface UIWindow : UIView + +@property(nullable, nonatomic,strong) UIViewController *rootViewController; + +@end + +@interface UIApplication : NSObject + +@property(class, nonatomic, readonly) UIApplication *sharedApplication; +@property(nullable, nonatomic,readonly) UIWindow *keyWindow; + +@end + +@interface PUICApplication : UIApplication + ++(instancetype)sharedPUICApplication; +-(void)_setStatusBarTimeHidden:(BOOL)hidden animated:(BOOL)animated completion:(void (^_Nullable)(void))completion; + +@end + NS_ASSUME_NONNULL_END #endif /* UIKit_h */ diff --git a/Mini vMac.xcodeproj/project.pbxproj b/Mini vMac.xcodeproj/project.pbxproj index b1c4fb4..a8701ad 100644 --- a/Mini vMac.xcodeproj/project.pbxproj +++ b/Mini vMac.xcodeproj/project.pbxproj @@ -1950,6 +1950,7 @@ "\"$(SRCROOT)/minivmac/src/\"", "\"$(SRCROOT)/Mini vMac/\"", "\"$(SRCROOT)/Mini vMac/MacPlus4M-WatchOS\"", + "\"$(SRCROOT)/Mini vMac WatchKit Extension\"", ); USE_HEADERMAP = NO; VERSIONING_SYSTEM = "apple-generic"; @@ -2003,6 +2004,7 @@ "\"$(SRCROOT)/minivmac/src/\"", "\"$(SRCROOT)/Mini vMac/\"", "\"$(SRCROOT)/Mini vMac/MacPlus4M-WatchOS\"", + "\"$(SRCROOT)/Mini vMac WatchKit Extension\"", ); USE_HEADERMAP = NO; VERSIONING_SYSTEM = "apple-generic"; diff --git a/Mini vMac/EmulatorProtocol.h b/Mini vMac/EmulatorProtocol.h index 4541afd..a3292f1 100644 --- a/Mini vMac/EmulatorProtocol.h +++ b/Mini vMac/EmulatorProtocol.h @@ -9,13 +9,14 @@ @import Foundation; @import CoreGraphics; #if TARGET_OS_WATCH -#define CALayer NSObject +#import "UIKit+Watch.h" @class InterfaceController; -#define UIViewController InterfaceController +#define RootViewControllerClass InterfaceController @interface NSObject (CALayer) - (void)setContents:(id)contents; @end #else +#define RootViewControllerClass UIViewController @import QuartzCore; #endif @@ -48,7 +49,7 @@ typedef NS_ENUM(NSInteger, EmulatorSpeed) { @property (nonatomic, readonly) NSString *currentApplication; @property (nonatomic, strong) void (^showAlert)(NSString *title, NSString *message); -@property (nonatomic, strong) UIViewController *rootViewController; +@property (nonatomic, strong) RootViewControllerClass *rootViewController; - (void)run; - (void)reset; diff --git a/Mini vMac/TrackPad.m b/Mini vMac/TrackPad.m index 3e19e9d..bcafe44 100644 --- a/Mini vMac/TrackPad.m +++ b/Mini vMac/TrackPad.m @@ -10,10 +10,11 @@ #if TARGET_OS_WATCH #import "InterfaceController.h" #define AppDelegate InterfaceController -#define AudioServicesPlaySystemSound +#define PlayHapticFeedback #else #import "AppDelegate.h" @import AudioToolbox; +#define PlayHapticFeedback AudioServicesPlaySystemSound(1519) #endif #define TRACKPAD_ACCEL_N 1 @@ -121,7 +122,7 @@ if (currentTouches.count > 0) { return; } else if (didForceClick) { - AudioServicesPlaySystemSound(1519); + PlayHapticFeedback; didForceClick = NO; [self cancelScheduledClick]; [self mouseUp]; @@ -163,7 +164,7 @@ - (void)handleForceClick:(UITouch *)touch { if (touch.force > 3.0 && !didForceClick) { - AudioServicesPlaySystemSound(1519); + PlayHapticFeedback; didForceClick = YES; [self startDragging]; }