Merge pull request #14630 from keymanapp/chore/merge-master-into-kmc-convert

auto: merge master into kmc-convert
This commit is contained in:
Marc Durdin 2025-08-28 16:54:12 +02:00 • committed by GitHub
commit 9e61a9267a
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
456 changed files with 4070 additions and 3109 deletions

1
.gitattributes vendored
View file

@ -7,3 +7,4 @@
# EOF
# ```
Dockerfile text eol=lf
*.sh text eol=lf

View file

@ -1,10 +1,9 @@
#
# Automatically merges pull requests opened by keyman-server
# The initial use of this action is to increment the patch
# version of Keyman with resources/build/increment-version.sh.
# That script creates a PR and then this workflow will be
# triggered to approve the PR (from github-actions account), and
# then automerge it.
# Automatically merges pull requests opened by keyman-server The initial use of
# this action is to increment the patch version of Keyman with
# resources/teamcity/triggers/trigger-release-builds.sh. That script creates a PR and
# then this workflow will be triggered to approve the PR (from github-actions
# account), and then automerge it.
#
name: Auto Merge PRs from keyman-server
on:
@ -17,12 +16,15 @@ jobs:
if: ${{ github.repository == 'keymanapp/keyman' && github.actor == 'keyman-server' && startsWith(github.event.pull_request.title, 'auto:') }}
steps:
- name: auto approve PR from keyman-server
uses: hmarr/auto-approve-action@f0939ea97e9205ef24d872e76833fa908a770363
with:
github-token: "${{ secrets.GITHUB_TOKEN }}"
- name: auto merge PR from keyman-server
uses: "pascalgn/automerge-action@7854d3bd607dccdaf0b2c134b699a812c8960213"
shell: bash
env:
GITHUB_TOKEN: "${{ secrets.AUTOINC_GITHUB_TOKEN }}"
MERGE_LABELS: "automerge"
MERGE_FORKS: false
GH_TOKEN: "${{ github.token }}"
run: |
gh pr review -R keymanapp/keyman --approve ${{ github.event.pull_request.number }}
- name: mark PR for auto-merge from keyman-server
shell: bash
if: contains(github.event.pull_request.labels.*.name, 'automerge')
env:
GH_TOKEN: "${{ secrets.AUTOINC_GITHUB_TOKEN }}"
run: |
gh pr merge -R keymanapp/keyman --merge --auto ${{ github.event.pull_request.number }}

View file

@ -86,7 +86,14 @@ jobs:
shell: bash
run: |
THIS_SCRIPT="$GITHUB_WORKSPACE/.github/workflows/deb-packaging.yml"
. "${THIS_SCRIPT%/*}/../../resources/build/build-utils.sh"
if [[ -f "${THIS_SCRIPT%/*}/../../resources/build/builder-basic.inc.sh" ]]; then
. "${THIS_SCRIPT%/*}/../../resources/build/builder-basic.inc.sh"
else
# TODO: remove following block post v19 release (file was renamed in v19 alpha)
if [[ -f "${THIS_SCRIPT%/*}/../../resources/build/build-utils.sh" ]]; then
. "${THIS_SCRIPT%/*}/../../resources/build/build-utils.sh"
fi
fi
echo "KEYMAN_VERSION=${KEYMAN_VERSION:-${VERSION}}" >> $GITHUB_OUTPUT
- name: Set prerelease tag as output parameter

6
.gitignore vendored
View file

@ -152,8 +152,8 @@
# Atom/Nuclide
compile_flags.txt
# Auto-generated resource script
resources/environment.sh
# Auto-generated resource script for xcode
resources/build/mac/xcode-environment.inc.sh
# Copy of the master VERSION.md used for Linux packaging
/core/VERSION.md
@ -164,7 +164,7 @@ tsconfig.tsbuildinfo
# Windows system files
Thumbs.db
# Temporary file for logging scripts in xcode runs, see build-utils.sh for
# Temporary file for logging scripts in xcode runs, see builder-basic.inc.sh for
# details
/xcodebuild-scripts.log

View file

