mirror of
https://github.com/keymanapp/keyman.git
synced 2026-10-29 09:17:45 +00:00
Merge branch 'epic/win-arm' into feat/windows/11905/keymanx64-keymanarm64
This commit is contained in:
commit
5ac167977b
681 changed files with 19854 additions and 8717 deletions
1
.gitattributes
vendored
1
.gitattributes
vendored
|
|
@ -7,3 +7,4 @@
|
|||
# EOF
|
||||
# ```
|
||||
Dockerfile text eol=lf
|
||||
*.sh text eol=lf
|
||||
|
|
|
|||
10
.github/workflows/api-verification.yml
vendored
10
.github/workflows/api-verification.yml
vendored
|
|
@ -23,6 +23,7 @@ jobs:
|
|||
GIT_BRANCH: ${{ steps.environment_step.outputs.GIT_BRANCH }}
|
||||
GIT_BASE_BRANCH: ${{ steps.environment_step.outputs.GIT_BASE_BRANCH }}
|
||||
GIT_USER: ${{ steps.environment_step.outputs.GIT_USER }}
|
||||
SKIP_API_CHECK: ${{ steps.environment_step.outputs.SKIP_API_CHECK }}
|
||||
|
||||
steps:
|
||||
- name: Restore artifacts
|
||||
|
|
@ -40,7 +41,7 @@ jobs:
|
|||
|
||||
- name: Set pending status on PR builds
|
||||
id: set_status
|
||||
if: steps.environment_step.outputs.IS_TEST_BUILD == 'true'
|
||||
if: steps.environment_step.outputs.IS_TEST_BUILD == 'true' && steps.environment_step.outputs.SKIP_API_CHECK != 'true'
|
||||
shell: bash
|
||||
run: |
|
||||
gh api \
|
||||
|
|
@ -53,6 +54,7 @@ jobs:
|
|||
-f context="$STATUS_CONTEXT"
|
||||
|
||||
- name: Checkout
|
||||
if: steps.environment_step.outputs.SKIP_API_CHECK != 'true'
|
||||
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 #v4.2.2
|
||||
with:
|
||||
ref: '${{ steps.environment_step.outputs.GIT_SHA }}'
|
||||
|
|
@ -61,11 +63,13 @@ jobs:
|
|||
path: ${{ github.workspace }}/keyman/
|
||||
|
||||
- name: Install devscripts
|
||||
if: steps.environment_step.outputs.SKIP_API_CHECK != 'true'
|
||||
uses: ./keyman/.github/actions/apt-install
|
||||
with:
|
||||
packages: devscripts equivs
|
||||
|
||||
- name: "Verify API for libkeymancore*.so (${{ steps.environment_step.outputs.GIT_BRANCH }}, branch ${{ steps.environment_step.outputs.GIT_BASE_BRANCH }}, by ${{ steps.environment_step.outputs.GIT_USER }})"
|
||||
if: steps.environment_step.outputs.SKIP_API_CHECK != 'true'
|
||||
run: |
|
||||
echo "Verify API for libkeymancore*.so (${{ steps.environment_step.outputs.GIT_BRANCH }}, branch ${{ steps.environment_step.outputs.GIT_BASE_BRANCH }}, by ${{ steps.environment_step.outputs.GIT_USER }}):" >> $GITHUB_STEP_SUMMARY
|
||||
|
||||
|
|
@ -79,17 +83,17 @@ jobs:
|
|||
verify 2>> $GITHUB_STEP_SUMMARY
|
||||
|
||||
- name: Archive .symbols file
|
||||
if: steps.environment_step.outputs.SKIP_API_CHECK != 'true' && always()
|
||||
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
|
||||
with:
|
||||
name: libkeymancore.symbols
|
||||
path: ${{ github.workspace }}/keyman/linux/debian/tmp/DEBIAN/symbols
|
||||
if: always()
|
||||
|
||||
set_status:
|
||||
name: Set result status on PR builds
|
||||
needs: [api_verification]
|
||||
runs-on: ubuntu-latest
|
||||
if: ${{ always() && needs.api_verification.outputs.IS_TEST_BUILD == 'true' }}
|
||||
if: ${{ always() && needs.api_verification.outputs.IS_TEST_BUILD == 'true' && needs.api_verification.outputs.SKIP_API_CHECK != 'true' }}
|
||||
steps:
|
||||
- name: Set success
|
||||
if: needs.api_verification.result == 'success'
|
||||
|
|
|
|||
|
|
@ -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 }}
|
||||
|
|
|
|||
79
.github/workflows/build-test-publish-docker.yml
vendored
Normal file
79
.github/workflows/build-test-publish-docker.yml
vendored
Normal file
|
|
@ -0,0 +1,79 @@
|
|||
# This workflow runs the build, test and publish steps for the
|
||||
# Keyman build Docker images.
|
||||
# It is triggered by a schedule and repository_dispatch event.
|
||||
|
||||
name: "Docker images: Build, publish and test "
|
||||
run-name: "Docker images: Build, publish and test (branch ${{ github.ref_name }} on ${{ github.event_name }}/${{ github.event.action }} by ${{ github.actor }})"
|
||||
defaults:
|
||||
run:
|
||||
shell: bash
|
||||
|
||||
on:
|
||||
schedule:
|
||||
#run every Fri, 3 pm UTC
|
||||
- cron: '0 15 * * 5'
|
||||
|
||||
repository_dispatch:
|
||||
types: ['build-test-publish-docker:*']
|
||||
|
||||
env:
|
||||
REGISTRY: ghcr.io
|
||||
USERNAME: "${{ github.actor }}"
|
||||
PASSWORD: "${{ secrets.KEYMAN_SERVER_REPO_ACCESS_PAT }}"
|
||||
|
||||
jobs:
|
||||
|
||||
message:
|
||||
name: Print message
|
||||
runs-on: ubuntu-latest
|
||||
if: ${{ github.event.act }}
|
||||
|
||||
steps:
|
||||
- name: Print message
|
||||
id: print-message
|
||||
run: |
|
||||
echo "Docker images: Build, publish and test (branch ${{ github.ref_name }} on ${{ github.event_name }}/${{ github.event.action }} by ${{ github.actor }})"
|
||||
|
||||
build:
|
||||
name: Build Docker images
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
id: checkout
|
||||
uses: actions/checkout@v4
|
||||
- name: Build Docker images
|
||||
id: build
|
||||
run: |
|
||||
if [ -z "${{ env.USERNAME }}" ]; then
|
||||
resources/docker-images/build.sh build: --registry ${{ env.REGISTRY }}
|
||||
else
|
||||
echo ${{ env.PASSWORD }} | resources/docker-images/build.sh build: --registry ${{ env.REGISTRY }} --username ${{ env.USERNAME }}
|
||||
fi
|
||||
- name: Publish Docker images
|
||||
id: publish
|
||||
run: |
|
||||
if [ -z "${{ env.USERNAME }}" ]; then
|
||||
resources/docker-images/build.sh publish: --registry ${{ env.REGISTRY }}
|
||||
else
|
||||
echo ${{ env.PASSWORD }} | resources/docker-images/build.sh publish: --registry ${{ env.REGISTRY }} --username ${{ env.USERNAME }}
|
||||
fi
|
||||
|
||||
test:
|
||||
name: Test Docker images
|
||||
runs-on: ubuntu-latest
|
||||
needs: build
|
||||
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
id: checkout
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Test Docker images
|
||||
id: test
|
||||
run: |
|
||||
if [ -z "${{ env.USERNAME }}" ]; then
|
||||
resources/docker-images/build.sh test: --registry ${{ env.REGISTRY }}
|
||||
else
|
||||
echo ${{ env.PASSWORD }} | resources/docker-images/build.sh test: --registry ${{ env.REGISTRY }} --username ${{ env.USERNAME }}
|
||||
fi
|
||||
45
.github/workflows/cleanup-ghcr.yml
vendored
Normal file
45
.github/workflows/cleanup-ghcr.yml
vendored
Normal file
|
|
@ -0,0 +1,45 @@
|
|||
# This workflow removes all untagged Docker images from the
|
||||
# GitHub Container Registry.
|
||||
# It is triggered by a schedule event or a manual workflow dispatch event.
|
||||
|
||||
name: "Docker images: Cleanup GitHub Container Registry"
|
||||
run-name: "Docker images: Cleanup GitHub Container Registry (branch ${{ github.ref_name }} on ${{ github.event_name }} by ${{ github.actor }})"
|
||||
defaults:
|
||||
run:
|
||||
shell: bash
|
||||
|
||||
on:
|
||||
|
||||
schedule:
|
||||
#run every Fri, 6 pm UTC
|
||||
- cron: '0 18 * * 5' #
|
||||
|
||||
workflow_dispatch:
|
||||
|
||||
|
||||
jobs:
|
||||
message:
|
||||
name: Print message
|
||||
runs-on: ubuntu-latest
|
||||
if: ${{ github.event.act }}
|
||||
|
||||
steps:
|
||||
- name: Print message
|
||||
id: print-message
|
||||
run: |
|
||||
echo "Docker images: Cleanup GitHub Container Registry (branch ${{ github.ref_name }} on ${{ github.event_name }} by ${{ github.actor }})"
|
||||
|
||||
cleanup-images:
|
||||
name: Cleanup GitHub Container Registry images
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- name: Removing all untagged images from GitHub Container Registry
|
||||
id: cleanup-ghcr
|
||||
uses: dataaxiom/ghcr-cleanup-action@cd0cdb900b5dbf3a6f2cc869f0dbb0b8211f50c4 # v1.0.16
|
||||
with:
|
||||
dry-run: false
|
||||
expand-packages: true
|
||||
packages: keyman-*-ci
|
||||
delete-untagged: true
|
||||
token: ${{ secrets.KEYMAN_SERVER_REPO_ACCESS_PAT }}
|
||||
6
.github/workflows/deb-packaging.README.md
vendored
6
.github/workflows/deb-packaging.README.md
vendored
|
|
@ -18,7 +18,8 @@ You can manually trigger a deb-packaging action on GitHub, e.g. to test changes:
|
|||
\"baseBranch\": \"master\",
|
||||
\"baseRef\": \"$(git rev-parse refs/heads/master^)\",
|
||||
\"user\": \"${USER}\",
|
||||
\"isTestBuild\": \"true\"}" \
|
||||
\"isTestBuild\": \"true\",
|
||||
\"force\": \"true\"}" \
|
||||
https://api.github.com/repos/<yourgithubname>/keyman/dispatches
|
||||
```
|
||||
|
||||
|
|
@ -36,6 +37,7 @@ You can manually trigger a deb-packaging action on GitHub, e.g. to test changes:
|
|||
\"baseBranch\": \"master\",
|
||||
\"baseRef\": \"$(git rev-parse refs/heads/master)\",
|
||||
\"user\": \"${USER}\",
|
||||
\"isTestBuild\": \"true\"}" \
|
||||
\"isTestBuild\": \"true\",
|
||||
\"force\": \"true\"}" \
|
||||
https://api.github.com/repos/<yourgithubname>/keyman/dispatches
|
||||
```
|
||||
|
|
|
|||
59
.github/workflows/deb-packaging.yml
vendored
59
.github/workflows/deb-packaging.yml
vendored
|
|
@ -23,6 +23,7 @@ on:
|
|||
# baseRef: The ref of the previous commit. For a PR the same as `baseBranch`.
|
||||
# user: The user that triggered the build or created the PR
|
||||
# isTestBuild: false for Releases, otherwise true
|
||||
# skipApiCheck: true to skip the API check, otherwise false
|
||||
|
||||
env:
|
||||
COLOR_GREEN: "\e[32m"
|
||||
|
|
@ -34,7 +35,7 @@ env:
|
|||
jobs:
|
||||
sourcepackage:
|
||||
name: Build source package
|
||||
if: github.repository == 'keymanapp/keyman'
|
||||
if: github.repository == 'keymanapp/keyman' || github.event.client_payload.force
|
||||
runs-on: ubuntu-24.04
|
||||
outputs:
|
||||
KEYMAN_VERSION: ${{ steps.version_step.outputs.KEYMAN_VERSION }}
|
||||
|
|
@ -86,7 +87,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
|
||||
|
|
@ -177,28 +185,36 @@ jobs:
|
|||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
# - name: Download Artifacts
|
||||
# uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4.3.0
|
||||
# with:
|
||||
# path: artifacts
|
||||
# merge-multiple: true
|
||||
- name: Download Source Artifacts
|
||||
uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4.3.0
|
||||
with:
|
||||
name: keyman-srcpkg
|
||||
path: artifacts
|
||||
|
||||
# - name: Install dependencies
|
||||
# run: |
|
||||
# sudo DEBIAN_FRONTEND=noninteractive apt-get -q -y install autopkgtest qemu-system qemu-utils autodep8 genisoimage python3-distro-info
|
||||
- name: Download Binary Artifacts
|
||||
uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4.3.0
|
||||
with:
|
||||
path: artifacts
|
||||
pattern: keyman-binarypkgs-*
|
||||
merge-multiple: true
|
||||
|
||||
# - name: Build test image
|
||||
# run: |
|
||||
# cd "${GITHUB_WORKSPACE}/artifacts"
|
||||
# autopkgtest-buildvm-ubuntu-cloud -v --release=jammy
|
||||
|
||||
# - name: Run tests
|
||||
# run: |
|
||||
# cd "${GITHUB_WORKSPACE}/artifacts"
|
||||
# autopkgtest -B *.deb keyman_*.dsc -- qemu autopkgtest-jammy-amd64.img
|
||||
- name: Ignore
|
||||
- name: Install dependencies
|
||||
run: |
|
||||
echo "Ignored for now - until working solution is in place (#13777)"
|
||||
sudo apt update
|
||||
sudo DEBIAN_FRONTEND=noninteractive apt-get -q -y install autopkgtest qemu-system qemu-utils autodep8 genisoimage python3-distro-info
|
||||
|
||||
- name: Build test image
|
||||
run: |
|
||||
cd "${GITHUB_WORKSPACE}/artifacts"
|
||||
sudo chown ${USER} /dev/kvm
|
||||
autopkgtest-buildvm-ubuntu-cloud -v --release=$(lsb_release -c -s)
|
||||
|
||||
- name: Run tests
|
||||
run: |
|
||||
# Tests are defined in linux/debian/tests/test-build
|
||||
cd "${GITHUB_WORKSPACE}/artifacts"
|
||||
DIST="$(lsb_release -c -s)"
|
||||
autopkgtest -B *${DIST}*.deb keyman_*.dsc -- qemu autopkgtest-${DIST}-amd64.img
|
||||
|
||||
deb_signing:
|
||||
name: Sign source and binary packages
|
||||
|
|
@ -325,6 +341,7 @@ jobs:
|
|||
echo "GIT_BRANCH=${{ github.event.client_payload.branch }}" >> artifacts/env
|
||||
echo "GIT_BASE_BRANCH=${{ github.event.client_payload.baseBranch }}" >> artifacts/env
|
||||
echo "GIT_USER=${{ github.event.client_payload.user }}" >> artifacts/env
|
||||
echo "SKIP_API_CHECK=${{ github.event.client_payload.skipApiCheck }}" >> artifacts/env
|
||||
|
||||
- name: Cache artifacts
|
||||
uses: actions/cache/save@5a3ec84eff668545956fd18022155c47e93e2684 # v4.2.3
|
||||
|
|
|
|||
60
.github/workflows/pr-build-status.yml
vendored
60
.github/workflows/pr-build-status.yml
vendored
|
|
@ -55,43 +55,61 @@ jobs:
|
|||
// check/web/file-size
|
||||
//
|
||||
|
||||
function addLog(message) {
|
||||
console.log(message);
|
||||
return message + String.fromCharCode(10);
|
||||
}
|
||||
|
||||
function addStatus(o, type, context, state) {
|
||||
if(!o[context]) {
|
||||
o[context] = {type, state};
|
||||
return addLog(`Found ${context}: ${state}`);
|
||||
} else {
|
||||
return addLog(`Skipping repeated ${context}: ${state}`);
|
||||
}
|
||||
}
|
||||
|
||||
function reduceStatuses(statuses) {
|
||||
let summary = '';
|
||||
const filtered_statuses = statuses.reduce((o, status) => {
|
||||
if(status.creator?.login == 'keyman-server' && status.context.startsWith('Test')) {
|
||||
if(!o[status.context]) o[status.context] = {type: 'build', state: status.state};
|
||||
summary += addStatus(o, 'build', status.context, status.state);
|
||||
} else if(status.creator?.login == 'keymanapp-test-bot[bot]' && status.context == 'user_testing') {
|
||||
if(!o[status.context]) o[status.context] = {type: 'user-test', state: status.state};;
|
||||
summary += addStatus(o, 'user-test', status.context, status.state);
|
||||
} else if(status.context == 'API Verification') {
|
||||
if(!o[status.context]) o[status.context] = {type: 'check', state: status.state};
|
||||
summary += addStatus(o, 'check', status.context, status.state);
|
||||
} else if(status.context == 'Ubuntu Packaging') {
|
||||
if(!o[status.context]) o[status.context] = {type: 'build', state: status.state};
|
||||
summary += addStatus(o, 'build', status.context, status.state);
|
||||
} else if(status.context == 'check/web/file-size') {
|
||||
// Ignore check/web/file-size -- we won't block automerge for this at this point
|
||||
summary += addLog(`Skipping ${status.context}`);
|
||||
} else {
|
||||
// We fail with an 'unknown status' response if we get a new status check
|
||||
// so we can be sure we are not skipping known status checks
|
||||
summary += addLog(`Found unknown ${status.context}: ${status.state}`);
|
||||
o[status.context] = {type: 'unknown', state: status.state};
|
||||
}
|
||||
return o;
|
||||
|
||||
}, {});
|
||||
return filtered_statuses;
|
||||
return { filtered_statuses, summary };
|
||||
}
|
||||
|
||||
//
|
||||
// Given the collection of status checks we care about, return
|
||||
// an aggregate status -- error, failed, pending, or success,
|
||||
// an aggregate status -- error, failure, pending, or success,
|
||||
// and a summary description
|
||||
//
|
||||
function calculateFinalStatus(filtered_statuses) {
|
||||
function calculateFinalStatus(filtered_statuses, summary) {
|
||||
const counts = {};
|
||||
let hasBuilds = false;
|
||||
for(const context of Object.keys(filtered_statuses)) {
|
||||
const { state, type } = filtered_statuses[context];
|
||||
if(type == 'unknown') {
|
||||
// We special-case for unknown status checks, and never permit them
|
||||
console.error(`An unknown context ${context} was found, cannot calculate build status.`);
|
||||
return [
|
||||
'error', `An unknown context ${context} was found, cannot calculate build status.`
|
||||
'error', `An unknown context ${context} was found, cannot calculate build status.`, summary
|
||||
];
|
||||
}
|
||||
if(type == 'build') {
|
||||
|
|
@ -102,12 +120,13 @@ jobs:
|
|||
|
||||
// If we do not have any statuses yet, we wait
|
||||
if(Object.keys(filtered_statuses).length == 0 || !hasBuilds) {
|
||||
return ['pending', 'Builds have not yet been triggered ⌛'];
|
||||
console.log(`Builds not yet triggered`);
|
||||
return ['pending', 'Builds have not yet been triggered ⌛', summary];
|
||||
}
|
||||
|
||||
const state =
|
||||
counts.error ? 'error' :
|
||||
counts.failed ? 'failed' :
|
||||
counts.failure ? 'failure' :
|
||||
counts.pending ? 'pending' :
|
||||
'success';
|
||||
|
||||
|
|
@ -118,14 +137,16 @@ jobs:
|
|||
description += `${count} check${count == 1 ? '' : 's'} ${state}`;
|
||||
}
|
||||
appendDescription(counts.error, 'in an error state ❌');
|
||||
appendDescription(counts.failed, 'failed ❌');
|
||||
appendDescription(counts.failure, 'failed ❌');
|
||||
appendDescription(counts.pending, 'pending ⌛');
|
||||
appendDescription(counts.success, 'completed successfully ✅');
|
||||
|
||||
return [ state, description ];
|
||||
console.log(`Finished filtering and reviewing status checks: ${state}: ${description}`);
|
||||
return [ state, description, summary ];
|
||||
}
|
||||
|
||||
async function getCommitStatuses(github, owner, repo, sha) {
|
||||
console.log(`Getting commit statuses for ${sha}`);
|
||||
const statuses = await github.paginate('GET /repos/{owner}/{repo}/commits/{sha}/statuses', {
|
||||
owner,
|
||||
repo,
|
||||
|
|
@ -138,6 +159,7 @@ jobs:
|
|||
}
|
||||
|
||||
async function getCommitCheckRuns(github, owner, repo, sha) {
|
||||
console.log(`Getting commit check runs for ${sha}`);
|
||||
const statuses = await github.paginate('GET /repos/{owner}/{repo}/commits/{sha}/check-runs', {
|
||||
owner,
|
||||
repo,
|
||||
|
|
@ -151,13 +173,11 @@ jobs:
|
|||
|
||||
function calculateCheckResult(statuses) {
|
||||
if(!Array.isArray(statuses)) {
|
||||
return ['error', 'Failed to retrieve status checks from GitHub ❌'];
|
||||
return ['error', 'Failed to retrieve status checks from GitHub ❌', 'statuses is not an array'];
|
||||
}
|
||||
|
||||
const filtered_statuses = reduceStatuses(statuses);
|
||||
|
||||
const result = calculateFinalStatus(filtered_statuses);
|
||||
return result;
|
||||
const { filtered_statuses, summary } = reduceStatuses(statuses);
|
||||
return calculateFinalStatus(filtered_statuses, summary);
|
||||
}
|
||||
|
||||
async function test(github, owner, repo, sha) {
|
||||
|
|
@ -177,7 +197,7 @@ jobs:
|
|||
return check.data.id;
|
||||
}
|
||||
|
||||
async function updateCheck(github, owner, repo, checkRunId, status, description) {
|
||||
async function updateCheck(github, owner, repo, checkRunId, status, description, summary) {
|
||||
const checkStatus = status == 'pending' ? 'in_progress' : 'completed';
|
||||
const conclusion = checkStatus == 'in_progress' ? undefined : (status == 'success' ? 'success' : 'failure');
|
||||
|
||||
|
|
@ -189,7 +209,7 @@ jobs:
|
|||
conclusion,
|
||||
output: {
|
||||
title: description,
|
||||
summary: ''
|
||||
summary
|
||||
}
|
||||
});
|
||||
}
|
||||
|
|
@ -204,5 +224,5 @@ jobs:
|
|||
|
||||
const checkRunId = await createCheck(github, owner, repo, sha);
|
||||
const res = await test(github, owner, repo, sha);
|
||||
await updateCheck(github, owner, repo, checkRunId, res[0], res[1]);
|
||||
await updateCheck(github, owner, repo, checkRunId, res[0], res[1], res[2]);
|
||||
|
||||
|
|
|
|||
6
.gitignore
vendored
6
.gitignore
vendored
|
|
@ -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
|
||||
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
external-sources=true
|
||||
|
||||
# If you get SC1091 for sourced files, add the following setting to
|
||||
# your .vscode/settings.json file:
|
||||
# "shellcheck.useWorkspaceRootAsCwd": false
|
||||
source-path=resources/build/
|
||||
source-path=resources/
|
||||
source-path=SCRIPTDIR
|
||||
source-path=linux/ibus-keyman/tests/scripts/
|
||||
|
|
|
|||
290
HISTORY.md
290
HISTORY.md
|
|
@ -1,5 +1,258 @@
|
|||
# Keyman Version History
|
||||
|
||||
## 19.0.128 alpha 2025-09-26
|
||||
|
||||
* fix(windows): sort setup UI language selector according to language names (#13573)
|
||||
* feat(windows): improve startup time by caching locale names (#14795)
|
||||
|
||||
## 19.0.127 alpha 2025-09-25
|
||||
|
||||
* fix(common): registry clean-up enabled, no terminal in github action (#14824)
|
||||
* maint(windows): check code signatures only in CI builds (#14815)
|
||||
* chore(deps-dev): bump tar-fs from 3.0.9 to 3.1.1 (#14827)
|
||||
* fix(windows): disable MSI shortcut advertisement (#14814)
|
||||
* maint(resources): lookup 7z on path on Windows if SEVENZ_HOME is not set (#14816)
|
||||
* fix(android): Apply bottom insets to system keyboard (#14808)
|
||||
* fix(android): Fix bottom insets for Sample and FirstVoices apps (#14828)
|
||||
* docs(android): Document getNavigationBarHeight API (#14830)
|
||||
|
||||
## 19.0.126 alpha 2025-09-24
|
||||
|
||||
* maint(linux): remove several shellcheck directives (#14819)
|
||||
|
||||
## 19.0.125 alpha 2025-09-23
|
||||
|
||||
* fix(common): some more tests running successfully in a container (#14784)
|
||||
|
||||
## 19.0.124 alpha 2025-09-22
|
||||
|
||||
* maint(linux): improve `upload-to-debian` script (#14798)
|
||||
* refactor(linux): remove a meson deprecation warning (#14801)
|
||||
* refactor(linux): remove shellcheck warnings (#14802)
|
||||
* refactor(resources): use array for Docker arguments (#14803)
|
||||
|
||||
## 19.0.123 alpha 2025-09-19
|
||||
|
||||
* chore(linux): Update debian changelog (#14783)
|
||||
|
||||
## 19.0.122 alpha 2025-09-18
|
||||
|
||||
* fix(android): Refresh the banner theme when system keyboard is changed (#14768)
|
||||
* maint(common): update HISTORY.md for 18.0.241 (#14780)
|
||||
|
||||
## 19.0.121 alpha 2025-09-17
|
||||
|
||||
* docs(developer): document `fileVersion` (#14766)
|
||||
* maint(linux): allow to force package build on non-Keyman repo (#14749)
|
||||
* feat(linux): add breadcrumbs and system information to Sentry error reports (#14765)
|
||||
* maint(resources): fix broken test build trigger for `master` branch (#14770)
|
||||
* chore(linux): remove automatic installation of `onboard-keyman` (#14772)
|
||||
|
||||
## 19.0.120 alpha 2025-09-16
|
||||
|
||||
* refactor(linux): remove warning (#14761)
|
||||
* fix(linux): don't crash on invalid languages in keyboard (#14760)
|
||||
|
||||
## 19.0.119 alpha 2025-09-15
|
||||
|
||||
* fix(developer): transform slashes to backslashes in paths in Package Editor (#14721)
|
||||
* fix(developer): restrict invalid characters in identifiers in kmcmplib (#14746)
|
||||
* fix(common): add name for cleanup ghcr (#14755)
|
||||
|
||||
## 19.0.118 alpha 2025-09-12
|
||||
|
||||
* chore(common): Update to Unicode 17.0 (#14728)
|
||||
* fix(resources): match cr to lf change in pr-build-status.mjs (#14734)
|
||||
* fix(common): merging build and publish step for docker (#14747)
|
||||
* chore(developer): use icons.res to verify that configure is done (#14733)
|
||||
|
||||
## 19.0.117 alpha 2025-09-11
|
||||
|
||||
* fix(resources): ignore KEYMAN_VERSION_FOR_FILENAME in test (#14730)
|
||||
* fix(resources): pr build status - find 'failure' state in status checks and log (#14732)
|
||||
|
||||
## 19.0.116 alpha 2025-09-10
|
||||
|
||||
* fix(windows): kmshell continues when sm is in waitingrestart and returns to idle (#14644)
|
||||
* maint(linux): allow to skip API check (#14699)
|
||||
* maint(resources): adding GitHub actions workflow for Docker builds (#14674)
|
||||
* maint(developer): use versioned filenames for PR artifacts (#14701)
|
||||
* maint(windows): use versioned filenames for PR artifacts (#14702)
|
||||
* maint(android): use versioned filenames for PR artifacts (#14703)
|
||||
* maint(ios): use versioned filenames for PR artifacts (#14704)
|
||||
* maint(mac): use versioned filenames for PR artifacts (#14705)
|
||||
* maint(resources): rename KEYMAN_VERSION_FOR_PR_FILENAME (#14720)
|
||||
|
||||
## 19.0.115 alpha 2025-09-09
|
||||
|
||||
* fix(linux): don't crash if `kmp.json` is missing `keyboards` section (#14708)
|
||||
|
||||
## 19.0.114 alpha 2025-09-08
|
||||
|
||||
* docs(web): Improve empty What's New page for Web (#14660)
|
||||
* maint(linux): remove obsolete Makefile (#14694)
|
||||
* maint(resources): honor configure comment character in commit message (#14695)
|
||||
* fix(web): fix error trying to calculate style scaling effects (#14684)
|
||||
* refactor(resources): remove shellcheck warnings (#14698)
|
||||
|
||||
## 19.0.113 alpha 2025-09-04
|
||||
|
||||
* fix(android): Update KMSample1 layout when changing orientation (#14678)
|
||||
|
||||
## 19.0.112 alpha 2025-09-03
|
||||
|
||||
* fix(developer): add clear messages about validation failures to New LM Project Parameters form (#14659)
|
||||
* docs(developer): tweak get-started for kmc and add entry to HISTORY.md (#14667)
|
||||
* fix(android): Cleanup list layout in Engine and FirstVoices for edge to edge (#14655)
|
||||
* docs(common): update license date and owner (#14668)
|
||||
* maint(linux): skip tarball creation for `Build-bot: build` buildLevel (#14671)
|
||||
* docs(common): update docs Keyman Desktop → Keyman for Windows (#14669)
|
||||
* feat(web): adds transform cataloging methods to predictive-text worker (#14581)
|
||||
* feat(web): batch correction-search paths by related subsets (#14592)
|
||||
* refactor(web): simplify edit-distance calculation-object inputs (#14618)
|
||||
|
||||
## 19.0.111 alpha 2025-09-02
|
||||
|
||||
* change(developer): update SIL logo (#14656)
|
||||
* fix(developer): remove incorrect offset for compiler error line (#14651)
|
||||
* fix(developer): add clear messages about validation failures to New Project Parameters form (#14657)
|
||||
* fix(developer): add clear messages about validation failures to New LDML Project Parameters form (#14658)
|
||||
* maint: add registry usage for Docker images (#14648)
|
||||
|
||||
## 19.0.110 alpha 2025-09-01
|
||||
|
||||
* maint(windows): for `build` buildlevel, do not publish artifacts (#14654)
|
||||
* maint(linux): generate tar-ignore in `dist.sh` (#14639)
|
||||
* fix: fixing some issues for bulding and testing with Docker containers (#14645)
|
||||
* maint(linux): create temporary worktree for packaging (#14598)
|
||||
|
||||
## 19.0.109 alpha 2025-08-31
|
||||
|
||||
* fix(developer): handle missing model id in package with compiler error (#14649)
|
||||
* fix(developer): handle failure to create destination path when generating new project (#14650)
|
||||
|
||||
## 19.0.108 alpha 2025-08-29
|
||||
|
||||
* fix(android): Fix insets for in-app vs system keyboard (#14619)
|
||||
* maint(resources): ensure REPO_ROOT is fully resolved (#14643)
|
||||
|
||||
## 19.0.107 alpha 2025-08-28
|
||||
|
||||
* maint(resources): fix parse bug in build-bot and add extra logging (#14611)
|
||||
* fix(android): Update Gradle files to remove flatDir warnings (#14583)
|
||||
* maint(resources): move build trigger scripts into resources/teamcity (#14607)
|
||||
* chore(linux): Update debian changelog (#14590)
|
||||
* docs: update package-editor page section details tab (#14585)
|
||||
* fix(android): polyfill globalThis for API 28 devices (#14541)
|
||||
* feat: support pagination in build bot PR commit reading (#14638)
|
||||
* refactor(linux): remove shellcheck warnings and reformat (#14572)
|
||||
|
||||
## 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)
|
||||
|
||||
## 19.0.93 alpha 2025-07-29
|
||||
|
||||
* test(developer): add unit tests for `isValidUtf8` (#14381)
|
||||
* maint(linux): fix stopping of test server (#14403)
|
||||
|
||||
## 19.0.92 alpha 2025-07-28
|
||||
|
||||
* build(deps): bump multer from 2.0.1 to 2.0.2 (#14373)
|
||||
* refactor(linux): remove shellcheck warnings (#14409)
|
||||
* refactor(linux): move dbus defines to common include (#14407)
|
||||
* docs(linux): update readme for test service (#14408)
|
||||
* fix(windows): add check a fix for registry datatypes (#14358)
|
||||
|
||||
## 19.0.91 alpha 2025-07-26
|
||||
|
||||
* maint(windows): fix calls of renamed functions (#14413)
|
||||
|
|
@ -557,6 +810,43 @@
|
|||
* refactor(windows): rename `TKeymanMutex.MutexOwned` to `TakeOwnership` and add `ReleaseOwnership` (#13168)
|
||||
* chore: increment to alpha 19.0 (#13187)
|
||||
|
||||
## 18.0.241 stable 2025-09-18
|
||||
|
||||
* maint(resources): use correct version for PR title for history cherry-pick (#14614)
|
||||
* chore(linux): Update debian changelog (#14589)
|
||||
* fix(android): Update: Android Target API to 35, Java to 21, and Gradle dependencies (#14584)
|
||||
* fix(android): Convert Keyman app layouts for edge to edge (#14597)
|
||||
* fix(android): Fix insets for in-app vs system keyboard (#14642)
|
||||
* maint(linux): create temporary worktree for packaging (#14599)
|
||||
* fix(android): Cleanup layouts for Engine, Sample apps, and FirstVoices apps for edge to edge (#14663)
|
||||
* fix(web): fix error trying to calculate style scaling effects (#14696)
|
||||
* fix(linux): don't crash if `kmp.json` is missing `keyboards` section (#14714)
|
||||
* fix(developer): transform slashes to backslashes in paths in Package Editor (#14722)
|
||||
* chore(linux): remove automatic installation of `onboard-keyman` (#14773)
|
||||
* docs(linux): update release notes for stable release (#14774)
|
||||
* fix(linux): don't crash on invalid languages in keyboard (#14771)
|
||||
|
||||
## 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(windows): fix download failing when cache.json missing (#14207)
|
||||
* 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)
|
||||
|
|
|
|||
|
|
@ -1 +1 @@
|
|||
19.0.92
|
||||
19.0.129
|
||||
|
|
@ -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'
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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,9 +40,13 @@ 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 \
|
||||
build /android/KMAPro/kMAPro/build/outputs/apk/$CONFIG/keyman-${KEYMAN_VERSION}.apk
|
||||
configure "/${MODELS_TARGET}" \
|
||||
build /android/KMAPro/kMAPro/build/outputs/apk/$CONFIG/keyman-${KEYMAN_VERSION_FOR_FILENAME}.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,7 +76,7 @@ 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
|
||||
|
|
@ -98,9 +84,7 @@ if builder_start_action build; then
|
|||
echo "BUILD_FLAGS $BUILD_FLAGS"
|
||||
./gradlew $DAEMON_FLAG clean $BUILD_FLAGS
|
||||
|
||||
if builder_has_option --upload-sentry; then
|
||||
makeLocalSentryRelease
|
||||
fi
|
||||
mv "${KEYMAN_ROOT}/android/KMAPro/kMAPro/build/outputs/apk/$CONFIG/keyman-${KEYMAN_VERSION}.apk" "${KEYMAN_ROOT}/android/KMAPro/kMAPro/build/outputs/apk/$CONFIG/keyman-${KEYMAN_VERSION_FOR_FILENAME}.apk"
|
||||
|
||||
builder_finish_action success build
|
||||
fi
|
||||
|
|
@ -113,12 +97,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
|
||||
|
|
|
|||
|
|
@ -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"
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
@ -125,8 +124,9 @@ public class SystemKeyboard extends InputMethodService implements OnKeyboardEven
|
|||
}
|
||||
|
||||
ViewGroup parent = (ViewGroup) inputView.getParent();
|
||||
if (parent != null)
|
||||
if (parent != null) {
|
||||
parent.removeView(inputView);
|
||||
}
|
||||
|
||||
return inputView;
|
||||
}
|
||||
|
|
@ -246,9 +246,10 @@ public class SystemKeyboard extends InputMethodService implements OnKeyboardEven
|
|||
inputViewHeight = inputView.getHeight();
|
||||
}
|
||||
|
||||
int navigationHeight = KMManager.getNavigationBarHeight(this);
|
||||
int bannerHeight = KMManager.getBannerHeight(this);
|
||||
int kbHeight = KMManager.getKeyboardHeight(this);
|
||||
outInsets.contentTopInsets = inputViewHeight - bannerHeight - kbHeight;
|
||||
outInsets.contentTopInsets = inputViewHeight - bannerHeight - kbHeight - navigationHeight;
|
||||
outInsets.visibleTopInsets = outInsets.contentTopInsets;
|
||||
outInsets.touchableInsets = InputMethodService.Insets.TOUCHABLE_INSETS_REGION;
|
||||
outInsets.touchableRegion.set(0, outInsets.contentTopInsets, size.x, size.y);
|
||||
|
|
@ -264,6 +265,8 @@ public class SystemKeyboard extends InputMethodService implements OnKeyboardEven
|
|||
|
||||
@Override
|
||||
public void onKeyboardChanged(String newKeyboard) {
|
||||
// Refresh banner theme
|
||||
BannerController.setHTMLBanner(this, KeyboardType.KEYBOARD_TYPE_SYSTEM);
|
||||
KMManager.showSystemKeyboard();
|
||||
}
|
||||
|
||||
|
|
@ -278,6 +281,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
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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() {
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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";
|
||||
}
|
||||
|
|
@ -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");
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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>
|
||||
|
|
|
|||
|
|
@ -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>
|
||||
|
|
|
|||
|
|
@ -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>
|
||||
|
|
|
|||
|
|
@ -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>
|
||||
|
|
|
|||
|
|
@ -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>
|
||||
|
|
|
|||
|
|
@ -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>
|
||||
|
|
|
|||
|
|
@ -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>
|
||||
|
|
|
|||
|
|
@ -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>
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -14,4 +14,10 @@ if(!Array.prototype.includes){
|
|||
Array.prototype.includes = function(search){
|
||||
return !!~this.indexOf(search);
|
||||
}
|
||||
}
|
||||
|
||||
// This file is only referenced by the main Web engine; its "global" object is `window`.
|
||||
// `globalThis` is defined in Chrome 71+.
|
||||
if(typeof globalThis == 'undefined') {
|
||||
var globalThis = window;
|
||||
}
|
||||
|
|
@ -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());
|
||||
|
||||
view.setPadding(
|
||||
insets.left,
|
||||
insets.top,
|
||||
insets.right,
|
||||
insets.bottom);
|
||||
|
||||
KMManager.applyInsetsToKeyboard(
|
||||
KMManager.KeyboardType.KEYBOARD_TYPE_INAPP, insets.left, insets.right, insets.bottom);
|
||||
return windowInsets;
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 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);
|
||||
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
|
||||
WindowInsetsControllerCompat windowInsetsController =
|
||||
WindowCompat.getInsetsController(window, window.getDecorView());
|
||||
windowInsetsController.setAppearanceLightStatusBars(true);
|
||||
|
||||
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.VANILLA_ICE_CREAM) {
|
||||
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
|
||||
|
|
|
|||
|
|
@ -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 = "";
|
||||
|
|
|
|||
|
|
@ -52,6 +52,9 @@ import android.widget.FrameLayout;
|
|||
import android.widget.RelativeLayout;
|
||||
|
||||
import androidx.core.content.ContextCompat;
|
||||
import androidx.core.graphics.Insets;
|
||||
import androidx.core.view.ViewCompat;
|
||||
import androidx.core.view.WindowInsetsCompat;
|
||||
|
||||
import io.sentry.Breadcrumb;
|
||||
import io.sentry.Sentry;
|
||||
|
|
@ -495,6 +498,11 @@ public final class KMManager {
|
|||
didCopyAssets = true;
|
||||
}
|
||||
|
||||
calculateDefaultKeyboardHeights(context);
|
||||
SharedPreferences prefs = context.getSharedPreferences(KMManager.KMEngine_PrefsKey, Context.MODE_PRIVATE);
|
||||
KeyboardHeight_Context_Portrait_Current = prefs.getInt(KMManager.KMKey_KeyboardHeightPortrait, KMManager.KeyboardHeight_Context_Portrait_Default);
|
||||
KeyboardHeight_Context_Landscape_Current = prefs.getInt(KMManager.KMKey_KeyboardHeightLandscape, KMManager.KeyboardHeight_Context_Landscape_Default);
|
||||
|
||||
if (keyboardType == KeyboardType.KEYBOARD_TYPE_UNDEFINED) {
|
||||
String msg = "Cannot initialize: Invalid keyboard type";
|
||||
KMLog.LogError(TAG, msg);
|
||||
|
|
@ -508,12 +516,6 @@ public final class KMManager {
|
|||
migrateCloudKeyboards(appContext);
|
||||
|
||||
CloudDownloadMgr.getInstance().initialize(appContext);
|
||||
|
||||
calculateDefaultKeyboardHeights(context);
|
||||
SharedPreferences prefs = context.getSharedPreferences(KMManager.KMEngine_PrefsKey, Context.MODE_PRIVATE);
|
||||
KeyboardHeight_Context_Portrait_Current = prefs.getInt(KMManager.KMKey_KeyboardHeightPortrait, KMManager.KeyboardHeight_Context_Portrait_Default);
|
||||
KeyboardHeight_Context_Landscape_Current = prefs.getInt(KMManager.KMKey_KeyboardHeightLandscape, KMManager.KeyboardHeight_Context_Landscape_Default);
|
||||
|
||||
}
|
||||
|
||||
public static void executeResourceUpdate(Context aContext)
|
||||
|
|
@ -692,15 +694,66 @@ 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 {KeyboardType} keyboard
|
||||
* @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(KeyboardType keyboardType, int left, int right, int bottom) {
|
||||
if (keyboardType == KeyboardType.KEYBOARD_TYPE_INAPP && InAppKeyboard != null) {
|
||||
applyInsetsPaddingToKeyboardView(InAppKeyboard, left, right, bottom);
|
||||
}
|
||||
|
||||
if (keyboardType == KeyboardType.KEYBOARD_TYPE_SYSTEM && SystemKeyboard != null) {
|
||||
applyInsetsPaddingToKeyboardView(SystemKeyboard, left, right, bottom);
|
||||
}
|
||||
}
|
||||
|
||||
private static void applyInsetsPaddingToKeyboardView(KMKeyboard keyboard, int left, int right, int bottom) {
|
||||
View parent = (View) keyboard.getParent();
|
||||
|
||||
if (keyboard.keyboardType == KeyboardType.KEYBOARD_TYPE_INAPP && 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) {
|
||||
|
|
@ -841,6 +894,25 @@ public final class KMManager {
|
|||
return mainLayout;
|
||||
}
|
||||
|
||||
if (mainLayout != null) {
|
||||
// Update insets
|
||||
ViewCompat.setOnApplyWindowInsetsListener(mainLayout,
|
||||
(view, windowInsets) -> {
|
||||
// Allocate insets for system bars and display cutout (notch)
|
||||
Insets insets = windowInsets.getInsets(
|
||||
WindowInsetsCompat.Type.systemBars() | WindowInsetsCompat.Type.displayCutout());
|
||||
|
||||
view.setPadding(
|
||||
insets.left,
|
||||
insets.top,
|
||||
insets.right,
|
||||
insets.bottom);
|
||||
|
||||
applyInsetsToKeyboard(KeyboardType.KEYBOARD_TYPE_SYSTEM, insets.left, insets.right, insets.bottom);
|
||||
return windowInsets;
|
||||
});
|
||||
}
|
||||
|
||||
RelativeLayout keyboardLayout = new RelativeLayout(appContext);
|
||||
keyboardLayout.setLayoutParams(new FrameLayout.LayoutParams(FrameLayout.LayoutParams.MATCH_PARENT, FrameLayout.LayoutParams.MATCH_PARENT));
|
||||
ViewGroup parent = (ViewGroup) SystemKeyboard.getParent();
|
||||
|
|
@ -2421,6 +2493,25 @@ public final class KMManager {
|
|||
KeyboardHeight_Context_Landscape_Default = (int) newResources.getDimension(R.dimen.keyboard_height);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the navigation bar height (if visible) in pixels
|
||||
* @param context - the context
|
||||
* @return int - navigation bar height in pixels
|
||||
*/
|
||||
public 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+
|
||||
|
|
|
|||
|
|
@ -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>
|
||||
|
|
|
|||
|
|
@ -1,13 +1,22 @@
|
|||
<?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"
|
||||
android:id="@+id/list_appbar"
|
||||
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>
|
||||
|
|
|
|||
|
|
@ -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>
|
||||
|
|
|
|||
|
|
@ -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>
|
||||
|
|
|
|||
|
|
@ -1,15 +1,20 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
<RelativeLayout
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent" >
|
||||
|
||||
|
||||
<!-- paddingBottom so last entry doesn't get covered by navigation bar -->
|
||||
<ListView
|
||||
style="@style/AppTheme.Light.ListView"
|
||||
android:id="@+id/listView"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:choiceMode="singleChoice"
|
||||
android:clipToPadding="false" />
|
||||
android:clipToPadding="false"
|
||||
android:paddingBottom="?attr/actionBarSize"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"/>
|
||||
|
||||
</RelativeLayout>
|
||||
|
|
|
|||
|
|
@ -1,16 +1,20 @@
|
|||
<com.google.android.material.appbar.AppBarLayout
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<com.google.android.material.appbar.AppBarLayout
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
android:id="@+id/list_appbar"
|
||||
app:theme="@style/AppTheme.ToolbarBackArrow"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:elevation="0dp">
|
||||
|
||||
<androidx.appcompat.widget.Toolbar
|
||||
android:id="@+id/list_toolbar"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="?attr/actionBarSize">
|
||||
android:layout_height="wrap_content"
|
||||
app:layout_constraintTop_toTopOf="parent">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/bar_title"
|
||||
|
|
@ -32,6 +36,8 @@
|
|||
style="@style/AppTheme.Divider"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="2dp"
|
||||
android:layout_alignParentBottom="true"/>
|
||||
app:layout_constraintTop_toBottomOf="@id/list_toolbar"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent" />
|
||||
|
||||
</com.google.android.material.appbar.AppBarLayout>
|
||||
|
|
|
|||
|
|
@ -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"
|
||||
|
|
|
|||
|
|
@ -83,13 +83,13 @@
|
|||
<!-- Context: Fatal keyboard error. -->
|
||||
<string name="fatal_keyboard_error_short" comment="Error in keyboard (keyboard ID::packageID for language)."> Error en el teclado %1$s:%2$s para %3$s idioma.</string>
|
||||
<!-- Context: Alert Dialog body: System WebView not installed -->
|
||||
<string name="body_install_webview" comment="Notification when WebView not installed"> Keyman requires WebView to be installed.\"</string>
|
||||
<string name="body_install_webview" comment="Notification when WebView not installed"> Keyman requiere que WebView esté instalado.\"</string>
|
||||
<!-- Context: Alert Dialog body: System WebView installed but not enabled -->
|
||||
<string name="body_enable_webview" comment="Notification when WebView installed but not enabled"> Keyman requires WebView to be enabled.\"</string>
|
||||
<string name="body_enable_webview" comment="Notification when WebView installed but not enabled"> Keyman requiere que WebView esté habilitado.\"</string>
|
||||
<!-- Context Button label: Install WebView -->
|
||||
<string name="label_install_webview" comment="Button label to install webview">Install WebView</string>
|
||||
<string name="label_install_webview" comment="Button label to install webview">Instalar WebView</string>
|
||||
<!-- Context Button label: Enable WebView -->
|
||||
<string name="label_enable_webview" comment="Button label to enable webview">Enable WebView</string>
|
||||
<string name="label_enable_webview" comment="Button label to enable webview">Habilitar WebView</string>
|
||||
<!-- Context: Query for associated dictionary -->
|
||||
<string name="query_associated_model" comment="Check if there's an available dictionary to download">Comprobando si hay un diccionario asociado para descargar</string>
|
||||
<string name="cannot_query_associated_model" comment="Cannot reach server to check if there's an available dictionary to download"> No se puede conectar al servidor Keyman para comprobar si hay un diccionario asociado para descargar</string>
|
||||
|
|
@ -124,7 +124,7 @@
|
|||
<!-- Context: General Updates -->
|
||||
<string name="update_check_unavailable" comment="Error message when a Keyman server can't be reached">¡Falló al acceder al servidor!</string>
|
||||
<!-- Context: Update-check failure notification -->
|
||||
<string name="update_check_download_manager_disabled" comment="Notification that a system service needed for updates is disabled">DownloadManager disabled - cannot check for updates</string>
|
||||
<string name="update_check_download_manager_disabled" comment="Notification that a system service needed for updates is disabled">Descargador deshabilitado: no se pueden comprobar actualizaciones</string>
|
||||
<!-- Context: General Updates -->
|
||||
<string name="update_check_current" comment="Notification that all resources are up to date">"¡Todos los recursos están actualizados!"</string>
|
||||
<!-- Context: General Updates -->
|
||||
|
|
|
|||
|
|
@ -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'
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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 ################################
|
||||
|
||||
|
|
|
|||
|
|
@ -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'
|
||||
|
|
|
|||
|
|
@ -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'
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,13 +1,16 @@
|
|||
package com.keyman.kmsample1;
|
||||
|
||||
import androidx.appcompat.app.AppCompatActivity;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.res.Configuration;
|
||||
import android.graphics.Point;
|
||||
import android.os.Bundle;
|
||||
import android.util.TypedValue;
|
||||
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,10 +22,12 @@ 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;
|
||||
private int lastOrientation = Configuration.ORIENTATION_UNDEFINED;
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
|
|
@ -34,6 +39,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
|
||||
|
|
@ -91,6 +102,18 @@ public class MainActivity extends AppCompatActivity implements OnKeyboardEventLi
|
|||
protected void onResume() {
|
||||
super.onResume();
|
||||
KMManager.onResume();
|
||||
|
||||
// onConfigurationChanged() only triggers when device is rotated while app is in foreground
|
||||
// This handles when device is rotated while app is in background
|
||||
// using KMManager.getOrientation() since getConfiguration().orientation is unreliable #10241
|
||||
int newOrientation = KMManager.getOrientation(context);
|
||||
if (newOrientation != lastOrientation) {
|
||||
lastOrientation = newOrientation;
|
||||
Configuration newConfig = this.getResources().getConfiguration();
|
||||
KMManager.onConfigurationChanged(newConfig);
|
||||
}
|
||||
resizeTextView(textView.isKeyboardVisible());
|
||||
|
||||
KMManager.addKeyboardEventListener(this);
|
||||
KMKeyboardDownloaderActivity.addKeyboardDownloadEventListener(this);
|
||||
}
|
||||
|
|
@ -108,6 +131,10 @@ public class MainActivity extends AppCompatActivity implements OnKeyboardEventLi
|
|||
@Override
|
||||
public void onConfigurationChanged(Configuration newConfig) {
|
||||
super.onConfigurationChanged(newConfig);
|
||||
KMManager.onConfigurationChanged(newConfig);
|
||||
|
||||
resizeTextView(textView.isKeyboardVisible());
|
||||
lastOrientation = newConfig.orientation;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
@ -123,11 +150,44 @@ public class MainActivity extends AppCompatActivity implements OnKeyboardEventLi
|
|||
@Override
|
||||
public void onKeyboardShown() {
|
||||
// Handle Keyman keyboard shown event here if needed
|
||||
resizeTextView(true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onKeyboardDismissed() {
|
||||
// Handle Keyman keyboard dismissed event here if needed
|
||||
resizeTextView(false);
|
||||
}
|
||||
|
||||
public void resizeTextView(boolean isKeyboardVisible) {
|
||||
int bannerHeight = 0;
|
||||
int keyboardHeight = 0;
|
||||
if (isKeyboardVisible) {
|
||||
bannerHeight = KMManager.getBannerHeight(this);
|
||||
keyboardHeight = KMManager.getKeyboardHeight(this);
|
||||
}
|
||||
|
||||
TypedValue outValue = new TypedValue();
|
||||
getTheme().resolveAttribute(android.R.attr.actionBarSize, outValue, true);
|
||||
int actionBarHeight = getResources().getDimensionPixelSize(outValue.resourceId);
|
||||
|
||||
// *** TO DO: Try to check if status bar is visible, set statusBarHeight to 0 if it is not visible ***
|
||||
int statusBarHeight = 0;
|
||||
int resourceId = getResources().getIdentifier("status_bar_height", "dimen", "android");
|
||||
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;
|
||||
textView.setHeight(
|
||||
screenHeight - statusBarHeight - actionBarHeight - bannerHeight - keyboardHeight - navigationBarHeight);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
|||
|
|
@ -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>
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -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'
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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() {
|
||||
|
|
|
|||
|
|
@ -184,12 +184,14 @@ public class SystemKeyboard extends InputMethodService implements OnKeyboardEven
|
|||
Point size = KMManager.getWindowSize(getApplicationContext());
|
||||
|
||||
int inputViewHeight = 0;
|
||||
if (inputView != null)
|
||||
if (inputView != null) {
|
||||
inputViewHeight = inputView.getHeight();
|
||||
}
|
||||
|
||||
int navigationHeight = KMManager.getNavigationBarHeight(this);
|
||||
int bannerHeight = KMManager.getBannerHeight(this);
|
||||
int kbHeight = KMManager.getKeyboardHeight(this);
|
||||
outInsets.contentTopInsets = inputViewHeight - bannerHeight - kbHeight;
|
||||
outInsets.contentTopInsets = inputViewHeight - bannerHeight - kbHeight - navigationHeight;
|
||||
outInsets.visibleTopInsets = outInsets.contentTopInsets;
|
||||
outInsets.touchableInsets = InputMethodService.Insets.TOUCHABLE_INSETS_REGION;
|
||||
outInsets.touchableRegion.set(0, outInsets.contentTopInsets, size.x, size.y);
|
||||
|
|
@ -215,6 +217,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) {
|
||||
|
|
|
|||
|
|
@ -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>
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -5,8 +5,14 @@ plugins {
|
|||
ext.rootPath = '../../../'
|
||||
apply from: "$rootPath/version.gradle"
|
||||
|
||||
java {
|
||||
toolchain {
|
||||
languageVersion = JavaLanguageVersion.of(21)
|
||||
}
|
||||
}
|
||||
|
||||
android {
|
||||
compileSdk 34
|
||||
compileSdk 35
|
||||
namespace="com.keyman.android.tests.keyboardHarness"
|
||||
|
||||
// Don't compress kmp files so they can be copied via AssetManager
|
||||
|
|
@ -21,7 +27,7 @@ android {
|
|||
defaultConfig {
|
||||
applicationId "com.keyman.android.tests.keyboardHarness"
|
||||
minSdkVersion 21
|
||||
targetSdkVersion 34
|
||||
targetSdkVersion 35
|
||||
|
||||
// KEYMAN_VERSION_CODE and KEYMAN_VERSION_NAME from version.gradle
|
||||
versionCode KEYMAN_VERSION_CODE as Integer
|
||||
|
|
@ -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'
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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>
|
||||
|
|
|
|||
|
|
@ -15,8 +15,8 @@ buildscript {
|
|||
|
||||
allprojects {
|
||||
repositories {
|
||||
maven { url uri("${projectDir}/libs") }
|
||||
google()
|
||||
jcenter()
|
||||
mavenCentral()
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -1,16 +1,23 @@
|
|||
apply plugin: 'com.android.application'
|
||||
plugins {
|
||||
id 'com.android.application'
|
||||
}
|
||||
|
||||
ext.rootPath = '../../../'
|
||||
apply from: "$rootPath/version.gradle"
|
||||
|
||||
android {
|
||||
compileSdk 34
|
||||
compileSdk 35
|
||||
namespace="com.keyman.android.tests.keycode"
|
||||
|
||||
buildFeatures {
|
||||
// needed for custom BuildConfigField values in defaultConfig
|
||||
buildConfig = true
|
||||
}
|
||||
|
||||
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
|
||||
|
|
@ -27,11 +34,10 @@ android {
|
|||
|
||||
dependencies {
|
||||
implementation fileTree(dir: 'libs', include: ['*.jar'])
|
||||
implementation 'androidx.appcompat:appcompat:1.6.1'
|
||||
implementation 'androidx.appcompat:appcompat:1.7.0'
|
||||
implementation 'androidx.constraintlayout:constraintlayout:2.2.1'
|
||||
implementation 'com.google.android.material:material:1.12.0'
|
||||
implementation 'androidx.constraintlayout:constraintlayout:2.1.4'
|
||||
|
||||
testImplementation 'androidx.test:core:1.5.0'
|
||||
testImplementation 'androidx.test.ext:junit:1.1.5'
|
||||
testImplementation 'org.robolectric:robolectric:4.10.3'
|
||||
testImplementation 'androidx.test.ext:junit:1.2.1'
|
||||
testImplementation 'org.robolectric:robolectric:4.14.1'
|
||||
testImplementation 'androidx.test:core:1.6.1'
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,25 +1,25 @@
|
|||
package com.keyman.android.tests.keycode;
|
||||
|
||||
import android.content.Context;
|
||||
import android.support.test.InstrumentationRegistry;
|
||||
import android.support.test.runner.AndroidJUnit4;
|
||||
import androidx.test.core.app.ApplicationProvider;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import android.content.Context;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.robolectric.RobolectricTestRunner;
|
||||
|
||||
/**
|
||||
* Instrumented test, which will execute on an Android device.
|
||||
*
|
||||
* @see <a href="http://d.android.com/tools/testing">Testing documentation</a>
|
||||
*/
|
||||
@RunWith(AndroidJUnit4.class)
|
||||
@RunWith(RobolectricTestRunner.class)
|
||||
public class ExampleInstrumentedTest {
|
||||
@Test
|
||||
public void useAppContext() {
|
||||
// Context of the app under test.
|
||||
Context appContext = InstrumentationRegistry.getTargetContext();
|
||||
Context appContext = ApplicationProvider.getApplicationContext();
|
||||
|
||||
assertEquals("com.keyman.android.tests.keycode", appContext.getPackageName());
|
||||
}
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
package com.example.darcy.keycode;
|
||||
package com.keyman.android.tests.keycode;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
|
|
|
|||
|
|
@ -4,10 +4,10 @@ buildscript {
|
|||
|
||||
repositories {
|
||||
google()
|
||||
jcenter()
|
||||
mavenCentral()
|
||||
}
|
||||
dependencies {
|
||||
classpath 'com.android.tools.build:gradle:7.4.2'
|
||||
classpath 'com.android.tools.build:gradle:8.9.2'
|
||||
|
||||
|
||||
// NOTE: Do not place your application dependencies here; they belong
|
||||
|
|
@ -18,10 +18,6 @@ buildscript {
|
|||
allprojects {
|
||||
repositories {
|
||||
google()
|
||||
jcenter()
|
||||
mavenCentral()
|
||||
}
|
||||
}
|
||||
|
||||
task clean(type: Delete) {
|
||||
delete rootProject.buildDir
|
||||
}
|
||||
|
|
|
|||
|
|
@ -14,4 +14,6 @@ org.gradle.jvmargs=-Xmx1024m
|
|||
# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
|
||||
# org.gradle.parallel=true
|
||||
|
||||
# AGP 8.0 generates R classes for resources defined in the current module only.
|
||||
android.nonTransitiveRClass=false
|
||||
|
||||
|
|
|
|||
|
|
@ -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" \
|
||||
|
|
@ -63,11 +62,12 @@ function do_test_help() {
|
|||
|
||||
function archive_artifacts() {
|
||||
local UPLOAD_PATH KEYMAN_ENGINE_ANDROID_ZIP KEYMAN_APK FIRSTVOICES_APK
|
||||
local KEYMAN_FULLY_VERSIONED_APK FIRSTVOICES_FULLY_VERSIONED_APK
|
||||
|
||||
UPLOAD_PATH="${KEYMAN_ROOT}/android/upload/${KEYMAN_VERSION}"
|
||||
KEYMAN_ENGINE_ANDROID_ZIP="keyman-engine-android-${KEYMAN_VERSION}.zip"
|
||||
KEYMAN_APK="keyman-${KEYMAN_VERSION}.apk"
|
||||
FIRSTVOICES_APK="firstvoices-${KEYMAN_VERSION}.apk"
|
||||
KEYMAN_APK="keyman-${KEYMAN_VERSION_FOR_FILENAME}.apk"
|
||||
FIRSTVOICES_APK="firstvoices-${KEYMAN_VERSION_FOR_FILENAME}.apk"
|
||||
|
||||
rm -rf "${UPLOAD_PATH}"
|
||||
mkdir -p "${UPLOAD_PATH}"
|
||||
|
|
@ -88,12 +88,12 @@ function archive_artifacts() {
|
|||
)
|
||||
|
||||
# Copy release APK
|
||||
cp "${KEYMAN_ROOT}/android/KMAPro/kMAPro/build/outputs/apk/release/${KEYMAN_APK}" "${UPLOAD_PATH}"
|
||||
cp "${KEYMAN_ROOT}/android/KMAPro/kMAPro/build/outputs/apk/release/${KEYMAN_APK}" "${UPLOAD_PATH}/${KEYMAN_APK}"
|
||||
|
||||
# FirstVoices app
|
||||
|
||||
if [[ "${RELEASE_OEM_FIRSTVOICES-false}" = true ]]; then
|
||||
cp "${KEYMAN_ROOT}/oem/firstvoices/android/app/build/outputs/apk/release/${FIRSTVOICES_APK}" "${UPLOAD_PATH}"
|
||||
cp "${KEYMAN_ROOT}/oem/firstvoices/android/app/build/outputs/apk/release/${FIRSTVOICES_APK}" "${UPLOAD_PATH}/${FIRSTVOICES_APK}"
|
||||
fi
|
||||
|
||||
#
|
||||
|
|
@ -108,8 +108,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 +130,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
|
||||
|
|
|
|||
42
android/docs/engine/KMManager/getNavigationBarHeight.md
Normal file
42
android/docs/engine/KMManager/getNavigationBarHeight.md
Normal file
|
|
@ -0,0 +1,42 @@
|
|||
---
|
||||
title: KMManager.getNavigationBarHeight()
|
||||
---
|
||||
|
||||
## Summary
|
||||
|
||||
The **`getNavigationBarHeight()`** method returns the height of the navigation bar.
|
||||
|
||||
## Syntax
|
||||
|
||||
``` javascript
|
||||
KMManager.getNavigationBarHeight(Context context)
|
||||
```
|
||||
|
||||
### Parameters
|
||||
|
||||
`context`
|
||||
: The context.
|
||||
|
||||
### Returns
|
||||
|
||||
Returns the height of the navigation bar in pixels.
|
||||
|
||||
## Description
|
||||
|
||||
Use this method to get the height of the navigation bar. The keyboard offsets must account for this height below the keyboard.
|
||||
|
||||
## Examples
|
||||
|
||||
### Example: Using `getNavigationBarHeight()`
|
||||
|
||||
The following script illustrate the use of `getNavigationBarHeight()`:
|
||||
|
||||
``` javascript
|
||||
int navigationHeight = KMManager.getNavigationBarHeight(this);
|
||||
|
||||
```
|
||||
|
||||
## See Also
|
||||
|
||||
- [`getBannerHeight()`](getBannerHeight)
|
||||
- [`getKeyboardHeight()`](getKeyboardHeight)
|
||||
|
|
@ -149,6 +149,9 @@ The KMManager is the core class which provides most of the methods and constants
|
|||
[`getMaySendCrashReport()`](getMaySendCrashReport)
|
||||
: returns whether Keyman Engine is allowed to send crash reports over the network to Sentry
|
||||
|
||||
[`getNavigationBarHeight()`](getNavigationBarHeight)
|
||||
: returns the height of the navigation bar system inset
|
||||
|
||||
[`getOrientation()`](getOrientation)
|
||||
: returns the device's current orientation (Portrait vs Landscape)
|
||||
|
||||
|
|
|
|||
Binary file not shown.
|
Before Width: | Height: | Size: 33 KiB After Width: | Height: | Size: 40 KiB |
|
|
@ -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.
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
2
build.sh
2
build.sh
|
|
@ -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" \
|
||||
|
|
|
|||
|
|
@ -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" \
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
#
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
#
|
||||
|
|
|
|||
|
|
@ -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" \
|
||||
|
|
|
|||
|
|
@ -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"
|
||||
|
|
|
|||
|
|
@ -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")"
|
||||
|
||||
|
|
|
|||
|
|
@ -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 };
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
|
|
|||
|
|
@ -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" \
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
};
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
#
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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 \
|
||||
|
|
|
|||
|
|
@ -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 \
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Reference in a new issue