Skip to content

Commit

Permalink
Merge pull request #12535 from keymanapp/chore/merge-master-into-web-…
Browse files Browse the repository at this point in the history
…core

chore: merge master into web-core 🎼
  • Loading branch information
mcdurdin authored Oct 11, 2024
2 parents fc5b972 + e44e0c9 commit 8ab2b8b
Show file tree
Hide file tree
Showing 34 changed files with 1,237 additions and 678 deletions.
9 changes: 5 additions & 4 deletions .github/workflows/api-verification.yml
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
name: "API Verification"
run-name: "API Verification for ${{ github.ref_name }}"
on:
workflow_run:
workflows: [Ubuntu packaging]
Expand Down Expand Up @@ -68,6 +67,8 @@ jobs:

- name: "Verify API for libkeymancore*.so (${{ steps.environment_step.outputs.GIT_BRANCH }}, branch ${{ steps.environment_step.outputs.GIT_BASE_BRANCH }}, by ${{ steps.environment_step.outputs.GIT_USER }})"
run: |
echo "Verify API for libkeymancore*.so (${{ steps.environment_step.outputs.GIT_BRANCH }}, branch ${{ steps.environment_step.outputs.GIT_BASE_BRANCH }}, by ${{ steps.environment_step.outputs.GIT_USER }})" >> $GITHUB_STEP_SUMMARY
BIN_PACKAGE=$(ls "${GITHUB_WORKSPACE}/artifacts/" | grep "${PKG_NAME}[0-9]*_${{ steps.environment_step.outputs.VERSION }}-1${{ steps.environment_step.outputs.PRERELEASE_TAG }}+$(lsb_release -c -s)1_amd64.deb")
cd ${{ github.workspace }}/keyman/linux
./scripts/deb-packaging.sh \
Expand All @@ -94,19 +95,19 @@ jobs:
if: needs.api_verification.result == 'success'
run: |
echo "RESULT=success" >> $GITHUB_ENV
echo "MSG=Package build succeeded" >> $GITHUB_ENV
echo "MSG=API verification succeeded" >> $GITHUB_ENV
- name: Set cancelled
if: needs.api_verification.result == 'cancelled'
run: |
echo "RESULT=error" >> $GITHUB_ENV
echo "MSG=Package build cancelled" >> $GITHUB_ENV
echo "MSG=API verification cancelled" >> $GITHUB_ENV
- name: Set failure
if: needs.api_verification.result == 'failure'
run: |
echo "RESULT=failure" >> $GITHUB_ENV
echo "MSG=Package build failed" >> $GITHUB_ENV
echo "MSG=API verification failed" >> $GITHUB_ENV
- name: Set final status
run: |
Expand Down
19 changes: 19 additions & 0 deletions HISTORY.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,24 @@
# Keyman Version History

## 18.0.125 alpha 2024-10-10

