Skip to content

Commit

Permalink
Bug 1847585 - Implement keyboardType, returnKeyType and autocapitaliz…
Browse files Browse the repository at this point in the history
…ationType. r=masayuki

Change virtual keyboard laybout via HTML elements and attributes.

Differential Revision: https://phabricator.services.mozilla.com/D185574
  • Loading branch information
makotokato committed Mar 4, 2024
1 parent 1ceed27 commit 264ed62
Show file tree
Hide file tree
Showing 5 changed files with 165 additions and 7 deletions.
14 changes: 8 additions & 6 deletions widget/IMEData.h
Original file line number Diff line number Diff line change
Expand Up @@ -451,18 +451,20 @@ struct InputContext final {

bool IsInputAttributeChanged(const InputContext& aOldContext) const {
return mIMEState.mEnabled != aOldContext.mIMEState.mEnabled ||
#if defined(ANDROID) || defined(MOZ_WIDGET_GTK) || defined(XP_WIN)
#if defined(ANDROID) || defined(MOZ_WIDGET_GTK) || defined(XP_WIN) || \
defined(XP_IOS)
// input type and inputmode are supported by Windows IME API, GTK
// IME API and Android IME API
// IME API, Android IME API and iOS API.
mHTMLInputType != aOldContext.mHTMLInputType ||
mHTMLInputMode != aOldContext.mHTMLInputMode ||
#endif
#if defined(ANDROID) || defined(MOZ_WIDGET_GTK)
// autocapitalize is supported by Android IME API and GTK IME API
#if defined(ANDROID) || defined(MOZ_WIDGET_GTK) || defined(XP_IOS)
// autocapitalize is supported by Android IME API, GTK IME API, and
// iOS API
mAutocapitalize != aOldContext.mAutocapitalize ||
#endif
#if defined(ANDROID)
// enterkeyhint is only supported by Android IME API.
#if defined(ANDROID) || defined(XP_IOS)
// enterkeyhint is only supported by Android IME API and iOS API.
mActionHint != aOldContext.mActionHint ||
#endif
false;
Expand Down
23 changes: 23 additions & 0 deletions widget/uikit/UIKitUtils.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */

#import <UIKit/UIKit.h>

#include "IMEData.h"

namespace mozilla::widget {

class UIKitUtils final {
public:
UIKitUtils() = delete;
~UIKitUtils() = delete;

static UIKeyboardType GetUIKeyboardType(const InputContext& aContext);
static UIReturnKeyType GetUIReturnKeyType(const InputContext& aContext);
static UITextAutocapitalizationType GetUITextAutocapitalizationType(
const InputContext& aContext);
};

} // namespace mozilla::widget
89 changes: 89 additions & 0 deletions widget/uikit/UIKitUtils.mm
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */

#include "UIKitUtils.h"

namespace mozilla::widget {

// static
UIKeyboardType UIKitUtils::GetUIKeyboardType(const InputContext& aContext) {
if (aContext.mHTMLInputMode.EqualsLiteral("email")) {
return UIKeyboardTypeEmailAddress;
}
if (aContext.mHTMLInputMode.EqualsLiteral("deciaml")) {
return UIKeyboardTypeDecimalPad;
}
if (aContext.mHTMLInputMode.EqualsLiteral("numeric")) {
return UIKeyboardTypeNumberPad;
}
if (aContext.mHTMLInputMode.EqualsLiteral("search")) {
return UIKeyboardTypeWebSearch;
}
if (aContext.mHTMLInputMode.EqualsLiteral("tel")) {
return UIKeyboardTypePhonePad;
}
if (aContext.mHTMLInputMode.EqualsLiteral("url")) {
return UIKeyboardTypeURL;
}

if (aContext.mHTMLInputType.EqualsLiteral("email")) {
return UIKeyboardTypeEmailAddress;
}
if (aContext.mHTMLInputType.EqualsLiteral("number")) {
return UIKeyboardTypeNumberPad;
}
if (aContext.mHTMLInputType.EqualsLiteral("tel")) {
return UIKeyboardTypePhonePad;
}
if (aContext.mHTMLInputType.EqualsLiteral("url")) {
return UIKeyboardTypeURL;
}

return UIKeyboardTypeDefault;
}

// static
UIReturnKeyType UIKitUtils::GetUIReturnKeyType(const InputContext& aContext) {
if (aContext.mActionHint.EqualsLiteral("done")) {
return UIReturnKeyDone;
}
if (aContext.mActionHint.EqualsLiteral("go")) {
return UIReturnKeyGo;
}
if (aContext.mActionHint.EqualsLiteral("next") ||
aContext.mActionHint.EqualsLiteral("maybenext")) {
return UIReturnKeyNext;
}
if (aContext.mActionHint.EqualsLiteral("search")) {
return UIReturnKeySearch;
}
if (aContext.mActionHint.EqualsLiteral("send")) {
return UIReturnKeySend;
}

return UIReturnKeyDefault;
}

// static
UITextAutocapitalizationType UIKitUtils::GetUITextAutocapitalizationType(
const InputContext& aContext) {
if (aContext.mAutocapitalize.EqualsLiteral("characters")) {
return UITextAutocapitalizationTypeAllCharacters;
}
if (aContext.mAutocapitalize.EqualsLiteral("none")) {
return UITextAutocapitalizationTypeNone;
}
if (aContext.mAutocapitalize.EqualsLiteral("sentences")) {
return UITextAutocapitalizationTypeSentences;
}
if (aContext.mAutocapitalize.EqualsLiteral("words")) {
return UITextAutocapitalizationTypeWords;
}
// TODO(m_kato):
// Infer autocapitalization type by input type like GeckoView.
return UITextAutocapitalizationTypeNone;
}

} // namespace mozilla::widget
1 change: 1 addition & 0 deletions widget/uikit/moz.build
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ SOURCES += [
"nsWidgetFactory.mm",
"nsWindow.mm",
"TextInputHandler.mm",
"UIKitUtils.mm",
]

include("/ipc/chromium/chromium-config.mozbuild")
Expand Down
45 changes: 44 additions & 1 deletion widget/uikit/nsWindow.mm
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */

#import <UIKit/UIEvent.h>
#import <UIKit/UIKit.h>
#import <UIKit/UIGraphics.h>
#import <UIKit/UIInterface.h>
#import <UIKit/UIScreen.h>
Expand Down Expand Up @@ -31,6 +32,7 @@
#include "nsRegion.h"
#include "nsTArray.h"
#include "TextInputHandler.h"
#include "UIKitUtils.h"

#include "mozilla/BasicEvents.h"
#include "mozilla/ProfilerLabels.h"
Expand All @@ -43,6 +45,7 @@
using namespace mozilla::gfx;
using namespace mozilla::layers;
using mozilla::dom::Touch;
using mozilla::widget::UIKitUtils;

#define ALOG(args...) \
fprintf(stderr, args); \
Expand Down Expand Up @@ -492,6 +495,40 @@ - (BOOL)hasText {
return YES;
}

// UITextInputTraits

- (UIKeyboardType)keyboardType {
if (!mGeckoChild || mGeckoChild->Destroyed()) {
return UIKeyboardTypeDefault;
}
return UIKitUtils::GetUIKeyboardType(mGeckoChild->GetInputContext());
}

- (UIReturnKeyType)returnKeyType {
if (!mGeckoChild || mGeckoChild->Destroyed()) {
return UIReturnKeyDefault;
}
return UIKitUtils::GetUIReturnKeyType(mGeckoChild->GetInputContext());
}

- (UITextAutocapitalizationType)autocapitalizationType {
if (!mGeckoChild || mGeckoChild->Destroyed()) {
return UITextAutocapitalizationTypeNone;
}
return UIKitUtils::GetUITextAutocapitalizationType(
mGeckoChild->GetInputContext());
}

- (BOOL)isSecureTextEntry {
if (!mGeckoChild || mGeckoChild->Destroyed()) {
return NO;
}
if (mGeckoChild->GetInputContext().IsPasswordEditor()) {
return YES;
}
return NO;
}

@end

nsWindow::nsWindow()
Expand Down Expand Up @@ -783,6 +820,9 @@ - (BOOL)hasText {
const InputContextAction& aAction) {
NS_OBJC_BEGIN_TRY_IGNORE_BLOCK;

const bool changingEnabledState =
aContext.IsInputAttributeChanged(mInputContext);

mInputContext = aContext;

if (IsVirtualKeyboardDisabled()) {
Expand All @@ -792,7 +832,10 @@ - (BOOL)hasText {

[mNativeView becomeFirstResponder];

if (aAction.UserMightRequestOpenVKB()) {
if (aAction.UserMightRequestOpenVKB() || changingEnabledState) {
// TODO(m_kato):
// It is unnecessary to call reloadInputViews with changingEnabledState if
// virtual keyboard is disappeared.
[mNativeView reloadInputViews];
}

Expand Down

0 comments on commit 264ed62

Please sign in to comment.