mirror of
https://github.com/moonlight-stream/moonlight-ios.git
synced 2026-02-16 10:31:02 +00:00
Refactor legacy UITextField-based keyboard support out of StreamView
This commit is contained in:
@@ -23,7 +23,7 @@
|
||||
|
||||
@end
|
||||
|
||||
@interface StreamView : OSView <UITextFieldDelegate, X1KitMouseDelegate>
|
||||
@interface StreamView : OSView <X1KitMouseDelegate>
|
||||
|
||||
@property (nonatomic, retain) IBOutlet UITextField* keyInputField;
|
||||
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
#include <Limelight.h>
|
||||
#import "DataManager.h"
|
||||
#import "ControllerSupport.h"
|
||||
#import "KeyboardSupport.h"
|
||||
#import "TextFieldKeyboardDelegate.h"
|
||||
|
||||
@implementation StreamView {
|
||||
CGPoint touchLocation, originalLocation;
|
||||
@@ -35,7 +35,7 @@
|
||||
NSTimer* interactionTimer;
|
||||
BOOL hasUserInteracted;
|
||||
|
||||
NSDictionary<NSString *, NSNumber *> *dictCodes;
|
||||
TextFieldKeyboardDelegate* textFieldDelegate;
|
||||
}
|
||||
|
||||
- (void) setMouseDeltaFactors:(float)x y:(float)y {
|
||||
@@ -75,6 +75,8 @@
|
||||
}
|
||||
#endif
|
||||
|
||||
textFieldDelegate = [[TextFieldKeyboardDelegate alloc] initWithTextField:_keyInputField];
|
||||
|
||||
x1mouse = [[X1Mouse alloc] init];
|
||||
x1mouse.delegate = self;
|
||||
[x1mouse start];
|
||||
@@ -229,10 +231,8 @@
|
||||
} else {
|
||||
Log(LOG_D, @"Opening the keyboard");
|
||||
// Prepare the textbox used to capture keyboard events.
|
||||
_keyInputField.delegate = self;
|
||||
_keyInputField.text = @"0";
|
||||
[_keyInputField becomeFirstResponder];
|
||||
[_keyInputField addTarget:self action:@selector(onKeyboardPressed:) forControlEvents:UIControlEventEditingChanged];
|
||||
|
||||
// Undo causes issues for our state management, so turn it off
|
||||
[_keyInputField.undoManager disableUndoRegistration];
|
||||
@@ -316,118 +316,14 @@
|
||||
return NO;
|
||||
}
|
||||
|
||||
- (BOOL)textFieldShouldReturn:(UITextField *)textField {
|
||||
// This method is called when the "Return" key is pressed.
|
||||
LiSendKeyboardEvent(0x0d, KEY_ACTION_DOWN, 0);
|
||||
usleep(50 * 1000);
|
||||
LiSendKeyboardEvent(0x0d, KEY_ACTION_UP, 0);
|
||||
return NO;
|
||||
}
|
||||
|
||||
- (void)onKeyboardPressed:(UITextField *)textField {
|
||||
NSString* inputText = textField.text;
|
||||
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), ^{
|
||||
// If the text became empty, we know the user pressed the backspace key.
|
||||
if ([inputText isEqual:@""]) {
|
||||
LiSendKeyboardEvent(0x08, KEY_ACTION_DOWN, 0);
|
||||
usleep(50 * 1000);
|
||||
LiSendKeyboardEvent(0x08, KEY_ACTION_UP, 0);
|
||||
} else {
|
||||
// Character 0 will be our known sentinel value
|
||||
for (int i = 1; i < [inputText length]; i++) {
|
||||
struct KeyEvent event = [KeyboardSupport translateKeyEvent:[inputText characterAtIndex:i] withModifierFlags:0];
|
||||
if (event.keycode == 0) {
|
||||
// If we don't know the code, don't send anything.
|
||||
Log(LOG_W, @"Unknown key code: [%c]", [inputText characterAtIndex:i]);
|
||||
continue;
|
||||
}
|
||||
[self sendLowLevelEvent:event];
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// Reset text field back to known state
|
||||
textField.text = @"0";
|
||||
|
||||
// Move the insertion point back to the end of the text box
|
||||
UITextRange *textRange = [textField textRangeFromPosition:textField.endOfDocument toPosition:textField.endOfDocument];
|
||||
[textField setSelectedTextRange:textRange];
|
||||
}
|
||||
|
||||
- (void)specialCharPressed:(UIKeyCommand *)cmd {
|
||||
struct KeyEvent event = [KeyboardSupport translateKeyEvent:0x20 withModifierFlags:[cmd modifierFlags]];
|
||||
event.keycode = [[dictCodes valueForKey:[cmd input]] intValue];
|
||||
[self sendLowLevelEvent:event];
|
||||
}
|
||||
|
||||
- (void)keyPressed:(UIKeyCommand *)cmd {
|
||||
struct KeyEvent event = [KeyboardSupport translateKeyEvent:[[cmd input] characterAtIndex:0] withModifierFlags:[cmd modifierFlags]];
|
||||
[self sendLowLevelEvent:event];
|
||||
}
|
||||
|
||||
- (void)sendLowLevelEvent:(struct KeyEvent)event {
|
||||
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), ^{
|
||||
// When we want to send a modified key (like uppercase letters) we need to send the
|
||||
// modifier ("shift") seperately from the key itself.
|
||||
if (event.modifier != 0) {
|
||||
LiSendKeyboardEvent(event.modifierKeycode, KEY_ACTION_DOWN, event.modifier);
|
||||
}
|
||||
LiSendKeyboardEvent(event.keycode, KEY_ACTION_DOWN, event.modifier);
|
||||
usleep(50 * 1000);
|
||||
LiSendKeyboardEvent(event.keycode, KEY_ACTION_UP, event.modifier);
|
||||
if (event.modifier != 0) {
|
||||
LiSendKeyboardEvent(event.modifierKeycode, KEY_ACTION_UP, event.modifier);
|
||||
}
|
||||
});
|
||||
- (NSArray<UIKeyCommand *> *)keyCommands {
|
||||
return [textFieldDelegate keyCommands];
|
||||
}
|
||||
|
||||
- (BOOL)canBecomeFirstResponder {
|
||||
return YES;
|
||||
}
|
||||
|
||||
- (NSArray<UIKeyCommand *> *)keyCommands
|
||||
{
|
||||
NSString *charset = @"qwertyuiopasdfghjklzxcvbnm1234567890\t§[]\\'\"/.,`<>-´ç+`¡'º;ñ= ";
|
||||
|
||||
NSMutableArray<UIKeyCommand *> * commands = [NSMutableArray<UIKeyCommand *> array];
|
||||
dictCodes = [[NSDictionary alloc] initWithObjectsAndKeys: [NSNumber numberWithInt: 0x0d], @"\r", [NSNumber numberWithInt: 0x08], @"\b", [NSNumber numberWithInt: 0x1b], UIKeyInputEscape, [NSNumber numberWithInt: 0x28], UIKeyInputDownArrow, [NSNumber numberWithInt: 0x26], UIKeyInputUpArrow, [NSNumber numberWithInt: 0x25], UIKeyInputLeftArrow, [NSNumber numberWithInt: 0x27], UIKeyInputRightArrow, nil];
|
||||
|
||||
[charset enumerateSubstringsInRange:NSMakeRange(0, charset.length)
|
||||
options:NSStringEnumerationByComposedCharacterSequences
|
||||
usingBlock:^(NSString *substring, NSRange substringRange, NSRange enclosingRange, BOOL *stop) {
|
||||
[commands addObject:[UIKeyCommand keyCommandWithInput:substring modifierFlags:0 action:@selector(keyPressed:)]];
|
||||
[commands addObject:[UIKeyCommand keyCommandWithInput:substring modifierFlags:UIKeyModifierShift action:@selector(keyPressed:)]];
|
||||
[commands addObject:[UIKeyCommand keyCommandWithInput:substring modifierFlags:UIKeyModifierControl action:@selector(keyPressed:)]];
|
||||
[commands addObject:[UIKeyCommand keyCommandWithInput:substring modifierFlags:UIKeyModifierAlternate action:@selector(keyPressed:)]];
|
||||
}];
|
||||
|
||||
for (NSString *c in [dictCodes keyEnumerator]) {
|
||||
[commands addObject:[UIKeyCommand keyCommandWithInput:c
|
||||
modifierFlags:0
|
||||
action:@selector(specialCharPressed:)]];
|
||||
[commands addObject:[UIKeyCommand keyCommandWithInput:c
|
||||
modifierFlags:UIKeyModifierShift
|
||||
action:@selector(specialCharPressed:)]];
|
||||
[commands addObject:[UIKeyCommand keyCommandWithInput:c
|
||||
modifierFlags:UIKeyModifierShift | UIKeyModifierAlternate
|
||||
action:@selector(specialCharPressed:)]];
|
||||
[commands addObject:[UIKeyCommand keyCommandWithInput:c
|
||||
modifierFlags:UIKeyModifierShift | UIKeyModifierControl
|
||||
action:@selector(specialCharPressed:)]];
|
||||
[commands addObject:[UIKeyCommand keyCommandWithInput:c
|
||||
modifierFlags:UIKeyModifierControl
|
||||
action:@selector(specialCharPressed:)]];
|
||||
[commands addObject:[UIKeyCommand keyCommandWithInput:c
|
||||
modifierFlags:UIKeyModifierControl | UIKeyModifierAlternate
|
||||
action:@selector(specialCharPressed:)]];
|
||||
[commands addObject:[UIKeyCommand keyCommandWithInput:c
|
||||
modifierFlags:UIKeyModifierAlternate
|
||||
action:@selector(specialCharPressed:)]];
|
||||
}
|
||||
|
||||
return commands;
|
||||
}
|
||||
|
||||
- (void)connectedStateDidChangeWithIdentifier:(NSUUID * _Nonnull)identifier isConnected:(BOOL)isConnected {
|
||||
NSLog(@"Citrix X1 mouse state change: %@ -> %s",
|
||||
identifier, isConnected ? "connected" : "disconnected");
|
||||
|
||||
18
Limelight/Input/TextFieldKeyboardDelegate.h
Normal file
18
Limelight/Input/TextFieldKeyboardDelegate.h
Normal file
@@ -0,0 +1,18 @@
|
||||
//
|
||||
// TextFieldKeyboardDelegate.h
|
||||
// Moonlight
|
||||
//
|
||||
// Created by Cameron Gutman on 3/24/20.
|
||||
// Copyright © 2020 Moonlight Game Streaming Project. All rights reserved.
|
||||
//
|
||||
|
||||
#pragma once
|
||||
|
||||
#import <UIKit/UIKit.h>
|
||||
|
||||
@interface TextFieldKeyboardDelegate : NSObject<UITextFieldDelegate>
|
||||
|
||||
- (id)initWithTextField:(UITextField*)textField;
|
||||
- (NSArray<UIKeyCommand *> *)keyCommands;
|
||||
|
||||
@end
|
||||
136
Limelight/Input/TextFieldKeyboardDelegate.m
Normal file
136
Limelight/Input/TextFieldKeyboardDelegate.m
Normal file
@@ -0,0 +1,136 @@
|
||||
//
|
||||
// TextFieldKeyboardDelegate.m
|
||||
// Moonlight
|
||||
//
|
||||
// Created by Cameron Gutman on 3/24/20.
|
||||
// Copyright © 2020 Moonlight Game Streaming Project. All rights reserved.
|
||||
//
|
||||
|
||||
#import "TextFieldKeyboardDelegate.h"
|
||||
#import "KeyboardSupport.h"
|
||||
|
||||
#include <Limelight.h>
|
||||
|
||||
@implementation TextFieldKeyboardDelegate {
|
||||
NSDictionary<NSString *, NSNumber *> *dictCodes;
|
||||
}
|
||||
|
||||
- (id)initWithTextField:(UITextField*)textField {
|
||||
self = [self init];
|
||||
|
||||
[textField addTarget:self action:@selector(onKeyboardPressed:) forControlEvents:UIControlEventEditingChanged];
|
||||
|
||||
textField.delegate = self;
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
- (BOOL)textFieldShouldReturn:(UITextField *)textField {
|
||||
// This method is called when the "Return" key is pressed.
|
||||
LiSendKeyboardEvent(0x0d, KEY_ACTION_DOWN, 0);
|
||||
usleep(50 * 1000);
|
||||
LiSendKeyboardEvent(0x0d, KEY_ACTION_UP, 0);
|
||||
return NO;
|
||||
}
|
||||
|
||||
- (void)onKeyboardPressed:(UITextField *)textField {
|
||||
NSString* inputText = textField.text;
|
||||
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), ^{
|
||||
// If the text became empty, we know the user pressed the backspace key.
|
||||
if ([inputText isEqual:@""]) {
|
||||
LiSendKeyboardEvent(0x08, KEY_ACTION_DOWN, 0);
|
||||
usleep(50 * 1000);
|
||||
LiSendKeyboardEvent(0x08, KEY_ACTION_UP, 0);
|
||||
} else {
|
||||
// Character 0 will be our known sentinel value
|
||||
for (int i = 1; i < [inputText length]; i++) {
|
||||
struct KeyEvent event = [KeyboardSupport translateKeyEvent:[inputText characterAtIndex:i] withModifierFlags:0];
|
||||
if (event.keycode == 0) {
|
||||
// If we don't know the code, don't send anything.
|
||||
Log(LOG_W, @"Unknown key code: [%c]", [inputText characterAtIndex:i]);
|
||||
continue;
|
||||
}
|
||||
[self sendLowLevelEvent:event];
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// Reset text field back to known state
|
||||
textField.text = @"0";
|
||||
|
||||
// Move the insertion point back to the end of the text box
|
||||
UITextRange *textRange = [textField textRangeFromPosition:textField.endOfDocument toPosition:textField.endOfDocument];
|
||||
[textField setSelectedTextRange:textRange];
|
||||
}
|
||||
|
||||
- (void)specialCharPressed:(UIKeyCommand *)cmd {
|
||||
struct KeyEvent event = [KeyboardSupport translateKeyEvent:0x20 withModifierFlags:[cmd modifierFlags]];
|
||||
event.keycode = [[dictCodes valueForKey:[cmd input]] intValue];
|
||||
[self sendLowLevelEvent:event];
|
||||
}
|
||||
|
||||
- (void)keyPressed:(UIKeyCommand *)cmd {
|
||||
struct KeyEvent event = [KeyboardSupport translateKeyEvent:[[cmd input] characterAtIndex:0] withModifierFlags:[cmd modifierFlags]];
|
||||
[self sendLowLevelEvent:event];
|
||||
}
|
||||
|
||||
- (void)sendLowLevelEvent:(struct KeyEvent)event {
|
||||
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), ^{
|
||||
// When we want to send a modified key (like uppercase letters) we need to send the
|
||||
// modifier ("shift") seperately from the key itself.
|
||||
if (event.modifier != 0) {
|
||||
LiSendKeyboardEvent(event.modifierKeycode, KEY_ACTION_DOWN, event.modifier);
|
||||
}
|
||||
LiSendKeyboardEvent(event.keycode, KEY_ACTION_DOWN, event.modifier);
|
||||
usleep(50 * 1000);
|
||||
LiSendKeyboardEvent(event.keycode, KEY_ACTION_UP, event.modifier);
|
||||
if (event.modifier != 0) {
|
||||
LiSendKeyboardEvent(event.modifierKeycode, KEY_ACTION_UP, event.modifier);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
- (NSArray<UIKeyCommand *> *)keyCommands
|
||||
{
|
||||
NSString *charset = @"qwertyuiopasdfghjklzxcvbnm1234567890\t§[]\\'\"/.,`<>-´ç+`¡'º;ñ= ";
|
||||
|
||||
NSMutableArray<UIKeyCommand *> * commands = [NSMutableArray<UIKeyCommand *> array];
|
||||
dictCodes = [[NSDictionary alloc] initWithObjectsAndKeys: [NSNumber numberWithInt: 0x0d], @"\r", [NSNumber numberWithInt: 0x08], @"\b", [NSNumber numberWithInt: 0x1b], UIKeyInputEscape, [NSNumber numberWithInt: 0x28], UIKeyInputDownArrow, [NSNumber numberWithInt: 0x26], UIKeyInputUpArrow, [NSNumber numberWithInt: 0x25], UIKeyInputLeftArrow, [NSNumber numberWithInt: 0x27], UIKeyInputRightArrow, nil];
|
||||
|
||||
[charset enumerateSubstringsInRange:NSMakeRange(0, charset.length)
|
||||
options:NSStringEnumerationByComposedCharacterSequences
|
||||
usingBlock:^(NSString *substring, NSRange substringRange, NSRange enclosingRange, BOOL *stop) {
|
||||
[commands addObject:[UIKeyCommand keyCommandWithInput:substring modifierFlags:0 action:@selector(keyPressed:)]];
|
||||
[commands addObject:[UIKeyCommand keyCommandWithInput:substring modifierFlags:UIKeyModifierShift action:@selector(keyPressed:)]];
|
||||
[commands addObject:[UIKeyCommand keyCommandWithInput:substring modifierFlags:UIKeyModifierControl action:@selector(keyPressed:)]];
|
||||
[commands addObject:[UIKeyCommand keyCommandWithInput:substring modifierFlags:UIKeyModifierAlternate action:@selector(keyPressed:)]];
|
||||
}];
|
||||
|
||||
for (NSString *c in [dictCodes keyEnumerator]) {
|
||||
[commands addObject:[UIKeyCommand keyCommandWithInput:c
|
||||
modifierFlags:0
|
||||
action:@selector(specialCharPressed:)]];
|
||||
[commands addObject:[UIKeyCommand keyCommandWithInput:c
|
||||
modifierFlags:UIKeyModifierShift
|
||||
action:@selector(specialCharPressed:)]];
|
||||
[commands addObject:[UIKeyCommand keyCommandWithInput:c
|
||||
modifierFlags:UIKeyModifierShift | UIKeyModifierAlternate
|
||||
action:@selector(specialCharPressed:)]];
|
||||
[commands addObject:[UIKeyCommand keyCommandWithInput:c
|
||||
modifierFlags:UIKeyModifierShift | UIKeyModifierControl
|
||||
action:@selector(specialCharPressed:)]];
|
||||
[commands addObject:[UIKeyCommand keyCommandWithInput:c
|
||||
modifierFlags:UIKeyModifierControl
|
||||
action:@selector(specialCharPressed:)]];
|
||||
[commands addObject:[UIKeyCommand keyCommandWithInput:c
|
||||
modifierFlags:UIKeyModifierControl | UIKeyModifierAlternate
|
||||
action:@selector(specialCharPressed:)]];
|
||||
[commands addObject:[UIKeyCommand keyCommandWithInput:c
|
||||
modifierFlags:UIKeyModifierAlternate
|
||||
action:@selector(specialCharPressed:)]];
|
||||
}
|
||||
|
||||
return commands;
|
||||
}
|
||||
|
||||
@end
|
||||
@@ -24,6 +24,8 @@
|
||||
98CFB82F1CAD481B0048EF74 /* libmoonlight-common.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 98AB2E841CAD46840089BB98 /* libmoonlight-common.a */; };
|
||||
98D5856D1C0EA79600F6CC00 /* TemporaryHost.m in Sources */ = {isa = PBXBuildFile; fileRef = 98D5856C1C0EA79600F6CC00 /* TemporaryHost.m */; };
|
||||
98D585701C0ED0E800F6CC00 /* TemporarySettings.m in Sources */ = {isa = PBXBuildFile; fileRef = 98D5856F1C0ED0E800F6CC00 /* TemporarySettings.m */; };
|
||||
98EB5208242AC4DF007127D3 /* TextFieldKeyboardDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 98EB5207242AC4DF007127D3 /* TextFieldKeyboardDelegate.m */; };
|
||||
98EB520A242AC86C007127D3 /* TextFieldKeyboardDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 98EB5207242AC4DF007127D3 /* TextFieldKeyboardDelegate.m */; };
|
||||
DC1F5A07206436B20037755F /* ConnectionHelper.m in Sources */ = {isa = PBXBuildFile; fileRef = DC1F5A06206436B20037755F /* ConnectionHelper.m */; };
|
||||
FB1A674D2131E65900507771 /* KeyboardSupport.m in Sources */ = {isa = PBXBuildFile; fileRef = FB1A674C2131E65900507771 /* KeyboardSupport.m */; };
|
||||
FB1A67602132419700507771 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = FB1A675E2132419700507771 /* Main.storyboard */; };
|
||||
@@ -173,6 +175,8 @@
|
||||
98D5856C1C0EA79600F6CC00 /* TemporaryHost.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = TemporaryHost.m; path = Database/TemporaryHost.m; sourceTree = "<group>"; };
|
||||
98D5856E1C0ED0E800F6CC00 /* TemporarySettings.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = TemporarySettings.h; path = Database/TemporarySettings.h; sourceTree = "<group>"; };
|
||||
98D5856F1C0ED0E800F6CC00 /* TemporarySettings.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = TemporarySettings.m; path = Database/TemporarySettings.m; sourceTree = "<group>"; };
|
||||
98EB5207242AC4DF007127D3 /* TextFieldKeyboardDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = TextFieldKeyboardDelegate.m; sourceTree = "<group>"; };
|
||||
98EB5209242AC4F3007127D3 /* TextFieldKeyboardDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = TextFieldKeyboardDelegate.h; sourceTree = "<group>"; };
|
||||
D4746EEA1CBC740C006FB401 /* Moonlight-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "Moonlight-Bridging-Header.h"; path = "Input/Moonlight-Bridging-Header.h"; sourceTree = "<group>"; };
|
||||
DC1F5A05206436B10037755F /* ConnectionHelper.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ConnectionHelper.h; sourceTree = "<group>"; };
|
||||
DC1F5A06206436B20037755F /* ConnectionHelper.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ConnectionHelper.m; sourceTree = "<group>"; };
|
||||
@@ -532,6 +536,8 @@
|
||||
FB1A674C2131E65900507771 /* KeyboardSupport.m */,
|
||||
9897B6A0221260EF00966419 /* Controller.m */,
|
||||
9897B6A32212610800966419 /* Controller.h */,
|
||||
98EB5207242AC4DF007127D3 /* TextFieldKeyboardDelegate.m */,
|
||||
98EB5209242AC4F3007127D3 /* TextFieldKeyboardDelegate.h */,
|
||||
);
|
||||
path = Input;
|
||||
sourceTree = "<group>";
|
||||
@@ -967,6 +973,7 @@
|
||||
FB1A67D1213245F800507771 /* TemporaryHost.m in Sources */,
|
||||
FB1A67D3213245F800507771 /* TemporarySettings.m in Sources */,
|
||||
FB1A67C3213245EA00507771 /* AppAssetManager.m in Sources */,
|
||||
98EB520A242AC86C007127D3 /* TextFieldKeyboardDelegate.m in Sources */,
|
||||
FB1A67C5213245EA00507771 /* AppAssetRetriever.m in Sources */,
|
||||
FB1A67C7213245EA00507771 /* PairManager.m in Sources */,
|
||||
FB1A67C9213245EA00507771 /* WakeOnLanManager.m in Sources */,
|
||||
@@ -1005,6 +1012,7 @@
|
||||
FB9AFD321A7D867C00872C98 /* AppAssetRetriever.m in Sources */,
|
||||
FB4678FF1A565DAC00377732 /* WakeOnLanManager.m in Sources */,
|
||||
FB53E1431BE5DC4400CD6ECE /* IdManager.m in Sources */,
|
||||
98EB5208242AC4DF007127D3 /* TextFieldKeyboardDelegate.m in Sources */,
|
||||
9897B6A1221260EF00966419 /* Controller.m in Sources */,
|
||||
FB89462919F646E200339C8A /* mkcert.c in Sources */,
|
||||
FB9AFD281A7C84ED00872C98 /* HttpResponse.m in Sources */,
|
||||
|
||||
Reference in New Issue
Block a user