* chore(common): allow to run `build.sh` scripts in `bashdb` debugger (#12518)
* chore(linux): Improve output of API Verification (#12522)
* chore(linux): allow to skip API change (#12519)
* fix(linux): fix problem with API checks with merge commits (#12520)
* refactor(web): move `KeyboardObject` type to `common/web/types` (#12514)

## 18.0.124 alpha 2024-10-09

* chore(common): fix links in minimum-versions.md (#12507)
* fix(developer): use richedit in debug memo to support Egyptian cartouches (#12464)
* feat(android): Add controls for auto-correct (#12443)

## 18.0.123 alpha 2024-10-08

* chore(developer,common): deps: replace xml2js with fast-xml-parser (#12502)
* chore(ios): renew certificate (#12512)

## 18.0.122 alpha 2024-10-07

* feat(mac): both option keys generate right alt if no left alt mapping (#12458)
Expand Down
2 changes: 1 addition & 1 deletion VERSION.md
Original file line number Diff line number Diff line change
@@ -1 +1 @@
18.0.123
18.0.126
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
import com.keyman.engine.KMManager;
import com.keyman.engine.KMManager.KeyboardType;
import com.keyman.engine.KMHardwareKeyboardInterpreter;
import com.keyman.engine.KMManager.SuggestionType;
import com.keyman.engine.KeyboardEventHandler.OnKeyboardEventListener;
import com.keyman.engine.R;
import com.keyman.engine.data.Keyboard;
Expand Down Expand Up @@ -169,8 +170,9 @@ public void onStartInput(EditorInfo attribute, boolean restarting) {
if (kbInfo != null) {
String langId = kbInfo.getLanguageID();
SharedPreferences prefs = appContext.getSharedPreferences(appContext.getString(R.string.kma_prefs_name), Context.MODE_PRIVATE);
boolean mayPredict = prefs.getBoolean(KMManager.getLanguagePredictionPreferenceKey(langId), true);
KMManager.setBannerOptions(mayPredict);
int maySuggest = prefs.getInt(KMManager.getLanguageAutoCorrectionPreferenceKey(langId), KMManager.KMDefault_Suggestion);
// Enable banner if maySuggest is not SuggestionType.SUGGESTIONS_DISABLED (0)
KMManager.setBannerOptions(maySuggest != SuggestionType.SUGGESTIONS_DISABLED.toInt());
} else {
KMManager.setBannerOptions(false);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,13 @@
import android.widget.ImageButton;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.RadioButton;
import android.widget.RadioGroup;
import android.widget.RadioGroup.OnCheckedChangeListener;
import android.widget.RelativeLayout;
import android.widget.TextView;

import androidx.annotation.IdRes;
import androidx.annotation.NonNull;
import androidx.appcompat.app.AlertDialog;
import androidx.appcompat.app.AppCompatActivity;
Expand Down Expand Up @@ -55,50 +59,6 @@ public final class LanguageSettingsActivity extends AppCompatActivity {

private final static String TAG = "LanguageSettingsAct";

private class PreferenceToggleListener implements View.OnClickListener {
String prefsKey;
String lgCode;

public PreferenceToggleListener(String prefsKey, String lgCode) {
this.prefsKey = prefsKey;
this.lgCode = lgCode;
}

@Override
public void onClick(View v) {
// For predictions/corrections toggle
SwitchCompat toggle = (SwitchCompat) v;

SharedPreferences.Editor prefEditor = prefs.edit();

// predictionsToggle overrides correctionToggle and correctionsTextView
if (prefsKey.endsWith(KMManager.predictionPrefSuffix)) {
boolean override = toggle.isChecked();
overrideCorrectionsToggle(override);
}

// This will allow preemptively making settings for languages without models.
// Seems more trouble than it's worth to block this.
prefEditor.putBoolean(prefsKey, toggle.isChecked());
prefEditor.apply();

// Don't use/apply language modeling settings for languages without models.
if (associatedLexicalModel.isEmpty()) {
return;
}

Keyboard kbInfo = KMManager.getCurrentKeyboardInfo(context);
if(kbInfo != null) {
// If the active keyboard is for this language, immediately enact the new pref setting.
String kbdLgCode = kbInfo.getLanguageID();
if (kbdLgCode.equals(lgCode)) {
// Not only registers the model but also applies our modeling preferences.
KMManager.registerAssociatedLexicalModel(lgCode);
}
}
}
}

@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Expand Down Expand Up @@ -139,33 +99,48 @@ public void onCreate(Bundle savedInstanceState) {

FilteredKeyboardsAdapter adapter = new FilteredKeyboardsAdapter(context, KeyboardPickerActivity.getInstalledDataset(context), lgCode);

// The following two layouts/toggles will need to link with these objects.
// The following radio group will need to link with these objects.
Context appContext = this.getApplicationContext();
prefs = appContext.getSharedPreferences(appContext.getString(R.string.kma_prefs_name), Context.MODE_PRIVATE);
boolean mayPredict = prefs.getBoolean(KMManager.getLanguagePredictionPreferenceKey(lgCode), true);
boolean mayCorrect = prefs.getBoolean(KMManager.getLanguageCorrectionPreferenceKey(lgCode), true);

RelativeLayout layout = (RelativeLayout)findViewById(R.id.corrections_toggle);
int maySuggest = prefs.getInt(KMManager.getLanguageAutoCorrectionPreferenceKey(lgCode), KMManager.KMDefault_Suggestion);

correctionsTextView = (TextView) layout.findViewById(R.id.text1);
correctionsTextView.setText(getString(R.string.enable_corrections));
correctionsToggle = layout.findViewById(R.id.toggle);
correctionsToggle.setChecked(mayCorrect); // Link to persistent option storage! Also needs handler.
String prefsKey = KMManager.getLanguageCorrectionPreferenceKey(lgCode);
correctionsToggle.setOnClickListener(new PreferenceToggleListener(prefsKey, lgCode));
// Initialize Radio button group change listeners
RadioGroup radioGroup = (RadioGroup) findViewById(R.id.suggestion_radio_group);
radioGroup.clearCheck();

layout = (RelativeLayout)findViewById(R.id.predictions_toggle);
int[] RadioButtonArray = {
R.id.suggestion_radio_0,
R.id.suggestion_radio_1,
R.id.suggestion_radio_2,
R.id.suggestion_radio_3};
RadioButton radioButton = (RadioButton)radioGroup.findViewById(RadioButtonArray[maySuggest]);
radioButton.setChecked(true);

textView = (TextView) layout.findViewById(R.id.text1);
textView.setText(getString(R.string.enable_predictions));
SwitchCompat predictionsToggle = layout.findViewById(R.id.toggle);
predictionsToggle.setChecked(mayPredict); // Link to persistent option storage! Also needs handler.
prefsKey = KMManager.getLanguagePredictionPreferenceKey(lgCode);
predictionsToggle.setOnClickListener(new PreferenceToggleListener(prefsKey, lgCode));
radioGroup.setOnCheckedChangeListener(new OnCheckedChangeListener() {
@Override
public void onCheckedChanged(RadioGroup group, @IdRes int checkId) {
RadioButton checkedButton = (RadioButton)radioGroup.findViewById(checkId);
int index = radioGroup.indexOfChild(checkedButton);
KMManager.setMaySuggest(lgCode, KMManager.SuggestionType.fromInt(index));

// Don't use/apply language modeling settings for languages without models.
if (associatedLexicalModel.isEmpty()) {
return;
}

overrideCorrectionsToggle(mayPredict);
Keyboard kbInfo = KMManager.getCurrentKeyboardInfo(context);
if(kbInfo != null) {
// If the active keyboard is for this language, immediately enact the new pref setting.
String kbdLgCode = kbInfo.getLanguageID();
if (kbdLgCode.equals(lgCode)) {
// Not only registers the model but also applies our modeling preferences.
KMManager.registerAssociatedLexicalModel(lgCode);
}
}
}
});

layout = (RelativeLayout)findViewById(R.id.model_picker);
RelativeLayout layout = (RelativeLayout)findViewById(R.id.model_picker);
textView = (TextView) layout.findViewById(R.id.text1);
textView.setText(getString(R.string.model_label));

Expand Down
18 changes: 15 additions & 3 deletions android/KMEA/app/src/main/assets/android-host.js
Original file line number Diff line number Diff line change
Expand Up @@ -229,11 +229,23 @@ function deregisterModel(modelID) {
keyman.removeModel(modelID);
}

function enableSuggestions(model, mayPredict, mayCorrect) {
function enableSuggestions(model, suggestionType) {
// Set the options first so that KMW's ModelManager can properly handle model enablement states
// the moment we actually register the new model.
keyman.core.languageProcessor.mayPredict = mayPredict;
keyman.core.languageProcessor.mayCorrect = mayCorrect;
// Use console_debug
console_debug('enableSuggestions(model, maySuggest='+suggestionType+')');
const suggestionSettings = [
// mayPredict, mayCorrect, mayAutoCorrect
[false, false, false], // 0 = SuggestionType.SUGGESTIONS_DISABLED
[true, false, false], // 1 = SuggestionType.PREDICTIONS_ONLY
[true, true, false], // 2 = SuggestionType.PREDICTIONS_WITH_CORRECTIONS
[true, true, true], // 3 = SuggestionType.PREDICTIONS_WITH_AUTO_CORRECT
];
const t = suggestionSettings[suggestionType]
? suggestionSettings[suggestionType] : suggestionSettings[0];
keyman.core.languageProcessor.mayPredict = t[0];
keyman.core.languageProcessor.maySuggest = t[1];
// keyman.core.languageProcessor.mayAutoCorrect = t[2];

registerModel(model);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
import com.keyman.engine.KeyboardEventHandler.EventType;
import com.keyman.engine.KMManager;
import com.keyman.engine.KMManager.KeyboardType;
import com.keyman.engine.KMManager.SuggestionType;
import com.keyman.engine.util.KMLog;
import com.keyman.engine.data.Keyboard;

Expand Down Expand Up @@ -165,7 +166,9 @@ public boolean shouldOverrideUrlLoading(WebView view, String url) {
SharedPreferences prefs = context.getSharedPreferences(context.getString(R.string.kma_prefs_name), Context.MODE_PRIVATE);
boolean modelPredictionPref = false;
if (!KMManager.getMayPredictOverride() && KMManager.currentLexicalModel != null) {
modelPredictionPref = prefs.getBoolean(KMManager.getLanguagePredictionPreferenceKey(KMManager.currentLexicalModel.get(KMManager.KMKey_LanguageID)), true);
modelPredictionPref = prefs.getInt(KMManager.getLanguageAutoCorrectionPreferenceKey(
KMManager.currentLexicalModel.get(KMManager.KMKey_LanguageID)), KMManager.KMDefault_Suggestion)
!= SuggestionType.SUGGESTIONS_DISABLED.toInt();
}
KMManager.setBannerOptions(modelPredictionPref);
RelativeLayout.LayoutParams params = KMManager.getKeyboardLayoutParams();
Expand Down
59 changes: 53 additions & 6 deletions android/KMEA/app/src/main/java/com/keyman/engine/KMManager.java
Original file line number Diff line number Diff line change
Expand Up @@ -192,6 +192,35 @@ public enum EnterModeType {
DEFAULT, // Default ENTER action
}

// Enum for whether the suggestion banner allows predictions, corrections, auto-corrections
public enum SuggestionType {
// Suggestion Disabled - No Predictions, No corrections, No auto-corrections
SUGGESTIONS_DISABLED,

// Suggestions Enabled
PREDICTIONS_ONLY, // Predictions with no corrections
PREDICTIONS_WITH_CORRECTIONS, // Predictions with corrections
PREDICTIONS_WITH_AUTO_CORRECT; // Predictions with auto-corrections

public static SuggestionType fromInt(int mode) {
switch (mode) {
case 0:
return SUGGESTIONS_DISABLED;
case 1:
return PREDICTIONS_ONLY;
case 2:
return PREDICTIONS_WITH_CORRECTIONS;
case 3:
return PREDICTIONS_WITH_AUTO_CORRECT;
}
return SUGGESTIONS_DISABLED;
}

public int toInt() {
return this.ordinal();
}
}

protected static InputMethodService IMService;

private static boolean debugMode = false;
Expand Down Expand Up @@ -220,6 +249,7 @@ public enum EnterModeType {

public final static String predictionPrefSuffix = ".mayPredict";
public final static String correctionPrefSuffix = ".mayCorrect";
public final static String autoCorrectionPrefSuffix = ".mayAutoCorect";

// Special override for when the keyboard may have haptic feedback when typing.
// haptic feedback disabled for hardware keystrokes
Expand Down Expand Up @@ -315,6 +345,8 @@ public enum EnterModeType {
public static final int KMMinimum_LongpressDelay = 300;
public static final int KMMaximum_LongpressDelay = 1500;

// Default prediction/correction setting
public static final int KMDefault_Suggestion = SuggestionType.PREDICTIONS_WITH_CORRECTIONS.toInt();

// Keyman files
protected static final String KMFilename_KeyboardHtml = "keyboard.html";
Expand Down Expand Up @@ -707,6 +739,10 @@ public static String getLanguageCorrectionPreferenceKey(String langID) {
return langID + correctionPrefSuffix;
}

public static String getLanguageAutoCorrectionPreferenceKey(String langID) {
return langID + autoCorrectionPrefSuffix;
}

public static void hideSystemKeyboard() {
if (SystemKeyboard != null) {
SystemKeyboard.hideKeyboard();
Expand Down Expand Up @@ -1350,6 +1386,18 @@ public static boolean getMayPredictOverride() {
return mayPredictOverride;
}

/**
* Store SuggestionType as int in preference
* @param languageID as String
* @param suggestType SuggestionType
*/
public static void setMaySuggest(String languageID, SuggestionType suggestType) {
SharedPreferences prefs = appContext.getSharedPreferences(appContext.getString(R.string.kma_prefs_name), Context.MODE_PRIVATE);
SharedPreferences.Editor editor = prefs.edit();
editor.putInt(KMManager.getLanguageAutoCorrectionPreferenceKey(languageID), suggestType.toInt());
editor.commit();
}

/**
* Determines if the InputType field is a numeric field
* @param inputType
Expand Down Expand Up @@ -1462,24 +1510,23 @@ public static boolean registerLexicalModel(HashMap<String, String> lexicalModelI
model = model.replaceAll("\'", "\\\\'"); // Double-escaped-backslash b/c regex.
model = model.replaceAll("\"", "'");

// When entering password field, mayPredict should override to false
// When entering password field, maySuggest should override to disabled
SharedPreferences prefs = appContext.getSharedPreferences(appContext.getString(R.string.kma_prefs_name), Context.MODE_PRIVATE);
boolean mayPredict = (mayPredictOverride) ? false :
prefs.getBoolean(getLanguagePredictionPreferenceKey(languageID), true);
boolean mayCorrect = prefs.getBoolean(getLanguageCorrectionPreferenceKey(languageID), true);
int maySuggest = mayPredictOverride ? SuggestionType.SUGGESTIONS_DISABLED.toInt() :
prefs.getInt(getLanguageAutoCorrectionPreferenceKey(languageID), KMDefault_Suggestion);

RelativeLayout.LayoutParams params;
if (isKeyboardLoaded(KeyboardType.KEYBOARD_TYPE_INAPP) && !InAppKeyboard.shouldIgnoreTextChange() && modelFileExists) {
params = getKeyboardLayoutParams();

// Do NOT re-layout here; it'll be triggered once the banner loads.
InAppKeyboard.loadJavascript(KMString.format("enableSuggestions(%s, %s, %s)", model, mayPredict, mayCorrect));
InAppKeyboard.loadJavascript(KMString.format("enableSuggestions(%s, %d)", model, maySuggest));
}
if (isKeyboardLoaded(KeyboardType.KEYBOARD_TYPE_SYSTEM) && !SystemKeyboard.shouldIgnoreTextChange() && modelFileExists) {
params = getKeyboardLayoutParams();

// Do NOT re-layout here; it'll be triggered once the banner loads.
SystemKeyboard.loadJavascript(KMString.format("enableSuggestions(%s, %s, %s)", model, mayPredict, mayCorrect));
SystemKeyboard.loadJavascript(KMString.format("enableSuggestions(%s, %d)", model, maySuggest));
}
return true;
}
Expand Down
Loading

0 comments on commit 8ab2b8b

Please sign in to comment.