keyboard for visionOS
@ -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 = "<group>"; };
|
||||
28CE8ED41CD4F56C00FE25A8 /* ScreenView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ScreenView.h; sourceTree = "<group>"; };
|
||||
28CE8ED51CD4F56C00FE25A8 /* ScreenView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ScreenView.m; sourceTree = "<group>"; };
|
||||
28D3C6132B7681420079E915 /* Mini vMac-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "Mini vMac-Bridging-Header.h"; sourceTree = "<group>"; };
|
||||
28D3C6142B7681420079E915 /* VisionSupport.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VisionSupport.swift; sourceTree = "<group>"; };
|
||||
28D3C6162B76B8970079E915 /* DefaultSceneDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DefaultSceneDelegate.swift; sourceTree = "<group>"; };
|
||||
28D3C61A2B7781700079E915 /* KeyboardSceneDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = KeyboardSceneDelegate.swift; sourceTree = "<group>"; };
|
||||
28D5A3FB1CD6868E001A33F6 /* TouchScreen.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TouchScreen.h; sourceTree = "<group>"; };
|
||||
28D5A3FC1CD6868E001A33F6 /* TouchScreen.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TouchScreen.m; sourceTree = "<group>"; };
|
||||
28E3B7CC251D0F12007C273F /* MOUSEMDV.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = MOUSEMDV.c; sourceTree = "<group>"; };
|
||||
@ -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 = "<group>";
|
||||
@ -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;
|
||||
|
7
Mini vMac.xcodeproj/project.xcworkspace/contents.xcworkspacedata
generated
Normal file
@ -0,0 +1,7 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Workspace
|
||||
version = "1.0">
|
||||
<FileRef
|
||||
location = "self:Mini vMac.xcodeproj">
|
||||
</FileRef>
|
||||
</Workspace>
|
@ -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"
|
||||
}
|
||||
]
|
||||
}
|
@ -10,6 +10,7 @@
|
||||
#import "AppDelegate.h"
|
||||
#import "SettingsViewController.h"
|
||||
#import "InsertDiskViewController.h"
|
||||
#import "ViewController.h"
|
||||
|
||||
static AppDelegate *sharedAppDelegate = nil;
|
||||
static NSObject<Emulator> *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<UISceneSession *> *)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
|
||||
|
@ -23,6 +23,11 @@
|
||||
"filename" : "KBCapsLock~ipad@2x.png",
|
||||
"idiom" : "ipad",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"filename" : "KBCapsLock~ipad@2x 1.png",
|
||||
"idiom" : "vision",
|
||||
"scale" : "2x"
|
||||
}
|
||||
],
|
||||
"info" : {
|
||||
|
BIN
Mini vMac/Assets.xcassets/KBCapsLock.imageset/KBCapsLock~ipad@2x 1.png
vendored
Normal file
After Width: | Height: | Size: 317 B |
@ -23,6 +23,11 @@
|
||||
"filename" : "KBClearDown~ipad@2x.png",
|
||||
"idiom" : "ipad",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"filename" : "KBClearDown~ipad@2x 1.png",
|
||||
"idiom" : "vision",
|
||||
"scale" : "2x"
|
||||
}
|
||||
],
|
||||
"info" : {
|
||||
|
BIN
Mini vMac/Assets.xcassets/KBClearDown.imageset/KBClearDown~ipad@2x 1.png
vendored
Normal file
After Width: | Height: | Size: 401 B |
@ -23,6 +23,11 @@
|
||||
"filename" : "KBClearUp~ipad@2x.png",
|
||||
"idiom" : "ipad",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"filename" : "KBClearUp~ipad@2x 1.png",
|
||||
"idiom" : "vision",
|
||||
"scale" : "2x"
|
||||
}
|
||||
],
|
||||
"info" : {
|
||||
|
BIN
Mini vMac/Assets.xcassets/KBClearUp.imageset/KBClearUp~ipad@2x 1.png
vendored
Normal file
After Width: | Height: | Size: 563 B |
@ -23,6 +23,11 @@
|
||||
"filename" : "KBCommand@2x~ipad.png",
|
||||
"idiom" : "ipad",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"filename" : "KBCommand@2x~ipad 1.png",
|
||||
"idiom" : "vision",
|
||||
"scale" : "2x"
|
||||
}
|
||||
],
|
||||
"info" : {
|
||||
|
BIN
Mini vMac/Assets.xcassets/KBCommand.imageset/KBCommand@2x~ipad 1.png
vendored
Normal file
After Width: | Height: | Size: 1.0 KiB |
@ -23,6 +23,11 @@
|
||||
"filename" : "KBDeleteDown~ipad@2x.png",
|
||||
"idiom" : "ipad",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"filename" : "KBDeleteDown~ipad@2x 1.png",
|
||||
"idiom" : "vision",
|
||||
"scale" : "2x"
|
||||
}
|
||||
],
|
||||
"info" : {
|
||||
|
BIN
Mini vMac/Assets.xcassets/KBDeleteDown.imageset/KBDeleteDown~ipad@2x 1.png
vendored
Normal file
After Width: | Height: | Size: 526 B |
@ -23,6 +23,11 @@
|
||||
"filename" : "KBDeleteUp~ipad@2x.png",
|
||||
"idiom" : "ipad",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"filename" : "KBDeleteUp~ipad@2x 1.png",
|
||||
"idiom" : "vision",
|
||||
"scale" : "2x"
|
||||
}
|
||||
],
|
||||
"info" : {
|
||||
|
BIN
Mini vMac/Assets.xcassets/KBDeleteUp.imageset/KBDeleteUp~ipad@2x 1.png
vendored
Normal file
After Width: | Height: | Size: 726 B |
@ -23,6 +23,11 @@
|
||||
"filename" : "KBForwardDeleteDown~ipad@2x.png",
|
||||
"idiom" : "ipad",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"filename" : "KBForwardDeleteDown~ipad@2x 1.png",
|
||||
"idiom" : "vision",
|
||||
"scale" : "2x"
|
||||
}
|
||||
],
|
||||
"info" : {
|
||||
|
BIN
Mini vMac/Assets.xcassets/KBForwardDeleteDown.imageset/KBForwardDeleteDown~ipad@2x 1.png
vendored
Normal file
After Width: | Height: | Size: 526 B |
@ -23,6 +23,11 @@
|
||||
"filename" : "KBForwardDeleteUp~ipad@2x.png",
|
||||
"idiom" : "ipad",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"filename" : "KBForwardDeleteUp~ipad@2x 1.png",
|
||||
"idiom" : "vision",
|
||||
"scale" : "2x"
|
||||
}
|
||||
],
|
||||
"info" : {
|
||||
|
BIN
Mini vMac/Assets.xcassets/KBForwardDeleteUp.imageset/KBForwardDeleteUp~ipad@2x 1.png
vendored
Normal file
After Width: | Height: | Size: 718 B |
@ -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" : {
|
||||
|
BIN
Mini vMac/Assets.xcassets/KBHide.imageset/KBHide~ipad 2.png
vendored
Normal file
After Width: | Height: | Size: 242 B |
BIN
Mini vMac/Assets.xcassets/KBHide.imageset/KBHide~ipad@2x 1.png
vendored
Normal file
After Width: | Height: | Size: 438 B |
@ -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" : {
|
||||
|
BIN
Mini vMac/Assets.xcassets/KBKey.imageset/KBKey@2x~ipad-2 1.png
vendored
Normal file
After Width: | Height: | Size: 634 B |
@ -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" : {
|
||||
|
BIN
Mini vMac/Assets.xcassets/KBKeyDark.imageset/KBKeyDark@2x~ipad-1 1.png
vendored
Normal file
After Width: | Height: | Size: 636 B |
@ -23,6 +23,11 @@
|
||||
"filename" : "KBNumPad@2x~ipad.png",
|
||||
"idiom" : "ipad",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"filename" : "KBNumPad@2x~ipad 1.png",
|
||||
"idiom" : "vision",
|
||||
"scale" : "2x"
|
||||
}
|
||||
],
|
||||
"info" : {
|
||||
|
BIN
Mini vMac/Assets.xcassets/KBNumPad.imageset/KBNumPad@2x~ipad 1.png
vendored
Normal file
After Width: | Height: | Size: 178 B |
@ -23,6 +23,11 @@
|
||||
"filename" : "KBOption@2x~ipad.png",
|
||||
"idiom" : "ipad",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"filename" : "KBOption@2x~ipad 1.png",
|
||||
"idiom" : "vision",
|
||||
"scale" : "2x"
|
||||
}
|
||||
],
|
||||
"info" : {
|
||||
|
BIN
Mini vMac/Assets.xcassets/KBOption.imageset/KBOption@2x~ipad 1.png
vendored
Normal file
After Width: | Height: | Size: 365 B |
@ -23,6 +23,11 @@
|
||||
"filename" : "KBShiftDown~ipad@2x.png",
|
||||
"idiom" : "ipad",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"filename" : "KBShiftDown~ipad@2x 1.png",
|
||||
"idiom" : "vision",
|
||||
"scale" : "2x"
|
||||
}
|
||||
],
|
||||
"info" : {
|
||||
|
BIN
Mini vMac/Assets.xcassets/KBShiftDown.imageset/KBShiftDown~ipad@2x 1.png
vendored
Normal file
After Width: | Height: | Size: 274 B |
@ -23,6 +23,11 @@
|
||||
"filename" : "KBShiftUp~ipad@2x.png",
|
||||
"idiom" : "ipad",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"filename" : "KBShiftUp~ipad@2x 1.png",
|
||||
"idiom" : "vision",
|
||||
"scale" : "2x"
|
||||
}
|
||||
],
|
||||
"info" : {
|
||||
|
BIN
Mini vMac/Assets.xcassets/KBShiftUp.imageset/KBShiftUp~ipad@2x 1.png
vendored
Normal file
After Width: | Height: | Size: 467 B |
@ -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"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
35
Mini vMac/DefaultSceneDelegate.swift
Normal file
@ -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()
|
||||
}
|
||||
}
|
||||
}
|
@ -176,5 +176,28 @@
|
||||
</dict>
|
||||
</dict>
|
||||
</array>
|
||||
<key>UIApplicationSceneManifest</key>
|
||||
<dict>
|
||||
<key>UIApplicationSupportsMultipleScenes</key>
|
||||
<true/>
|
||||
<key>UISceneConfigurations</key>
|
||||
<dict>
|
||||
<key>UIWindowSceneSessionRoleApplication</key>
|
||||
<array>
|
||||
<dict>
|
||||
<key>UISceneConfigurationName</key>
|
||||
<string>Default</string>
|
||||
<key>UISceneDelegateClassName</key>
|
||||
<string>$(PRODUCT_MODULE_NAME).DefaultSceneDelegate</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>UISceneConfigurationName</key>
|
||||
<string>Keyboard</string>
|
||||
<key>UISceneDelegateClassName</key>
|
||||
<string>$(PRODUCT_MODULE_NAME).KeyboardSceneDelegate</string>
|
||||
</dict>
|
||||
</array>
|
||||
</dict>
|
||||
</dict>
|
||||
</dict>
|
||||
</plist>
|
||||
|
@ -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;
|
||||
|
32
Mini vMac/KeyboardSceneDelegate.swift
Normal file
@ -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()
|
||||
}
|
||||
}
|
||||
}
|
8
Mini vMac/Mini vMac-Bridging-Header.h
Normal file
@ -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"
|
@ -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;
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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<NSString *,id> *)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 {
|
||||
|
66
Mini vMac/VisionSupport.swift
Normal file
@ -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
|
||||
}
|