mirror of
https://gitlab.futo.org/keyboard/latinime.git
synced 2024-09-28 14:54:30 +01:00
636 lines
21 KiB
Kotlin
636 lines
21 KiB
Kotlin
package org.futo.inputmethod.latin
|
|
|
|
import android.content.ComponentCallbacks2
|
|
import android.content.Context
|
|
import android.content.res.Configuration
|
|
import android.inputmethodservice.InputMethodService
|
|
import android.os.Build
|
|
import android.os.Bundle
|
|
import android.view.KeyEvent
|
|
import android.view.View
|
|
import android.view.ViewGroup
|
|
import android.view.inputmethod.CompletionInfo
|
|
import android.view.inputmethod.EditorInfo
|
|
import android.view.inputmethod.InlineSuggestion
|
|
import android.view.inputmethod.InlineSuggestionsRequest
|
|
import android.view.inputmethod.InlineSuggestionsResponse
|
|
import android.view.inputmethod.InputMethodSubtype
|
|
import androidx.annotation.RequiresApi
|
|
import androidx.compose.foundation.layout.Box
|
|
import androidx.compose.foundation.layout.Column
|
|
import androidx.compose.foundation.layout.Row
|
|
import androidx.compose.foundation.layout.Spacer
|
|
import androidx.compose.foundation.layout.fillMaxWidth
|
|
import androidx.compose.foundation.layout.height
|
|
import androidx.compose.foundation.layout.size
|
|
import androidx.compose.material3.ColorScheme
|
|
import androidx.compose.material3.Icon
|
|
import androidx.compose.material3.IconButton
|
|
import androidx.compose.material3.MaterialTheme
|
|
import androidx.compose.material3.Surface
|
|
import androidx.compose.material3.Text
|
|
import androidx.compose.runtime.Composable
|
|
import androidx.compose.runtime.MutableState
|
|
import androidx.compose.runtime.key
|
|
import androidx.compose.ui.Alignment.Companion.CenterVertically
|
|
import androidx.compose.ui.Modifier
|
|
import androidx.compose.ui.draw.clipToBounds
|
|
import androidx.compose.ui.layout.onSizeChanged
|
|
import androidx.compose.ui.platform.ComposeView
|
|
import androidx.compose.ui.platform.LocalDensity
|
|
import androidx.compose.ui.platform.ViewCompositionStrategy
|
|
import androidx.compose.ui.res.painterResource
|
|
import androidx.compose.ui.unit.dp
|
|
import androidx.compose.ui.viewinterop.AndroidView
|
|
import androidx.lifecycle.Lifecycle
|
|
import androidx.lifecycle.LifecycleCoroutineScope
|
|
import androidx.lifecycle.LifecycleOwner
|
|
import androidx.lifecycle.LifecycleRegistry
|
|
import androidx.lifecycle.ViewModelStore
|
|
import androidx.lifecycle.ViewModelStoreOwner
|
|
import androidx.lifecycle.findViewTreeLifecycleOwner
|
|
import androidx.lifecycle.findViewTreeViewModelStoreOwner
|
|
import androidx.lifecycle.lifecycleScope
|
|
import androidx.lifecycle.setViewTreeLifecycleOwner
|
|
import androidx.lifecycle.setViewTreeViewModelStoreOwner
|
|
import androidx.savedstate.SavedStateRegistry
|
|
import androidx.savedstate.SavedStateRegistryController
|
|
import androidx.savedstate.SavedStateRegistryOwner
|
|
import androidx.savedstate.findViewTreeSavedStateRegistryOwner
|
|
import androidx.savedstate.setViewTreeSavedStateRegistryOwner
|
|
import kotlinx.coroutines.Job
|
|
import kotlinx.coroutines.flow.Flow
|
|
import kotlinx.coroutines.runBlocking
|
|
import org.futo.inputmethod.latin.common.Constants
|
|
import org.futo.inputmethod.latin.uix.Action
|
|
import org.futo.inputmethod.latin.uix.ActionBar
|
|
import org.futo.inputmethod.latin.uix.ActionWindow
|
|
import org.futo.inputmethod.latin.uix.BasicThemeProvider
|
|
import org.futo.inputmethod.latin.uix.DynamicThemeProvider
|
|
import org.futo.inputmethod.latin.uix.DynamicThemeProviderOwner
|
|
import org.futo.inputmethod.latin.uix.KeyboardManagerForAction
|
|
import org.futo.inputmethod.latin.uix.PersistentActionState
|
|
import org.futo.inputmethod.latin.uix.THEME_KEY
|
|
import org.futo.inputmethod.latin.uix.actions.VoiceInputAction
|
|
import org.futo.inputmethod.latin.uix.createInlineSuggestionsRequest
|
|
import org.futo.inputmethod.latin.uix.deferGetSetting
|
|
import org.futo.inputmethod.latin.uix.deferSetSetting
|
|
import org.futo.inputmethod.latin.uix.differsFrom
|
|
import org.futo.inputmethod.latin.uix.inflateInlineSuggestion
|
|
import org.futo.inputmethod.latin.uix.theme.DarkColorScheme
|
|
import org.futo.inputmethod.latin.uix.theme.ThemeOption
|
|
import org.futo.inputmethod.latin.uix.theme.ThemeOptions
|
|
import org.futo.inputmethod.latin.uix.theme.Typography
|
|
import org.futo.inputmethod.latin.uix.theme.UixThemeWrapper
|
|
import org.futo.inputmethod.latin.uix.theme.presets.ClassicMaterialDark
|
|
import org.futo.inputmethod.latin.uix.theme.presets.DynamicSystemTheme
|
|
import org.futo.inputmethod.latin.uix.theme.presets.VoiceInputTheme
|
|
|
|
class LatinIME : InputMethodService(), LifecycleOwner, ViewModelStoreOwner, SavedStateRegistryOwner,
|
|
LatinIMELegacy.SuggestionStripController, DynamicThemeProviderOwner, KeyboardManagerForAction {
|
|
|
|
private val mSavedStateRegistryController = SavedStateRegistryController.create(this)
|
|
|
|
override val savedStateRegistry: SavedStateRegistry
|
|
get() = mSavedStateRegistryController.savedStateRegistry
|
|
|
|
private val mLifecycleRegistry = LifecycleRegistry(this)
|
|
private fun handleLifecycleEvent(event: Lifecycle.Event) =
|
|
mLifecycleRegistry.handleLifecycleEvent(event)
|
|
|
|
override val lifecycle
|
|
get() = mLifecycleRegistry
|
|
|
|
private val store = ViewModelStore()
|
|
override val viewModelStore
|
|
get() = store
|
|
|
|
private fun setOwners() {
|
|
val decorView = window.window?.decorView
|
|
if (decorView?.findViewTreeLifecycleOwner() == null) {
|
|
decorView?.setViewTreeLifecycleOwner(this)
|
|
}
|
|
if (decorView?.findViewTreeViewModelStoreOwner() == null) {
|
|
decorView?.setViewTreeViewModelStoreOwner(this)
|
|
}
|
|
if (decorView?.findViewTreeSavedStateRegistryOwner() == null) {
|
|
decorView?.setViewTreeSavedStateRegistryOwner(this)
|
|
}
|
|
}
|
|
|
|
private var composeView: ComposeView? = null
|
|
|
|
private val latinIMELegacy = LatinIMELegacy(
|
|
this as InputMethodService,
|
|
this as LatinIMELegacy.SuggestionStripController
|
|
)
|
|
|
|
private var activeThemeOption: ThemeOption? = null
|
|
private var activeColorScheme = DarkColorScheme
|
|
private var colorSchemeLoaderJob: Job? = null
|
|
|
|
private var drawableProvider: DynamicThemeProvider? = null
|
|
|
|
private var currWindowAction: Action? = null
|
|
private var currWindowActionWindow: ActionWindow? = null
|
|
private var persistentStates: HashMap<Action, PersistentActionState?> = hashMapOf()
|
|
private fun isActionWindowOpen(): Boolean {
|
|
return currWindowActionWindow != null
|
|
}
|
|
|
|
private var inlineSuggestions: List<MutableState<View?>> = listOf()
|
|
|
|
private var lastEditorInfo: EditorInfo? = null
|
|
|
|
private fun recreateKeyboard() {
|
|
latinIMELegacy.updateTheme()
|
|
latinIMELegacy.mKeyboardSwitcher.mState.onLoadKeyboard(latinIMELegacy.currentAutoCapsState, latinIMELegacy.currentRecapitalizeState);
|
|
}
|
|
|
|
private fun updateDrawableProvider(colorScheme: ColorScheme) {
|
|
activeColorScheme = colorScheme
|
|
drawableProvider = BasicThemeProvider(this, overrideColorScheme = colorScheme)
|
|
|
|
window.window?.navigationBarColor = drawableProvider!!.primaryKeyboardColor
|
|
setContent()
|
|
}
|
|
|
|
override fun getDrawableProvider(): DynamicThemeProvider {
|
|
if (drawableProvider == null) {
|
|
if (colorSchemeLoaderJob != null && !colorSchemeLoaderJob!!.isCompleted) {
|
|
// Must have completed by now!
|
|
runBlocking {
|
|
colorSchemeLoaderJob!!.join()
|
|
}
|
|
}
|
|
drawableProvider = BasicThemeProvider(this, activeColorScheme)
|
|
}
|
|
|
|
return drawableProvider!!
|
|
}
|
|
|
|
private fun updateColorsIfDynamicChanged() {
|
|
if(activeThemeOption?.dynamic == true) {
|
|
val currColors = activeColorScheme
|
|
val nextColors = activeThemeOption!!.obtainColors(this)
|
|
|
|
if(currColors.differsFrom(nextColors)) {
|
|
updateDrawableProvider(nextColors)
|
|
}
|
|
}
|
|
}
|
|
|
|
override fun onCreate() {
|
|
super.onCreate()
|
|
|
|
colorSchemeLoaderJob = deferGetSetting(THEME_KEY, DynamicSystemTheme.key) {
|
|
var themeKey = it
|
|
var themeOption = ThemeOptions[themeKey]
|
|
if (themeOption == null || !themeOption.available(this@LatinIME)) {
|
|
themeKey = VoiceInputTheme.key
|
|
themeOption = ThemeOptions[themeKey]!!
|
|
}
|
|
|
|
activeThemeOption = themeOption
|
|
activeColorScheme = themeOption.obtainColors(this@LatinIME)
|
|
}
|
|
|
|
mSavedStateRegistryController.performRestore(null)
|
|
handleLifecycleEvent(Lifecycle.Event.ON_RESUME)
|
|
|
|
latinIMELegacy.onCreate()
|
|
}
|
|
|
|
override fun onDestroy() {
|
|
latinIMELegacy.onDestroy()
|
|
super.onDestroy()
|
|
}
|
|
|
|
override fun onConfigurationChanged(newConfig: Configuration) {
|
|
latinIMELegacy.onConfigurationChanged(newConfig)
|
|
super.onConfigurationChanged(newConfig)
|
|
}
|
|
|
|
override fun onInitializeInterface() {
|
|
latinIMELegacy.onInitializeInterface()
|
|
}
|
|
|
|
private var legacyInputView: View? = null
|
|
private var touchableHeight: Int = 0
|
|
override fun onCreateInputView(): View {
|
|
legacyInputView = latinIMELegacy.onCreateInputView()
|
|
composeView = ComposeView(this).apply {
|
|
setViewCompositionStrategy(ViewCompositionStrategy.DisposeOnViewTreeLifecycleDestroyed)
|
|
setParentCompositionContext(null)
|
|
|
|
this@LatinIME.setOwners()
|
|
}
|
|
|
|
setContent()
|
|
|
|
latinIMELegacy.setComposeInputView(composeView)
|
|
|
|
return composeView!!
|
|
}
|
|
|
|
private fun onActionActivated(action: Action) {
|
|
if (action.windowImpl != null) {
|
|
enterActionWindowView(action)
|
|
} else if (action.simplePressImpl != null) {
|
|
action.simplePressImpl.invoke(this, persistentStates[action])
|
|
} else {
|
|
throw IllegalStateException("An action must have either a window implementation or a simple press implementation")
|
|
}
|
|
}
|
|
|
|
private var inputViewHeight: Int = -1
|
|
private var shouldShowSuggestionStrip: Boolean = true
|
|
private var suggestedWords: SuggestedWords? = null
|
|
|
|
@Composable
|
|
private fun LegacyKeyboardView(hidden: Boolean) {
|
|
val modifier = if(hidden) {
|
|
Modifier.clipToBounds().size(0.dp)
|
|
} else {
|
|
Modifier.onSizeChanged {
|
|
inputViewHeight = it.height
|
|
}
|
|
}
|
|
key(legacyInputView) {
|
|
AndroidView(factory = {
|
|
legacyInputView!!
|
|
}, update = { }, modifier = modifier)
|
|
}
|
|
}
|
|
|
|
@Composable
|
|
private fun MainKeyboardViewWithActionBar() {
|
|
Column {
|
|
// Don't show suggested words when it's not meant to be shown
|
|
val suggestedWordsOrNull = if(shouldShowSuggestionStrip) {
|
|
suggestedWords
|
|
} else {
|
|
null
|
|
}
|
|
|
|
ActionBar(
|
|
suggestedWordsOrNull,
|
|
latinIMELegacy,
|
|
inlineSuggestions = inlineSuggestions,
|
|
onActionActivated = { onActionActivated(it) }
|
|
)
|
|
}
|
|
}
|
|
|
|
private fun enterActionWindowView(action: Action) {
|
|
assert(action.windowImpl != null)
|
|
|
|
latinIMELegacy.mKeyboardSwitcher.saveKeyboardState()
|
|
|
|
currWindowAction = action
|
|
|
|
if (persistentStates[action] == null) {
|
|
persistentStates[action] = action.persistentState?.let { it(this) }
|
|
}
|
|
|
|
currWindowActionWindow = action.windowImpl?.let { it(this, persistentStates[action]) }
|
|
|
|
setContent()
|
|
}
|
|
|
|
private fun returnBackToMainKeyboardViewFromAction() {
|
|
assert(currWindowActionWindow != null)
|
|
|
|
currWindowActionWindow!!.close()
|
|
|
|
currWindowAction = null
|
|
currWindowActionWindow = null
|
|
|
|
setContent()
|
|
}
|
|
|
|
@Composable
|
|
private fun ActionViewWithHeader(windowImpl: ActionWindow) {
|
|
Column {
|
|
Surface(
|
|
modifier = Modifier
|
|
.fillMaxWidth()
|
|
.height(40.dp), color = MaterialTheme.colorScheme.background
|
|
)
|
|
{
|
|
Row {
|
|
IconButton(onClick = {
|
|
returnBackToMainKeyboardViewFromAction()
|
|
}) {
|
|
Icon(
|
|
painter = painterResource(id = R.drawable.arrow_left),
|
|
contentDescription = "Back"
|
|
)
|
|
}
|
|
|
|
Text(
|
|
windowImpl.windowName(),
|
|
style = Typography.titleMedium,
|
|
modifier = Modifier.align(CenterVertically)
|
|
)
|
|
}
|
|
}
|
|
|
|
Box(modifier = Modifier
|
|
.fillMaxWidth()
|
|
.height(with(LocalDensity.current) { inputViewHeight.toDp() })
|
|
) {
|
|
windowImpl.WindowContents()
|
|
}
|
|
}
|
|
}
|
|
|
|
private fun setContent() {
|
|
composeView?.setContent {
|
|
UixThemeWrapper(activeColorScheme) {
|
|
Column {
|
|
Spacer(modifier = Modifier.weight(1.0f))
|
|
Surface(modifier = Modifier.onSizeChanged {
|
|
touchableHeight = it.height
|
|
}) {
|
|
Column {
|
|
when {
|
|
isActionWindowOpen() -> ActionViewWithHeader(
|
|
currWindowActionWindow!!
|
|
)
|
|
|
|
else -> MainKeyboardViewWithActionBar()
|
|
}
|
|
|
|
// The keyboard view really doesn't like being detached, so it's always
|
|
// shown, but resized to 0 if an action window is open
|
|
LegacyKeyboardView(hidden = isActionWindowOpen())
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// necessary for when KeyboardSwitcher updates the theme
|
|
fun updateLegacyView(newView: View) {
|
|
legacyInputView = newView
|
|
setContent()
|
|
|
|
if (composeView != null) {
|
|
latinIMELegacy.setComposeInputView(composeView)
|
|
}
|
|
|
|
latinIMELegacy.setInputView(legacyInputView)
|
|
}
|
|
|
|
override fun setInputView(view: View?) {
|
|
super.setInputView(view)
|
|
|
|
if (composeView != null) {
|
|
latinIMELegacy.setComposeInputView(composeView)
|
|
}
|
|
|
|
latinIMELegacy.setInputView(legacyInputView)
|
|
}
|
|
|
|
override fun setCandidatesView(view: View?) {
|
|
return latinIMELegacy.setCandidatesView(view)
|
|
}
|
|
|
|
override fun onStartInput(attribute: EditorInfo?, restarting: Boolean) {
|
|
super.onStartInput(attribute, restarting)
|
|
latinIMELegacy.onStartInput(attribute, restarting)
|
|
}
|
|
|
|
override fun onStartInputView(info: EditorInfo?, restarting: Boolean) {
|
|
lastEditorInfo = info
|
|
|
|
super.onStartInputView(info, restarting)
|
|
latinIMELegacy.onStartInputView(info, restarting)
|
|
}
|
|
|
|
override fun onFinishInputView(finishingInput: Boolean) {
|
|
super.onFinishInputView(finishingInput)
|
|
latinIMELegacy.onFinishInputView(finishingInput)
|
|
}
|
|
|
|
override fun onFinishInput() {
|
|
super.onFinishInput()
|
|
latinIMELegacy.onFinishInput()
|
|
}
|
|
|
|
override fun onCurrentInputMethodSubtypeChanged(newSubtype: InputMethodSubtype?) {
|
|
super.onCurrentInputMethodSubtypeChanged(newSubtype)
|
|
latinIMELegacy.onCurrentInputMethodSubtypeChanged(newSubtype)
|
|
}
|
|
|
|
override fun onWindowShown() {
|
|
super.onWindowShown()
|
|
latinIMELegacy.onWindowShown()
|
|
|
|
updateColorsIfDynamicChanged()
|
|
}
|
|
|
|
override fun onWindowHidden() {
|
|
super.onWindowHidden()
|
|
latinIMELegacy.onWindowHidden()
|
|
}
|
|
|
|
override fun onUpdateSelection(
|
|
oldSelStart: Int,
|
|
oldSelEnd: Int,
|
|
newSelStart: Int,
|
|
newSelEnd: Int,
|
|
candidatesStart: Int,
|
|
candidatesEnd: Int
|
|
) {
|
|
super.onUpdateSelection(
|
|
oldSelStart,
|
|
oldSelEnd,
|
|
newSelStart,
|
|
newSelEnd,
|
|
candidatesStart,
|
|
candidatesEnd
|
|
)
|
|
|
|
latinIMELegacy.onUpdateSelection(
|
|
oldSelStart,
|
|
oldSelEnd,
|
|
newSelStart,
|
|
newSelEnd,
|
|
candidatesStart,
|
|
candidatesEnd
|
|
)
|
|
}
|
|
|
|
override fun onExtractedTextClicked() {
|
|
latinIMELegacy.onExtractedTextClicked()
|
|
super.onExtractedTextClicked()
|
|
}
|
|
|
|
override fun onExtractedCursorMovement(dx: Int, dy: Int) {
|
|
latinIMELegacy.onExtractedCursorMovement(dx, dy)
|
|
super.onExtractedCursorMovement(dx, dy)
|
|
}
|
|
|
|
override fun hideWindow() {
|
|
latinIMELegacy.hideWindow()
|
|
super.hideWindow()
|
|
}
|
|
|
|
override fun onDisplayCompletions(completions: Array<out CompletionInfo>?) {
|
|
latinIMELegacy.onDisplayCompletions(completions)
|
|
}
|
|
|
|
override fun onComputeInsets(outInsets: Insets?) {
|
|
// This method may be called before {@link #setInputView(View)}.
|
|
if (legacyInputView == null || composeView == null) {
|
|
return
|
|
}
|
|
|
|
val inputHeight: Int = composeView!!.height
|
|
if (latinIMELegacy.isImeSuppressedByHardwareKeyboard && !legacyInputView!!.isShown) {
|
|
// If there is a hardware keyboard and a visible software keyboard view has been hidden,
|
|
// no visual element will be shown on the screen.
|
|
latinIMELegacy.setInsets(outInsets!!.apply {
|
|
contentTopInsets = inputHeight
|
|
visibleTopInsets = inputHeight
|
|
})
|
|
return
|
|
}
|
|
|
|
val visibleTopY = inputHeight - touchableHeight
|
|
|
|
val touchLeft = 0
|
|
val touchTop = visibleTopY
|
|
val touchRight = composeView!!.width
|
|
val touchBottom = inputHeight
|
|
|
|
latinIMELegacy.setInsets(outInsets!!.apply {
|
|
touchableInsets = Insets.TOUCHABLE_INSETS_REGION;
|
|
touchableRegion.set(touchLeft, touchTop, touchRight, touchBottom);
|
|
contentTopInsets = visibleTopY
|
|
visibleTopInsets = visibleTopY
|
|
})
|
|
}
|
|
|
|
override fun onShowInputRequested(flags: Int, configChange: Boolean): Boolean {
|
|
return latinIMELegacy.onShowInputRequested(
|
|
flags,
|
|
configChange
|
|
) || super.onShowInputRequested(flags, configChange)
|
|
}
|
|
|
|
override fun onEvaluateInputViewShown(): Boolean {
|
|
return latinIMELegacy.onEvaluateInputViewShown() || super.onEvaluateInputViewShown()
|
|
}
|
|
|
|
override fun onEvaluateFullscreenMode(): Boolean {
|
|
return latinIMELegacy.onEvaluateFullscreenMode(super.onEvaluateFullscreenMode())
|
|
}
|
|
|
|
override fun updateFullscreenMode() {
|
|
super.updateFullscreenMode()
|
|
latinIMELegacy.updateFullscreenMode()
|
|
}
|
|
|
|
override fun onKeyDown(keyCode: Int, event: KeyEvent?): Boolean {
|
|
return latinIMELegacy.onKeyDown(keyCode, event) || super.onKeyDown(keyCode, event)
|
|
}
|
|
|
|
override fun onKeyUp(keyCode: Int, event: KeyEvent?): Boolean {
|
|
return latinIMELegacy.onKeyUp(keyCode, event) || super.onKeyUp(keyCode, event)
|
|
}
|
|
|
|
override fun updateVisibility(shouldShowSuggestionsStrip: Boolean, fullscreenMode: Boolean) {
|
|
this.shouldShowSuggestionStrip = shouldShowSuggestionsStrip
|
|
setContent()
|
|
}
|
|
|
|
override fun setSuggestions(suggestedWords: SuggestedWords?, rtlSubtype: Boolean) {
|
|
this.suggestedWords = suggestedWords
|
|
setContent()
|
|
}
|
|
|
|
override fun maybeShowImportantNoticeTitle(): Boolean {
|
|
return false
|
|
}
|
|
|
|
private fun cleanUpPersistentStates() {
|
|
println("Cleaning up persistent states")
|
|
for((key, value) in persistentStates.entries) {
|
|
if(currWindowAction != key) {
|
|
value?.cleanUp()
|
|
}
|
|
}
|
|
}
|
|
|
|
override fun onLowMemory() {
|
|
super.onLowMemory()
|
|
cleanUpPersistentStates()
|
|
}
|
|
|
|
override fun onTrimMemory(level: Int) {
|
|
super.onTrimMemory(level)
|
|
cleanUpPersistentStates()
|
|
}
|
|
|
|
override fun getContext(): Context {
|
|
return this
|
|
}
|
|
|
|
override fun getLifecycleScope(): LifecycleCoroutineScope {
|
|
return lifecycleScope
|
|
}
|
|
|
|
override fun triggerContentUpdate() {
|
|
setContent()
|
|
}
|
|
|
|
override fun typePartialText(v: String) {
|
|
latinIMELegacy.mInputLogic.mConnection.setComposingText(v, 1)
|
|
}
|
|
|
|
override fun typeText(v: String) {
|
|
latinIMELegacy.onTextInput(v)
|
|
}
|
|
|
|
override fun closeActionWindow() {
|
|
returnBackToMainKeyboardViewFromAction()
|
|
}
|
|
|
|
override fun triggerSystemVoiceInput() {
|
|
latinIMELegacy.onCodeInput(
|
|
Constants.CODE_SHORTCUT,
|
|
Constants.SUGGESTION_STRIP_COORDINATE,
|
|
Constants.SUGGESTION_STRIP_COORDINATE,
|
|
false
|
|
);
|
|
}
|
|
|
|
override fun updateTheme(newTheme: ThemeOption) {
|
|
assert(newTheme.available(this))
|
|
activeThemeOption = newTheme
|
|
updateDrawableProvider(newTheme.obtainColors(this))
|
|
|
|
deferSetSetting(THEME_KEY, newTheme.key)
|
|
|
|
recreateKeyboard()
|
|
}
|
|
|
|
@RequiresApi(Build.VERSION_CODES.R)
|
|
override fun onCreateInlineSuggestionsRequest(uiExtras: Bundle): InlineSuggestionsRequest {
|
|
return createInlineSuggestionsRequest(this, this.activeColorScheme)
|
|
}
|
|
|
|
@RequiresApi(Build.VERSION_CODES.R)
|
|
override fun onInlineSuggestionsResponse(response: InlineSuggestionsResponse): Boolean {
|
|
inlineSuggestions = response.inlineSuggestions.map {
|
|
inflateInlineSuggestion(it)
|
|
}
|
|
setContent()
|
|
|
|
return true
|
|
}
|
|
} |