diff --git a/HISTORY.md b/HISTORY.md
index ce88c9fcdf..2b0aa8171a 100644
--- a/HISTORY.md
+++ b/HISTORY.md
@@ -1,5 +1,14 @@
# Keyman Version History
+## 17.0.44 alpha 2023-02-07
+
+* chore(linux): Set test-helper script executable (#8178)
+* chore(linux): Update debian changelog (#8156)
+
+## 17.0.43 alpha 2023-02-06
+
+* chore(linux): Build with meson instead of autotools ️ (#8111)
+
## 17.0.42 alpha 2023-02-03
* chore(deps): bump http-cache-semantics from 4.1.0 to 4.1.1 (#8144)
diff --git a/VERSION.md b/VERSION.md
index 8a45cf78ed..288124f305 100644
--- a/VERSION.md
+++ b/VERSION.md
@@ -1 +1 @@
-17.0.43
\ No newline at end of file
+17.0.45
\ No newline at end of file
diff --git a/core/src/meson.build b/core/src/meson.build
index cbf2f8c6da..79f06a9706 100644
--- a/core/src/meson.build
+++ b/core/src/meson.build
@@ -58,18 +58,7 @@ if compiler.get_id() == 'emscripten'
links = []
endif
-lib = library('kmnkbp0',
- 'option.cpp',
- 'keyboard.cpp',
- 'state.cpp',
- 'km_kbp_context_api.cpp',
- 'km_kbp_keyboard_api.cpp',
- 'km_kbp_options_api.cpp',
- 'km_kbp_state_api.cpp',
- 'km_kbp_debug_api.cpp',
- 'km_kbp_processevent_api.cpp',
- 'jsonpp.cpp',
- 'mock/mock_processor.cpp',
+kmx_files = files(
'kmx/kmx_consts.cpp',
'kmx/kmx_processevent.cpp',
'kmx/kmx_actions.cpp',
@@ -84,14 +73,58 @@ lib = library('kmnkbp0',
'kmx/kmx_options.cpp',
'kmx/kmx_processor.cpp',
'kmx/kmx_xstring.cpp',
+)
+
+api_files = files(
+ 'km_kbp_context_api.cpp',
+ 'km_kbp_keyboard_api.cpp',
+ 'km_kbp_options_api.cpp',
+ 'km_kbp_state_api.cpp',
+ 'km_kbp_debug_api.cpp',
+ 'km_kbp_processevent_api.cpp',
+)
+
+core_files = files(
+ 'option.cpp',
+ 'keyboard.cpp',
+ 'state.cpp',
+ 'jsonpp.cpp',
'utfcodec.cpp',
+)
+
+mock_files = files(
+ 'mock/mock_processor.cpp',
+)
+
+lib = library('kmnkbp0',
+ api_files,
+ core_files,
+ kmx_files,
+ mock_files,
version_res,
cpp_args: defns + warns + flags,
link_args: links,
version: lib_version,
include_directories: inc,
+ pic: true,
install: true)
+if host_machine.system() == 'linux'
+ # on Linux we need the static lib for ibus-keyman tests
+ static_library('kmnkbp0-static',
+ api_files,
+ core_files,
+ kmx_files,
+ mock_files,
+ version_res,
+ cpp_args: defns + warns + flags,
+ link_args: links,
+ include_directories: inc,
+ pic: true,
+ install: false
+ )
+endif
+
headerdirs = [ '.', 'keyman' ] # subdirectories of ${prefix}/include to add to header path
kmnkbp = declare_dependency(link_with: lib, include_directories: inc)
diff --git a/core/tests/meson.build b/core/tests/meson.build
index 3b33c1ef23..be58e6975c 100644
--- a/core/tests/meson.build
+++ b/core/tests/meson.build
@@ -8,7 +8,7 @@
# Note: this version of cmpfiles ignores line endings, which is better for platform independence
cmpfiles = ['-c', 'import sys; a = open(sys.argv[1], \'r\').read(); b = open(sys.argv[2], \'r\').read(); exit(not (a==b))']
-stnds = join_paths(meson.source_root(), 'tests', 'standards')
+stnds = join_paths(meson.current_source_dir(), 'standards')
libsrc = include_directories(join_paths('../', 'src'))
diff --git a/core/tests/unit/kmx/meson.build b/core/tests/unit/kmx/meson.build
index 63188c764a..c347b2e8fd 100644
--- a/core/tests/unit/kmx/meson.build
+++ b/core/tests/unit/kmx/meson.build
@@ -25,14 +25,28 @@ else
test_path = meson.current_build_dir()
endif
+coretest_files = files(
+ 'kmx_test_source.cpp',
+)
+
kmx = executable('kmx',
'kmx.cpp',
- 'kmx_test_source.cpp',
+ coretest_files,
cpp_args: defns + warns,
include_directories: [inc, libsrc],
link_args: links + tests_flags,
objects: lib.extract_all_objects())
+test_lib = static_library('kmnkbp-tests',
+ coretest_files,
+ cpp_args: defns + warns + flags,
+ include_directories: [inc, libsrc],
+ link_args: links + tests_flags,
+ objects: lib.extract_all_objects(),
+ pic: true,
+ install: false
+)
+
tests = [
'000 - null keyboard',
'001 - basic input UnicodeI',
@@ -87,7 +101,7 @@ tests = [
]
if build_machine.system() == 'windows'
- kmcomp = find_program(join_paths(meson.source_root(),'..','..','..','windows','bin','developer','kmcomp.exe'), 'kmcomp.exe', required: false)
+ kmcomp = find_program(join_paths(meson.current_source_dir(),'..','..','..','..','windows','bin','developer','kmcomp.exe'), 'kmcomp.exe', required: false)
kmcomp_cmd = [kmcomp]
copy_cmd = [find_program('cmd.exe', required: true), '/c', 'copy']
cat_cmd = [find_program('cmd.exe', required: true), '/c', 'type']
diff --git a/docs/linux/keyman-config.md b/docs/linux/keyman-config.md
index c12db30c94..f050fd96ad 100644
--- a/docs/linux/keyman-config.md
+++ b/docs/linux/keyman-config.md
@@ -13,7 +13,8 @@ sudo apt install python3-lxml python3-magic python3-numpy python3-qrcode python3
python3-setuptools python3-pip python3-dbus ibus libglib2.0-bin liblocale-gettext-perl
```
-Either `python3-raven` or `python3-sentry-sdk` (>= 1.4) is required as well. On Ubuntu 22.04 and later run:
+Either `python3-raven` or `python3-sentry-sdk` (>= 1.4) is required as well.
+On Ubuntu 22.04 and later run:
```bash
sudo apt install python3-sentry-sdk
@@ -34,8 +35,8 @@ or install it with pip:
pip3 install sentry-sdk
```
-Run the script `./createkeymandirs.sh` to create the directories for these programs to
-install the packages to.
+Run the script `./createkeymandirs.sh` to create the directories for these
+programs to install the packages to.
Also copy and compile the GSettings schema:
@@ -65,7 +66,8 @@ To uninstall you can run `sudo make uninstall`.
`./km-config`
-This displays a configuration panel that shows the currently installed Keyman keyboard packages and can download and install additional keyboards.
+This displays a configuration panel that shows the currently installed Keyman
+keyboard packages and can download and install additional keyboards.
#### Buttons
diff --git a/ios/exportAppStore.plist b/ios/exportAppStore.plist
index 585577ec2d..6393f3c4cb 100644
--- a/ios/exportAppStore.plist
+++ b/ios/exportAppStore.plist
@@ -7,9 +7,9 @@
teamID
3YE4W86L3G
signingCertificate
- 3F2AB892E24387929F51C36E7A03EF33502D341A
+ 05473BF50CCD4B78B304656FB4D93FDC7EE7ACD0
installerSigningCertificate
- 3F2AB892E24387929F51C36E7A03EF33502D341A
+ 05473BF50CCD4B78B304656FB4D93FDC7EE7ACD0
provisioningProfiles
Tavultesoft.Keyman
diff --git a/linux/.gitignore b/linux/.gitignore
index cf78b5ab49..bb6ad7a741 100644
--- a/linux/.gitignore
+++ b/linux/.gitignore
@@ -92,7 +92,6 @@ test.sh
debianpackage/
*.deb
*.ddeb
-*.build
*.buildinfo
*.changes
*.tar.xz
diff --git a/linux/debian/changelog b/linux/debian/changelog
index 90fdff22b0..638743e61e 100644
--- a/linux/debian/changelog
+++ b/linux/debian/changelog
@@ -1,8 +1,13 @@
-keyman (15.0.274-2) UNRELEASED; urgency=medium
+keyman (16.0.138-1) unstable; urgency=medium
+ [ Jelmer Vernooij ]
* Include packaging path in Vcs-Git header.
- -- Jelmer Vernooij Wed, 25 Jan 2023 23:46:54 +0000
+ [ Eberhard Beilharz ]
+ * New upstream release.
+ * Re-release to Debian
+
+ -- Eberhard Beilharz Thu, 02 Feb 2023 10:53:17 +0100
keyman (15.0.274-1) unstable; urgency=medium
diff --git a/linux/ibus-keyman/icons/meson.build b/linux/ibus-keyman/icons/meson.build
new file mode 100644
index 0000000000..dce1d23614
--- /dev/null
+++ b/linux/ibus-keyman/icons/meson.build
@@ -0,0 +1,6 @@
+icons = files('default.png')
+
+install_data(
+ icons,
+ install_dir: '{datadir}/keyman/icons'
+)
diff --git a/linux/ibus-keyman/meson.build b/linux/ibus-keyman/meson.build
new file mode 100644
index 0000000000..689cf5a5ec
--- /dev/null
+++ b/linux/ibus-keyman/meson.build
@@ -0,0 +1,44 @@
+project('ibus-keyman', 'c', 'cpp',
+ version: run_command('cat', '../../VERSION.md', check: true).stdout().strip(),
+ license: 'GPL-2+',
+ # default_options : ['buildtype=release',
+ # 'cpp_std=c++14',
+ # 'b_vscrt=static_from_buildtype',
+ # 'warning_level=2'],
+ meson_version: '>=0.53.0')
+cc = meson.get_compiler('c')
+conf = configuration_data()
+
+ibus = dependency('ibus-1.0', version: '>= 1.2.0')
+gtk = dependency('gtk+-3.0', version: '>= 2.4')
+x11 = dependency('x11', version: '>= 1.6')
+json_glib = dependency('json-glib-1.0', version: '>= 1.0')
+
+core_dir = meson.current_source_dir() / '../../core'
+common_dir = meson.current_source_dir() / '../../common'
+
+kmnkbp_lib = cc.find_library(
+ 'libkmnkbp0',
+ dirs: [ core_dir / 'build/arch' / get_option('buildtype') / 'src' ]
+)
+
+env = find_program('env')
+
+# Check if we have patched ibus (https://github.com/ibus/ibus/pull/2440)
+if cc.has_header_symbol('ibus.h', 'IBUS_CAP_PREFILTER', dependencies: [ibus], required: false)
+ conf.set('IBUS_HAS_PREFILTER', 1)
+endif
+
+conf.set('HAVE_CONFIG_H', 1)
+configure_file(output : 'config.h',
+ configuration : conf)
+
+core_include_dirs = [
+ include_directories('../../core/src'),
+ include_directories('../../core/src/kmx'),
+ include_directories('../../common/include'),
+]
+
+subdir('icons')
+subdir('src')
+subdir('tests')
diff --git a/linux/ibus-keyman/src/Makefile.am b/linux/ibus-keyman/src/Makefile.am
index 95361020c5..ce9f72640a 100644
--- a/linux/ibus-keyman/src/Makefile.am
+++ b/linux/ibus-keyman/src/Makefile.am
@@ -50,11 +50,11 @@ TESTS = \
$(NULL)
print_kmp_SOURCES = \
- print_kmp.c
+ test/print_kmp.c
print_kmpdetails_SOURCES = \
kmpdetails.c \
- print_kmpdetails.c \
+ test/print_kmpdetails.c \
$(NULL)
print_kmpdetails_CFLAGS = \
$(AM_CFLAGS) \
diff --git a/linux/ibus-keyman/src/keyman.xml.in b/linux/ibus-keyman/src/keyman.xml.in
new file mode 100644
index 0000000000..d41cc8021c
--- /dev/null
+++ b/linux/ibus-keyman/src/keyman.xml.in
@@ -0,0 +1,17 @@
+
+
+ org.freedesktop.IBus.Keyman
+ Keyman Component
+ @libexecdir@/ibus-engine-keyman --ibus
+ @VERSION@
+ Keyman Team <support@keyman.com>
+ GPL
+ https://keyman.com
+ ibus-keyman
+
+ /usr/share/keyman/
+ /usr/local/share/keyman/
+ ~/.local/share/keyman/
+
+
+
diff --git a/linux/ibus-keyman/src/meson.build b/linux/ibus-keyman/src/meson.build
new file mode 100644
index 0000000000..708c4751ea
--- /dev/null
+++ b/linux/ibus-keyman/src/meson.build
@@ -0,0 +1,49 @@
+util_files = files(
+ 'keymanutil.c',
+ 'keymanutil.h',
+ 'kmpdetails.c',
+ 'kmpdetails.h',
+)
+
+engine_files = files(
+ 'main.c',
+ 'engine.c',
+ 'engine.h',
+ 'keycodes.h',
+ 'keyman-service.c',
+ 'keyman-service.h',
+)
+
+include_dirs = [
+ core_include_dirs,
+ include_directories('..'),
+ include_directories(meson.current_build_dir() / '..'),
+]
+
+deps = [ibus, gtk, x11, json_glib, kmnkbp_lib]
+
+prefix = get_option('prefix')
+cfg = configuration_data()
+cfg.set('VERSION', meson.project_version())
+cfg.set('libexecdir', prefix / get_option('libexecdir'))
+
+configure_file(
+ configuration: cfg,
+ input: 'keyman.xml.in',
+ output: 'keyman.xml'
+)
+
+configure_file(
+ configuration: cfg,
+ input: 'keyman-version.h.in',
+ output: 'keyman-version.h'
+)
+
+exe = executable(
+ 'ibus-engine-keyman',
+ sources: [engine_files, util_files],
+ dependencies: deps,
+ include_directories: include_dirs,
+)
+
+subdir('test')
diff --git a/linux/ibus-keyman/src/test/meson.build b/linux/ibus-keyman/src/test/meson.build
new file mode 100644
index 0000000000..c652d8f783
--- /dev/null
+++ b/linux/ibus-keyman/src/test/meson.build
@@ -0,0 +1,62 @@
+keymanutil_sources = [
+ 'keymanutil_tests.c',
+ util_files,
+]
+
+keymanutil_deps = [ibus, gtk, x11, json_glib, kmnkbp_lib]
+
+test_env = [
+ 'G_TEST_SRCDIR=' + meson.current_source_dir(),
+ 'G_TEST_BUILDDIR=' + meson.current_build_dir(),
+]
+
+test_include_dirs = [
+ include_dirs,
+ include_directories('..'),
+ include_directories(meson.current_build_dir() / '..'),
+]
+
+executable(
+ 'keymanutil-tests',
+ sources: keymanutil_sources,
+ dependencies: keymanutil_deps,
+ include_directories : test_include_dirs
+)
+
+test(
+ 'keymanutil-tests',
+ find_program('run-tests.sh'),
+ env: test_env,
+ protocol: 'tap',
+)
+
+test(
+ 'print-kmpdetails-test',
+ executable(
+ 'print_kmpdetails',
+ sources: [
+ 'print_kmpdetails.c',
+ '../kmpdetails.c'
+ ],
+ dependencies: [ json_glib ],
+ include_directories: test_include_dirs
+ ),
+ args: [ meson.current_source_dir() ],
+ env: test_env,
+ protocol: 'exitcode',
+)
+
+test(
+ 'print-kmp-test',
+ executable(
+ 'print_kmp',
+ sources: [
+ 'print_kmp.c',
+ ],
+ dependencies: [ json_glib ],
+ include_directories: test_include_dirs
+ ),
+ args: [ meson.current_source_dir() / 'kmp.json' ],
+ env: test_env,
+ protocol: 'exitcode',
+)
diff --git a/linux/ibus-keyman/src/print_kmp.c b/linux/ibus-keyman/src/test/print_kmp.c
similarity index 100%
rename from linux/ibus-keyman/src/print_kmp.c
rename to linux/ibus-keyman/src/test/print_kmp.c
diff --git a/linux/ibus-keyman/src/print_kmpdetails.c b/linux/ibus-keyman/src/test/print_kmpdetails.c
similarity index 100%
rename from linux/ibus-keyman/src/print_kmpdetails.c
rename to linux/ibus-keyman/src/test/print_kmpdetails.c
diff --git a/linux/ibus-keyman/src/test/run-tests.sh b/linux/ibus-keyman/src/test/run-tests.sh
index 04b78a95fe..932f64b886 100755
--- a/linux/ibus-keyman/src/test/run-tests.sh
+++ b/linux/ibus-keyman/src/test/run-tests.sh
@@ -1,6 +1,6 @@
#!/bin/bash
-SRCDIR=${top_srcdir:-$(realpath $(dirname $0)/../..)}
+SRCDIR=${top_srcdir:-$(realpath "$(dirname $0)/../..")}
PID_FILE=/tmp/keymanutil-tests-pids
if [ -v KEYMAN_PKG_BUILD ]; then
@@ -12,19 +12,20 @@ if [ -v KEYMAN_PKG_BUILD ]; then
exit 0
fi
+
if ! which Xvfb > /dev/null || ! which Xephyr > /dev/null || ! which metacity > /dev/null; then
- echo "Please install Xvfb, Xephyr and metacity before running these tests!"
+ echo "# Please install Xvfb, Xephyr and metacity before running these tests!"
exit 1
fi
function cleanup() {
if [ -f $PID_FILE ]; then
echo
- echo "Shutting down processes..."
+ echo "# Shutting down processes..."
bash $PID_FILE > /dev/null 2>&1
rm $PID_FILE
- rm -rf $TEMP_DATA_DIR
- echo "Finished shutdown of processes."
+ rm -rf "$TEMP_DATA_DIR"
+ echo "# Finished shutdown of processes."
fi
}
@@ -32,15 +33,15 @@ echo > $PID_FILE
trap cleanup EXIT SIGINT
-echo "Starting Xvfb..."
+echo "# Starting Xvfb..."
Xvfb -screen 0 1024x768x24 :33 &> /dev/null &
echo "kill -9 $!" >> $PID_FILE
sleep 1
-echo "Starting Xephyr..."
+echo "# Starting Xephyr..."
DISPLAY=:33 Xephyr :32 -screen 1024x768 &> /dev/null &
echo "kill -9 $!" >> $PID_FILE
sleep 1
-echo "Starting metacity"
+echo "# Starting metacity"
metacity --display=:32 &> /dev/null &
echo "kill -9 $!" >> $PID_FILE
@@ -51,10 +52,10 @@ TEMP_DATA_DIR=$(mktemp --directory)
SCHEMA_DIR=$TEMP_DATA_DIR/glib-2.0/schemas
export XDG_DATA_DIRS=$TEMP_DATA_DIR:$XDG_DATA_DIRS
-mkdir -p $SCHEMA_DIR
-cp $SRCDIR/../keyman-config/com.keyman.gschema.xml $SCHEMA_DIR/
-glib-compile-schemas $SCHEMA_DIR
+mkdir -p "$SCHEMA_DIR"
+cp "$SRCDIR/../keyman-config/com.keyman.gschema.xml" "$SCHEMA_DIR/"
+glib-compile-schemas "$SCHEMA_DIR"
export GSETTINGS_BACKEND=memory
-./keymanutil-tests $@
+${G_TEST_BUILDDIR:-.}/keymanutil-tests "$@"
diff --git a/linux/ibus-keyman/tests/README.md b/linux/ibus-keyman/tests/README.md
index 8088f2f534..f7537a79fd 100644
--- a/linux/ibus-keyman/tests/README.md
+++ b/linux/ibus-keyman/tests/README.md
@@ -13,7 +13,7 @@ The tests get run as part of building `ibus-keyman`, more specifically when runn
All tests can be run with the test script:
```bash
-./run-tests.sh
+scripts/run-tests.sh
```
### Run specific tests
@@ -22,5 +22,5 @@ To run a single test you pass the testname (as found in
`core/build/arch/*/tests/unit/kmx`). Multiple tests should be separated by space.
```bash
-./run-tests.sh -- k_000___null_keyboard k_005___nul_with_initial_context
+scripts/run-tests.sh -- k_000___null_keyboard k_005___nul_with_initial_context
```
diff --git a/linux/ibus-keyman/tests/ibusimcontext.c b/linux/ibus-keyman/tests/ibusimcontext.c
index d35441a695..dc83cf8b97 100644
--- a/linux/ibus-keyman/tests/ibusimcontext.c
+++ b/linux/ibus-keyman/tests/ibusimcontext.c
@@ -28,9 +28,7 @@
// simplyfying the code a bit by replacing async calls with direct synchronous
// method calls.
-#ifdef HAVE_CONFIG_H
#include
-#endif
#ifndef IBUS_HAS_PREFILTER
#warning Compiling against ibus version that does not include prefilter mask patch (https://github.com/ibus/ibus/pull/2440). Output ordering guarantees will be disabled.
diff --git a/linux/ibus-keyman/tests/meson.build b/linux/ibus-keyman/tests/meson.build
new file mode 100644
index 0000000000..1e5db19573
--- /dev/null
+++ b/linux/ibus-keyman/tests/meson.build
@@ -0,0 +1,142 @@
+test_files = [
+ 'ibusimcontext.c',
+ 'ibusimcontext.h',
+ 'testfixture.cpp',
+ 'testmodule.c',
+ 'testmodule.h',
+]
+
+kmx_dir = [
+ core_dir / 'build/arch' / get_option('buildtype') / 'tests/unit/kmx'
+]
+
+kmnkbp_tests_lib = cc.find_library(
+ 'libkmnkbp-tests',
+ dirs: kmx_dir
+)
+
+deps = [ibus, gtk, x11, json_glib, kmnkbp_lib, kmnkbp_tests_lib]
+
+test_env = [
+ 'G_TEST_SRCDIR=' + meson.current_source_dir(),
+ 'G_TEST_BUILDDIR=' + meson.current_build_dir(),
+]
+
+test_include_dirs = [
+ core_include_dirs,
+ include_directories('../../../core/tests/unit/kmx'),
+ include_directories('../src'),
+ include_directories('..'),
+]
+
+test_exe = executable(
+ 'ibus-keyman-tests',
+ test_files, util_files,
+ dependencies: deps,
+ include_directories: test_include_dirs,
+)
+
+env_file = '/tmp/env.txt'
+pid_file = '/tmp/ibus-keyman-test-pids'
+
+setup_tests = find_program('setup-tests.sh', dirs: [meson.current_source_dir() / 'scripts'])
+teardown_tests = find_program('teardown-tests.sh', dirs: [meson.current_source_dir() / 'scripts'])
+run_test = find_program('run-single-test.sh', dirs: [meson.current_source_dir() / 'scripts'])
+find_tests = find_program('find-tests.sh', dirs: [meson.current_source_dir() / 'scripts'])
+
+test(
+ 'setup-x11',
+ setup_tests,
+ args: ['--x11', env_file, pid_file],
+ env: test_env,
+ priority: -10,
+ is_parallel: false,
+ protocol: 'exitcode'
+)
+
+test(
+ 'setup-wayland',
+ setup_tests,
+ args: ['--wayland', env_file, pid_file],
+ env: test_env,
+ priority: -20,
+ is_parallel: false,
+ protocol: 'exitcode'
+)
+
+test(
+ 'teardown-x11',
+ teardown_tests,
+ args: [pid_file],
+ priority: -19,
+ is_parallel: false,
+ protocol: 'exitcode'
+)
+
+test(
+ 'teardown-wayland',
+ teardown_tests,
+ args: [pid_file],
+ priority: -29,
+ is_parallel: false,
+ protocol: 'exitcode'
+)
+
+kmxtest_files = run_command(
+ find_tests,
+ kmx_dir,
+ check: true,
+).stdout().split('\n')
+
+foreach kmx: kmxtest_files
+ filename = kmx.split('\t')
+ if filename[0] == ''
+ continue
+ endif
+ testname = filename[1].split('.kmx')[0]
+ test_args = [ '--tap', '-k', '--env', env_file, '--', filename]
+ test(
+ 'X11-' + testname + '__surrounding-text',
+ run_test,
+ args: [ '--x11', '--surrounding-text', test_args],
+ env: test_env,
+ depends: [test_exe],
+ priority: -11,
+ is_parallel: false,
+ timeout: 120,
+ protocol: 'tap',
+ )
+ test(
+ 'X11-' + testname + '__no-surrounding-text',
+ run_test,
+ args: [ '--x11', '--no-surrounding-text', test_args],
+ env: test_env,
+ depends: [test_exe],
+ priority: -12,
+ is_parallel: false,
+ timeout: 120,
+ protocol: 'tap',
+ )
+ test(
+ 'Wayland-' + testname + '__surrounding-text',
+ run_test,
+ args: [ '--wayland', '--surrounding-text', test_args],
+ env: test_env,
+ depends: [test_exe],
+ priority: -21,
+ is_parallel: false,
+ timeout: 120,
+ protocol: 'tap',
+ )
+ test(
+ 'Wayland-' + testname + '__no-surrounding-text',
+ run_test,
+ args: [ '--wayland', '--no-surrounding-text', test_args],
+ env: test_env,
+ depends: [test_exe],
+ priority: -22,
+ is_parallel: false,
+ timeout: 120,
+ protocol: 'tap',
+ )
+endforeach
diff --git a/linux/ibus-keyman/tests/scripts/find-tests.sh b/linux/ibus-keyman/tests/scripts/find-tests.sh
new file mode 100755
index 0000000000..502cbab55f
--- /dev/null
+++ b/linux/ibus-keyman/tests/scripts/find-tests.sh
@@ -0,0 +1,16 @@
+#!/usr/bin/env bash
+set -eu
+while [ -n "$1" ]; do
+ if [ ! -d "$1" ]; then
+ shift
+ continue
+ fi
+ pushd "$1" > /dev/null
+ while IFS= read -r -d '' file; do
+ testname=$(basename "$file" .kmx)
+ #shellcheck disable=SC2059
+ printf "$(basename "$file")\t${testname#k_}\n"
+ done < <(find . -name \*.kmx -print0 | sort -z)
+ popd > /dev/null
+ exit 0
+done
diff --git a/linux/ibus-keyman/tests/scripts/run-single-test.sh b/linux/ibus-keyman/tests/scripts/run-single-test.sh
new file mode 100755
index 0000000000..c265c27ccd
--- /dev/null
+++ b/linux/ibus-keyman/tests/scripts/run-single-test.sh
@@ -0,0 +1,73 @@
+#!/usr/bin/env bash
+TESTDIR=${XDG_DATA_HOME:-$HOME/.local/share}/keyman/test_kmx
+
+. "$(dirname "$0")"/test-helper.sh
+
+if [ -v KEYMAN_PKG_BUILD ]; then
+ # During package builds we skip these tests that require to start ibus because
+ # ibus requires to find /var/lib/dbus/machine-id or /etc/machine-id, otherwise it fails with:
+ # "Bail out! IBUS-FATAL-WARNING: Unable to load /var/lib/dbus/machine-id: Failed to open file
+ # “/var/lib/dbus/machine-id”: No such file or directory"
+ echo "1..1"
+ echo "ok 1 - Integration tests # SKIP on package build"
+ exit 0
+fi
+
+if ! which Xvfb > /dev/null || ! which Xephyr > /dev/null || ! which metacity > /dev/null || ! which mutter > /dev/null; then
+ echo "Please install Xvfb, Xephyr, metacity and mutter before running these tests!"
+ exit 1
+fi
+
+function help() {
+ echo "Usage:"
+ echo " $0 [--env ] [-k] [--tap] [--surrounding-text] [--no-surrounding-text] [--wayland|--x11] [--] TEST"
+ echo
+ echo "Arguments:"
+ echo " --help, -h, -? Display this help"
+ echo " --verbose, -v Run tests verbosely"
+ echo " --debug debug test logging output"
+ echo " -k passed to GLib testing framework"
+ echo " --tap output in TAP format. Passed to GLib testing framework"
+ echo " --surrounding-text run tests with surrounding texts enabled"
+ echo " --no-surrounding-text run tests without support for surrounding text"
+ echo " --wayland run tests with Wayland"
+ echo " --x11 run tests with X11"
+ echo " --env Name of the file containing environment variables to use"
+ exit 0
+}
+
+function run_tests() {
+ echo "# NOTE: When the tests fail check /tmp/ibus-engine-keyman.log and /tmp/ibus-daemon.log!"
+ echo ""
+
+ echo "# Starting tests..."
+ # Note: -k and --tap are consumed by the GLib testing framework
+ # shellcheck disable=SC2086
+ "${G_TEST_BUILDDIR:-.}"/ibus-keyman-tests ${ARG_K-} ${ARG_TAP-} \
+ ${ARG_VERBOSE-} ${ARG_DEBUG-} ${ARG_SURROUNDING_TEXT-} ${ARG_NO_SURROUNDING_TEXT-} \
+ --directory "$TESTDIR" ${ARG_DISPLAY_SERVER} "$TESTFILE"
+ echo "# Finished tests."
+}
+
+while (( $# )); do
+ case $1 in
+ --help|-h|-\?) help ;;
+ -k) ARG_K=$1 ;;
+ --tap) ARG_TAP=$1 ;;
+ --surrounding-text) ARG_SURROUNDING_TEXT=$1 ;;
+ --no-surrounding-text) ARG_NO_SURROUNDING_TEXT=$1 ;;
+ --wayland) ARG_DISPLAY_SERVER=$1 ;;
+ --x11) ARG_DISPLAY_SERVER=$1 ;;
+ --verbose|-v) ARG_VERBOSE=--verbose;;
+ --debug) ARG_DEBUG=--debug-log;;
+ --env) shift ; ARG_ENV=$1 ;;
+ --) shift ; TESTFILE=$1; break ;;
+ *) echo "Error: Unexpected argument \"$1\". Exiting." ; exit 4 ;;
+ esac
+ shift || (echo "Error: The last argument is missing a value. Exiting."; false) || exit 5
+done
+
+# shellcheck source=/dev/null
+. "$ARG_ENV"
+
+run_tests
diff --git a/linux/ibus-keyman/tests/scripts/run-tests.sh b/linux/ibus-keyman/tests/scripts/run-tests.sh
new file mode 100755
index 0000000000..b80dd1a5f4
--- /dev/null
+++ b/linux/ibus-keyman/tests/scripts/run-tests.sh
@@ -0,0 +1,206 @@
+#!/usr/bin/env bash
+
+TOP_SRCDIR=${top_srcdir:-$(realpath "$(dirname "$0")/..")}
+TESTDIR=${XDG_DATA_HOME:-$HOME/.local/share}/keyman/test_kmx
+
+. "$(dirname "$0")"/test-helper.sh
+
+if [ -v KEYMAN_PKG_BUILD ]; then
+ # During package builds we skip these tests that require to start ibus because
+ # ibus requires to find /var/lib/dbus/machine-id or /etc/machine-id, otherwise it fails with:
+ # "Bail out! IBUS-FATAL-WARNING: Unable to load /var/lib/dbus/machine-id: Failed to open file
+ # “/var/lib/dbus/machine-id”: No such file or directory"
+ echo "1..1"
+ echo "ok 1 - Integration tests # SKIP on package build"
+ exit 0
+fi
+
+if ! which Xvfb > /dev/null || ! which Xephyr > /dev/null || ! which metacity > /dev/null || ! which mutter > /dev/null; then
+ echo "Please install Xvfb, Xephyr, metacity and mutter before running these tests!"
+ exit 1
+fi
+
+function cleanup() {
+ if [ -f "$PID_FILE" ]; then
+ echo
+ echo "# Shutting down processes..."
+ bash "$PID_FILE" > /dev/null 2>&1
+ rm "$PID_FILE"
+ echo "# Finished shutdown of processes."
+ fi
+}
+
+function help() {
+ echo "Usage:"
+ echo " $0 [-k] [--tap] [--surrounding-text] [--no-surrounding-text] [--no-wayland] [--no-x11] [[--] TEST...]"
+ echo
+ echo "Arguments:"
+ echo " --help, -h, -? Display this help"
+ echo " --verbose, -v Run tests verbosely"
+ echo " --debug debug test logging output"
+ echo " -k passed to GLib testing framework"
+ echo " --tap output in TAP format. Passed to GLib testing framework"
+ echo " --surrounding-text run tests with surrounding texts enabled"
+ echo " --no-surrounding-text run tests without support for surrounding text"
+ echo " --no-wayland don't run tests with Wayland"
+ echo " --no-x11 don't run tests with X11"
+ echo
+ echo "If no TESTs are specified then all tests are run."
+ echo "If neither --surrounding-text nor --no-surrounding-text are specified then the tests run with both settings."
+ exit 0
+}
+
+function run_tests() {
+ DISPLAY_SERVER=$1
+ shift
+
+ echo > "$PID_FILE"
+ TEMP_DATA_DIR=$(mktemp --directory)
+ echo "rm -rf ${TEMP_DATA_DIR}" >> "$PID_FILE"
+
+ COMMON_ARCH_DIR=
+ [ -d "${TOP_SRCDIR}"/../../core/build/arch ] && COMMON_ARCH_DIR=${TOP_SRCDIR}/../../core/build/arch
+ [ -d "${TOP_SRCDIR}"/../keyboardprocessor/arch ] && COMMON_ARCH_DIR=${TOP_SRCDIR}/../keyboardprocessor/arch
+
+ if [ -d "${COMMON_ARCH_DIR}"/release ]; then
+ COMMON_ARCH_DIR=${COMMON_ARCH_DIR}/release
+ elif [ -d "${COMMON_ARCH_DIR}"/debug ]; then
+ COMMON_ARCH_DIR=${COMMON_ARCH_DIR}/debug
+ else
+ echo "Can't find neither ${COMMON_ARCH_DIR}/release nor ${COMMON_ARCH_DIR}/debug"
+ exit 2
+ fi
+
+ if [ ! -d "$TESTDIR" ] || ! [[ $(find "${TESTDIR}/" -name \*.kmx 2>/dev/null | wc -l) -gt 0 ]]; then
+ if [[ $(find "${COMMON_ARCH_DIR}/tests/unit/kmx/" -name \*.kmx 2>/dev/null | wc -l) -gt 0 ]]; then
+ mkdir -p "$(realpath --canonicalize-missing "$TESTDIR"/..)"
+ ln -sf "$(realpath "${COMMON_ARCH_DIR}"/tests/unit/kmx)" "$TESTDIR"
+ else
+ echo "Can't find kmx files in ${COMMON_ARCH_DIR}/tests/unit/kmx"
+ exit 3
+ fi
+ fi
+
+ echo "# NOTE: When the tests fail check /tmp/ibus-engine-keyman.log and /tmp/ibus-daemon.log!"
+ echo ""
+
+ if [ "$DISPLAY_SERVER" == "wayland" ]; then
+ if ! can_run_wayland; then
+ # support for --headless got added in mutter 40.x
+ echo "ERROR: mutter doesn't support running headless. Can't run Wayland tests."
+ exit 7
+ fi
+ echo "# Running on Wayland..."
+ TMPFILE=$(mktemp)
+ # mutter-Message: 18:56:15.422: Using Wayland display name 'wayland-1'
+ mutter --wayland --headless --no-x11 --virtual-monitor 1024x768 &> "$TMPFILE" &
+ echo "kill -9 $!" >> "$PID_FILE"
+ sleep 1s
+ export WAYLAND_DISPLAY
+ WAYLAND_DISPLAY=$(cat "$TMPFILE" | grep "Using Wayland display" | cut -d"'" -f2)
+ rm "$TMPFILE"
+ else
+ echo "# Starting Xvfb..."
+ Xvfb -screen 0 1024x768x24 :33 &> /dev/null &
+ echo "kill -9 $!" >> "$PID_FILE"
+ sleep 1
+ echo "# Starting Xephyr..."
+ DISPLAY=:33 Xephyr :32 -screen 1024x768 &> /dev/null &
+ echo "kill -9 $!" >> "$PID_FILE"
+ sleep 1
+ echo "# Starting metacity"
+ metacity --display=:32 &> /dev/null &
+ echo "kill -9 $!" >> "$PID_FILE"
+
+ export DISPLAY=:32
+ fi
+
+ # Install schema to temporary directory. This removes the build dependency on the keyman package.
+ SCHEMA_DIR=$TEMP_DATA_DIR/glib-2.0/schemas
+ export XDG_DATA_DIRS=$TEMP_DATA_DIR:$XDG_DATA_DIRS
+
+ mkdir -p "$SCHEMA_DIR"
+ cp "${TOP_SRCDIR}"/../keyman-config/com.keyman.gschema.xml "$SCHEMA_DIR"/
+ glib-compile-schemas "$SCHEMA_DIR"
+
+ if [ $# -gt 0 ]; then
+ TESTFILES=($@)
+ else
+ pushd "$TESTDIR" > /dev/null || exit
+ TESTFILES=(*.kmx)
+ popd > /dev/null || exit
+ fi
+
+ export LD_LIBRARY_PATH=${COMMON_ARCH_DIR}/src:$LD_LIBRARY_PATH
+
+ # Ubuntu 18.04 Bionic doesn't have ibus-memconf, and glib is not compiled with the keyfile
+ # backend enabled, so we just use the default backend. Otherwise we use the keyfile
+ # store which interferes less when running on a dev machine.
+ if [ -f /usr/libexec/ibus-memconf ]; then
+ export GSETTINGS_BACKEND=keyfile
+ IBUS_CONFIG=--config=/usr/libexec/ibus-memconf
+ fi
+
+ ibus-daemon "${ARG_VERBOSE-}" --panel=disable ${IBUS_CONFIG-} &> /tmp/ibus-daemon.log &
+ echo "kill -9 $!" >> "$PID_FILE"
+ sleep 1s
+
+ ../src/ibus-engine-keyman "${ARG_VERBOSE-}" &> /tmp/ibus-engine-keyman.log &
+ echo "kill -9 $!" >> "$PID_FILE"
+ sleep 1s
+
+ echo "# Starting tests..."
+ # Note: -k and --tap are consumed by the GLib testing framework
+ "${G_TEST_BUILDDIR:-.}"/ibus-keyman-tests "${ARG_K-}" "${ARG_TAP-}" \
+ "${ARG_VERBOSE-}" "${ARG_DEBUG-}" "${ARG_SURROUNDING_TEXT-}" "${ARG_NO_SURROUNDING_TEXT-}" \
+ --directory "$TESTDIR" --"${DISPLAY_SERVER}" "${TESTFILES[@]}"
+ echo "# Finished tests."
+
+ cleanup
+}
+
+USE_WAYLAND=1
+USE_X11=1
+
+while (( $# )); do
+ case $1 in
+ --help|-h|-\?) help ;;
+ -k) ARG_K=$1 ;;
+ --tap) ARG_TAP=$1 ;;
+ --surrounding-text) ARG_SURROUNDING_TEXT=$1 ;;
+ --no-surrounding-text) ARG_NO_SURROUNDING_TEXT=$1 ;;
+ --no-wayland) USE_WAYLAND=0;;
+ --no-x11) USE_X11=0;;
+ --verbose|-v) ARG_VERBOSE=--verbose;;
+ --debug) ARG_DEBUG=--debug-log;;
+ --) shift && break ;;
+ *) echo "Error: Unexpected argument \"$1\". Exiting." ; exit 4 ;;
+ esac
+ shift || (echo "Error: The last argument is missing a value. Exiting."; false) || exit 5
+done
+
+if ! can_run_wayland; then
+ # support for --headless got added in mutter 40.x
+ echo "# WARNING: mutter doesn't support running headless. Skipping Wayland tests."
+ USE_WAYLAND=0
+ if [ "$USE_X11" == "0" ]; then
+ echo "ERROR: no tests to run. Can't run Wayland tests, and --no-x11 is specified."
+ exit 8
+ fi
+fi
+
+if [ "$USE_WAYLAND" == "0" ] && [ "$USE_X11" == "0" ]; then
+ echo "ERROR: I'll have to run somewhere. Specifying both --no-wayland and --no-x11 is not allowed."
+ exit 6
+fi
+
+echo > "$PID_FILE"
+trap cleanup EXIT SIGINT
+
+if [ "$USE_WAYLAND" == "1" ]; then
+ run_tests wayland "$@"
+fi
+
+if [ "$USE_X11" == "1" ]; then
+ run_tests x11 "$@"
+fi
diff --git a/linux/ibus-keyman/tests/scripts/setup-tests.sh b/linux/ibus-keyman/tests/scripts/setup-tests.sh
new file mode 100755
index 0000000000..e48d36eba9
--- /dev/null
+++ b/linux/ibus-keyman/tests/scripts/setup-tests.sh
@@ -0,0 +1,111 @@
+#!/usr/bin/env bash
+DISPLAY_SERVER=$1
+ENV_FILE=$2
+PID_FILE=$3
+
+TOP_SRCDIR=${G_TEST_SRCDIR:-$(realpath "$(dirname "$0")/..")}/..
+TOP_BINDIR=${G_TEST_BUILDDIR:-$(realpath "$(dirname "$0/..")")}/..
+TESTDIR=${XDG_DATA_HOME:-$HOME/.local/share}/keyman/test_kmx
+
+. "$(dirname "$0")/"/test-helper.sh
+
+echo > "$ENV_FILE"
+
+if [ -f "$PID_FILE" ]; then
+ # kill previous instances
+ "$(dirname "$0")"/teardown-tests.sh "$PID_FILE"
+fi
+
+echo > "$PID_FILE"
+TEMP_DATA_DIR=$(mktemp --directory)
+echo "rm -rf ${TEMP_DATA_DIR}" >> "$PID_FILE"
+
+COMMON_ARCH_DIR=
+[ -d "${TOP_SRCDIR}"/../../core/build/arch ] && COMMON_ARCH_DIR=${TOP_SRCDIR}/../../core/build/arch
+[ -d "${TOP_SRCDIR}"/../keyboardprocessor/arch ] && COMMON_ARCH_DIR=${TOP_SRCDIR}/../keyboardprocessor/arch
+
+if [ -d "${COMMON_ARCH_DIR}"/release ]; then
+ COMMON_ARCH_DIR=${COMMON_ARCH_DIR}/release
+elif [ -d "${COMMON_ARCH_DIR}"/debug ]; then
+ COMMON_ARCH_DIR=${COMMON_ARCH_DIR}/debug
+else
+ echo "Can't find neither ${COMMON_ARCH_DIR}/release nor ${COMMON_ARCH_DIR}/debug"
+ exit 2
+fi
+
+if [ ! -d "$TESTDIR" ] || ! [[ $(find "${TESTDIR}/" -name \*.kmx 2>/dev/null | wc -l) -gt 0 ]]; then
+ if [[ $(find "${COMMON_ARCH_DIR}/tests/unit/kmx/" -name \*.kmx 2>/dev/null | wc -l) -gt 0 ]]; then
+ mkdir -p "$(realpath --canonicalize-missing "$TESTDIR"/..)"
+ ln -sf "$(realpath "${COMMON_ARCH_DIR}"/tests/unit/kmx)" "$TESTDIR"
+ else
+ echo "Can't find kmx files in ${COMMON_ARCH_DIR}/tests/unit/kmx"
+ exit 3
+ fi
+fi
+
+if [ "$DISPLAY_SERVER" == "wayland" ]; then
+ if ! can_run_wayland; then
+ # support for --headless got added in mutter 40.x
+ echo "ERROR: mutter doesn't support running headless. Can't run Wayland tests."
+ exit 7
+ fi
+ echo "Running on Wayland..."
+ TMPFILE=$(mktemp)
+ # mutter-Message: 18:56:15.422: Using Wayland display name 'wayland-1'
+ mutter --wayland --headless --no-x11 --virtual-monitor 1024x768 &> "$TMPFILE" &
+ echo "kill -9 $!" >> "$PID_FILE"
+ sleep 1s
+ export WAYLAND_DISPLAY
+ WAYLAND_DISPLAY=$(grep "Using Wayland display" "$TMPFILE" | cut -d"'" -f2)
+ rm "$TMPFILE"
+ echo "export WAYLAND_DISPLAY=\"$WAYLAND_DISPLAY\"" >> "$ENV_FILE"
+else
+ echo "Starting Xvfb..."
+ Xvfb -screen 0 1024x768x24 :33 &> /dev/null &
+ echo "kill -9 $!" >> "$PID_FILE"
+ sleep 1
+ echo "Starting Xephyr..."
+ DISPLAY=:33 Xephyr :32 -screen 1024x768 &> /dev/null &
+ echo "kill -9 $!" >> "$PID_FILE"
+ sleep 1
+ echo "Starting metacity"
+ metacity --display=:32 &> /dev/null &
+ echo "kill -9 $!" >> "$PID_FILE"
+
+ export DISPLAY=:32
+ echo "export DISPLAY=\"$DISPLAY\"" >> "$ENV_FILE"
+fi
+
+ # Install schema to temporary directory. This removes the build dependency on the keyman package.
+ SCHEMA_DIR=$TEMP_DATA_DIR/glib-2.0/schemas
+ export XDG_DATA_DIRS=$TEMP_DATA_DIR:$XDG_DATA_DIRS
+ echo "export XDG_DATA_DIRS=\"$XDG_DATA_DIRS\"" >> "$ENV_FILE"
+
+ mkdir -p "$SCHEMA_DIR"
+ cp "${TOP_SRCDIR}"/../keyman-config/com.keyman.gschema.xml "$SCHEMA_DIR"/
+ glib-compile-schemas "$SCHEMA_DIR"
+
+ export LD_LIBRARY_PATH=${COMMON_ARCH_DIR}/src:$LD_LIBRARY_PATH
+ echo "export LD_LIBRARY_PATH=\"$LD_LIBRARY_PATH\"" >> "$ENV_FILE"
+
+ # Ubuntu 18.04 Bionic doesn't have ibus-memconf, and glib is not compiled with the keyfile
+ # backend enabled, so we just use the default backend. Otherwise we use the keyfile
+ # store which interferes less when running on a dev machine.
+ if [ -f /usr/libexec/ibus-memconf ]; then
+ export GSETTINGS_BACKEND=keyfile
+ echo "export GSETTINGS_BACKEND=\"$GSETTINGS_BACKEND\"" >> "$ENV_FILE"
+ IBUS_CONFIG=--config=/usr/libexec/ibus-memconf
+ fi
+
+ ibus-daemon "${ARG_VERBOSE-}" --daemonize --panel=disable ${IBUS_CONFIG-} &> /tmp/ibus-daemon.log
+ echo "kill -9 $!" >> "$PID_FILE"
+ sleep 1s
+
+ IBUS_ADDRESS=$(ibus address)
+ export IBUS_ADDRESS
+
+ echo "export IBUS_ADDRESS=\"$IBUS_ADDRESS\"" >> "$ENV_FILE"
+
+ "${TOP_BINDIR}"/src/ibus-engine-keyman "${ARG_VERBOSE-}" &> /tmp/ibus-engine-keyman.log &
+ echo "kill -9 $!" >> "$PID_FILE"
+ sleep 1s
diff --git a/linux/ibus-keyman/tests/scripts/teardown-tests.sh b/linux/ibus-keyman/tests/scripts/teardown-tests.sh
new file mode 100755
index 0000000000..489769d721
--- /dev/null
+++ b/linux/ibus-keyman/tests/scripts/teardown-tests.sh
@@ -0,0 +1,7 @@
+#!/usr/bin/env bash
+PID_FILE=$1
+
+echo "Shutting down processes..."
+bash "$PID_FILE" > /dev/null 2>&1
+rm "$PID_FILE"
+echo "Finished shutdown of processes."
diff --git a/linux/ibus-keyman/tests/scripts/test-helper.sh b/linux/ibus-keyman/tests/scripts/test-helper.sh
new file mode 100755
index 0000000000..92c8a7e528
--- /dev/null
+++ b/linux/ibus-keyman/tests/scripts/test-helper.sh
@@ -0,0 +1,11 @@
+#!/usr/bin/env bash
+
+function can_run_wayland() {
+ local MUTTER_VERSION
+ MUTTER_VERSION=$(mutter --version | head -1 | cut -f2 -d' ' | cut -f1 -d'.')
+ if (( MUTTER_VERSION < 40 )); then
+ return 1
+ else
+ return 0
+ fi
+}