From f175ffe7ca597513ef87189825a3c907ad90ef3f Mon Sep 17 00:00:00 2001 From: Patrick Goldinger Date: Thu, 1 Jun 2023 10:43:42 +0200 Subject: [PATCH] Add support for plugins requiring always suggestion enabled --- .../localization/LocalizationScreen.kt | 4 ++-- .../ime/editor/AbstractEditorInstance.kt | 5 +---- .../florisboard/ime/editor/EditorInstance.kt | 15 +++---------- .../ime/keyboard/KeyboardManager.kt | 16 ++++++-------- .../florisboard/ime/nlp/NlpManager.kt | 21 +++++++------------ .../main/res/xml/latin_language_provider.xml | 2 +- .../plugin/FlorisPluginMetadata.kt | 11 ++++++++-- 7 files changed, 30 insertions(+), 44 deletions(-) diff --git a/app/src/main/kotlin/dev/patrickgold/florisboard/app/settings/localization/LocalizationScreen.kt b/app/src/main/kotlin/dev/patrickgold/florisboard/app/settings/localization/LocalizationScreen.kt index 37ab6084..2ad713ec 100644 --- a/app/src/main/kotlin/dev/patrickgold/florisboard/app/settings/localization/LocalizationScreen.kt +++ b/app/src/main/kotlin/dev/patrickgold/florisboard/app/settings/localization/LocalizationScreen.kt @@ -264,7 +264,7 @@ private fun FlorisInvalidPluginBox(plugin: IndexedPlugin) { @Composable private fun florisPluginFeatureToString(feature: FlorisPluginFeature): String { return when (feature) { - FlorisPluginFeature.SpellingConfig -> "Spelling" - FlorisPluginFeature.SuggestionConfig -> "Suggestion" + is FlorisPluginFeature.SpellingConfig -> "Spelling" + is FlorisPluginFeature.SuggestionConfig -> "Suggestion" } } diff --git a/app/src/main/kotlin/dev/patrickgold/florisboard/ime/editor/AbstractEditorInstance.kt b/app/src/main/kotlin/dev/patrickgold/florisboard/ime/editor/AbstractEditorInstance.kt index b757aff8..f05c9cf3 100644 --- a/app/src/main/kotlin/dev/patrickgold/florisboard/ime/editor/AbstractEditorInstance.kt +++ b/app/src/main/kotlin/dev/patrickgold/florisboard/ime/editor/AbstractEditorInstance.kt @@ -40,7 +40,6 @@ import kotlinx.coroutines.flow.asStateFlow import kotlinx.coroutines.launch import kotlinx.coroutines.runBlocking -@Suppress("BlockingMethodInNonBlockingContext") abstract class AbstractEditorInstance(context: Context) { companion object { private const val NumCharsBeforeCursor: Int = 256 @@ -242,7 +241,7 @@ abstract class AbstractEditorInstance(context: Context) { } else { EditorRange.Unspecified } - val localComposing = if (determineComposingEnabled()) localCurrentWord else EditorRange.Unspecified + val localComposing = if (nlpManager.isSuggestionEnabled()) localCurrentWord else EditorRange.Unspecified // Build and publish text and content val text = buildString { @@ -276,8 +275,6 @@ abstract class AbstractEditorInstance(context: Context) { } } - abstract fun determineComposingEnabled(): Boolean - abstract fun determineComposer(composerName: ExtensionComponentName): Composer protected open fun shouldDetermineComposingRegion(editorInfo: FlorisEditorInfo): Boolean { diff --git a/app/src/main/kotlin/dev/patrickgold/florisboard/ime/editor/EditorInstance.kt b/app/src/main/kotlin/dev/patrickgold/florisboard/ime/editor/EditorInstance.kt index 98d48499..00bb305b 100644 --- a/app/src/main/kotlin/dev/patrickgold/florisboard/ime/editor/EditorInstance.kt +++ b/app/src/main/kotlin/dev/patrickgold/florisboard/ime/editor/EditorInstance.kt @@ -111,13 +111,8 @@ class EditorInstance(context: Context) : AbstractEditorInstance(context) { activeState.keyboardMode = keyboardMode activeState.isComposingEnabled = when (keyboardMode) { KeyboardMode.NUMERIC, - KeyboardMode.PHONE, - KeyboardMode.PHONE2, - -> false - else -> activeState.keyVariation != KeyVariation.PASSWORD && - prefs.suggestion.enabled.get()// && - //!instance.inputAttributes.flagTextAutoComplete && - //!instance.inputAttributes.flagTextNoSuggestions + KeyboardMode.PHONE -> false + else -> activeState.keyVariation != KeyVariation.PASSWORD } activeState.isIncognitoMode = when (prefs.advanced.incognitoMode.get()) { IncognitoMode.FORCE_OFF -> false @@ -138,10 +133,6 @@ class EditorInstance(context: Context) : AbstractEditorInstance(context) { } } - override fun determineComposingEnabled(): Boolean { - return nlpManager.isSuggestionOn() - } - override fun determineComposer(composerName: ExtensionComponentName): Composer { return keyboardManager.resources.composers.value?.get(composerName) ?: Appender } @@ -251,7 +242,7 @@ class EditorInstance(context: Context) : AbstractEditorInstance(context) { * @return True on success, false if an error occurred or the input connection is invalid. */ fun commitCompletion(candidate: SuggestionCandidate): Boolean { - val text = candidate.text.toString() + val text = candidate.text if (text.isEmpty() || activeInfo.isRawInputEditor) return false val content = activeContent return if (content.composing.isValid) { diff --git a/app/src/main/kotlin/dev/patrickgold/florisboard/ime/keyboard/KeyboardManager.kt b/app/src/main/kotlin/dev/patrickgold/florisboard/ime/keyboard/KeyboardManager.kt index 2ebe1a93..f1908061 100644 --- a/app/src/main/kotlin/dev/patrickgold/florisboard/ime/keyboard/KeyboardManager.kt +++ b/app/src/main/kotlin/dev/patrickgold/florisboard/ime/keyboard/KeyboardManager.kt @@ -45,7 +45,6 @@ import dev.patrickgold.florisboard.ime.input.InputKeyEventReceiver import dev.patrickgold.florisboard.ime.input.InputShiftState import dev.patrickgold.florisboard.ime.nlp.PunctuationRule import dev.patrickgold.florisboard.ime.nlp.SuggestionCandidate -import dev.patrickgold.florisboard.ime.nlp.latin.LatinNlpSession import dev.patrickgold.florisboard.ime.onehanded.OneHandedMode import dev.patrickgold.florisboard.ime.popup.PopupMappingComponent import dev.patrickgold.florisboard.ime.text.composing.Composer @@ -147,13 +146,13 @@ class KeyboardManager(context: Context) : InputKeyEventReceiver { reevaluateInputShiftState() updateActiveEvaluators() editorInstance.refreshComposing() - resetSuggestions(editorInstance.activeContent) + generateSuggestions(editorInstance.activeContent) } clipboardManager.primaryClipFlow.collectLatestIn(scope) { updateActiveEvaluators() } editorInstance.activeContentFlow.collectIn(scope) { content -> - resetSuggestions(content) + generateSuggestions(content) } prefs.devtools.enabled.observeForever { reevaluateDebugFlags() @@ -213,15 +212,12 @@ class KeyboardManager(context: Context) : InputKeyEventReceiver { } } - fun resetSuggestions(content: EditorContent) { - if (content.textBeforeSelection == "crash") { - LatinNlpSession.nativeInit() - } - if (!(activeState.isComposingEnabled || nlpManager.isSuggestionOn())) { + private suspend fun generateSuggestions(content: EditorContent) { + if (nlpManager.isSuggestionEnabled()) { + nlpManager.suggest(subtypeManager.activeSubtype, content) + } else { nlpManager.clearSuggestions() - return } - nlpManager.suggest(subtypeManager.activeSubtype, content) } /** diff --git a/app/src/main/kotlin/dev/patrickgold/florisboard/ime/nlp/NlpManager.kt b/app/src/main/kotlin/dev/patrickgold/florisboard/ime/nlp/NlpManager.kt index 9d99596f..a6c015db 100644 --- a/app/src/main/kotlin/dev/patrickgold/florisboard/ime/nlp/NlpManager.kt +++ b/app/src/main/kotlin/dev/patrickgold/florisboard/ime/nlp/NlpManager.kt @@ -69,8 +69,6 @@ class NlpManager(context: Context) { private val scope = CoroutineScope(Dispatchers.Main + SupervisorJob()) private val clipboardSuggestionProvider = ClipboardSuggestionProvider() - // lock unnecessary because values constant - private val providersForceSuggestionOn = mutableMapOf() val plugins = FlorisPluginIndexer(context) private val internalSuggestionsGuard = Mutex() @@ -195,18 +193,15 @@ class NlpManager(context: Context) { } } - fun providerForcesSuggestionOn(subtype: Subtype): Boolean { - // Using a cache because I have no idea how fast the runBlocking is - //return providersForceSuggestionOn.getOrPut(subtype.nlpProviders.suggestion) { - // runBlocking { - // nlpProviderRegistry.getSuggestionProvider(subtype).forcesSuggestionOn - // } - //} - return false + private suspend fun providerRequiresSuggestionAlwaysEnabled(subtype: Subtype): Boolean { + return plugins.getOrNull(subtype.nlpProviders.suggestion) + ?.metadata?.suggestionConfig?.requireAlwaysEnabled ?: false } - fun isSuggestionOn(): Boolean = - prefs.suggestion.enabled.get() || providerForcesSuggestionOn(subtypeManager.activeSubtype) + suspend fun isSuggestionEnabled(): Boolean { + return keyboardManager.activeState.isComposingEnabled && + (prefs.suggestion.enabled.get() || providerRequiresSuggestionAlwaysEnabled(subtypeManager.activeSubtype)) + } fun suggest(subtype: Subtype, content: EditorContent) { val reqTime = SystemClock.uptimeMillis() @@ -274,7 +269,7 @@ class NlpManager(context: Context) { private fun assembleCandidates() { runBlocking { val candidates = when { - isSuggestionOn() -> { + isSuggestionEnabled() -> { clipboardSuggestionProvider.suggest( subtypeId = Subtype.FALLBACK.id, word = editorInstance.activeContent.currentWordText, diff --git a/app/src/main/res/xml/latin_language_provider.xml b/app/src/main/res/xml/latin_language_provider.xml index 2e85ad74..ee9b910c 100644 --- a/app/src/main/res/xml/latin_language_provider.xml +++ b/app/src/main/res/xml/latin_language_provider.xml @@ -15,6 +15,6 @@ - + diff --git a/plugin/src/main/kotlin/dev/patrickgold/florisboard/plugin/FlorisPluginMetadata.kt b/plugin/src/main/kotlin/dev/patrickgold/florisboard/plugin/FlorisPluginMetadata.kt index a69ef031..0afad167 100644 --- a/plugin/src/main/kotlin/dev/patrickgold/florisboard/plugin/FlorisPluginMetadata.kt +++ b/plugin/src/main/kotlin/dev/patrickgold/florisboard/plugin/FlorisPluginMetadata.kt @@ -109,7 +109,11 @@ data class FlorisPluginMetadata( ) } "spelling" -> pluginMetadata?.spellingConfig = FlorisPluginFeature.SpellingConfig - "suggestion" -> pluginMetadata?.suggestionConfig = FlorisPluginFeature.SuggestionConfig + "suggestion" -> { + pluginMetadata?.suggestionConfig = FlorisPluginFeature.SuggestionConfig( + requireAlwaysEnabled = attrOrNull("requireAlwaysEnabled").toBoolean(), + ) + } } eventType = parser.next() } @@ -121,5 +125,8 @@ data class FlorisPluginMetadata( sealed interface FlorisPluginFeature { object SpellingConfig : FlorisPluginFeature - object SuggestionConfig : FlorisPluginFeature + + data class SuggestionConfig( + val requireAlwaysEnabled: Boolean, + ) : FlorisPluginFeature }