Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import android.util.SparseIntArray
import android.view.inputmethod.EditorInfo
import helium314.keyboard.keyboard.Key
import helium314.keyboard.keyboard.Keyboard
import helium314.keyboard.keyboard.KeyboardId
import helium314.keyboard.keyboard.KeyboardElement
import helium314.keyboard.keyboard.internal.keyboard_parser.floris.KeyCode
import helium314.keyboard.latin.R
import helium314.keyboard.latin.common.Constants
Expand Down Expand Up @@ -129,13 +129,13 @@ internal class KeyCodeDescriptionMapper private constructor() {
* @return a character sequence describing the action performed by pressing the key
*/
private fun getDescriptionForSwitchAlphaSymbol(context: Context, keyboard: Keyboard?): String? {
val resId = when (val elementId = keyboard?.mId?.mElementId) {
KeyboardId.ELEMENT_ALPHABET, KeyboardId.ELEMENT_ALPHABET_AUTOMATIC_SHIFTED, KeyboardId.ELEMENT_ALPHABET_MANUAL_SHIFTED, KeyboardId.ELEMENT_ALPHABET_SHIFT_LOCK_SHIFTED, KeyboardId.ELEMENT_ALPHABET_SHIFT_LOCKED -> R.string.spoken_description_to_symbol
KeyboardId.ELEMENT_SYMBOLS, KeyboardId.ELEMENT_SYMBOLS_SHIFTED -> R.string.spoken_description_to_alpha
KeyboardId.ELEMENT_PHONE -> R.string.spoken_description_to_symbol
KeyboardId.ELEMENT_PHONE_SYMBOLS -> R.string.spoken_description_to_numeric
val resId = when (val element = keyboard?.mId?.element) {
KeyboardElement.ALPHABET, KeyboardElement.ALPHABET_AUTOMATIC_SHIFTED, KeyboardElement.ALPHABET_MANUAL_SHIFTED, KeyboardElement.ALPHABET_SHIFT_LOCK_SHIFTED, KeyboardElement.ALPHABET_SHIFT_LOCKED -> R.string.spoken_description_to_symbol
KeyboardElement.SYMBOLS, KeyboardElement.SYMBOLS_SHIFTED -> R.string.spoken_description_to_alpha
KeyboardElement.PHONE -> R.string.spoken_description_to_symbol
KeyboardElement.PHONE_SYMBOLS -> R.string.spoken_description_to_numeric
else -> {
Log.e(TAG, "Missing description for keyboard element ID:$elementId")
Log.e(TAG, "Missing description for keyboard element ID:$element")
return null
}
}
Expand All @@ -150,11 +150,11 @@ internal class KeyCodeDescriptionMapper private constructor() {
* @return A context-sensitive description of the "Shift" key.
*/
private fun getDescriptionForShiftKey(context: Context, keyboard: Keyboard?): String {
val resId: Int = when (keyboard?.mId?.mElementId) {
KeyboardId.ELEMENT_ALPHABET_SHIFT_LOCK_SHIFTED, KeyboardId.ELEMENT_ALPHABET_SHIFT_LOCKED -> R.string.spoken_description_caps_lock
KeyboardId.ELEMENT_ALPHABET_AUTOMATIC_SHIFTED, KeyboardId.ELEMENT_ALPHABET_MANUAL_SHIFTED -> R.string.spoken_description_shift_shifted
KeyboardId.ELEMENT_SYMBOLS -> R.string.spoken_description_symbols_shift
KeyboardId.ELEMENT_SYMBOLS_SHIFTED -> R.string.spoken_description_symbols_shift_shifted
val resId: Int = when (keyboard?.mId?.element) {
KeyboardElement.ALPHABET_SHIFT_LOCK_SHIFTED, KeyboardElement.ALPHABET_SHIFT_LOCKED -> R.string.spoken_description_caps_lock
KeyboardElement.ALPHABET_AUTOMATIC_SHIFTED, KeyboardElement.ALPHABET_MANUAL_SHIFTED -> R.string.spoken_description_shift_shifted
KeyboardElement.SYMBOLS -> R.string.spoken_description_symbols_shift
KeyboardElement.SYMBOLS_SHIFTED -> R.string.spoken_description_symbols_shift_shifted
else -> R.string.spoken_description_shift
}
return context.getString(resId)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -269,7 +269,7 @@ class KeyboardAccessibilityNodeProvider<KV : KeyboardView>(
* @return The context-specific description of the key.
*/
private fun getKeyDescription(key: Key): String? {
val editorInfo = mKeyboard?.mId?.mEditorInfo
val editorInfo = mKeyboard?.mId?.editorInfo
val shouldObscure = mAccessibilityUtils.shouldObscureInput(editorInfo)
val currentSettings = Settings.getValues()
val keyCodeDescription = mKeyCodeDescriptionMapper.getDescriptionForKey(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ package helium314.keyboard.accessibility
import android.graphics.Rect
import android.os.SystemClock
import helium314.keyboard.latin.utils.Log
import android.util.SparseIntArray
import android.view.MotionEvent
import helium314.keyboard.accessibility.AccessibilityLongPressTimer.LongPressTimerCallback
import helium314.keyboard.keyboard.*
Expand All @@ -25,7 +24,7 @@ class MainKeyboardAccessibilityDelegate(
keyDetector: KeyDetector
) : KeyboardAccessibilityDelegate<MainKeyboardView>(mainKeyboardView, keyDetector), LongPressTimerCallback {
/** The most recently set keyboard mode. */
private var mLastKeyboardMode = KEYBOARD_IS_HIDDEN
private var mLastKeyboardMode: KeyboardMode? = null
// The rectangle region to ignore hover events.
private val mBoundsToIgnoreHoverEvent = Rect()
private val mAccessibilityLongPressTimer = AccessibilityLongPressTimer(this /* callback */, mainKeyboardView.context)
Expand All @@ -47,24 +46,24 @@ class MainKeyboardAccessibilityDelegate(
val lastKeyboard = super.keyboard
super.keyboard = keyboard
val lastKeyboardMode = mLastKeyboardMode
mLastKeyboardMode = keyboard.mId.mMode
mLastKeyboardMode = keyboard.mId.mode
// Since this method is called even when accessibility is off, make sure
// to check the state before announcing anything.
if (!AccessibilityUtils.instance.isAccessibilityEnabled) {
return
}
// Announce the language name only when the language is changed.
if (lastKeyboard == null || keyboard.mId.mSubtype != lastKeyboard.mId.mSubtype) {
if (lastKeyboard == null || keyboard.mId.subtype != lastKeyboard.mId.subtype) {
announceKeyboardLanguage(keyboard)
return
}
// Announce the mode only when the mode is changed.
if (keyboard.mId.mMode != lastKeyboardMode) {
if (keyboard.mId.mode != lastKeyboardMode) {
announceKeyboardMode(keyboard)
return
}
// Announce the keyboard type only when the type is changed.
if (keyboard.mId.mElementId != lastKeyboard.mId.mElementId) {
if (keyboard.mId.element != lastKeyboard.mId.element) {
announceKeyboardType(keyboard, lastKeyboard)
return
}
Expand All @@ -74,10 +73,10 @@ class MainKeyboardAccessibilityDelegate(
* Called when the keyboard is hidden and accessibility is enabled.
*/
fun onHideWindow() {
if (mLastKeyboardMode != KEYBOARD_IS_HIDDEN) {
if (mLastKeyboardMode != null) {
announceKeyboardHidden()
}
mLastKeyboardMode = KEYBOARD_IS_HIDDEN
mLastKeyboardMode = null
}

/**
Expand All @@ -86,7 +85,7 @@ class MainKeyboardAccessibilityDelegate(
* @param keyboard The new keyboard.
*/
private fun announceKeyboardLanguage(keyboard: Keyboard) {
sendWindowStateChanged(keyboard.mId.mSubtype.rawSubtype.displayName())
sendWindowStateChanged(keyboard.mId.subtype.rawSubtype.displayName())
}

/**
Expand All @@ -96,13 +95,10 @@ class MainKeyboardAccessibilityDelegate(
* @param keyboard The new keyboard.
*/
private fun announceKeyboardMode(keyboard: Keyboard) {
val context = mKeyboardView.context
val modeTextResId = KEYBOARD_MODE_RES_IDS[keyboard.mId.mMode]
if (modeTextResId == 0) {
return
}
val modeText = context.getString(modeTextResId)
val text = context.getString(R.string.announce_keyboard_mode, modeText)
val res = mKeyboardView.resources
val modeText = res.getString(keyboard.mId.mode.contentDescription)
val text = res.getString(R.string.announce_keyboard_mode, modeText)
// TODO: this is saying "Showing showing (text) keyboard"
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Did it always say "showing showing", or is this new?
How do I actually test this? Looks like I need "accessibility" enabled, but the accessibility settings on my phone don't have a generic on/off switch...

sendWindowStateChanged(text)
}

Expand All @@ -113,41 +109,40 @@ class MainKeyboardAccessibilityDelegate(
* @param lastKeyboard The last keyboard.
*/
private fun announceKeyboardType(keyboard: Keyboard, lastKeyboard: Keyboard) {
val lastElementId = lastKeyboard.mId.mElementId
val resId = when (keyboard.mId.mElementId) {
KeyboardId.ELEMENT_ALPHABET_AUTOMATIC_SHIFTED, KeyboardId.ELEMENT_ALPHABET -> {
if (lastElementId == KeyboardId.ELEMENT_ALPHABET
|| lastElementId == KeyboardId.ELEMENT_ALPHABET_AUTOMATIC_SHIFTED) {
val lastElement = lastKeyboard.mId.element
val element = keyboard.mId.element
when (element) {
KeyboardElement.ALPHABET, KeyboardElement.ALPHABET_AUTOMATIC_SHIFTED -> {
if (lastElement == KeyboardElement.ALPHABET || lastElement == KeyboardElement.ALPHABET_AUTOMATIC_SHIFTED) {
// Transition between alphabet mode and automatic shifted mode should be silently
// ignored because it can be determined by each key's talk back announce.
return
}
R.string.spoken_description_mode_alpha
}
KeyboardId.ELEMENT_ALPHABET_MANUAL_SHIFTED -> {
if (lastElementId == KeyboardId.ELEMENT_ALPHABET_AUTOMATIC_SHIFTED) {
KeyboardElement.ALPHABET_MANUAL_SHIFTED -> {
if (lastElement == KeyboardElement.ALPHABET_AUTOMATIC_SHIFTED) {
// Resetting automatic shifted mode by pressing the shift key causes the transition
// from automatic shifted to manual shifted that should be silently ignored.
return
}
R.string.spoken_description_shiftmode_on
}
KeyboardId.ELEMENT_ALPHABET_SHIFT_LOCK_SHIFTED -> {
if (lastElementId == KeyboardId.ELEMENT_ALPHABET_SHIFT_LOCKED) {
KeyboardElement.ALPHABET_SHIFT_LOCK_SHIFTED -> {
if (lastElement == KeyboardElement.ALPHABET_SHIFT_LOCKED) {
// Resetting caps locked mode by pressing the shift key causes the transition
// from shift locked to shift lock shifted that should be silently ignored.
return
}
R.string.spoken_description_shiftmode_locked
}
KeyboardId.ELEMENT_ALPHABET_SHIFT_LOCKED -> R.string.spoken_description_shiftmode_locked
KeyboardId.ELEMENT_SYMBOLS -> R.string.spoken_description_mode_symbol
KeyboardId.ELEMENT_SYMBOLS_SHIFTED -> R.string.spoken_description_mode_symbol_shift
KeyboardId.ELEMENT_PHONE -> R.string.spoken_description_mode_phone
KeyboardId.ELEMENT_PHONE_SYMBOLS -> R.string.spoken_description_mode_phone_shift
else -> return
else -> {}
}
if (element.isEmojiLayout) {
// the emoji pages are handled in EmojiCategory
return
}
val contentDescription = element.contentDescription
if (contentDescription != 0) {
sendWindowStateChanged(contentDescription)
}
sendWindowStateChanged(resId)
}

/**
Expand Down Expand Up @@ -243,18 +238,5 @@ class MainKeyboardAccessibilityDelegate(

companion object {
private val TAG = MainKeyboardAccessibilityDelegate::class.java.simpleName
/** Map of keyboard modes to resource IDs. */
private val KEYBOARD_MODE_RES_IDS = SparseIntArray().apply {
put(KeyboardId.MODE_DATE, R.string.keyboard_mode_date)
put(KeyboardId.MODE_DATETIME, R.string.keyboard_mode_date_time)
put(KeyboardId.MODE_EMAIL, R.string.keyboard_mode_email)
put(KeyboardId.MODE_IM, R.string.keyboard_mode_im)
put(KeyboardId.MODE_NUMBER, R.string.keyboard_mode_number)
put(KeyboardId.MODE_PHONE, R.string.keyboard_mode_phone)
put(KeyboardId.MODE_TEXT, R.string.keyboard_mode_text)
put(KeyboardId.MODE_TIME, R.string.keyboard_mode_time)
put(KeyboardId.MODE_URL, R.string.keyboard_mode_url)
}
private const val KEYBOARD_IS_HIDDEN = -1
}
}
}
25 changes: 11 additions & 14 deletions app/src/main/java/helium314/keyboard/keyboard/Key.java
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@

import java.util.Arrays;
import java.util.Locale;
import java.util.Objects;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
Expand Down Expand Up @@ -363,17 +364,12 @@ public static Key removeRedundantPopupKeys(@NonNull final Key key,
return (filteredPopupKeys == popupKeys) ? key : new Key(key, filteredPopupKeys);
}

private static boolean needsToUpcase(final int labelFlags, final int keyboardElementId) {
if ((labelFlags & LABEL_FLAGS_PRESERVE_CASE) != 0) return false;
return switch (keyboardElementId) {
case KeyboardId.ELEMENT_ALPHABET_MANUAL_SHIFTED, KeyboardId.ELEMENT_ALPHABET_AUTOMATIC_SHIFTED,
KeyboardId.ELEMENT_ALPHABET_SHIFT_LOCKED, KeyboardId.ELEMENT_ALPHABET_SHIFT_LOCK_SHIFTED -> true;
default -> false;
};
private static boolean needsToUpcase(final int labelFlags, final KeyboardElement element) {
return (labelFlags & LABEL_FLAGS_PRESERVE_CASE) == 0 && element.isAlphabetShifted();
}

private static int computeHashCode(final Key key) {
return Arrays.hashCode(new Object[] {
return Objects.hash(
key.mX,
key.mY,
key.mWidth,
Expand All @@ -386,7 +382,7 @@ private static int computeHashCode(final Key key) {
Arrays.hashCode(key.mPopupKeys),
key.getOutputText(),
key.mActionFlags,
key.mLabelFlags,
key.mLabelFlags
// Key can be distinguishable without the following members.
// key.mOptionalAttributes.mAltCode,
// key.mOptionalAttributes.mDisabledIconId,
Expand All @@ -396,7 +392,7 @@ private static int computeHashCode(final Key key) {
// key.mOptionalAttributes.mVisualInsetLeft,
// key.mOptionalAttributes.mVisualInsetRight,
// key.mMaxPopupKeysColumn,
});
);
}

private boolean equalsInternal(final Key o) {
Expand Down Expand Up @@ -1071,16 +1067,17 @@ public KeyParams(
mHeight = params.mDefaultRowHeight;
mIconName = KeySpecParser.getIconName(keySpec);

final boolean needsToUpcase = needsToUpcase(mLabelFlags, params.mId.mElementId);
KeyboardElement element = params.mId.element;
final boolean needsToUpcase = needsToUpcase(mLabelFlags, element);
final Locale localeForUpcasing = params.mId.getLocale();
int actionFlags = 0;
if (params.mId.isNumberLayout())
if (element.isNumberLayout())
actionFlags = ACTION_FLAGS_NO_KEY_PREVIEW;

// label
String label = null;
if ((mLabelFlags & LABEL_FLAGS_FROM_CUSTOM_ACTION_LABEL) != 0) {
mLabel = params.mId.mCustomActionLabel;
mLabel = params.mId.customActionLabel;
} else if (code >= Character.MIN_SUPPLEMENTARY_CODE_POINT) {
// This is a workaround to have a key that has a supplementary code point in its label.
// Because we can put a string in resource neither as a XML entity of a supplementary
Expand Down Expand Up @@ -1153,7 +1150,7 @@ public KeyParams(
// action flags don't need to be specified, they can be deduced from the key
if (mCode == Constants.CODE_SPACE
|| mCode == KeyCode.LANGUAGE_SWITCH
|| (mCode == KeyCode.SYMBOL_ALPHA && !params.mId.isAlphabetKeyboard())
|| (mCode == KeyCode.SYMBOL_ALPHA && !element.isAlphabetLayout())
)
actionFlags |= ACTION_FLAGS_ENABLE_LONG_PRESS;
if (mCode <= Constants.CODE_SPACE && mCode != KeyCode.MULTIPLE_CODE_POINTS && mIconName == null)
Expand Down
6 changes: 3 additions & 3 deletions app/src/main/java/helium314/keyboard/keyboard/Keyboard.java
Original file line number Diff line number Diff line change
Expand Up @@ -147,9 +147,9 @@ public boolean hasProximityCharsCorrection(final int code) {
}
// Note: The native code has the main keyboard layout only at this moment.
// TODO: Figure out how to handle proximity characters information of all layouts.
final boolean canAssumeNativeHasProximityCharsInfoOfAllKeys = (
mId.mElementId == KeyboardId.ELEMENT_ALPHABET
|| mId.mElementId == KeyboardId.ELEMENT_ALPHABET_AUTOMATIC_SHIFTED);
final boolean canAssumeNativeHasProximityCharsInfoOfAllKeys =
mId.element == KeyboardElement.ALPHABET
|| mId.element == KeyboardElement.ALPHABET_AUTOMATIC_SHIFTED;
return canAssumeNativeHasProximityCharsInfoOfAllKeys || Character.isLetter(code);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ class KeyboardActionListenerImpl(private val latinIME: LatinIME, private val inp

val event: Event
if (settings.current.mLocale.language == "ko") { // todo: this does not appear to be the right place
val subtype = keyboardSwitcher.keyboard?.mId?.mSubtype ?: RichInputMethodManager.getInstance().currentSubtype
val subtype = keyboardSwitcher.keyboard?.mId?.subtype ?: RichInputMethodManager.getInstance().currentSubtype
event = HangulEventDecoder.decodeHardwareKeyEvent(subtype, keyEvent) {
getHardwareKeyEventDecoder(keyEvent.deviceId).decodeHardwareKey(keyEvent)
}
Expand Down Expand Up @@ -113,7 +113,7 @@ class KeyboardActionListenerImpl(private val latinIME: LatinIME, private val inp
// todo:
// setting meta shift should only be done for arrow and similar cursor movement keys
// should only be enabled once it works more reliably (currently depends on app for some reason)
// if (mkv.keyboard?.mId?.isAlphabetShiftedManually == true)
// if (mkv.keyboard?.mId?.element.isAlphabetShiftedManually == true)
// Event.createSoftwareKeypressEvent(primaryCode, metaState or KeyEvent.META_SHIFT_ON, mkv.getKeyX(x), mkv.getKeyY(y), isKeyRepeat)
// else Event.createSoftwareKeypressEvent(primaryCode, metaState, mkv.getKeyX(x), mkv.getKeyY(y), isKeyRepeat)
Event.createSoftwareKeypressEvent(primaryCode, metaState, mkv.getKeyX(x), mkv.getKeyY(y), isKeyRepeat)
Expand Down
Loading