// Copyright 2017 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. #if !defined(__has_feature) || !__has_feature(objc_arc) #error "This file requires ARC support." #endif #import "remoting/ios/client_keyboard.h" #include "remoting/client/input/keycode_map.h" // TODO(nicholss): Look into inputAccessoryView to get the top bar for sending // special keys. // TODO(nicholss): Look into inputView - The custom input view to display when // the receiver becomes the first responder @interface ClientKeyboard () { UIView* _inputView; } @end @implementation ClientKeyboard @synthesize autocapitalizationType = _autocapitalizationType; @synthesize autocorrectionType = _autocorrectionType; @synthesize keyboardAppearance = _keyboardAppearance; @synthesize keyboardType = _keyboardType; @synthesize spellCheckingType = _spellCheckingType; @synthesize selectedTextRange = _selectedTextRange; @synthesize delegate = _delegate; // TODO(nicholss): For physical keyboard, look at UIKeyCommand // https://developer.apple.com/reference/uikit/uikeycommand?language=objc - (instancetype)init { self = [super init]; if (self) { _autocapitalizationType = UITextAutocapitalizationTypeNone; _autocorrectionType = UITextAutocorrectionTypeNo; _keyboardAppearance = UIKeyboardAppearanceDefault; _keyboardType = UIKeyboardTypeASCIICapable; _spellCheckingType = UITextSpellCheckingTypeNo; self.showsSoftKeyboard = NO; } return self; } #pragma mark - UIKeyInput - (void)insertText:(NSString*)text { if (text.length == 1) { // TODO(yuweih): KeyboardLayout should be configurable. remoting::KeypressInfo keypress = remoting::KeypressFromUnicode([text characterAtIndex:0]); if (keypress.dom_code != ui::DomCode::NONE) { [_delegate clientKeyboardShouldSendKey:keypress]; return; } } // Fallback to text injection. [_delegate clientKeyboardShouldSend:text]; } - (void)deleteBackward { [_delegate clientKeyboardShouldDelete]; } - (BOOL)hasText { return NO; } #pragma mark - UIResponder - (BOOL)canBecomeFirstResponder { return YES; } - (BOOL)resignFirstResponder { if (self.showsSoftKeyboard) { // This translates the action of resigning first responder when the keyboard // is showing into hiding the soft keyboard while keeping the view first // responder. This is to allow the hide keyboard button on the soft keyboard // to work properly with ClientKeyboard's soft keyboard logic, which calls // resignFirstResponder. // This may cause weird behavior if the superview has multiple responders // (text views). self.showsSoftKeyboard = NO; return NO; } return [super resignFirstResponder]; } - (UIView*)inputAccessoryView { return nil; } - (UIView*)inputView { return _inputView; } #pragma mark - UITextInputTraits #pragma mark - Properties - (void)setShowsSoftKeyboard:(BOOL)showsSoftKeyboard { if (self.showsSoftKeyboard == showsSoftKeyboard) { return; } // Returning nil for inputView will fallback to the system soft keyboard. // Returning an empty view will effectively hide it. _inputView = showsSoftKeyboard ? nil : [[UIView alloc] initWithFrame:CGRectZero]; [self reloadInputViews]; } - (BOOL)showsSoftKeyboard { return _inputView == nil; } @end