diff --git a/res/values-bg/strings.xml b/res/values-bg/strings.xml
index 190d34c5..2cc03ac5 100644
--- a/res/values-bg/strings.xml
+++ b/res/values-bg/strings.xml
@@ -28,6 +28,8 @@
Съвместимост
Облик
Бутони за бърз достъп
+ Изпращай съобщения с ОК в Messenger
+ Позволява изпращането на съобщения с бутона ОК във Facebook Messenger и Messenger Lite.
Бутони на екрана
Назад
Зелена слушалка
diff --git a/res/values-fr/strings.xml b/res/values-fr/strings.xml
index ad81fd05..29d37e5f 100644
--- a/res/values-fr/strings.xml
+++ b/res/values-fr/strings.xml
@@ -28,6 +28,8 @@
Apparance
Echec du chargement. Mot inadmissible «%1$s» à la ligne %2$d de langue «%3$s».
Le dictionaire est supprimé avec succès.
+ Envoyer des messages avec OK dans Messenger
+ La touche OK servira pour envoyer des messages dans Facebook Messenger et Messenger Lite.
Boutons à l\'écran
Chargement du dictionnaire
Chargement est annulé.
diff --git a/res/values-ru/strings.xml b/res/values-ru/strings.xml
index db8b307d..250ebb43 100644
--- a/res/values-ru/strings.xml
+++ b/res/values-ru/strings.xml
@@ -42,6 +42,8 @@
Авто заглавные буквы
Автоматически начинать предложение с заглавной буквы.
Символ при двойном нажатии клавиши 0
+ Отправка сообщения с «ОК» в Messenger
+ Позволяет отправлять сообщения с помощью кнопки «ОК» в Facebook Messenger и Messenger Lite.
Кнопки на экране
Не удалось загрузить словарь. Проблема в слове «%1$s» в строке %2$d для языка «%3$s».
Отсутствует словарь для языка «%1$s». Вы можете загрузить его в Настройках.
diff --git a/res/values-uk/strings.xml b/res/values-uk/strings.xml
index d9184979..3fd4c2f1 100644
--- a/res/values-uk/strings.xml
+++ b/res/values-uk/strings.xml
@@ -41,6 +41,8 @@
Авто заголовні букви
Автоматично починати речення з заголовної букви.
Символ при подвійному натисканні клавіші 0
+ Надсилати повідомлення з «ОК» до Messenger
+ Дозволяє надсилати повідомлення за допомогою клавіші «ОК» у Facebook Messenger і Messenger Lite.
Кнопки на екрані
Назад
Виклик
diff --git a/res/values/strings.xml b/res/values/strings.xml
index baa4a497..8bd20fe2 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -47,6 +47,8 @@
Detailed Debug Logs
System Logs
Character for Double 0-key Press
+ Send messages with OK in Messenger
+ Allows sending messages with the OK key in Facebook Messenger and Messenger Lite.
Show On-Screen Keys
Show On-Screen Numpad
(BETA)
diff --git a/res/xml/prefs_screen_setup.xml b/res/xml/prefs_screen_setup.xml
index eb4a222b..1e4a7ab2 100644
--- a/res/xml/prefs_screen_setup.xml
+++ b/res/xml/prefs_screen_setup.xml
@@ -23,5 +23,11 @@
app:title="@string/pref_alternative_suggestion_scrolling"
app:summary="@string/pref_alternative_suggestion_scrolling_summary"/>
+
+
diff --git a/src/io/github/sspanak/tt9/ime/KeyPadHandler.java b/src/io/github/sspanak/tt9/ime/KeyPadHandler.java
index 44e99e57..781c4759 100644
--- a/src/io/github/sspanak/tt9/ime/KeyPadHandler.java
+++ b/src/io/github/sspanak/tt9/ime/KeyPadHandler.java
@@ -6,6 +6,7 @@ import android.view.View;
import android.view.inputmethod.EditorInfo;
import android.view.inputmethod.InputConnection;
+import io.github.sspanak.tt9.Logger;
import io.github.sspanak.tt9.ime.helpers.Key;
import io.github.sspanak.tt9.preferences.SettingsStore;
@@ -74,7 +75,10 @@ abstract class KeyPadHandler extends InputMethodService {
*/
@Override
public void onStartInput(EditorInfo inputField, boolean restarting) {
- // Logger.d("T9.onStartInput", "inputType: " + inputField.inputType + " fieldId: " + inputField.fieldId + " fieldName: " + inputField.fieldName + " packageName: " + inputField.packageName + " privateImeOptions: " + inputField.privateImeOptions + " imeOptions: " + inputField.imeOptions + " extras: " + inputField.extras);
+ Logger.d(
+ "KeyPadHandler",
+ "===> Start Up; packageName: " + inputField.packageName + " inputType: " + inputField.inputType + " fieldId: " + inputField.fieldId + " fieldName: " + inputField.fieldName + " privateImeOptions: " + inputField.privateImeOptions + " imeOptions: " + inputField.imeOptions + " extras: " + inputField.extras
+ );
currentInputConnection = getCurrentInputConnection();
onStart(inputField);
}
diff --git a/src/io/github/sspanak/tt9/ime/helpers/AppHacks.java b/src/io/github/sspanak/tt9/ime/helpers/AppHacks.java
index 4e0c2ab5..1020735d 100644
--- a/src/io/github/sspanak/tt9/ime/helpers/AppHacks.java
+++ b/src/io/github/sspanak/tt9/ime/helpers/AppHacks.java
@@ -31,7 +31,7 @@ public class AppHacks {
* weird side effects occur. Nevertheless, all other text fields in the app are fine, so we detect only these two particular ones.
*/
private boolean isKindleInvertedTextField() {
- return editorInfo != null && editorInfo.inputType == 1 && editorInfo.packageName.contains("com.amazon.kindle");
+ return isAppField("com.amazon.kindle", EditorInfo.TYPE_CLASS_TEXT);
}
@@ -42,10 +42,52 @@ public class AppHacks {
* and are ignored by TT9 by default. In order not to ignore Termux, we need this.
*/
public boolean isTermux() {
- return editorInfo != null && editorInfo.inputType == 0 && editorInfo.fieldId > 0 && editorInfo.packageName.contains("com.termux");
+ return isAppField("com.termux", EditorInfo.TYPE_NULL) && editorInfo.fieldId > 0;
}
+ /**
+ * isMessenger
+ * Facebook Messenger has flaky support for sending messages. To fix that, we detect the chat input field and send the appropriate
+ * key codes to it. See "onFbMessengerEnter()" for info how the hack works.
+ */
+ private boolean isMessenger() {
+ return isAppField(
+ "com.facebook.orca",
+ EditorInfo.TYPE_CLASS_TEXT | EditorInfo.TYPE_TEXT_FLAG_MULTI_LINE | EditorInfo.TYPE_TEXT_FLAG_CAP_SENTENCES
+ );
+ }
+
+
+ /**
+ * isMessengerLite
+ * Facebook Messenger Lite does not support sending messages with OK/ENTER. To enable that, we
+ * detect the chat field and apply the proper series of commands to it. See "onFbMessengerEnter()" for info how the hack works.
+ */
+ private boolean isMessengerLite() {
+ return isAppField(
+ "com.facebook.mlite",
+ EditorInfo.TYPE_CLASS_TEXT | EditorInfo.TYPE_TEXT_FLAG_MULTI_LINE | EditorInfo.TYPE_TEXT_FLAG_CAP_SENTENCES | EditorInfo.TYPE_TEXT_FLAG_AUTO_CORRECT
+ );
+ }
+
+
+ /**
+ * isAppField
+ * Detects a particular input field of a particular application.
+ */
+ private boolean isAppField(String appPackageName, int fieldSpec) {
+ return
+ editorInfo != null
+ && ((editorInfo.inputType & fieldSpec) == fieldSpec)
+ && editorInfo.packageName.equals(appPackageName);
+ }
+
+
+ /**
+ * setComposingTextWithHighlightedStem
+ * A compatibility function for text fields that do not support SpannableString. Effectively disables highlighting.
+ */
public boolean setComposingTextWithHighlightedStem(@NonNull String word) {
if (isKindleInvertedTextField()) {
textField.setComposingText(word);
@@ -55,6 +97,7 @@ public class AppHacks {
return false;
}
+
/**
* onBackspace
* Performs extra Backspace operations and returns "false", or completely replaces Backspace and returns "true". When "true" is
@@ -82,6 +125,8 @@ public class AppHacks {
if (isTermux()) {
sendDownUpKeyEvents(KeyEvent.KEYCODE_ENTER);
return true;
+ } else if (isMessenger() || isMessengerLite()) {
+ return onEnterFbMessenger();
}
return onEnterDefault();
@@ -121,6 +166,45 @@ public class AppHacks {
}
+ /**
+ * onEnterFbMessenger
+ * Once we have detected the chat message field we apply the appropriate key combo to send the message.
+ */
+ private boolean onEnterFbMessenger() {
+ if (textField == null) {
+ return false;
+ }
+
+ // in case the setting is disabled, just type a new line as one would expect
+ if (!settings.getFbMessengerHack()) {
+ inputConnection.commitText("\n", 1);
+ return true;
+ }
+
+ // do not send any commands if the user has not typed anything or the field is invalid
+ if (!textField.isThereText()) {
+ return false;
+ }
+
+ if (isMessenger()) {
+ // Messenger responds only to ENTER, but not DPAD_CENTER, so we make sure to send the correct code,
+ // no matter how the hardware key is implemented.
+ sendDownUpKeyEvents(KeyEvent.KEYCODE_ENTER);
+ } else {
+ // Messenger Lite responds to no key codes, so we trick it by going right to the Send button, pressing it,
+ // then going back to the chat field.
+ sendDownUpKeyEvents(KeyEvent.KEYCODE_DPAD_RIGHT);
+ sendDownUpKeyEvents(KeyEvent.KEYCODE_DPAD_RIGHT);
+ sendDownUpKeyEvents(KeyEvent.KEYCODE_DPAD_CENTER);
+ sendDownUpKeyEvents(KeyEvent.KEYCODE_DPAD_LEFT);
+ sendDownUpKeyEvents(KeyEvent.KEYCODE_DPAD_LEFT);
+ }
+
+
+ return true;
+ }
+
+
private void sendDownUpKeyEvents(int keyCode) {
if (inputConnection != null) {
inputConnection.sendKeyEvent(new KeyEvent(KeyEvent.ACTION_DOWN, keyCode));
diff --git a/src/io/github/sspanak/tt9/preferences/SettingsStore.java b/src/io/github/sspanak/tt9/preferences/SettingsStore.java
index 561b800a..a681202d 100644
--- a/src/io/github/sspanak/tt9/preferences/SettingsStore.java
+++ b/src/io/github/sspanak/tt9/preferences/SettingsStore.java
@@ -265,10 +265,6 @@ public class SettingsStore {
/************* internal settings *************/
- public int getSuggestionScrollingDelay() {
- return prefs.getBoolean("pref_alternative_suggestion_scrolling", false) ? 200 : 0;
- }
-
public int getDictionaryImportProgressUpdateInterval() { return 250; /* ms */ }
public int getDictionaryImportWordChunkSize() { return 1000; /* words */ }
@@ -284,4 +280,15 @@ public class SettingsStore {
public int getWordFrequencyMax() { return 25500; }
public int getWordFrequencyNormalizationDivider() { return 100; } // normalized frequency = getWordFrequencyMax() / getWordFrequencyNormalizationDivider()
+
+
+ /************* hack settings *************/
+
+ public int getSuggestionScrollingDelay() {
+ return prefs.getBoolean("pref_alternative_suggestion_scrolling", false) ? 200 : 0;
+ }
+
+ public boolean getFbMessengerHack() {
+ return prefs.getBoolean("pref_hack_fb_messenger", false);
+ }
}