diff --git a/HISTORY.md b/HISTORY.md index 7bb236717b..904e03468a 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -1,5 +1,25 @@ # Keyman Version History +## 18.0.97 alpha 2024-08-24 + +* refactor(linux): cleanup API of kvk2ldml.py (#12276) +* chore(common): adjust build settings for windows clean builds (#12264) +* chore(windows): remove remaining unused Makefiles (#12274) +* docs(developer): update build documentation to refer to build.sh (#12272) + +## 18.0.96 alpha 2024-08-23 + +* fix(android): Fix navigation arrows in Info Activity for RTL (#12244) +* fix(web): fix documentation-keyboard spacebar-text scaling (#12232) +* fix(android): Use increment and decrement arrows on longpress delay menu (#12242) +* fix(android): Add RTL assets for adjusting keyboard height menu (#12261) +* chore(common): use `npm install` in emsdk update (#12269) +* docs: refresh windows.md (#12248) + +## 18.0.95 alpha 2024-08-22 + +* chore(common): allow build agents to automatically select emsdk version, and enable support for 3.1.60+ (#12243) + ## 18.0.94 alpha 2024-08-21 * fix(core): look for `emcc` instead of `emcc.py` (#12235) diff --git a/VERSION.md b/VERSION.md index a41e5425c0..48b8081cd1 100644 --- a/VERSION.md +++ b/VERSION.md @@ -1 +1 @@ -18.0.95 \ No newline at end of file +18.0.98 \ No newline at end of file diff --git a/android/KMAPro/kMAPro/src/main/res/drawable-ldrtl-hdpi/blank_osk.png b/android/KMAPro/kMAPro/src/main/res/drawable-ldrtl-hdpi/blank_osk.png new file mode 100644 index 0000000000..c5d555caca Binary files /dev/null and b/android/KMAPro/kMAPro/src/main/res/drawable-ldrtl-hdpi/blank_osk.png differ diff --git a/android/KMAPro/kMAPro/src/main/res/drawable-ldrtl-land-hdpi/blank_osk.png b/android/KMAPro/kMAPro/src/main/res/drawable-ldrtl-land-hdpi/blank_osk.png new file mode 100644 index 0000000000..3e41a359a0 Binary files /dev/null and b/android/KMAPro/kMAPro/src/main/res/drawable-ldrtl-land-hdpi/blank_osk.png differ diff --git a/android/KMAPro/kMAPro/src/main/res/drawable-ldrtl-sw600dp-land/blank_osk.png b/android/KMAPro/kMAPro/src/main/res/drawable-ldrtl-sw600dp-land/blank_osk.png new file mode 100644 index 0000000000..282606a9d5 Binary files /dev/null and b/android/KMAPro/kMAPro/src/main/res/drawable-ldrtl-sw600dp-land/blank_osk.png differ diff --git a/android/KMAPro/kMAPro/src/main/res/drawable-ldrtl-sw600dp/blank_osk.png b/android/KMAPro/kMAPro/src/main/res/drawable-ldrtl-sw600dp/blank_osk.png new file mode 100644 index 0000000000..8246a64168 Binary files /dev/null and b/android/KMAPro/kMAPro/src/main/res/drawable-ldrtl-sw600dp/blank_osk.png differ diff --git a/android/KMAPro/kMAPro/src/main/res/drawable-ldrtl-sw720dp-land/blank_osk.png b/android/KMAPro/kMAPro/src/main/res/drawable-ldrtl-sw720dp-land/blank_osk.png new file mode 100644 index 0000000000..740c8559c9 Binary files /dev/null and b/android/KMAPro/kMAPro/src/main/res/drawable-ldrtl-sw720dp-land/blank_osk.png differ diff --git a/android/KMAPro/kMAPro/src/main/res/drawable-ldrtl-sw720dp/blank_osk.png b/android/KMAPro/kMAPro/src/main/res/drawable-ldrtl-sw720dp/blank_osk.png new file mode 100644 index 0000000000..0e3343bbd1 Binary files /dev/null and b/android/KMAPro/kMAPro/src/main/res/drawable-ldrtl-sw720dp/blank_osk.png differ diff --git a/android/KMAPro/kMAPro/src/main/res/layout/activity_adjust_longpress_delay.xml b/android/KMAPro/kMAPro/src/main/res/layout/activity_adjust_longpress_delay.xml index ed0bed54a9..ef1ebd613b 100644 --- a/android/KMAPro/kMAPro/src/main/res/layout/activity_adjust_longpress_delay.xml +++ b/android/KMAPro/kMAPro/src/main/res/layout/activity_adjust_longpress_delay.xml @@ -23,7 +23,7 @@ android:layout_marginStart="5dp" android:layout_marginEnd="5dp" android:contentDescription="@string/ic_delay_time_down" - android:src="@drawable/ic_light_dialog_textsize_down" /> + android:src="@drawable/ic_action_decrement" /> + android:src="@drawable/ic_action_increment" /> diff --git a/android/KMAPro/kMAPro/src/main/res/layout/activity_info.xml b/android/KMAPro/kMAPro/src/main/res/layout/activity_info.xml index 3b71e87178..314a503412 100644 --- a/android/KMAPro/kMAPro/src/main/res/layout/activity_info.xml +++ b/android/KMAPro/kMAPro/src/main/res/layout/activity_info.xml @@ -1,12 +1,12 @@ + xmlns:tools="http://schemas.android.com/tools" + xmlns:app="http://schemas.android.com/apk/res-auto" + android:layout_width="match_parent" + android:layout_height="match_parent" + android:orientation="vertical" + android:background="@color/ms_white" + tools:context=".InfoActivity" > - - + android:orientation="horizontal"> - + + + + + nul 2>nul - $(CLEAN) ExcMagic.Debug *.wixpdb *.identcache *.embed.manifest *.embed.manifest.res *.intermediate.manifest error.log >nul 2>nul - if exist bin rd /s/q bin - if exist obj rd /s/q obj - -!CMDSWITCHES -S - -# This virtual rule forces targets which are folders, e.g. `kmshell` to -# always execute -.virtual: - rem always execute diff --git a/common/windows/delphi/components/common_components.dproj b/common/windows/delphi/components/common_components.dproj index 2bd91473ab..4ecda90464 100644 --- a/common/windows/delphi/components/common_components.dproj +++ b/common/windows/delphi/components/common_components.dproj @@ -13,31 +13,6 @@ true - - true - Base - true - - - true - Base - true - - - true - Base - true - - - true - Base - true - - - true - Base - true - true Base @@ -59,6 +34,12 @@ Base true + + true + Cfg_2 + true + true + .\obj\$(Platform)\$(Config) .\$(Platform)\$(Config) @@ -77,23 +58,6 @@ 3081 CompanyName=;FileDescription=$(MSBuildProjectName);FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProgramID=com.embarcadero.$(MSBuildProjectName);ProductName=$(MSBuildProjectName);ProductVersion=1.0.0.0;Comments= - - None - android-support-v4.dex.jar;cloud-messaging.dex.jar;com-google-android-gms.play-services-ads-base.17.2.0.dex.jar;com-google-android-gms.play-services-ads-identifier.16.0.0.dex.jar;com-google-android-gms.play-services-ads-lite.17.2.0.dex.jar;com-google-android-gms.play-services-ads.17.2.0.dex.jar;com-google-android-gms.play-services-analytics-impl.16.0.8.dex.jar;com-google-android-gms.play-services-analytics.16.0.8.dex.jar;com-google-android-gms.play-services-base.16.0.1.dex.jar;com-google-android-gms.play-services-basement.16.2.0.dex.jar;com-google-android-gms.play-services-gass.17.2.0.dex.jar;com-google-android-gms.play-services-identity.16.0.0.dex.jar;com-google-android-gms.play-services-maps.16.1.0.dex.jar;com-google-android-gms.play-services-measurement-base.16.4.0.dex.jar;com-google-android-gms.play-services-measurement-sdk-api.16.4.0.dex.jar;com-google-android-gms.play-services-stats.16.0.1.dex.jar;com-google-android-gms.play-services-tagmanager-v4-impl.16.0.8.dex.jar;com-google-android-gms.play-services-tasks.16.0.1.dex.jar;com-google-android-gms.play-services-wallet.16.0.1.dex.jar;com-google-firebase.firebase-analytics.16.4.0.dex.jar;com-google-firebase.firebase-common.16.1.0.dex.jar;com-google-firebase.firebase-iid-interop.16.0.1.dex.jar;com-google-firebase.firebase-iid.17.1.1.dex.jar;com-google-firebase.firebase-measurement-connector.17.0.1.dex.jar;com-google-firebase.firebase-messaging.17.5.0.dex.jar;fmx.dex.jar;google-play-billing.dex.jar;google-play-licensing.dex.jar - - - None - android-support-v4.dex.jar;cloud-messaging.dex.jar;com-google-android-gms.play-services-ads-base.17.2.0.dex.jar;com-google-android-gms.play-services-ads-identifier.16.0.0.dex.jar;com-google-android-gms.play-services-ads-lite.17.2.0.dex.jar;com-google-android-gms.play-services-ads.17.2.0.dex.jar;com-google-android-gms.play-services-analytics-impl.16.0.8.dex.jar;com-google-android-gms.play-services-analytics.16.0.8.dex.jar;com-google-android-gms.play-services-base.16.0.1.dex.jar;com-google-android-gms.play-services-basement.16.2.0.dex.jar;com-google-android-gms.play-services-gass.17.2.0.dex.jar;com-google-android-gms.play-services-identity.16.0.0.dex.jar;com-google-android-gms.play-services-maps.16.1.0.dex.jar;com-google-android-gms.play-services-measurement-base.16.4.0.dex.jar;com-google-android-gms.play-services-measurement-sdk-api.16.4.0.dex.jar;com-google-android-gms.play-services-stats.16.0.1.dex.jar;com-google-android-gms.play-services-tagmanager-v4-impl.16.0.8.dex.jar;com-google-android-gms.play-services-tasks.16.0.1.dex.jar;com-google-android-gms.play-services-wallet.16.0.1.dex.jar;com-google-firebase.firebase-analytics.16.4.0.dex.jar;com-google-firebase.firebase-common.16.1.0.dex.jar;com-google-firebase.firebase-iid-interop.16.0.1.dex.jar;com-google-firebase.firebase-iid.17.1.1.dex.jar;com-google-firebase.firebase-measurement-connector.17.0.1.dex.jar;com-google-firebase.firebase-messaging.17.5.0.dex.jar;fmx.dex.jar;google-play-billing.dex.jar;google-play-licensing.dex.jar - - - None - - - None - - - None - Winapi;System.Win;Data.Win;Datasnap.Win;Web.Win;Soap.Win;Xml.Win;Bde;$(DCC_Namespace) Debug @@ -113,6 +77,7 @@ false true 1033 + ..\..\lib false @@ -120,6 +85,11 @@ 0 0 + + ..\..\lib + true + 1033 + MainSource @@ -164,8 +134,6 @@ common_components.dpk - File c:\projects\keyman\app\windows\lib\DCPdelphi2009.bpl not found - File c:\projects\keyman\app\windows\lib\delphiprojectmanager.bpl not found Microsoft Office 2000 Sample Automation Server Wrapper Components Microsoft Office XP Sample Automation Server Wrapper Components @@ -944,13 +912,6 @@ - False - False - False - False - False - False - False True False diff --git a/common/windows/delphi/ext/cef4delphi/packages/CEF4Delphi.res b/common/windows/delphi/ext/cef4delphi/packages/CEF4Delphi.res deleted file mode 100644 index b9b013c212..0000000000 Binary files a/common/windows/delphi/ext/cef4delphi/packages/CEF4Delphi.res and /dev/null differ diff --git a/common/windows/delphi/tools/certificates/build.sh b/common/windows/delphi/tools/certificates/build.sh index 378723a125..10ab4c75ce 100755 --- a/common/windows/delphi/tools/certificates/build.sh +++ b/common/windows/delphi/tools/certificates/build.sh @@ -21,6 +21,8 @@ builder_describe_outputs \ function do_certificates() { rm -f KeymanTestCA-sha1.* KeymanTest-sha1.* KeymanTest-sha256.* KeymanTestCA-sha256.* + source "$KEYMAN_ROOT/resources/build/win/visualstudio_environment.inc.sh" + makecert -r -pe -n "CN=Keyman Test CA SHA1" -ss CA -sr CurrentUser -a sha1 -cy authority -sky signature -sv KeymanTestCA-sha1.pvk KeymanTestCA-sha1.cer certutil -user -addstore Root KeymanTestCA-sha1.cer makecert -pe -n "CN=Keyman Test Certificate SHA1" -a sha1 -cy end -sky signature -ic KeymanTestCA-sha1.cer -iv KeymanTestCA-sha1.pvk -sv KeymanTest-sha1.pvk KeymanTest-sha1.cer diff --git a/developer/src/README.md b/developer/src/README.md index 7e7ea9d336..d789b63f08 100644 --- a/developer/src/README.md +++ b/developer/src/README.md @@ -2,6 +2,42 @@ This is the current home for Keyman Developer. +## Build Prerequisites + +* See [Windows Build Environment Configuration](../../docs/build/windows.md). + +## Building Keyman Developer + +1. Start 'Git Bash' (part of Git for Windows). +2. Run `developer/src/build.sh`. +3. Artifacts from a successful build will be placed in **developer/bin** folder. + +*Note*: running `build.sh` will currently reset the packages and path settings +in your Delphi environment. If you use Delphi for other projects, you should +consider building Keyman under a login user dedicated to it, or in a VM. + +Type `build.sh` to see build targets and actions. Common build actions are: + +* `build.sh build` +: builds Keyman Developer + +* `build.sh clean` +: remove temporary files and build artifacts + +* `build.sh publish` +: makes a release of all Keyman Developer projects + +* `build.sh install` +: install some or all components to Program Files (requires elevated command prompt). + +### Building without Delphi + +It is possible to build all components that do _not_ require Delphi. Currently a +few components are Delphi-based (TIKE, setup, a few others), but you may be able +to get away without building them. In this situation, we recommend copying the +relevant Delphi-built components into developer/bin folders from a compatible +installed version of Keyman Developer for testing and debugging purposes. + # Folders ## common @@ -106,4 +142,6 @@ testing and packing keyboards for distribution. ## tools -Various build-time tools for Keyman Developer. \ No newline at end of file +Various build-time tools for Keyman Developer. + + diff --git a/developer/src/kmc-ldml/src/compiler/visual-keyboard-compiler.ts b/developer/src/kmc-ldml/src/compiler/visual-keyboard-compiler.ts index 6182e6e2c8..6d76bc403e 100644 --- a/developer/src/kmc-ldml/src/compiler/visual-keyboard-compiler.ts +++ b/developer/src/kmc-ldml/src/compiler/visual-keyboard-compiler.ts @@ -3,6 +3,23 @@ import { LDMLKeyboard, CompilerCallbacks } from "@keymanapp/developer-utils"; import { KeysCompiler } from "./keys.js"; import { LdmlCompilerMessages } from "./ldml-compiler-messages.js"; +// This is a partial polyfill for findLast, so not polluting Array.prototype +// https://medium.com/@stheodorejohn/findlast-method-polyfill-in-javascript-bridging-browser-gaps-c3baf6aabae1 +// TODO: remove and replace with Array.prototype.findLast when it is +// well-supported +function findLast(arr: any, callback: any) { + if (!arr) { + return undefined; + } + const len = arr.length >>> 0; + for (let i = len - 1; i >= 0; i--) { + if (callback(arr[i], i, arr)) { + return arr[i]; + } + } + return undefined; +} + export class LdmlKeyboardVisualKeyboardCompiler { public constructor(private callbacks: CompilerCallbacks) { } @@ -57,7 +74,8 @@ export class LdmlKeyboardVisualKeyboardCompiler { const keyId = key; x++; - let keydef = source.keyboard3.keys?.key?.find(x => x.id == key); + //@ts-ignore + let keydef = findLast(source.keyboard3.keys?.key, x => x.id == key); if (!keydef) { this.callbacks.reportMessage( diff --git a/developer/src/kmc-model/test/test-compile-model.ts b/developer/src/kmc-model/test/test-compile-model.ts index e3074d697a..7de9d6d5da 100644 --- a/developer/src/kmc-model/test/test-compile-model.ts +++ b/developer/src/kmc-model/test/test-compile-model.ts @@ -9,6 +9,8 @@ import { KeymanFileTypes } from '@keymanapp/common-types'; describe('LexicalModelCompiler', function () { let callbacks = new TestCompilerCallbacks(); + this.timeout(5000); + // Try to compile ALL of the correct models. const MODELS = [ 'example.qaa.sencoten', diff --git a/developer/src/tike/build.sh b/developer/src/tike/build.sh index 1ab9dbe320..fd81ca692d 100755 --- a/developer/src/tike/build.sh +++ b/developer/src/tike/build.sh @@ -19,7 +19,7 @@ source "$KEYMAN_ROOT/resources/build/win/environment.inc.sh" WIN32_TARGET="$WIN32_TARGET_PATH/tike.exe" builder_describe_outputs \ - configure:project /resources/build/win/delphi_environment_generated.inc.sh \ + configure:project /developer/src/tike/xml/layoutbuilder/keymanweb-osk.ttf \ build:project /developer/src/tike/$WIN32_TARGET #------------------------------------------------------------------------------------------------------------------- @@ -31,6 +31,7 @@ function do_configure() { mkdir -p "$DEVELOPER_PROGRAM" cp "$KEYMAN_ROOT/common/schemas/kps/kps.xsd" "$DEVELOPER_PROGRAM" cp "$KEYMAN_ROOT/common/resources/fonts/keymanweb-osk.ttf" "$DEVELOPER_ROOT/src/tike/xml/layoutbuilder/keymanweb-osk.ttf" + run_in_vs_env rc icons.rc } function do_monaco_copy() { @@ -52,8 +53,6 @@ function do_monaco_copy() { pushd "$DEVELOPER_ROOT/src/tike/xml/app/lib/sentry" replaceVersionStrings_Mkver init.js.in init.js popd - - run_in_vs_env rc icons.rc } KEYMANCORE_DLL=keymancore-2.dll diff --git a/docs/build/linux-ubuntu.md b/docs/build/linux-ubuntu.md index 0107491dda..a45d9390ba 100644 --- a/docs/build/linux-ubuntu.md +++ b/docs/build/linux-ubuntu.md @@ -63,17 +63,33 @@ See [node.md](node.md) for more information. #### Emscripten -You'll also have to install `emscripten` (version 3.1.44 is known to work): +You'll also have to install `emscripten`: ```shell git clone https://github.com/emscripten-core/emsdk.git cd emsdk -./emsdk install 3.1.44 -./emsdk activate 3.1.44 -export EMSCRIPTEN_BASE=$(pwd)/upstream/emscripten +./emsdk install 3.1.58 +./emsdk activate 3.1.58 +export EMSCRIPTEN_BASE="$(pwd)/upstream/emscripten" +echo "export EMSCRIPTEN_BASE=\"$EMSCRIPTEN_BASE\"" >> .bashrc ``` -**NOTE:** Don't put EMSDK on the path, i.e. don't source `emsdk_env.sh`. +> ![WARNING] +> Don't put EMSDK on the path, i.e. don't source `emsdk_env.sh`. +> +> Emscripten very unhelpfully overwrites `JAVA_HOME`, and adds its own +> versions of Python, Node and Java to the `PATH`. For best results, restart +> your shell after installing Emscripten so that you don't end up with the +> wrong versions. + +**Optional environment variables**: + +To let the Keyman build scripts control the version of Emscripten installed on +your computer: + +```shell +export KEYMAN_USE_EMSDK=1 +``` ## Keyman Core diff --git a/docs/build/macos.md b/docs/build/macos.md index 81b1bcd0e7..25b0c1f82a 100644 --- a/docs/build/macos.md +++ b/docs/build/macos.md @@ -91,16 +91,38 @@ See [node.md](node.md) for more information. ### emscripten -To install emscripten: +The recommended way to install emscripten is with the official method, as that +then allows the build scripts to select the appropriate version automatically. -```shell -brew install emscripten +To install emscripten, `cd` to an appropriate path, and then: + +```bash +git clone https://github.com/emscripten-core/emsdk +cd emsdk +emsdk install 3.1.58 +emsdk activate 3.1.58 +export EMSCRIPTEN_BASE="$(pwd)/upstream/emscripten" +echo "export EMSCRIPTEN_BASE=\"$EMSCRIPTEN_BASE\"" >> .bashrc ``` -Note: if you install emscripten with brew on macOS, only emscripten binaries are -added to the path via symlinks. This makes it reasonably safe to have emscripten -on the path, unlike on other platforms where emscripten also ends up adding its -versions of node, python, and other binaries to the path. +You will want to add `EMSCRIPTEN_BASE` to your .bashrc. + +> ![WARNING] +> Don't put EMSDK on the path, i.e. don't source `emsdk_env.sh`. +> +> Emscripten very unhelpfully overwrites `JAVA_HOME`, and adds its own +> versions of Python, Node and Java to the `PATH`. For best results, restart +> your shell after installing Emscripten so that you don't end up with the +> wrong versions. + +**Optional environment variables**: + +To let the Keyman build scripts control the version of Emscripten installed on +your computer: + +```shell +export KEYMAN_USE_EMSDK=1 +``` ## Keyman for iOS Dependencies diff --git a/docs/build/windows.md b/docs/build/windows.md index dcb55ce4a4..3168bcd0ae 100644 --- a/docs/build/windows.md +++ b/docs/build/windows.md @@ -6,13 +6,13 @@ On Windows, you can build the following projects: * [Keyman for Android](#keyman-for-android) * [Keyman for Windows](#keyman-for-windows) -* [Keyman Developer](#keyman-developer) (together with Keyman for Windows) +* [Keyman Developer](#keyman-developer) * [KeymanWeb](#keymanweb) The following libraries can also be built: -* Keyman Core (Windows, wasm targets) (aka core) -* Common/Web +* Keyman Core (Windows, wasm targets) +* Common libraries The following projects **cannot** be built on Windows: @@ -63,10 +63,6 @@ Dependencies: * [Base](#base-dependencies) * [Windows Platform](#windows-platform-dependencies) -**Note**: Keyman for Windows is currently built together with Keyman Developer. -We are working on splitting these projects. For now, you will need the Keyman -Developer dependencies as well. - Building: * [Building Keyman for Windows](../../windows/src/README.md) @@ -75,7 +71,7 @@ Building: Dependencies: * [Base](#base-dependencies) * [Web](#web-dependencies) -* [Windows Platform](#windows-platform-dependencies) +* [Windows Platform](#windows-platform-dependencies) (optional, for Windows-only components) Building: * [Building Keyman Developer](../../windows/src/README.md) @@ -94,42 +90,19 @@ Building: **Dependencies**: * [Base](#base-dependencies) * [Web](#web-dependencies) - -**Additional requirements**: -* Android SDK -* Android Studio -* Ant -* Gradle -* Maven -* Optional: OpenJDK 11 (https://learn.microsoft.com/en-us/java/openjdk/download) - -```ps1 -# Elevated PowerShell -choco install android-sdk android-studio ant gradle maven -# optionally install sdk images -sdkmanager "system-images;android-33;google_apis;armeabi-v7a" -sdkmanager --update -sdkmanager --licenses -``` - -* Run Android Studio once after installation to install additional components - such as emulator images and SDK updates. - -**Required environment variables**: -* [`JAVA_HOME`](#java_home) - -**Optional environment variables**: -* [`JAVA_HOME_11`](#java_home) +* [Android](#android-dependencies) Building: * [Building Keyman for Android](../../android/README.md) -## Prerequisites +--- + +## Dependencies and Prerequisites Many dependencies are only required for specific projects. We prefer [Chocolatey](https://chocolatey.org/install) at present for -installation of dependencies. Chocolatey should be run in an elevated +installation of most dependencies. Chocolatey should be run in an elevated PowerShell. ### Base Dependencies @@ -150,28 +123,36 @@ PowerShell. # for *much* faster download, hide progress bar (PowerShell/PowerShell#2138) $ProgressPreference = 'SilentlyContinue' choco install git jq python ninja pandoc meson -refreshenv ``` **Environment variables**: -* [`KEYMAN_ROOT`](#keyman_root) -* `PATH`: add your Python scripts folder to your path: it will normally be `%appdata%\Python\Python310\Scripts`. + +If you pull the entire `keyman.git` repo to `c:\keyman`, then the paths by +default will work without changes. Otherwise, you will need to set an +environment variable `KEYMAN_ROOT` to the root path of the Keyman repo. For +example: ```bat -SET KEYMAN_ROOT=c:\Projects\keyman\keyman -SET PATH=%path%;%appdata%\Python\Python310\Scripts +SETX KEYMAN_ROOT "c:\Projects\keyman\keyman" ``` -To check whether environment variables are set, run `SET ` in command -prompt. +> [!NOTE] +> The `SETX` command will set persistent environment variables but they do not +> impact the current shell environment. Start a new shell to see the variables. -You can use Windows Settings to add these environment variables permanently: - -1. In Windows Search, type "environment" and select "Edit System Environment - Variables" -2. Click `Environment Variables...` -3. You can add or edit variables in either User or System settings, as you - prefer. +> [!TIP] +> +> To check whether environment variables are set, run `SET ` in command +> prompt. +> +> You can alternatively use Windows Settings to add these environment variables +> permanently: +> +> 1. In Windows Search, type "environment" and select "Edit System Environment +> Variables" +> 2. Click `Environment Variables...` +> 3. You can add or edit variables in either User or System settings, as you +> prefer. ### Web Dependencies @@ -181,32 +162,46 @@ You can use Windows Settings to add these environment variables permanently: * KeymanWeb **Requirements**: -* emscripten 3.1.46 or later -* node.js 18+ -* [openjdk 11](https://learn.microsoft.com/en-us/java/openjdk/download#openjdk-11)+ +* Emscripten +* node.js -```ps1 -# Elevated PowerShell +#### Emscripten -# for *much* faster download, hide progress bar (PowerShell/PowerShell#2138) -$ProgressPreference = 'SilentlyContinue' +In bash, run the following commands: -choco install emscripten --version 3.1.46 +```bash +cd /c/Projects/keyman +git clone https://github.com/emscripten-core/emsdk +cd emsdk +emsdk install 3.1.58 +emsdk activate 3.1.58 ``` -Note: emscripten very unhelpfully overwrites JAVA_HOME, and adds its own -versions of Python, Node and Java to the PATH. For best results, go ahead -and remove those paths from your PATH variable before continuing. +> ![WARNING] +> Emscripten very unhelpfully overwrites `JAVA_HOME`, and adds its own +> versions of Python, Node and Java to the `PATH`. For best results, restart +> your shell after installing Emscripten so that you don't end up with the +> wrong versions. There is no need to add emscripten to the path in order to build Keyman. -However, you should set the EMSCRIPTEN_BASE variable to the path where `emcc` -can be found, but always in the upstream\emscripten subdirectory where you -installed emsdk (most likely %LocalAppData%\emsdk\upstream\emscripten) +However, you should set the `EMSCRIPTEN_BASE` variable to the path where `emcc` +can be found, in the `upstream\emscripten` subdirectory of where you installed +emsdk. **Environment variables**: -* `EMSCRIPTEN_BASE`: `\upstream\emscripten` -After installing emscripten, you'll need to install node.js and openjdk. +```bat +SETX EMSCRIPTEN_BASE "\upstream\emscripten" +``` + +**Optional environment variables**: + +To let the Keyman build scripts control the version of Emscripten +installed on your computer: + +```bat +SETX KEYMAN_USE_EMSDK 1 +``` #### node.js @@ -214,30 +209,22 @@ Our recommended way to install node.js is to use [nvm-windows](https://github.com/coreybutler/nvm-windows). This makes it easy to switch between versions of node.js. -Alternatively, use Powershell + Chocolatey to install node.js: - -```ps1 -# Elevated PowerShell - -# for *much* faster download, hide progress bar (PowerShell/PowerShell#2138) -$ProgressPreference = 'SilentlyContinue' -choco install nodejs +```bat +nvm install 20.16.0 +nvm use 20.16.0 ``` -See [node.md](node.md) for more information. +**Optional environment variables**: -#### openjdk +To let the Keyman build scripts control the version of node.js installed +and active on your computer: -Use Powershell + Chocolatey to install OpenJDK: - -```ps1 -# Elevated PowerShell - -# for *much* faster download, hide progress bar (PowerShell/PowerShell#2138) -$ProgressPreference = 'SilentlyContinue' -choco install openjdk -``` +```bat +SETX KEYMAN_USE_NVM 1 +```` +See [node.md](node.md) for more information, including automatic selection +of appropriate node versions during builds. ### Windows Platform Dependencies @@ -260,8 +247,7 @@ choco install openjdk Start Delphi IDE once after installation as it will create various environment files and take you through required registration. - * Note: It is possible to build all components that do _not_ require Delphi by - adding the environment variable `NODELPHI=1` before starting the build. + * Note: It is possible to build all components that do _not_ require Delphi. Currently many components are Delphi-based, but if you are working just in Keyman Core, the compiler, or Keyman Engine's C++ components, you may be able to get away without building them. In this situation, we recommend @@ -273,10 +259,12 @@ choco install openjdk ```ps1 choco install visualstudio2019community visualstudio2019-workload-nativedesktop visualstudio2019buildtools ``` + * Verify required build tools are installed * Run `Visual Studio Installer` * Check the `Individual components` tab - * Verify `MSVC v142 - VS 2019 c++ x64/x86 build tools (Latest)` is installed. If not, install it. + * Verify `MSVC v142 - VS 2019 c++ x64/x86 build tools (Latest)` is installed. + If not, install it. Recommended: configure Visual Studio to use two-space tab stops: 1. Open the options dialog: Tools > Options. @@ -284,55 +272,15 @@ choco install openjdk 3. Change 'Tab size' to 2 and 'Indent size' to 2. 4. Select 'Insert spaces'. +* Windows SDK (C++ Desktop Development) + + https://developer.microsoft.com/en-us/windows/downloads/windows-sdk/ + **Required environment variables**: * `PATH` - * Add the C:\Projects\keyman\keyman\windows\lib folder in the Keyman + * Add the `C:\Projects\keyman\keyman\windows\lib` folder in the Keyman repository to your `PATH` environment variable. This is required for Keyman's design-time packages to load in Delphi. -* [`KEYMAN_CEF4DELPHI_ROOT`](#keyman_cef4delphi_root) - -**Optional environment variables**: -* [`GIT_BASH_FOR_KEYMAN`](#git_bash_for_keyman) -* [`USERDEFINES`](#userdefines) - -```bat -SET KEYMAN_CEF4DELPHI_ROOT=c:\Projects\keyman\CEF4Delphi_Binary -SET GIT_BASH_FOR_KEYMAN="C:\Program Files\Git\bin\bash.exe" --init-file "c:\Program Files\Git\etc\profile" -l -``` - -**Additional requirements for release builds**: -* [Certificates](#certificates) -* [7-Zip](http://www.7-zip.org/), used for archiving build files -* [HTML Help Workshop](http://web.archive.org/web/20160201063255/http://download.microsoft.com/download/0/A/9/0A939EF6-E31C-430F-A3DF-DFAE7960D564/htmlhelp.exe) note: Microsoft no longer offer this download... -* [WiX 3.11.1](https://github.com/wixtoolset/wix3/releases/tag/wix3111rtm) -* [CEF4Delphi_Binary](https://github.com/keymanapp/CEF4Delphi_Binary) repository - -```ps1 -# Elevated PowerShell -choco install 7zip html-help-workshop -choco install wixtoolset --version=3.11.1 -git clone https://github.com/keymanapp/CEF4Delphi_Binary C:\Projects\keyman\CEF4Delphi_Binary -``` - -## Certificates - -In order to make a release build, you need to sign all the executables. See -[windows/src/README.md#Certificates](../../windows/src/README.md#Certificates) -for details on how to create test code signing certificates or specify your own -certificates for the build. - -## Notes on Environment Variables - -### KEYMAN_ROOT - -If you pull the entire `keyman.git` repo to `c:\keyman`, then the paths by -default will work without changes. Otherwise, you will need to set an -environment variable `KEYMAN_ROOT` to the root path of the Keyman repo. For -example: - -```bat -SET KEYMAN_ROOT=c:\projects\keyman\keyman -``` ### KEYMAN_CEF4DELPHI_ROOT @@ -349,41 +297,85 @@ release build, the common/windows/cef-checkout.sh script will checkout the corre branch of the repository automatically and extract any compressed files found in it. -### GIT_BASH_FOR_KEYMAN - -This environment variable is optional: the build will run bash in a separate -window in order to build KeymanWeb if it isn't present, but you'll lose logging -and have the annoyance of a window popping up halfway through the build. To -resolve both of those issues, set the environment variable to: +The [`KEYMAN_CEF4DELPHI_ROOT`](#keyman_cef4delphi_root) variable is +used to specify the path to the CEF4Delphi binaries. ```bat -SET GIT_BASH_FOR_KEYMAN="C:\Program Files\Git\bin\bash.exe" --init-file "c:\Program Files\Git\etc\profile" -l +SETX KEYMAN_CEF4DELPHI_ROOT "c:\Projects\keyman\CEF4Delphi_Binary" ``` -You should verify the install location of Git on your computer as it may vary. +**Additional requirements for release builds**: +* [Certificates](#certificates) +* [7-Zip](http://www.7-zip.org/), used for archiving build files +* [HTML Help Workshop](http://web.archive.org/web/20160201063255/http://download.microsoft.com/download/0/A/9/0A939EF6-E31C-430F-A3DF-DFAE7960D564/htmlhelp.exe) note: Microsoft no longer offer this download... +* [WiX 3.11.1](https://github.com/wixtoolset/wix3/releases/tag/wix3111rtm) +* [CEF4Delphi_Binary](https://github.com/keymanapp/CEF4Delphi_Binary) repository -### USERDEFINES - -You can specify defines that will not be added to the git repository and will be -used in the build in the UserDefines.mak file in the root folder. This is used -mostly for code signing certificates. If not specified, a test certificate will -be used to sign executables when you build a release. - -To include UserDefines.mak in the build, use the command line parameter -`-DUSERDEFINES`. You can also set an environment variable `USERDEFINES=1` to get -the same result. - -### JAVA_HOME - -This environment variable tells Gradle what version of Java to use for building Keyman for Android. - -**Multiple versions of Java:** If you need to build Keyman for Android 16.0 or older versions, you can set `JAVA_HOME_11` to the OpenJDK 11 path and `JAVA_HOME` to the OpenJDK 8 path. This will build both versions correctly from command line. But note that you do need to update your `JAVA_HOME` env var to the associated version before opening Android Studio and loading any Android projects. `JAVA_HOME_11` is mostly used by CI. - -```bat -SET JAVA_HOME="path to OpenJDK 8" -SET JAVA_HOME_11="path to OpenJDK 11" +```ps1 +# Elevated PowerShell +choco install 7zip html-help-workshop +choco install wixtoolset --version=3.11.1 +git clone https://github.com/keymanapp/CEF4Delphi_Binary C:\Projects\keyman\CEF4Delphi_Binary ``` +### Android dependencies + +**Projects**: +* Keyman for Android + +**Requirements**: +* Android SDK +* Android Studio +* Ant +* Gradle +* Maven +* JDK 11 (Temurin11) + +#### JDK 11 + +Use Powershell + Chocolatey to install JDK 11: + +```ps1 +# Elevated PowerShell + +# for *much* faster download, hide progress bar (PowerShell/PowerShell#2138) +$ProgressPreference = 'SilentlyContinue' +choco install temurin11 +``` + +**Multiple versions of Java:** If you need to build Keyman for Android 16.0 or +older versions, you can set `JAVA_HOME_11` to the JDK 11 path and +`JAVA_HOME` to the JDK 8 path. This will build both versions correctly +from command line. But note that you do need to update your `JAVA_HOME` env +var to the associated version before opening Android Studio and loading any +Android projects. `JAVA_HOME_11` is mostly used by CI. + +#### Android Studio and friends + +```ps1 +# Elevated PowerShell +choco install androidstudio ant gradle maven android-sdk +``` + +Start a new shell to get the new paths and then update Android SDKs: + +```ps1 +# optionally install sdk images +sdkmanager --update +# sdkmanager "system-images;android-33;google_apis;armeabi-v7a" +sdkmanager --licenses +``` + +* Run Android Studio once after installation to install additional components + such as emulator images and SDK updates. + +## Certificates + +In order to make a release build, you need to sign all the executables. See +[windows/src/README.md#Certificates](../../windows/src/README.md#Certificates) +for details on how to create test code signing certificates or specify your own +certificates for the build. + ## Optional Tools * sentry-cli (optional) diff --git a/docs/minimum-versions.md b/docs/minimum-versions.md index a9a2ead26b..f582632007 100644 --- a/docs/minimum-versions.md +++ b/docs/minimum-versions.md @@ -49,7 +49,6 @@ https://help.keyman.com/developer/engine/android/latest-version/ | KEYMAN Variable | Value | |-----------------------------------|--------------| | KEYMAN_DEFAULT_VERSION_UBUNTU_CONTAINER | noble | -| KEYMAN_MAX_VERSION_EMSCRIPTEN | 3.1.58 | | KEYMAN_MIN_TARGET_VERSION_ANDROID | 5 | | KEYMAN_MIN_TARGET_VERSION_CHROME | 95.0 | | KEYMAN_MIN_TARGET_VERSION_IOS | 12.2 | @@ -58,7 +57,7 @@ https://help.keyman.com/developer/engine/android/latest-version/ | KEYMAN_MIN_TARGET_VERSION_WINDOWS | 10 | | KEYMAN_MIN_VERSION_ANDROID_SDK | 21 | | KEYMAN_MIN_VERSION_CPP | 17 | -| KEYMAN_MIN_VERSION_EMSCRIPTEN | 3.1.44 | +| KEYMAN_MIN_VERSION_EMSCRIPTEN | 3.1.58 | | KEYMAN_MIN_VERSION_MESON | 1.0.0 | | KEYMAN_MIN_VERSION_NODE_MAJOR | 20 | | KEYMAN_MIN_VERSION_NPM | 10.5.1 | diff --git a/ios/engine/KMEI/KeymanEngine/Classes/Manager.swift b/ios/engine/KMEI/KeymanEngine/Classes/Manager.swift index 5b77f79307..d1d134b249 100644 --- a/ios/engine/KMEI/KeymanEngine/Classes/Manager.swift +++ b/ios/engine/KMEI/KeymanEngine/Classes/Manager.swift @@ -831,12 +831,22 @@ public class Manager: NSObject, UIGestureRecognizerDelegate { shared.copyUserDefaults(to: nonShared, withKeys: keysToCopy, shouldOverwrite: true) do { try shared.copyFiles(to: nonShared) - FontManager.shared.registerCustomFonts() } catch { let message = ("Failed to copy from shared container: \(error)") os_log("%{public}s", log:KeymanEngineLogger.settings, type: .error, message) SentryManager.capture(error, message:message) } + + // This operation has a surprisingly high cost and isn't critical + // for getting the keyboard loaded and available to the OS. + // + // We certainly want it done _soon_... but we don't want it to cause + // the primary, synchronous initialization call from the OS to run so + // long that the keyboard fails to start due to its enforced time + // constraints. + DispatchQueue.main.async { + FontManager.shared.registerCustomFonts() + } } } diff --git a/ios/engine/KMEI/KeymanEngine/Classes/Resource Data/FontManager.swift b/ios/engine/KMEI/KeymanEngine/Classes/Resource Data/FontManager.swift index d64019cc27..6070de2c96 100644 --- a/ios/engine/KMEI/KeymanEngine/Classes/Resource Data/FontManager.swift +++ b/ios/engine/KMEI/KeymanEngine/Classes/Resource Data/FontManager.swift @@ -26,6 +26,17 @@ public class FontManager { fonts[url] = RegisteredFont(name: name, isRegistered: false) return name } + + private func cachedFont(at url: URL) -> RegisteredFont? { + if let font = fonts[url] { + return font + } + guard let name = readFontName(at: url) else { + return nil + } + fonts[url] = RegisteredFont(name: name, isRegistered: false) + return fonts[url] + } /// Registers all new fonts found in the font path. Call this after you have preloaded all your font files /// with `preloadFontFile(atPath:shouldOverwrite:)` @@ -33,8 +44,50 @@ public class FontManager { guard let keyboardDirs = Storage.active.keyboardDirs else { return } + + var fontSet: Set = [] for dir in keyboardDirs { - registerFonts(in: dir) + fontSet = fontSet.union(listFonts(in: dir)) + } + + registerListedFonts(fontSet) + } + + /** + * Iterates across all listed fonts, registering those not yet registered. + * Checks for, and filters out, any fonts already registered on the system. + * Also initializes the registration cache per URL if needed. + */ + private func registerListedFonts(_ initialFontSet: Set) { + // If we are unable to read the font file's properties sufficiently, + // skip it. We also don't need to register anything already registered or + // that cannot be registered due to loading/parsing errors. + // + // Calls to `cachedFont` after the `.filter` below may be assumed to have + // non-nil return values. + var fontSet = initialFontSet.filter { !(cachedFont(at: $0)?.isRegistered ?? true) } + + // The prior line filters out any entries where cachedFont(at: $0) would be nil. + // Batch-lookups all fonts lacking cache-confirmation of prior registration. + var fontNamesToRegister = missingFonts(from: Set(fontSet.map { cachedFont(at: $0)!.name })) + + for fontUrl in fontSet { + let fontName = cachedFont(at: fontUrl)!.name + + guard fontNamesToRegister.contains(fontName) else { + let message = "Did not register font at \(fontUrl) because font name \(fontName) is already registered" + os_log("%{public}s", log:KeymanEngineLogger.resources, type: .info, message) + continue + } + + let didRegister = _registerFont(at: fontUrl) + fonts[fontUrl] = RegisteredFont(name: fontName, isRegistered: didRegister) + + // We no longer need to register a font with this name, so drop it from + // the set to register. + if didRegister { + fontNamesToRegister.remove(fontName) + } } } @@ -43,6 +96,8 @@ public class FontManager { guard let keyboardDirs = Storage.active.keyboardDirs else { return } + // This doesn't use the expensive looped lookup operation seen in missingFonts, + // so there's no need to batch similar operations here. for dir in keyboardDirs { unregisterFonts(in: dir) } @@ -63,44 +118,29 @@ public class FontManager { } return name as String } + + private func _registerFont(at url: URL) -> Bool { + var errorRef: Unmanaged? + let fontName = fontName(at: url)! + let didRegister = CTFontManagerRegisterFontsForURL(url as CFURL, .none, &errorRef) + let error = errorRef?.takeRetainedValue() // Releases errorRef + if !didRegister { + let message = "Failed to register font \(fontName) at \(url) reason: \(String(describing: error))" + os_log("%{public}s", log:KeymanEngineLogger.resources, type: .error, message) + } else { + let message = "Registered font \(fontName) at \(url)" + os_log("%{public}s", log:KeymanEngineLogger.resources, type: .info, message) + } + + return didRegister + } /// - Parameters: /// - url: URL of the font to register /// - Returns: Font is registered. public func registerFont(at url: URL) -> Bool { - let fontName: String - if let font = fonts[url] { - if font.isRegistered { - return true - } - fontName = font.name - } else { - guard let name = readFontName(at: url) else { - return false - } - fontName = name - } - - let didRegister: Bool - if !fontExists(fontName) { - var errorRef: Unmanaged? - didRegister = CTFontManagerRegisterFontsForURL(url as CFURL, .none, &errorRef) - let error = errorRef?.takeRetainedValue() // Releases errorRef - if !didRegister { - let message = "Failed to register font \(fontName) at \(url) reason: \(String(describing: error))" - os_log("%{public}s", log:KeymanEngineLogger.resources, type: .error, message) - } else { - let message = "Registered font \(fontName) at \(url)" - os_log("%{public}s", log:KeymanEngineLogger.resources, type: .info, message) - } - } else { - didRegister = false - let message = "Did not register font at \(url) because font name \(fontName) is already registered" - os_log("%{public}s", log:KeymanEngineLogger.resources, type: .info, message) - } - let font = RegisteredFont(name: fontName, isRegistered: didRegister) - fonts[url] = font - return didRegister + registerListedFonts([url]) + return fonts[url]?.isRegistered ?? false } /// - Parameters: @@ -133,32 +173,53 @@ public class FontManager { return font.isRegistered } - - public func registerFonts(in directory: URL) { + + private func listFonts(in directory: URL) -> [URL] { guard let urls = try? FileManager.default.contentsOfDirectory(at: directory, includingPropertiesForKeys: nil) else { let message = "Could not list contents of directory \(directory)" os_log("%{public}s", log:KeymanEngineLogger.resources, type: .error, message) - return - } - for url in urls where url.lastPathComponent.hasFontExtension { - _ = registerFont(at: url) + return [] } + return urls.filter { $0.lastPathComponent.hasFontExtension } + } + + public func registerFonts(in directory: URL) { + let fontsToRegister = listFonts(in: directory) + registerListedFonts(Set(fontsToRegister)) } public func unregisterFonts(in directory: URL, fromSystemOnly: Bool = true) { - guard let urls = try? FileManager.default.contentsOfDirectory(at: directory, includingPropertiesForKeys: nil) else { - let message = "Could not list contents of directory \(directory)" - os_log("%{public}s", log:KeymanEngineLogger.resources, type: .error, message) - return - } - for url in urls where url.lastPathComponent.hasFontExtension { + let fontsToUnregister = listFonts(in: directory) + for url in fontsToUnregister { _ = unregisterFont(at: url, fromSystemOnly: fromSystemOnly) } } - private func fontExists(_ fontName: String) -> Bool { - return UIFont.familyNames.contains { familyName in - UIFont.fontNames(forFamilyName: familyName).contains(fontName) + /** + * Queries the system for existing registrations for the specified fonts with a single batch run. + * Only fonts that could not be found will be returned within the result set. + */ + private func missingFonts(from fontNames: Set) -> Set { + var fontsToFind = fontNames + + UIFont.familyNames.forEach { familyName in + if fontsToFind.count == 0 { + return + } + + let familyFonts = UIFont.fontNames(forFamilyName: familyName) + + for font in familyFonts { + if fontsToFind.contains(font) { + fontsToFind.remove(font) + } + + if fontsToFind.count == 0 { + break + } + } } + + return fontsToFind } } diff --git a/linux/keyman-config/keyman_config/kvk2ldml.py b/linux/keyman-config/keyman_config/kvk2ldml.py index 5b3ab85ae8..3b3aee281b 100755 --- a/linux/keyman-config/keyman_config/kvk2ldml.py +++ b/linux/keyman-config/keyman_config/kvk2ldml.py @@ -164,43 +164,43 @@ VKey_to_Iso = { } -def bytecheck(value, check): +def _bytecheck(value, check): if bytes([value & check[0]]) == check: return True else: return False -def get_nkey(file, fileContent, offset): +def _get_nkey(file, fileContent, offset): nkey = NKey() data = struct.unpack_from(" 256: @@ -224,7 +224,7 @@ def get_nstring(file, fileContent, offset): return stringdata.decode('utf-16'), offset + 2 + (2 * stringlength[0]) -def get_nbitmap(file, fileContent, offset): +def _get_nbitmap(file, fileContent, offset): bitmap = None bitmaplength = struct.unpack_from("CFBundlePackageType APPL CFBundleShortVersionString - Keyman $(PRODUCT_VERSION) for macOS + $(PRODUCT_VERSION) CFBundleSignature ???? CFBundleURLTypes diff --git a/mac/Keyman4MacIM/Keyman4MacIM/TextApiCompliance.h b/mac/Keyman4MacIM/Keyman4MacIM/TextApiCompliance.h index 6c80417faf..81cc4c3b34 100644 --- a/mac/Keyman4MacIM/Keyman4MacIM/TextApiCompliance.h +++ b/mac/Keyman4MacIM/Keyman4MacIM/TextApiCompliance.h @@ -16,6 +16,7 @@ NS_ASSUME_NONNULL_BEGIN @property (readonly) NSString *clientApplicationId; -(instancetype)initWithClient:(id) client applicationId:(NSString *)appId; +-(NSString *)description; -(void)checkCompliance:(id) client; -(void) checkComplianceAfterInsert:(id) client delete:(NSString *)textToDelete insert:(NSString *)textToInsert; -(BOOL)isComplianceUncertain; diff --git a/mac/Keyman4MacIM/Keyman4MacIM/TextApiCompliance.m b/mac/Keyman4MacIM/Keyman4MacIM/TextApiCompliance.m index 0f62fa61a8..e83439794b 100644 --- a/mac/Keyman4MacIM/Keyman4MacIM/TextApiCompliance.m +++ b/mac/Keyman4MacIM/Keyman4MacIM/TextApiCompliance.m @@ -73,7 +73,7 @@ NSString *const kKMLegacyApps = @"KMLegacyApps"; -(NSString *)description { - return [NSString stringWithFormat:@"complianceUncertain: %d, hasCompliantSelectionApi: %d, canReadText: %d, canReplaceText: %d, mustBackspaceUsingEvents: %d, clientAppId: %@, client: %@", self.complianceUncertain, self.hasCompliantSelectionApi, [self canReadText], [self canReplaceText], [self mustBackspaceUsingEvents], _clientApplicationId, _client]; + return [NSString stringWithFormat:@"complianceUncertain: %d, hasCompliantSelectionApi: %d, canReadText: %d, canReplaceText: %d, mustBackspaceUsingEvents: %d, clientApplicationId: %@, client: %@", self.complianceUncertain, self.hasCompliantSelectionApi, [self canReadText], [self canReplaceText], [self mustBackspaceUsingEvents], _clientApplicationId, _client]; } /** test to see if the API selectedRange functions properly for the text input client */ diff --git a/mac/Keyman4MacIM/KeymanTests/InputMethodTests.m b/mac/Keyman4MacIM/KeymanTests/InputMethodTests.m index 8eb9d974ce..7372a2a548 100644 --- a/mac/Keyman4MacIM/KeymanTests/InputMethodTests.m +++ b/mac/Keyman4MacIM/KeymanTests/InputMethodTests.m @@ -15,23 +15,27 @@ #import "TextApiCompliance.h" KMInputMethodEventHandler *testEventHandler = nil; +id testClient = nil; @interface InputMethodTests : XCTestCase @end @interface KMInputMethodEventHandler (Testing) - +@property (nonatomic, retain) TextApiCompliance* apiCompliance; +@property (nonatomic, retain) NSString* clientApplicationId; +@property BOOL contextChanged; - (instancetype)initWithClient:(NSString *)clientAppId client:(id) sender; - (NSRange) calculateInsertRangeForDeletedText:(NSString*)textToDelete selectionRange:(NSRange) selection; +- (void)checkTextApiCompliance:(id)client; @end @implementation InputMethodTests - (void)setUp { - id client = [[AppleCompliantTestClient alloc] init]; + testClient = [[AppleCompliantTestClient alloc] init]; NSString *clientAppId = @"com.compliant.app"; - testEventHandler = [[KMInputMethodEventHandler alloc]initWithClient:clientAppId client:client]; + testEventHandler = [[KMInputMethodEventHandler alloc]initWithClient:clientAppId client:testClient]; } - (void)tearDown { @@ -85,4 +89,43 @@ KMInputMethodEventHandler *testEventHandler = nil; XCTAssertTrue(correctResult, @"insert or replacement range expected to be {1,2}"); } +/** + * test compliance check of a KMInputMethodEventHandler with a nil client application ID + * not sure if this can ever happen, but the lifecycle of the input method is not 100% clear, + * and we would like this scenario, if it can occur, to not result in a crash + */ +- (void)testCheckCompliance_withUnknownApplicationId_createsComplianceObject { + id client = [[AppleCompliantTestClient alloc] init]; + KMInputMethodEventHandler *eventHandler = [[KMInputMethodEventHandler alloc]initWithClient:nil client:client]; + [eventHandler checkTextApiCompliance:client]; + XCTAssertNotNil(eventHandler.apiCompliance, @"apiCompliance object was not created"); +} + +- (void)testCheckCompliance_withNilComplianceObject_createsComplianceObject { + [testEventHandler checkTextApiCompliance:testClient]; + XCTAssertNotNil(testEventHandler.apiCompliance, @"apiCompliance object was not created"); +} + +- (void)testCheckCompliance_withChangedClientApplicationId_createsNewComplianceObject { + // first call causes textApiCompliance object to be created + [testEventHandler checkTextApiCompliance:testClient]; + TextApiCompliance *originalComplianceObject = testEventHandler.apiCompliance; + + testEventHandler.clientApplicationId = @"com.different.app"; + // second call causes new textApiCompliance object to be created due to stale application ID + [testEventHandler checkTextApiCompliance:testClient]; + XCTAssertNotEqualObjects(originalComplianceObject, testEventHandler.apiCompliance, @"New TextApiCompliance object not created for new client application ID"); +} + +- (void)testCheckCompliance_withContextChanged_createsNewComplianceObject { + // first call causes textApiCompliance object to be created + [testEventHandler checkTextApiCompliance:testClient]; + TextApiCompliance *originalComplianceObject = testEventHandler.apiCompliance; + + testEventHandler.contextChanged = YES; + // second call causes new textApiCompliance object to be created due to setting contextChanged flag + [testEventHandler checkTextApiCompliance:testClient]; + XCTAssertNotEqualObjects(originalComplianceObject, testEventHandler.apiCompliance, @"New TextApiCompliance object not created after contextChanged flag set"); +} + @end diff --git a/mac/KeymanEngine4Mac/KeymanEngine4Mac/Info.plist b/mac/KeymanEngine4Mac/KeymanEngine4Mac/Info.plist index 970606a26a..3f42d3e63f 100644 --- a/mac/KeymanEngine4Mac/KeymanEngine4Mac/Info.plist +++ b/mac/KeymanEngine4Mac/KeymanEngine4Mac/Info.plist @@ -17,7 +17,7 @@ CFBundlePackageType FMWK CFBundleShortVersionString - Keyman Engine $(PRODUCT_VERSION) for macOS + $(PRODUCT_VERSION) CFBundleSignature ???? CFBundleVersion diff --git a/resources/build/win/environment.inc.sh b/resources/build/win/environment.inc.sh index d2b351fcbc..620e96146a 100644 --- a/resources/build/win/environment.inc.sh +++ b/resources/build/win/environment.inc.sh @@ -23,8 +23,10 @@ source "$KEYMAN_ROOT/resources/build/win/environment_generated.inc.sh" WINDOWS_ROOT="$KEYMAN_ROOT/windows" WINDOWS_PROGRAM_APP="$WINDOWS_ROOT/bin/desktop" WINDOWS_PROGRAM_ENGINE="$WINDOWS_ROOT/bin/engine" +WINDOWS_PROGRAM_SUPPORT="$WINDOWS_ROOT/bin/support" WINDOWS_DEBUGPATH_APP="$WINDOWS_ROOT/debug/desktop" WINDOWS_DEBUGPATH_ENGINE="$WINDOWS_ROOT/debug/engine" +WINDOWS_DEBUGPATH_SUPPORT="$WINDOWS_ROOT/debug/suppor" COMMON_ROOT="$KEYMAN_ROOT/common/windows/delphi" OUTLIB="$WINDOWS_ROOT/lib" @@ -141,6 +143,8 @@ create-windows-output-folders() { mkdir -p "$OUTLIB" mkdir -p "$WINDOWS_PROGRAM_APP" mkdir -p "$WINDOWS_PROGRAM_ENGINE" + mkdir -p "$WINDOWS_PROGRAM_SUPPORT" mkdir -p "$WINDOWS_DEBUGPATH_APP" mkdir -p "$WINDOWS_DEBUGPATH_ENGINE" + mkdir -p "$WINDOWS_DEBUGPATH_SUPPORT" } \ No newline at end of file diff --git a/resources/locate_emscripten.inc.sh b/resources/locate_emscripten.inc.sh index f678e8449e..3d470f7577 100644 --- a/resources/locate_emscripten.inc.sh +++ b/resources/locate_emscripten.inc.sh @@ -69,5 +69,7 @@ _select_emscripten_version_with_emsdk() { git pull ./emsdk install "$KEYMAN_MIN_VERSION_EMSCRIPTEN" ./emsdk activate "$KEYMAN_MIN_VERSION_EMSCRIPTEN" + cd upstream/emscripten + npm install popd > /dev/null } diff --git a/web/src/engine/osk/src/visualKeyboard.ts b/web/src/engine/osk/src/visualKeyboard.ts index 013ad76241..570a82a209 100644 --- a/web/src/engine/osk/src/visualKeyboard.ts +++ b/web/src/engine/osk/src/visualKeyboard.ts @@ -1239,6 +1239,7 @@ export default class VisualKeyboard extends EventEmitter implements Ke const groupStyle = getComputedStyle(this.layerGroup.element); const isInDOM = computedStyle.height != '' && computedStyle.height != 'auto'; + const isGroupInDOM = groupStyle.height != '' && groupStyle.height != 'auto'; if (computedStyle.border) { this._borderWidth = new ParsedLengthStyle(computedStyle.borderWidth).val; @@ -1251,10 +1252,11 @@ export default class VisualKeyboard extends EventEmitter implements Ke this._computedHeight = this.height; } else if (isInDOM) { this._computedWidth = parseInt(computedStyle.width, 10); - if (!this._computedWidth) { - this._computedWidth = parseInt(groupStyle.width, 10); - } this._computedHeight = parseInt(computedStyle.height, 10); + } else if (isGroupInDOM) { + // May occur for documentation-keyboards, which are detached from their VisualKeyboard base. + this._computedWidth = parseInt(groupStyle.width, 10); + this._computedHeight = parseInt(groupStyle.height, 10); } else { // Cannot perform layout operations! return; @@ -1597,6 +1599,16 @@ export default class VisualKeyboard extends EventEmitter implements Ke // the page. kbdObj.appendStyleSheet(); + // Unset the width + height we used thus far; this method's consumer may choose to rescale + // the returned element. If so, we don't want to use our outdated value by mistake. + // + // While `kbdObj.setSize()` could be used in theory, it _also_ unsets the element styling. + // We actually wish to _leave_ this styling in place - one of our parameters is `height`, and + // it should remain in place in the styling on the output element as the default in case + // the consumer _doesn't_ add styling afterward. + delete kbdObj._width; + delete kbdObj._height; + return classWrapper; } diff --git a/windows/src/.gitignore b/windows/src/.gitignore index 350b7e4bdb..065f4a07f3 100644 --- a/windows/src/.gitignore +++ b/windows/src/.gitignore @@ -34,3 +34,8 @@ keyman-windows-coverity.tgz # This file is still generated by devtools. TODO: eliminate in future PathDefines.mak + +# .res files, generated during build +desktop/kmshell/kmshell.res +engine/keyman/keyman.res +engine/keyman32/version64.res diff --git a/windows/src/README.md b/windows/src/README.md index 1d057482bb..b18b626dc0 100644 --- a/windows/src/README.md +++ b/windows/src/README.md @@ -1,40 +1,39 @@ -# Keyman for Windows and Keyman Developer +# Keyman for Windows ## Build Prerequisites * See [Windows Build Environment Configuration](../../docs/build/windows.md). -## Building Keyman for Windows and Keyman Developer +## Building Keyman for Windows -1. Start 'Developer Command Prompt for VS 2019'. -2. Run `nmake build` from the **windows/src** folder. +1. Start 'Git Bash' (part of Git for Windows). +2. Run `windows/src/build.sh`. 3. Artifacts from a successful build will be placed in **windows/bin** folder. -*Note*: running `nmake build` will currently reset the packages and path settings +*Note*: running `build.sh` will currently reset the packages and path settings in your Delphi environment. If you use Delphi for other projects, you should consider building Keyman under a login user dedicated to it, or in a VM. -Type `nmake` to see build targets. Common build targets are: +Type `build.sh` to see build targets and actions. Common build actions are: -* `nmake build` -: builds Keyman for Windows and Keyman Developer +* `build.sh build` +: builds Keyman for Windows -* `nmake clean` +* `build.sh clean` : remove temporary files and build artifacts -* `nmake release` +* `build.sh publish` : makes a release of all Keyman Windows projects -* `nmake install` +* `build.sh install` : install some or all components to Program Files (requires elevated command prompt). ### Building without Delphi -It is possible to build all components that do _not_ require Delphi by adding -the environment variable `NODELPHI=1` before starting the build. Currently many -components are Delphi-based, but if you are working just in Keyman Core, the -compiler, or Keyman Engine's C++ components, you may be able to get away without -building them. In this situation, we recommend copying the relevant Delphi-built +It is possible to build all components that do _not_ require Delphi. Currently +many components are Delphi-based, but if you are working just in Keyman Core, or +Keyman Engine's C++ components, you may be able to get away without building +them. In this situation, we recommend copying the relevant Delphi-built components into windows/bin folders from a compatible installed version of Keyman for testing and debugging purposes. @@ -45,8 +44,8 @@ build, you will need to obtain valid code signing certificates. See Certificates, below. Official release builds for Keyman are built in the Keyman project's CI environment. -1. Start 'Developer Command Prompt for VS 2019'. -2. Run `nmake release` from the **windows/src** folder. +1. Start 'Git Bash'. +2. Run `windows/src/build.sh publish`. 3. Artifacts from a successful build will be placed in **windows/release** folder. 4. **buildtools/help-keyman-com.sh** will push updated documentation to @@ -65,7 +64,7 @@ globally trusted. The environment variables `SC_PFX_SHA1` and `SC_PFX_SHA256` can be set to custom certificate paths. The Keyman repo can build test certificates for you. To build your own, run -`./build.sh certificates` from **common/windows/delphi/tools/certificates** to +`./common/windows/delphi/tools/certificates/build.sh certificates` to build and install your own local root CA "**KeymanTestCA**" certificates. If you specify a password for the certificate, you'll need to set that in the environment variable `SC_PWD`. @@ -76,7 +75,7 @@ You do not need to install the **KeymanTest** certificates, only the **KeymanTestCA** certificates. If you have not already installed the **KeymanTestCA** certificates using the -`nmake` command above, to manually install the Keyman **KeymanTestCA** +`build.sh` command above, to manually install the Keyman **KeymanTestCA** certificates, do the following in **common/windows/delphi/tools/certificates**: 1. Open the certificate and click 'Install certificate...' to open the diff --git a/windows/src/build.sh b/windows/src/build.sh index a1fc4d0e1a..4ef6da65b8 100755 --- a/windows/src/build.sh +++ b/windows/src/build.sh @@ -18,6 +18,7 @@ builder_describe \ ":engine Keyman Engine for Windows" \ ":desktop Keyman for Windows" \ ":components=global/delphi Delphi components" \ + ":support Support tools" \ ":test=test/unit-tests Shared unit tests" \ ":fv=../../oem/firstvoices/windows/src/inst OEM FirstVoices for Windows app" diff --git a/windows/src/desktop/kmshell/kmshell.res b/windows/src/desktop/kmshell/kmshell.res deleted file mode 100644 index cfcbd309f1..0000000000 Binary files a/windows/src/desktop/kmshell/kmshell.res and /dev/null differ diff --git a/windows/src/engine/keyman/build.sh b/windows/src/engine/keyman/build.sh index 50ef210ce2..ce34599410 100755 --- a/windows/src/engine/keyman/build.sh +++ b/windows/src/engine/keyman/build.sh @@ -8,6 +8,7 @@ THIS_SCRIPT="$(readlink -f "${BASH_SOURCE[0]}")" builder_describe "Keyman main host process (32-bit)" \ @/common/include \ @/common/windows/delphi \ + @/windows/src/global/delphi \ clean configure build test publish install debug-manifest builder_parse "$@" diff --git a/windows/src/support/Makefile b/windows/src/support/Makefile deleted file mode 100644 index 56609e21e4..0000000000 --- a/windows/src/support/Makefile +++ /dev/null @@ -1,38 +0,0 @@ -# -# Support Makefile -# - -!ifdef NODELPHI -TARGETS=etl2log texteditor -!else -TARGETS=oskbulkrenderer etl2log texteditor -!endif -CLEANS=clean-support - -!include ..\Header.mak - -# ---------------------------------------------------------------------- - -oskbulkrenderer: .virtual - cd $(ROOT)\src\support\oskbulkrenderer - $(MAKE) $(TARGET) - -etl2log: .virtual - cd $(ROOT)\src\support\etl2log - $(MAKE) $(TARGET) - -texteditor: .virtual - cd $(ROOT)\src\support\texteditor - $(MAKE) $(TARGET) - -# ---------------------------------------------------------------------- - -clean-support: - cd $(ROOT)\src\support - -del version.txt - -!include ..\Target.mak - -# ---------------------------------------------------------------------- -# EOF -# ---------------------------------------------------------------------- diff --git a/windows/src/support/build.sh b/windows/src/support/build.sh new file mode 100755 index 0000000000..f9f20f1716 --- /dev/null +++ b/windows/src/support/build.sh @@ -0,0 +1,22 @@ +#!/usr/bin/env bash +## START STANDARD BUILD SCRIPT INCLUDE +# adjust relative paths as necessary +THIS_SCRIPT="$(readlink -f "${BASH_SOURCE[0]}")" +. "${THIS_SCRIPT%/*}/../../../resources/build/builder.inc.sh" +## END STANDARD BUILD SCRIPT INCLUDE + +builder_describe \ + "Keyman for Windows support tools" \ + \ + clean \ + configure \ + build \ + test \ + \ + :oskbulkrenderer \ + :etl2log \ + :texteditor + +builder_parse "$@" + +builder_run_child_actions clean configure build test publish install diff --git a/windows/src/support/charident/Makefile b/windows/src/support/charident/Makefile deleted file mode 100644 index cff6741677..0000000000 --- a/windows/src/support/charident/Makefile +++ /dev/null @@ -1,20 +0,0 @@ -# -# charident Makefile -# - -!include ..\..\Defines.mak - -build: version.res dirs - $(DCC32) charident.dpr - $(COPY) charident.exe $(PROGRAM)\support - -clean: def-clean - -signcode: - $(SIGNCODE) /d "Character Identifier" $(PROGRAM)\support\charident.exe - -wrap-symbols: - $(SYMSTORE) $(PROGRAM)\support\charident.exe /t keyman-windows -#TODO: $(SYMSTORE) $(DEBUGPATH)\support\charident.dbg /t keyman-windows - -!include ..\..\Target.mak diff --git a/windows/src/support/etl2log/Makefile b/windows/src/support/etl2log/Makefile deleted file mode 100644 index 48bdb1a592..0000000000 --- a/windows/src/support/etl2log/Makefile +++ /dev/null @@ -1,22 +0,0 @@ -# -# etl2log Makefile -# - -!include ..\..\Defines.mak - -build: version.res dirs - $(MSBUILD) etl2log.vcxproj $(MSBUILD_BUILD) - $(COPY) $(WIN32_TARGET_PATH)\etl2log.exe $(PROGRAM)\support - $(COPY) $(WIN32_TARGET_PATH)\etl2log.pdb $(DEBUGPATH)\support - -clean: def-clean - $(MSBUILD) etl2log.vcxproj $(MSBUILD_CLEAN) - -signcode: - $(SIGNCODE) /d "Keyman Engine Tools" $(PROGRAM)\support\etl2log.exe - -wrap-symbols: - $(SYMSTORE) $(PROGRAM)\support\etl2log.exe /t keyman-windows - $(SYMSTORE) $(DEBUGPATH)\support\etl2log.pdb /t keyman-windows - -!include ..\..\Target.mak diff --git a/windows/src/support/etl2log/build.sh b/windows/src/support/etl2log/build.sh new file mode 100755 index 0000000000..e2fdee1acd --- /dev/null +++ b/windows/src/support/etl2log/build.sh @@ -0,0 +1,40 @@ +#!/usr/bin/env bash +## START STANDARD BUILD SCRIPT INCLUDE +# adjust relative paths as necessary +THIS_SCRIPT="$(readlink -f "${BASH_SOURCE[0]}")" +. "${THIS_SCRIPT%/*}/../../../../resources/build/builder.inc.sh" +## END STANDARD BUILD SCRIPT INCLUDE + +builder_describe "etl2log" \ + clean configure build test + +builder_parse "$@" + +#------------------------------------------------------------------------------------------------------------------- + +source "$KEYMAN_ROOT/resources/build/win/environment.inc.sh" +WIN32_TARGET="$WIN32_TARGET_PATH/etl2log.exe" + +builder_describe_outputs \ + configure:project /resources/build/win/delphi_environment_generated.inc.sh \ + build:project /windows/src/support/etl2log/$WIN32_TARGET + +#------------------------------------------------------------------------------------------------------------------- + +function do_clean() { + vs_msbuild etl2log.vcxproj //t:Clean + clean_windows_project_files +} + +function do_build() { + create-windows-output-folders + build_version.res + vs_msbuild etl2log.vcxproj //t:Build "//p:Platform=Win32" + cp "$WIN32_TARGET" "$WINDOWS_PROGRAM_SUPPORT" + cp "$WIN32_TARGET_PATH/etl2log.pdb" "$WINDOWS_DEBUGPATH_SUPPORT" +} + +builder_run_action clean:project do_clean +builder_run_action configure:project configure_windows_build_environment +builder_run_action build:project do_build +# builder_run_action test:project do_test diff --git a/windows/src/support/kdebug/Makefile b/windows/src/support/kdebug/Makefile deleted file mode 100644 index 1a13a18ebe..0000000000 --- a/windows/src/support/kdebug/Makefile +++ /dev/null @@ -1,21 +0,0 @@ -# -# KDebug Makefile -# - -!include ..\..\Defines.mak - -!ifdef DEBUG - NMCFG=kdebug - Win32 Debug -!else - NMCFG=kdebug - Win32 Release -!endif - -install: dirs build - -build: version.res - $(NMAKE) /f kdebug.mak "CFG=$(NMCFG)" - -clean: def-clean - $(NMAKE) /f kdebug.mak "CFG=$(NMCFG)" CLEAN - -!include ..\..\Target.mak diff --git a/windows/src/support/keycodetester/Makefile b/windows/src/support/keycodetester/Makefile deleted file mode 100644 index 38687abaeb..0000000000 --- a/windows/src/support/keycodetester/Makefile +++ /dev/null @@ -1,15 +0,0 @@ -# -# Keycodetester Makefile -# - -!include ..\..\Defines.mak - -install: dirs build - $(COPY) keycodetester.exe $(PROGRAM)\bldutil - -build: - $(DCC32) keycodetester.dpr - -clean: def-clean - -!include ..\..\Target.mak diff --git a/windows/src/support/km_yim/Makefile b/windows/src/support/km_yim/Makefile deleted file mode 100644 index 1aef5f80f0..0000000000 --- a/windows/src/support/km_yim/Makefile +++ /dev/null @@ -1,24 +0,0 @@ -# -# TODO: remove this project -# - -!include ..\..\Defines.mak - -build: -# version.res - $(DCC32) km_yim.dpr - rem $(TDSPACK) $(PROGRAM)\desktop\km_yim.exe km_yim.tds - rem $(TDS2DBG) $(PROGRAM)\desktop\km_yim.exe - $(WZZIP) inst_km_yim.zip km_yim.exe -# $(WZSE) inst_km_yim -setup -t inst_km_yim.dialog.txt -st "Tavultesoft Keyman Desktop Yahoo Messenger Addin" -c km_yim.exe - -clean: def-clean - if exist inst_km_yim.zip del inst_km_yim.zip - -signcode: - $(SIGNCODE) /d "Tavultesoft Keyman Desktop Yahoo Messenger Addin" inst_km_yim.exe - -wrap-symbols: - rem - -!include ..\..\Target.mak diff --git a/windows/src/support/kmkb0045/Makefile b/windows/src/support/kmkb0045/Makefile deleted file mode 100644 index 3e914c8acd..0000000000 --- a/windows/src/support/kmkb0045/Makefile +++ /dev/null @@ -1,19 +0,0 @@ -# -# TODO: remove this project -# - -!include ..\..\Defines.mak - -build: version.res manifest.res - $(DCC32) kmkb0045.dpr - $(SENTRYTOOL_DELPHIPREP) kmkb0045.exe -dpr kmkb0045.dpr - $(TDS2DBG) kmkb0045.exe - $(COPY) kmkb0045.exe $(PROGRAM)\support - -clean: def-clean - -signcode: - $(SIGNCODE) /d "Tavultesoft KMKB0045" $(PROGRAM)\support\kmkb0045.exe - - -!include ..\..\Target.mak diff --git a/windows/src/support/oskbulkrenderer/Makefile b/windows/src/support/oskbulkrenderer/Makefile deleted file mode 100644 index 65b8e02ba6..0000000000 --- a/windows/src/support/oskbulkrenderer/Makefile +++ /dev/null @@ -1,24 +0,0 @@ -# -# oskbulkrenderer Makefile -# - -!include ..\..\Defines.mak - -build: version.res dirs - $(DELPHI_MSBUILD) oskbulkrenderer.dproj "/p:Platform=Win32" - - $(SENTRYTOOL_DELPHIPREP) $(WIN32_TARGET_PATH)\oskbulkrenderer.exe -dpr oskbulkrenderer.dpr - $(TDS2DBG) $(WIN32_TARGET_PATH)\oskbulkrenderer.exe - $(COPY) $(WIN32_TARGET_PATH)\oskbulkrenderer.exe $(PROGRAM)\support - if exist $(WIN32_TARGET_PATH)\oskbulkrenderer.dbg $(COPY) $(WIN32_TARGET_PATH)\oskbulkrenderer.dbg $(DEBUGPATH)\support - -clean: def-clean - -rd /s/q Win32 - -signcode: - rem Not signing this utility - -wrap-symbols: - @rem - -!include ..\..\Target.mak diff --git a/windows/src/support/oskbulkrenderer/build.sh b/windows/src/support/oskbulkrenderer/build.sh new file mode 100755 index 0000000000..76fa8a4032 --- /dev/null +++ b/windows/src/support/oskbulkrenderer/build.sh @@ -0,0 +1,39 @@ +#!/usr/bin/env bash +## START STANDARD BUILD SCRIPT INCLUDE +# adjust relative paths as necessary +THIS_SCRIPT="$(readlink -f "${BASH_SOURCE[0]}")" +. "${THIS_SCRIPT%/*}/../../../../resources/build/builder.inc.sh" +## END STANDARD BUILD SCRIPT INCLUDE + +builder_describe "oskbuildrenderer" \ + clean configure build test + +builder_parse "$@" + +#------------------------------------------------------------------------------------------------------------------- + +source "$KEYMAN_ROOT/resources/build/win/environment.inc.sh" +WIN32_TARGET="$WIN32_TARGET_PATH/oskbulkrenderer.exe" + +builder_describe_outputs \ + configure:project /resources/build/win/delphi_environment_generated.inc.sh \ + build:project /windows/src/support/oskbulkrenderer/$WIN32_TARGET + +#------------------------------------------------------------------------------------------------------------------- + +function do_clean() { + clean_windows_project_files +} + +function do_build() { + create-windows-output-folders + build_version.res + delphi_msbuild oskbulkrenderer.dproj "//p:Platform=Win32" + + cp "$WIN32_TARGET" "$WINDOWS_PROGRAM_SUPPORT" +} + +builder_run_action clean:project do_clean +builder_run_action configure:project configure_windows_build_environment +builder_run_action build:project do_build +# builder_run_action test:project do_test diff --git a/windows/src/support/richedit_examine/Makefile b/windows/src/support/richedit_examine/Makefile deleted file mode 100644 index adacba5901..0000000000 --- a/windows/src/support/richedit_examine/Makefile +++ /dev/null @@ -1,15 +0,0 @@ -# -# richedit_examine Makefile -# - -!include ..\..\Defines.mak - -install: dirs build - $(COPY) richedit_examine.exe $(PROGRAM)\bldutil - -build: version.res - $(DCC32) richedit_examine.dpr - -clean: def-clean - -!include ..\..\Target.mak diff --git a/windows/src/support/texteditor/Makefile b/windows/src/support/texteditor/Makefile deleted file mode 100644 index 473bf57598..0000000000 --- a/windows/src/support/texteditor/Makefile +++ /dev/null @@ -1,36 +0,0 @@ -# -# Keyman Text Editor Makefile -# - -!include ..\..\Defines.mak - -build: - $(MSBUILD) editor.vcxproj $(MSBUILD_BUILD) /p:Platform=x86 - $(MSBUILD) editor.vcxproj $(MSBUILD_BUILD) /p:Platform=x64 - $(COPY) $(WIN32_TARGET_PATH)\editor32.exe $(PROGRAM)\support - $(COPY) $(WIN32_TARGET_PATH)\editor32.pdb $(DEBUGPATH)\support - $(COPY) $(X64_TARGET_PATH)\editor64.exe $(PROGRAM)\support - $(COPY) $(X64_TARGET_PATH)\editor64.pdb $(DEBUGPATH)\support - -clean: def-clean - $(MSBUILD) $(MSBUILD_CLEAN) editor.sln - -signcode: - $(SIGNCODE) /d "Text Editor for testing Keyman" $(PROGRAM)\support\editor32.exe - $(SIGNCODE) /d "Text Editor for testing Keyman" $(PROGRAM)\support\editor64.exe - -install: - $(COPY) $(PROGRAM)\support\editor32.exe "$(INSTALLPATH_KEYMANENGINE)" - $(COPY) $(PROGRAM)\support\editor64.exe "$(INSTALLPATH_KEYMANENGINE)" - -wrap-symbols: - $(SYMSTORE) $(PROGRAM)\support\editor32.exe /t keyman-windows - $(SYMSTORE) $(PROGRAM)\support\editor64.exe /t keyman-windows - $(SYMSTORE) $(DEBUGPATH)\support\editor32.pdb /t keyman-windows - $(SYMSTORE) $(DEBUGPATH)\support\editor64.pdb /t keyman-windows - - -!include ..\..\Target.mak -# ---------------------------------------------------------------------- -# EOF -# ---------------------------------------------------------------------- diff --git a/windows/src/support/texteditor/build.sh b/windows/src/support/texteditor/build.sh new file mode 100755 index 0000000000..312ee1d0f4 --- /dev/null +++ b/windows/src/support/texteditor/build.sh @@ -0,0 +1,44 @@ +#!/usr/bin/env bash +## START STANDARD BUILD SCRIPT INCLUDE +# adjust relative paths as necessary +THIS_SCRIPT="$(readlink -f "${BASH_SOURCE[0]}")" +. "${THIS_SCRIPT%/*}/../../../../resources/build/builder.inc.sh" +## END STANDARD BUILD SCRIPT INCLUDE + +builder_describe "texteditor" \ + clean configure build test + +builder_parse "$@" + +#------------------------------------------------------------------------------------------------------------------- + +source "$KEYMAN_ROOT/resources/build/win/environment.inc.sh" +WIN32_TARGET="$WIN32_TARGET_PATH/editor32.exe" +X64_TARGET="$X64_TARGET_PATH/editor64.exe" + +builder_describe_outputs \ + configure:project /resources/build/win/delphi_environment_generated.inc.sh \ + build:project /windows/src/support/texteditor/$WIN32_TARGET + +#------------------------------------------------------------------------------------------------------------------- + +function do_clean() { + vs_msbuild Editor.vcxproj //t:Clean + clean_windows_project_files +} + +function do_build() { + create-windows-output-folders + # build_version.res + vs_msbuild Editor.vcxproj //t:Build "//p:Platform=Win32" + vs_msbuild Editor.vcxproj //t:Build "//p:Platform=x64" + cp "$WIN32_TARGET" "$WINDOWS_PROGRAM_SUPPORT" + cp "$X64_TARGET" "$WINDOWS_PROGRAM_SUPPORT" + cp "$WIN32_TARGET_PATH/editor32.pdb" "$WINDOWS_DEBUGPATH_SUPPORT" + cp "$X64_TARGET_PATH/editor64.pdb" "$WINDOWS_DEBUGPATH_SUPPORT" +} + +builder_run_action clean:project do_clean +builder_run_action configure:project configure_windows_build_environment +builder_run_action build:project do_build +# builder_run_action test:project do_test diff --git a/windows/src/support/windowinfo/Makefile b/windows/src/support/windowinfo/Makefile deleted file mode 100644 index ac7da2c182..0000000000 --- a/windows/src/support/windowinfo/Makefile +++ /dev/null @@ -1,15 +0,0 @@ -# -# windowinfo Makefile -# - -!include ..\..\Defines.mak - -install: dirs build - $(COPY) windowinfo.exe $(PROGRAM)\bldutil - -build: version.res - $(DCC32) windowinfo.dpr - -clean: def-clean - -!include ..\..\Target.mak diff --git a/windows/src/test/manual-tests/integration-tests/Makefile b/windows/src/test/manual-tests/integration-tests/Makefile deleted file mode 100644 index 093dc44140..0000000000 --- a/windows/src/test/manual-tests/integration-tests/Makefile +++ /dev/null @@ -1,26 +0,0 @@ -# -# Integration Tests Makefile. -# - -# ---------------------------------------------------------------------- - -TARGETS=keymanapi - -test: - $(MAKE) "TARGET=test" $(TARGETS) - -!include ..\..\Header.mak - -# ---------------------------------------------------------------------- - -keymanapi: - cd $(ROOT)\src\test\integration-tests\keymanapi - $(MAKE) $(TARGET) - -# ---------------------------------------------------------------------- - -!include ..\..\Target.mak - -# ---------------------------------------------------------------------- -# EOF -# ---------------------------------------------------------------------- diff --git a/windows/src/test/manual-tests/integration-tests/keymanapi/Makefile b/windows/src/test/manual-tests/integration-tests/keymanapi/Makefile deleted file mode 100644 index 7becbb044d..0000000000 --- a/windows/src/test/manual-tests/integration-tests/keymanapi/Makefile +++ /dev/null @@ -1,23 +0,0 @@ -# -# Integration tests for keymanapi -# - -!include ..\..\..\Defines.mak - -!ifdef EXCLUDE_ELEVATED -TEST_MODE=--exclude:Elevated -!endif - -test: build - $(WIN32_TARGET_PATH)\keymanapi_test.exe -b -exit:continue $(TEST_MODE) - $(WIN64_TARGET_PATH)\keymanapi_test.exe -b -exit:continue $(TEST_MODE) - -build: - $(DELPHI_MSBUILD) "/p:Platform=Win32" keymanapi_test.dproj - $(DELPHI_MSBUILD) "/p:Platform=Win64" keymanapi_test.dproj - -clean: def-clean - -rd /s/q Win32 - -rd /s/q Win64 - -!include ..\..\..\Target.mak diff --git a/windows/src/test/manual-tests/regressiontest/Makefile b/windows/src/test/manual-tests/regressiontest/Makefile deleted file mode 100644 index dbfa70078c..0000000000 --- a/windows/src/test/manual-tests/regressiontest/Makefile +++ /dev/null @@ -1,16 +0,0 @@ -# -# REGRESSIONTEST Makefile -# - - -!include ..\..\Defines.mak - -build: dirs - $(DCC32) regressiontest.dpr - $(COPY) regressiontest.exe $(PROGRAM)\support - -clean: def-clean - cd tests - $(MAKE) clean - -!include ..\..\Target.mak diff --git a/windows/src/test/manual-tests/regressiontest/tests/Makefile b/windows/src/test/manual-tests/regressiontest/tests/Makefile deleted file mode 100644 index 01f8705399..0000000000 --- a/windows/src/test/manual-tests/regressiontest/tests/Makefile +++ /dev/null @@ -1,11 +0,0 @@ - -!include ..\..\..\Defines.mak - -all: - for %d in (*.kmn) do $(PROGRAM)\bin\kmc.cmd build "%d" - -.kmn.kmx: - &$(PROGRAM)\bin\kmc.cmd build $** - -clean: - -del *.kmx diff --git a/windows/src/test/manual-tests/test_httpuploader/Makefile b/windows/src/test/manual-tests/test_httpuploader/Makefile deleted file mode 100644 index b6250f4bfd..0000000000 --- a/windows/src/test/manual-tests/test_httpuploader/Makefile +++ /dev/null @@ -1,18 +0,0 @@ -# -# test_httpuploader Makefile -# - -!include ..\..\Defines.mak - -build: version.res manifest.res - $(DCC32) test_httpuploader.dpr - -icons: - rc icons.rc - -clean: def-clean - -signcode: - rem no signcode - -!include ..\..\Target.mak