@ -1,5 +1,94 @@
# Keyman Version History
## 19.0.106 alpha 2025-08-27
* fix(windows): check if automatic updates off before prompt (#14295)
* refactor(linux): use bash testing framework for packaging tests (#14603)
* maint(resources): use correct version for PR title for history cherry-pick (#14610)
* refactor(common): fix shellcheck warnings (#14580)
## 19.0.105 alpha 2025-08-25
* maint(linux): ignore generate patch directories (#14600)
## 19.0.104 alpha 2025-08-21
* fix(android): Update sentry-android dependency to 8.19.1 for 16 KB page alignment (#14559)
* maint(android): Cleanup builder_describe_outputs for configure action (#14566)
* fix(windows): emit nunit report path correctly and update TeamCity links (#14564)
* maint(common): rename and move node-related script functions into node.inc.sh (#14568)
## 19.0.103 alpha 2025-08-20
* fix(android): Show system OSK when physical keyboard connected on Android API 36 (#14538)
* fix(android): Add "Show On-screen keyboard" preference to display OSK when physical keyboard is connected (#14539)
* fix(android): Add FirstVoices preference to show on-screen keyboard (#14546)
* fix(linux): normalize language tags from keyboard (#14542)
* maint(common): fix running docker on Windows (#14154)
* maint(mac): use mac_ prefix for functions in mac.inc.sh (#14562)
* maint(android): publish symbols to Sentry on release buildLevel (#14490)
* maint(linux): add missing `--help.keyman.com` option (#14571)
* docs(web): improve documentation for SearchSpace and SearchNode (#14555)
## 19.0.102 alpha 2025-08-19
* maint(mac): skip unnecessary network steps when buildLevel is build (#14467)
* maint(common): cleanup and reorganize ci scripts (#14459)
* refactor(linux): cleanup some code in bash completion script (#14543)
* maint(resources): handle build-bot skip correctly (#14551)
* maint(resources): don't fall back to 'build' action (#14552)
* maint(resources): handle unset build platform in trigger-build-bot (#14554)
## 19.0.101 alpha 2025-08-18
* maint(android): Update Android Target API to 35 (#14395)
* fix(android): Convert Keyman app layout to use ConstraintLayout for handling edge-to-edge (#14396)
* fix(android): Update other activities for edge to edge (#14463)
* fix(android): Update Sample, Test, and FirstVoices apps for edge to edge (#14514)
* maint(common): rename and move node-related script functions into node.inc.sh (#14540)
## 19.0.100 alpha 2025-08-14
* maint(resources): add space to test-bot command (#14528)
* fix(web): improve accuracy of types for suggestions & suggestion-generation (#14517)
* refactor(web): move applySuggestionCasing to standalone exportable method (#14518)
* chore(web): convert worker-thread tests to TS (#14510)
## 19.0.99 alpha 2025-08-14
* maint(web): skip unnecessary steps for `build` buildLevel (#14516)
## 19.0.98 alpha 2025-08-14
* maint(resources): specify `keymanapp/keyman` for gh in automerge (#14524)
## 19.0.97 alpha 2025-08-14
* maint(resources): use GH_TOKEN variable for gh calls (#14522)
## 19.0.96 alpha 2025-08-14
* maint(resources): add build-bot commands to increment-version auto PRs (#14504)
* maint(resources): use GH builtin automerge for auto PRs (#14519)
## 19.0.95 alpha 2025-08-13
* fix(web): use actual legacy model for legacy-model support unit tests (#14460)
* chore(common): Update Crowdin strings for Spanish (#14464)
* fix(android): Get default sizes before initializing keyboard (#14472)
* docs(resources): clarify Build-bot usage (#14282)
* maint(resources): build.sh-style commands for build-bot (#14461)
* chore(android): Update keycode test app dependencies (#14474)
* maint(common): update npm modules brace-expansion to 1.1.12, form-data to 4.0.4 (#14479)
* chore(android): Specify Java language version 21 (#14491)
* maint(ios): skip unnecessary network steps when buildLevel is build (#14466)
* maint(common): rename shellHelperFunctions.sh to utils.inc.sh (#14446)
* maint(common): consolidate builder scripts (#14449)
* maint(common): rename and move node-related script functions into node.inc.sh (#14451)
* maint(common): move typescript script functions into typescript.inc.sh (#14452)
* maint(common): reorganize mac/ios build script includes (#14458)
* docs(resources): add note on builder-basic vs builder-full (#14507)
## 19.0.94 alpha 2025-08-01
* maint(common): use `cpp_std=c++17` in meson project default_options (#14433)
@ -574,6 +663,26 @@
* refactor(windows): rename `TKeymanMutex.MutexOwned` to `TakeOwnership` and add `ReleaseOwnership` (#13168)
* chore: increment to alpha 19.0 (#13187)
## 18.0.240 stable 2025-08-27
* maint(resources): automatically cherry-pick history updates to master (#14596)
* maint(linux): fix lintian warnings (#14591)
* maint(linux): ignore generate patch directories (#14601)
## 18.0.239 stable 2025-08-22
* docs(linux): clarify requirement of patched ibus for Keyman < 18 (#14113)
* chore(linux): Update debian changelog (#14118)
* fix(windows): add values wucUpdateAvailable and wucNotChecked to TRemoteUpdateCheckResult enum (#14208)
* fix(web): deploy `web/build/publish` folder (#14238)
* fix(ios): restore keyboard scale map for iPad Air 2 (#14306)
* chore(developer): upgrade multer to 2.0.2 (#14417)
* fix(android): cherry-pick getting default sizes before initializing keyboard (#14473)
* fix(android): polyfill globalThis for API 28 devices (#14553)
* fix(android): Update sentry-android dependency to 7.22.6 for 16 KB page alignment (#14560)
* fix(android): Show system OSK when physical keyboard connected (#14547)
* fix(android): Add preference to show on-screen keyboard to Keyman and FirstVoices apps (#14561)
## 18.0.238 stable 2025-06-04
* fix(developer): ldml: make sure .run() calls compile() for validation (#14071)

View file

@ -1 +1 @@
19.0.95
19.0.107

View file

@ -3,19 +3,12 @@ buildscript {
repositories {
google()
mavenCentral()
flatDir {
dirs "kMAPro/libs/com/stepstone/stepper/material-stepper/4.3.1/"
}
}
dependencies {
classpath 'com.android.tools.build:gradle:8.9.2'
// sentry-android-gradle-plugin 2.1.5+ requires AGP 7.0
classpath 'io.sentry:sentry-android-gradle-plugin:4.6.0'
classpath 'io.sentry:sentry-android-gradle-plugin:5.9.0'
classpath 'name.remal:gradle-plugins:1.9.2'
// From jcenter() which was deprecated August 2024
// https://jfrog.com/blog/into-the-sunset-bintray-jcenter-gocenter-and-chartcenter/
classpath 'com.stepstone.stepper:material-stepper:4.3.1@aar'
}
}

View file

@ -3,11 +3,10 @@
## START STANDARD BUILD SCRIPT INCLUDE
# adjust relative paths as necessary
THIS_SCRIPT="$(readlink -f "${BASH_SOURCE[0]}")"
. "${THIS_SCRIPT%/*}/../../resources/build/builder.inc.sh"
. "${THIS_SCRIPT%/*}/../../resources/build/builder-full.inc.sh"
## END STANDARD BUILD SCRIPT INCLUDE
. "$KEYMAN_ROOT/resources/shellHelperFunctions.sh"
. "$KEYMAN_ROOT/resources/build/build-utils-ci.inc.sh"
. "$KEYMAN_ROOT/resources/build/utils.inc.sh"
. "$KEYMAN_ROOT/resources/build/build-help.inc.sh"
. "$KEYMAN_ROOT/resources/build/build-download-resources.sh"
@ -28,8 +27,8 @@ builder_describe "Builds Keyman for Android app." \
"configure" \
"build" \
"test Runs lint and unit tests." \
"publish Publishes symbols to Sentry and the APK to the Play Store." \
"--upload-sentry Upload to sentry"
"publish-symbols Publishes symbols to Sentry." \
"publish-play-store Publishes the APK to the Play Store."
# parse before describe_outputs to check debug flags
builder_parse "$@"
@ -41,8 +40,12 @@ if builder_is_debug_build; then
TEST_FLAGS="-x assembleDebug lintDebug testDebug"
fi
KEYBOARD_PACKAGE_ID="sil_euro_latin"
KEYBOARDS_TARGET="android/KMAPro/kMAPro/src/main/assets/${KEYBOARD_PACKAGE_ID}.kmp"
MODEL_PACKAGE_ID="nrc.en.mtnt"
MODELS_TARGET="android/KMAPro/kMAPro/src/main/assets/${MODEL_PACKAGE_ID}.model.kmp"
builder_describe_outputs \
configure /android/KMAPro/kMAPro/libs/keyman-engine.aar \
configure "/${MODELS_TARGET}" \
build /android/KMAPro/kMAPro/build/outputs/apk/$CONFIG/keyman-${KEYMAN_VERSION}.apk
#### Build
@ -54,18 +57,6 @@ if builder_is_ci_build; then
DAEMON_FLAG=--no-daemon
fi
#### Build action definitions ####
function makeLocalSentryRelease() {
echo "Making a Sentry release for tag $KEYMAN_VERSION_GIT_TAG"
sentry-cli upload-dif -p keyman-android --include-sources
sentry-cli releases -p keyman-android files $KEYMAN_VERSION_GIT_TAG upload-sourcemaps ./
echo "Finalizing release tag $KEYMAN_VERSION_GIT_TAG"
sentry-cli releases finalize "$KEYMAN_VERSION_GIT_TAG"
}
#### Build action definitions ####
# Check about cleaning artifact paths
@ -76,13 +67,8 @@ fi
if builder_start_action configure; then
KEYBOARD_PACKAGE_ID="sil_euro_latin"
KEYBOARDS_TARGET="$KEYMAN_ROOT/android/KMAPro/kMAPro/src/main/assets/${KEYBOARD_PACKAGE_ID}.kmp"
MODEL_PACKAGE_ID="nrc.en.mtnt"
MODELS_TARGET="$KEYMAN_ROOT/android/KMAPro/kMAPro/src/main/assets/${MODEL_PACKAGE_ID}.model.kmp"
downloadKeyboardPackage "$KEYBOARD_PACKAGE_ID" "$KEYBOARDS_TARGET"
downloadModelPackage "$MODEL_PACKAGE_ID" "$MODELS_TARGET"
downloadKeyboardPackage "$KEYBOARD_PACKAGE_ID" "${KEYMAN_ROOT}/$KEYBOARDS_TARGET"
downloadModelPackage "$MODEL_PACKAGE_ID" "${KEYMAN_ROOT}/$MODELS_TARGET"
builder_finish_action success configure
fi
@ -90,18 +76,14 @@ fi
if builder_start_action build; then
# Copy Keyman Engine for Android
cp "$KEYMAN_ROOT/android/KMEA/app/build/outputs/aar/keyman-engine-${CONFIG}.aar" "$KEYMAN_ROOT/android/KMAPro/kMAPro/libs/keyman-engine.aar"
cp "${KEYMAN_ROOT}/android/KMEA/app/build/outputs/aar/keyman-engine-${CONFIG}.aar" "${KEYMAN_ROOT}/android/KMAPro/kMAPro/libs/keyman-engine.aar"
# Convert markdown to html for offline help
build_help_html android KMAPro/kMAPro/src/main/assets/info
echo "BUILD_FLAGS $BUILD_FLAGS"
./gradlew $DAEMON_FLAG clean $BUILD_FLAGS
if builder_has_option --upload-sentry; then
makeLocalSentryRelease
fi
builder_finish_action success build
fi
@ -113,12 +95,23 @@ if builder_start_action test; then
builder_finish_action success test
fi
if builder_start_action publish; then
# Copy Release Notes
generateReleaseNotes
publish_symbols() {
if builder_is_ci_build && builder_is_ci_build_level_release; then
# TODO: what does publishSentry even do?
./gradlew $DAEMON_FLAG publishSentry
builder_echo "Making a Sentry release for tag $KEYMAN_VERSION_GIT_TAG"
sentry-cli upload-dif -p keyman-android --include-sources
sentry-cli releases -p keyman-android files $KEYMAN_VERSION_GIT_TAG upload-sourcemaps ./
fi
}
# Publish symbols and Keyman for Android to Play Store
./gradlew $DAEMON_FLAG publishSentry publishReleaseApk
publish_play_store() {
if builder_is_ci_build && builder_is_ci_build_level_release; then
generateReleaseNotes
# Publish Keyman for Android to Play Store
./gradlew $DAEMON_FLAG publishReleaseApk
fi
}
builder_finish_action success publish
fi
builder_run_action publish-symbols publish_symbols
builder_run_action publish-play-store publish_play_store

View file

@ -11,8 +11,14 @@ apply from: "$rootPath/version.gradle"
String tier = new File('../../TIER.md').getText('UTF-8').trim();
java {
toolchain {
languageVersion = JavaLanguageVersion.of(21)
}
}
android {
compileSdk 34
compileSdk 35
namespace="com.tavultesoft.kmapro"
// Don't compress kmp files so they can be copied via AssetManager
@ -24,15 +30,10 @@ android {
buildConfig = true
}
compileOptions {
sourceCompatibility = JavaVersion.VERSION_21
targetCompatibility = JavaVersion.VERSION_21
}
defaultConfig {
applicationId "com.tavultesoft.kmapro"
minSdkVersion 21
targetSdkVersion 34
targetSdkVersion 35
//println "===DUMPING PROPERTIES==="
//dumpProperties(project) // Use this to dump all external properties for debugging TeamCity integration
@ -113,6 +114,12 @@ android {
disable 'MissingQuantity', 'MissingTranslation'
lintConfig file("lint.xml")
}
sourceSets {
main {
jniLibs.srcDirs = ['libs']
}
}
}
// how to configure the sentry android gradle plugin
@ -157,19 +164,17 @@ if (env_keys_json_file != null && file(env_keys_json_file).exists()) {
}
repositories {
flatDir {
dirs 'libs'
}
google()
}
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
implementation 'androidx.appcompat:appcompat:1.7.0'
implementation 'androidx.constraintlayout:constraintlayout:2.2.1'
implementation 'com.google.android.material:material:1.12.0'
implementation 'com.stepstone.stepper:material-stepper:4.3.1'
api(name: 'keyman-engine', ext: 'aar')
implementation 'io.sentry:sentry-android:7.8.0'
implementation files('libs/keyman-engine.aar')
implementation 'io.sentry:sentry-android:8.19.1'
implementation 'androidx.preference:preference:1.2.1'
implementation "com.android.installreferrer:installreferrer:2.2"

View file

@ -5,10 +5,10 @@
package com.keyman.android;
import com.keyman.engine.util.DownloadFileUtils;
import com.tavultesoft.kmapro.AdjustLongpressDelayActivity;
import com.tavultesoft.kmapro.BuildConfig;
import com.tavultesoft.kmapro.DefaultLanguageResource;
import com.tavultesoft.kmapro.KeymanSettingsActivity;
import com.tavultesoft.kmapro.PreferencesManager;
import com.keyman.engine.KMManager;
import com.keyman.engine.KMManager.KeyboardType;
import com.keyman.engine.KMHardwareKeyboardInterpreter;
@ -30,7 +30,6 @@ import android.view.KeyEvent;
import android.view.View;
import android.view.ViewGroup;
import android.view.Window;
import android.view.WindowManager;
import android.view.inputmethod.EditorInfo;
import android.view.inputmethod.ExtractedText;
import android.view.inputmethod.ExtractedTextRequest;
@ -278,6 +277,21 @@ public class SystemKeyboard extends InputMethodService implements OnKeyboardEven
// Do nothing
}
@Override
public boolean onEvaluateInputViewShown() {
// On Android API 36+, the OSK defaults to not appearing when a physical keyboard is connected.
// If the default implementation returns true, recommend honoring it
// Reference: https://android.googlesource.com/platform/frameworks/base/+/7b739a8%5E%21/
if (super.onEvaluateInputViewShown()) {
return true;
};
Context context = getApplicationContext();
SharedPreferences prefs = context.getSharedPreferences(PreferencesManager.kma_prefs_name, Context.MODE_PRIVATE);
boolean showOSK = prefs.getBoolean(KeymanSettingsActivity.oskWithPhysicalKeyboardKey, false);
return showOSK;
}
@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
// Determine if Physical keystroke should be passed off

View file

@ -44,6 +44,9 @@ public class AdjustKeyboardHeightActivity extends BaseActivity {
setContentView(R.layout.activity_adjust_keyboard_height);
setupEdgeToEdge(R.id.adjust_keyboard_layout);
setupStatusBarColors(R.color.keyman_blue, android.R.color.white);
Toolbar toolbar = (Toolbar) findViewById(R.id.titlebar);
setSupportActionBar(toolbar);
ActionBar actionBar = getSupportActionBar();

View file

@ -34,6 +34,7 @@ public class InfoActivity extends BaseActivity {
final Context context = this;
setContentView(R.layout.activity_info);
setupEdgeToEdge(R.id.info_layout);
// Navigation buttons
final ImageButton backButton = (ImageButton) findViewById(R.id.back_button);

View file

@ -79,6 +79,9 @@ public class KMPBrowserActivity extends BaseActivity {
return;
}
setupEdgeToEdge(R.id.kmp_browser_layout);
setupStatusBarColors(R.color.complementary_5, android.R.color.white);
webView = (WebView) findViewById(R.id.kmpBrowserWebView);
webView.getSettings().setLayoutAlgorithm(WebSettings.LayoutAlgorithm.NORMAL);
webView.getSettings().setJavaScriptEnabled(true);

View file

@ -5,7 +5,6 @@ import android.os.Bundle;
import com.keyman.engine.BaseActivity;
import com.keyman.engine.KMManager;
import androidx.appcompat.app.AppCompatActivity;
import androidx.appcompat.widget.Toolbar;
public class KeymanSettingsActivity extends BaseActivity {
@ -14,6 +13,7 @@ public class KeymanSettingsActivity extends BaseActivity {
protected static final String sendCrashReport = "SendCrashReport";
public static final String spacebarTextKey = "SpacebarText";
public static final String hapticFeedbackKey = "HapticFeedback";
public static final String oskWithPhysicalKeyboardKey = "ShowOSK";
protected KeymanSettingsFragment innerFragment;
@ -22,6 +22,10 @@ public class KeymanSettingsActivity extends BaseActivity {
super.onCreate(savedInstanceState);
setContentView(R.layout.keyman_settings_layout);
setupEdgeToEdge(R.id.keyman_settings_layout);
setupStatusBarColors(R.color.keyman_blue, android.R.color.white);
Toolbar toolbar = (Toolbar) findViewById(R.id.keyman_settings_toolbar);
toolbar.setTitleTextColor(getResources().getColor(android.R.color.white));
toolbar.setTitle(R.string.keyman_settings);

View file

@ -6,6 +6,7 @@ package com.tavultesoft.kmapro;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.os.Bundle;
import android.provider.Settings;
import android.view.inputmethod.InputMethodManager;
@ -20,6 +21,7 @@ import androidx.preference.SwitchPreference;
import com.keyman.engine.DisplayLanguages;
import com.keyman.engine.KMManager;
import com.keyman.engine.data.Dataset;
import com.tavultesoft.kmapro.PreferencesManager;
import java.util.HashMap;
@ -157,6 +159,31 @@ public class KeymanSettingsFragment extends PreferenceFragmentCompat {
}
});
SwitchPreference oskWithPhysicalKeyboardPreference = new SwitchPreference(context);
oskWithPhysicalKeyboardPreference.setKey(KeymanSettingsActivity.oskWithPhysicalKeyboardKey);
oskWithPhysicalKeyboardPreference.setTitle(getString(R.string.show_osk));
oskWithPhysicalKeyboardPreference.setSummary(getString(R.string.show_osk_hint));
SharedPreferences prefs = context.getSharedPreferences(
PreferencesManager.kma_prefs_name, Context.MODE_PRIVATE);
SharedPreferences.Editor editor = prefs.edit();
boolean showOSK = prefs.getBoolean(
KeymanSettingsActivity.oskWithPhysicalKeyboardKey, false);
oskWithPhysicalKeyboardPreference.setDefaultValue(showOSK);
oskWithPhysicalKeyboardPreference.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() {
@Override
public boolean onPreferenceChange(Preference preference, Object newValue) {
if (newValue == null) {
return false;
}
editor.putBoolean(KeymanSettingsActivity.oskWithPhysicalKeyboardKey, (boolean)newValue);
editor.commit();
return true;
}
});
SwitchPreference hapticFeedbackPreference = new SwitchPreference(context);
hapticFeedbackPreference.setKey(KeymanSettingsActivity.hapticFeedbackKey);
hapticFeedbackPreference.setTitle(getString(R.string.haptic_feedback));
@ -198,6 +225,8 @@ public class KeymanSettingsFragment extends PreferenceFragmentCompat {
screen.addPreference(adjustKeyboardHeight);
screen.addPreference(adjustLongpressDelay);
screen.addPreference(oskWithPhysicalKeyboardPreference);
screen.addPreference(spacebarTextPreference);
screen.addPreference(hapticFeedbackPreference);

View file

@ -7,7 +7,6 @@ import java.util.ArrayList;
import java.util.HashMap;
import androidx.appcompat.app.AlertDialog;
import androidx.appcompat.app.AppCompatActivity;
import androidx.appcompat.widget.Toolbar;
import android.content.Context;
@ -24,11 +23,12 @@ import android.os.Bundle;
import android.widget.SimpleAdapter;
import android.widget.TextView;
import com.keyman.engine.BaseActivity;
import com.keyman.engine.KMManager;
import com.keyman.engine.data.KeyboardController;
import com.keyman.engine.util.MapCompat;
public class KeymanSettingsInstallActivity extends AppCompatActivity {
public class KeymanSettingsInstallActivity extends BaseActivity {
private static final String TAG = "SettingsInstallActivity";
private static ArrayList<HashMap<String, String>> installOptionList = null;
private static Typeface titleFont = null;
@ -45,6 +45,8 @@ public class KeymanSettingsInstallActivity extends AppCompatActivity {
context = this;
setContentView(R.layout.activity_list_layout);
setupEdgeToEdge(R.id.list_toolbar);
final Toolbar toolbar = findViewById(R.id.list_toolbar);
setSupportActionBar(toolbar);
getSupportActionBar().setDisplayHomeAsUpEnabled(true);

View file

@ -25,10 +25,10 @@ import android.widget.TextView;
import androidx.annotation.IdRes;
import androidx.annotation.NonNull;
import androidx.appcompat.app.AlertDialog;
import androidx.appcompat.app.AppCompatActivity;
import androidx.appcompat.widget.SwitchCompat;
import androidx.appcompat.widget.Toolbar;
import com.keyman.engine.BaseActivity;
import com.keyman.engine.KeyboardPickerActivity;
import com.keyman.engine.KMManager;
import com.keyman.engine.ModelPickerActivity;
@ -43,7 +43,7 @@ import java.util.HashMap;
* Keyman Settings --> Languages Settings --> Language Settings
* Displays a list of installed keyboards and some lexical model switches.
*/
public final class LanguageSettingsActivity extends AppCompatActivity {
public final class LanguageSettingsActivity extends BaseActivity {
private Context context;
private static Toolbar toolbar = null;
private static ListView listView = null;
@ -66,6 +66,8 @@ public final class LanguageSettingsActivity extends AppCompatActivity {
context = this;
setContentView(R.layout.language_settings_list_layout);
setupEdgeToEdge(R.id.list_toolbar);
toolbar = (Toolbar) findViewById(R.id.list_toolbar);
setSupportActionBar(toolbar);
getSupportActionBar().setDisplayHomeAsUpEnabled(true);

View file

@ -19,9 +19,9 @@ import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.appcompat.app.AlertDialog;
import androidx.appcompat.app.AppCompatActivity;
import androidx.appcompat.widget.Toolbar;
import com.keyman.engine.BaseActivity;
import com.keyman.engine.data.Dataset;
import com.keyman.engine.data.adapters.AdapterFilter;
import com.keyman.engine.data.adapters.NestedAdapter;
@ -36,7 +36,7 @@ import java.util.List;
* Keyman Settings --> Languages Settings
* Displays a list of installed languages and a count of their associated installed keyboards.
*/
public final class LanguagesSettingsActivity extends AppCompatActivity {
public final class LanguagesSettingsActivity extends BaseActivity {
private Context context;
private static Toolbar toolbar = null;
@ -53,6 +53,8 @@ public final class LanguagesSettingsActivity extends AppCompatActivity {
context = this;
setContentView(R.layout.languages_settings_list_layout);
setupEdgeToEdge(R.id.languages_list_layout);
toolbar = (Toolbar) findViewById(R.id.list_toolbar);
setSupportActionBar(toolbar);
getSupportActionBar().setDisplayHomeAsUpEnabled(true);

View file

@ -67,6 +67,7 @@ import androidx.activity.result.ActivityResultLauncher;
import androidx.activity.result.contract.ActivityResultContracts;
import androidx.appcompat.widget.Toolbar;
import androidx.appcompat.app.AlertDialog;
import androidx.constraintlayout.widget.ConstraintLayout;
import android.content.ClipData;
import android.content.Context;
import android.content.DialogInterface;
@ -85,7 +86,6 @@ import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import androidx.annotation.NonNull;
import androidx.core.app.ActivityCompat;
import androidx.core.content.ContextCompat;
import android.provider.Settings;
import android.text.Html;
@ -98,8 +98,6 @@ import android.view.MenuItem;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.view.WindowManager;
import android.webkit.WebView;
import android.widget.Button;
import android.widget.LinearLayout;
import android.widget.SeekBar;
@ -118,6 +116,7 @@ public class MainActivity extends BaseActivity implements OnKeyboardEventListene
private static final String TAG = "MainActivity";
private ConstraintLayout constraintLayout;
private KMTextView textView;
private final int minTextSize = 16;
private final int maxTextSize = 72;
@ -170,6 +169,10 @@ public class MainActivity extends BaseActivity implements OnKeyboardEventListene
setContentView(R.layout.activity_main);
constraintLayout = (ConstraintLayout)findViewById(R.id.constraintLayout);
setupEdgeToEdge(R.id.constraintLayout);
setupStatusBarColors(android.R.color.white, R.color.neutral_2);
toolbar = (Toolbar) findViewById(R.id.titlebar);
setSupportActionBar(toolbar);
getSupportActionBar().setTitle(null);
@ -622,10 +625,18 @@ public class MainActivity extends BaseActivity implements OnKeyboardEventListene
if (resourceId > 0)
statusBarHeight = getResources().getDimensionPixelSize(resourceId);
// Navigation bar height
int navigationBarHeight = 0;
resourceId = getResources().getIdentifier("navigation_bar_height", "dimen", "android");
if (resourceId > 0) {
navigationBarHeight = getResources().getDimensionPixelSize(resourceId);
}
Point size = KMManager.getWindowSize(context);
int screenHeight = size.y;
Log.d(TAG, "Main resizeTextView bannerHeight: " + bannerHeight);
textView.setHeight(screenHeight - statusBarHeight - actionBarHeight - bannerHeight - keyboardHeight);
textView.setHeight(
screenHeight - statusBarHeight - actionBarHeight - bannerHeight - keyboardHeight - navigationBarHeight);
}
private void showInfo() {

View file

@ -4,7 +4,6 @@
package com.tavultesoft.kmapro;
import android.annotation.SuppressLint;
import androidx.appcompat.app.AppCompatActivity;
import androidx.appcompat.app.AlertDialog;
import androidx.fragment.app.Fragment;
@ -18,6 +17,7 @@ import android.widget.Toast;
import com.stepstone.stepper.StepperLayout;
import com.stepstone.stepper.VerificationError;
import com.keyman.engine.BaseActivity;
import com.keyman.engine.KMManager;
import com.keyman.engine.KeyboardEventHandler;
import com.keyman.engine.KmpInstallMode;
@ -34,7 +34,7 @@ import java.util.ArrayList;
import java.util.List;
import java.util.Map;
public class PackageActivity extends AppCompatActivity implements
public class PackageActivity extends BaseActivity implements
StepperLayout.StepperListener, WebViewFragment.OnInstallClickedListener,
SelectLanguageFragment.OnLanguagesSelectedListener {
private final static String TAG = "PackageActivity";
@ -52,6 +52,7 @@ public class PackageActivity extends AppCompatActivity implements
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_package_installer);
setupEdgeToEdge(R.id.package_installer_layout);
KmpInstallMode installMode = KmpInstallMode.Full;
String languageID = null;

View file

@ -0,0 +1,11 @@
/**
* Keyman is copyright (C) SIL Global. MIT License.
*
*/
package com.tavultesoft.kmapro;
public class PreferencesManager {
// TODO: Separate this from the Keyman Engine preference key name in strings.xml: #13633
public static final String kma_prefs_name = "KMAPreferences";
}

View file

@ -8,11 +8,11 @@ import android.os.Bundle;
import android.view.View;
import android.widget.Toast;
import androidx.appcompat.app.AppCompatActivity;
import androidx.fragment.app.Fragment;
import com.stepstone.stepper.StepperLayout;
import com.stepstone.stepper.VerificationError;
import com.keyman.engine.BaseActivity;
import com.keyman.engine.KMManager;
import com.keyman.engine.data.Keyboard;
import com.keyman.engine.packages.PackageProcessor;
@ -29,7 +29,7 @@ import java.util.List;
* Also available during keyboard package installation that involves a language choice.
* Displays a list of available language names for the user to add for a given installed packageID/keyboardID.
*/
public class SelectLanguageActivity extends AppCompatActivity implements
public class SelectLanguageActivity extends BaseActivity implements
StepperLayout.StepperListener, SelectLanguageFragment.OnLanguagesSelectedListener {
private final static String TAG = "SelectLanguageActivity";
private File packagePath;
@ -43,6 +43,7 @@ public class SelectLanguageActivity extends AppCompatActivity implements
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_select_language);
setupEdgeToEdge(R.id.select_language_layout);
Bundle bundle = getIntent().getExtras();
keyboard = (Keyboard)bundle.getSerializable("keyboard");

View file

@ -16,9 +16,9 @@ import android.widget.ListView;
import android.widget.SimpleAdapter;
import android.widget.TextView;
import androidx.appcompat.app.AppCompatActivity;
import androidx.appcompat.widget.Toolbar;
import com.keyman.engine.BaseActivity;
import com.keyman.engine.KMManager;
import com.keyman.engine.data.Keyboard;
import com.keyman.engine.data.KeyboardController;
@ -33,7 +33,7 @@ import java.util.List;
* Keyman Settings --> KeymanInstallActivity --> SelectPackageActivity
* Displays a list of installed package ID / keyboard IDs so the user can select a language from the kmp.json
*/
public final class SelectPackageActivity extends AppCompatActivity {
public final class SelectPackageActivity extends BaseActivity {
private static final String TAG = "SelectPackageActivity";
private static ArrayList<HashMap<String, String>> list = null;
private static Typeface titleFont = null;
@ -49,6 +49,8 @@ public final class SelectPackageActivity extends AppCompatActivity {
context = this;
setContentView(R.layout.activity_list_layout);
setupEdgeToEdge(R.id.activity_list_layout);
final Toolbar toolbar = findViewById(R.id.list_toolbar);
setSupportActionBar(toolbar);
getSupportActionBar().setDisplayHomeAsUpEnabled(true);

View file

@ -1,9 +1,11 @@
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:orientation="vertical"
android:id="@+id/adjust_keyboard_layout"
android:fitsSystemWindows="true"
android:layout_width="match_parent"
android:layout_height="match_parent">
android:layout_height="match_parent"
android:orientation="vertical">
<include layout="@layout/titlebar" />
@ -15,7 +17,7 @@
android:layout_marginStart="@dimen/activity_horizontal_margin"
android:text="@string/drag_the_keyboard"
android:textSize="@dimen/adjust_keyboard_height_label_textsize"
/>
app:layout_constraintTop_toBottomOf="@id/titlebar" />
<TextView
android:id="@+id/rotate_the_device"
@ -25,23 +27,35 @@
android:layout_marginStart="@dimen/activity_horizontal_margin"
android:text="@string/rotate_the_device"
android:textSize="@dimen/adjust_keyboard_height_label_textsize"
/>
app:layout_constraintTop_toBottomOf="@id/drag_the_keyboard" />
<Button
android:id="@+id/reset_to_defaults"
style="@style/Widget.AppCompat.Button.Colored"
android:background="@color/keyman_blue"
android:textColor="@color/ms_white"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@id/rotate_the_device"
android:layout_centerInParent="true"
android:singleLine="true"
android:layout_marginTop="8dp"
android:paddingStart="8dp"
android:paddingEnd="8dp"
android:text="@string/reset_to_defaults"
android:textSize="@dimen/adjust_keyboard_height_label_textsize" />
<androidx.constraintlayout.widget.ConstraintLayout
android:id="@+id/button_layout"
android:orientation="horizontal"
android:layout_below="@id/rotate_the_device"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_constraintTop_toBottomOf="@id/rotate_the_device">
<Button
android:id="@+id/reset_to_defaults"
style="@style/Widget.AppCompat.Button.Colored"
android:background="@color/keyman_blue"
android:textColor="@color/ms_white"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:singleLine="true"
android:layout_marginTop="8dp"
android:paddingStart="8dp"
android:paddingEnd="8dp"
android:text="@string/reset_to_defaults"
android:textSize="@dimen/adjust_keyboard_height_label_textsize"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
<!-- Resizable keyboard "image -->
<ImageView
@ -56,6 +70,10 @@
android:paddingStart="@dimen/blank_osk_padding"
android:paddingEnd="@dimen/blank_osk_padding"
android:paddingTop="@dimen/blank_osk_padding"
android:paddingBottom="@dimen/blank_osk_padding"/>
android:paddingBottom="@dimen/blank_osk_padding"
app:layout_constraintTop_toBottomOf="@id/button_layout"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintVertical_bias="1.0" />
</RelativeLayout>
</androidx.constraintlayout.widget.ConstraintLayout>

View file

@ -1,75 +1,92 @@
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/info_layout"
android:fitsSystemWindows="true"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:background="@color/ms_white"
tools:context=".InfoActivity" >
<androidx.appcompat.widget.Toolbar
android:id="@+id/titlebar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:layout_alignParentTop="true"
app:popupTheme="@style/ThemeOverlay.AppCompat.Light">
<androidx.appcompat.widget.Toolbar
android:id="@+id/titlebar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:popupTheme="@style/ThemeOverlay.AppCompat.Light">
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal">
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:orientation="horizontal"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toStartOf="@+id/close_button" >
<!-- Navigation buttons in a LinearLayout to mirror on RTL -->
<ImageButton
android:id="@+id/back_button"
style="?android:attr/actionButtonStyle"
app:tint="@color/image_button_color"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="start"
android:contentDescription="@string/label_back"
android:src="@drawable/ic_action_back" />
<!-- Navigation buttons in a LinearLayout to mirror on RTL -->
<ImageButton
android:id="@+id/back_button"
style="?android:attr/actionButtonStyle"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_gravity="start"
android:contentDescription="@string/label_back"
android:src="@drawable/ic_action_back"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:tint="@color/image_button_color" />
<ImageButton
android:id="@+id/forward_button"
style="?android:attr/actionButtonStyle"
app:tint="@color/image_button_color"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:contentDescription="@string/label_forward"
android:src="@drawable/ic_action_forward" />
</LinearLayout>
<ImageButton
android:id="@+id/forward_button"
style="?android:attr/actionButtonStyle"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:contentDescription="@string/label_forward"
android:src="@drawable/ic_action_forward"
app:layout_constraintStart_toEndOf="@id/back_button"
app:layout_constraintTop_toTopOf="parent"
app:tint="@color/image_button_color" />
<ImageButton
android:id="@+id/close_button"
style="?android:attr/actionButtonStyle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="end"
android:contentDescription="@string/label_close"
android:src="@drawable/ic_action_close" />
</androidx.constraintlayout.widget.ConstraintLayout>
</androidx.appcompat.widget.Toolbar>
<ImageButton
android:id="@+id/close_button"
style="?android:attr/actionButtonStyle"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_gravity="end"
android:contentDescription="@string/label_close"
android:src="@drawable/ic_action_close"
app:layout_constraintEnd_toEndOf="parent" />
<WebView
android:id="@+id/infoWebView"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_below="@id/titlebar"
android:layout_marginBottom="@dimen/info_label_height" />
</androidx.appcompat.widget.Toolbar>
<!-- layout_height 0dp to fill the remaining area -->
<WebView
android:id="@+id/infoWebView"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_below="@id/titlebar"
android:layout_marginStart="4dp"
app:layout_constraintTop_toBottomOf="@id/titlebar"
app:layout_constraintBottom_toTopOf="@+id/infoVersion"
app:layout_constraintStart_toStartOf="parent" />
<!-- Version string on the bottom of the page -->
<TextView
android:id="@+id/infoVersion"
android:layout_width="match_parent"
android:layout_height="@dimen/info_label_height"
android:layout_gravity="center_horizontal"
android:gravity="center"
android:ellipsize="end"
android:singleLine="true"
android:text="@string/title_version"
android:textSize="@dimen/info_label_textsize"
android:layout_alignParentBottom="true" />
android:id="@id/infoVersion"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="bottom"
android:gravity="center"
android:ellipsize="end"
android:singleLine="true"
android:text="@string/title_version"
android:textSize="@dimen/info_label_textsize"
android:layout_alignParentBottom="true"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintBottom_toBottomOf="parent" />
</RelativeLayout>
</androidx.constraintlayout.widget.ConstraintLayout>

View file

@ -1,6 +1,9 @@
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/kmp_browser_layout"
android:fitsSystemWindows="true"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".KMPBrowserActivity"
@ -9,6 +12,8 @@
<WebView
android:id="@+id/kmpBrowserWebView"
android:layout_width="match_parent"
android:layout_height="match_parent" />
android:layout_height="match_parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintStart_toStartOf="parent" />
</RelativeLayout>
</androidx.constraintlayout.widget.ConstraintLayout>

View file

@ -1,6 +1,8 @@
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/constraintLayout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true"
@ -9,27 +11,32 @@
android:background="@color/yellow_background"
tools:context=".MainActivity">
<include layout="@layout/titlebar" />
<include layout="@layout/titlebar"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintStart_toStartOf="parent" />
<include layout="@layout/check_chrome_webview_layout"
android:visibility="gone"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@id/titlebar"/>
<include
layout="@layout/check_chrome_webview_layout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@id/titlebar"
android:visibility="gone"
app:layout_constraintTop_toBottomOf="@id/titlebar" />
<com.keyman.engine.KMTextView
android:id="@+id/kmTextView"
android:background="@drawable/textview_bg"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@id/checkWebViewChromeLayout"
android:background="@drawable/textview_bg"
android:ems="10"
android:inputType="textMultiLine|textNoSuggestions"
android:hint="@string/textview_hint"
android:gravity="top"
android:scrollbars="vertical">
android:hint="@string/textview_hint"
android:inputType="textMultiLine|textNoSuggestions"
android:scrollbars="vertical"
app:layout_constraintTop_toBottomOf="@id/checkWebViewChromeLayout">
<requestFocus />
</com.keyman.engine.KMTextView>
</RelativeLayout>
</androidx.constraintlayout.widget.ConstraintLayout>

View file

@ -1,7 +1,8 @@
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/package_installer_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
@ -23,6 +24,17 @@
app:ms_nextButtonText="@string/label_next"
app:ms_completeButtonColor="@color/keyman_blue"
app:ms_completeButtonText="@string/label_ok"
app:ms_stepperType="dots" />
app:ms_stepperType="dots"
app:layout_constraintTop_toBottomOf="@+id/titlebar"
app:layout_constraintBottom_toTopOf="@+id/bottom_navigation"
app:layout_constraintStart_toStartOf="parent" />
</RelativeLayout>
<com.google.android.material.bottomnavigation.BottomNavigationView
android:id="@id/bottom_navigation"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@android:color/transparent"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>

View file

@ -1,7 +1,9 @@
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:fitsSystemWindows="true"
android:id="@+id/select_language_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
@ -15,7 +17,7 @@
android:id="@+id/stepperLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_below="@+id/titlebar"
app:ms_showBackButtonOnFirstStep="true"
app:ms_backButtonColor="@color/keyman_blue"
app:ms_backButtonText="@string/label_back"
@ -23,6 +25,18 @@
app:ms_nextButtonText="@string/label_next"
app:ms_completeButtonColor="@color/keyman_blue"
app:ms_completeButtonText="@string/label_ok"
app:ms_stepperType="dots" />
app:ms_stepperType="dots"
app:layout_constraintTop_toBottomOf="@id/titlebar"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintBottom_toTopOf="@+id/bottom_navigation" />
</RelativeLayout>
<com.google.android.material.bottomnavigation.BottomNavigationView
android:id="@+id/bottom_navigation"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@android:color/transparent"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintVertical_bias="1.0"/>
</androidx.constraintlayout.widget.ConstraintLayout>

View file

@ -1,23 +1,18 @@
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/keyman_settings_layout"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<com.google.android.material.appbar.AppBarLayout
<androidx.appcompat.widget.Toolbar
android:id="@+id/keyman_settings_toolbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:elevation="0dp">
<androidx.appcompat.widget.Toolbar
android:id="@+id/keyman_settings_toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="@color/keyman_blue">
</androidx.appcompat.widget.Toolbar>
</com.google.android.material.appbar.AppBarLayout>
android:layout_height="?attr/actionBarSize"
android:background="@color/keyman_blue"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintStart_toStartOf="parent" />
<fragment
android:layout_marginTop="?attr/actionBarSize"
@ -26,4 +21,4 @@
android:layout_width="match_parent"
android:layout_height="match_parent" />
</RelativeLayout>
</androidx.constraintlayout.widget.ConstraintLayout>

View file

@ -146,6 +146,12 @@
<!-- Context: Keyman Settings menu / Spacebar caption hint -->
<string name="spacebar_caption_hint_blank" comment="Spacebar caption hint - blank">Do not show caption on spacebar</string>
<!-- Context: Keyman Settings menu / Show OSK with Physical Keyboard -->
<string name="show_osk" comment="show OSK when physical keyboard is connected">Show On-Screen Keyboard</string>
<!-- Context: Keyman Settings menu / Show OSK with Physical Keyboard hint -->
<string name="show_osk_hint" comment="When physical keyboard is connected">When physical keyboard is connected</string>
<!-- Context: Keyman Settings menu / Haptic feedback -->
<string name="haptic_feedback" comment="haptic feedback on key press">Vibrate when typing</string>

View file

@ -12,8 +12,14 @@ base {
archivesName = "keyman-engine"
}
java {
toolchain {
languageVersion = JavaLanguageVersion.of(21)
}
}
android {
compileSdk 34
compileSdk 35
namespace "com.keyman.engine"
buildFeatures {
@ -21,14 +27,9 @@ android {
buildConfig = true
}
compileOptions {
sourceCompatibility = JavaVersion.VERSION_21
targetCompatibility = JavaVersion.VERSION_21
}
defaultConfig {
minSdkVersion 21
targetSdkVersion 34
targetSdkVersion 35
// KEYMAN_VERSION_CODE and KEYMAN_VERSION_NAME from version.gradle but Gradle removes them for libraries
buildConfigField "String", "KEYMAN_ENGINE_VERSION_NAME", "\""+KEYMAN_VERSION_NAME+"\""
@ -65,10 +66,11 @@ android {
dependencies {
// 1.6.0-rc01 needed to resolve https://issuetracker.google.com/issues/238425626
implementation 'androidx.appcompat:appcompat:1.7.0'
implementation 'androidx.constraintlayout:constraintlayout:2.2.1'
// material:1.7.0 will need Gradle plugin 7.1.0+
implementation 'com.google.android.material:material:1.12.0'
implementation 'commons-io:commons-io:2.16.1'
implementation 'io.sentry:sentry-android:7.8.0'
implementation 'io.sentry:sentry-android:8.19.1'
implementation 'androidx.preference:preference:1.2.1'
// Robolectric

View file

@ -9,10 +9,19 @@ import android.content.ContextWrapper;
import android.content.SharedPreferences;
import android.os.Build;
import android.os.LocaleList;
import android.view.View;
import android.view.ViewGroup;
import android.view.Window;
import android.view.WindowManager;
import android.widget.Toast;
import androidx.activity.EdgeToEdge;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.graphics.Insets;
import androidx.core.view.ViewCompat;
import androidx.core.view.WindowInsetsCompat;
import androidx.core.view.WindowCompat;
import androidx.core.view.WindowInsetsControllerCompat;
import androidx.preference.PreferenceManager;
import com.keyman.engine.util.ContextUtils;
@ -22,6 +31,7 @@ import java.util.Locale;
public class BaseActivity extends AppCompatActivity {
private static final String TAG = "BaseActivity";
static ContextWrapper localeUpdatedContext;
/**
@ -68,6 +78,58 @@ public class BaseActivity extends AppCompatActivity {
return "";
}
/**
* Setup the activity for edge-to-edge
* https://developer.android.com/develop/ui/views/layout/edge-to-edge-manually
* https://stackoverflow.com/questions/57293449/go-edge-to-edge-on-android-correctly-with-windowinsets
* @param layoutID - Top level ID of the view
*/
public void setupEdgeToEdge(int layoutID) {
EdgeToEdge.enable(this);
View anchor = findViewById(layoutID);
ViewCompat.setOnApplyWindowInsetsListener(anchor,
(view, windowInsets) -> {
// Allocate insets for system bars and display cutout (notch)
Insets insets = windowInsets.getInsets(
WindowInsetsCompat.Type.systemBars() | WindowInsetsCompat.Type.displayCutout());
ViewGroup.MarginLayoutParams mlp = (ViewGroup.MarginLayoutParams)view.getLayoutParams();
mlp.topMargin = insets.top;
mlp.bottomMargin = insets.bottom;
mlp.leftMargin = insets.left;
mlp.rightMargin = insets.right;
view.setLayoutParams(mlp);
KMManager.applyInsetsToKeyboard(insets.left, insets.right, insets.bottom);
return windowInsets;
});
// Trigger an initial pass
ViewCompat.requestApplyInsets(anchor);
}
/**
* If Android API < 35, apply colors to the status bar and navigation bar
* @param statusBarcolor - int value of the color to use on the status bar.
* @param navigationBarColor - int value of the color to use on the navigation bar.
*/
public void setupStatusBarColors(int statusBarColor, int navigationBarColor) {
// Set status bar colors
// https://stackoverflow.com/a/79706054
Window window = getWindow();
window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);
window.clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
WindowInsetsControllerCompat windowInsetsController =
WindowCompat.getInsetsController(window, window.getDecorView());
windowInsetsController.setAppearanceLightStatusBars(true);
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.VANILLA_ICE_CREAM &&
Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
window.setStatusBarColor(getColor(statusBarColor));
window.setNavigationBarColor(getColor(navigationBarColor));
}
}
@Override
protected void attachBaseContext(Context newBase) {
// Override the app locale using the BCP 47 tag from shared preferences

View file

@ -64,6 +64,8 @@ public class KMHelpFileActivity extends BaseActivity {
}
setContentView(R.layout.activity_help_file_layout);
setupEdgeToEdge(R.id.help_file_layout);
setupStatusBarColors(android.R.color.white, android.R.color.white);
Bundle bundle = getIntent().getExtras();
pkgID = "";

View file

@ -691,15 +691,68 @@ public final class KMManager {
/**
* Adjust the keyboard dimensions. If the suggestion banner is active, use the
* combined banner height and keyboard height
*
* Android API 35+ enforces edge-to-edge so we need to determine the navigation bar height (if visible)
* so the keyboard isn't covered up by the navigation bar.
* In portrait orientation, this affects the keyboard bottom margin.
* On phones in landscape orientation, this affects the left/right side of the keyboard
* @return RelativeLayout.LayoutParams
*/
public static RelativeLayout.LayoutParams getKeyboardLayoutParams() {
int bannerHeight = getBannerHeight(appContext);
int kbHeight = getKeyboardHeight(appContext);
int navigationHeight = getNavigationBarHeight(appContext);
int orientation = getOrientation(appContext);
FormFactor formFactor = getFormFactor();
RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(
RelativeLayout.LayoutParams.MATCH_PARENT, bannerHeight + kbHeight);
params.addRule(RelativeLayout.ALIGN_PARENT_BOTTOM, RelativeLayout.TRUE);
return params;
return params;
}
/**
* Applies padding to the keyboard so it's not covered by system insets
* @param left int padding to account for notch/navigation bar on left side of screen
* @param right int padding to account for notch/navigation bar on right side of screen
* @param bottom int padding to account for navigation bar on bottom of screen
*/
public static void applyInsetsToKeyboard(int left, int right, int bottom) {
// System keyboard
if (SystemKeyboard != null) {
applyInsetsPaddingToKeyboardView(SystemKeyboard, left, right, bottom);
}
// In-App Keyboard
if (InAppKeyboard != null) {
applyInsetsPaddingToKeyboardView(InAppKeyboard, left, right, bottom);
}
}
private static void applyInsetsPaddingToKeyboardView(KMKeyboard keyboard, int left, int right, int bottom) {
View parent = (View) keyboard.getParent();
if (parent != null) {
// Keep existing top padding, add bottom padding for the inset
parent.setPadding(
left,
parent.getPaddingTop(),
right,
bottom
);
// No need to change WebView margins; keep height as-is
parent.requestLayout();
}
else {
// Fallback: apply on the WebView itself
keyboard.setPadding(
left,
keyboard.getPaddingTop(),
right,
bottom
);
keyboard.requestLayout();
}
}
private static void initKeyboard(Context appContext, KeyboardType keyboardType) {
@ -2420,6 +2473,21 @@ public final class KMManager {
KeyboardHeight_Context_Landscape_Default = (int) newResources.getDimension(R.dimen.keyboard_height);
}
// Get the navigation bar height (if visible) in pixels
private static int getNavigationBarHeight(Context context) {
// Determine if navigation bar is visible
int resourceId = context.getResources().getIdentifier(
"config_showNavigationBar", "bool", "android");
if (resourceId <= 0) {
return 0;
}
// Navigation bar visible so get the height
resourceId = context.getResources().getIdentifier(
"navigation_bar_height", "dimen", "android");
return (resourceId > 0) ? context.getResources().getDimensionPixelSize(resourceId) : 0;
}
/**
* Get the size of the area the window would occupy.
* API 30+

View file

@ -1,5 +1,8 @@
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/help_file_layout"
android:fitsSystemWindows="true"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
@ -9,36 +12,28 @@
<WebView
android:id="@+id/kmHelpFileWebView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_height="0dp"
android:layout_below="@+id/titlebar"
android:layout_above="@+id/buttonBar" />
<LinearLayout
android:id="@+id/buttonBar"
style="?android:attr/buttonBarStyle"
android:layout_alignParentBottom="true"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<!-- Spacer to pad buttons to the right -->
<View
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_weight="1" />
app:layout_constraintTop_toBottomOf="@id/titlebar"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintBottom_toTopOf="@+id/finishButton" />
<Button
android:id="@+id/finishButton"
android:id="@id/finishButton"
style="@style/Widget.AppCompat.Button.Borderless.Colored"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/label_ok"
android:layout_marginStart="10dp"
android:layout_marginEnd="15dp"
android:layout_gravity="end"
android:elevation="1dp"
android:singleLine="true"
android:layout_marginStart="10dp" android:layout_marginEnd="15dp">
<requestFocus/>
android:text="@string/label_ok"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="1.0">
<requestFocus />
</Button>
</LinearLayout>
</RelativeLayout>
</androidx.constraintlayout.widget.ConstraintLayout>

View file

@ -1,13 +1,21 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
<androidx.constraintlayout.widget.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/activity_list_layout"
android:fitsSystemWindows="true"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<include layout="@layout/list_toolbar" />
<include layout="@layout/list_toolbar"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintStart_toStartOf="parent" />
<include layout="@layout/list_layout" />
<include layout="@layout/list_layout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_constraintTop_toBottomOf="@+id/list_appbar"
app:layout_constraintStart_toStartOf="parent" />
</LinearLayout>
</androidx.constraintlayout.widget.ConstraintLayout>

View file

@ -1,12 +1,15 @@
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:fitsSystemWindows="true"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<include layout="@layout/list_toolbar" />
<include layout="@layout/list_toolbar"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintStart_toStartOf="parent" />
<!-- ListView of installed keyboards. TODO: calculate height -->
<include
@ -14,45 +17,35 @@
layout="@layout/list_layout"
android:layout_width="match_parent"
android:layout_height="200dp"
android:layout_above="@+id/keyboard_linear_layout"
android:layout_below="@id/list_appbar" />
android:layout_above="@+id/modeling_settings_layout"
android:layout_below="@id/list_appbar"
app:layout_constraintTop_toBottomOf="@id/list_appbar"/>
<LinearLayout
android:id="@+id/keyboard_linear_layout"
android:layout_width="match_parent"
<com.google.android.material.floatingactionbutton.FloatingActionButton
android:id="@+id/add_button"
style="?android:attr/actionButtonStyle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_above="@id/modeling_settings_layout"
android:orientation="horizontal">
<Space
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_weight="10" />
<com.google.android.material.floatingactionbutton.FloatingActionButton
android:id="@+id/add_button"
style="?android:attr/actionButtonStyle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="end|center_vertical"
android:layout_marginTop="@dimen/fab_margin"
android:layout_marginBottom="@dimen/fab_margin"
android:layout_weight="1"
android:contentDescription="@string/image_button"
android:src="@drawable/ic_add_white"
app:fabSize="normal" />
</LinearLayout>
android:layout_gravity="end|center_vertical"
android:contentDescription="@string/image_button"
android:src="@drawable/ic_add_white"
android:layout_marginEnd="@dimen/fab_margin"
android:layout_marginBottom="@dimen/fab_margin"
app:fabSize="normal"
app:layout_constraintBottom_toTopOf="@+id/modeling_settings_layout"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="1.0"/>
<LinearLayout
android:id="@+id/modeling_settings_layout"
android:id="@id/modeling_settings_layout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_marginTop="0dp"
android:layout_marginBottom="0dp"
android:orientation="vertical">
android:orientation="vertical"
app:layout_constraintVertical_bias="1.0"
app:layout_constraintBottom_toBottomOf="parent">
<View
android:id="@+id/separator"
@ -117,4 +110,4 @@
android:layout_height="wrap_content"
android:layout_below="@id/model_picker"/> -->
</RelativeLayout>
</androidx.constraintlayout.widget.ConstraintLayout>

View file

@ -1,31 +1,25 @@
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/languages_list_layout"
android:fitsSystemWindows="true"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<include layout="@layout/list_toolbar" />
<include layout="@layout/list_toolbar"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintStart_toStartOf="parent" />
<include
android:id="@+id/keyboard_list_layout"
layout="@layout/list_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_below="@id/list_appbar" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:orientation="horizontal">
<Space
android:layout_width="wrap_content"
<include
android:id="@+id/keyboard_list_layout"
layout="@layout/list_layout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_weight="10" />
android:layout_below="@+id/list_appbar"
app:layout_constraintTop_toBottomOf="@id/list_appbar"
app:layout_constraintStart_toStartOf="parent"/>
<com.google.android.material.floatingactionbutton.FloatingActionButton
android:id="@+id/add_button"
@ -33,12 +27,13 @@
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="end|center_vertical"
android:layout_marginTop="@dimen/fab_margin"
android:layout_marginBottom="@dimen/fab_margin"
android:layout_weight="1"
android:contentDescription="@string/image_button"
android:src="@drawable/ic_add_white"
app:fabSize="normal" />
android:layout_marginEnd="@dimen/fab_margin"
android:layout_marginBottom="@dimen/fab_margin"
app:fabSize="normal"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="1.0"/>
</LinearLayout>
</RelativeLayout>
</androidx.constraintlayout.widget.ConstraintLayout>

View file

@ -7,31 +7,39 @@
android:layout_height="wrap_content"
app:elevation="0dp">
<androidx.appcompat.widget.Toolbar
android:id="@+id/list_toolbar"
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize">
<TextView
android:id="@+id/bar_title"
android:layout_width="wrap_content"
<androidx.appcompat.widget.Toolbar
android:id="@+id/list_toolbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:gravity="center"
android:ellipsize="end"
android:singleLine="true"
android:text="@string/title_add_keyboard"
android:textSize="@dimen/titlebar_label_textsize"
android:textStyle="bold" />
app:layout_constraintTop_toTopOf="parent">
</androidx.appcompat.widget.Toolbar>
<TextView
android:id="@+id/bar_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:gravity="center"
android:ellipsize="end"
android:singleLine="true"
android:text="@string/title_add_keyboard"
android:textSize="@dimen/titlebar_label_textsize"
android:textStyle="bold" />
<!-- optional accent -->
<View
android:id="@+id/bar_accent"
style="@style/AppTheme.Divider"
android:layout_width="match_parent"
android:layout_height="2dp"
android:layout_alignParentBottom="true"/>
</androidx.appcompat.widget.Toolbar>
<!-- optional accent -->
<View
android:id="@+id/bar_accent"
style="@style/AppTheme.Divider"
android:layout_width="match_parent"
android:layout_height="2dp"
app:layout_constraintTop_toBottomOf="@id/list_toolbar"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
</com.google.android.material.appbar.AppBarLayout>

View file

@ -6,7 +6,9 @@
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:layout_alignParentTop="true"
app:popupTheme="@style/ThemeOverlay.AppCompat.Light">
app:popupTheme="@style/ThemeOverlay.AppCompat.Light"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintStart_toStartOf="parent">
<TextView
android:id="@id/bar_title"

View file

@ -7,7 +7,6 @@ buildscript {
dependencies {
classpath 'com.android.tools.build:gradle:8.9.2'
// io.sentry:sentry-android-gradle-plugin not available for library project
classpath 'io.sentry:sentry-android:7.8.0'
classpath 'name.remal:gradle-plugins:1.9.2'
}
}

View file

@ -4,11 +4,10 @@
## START STANDARD BUILD SCRIPT INCLUDE
# adjust relative paths as necessary
THIS_SCRIPT="$(readlink -f "${BASH_SOURCE[0]}")"
. "${THIS_SCRIPT%/*}/../../resources/build/builder.inc.sh"
. "${THIS_SCRIPT%/*}/../../resources/build/builder-full.inc.sh"
## END STANDARD BUILD SCRIPT INCLUDE
. "$KEYMAN_ROOT/resources/shellHelperFunctions.sh"
. "$KEYMAN_ROOT/resources/build/build-utils-ci.inc.sh"
. "$KEYMAN_ROOT/resources/build/utils.inc.sh"
# ################################ Main script ################################

View file

@ -34,10 +34,10 @@ analytics for Debug are associated with an App Bundle ID
### Compiling From Command Line
1. Launch a command prompt and cd to the directory **keyman/android**
2. Run the top level build script `./build.sh configure build:engine build:app --debug` which will:
* Compile KMEA (and its KMW dependency)
2. Run the top level build script `./build.sh configure build:engine build:app` which will:
* Compile debug version of KMEA (and its KMW dependency)
* Download default keyboard and dictionary resources as needed
* Compile KMAPro
* Compile debug version of KMAPro
3. The APK will be found in **keyman/android/KMAPro/kMAPro/build/outputs/apk/debug/keyman-\${version}.apk**
where `${version}` is the current version number.
@ -98,10 +98,10 @@ There are two included sample projects that can be modified to test a keyboard.
**android/Samples/KMSample2** app provides prompts for setting KMSample2 as a system level keyboard.
Both sample apps include a default Tamil keyboard and sample dictionary.
Building these projects follow the same steps as KMAPro:
Building the debug versions of these projects follow the same steps as KMAPro:
1. cd to the desired KMSample directory
2. `./build.sh configure build --debug`
2. `./build.sh configure build`
3. Open Android Studio to run the app
### Tests: KeyboardHarness
@ -114,14 +114,14 @@ Building these projects follow the same steps as KMAPro:
* Build the keyboardharness.kmp keyboard package
3. Add the keyboard in *android/Tests/KeyboardHarness/app/src/main/java/com/keyman/android/tests/keyboardHarness/MainActivity.java*
4. cd to android/Tests/KeyboardHarness/
5. `./build.sh configure build --debug`
5. `./build.sh configure build`
6. Open Android Studio to run the app
--------------------------------------------------------------
## How to Build Keyman Engine for Android
1. Open a terminal or Git Bash prompt and go to the Android project folder (e.g. `cd ~/keyman/android/`)
2. Run `./build.sh build:engine --debug`
2. Run `./build.sh build:engine`
Keyman Engine for Android library (**keyman-engine.aar**) is now ready to be imported in any project.
@ -135,7 +135,7 @@ Keyman Engine for Android library (**keyman-engine.aar**) is now ready to be imp
4. Check that the `android{}` object, includes the following:
```gradle
android {
compileSdkVersion 34
compileSdkVersion 35
// Don't compress kmp files so they can be copied via AssetManager
aaptOptions {
@ -159,6 +159,7 @@ repositories {
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
implementation 'androidx.appcompat:appcompat:1.7.0'
implementation 'androidx.constraintlayout:constraintlayout:2.2.1'
implementation 'com.google.android.material:material:1.12.0'
api (name:'keyman-engine', ext:'aar')
implementation 'androidx.preference:preference:1.2.1'

View file

@ -2,8 +2,14 @@ plugins {
id 'com.android.application'
}
java {
toolchain {
languageVersion = JavaLanguageVersion.of(21)
}
}
android {
compileSdk 34
compileSdk 35
namespace="com.keyman.kmsample1"
// Don't compress kmp files so they can be copied via AssetManager
@ -14,7 +20,7 @@ android {
defaultConfig {
applicationId "com.keyman.kmsample1"
minSdkVersion 21
targetSdkVersion 34
targetSdkVersion 35
versionCode 1
versionName "1.0"
}
@ -24,12 +30,15 @@ android {
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
sourceSets {
main {
jniLibs.srcDirs = ['libs']
}
}
}
repositories {
flatDir {
dirs 'libs'
}
google()
}
@ -37,7 +46,8 @@ repositories {
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
implementation 'androidx.appcompat:appcompat:1.7.0'
implementation 'androidx.constraintlayout:constraintlayout:2.2.1'
implementation 'com.google.android.material:material:1.12.0'
api(name: 'keyman-engine', ext: 'aar')
implementation files('libs/keyman-engine.aar')
implementation 'androidx.preference:preference:1.2.1'
}

View file

@ -1,13 +1,14 @@
package com.keyman.kmsample1;
import androidx.appcompat.app.AppCompatActivity;
import android.content.Context;
import android.content.res.Configuration;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import androidx.constraintlayout.widget.ConstraintLayout;
import com.keyman.engine.BaseActivity;
import com.keyman.engine.data.Keyboard;
import com.keyman.engine.KMKeyboardDownloaderActivity;
import com.keyman.engine.KMManager;
@ -19,9 +20,10 @@ import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class MainActivity extends AppCompatActivity implements OnKeyboardEventListener, OnKeyboardDownloadEventListener {
public class MainActivity extends BaseActivity implements OnKeyboardEventListener, OnKeyboardDownloadEventListener {
public static Context context;
private ConstraintLayout constraintLayout;
private KMTextView textView;
@Override
@ -34,6 +36,12 @@ public class MainActivity extends AppCompatActivity implements OnKeyboardEventLi
KMManager.initialize(this, KeyboardType.KEYBOARD_TYPE_INAPP);
setContentView(R.layout.activity_main);
constraintLayout = findViewById(R.id.constraintLayout);
setupEdgeToEdge(R.id.constraintLayout);
setupStatusBarColors(
android.R.color.white, // Color for top status bar
android.R.color.darker_gray); // Color for bottom navigation bar
textView = (KMTextView) findViewById(R.id.kmTextView);
// Add a custom keyboard

View file

@ -1,7 +1,11 @@
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/constraintLayout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true"
android:orientation="vertical"
tools:context=".MainActivity">
<com.keyman.engine.KMTextView
@ -12,8 +16,10 @@
android:ems="10"
android:inputType="textMultiLine"
android:gravity="top"
android:scrollbars="vertical" >
android:scrollbars="vertical"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintStart_toStartOf="parent">
<requestFocus />
</com.keyman.engine.KMTextView>
</RelativeLayout>
</androidx.constraintlayout.widget.ConstraintLayout>

View file

@ -4,11 +4,10 @@
## START STANDARD BUILD SCRIPT INCLUDE
# adjust relative paths as necessary
THIS_SCRIPT="$(readlink -f "${BASH_SOURCE[0]}")"
. "${THIS_SCRIPT%/*}/../../../resources/build/builder.inc.sh"
. "${THIS_SCRIPT%/*}/../../../resources/build/builder-full.inc.sh"
## END STANDARD BUILD SCRIPT INCLUDE
. "$KEYMAN_ROOT/resources/shellHelperFunctions.sh"
. "$KEYMAN_ROOT/resources/build/build-utils-ci.inc.sh"
. "$KEYMAN_ROOT/resources/build/utils.inc.sh"
################################ Main script ################################
@ -23,7 +22,7 @@ builder_describe "Build KMSample1 app for Android." \
"configure" \
"build" \
"test" \
":app KMSample1"
":app KMSample1"
# parse before describe_outputs to check debug flags
builder_parse "$@"
@ -39,7 +38,6 @@ fi
builder_describe_outputs \
configure /android/Samples/KMSample1/app/libs/keyman-engine.aar \
build:app /android/Samples/KMSample1/app/build/outputs/apk/$CONFIG/$ARTIFACT

View file

@ -2,8 +2,14 @@ plugins {
id 'com.android.application'
}
java {
toolchain {
languageVersion = JavaLanguageVersion.of(21)
}
}
android {
compileSdk 34
compileSdk 35
namespace="com.keyman.kmsample2"
// Don't compress kmp files so they can be copied via AssetManager
@ -14,7 +20,7 @@ android {
defaultConfig {
applicationId "com.keyman.kmsample2"
minSdkVersion 21
targetSdkVersion 34
targetSdkVersion 35
versionCode 1
versionName "1.0"
}
@ -24,19 +30,23 @@ android {
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
sourceSets {
main {
jniLibs.srcDirs = ['libs']
}
}
}
repositories {
flatDir {
dirs 'libs'
}
google()
}
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
implementation 'androidx.appcompat:appcompat:1.7.0'
implementation 'androidx.constraintlayout:constraintlayout:2.2.1'
implementation 'com.google.android.material:material:1.12.0'
api (name:'keyman-engine', ext:'aar')
implementation files('libs/keyman-engine.aar')
implementation 'androidx.preference:preference:1.2.1'
}

View file

@ -1,6 +1,5 @@
package com.keyman.kmsample2;
import androidx.appcompat.app.AppCompatActivity;
import android.content.Context;
import android.content.Intent;
import android.provider.Settings;
@ -11,13 +10,20 @@ import android.view.View;
import android.view.inputmethod.InputMethodManager;
import android.widget.Button;
public class MainActivity extends AppCompatActivity {
import com.keyman.engine.BaseActivity;
public class MainActivity extends BaseActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
setTheme(R.style.AppTheme);
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
setupEdgeToEdge(R.id.constraintLayout);
setupStatusBarColors( // Inset colors for Android API < 35
android.R.color.black, // Color for status bar on top
android.R.color.white // Color for navigation bar on bottom
);
Button button1 = (Button) findViewById(R.id.button1);
button1.setOnClickListener(new View.OnClickListener() {

View file

@ -215,6 +215,20 @@ public class SystemKeyboard extends InputMethodService implements OnKeyboardEven
// Handle Keyman keyboard dismissed event here if needed
}
@Override
public boolean onEvaluateInputViewShown() {
// On Android API 36+, the OSK defaults to not appearing when a physical keyboard is connected.
// If the default implementation returns true, recommend honoring it
// Reference: https://android.googlesource.com/platform/frameworks/base/+/7b739a8%5E%21/
if (super.onEvaluateInputViewShown()) {
return true;
};
// TODO: Implement IME setting similar to Gboard "Show on-screen keyboard" with physical keyboard
// (default false)
return true;
}
@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
if (event.getAction() == KeyEvent.ACTION_DOWN) {

View file

@ -1,31 +1,50 @@
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent"
android:layout_height="match_parent" android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/constraintLayout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true"
android:orientation="vertical"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
android:paddingBottom="@dimen/activity_vertical_margin" tools:context=".MainActivity">
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingBottom="@dimen/activity_vertical_margin"
tools:context=".MainActivity">
<TextView android:text="@string/description" android:layout_width="wrap_content"
android:layout_height="wrap_content"
<TextView
android:id="@+id/textView"
android:layout_centerHorizontal="true" />
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/description"
app:layout_constraintHorizontal_bias="0.5"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<Button
android:layout_width="260dp"
android:layout_height="wrap_content"
android:text="Open input method settings"
android:id="@+id/button1"
android:layout_below="@+id/textView"
android:layout_centerHorizontal="true"
android:layout_marginTop="16dp" />
<Button
android:layout_width="260dp"
android:layout_height="wrap_content"
android:text="Open input method menu"
android:id="@+id/button2"
android:layout_below="@+id/button1"
android:layout_centerHorizontal="true"
android:layout_marginTop="16dp" />
android:layout_below="@+id/textView"
android:layout_centerInParent="true"
android:layout_marginTop="16dp"
android:text="Open input method settings"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.5"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/textView" />
</RelativeLayout>
<Button
android:id="@+id/button2"
android:layout_width="260dp"
android:layout_height="wrap_content"
android:layout_below="@+id/button1"
android:layout_marginTop="16dp"
android:text="Open input method menu"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.5"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/button1" />
</androidx.constraintlayout.widget.ConstraintLayout>

View file

@ -4,11 +4,10 @@
## START STANDARD BUILD SCRIPT INCLUDE
# adjust relative paths as necessary
THIS_SCRIPT="$(readlink -f "${BASH_SOURCE[0]}")"
. "${THIS_SCRIPT%/*}/../../../resources/build/builder.inc.sh"
. "${THIS_SCRIPT%/*}/../../../resources/build/builder-full.inc.sh"
## END STANDARD BUILD SCRIPT INCLUDE
. "$KEYMAN_ROOT/resources/shellHelperFunctions.sh"
. "$KEYMAN_ROOT/resources/build/build-utils-ci.inc.sh"
. "$KEYMAN_ROOT/resources/build/utils.inc.sh"
################################ Main script ################################
@ -23,7 +22,7 @@ builder_describe "Build KMSample2 app for Android." \
"configure" \
"build" \
"test" \
":app KMSample2"
":app KMSample2"
# parse before describe_outputs to check debug flags
builder_parse "$@"
@ -40,7 +39,6 @@ fi
builder_describe_outputs \
configure /android/Samples/KMSample2/app/libs/keyman-engine.aar \
build:app /android/Samples/KMSample2/app/build/outputs/apk/$CONFIG/$ARTIFACT

View file

@ -5,6 +5,12 @@ plugins {
ext.rootPath = '../../../'
apply from: "$rootPath/version.gradle"
java {
toolchain {
languageVersion = JavaLanguageVersion.of(21)
}
}
android {
compileSdk 35
namespace="com.keyman.android.tests.keyboardHarness"
@ -34,12 +40,15 @@ android {
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
sourceSets {
main {
jniLibs.srcDirs = ['libs']
}
}
}
repositories {
flatDir {
dirs 'libs'
}
google()
mavenCentral()
}
@ -47,7 +56,8 @@ repositories {
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
implementation 'androidx.appcompat:appcompat:1.7.0'
implementation 'androidx.constraintlayout:constraintlayout:2.2.1'
implementation 'com.google.android.material:material:1.12.0'
api (name:'keyman-engine', ext:'aar')
implementation files('libs/keyman-engine.aar')
implementation 'androidx.preference:preference:1.2.1'
}

View file

@ -1,11 +1,13 @@
package com.keyman.android.tests.keyboardHarness;
import androidx.appcompat.app.AppCompatActivity;
import android.content.res.Configuration;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import androidx.constraintlayout.widget.ConstraintLayout;
import com.keyman.engine.BaseActivity;
import com.keyman.engine.data.Keyboard;
import com.keyman.engine.KMKeyboardDownloaderActivity;
import com.keyman.engine.KMManager;
@ -18,8 +20,9 @@ import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class MainActivity extends AppCompatActivity implements OnKeyboardEventListener, OnKeyboardDownloadEventListener {
public class MainActivity extends BaseActivity implements OnKeyboardEventListener, OnKeyboardDownloadEventListener {
private ConstraintLayout constraintLayout;
private KMTextView textView;
@Override
@ -31,6 +34,12 @@ public class MainActivity extends AppCompatActivity implements OnKeyboardEventLi
KMManager.initialize(this, KeyboardType.KEYBOARD_TYPE_INAPP);
setContentView(R.layout.activity_main);
constraintLayout = findViewById(R.id.constraintLayout);
setupEdgeToEdge(R.id.constraintLayout);
setupStatusBarColors(
android.R.color.white, // Color for top status bar
android.R.color.darker_gray); // Color for bottom navigation bar
textView = (KMTextView) findViewById(R.id.kmTextView);
// Add custom keyboards

View file

@ -1,7 +1,11 @@
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/constraintLayout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true"
android:orientation="vertical"
tools:context=".MainActivity">
<com.keyman.engine.KMTextView
@ -12,9 +16,11 @@
android:ems="10"
android:inputType="textMultiLine"
android:gravity="top"
android:scrollbars="vertical" >
android:scrollbars="vertical"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintStart_toStartOf="parent">
<requestFocus />
</com.keyman.engine.KMTextView>
</RelativeLayout>
</androidx.constraintlayout.widget.ConstraintLayout>

View file

@ -4,11 +4,10 @@
## START STANDARD BUILD SCRIPT INCLUDE
# adjust relative paths as necessary
THIS_SCRIPT="$(readlink -f "${BASH_SOURCE[0]}")"
. "${THIS_SCRIPT%/*}/../../../resources/build/builder.inc.sh"
. "${THIS_SCRIPT%/*}/../../../resources/build/builder-full.inc.sh"
## END STANDARD BUILD SCRIPT INCLUDE
. "$KEYMAN_ROOT/resources/shellHelperFunctions.sh"
. "$KEYMAN_ROOT/resources/build/build-utils-ci.inc.sh"
. "$KEYMAN_ROOT/resources/build/utils.inc.sh"
################################ Main script ################################
@ -23,7 +22,7 @@ builder_describe "Build KeyboardHarness test app for Android." \
"configure" \
"build" \
"test" \
":app KeyboardHarness"
":app KeyboardHarness"
# parse before describe outputs to check debug flags
builder_parse "$@"
@ -40,7 +39,6 @@ fi
builder_describe_outputs \
configure /android/Tests/KeyboardHarness/app/libs/keyman-engine.aar \
build:app /android/Tests/KeyboardHarness/app/build/outputs/apk/$CONFIG/${ARTIFACT}
#### Build

View file

@ -6,8 +6,8 @@ ext.rootPath = '../../../'
apply from: "$rootPath/version.gradle"
android {
compileSdk 34
namespace "com.keyman.android.tests.keycode"
compileSdk 35
namespace="com.keyman.android.tests.keycode"
buildFeatures {
// needed for custom BuildConfigField values in defaultConfig
@ -17,7 +17,7 @@ android {
defaultConfig {
applicationId "com.keyman.android.tests.keycode"
minSdkVersion 21
targetSdkVersion 34
targetSdkVersion 35
// KEYMAN_VERSION_CODE and KEYMAN_VERSION_NAME from version.gradle
versionCode KEYMAN_VERSION_CODE as Integer

View file

@ -10,12 +10,11 @@
## START STANDARD BUILD SCRIPT INCLUDE
# adjust relative paths as necessary
THIS_SCRIPT="$(readlink -f "${BASH_SOURCE[0]}")"
. "${THIS_SCRIPT%/*}/../resources/build/builder.inc.sh"
. "${THIS_SCRIPT%/*}/../resources/build/builder-full.inc.sh"
## END STANDARD BUILD SCRIPT INCLUDE
# shellcheck disable=SC2154
. "${KEYMAN_ROOT}/resources/shellHelperFunctions.sh"
. "${KEYMAN_ROOT}/resources/build/build-utils-ci.inc.sh"
. "${KEYMAN_ROOT}/resources/build/utils.inc.sh"
. "${KEYMAN_ROOT}/resources/build/zip.inc.sh"
################################ Main script ################################
@ -38,9 +37,9 @@ builder_describe \
configure \
build \
test \
"publish Publishes symbols to Sentry and the APKs to the Play Store." \
"publish-symbols Publishes symbols to Sentry" \
"publish-play-store Publishes APKs to the Play Store" \
"archive Copy release artifacts to upload/ and create zip" \
--upload-sentry+ \
":engine=KMEA Keyman Engine for Android" \
":app=KMAPro Keyman for Android" \
":help Online documentation" \
@ -108,8 +107,18 @@ function archive_artifacts() {
fi
}
# Override JAVA_HOME to OpenJDK 11
set_java_home
# For CI compatibility of building Keyman for Android 18.0 with OpenJDK 11,
# this overrides JAVA_HOME for the builder script to use OpenJDK 21.
android_set_java_home() {
if [[ ! -z ${JAVA_HOME_21+x} ]]; then
builder_echo "Setting JAVA_HOME to JAVA_HOME_21 (${JAVA_HOME_21})"
export JAVA_HOME="${JAVA_HOME_21}"
fi
}
# Override JAVA_HOME
android_set_java_home
# This script also responsible for cleaning up /android/upload
builder_run_child_actions clean
@ -120,6 +129,6 @@ builder_run_child_actions configure build test
builder_run_action test:help do_test_help
builder_run_child_actions publish
builder_run_child_actions publish-symbols publish-play-store
builder_run_action archive archive_artifacts

Binary file not shown.

Before

Width:  |  Height:  |  Size: 33 KiB

After

Width:  |  Height:  |  Size: 40 KiB

View file

@ -49,6 +49,9 @@ Click on this to [adjust the keyboard height](adjust-keyboard-height).
Click on this to [adjust the delay time](adjust-longpress-delay) for a longpress gesture.
## Show On-Screen Keyboard
By default, Android 16 (Baklava) and later versions won't display the On-Screen keyboard if a physical keyboard is connected. When enabled, show the Keyman system keyboard even if a physical keyboard is connected.
## Spacebar Caption
Click on this to [change the displayed keyboard name](spacebar-caption) on the spacebar.

View file

@ -25,7 +25,7 @@ set -u # die on undefined variables
## START STANDARD BUILD SCRIPT INCLUDE
# adjust relative paths as necessary
THIS_SCRIPT="$(readlink -f "${BASH_SOURCE[0]}")"
. "${THIS_SCRIPT%/*}/../../resources/build/build-utils.sh"
. "${THIS_SCRIPT%/*}/../../resources/build/builder-basic.inc.sh"
## END STANDARD BUILD SCRIPT INCLUDE
# Preparation

View file

@ -2,7 +2,7 @@
## START STANDARD BUILD SCRIPT INCLUDE
# adjust relative paths as necessary
THIS_SCRIPT="$(readlink -f "${BASH_SOURCE[0]}")"
. "${THIS_SCRIPT%/*}/resources/build/builder.inc.sh"
. "${THIS_SCRIPT%/*}/resources/build/builder-full.inc.sh"
## END STANDARD BUILD SCRIPT INCLUDE
builder_describe "Keyman -- all projects" \

View file

@ -2,7 +2,7 @@
## START STANDARD BUILD SCRIPT INCLUDE
# adjust relative paths as necessary
THIS_SCRIPT="$(readlink -f "${BASH_SOURCE[0]}")"
. "${THIS_SCRIPT%/*}/../resources/build/builder.inc.sh"
. "${THIS_SCRIPT%/*}/../resources/build/builder-full.inc.sh"
## END STANDARD BUILD SCRIPT INCLUDE
builder_describe "Keyman common and resources modules" \

View file

@ -5,7 +5,7 @@
## START STANDARD BUILD SCRIPT INCLUDE
# adjust relative paths as necessary
THIS_SCRIPT="$(readlink -f "${BASH_SOURCE[0]}")"
. "${THIS_SCRIPT%/*}/../../resources/build/builder.inc.sh"
. "${THIS_SCRIPT%/*}/../../resources/build/builder-full.inc.sh"
## END STANDARD BUILD SCRIPT INCLUDE
builder_describe "Build keymanversion_build.h" configure build clean

View file

@ -2,7 +2,7 @@
## START STANDARD BUILD SCRIPT INCLUDE
# adjust relative paths as necessary
THIS_SCRIPT="$(readlink -f "${BASH_SOURCE[0]}")"
. "${THIS_SCRIPT%/*}/../../resources/build/builder.inc.sh"
. "${THIS_SCRIPT%/*}/../../resources/build/builder-full.inc.sh"
## END STANDARD BUILD SCRIPT INCLUDE
#

View file

@ -2,7 +2,7 @@
## START STANDARD BUILD SCRIPT INCLUDE
# adjust relative paths as necessary
THIS_SCRIPT="$(readlink -f "${BASH_SOURCE[0]}")"
. "${THIS_SCRIPT%/*}/../../resources/build/builder.inc.sh"
. "${THIS_SCRIPT%/*}/../../resources/build/builder-full.inc.sh"
## END STANDARD BUILD SCRIPT INCLUDE
#

View file

@ -2,7 +2,7 @@
## START STANDARD BUILD SCRIPT INCLUDE
# adjust relative paths as necessary
THIS_SCRIPT="$(readlink -f "${BASH_SOURCE[0]}")"
. "${THIS_SCRIPT%/*}/../../../../resources/build/builder.inc.sh"
. "${THIS_SCRIPT%/*}/../../../../resources/build/builder-full.inc.sh"
## END STANDARD BUILD SCRIPT INCLUDE
builder_describe "Baseline keyboards tests -- built with 16.0 compiler" \

View file

@ -2,7 +2,7 @@
## START STANDARD BUILD SCRIPT INCLUDE
# adjust relative paths as necessary
THIS_SCRIPT="$(readlink -f "${BASH_SOURCE[0]}")"
. "${THIS_SCRIPT%/*}/../../../resources/build/builder.inc.sh"
. "${THIS_SCRIPT%/*}/../../../resources/build/builder-full.inc.sh"
## END STANDARD BUILD SCRIPT INCLUDE
. "$KEYMAN_ROOT/resources/build/zip.inc.sh"

View file

@ -3,8 +3,8 @@
## START STANDARD BUILD SCRIPT INCLUDE
# adjust relative paths as necessary
THIS_SCRIPT="$(readlink -f "${BASH_SOURCE[0]}")"
. "${THIS_SCRIPT%/*}/../../../../../resources/build/build-utils.sh"
# . "$KEYMAN_ROOT/resources/shellHelperFunctions.sh"
. "${THIS_SCRIPT%/*}/../../../../../resources/build/builder-basic.inc.sh"
# . "$KEYMAN_ROOT/resources/build/utils.inc.sh"
## END STANDARD BUILD SCRIPT INCLUDE
THIS_DIR="$(dirname "$THIS_SCRIPT")"

View file

@ -19,7 +19,9 @@ import { fileURLToPath } from 'url';
/**
* Creates a MessageEvent (for inter-worker communication), with the given data payload.
*
* @param {*} data
* @template {T}
* @param {T} data
* @returns {T}
*/
export function createMessageEventWithData(data) {
return { data };

View file

@ -8,7 +8,7 @@ set -eu
## START STANDARD BUILD SCRIPT INCLUDE
# adjust relative paths as necessary
THIS_SCRIPT="$(readlink -f "${BASH_SOURCE[0]}")"
. "${THIS_SCRIPT%/*}/../../../resources/build/build-utils.sh"
. "${THIS_SCRIPT%/*}/../../../resources/build/builder-basic.inc.sh"
## END STANDARD BUILD SCRIPT INCLUDE

View file

@ -2,10 +2,11 @@
## START STANDARD BUILD SCRIPT INCLUDE
# adjust relative paths as necessary
THIS_SCRIPT="$(readlink -f "${BASH_SOURCE[0]}")"
. "${THIS_SCRIPT%/*}/../../../resources/build/builder.inc.sh"
. "${THIS_SCRIPT%/*}/../../../resources/build/builder-full.inc.sh"
## END STANDARD BUILD SCRIPT INCLUDE
. "$KEYMAN_ROOT/resources/shellHelperFunctions.sh"
. "$KEYMAN_ROOT/resources/build/utils.inc.sh"
. "$KEYMAN_ROOT/resources/build/node.inc.sh"
################################ Main script ################################
@ -17,5 +18,5 @@ builder_describe_outputs \
builder_parse "$@"
builder_run_action clean rm -rf build/ node_modules/
builder_run_action configure verify_npm_setup
builder_run_action configure node_select_version_and_npm_ci
builder_run_action build tsc --build

View file

@ -6,10 +6,11 @@
## START STANDARD BUILD SCRIPT INCLUDE
# adjust relative paths as necessary
THIS_SCRIPT="$(readlink -f "${BASH_SOURCE[0]}")"
. "${THIS_SCRIPT%/*}/../../../resources/build/builder.inc.sh"
. "${THIS_SCRIPT%/*}/../../../resources/build/builder-full.inc.sh"
## END STANDARD BUILD SCRIPT INCLUDE
. "$KEYMAN_ROOT/resources/shellHelperFunctions.sh"
. "$KEYMAN_ROOT/resources/build/utils.inc.sh"
. "$KEYMAN_ROOT/resources/build/node.inc.sh"
################################ Main script ################################
@ -34,7 +35,7 @@ fi
### CONFIGURE ACTIONS
if builder_start_action configure; then
verify_npm_setup
node_select_version_and_npm_ci
builder_finish_action success configure
fi

View file

@ -5,7 +5,7 @@
## START STANDARD BUILD SCRIPT INCLUDE
# adjust relative paths as necessary
THIS_SCRIPT="$(readlink -f "${BASH_SOURCE[0]}")"
. "${THIS_SCRIPT%/*}/../../resources/build/builder.inc.sh"
. "${THIS_SCRIPT%/*}/../../resources/build/builder-full.inc.sh"
## END STANDARD BUILD SCRIPT INCLUDE
builder_describe "Keyman common web modules" \

View file

@ -2,11 +2,12 @@
## START STANDARD BUILD SCRIPT INCLUDE
# adjust relative paths as necessary
THIS_SCRIPT="$(readlink -f "${BASH_SOURCE[0]}")"
. "${THIS_SCRIPT%/*}/../../../resources/build/builder.inc.sh"
. "${THIS_SCRIPT%/*}/../../../resources/build/builder-full.inc.sh"
## END STANDARD BUILD SCRIPT INCLUDE
. "$KEYMAN_ROOT/resources/shellHelperFunctions.sh"
. "$KEYMAN_ROOT/resources/build/build-utils-ci.inc.sh"
. "$KEYMAN_ROOT/resources/build/utils.inc.sh"
. "$KEYMAN_ROOT/resources/build/node.inc.sh"
. "$KEYMAN_ROOT/resources/build/ci/ci-publish.inc.sh"
################################ Main script ################################
@ -53,6 +54,6 @@ export default KEYMAN_VERSION;
}
builder_run_action clean rm -rf version.inc.ts keyman-version.mts build/
builder_run_action configure verify_npm_setup
builder_run_action configure node_select_version_and_npm_ci
builder_run_action build do_build
builder_run_action publish builder_publish_npm
builder_run_action publish ci_publish_npm

View file

@ -2,11 +2,12 @@
## START STANDARD BUILD SCRIPT INCLUDE
# adjust relative paths as necessary
THIS_SCRIPT="$(readlink -f "${BASH_SOURCE[0]}")"
. "${THIS_SCRIPT%/*}/../../../resources/build/builder.inc.sh"
. "${THIS_SCRIPT%/*}/../../../resources/build/builder-full.inc.sh"
## END STANDARD BUILD SCRIPT INCLUDE
. "$KEYMAN_ROOT/resources/shellHelperFunctions.sh"
. "$KEYMAN_ROOT/resources/build/build-utils-ci.inc.sh"
. "$KEYMAN_ROOT/resources/build/utils.inc.sh"
. "$KEYMAN_ROOT/resources/build/node.inc.sh"
. "$KEYMAN_ROOT/resources/build/ci/ci-publish.inc.sh"
builder_describe "Build Keyman langtags.js common module" \
"clean" \
@ -32,7 +33,7 @@ function compile_langtags() {
}
function do_configure() {
verify_npm_setup
node_select_version_and_npm_ci
compile_langtags
}
@ -42,4 +43,4 @@ builder_run_action clean rm -rf ./build ./src/imports ./node_modules
builder_run_action configure do_configure
builder_run_action build tsc --build
builder_run_action test echo 'no tests for langtags'
builder_run_action publish builder_publish_npm
builder_run_action publish ci_publish_npm

View file

@ -2,11 +2,12 @@
## START STANDARD BUILD SCRIPT INCLUDE
# adjust relative paths as necessary
THIS_SCRIPT="$(readlink -f "${BASH_SOURCE[0]}")"
. "${THIS_SCRIPT%/*}/../../../resources/build/builder.inc.sh"
. "${THIS_SCRIPT%/*}/../../../resources/build/builder-full.inc.sh"
## END STANDARD BUILD SCRIPT INCLUDE
. "$KEYMAN_ROOT/resources/shellHelperFunctions.sh"
. "$KEYMAN_ROOT/resources/build/build-utils-ci.inc.sh"
. "$KEYMAN_ROOT/resources/build/utils.inc.sh"
. "$KEYMAN_ROOT/resources/build/node.inc.sh"
. "$KEYMAN_ROOT/resources/build/ci/ci-publish.inc.sh"
builder_describe "Build Keyman common file types module" \
"@/core/include/ldml" \
@ -76,7 +77,7 @@ function compile_schemas() {
function do_configure() {
compile_schemas
verify_npm_setup
node_select_version_and_npm_ci
}
function do_test() {
@ -104,4 +105,4 @@ builder_run_action clean rm -rf ./build/ ./tsconfig.tsbuildinfo ./src/schem
builder_run_action configure do_configure
builder_run_action build tsc --build
builder_run_action test do_test
builder_run_action publish builder_publish_npm
builder_run_action publish ci_publish_npm

View file

@ -417,13 +417,24 @@ export interface ProbabilityMass<T> {
export type Distribution<T> = ProbabilityMass<T>[];
/**
* A type augmented with an optional probability.
* A type augmented with optional probability data.
*/
export type Outcome<T> = T & {
/**
* [optional] probability of this outcome.
* [optional] the modeled likelihood associated with this outcome.
*/
p?: number;
/**
* The likelihood of the suggestion itself based solely on the lexical model
*/
['lexical-p']?: number
/**
* The likelihood associated with the keystroke sequence and/or associated
* text corrections best matching the suggestion.
*/
['correction-p']?: number
};
/**
@ -434,6 +445,21 @@ export type WithOutcome<T> = T & {
* Probability of this outcome.
*/
p: number;
/**
* The likelihood of the suggestion itself based solely on the lexical model
*
* Only emitted for verbose mode.
*/
['lexical-p']?: number
/**
* The likelihood associated with the keystroke sequence and/or associated
* text corrections best matching the suggestion.
*
* Only omitted for verbose mode.
*/
['correction-p']?: number
};

View file

@ -2,7 +2,7 @@
## START STANDARD BUILD SCRIPT INCLUDE
# adjust relative paths as necessary
THIS_SCRIPT="$(readlink -f "${BASH_SOURCE[0]}")"
. "${THIS_SCRIPT%/*}/../../resources/build/builder.inc.sh"
. "${THIS_SCRIPT%/*}/../../resources/build/builder-full.inc.sh"
## END STANDARD BUILD SCRIPT INCLUDE
#

View file

@ -13,8 +13,8 @@ set -u
## START STANDARD BUILD SCRIPT INCLUDE
# adjust relative paths as necessary
THIS_SCRIPT="$(readlink -f "${BASH_SOURCE[0]}")"
. "${THIS_SCRIPT%/*}/../../resources/build/build-utils.sh"
# . "$KEYMAN_ROOT/resources/shellHelperFunctions.sh"
. "${THIS_SCRIPT%/*}/../../resources/build/builder-basic.inc.sh"
# . "$KEYMAN_ROOT/resources/build/utils.inc.sh"
## END STANDARD BUILD SCRIPT INCLUDE
pushd $KEYMAN_CEF4DELPHI_ROOT > /dev/null

View file

@ -2,7 +2,7 @@
## START STANDARD BUILD SCRIPT INCLUDE
# adjust relative paths as necessary
THIS_SCRIPT="$(readlink -f "${BASH_SOURCE[0]}")"
. "${THIS_SCRIPT%/*}/../../../resources/build/builder.inc.sh"
. "${THIS_SCRIPT%/*}/../../../resources/build/builder-full.inc.sh"
## END STANDARD BUILD SCRIPT INCLUDE
builder_describe \

View file

@ -2,7 +2,7 @@
## START STANDARD BUILD SCRIPT INCLUDE
# adjust relative paths as necessary
THIS_SCRIPT="$(readlink -f "${BASH_SOURCE[0]}")"
. "${THIS_SCRIPT%/*}/../../../resources/build/builder.inc.sh"
. "${THIS_SCRIPT%/*}/../../../resources/build/builder-full.inc.sh"
## END STANDARD BUILD SCRIPT INCLUDE
builder_describe \

View file

@ -2,7 +2,7 @@
## START STANDARD BUILD SCRIPT INCLUDE
# adjust relative paths as necessary
THIS_SCRIPT="$(readlink -f "${BASH_SOURCE[0]}")"
. "${THIS_SCRIPT%/*}/../../../../resources/build/builder.inc.sh"
. "${THIS_SCRIPT%/*}/../../../../resources/build/builder-full.inc.sh"
## END STANDARD BUILD SCRIPT INCLUDE
builder_describe "Common Delphi components" clean configure build test edit

View file

@ -2,7 +2,7 @@
## START STANDARD BUILD SCRIPT INCLUDE
# adjust relative paths as necessary
THIS_SCRIPT="$(readlink -f "${BASH_SOURCE[0]}")"
. "${THIS_SCRIPT%/*}/../../../../resources/build/builder.inc.sh"
. "${THIS_SCRIPT%/*}/../../../../resources/build/builder-full.inc.sh"
## END STANDARD BUILD SCRIPT INCLUDE
builder_describe \

View file

@ -2,7 +2,7 @@
## START STANDARD BUILD SCRIPT INCLUDE
# adjust relative paths as necessary
THIS_SCRIPT="$(readlink -f "${BASH_SOURCE[0]}")"
. "${THIS_SCRIPT%/*}/../../../../../resources/build/builder.inc.sh"
. "${THIS_SCRIPT%/*}/../../../../../resources/build/builder-full.inc.sh"
## END STANDARD BUILD SCRIPT INCLUDE
builder_describe "cef4delphi component" clean configure build test

View file

@ -2,7 +2,7 @@
## START STANDARD BUILD SCRIPT INCLUDE
# adjust relative paths as necessary
THIS_SCRIPT="$(readlink -f "${BASH_SOURCE[0]}")"
. "${THIS_SCRIPT%/*}/../../../../../resources/build/builder.inc.sh"
. "${THIS_SCRIPT%/*}/../../../../../resources/build/builder-full.inc.sh"
## END STANDARD BUILD SCRIPT INCLUDE
builder_describe "dcpcrypt component" clean configure build test

View file

@ -2,7 +2,7 @@
## START STANDARD BUILD SCRIPT INCLUDE
# adjust relative paths as necessary
THIS_SCRIPT="$(readlink -f "${BASH_SOURCE[0]}")"
. "${THIS_SCRIPT%/*}/../../../../../resources/build/builder.inc.sh"
. "${THIS_SCRIPT%/*}/../../../../../resources/build/builder-full.inc.sh"
## END STANDARD BUILD SCRIPT INCLUDE
builder_describe "jwa component" clean configure build test

View file

@ -2,7 +2,7 @@
## START STANDARD BUILD SCRIPT INCLUDE
# adjust relative paths as necessary
THIS_SCRIPT="$(readlink -f "${BASH_SOURCE[0]}")"
. "${THIS_SCRIPT%/*}/../../../../../resources/build/builder.inc.sh"
. "${THIS_SCRIPT%/*}/../../../../../resources/build/builder-full.inc.sh"
## END STANDARD BUILD SCRIPT INCLUDE
builder_describe "Sentry component for Delphi" clean configure build test

View file

@ -2,7 +2,7 @@
## START STANDARD BUILD SCRIPT INCLUDE
# adjust relative paths as necessary
THIS_SCRIPT="$(readlink -f "${BASH_SOURCE[0]}")"
. "${THIS_SCRIPT%/*}/../../../../../resources/build/builder.inc.sh"
. "${THIS_SCRIPT%/*}/../../../../../resources/build/builder-full.inc.sh"
## END STANDARD BUILD SCRIPT INCLUDE
# TODO: move this out of ext and into tools

View file

@ -11,13 +11,11 @@ uses
procedure ReportToTeamCity;
var
KeymanRoot: string;
ReportPath: string;
begin
if GetEnvironmentVariable('TEAMCITY_GIT_PATH') <> '' then
begin
KeymanRoot := ExcludeTrailingPathDelimiter(GetEnvironmentVariable('KEYMAN_ROOT'));
ReportPath := ExtractRelativePath(KeymanRoot, ExtractFilePath(ParamStr(0)) + 'dunitx-results.xml');
ReportPath := ExtractFilePath(ParamStr(0)) + 'dunitx-results.xml';
writeln('##teamcity[importData type=''nunit'' path='''+ReportPath+''']');
end;
end;

View file

@ -1,6 +1,6 @@
type
TKeymanVersionInfo = record
// These fields match fields in /resources/build/build-utils.sh
// These fields match fields in /resources/build/builder-basic.inc.sh
Version: string; // 14.0.2
VersionWin: string; // 14.0.2.0
VersionRelease: string; // 14.0

View file

@ -6,7 +6,7 @@
// Keyman Version Information
CKeymanVersionInfo: TKeymanVersionInfo = (
// These fields match fields in /resources/build/build-utils.sh
// These fields match fields in /resources/build/builder-basic.inc.sh
Version: '$Version';
VersionWin: '$VersionWin';
VersionRelease: '$VersionRelease';

View file

@ -2,7 +2,7 @@
## START STANDARD BUILD SCRIPT INCLUDE
# adjust relative paths as necessary
THIS_SCRIPT="$(readlink -f "${BASH_SOURCE[0]}")"
. "${THIS_SCRIPT%/*}/../../../../resources/build/builder.inc.sh"
. "${THIS_SCRIPT%/*}/../../../../resources/build/builder-full.inc.sh"
## END STANDARD BUILD SCRIPT INCLUDE
builder_describe \

View file

@ -2,7 +2,7 @@
## START STANDARD BUILD SCRIPT INCLUDE
# adjust relative paths as necessary
THIS_SCRIPT="$(readlink -f "${BASH_SOURCE[0]}")"
. "${THIS_SCRIPT%/*}/../../../../../resources/build/builder.inc.sh"
. "${THIS_SCRIPT%/*}/../../../../../resources/build/builder-full.inc.sh"
## END STANDARD BUILD SCRIPT INCLUDE
builder_describe "Build build_standards_data tool" clean configure build test edit

View file

@ -2,7 +2,7 @@
## START STANDARD BUILD SCRIPT INCLUDE
# adjust relative paths as necessary
THIS_SCRIPT="$(readlink -f "${BASH_SOURCE[0]}")"
. "${THIS_SCRIPT%/*}/../../../../../resources/build/builder.inc.sh"
. "${THIS_SCRIPT%/*}/../../../../../resources/build/builder-full.inc.sh"
## END STANDARD BUILD SCRIPT INCLUDE
builder_describe "Unicode character database build tool" \

View file

@ -2,7 +2,7 @@
## START STANDARD BUILD SCRIPT INCLUDE
# adjust relative paths as necessary
THIS_SCRIPT="$(readlink -f "${BASH_SOURCE[0]}")"
. "${THIS_SCRIPT%/*}/../../../../../resources/build/builder.inc.sh"
. "${THIS_SCRIPT%/*}/../../../../../resources/build/builder-full.inc.sh"
## END STANDARD BUILD SCRIPT INCLUDE
builder_describe "Build and install test certificates" clean configure build test \

View file

@ -2,7 +2,7 @@
## START STANDARD BUILD SCRIPT INCLUDE
# adjust relative paths as necessary
THIS_SCRIPT="$(readlink -f "${BASH_SOURCE[0]}")"
. "${THIS_SCRIPT%/*}/../../../../../resources/build/builder.inc.sh"
. "${THIS_SCRIPT%/*}/../../../../../resources/build/builder-full.inc.sh"
## END STANDARD BUILD SCRIPT INCLUDE
builder_describe \

View file

@ -2,7 +2,7 @@
## START STANDARD BUILD SCRIPT INCLUDE
# adjust relative paths as necessary
THIS_SCRIPT="$(readlink -f "${BASH_SOURCE[0]}")"
. "${THIS_SCRIPT%/*}/../../../../../resources/build/builder.inc.sh"
. "${THIS_SCRIPT%/*}/../../../../../resources/build/builder-full.inc.sh"
## END STANDARD BUILD SCRIPT INCLUDE
builder_describe "Sentrytool for converting Delphi symbols into sentry-readable format" \

View file

@ -2,7 +2,7 @@
## START STANDARD BUILD SCRIPT INCLUDE
# adjust relative paths as necessary
THIS_SCRIPT="$(readlink -f "${BASH_SOURCE[0]}")"
. "${THIS_SCRIPT%/*}/../../../../../resources/build/builder.inc.sh"
. "${THIS_SCRIPT%/*}/../../../../../resources/build/builder-full.inc.sh"
## END STANDARD BUILD SCRIPT INCLUDE
builder_describe "Tool for validating klog is disabled for release builds" \

Some files were not shown because too many files have changed in this diff Show more