public inbox for git-commits@fedoraproject.org
help / color / mirror / Atom feed
From: Takao Fujiwara <tfujiwar@redhat.com>
To: git-commits@fedoraproject.org
Subject: [rpms/ibus] autotool: Delete upstreamed ibus-HEAD.patch
Date: Sun, 31 May 2026 02:08:40 GMT	[thread overview]
Message-ID: <178019332078.1.7564135766380726412.rpms-ibus-8e894714961b@fedoraproject.org> (raw)

A new commit has been pushed.

Repo   : rpms/ibus
Branch : autotool
Commit : 8e894714961b83c1b7128d3e38bb412683422532
Author : Takao Fujiwara <tfujiwar@redhat.com>
Date   : 2024-08-25T09:09:54+09:00
Stats  : +0/-4011 in 1 file(s)
URL    : https://src.fedoraproject.org/rpms/ibus/c/8e894714961b83c1b7128d3e38bb412683422532?branch=autotool

Log:
Delete upstreamed ibus-HEAD.patch

---
diff --git a/ibus-HEAD.patch b/ibus-HEAD.patch
deleted file mode 100644
index 6e624de..0000000
--- a/ibus-HEAD.patch
+++ /dev/null
@@ -1,4011 +0,0 @@
-From a1a2fe5d13ad76956a94c0695af15d76e3edfdca Mon Sep 17 00:00:00 2001
-From: fujiwarat <takao.fujiwara1@gmail.com>
-Date: Thu, 18 Jul 2024 01:25:41 +0900
-Subject: [PATCH] Fix memory leaks in error handlings
-
-- bus/ibusimpl: Free keys not in case of TYPE_IME_SWITCHER
-- src/ibuscomposetable: Correct handling G_MAXSIZE * G_MAXSIZE
-- src/ibuscomposetable: Fee ibus_compose_seqs in error handlings
----
- bus/ibusimpl.c         | 3 ++-
- src/ibuscomposetable.c | 6 +++++-
- 2 files changed, 7 insertions(+), 2 deletions(-)
-
-diff --git a/bus/ibusimpl.c b/bus/ibusimpl.c
-index 31a095f3..445c062b 100644
---- a/bus/ibusimpl.c
-+++ b/bus/ibusimpl.c
-@@ -1986,7 +1986,8 @@ _ibus_set_global_shortcut_keys (BusIBusImpl     *ibus,
-         }
-         ibus->ime_switcher_keys = keys;
-         break;
--    default:;
-+    default:
-+        g_slice_free1 (sizeof (IBusProcessKeyEventData) * (size + 1), keys);
-     }
-     return TRUE;
- }
-diff --git a/src/ibuscomposetable.c b/src/ibuscomposetable.c
-index 7531a4b2..a8e41a33 100644
---- a/src/ibuscomposetable.c
-+++ b/src/ibuscomposetable.c
-@@ -849,7 +849,7 @@ compose_data_to_variant (gconstpointer compose_data,
-     g_assert (compose_data);
-     if (error)
-         *error = NULL;
--    if ((index_stride * n_seqs) > G_MAXUINT64) {
-+    if (n_seqs == 0 || index_stride > (G_MAXSIZE / n_seqs)) {
-         if (error) {
-             g_set_error (error, IBUS_ERROR, IBUS_ERROR_FAILED,
-                          "Length %u x %lu is too long",
-@@ -1404,6 +1404,7 @@ ibus_compose_table_new_with_list (GList   *compose_list,
-                         (G_MAXSIZE / sizeof (guint16)))) {
-             g_warning ("Too long allocation %lu x %u",
-                        s_size_total - s_size_16bit, n_index_stride);
-+            g_free (ibus_compose_seqs);
-             return NULL;
-         }
-         rawdata = (gpointer)g_new (
-@@ -1416,6 +1417,8 @@ ibus_compose_table_new_with_list (GList   *compose_list,
-                        s_size_total - s_size_16bit,
-                        n_index_stride,
-                        v_size_32bit);
-+            g_free (ibus_compose_seqs);
-+            g_free (rawdata);
-             return NULL;
-         }
-         if (G_LIKELY (rawdata)) {
-@@ -1432,6 +1435,7 @@ ibus_compose_table_new_with_list (GList   *compose_list,
-         }
-         if (!ibus_compose_seqs_32bit_first || !ibus_compose_seqs_32bit_second) {
-             g_warning ("Failed g_new");
-+            g_free (ibus_compose_seqs);
-             g_free (rawdata);
-             return NULL;
-         }
--- 
-2.45.0
-
-From a52861385bb5d15598f6c3c3d86c7a9ee19f140a Mon Sep 17 00:00:00 2001
-From: fujiwarat <takao.fujiwara1@gmail.com>
-Date: Sat, 27 Jul 2024 19:00:53 +0900
-Subject: [PATCH 1/6] src/tests: Enable CI in GNOME Wayland
-
-- Implement headless desktop to test Wayland sessions
-- Implement ibus-desktop-testing-autostart to be executed in XDG
-  autostart in GNOME Wayland
-- Move shared codes to ibus-desktop-testing-module between
-  ibus-desktop-testing-runner and ibus-desktop-testing-autostart
-- Add --no-systemd option to enable the previous testing frame with running
-  gnome-session directly
-- Rename --desktop option to --session
-- Move save_screen() from runner to module
-- Copy gnome-shell service file to user home for headless & virtual-monitor
-- Add --delete-tests option to clean up tests
-- Add AutostartCondition=if-exists in XDG autostart desktop file
-- Add 60 secs in ibus-compose-locales for systemd desktop sessions
-- Quote file names as much as possible.
-- Check file existant and not to use "rm -f" as much as possible
-- Do not set GTK_IM_MODULE=ibus for Wayland
-
-BUG=https://github.com/ibus/ibus/pull/2657
----
- src/tests/Makefile.am                       |  23 +-
- src/tests/ibus-compose-locales.in           |  16 +-
- src/tests/ibus-desktop-testing-autostart    |  57 --
- src/tests/ibus-desktop-testing-autostart.in |  83 ++
- src/tests/ibus-desktop-testing-module       | 876 ++++++++++++++++++++
- src/tests/ibus-desktop-testing-runner.in    | 495 +----------
- src/tests/ibus-desktop-testing.desktop.in   |   2 +-
- 7 files changed, 1034 insertions(+), 518 deletions(-)
- delete mode 100755 src/tests/ibus-desktop-testing-autostart
- create mode 100755 src/tests/ibus-desktop-testing-autostart.in
- create mode 100755 src/tests/ibus-desktop-testing-module
-
-diff --git a/src/tests/Makefile.am b/src/tests/Makefile.am
-index b30a39fb..6c4c86cf 100644
---- a/src/tests/Makefile.am
-+++ b/src/tests/Makefile.am
-@@ -106,6 +106,7 @@ test_sourcesdir = $(datadir)/installed-tests/ibus
- 
- CLEANFILES += \
-     $(test_metas) \
-+    ibus-desktop-testing-autostart \
-     ibus-desktop-testing-runner \
-     org.freedesktop.IBus.Desktop.Testing.desktop \
-     $(NULL)
-@@ -119,7 +120,10 @@ CLEANFILES += \
-     $(NULL)
- endif
- test_execsdir = $(libexecdir)/installed-tests/ibus
--libexec_SCRIPTS = ibus-desktop-testing-autostart
-+libexec_SCRIPTS = \
-+  ibus-desktop-testing-autostart \
-+  ibus-desktop-testing-module \
-+  $(NULL)
- 
- test_frame_DATA = org.freedesktop.IBus.Desktop.Testing.desktop
- test_framedir = $(pkgdatadir)/tests
-@@ -142,9 +146,21 @@ ibus-compose-locales: ibus-compose-locales.in
- 	mv $@.tmp $@; \
- 	$(NULL)
- 
-+ibus-desktop-testing-autostart: ibus-desktop-testing-autostart.in
-+	INSTALLEDDIR=$(datadir)/installed-tests; \
-+	sed -e "s|@DATADIR[@]|$(datadir)|g" \
-+	    -e "s|@INSTALLEDDIR[@]|$$INSTALLEDDIR|g" \
-+	    -e "s|@LIBEXECDIR[@]|$(libexecdir)|g" \
-+	    $< > $@.tmp; \
-+	mv $@.tmp $@; \
-+	$(NULL)
-+
- ibus-desktop-testing-runner: ibus-desktop-testing-runner.in
- 	INSTALLEDDIR=$(datadir)/installed-tests; \
--	sed -e "s|@INSTALLEDDIR[@]|$$INSTALLEDDIR|g" $< > $@.tmp; \
-+	sed -e "s|@DATADIR[@]|$(datadir)|g" \
-+	    -e "s|@INSTALLEDDIR[@]|$$INSTALLEDDIR|g" \
-+	    -e "s|@LIBEXECDIR[@]|$(libexecdir)|g" \
-+	    $< > $@.tmp; \
- 	mv $@.tmp $@; \
- 	$(NULL)
- 
-@@ -157,7 +173,8 @@ EXTRA_DIST = \
-     ibus-compose.env \
-     ibus-compose-locales.in \
-     ibus-desktop-testing.desktop.in \
--    ibus-desktop-testing-autostart \
-+    ibus-desktop-testing-autostart.in \
-+    ibus-desktop-testing-module \
-     ibus-desktop-testing-runner.in \
-     $(NULL)
- 
-diff --git a/src/tests/ibus-compose-locales.in b/src/tests/ibus-compose-locales.in
-index b36165fe..7a133ce0 100755
---- a/src/tests/ibus-compose-locales.in
-+++ b/src/tests/ibus-compose-locales.in
-@@ -6,7 +6,8 @@ BUILDDIR=`dirname $0`
- 
- export IBUS_COMPOSE_CACHE_DIR=$PWD
- 
--retval=0
-+RETVAL=0
-+INITED=0
- # Deleted for var in `cat *.env` because IFS=$'\n' is not supported in POSIX sh
- while read var
- do
-@@ -14,19 +15,26 @@ do
-     if [ "x$IS_COMMENT" != x ] ; then
-         continue
-     fi
-+    while [ x"$IBUS_DAEMON_WITH_SYSTEMD" != x ] && [ $INITED -lt 6 ] ; do
-+        echo "Waiting for ${INITED}0 secs till 60 secs"
-+        sleep 10
-+        INITED=`expr $INITED + 1`
-+    done
-     # Use $* instead of $@ not to mix strings and integers
-     echo "# Starting $var $BUILDDIR/ibus-compose $SRCDIR $*"
-     # Need to enclose $@ with double quotes not to split the array.
-     env $var $BUILDDIR/ibus-compose $SRCDIR "$@"
--    retval=`expr $retval + $?`
--    echo "# Finished $var $BUILDDIR/ibus-compose $SRCDIR $* with $retval"
-+    RETVAL=`expr $RETVAL + $?`
-+    echo "# Finished $var $BUILDDIR/ibus-compose $SRCDIR $* with $RETVAL"
- 
-     CACHE_FILES=`ls *.cache`
-     if [ x"$CACHE_FILES" != x ] ; then
-         echo "Clean $CACHE_FILES"
-         rm $CACHE_FILES
-     fi
-+    # Need to wait for 1 sec not to be freezed with gnome-shell in Wayland
-+    sleep 1
- done << EOF_ENVS
- `cat $SRCDIR/ibus-compose.env`
- EOF_ENVS
--exit $retval
-+exit $RETVAL
-diff --git a/src/tests/ibus-desktop-testing-autostart b/src/tests/ibus-desktop-testing-autostart
-deleted file mode 100755
-index 1e1eb180..00000000
---- a/src/tests/ibus-desktop-testing-autostart
-+++ /dev/null
-@@ -1,57 +0,0 @@
--#!/bin/sh
--# -*- mode: C; c-basic-offset: 4; indent-tabs-mode: nil; -*-
--# vim:set noet ts=4:
--#
--# ibus - The Input Bus
--#
--# Copyright (c) 2021 Takao Fujiwara <takao.fujiwara1@gmail.com>
--# Copyright (c) 2021 Red Hat, Inc.
--#
--# This program is free software; you can redistribute it and/or modify
--# it under the terms of the GNU General Public License as published by
--# the Free Software Foundation; either version 2 of the License, or
--# (at your option) any later version.
--#
--# This program is distributed in the hope that it will be useful,
--# but WITHOUT ANY WARRANTY; without even the implied warranty of
--# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
--# GNU General Public License for more details.
--#
--# You should have received a copy of the GNU General Public License along
--# with this program; if not, write to the Free Software Foundation, Inc.,
--# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
--
--TEST_LOG=
--COMMANDS='
--id
--echo $DISPLAY
--pwd
--pstree -asp $$
--gsettings list-recursively org.gnome.shell
--rpm -q gnome-shell-extension-no-overview gnome-shell gnome-session
--ps -ef | grep ibus | grep -v grep
--ibus address
--'
--
--if [ $# -gt 0 ] ; then
--    TEST_LOG=$1
--fi
--
--run_test()
--{
--while read cmd ; do
--    if [ x"$cmd" = x ] ; then
--        continue
--    fi
--    echo "# $cmd"
--    eval "$cmd"
--done << EOF_COMMANDS
--`echo "$COMMANDS"`
--EOF_COMMANDS
--}
--
--if [ x"$TEST_LOG" = x ] ; then
--    run_test
--else
--    run_test 2>>$TEST_LOG 1>>$TEST_LOG
--fi
-diff --git a/src/tests/ibus-desktop-testing-autostart.in b/src/tests/ibus-desktop-testing-autostart.in
-new file mode 100755
-index 00000000..d50354df
---- /dev/null
-+++ b/src/tests/ibus-desktop-testing-autostart.in
-@@ -0,0 +1,83 @@
-+#!/bin/sh
-+# -*- mode: C; c-basic-offset: 4; indent-tabs-mode: nil; -*-
-+# vim:set noet ts=4:
-+#
-+# ibus - The Input Bus
-+#
-+# Copyright (c) 2021-2024 Takao Fujiwara <takao.fujiwara1@gmail.com>
-+# Copyright (c) 2021 Red Hat, Inc.
-+#
-+# This program is free software; you can redistribute it and/or modify
-+# it under the terms of the GNU General Public License as published by
-+# the Free Software Foundation; either version 2 of the License, or
-+# (at your option) any later version.
-+#
-+# This program is distributed in the hope that it will be useful,
-+# but WITHOUT ANY WARRANTY; without even the implied warranty of
-+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-+# GNU General Public License for more details.
-+#
-+# You should have received a copy of the GNU General Public License along
-+# with this program; if not, write to the Free Software Foundation, Inc.,
-+# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-+
-+
-+PROGNAME=`basename $0`
-+TEST_CASE_DIR="@INSTALLEDDIR@"
-+MODULE_SH='ibus-desktop-testing-module'
-+MODULE_SH_PATH="@LIBEXECDIR@/$MODULE_SH"
-+TEST_LOG="test-autostart.log"
-+TESTING_RUNNER=""
-+
-+
-+if test -f $MODULE_SH_PATH ; then
-+  . $MODULE_SH_PATH
-+elif test -f $(dirname $0)/$MODULE_SH ; then
-+  . $(dirname $0)/$MODULE_SH
-+else
-+  echo "Not found $MODULE_SH"
-+  exit 1
-+fi
-+
-+
-+usage()
-+{
-+    $ECHO -e \
-+"This test suite is called from /etc/xdg/autostart for systemd sessions\n"     \
-+"$PROGNAME [OPTIONS…]\n"                                                       \
-+"\n"                                                                           \
-+"OPTIONS:\n"                                                                   \
-+"-h, --help                       This help\n"                                 \
-+"-v, --version                    Show version\n"                              \
-+"-b, --builddir=BUILDDIR          Set the BUILDDIR\n"                          \
-+"-s, --srcdir=SOURCEDIR           Set the SOURCEDIR\n"                         \
-+"-V, --verbose                    Verbose log for ibus-daemon\n"               \
-+"-t, --tests=\"TESTS...\"           Run TESTS programs which is separated by space\n" \
-+"-r, --runner=RUNNER              Run TESTS programs with a test RUNNER.\n"    \
-+"                                 RUNNDER = 'gnome', 'default' or ''.\n"       \
-+"                                 'default' is an embedded runner.\n"          \
-+"                                 '' is no tests.\n"                           \
-+"-T, --timeout=TIMEOUT            Set timeout (default TIMEOUT is 300 sec).\n" \
-+"-o, --output=OUTPUT_FILE         Output the log to OUTPUT_FILE\n"             \
-+"                                 default is $TEST_LOG\n"                      \
-+"-O, --result=RESULT_FILE         Output the result to RESULT_FILE\n"          \
-+"                                 default is stdout\n"                         \
-+"-S, --screendump=DUMP_FILE       Output the screen to DUMP_FILE ('STDOUT' can be stdout)\n" \
-+"-e, --envcheck                   Retrieve environment variables\n"            \
-+""
-+}
-+
-+
-+main()
-+{
-+    parse_args "$@"
-+    init_session
-+    check_env
-+    save_screen
-+    run_test_suite
-+    finit
-+}
-+
-+
-+# Need to enclose $@ with double quotes not to split the array.
-+main "$@"
-diff --git a/src/tests/ibus-desktop-testing-module b/src/tests/ibus-desktop-testing-module
-new file mode 100755
-index 00000000..2d686813
---- /dev/null
-+++ b/src/tests/ibus-desktop-testing-module
-@@ -0,0 +1,876 @@
-+#!/bin/sh
-+# -*- mode: C; c-basic-offset: 4; indent-tabs-mode: nil; -*-
-+# vim:set noet ts=4:
-+#
-+# ibus - The Input Bus
-+#
-+# Copyright (c) 2018-2024 Takao Fujiwara <takao.fujiwara1@gmail.com>
-+# Copyright (c) 2018 Red Hat, Inc.
-+#
-+# This program is free software; you can redistribute it and/or modify
-+# it under the terms of the GNU General Public License as published by
-+# the Free Software Foundation; either version 2 of the License, or
-+# (at your option) any later version.
-+#
-+# This program is distributed in the hope that it will be useful,
-+# but WITHOUT ANY WARRANTY; without even the implied warranty of
-+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-+# GNU General Public License for more details.
-+#
-+# You should have received a copy of the GNU General Public License along
-+# with this program; if not, write to the Free Software Foundation, Inc.,
-+# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-+
-+
-+# POSIX sh has no 'echo -e'
-+: ${ECHO:='/usr/bin/echo'}
-+# POSIX sh has $UID
-+# DASH saves the graves in '``' as characters not to be extracted
-+: ${UID:=`id -u`}
-+: ${TEST_CASE_DIR='/usr/share/installed-tests'}
-+: ${AUTOSTART_DESKTOP_DIR='/usr/share/ibus/tests'}
-+
-+
-+VERSION=0.4
-+BUILDDIR="."
-+SRCDIR="."
-+TEST_LOG_STDOUT=0
-+RESULT_LOG=""
-+SCREEN_LOG=""
-+HAVE_GRAPHICS=1
-+VERBOSE=0
-+SESSION_COMMAND="dbus-launch --exit-with-session gnome-session"
-+SESSION_LANG=
-+SESSION_IS_GNOME=1
-+GNOME_SHELL_WAYLAND_COMMAND="gnome-shell --wayland --headless --virtual-monitor 1024x768"
-+SYSTEMD_SYSTEM_DIR="/usr/lib/systemd/user"
-+PID_XORG=0
-+PID_GNOME_SESSION=0
-+ENABLED_SYSTEMD=1
-+TEST_USER=itestuser
-+TEST_USER_HOME=/export/home/$TEST_USER
-+GDM_CONF=/run/gdm/custom.conf
-+AUTOSTART_DESKTOP_FILE="org.freedesktop.IBus.Desktop.Testing.desktop"
-+TESTS=""
-+TIMEOUT=300
-+GREEN='\033[0;32m'
-+RED='\033[0;31m'
-+NC='\033[0m'
-+ENV_CHECK=0
-+ENV_COMMANDS='
-+id
-+pwd
-+pstree -asp $$
-+gsettings list-recursively org.gnome.shell
-+rpm -q gnome-shell-extension-no-overview gnome-shell gnome-session
-+ps -ef | grep ibus | grep -v grep
-+ibus address
-+env
-+#dbus-send --session --print-reply --dest=org.gnome.Shell.Introspect /org/gnome/Shell/Introspect org.gnome.Shell.Introspect.GetWindows
-+'
-+
-+
-+print_log()
-+{
-+    if [ x"$RESULT_LOG" != x ] ; then
-+        # avoid 'echo -e' before call 'sed'.
-+        if [ x"$1" = x'-e' ] ; then
-+            shift
-+        fi
-+        NO_ESCAPE=`echo "$@" | sed -e 's/\\\033\\[0;3.m//g' -e 's/\\\033\\[0m//g'`
-+        $ECHO $NO_ESCAPE >> $RESULT_LOG
-+    else
-+        $ECHO "$@"
-+    fi
-+}
-+
-+
-+parse_args()
-+{
-+    # This is GNU getopt. "sudo port getopt" in BSD?
-+    ARGS=`getopt -o hvb:s:cVd:t:r:iT:o:O:S:el:D --long \
-+help,version,builddir:,srcdir:,no-graphics,verbose,desktop:,session:,tests:,\
-+runner:,no-systemd,timeout:,output:,result:,screendump:,envcheck,lang:,\
-+delete-tests\
-+        -- "$@"`;
-+    eval set -- "$ARGS"
-+    while [ 1 ] ; do
-+        case "$1" in
-+        -h | --help )        usage; exit 0;;
-+        -v | --version )     $ECHO -e "$VERSION"; exit 0;;
-+        -b | --builddir )    BUILDDIR="$2"; shift 2;;
-+        -s | --srcdir )      SRCDIR="$2"; shift 2;;
-+        -c | --no-graphics ) HAVE_GRAPHICS=0; shift;;
-+        -V | --verbose )     VERBOSE=1; shift;;
-+        --desktop )          SESSION_COMMAND="$2"
-+                             print_log -e "--desktop is deprecated. Use --session instead"
-+                             shift 2;;
-+        -d | --session )     SESSION_COMMAND="$2"; shift 2;;
-+        -t | --tests )       TESTS="$2"; shift 2;;
-+        -r | --runner )      TESTING_RUNNER="$2"; shift 2;;
-+        -i | --no-systemd )  ENABLED_SYSTEMD=0; shift;;
-+        -T | --timeout )     TIMEOUT="$2"; shift 2;;
-+        -o | --output )      TEST_LOG="$2"; shift 2;;
-+        -O | --result )      RESULT_LOG="$2"; shift 2;;
-+        -S | --screendump )  SCREEN_LOG="$2"; shift 2;;
-+        -e | --envcheck )    ENV_CHECK=1; shift;;
-+        -l | --lang )        SESSION_LANG="$2"; shift 2;;
-+        -D | --delete-tests ) delete_test_user; exit 0;;
-+        -- )                 shift; break;;
-+        * )                  usage; exit 1;;
-+        esac
-+    done
-+    DL='$'
-+    if echo "$SESSION_COMMAND" | grep -q -E ".*-with-dbus$DL" ; then
-+        SESSION_COMMAND=`echo "$SESSION_COMMAND" | sed -e 's/-with-dbus$//'`
-+        SESSION_COMMAND="dbus-launch --exit-with-session $SESSION_COMMAND"
-+    fi
-+}
-+
-+
-+check_tty()
-+{
-+    TTY=`tty`
-+    if echo $PROGNAME | grep -q runner ; then
-+        if [ $ENABLED_SYSTEMD -eq 1 ] && [  $SESSION_IS_GNOME -eq 1 ] ; then
-+            if echo "$TTY" | grep -E 'tty|console' ; then
-+               print_log -e "${RED}FAIL${NC}: ${RED}ERROR${NC}: Changing runlevel does not support console. Please log into the host with ssh."
-+               exit 1
-+            fi
-+        fi
-+        if [ $ENABLED_SYSTEMD -eq 0 ] ; then
-+            if echo "$TTY" | grep -E 'pts' ; then
-+               print_log -e "Running session with ssh. It might be good to use console instead."
-+            fi
-+        fi
-+        SESSION=`ps -ef | grep session | grep -v grep`
-+        if [ x"$SESSION" != x ] ; then
-+               print_log -e "${RED}FAIL${NC}: ${RED}ERROR${NC}: Session is running: $SESSION"
-+               exit 1
-+        fi
-+    fi
-+}
-+
-+
-+check_env()
-+{
-+    if test $ENV_CHECK -eq 0 ; then
-+        return
-+    fi
-+    while read cmd ; do
-+        if test x"$cmd" = x ; then
-+            continue
-+        fi
-+        if echo "$cmd" | grep -q "^#"; then
-+            continue
-+        fi
-+        echo "# $cmd" 2>>$TEST_LOG 1>>$TEST_LOG
-+        eval "$cmd" 2>>$TEST_LOG 1>>$TEST_LOG
-+    done << EOF_ENV_COMMANDS
-+`echo "$ENV_COMMANDS"`
-+EOF_ENV_COMMANDS
-+}
-+
-+
-+save_screen_real()
-+{
-+    SCREEN_PNG="`date '+%Y%m%d%H%M%S'`.png"
-+    gnome-screenshot --file=$SCREEN_PNG
-+    if test x"$SCREEN_LOG" = xSTDOUT ; then
-+        base64 $SCREEN_PNG
-+        touch /var/tmp/STDOUT.log
-+    else
-+        base64 $SCREEN_PNG > $SCREEN_LOG
-+    fi
-+}
-+
-+
-+save_screen()
-+{
-+    if test x"$SCREEN_LOG" = x ; then
-+        return
-+    fi
-+    if test x"$SCREEN_LOG" = xSTDOUT ; then
-+        if test -f /var/tmp/STDOUT.log ; then
-+            rm /var/tmp/STDOUT.log
-+        fi
-+    else
-+        if test -f "$SCREEN_LOG" ; then
-+            rm "$SCREEN_LOG"
-+        fi
-+    fi
-+    save_screen_real &
-+    while test 1 ; do
-+        if test x"$SCREEN_LOG" = xSTDOUT ; then
-+            if test -f /var/tmp/STDOUT.log ; then
-+                break
-+            fi
-+        else
-+            if test -f "$SCREEN_LOG" ; then
-+                break
-+            fi
-+        fi
-+        sleep 1
-+    done
-+}
-+
-+
-+create_test_user()
-+{
-+    if grep -q $TEST_USER /etc/passwd; then
-+        return;
-+    fi
-+    useradd -d $TEST_USER_HOME -m -s /bin/bash $TEST_USER
-+    pwconv
-+    passwd -d $TEST_USER
-+}
-+
-+
-+create_autologin_gdm()
-+{
-+    if test -f $GDM_CONF && grep -q $TEST_USER $GDM_CONF; then
-+        return;
-+    fi
-+    cat > $GDM_CONF << _EOF_GDM_CONF
-+[daemon]
-+AutomaticLoginEnable=true
-+AutomaticLogin=$TEST_USER
-+_EOF_GDM_CONF
-+}
-+
-+
-+create_xdg_autostart()
-+{
-+    if test -f "$TEST_USER_HOME/.config/autostart/$AUTOSTART_DESKTOP_FILE" ; then
-+        return
-+    fi
-+    if test ! -d "$TEST_USER_HOME" ; then
-+        print_log -e "${RED}FAIL${NC}: ${RED}ERROR${NC}: No $TEST_USER_HOME"
-+        exit 1
-+    fi
-+    desktop_file="$AUTOSTART_DESKTOP_DIR/$AUTOSTART_DESKTOP_FILE"
-+    if test ! -f $desktop_file ; then
-+        print_log -e "${RED}FAIL${NC}: ${RED}ERROR${NC}: No $desktop_file"
-+        exit 1
-+    fi
-+    mkdir -p "$TEST_USER_HOME/.config/autostart"
-+    cp "$desktop_file" "$TEST_USER_HOME/.config/autostart"
-+    LINE="AutostartCondition=if-exists $TEST_USER_HOME/.config/autostart/$AUTOSTART_DESKTOP_FILE"
-+    echo "$LINE" >> "$TEST_USER_HOME/.config/autostart/$AUTOSTART_DESKTOP_FILE"
-+    chown -R "$TEST_USER" "$TEST_USER_HOME/.config"
-+}
-+
-+
-+delete_test_user()
-+{
-+    print_log "Deleting $TEST_USER"
-+    pkill -u $TEST_USER
-+    if grep -q $TEST_USER /etc/passwd; then
-+        userdel -r $TEST_USER
-+    fi
-+    if test -f $GDM_CONF && grep -q $TEST_USER $GDM_CONF; then
-+        rm $GDM_CONF
-+    fi
-+
-+    if echo "$SESSION_COMMAND" | grep -q gnome-session ; then
-+        SESSION_IS_GNOME=1
-+    else
-+        SESSION_IS_GNOME=0
-+    fi
-+
-+    LOGIN_USER=$USER
-+    LOGIN_HOME=$HOME
-+    if [ $ENABLED_SYSTEMD -eq 1 ] && [  $SESSION_IS_GNOME -eq 1 ] ; then
-+        LOGIN_USER=$TEST_USER
-+        LOGIN_HOME=$TEST_USER_HOME
-+    fi
-+
-+    print_log "Deleting $LOGIN_USER environments"
-+    if test -f "$LOGIN_HOME/.config/gnome-initial-setup-done" ; then
-+        rm "$LOGIN_HOME/.config/gnome-initial-setup-done"
-+    fi
-+    if test -f "$LOGIN_HOME/.config/user-dirs.locale" ; then
-+        rm "$LOGIN_HOME/.config/user-dirs.locale"
-+    fi
-+    if test -f /var/lib/AccountsService/users/$LOGIN_USER ; then
-+        rm /var/lib/AccountsService/users/$LOGIN_USER
-+    fi
-+    sync
-+}
-+
-+
-+init_session()
-+{
-+    if [ "$RESULT_LOG" != "" ] ; then
-+        if [ -f $RESULT_LOG ] ; then
-+            rm $RESULT_LOG
-+        fi
-+    fi
-+    echo "$TEST_LOG" | grep ':stdout' > /dev/null
-+    HAS_STDOUT=$?
-+    if [ $HAS_STDOUT -eq 0 ] ; then
-+        TEST_LOG=`echo "$TEST_LOG" | sed -e 's|:stdout||'`
-+        TEST_LOG_STDOUT=1
-+    fi
-+    if [ "$TEST_LOG" = "" ] ; then
-+        print_log -e "${RED}FAIL${NC}: ${RED}ERROR${NC}: a log file is required to get return value with 'read' command"
-+        exit 1
-+    elif [ -f $TEST_LOG ] ; then
-+        rm $TEST_LOG
-+    fi
-+
-+    if echo "$SESSION_COMMAND" | grep -q gnome-session ; then
-+        SESSION_IS_GNOME=1
-+    else
-+        SESSION_IS_GNOME=0
-+    fi
-+
-+    LOGIN_USER=$USER
-+    LOGIN_HOME=$HOME
-+    check_tty
-+    if [ $ENABLED_SYSTEMD -eq 1 ] && [  $SESSION_IS_GNOME -eq 1 ] ; then
-+        SESSION_FILE1="/usr/lib/systemd/system/gnome-headless-session@.service"
-+        SESSION_FILE2="/usr/lib/systemd/system/graphical.target"
-+        if [ $HAVE_GRAPHICS -eq 0 ] && [ ! -f "$SESSION_FILE1" ] ; then
-+            print_log -e "${RED}FAIL${NC}: ${RED}ERROR${NC}: No $SESSION_FILE1: You need to install 'gdm' and 'systemd' package"
-+            exit 1
-+        fi
-+        if [ $HAVE_GRAPHICS -eq 1 ] ; then
-+            if [ ! -f "$SESSION_FILE2" ] ; then
-+                print_log -e "${RED}FAIL${NC}: ${RED}ERROR${NC}: No $SESSION_FILE2: You need to install 'systemd' package"
-+                exit 1
-+            fi
-+            if [ ! -f /usr/sbin/gdm ] ; then
-+                print_log -e "${RED}FAIL${NC}: ${RED}ERROR${NC}: No /usr/sbin/gdm: Currently only gdm is supported for auto login."
-+                exit 1
-+            fi
-+        fi
-+        create_test_user
-+        create_autologin_gdm
-+        create_xdg_autostart
-+        LOGIN_USER=$TEST_USER
-+        LOGIN_HOME=$TEST_USER_HOME
-+    else
-+        rm -f $TEST_USER_HOME/.config/autostart/$AUTOSTART_DESKTOP_FILE
-+    fi
-+
-+    if [ ! -f $LOGIN_HOME/.config/gnome-initial-setup-done ] ; then
-+        mkdir -p $LOGIN_HOME/.config
-+        touch $LOGIN_HOME/.config/gnome-initial-setup-done
-+        chown -R $LOGIN_USER $LOGIN_HOME/.config
-+    fi
-+    IS_SYSTEM_ACCOUNT=false
-+    if [ "$LOGIN_USER" = "root" ] ; then
-+            IS_SYSTEM_ACCOUNT=true
-+    fi
-+    if test x"$SESSION_LANG" = x ; then
-+        SESSION_LANG=$LANG
-+    fi
-+    if test -f /var/lib/AccountsService/users/$LOGIN_USER; then
-+        sed -i -e "s/\(Language=\).*/\1$SESSION_LANG/" \
-+                /var/lib/AccountsService/users/$LOGIN_USER
-+    else
-+        mkdir -p /var/lib/AccountsService/users
-+        cat > /var/lib/AccountsService/users/$LOGIN_USER << _EOF_AS_CONF
-+[User]
-+Language=$SESSION_LANG
-+XSession=gnome
-+SystemAccount=$IS_SYSTEM_ACCOUNT
-+_EOF_AS_CONF
-+    fi
-+
-+    # Prevent from launching a XDG dialog
-+    XDG_LOCALE_FILE="$LOGIN_HOME/.config/user-dirs.locale"
-+    if [ -f $XDG_LOCALE_FILE ] ; then
-+        XDG_LANG_ORIG=`cat $XDG_LOCALE_FILE`
-+        XDG_LANG_NEW=`echo $SESSION_LANG | sed -e 's/\(.*\)\..*/\1/'`
-+        if [ "$XDG_LANG_ORIG" != "$XDG_LANG_NEW" ] ; then
-+            echo "# Overriding XDG locale $XDG_LANG_ORIG with $XDG_LANG_NEW"
-+            echo "$XDG_LANG_NEW" > $XDG_LOCALE_FILE
-+        fi
-+    fi
-+
-+    if [ $ENABLED_SYSTEMD -eq 1 ] && [  $SESSION_IS_GNOME -eq 1 ] ; then
-+        return
-+    fi
-+    # `su` command does not run loginctl
-+    export XDG_SESSION_TYPE='x11'
-+    export XDG_SESSION_CLASS=user
-+    # `su` command does not get focus in events without this variable.
-+    # Need to restart sshd after set "PermitRootLogin yes" in sshd_config
-+    if [ "x$XDG_RUNTIME_DIR" = x ] ; then
-+        export XDG_RUNTIME_DIR="/run/user/$UID"
-+        is_root_login=`grep "^PermitRootLogin" /etc/ssh/sshd_config | grep yes`
-+        if [ "x$ANSIBLE" != x ] && [ "x$is_root_login" = x ] ; then
-+            print_log -e "${RED}FAIL${NC}: No permission to get focus-in events in GtkWindow with ansible"
-+            echo "su command does not configure necessary login info "         \
-+                 "with systemd and GtkWindow cannot receive focus-events "     \
-+                 "when ibus-desktop-testing-runner is executed by "            \
-+                 "ansible-playbook." >> $TEST_LOG
-+            echo "Enabling root login via sshd, restarting sshd, set "         \
-+                 "XDG_RUNTIME_DIR can resolve the problem under "              \
-+                 "ansible-playbook." >> $TEST_LOG
-+            exit 1
-+        fi
-+    fi
-+    #  Do we need XDG_SESSION_ID and XDG_SEAT?
-+    #export XDG_CONFIG_DIRS=/etc/xdg
-+    #export XDG_SESSION_ID=10
-+    #export XDG_SESSION_DESKTOP=gnome
-+    #export XDG_SEAT=seat0
-+}
-+
-+
-+run_dbus_daemon()
-+{
-+    if [ $ENABLED_SYSTEMD -eq 1 ] && [  $SESSION_IS_GNOME -eq 1 ] ; then
-+        return
-+    fi
-+    # Use dbus-launch --exit-with-session later instead of --sh-syntax
-+    # GNOME uses a unix:abstract address and it effects gsettings set values
-+    # in each test case.
-+    # TODO: Should we comment out this line?
-+    export DBUS_SESSION_BUS_ADDRESS="unix:path=/run/user/$UID/bus"
-+}
-+
-+
-+init_gnome()
-+{
-+    if test $SESSION_IS_GNOME -ne 1 ; then
-+        print_log -e "${RED}FAIL${NC}: ${RED}ERROR${NC}: Should not be called"
-+        exit 1
-+    fi
-+    LOGIN_USER=$USER
-+    if test $ENABLED_SYSTEMD -eq 1 ; then
-+        LOGIN_USER=$TEST_USER
-+    fi
-+    # gsettings set command needs dconf-service with the same $DISPLAY
-+    pkill dconf-service
-+    # G_MESSAGES_DEBUG=all or G_MESSAGES_DEBUG=GLib-GIO-DEBUG would append
-+    # debug messages to gsettings output and could not get the result correctly.
-+    backup_G_MESSAGES_DEBUG="$G_MESSAGES_DEBUG"
-+    unset G_MESSAGES_DEBUG
-+    # Disable Tour dialog to get focus
-+    GET_WELCOME_DIALOG="gsettings get org.gnome.shell welcome-dialog-last-shown-version"
-+    if test $LOGIN_USER = $USER ; then
-+        V=`dbus-run-session $GET_WELCOME_DIALOG`
-+    else
-+        V=`sudo -u $LOGIN_USER dbus-run-session $GET_WELCOME_DIALOG`
-+    fi
-+    if [ x"$V" = x"''" ] ; then
-+        SET_WELCOME_DIALOG="gsettings set org.gnome.shell welcome-dialog-last-shown-version '100'"
-+        if test $LOGIN_USER = $USER ; then
-+            dbus-run-session $SET_WELCOME_DIALOG
-+        else
-+            sudo -u $LOGIN_USER dbus-run-session $SET_WELCOME_DIALOG
-+        fi
-+    fi
-+    # gnome-shell now starts overview mode by login.
-+    # https://extensions.gnome.org/extension/4099/no-overview/
-+    NO_SYS_DIR=/usr/share/gnome-shell/extensions/no-overview@fthx
-+    if test $LOGIN_USER = $USER ; then
-+        NO_USER_DIR=$HOME/.local/share/gnome-shell/extensions/no-overview@fthx
-+    else
-+        NO_USER_DIR=$TEST_USER_HOME/.local/share/gnome-shell/extensions/no-overview@fthx
-+    fi
-+    if [ ! -d $NO_SYS_DIR ] && [ ! -d $NO_USER_DIR ] ; then
-+        mkdir -p "`dirname $NO_USER_DIR`"
-+        cp -R "no-overview@fthx" "`dirname $NO_USER_DIR`"
-+        if test $LOGIN_USER = $USER ; then
-+            chown -R $LOGIN_USER $HOME/.local
-+        else
-+            chown -R $LOGIN_USER $TEST_USER_HOME/.local
-+        fi
-+    fi
-+    if [ $LOGIN_USER != $USER ] ; then
-+        SHELL_SERVICE_FILE="org.gnome.Shell@wayland.service"
-+        SYSTEMD_USER_DIR="$TEST_USER_HOME/.config/systemd/user"
-+        if test $HAVE_GRAPHICS -ne 1 ; then
-+            if test ! -f "$SYSTEMD_USER_DIR/$SHELL_SERVICE_FILE" ; then
-+                mkdir -p "$SYSTEMD_USER_DIR"
-+                pushd "$SYSTEMD_USER_DIR"
-+                sed -e "s|^ExecStart=.*|ExecStart=$GNOME_SHELL_WAYLAND_COMMAND|" \
-+                    $SYSTEMD_SYSTEM_DIR/$SHELL_SERVICE_FILE \
-+                    > $SHELL_SERVICE_FILE
-+                diff $SYSTEMD_SYSTEM_DIR/$SHELL_SERVICE_FILE $SHELL_SERVICE_FILE
-+                popd
-+                chown -R $LOGIN_USER "$TEST_USER_HOME/.config"
-+            fi
-+        else
-+            if test -f "$SYSTEMD_USER_DIR/$SHELL_SERVICE_FILE" ; then
-+                rm "$SYSTEMD_USER_DIR/$SHELL_SERVICE_FILE"
-+            fi
-+        fi
-+    fi
-+    GET_DISABLE_USER_EX="gsettings get org.gnome.shell disable-user-extensions"
-+    if test $LOGIN_USER = $USER ; then
-+        V=`dbus-run-session $GET_DISABLE_USER_EX`
-+    else
-+        V=`sudo -u $LOGIN_USER dbus-run-session $GET_DISABLE_USER_EX`
-+    fi
-+    if [ x"$V" = x"true" ] ; then
-+        SET_DISABLE_USER_EX="gsettings set org.gnome.shell disable-user-extensions false"
-+        if test $LOGIN_USER = $USER ; then
-+            dbus-run-session $SET_DISABLE_USER_EX
-+        else
-+            sudo -u $LOGIN_USER dbus-run-session $SET_DISABLE_USER_EX
-+        fi
-+    fi
-+    GET_ENABLED_EXS="gsettings get org.gnome.shell enabled-extensions"
-+    if test $LOGIN_USER = $USER ; then
-+        V=`dbus-run-session $GET_ENABLED_EXS`
-+    else
-+        V=`sudo -u $LOGIN_USER dbus-run-session $GET_ENABLED_EXS`
-+    fi
-+    echo "$V" | grep "no-overview" > /dev/null
-+    V2=$?
-+    if [ $V2 -ne 0 ] ; then
-+        V3=`echo "$V" | sed -e 's/@as //' -e 's/\[//' -e 's/\]//'`
-+        if [ x"$V3" = x"''" ] || [ x"$V3" = x"" ]; then
-+            V4="['no-overview@fthx']"
-+        else
-+            V4="[$V3,'no-overview@fthx']"
-+        fi
-+        SET_ENABLED_EXS="gsettings set org.gnome.shell enabled-extensions \"$V4\""
-+        if test $LOGIN_USER = $USER ; then
-+            eval dbus-run-session $SET_ENABLED_EXS
-+        else
-+            eval sudo -u $LOGIN_USER dbus-run-session $SET_ENABLED_EXS
-+        fi
-+    fi
-+    # Disable notify dialog when the disk usage is low.
-+    SET_NOTIFY_DISK="gsettings set org.gnome.settings-daemon.plugins.housekeeping free-size-gb-no-notify 0"
-+    if test $LOGIN_USER = $USER ; then
-+            eval dbus-run-session $SET_NOTIFY_DISK
-+    else
-+            eval sudo -u $LOGIN_USER dbus-run-session $SET_NOTIFY_DISK
-+    fi
-+    if [ x"$backup_G_MESSAGES_DEBUG" != x ] ; then
-+        export G_MESSAGES_DEBUG="$backup_G_MESSAGES_DEBUG"
-+    fi
-+}
-+
-+
-+operate_desktop_with_systemd()
-+{
-+    SESSION=gnome-headless-session
-+    COMMAND="$1"
-+
-+    #if test $HAVE_GRAPHICS -eq 1 ; then
-+        case "$COMMAND" in
-+        "start") systemctl isolate graphical.target
-+                 echo ""
-+                 ;;
-+        "stop")  init 3;;
-+        "")      print_log -e "${RED}FAIL${NC}: ${RED}ERROR${NC}: Wrong command $COMMAND"
-+                 exit 1;;
-+        esac
-+    #else
-+    #    setenforce 0
-+    #    systemctl $COMMAND ${SESSION}@${TEST_USER}
-+    #fi
-+    case "$COMMAND" in
-+    "start") sleep 30;;
-+    "") ;;
-+    esac
-+    #if test $HAVE_GRAPHICS -eq 1 ; then
-+        systemctl status --no-pager graphical.target
-+    #else
-+    #    systemctl status --no-pager ${SESSION}@${TEST_USER}
-+    #fi
-+    ps -ef | grep X
-+    ps -ef | grep session
-+    ps -ef | grep ibus
-+}
-+
-+
-+run_session()
-+{
-+    if [ $ENABLED_SYSTEMD -eq 1 ] && [  $SESSION_IS_GNOME -eq 1 ] ; then
-+        init_gnome
-+        operate_desktop_with_systemd "start"
-+        return
-+    fi
-+    export DISPLAY=:99.0
-+    if test $HAVE_GRAPHICS -eq 1 ; then
-+        /usr/libexec/Xorg.wrap -noreset +extension GLX +extension RANDR +extension RENDER -logfile ./xorg.log -config ./xorg.conf -configdir . $DISPLAY &
-+    else
-+        /usr/bin/Xvfb $DISPLAY -noreset +extension GLX +extension RANDR +extension RENDER -screen 0 1280x1024x24 &
-+    fi
-+    PID_XORG=$!
-+    sleep 1
-+    # init_gnome need to be called with $DISPLAY before gnome-session is called
-+    if [  $SESSION_IS_GNOME -eq 1 ] ; then
-+        init_gnome
-+    fi
-+    echo "Running $SESSION_COMMAND with $USER and LANG=$SESSION_LANG in `tty`"
-+    if test x"$SESSION_LANG" = x ; then
-+        $SESSION_COMMAND &
-+    else
-+        env LANG=$SESSION_LANG $SESSION_COMMAND &
-+    fi
-+    PID_GNOME_SESSION=$!
-+    sleep 30
-+
-+    IBUS_ARGS="--verbose --panel disable"
-+    # gnome-shell 42 checks if org.freedesktop.IBus.session.GNOME.service
-+    # systemd file is available with org.freedesktop.systemd1.Manager.GetUnit
-+    # D-Bus method, which is provided by IBus 1.5.26, and if the file
-+    # is available, gnome-shell no longer launch ibus-daemon
-+    # because gnome-shell assumes gnome-session would launch ibus-daemon
-+    # with org.freedesktop.systemd1.Manager.StartUnit D-Bus method.
-+    # But actually gnome-session failed to launch ibus-daemon
-+    # because the IBus systemd file depends on gnome-session.target
-+    # but this CI launches gnome-session directly.
-+    #
-+    # So ibus-dameon is now always called here after gnome-shell fails to
-+    # launch ibus-daemon.
-+    # It may be better this CI launches GDM autologin to run gnome-session
-+    # with gnome-session.target systemd file.
-+    # But `systemctl start gdm` terminates the parent script forcibly
-+    # and the script cannot get the CI result.
-+    if test $VERBOSE -eq 1 ; then
-+        ibus-daemon $IBUS_ARGS &
-+    else
-+        ibus-daemon $IBUS_ARGS --daemonize
-+    fi
-+    sleep 3
-+    ps -ef | grep ibus
-+}
-+
-+
-+count_case_result()
-+{
-+    retval=$1
-+    pass=$2
-+    fail=$3
-+
-+    if test $retval -eq  0 ; then
-+        pass=`expr $pass + 1`
-+    else
-+        fail=`expr $fail + 1`
-+    fi
-+    echo $pass $fail
-+}
-+
-+
-+echo_case_result()
-+{
-+    retval=$1
-+    tst=$2
-+    subtst=${3:-''}
-+
-+    if test $retval -eq  0 ; then
-+        echo "PASS: $tst $subtst" >>$TEST_LOG
-+    else
-+        echo "FAIL: $tst $subtst" >>$TEST_LOG
-+    fi
-+}
-+
-+
-+wait_for_systemd_autostart()
-+{
-+    PS_IBUS="ps -ef | grep ibus-desktop-testing | grep autostart | grep -v grep"
-+    i=0
-+    while test 1 ; do
-+        R=`eval "$PS_IBUS"`
-+        if test x"$R" != x ; then
-+            break;
-+        fi
-+        if test $i -ge 12 ; then
-+            print_log -e "${RED}FAIL${NC}: Timeout to run ibus-desktop-testing-autostart"
-+            return
-+        fi
-+        i=`expr $i + 1`
-+        sleep 5
-+    done
-+    print_log -e "Start ibus-desktop-testing-autostart"
-+    i=0
-+    while test 1 ; do
-+        R=`eval "$PS_IBUS"`
-+        if test x"$R" = x ; then
-+            break;
-+        fi
-+        if test $i -ge $TIMEOUT ; then
-+            print_log -e "${RED}FAIL${NC}: Timeout to exit ibus-desktop-testing-autostart"
-+            return
-+        fi
-+        i=`expr $i + 1`
-+        sleep 5
-+    done
-+    print_log -e "Exit ibus-desktop-testing-autostart"
-+}
-+
-+run_direct_test_cases()
-+{
-+    pass=0
-+    fail=0
-+    for tst in $TESTS; do
-+        ENVS=
-+        if test -f $SRCDIR/${tst}.env ; then
-+            ENVS="`cat $SRCDIR/${tst}.env`"
-+        fi
-+        if test x"$ENVS" = x ; then
-+            $BUILDDIR/$tst $SRCDIR 2>>$TEST_LOG 1>>$TEST_LOG
-+            retval=$?
-+            read pass fail << EOF_COUNT
-+            `count_case_result $retval $pass $fail`
-+EOF_COUNT
-+            echo_case_result $retval $tst
-+            CACHE_FILES=`ls *.cache`
-+            if [ x"$CACHE_FILES" != x ] ; then
-+                echo "# Clean $CACHE_FILES" >>$TEST_LOG
-+                rm $CACHE_FILES
-+            fi
-+        else
-+            i=1
-+            # Deleted for var in "$ENVS" because IFS=$'\n' is not supported
-+            # in POSIX sh
-+            while read e ; do
-+                first=`echo "$e" | grep '^#'`
-+                if test x"$first" = x"#" ; then
-+                    continue
-+                fi
-+                echo "# Starting $e $BUILDDIR/$tst $SRCDIR" >>$TEST_LOG
-+                env $e $BUILDDIR/$tst $SRCDIR 2>>$TEST_LOG 1>>$TEST_LOG
-+                retval=$?
-+                echo "# Finished $e $BUILDDIR/$tst $SRCDIR with $retval" >>$TEST_LOG
-+                read pass fail << EOF_COUNT
-+                `count_case_result $retval $pass $fail`
-+EOF_COUNT
-+                echo_case_result $retval $tst $e
-+                CACHE_FILES=`ls *.cache`
-+                if [ x"$CACHE_FILES" != x ] ; then
-+                    echo "# Clean $CACHE_FILES" >>$TEST_LOG
-+                    rm $CACHE_FILES
-+                fi
-+                i=`expr $i + 1`
-+            done << EOF_ENVS
-+            `echo "$ENVS"`
-+EOF_ENVS
-+        fi
-+    done
-+    echo $pass $fail
-+}
-+
-+
-+run_gnome_desktop_testing_runner()
-+{
-+    pass=0
-+    fail=0
-+    if [ x"$TESTS" = x ] ; then
-+        TESTS='ibus'
-+    fi
-+    if echo $PROGNAME | grep -q autostart ; then
-+        export IBUS_DAEMON_WITH_SYSTEMD=1
-+    fi
-+    for tst in $TESTS; do
-+        tst_dir="$TEST_CASE_DIR/$tst"
-+        if [ ! -d "$tst_dir" ] ; then
-+            print_log -e "${RED}FAIL${NC}: Not found %tst_dir"
-+            fail=1
-+            continue
-+        fi
-+        gnome-desktop-testing-runner --timeout=$TIMEOUT $tst \
-+                2>>$TEST_LOG 1>>$TEST_LOG
-+        retval=$?
-+        read pass fail << EOF
-+        `count_case_result $retval $pass $fail`
-+EOF
-+    done
-+    child_pass=`grep '^PASS:' $TEST_LOG | wc -l`
-+    child_fail=`grep '^FAIL:' $TEST_LOG | wc -l`
-+    if [ $child_pass -ne 0 ] || [ $child_fail -ne 0 ] ; then
-+        pass=$child_pass
-+        if [ $child_fail -ne 0 ] ; then
-+            fail=`expr $child_fail / 2`
-+        else
-+            fail=0
-+        fi
-+    fi
-+    echo $pass $fail
-+}
-+
-+
-+run_test_suite()
-+{
-+    print_log -e "Start test suite `date '+%F %H:%M:%S:%N'`"
-+    if echo $PROGNAME | grep -q runner ; then
-+        if [ $ENABLED_SYSTEMD -eq 1 ] && [  $SESSION_IS_GNOME -eq 1 ] ; then
-+            wait_for_systemd_autostart
-+            return
-+        fi
-+        if ps -ef | grep X | grep -q wayland ; then
-+            # Expect GTK_IM_MODULE=wayland by default
-+            :
-+        else
-+            export GTK_IM_MODULE=ibus
-+        fi
-+    else
-+        if test x"$XDG_SESSION_TYPE" = xwayland ; then
-+            :
-+        else
-+            export GTK_IM_MODULE=ibus
-+        fi
-+    fi
-+    pass=0
-+    fail=0
-+    export IBUS_COMPOSE_CACHE_DIR=$PWD
-+    if test x"$TESTING_RUNNER" = x ; then
-+        return
-+    fi
-+    case $TESTING_RUNNER in
-+    default)
-+        # Get only the last value with do-while.
-+        read pass fail << EOF_RUNNER
-+        `run_direct_test_cases`
-+EOF_RUNNER
-+        ;;
-+    gnome)
-+        read pass fail << EOF_RUNNER
-+        `run_gnome_desktop_testing_runner`
-+EOF_RUNNER
-+        ;;
-+    esac
-+    echo ""
-+    print_log -e "End test suite `date '+%F %H:%M:%S:%N'`"
-+    # Fedora CI assumes the test is failed even if $fail is 0.
-+    if [ $pass -ne 0 ] ; then
-+        print_log -e "${GREEN}PASS${NC}: $pass"
-+    fi
-+    if [ $fail -ne 0 ] ; then
-+        print_log -e "${RED}FAIL${NC}: $fail"
-+    fi
-+}
-+
-+
-+finit()
-+{
-+    if test $PID_XORG -ne 0 ; then
-+        echo "# Killing left gnome-session and Xorg"
-+        kill $PID_GNOME_SESSION $PID_XORG
-+        ibus exit
-+        SUSER=`echo "$USER" | cut -c 1-7`
-+        LEFT_CALENDAR=`ps -ef | grep gnome-shell-calendar-server | grep $SUSER | grep -v grep`
-+        if test x"$LEFT_CALENDAR" != x ; then
-+            echo "# Killing left gnome-shell-calendar-server"
-+            echo "$LEFT_CALENDAR"
-+            echo "$LEFT_CALENDAR" | awk '{print $2}' | xargs kill
-+        fi
-+    fi
-+    if echo $PROGNAME | grep -q runner ; then
-+        if [ $ENABLED_SYSTEMD -eq 1 ] && [  $SESSION_IS_GNOME -eq 1 ] ; then
-+            operate_desktop_with_systemd "stop"
-+        fi
-+    fi
-+
-+    echo ""
-+    if test -f $TEST_LOG ; then
-+        if [ $TEST_LOG_STDOUT -eq 1 ] ; then
-+            cat $TEST_LOG
-+        else
-+            echo "# See $TEST_LOG"
-+        fi
-+    fi
-+    echo "# Finished $PROGNAME testing"
-+}
-diff --git a/src/tests/ibus-desktop-testing-runner.in b/src/tests/ibus-desktop-testing-runner.in
-index 1ac2dfc8..1d82bc76 100755
---- a/src/tests/ibus-desktop-testing-runner.in
-+++ b/src/tests/ibus-desktop-testing-runner.in
-@@ -4,7 +4,7 @@
- #
- # ibus - The Input Bus
- #
--# Copyright (c) 2018-2021 Takao Fujiwara <takao.fujiwara1@gmail.com>
-+# Copyright (c) 2018-2024 Takao Fujiwara <takao.fujiwara1@gmail.com>
- # Copyright (c) 2018 Red Hat, Inc.
- #
- # This program is free software; you can redistribute it and/or modify
-@@ -22,58 +22,39 @@
- # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- 
- # This test runs /usr/bin/ibus-daemon after install ibus
--#
--# # init 3
--# Login as root
--# # /root/ibus/tests/test-console.sh --tests ibus-compose \
--#   --builddir /root/ibus/src/tests --srcdir /root/ibus/src/tests
--
--# POSIX sh has no 'echo -e'
--: ${ECHO:='/usr/bin/echo'}
--# POSIX sh has $UID
--# DASH saves the graves in '``' as characters not to be extracted
--: ${UID:=`id -u`}
- 
- 
- PROGNAME=`basename $0`
--VERSION=0.3
--DISPLAY=:99.0
--BUILDDIR="."
--SRCDIR="."
-+TEST_CASE_DIR="@INSTALLEDDIR@"
-+MODULE_SH='ibus-desktop-testing-module'
-+MODULE_SH_PATH="@LIBEXECDIR@/$MODULE_SH"
-+AUTOSTART_DESKTOP_DIR="@DATADIR@/ibus/tests"
- TEST_LOG="test-suite.log"
--TEST_LOG_STDOUT=0
--RESULT_LOG=""
--SCREEN_LOG=""
--HAVE_GRAPHICS=1
--VERBOSE=0
--DESKTOP_COMMAND="dbus-launch --exit-with-session gnome-session"
--PID_XORG=0
--PID_GNOME_SESSION=0
- TESTING_RUNNER="default"
--TESTS=""
--TIMEOUT=300
--GREEN='\033[0;32m'
--RED='\033[0;31m'
--NC='\033[0m'
- 
- 
--print_log()
--{
--    if [ x"$RESULT_LOG" != x ] ; then
--        # avoid 'echo -e' before call 'sed'.
--        if [ x"$1" = x'-e' ] ; then
--            shift
--        fi
--        NO_ESCAPE=`echo "$@" | sed -e 's/\\\033\\[0;3.m//g' -e 's/\\\033\\[0m//g'`
--        $ECHO $NO_ESCAPE >> $RESULT_LOG
--    else
--        $ECHO "$@"
--    fi
--}
-+if test -f $MODULE_SH_PATH ; then
-+  . $MODULE_SH_PATH
-+elif test -f $(dirname $0)/$MODULE_SH ; then
-+  . $(dirname $0)/$MODULE_SH
-+else
-+  echo "Not found $MODULE_SH"
-+  exit 1
-+fi
- 
- 
- usage()
- {
-+    command=""
-+    for element in $SESSION_COMMAND; do
-+        if test x"$element" = x; then
-+            continue
-+        fi
-+        if echo "$element" | grep -q -E "^-" ; then
-+            continue
-+        fi
-+        command="$element"
-+    done
-     $ECHO -e \
- "This test runs /usr/bin/ibus-daemon after install ibus\n"                     \
- "$PROGNAME [OPTIONS…]\n"                                                       \
-@@ -83,429 +64,37 @@ usage()
- "-v, --version                    Show version\n"                              \
- "-b, --builddir=BUILDDIR          Set the BUILDDIR\n"                          \
- "-s, --srcdir=SOURCEDIR           Set the SOURCEDIR\n"                         \
--"-c, --no-graphics                Use Xvfb instead of Xorg\n"                  \
-+"-c, --no-graphics                Use Xvfb instead of Xorg or Wayland\n"       \
- "-V, --verbose                    Verbose log for ibus-daemon\n"               \
--"-d, --desktop=DESKTOP            Run DESTKTOP. The default is gnome-session.\n" \
--"                                 Suffix '-with-dbus' can run DESKTOP with dbus session." \
--"                                 E.g. --desktop=mutter-with-dbus"             \
-+"-d, --session=SESSION            Run SESSION. The default is ${command}.\n"   \
-+"                                 Suffix '-with-dbus' can run SESSION with dbus session.\n" \
-+"                                 E.g. --session=${command}-with-dbus\n"       \
-+"-l, --lang=LANG                  Run SESSION with LANG\n"                     \
- "-t, --tests=\"TESTS...\"           Run TESTS programs which is separated by space\n" \
- "-r, --runner=RUNNER              Run TESTS programs with a test RUNNER.\n"    \
--"                                 RUNNDER = gnome or default.\n"               \
--"                                 default is an embedded runner.\n"            \
-+"                                 RUNNDER = 'gnome' or 'default'.\n"           \
-+"                                 'default' is an embedded runner.\n"          \
-+"-i, --no-systemd                 Run gnome-seesion directly withoout systemd\n" \
-+"                                 and login manager for legacy GNOME and this\n" \
-+"                                 mode does not support Wayland.\n" \
- "-T, --timeout=TIMEOUT            Set timeout (default TIMEOUT is 300 sec).\n" \
--"-o, --output=OUTPUT_FILE         OUtput the log to OUTPUT_FILE\n"             \
--"-O, --result=RESULT_FILE         OUtput the result to RESULT_FILE\n"          \
--"-S, --screendump=DUMP_FILE       OUtput the screen to DUMP_FILE ('STDOUT' can be stdout)\n" \
-+"-o, --output=OUTPUT_FILE         Output the log to OUTPUT_FILE\n"             \
-+"                                 default is $TEST_LOG\n"                      \
-+"-O, --result=RESULT_FILE         Output the result to RESULT_FILE\n"          \
-+"                                 default is stdout\n"                         \
-+"-S, --screendump=DUMP_FILE       Output the screen to DUMP_FILE ('STDOUT' can be stdout)\n" \
-+"-D, --delete-tests               Delete test enviroments and user $TEST_USER\n" \
- ""
- }
- 
- 
--parse_args()
--{
--    # This is GNU getopt. "sudo port getopt" in BSD?
--    ARGS=`getopt -o hvb:s:cVd:t:r:T:o:O:S: --long \
--          help,version,builddir:,srcdir:,no-graphics,verbose,desktop:,tests:,runner:,timeout:,output:,result:,screendump:\
--        -- "$@"`;
--    eval set -- "$ARGS"
--    while [ 1 ] ; do
--        case "$1" in
--        -h | --help )        usage; exit 0;;
--        -v | --version )     $ECHO -e "$VERSION"; exit 0;;
--        -b | --builddir )    BUILDDIR="$2"; shift 2;;
--        -s | --srcdir )      SRCDIR="$2"; shift 2;;
--        -c | --no-graphics ) HAVE_GRAPHICS=0; shift;;
--        -V | --verbose )     VERBOSE=1; shift;;
--        -d | --desktop )     DESKTOP_COMMAND="$2"; shift 2;;
--        -t | --tests )       TESTS="$2"; shift 2;;
--        -r | --runner )      TESTING_RUNNER="$2"; shift 2;;
--        -T | --timeout )     TIMEOUT="$2"; shift 2;;
--        -o | --output )      TEST_LOG="$2"; shift 2;;
--        -O | --result )      RESULT_LOG="$2"; shift 2;;
--        -S | --screendump )  SCREEN_LOG="$2"; shift 2;;
--        -- )                 shift; break;;
--        * )                  usage; exit 1;;
--        esac
--    done
--    DL='$'
--    echo "$DESKTOP_COMMAND" | grep "\-with\-dbus$DL" > /dev/null
--    HAS_DBUS_SUFFIX=$?
--    if [ $HAS_DBUS_SUFFIX -eq 0 ] ; then
--        DESKTOP_COMMAND=`echo "$DESKTOP_COMMAND" | sed -e 's/-with-dbus$//'`
--        DESKTOP_COMMAND="dbus-launch --exit-with-session $DESKTOP_COMMAND"
--    fi
--}
--
--
--init_desktop()
--{
--    if [ "$RESULT_LOG" != "" ] ; then
--        if [ -f $RESULT_LOG ] ; then
--            rm $RESULT_LOG
--        fi
--    fi
--    echo "$TEST_LOG" | grep ':stdout' > /dev/null
--    HAS_STDOUT=$?
--    if [ $HAS_STDOUT -eq 0 ] ; then
--        TEST_LOG=`echo "$TEST_LOG" | sed -e 's|:stdout||'`
--        TEST_LOG_STDOUT=1
--    fi
--    if [ "$TEST_LOG" = "" ] ; then
--        print_log -e "${RED}FAIL${NC}: ${RED}ERROR${NC}: a log file is required to get return value with 'read' command"
--        exit 255
--    elif [ -f $TEST_LOG ] ; then
--        rm $TEST_LOG
--    fi
--    if [ x$FORCE_TEST != x ] ; then
--        RUN_ARGS="$RUN_ARGS --force"
--    fi
--
--    if [ ! -f $HOME/.config/gnome-initial-setup-done ] ; then
--        IS_SYSTEM_ACCOUNT=false
--        if [ "$USER" = "root" ] ; then
--            IS_SYSTEM_ACCOUNT=true
--        fi
--        if test ! -f /var/lib/AccountsService/users/$USER ; then
--            mkdir -p /var/lib/AccountsService/users
--            cat >> /var/lib/AccountsService/users/$USER << _EOF
--[User]
--Language=ja_JP.UTF-8
--XSession=gnome
--SystemAccount=$IS_SYSTEM_ACCOUNT
--_EOF
--        fi
--        mkdir -p $HOME/.config
--        touch $HOME/.config/gnome-initial-setup-done
--    fi
--
--    # Prevent from launching a XDG dialog
--    XDG_LOCALE_FILE="$HOME/.config/user-dirs.locale"
--    if [ -f $XDG_LOCALE_FILE ] ; then
--        XDG_LANG_ORIG=`cat $XDG_LOCALE_FILE`
--        XDG_LANG_NEW=`echo $LANG | sed -e 's/\(.*\)\..*/\1/'`
--        if [ "$XDG_LANG_ORIG" != "$XDG_LANG_NEW" ] ; then
--            echo "# Overriding XDG locale $XDG_LANG_ORIG with $XDG_LANG_NEW"
--            echo "$XDG_LANG_NEW" > $XDG_LOCALE_FILE
--        fi
--    fi
--    # `su` command does not run loginctl
--    export XDG_SESSION_TYPE='x11'
--    export XDG_SESSION_CLASS=user
--    # `su` command does not get focus in events without this variable.
--    # Need to restart sshd after set "PermitRootLogin yes" in sshd_config
--    if [ "x$XDG_RUNTIME_DIR" = x ] ; then
--        export XDG_RUNTIME_DIR="/run/user/$UID"
--        is_root_login=`grep "^PermitRootLogin" /etc/ssh/sshd_config | grep yes`
--        if [ "x$ANSIBLE" != x ] && [ "x$is_root_login" = x ] ; then
--            print_log -e "${RED}FAIL${NC}: No permission to get focus-in events in GtkWindow with ansible"
--            echo "su command does not configure necessary login info "         \
--                 "with systemd and GtkWindow cannot receive focus-events "     \
--                 "when ibus-desktop-testing-runner is executed by "            \
--                 "ansible-playbook." >> $TEST_LOG
--            echo "Enabling root login via sshd, restarting sshd, set "         \
--                 "XDG_RUNTIME_DIR can resolve the problem under "              \
--                 "ansible-playbook." >> $TEST_LOG
--            exit 255
--        fi
--    fi
--    #  Do we need XDG_SESSION_ID and XDG_SEAT?
--    #export XDG_CONFIG_DIRS=/etc/xdg
--    #export XDG_SESSION_ID=10
--    #export XDG_SESSION_DESKTOP=gnome
--    #export XDG_SEAT=seat0
--}
--
--
--run_dbus_daemon()
--{
--    # Use dbus-launch --exit-with-session later instead of --sh-syntax
--    # GNOME uses a unix:abstract address and it effects gsettings set values
--    # in each test case.
--    # TODO: Should we comment out this line?
--    export DBUS_SESSION_BUS_ADDRESS="unix:path=/run/user/$UID/bus"
--}
--
--
--init_gnome()
--{
--    # gsettings set command needs dconf-service with the same $DISPLAY
--    pkill dconf-service
--    # G_MESSAGES_DEBUG=all or G_MESSAGES_DEBUG=GLib-GIO-DEBUG would append
--    # debug messages to gsettings output and could not get the result correctly.
--    backup_G_MESSAGES_DEBUG="$G_MESSAGES_DEBUG"
--    unset G_MESSAGES_DEBUG
--    # Disable Tour dialog to get focus
--    V=`gsettings get org.gnome.shell welcome-dialog-last-shown-version`
--    if [ x"$V" = x"''" ] ; then
--        gsettings set org.gnome.shell welcome-dialog-last-shown-version '100'
--    fi
--    # gnome-shell now starts overview mode by login.
--    # https://extensions.gnome.org/extension/4099/no-overview/
--    NO_SYS_DIR=/usr/share/gnome-shell/extensions/no-overview@fthx
--    NO_USER_DIR=$HOME/.local/share/gnome-shell/extensions/no-overview@fthx
--    if [ ! -d $NO_SYS_DIR ] && [ ! -d $NO_USER_DIR ] ; then
--        mkdir -p "`dirname $NO_USER_DIR`"
--        cp -R "no-overview@fthx" "`dirname $NO_USER_DIR`"
--    fi
--    V=`gsettings get org.gnome.shell disable-user-extensions`
--    if [ x"$V" = x"true" ] ; then
--        gsettings set org.gnome.shell disable-user-extensions false
--    fi
--    V=`gsettings get org.gnome.shell enabled-extensions`
--    echo "$V" | grep "no-overview" > /dev/null
--    V2=$?
--    if [ $V2 -ne 0 ] ; then
--        V3=`echo "$V" | sed -e 's/@as //' -e 's/\[//' -e 's/\]//'`
--        if [ x"$V3" = x"''" ] || [ x"$V3" = x"" ]; then
--            V4="['no-overview@fthx']"
--        else
--            V4="[$V3, 'no-overview@fthx']"
--        fi
--        gsettings set org.gnome.shell enabled-extensions "$V4"
--    fi
--    if [ x"$backup_G_MESSAGES_DEBUG" != x ] ; then
--        export G_MESSAGES_DEBUG="$backup_G_MESSAGES_DEBUG"
--    fi
--}
--
--
--run_desktop()
--{
--    echo "$DESKTOP_COMMAND" | grep gnome-session > /dev/null
--    HAS_GNOME=$?
--    export DISPLAY=$DISPLAY
--    if test $HAVE_GRAPHICS -eq 1 ; then
--        /usr/libexec/Xorg.wrap -noreset +extension GLX +extension RANDR +extension RENDER -logfile ./xorg.log -config ./xorg.conf -configdir . $DISPLAY &
--    else
--        /usr/bin/Xvfb $DISPLAY -noreset +extension GLX +extension RANDR +extension RENDER -screen 0 1280x1024x24 &
--    fi
--    PID_XORG=$!
--    sleep 1
--    # init_gnome need to be called with $DISPLAY before gnome-session is called
--    if [  $HAS_GNOME -eq 0 ] ; then
--        init_gnome
--    fi
--    echo "Running $DESKTOP_COMMAND with $USER in `tty`"
--    $DESKTOP_COMMAND &
--    PID_GNOME_SESSION=$!
--    sleep 30
--
--    IBUS_ARGS="--verbose --panel disable"
--    # gnome-shell 42 checks if org.freedesktop.IBus.session.GNOME.service
--    # systemd file is available with org.freedesktop.systemd1.Manager.GetUnit
--    # D-Bus method, which is provided by IBus 1.5.26, and if the file
--    # is available, gnome-shell no longer launch ibus-daemon
--    # because gnome-shell assumes gnome-session would launch ibus-daemon
--    # with org.freedesktop.systemd1.Manager.StartUnit D-Bus method.
--    # But actually gnome-session failed to launch ibus-daemon
--    # because the IBus systemd file depends on gnome-session.target
--    # but this CI launches gnome-session directly.
--    #
--    # So ibus-dameon is now always called here after gnome-shell fails to
--    # launch ibus-daemon.
--    # It may be better this CI launches GDM autologin to run gnome-session
--    # with gnome-session.target systemd file.
--    # But `systemctl start gdm` terminates the parent script forcibly
--    # and the script cannot get the CI result.
--    if test $VERBOSE -eq 1 ; then
--        ibus-daemon $IBUS_ARGS &
--    else
--        ibus-daemon $IBUS_ARGS --daemonize
--    fi
--    sleep 3
--    if test $VERBOSE -eq 1 ; then
--        ps -ef | grep ibus
--    fi
--}
--
--
--count_case_result()
--{
--    retval=$1
--    pass=$2
--    fail=$3
--
--    if test $retval -eq  0 ; then
--        pass=`expr $pass + 1`
--    else
--        fail=`expr $fail + 1`
--    fi
--    echo $pass $fail
--}
--
--
--echo_case_result()
--{
--    retval=$1
--    tst=$2
--    subtst=${3:-''}
--
--    if test $retval -eq  0 ; then
--        echo "PASS: $tst $subtst" >>$TEST_LOG
--    else
--        echo "FAIL: $tst $subtst" >>$TEST_LOG
--    fi
--}
--
--
--run_direct_test_cases()
--{
--    pass=0
--    fail=0
--    for tst in $TESTS; do
--        ENVS=
--        if test -f $SRCDIR/${tst}.env ; then
--            ENVS="`cat $SRCDIR/${tst}.env`"
--        fi
--        if test x"$ENVS" = x ; then
--            $BUILDDIR/$tst $SRCDIR 2>>$TEST_LOG 1>>$TEST_LOG
--            retval=$?
--            read pass fail << EOF_COUNT
--            `count_case_result $retval $pass $fail`
--EOF_COUNT
--            echo_case_result $retval $tst
--            CACHE_FILES=`ls *.cache`
--            if [ x"$CACHE_FILES" != x ] ; then
--                echo "# Clean $CACHE_FILES" >>$TEST_LOG
--                rm $CACHE_FILES
--            fi
--        else
--            i=1
--            # Deleted for var in "$ENVS" because IFS=$'\n' is not supported
--            # in POSIX sh
--            while read e ; do
--                first=`echo "$e" | grep '^#'`
--                if test x"$first" = x"#" ; then
--                    continue
--                fi
--                echo "# Starting $e $BUILDDIR/$tst $SRCDIR" >>$TEST_LOG
--                env $e $BUILDDIR/$tst $SRCDIR 2>>$TEST_LOG 1>>$TEST_LOG
--                retval=$?
--                echo "# Finished $e $BUILDDIR/$tst $SRCDIR with $retval" >>$TEST_LOG
--                read pass fail << EOF_COUNT
--                `count_case_result $retval $pass $fail`
--EOF_COUNT
--                echo_case_result $retval $tst $e
--                CACHE_FILES=`ls *.cache`
--                if [ x"$CACHE_FILES" != x ] ; then
--                    echo "# Clean $CACHE_FILES" >>$TEST_LOG
--                    rm $CACHE_FILES
--                fi
--                i=`expr $i + 1`
--            done << EOF_ENVS
--            `echo "$ENVS"`
--EOF_ENVS
--        fi
--    done
--    echo $pass $fail
--}
--
--
--run_gnome_desktop_testing_runner()
--{
--    pass=0
--    fail=0
--    if [ x"$TESTS" = x ] ; then
--        TESTS='ibus'
--    fi
--    for tst in $TESTS; do
--        tst_dir="@INSTALLEDDIR@/$tst"
--        if [ ! -d "$tst_dir" ] ; then
--            print_log -e "${RED}FAIL${NC}: Not found %tst_dir"
--            fail=1
--            continue
--        fi
--        gnome-desktop-testing-runner --timeout=$TIMEOUT $tst \
--                2>>$TEST_LOG 1>>$TEST_LOG
--        retval=$?
--        read pass fail << EOF
--        `count_case_result $retval $pass $fail`
--EOF
--    done
--    child_pass=`grep '^PASS:' $TEST_LOG | wc -l`
--    child_fail=`grep '^FAIL:' $TEST_LOG | wc -l`
--    if [ $child_pass -ne 0 ] || [ $child_fail -ne 0 ] ; then
--        pass=$child_pass
--        if [ $child_fail -ne 0 ] ; then
--            fail=`expr $child_fail / 2`
--        else
--            fail=0
--        fi
--    fi
--    echo $pass $fail
--}
--
--
--run_test_suite()
--{
--    pass=0
--    fail=0
--    export GTK_IM_MODULE=ibus
--    export IBUS_COMPOSE_CACHE_DIR=$PWD
--    if [ x"$TESTING_RUNNER" = x ] ; then
--        TESTING_RUNNER="default"
--    fi
--    case $TESTING_RUNNER in
--    default)
--        # Get only the last value with do-while.
--        read pass fail << EOF_RUNNER
--        `run_direct_test_cases`
--EOF_RUNNER
--        ;;
--    gnome)
--        read pass fail << EOF_RUNNER
--        `run_gnome_desktop_testing_runner`
--EOF_RUNNER
--        ;;
--    esac
--    echo ""
--    # Fedora CI assumes the test is failed even if $fail is 0.
--    if [ $pass -ne 0 ] ; then
--        print_log -e "${GREEN}PASS${NC}: $pass"
--    fi
--    if [ $fail -ne 0 ] ; then
--        print_log -e "${RED}FAIL${NC}: $fail"
--    fi
--    echo ""
--    if [ $TEST_LOG_STDOUT -eq 1 ] ; then
--        cat $TEST_LOG
--    else
--        echo "# See $TEST_LOG"
--    fi
--}
--
--
--finit()
--{
--    echo "# Killing left gnome-session and Xorg"
--    kill $PID_GNOME_SESSION $PID_XORG
--    ibus exit
--    SUSER=`echo "$USER" | cut -c 1-7`
--    LEFT_CALENDAR=`ps -ef | grep gnome-shell-calendar-server | grep $SUSER | grep -v grep`
--    if [ x"$LEFT_CALENDAR" != x ] ; then
--        echo "# Killing left gnome-shell-calendar-server"
--        echo "$LEFT_CALENDAR"
--        echo "$LEFT_CALENDAR" | awk '{print $2}' | xargs kill
--    fi
--
--    echo "# Finished $PROGNAME testing"
--}
--
--
- main()
- {
-     parse_args "$@"
--    init_desktop
-+    init_session
-     run_dbus_daemon 2>>$TEST_LOG 1>>$TEST_LOG
--    run_desktop 2>>$TEST_LOG 1>>$TEST_LOG
--    if [ x"$SCREEN_LOG" != x ] ; then
--        SCREEN_PNG="`date '+%Y%m%d%H%M%S'`.png"
--        gnome-screenshot --file=$SCREEN_PNG
--        if [ x"$SCREEN_LOG" = xSTDOUT ] ; then
--            base64 $SCREEN_PNG
--        else
--            base64 $SCREEN_PNG > $SCREEN_LOG
--        fi
--    fi
-+    run_session 2>>$TEST_LOG 1>>$TEST_LOG
-+    save_screen
-     run_test_suite
-     finit
- }
-diff --git a/src/tests/ibus-desktop-testing.desktop.in b/src/tests/ibus-desktop-testing.desktop.in
-index 1b815345..e91900ed 100644
---- a/src/tests/ibus-desktop-testing.desktop.in
-+++ b/src/tests/ibus-desktop-testing.desktop.in
-@@ -2,7 +2,7 @@
- Name=IBus Desktop Testing Runner
- GenericName=Input Method Desktop Testing Runner
- Comment=Test plugin for IBus Desktop Testing
--Exec=@libexecdir@/ibus-desktop-testing-autostart /var/tmp/ibus-ci-autostart.log
-+Exec=sh -c 'exec @libexecdir@/ibus-desktop-testing-autostart --envcheck --output $HOME/test-autostart.log --result $HOME/test.log --runner gnome --screendump $HOME/screen.log --tests ibus'
- Terminal=false
- Type=Application
- Encoding=UTF-8
--- 
-2.45.0
-
-From 039fcb16f18d341a244362c3e797eeaa5c51010e Mon Sep 17 00:00:00 2001
-From: fujiwarat <takao.fujiwara1@gmail.com>
-Date: Sat, 27 Jul 2024 19:02:09 +0900
-Subject: [PATCH 2/6] Fix tests cases to be run in Wayland
-
-- Fix ibus-bus since ibus_bus_exit_async() does not work ibus-daemon
-  with systemd and run `ibus restart` instead.
-- Fix ibus-compose-locales to wait for 1 sec between key event test cases
-  to reset gnome-shell/mutter.
-- Fix ibus-compose to wait for commit-text event since the gnome-shell/mutter
-  process is a bit slow and can reset the previous commit-text events
-  before the previous events are not committed.
-- Fix counts in ibus-engine-switch.
-- Unref IBusEngineDesc in ibus-engine-switch.
-- Fix ibusimpl not to change the engine of the context when global-engine
-  is enabled.
-- Check DISPLAY and setxkbmap in xkb-latin-layouts for Wayland
-
-BUG=https://github.com/ibus/ibus/pull/2657
----
- bus/ibusimpl.c                 |   8 ++
- bus/ibusimpl.h                 |   3 +-
- bus/inputcontext.c             |   9 +++
- src/ibusshare.c                |   2 +-
- src/tests/ibus-bus.c           |  92 +++++++++++++++++++---
- src/tests/ibus-compose.c       | 139 ++++++++++++++++++++++++---------
- src/tests/ibus-engine-switch.c |  45 ++++++++++-
- src/tests/xkb-latin-layouts    |   9 +++
- 8 files changed, 254 insertions(+), 53 deletions(-)
-
-diff --git a/bus/ibusimpl.c b/bus/ibusimpl.c
-index 445c062b..4bed9bc0 100644
---- a/bus/ibusimpl.c
-+++ b/bus/ibusimpl.c
-@@ -2463,6 +2463,14 @@ bus_ibus_impl_is_embed_preedit_text (BusIBusImpl *ibus)
-     return ibus->embed_preedit_text;
- }
- 
-+gboolean
-+bus_ibus_impl_is_use_global_engine (BusIBusImpl *ibus)
-+{
-+    g_assert (BUS_IS_IBUS_IMPL (ibus));
-+
-+    return ibus->use_global_engine;
-+}
-+
- BusInputContext *
- bus_ibus_impl_get_focused_input_context (BusIBusImpl *ibus)
- {
-diff --git a/bus/ibusimpl.h b/bus/ibusimpl.h
-index e3b43f87..428b773b 100644
---- a/bus/ibusimpl.h
-+++ b/bus/ibusimpl.h
-@@ -2,7 +2,7 @@
- /* vim:set et sts=4: */
- /* bus - The Input Bus
-  * Copyright (C) 2008-2013 Peng Huang <shawn.p.huang@gmail.com>
-- * Copyright (C) 2022-2023 Takao Fujiwara <takao.fujiwara1@gmail.com>
-+ * Copyright (C) 2022-2024 Takao Fujiwara <takao.fujiwara1@gmail.com>
-  * Copyright (C) 2008-2022 Red Hat, Inc.
-  *
-  * This library is free software; you can redistribute it and/or
-@@ -94,6 +94,7 @@ BusComponent    *bus_ibus_impl_lookup_component_by_name
- gboolean         bus_ibus_impl_is_use_sys_layout    (BusIBusImpl        *ibus);
- gboolean         bus_ibus_impl_is_embed_preedit_text
-                                                     (BusIBusImpl        *ibus);
-+gboolean         bus_ibus_impl_is_use_global_engine (BusIBusImpl        *ibus);
- BusInputContext *bus_ibus_impl_get_focused_input_context
-                                                     (BusIBusImpl        *ibus);
- GHashTable      *bus_ibus_impl_get_engine_focus_id_table
-diff --git a/bus/inputcontext.c b/bus/inputcontext.c
-index 1e795733..85358241 100644
---- a/bus/inputcontext.c
-+++ b/bus/inputcontext.c
-@@ -1289,6 +1289,15 @@ _ic_set_engine (BusInputContext       *context,
-                 GDBusMethodInvocation *invocation)
- {
-     gchar *engine_name = NULL;
-+    BusIBusImpl *ibus = bus_ibus_impl_get_default ();
-+
-+    if (bus_ibus_impl_is_use_global_engine (ibus)) {
-+        g_dbus_method_invocation_return_error (invocation,
-+                G_DBUS_ERROR, G_DBUS_ERROR_FAILED,
-+                "Cannot set engines when use-global-engine is enabled.");
-+        return;
-+    }
-+
-     g_variant_get (parameters, "(&s)", &engine_name);
- 
-     if (!bus_input_context_has_focus (context)) {
-diff --git a/src/ibusshare.c b/src/ibusshare.c
-index 5ab6e889..57e3ef14 100644
---- a/src/ibusshare.c
-+++ b/src/ibusshare.c
-@@ -2,7 +2,7 @@
- /* vim:set et sts=4: */
- /* ibus - The Input Bus
-  * Copyright (C) 2008-2010 Peng Huang <shawn.p.huang@gmail.com>
-- * Copyright (C) 2015-2023 Takao Fujiwara <takao.fujiwara1@gmail.com>
-+ * Copyright (C) 2015-2024 Takao Fujiwara <takao.fujiwara1@gmail.com>
-  * Copyright (C) 2008-2018 Red Hat, Inc.
-  *
-  * This library is free software; you can redistribute it and/or
-diff --git a/src/tests/ibus-bus.c b/src/tests/ibus-bus.c
-index d6b105cf..76120354 100644
---- a/src/tests/ibus-bus.c
-+++ b/src/tests/ibus-bus.c
-@@ -802,20 +802,29 @@ start_set_preload_engines_async (void)
-             NULL); /* user_data */
- }
- 
-+typedef struct _ExitAsyncData {
-+    gboolean has_socket_path;
-+    gboolean exited;
-+    guint    timeout_id;
-+} ExitAsyncData;
-+
- static void
- _socket_changed_cb (GFileMonitor       *monitor,
-                     GFile              *file,
-                     GFile              *other_file,
-                     GFileMonitorEvent   event_type,
--                    IBusBus            *bus)
-+                    ExitAsyncData      *data)
- {
-     switch (event_type) {
-     case G_FILE_MONITOR_EVENT_CHANGED:
-         g_debug ("IBus socket file is changed");
-         call_next_async_function ();
-+        data->exited = TRUE;
-         g_signal_handlers_disconnect_by_func (monitor,
-                                               G_CALLBACK (_socket_changed_cb),
--                                              NULL);
-+                                              data);
-+        if (data->timeout_id)
-+            g_source_remove (data->timeout_id);
-         g_object_unref (monitor);
-         break;
-     case G_FILE_MONITOR_EVENT_CREATED:
-@@ -829,6 +838,33 @@ _socket_changed_cb (GFileMonitor       *monitor,
-     }
- }
- 
-+static gboolean
-+_exit_timeout (gpointer user_data)
-+{
-+    g_error ("start_exit_async() is timeout. You might run ibus-daemon " \
-+             "with systemd under GNOME and the exit API does not work. " \
-+             "You need to export IBUS_DAEMON_WITH_SYSTEMD=1 .\n");
-+    return G_SOURCE_REMOVE;
-+}
-+
-+static void
-+finish_ibus_restart_async (GPid      pid,
-+                           gint      status,
-+                           gpointer *user_data)
-+{
-+    ExitAsyncData *data = (ExitAsyncData *)user_data;
-+    g_spawn_close_pid (pid);
-+    if (data->has_socket_path == FALSE) {
-+        g_debug ("ibus_bus_exit_finish: OK socket file: none");
-+        g_usleep (G_USEC_PER_SEC);
-+        call_next_async_function ();
-+    } else {
-+        g_debug ("ibus_bus_exit_finish: OK socket file: monitored");
-+        if (!data->exited)
-+            data->timeout_id = g_timeout_add_seconds (10, _exit_timeout, NULL);
-+    }
-+}
-+
- static void
- finish_exit_async (GObject *source_object,
-                    GAsyncResult *res,
-@@ -838,25 +874,32 @@ finish_exit_async (GObject *source_object,
-     gboolean result = ibus_bus_exit_async_finish (bus,
-                                                   res,
-                                                   &error);
--    gboolean has_socket_path = GPOINTER_TO_INT (user_data);
-+    ExitAsyncData *data = (ExitAsyncData *)user_data;
-     if (error) {
-         g_warning ("Failed to ibus_bus_exit(): %s", error->message);
-         g_error_free (error);
-     }
-     g_assert (result);
--    if (has_socket_path == FALSE) {
-+    g_assert (data);
-+    if (data->has_socket_path == FALSE) {
-         g_debug ("ibus_bus_exit_finish: OK socket file: none");
-         g_usleep (G_USEC_PER_SEC);
-         call_next_async_function ();
-     } else {
-         g_debug ("ibus_bus_exit_finish: OK socket file: monitored");
-+        if (!data->exited)
-+            data->timeout_id = g_timeout_add_seconds (10, _exit_timeout, NULL);
-     }
- }
- 
- static void
- start_exit_async (void)
- {
--    gboolean has_socket_path = FALSE;
-+    static ExitAsyncData data = {
-+        .has_socket_path = FALSE,
-+        .exited          = FALSE,
-+        .timeout_id      = 0
-+    };
-     /* When `./runtest ibus-bus` runs, ibus-daemon sometimes failed to
-      * restart because closing a file descriptor was failed in
-      * bus/server.c:_restart_server() with a following error:
-@@ -879,7 +922,7 @@ start_exit_async (void)
-         g_assert (address_path);
-         file = g_file_new_for_path (address_path);
-         g_assert (file);
--        has_socket_path = TRUE;
-+        data.has_socket_path = TRUE;
-         monitor = g_file_monitor (file, G_FILE_MONITOR_NONE, NULL, &error);
-         if (error) {
-             g_warning ("Failed to monitor socket file: %s", error->message);
-@@ -887,15 +930,38 @@ start_exit_async (void)
-         }
-         g_assert (monitor);
-         g_signal_connect (monitor, "changed",
--                          G_CALLBACK (_socket_changed_cb), NULL);
-+                          G_CALLBACK (_socket_changed_cb),
-+                          &data);
-         g_object_unref (file);
-     }
--    ibus_bus_exit_async (bus,
--                         TRUE, /* restart */
--                         -1, /* timeout */
--                         NULL, /* cancellable */
--                         finish_exit_async,
--                         GINT_TO_POINTER (has_socket_path)); /* user_data */
-+    /* When ibus-daemon runs with systemd, restarting the daemon with
-+     * ibus_bus_exit_async() does not work so runs `ibus restart` command
-+     * with IBUS_DAEMON_WITH_SYSTEMD variable instead.
-+     */
-+    if (g_getenv ("IBUS_DAEMON_WITH_SYSTEMD")) {
-+        gchar *argv[] = { "ibus", "restart", NULL };
-+        GSpawnFlags flags = G_SPAWN_DO_NOT_REAP_CHILD \
-+                            | G_SPAWN_SEARCH_PATH \
-+                            | G_SPAWN_STDOUT_TO_DEV_NULL \
-+                            | G_SPAWN_STDERR_TO_DEV_NULL;
-+        GPid pid = 0;
-+        GError *error = NULL;
-+        g_spawn_async (NULL, argv, NULL, flags, NULL, NULL, &pid, &error);
-+        if (error) {
-+            g_warning ("Failed to call ibus restart: %s", error->message);
-+            g_error_free (error);
-+        }
-+        g_child_watch_add (pid,
-+                           (GChildWatchFunc)finish_ibus_restart_async,
-+                           &data);
-+    } else {
-+        ibus_bus_exit_async (bus,
-+                             TRUE, /* restart */
-+                             -1, /* timeout */
-+                             NULL, /* cancellable */
-+                             finish_exit_async,
-+                             &data); /* user_data */
-+    }
- }
- 
- static gboolean
-diff --git a/src/tests/ibus-compose.c b/src/tests/ibus-compose.c
-index 21de7a22..660aee7f 100644
---- a/src/tests/ibus-compose.c
-+++ b/src/tests/ibus-compose.c
-@@ -7,19 +7,28 @@
- #define RED   "\033[0;31m"
- #define NC    "\033[0m"
- 
--IBusBus *m_bus;
--gchar *m_compose_file;
--IBusComposeTableEx *m_compose_table;
--IBusEngine *m_engine;
--gchar *m_srcdir;
--
--guint ibus_compose_key_flag (guint key);
--
-+static IBusBus *m_bus;
-+static gchar *m_compose_file;
-+static IBusComposeTableEx *m_compose_table;
-+static IBusEngine *m_engine;
-+static gchar *m_srcdir;
-+static GMainLoop *m_loop;
-+
-+typedef enum {
-+    TEST_CREATE_ENGINE,
-+    TEST_COMMIT_TEXT
-+} TestIDleCategory;
-+
-+typedef struct _TestIdleData {
-+    TestIDleCategory category;
-+    guint            idle_id;
-+} TestIdleData;
-+
-+extern guint ibus_compose_key_flag (guint key);
- static gboolean window_focus_in_event_cb (GtkWidget     *entry,
-                                           GdkEventFocus *event,
-                                           gpointer       data);
- 
--
- static gchar *
- get_compose_path ()
- {
-@@ -51,17 +60,50 @@ get_compose_path ()
- }
- 
- 
-+gboolean
-+idle_cb (gpointer user_data)
-+{
-+    TestIdleData *data = (TestIdleData *)user_data;
-+    g_assert (data);
-+    switch (data->category) {
-+    case TEST_CREATE_ENGINE:
-+        g_test_fail_printf ("\"create-engine\" signal is timeout.");
-+        break;
-+    case TEST_COMMIT_TEXT:
-+        if (data->idle_id)
-+            g_test_fail_printf ("Commiting composed chars is timeout.");
-+        if (m_loop) {
-+            if (g_main_loop_is_running (m_loop))
-+                g_main_loop_quit (m_loop);
-+            g_clear_pointer (&m_loop, g_main_loop_unref);
-+            gtk_main_quit ();
-+        }
-+        data->idle_id = 0;
-+        break;
-+    default:
-+        g_test_fail_printf ("Idle func is called by wrong category:%d.",
-+                            data->category);
-+        break;
-+    }
-+    return G_SOURCE_REMOVE;
-+}
-+
-+
- static IBusEngine *
- create_engine_cb (IBusFactory *factory,
-                   const gchar *name,
--                  gpointer     data)
-+                  gpointer     user_data)
- {
-     static int i = 1;
-     gchar *engine_path =
-             g_strdup_printf ("/org/freedesktop/IBus/engine/simpletest/%d",
-                              i++);
-     gchar *compose_path;
-+    TestIdleData *data = (TestIdleData *)user_data;
- 
-+    g_assert (data);
-+    /* Don't reset idle_id to avoid duplicated register_ibus_engine(). */
-+    g_source_remove (data->idle_id);
-     m_engine = ibus_engine_new_with_type (IBUS_TYPE_ENGINE_SIMPLE,
-                                           name,
-                                           engine_path,
-@@ -75,28 +117,33 @@ create_engine_cb (IBusFactory *factory,
-         ibus_engine_simple_add_compose_file (IBUS_ENGINE_SIMPLE (m_engine),
-                                              compose_path);
-         m_compose_table = ibus_compose_table_load_cache (compose_path);
--        if (m_compose_table == NULL)
--            g_warning ("Your locale uses en_US compose table.");
-     }
-     g_free (compose_path);
-     return m_engine;
- }
- 
-+
- static gboolean
- register_ibus_engine ()
- {
-+    static TestIdleData data = { .category = TEST_CREATE_ENGINE, .idle_id = 0 };
-     IBusFactory *factory;
-     IBusComponent *component;
-     IBusEngineDesc *desc;
- 
-+    if (data.idle_id) {
-+        g_test_incomplete ("Test is called twice due to a timeout.");
-+        return TRUE;
-+    }
-     m_bus = ibus_bus_new ();
-     if (!ibus_bus_is_connected (m_bus)) {
--        g_critical ("ibus-daemon is not running.");
-+        g_test_fail_printf ("ibus-daemon is not running.");
-         return FALSE;
-     }
-     factory = ibus_factory_new (ibus_bus_get_connection (m_bus));
-+    data.idle_id = g_timeout_add_seconds (20, idle_cb, &data);
-     g_signal_connect (factory, "create-engine",
--                      G_CALLBACK (create_engine_cb), NULL);
-+                      G_CALLBACK (create_engine_cb), &data);
- 
-     component = ibus_component_new (
-             "org.freedesktop.IBus.SimpleTest",
-@@ -122,34 +169,29 @@ register_ibus_engine ()
-     return TRUE;
- }
- 
--static gboolean
--finit (gpointer data)
--{
--    g_test_incomplete ("time out");
--    gtk_main_quit ();
--    return FALSE;
--}
- 
- static void
--set_engine_cb (GObject *object, GAsyncResult *res, gpointer data)
-+set_engine_cb (GObject      *object,
-+               GAsyncResult *res,
-+               gpointer      user_data)
- {
-     IBusBus *bus = IBUS_BUS (object);
--    GtkWidget *entry = GTK_WIDGET (data);
-+    GtkWidget *entry = GTK_WIDGET (user_data);
-     GError *error = NULL;
-+    static TestIdleData data = { .category = TEST_COMMIT_TEXT, .idle_id = 0 };
-     int i, j;
-     int index_stride;
-     IBusComposeTablePrivate *priv;
- 
-     if (!ibus_bus_set_global_engine_async_finish (bus, res, &error)) {
--        gchar *msg = g_strdup_printf ("set engine failed: %s", error->message);
--        g_test_incomplete (msg);
--        g_free (msg);
-+        g_test_fail_printf ("set engine failed: %s", error->message);
-         g_error_free (error);
-         return;
-     }
- 
-     if (m_compose_table == NULL) {
--        gtk_main_quit ();
-+        g_test_skip ("Your locale uses en_US compose table.");
-+        idle_cb (&data);
-         return;
-     }
- 
-@@ -157,6 +199,7 @@ set_engine_cb (GObject *object, GAsyncResult *res, gpointer data)
-     for (i = 0;
-          i < (m_compose_table->n_seqs * index_stride);
-          i += index_stride) {
-+        data.idle_id = g_timeout_add_seconds (20, idle_cb, &data);
-         for (j = i; j < i + (index_stride - 2); j++) {
-             guint keyval = m_compose_table->data[j];
-             guint keycode = 0;
-@@ -172,12 +215,22 @@ set_engine_cb (GObject *object, GAsyncResult *res, gpointer data)
-             g_signal_emit_by_name (m_engine, "process-key-event",
-                                    keyval, keycode, modifiers, &retval);
-         }
-+        /* Need to wait for calling window_inserted_text_cb() with
-+         * g_main_loop_run() because the commit-text event could be cancelled
-+         * by the next commit-text event with gnome-shell in Wayland.
-+         */
-+        g_main_loop_run (m_loop);
-+        if (data.idle_id) {
-+            g_source_remove (data.idle_id);
-+            data.idle_id = 0;
-+        }
-     }
-     priv = m_compose_table->priv;
-     if (priv) {
-         for (i = 0;
-              i < (priv->first_n_seqs * index_stride);
-              i += index_stride) {
-+            data.idle_id = g_timeout_add_seconds (20, idle_cb, &data);
-             for (j = i; j < i + (index_stride - 2); j++) {
-                 guint keyval = priv->data_first[j];
-                 guint keycode = 0;
-@@ -193,13 +246,18 @@ set_engine_cb (GObject *object, GAsyncResult *res, gpointer data)
-                 g_signal_emit_by_name (m_engine, "process-key-event",
-                                        keyval, keycode, modifiers, &retval);
-             }
-+            g_main_loop_run (m_loop);
-+            if (data.idle_id) {
-+                g_source_remove (data.idle_id);
-+                data.idle_id = 0;
-+            }
-         }
-     }
- 
-     g_signal_handlers_disconnect_by_func (entry, 
-                                           G_CALLBACK (window_focus_in_event_cb),
-                                           NULL);
--    g_timeout_add_seconds (10, finit, NULL);
-+    data.idle_id = g_timeout_add_seconds (10, idle_cb, &data);
- }
- 
- static gboolean
-@@ -215,12 +273,13 @@ window_focus_in_event_cb (GtkWidget *entry, GdkEventFocus *event, gpointer data)
-     return FALSE;
- }
- 
-+
- static void
- window_inserted_text_cb (GtkEntryBuffer *buffer,
-                          guint           position,
-                          const gchar    *chars,
-                          guint           nchars,
--                         gpointer        data)
-+                         gpointer        user_data)
- {
- /* https://gitlab.gnome.org/GNOME/gtk/commit/9981f46e0b
-  * The latest GTK does not emit "inserted-text" when the text is "".
-@@ -234,8 +293,9 @@ window_inserted_text_cb (GtkEntryBuffer *buffer,
-     int seq;
-     gunichar code = g_utf8_get_char (chars);
-     const gchar *test;
--    GtkEntry *entry = GTK_ENTRY (data);
-+    GtkEntry *entry = GTK_ENTRY (user_data);
-     IBusComposeTablePrivate *priv;
-+    static TestIdleData data = { .category = TEST_COMMIT_TEXT, .idle_id = 0 };
- 
-     g_assert (m_compose_table != NULL);
- 
-@@ -302,21 +362,26 @@ window_inserted_text_cb (GtkEntryBuffer *buffer,
-             stride = 0;
-             seq = 0;
-         } else {
--            gtk_main_quit ();
-+            /* Finish tests */
-+            idle_cb (&data);
-             return;
-         }
-     }
-     if (enable_32bit && seq == priv->first_n_seqs) {
--        gtk_main_quit ();
-+        /* Finish tests */
-+        idle_cb (&data);
-         return;
-     }
- 
- #if !GTK_CHECK_VERSION (3, 22, 16)
-     n_loop++;
- #endif
-+
-     gtk_entry_set_text (entry, "");
-+    g_main_loop_quit (m_loop);
- }
- 
-+
- static void
- create_window ()
- {
-@@ -335,14 +400,13 @@ create_window ()
-     gtk_widget_show_all (window);
- }
- 
-+
- static void
- test_compose (void)
- {
-     GLogLevelFlags flags;
--    if (!register_ibus_engine ()) {
--        g_test_fail ();
-+    if (!register_ibus_engine ())
-         return;
--    }
- 
-     create_window ();
-     /* FIXME:
-@@ -357,6 +421,7 @@ test_compose (void)
-     g_log_set_always_fatal (flags);
- }
- 
-+
- int
- main (int argc, char *argv[])
- {
-@@ -380,10 +445,12 @@ main (int argc, char *argv[])
- #else
-     test_name = g_strdup (g_getenv ("LANG"));
- #endif
--    if (!test_name || !g_ascii_strncasecmp (test_name, "en_US", 5)) {
-+    if (m_compose_file &&
-+        (!test_name || !g_ascii_strncasecmp (test_name, "en_US", 5))) {
-         g_free (test_name);
-         test_name = g_path_get_basename (m_compose_file);
-     }
-+    m_loop = g_main_loop_new (NULL, TRUE);
-     test_path = g_build_filename ("/ibus-compose", test_name, NULL);
-     g_test_add_func (test_path, test_compose);
-     g_free (test_path);
-diff --git a/src/tests/ibus-engine-switch.c b/src/tests/ibus-engine-switch.c
-index a1eeba2a..b50bac59 100644
---- a/src/tests/ibus-engine-switch.c
-+++ b/src/tests/ibus-engine-switch.c
-@@ -1,6 +1,7 @@
- /* -*- mode: C; c-basic-offset: 4; indent-tabs-mode: nil; -*- */
- 
- #include <string.h>
-+#include <unistd.h>
- #include "ibus.h"
- 
- static IBusBus *bus;
-@@ -47,6 +48,7 @@ change_context_engine (IBusInputContext *context)
-         g_assert_cmpstr (ibus_engine_desc_get_name (engine_desc),
-                          ==,
-                          engine_names[i]);
-+        g_object_unref (engine_desc);
-     }
- }
- 
-@@ -61,7 +63,7 @@ static void
- global_engine_changed_cb (IBusBus *bus, gchar *name, gpointer user_data)
- {
-     GlobalEngineChangedData *data = (GlobalEngineChangedData *) user_data;
--    if (data->count++ == 0)
-+    if (data->count++ == 1)
-         ibus_quit ();
- }
- 
-@@ -84,6 +86,35 @@ change_global_engine_cb (gpointer user_data)
-     return FALSE;
- }
- 
-+gboolean
-+_wait_for_key_release_cb (gpointer user_data)
-+{
-+    GMainLoop *loop = (GMainLoop *)user_data;
-+    /* If this program is invoked by manual with Enter key in GNOME
-+     * Wayland session, ibus_input_context_focus_in() can be called in
-+     * test_context_engine_set_by_global() before the key release of
-+     * the Enter key so ibus/bus/inputcontext.c:_ic_process_key_event()
-+     * could call another bus_input_context_focus_in() in that test case
-+     * and fail.
-+     */
-+    g_test_message ("Wait for 3 seconds for key release event");
-+    g_main_loop_quit (loop);
-+    return G_SOURCE_REMOVE;
-+}
-+
-+static void
-+test_init (void)
-+{
-+    char *tty_name = ttyname (STDIN_FILENO);
-+    GMainLoop *loop = g_main_loop_new (NULL, TRUE);
-+    g_test_message ("Test on %s", tty_name ? tty_name : "(null)");
-+    if (tty_name && g_strstr_len (tty_name, -1, "pts")) {
-+        g_timeout_add_seconds (3, _wait_for_key_release_cb, loop);
-+        g_main_loop_run (loop);
-+    }
-+    g_main_loop_unref (loop);
-+}
-+
- static void
- test_global_engine (void)
- {
-@@ -105,6 +136,10 @@ test_global_engine (void)
-     } else {
-         data.reverse = FALSE;
-     }
-+    g_test_message ("Initial engine name: %s",
-+                    desc ? ibus_engine_desc_get_name (desc) : "(null)");
-+    if (desc)
-+        g_object_unref (desc);
- 
-     data.count = 0;
- 
-@@ -112,7 +147,7 @@ test_global_engine (void)
-                                    "global-engine-changed",
-                                    G_CALLBACK (global_engine_changed_cb),
-                                    &data);
--    data.timeout_id = g_timeout_add_seconds (1, timeout_cb, &data);
-+    data.timeout_id = g_timeout_add_seconds (3, timeout_cb, &data);
-     data.idle_id = g_idle_add ((GSourceFunc) change_global_engine_cb, &data);
- 
-     ibus_main ();
-@@ -144,6 +179,7 @@ test_context_engine (void)
-     change_context_engine (context);
-     engine_desc = ibus_input_context_get_engine (context);
-     g_assert_cmpstr (ibus_engine_desc_get_name (engine_desc), ==, AFTER_ENGINE);
-+    g_object_unref (engine_desc);
- 
-     g_object_unref (context);
- }
-@@ -171,6 +207,7 @@ test_context_engine_set_by_global (void)
- 
-     engine_desc = ibus_input_context_get_engine (context);
-     g_assert_cmpstr (ibus_engine_desc_get_name (engine_desc), ==, AFTER_ENGINE);
-+    g_object_unref (engine_desc);
- 
-     g_object_unref (context);
- }
-@@ -199,9 +236,11 @@ test_context_engine_set_by_focus (void)
- 
-     engine_desc = ibus_input_context_get_engine (context);
-     g_assert_cmpstr (ibus_engine_desc_get_name (engine_desc), ==, "dummy");
-+    g_object_unref (engine_desc);
- 
-     engine_desc = ibus_input_context_get_engine (another_context);
-     g_assert_cmpstr (ibus_engine_desc_get_name (engine_desc), ==, AFTER_ENGINE);
-+    g_object_unref (engine_desc);
- 
-     g_object_unref (context);
-     g_object_unref (another_context);
-@@ -220,6 +259,8 @@ main (gint    argc,
- 
-     ibus_bus_set_watch_ibus_signal (bus, TRUE);
- 
-+    g_test_add_func ("/ibus/engine-switch/test-init",
-+                     test_init);
-     g_test_add_func ("/ibus/engine-switch/global-engine",
-                      test_global_engine);
-     g_test_add_func ("/ibus/engine-switch/context-engine",
-diff --git a/src/tests/xkb-latin-layouts b/src/tests/xkb-latin-layouts
-index 92464234..45c99358 100755
---- a/src/tests/xkb-latin-layouts
-+++ b/src/tests/xkb-latin-layouts
-@@ -120,6 +120,15 @@ EOF_READ_XKB
- 
- main()
- {
-+    if [ x"$DISPLAY" = x ] ; then
-+        echo "skip: No display. Maybe headless mode."
-+        exit 77
-+    fi
-+    if ! which setxkbmap > /dev/null ; then
-+        echo "skip: No setxkbmap"
-+        exit 77
-+    fi
-+
-     parse_args "$@"
- 
-     if [ x"$INSTALLED_SCHEMAS_DIR" != x ] ; then
--- 
-2.45.0
-
-From 44f9a5957e4c53b4a6e6b3f42b56f2d20d58a21c Mon Sep 17 00:00:00 2001
-From: fujiwarat <takao.fujiwara1@gmail.com>
-Date: Sat, 27 Jul 2024 19:04:39 +0900
-Subject: [PATCH 3/6] src/tests: Enable GTK4
-
-Seems GTK3 does not work in GNOME Wayland headless session to get
-GdkMonitor in gtk_init() and trying to migrate the test cases to
-GTK4.
-Calling ibus_init() twice with g_static_resource_init() causes a
-memory error and fix it.
-
-BUG=https://github.com/ibus/ibus/pull/2657
----
- src/tests/Makefile.am     |   8 +--
- src/tests/ibus-compose.c  | 147 ++++++++++++++++++++++++++++++++------
- src/tests/ibus-keypress.c | 146 ++++++++++++++++++++++++++++++-------
- 3 files changed, 251 insertions(+), 50 deletions(-)
-
-diff --git a/src/tests/Makefile.am b/src/tests/Makefile.am
-index 6c4c86cf..10acd0a7 100644
---- a/src/tests/Makefile.am
-+++ b/src/tests/Makefile.am
-@@ -182,8 +182,8 @@ ibus_bus_SOURCES = ibus-bus.c
- ibus_bus_LDADD = $(prog_ldadd)
- 
- ibus_compose_SOURCES = ibus-compose.c
--ibus_compose_CFLAGS = @GTK3_CFLAGS@
--ibus_compose_LDADD = $(prog_ldadd) @GTK3_LIBS@
-+ibus_compose_CFLAGS = @GTK4_CFLAGS@
-+ibus_compose_LDADD = $(prog_ldadd) @GTK4_LIBS@
- 
- ibus_config_SOURCES = ibus-config.c
- ibus_config_LDADD = $(prog_ldadd)
-@@ -207,8 +207,8 @@ ibus_keynames_SOURCES = ibus-keynames.c
- ibus_keynames_LDADD = $(prog_ldadd)
- 
- ibus_keypress_SOURCES = ibus-keypress.c
--ibus_keypress_CFLAGS = @GTK3_CFLAGS@ @XTEST_CFLAGS@
--ibus_keypress_LDADD = $(prog_ldadd) @GTK3_LIBS@ @XTEST_LIBS@
-+ibus_keypress_CFLAGS = @GTK4_CFLAGS@ @XTEST_CFLAGS@
-+ibus_keypress_LDADD = $(prog_ldadd) @GTK4_LIBS@ @XTEST_LIBS@
- 
- ibus_registry_SOURCES = ibus-registry.c
- ibus_registry_LDADD = $(prog_ldadd)
-diff --git a/src/tests/ibus-compose.c b/src/tests/ibus-compose.c
-index 660aee7f..57851b0a 100644
---- a/src/tests/ibus-compose.c
-+++ b/src/tests/ibus-compose.c
-@@ -13,6 +13,9 @@ static IBusComposeTableEx *m_compose_table;
- static IBusEngine *m_engine;
- static gchar *m_srcdir;
- static GMainLoop *m_loop;
-+#if GTK_CHECK_VERSION (4, 0, 0)
-+static gboolean m_list_toplevel;
-+#endif
- 
- typedef enum {
-     TEST_CREATE_ENGINE,
-@@ -25,9 +28,16 @@ typedef struct _TestIdleData {
- } TestIdleData;
- 
- extern guint ibus_compose_key_flag (guint key);
-+
-+#if GTK_CHECK_VERSION (4, 0, 0)
-+static void     event_controller_enter_cb (GtkEventController *controller,
-+                                           gpointer            user_data);
-+#else
- static gboolean window_focus_in_event_cb (GtkWidget     *entry,
-                                           GdkEventFocus *event,
-                                           gpointer       data);
-+#endif
-+
- 
- static gchar *
- get_compose_path ()
-@@ -76,7 +86,11 @@ idle_cb (gpointer user_data)
-             if (g_main_loop_is_running (m_loop))
-                 g_main_loop_quit (m_loop);
-             g_clear_pointer (&m_loop, g_main_loop_unref);
-+#if GTK_CHECK_VERSION (4, 0, 0)
-+            m_list_toplevel = FALSE;
-+#else
-             gtk_main_quit ();
-+#endif
-         }
-         data->idle_id = 0;
-         break;
-@@ -170,13 +184,28 @@ register_ibus_engine ()
- }
- 
- 
-+static void
-+window_destroy_cb (void)
-+{
-+#if GTK_CHECK_VERSION (4, 0, 0)
-+    m_list_toplevel = FALSE;
-+#else
-+    gtk_main_quit ();
-+#endif
-+}
-+
-+
- static void
- set_engine_cb (GObject      *object,
-                GAsyncResult *res,
-                gpointer      user_data)
- {
-     IBusBus *bus = IBUS_BUS (object);
-+#if GTK_CHECK_VERSION (4, 0, 0)
-+    GtkEventController *controller = GTK_EVENT_CONTROLLER (user_data);
-+#else
-     GtkWidget *entry = GTK_WIDGET (user_data);
-+#endif
-     GError *error = NULL;
-     static TestIdleData data = { .category = TEST_COMMIT_TEXT, .idle_id = 0 };
-     int i, j;
-@@ -254,24 +283,55 @@ set_engine_cb (GObject      *object,
-         }
-     }
- 
-+#if GTK_CHECK_VERSION (4, 0, 0)
-+    g_signal_handlers_disconnect_by_func (
-+            controller,
-+            G_CALLBACK (event_controller_enter_cb),
-+            NULL);
-+#else
-     g_signal_handlers_disconnect_by_func (entry, 
-                                           G_CALLBACK (window_focus_in_event_cb),
-                                           NULL);
-+#endif
-     data.idle_id = g_timeout_add_seconds (10, idle_cb, &data);
- }
- 
--static gboolean
--window_focus_in_event_cb (GtkWidget *entry, GdkEventFocus *event, gpointer data)
-+
-+static void
-+set_engine (gpointer user_data)
- {
-+    g_test_message ("set_engine() is calling");
-     g_assert (m_bus != NULL);
-     ibus_bus_set_global_engine_async (m_bus,
-                                       "xkbtest:us::eng",
-                                       -1,
-                                       NULL,
-                                       set_engine_cb,
--                                      entry);
-+                                      user_data);
-+}
-+
-+
-+#if GTK_CHECK_VERSION (4, 0, 0)
-+static void
-+event_controller_enter_cb (GtkEventController *controller,
-+                           gpointer            user_data)
-+{
-+    g_test_message ("EventController emits \"enter\" signal");
-+    set_engine (controller);
-+}
-+
-+#else
-+
-+static gboolean
-+window_focus_in_event_cb (GtkWidget     *entry,
-+                          GdkEventFocus *event,
-+                          gpointer       data)
-+{
-+    g_test_message ("Entry emits \"focus-in-event\" signal");
-+    set_engine (entry);
-     return FALSE;
- }
-+#endif
- 
- 
- static void
-@@ -293,7 +353,9 @@ window_inserted_text_cb (GtkEntryBuffer *buffer,
-     int seq;
-     gunichar code = g_utf8_get_char (chars);
-     const gchar *test;
-+#if ! GTK_CHECK_VERSION (4, 0, 0)
-     GtkEntry *entry = GTK_ENTRY (user_data);
-+#endif
-     IBusComposeTablePrivate *priv;
-     static TestIdleData data = { .category = TEST_COMMIT_TEXT, .idle_id = 0 };
- 
-@@ -306,6 +368,10 @@ window_inserted_text_cb (GtkEntryBuffer *buffer,
-         n_loop = 0;
-         return;
-     }
-+#endif
-+#if GTK_CHECK_VERSION (4, 0, 0)
-+    if (code == 0)
-+        return;
- #endif
-     i = stride + (m_compose_table->max_seq_len + 2) - 2;
-     seq = (i + 2) / (m_compose_table->max_seq_len + 2);
-@@ -318,12 +384,12 @@ window_inserted_text_cb (GtkEntryBuffer *buffer,
-             test = RED "FAIL" NC;
-             g_test_fail ();
-         }
--        g_print ("%05d/%05d %s expected: %04X typed: %04X\n",
--                 seq,
--                 m_compose_table->n_seqs,
--                 test,
--                 m_compose_table->data[i],
--                 code);
-+        g_test_message ("%05d/%05d %s expected: %04X typed: %04X",
-+                        seq,
-+                        m_compose_table->n_seqs,
-+                        test,
-+                        m_compose_table->data[i],
-+                        code);
-     } else {
-         const gchar *p = chars;
-         guint num = priv->data_first[i];
-@@ -344,14 +410,14 @@ window_inserted_text_cb (GtkEntryBuffer *buffer,
-             test = RED "FAIL" NC;
-             g_test_fail ();
-         }
--        g_print ("%05d/%05ld %s expected: %04X[%d] typed: %04X\n",
--                 seq,
--                 priv->first_n_seqs,
--                 test,
--                 valid_output ? priv->data_second[index]
--                         : priv->data_second[index + j],
--                 valid_output ? index + num : index + j,
--                 valid_output ? g_utf8_get_char (chars) : code);
-+        g_test_message ("%05d/%05ld %s expected: %04X[%d] typed: %04X",
-+                        seq,
-+                        priv->first_n_seqs,
-+                        test,
-+                        valid_output ? priv->data_second[index]
-+                                : priv->data_second[index + j],
-+                        valid_output ? index + num : index + j,
-+                        valid_output ? g_utf8_get_char (chars) : code);
-     }
- 
-     stride += m_compose_table->max_seq_len + 2;
-@@ -377,7 +443,11 @@ window_inserted_text_cb (GtkEntryBuffer *buffer,
-     n_loop++;
- #endif
- 
-+#if GTK_CHECK_VERSION (4, 0, 0)
-+    gtk_entry_buffer_set_text (buffer, "", 0);
-+#else
-     gtk_entry_set_text (entry, "");
-+#endif
-     g_main_loop_quit (m_loop);
- }
- 
-@@ -385,19 +455,43 @@ window_inserted_text_cb (GtkEntryBuffer *buffer,
- static void
- create_window ()
- {
--    GtkWidget *window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
--    GtkWidget *entry = gtk_entry_new ();
-+    GtkWidget *window;
-+    GtkWidget *entry;
-     GtkEntryBuffer *buffer;
-+#if GTK_CHECK_VERSION (4, 0, 0)
-+    GtkEventController *controller;
-+    GtkEditable *text;
-+
-+    window = gtk_window_new ();
-+#else
-+    window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
-+#endif
-+    entry = gtk_entry_new ();
- 
-     g_signal_connect (window, "destroy",
--                      G_CALLBACK (gtk_main_quit), NULL);
-+                      G_CALLBACK (window_destroy_cb), NULL);
-+#if GTK_CHECK_VERSION (4, 0, 0)
-+    controller = gtk_event_controller_focus_new ();
-+    text = gtk_editable_get_delegate (GTK_EDITABLE (entry));
-+    g_signal_connect (controller, "enter",
-+                      G_CALLBACK (event_controller_enter_cb), NULL);
-+    gtk_widget_add_controller (GTK_WIDGET (text), controller);
-+#else
-     g_signal_connect (entry, "focus-in-event",
-                       G_CALLBACK (window_focus_in_event_cb), NULL);
-+#endif
-     buffer = gtk_entry_get_buffer (GTK_ENTRY (entry));
-     g_signal_connect (buffer, "inserted-text",
-                       G_CALLBACK (window_inserted_text_cb), entry);
-+
-+#if GTK_CHECK_VERSION (4, 0, 0)
-+    gtk_window_set_child (GTK_WINDOW (window), entry);
-+    gtk_window_set_focus (GTK_WINDOW (window), entry);
-+    gtk_window_present (GTK_WINDOW (window));
-+#else
-     gtk_container_add (GTK_CONTAINER (window), entry);
-     gtk_widget_show_all (window);
-+#endif
- }
- 
- 
-@@ -408,6 +502,9 @@ test_compose (void)
-     if (!register_ibus_engine ())
-         return;
- 
-+#if GTK_CHECK_VERSION (4, 0, 0)
-+    m_list_toplevel = TRUE;
-+#endif
-     create_window ();
-     /* FIXME:
-      * IBusIMContext opens GtkIMContextSimple as the slave and
-@@ -417,7 +514,13 @@ test_compose (void)
-      " "GTK+ supports to output one char only: "
-      */
-     flags = g_log_set_always_fatal (G_LOG_LEVEL_CRITICAL);
-+#if GTK_CHECK_VERSION (4, 0, 0)
-+    gtk_window_list_toplevels ();
-+    while (m_list_toplevel)
-+        g_main_context_iteration (NULL, TRUE);
-+#else
-     gtk_main ();
-+#endif
-     g_log_set_always_fatal (flags);
- }
- 
-@@ -435,7 +538,11 @@ main (int argc, char *argv[])
-     if (!g_setenv ("NO_AT_BRIDGE", "1", TRUE))
-         g_message ("Failed setenv NO_AT_BRIDGE\n");
-     g_test_init (&argc, &argv, NULL);
-+#if GTK_CHECK_VERSION (4, 0, 0)
-+    gtk_init ();
-+#else
-     gtk_init (&argc, &argv);
-+#endif
- 
-     m_srcdir = (argc > 1 && strlen (argv[1]) < FILENAME_MAX)
-             ? g_strdup (argv[1]) : g_strdup (".");
-diff --git a/src/tests/ibus-keypress.c b/src/tests/ibus-keypress.c
-index d44f39b2..a9288260 100644
---- a/src/tests/ibus-keypress.c
-+++ b/src/tests/ibus-keypress.c
-@@ -1,12 +1,16 @@
- #include <gtk/gtk.h>
-+#if GTK_CHECK_VERSION (4, 0, 0)
-+#include <gdk/x11/gdkx.h>
-+#else
- #include <gdk/gdkx.h>
-+#endif
- #include "ibus.h"
- #include <stdlib.h>
- #include <X11/Xlib.h>
- #include <X11/extensions/XTest.h>
- 
- #ifdef GDK_WINDOWING_WAYLAND
--#if GTK_CHECK_VERSION (3, 98, 4)
-+#if GTK_CHECK_VERSION (4, 0, 0)
- #include <gdk/wayland/gdkwayland.h>
- #else
- #include <gdk/gdkwayland.h>
-@@ -51,12 +55,18 @@ static const gunichar test_results[][60] = {
- };
- 
- 
--IBusBus *m_bus;
--IBusEngine *m_engine;
-+static IBusBus *m_bus;
-+static IBusEngine *m_engine;
-+#if GTK_CHECK_VERSION (4, 0, 0)
-+static gboolean m_list_toplevel;
- 
-+static gboolean event_controller_enter_cb (GtkEventController *controller,
-+                                           gpointer            user_data);
-+#else
- static gboolean window_focus_in_event_cb (GtkWidget     *entry,
-                                           GdkEventFocus *event,
-                                           gpointer       data);
-+#endif
- 
- static IBusEngine *
- create_engine_cb (IBusFactory *factory, const gchar *name, gpointer data)
-@@ -118,7 +128,11 @@ static gboolean
- finit (gpointer data)
- {
-     g_critical ("time out");
-+#if GTK_CHECK_VERSION (4, 0, 0)
-+    m_list_toplevel = FALSE;
-+#else
-     gtk_main_quit ();
-+#endif
-     return FALSE;
- }
- 
-@@ -173,27 +187,41 @@ send_key_event (Display *xdisplay,
-     }
- }
- 
-+static void
-+window_destroy_cb (void)
-+{
-+#if GTK_CHECK_VERSION (4, 0, 0)
-+    m_list_toplevel = FALSE;
-+#else
-+    gtk_main_quit ();
-+#endif
-+}
-+
- static void
- set_engine_cb (GObject      *object,
-                GAsyncResult *res,
--               gpointer      data)
-+               gpointer      user_data)
- {
-     IBusBus *bus = IBUS_BUS (object);
--    GtkWidget *entry = GTK_WIDGET (data);
-+#if ! GTK_CHECK_VERSION (4, 0, 0)
-+    GtkWidget *entry = GTK_WIDGET (user_data);
-+#endif
-     GdkDisplay *display;
-     Display *xdisplay = NULL;
-     GError *error = NULL;
-     int i, j;
- 
--    g_assert (GTK_IS_ENTRY (entry));
--
-     if (!ibus_bus_set_global_engine_async_finish (bus, res, &error)) {
-         g_critical ("set engine failed: %s", error->message);
-         g_error_free (error);
-         return;
-     }
- 
-+#if GTK_CHECK_VERSION (4, 0, 0)
-+    display = gdk_display_get_default ();
-+#else
-     display = gtk_widget_get_display (entry);
-+#endif
-     g_assert (GDK_IS_X11_DISPLAY (display));
-     xdisplay = gdk_x11_display_get_xdisplay (display);
-     g_return_if_fail (xdisplay);
-@@ -210,8 +238,8 @@ set_engine_cb (GObject      *object,
-     g_timeout_add_seconds (10, finit, NULL);
- }
- 
--static gboolean
--window_focus_in_event_cb (GtkWidget *entry, GdkEventFocus *event, gpointer data)
-+static void
-+set_engine (gpointer user_data)
- {
-     g_assert (m_bus != NULL);
-     ibus_bus_set_global_engine_async (m_bus,
-@@ -219,18 +247,40 @@ window_focus_in_event_cb (GtkWidget *entry, GdkEventFocus *event, gpointer data)
-                                       -1,
-                                       NULL,
-                                       set_engine_cb,
--                                      entry);
-+                                      user_data);
-+}
-+
-+#if GTK_CHECK_VERSION (4, 0, 0)
-+static gboolean
-+event_controller_enter_cb (GtkEventController *controller,
-+                           gpointer            user_data)
-+{
-+    set_engine (controller);
-+    return FALSE;
-+}
-+
-+#else
-+
-+static gboolean
-+window_focus_in_event_cb (GtkWidget     *entry,
-+                          GdkEventFocus *event,
-+                          gpointer       user_data)
-+{
-+    set_engine (entry);
-     return FALSE;
- }
-+#endif
- 
- static void
- window_inserted_text_cb (GtkEntryBuffer *buffer,
-                          guint           position,
-                          const gchar    *chars,
-                          guint           nchars,
--                         gpointer        data)
-+                         gpointer        user_data)
- {
--    GtkWidget *entry = data;
-+#if ! GTK_CHECK_VERSION (4, 0, 0)
-+    GtkWidget *entry = user_data;
-+#endif
-     static int i = 0;
-     static int j = 0;
- 
-@@ -242,10 +292,19 @@ window_inserted_text_cb (GtkEntryBuffer *buffer,
-         g_print ("\n");
-         i++;
-         j = 0;
--        if (test_results[i][0] == 0)
-+        if (test_results[i][0] == 0) {
-+#if GTK_CHECK_VERSION (4, 0, 0)
-+            m_list_toplevel = FALSE;
-+#else
-             gtk_main_quit ();
--        else
-+#endif
-+        } else {
-+#if GTK_CHECK_VERSION (4, 0, 0)
-+            gtk_entry_buffer_set_text (buffer, "", 1);
-+#else
-             gtk_entry_set_text (GTK_ENTRY (entry), "");
-+#endif
-+        }
-         return;
-     }
-     g_assert (g_utf8_get_char (chars) == test_results[i][j]);
-@@ -255,19 +314,39 @@ window_inserted_text_cb (GtkEntryBuffer *buffer,
- static void
- create_window ()
- {
--    GtkWidget *window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
-+    GtkWidget *window;
-     GtkWidget *entry = gtk_entry_new ();
-     GtkEntryBuffer *buffer;
-+#if GTK_CHECK_VERSION (4, 0, 0)
-+    GtkEventController *controller;
-+
-+    window = gtk_window_new ();
-+#else
-+    window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
-+#endif
- 
-     g_signal_connect (window, "destroy",
--                      G_CALLBACK (gtk_main_quit), NULL);
-+                      G_CALLBACK (window_destroy_cb), NULL);
-+#if GTK_CHECK_VERSION (4, 0, 0)
-+    controller = gtk_event_controller_focus_new ();
-+    g_signal_connect (controller, "enter",
-+                      G_CALLBACK (event_controller_enter_cb), NULL);
-+    gtk_widget_add_controller (window, controller);
-+#else
-     g_signal_connect (entry, "focus-in-event",
-                       G_CALLBACK (window_focus_in_event_cb), NULL);
-+#endif
-     buffer = gtk_entry_get_buffer (GTK_ENTRY (entry));
-     g_signal_connect (buffer, "inserted-text",
-                       G_CALLBACK (window_inserted_text_cb), entry);
-+#if GTK_CHECK_VERSION (4, 0, 0)
-+    gtk_window_set_child (GTK_WINDOW (window), entry);
-+    gtk_window_set_focus (GTK_WINDOW (window), entry);
-+    gtk_window_present (GTK_WINDOW (window));
-+#else
-     gtk_container_add (GTK_CONTAINER (window), entry);
-     gtk_widget_show_all (window);
-+#endif
- }
- 
- static void
-@@ -277,6 +356,16 @@ test_keypress (void)
-     int status = 0;
-     GError *error = NULL;
- 
-+#ifdef GDK_WINDOWING_WAYLAND
-+    {
-+        GdkDisplay *display = gdk_display_get_default ();
-+        if (GDK_IS_WAYLAND_DISPLAY (display)) {
-+            g_test_skip_printf ("setxkbmap and XTEST do not work in Wayland.");
-+            return;
-+        }
-+    }
-+#endif
-+
-     /* localectl does not change the session keymap. */
-     path = g_find_program_in_path ("setxkbmap");
-     if (path) {
-@@ -287,33 +376,38 @@ test_keypress (void)
-     g_free (path);
-     g_assert (register_ibus_engine ());
- 
-+#if GTK_CHECK_VERSION (4, 0, 0)
-+    m_list_toplevel = TRUE;
-+#endif
-     create_window ();
-+#if GTK_CHECK_VERSION (4, 0, 0)
-+    while (m_list_toplevel)
-+        g_main_context_iteration (NULL, TRUE);
-+#else
-     gtk_main ();
-+#endif
- }
- 
- int
- main (int argc, char *argv[])
- {
--    ibus_init ();
-+    /* ibus_init() should not be called here because
-+     * ibus_init() is called from IBus Gtk4 IM module even if
-+     * GTK_IM_MODULE=wayland is exported.
-+     */
-     /* Avoid a warning of "AT-SPI: Could not obtain desktop path or name"
-      * with gtk_main().
-      */
-     if (!g_setenv ("NO_AT_BRIDGE", "1", TRUE))
-         g_message ("Failed setenv NO_AT_BRIDGE\n");
-     g_test_init (&argc, &argv, NULL);
-+#if GTK_CHECK_VERSION (4, 0, 0)
-+    gtk_init ();
-+#else
-     gtk_init (&argc, &argv);
--#ifdef GDK_WINDOWING_WAYLAND
--    {
--        GdkDisplay *display = gdk_display_get_default ();
--        if (GDK_IS_WAYLAND_DISPLAY (display)) {
--            g_print ("setxkbmap and XTEST do not work in Wayland.\n");
--            return 0;
--        }
--    }
- #endif
- 
-     g_test_add_func ("/ibus/keyrepss", test_keypress);
- 
--
-     return g_test_run ();
- }
--- 
-2.45.0
-
-From a2689c4d66d1f5ae73d2ddbbb94374c98914a029 Mon Sep 17 00:00:00 2001
-From: fujiwarat <takao.fujiwara1@gmail.com>
-Date: Sat, 27 Jul 2024 19:07:58 +0900
-Subject: [PATCH 4/6] src/tests: Fix test cases in GNOME Xorg in ibus-compose
-
-"focus-in" signal is sent to IBus GtkIMModule with a delay in GNOME
-desktop session and the signal order is not fixed with GTK_PHASE_TARGET
-also "focus-in" signal is also sent with GtkText "realize"' signal.
-Now the test cases wait for GtkText 'realize' signal.
-This fixes the test cases in GNOME Xorg but there are still sone issues
-in GNOME Wayland.
-
-BUG=https://github.com/ibus/ibus/pull/2657
----
- src/tests/ibus-compose.c | 71 ++++++++++++++++++++++++++++++++++++++--
- 1 file changed, 68 insertions(+), 3 deletions(-)
-
-diff --git a/src/tests/ibus-compose.c b/src/tests/ibus-compose.c
-index 57851b0a..e9f102a1 100644
---- a/src/tests/ibus-compose.c
-+++ b/src/tests/ibus-compose.c
-@@ -39,6 +39,23 @@ static gboolean window_focus_in_event_cb (GtkWidget     *entry,
- #endif
- 
- 
-+gboolean
-+_wait_for_key_release_cb (gpointer user_data)
-+{
-+    GMainLoop *loop = (GMainLoop *)user_data;
-+    /* If this program is invoked by manual with Enter key in GNOME
-+     * Wayland session, ibus_input_context_focus_in() can be called in
-+     * test_context_engine_set_by_global() before the key release of
-+     * the Enter key so ibus/bus/inputcontext.c:_ic_process_key_event()
-+     * could call another bus_input_context_focus_in() in that test case
-+     * and fail.
-+     */
-+    g_test_message ("Wait for 3 seconds for key release event");
-+    g_main_loop_quit (loop);
-+    return G_SOURCE_REMOVE;
-+}
-+
-+
- static gchar *
- get_compose_path ()
- {
-@@ -312,12 +329,45 @@ set_engine (gpointer user_data)
- 
- 
- #if GTK_CHECK_VERSION (4, 0, 0)
-+static gboolean
-+event_controller_enter_delay (gpointer user_data)
-+{
-+    GtkEventController *controller = (GtkEventController *)user_data;
-+    GtkWidget *text = gtk_event_controller_get_widget (controller);
-+    static int i = 0;
-+
-+    /* Wait for gtk_text_realize() which calls gtk_text_im_set_focus_in()
-+     * while gtk_text_focus_changed() also calls gtk_text_im_set_focus_in()
-+     * in GNOME Xorg.
-+     */
-+    if (gtk_widget_get_realized (text)) {
-+        set_engine (user_data);
-+        return G_SOURCE_REMOVE;
-+    }
-+    if (i++ == 10) {
-+        g_test_fail_printf ("Window is not realized with %d times", i);
-+        return G_SOURCE_REMOVE;
-+    }
-+    g_test_message ("event_controller_enter_delay %d", i);
-+    return G_SOURCE_CONTINUE;
-+}
-+
-+
- static void
- event_controller_enter_cb (GtkEventController *controller,
-                            gpointer            user_data)
- {
-+    static guint id = 0;
-+
-     g_test_message ("EventController emits \"enter\" signal");
--    set_engine (controller);
-+    /* Call an idle function because gtk_widget_add_controller()
-+     * calls g_list_prepend() for event_controllers and this controller is
-+     * always called before "gtk-text-focus-controller"
-+     * is caleld and the IM context does not receive the focus-in yet.
-+     */
-+    if (id)
-+        return;
-+    id = g_idle_add (event_controller_enter_delay, controller);
- }
- 
- #else
-@@ -473,8 +523,9 @@ create_window ()
- #if GTK_CHECK_VERSION (4, 0, 0)
-     controller = gtk_event_controller_focus_new ();
-     text = gtk_editable_get_delegate (GTK_EDITABLE (entry));
--    g_signal_connect (controller, "enter",
--                      G_CALLBACK (event_controller_enter_cb), NULL);
-+    gtk_event_controller_set_propagation_phase (controller, GTK_PHASE_BUBBLE);
-+    g_signal_connect_after (controller, "enter",
-+                            G_CALLBACK (event_controller_enter_cb), NULL);
-     gtk_widget_add_controller (GTK_WIDGET (text), controller);
- #else
-     g_signal_connect (entry, "focus-in-event",
-@@ -495,6 +546,19 @@ create_window ()
- }
- 
- 
-+static void
-+test_init (void)
-+{
-+    char *tty_name = ttyname (STDIN_FILENO);
-+    GMainLoop *loop = g_main_loop_new (NULL, TRUE);
-+    g_test_message ("Test on %s", tty_name ? tty_name : "(null)");
-+    if (tty_name && g_strstr_len (tty_name, -1, "pts")) {
-+        g_timeout_add_seconds (3, _wait_for_key_release_cb, loop);
-+        g_main_loop_run (loop);
-+    }
-+    g_main_loop_unref (loop);
-+}
-+
- static void
- test_compose (void)
- {
-@@ -557,6 +621,7 @@ main (int argc, char *argv[])
-         g_free (test_name);
-         test_name = g_path_get_basename (m_compose_file);
-     }
-+    g_test_add_func ("/ibus-compose/test-init", test_init);
-     m_loop = g_main_loop_new (NULL, TRUE);
-     test_path = g_build_filename ("/ibus-compose", test_name, NULL);
-     g_test_add_func (test_path, test_compose);
--- 
-2.45.0
-
-From e65110a9bed03c981884e28ff44e2ac1f639df45 Mon Sep 17 00:00:00 2001
-From: fujiwarat <takao.fujiwara1@gmail.com>
-Date: Sat, 27 Jul 2024 19:09:10 +0900
-Subject: [PATCH 5/6] src/tests: Fix ibus-compose for GNOME Wayland
-
-mutter calls meta_wayland_text_input_set_focus() after meta_window_show()
-and the delayed focus-in/out events are sent to IBusEngine.
-Now sleep() is added in ibus-compose because MetaWaylandInputMethod
-cannot know the application status while GTK application is already
-realized.
-
-Also GTK4 compose table supports 16bit compose keys only and it
-causes a warning with pt-BR and fi-FI compose tables but the warning
-is treated as a failure with g_test_init().
-Set LANG=en_US.UTF-8 for thw workaround to test pt-BR and fi-FI IBus
-compose tables.
-
-BUG=https://github.com/ibus/ibus/pull/2657
----
- src/tests/ibus-compose.c | 223 ++++++++++++++++++++++++++++++++++-----
- 1 file changed, 195 insertions(+), 28 deletions(-)
-
-diff --git a/src/tests/ibus-compose.c b/src/tests/ibus-compose.c
-index e9f102a1..0679c259 100644
---- a/src/tests/ibus-compose.c
-+++ b/src/tests/ibus-compose.c
-@@ -7,19 +7,24 @@
- #define RED   "\033[0;31m"
- #define NC    "\033[0m"
- 
-+static gchar *m_test_name;
-+static gchar *m_session_name;
- static IBusBus *m_bus;
- static gchar *m_compose_file;
- static IBusComposeTableEx *m_compose_table;
- static IBusEngine *m_engine;
- static gchar *m_srcdir;
-+static gboolean m_is_gtk_32bit_compose_error;
- static GMainLoop *m_loop;
-+static char *m_engine_is_focused;
- #if GTK_CHECK_VERSION (4, 0, 0)
- static gboolean m_list_toplevel;
- #endif
- 
- typedef enum {
-+    TEST_COMMIT_TEXT,
-     TEST_CREATE_ENGINE,
--    TEST_COMMIT_TEXT
-+    TEST_DELAYED_FOCUS_IN
- } TestIDleCategory;
- 
- typedef struct _TestIdleData {
-@@ -39,6 +44,19 @@ static gboolean window_focus_in_event_cb (GtkWidget     *entry,
- #endif
- 
- 
-+gboolean
-+is_integrated_desktop ()
-+{
-+    if (!m_session_name)
-+        m_session_name = g_strdup (g_getenv ("XDG_SESSION_DESKTOP"));
-+    if (!m_session_name)
-+        return FALSE;
-+    if (!g_ascii_strncasecmp (m_session_name, "gnome", strlen ("gnome")))
-+       return TRUE;
-+    return FALSE;
-+}
-+
-+
- gboolean
- _wait_for_key_release_cb (gpointer user_data)
- {
-@@ -63,11 +81,15 @@ get_compose_path ()
-     const gchar * const *l;
-     gchar *compose_path = NULL;
- 
-+    if (m_is_gtk_32bit_compose_error)
-+        g_assert (g_setenv ("LANG", m_test_name, TRUE));
- #if GLIB_CHECK_VERSION (2, 58, 0)
-     langs = g_get_language_names_with_category ("LC_CTYPE");
- #else
-     langs = g_get_language_names ();
- #endif
-+    if (m_is_gtk_32bit_compose_error)
-+        g_assert (g_setenv ("LANG", "en_US.UTF-8", TRUE));
-     for (l = langs; *l; l++) {
-         if (g_str_has_prefix (*l, "en_US"))
-             break;
-@@ -91,6 +113,9 @@ gboolean
- idle_cb (gpointer user_data)
- {
-     TestIdleData *data = (TestIdleData *)user_data;
-+    static int n = 0;
-+    gboolean terminate_program = FALSE;
-+
-     g_assert (data);
-     switch (data->category) {
-     case TEST_CREATE_ENGINE:
-@@ -103,23 +128,75 @@ idle_cb (gpointer user_data)
-             if (g_main_loop_is_running (m_loop))
-                 g_main_loop_quit (m_loop);
-             g_clear_pointer (&m_loop, g_main_loop_unref);
--#if GTK_CHECK_VERSION (4, 0, 0)
--            m_list_toplevel = FALSE;
--#else
--            gtk_main_quit ();
--#endif
-+            terminate_program = TRUE;
-         }
-         data->idle_id = 0;
-         break;
-+    case TEST_DELAYED_FOCUS_IN:
-+        if (m_engine_is_focused) {
-+            data->idle_id = 0;
-+            n = 0;
-+            g_main_loop_quit (m_loop);
-+            return G_SOURCE_REMOVE;
-+        }
-+        if (n++ < 10) {
-+            g_test_message ("Waiting for \"focus-in\" signal %dth times", n);
-+            return G_SOURCE_CONTINUE;
-+        }
-+        g_test_fail_printf ("\"focus-in\" signal is timeout.");
-+        g_main_loop_quit (m_loop);
-+        terminate_program = TRUE;
-+        n = 0;
-+        break;
-     default:
-         g_test_fail_printf ("Idle func is called by wrong category:%d.",
-                             data->category);
-         break;
-     }
-+    if (terminate_program) {
-+#if GTK_CHECK_VERSION (4, 0, 0)
-+        m_list_toplevel = FALSE;
-+#else
-+        gtk_main_quit ();
-+#endif
-+    }
-     return G_SOURCE_REMOVE;
- }
- 
- 
-+static void
-+engine_focus_in_cb (IBusEngine *engine,
-+#ifdef IBUS_FOCUS_IN_ID
-+                    gchar      *object_path,
-+                    gchar      *client,
-+#endif
-+                    gpointer    user_data)
-+{
-+#ifdef IBUS_FOCUS_IN_ID
-+    g_test_message ("engine_focus_in_cb %s %s", object_path, client);
-+    m_engine_is_focused = g_strdup (client);
-+#else
-+    g_test_message ("engine_focus_in_cb");
-+    m_engine_is_focused = g_strdup ("No named");
-+#endif
-+}
-+
-+static void
-+engine_focus_out_cb (IBusEngine *engine,
-+#ifdef IBUS_FOCUS_IN_ID
-+                     gchar      *object_path,
-+#endif
-+                     gpointer    user_data)
-+{
-+#ifdef IBUS_FOCUS_IN_ID
-+    g_test_message ("engine_focus_out_cb %s", object_path);
-+#else
-+    g_test_message ("engine_focus_out_cb");
-+#endif
-+    g_clear_pointer (&m_engine_is_focused, g_free);
-+}
-+
-+
- static IBusEngine *
- create_engine_cb (IBusFactory *factory,
-                   const gchar *name,
-@@ -135,11 +212,30 @@ create_engine_cb (IBusFactory *factory,
-     g_assert (data);
-     /* Don't reset idle_id to avoid duplicated register_ibus_engine(). */
-     g_source_remove (data->idle_id);
--    m_engine = ibus_engine_new_with_type (IBUS_TYPE_ENGINE_SIMPLE,
--                                          name,
--                                          engine_path,
--                                          ibus_bus_get_connection (m_bus));
-+    m_engine = (IBusEngine *)g_object_new (
-+            IBUS_TYPE_ENGINE_SIMPLE,
-+            "engine-name",      name,
-+            "object-path",      engine_path,
-+            "connection",       ibus_bus_get_connection (m_bus),
-+#ifdef IBUS_FOCUS_IN_ID
-+            "has-focus-id",     TRUE,
-+#endif
-+            NULL);
-     g_free (engine_path);
-+
-+    m_engine_is_focused = NULL;
-+#ifdef IBUS_FOCUS_IN_ID
-+    g_signal_connect (m_engine, "focus-in-id",
-+#else
-+    g_signal_connect (m_engine, "focus-in",
-+#endif
-+                      G_CALLBACK (engine_focus_in_cb), NULL);
-+#ifdef IBUS_FOCUS_IN_ID
-+    g_signal_connect (m_engine, "focus-out-id",
-+#else
-+    g_signal_connect (m_engine, "focus-out",
-+#endif
-+                      G_CALLBACK (engine_focus_out_cb), NULL);
-     if (m_compose_file)
-         compose_path = g_build_filename (m_srcdir, m_compose_file, NULL);
-     else
-@@ -235,6 +331,13 @@ set_engine_cb (GObject      *object,
-         return;
-     }
- 
-+    /* ibus_im_context_focus_in() is called after GlboalEngine is set. */
-+    if (is_integrated_desktop () && !m_engine_is_focused) {
-+        data.category = TEST_DELAYED_FOCUS_IN;
-+        data.idle_id = g_timeout_add_seconds (1, idle_cb, &data);
-+        g_main_loop_run (m_loop);
-+        if (data.idle_id != 0)
-+            return;
-     if (m_compose_table == NULL) {
-         g_test_skip ("Your locale uses en_US compose table.");
-         idle_cb (&data);
-@@ -319,6 +422,7 @@ set_engine (gpointer user_data)
- {
-     g_test_message ("set_engine() is calling");
-     g_assert (m_bus != NULL);
-+
-     ibus_bus_set_global_engine_async (m_bus,
-                                       "xkbtest:us::eng",
-                                       -1,
-@@ -346,6 +450,11 @@ event_controller_enter_delay (gpointer user_data)
-     }
-     if (i++ == 10) {
-         g_test_fail_printf ("Window is not realized with %d times", i);
-+#if GTK_CHECK_VERSION (4, 0, 0)
-+        m_list_toplevel = FALSE;
-+#else
-+        gtk_main_quit ();
-+#endif
-         return G_SOURCE_REMOVE;
-     }
-     g_test_message ("event_controller_enter_delay %d", i);
-@@ -360,16 +469,43 @@ event_controller_enter_cb (GtkEventController *controller,
-     static guint id = 0;
- 
-     g_test_message ("EventController emits \"enter\" signal");
--    /* Call an idle function because gtk_widget_add_controller()
--     * calls g_list_prepend() for event_controllers and this controller is
--     * always called before "gtk-text-focus-controller"
--     * is caleld and the IM context does not receive the focus-in yet.
--     */
-     if (id)
-         return;
--    id = g_idle_add (event_controller_enter_delay, controller);
-+    if (is_integrated_desktop ()) {
-+        /* Wait for 3 seconds in GNOME Wayland because there is a long time lag
-+         * between the "enter" signal on the event controller in GtkText
-+         * and the "FocusIn" D-Bus signal in BusInputContext of ibus-daemon
-+         * because mutter/core/window.c:meta_window_show() calls
-+         * mutter/core/window.c:meta_window_focus() ->
-+         * mutter/wayland/meta-wayland-text-input.c:
-+         *   meta_wayland_text_input_set_focus() ->
-+         * mutter/clutter/clutter/clutter-input-method.c:
-+         *   clutter_input_method_focus_out()
-+         * I.e. "FocusOut" and "FocusIn" D-Bus methods are always delayed
-+         * against the window present in GNOME Wayland.
-+         * If "FocusOut" and "FocusIn" D-Bus signals would be called after
-+         * "SetGlobalEngine" D-BUs signal was called in ibus-daemon,
-+         * the following functions could be called:
-+         *   engine_focus_out_cb() for the "gnome-shell" context
-+         *   engine_focus_in_cb() for the "fake" context
-+         *   engine_focus_out_cb() for the "fake" context
-+         *   engine_focus_in_cb() for the "gnome-shell" context
-+         * and ibus_engine_commit_text() would not work.
-+         * This assume the focus-in/out signals are called within the timeout
-+         * seconds.
-+         */
-+        id = g_timeout_add_seconds (3,
-+                                    event_controller_enter_delay,
-+                                    controller);
-+    } else {
-+        /* Call an idle function in Xorg because gtk_widget_add_controller()
-+         * calls g_list_prepend() for event_controllers and this controller is
-+         * always called before "gtk-text-focus-controller"
-+         * is caleld and the IM context does not receive the focus-in yet.
-+         */
-+        id = g_idle_add (event_controller_enter_delay, controller);
-+    }
- }
--
- #else
- 
- static gboolean
-@@ -550,10 +686,18 @@ static void
- test_init (void)
- {
-     char *tty_name = ttyname (STDIN_FILENO);
--    GMainLoop *loop = g_main_loop_new (NULL, TRUE);
-+    GMainLoop *loop;
-+    static guint idle_id = 0;
-+
-+    if (idle_id) {
-+        g_test_incomplete ("Test is called twice due to a timeout.");
-+        return;
-+    }
-+
-+    loop = g_main_loop_new (NULL, TRUE);
-     g_test_message ("Test on %s", tty_name ? tty_name : "(null)");
-     if (tty_name && g_strstr_len (tty_name, -1, "pts")) {
--        g_timeout_add_seconds (3, _wait_for_key_release_cb, loop);
-+        idle_id = g_timeout_add_seconds (3, _wait_for_key_release_cb, loop);
-         g_main_loop_run (loop);
-     }
-     g_main_loop_unref (loop);
-@@ -586,14 +730,16 @@ test_compose (void)
-     gtk_main ();
- #endif
-     g_log_set_always_fatal (flags);
-+    g_clear_pointer (&m_engine_is_focused, g_free);
-+    g_clear_pointer (&m_session_name, g_free);
- }
- 
- 
- int
- main (int argc, char *argv[])
- {
--    gchar *test_name;
-     gchar *test_path;
-+    int retval;
- 
-     ibus_init ();
-     /* Avoid a warning of "AT-SPI: Could not obtain desktop path or name"
-@@ -612,21 +758,42 @@ main (int argc, char *argv[])
-             ? g_strdup (argv[1]) : g_strdup (".");
-     m_compose_file = g_strdup (g_getenv ("COMPOSE_FILE"));
- #if GLIB_CHECK_VERSION (2, 58, 0)
--    test_name = g_strdup (g_get_language_names_with_category ("LC_CTYPE")[0]);
-+    m_test_name = g_strdup (g_get_language_names_with_category ("LC_CTYPE")[0]);
- #else
--    test_name = g_strdup (g_getenv ("LANG"));
-+    m_test_name = g_strdup (g_getenv ("LANG"));
- #endif
-     if (m_compose_file &&
--        (!test_name || !g_ascii_strncasecmp (test_name, "en_US", 5))) {
--        g_free (test_name);
--        test_name = g_path_get_basename (m_compose_file);
-+        (!m_test_name || !g_ascii_strncasecmp (m_test_name, "en_US", 5))) {
-+        g_free (m_test_name);
-+        m_test_name = g_path_get_basename (m_compose_file);
-+    }
-+    /* The parent of GtkIMContextWayland is GtkIMContextSimple and
-+     * it outputs a warning of "Can't handle >16bit keyvals" in
-+     * gtk/gtkcomposetable.c:parse_compose_sequence() in pt-BR locales
-+     * and any warnings are treated as errors with g_test_run()
-+     * So export LANG=en_US.UTF-8 for GNOME Wayland as a workaround.
-+     */
-+    if (m_test_name && (!g_ascii_strncasecmp (m_test_name, "pt_BR", 5) ||
-+                        !g_ascii_strncasecmp (m_test_name, "fi_FI", 5)
-+                       )) {
-+        m_is_gtk_32bit_compose_error = TRUE;
-+    }
-+    if (m_is_gtk_32bit_compose_error) {
-+#if 1
-+        g_assert (g_setenv ("LANG", "en_US.UTF-8", TRUE));
-+#else
-+        /* FIXME: Use expected_messages in g_log_structured() */
-+        g_test_expect_message ("Gtk", G_LOG_LEVEL_WARNING,
-+                               "Can't handle >16bit keyvals");
-+#endif
-     }
-     g_test_add_func ("/ibus-compose/test-init", test_init);
-     m_loop = g_main_loop_new (NULL, TRUE);
--    test_path = g_build_filename ("/ibus-compose", test_name, NULL);
-+    test_path = g_build_filename ("/ibus-compose", m_test_name, NULL);
-     g_test_add_func (test_path, test_compose);
-     g_free (test_path);
--    g_free (test_name);
- 
--    return g_test_run ();
-+    retval = g_test_run ();
-+    g_free (m_test_name);
-+    return retval;
- }
--- 
-2.45.0
-
-From 23785e6c8150aceda7f9665a3335f1e4baecd1cc Mon Sep 17 00:00:00 2001
-From: fujiwarat <takao.fujiwara1@gmail.com>
-Date: Thu, 1 Aug 2024 08:23:09 +0900
-Subject: [PATCH 6/6] src/tests: Fix some CI issues with busy TMT virtual session
-
-- Increase waiting time in ibus-compose-locales.
-- Wait for 3 secs after set-engine in ibus-compose to wait for the delayed
-  focus-in/out events.
-- delete screendump option in ibus-desktop-testing.desktop not to
-  support no display.
-- setlocale in ibus-engine-switch to get UTF-8 warnings.
-- Quote file names as shell syntax as much as possible.
-- Check file existent and do not use "rm -f" as much as possible.
-- Do not set GTK_IM_MODULE=ibus for Wayland.
-- Exclude sshd-session to check existent sessions.
-
-BUG=https://github.com/ibus/ibus/pull/2657
----
- src/tests/ibus-compose-locales.in           |  4 +-
- src/tests/ibus-compose.c                    | 23 ++++--
- src/tests/ibus-desktop-testing-autostart.in |  1 +
- src/tests/ibus-desktop-testing-module       | 79 ++++++++++++++++-----
- src/tests/ibus-desktop-testing.desktop.in   |  2 +-
- src/tests/ibus-engine-switch.c              |  3 +
- 6 files changed, 85 insertions(+), 27 deletions(-)
-
-diff --git a/src/tests/ibus-compose-locales.in b/src/tests/ibus-compose-locales.in
-index 7a133ce0..485204c0 100755
---- a/src/tests/ibus-compose-locales.in
-+++ b/src/tests/ibus-compose-locales.in
-@@ -15,8 +15,8 @@ do
-     if [ "x$IS_COMMENT" != x ] ; then
-         continue
-     fi
--    while [ x"$IBUS_DAEMON_WITH_SYSTEMD" != x ] && [ $INITED -lt 6 ] ; do
--        echo "Waiting for ${INITED}0 secs till 60 secs"
-+    while [ x"$IBUS_DAEMON_WITH_SYSTEMD" != x ] && [ $INITED -lt 12 ] ; do
-+        echo "Waiting for ${INITED}0 secs till 120 secs"
-         sleep 10
-         INITED=`expr $INITED + 1`
-     done
-diff --git a/src/tests/ibus-compose.c b/src/tests/ibus-compose.c
-index 0679c259..326d3b90 100644
---- a/src/tests/ibus-compose.c
-+++ b/src/tests/ibus-compose.c
-@@ -331,13 +331,22 @@ set_engine_cb (GObject      *object,
-         return;
-     }
- 
--    /* ibus_im_context_focus_in() is called after GlboalEngine is set. */
--    if (is_integrated_desktop () && !m_engine_is_focused) {
--        data.category = TEST_DELAYED_FOCUS_IN;
--        data.idle_id = g_timeout_add_seconds (1, idle_cb, &data);
--        g_main_loop_run (m_loop);
--        if (data.idle_id != 0)
--            return;
-+    /* ibus_im_context_focus_in() is called after GlboalEngine is set.
-+     * The focus-in/out events happen more slowly in a busy system
-+     * likes with a TMT tool.
-+     */
-+    if (is_integrated_desktop () && g_getenv ("IBUS_DAEMON_WITH_SYSTEMD")) {
-+        g_test_message ("Start tiny \"focus-in\" signal test");
-+        for (i = 0; i < 3; i++) {
-+            data.category = TEST_DELAYED_FOCUS_IN;
-+            data.idle_id = g_timeout_add_seconds (1, idle_cb, &data);
-+            g_main_loop_run (m_loop);
-+            if (data.idle_id != 0)
-+                return;
-+        }
-+        g_test_message ("End tiny \"focus-in\" signal test");
-+        data.category = TEST_COMMIT_TEXT;
-+    }
-     if (m_compose_table == NULL) {
-         g_test_skip ("Your locale uses en_US compose table.");
-         idle_cb (&data);
-diff --git a/src/tests/ibus-desktop-testing-autostart.in b/src/tests/ibus-desktop-testing-autostart.in
-index d50354df..9ecc8c27 100755
---- a/src/tests/ibus-desktop-testing-autostart.in
-+++ b/src/tests/ibus-desktop-testing-autostart.in
-@@ -73,6 +73,7 @@ main()
-     parse_args "$@"
-     init_session
-     check_env
-+    #run_monitor
-     save_screen
-     run_test_suite
-     finit
-diff --git a/src/tests/ibus-desktop-testing-module b/src/tests/ibus-desktop-testing-module
-index 2d686813..55eb248e 100755
---- a/src/tests/ibus-desktop-testing-module
-+++ b/src/tests/ibus-desktop-testing-module
-@@ -63,8 +63,9 @@ pwd
- pstree -asp $$
- gsettings list-recursively org.gnome.shell
- rpm -q gnome-shell-extension-no-overview gnome-shell gnome-session
--ps -ef | grep ibus | grep -v grep
-+ps -ef | grep ibus | grep -v TMT | grep -v grep
- ibus address
-+locale
- env
- #dbus-send --session --print-reply --dest=org.gnome.Shell.Introspect /org/gnome/Shell/Introspect org.gnome.Shell.Introspect.GetWindows
- '
-@@ -133,7 +134,8 @@ check_tty()
-     TTY=`tty`
-     if echo $PROGNAME | grep -q runner ; then
-         if [ $ENABLED_SYSTEMD -eq 1 ] && [  $SESSION_IS_GNOME -eq 1 ] ; then
--            if echo "$TTY" | grep -E 'tty|console' ; then
-+            # "not a tty" is correct with TMT tool
-+            if echo "$TTY" | grep -E 'tty|console' | grep -v "not a tty" ; then
-                print_log -e "${RED}FAIL${NC}: ${RED}ERROR${NC}: Changing runlevel does not support console. Please log into the host with ssh."
-                exit 1
-             fi
-@@ -143,7 +145,7 @@ check_tty()
-                print_log -e "Running session with ssh. It might be good to use console instead."
-             fi
-         fi
--        SESSION=`ps -ef | grep session | grep -v grep`
-+        SESSION=`ps -ef | grep session | grep -v TMT | grep -v sshd-session | grep -v grep`
-         if [ x"$SESSION" != x ] ; then
-                print_log -e "${RED}FAIL${NC}: ${RED}ERROR${NC}: Session is running: $SESSION"
-                exit 1
-@@ -254,7 +256,8 @@ create_xdg_autostart()
-         exit 1
-     fi
-     mkdir -p "$TEST_USER_HOME/.config/autostart"
--    cp "$desktop_file" "$TEST_USER_HOME/.config/autostart"
-+    sed -e "s/\(^Exec=.*\)tests ibus\(.*\)/\1tests $TESTS\2/" "$desktop_file" \
-+        > "$TEST_USER_HOME/.config/autostart/$AUTOSTART_DESKTOP_FILE"
-     LINE="AutostartCondition=if-exists $TEST_USER_HOME/.config/autostart/$AUTOSTART_DESKTOP_FILE"
-     echo "$LINE" >> "$TEST_USER_HOME/.config/autostart/$AUTOSTART_DESKTOP_FILE"
-     chown -R "$TEST_USER" "$TEST_USER_HOME/.config"
-@@ -327,6 +330,9 @@ init_session()
- 
-     LOGIN_USER=$USER
-     LOGIN_HOME=$HOME
-+    if [ x"$TESTS" = x ] ; then
-+        TESTS='ibus'
-+    fi
-     check_tty
-     if [ $ENABLED_SYSTEMD -eq 1 ] && [  $SESSION_IS_GNOME -eq 1 ] ; then
-         SESSION_FILE1="/usr/lib/systemd/system/gnome-headless-session@.service"
-@@ -482,9 +488,25 @@ init_gnome()
-             chown -R $LOGIN_USER $TEST_USER_HOME/.local
-         fi
-     fi
-+
-+    ## Use gnome-headless-session for the no-graphics option because currently
-+    ## GDM itself cannot run the login screen(greeter) without a display so
-+    ## the no-graphics option does not work with GDM and the TMT tool
-+    ## while GDM can invoke the headless GNOME Wayland sessions.
-+    ##
-+    ## Use GNOME_SHELL_WAYLAND_COMMAND for the no-graphics option to add a
-+    ## virtual monitor since gnome-headless-session provides a headless mode
-+    ## but no monitor and IBus focus-in/out events does not work without
-+    ## any monitors.
-+    ##
-+    ## Use the systemd locale configuration for the no-graphcis mode since
-+    ## gnome-headless-session does not pull LANG from AccountsService.
-+    ##
-     if [ $LOGIN_USER != $USER ] ; then
-         SHELL_SERVICE_FILE="org.gnome.Shell@wayland.service"
-         SYSTEMD_USER_DIR="$TEST_USER_HOME/.config/systemd/user"
-+        ENV_USER_DIR="$TEST_USER_HOME/.config/environment.d"
-+        LOCALE_CONF="$ENV_USER_DIR/ibus.conf"
-         if test $HAVE_GRAPHICS -ne 1 ; then
-             if test ! -f "$SYSTEMD_USER_DIR/$SHELL_SERVICE_FILE" ; then
-                 mkdir -p "$SYSTEMD_USER_DIR"
-@@ -494,12 +516,19 @@ init_gnome()
-                     > $SHELL_SERVICE_FILE
-                 diff $SYSTEMD_SYSTEM_DIR/$SHELL_SERVICE_FILE $SHELL_SERVICE_FILE
-                 popd
--                chown -R $LOGIN_USER "$TEST_USER_HOME/.config"
-             fi
-+            mkdir -p "$ENV_USER_DIR"
-+            cat > "$LOCALE_CONF" << _EOF_LOCALE_CONF
-+LANG=$SESSION_LANG
-+_EOF_LOCALE_CONF
-+            chown -R $LOGIN_USER "$TEST_USER_HOME/.config"
-         else
-             if test -f "$SYSTEMD_USER_DIR/$SHELL_SERVICE_FILE" ; then
-                 rm "$SYSTEMD_USER_DIR/$SHELL_SERVICE_FILE"
-             fi
-+            if test -f "$LOCALE_CONF" ; then
-+                rm "$LOCALE_CONF"
-+            fi
-         fi
-     fi
-     GET_DISABLE_USER_EX="gsettings get org.gnome.shell disable-user-extensions"
-@@ -556,7 +585,7 @@ operate_desktop_with_systemd()
-     SESSION=gnome-headless-session
-     COMMAND="$1"
- 
--    #if test $HAVE_GRAPHICS -eq 1 ; then
-+    if test $HAVE_GRAPHICS -eq 1 ; then
-         case "$COMMAND" in
-         "start") systemctl isolate graphical.target
-                  echo ""
-@@ -565,22 +594,24 @@ operate_desktop_with_systemd()
-         "")      print_log -e "${RED}FAIL${NC}: ${RED}ERROR${NC}: Wrong command $COMMAND"
-                  exit 1;;
-         esac
--    #else
--    #    setenforce 0
--    #    systemctl $COMMAND ${SESSION}@${TEST_USER}
--    #fi
-+    else
-+        setenforce 0
-+        systemctl $COMMAND ${SESSION}@${TEST_USER}
-+    fi
-     case "$COMMAND" in
-     "start") sleep 30;;
-     "") ;;
-     esac
--    #if test $HAVE_GRAPHICS -eq 1 ; then
-+    if test $HAVE_GRAPHICS -eq 1 ; then
-         systemctl status --no-pager graphical.target
--    #else
--    #    systemctl status --no-pager ${SESSION}@${TEST_USER}
--    #fi
-+    else
-+        systemctl status --no-pager ${SESSION}@${TEST_USER}
-+    fi
-     ps -ef | grep X
-     ps -ef | grep session
-     ps -ef | grep ibus
-+    SUSER=`echo "$LOGIN_USER" | cut -c 1-7`
-+    ps -ef | grep $SUSER
- }
- 
- 
-@@ -639,6 +670,23 @@ run_session()
- }
- 
- 
-+run_monitor()
-+{
-+    if ! which gnome-monitor-config > /dev/null ; then
-+        print_log -e "${RED}FAIL${NC}: No gnome-monitor-config"
-+        return
-+    fi
-+    if [ $ENABLED_SYSTEMD -ne 1 ] || [  $SESSION_IS_GNOME -ne 1 ] \
-+       || [ $HAVE_GRAPHICS -ne 1 ] ; then
-+        return
-+    fi
-+    /usr/libexec/gnome-screen-cast.py -v 1024 768 &
-+    sleep 3
-+    gnome-monitor-config list
-+    #gnome-monitor-config set -LpM Virtual-1 -t normal -m 1024x768@60.004
-+}
-+
-+
- count_case_result()
- {
-     retval=$1
-@@ -758,9 +806,6 @@ run_gnome_desktop_testing_runner()
- {
-     pass=0
-     fail=0
--    if [ x"$TESTS" = x ] ; then
--        TESTS='ibus'
--    fi
-     if echo $PROGNAME | grep -q autostart ; then
-         export IBUS_DAEMON_WITH_SYSTEMD=1
-     fi
-diff --git a/src/tests/ibus-desktop-testing.desktop.in b/src/tests/ibus-desktop-testing.desktop.in
-index e91900ed..fe9356ad 100644
---- a/src/tests/ibus-desktop-testing.desktop.in
-+++ b/src/tests/ibus-desktop-testing.desktop.in
-@@ -2,7 +2,7 @@
- Name=IBus Desktop Testing Runner
- GenericName=Input Method Desktop Testing Runner
- Comment=Test plugin for IBus Desktop Testing
--Exec=sh -c 'exec @libexecdir@/ibus-desktop-testing-autostart --envcheck --output $HOME/test-autostart.log --result $HOME/test.log --runner gnome --screendump $HOME/screen.log --tests ibus'
-+Exec=sh -c 'exec @libexecdir@/ibus-desktop-testing-autostart --envcheck --output $HOME/test-autostart.log --result $HOME/test.log --runner gnome --tests ibus'
- Terminal=false
- Type=Application
- Encoding=UTF-8
-diff --git a/src/tests/ibus-engine-switch.c b/src/tests/ibus-engine-switch.c
-index b50bac59..7359e125 100644
---- a/src/tests/ibus-engine-switch.c
-+++ b/src/tests/ibus-engine-switch.c
-@@ -1,5 +1,6 @@
- /* -*- mode: C; c-basic-offset: 4; indent-tabs-mode: nil; -*- */
- 
-+#include <locale.h>
- #include <string.h>
- #include <unistd.h>
- #include "ibus.h"
-@@ -251,6 +252,8 @@ main (gint    argc,
-       gchar **argv)
- {
-     gint result;
-+    /* To get UTF-8 error messages with glib2 */
-+    setlocale (LC_ALL, "");
-     ibus_init ();
-     g_test_init (&argc, &argv, NULL);
-     bus = ibus_bus_new ();
--- 
-2.45.0
-
-From 803b71fbcc2de6faaaf3b20e2bc08fea2e1abbe8 Mon Sep 17 00:00:00 2001
-From: fujiwarat <takao.fujiwara1@gmail.com>
-Date: Wed, 14 Aug 2024 09:12:58 +0900
-Subject: [PATCH] util/IMdkit: Revert to fix typing freeze with barcode reader
-
-The original barcode reader issue is fixed with libX11 1.8.10 and
-it's now available in Fedora.
-The typing freezing issue is no longer reproducible with the latest
-libX11 in Fedora 40.
-
-Now the previous change(b49f3a4736540f3cf2f7e7b3ac7f965970393c74) is
-reverted and I continue to trace the issue.
-
-Fixes: https://github.com/ibus/ibus/commit/b49f3a4
-BUG=https://gitlab.freedesktop.org/xorg/lib/libx11/-/issues/198
-BUG=https://github.com/ibus/ibus/issues/2560
----
- util/IMdkit/i18nPtHdr.c | 1 -
- 1 file changed, 1 deletion(-)
-
-diff --git a/util/IMdkit/i18nPtHdr.c b/util/IMdkit/i18nPtHdr.c
-index 07aecbb1..ec20e322 100644
---- a/util/IMdkit/i18nPtHdr.c
-+++ b/util/IMdkit/i18nPtHdr.c
-@@ -1757,7 +1757,6 @@ static void ProcessQueue (XIMS ims, CARD16 connect_id)
-         switch (hdr->major_opcode)
-         {
-         case XIM_FORWARD_EVENT:
--            sync();
-             ForwardEventMessageProc(ims, &call_data, p1);
-             break;
-         }
--- 
-2.45.2
-

             reply	other threads:[~2026-05-31  2:08 UTC|newest]

Thread overview: 8+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-05-31  2:08 Takao Fujiwara [this message]
  -- strict thread matches above, loose matches on Subject: below --
2026-05-31  2:09 [rpms/ibus] autotool: Delete upstreamed ibus-HEAD.patch Takao Fujiwara
2026-05-31  2:09 Takao Fujiwara
2026-05-31  2:08 Takao Fujiwara
2026-05-31  2:08 Takao Fujiwara
2026-05-31  2:07 Takao Fujiwara
2026-05-31  2:07 Takao Fujiwara
2026-05-31  2:07 Takao Fujiwara

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=178019332078.1.7564135766380726412.rpms-ibus-8e894714961b@fedoraproject.org \
    --to=tfujiwar@redhat.com \
    --cc=git-commits@fedoraproject.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox