diff --git a/Mini vMac.xcodeproj/project.pbxproj b/Mini vMac.xcodeproj/project.pbxproj index d0b0be1..d21034a 100644 --- a/Mini vMac.xcodeproj/project.pbxproj +++ b/Mini vMac.xcodeproj/project.pbxproj @@ -58,6 +58,9 @@ 28C67BE92AC49E46000C7540 /* Icon@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = 283423EE1CFA329C0088B634 /* Icon@3x.png */; }; 28C67BF62AC49FA1000C7540 /* MacII-512x384.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 28C67BEE2AC49E46000C7540 /* MacII-512x384.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; 28CE8ED61CD4F56C00FE25A8 /* ScreenView.m in Sources */ = {isa = PBXBuildFile; fileRef = 28CE8ED51CD4F56C00FE25A8 /* ScreenView.m */; }; + 28D3C6152B7681420079E915 /* VisionSupport.swift in Sources */ = {isa = PBXBuildFile; fileRef = 28D3C6142B7681420079E915 /* VisionSupport.swift */; }; + 28D3C6172B76B8970079E915 /* DefaultSceneDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 28D3C6162B76B8970079E915 /* DefaultSceneDelegate.swift */; }; + 28D3C61B2B7781700079E915 /* KeyboardSceneDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 28D3C61A2B7781700079E915 /* KeyboardSceneDelegate.swift */; }; 28D5A3FD1CD6868F001A33F6 /* TouchScreen.m in Sources */ = {isa = PBXBuildFile; fileRef = 28D5A3FC1CD6868E001A33F6 /* TouchScreen.m */; }; 28E3B7DF251D0F13007C273F /* MOUSEMDV.c in Sources */ = {isa = PBXBuildFile; fileRef = 28E3B7CC251D0F12007C273F /* MOUSEMDV.c */; }; 28E3B7E0251D0F13007C273F /* MOUSEMDV.c in Sources */ = {isa = PBXBuildFile; fileRef = 28E3B7CC251D0F12007C273F /* MOUSEMDV.c */; }; @@ -282,6 +285,10 @@ 28CE8ECB1CD4CDC500FE25A8 /* MYOSGLUE.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MYOSGLUE.m; sourceTree = ""; }; 28CE8ED41CD4F56C00FE25A8 /* ScreenView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ScreenView.h; sourceTree = ""; }; 28CE8ED51CD4F56C00FE25A8 /* ScreenView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ScreenView.m; sourceTree = ""; }; + 28D3C6132B7681420079E915 /* Mini vMac-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "Mini vMac-Bridging-Header.h"; sourceTree = ""; }; + 28D3C6142B7681420079E915 /* VisionSupport.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VisionSupport.swift; sourceTree = ""; }; + 28D3C6162B76B8970079E915 /* DefaultSceneDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DefaultSceneDelegate.swift; sourceTree = ""; }; + 28D3C61A2B7781700079E915 /* KeyboardSceneDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = KeyboardSceneDelegate.swift; sourceTree = ""; }; 28D5A3FB1CD6868E001A33F6 /* TouchScreen.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TouchScreen.h; sourceTree = ""; }; 28D5A3FC1CD6868E001A33F6 /* TouchScreen.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TouchScreen.m; sourceTree = ""; }; 28E3B7CC251D0F12007C273F /* MOUSEMDV.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = MOUSEMDV.c; sourceTree = ""; }; @@ -611,6 +618,7 @@ 28BA89841CE73E7200A98104 /* TrackPad.m */, 28F676C61CD15E0B00FC6FA6 /* ViewController.h */, 28F676C71CD15E0B00FC6FA6 /* ViewController.m */, + 28D3C6142B7681420079E915 /* VisionSupport.swift */, 28848B601CDE97D600B86C45 /* InsertDiskViewController.h */, 28848B611CDE97D600B86C45 /* InsertDiskViewController.m */, 28848B631CDE97E900B86C45 /* SettingsViewController.h */, @@ -627,6 +635,8 @@ 28F6B4CE1CF77099002D76D0 /* compat.m */, 283CA9821DF47AF300B33D5E /* BTCMouse.h */, 283422EF1CF8F33A0088B634 /* Emulator Bundles */, + 28D3C6162B76B8970079E915 /* DefaultSceneDelegate.swift */, + 28D3C61A2B7781700079E915 /* KeyboardSceneDelegate.swift */, ); path = "Mini vMac"; sourceTree = ""; @@ -634,6 +644,7 @@ 28F676C01CD15E0B00FC6FA6 /* Supporting Files */ = { isa = PBXGroup; children = ( + 28D3C6132B7681420079E915 /* Mini vMac-Bridging-Header.h */, 28F6B4551CF07C9A002D76D0 /* libhfs */, 28F6B4541CF07C8D002D76D0 /* libmfs */, 28F6B4531CF07C83002D76D0 /* libres */, @@ -950,6 +961,7 @@ 28F676BC1CD15E0B00FC6FA6 = { CreatedOnToolsVersion = 7.3; DevelopmentTeam = UJXNDZ5TNU; + LastSwiftMigration = 1520; }; 28F6B48D1CF07DDD002D76D0 = { CreatedOnToolsVersion = 7.3.1; @@ -1287,14 +1299,17 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( + 28D3C6152B7681420079E915 /* VisionSupport.swift in Sources */, 28BA897E1CE7315400A98104 /* KBKey.m in Sources */, 28BA89851CE73E7200A98104 /* TrackPad.m in Sources */, + 28D3C6172B76B8970079E915 /* DefaultSceneDelegate.swift in Sources */, 28CE8ED61CD4F56C00FE25A8 /* ScreenView.m in Sources */, 28848B651CDE97E900B86C45 /* SettingsViewController.m in Sources */, 28BA89881CE73FBC00A98104 /* MNVMApplication.m in Sources */, 28F6B4CF1CF77099002D76D0 /* compat.m in Sources */, 28F6B4521CF07C48002D76D0 /* UIImage+DiskImageIcon.m in Sources */, 28BA897F1CE7315400A98104 /* KBKeyboardLayout.m in Sources */, + 28D3C61B2B7781700079E915 /* KeyboardSceneDelegate.swift in Sources */, 28848B621CDE97D600B86C45 /* InsertDiskViewController.m in Sources */, 28F676C81CD15E0B00FC6FA6 /* ViewController.m in Sources */, 28D5A3FD1CD6868F001A33F6 /* TouchScreen.m in Sources */, @@ -1902,6 +1917,7 @@ isa = XCBuildConfiguration; buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CLANG_ENABLE_MODULES = YES; CODE_SIGN_IDENTITY = "iPhone Developer"; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; CURRENT_PROJECT_VERSION = 14; @@ -1921,6 +1937,9 @@ SUPPORTED_PLATFORMS = "iphoneos iphonesimulator xros xrsimulator"; SUPPORTS_MACCATALYST = NO; SUPPORTS_XR_DESIGNED_FOR_IPHONE_IPAD = NO; + SWIFT_OBJC_BRIDGING_HEADER = "Mini vMac/Mini vMac-Bridging-Header.h"; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + SWIFT_VERSION = 5.0; TARGETED_DEVICE_FAMILY = "1,2,7"; }; name = Debug; @@ -1929,6 +1948,7 @@ isa = XCBuildConfiguration; buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CLANG_ENABLE_MODULES = YES; CODE_SIGN_IDENTITY = "iPhone Developer"; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; CURRENT_PROJECT_VERSION = 14; @@ -1948,6 +1968,8 @@ SUPPORTED_PLATFORMS = "iphoneos iphonesimulator xros xrsimulator"; SUPPORTS_MACCATALYST = NO; SUPPORTS_XR_DESIGNED_FOR_IPHONE_IPAD = NO; + SWIFT_OBJC_BRIDGING_HEADER = "Mini vMac/Mini vMac-Bridging-Header.h"; + SWIFT_VERSION = 5.0; TARGETED_DEVICE_FAMILY = "1,2,7"; }; name = Release; diff --git a/Mini vMac.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/Mini vMac.xcodeproj/project.xcworkspace/contents.xcworkspacedata new file mode 100644 index 0000000..33dea32 --- /dev/null +++ b/Mini vMac.xcodeproj/project.xcworkspace/contents.xcworkspacedata @@ -0,0 +1,7 @@ + + + + + diff --git a/Mini vMac.xcodeproj/project.xcworkspace/xcshareddata/Mini vMac.xcscmblueprint b/Mini vMac.xcodeproj/project.xcworkspace/xcshareddata/Mini vMac.xcscmblueprint new file mode 100644 index 0000000..3dde625 --- /dev/null +++ b/Mini vMac.xcodeproj/project.xcworkspace/xcshareddata/Mini vMac.xcscmblueprint @@ -0,0 +1,37 @@ +{ + "DVTSourceControlWorkspaceBlueprintPrimaryRemoteRepositoryKey" : "9C19786155D97B8ED78AB84AFAAA50249126341A", + "DVTSourceControlWorkspaceBlueprintWorkingCopyRepositoryLocationsKey" : { + + }, + "DVTSourceControlWorkspaceBlueprintWorkingCopyStatesKey" : { + "9C19786155D97B8ED78AB84AFAAA50249126341A" : 0, + "F2E8D120DACD6BF5E1EFFA012C92CE6FA0E44B4C" : 0, + "45D35ABA2A883CFEB6F6014CF9723CDA568B602B" : 0 + }, + "DVTSourceControlWorkspaceBlueprintIdentifierKey" : "A273011D-9F4F-4F93-8287-77CF2E175709", + "DVTSourceControlWorkspaceBlueprintWorkingCopyPathsKey" : { + "9C19786155D97B8ED78AB84AFAAA50249126341A" : "minivmac4ios\/", + "F2E8D120DACD6BF5E1EFFA012C92CE6FA0E44B4C" : "minivmac4ios\/libres\/", + "45D35ABA2A883CFEB6F6014CF9723CDA568B602B" : "minivmac4ios\/libmfs\/" + }, + "DVTSourceControlWorkspaceBlueprintNameKey" : "Mini vMac", + "DVTSourceControlWorkspaceBlueprintVersion" : 204, + "DVTSourceControlWorkspaceBlueprintRelativePathToProjectKey" : "Mini vMac.xcodeproj", + "DVTSourceControlWorkspaceBlueprintRemoteRepositoriesKey" : [ + { + "DVTSourceControlWorkspaceBlueprintRemoteRepositoryURLKey" : "https:\/\/github.com\/zydeco\/libmfs.git", + "DVTSourceControlWorkspaceBlueprintRemoteRepositorySystemKey" : "com.apple.dt.Xcode.sourcecontrol.Git", + "DVTSourceControlWorkspaceBlueprintRemoteRepositoryIdentifierKey" : "45D35ABA2A883CFEB6F6014CF9723CDA568B602B" + }, + { + "DVTSourceControlWorkspaceBlueprintRemoteRepositoryURLKey" : "github.com:zydeco\/minivmac4ios.git", + "DVTSourceControlWorkspaceBlueprintRemoteRepositorySystemKey" : "com.apple.dt.Xcode.sourcecontrol.Git", + "DVTSourceControlWorkspaceBlueprintRemoteRepositoryIdentifierKey" : "9C19786155D97B8ED78AB84AFAAA50249126341A" + }, + { + "DVTSourceControlWorkspaceBlueprintRemoteRepositoryURLKey" : "https:\/\/github.com\/zydeco\/libres.git", + "DVTSourceControlWorkspaceBlueprintRemoteRepositorySystemKey" : "com.apple.dt.Xcode.sourcecontrol.Git", + "DVTSourceControlWorkspaceBlueprintRemoteRepositoryIdentifierKey" : "F2E8D120DACD6BF5E1EFFA012C92CE6FA0E44B4C" + } + ] +} \ No newline at end of file diff --git a/Mini vMac/AppDelegate.m b/Mini vMac/AppDelegate.m index 378a72a..317d054 100644 --- a/Mini vMac/AppDelegate.m +++ b/Mini vMac/AppDelegate.m @@ -10,6 +10,7 @@ #import "AppDelegate.h" #import "SettingsViewController.h" #import "InsertDiskViewController.h" +#import "ViewController.h" static AppDelegate *sharedAppDelegate = nil; static NSObject *sharedEmulator = nil; @@ -106,6 +107,9 @@ NSString *DocumentsChangedNotification = @"documentsChanged"; [self showAlertWithTitle:title message:message]; }; sharedEmulator.dataPath = self.documentsPath; +#if defined(TARGET_OS_VISION) && TARGET_OS_VISION == 1 + [ViewController adjustToScreenSize]; +#endif return sharedEmulator != nil; } @@ -311,4 +315,36 @@ NSString *DocumentsChangedNotification = @"documentsChanged"; return YES; } +#pragma mark - Making a Scene + +- (UISceneConfiguration *)application:(UIApplication *)application configurationForConnectingSceneSession:(UISceneSession *)connectingSceneSession options:(UISceneConnectionOptions *)options { + for (NSUserActivity *activity in options.userActivities) { + if ([activity.activityType isEqualToString:@"net.namedfork.keyboard"]) { + return [UISceneConfiguration configurationWithName:@"Keyboard" sessionRole:UIWindowSceneSessionRoleApplication]; + } + } + if (![self hasDefaultScene]) { + return [UISceneConfiguration configurationWithName:@"Default" sessionRole:UIWindowSceneSessionRoleApplication]; + } + return nil; +} + + +- (void)application:(UIApplication *)application didDiscardSceneSessions:(NSSet *)sceneSessions { + // if only keyboard is left, show default view again + if (![self hasDefaultScene]) { + UISceneSessionActivationRequest *request = [UISceneSessionActivationRequest requestWithRole:UIWindowSceneSessionRoleApplication]; + [application activateSceneSessionForRequest:request errorHandler:nil]; + } +} + +- (BOOL)hasDefaultScene { + for (UIScene *scene in [UIApplication sharedApplication].connectedScenes) { + if ([scene.session.configuration.name isEqualToString:@"Default"]) { + return YES; + } + } + return NO; +} + @end diff --git a/Mini vMac/Assets.xcassets/KBCapsLock.imageset/Contents.json b/Mini vMac/Assets.xcassets/KBCapsLock.imageset/Contents.json index 68dd648..a3d53fe 100644 --- a/Mini vMac/Assets.xcassets/KBCapsLock.imageset/Contents.json +++ b/Mini vMac/Assets.xcassets/KBCapsLock.imageset/Contents.json @@ -23,6 +23,11 @@ "filename" : "KBCapsLock~ipad@2x.png", "idiom" : "ipad", "scale" : "2x" + }, + { + "filename" : "KBCapsLock~ipad@2x 1.png", + "idiom" : "vision", + "scale" : "2x" } ], "info" : { diff --git a/Mini vMac/Assets.xcassets/KBCapsLock.imageset/KBCapsLock~ipad@2x 1.png b/Mini vMac/Assets.xcassets/KBCapsLock.imageset/KBCapsLock~ipad@2x 1.png new file mode 100644 index 0000000..1032731 Binary files /dev/null and b/Mini vMac/Assets.xcassets/KBCapsLock.imageset/KBCapsLock~ipad@2x 1.png differ diff --git a/Mini vMac/Assets.xcassets/KBClearDown.imageset/Contents.json b/Mini vMac/Assets.xcassets/KBClearDown.imageset/Contents.json index b6f380c..0cb3e83 100644 --- a/Mini vMac/Assets.xcassets/KBClearDown.imageset/Contents.json +++ b/Mini vMac/Assets.xcassets/KBClearDown.imageset/Contents.json @@ -23,6 +23,11 @@ "filename" : "KBClearDown~ipad@2x.png", "idiom" : "ipad", "scale" : "2x" + }, + { + "filename" : "KBClearDown~ipad@2x 1.png", + "idiom" : "vision", + "scale" : "2x" } ], "info" : { diff --git a/Mini vMac/Assets.xcassets/KBClearDown.imageset/KBClearDown~ipad@2x 1.png b/Mini vMac/Assets.xcassets/KBClearDown.imageset/KBClearDown~ipad@2x 1.png new file mode 100644 index 0000000..d35aecb Binary files /dev/null and b/Mini vMac/Assets.xcassets/KBClearDown.imageset/KBClearDown~ipad@2x 1.png differ diff --git a/Mini vMac/Assets.xcassets/KBClearUp.imageset/Contents.json b/Mini vMac/Assets.xcassets/KBClearUp.imageset/Contents.json index 8143eda..4315226 100644 --- a/Mini vMac/Assets.xcassets/KBClearUp.imageset/Contents.json +++ b/Mini vMac/Assets.xcassets/KBClearUp.imageset/Contents.json @@ -23,6 +23,11 @@ "filename" : "KBClearUp~ipad@2x.png", "idiom" : "ipad", "scale" : "2x" + }, + { + "filename" : "KBClearUp~ipad@2x 1.png", + "idiom" : "vision", + "scale" : "2x" } ], "info" : { diff --git a/Mini vMac/Assets.xcassets/KBClearUp.imageset/KBClearUp~ipad@2x 1.png b/Mini vMac/Assets.xcassets/KBClearUp.imageset/KBClearUp~ipad@2x 1.png new file mode 100644 index 0000000..0ae8d68 Binary files /dev/null and b/Mini vMac/Assets.xcassets/KBClearUp.imageset/KBClearUp~ipad@2x 1.png differ diff --git a/Mini vMac/Assets.xcassets/KBCommand.imageset/Contents.json b/Mini vMac/Assets.xcassets/KBCommand.imageset/Contents.json index 94564ff..839fff1 100644 --- a/Mini vMac/Assets.xcassets/KBCommand.imageset/Contents.json +++ b/Mini vMac/Assets.xcassets/KBCommand.imageset/Contents.json @@ -23,6 +23,11 @@ "filename" : "KBCommand@2x~ipad.png", "idiom" : "ipad", "scale" : "2x" + }, + { + "filename" : "KBCommand@2x~ipad 1.png", + "idiom" : "vision", + "scale" : "2x" } ], "info" : { diff --git a/Mini vMac/Assets.xcassets/KBCommand.imageset/KBCommand@2x~ipad 1.png b/Mini vMac/Assets.xcassets/KBCommand.imageset/KBCommand@2x~ipad 1.png new file mode 100644 index 0000000..629a05f Binary files /dev/null and b/Mini vMac/Assets.xcassets/KBCommand.imageset/KBCommand@2x~ipad 1.png differ diff --git a/Mini vMac/Assets.xcassets/KBDeleteDown.imageset/Contents.json b/Mini vMac/Assets.xcassets/KBDeleteDown.imageset/Contents.json index c22e522..c42613f 100644 --- a/Mini vMac/Assets.xcassets/KBDeleteDown.imageset/Contents.json +++ b/Mini vMac/Assets.xcassets/KBDeleteDown.imageset/Contents.json @@ -23,6 +23,11 @@ "filename" : "KBDeleteDown~ipad@2x.png", "idiom" : "ipad", "scale" : "2x" + }, + { + "filename" : "KBDeleteDown~ipad@2x 1.png", + "idiom" : "vision", + "scale" : "2x" } ], "info" : { diff --git a/Mini vMac/Assets.xcassets/KBDeleteDown.imageset/KBDeleteDown~ipad@2x 1.png b/Mini vMac/Assets.xcassets/KBDeleteDown.imageset/KBDeleteDown~ipad@2x 1.png new file mode 100644 index 0000000..4ee72f6 Binary files /dev/null and b/Mini vMac/Assets.xcassets/KBDeleteDown.imageset/KBDeleteDown~ipad@2x 1.png differ diff --git a/Mini vMac/Assets.xcassets/KBDeleteUp.imageset/Contents.json b/Mini vMac/Assets.xcassets/KBDeleteUp.imageset/Contents.json index e46a6d3..83412c4 100644 --- a/Mini vMac/Assets.xcassets/KBDeleteUp.imageset/Contents.json +++ b/Mini vMac/Assets.xcassets/KBDeleteUp.imageset/Contents.json @@ -23,6 +23,11 @@ "filename" : "KBDeleteUp~ipad@2x.png", "idiom" : "ipad", "scale" : "2x" + }, + { + "filename" : "KBDeleteUp~ipad@2x 1.png", + "idiom" : "vision", + "scale" : "2x" } ], "info" : { diff --git a/Mini vMac/Assets.xcassets/KBDeleteUp.imageset/KBDeleteUp~ipad@2x 1.png b/Mini vMac/Assets.xcassets/KBDeleteUp.imageset/KBDeleteUp~ipad@2x 1.png new file mode 100644 index 0000000..ab4c7ef Binary files /dev/null and b/Mini vMac/Assets.xcassets/KBDeleteUp.imageset/KBDeleteUp~ipad@2x 1.png differ diff --git a/Mini vMac/Assets.xcassets/KBForwardDeleteDown.imageset/Contents.json b/Mini vMac/Assets.xcassets/KBForwardDeleteDown.imageset/Contents.json index 50d4167..bb246b4 100644 --- a/Mini vMac/Assets.xcassets/KBForwardDeleteDown.imageset/Contents.json +++ b/Mini vMac/Assets.xcassets/KBForwardDeleteDown.imageset/Contents.json @@ -23,6 +23,11 @@ "filename" : "KBForwardDeleteDown~ipad@2x.png", "idiom" : "ipad", "scale" : "2x" + }, + { + "filename" : "KBForwardDeleteDown~ipad@2x 1.png", + "idiom" : "vision", + "scale" : "2x" } ], "info" : { diff --git a/Mini vMac/Assets.xcassets/KBForwardDeleteDown.imageset/KBForwardDeleteDown~ipad@2x 1.png b/Mini vMac/Assets.xcassets/KBForwardDeleteDown.imageset/KBForwardDeleteDown~ipad@2x 1.png new file mode 100644 index 0000000..b3de016 Binary files /dev/null and b/Mini vMac/Assets.xcassets/KBForwardDeleteDown.imageset/KBForwardDeleteDown~ipad@2x 1.png differ diff --git a/Mini vMac/Assets.xcassets/KBForwardDeleteUp.imageset/Contents.json b/Mini vMac/Assets.xcassets/KBForwardDeleteUp.imageset/Contents.json index f9eb364..702e5be 100644 --- a/Mini vMac/Assets.xcassets/KBForwardDeleteUp.imageset/Contents.json +++ b/Mini vMac/Assets.xcassets/KBForwardDeleteUp.imageset/Contents.json @@ -23,6 +23,11 @@ "filename" : "KBForwardDeleteUp~ipad@2x.png", "idiom" : "ipad", "scale" : "2x" + }, + { + "filename" : "KBForwardDeleteUp~ipad@2x 1.png", + "idiom" : "vision", + "scale" : "2x" } ], "info" : { diff --git a/Mini vMac/Assets.xcassets/KBForwardDeleteUp.imageset/KBForwardDeleteUp~ipad@2x 1.png b/Mini vMac/Assets.xcassets/KBForwardDeleteUp.imageset/KBForwardDeleteUp~ipad@2x 1.png new file mode 100644 index 0000000..26644fd Binary files /dev/null and b/Mini vMac/Assets.xcassets/KBForwardDeleteUp.imageset/KBForwardDeleteUp~ipad@2x 1.png differ diff --git a/Mini vMac/Assets.xcassets/KBHide.imageset/Contents.json b/Mini vMac/Assets.xcassets/KBHide.imageset/Contents.json index f01cb0e..7838a85 100644 --- a/Mini vMac/Assets.xcassets/KBHide.imageset/Contents.json +++ b/Mini vMac/Assets.xcassets/KBHide.imageset/Contents.json @@ -1,6 +1,7 @@ { "images" : [ { + "filename" : "KBHide~ipad 2.png", "idiom" : "iphone", "scale" : "1x" }, @@ -23,6 +24,11 @@ "filename" : "KBHide~ipad@2x.png", "idiom" : "ipad", "scale" : "2x" + }, + { + "filename" : "KBHide~ipad@2x 1.png", + "idiom" : "vision", + "scale" : "2x" } ], "info" : { diff --git a/Mini vMac/Assets.xcassets/KBHide.imageset/KBHide~ipad 2.png b/Mini vMac/Assets.xcassets/KBHide.imageset/KBHide~ipad 2.png new file mode 100644 index 0000000..2c28bb8 Binary files /dev/null and b/Mini vMac/Assets.xcassets/KBHide.imageset/KBHide~ipad 2.png differ diff --git a/Mini vMac/Assets.xcassets/KBHide.imageset/KBHide~ipad@2x 1.png b/Mini vMac/Assets.xcassets/KBHide.imageset/KBHide~ipad@2x 1.png new file mode 100644 index 0000000..faa6196 Binary files /dev/null and b/Mini vMac/Assets.xcassets/KBHide.imageset/KBHide~ipad@2x 1.png differ diff --git a/Mini vMac/Assets.xcassets/KBKey.imageset/Contents.json b/Mini vMac/Assets.xcassets/KBKey.imageset/Contents.json index a77a97f..a82f586 100644 --- a/Mini vMac/Assets.xcassets/KBKey.imageset/Contents.json +++ b/Mini vMac/Assets.xcassets/KBKey.imageset/Contents.json @@ -219,6 +219,25 @@ "mode" : "9-part" }, "scale" : "2x" + }, + { + "filename" : "KBKey@2x~ipad-2 1.png", + "idiom" : "vision", + "resizing" : { + "cap-insets" : { + "bottom" : 32, + "left" : 32, + "right" : 32, + "top" : 32 + }, + "center" : { + "height" : 2, + "mode" : "tile", + "width" : 2 + }, + "mode" : "9-part" + }, + "scale" : "2x" } ], "info" : { diff --git a/Mini vMac/Assets.xcassets/KBKey.imageset/KBKey@2x~ipad-2 1.png b/Mini vMac/Assets.xcassets/KBKey.imageset/KBKey@2x~ipad-2 1.png new file mode 100644 index 0000000..89ef4d1 Binary files /dev/null and b/Mini vMac/Assets.xcassets/KBKey.imageset/KBKey@2x~ipad-2 1.png differ diff --git a/Mini vMac/Assets.xcassets/KBKeyDark.imageset/Contents.json b/Mini vMac/Assets.xcassets/KBKeyDark.imageset/Contents.json index 975f84b..d8cdc7c 100644 --- a/Mini vMac/Assets.xcassets/KBKeyDark.imageset/Contents.json +++ b/Mini vMac/Assets.xcassets/KBKeyDark.imageset/Contents.json @@ -219,6 +219,25 @@ "mode" : "9-part" }, "scale" : "2x" + }, + { + "filename" : "KBKeyDark@2x~ipad-1 1.png", + "idiom" : "vision", + "resizing" : { + "cap-insets" : { + "bottom" : 32, + "left" : 32, + "right" : 32, + "top" : 32 + }, + "center" : { + "height" : 2, + "mode" : "tile", + "width" : 2 + }, + "mode" : "9-part" + }, + "scale" : "2x" } ], "info" : { diff --git a/Mini vMac/Assets.xcassets/KBKeyDark.imageset/KBKeyDark@2x~ipad-1 1.png b/Mini vMac/Assets.xcassets/KBKeyDark.imageset/KBKeyDark@2x~ipad-1 1.png new file mode 100644 index 0000000..ea0372a Binary files /dev/null and b/Mini vMac/Assets.xcassets/KBKeyDark.imageset/KBKeyDark@2x~ipad-1 1.png differ diff --git a/Mini vMac/Assets.xcassets/KBNumPad.imageset/Contents.json b/Mini vMac/Assets.xcassets/KBNumPad.imageset/Contents.json index ddc90b7..564f943 100644 --- a/Mini vMac/Assets.xcassets/KBNumPad.imageset/Contents.json +++ b/Mini vMac/Assets.xcassets/KBNumPad.imageset/Contents.json @@ -23,6 +23,11 @@ "filename" : "KBNumPad@2x~ipad.png", "idiom" : "ipad", "scale" : "2x" + }, + { + "filename" : "KBNumPad@2x~ipad 1.png", + "idiom" : "vision", + "scale" : "2x" } ], "info" : { diff --git a/Mini vMac/Assets.xcassets/KBNumPad.imageset/KBNumPad@2x~ipad 1.png b/Mini vMac/Assets.xcassets/KBNumPad.imageset/KBNumPad@2x~ipad 1.png new file mode 100644 index 0000000..332186c Binary files /dev/null and b/Mini vMac/Assets.xcassets/KBNumPad.imageset/KBNumPad@2x~ipad 1.png differ diff --git a/Mini vMac/Assets.xcassets/KBOption.imageset/Contents.json b/Mini vMac/Assets.xcassets/KBOption.imageset/Contents.json index bfe4b76..b6885b1 100644 --- a/Mini vMac/Assets.xcassets/KBOption.imageset/Contents.json +++ b/Mini vMac/Assets.xcassets/KBOption.imageset/Contents.json @@ -23,6 +23,11 @@ "filename" : "KBOption@2x~ipad.png", "idiom" : "ipad", "scale" : "2x" + }, + { + "filename" : "KBOption@2x~ipad 1.png", + "idiom" : "vision", + "scale" : "2x" } ], "info" : { diff --git a/Mini vMac/Assets.xcassets/KBOption.imageset/KBOption@2x~ipad 1.png b/Mini vMac/Assets.xcassets/KBOption.imageset/KBOption@2x~ipad 1.png new file mode 100644 index 0000000..3bc0e82 Binary files /dev/null and b/Mini vMac/Assets.xcassets/KBOption.imageset/KBOption@2x~ipad 1.png differ diff --git a/Mini vMac/Assets.xcassets/KBShiftDown.imageset/Contents.json b/Mini vMac/Assets.xcassets/KBShiftDown.imageset/Contents.json index e6d47eb..c309287 100644 --- a/Mini vMac/Assets.xcassets/KBShiftDown.imageset/Contents.json +++ b/Mini vMac/Assets.xcassets/KBShiftDown.imageset/Contents.json @@ -23,6 +23,11 @@ "filename" : "KBShiftDown~ipad@2x.png", "idiom" : "ipad", "scale" : "2x" + }, + { + "filename" : "KBShiftDown~ipad@2x 1.png", + "idiom" : "vision", + "scale" : "2x" } ], "info" : { diff --git a/Mini vMac/Assets.xcassets/KBShiftDown.imageset/KBShiftDown~ipad@2x 1.png b/Mini vMac/Assets.xcassets/KBShiftDown.imageset/KBShiftDown~ipad@2x 1.png new file mode 100644 index 0000000..7f5a483 Binary files /dev/null and b/Mini vMac/Assets.xcassets/KBShiftDown.imageset/KBShiftDown~ipad@2x 1.png differ diff --git a/Mini vMac/Assets.xcassets/KBShiftUp.imageset/Contents.json b/Mini vMac/Assets.xcassets/KBShiftUp.imageset/Contents.json index 6a811f9..09f9e53 100644 --- a/Mini vMac/Assets.xcassets/KBShiftUp.imageset/Contents.json +++ b/Mini vMac/Assets.xcassets/KBShiftUp.imageset/Contents.json @@ -23,6 +23,11 @@ "filename" : "KBShiftUp~ipad@2x.png", "idiom" : "ipad", "scale" : "2x" + }, + { + "filename" : "KBShiftUp~ipad@2x 1.png", + "idiom" : "vision", + "scale" : "2x" } ], "info" : { diff --git a/Mini vMac/Assets.xcassets/KBShiftUp.imageset/KBShiftUp~ipad@2x 1.png b/Mini vMac/Assets.xcassets/KBShiftUp.imageset/KBShiftUp~ipad@2x 1.png new file mode 100644 index 0000000..8ee7923 Binary files /dev/null and b/Mini vMac/Assets.xcassets/KBShiftUp.imageset/KBShiftUp~ipad@2x 1.png differ diff --git a/Mini vMac/Assets.xcassets/Reset.imageset/Contents.json b/Mini vMac/Assets.xcassets/Reset.imageset/Contents.json index 9f4d431..12d947f 100644 --- a/Mini vMac/Assets.xcassets/Reset.imageset/Contents.json +++ b/Mini vMac/Assets.xcassets/Reset.imageset/Contents.json @@ -1,23 +1,26 @@ { "images" : [ { - "idiom" : "universal", "filename" : "reset.png", + "idiom" : "universal", "scale" : "1x" }, { - "idiom" : "universal", "filename" : "reset@2x.png", + "idiom" : "universal", "scale" : "2x" }, { - "idiom" : "universal", "filename" : "reset@3x.png", + "idiom" : "universal", "scale" : "3x" } ], "info" : { - "version" : 1, - "author" : "xcode" + "author" : "xcode", + "version" : 1 + }, + "properties" : { + "template-rendering-intent" : "template" } -} \ No newline at end of file +} diff --git a/Mini vMac/Assets.xcassets/Settings.imageset/Contents.json b/Mini vMac/Assets.xcassets/Settings.imageset/Contents.json index fad3ac1..83165a8 100644 --- a/Mini vMac/Assets.xcassets/Settings.imageset/Contents.json +++ b/Mini vMac/Assets.xcassets/Settings.imageset/Contents.json @@ -1,23 +1,26 @@ { "images" : [ { - "idiom" : "universal", "filename" : "Settings.png", + "idiom" : "universal", "scale" : "1x" }, { - "idiom" : "universal", "filename" : "Settings@2x.png", + "idiom" : "universal", "scale" : "2x" }, { - "idiom" : "universal", "filename" : "Settings@3x.png", + "idiom" : "universal", "scale" : "3x" } ], "info" : { - "version" : 1, - "author" : "xcode" + "author" : "xcode", + "version" : 1 + }, + "properties" : { + "template-rendering-intent" : "template" } -} \ No newline at end of file +} diff --git a/Mini vMac/DefaultSceneDelegate.swift b/Mini vMac/DefaultSceneDelegate.swift new file mode 100644 index 0000000..62a222c --- /dev/null +++ b/Mini vMac/DefaultSceneDelegate.swift @@ -0,0 +1,35 @@ +// +// DefaultSceneDelegate.swift +// Mini vMac +// +// Created by Jesús A. Álvarez on 2024-02-09. +// Copyright © 2024 namedfork. All rights reserved. +// + +import UIKit + +class DefaultSceneDelegate: UIResponder, UIWindowSceneDelegate { + var window: UIWindow? + + func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) { + guard let windowScene = scene as? UIWindowScene else { + fatalError("Expected scene of type UIWindowScene but got an unexpected type") + } + guard let appDelegate = AppDelegate.sharedInstance() else { + fatalError("No app delegate") + } + + let size = CGSize(width: 1024.0, height: 684.0) + windowScene.sizeRestrictions?.minimumSize = size + windowScene.sizeRestrictions?.maximumSize = size + + window = UIWindow(windowScene: windowScene) + let rootViewController = appDelegate.window?.rootViewController ?? UIStoryboard(name: "Main", bundle: .main).instantiateInitialViewController() + + if let window { + appDelegate.window = window + window.rootViewController = rootViewController + window.makeKeyAndVisible() + } + } +} diff --git a/Mini vMac/Info.plist b/Mini vMac/Info.plist index 12b1105..baeff30 100644 --- a/Mini vMac/Info.plist +++ b/Mini vMac/Info.plist @@ -176,5 +176,28 @@ + UIApplicationSceneManifest + + UIApplicationSupportsMultipleScenes + + UISceneConfigurations + + UIWindowSceneSessionRoleApplication + + + UISceneConfigurationName + Default + UISceneDelegateClassName + $(PRODUCT_MODULE_NAME).DefaultSceneDelegate + + + UISceneConfigurationName + Keyboard + UISceneDelegateClassName + $(PRODUCT_MODULE_NAME).KeyboardSceneDelegate + + + + diff --git a/Mini vMac/KBKeyboardView.m b/Mini vMac/KBKeyboardView.m index 8e21f81..b124bd0 100644 --- a/Mini vMac/KBKeyboardView.m +++ b/Mini vMac/KBKeyboardView.m @@ -126,8 +126,13 @@ keyFrame.origin.x += safeAreaInsets.left; } if (scancode == VKC_HIDE) { +#if defined(TARGET_OS_VISION) && TARGET_OS_VISION == 1 + // close window to hide + return; +#else key = [[KBHideKey alloc] initWithFrame:keyFrame]; [key addTarget:self action:@selector(hideKeyboard:) forControlEvents:UIControlEventTouchUpInside]; +#endif } else if (scancode == VKC_SHIFT_CAPS) { key = [[KBShiftCapsKey alloc] initWithFrame:keyFrame]; key.scancode = KC_SHIFT; diff --git a/Mini vMac/KeyboardSceneDelegate.swift b/Mini vMac/KeyboardSceneDelegate.swift new file mode 100644 index 0000000..b780975 --- /dev/null +++ b/Mini vMac/KeyboardSceneDelegate.swift @@ -0,0 +1,32 @@ +// +// KeyboardSceneDelegate.swift +// Mini vMac +// +// Created by Jesús A. Álvarez on 2024-02-10. +// Copyright © 2024 namedfork. All rights reserved. +// + +import UIKit + +class KeyboardSceneDelegate: UIResponder, UIWindowSceneDelegate { + var window: UIWindow? + + func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) { + guard let windowScene = scene as? UIWindowScene else { + fatalError("Expected scene of type UIWindowScene but got an unexpected type") + } + guard let mainViewController = AppDelegate.sharedInstance().window.rootViewController as? ViewController else { + fatalError("No main view controller") + } + + let size = mainViewController.keyboardViewController.preferredContentSize + windowScene.sizeRestrictions?.minimumSize = size + windowScene.sizeRestrictions?.maximumSize = size + window = UIWindow(windowScene: windowScene) + + if let window { + window.rootViewController = mainViewController.keyboardViewController + window.makeKeyAndVisible() + } + } +} diff --git a/Mini vMac/Mini vMac-Bridging-Header.h b/Mini vMac/Mini vMac-Bridging-Header.h new file mode 100644 index 0000000..0a5bcae --- /dev/null +++ b/Mini vMac/Mini vMac-Bridging-Header.h @@ -0,0 +1,8 @@ +// +// Use this file to import your target's public headers that you would like to expose to Swift. +// + +#import "ViewController.h" +#import "AppDelegate.h" +#import "KBKeyboardView.h" +#import "KBKeyboardLayout.h" diff --git a/Mini vMac/SettingsViewController.m b/Mini vMac/SettingsViewController.m index 7367226..ffd65a6 100644 --- a/Mini vMac/SettingsViewController.m +++ b/Mini vMac/SettingsViewController.m @@ -177,7 +177,11 @@ typedef enum : NSInteger { case SettingsSectionMachine: return machineList.count; case SettingsSectionAbout: +#if !defined(TARGET_OS_VISION) || TARGET_OS_VISION == 0 return aboutItems.count + 1; +#else + return aboutItems.count; +#endif default: return 1; } diff --git a/Mini vMac/ViewController.h b/Mini vMac/ViewController.h index e94b244..38d7e95 100644 --- a/Mini vMac/ViewController.h +++ b/Mini vMac/ViewController.h @@ -18,6 +18,14 @@ - (IBAction)showGestureHelp:(id)sender; - (IBAction)hideGestureHelp:(id)sender; +- (void)showKeyboard:(id)sender; @end +#if defined(TARGET_OS_VISION) && TARGET_OS_VISION == 1 +@interface ViewController (VisionSupport) +@property (nonatomic, readonly) UIViewController* keyboardViewController; +- (void)initXr; ++ (void)adjustToScreenSize; +@end +#endif diff --git a/Mini vMac/ViewController.m b/Mini vMac/ViewController.m index 0d5cb9b..be6fdcc 100644 --- a/Mini vMac/ViewController.m +++ b/Mini vMac/ViewController.m @@ -29,6 +29,7 @@ API_AVAILABLE(ios(13.4)) KBKeyboardView *keyboardView; UISwipeGestureRecognizer *showKeyboardGesture, *hideKeyboardGesture, *insertDiskGesture, *showSettingsGesture; UIControl *pointingDeviceView; + UIViewController *_keyboardViewController; id interaction; } @@ -43,20 +44,55 @@ API_AVAILABLE(ios(13.4)) - (void)viewDidLoad { [super viewDidLoad]; + + [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(emulatorDidShutDown:) name:[AppDelegate sharedEmulator].shutdownNotification object:nil]; + +#if defined(TARGET_OS_VISION) && TARGET_OS_VISION == 1 + [self initXr]; +#else + [self scheduleHelpPresentationIfNeededAfterDelay:6.0]; + [self installGestures]; +#endif +} + +#if defined(TARGET_OS_VISION) && TARGET_OS_VISION == 1 +- (UIViewController *)keyboardViewController { + if (keyboardView == nil) { + [[NSUserDefaults standardUserDefaults] addObserver:self forKeyPath:@"keyboardLayout" options:0 context:NULL]; + KBKeyboardLayout *layout = [self keyboardLayout]; + CGSize keyboardSize = CGSizeZero; + for (NSValue *size in layout.availableSizes) { + if (size.CGSizeValue.width > keyboardSize.width) { + keyboardSize = size.CGSizeValue; + } + } + keyboardView = [[KBKeyboardView alloc] initWithFrame:CGRectMake(0, 0, keyboardSize.width, keyboardSize.height)]; + keyboardView.layout = layout; + keyboardView.delegate = self; + } + if (_keyboardViewController == nil) { + _keyboardViewController = [UIViewController alloc]; + _keyboardViewController.view = keyboardView; + _keyboardViewController.preferredContentSize = keyboardView.frame.size; + } else if (_keyboardViewController.view != keyboardView) { + _keyboardViewController.view = keyboardView; + } + return _keyboardViewController; +} +#endif + +- (void)installGestures { [self installKeyboardGestures]; insertDiskGesture = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:@selector(showInsertDisk:)]; insertDiskGesture.direction = UISwipeGestureRecognizerDirectionLeft; insertDiskGesture.numberOfTouchesRequired = 2; [self.view addGestureRecognizer:insertDiskGesture]; - + showSettingsGesture = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:@selector(showSettings:)]; showSettingsGesture.direction = UISwipeGestureRecognizerDirectionRight; showSettingsGesture.numberOfTouchesRequired = 2; [self.view addGestureRecognizer:showSettingsGesture]; - - [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(emulatorDidShutDown:) name:[AppDelegate sharedEmulator].shutdownNotification object:nil]; - - [self scheduleHelpPresentationIfNeededAfterDelay:6.0]; + } - (void)showSettings:(id)sender { @@ -149,6 +185,11 @@ API_AVAILABLE(ios(13.4)) - (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context { if (object == [NSUserDefaults standardUserDefaults]) { if ([keyPath isEqualToString:@"keyboardLayout"] && keyboardView != nil) { +#if defined(TARGET_OS_VISION) && TARGET_OS_VISION == 1 + // FIXME: do this nicelier + keyboardView = nil; + [self keyboardViewController]; +#else BOOL keyboardWasVisible = self.keyboardVisible; [self setKeyboardVisible:NO animated:NO]; [keyboardView removeFromSuperview]; @@ -156,6 +197,7 @@ API_AVAILABLE(ios(13.4)) if (keyboardWasVisible) { [self setKeyboardVisible:YES animated:NO]; } +#endif } else if ([keyPath isEqualToString:@"trackpad"]) { [self setUpPointingDevice]; } @@ -215,7 +257,9 @@ API_AVAILABLE(ios(13.4)) #pragma mark - Gesture Help - (void)showGestureHelp:(id)sender { +#if !defined(TARGET_OS_VISION) || TARGET_OS_VISION == 0 [self setGestureHelpHidden:NO]; +#endif } - (void)hideGestureHelp:(id)sender { @@ -271,7 +315,11 @@ API_AVAILABLE(ios(13.4)) } - (BOOL)isKeyboardVisible { +#if defined(TARGET_OS_VISION) && TARGET_OS_VISION == 1 + return _keyboardViewController.view.window != nil; +#else return keyboardView != nil && CGRectIntersectsRect(keyboardView.frame, self.view.bounds) && !keyboardView.hidden; +#endif } - (void)setKeyboardVisible:(BOOL)keyboardVisible { @@ -291,6 +339,13 @@ API_AVAILABLE(ios(13.4)) return; } +#if defined(TARGET_OS_VISION) && TARGET_OS_VISION == 1 + if (visible) { + UISceneSessionActivationRequest *request = [UISceneSessionActivationRequest requestWithRole:UIWindowSceneSessionRoleApplication]; + request.userActivity = [[NSUserActivity alloc] initWithActivityType:@"net.namedfork.keyboard"]; + [[UIApplication sharedApplication] activateSceneSessionForRequest:request errorHandler:nil]; + } // only show, no hide +#else if (visible) { [[NSUserDefaults standardUserDefaults] addObserver:self forKeyPath:@"keyboardLayout" options:0 context:NULL]; [self loadKeyboardView]; @@ -324,7 +379,7 @@ API_AVAILABLE(ios(13.4)) keyboardView.hidden = YES; } } - +#endif } - (void)loadKeyboardView { diff --git a/Mini vMac/VisionSupport.swift b/Mini vMac/VisionSupport.swift new file mode 100644 index 0000000..1379de9 --- /dev/null +++ b/Mini vMac/VisionSupport.swift @@ -0,0 +1,66 @@ +// +// VisionSupport.swift +// Mini vMac +// +// Created by Jesús A. Álvarez on 2024-02-09. +// Copyright © 2024 namedfork. All rights reserved. +// + +import Foundation +import UIKit +import SwiftUI + +extension ViewController { +#if os(visionOS) + @objc + func initXr() { + ViewController.adjustToScreenSize() + ornaments = [ + UIHostingOrnament(sceneAnchor: .bottom, contentAlignment: .center) { + VStack { + Spacer(minLength: 80.0) + HStack { + Button(action: { + AppDelegate.sharedInstance().showSettings(self) + }, label: { + Image(systemName: "gear") + }).glassBackgroundEffect() + + Button(action: { + AppDelegate.sharedInstance().showInsertDisk(self) + }, label: { + Image(systemName: "opticaldiscdrive") + }).glassBackgroundEffect() + + Button(action: { + self.showKeyboard(self) + }, label: { + Image(systemName: "keyboard") + }).glassBackgroundEffect() + }.padding(.all) + .glassBackgroundEffect() + } + } + ] + } + + @objc + static func adjustToScreenSize() { + let screenSize = AppDelegate.sharedEmulator().screenSize + guard let windowScene = UIApplication.shared.connectedScenes.first as? UIWindowScene else { + return + } + let minSize = screenSize + let defaultSize = screenSize.applying(.init(scaleX: 2.0, y: 2.0)) + let maxSize = screenSize.applying(.init(scaleX: 3.0, y: 3.0)) + windowScene.sizeRestrictions?.minimumSize = minSize + windowScene.sizeRestrictions?.maximumSize = maxSize + windowScene.requestGeometryUpdate(UIWindowScene.GeometryPreferences.Vision( + size: defaultSize, + minimumSize: minSize, + maximumSize: maxSize, + resizingRestrictions: .uniform + )) + } +#endif +}