some cleanup after increasing required api level

This commit is contained in:
Helium314 2024-01-18 16:27:22 +01:00
parent ffea3271f9
commit 96ad9482fb
42 changed files with 87 additions and 658 deletions

View file

@ -2,14 +2,12 @@
package org.dslul.openboard.inputmethod.compat; package org.dslul.openboard.inputmethod.compat;
import android.annotation.TargetApi;
import android.content.ClipData; import android.content.ClipData;
import android.content.ClipboardManager; import android.content.ClipboardManager;
import android.os.Build; import android.os.Build;
public class ClipboardManagerCompat { public class ClipboardManagerCompat {
@TargetApi(Build.VERSION_CODES.P)
public static void clearPrimaryClip(ClipboardManager cm) { public static void clearPrimaryClip(ClipboardManager cm) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
try { try {
@ -23,7 +21,6 @@ public class ClipboardManagerCompat {
} }
} }
@TargetApi(Build.VERSION_CODES.O)
public static Long getClipTimestamp(ClipData cd) { public static Long getClipTimestamp(ClipData cd) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
return cd.getDescription().getTimestamp(); return cd.getDescription().getTimestamp();

View file

@ -1,190 +0,0 @@
/*
* Copyright (C) 2011 The Android Open Source Project
* modified
* SPDX-License-Identifier: Apache-2.0 AND GPL-3.0-only
*/
package org.dslul.openboard.inputmethod.compat
import android.text.TextUtils
import org.dslul.openboard.inputmethod.latin.utils.Log
import java.lang.reflect.Constructor
import java.lang.reflect.Field
import java.lang.reflect.InvocationTargetException
import java.lang.reflect.Method
object CompatUtils {
private val TAG = CompatUtils::class.java.simpleName
fun getClass(className: String?): Class<*>? {
return try {
Class.forName(className!!)
} catch (e: ClassNotFoundException) {
null
}
}
fun getMethod(targetClass: Class<*>?, name: String?,
vararg parameterTypes: Class<*>?): Method? {
if (targetClass == null || TextUtils.isEmpty(name)) {
return null
}
try {
return targetClass.getMethod(name!!, *parameterTypes)
} catch (_: SecurityException) { // ignore
} catch (_: NoSuchMethodException) {
}
return null
}
fun getField(targetClass: Class<*>?, name: String?): Field? {
if (targetClass == null || TextUtils.isEmpty(name)) {
return null
}
try {
return targetClass.getField(name!!)
} catch (_: SecurityException) { // ignore
} catch (_: NoSuchFieldException) {
}
return null
}
fun getConstructor(targetClass: Class<*>?,
vararg types: Class<*>?): Constructor<*>? {
if (targetClass == null || types == null) {
return null
}
try {
return targetClass.getConstructor(*types)
} catch (_: SecurityException) { // ignore
} catch (_: NoSuchMethodException) {
}
return null
}
fun newInstance(constructor: Constructor<*>?, vararg args: Any?): Any? {
if (constructor == null) {
return null
}
try {
return constructor.newInstance(*args)
} catch (e: InstantiationException) {
Log.e(TAG, "Exception in newInstance", e)
} catch (e: IllegalAccessException) {
Log.e(TAG, "Exception in newInstance", e)
} catch (e: IllegalArgumentException) {
Log.e(TAG, "Exception in newInstance", e)
} catch (e: InvocationTargetException) {
Log.e(TAG, "Exception in newInstance", e)
}
return null
}
operator fun invoke(receiver: Any?, defaultValue: Any?,
method: Method?, vararg args: Any?): Any? {
if (method == null) {
return defaultValue
}
try {
return method.invoke(receiver, *args)
} catch (e: IllegalAccessException) {
Log.e(TAG, "Exception in invoke", e)
} catch (e: IllegalArgumentException) {
Log.e(TAG, "Exception in invoke", e)
} catch (e: InvocationTargetException) {
Log.e(TAG, "Exception in invoke", e)
}
return defaultValue
}
fun getFieldValue(receiver: Any?, defaultValue: Any?,
field: Field?): Any? {
if (field == null) {
return defaultValue
}
try {
return field[receiver]
} catch (e: IllegalAccessException) {
Log.e(TAG, "Exception in getFieldValue", e)
} catch (e: IllegalArgumentException) {
Log.e(TAG, "Exception in getFieldValue", e)
}
return defaultValue
}
fun setFieldValue(receiver: Any?, field: Field?, value: Any?) {
if (field == null) {
return
}
try {
field[receiver] = value
} catch (e: IllegalAccessException) {
Log.e(TAG, "Exception in setFieldValue", e)
} catch (e: IllegalArgumentException) {
Log.e(TAG, "Exception in setFieldValue", e)
}
}
fun getClassWrapper(className: String?): ClassWrapper {
return ClassWrapper(getClass(className))
}
class ClassWrapper(private val mClass: Class<*>?) {
fun exists(): Boolean {
return mClass != null
}
fun <T> getMethod(name: String?,
defaultValue: T, vararg parameterTypes: Class<*>?): ToObjectMethodWrapper<T> {
return ToObjectMethodWrapper(getMethod(mClass, name, *parameterTypes),
defaultValue)
}
fun getPrimitiveMethod(name: String?, defaultValue: Int,
vararg parameterTypes: Class<*>?): ToIntMethodWrapper {
return ToIntMethodWrapper(getMethod(mClass, name, *parameterTypes),
defaultValue)
}
fun getPrimitiveMethod(name: String?, defaultValue: Float,
vararg parameterTypes: Class<*>?): ToFloatMethodWrapper {
return ToFloatMethodWrapper(getMethod(mClass, name, *parameterTypes),
defaultValue)
}
fun getPrimitiveMethod(name: String?,
defaultValue: Boolean, vararg parameterTypes: Class<*>?): ToBooleanMethodWrapper {
return ToBooleanMethodWrapper(getMethod(mClass, name, *parameterTypes),
defaultValue)
}
}
@Suppress("unchecked_cast")
class ToObjectMethodWrapper<T>(private val mMethod: Method?, private val mDefaultValue: T) {
operator fun invoke(receiver: Any?, vararg args: Any?): T {
return CompatUtils.invoke(receiver, mDefaultValue, mMethod, *args) as T
}
}
class ToIntMethodWrapper(private val mMethod: Method?, private val mDefaultValue: Int) {
operator fun invoke(receiver: Any?, vararg args: Any?): Int {
return CompatUtils.invoke(receiver, mDefaultValue, mMethod, *args) as Int
}
}
class ToFloatMethodWrapper(private val mMethod: Method?, private val mDefaultValue: Float) {
operator fun invoke(receiver: Any?, vararg args: Any?): Float {
return CompatUtils.invoke(receiver, mDefaultValue, mMethod, *args) as Float
}
}
class ToBooleanMethodWrapper(private val mMethod: Method?, private val mDefaultValue: Boolean) {
operator fun invoke(receiver: Any?, vararg args: Any?): Boolean {
return CompatUtils.invoke(receiver, mDefaultValue, mMethod, *args) as Boolean
}
}
}

View file

@ -1,164 +0,0 @@
/*
* Copyright (C) 2014 The Android Open Source Project
* modified
* SPDX-License-Identifier: Apache-2.0 AND GPL-3.0-only
*/
package org.dslul.openboard.inputmethod.compat
import android.annotation.TargetApi
import android.graphics.Matrix
import android.graphics.RectF
import android.os.Build
import android.os.Build.VERSION_CODES
import android.view.inputmethod.CursorAnchorInfo
/**
* A wrapper for [CursorAnchorInfo], which has been introduced in API Level 21. You can use
* this wrapper to avoid direct dependency on newly introduced types.
*/
open class CursorAnchorInfoCompatWrapper internal constructor() {
open val selectionStart: Int
get() {
throw UnsupportedOperationException("not supported.")
}
open val selectionEnd: Int
get() {
throw UnsupportedOperationException("not supported.")
}
open val composingText: CharSequence?
get() {
throw UnsupportedOperationException("not supported.")
}
open val composingTextStart: Int
get() {
throw UnsupportedOperationException("not supported.")
}
open val matrix: Matrix?
get() {
throw UnsupportedOperationException("not supported.")
}
open fun getCharacterBounds(index: Int): RectF? {
throw UnsupportedOperationException("not supported.")
}
open fun getCharacterBoundsFlags(index: Int): Int {
throw UnsupportedOperationException("not supported.")
}
open val insertionMarkerBaseline: Float
get() {
throw UnsupportedOperationException("not supported.")
}
open val insertionMarkerBottom: Float
get() {
throw UnsupportedOperationException("not supported.")
}
open val insertionMarkerHorizontal: Float
get() {
throw UnsupportedOperationException("not supported.")
}
open val insertionMarkerTop: Float
get() {
throw UnsupportedOperationException("not supported.")
}
open val insertionMarkerFlags: Int
get() {
throw UnsupportedOperationException("not supported.")
}
@TargetApi(VERSION_CODES.LOLLIPOP)
private class RealWrapper(private val mInstance: CursorAnchorInfo) : CursorAnchorInfoCompatWrapper() {
override val selectionStart: Int
get() {
return mInstance.selectionStart
}
override val selectionEnd: Int
get() {
return mInstance.selectionEnd
}
override val composingText: CharSequence?
get() {
return mInstance.composingText
}
override val composingTextStart: Int
get() {
return mInstance.composingTextStart
}
override val matrix: Matrix?
get() {
return mInstance.matrix
}
override fun getCharacterBounds(index: Int): RectF? {
return mInstance.getCharacterBounds(index)
}
override fun getCharacterBoundsFlags(index: Int): Int {
return mInstance.getCharacterBoundsFlags(index)
}
override val insertionMarkerBaseline: Float
get() {
return mInstance.insertionMarkerBaseline
}
override val insertionMarkerBottom: Float
get() {
return mInstance.insertionMarkerBottom
}
override val insertionMarkerHorizontal: Float
get() {
return mInstance.insertionMarkerHorizontal
}
override val insertionMarkerTop: Float
get() {
return mInstance.insertionMarkerTop
}
override val insertionMarkerFlags: Int
get() {
return mInstance.insertionMarkerFlags
}
}
companion object {
/**
* The insertion marker or character bounds have at least one visible region.
*/
const val FLAG_HAS_VISIBLE_REGION = 0x01
/**
* The insertion marker or character bounds have at least one invisible (clipped) region.
*/
const val FLAG_HAS_INVISIBLE_REGION = 0x02
/**
* The insertion marker or character bounds is placed at right-to-left (RTL) character.
*/
const val FLAG_IS_RTL = 0x04
@JvmStatic
@TargetApi(VERSION_CODES.LOLLIPOP)
fun wrap(instance: CursorAnchorInfo?): CursorAnchorInfoCompatWrapper? {
return if (Build.VERSION.SDK_INT < VERSION_CODES.LOLLIPOP) {
null
} else instance?.let { RealWrapper(it) }
}
}
}

View file

@ -14,18 +14,13 @@ import org.dslul.openboard.inputmethod.latin.utils.locale
import java.util.* import java.util.*
object InputMethodSubtypeCompatUtils { object InputMethodSubtypeCompatUtils {
// Note that InputMethodSubtype.getLanguageTag() is expected to be available in Android N+.
private val GET_LANGUAGE_TAG = CompatUtils.getMethod(InputMethodSubtype::class.java, "getLanguageTag")
@JvmStatic @JvmStatic
fun getLocaleObject(subtype: InputMethodSubtype): Locale { // Locale.forLanguageTag() is available only in Android L and later. fun getLocaleObject(subtype: InputMethodSubtype): Locale { // Locale.forLanguageTag() is available only in Android L and later.
if (Build.VERSION.SDK_INT >= VERSION_CODES.LOLLIPOP) { if (Build.VERSION.SDK_INT >= VERSION_CODES.N) {
val languageTag = CompatUtils.invoke(subtype, null, GET_LANGUAGE_TAG) as String? val languageTag = subtype.languageTag
if (!languageTag.isNullOrEmpty()) { if (languageTag.isNotEmpty())
return Locale.forLanguageTag(languageTag) return Locale.forLanguageTag(languageTag)
} }
}
return LocaleUtils.constructLocaleFromString(subtype.locale()) return LocaleUtils.constructLocaleFromString(subtype.locale())
} }
} }

View file

@ -14,6 +14,7 @@ import android.text.style.SuggestionSpan
import org.dslul.openboard.inputmethod.annotations.UsedForTesting import org.dslul.openboard.inputmethod.annotations.UsedForTesting
import java.util.* import java.util.*
// todo: this is not compat any more
object SuggestionSpanUtils { object SuggestionSpanUtils {
@JvmStatic @JvmStatic
@UsedForTesting @UsedForTesting

View file

@ -1,47 +0,0 @@
/*
* Copyright (C) 2014 The Android Open Source Project
* modified
* SPDX-License-Identifier: Apache-2.0 AND GPL-3.0-only
*/
package org.dslul.openboard.inputmethod.compat
import android.os.Build
import android.view.textservice.TextInfo
import org.dslul.openboard.inputmethod.annotations.UsedForTesting
object TextInfoCompatUtils {
// Note that TextInfo.getCharSequence() is supposed to be available in API level 21 and later.
private val TEXT_INFO_GET_CHAR_SEQUENCE = CompatUtils.getMethod(TextInfo::class.java, "getCharSequence")
@get:UsedForTesting
val isCharSequenceSupported: Boolean
get() = TEXT_INFO_GET_CHAR_SEQUENCE != null
@JvmStatic
@UsedForTesting
fun newInstance(charSequence: CharSequence, start: Int, end: Int, cookie: Int,
sequenceNumber: Int): TextInfo {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP)
return TextInfo(charSequence, start, end, cookie, sequenceNumber)
return TextInfo(charSequence.subSequence(start, end).toString(), cookie, sequenceNumber)
}
/**
* Returns the result of [TextInfo.getCharSequence] when available. Otherwise returns
* the result of [TextInfo.getText] as fall back.
* @param textInfo the instance for which [TextInfo.getCharSequence] or
* [TextInfo.getText] is called.
* @return the result of [TextInfo.getCharSequence] when available. Otherwise returns
* the result of [TextInfo.getText] as fall back. If `textInfo` is `null`,
* returns `null`.
*/
@JvmStatic
@UsedForTesting
fun getCharSequenceOrString(textInfo: TextInfo): CharSequence {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP)
return textInfo.charSequence
val defaultValue = textInfo.text
return CompatUtils.invoke(textInfo, defaultValue, TEXT_INFO_GET_CHAR_SEQUENCE) as CharSequence
}
}

View file

@ -6,24 +6,44 @@
package org.dslul.openboard.inputmethod.compat package org.dslul.openboard.inputmethod.compat
import android.graphics.Outline
import android.inputmethodservice.InputMethodService import android.inputmethodservice.InputMethodService
import android.os.Build
import android.os.Build.VERSION_CODES
import android.view.View import android.view.View
import android.view.ViewOutlineProvider
// todo: this is not compat any more
object ViewOutlineProviderCompatUtils { object ViewOutlineProviderCompatUtils {
private val EMPTY_INSETS_UPDATER: InsetsUpdater = object : InsetsUpdater {
override fun setInsets(insets: InputMethodService.Insets) {}
}
@JvmStatic @JvmStatic
fun setInsetsOutlineProvider(view: View): InsetsUpdater { fun setInsetsOutlineProvider(view: View): InsetsOutlineProvider {
return if (Build.VERSION.SDK_INT < VERSION_CODES.LOLLIPOP) { val provider = InsetsOutlineProvider(view)
EMPTY_INSETS_UPDATER view.outlineProvider = provider
} else ViewOutlineProviderCompatUtilsLXX.setInsetsOutlineProvider(view) return provider
} }
}
interface InsetsUpdater {
fun setInsets(insets: InputMethodService.Insets) class InsetsOutlineProvider(private val mView: View) : ViewOutlineProvider() {
private var mLastVisibleTopInsets = NO_DATA
init {
mView.outlineProvider = this
}
fun setInsets(insets: InputMethodService.Insets) {
val visibleTopInsets = insets.visibleTopInsets
if (mLastVisibleTopInsets != visibleTopInsets) {
mLastVisibleTopInsets = visibleTopInsets
mView.invalidateOutline()
}
}
override fun getOutline(view: View, outline: Outline) {
if (mLastVisibleTopInsets == NO_DATA) { // Call default implementation.
BACKGROUND.getOutline(view, outline)
return
}
// TODO: Revisit this when floating/resize keyboard is supported.
outline.setRect(view.left, mLastVisibleTopInsets, view.right, view.bottom)
}
companion object {
private const val NO_DATA = -1
} }
} }

View file

@ -1,52 +0,0 @@
/*
* Copyright (C) 2014 The Android Open Source Project
* modified
* SPDX-License-Identifier: Apache-2.0 AND GPL-3.0-only
*/
package org.dslul.openboard.inputmethod.compat
import android.graphics.Outline
import android.inputmethodservice.InputMethodService
import android.os.Build
import android.view.View
import android.view.ViewOutlineProvider
import androidx.annotation.RequiresApi
import org.dslul.openboard.inputmethod.compat.ViewOutlineProviderCompatUtils.InsetsUpdater
@RequiresApi(Build.VERSION_CODES.LOLLIPOP)
internal object ViewOutlineProviderCompatUtilsLXX {
fun setInsetsOutlineProvider(view: View): InsetsUpdater {
val provider = InsetsOutlineProvider(view)
view.outlineProvider = provider
return provider
}
private class InsetsOutlineProvider(private val mView: View) : ViewOutlineProvider(), InsetsUpdater {
private var mLastVisibleTopInsets = NO_DATA
override fun setInsets(insets: InputMethodService.Insets) {
val visibleTopInsets = insets.visibleTopInsets
if (mLastVisibleTopInsets != visibleTopInsets) {
mLastVisibleTopInsets = visibleTopInsets
mView.invalidateOutline()
}
}
override fun getOutline(view: View, outline: Outline) {
if (mLastVisibleTopInsets == NO_DATA) { // Call default implementation.
BACKGROUND.getOutline(view, outline)
return
}
// TODO: Revisit this when floating/resize keyboard is supported.
outline.setRect(view.left, mLastVisibleTopInsets, view.right, view.bottom)
}
companion object {
private const val NO_DATA = -1
}
init {
mView.outlineProvider = this
}
}
}

View file

@ -23,7 +23,7 @@ import org.dslul.openboard.inputmethod.latin.utils.DeviceProtectedUtils;
import java.util.Arrays; import java.util.Arrays;
public final class KeyboardTheme implements Comparable<KeyboardTheme> { public final class KeyboardTheme {
// old themes // old themes
public static final String STYLE_MATERIAL = "Material"; public static final String STYLE_MATERIAL = "Material";
@ -59,43 +59,23 @@ public final class KeyboardTheme implements Comparable<KeyboardTheme> {
/* package private for testing */ /* package private for testing */
static final KeyboardTheme[] KEYBOARD_THEMES = { static final KeyboardTheme[] KEYBOARD_THEMES = {
new KeyboardTheme(THEME_ID_HOLO_BASE, "HoloBase", R.style.KeyboardTheme_HoloBase, new KeyboardTheme(THEME_ID_HOLO_BASE, "HoloBase", R.style.KeyboardTheme_HoloBase),
VERSION_CODES.BASE), new KeyboardTheme(THEME_ID_LXX_BASE, "LXXBase", R.style.KeyboardTheme_LXX_Base),
new KeyboardTheme(THEME_ID_LXX_BASE, "LXXBase", R.style.KeyboardTheme_LXX_Base, new KeyboardTheme(THEME_ID_LXX_BASE_BORDER, "LXXBaseBorder", R.style.KeyboardTheme_LXX_Base_Border),
VERSION_CODES.LOLLIPOP), new KeyboardTheme(THEME_ID_ROUNDED_BASE, "RoundedBase", R.style.KeyboardTheme_Rounded_Base),
new KeyboardTheme(THEME_ID_LXX_BASE_BORDER, "LXXBaseBorder", R.style.KeyboardTheme_LXX_Base_Border, new KeyboardTheme(THEME_ID_ROUNDED_BASE_BORDER, "RoundedBaseBorder", R.style.KeyboardTheme_Rounded_Base_Border)
VERSION_CODES.LOLLIPOP),
new KeyboardTheme(THEME_ID_ROUNDED_BASE, "RoundedBase", R.style.KeyboardTheme_Rounded_Base,
VERSION_CODES.LOLLIPOP),
new KeyboardTheme(THEME_ID_ROUNDED_BASE_BORDER, "RoundedBaseBorder", R.style.KeyboardTheme_Rounded_Base_Border,
VERSION_CODES.LOLLIPOP)
}; };
static {
// Sort {@link #KEYBOARD_THEME} by descending order of {@link #mMinApiVersion}.
Arrays.sort(KEYBOARD_THEMES);
}
public final int mThemeId; public final int mThemeId;
public final int mStyleId; public final int mStyleId;
public final String mThemeName; public final String mThemeName;
public final int mMinApiVersion;
// Note: The themeId should be aligned with "themeId" attribute of Keyboard style // Note: The themeId should be aligned with "themeId" attribute of Keyboard style
// in values/themes-<style>.xml. // in values/themes-<style>.xml.
private KeyboardTheme(final int themeId, final String themeName, final int styleId, private KeyboardTheme(final int themeId, final String themeName, final int styleId) {
final int minApiVersion) {
mThemeId = themeId; mThemeId = themeId;
mThemeName = themeName; mThemeName = themeName;
mStyleId = styleId; mStyleId = styleId;
mMinApiVersion = minApiVersion;
}
@Override
public int compareTo(final KeyboardTheme rhs) {
if (mMinApiVersion > rhs.mMinApiVersion) return -1;
if (mMinApiVersion < rhs.mMinApiVersion) return 1;
return 0;
} }
@Override @Override

View file

@ -672,10 +672,9 @@ abstract class KeyboardParser(private val params: KeyboardParams, private val co
} }
// crappy workaround... // crappy workaround...
val locale = when (params.mId.locale.toString().lowercase()) { val locale = when (params.mId.locale.toString().lowercase()) {
// todo: improve this when switching (rich input) subtype to use language tag
"hi_zz" -> Locale("en", "IN") "hi_zz" -> Locale("en", "IN")
"sr_zz" -> if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) "sr_zz" -> Locale.forLanguageTag("sr-Latn")
Locale.forLanguageTag("sr-Latn")
else params.mId.locale // todo: copy strings to sr-rZZ when definitely not increasing min SDK to 21
else -> params.mId.locale else -> params.mId.locale
} }
return ril.runInLocale(context.resources, locale) return ril.runInLocale(context.resources, locale)

View file

@ -42,8 +42,8 @@ import android.view.inputmethod.InputMethodSubtype;
import org.dslul.openboard.inputmethod.accessibility.AccessibilityUtils; import org.dslul.openboard.inputmethod.accessibility.AccessibilityUtils;
import org.dslul.openboard.inputmethod.annotations.UsedForTesting; import org.dslul.openboard.inputmethod.annotations.UsedForTesting;
import org.dslul.openboard.inputmethod.compat.EditorInfoCompatUtils; import org.dslul.openboard.inputmethod.compat.EditorInfoCompatUtils;
import org.dslul.openboard.inputmethod.compat.InsetsOutlineProvider;
import org.dslul.openboard.inputmethod.compat.ViewOutlineProviderCompatUtils; import org.dslul.openboard.inputmethod.compat.ViewOutlineProviderCompatUtils;
import org.dslul.openboard.inputmethod.compat.ViewOutlineProviderCompatUtils.InsetsUpdater;
import org.dslul.openboard.inputmethod.dictionarypack.DictionaryPackConstants; import org.dslul.openboard.inputmethod.dictionarypack.DictionaryPackConstants;
import org.dslul.openboard.inputmethod.event.Event; import org.dslul.openboard.inputmethod.event.Event;
import org.dslul.openboard.inputmethod.event.HangulEventDecoder; import org.dslul.openboard.inputmethod.event.HangulEventDecoder;
@ -142,7 +142,7 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
// TODO: Move these {@link View}s to {@link KeyboardSwitcher}. // TODO: Move these {@link View}s to {@link KeyboardSwitcher}.
private View mInputView; private View mInputView;
private InsetsUpdater mInsetsUpdater; private InsetsOutlineProvider mInsetsUpdater;
private SuggestionStripView mSuggestionStripView; private SuggestionStripView mSuggestionStripView;
private RichInputMethodManager mRichImm; private RichInputMethodManager mRichImm;
@ -2006,9 +2006,10 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
} }
// slightly modified from Simple Keyboard: https://github.com/rkkr/simple-keyboard/blob/master/app/src/main/java/rkr/simplekeyboard/inputmethod/latin/LatinIME.java // slightly modified from Simple Keyboard: https://github.com/rkkr/simple-keyboard/blob/master/app/src/main/java/rkr/simplekeyboard/inputmethod/latin/LatinIME.java
@SuppressWarnings("deprecation")
private void setNavigationBarColor() { private void setNavigationBarColor() {
final SettingsValues settingsValues = mSettings.getCurrent(); final SettingsValues settingsValues = mSettings.getCurrent();
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP || !settingsValues.mCustomNavBarColor) if (!settingsValues.mCustomNavBarColor)
return; return;
final int color = settingsValues.mColors.get(ColorType.NAVIGATION_BAR); final int color = settingsValues.mColors.get(ColorType.NAVIGATION_BAR);
final Window window = getWindow().getWindow(); final Window window = getWindow().getWindow();
@ -2031,7 +2032,7 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
@SuppressWarnings("deprecation") @SuppressWarnings("deprecation")
private void clearNavigationBarColor() { private void clearNavigationBarColor() {
final SettingsValues settingsValues = mSettings.getCurrent(); final SettingsValues settingsValues = mSettings.getCurrent();
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP || !settingsValues.mCustomNavBarColor) if (!settingsValues.mCustomNavBarColor)
return; return;
final Window window = getWindow().getWindow(); final Window window = getWindow().getWindow();
if (window == null) { if (window == null) {

View file

@ -1176,14 +1176,11 @@ public final class RichInputConnection implements PrivateCommandPerformer {
* prevents the application from fulfilling the request. (TODO: Improve the API when it turns * prevents the application from fulfilling the request. (TODO: Improve the API when it turns
* out that we actually need more detailed error codes) * out that we actually need more detailed error codes)
*/ */
public boolean requestCursorUpdates(final boolean enableMonitor, public boolean requestCursorUpdates(final boolean enableMonitor, final boolean requestImmediateCallback) {
final boolean requestImmediateCallback) {
mIC = mParent.getCurrentInputConnection(); mIC = mParent.getCurrentInputConnection();
if (!isConnected()) { if (!isConnected()) {
return false; return false;
} }
if (android.os.Build.VERSION.SDK_INT < android.os.Build.VERSION_CODES.LOLLIPOP)
return false;
final int cursorUpdateMode = (enableMonitor ? InputConnection.CURSOR_UPDATE_MONITOR : 0) final int cursorUpdateMode = (enableMonitor ? InputConnection.CURSOR_UPDATE_MONITOR : 0)
| (requestImmediateCallback ? InputConnection.CURSOR_UPDATE_IMMEDIATE : 0); | (requestImmediateCallback ? InputConnection.CURSOR_UPDATE_IMMEDIATE : 0);
return mIC.requestCursorUpdates(cursorUpdateMode); return mIC.requestCursorUpdates(cursorUpdateMode);

View file

@ -33,6 +33,7 @@ import androidx.annotation.Nullable;
public class RichInputMethodSubtype { public class RichInputMethodSubtype {
private static final String TAG = RichInputMethodSubtype.class.getSimpleName(); private static final String TAG = RichInputMethodSubtype.class.getSimpleName();
// todo: remove this map when switching (rich input) subtype to use language tag
private static final HashMap<Locale, Locale> sLocaleMap = initializeLocaleMap(); private static final HashMap<Locale, Locale> sLocaleMap = initializeLocaleMap();
private static HashMap<Locale, Locale> initializeLocaleMap() { private static HashMap<Locale, Locale> initializeLocaleMap() {
final HashMap<Locale, Locale> map = new HashMap<>(); final HashMap<Locale, Locale> map = new HashMap<>();

View file

@ -90,11 +90,10 @@ public class SuggestedWords {
/** /**
* Get suggested word to show as suggestions to UI. * Get suggested word to show as suggestions to UI.
* *
* @param shouldShowLxxSuggestionUi true if showing suggestion UI introduced in LXX and later.
* @return the count of suggested word to show as suggestions to UI. * @return the count of suggested word to show as suggestions to UI.
*/ */
public int getWordCountToShow(final boolean shouldShowLxxSuggestionUi) { public int getWordCountToShow() {
if (isPrediction() || !shouldShowLxxSuggestionUi) { if (isPrediction()) {
return size(); return size();
} }
return size() - /* typed word */ 1; return size() - /* typed word */ 1;

View file

@ -155,11 +155,8 @@ public final class InputLogic {
} else { } else {
mInputLogicHandler.reset(); mInputLogicHandler.reset();
} }
if (settingsValues.mShouldShowLxxSuggestionUi) {
mConnection.requestCursorUpdates(true, true); mConnection.requestCursorUpdates(true, true);
} }
}
/** /**
* Call this when the subtype changes. * Call this when the subtype changes.

View file

@ -7,8 +7,6 @@ package org.dslul.openboard.inputmethod.latin.settings
import android.app.Activity import android.app.Activity
import android.content.Intent import android.content.Intent
import android.graphics.Color
import android.os.Build
import android.os.Bundle import android.os.Bundle
import android.text.method.LinkMovementMethod import android.text.method.LinkMovementMethod
import android.view.View import android.view.View
@ -16,7 +14,6 @@ import android.widget.TextView
import android.widget.Toast import android.widget.Toast
import androidx.activity.result.contract.ActivityResultContracts import androidx.activity.result.contract.ActivityResultContracts
import androidx.appcompat.app.AlertDialog import androidx.appcompat.app.AlertDialog
import androidx.core.graphics.drawable.DrawableCompat
import androidx.preference.Preference import androidx.preference.Preference
import org.dslul.openboard.inputmethod.latin.BuildConfig import org.dslul.openboard.inputmethod.latin.BuildConfig
import org.dslul.openboard.inputmethod.latin.R import org.dslul.openboard.inputmethod.latin.R
@ -31,15 +28,6 @@ class AboutFragment : SubScreenFragment() {
super.onCreate(icicle) super.onCreate(icicle)
addPreferencesFromResource(R.xml.prefs_screen_about) addPreferencesFromResource(R.xml.prefs_screen_about)
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) {
// need to set icon tint because old android versions don't use the vector drawables
for (i in 0 until preferenceScreen.preferenceCount) {
val p = preferenceScreen.getPreference(0)
val icon = p.icon
if (icon != null) DrawableCompat.setTint(icon, Color.WHITE)
}
}
setupHiddenFeatures() setupHiddenFeatures()
setupVersionPref() setupVersionPref()
findPreference<Preference>("log_reader")?.setOnPreferenceClickListener { findPreference<Preference>("log_reader")?.setOnPreferenceClickListener {

View file

@ -120,11 +120,7 @@ class AdvancedSettingsFragment : SubScreenFragment() {
private fun onClickLoadLibrary(): Boolean { private fun onClickLoadLibrary(): Boolean {
// get architecture for telling user which file to use // get architecture for telling user which file to use
val abi = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { val abi = Build.SUPPORTED_ABIS[0]
Build.SUPPORTED_ABIS[0]
} else {
@Suppress("Deprecation") Build.CPU_ABI
}
// show delete / add dialog // show delete / add dialog
val builder = AlertDialog.Builder(requireContext()) val builder = AlertDialog.Builder(requireContext())
.setTitle(R.string.load_gesture_library) .setTitle(R.string.load_gesture_library)
@ -161,11 +157,7 @@ class AdvancedSettingsFragment : SubScreenFragment() {
if (checksum == JniUtils.expectedDefaultChecksum()) { if (checksum == JniUtils.expectedDefaultChecksum()) {
renameToLibfileAndRestart(tmpfile, checksum) renameToLibfileAndRestart(tmpfile, checksum)
} else { } else {
val abi = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { val abi = Build.SUPPORTED_ABIS[0]
Build.SUPPORTED_ABIS[0]
} else {
@Suppress("Deprecation") Build.CPU_ABI
}
AlertDialog.Builder(requireContext()) AlertDialog.Builder(requireContext())
.setMessage(getString(R.string.checksum_mismatch_message, abi)) .setMessage(getString(R.string.checksum_mismatch_message, abi))
.setPositiveButton(android.R.string.ok) { _, _ -> renameToLibfileAndRestart(tmpfile, checksum) } .setPositiveButton(android.R.string.ok) { _, _ -> renameToLibfileAndRestart(tmpfile, checksum) }

View file

@ -12,7 +12,6 @@ import androidx.preference.TwoStatePreference
import org.dslul.openboard.inputmethod.keyboard.KeyboardSwitcher import org.dslul.openboard.inputmethod.keyboard.KeyboardSwitcher
import org.dslul.openboard.inputmethod.keyboard.KeyboardTheme import org.dslul.openboard.inputmethod.keyboard.KeyboardTheme
import org.dslul.openboard.inputmethod.latin.R import org.dslul.openboard.inputmethod.latin.R
import org.dslul.openboard.inputmethod.latin.define.ProductionFlags
import java.lang.Float.max import java.lang.Float.max
import java.lang.Float.min import java.lang.Float.min
import java.util.* import java.util.*
@ -79,10 +78,6 @@ class AppearanceSettingsFragment : SubScreenFragment() {
removePreference("theme_select_colors_night") removePreference("theme_select_colors_night")
} }
} }
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) {
// todo: consider removing the preference, and always set the navbar color
removePreference(Settings.PREF_NAVBAR_COLOR)
}
val metrics = requireContext().resources.displayMetrics val metrics = requireContext().resources.displayMetrics
val widthDp = metrics.widthPixels / metrics.density val widthDp = metrics.widthPixels / metrics.density
val heightDp = metrics.heightPixels / metrics.density val heightDp = metrics.heightPixels / metrics.density

View file

@ -12,7 +12,6 @@ package org.dslul.openboard.inputmethod.latin.settings;
public final class DebugSettings { public final class DebugSettings {
public static final String PREF_DEBUG_MODE = "debug_mode"; public static final String PREF_DEBUG_MODE = "debug_mode";
public static final String PREF_FORCE_NON_DISTINCT_MULTITOUCH = "force_non_distinct_multitouch"; public static final String PREF_FORCE_NON_DISTINCT_MULTITOUCH = "force_non_distinct_multitouch";
public static final String PREF_SHOULD_SHOW_LXX_SUGGESTION_UI = "pref_should_show_lxx_suggestion_ui";
public static final String PREF_SLIDING_KEY_INPUT_PREVIEW = "pref_sliding_key_input_preview"; public static final String PREF_SLIDING_KEY_INPUT_PREVIEW = "pref_sliding_key_input_preview";
public static final String PREF_SHOW_DEBUG_SETTINGS = "pref_show_debug_settings"; public static final String PREF_SHOW_DEBUG_SETTINGS = "pref_show_debug_settings";

View file

@ -40,10 +40,6 @@ public final class DebugSettingsFragment extends SubScreenFragment
super.onCreate(icicle); super.onCreate(icicle);
addPreferencesFromResource(R.xml.prefs_screen_debug); addPreferencesFromResource(R.xml.prefs_screen_debug);
if (!Settings.SHOULD_SHOW_LXX_SUGGESTION_UI) {
removePreference(DebugSettings.PREF_SHOULD_SHOW_LXX_SUGGESTION_UI);
}
final PreferenceGroup dictDumpPreferenceGroup = findPreference(PREF_KEY_DUMP_DICTS); final PreferenceGroup dictDumpPreferenceGroup = findPreference(PREF_KEY_DUMP_DICTS);
for (final String dictName : DictionaryFacilitatorImpl.DICT_TYPE_TO_CLASS.keySet()) { for (final String dictName : DictionaryFacilitatorImpl.DICT_TYPE_TO_CLASS.keySet()) {
final Preference pref = new DictDumpPreference(getActivity(), dictName); final Preference pref = new DictDumpPreference(getActivity(), dictName);

View file

@ -13,8 +13,8 @@ import android.view.View
import android.view.ViewGroup import android.view.ViewGroup
import android.widget.EditText import android.widget.EditText
import android.widget.LinearLayout import android.widget.LinearLayout
import android.widget.Switch
import android.widget.TextView import android.widget.TextView
import androidx.appcompat.widget.SwitchCompat
import androidx.core.view.isGone import androidx.core.view.isGone
import androidx.core.view.isVisible import androidx.core.view.isVisible
import androidx.core.widget.doAfterTextChanged import androidx.core.widget.doAfterTextChanged
@ -114,7 +114,7 @@ private class LanguageAdapter(list: List<MutableList<SubtypeInfo>> = listOf(), c
else isVisible = true else isVisible = true
} }
view.findViewById<SwitchCompat>(R.id.language_switch).apply { view.findViewById<Switch>(R.id.language_switch).apply {
isEnabled = !onlySystemLocales isEnabled = !onlySystemLocales
// take care: isChecked changes if the language is scrolled out of view and comes back! // take care: isChecked changes if the language is scrolled out of view and comes back!
// disable the change listener when setting the checked status on scroll // disable the change listener when setting the checked status on scroll

View file

@ -11,9 +11,9 @@ import android.view.LayoutInflater
import android.view.View import android.view.View
import android.widget.ImageView import android.widget.ImageView
import android.widget.ScrollView import android.widget.ScrollView
import android.widget.Switch
import android.widget.TextView import android.widget.TextView
import androidx.appcompat.app.AlertDialog import androidx.appcompat.app.AlertDialog
import androidx.appcompat.widget.SwitchCompat
import androidx.core.view.get import androidx.core.view.get
import androidx.core.view.isGone import androidx.core.view.isGone
import androidx.core.view.isVisible import androidx.core.view.isVisible
@ -170,7 +170,7 @@ class LanguageSettingsDialog(
} else { } else {
row.findViewById<View>(R.id.language_details).isGone = true row.findViewById<View>(R.id.language_details).isGone = true
} }
row.findViewById<SwitchCompat>(R.id.language_switch).apply { row.findViewById<Switch>(R.id.language_switch).apply {
isChecked = subtype.isEnabled isChecked = subtype.isEnabled
isEnabled = !onlySystemLocales isEnabled = !onlySystemLocales
setOnCheckedChangeListener { _, b -> setOnCheckedChangeListener { _, b ->
@ -186,7 +186,7 @@ class LanguageSettingsDialog(
} }
} }
if (isAdditionalSubtype(subtype.subtype)) { if (isAdditionalSubtype(subtype.subtype)) {
row.findViewById<SwitchCompat>(R.id.language_switch).isEnabled = true row.findViewById<Switch>(R.id.language_switch).isEnabled = true
row.findViewById<ImageView>(R.id.delete_button).apply { row.findViewById<ImageView>(R.id.delete_button).apply {
isVisible = true isVisible = true
setOnClickListener { setOnClickListener {

View file

@ -12,9 +12,9 @@ import android.view.LayoutInflater
import android.view.View import android.view.View
import android.view.ViewGroup import android.view.ViewGroup
import android.view.inputmethod.InputMethodSubtype import android.view.inputmethod.InputMethodSubtype
import android.widget.Switch
import androidx.activity.result.contract.ActivityResultContracts import androidx.activity.result.contract.ActivityResultContracts
import androidx.appcompat.app.AppCompatActivity import androidx.appcompat.app.AppCompatActivity
import androidx.appcompat.widget.SwitchCompat
import androidx.core.content.edit import androidx.core.content.edit
import androidx.fragment.app.Fragment import androidx.fragment.app.Fragment
import org.dslul.openboard.inputmethod.latin.R import org.dslul.openboard.inputmethod.latin.R
@ -37,7 +37,7 @@ class LanguageSettingsFragment : Fragment(R.layout.language_settings) {
private val systemLocales = mutableListOf<Locale>() private val systemLocales = mutableListOf<Locale>()
private lateinit var languageFilterList: LanguageFilterList private lateinit var languageFilterList: LanguageFilterList
private lateinit var sharedPreferences: SharedPreferences private lateinit var sharedPreferences: SharedPreferences
private lateinit var systemOnlySwitch: SwitchCompat private lateinit var systemOnlySwitch: Switch
private val dictionaryLocales by lazy { getDictionaryLocales(requireContext()).mapTo(HashSet()) { it.languageConsideringZZ() } } private val dictionaryLocales by lazy { getDictionaryLocales(requireContext()).mapTo(HashSet()) { it.languageConsideringZZ() } }
private val dictionaryFilePicker = registerForActivityResult(ActivityResultContracts.StartActivityForResult()) { private val dictionaryFilePicker = registerForActivityResult(ActivityResultContracts.StartActivityForResult()) {

View file

@ -9,14 +9,10 @@ package org.dslul.openboard.inputmethod.latin.settings;
import android.content.Context; import android.content.Context;
import android.content.SharedPreferences; import android.content.SharedPreferences;
import android.content.res.Resources; import android.content.res.Resources;
import android.graphics.Color;
import android.graphics.drawable.Drawable;
import android.media.AudioManager; import android.media.AudioManager;
import android.os.Build;
import android.os.Bundle; import android.os.Bundle;
import android.view.inputmethod.InputMethodSubtype; import android.view.inputmethod.InputMethodSubtype;
import androidx.core.graphics.drawable.DrawableCompat;
import androidx.preference.Preference; import androidx.preference.Preference;
import org.dslul.openboard.inputmethod.keyboard.KeyboardLayoutSet; import org.dslul.openboard.inputmethod.keyboard.KeyboardLayoutSet;
@ -39,16 +35,6 @@ public final class PreferencesSettingsFragment extends SubScreenFragment {
super.onCreate(icicle); super.onCreate(icicle);
addPreferencesFromResource(R.xml.prefs_screen_preferences); addPreferencesFromResource(R.xml.prefs_screen_preferences);
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) {
// need to set icon tint because old android versions don't use the vector drawables
for (int i = 0; i < getPreferenceScreen().getPreferenceCount(); i++) {
final Preference p = getPreferenceScreen().getPreference(0);
final Drawable icon = p.getIcon();
if (icon != null)
DrawableCompat.setTint(icon, Color.WHITE);
}
}
final Resources res = getResources(); final Resources res = getResources();
final Context context = getActivity(); final Context context = getActivity();

View file

@ -87,7 +87,6 @@ public final class Settings implements SharedPreferences.OnSharedPreferenceChang
public static final String PREF_KEY_USE_PERSONALIZED_DICTS = "pref_key_use_personalized_dicts"; public static final String PREF_KEY_USE_PERSONALIZED_DICTS = "pref_key_use_personalized_dicts";
public static final String PREF_KEY_USE_DOUBLE_SPACE_PERIOD = "pref_key_use_double_space_period"; public static final String PREF_KEY_USE_DOUBLE_SPACE_PERIOD = "pref_key_use_double_space_period";
public static final String PREF_BLOCK_POTENTIALLY_OFFENSIVE = "pref_key_block_potentially_offensive"; public static final String PREF_BLOCK_POTENTIALLY_OFFENSIVE = "pref_key_block_potentially_offensive";
public static final boolean SHOULD_SHOW_LXX_SUGGESTION_UI = Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP;
public static final String PREF_LANGUAGE_SWITCH_KEY = "pref_language_switch_key"; public static final String PREF_LANGUAGE_SWITCH_KEY = "pref_language_switch_key";
public static final String PREF_SHOW_EMOJI_KEY = "pref_show_emoji_key"; public static final String PREF_SHOW_EMOJI_KEY = "pref_show_emoji_key";
public static final String PREF_ADDITIONAL_SUBTYPES = "pref_additional_subtypes"; public static final String PREF_ADDITIONAL_SUBTYPES = "pref_additional_subtypes";

View file

@ -96,8 +96,6 @@ public class SettingsValues {
public final int mKeyLongpressTimeout; public final int mKeyLongpressTimeout;
public final boolean mEnableEmojiAltPhysicalKey; public final boolean mEnableEmojiAltPhysicalKey;
public final boolean mIsShowAppIconSettingInPreferences; public final boolean mIsShowAppIconSettingInPreferences;
public final boolean mShouldShowLxxSuggestionUi;
// Use split layout for keyboard.
public final boolean mIsSplitKeyboardEnabled; public final boolean mIsSplitKeyboardEnabled;
public final float mSplitKeyboardSpacerRelativeWidth; public final float mSplitKeyboardSpacerRelativeWidth;
public final int mScreenMetrics; public final int mScreenMetrics;
@ -177,8 +175,6 @@ public class SettingsValues {
: 0f; : 0f;
mScreenMetrics = Settings.readScreenMetrics(res); mScreenMetrics = Settings.readScreenMetrics(res);
mShouldShowLxxSuggestionUi = Settings.SHOULD_SHOW_LXX_SUGGESTION_UI
&& prefs.getBoolean(DebugSettings.PREF_SHOULD_SHOW_LXX_SUGGESTION_UI, true);
// Compute other readable settings // Compute other readable settings
mKeyLongpressTimeout = Settings.readKeyLongpressTimeout(prefs, res); mKeyLongpressTimeout = Settings.readKeyLongpressTimeout(prefs, res);
mKeypressVibrationDuration = Settings.readKeypressVibrationDuration(prefs, res); mKeypressVibrationDuration = Settings.readKeypressVibrationDuration(prefs, res);

View file

@ -14,7 +14,6 @@ import android.view.textservice.SentenceSuggestionsInfo;
import android.view.textservice.SuggestionsInfo; import android.view.textservice.SuggestionsInfo;
import android.view.textservice.TextInfo; import android.view.textservice.TextInfo;
import org.dslul.openboard.inputmethod.compat.TextInfoCompatUtils;
import org.dslul.openboard.inputmethod.latin.NgramContext; import org.dslul.openboard.inputmethod.latin.NgramContext;
import org.dslul.openboard.inputmethod.latin.utils.SpannableStringUtils; import org.dslul.openboard.inputmethod.latin.utils.SpannableStringUtils;
@ -34,7 +33,7 @@ public final class AndroidSpellCheckerSession extends AndroidWordLevelSpellCheck
private SentenceSuggestionsInfo fixWronglyInvalidatedWordWithSingleQuote(TextInfo ti, private SentenceSuggestionsInfo fixWronglyInvalidatedWordWithSingleQuote(TextInfo ti,
SentenceSuggestionsInfo ssi) { SentenceSuggestionsInfo ssi) {
final CharSequence typedText = TextInfoCompatUtils.getCharSequenceOrString(ti); final CharSequence typedText = ti.getCharSequence();
if (!typedText.toString().contains(AndroidSpellCheckerService.SINGLE_QUOTE)) { if (!typedText.toString().contains(AndroidSpellCheckerService.SINGLE_QUOTE)) {
return null; return null;
} }
@ -184,8 +183,7 @@ public final class AndroidSpellCheckerSession extends AndroidWordLevelSpellCheck
final CharSequence prevWord; final CharSequence prevWord;
if (sequentialWords && i > 0) { if (sequentialWords && i > 0) {
final TextInfo prevTextInfo = textInfos[i - 1]; final TextInfo prevTextInfo = textInfos[i - 1];
final CharSequence prevWordCandidate = final CharSequence prevWordCandidate = prevTextInfo.getCharSequence();
TextInfoCompatUtils.getCharSequenceOrString(prevTextInfo);
// Note that an empty string would be used to indicate the initial word // Note that an empty string would be used to indicate the initial word
// in the future. // in the future.
prevWord = TextUtils.isEmpty(prevWordCandidate) ? null : prevWordCandidate; prevWord = TextUtils.isEmpty(prevWordCandidate) ? null : prevWordCandidate;

View file

@ -11,7 +11,6 @@ import android.view.textservice.SentenceSuggestionsInfo;
import android.view.textservice.SuggestionsInfo; import android.view.textservice.SuggestionsInfo;
import android.view.textservice.TextInfo; import android.view.textservice.TextInfo;
import org.dslul.openboard.inputmethod.compat.TextInfoCompatUtils;
import org.dslul.openboard.inputmethod.latin.common.Constants; import org.dslul.openboard.inputmethod.latin.common.Constants;
import org.dslul.openboard.inputmethod.latin.settings.SpacingAndPunctuations; import org.dslul.openboard.inputmethod.latin.settings.SpacingAndPunctuations;
import org.dslul.openboard.inputmethod.latin.utils.RunInLocale; import org.dslul.openboard.inputmethod.latin.utils.RunInLocale;
@ -124,8 +123,7 @@ public class SentenceLevelAdapter {
public SentenceTextInfoParams getSplitWords(TextInfo originalTextInfo) { public SentenceTextInfoParams getSplitWords(TextInfo originalTextInfo) {
final WordIterator wordIterator = mWordIterator; final WordIterator wordIterator = mWordIterator;
final CharSequence originalText = final CharSequence originalText = originalTextInfo.getCharSequence();
TextInfoCompatUtils.getCharSequenceOrString(originalTextInfo);
final int cookie = originalTextInfo.getCookie(); final int cookie = originalTextInfo.getCookie();
final int start = -1; final int start = -1;
final int end = originalText.length(); final int end = originalText.length();
@ -134,7 +132,7 @@ public class SentenceLevelAdapter {
int wordEnd = wordIterator.getEndOfWord(originalText, wordStart); int wordEnd = wordIterator.getEndOfWord(originalText, wordStart);
while (wordStart <= end && wordEnd != -1 && wordStart != -1) { while (wordStart <= end && wordEnd != -1 && wordStart != -1) {
if (wordEnd >= start && wordEnd > wordStart) { if (wordEnd >= start && wordEnd > wordStart) {
final TextInfo ti = TextInfoCompatUtils.newInstance(originalText, wordStart, final TextInfo ti = new TextInfo(originalText, wordStart,
wordEnd, cookie, originalText.subSequence(wordStart, wordEnd).hashCode()); wordEnd, cookie, originalText.subSequence(wordStart, wordEnd).hashCode());
wordItems.add(new SentenceWordItem(ti, wordStart, wordEnd)); wordItems.add(new SentenceWordItem(ti, wordStart, wordEnd));
} }

View file

@ -225,11 +225,9 @@ final class SuggestionStripLayoutHelper {
final SuggestedWords suggestedWords) { final SuggestedWords suggestedWords) {
final SettingsValues settingsValues = Settings.getInstance().getCurrent(); final SettingsValues settingsValues = Settings.getInstance().getCurrent();
final boolean shouldOmitTypedWord = shouldOmitTypedWord(suggestedWords.mInputStyle, final boolean shouldOmitTypedWord = shouldOmitTypedWord(suggestedWords.mInputStyle,
settingsValues.mGestureFloatingPreviewTextEnabled, settingsValues.mGestureFloatingPreviewTextEnabled, true);
settingsValues.mShouldShowLxxSuggestionUi);
return getPositionInSuggestionStrip(indexInSuggestedWords, suggestedWords.mWillAutoCorrect, return getPositionInSuggestionStrip(indexInSuggestedWords, suggestedWords.mWillAutoCorrect,
settingsValues.mShouldShowLxxSuggestionUi && shouldOmitTypedWord, shouldOmitTypedWord, mCenterPositionInStrip, mTypedWordPositionWhenAutocorrect);
mCenterPositionInStrip, mTypedWordPositionWhenAutocorrect);
} }
@UsedForTesting @UsedForTesting
@ -337,8 +335,7 @@ final class SuggestionStripLayoutHelper {
(PunctuationSuggestions)suggestedWords, stripView); (PunctuationSuggestions)suggestedWords, stripView);
} }
final int wordCountToShow = suggestedWords.getWordCountToShow( final int wordCountToShow = suggestedWords.getWordCountToShow();
Settings.getInstance().getCurrent().mShouldShowLxxSuggestionUi);
final int startIndexOfMoreSuggestions = setupWordViewsAndReturnStartIndexOfMoreSuggestions( final int startIndexOfMoreSuggestions = setupWordViewsAndReturnStartIndexOfMoreSuggestions(
suggestedWords, mSuggestionsCountInStrip); suggestedWords, mSuggestionsCountInStrip);
final TextView centerWordView = mWordViews.get(mCenterPositionInStrip); final TextView centerWordView = mWordViews.get(mCenterPositionInStrip);

View file

@ -6,12 +6,10 @@
package org.dslul.openboard.inputmethod.latin.utils; package org.dslul.openboard.inputmethod.latin.utils;
import android.annotation.TargetApi;
import android.graphics.Matrix; import android.graphics.Matrix;
import android.graphics.Rect; import android.graphics.Rect;
import android.inputmethodservice.ExtractEditText; import android.inputmethodservice.ExtractEditText;
import android.inputmethodservice.InputMethodService; import android.inputmethodservice.InputMethodService;
import android.os.Build;
import android.text.Layout; import android.text.Layout;
import android.text.Spannable; import android.text.Spannable;
import android.text.Spanned; import android.text.Spanned;
@ -23,8 +21,7 @@ import android.widget.TextView;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
import androidx.annotation.Nullable; import androidx.annotation.Nullable;
import org.dslul.openboard.inputmethod.compat.CursorAnchorInfoCompatWrapper; // todo: remove this? or is there anything it could be useful for?
/** /**
* This class allows input methods to extract {@link CursorAnchorInfo} directly from the given * This class allows input methods to extract {@link CursorAnchorInfo} directly from the given
* {@link TextView}. This is useful and even necessary to support full-screen mode where the default * {@link TextView}. This is useful and even necessary to support full-screen mode where the default
@ -74,30 +71,12 @@ public final class CursorAnchorInfoUtils {
return true; return true;
} }
/**
* Extracts {@link CursorAnchorInfoCompatWrapper} from the given {@link TextView}.
* @param textView the target text view from which {@link CursorAnchorInfoCompatWrapper} is to
* be extracted.
* @return the {@link CursorAnchorInfoCompatWrapper} object based on the current layout.
* {@code null} if {@code Build.VERSION.SDK_INT} is 20 or prior or {@link TextView} is not
* ready to provide layout information.
*/
@Nullable
public static CursorAnchorInfoCompatWrapper extractFromTextView(
@NonNull final TextView textView) {
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) {
return null;
}
return CursorAnchorInfoCompatWrapper.wrap(extractFromTextViewInternal(textView));
}
/** /**
* Returns {@link CursorAnchorInfo} from the given {@link TextView}. * Returns {@link CursorAnchorInfo} from the given {@link TextView}.
* @param textView the target text view from which {@link CursorAnchorInfo} is to be extracted. * @param textView the target text view from which {@link CursorAnchorInfo} is to be extracted.
* @return the {@link CursorAnchorInfo} object based on the current layout. {@code null} if it * @return the {@link CursorAnchorInfo} object based on the current layout. {@code null} if it
* is not feasible. * is not feasible.
*/ */
@TargetApi(Build.VERSION_CODES.LOLLIPOP)
@Nullable @Nullable
private static CursorAnchorInfo extractFromTextViewInternal(@NonNull final TextView textView) { private static CursorAnchorInfo extractFromTextViewInternal(@NonNull final TextView textView) {
final Layout layout = textView.getLayout(); final Layout layout = textView.getLayout();

View file

@ -26,7 +26,7 @@ public final class JniUtils {
private static final String CHECKSUM_X86 = "bd946d126c957b5a6dea3bafa07fa36a27950b30e2b684dffc60746d0a1c7ad8"; private static final String CHECKSUM_X86 = "bd946d126c957b5a6dea3bafa07fa36a27950b30e2b684dffc60746d0a1c7ad8";
public static String expectedDefaultChecksum() { public static String expectedDefaultChecksum() {
final String abi = Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP ? Build.SUPPORTED_ABIS[0] : Build.CPU_ABI; final String abi = Build.SUPPORTED_ABIS[0];
return switch (abi) { return switch (abi) {
case "arm64-v8a" -> CHECKSUM_ARM64; case "arm64-v8a" -> CHECKSUM_ARM64;
case "armeabi-v7a" -> CHECKSUM_ARM32; case "armeabi-v7a" -> CHECKSUM_ARM32;

View file

@ -5,9 +5,9 @@ import android.content.Context
import android.content.SharedPreferences import android.content.SharedPreferences
import android.view.LayoutInflater import android.view.LayoutInflater
import android.view.ViewGroup import android.view.ViewGroup
import android.widget.Switch
import android.widget.TextView import android.widget.TextView
import androidx.appcompat.app.AlertDialog import androidx.appcompat.app.AlertDialog
import androidx.appcompat.widget.SwitchCompat
import androidx.core.content.ContextCompat import androidx.core.content.ContextCompat
import androidx.recyclerview.widget.DiffUtil import androidx.recyclerview.widget.DiffUtil
import androidx.recyclerview.widget.ItemTouchHelper import androidx.recyclerview.widget.ItemTouchHelper
@ -135,7 +135,7 @@ fun reorderMoreKeysDialog(context: Context, key: String, defaultSetting: String,
val displayTextId = context.resources.getIdentifier(text.lowercase(), "string", context.packageName) val displayTextId = context.resources.getIdentifier(text.lowercase(), "string", context.packageName)
val displayText = if (displayTextId == 0) text else context.getString(displayTextId) val displayText = if (displayTextId == 0) text else context.getString(displayTextId)
p0.itemView.findViewById<TextView>(R.id.morekeys_type)?.text = displayText p0.itemView.findViewById<TextView>(R.id.morekeys_type)?.text = displayText
val switch = p0.itemView.findViewById<SwitchCompat>(R.id.morekeys_switch) val switch = p0.itemView.findViewById<Switch>(R.id.morekeys_switch)
switch?.isChecked = wasChecked switch?.isChecked = wasChecked
switch?.isEnabled = !(key.contains(Settings.PREF_MORE_KEYS_ORDER) && text == MORE_KEYS_LAYOUT) // layout can't be disabled switch?.isEnabled = !(key.contains(Settings.PREF_MORE_KEYS_ORDER) && text == MORE_KEYS_LAYOUT) // layout can't be disabled
switch?.setOnCheckedChangeListener { _, isChecked -> switch?.setOnCheckedChangeListener { _, isChecked ->

View file

@ -34,7 +34,7 @@
android:paddingHorizontal="10dp" android:paddingHorizontal="10dp"
style="@style/PreferenceSubtitleText" /> style="@style/PreferenceSubtitleText" />
</LinearLayout> </LinearLayout>
<androidx.appcompat.widget.SwitchCompat <Switch
android:id="@+id/color_switch" android:id="@+id/color_switch"
android:layout_gravity="center_vertical" android:layout_gravity="center_vertical"
android:layout_width="0dp" android:layout_width="0dp"

View file

@ -40,7 +40,7 @@
<RelativeLayout <RelativeLayout
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" > android:layout_height="wrap_content" >
<androidx.appcompat.widget.SwitchCompat <Switch
android:id="@+id/language_switch" android:id="@+id/language_switch"
android:padding="6dp" android:padding="6dp"
android:layout_gravity="center_vertical" android:layout_gravity="center_vertical"

View file

@ -7,7 +7,7 @@
android:paddingTop="6dp" android:paddingTop="6dp"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent"> android:layout_height="match_parent">
<androidx.appcompat.widget.SwitchCompat <Switch
android:id="@+id/language_switch" android:id="@+id/language_switch"
android:text="@string/use_system_language_to_select_input_method_subtypes" android:text="@string/use_system_language_to_select_input_method_subtypes"
style="@style/PreferenceTitleText" style="@style/PreferenceTitleText"

View file

@ -17,7 +17,7 @@
android:layout_width="0dp" android:layout_width="0dp"
android:layout_weight="1" android:layout_weight="1"
android:layout_height="wrap_content" /> android:layout_height="wrap_content" />
<androidx.appcompat.widget.SwitchCompat <Switch
android:id="@+id/morekeys_switch" android:id="@+id/morekeys_switch"
android:padding="6dp" android:padding="6dp"
android:layout_gravity="center_vertical" android:layout_gravity="center_vertical"

View file

@ -1,13 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
Copyright (C) 2014 The Android Open Source Project
modified
SPDX-License-Identifier: Apache-2.0 AND GPL-3.0-only
-->
<resources xmlns:android="http://schemas.android.com/apk/res/android">
<style name="platformActivityTheme" parent="Theme.AppCompat.DayNight">
<item name="android:colorAccent">@color/accent</item>
<item name="colorAccent">@color/accent</item>
</style>
</resources>

View file

@ -1,14 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
Copyright (C) 2014 The Android Open Source Project
SPDX-License-Identifier: Apache-2.0
-->
<resources xmlns:android="http://schemas.android.com/apk/res/android">
<style
name="InputView.LXX"
parent="InputView"
>
<item name="android:elevation">8dp</item>
</style>
</resources>

View file

@ -12,7 +12,6 @@
<string name="prefs_debug_mode" translatable="false">Debug Mode</string> <string name="prefs_debug_mode" translatable="false">Debug Mode</string>
<string name="prefs_show_suggestion_infos" translatable="false">Show suggestion infos</string> <string name="prefs_show_suggestion_infos" translatable="false">Show suggestion infos</string>
<string name="prefs_force_non_distinct_multitouch" translatable="false">Force non-distinct multitouch</string> <string name="prefs_force_non_distinct_multitouch" translatable="false">Force non-distinct multitouch</string>
<string name="prefs_should_show_lxx_suggestion_ui" translatable="false">Show LXX suggestion UI</string>
<!-- Option to enable sliding key input indicator. The user can see a rubber band-like effect during sliding key input. [CHAR LIMIT=30]--> <!-- Option to enable sliding key input indicator. The user can see a rubber band-like effect during sliding key input. [CHAR LIMIT=30]-->
<string name="sliding_key_input_preview" translatable="false">Show slide indicator</string> <string name="sliding_key_input_preview" translatable="false">Show slide indicator</string>
<!-- Option summary to enable sliding key input indicator. The user can see a rubber band-like effect during sliding key input. [CHAR LIMIT=66]--> <!-- Option summary to enable sliding key input indicator. The user can see a rubber band-like effect during sliding key input. [CHAR LIMIT=66]-->

View file

@ -6,5 +6,8 @@
--> -->
<resources xmlns:android="http://schemas.android.com/apk/res/android"> <resources xmlns:android="http://schemas.android.com/apk/res/android">
<style name="platformActivityTheme" parent="Theme.AppCompat.DayNight" /> <style name="platformActivityTheme" parent="Theme.AppCompat.DayNight">
<item name="android:colorAccent">@color/accent</item>
<item name="colorAccent">@color/accent</item>
</style>
</resources> </resources>

View file

@ -8,7 +8,9 @@
<style <style
name="InputView.LXX" name="InputView.LXX"
parent="InputView" parent="InputView"
/> >
<item name="android:elevation">8dp</item>
</style>
<!-- LXX KeyboardView theme --> <!-- LXX KeyboardView theme -->
<style <style
name="KeyboardView.LXX" name="KeyboardView.LXX"

View file

@ -28,11 +28,6 @@
android:title="@string/prefs_force_non_distinct_multitouch" android:title="@string/prefs_force_non_distinct_multitouch"
android:defaultValue="false" android:defaultValue="false"
android:persistent="true" /> android:persistent="true" />
<SwitchPreferenceCompat
android:key="pref_should_show_lxx_suggestion_ui"
android:title="@string/prefs_should_show_lxx_suggestion_ui"
android:defaultValue="true"
android:persistent="true" />
<SwitchPreferenceCompat <SwitchPreferenceCompat
android:key="pref_sliding_key_input_preview" android:key="pref_sliding_key_input_preview"
android:title="@string/sliding_key_input_preview" android:title="@string/sliding_key_input_preview"