diff --git a/SOURCES/ibus-1470673-emoji-warn-instead-assert.patch b/SOURCES/ibus-1470673-emoji-warn-instead-assert.patch new file mode 100644 index 0000000..35710f8 --- /dev/null +++ b/SOURCES/ibus-1470673-emoji-warn-instead-assert.patch @@ -0,0 +1,48 @@ +From 0f5084e07c215d74adc4eeeda40b374855cce59a Mon Sep 17 00:00:00 2001 +From: fujiwarat +Date: Fri, 11 Jan 2019 12:56:42 +0900 +Subject: [PATCH] src/ibuscomposetable: Replace assert with warning for + .XCompose + +BUG=rhbz#1470673 +--- + src/ibuscomposetable.c | 12 +++++++----- + 1 file changed, 7 insertions(+), 5 deletions(-) + +diff --git a/src/ibuscomposetable.c b/src/ibuscomposetable.c +index b843e7e1..1c0ece41 100644 +--- a/src/ibuscomposetable.c ++++ b/src/ibuscomposetable.c +@@ -1,7 +1,7 @@ + /* -*- mode: C; c-basic-offset: 4; indent-tabs-mode: nil; -*- */ + /* ibus - The Input Bus + * Copyright (C) 2013-2014 Peng Huang +- * Copyright (C) 2013-2018 Takao Fujiwara ++ * Copyright (C) 2013-2019 Takao Fujiwara + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public +@@ -98,14 +98,16 @@ parse_compose_value (IBusComposeData *compose_data, + uch = words[1][1]; + + /* The escaped string "\"" is separated with '\\' and '"'. */ +- if (uch == '\0' && words[2][0] == '"') ++ if (uch == '\0' && words[2][0] == '"') { + uch = '"'; + /* The escaped octal */ +- else if (uch >= '0' && uch <= '8') ++ } else if (uch >= '0' && uch <= '8') { + uch = g_ascii_strtoll(words[1] + 1, NULL, 8); + /* If we need to handle other escape sequences. */ +- else if (uch != '\\') +- g_assert_not_reached (); ++ } else if (uch != '\\') { ++ g_warning ("Invalid backslash: %s: %s", val, line); ++ goto fail; ++ } + } + + if (g_utf8_get_char (g_utf8_next_char (words[1])) > 0) { +-- +2.21.0 + diff --git a/SOURCES/ibus-1682157-ci.patch b/SOURCES/ibus-1682157-ci.patch new file mode 100644 index 0000000..28dc8ed --- /dev/null +++ b/SOURCES/ibus-1682157-ci.patch @@ -0,0 +1,2393 @@ +From c360cbd830943a4bfb0ece9cc07b99a426dc2121 Mon Sep 17 00:00:00 2001 +From: fujiwarat +Date: Mon, 9 Apr 2018 11:57:09 +0900 +Subject: [PATCH] src/tests: Add ibus-compose.env + +--- + src/tests/ibus-compose.env | 3 +++ + 1 file changed, 3 insertions(+) + create mode 100644 src/tests/ibus-compose.env + +diff --git a/src/tests/ibus-compose.env b/src/tests/ibus-compose.env +new file mode 100644 +index 00000000..734ab8fa +--- /dev/null ++++ b/src/tests/ibus-compose.env +@@ -0,0 +1,3 @@ ++LANG=el_GR.UTF-8 ++LANG=fi_FI.UTF-8 ++LANG=pt_BR.UTF-8 +-- +2.21.0 + +From b497de5bc6525769e03b65c73fc991d4aa006223 Mon Sep 17 00:00:00 2001 +From: fujiwarat +Date: Wed, 20 Mar 2019 17:44:26 +0900 +Subject: [PATCH] test: Set GTK_IM_MODULE in test-console.sh + +--- + src/tests/Makefile.am | 4 ++-- + 2 files changed, 14 insertions(+), 2 deletions(-) + +diff --git a/src/tests/Makefile.am b/src/tests/Makefile.am +index e337a59b..e2ff5ea7 100644 +--- a/src/tests/Makefile.am ++++ b/src/tests/Makefile.am +@@ -3,7 +3,7 @@ + # ibus - The Input Bus + # + # Copyright (c) 2007-2015 Peng Huang +-# Copyright (c) 2015-2018 Takao Fujiwara ++# Copyright (c) 2015-2019 Takao Fujiwara + # Copyright (c) 2007-2018 Red Hat, Inc. + # + # This library is free software; you can redistribute it and/or +@@ -78,7 +78,7 @@ TESTS_ENVIRONMENT = \ + + LOG_COMPILER = $(srcdir)/runtest + +-EXTRA_DIST = runtest ++EXTRA_DIST = runtest ibus-compose.env + + ibus_bus_SOURCES = ibus-bus.c + ibus_bus_LDADD = $(prog_ldadd) +-- +2.21.0 + +From ac492f31b435b9464d591094d470bc94027168e8 Mon Sep 17 00:00:00 2001 +From: fujiwarat +Date: Fri, 28 Jun 2019 21:15:07 +0900 +Subject: [PATCH] src/tests: Fix ibus-compose for IBusComposeTableEx + +Recently IBusComposeTablEx has been integrated and the return value of +ibus_compose_table_new_with_file() is also changed and ibus-compose +needs to be updated. + +Clear IBusComposeTablePrivate in ibus_compose_table_list_add_array() +for the ibus-compose testing. + +Clear compose_buffer in IBusEngineSimple. + +Use g_get_language_names_with_category instead() of g_get_locale_variants(). + +Add ibus-compose.emoji for the tests of long compose sequences and +multiple compose output characters. + +IBUS_COMPOSE_CACHE_DIR variable is added for the temporary caches. +--- + src/ibuscomposetable.c | 15 ++-- + src/tests/Makefile.am | 2 +- + src/tests/ibus-compose.c | 10 +++ + src/tests/ibus-compose.emoji | 11 +++ + src/tests/ibus-compose.env | 1 + + src/tests/runtest | 4 +- + 9 files changed, 174 insertions(+), 47 deletions(-) + create mode 100644 src/tests/ibus-compose.emoji + +diff --git a/src/ibuscomposetable.c b/src/ibuscomposetable.c +index 4ac54e25..5fd37f10 100644 +--- a/src/ibuscomposetable.c ++++ b/src/ibuscomposetable.c +@@ -497,13 +497,18 @@ static gchar * + ibus_compose_hash_get_cache_path (guint32 hash) + { + gchar *basename = NULL; ++ const gchar *cache_dir; + gchar *dir = NULL; + gchar *path = NULL; + + basename = g_strdup_printf ("%08x.cache", hash); + +- dir = g_build_filename (g_get_user_cache_dir (), +- "ibus", "compose", NULL); ++ if ((cache_dir = g_getenv ("IBUS_COMPOSE_CACHE_DIR"))) { ++ dir = g_strdup (cache_dir); ++ } else { ++ dir = g_build_filename (g_get_user_cache_dir (), ++ "ibus", "compose", NULL); ++ } + path = g_build_filename (dir, basename, NULL); + if (g_mkdir_with_parents (dir, 0755) != 0) { + g_warning ("Failed to mkdir %s", dir); +@@ -1068,7 +1073,7 @@ ibus_compose_table_list_add_array (GSList *compose_tables, + for (i = 0; i < length; i++) + ibus_compose_seqs[i] = data[i]; + +- compose_table = g_new (IBusComposeTable, 1); ++ compose_table = g_new0 (IBusComposeTable, 1); + compose_table->data = ibus_compose_seqs; + compose_table->max_seq_len = max_seq_len; + compose_table->n_seqs = n_seqs; +diff --git a/src/tests/Makefile.am b/src/tests/Makefile.am +index e2ff5ea7..a58504a3 100644 +--- a/src/tests/Makefile.am ++++ b/src/tests/Makefile.am +@@ -78,7 +78,7 @@ TESTS_ENVIRONMENT = \ + + LOG_COMPILER = $(srcdir)/runtest + +-EXTRA_DIST = runtest ibus-compose.env ++EXTRA_DIST = runtest ibus-compose.emoji ibus-compose.env + + ibus_bus_SOURCES = ibus-bus.c + ibus_bus_LDADD = $(prog_ldadd) +diff --git a/src/tests/ibus-compose.c b/src/tests/ibus-compose.c +index e2ff5ea7..a58504a3 100644 +--- a/src/tests/ibus-compose.c ++++ b/src/tests/ibus-compose.c +@@ -7,8 +7,10 @@ + #define NC "\033[0m" + + IBusBus *m_bus; ++gchar *m_compose_file; + IBusComposeTable *m_compose_table; + IBusEngine *m_engine; ++gchar *m_srcdir; + int m_retval; + + static gboolean window_focus_in_event_cb (GtkWidget *entry, +@@ -31,8 +33,11 @@ create_engine_cb (IBusFactory *factory, + engine_path, + ibus_bus_get_connection (m_bus)); + g_free (engine_path); +- langs = g_get_language_names (); +- for (l = langs; *l; l++) { ++ if (m_compose_file) { ++ compose_path = g_build_filename (m_srcdir, m_compose_file, NULL); ++ } else { ++ langs = g_get_language_names (); ++ for (l = langs; *l; l++) { + if (g_str_has_prefix (*l, "en_US")) + break; + if (g_strcmp0 (*l, "C") == 0) +@@ -41,10 +46,11 @@ create_engine_cb (IBusFactory *factory, + *l, + "Compose", + NULL); + if (g_file_test (compose_path, G_FILE_TEST_EXISTS)) + break; + g_free (compose_path); + compose_path = NULL; ++ } + } + if (compose_path != NULL) { + m_compose_table = ibus_compose_table_new_with_file (compose_path); +@@ -248,6 +254,9 @@ main (int argc, char *argv[]) + ibus_init (); + gtk_init (&argc, &argv); + ++ m_srcdir = argc > 1 ? g_strdup (argv[1]) : g_strdup ("."); ++ m_compose_file = g_strdup (g_getenv ("COMPOSE_FILE")); ++ + if (!register_ibus_engine ()) + return -1; + +diff --git a/src/tests/ibus-compose.emoji b/src/tests/ibus-compose.emoji +new file mode 100644 +index 00000000..7fbf82cf +--- /dev/null ++++ b/src/tests/ibus-compose.emoji +@@ -0,0 +1,2 @@ ++ : "♌" U264C # LEO ++ : "∫" +diff --git a/src/tests/ibus-compose.env b/src/tests/ibus-compose.env +index 734ab8fa..a9e289e4 100644 +--- a/src/tests/ibus-compose.env ++++ b/src/tests/ibus-compose.env +@@ -1,3 +1,4 @@ + LANG=el_GR.UTF-8 + LANG=fi_FI.UTF-8 + LANG=pt_BR.UTF-8 ++LANG=en_US.UTF-8 COMPOSE_FILE=ibus-compose.emoji +diff --git a/src/tests/runtest b/src/tests/runtest +index 4e980c71..35ccc5a0 100755 +--- a/src/tests/runtest ++++ b/src/tests/runtest +@@ -184,7 +184,9 @@ run_test_case() + export GTK_IM_MODULE=ibus + fi + +- "../$tst" ${1+"$@"} ++ export IBUS_COMPOSE_CACHE_DIR=$PWD ++ ++ "../$tst" ../$top_srcdir/src/tests ${1+"$@"} + + retval=`expr $retval \| $?` + +-- +2.21.0 + +From 76dec798d5cf6cdaa96c3373f9c0e1cd13eb31f5 Mon Sep 17 00:00:00 2001 +From: fujiwarat +Date: Fri, 28 Jun 2019 21:28:32 +0900 +Subject: [PATCH] src/tests: Use GTest for ibus-compose + +--- + src/tests/ibus-compose.c | 45 ++++++++++++++++++++++++++++------------ + 1 file changed, 32 insertions(+), 13 deletions(-) + +diff --git a/src/tests/ibus-compose.c b/src/tests/ibus-compose.c +index e1911b32..09c687c2 100644 +--- a/src/tests/ibus-compose.c ++++ b/src/tests/ibus-compose.c +@@ -11,7 +11,6 @@ gchar *m_compose_file; + IBusComposeTable *m_compose_table; + IBusEngine *m_engine; + gchar *m_srcdir; +-int m_retval; + + static gboolean window_focus_in_event_cb (GtkWidget *entry, + GdkEventFocus *event, +@@ -111,8 +110,7 @@ register_ibus_engine () + static gboolean + finit (gpointer data) + { +- m_retval = -1; +- g_warning ("time out"); ++ g_test_incomplete ("time out"); + gtk_main_quit (); + return FALSE; + } +@@ -127,7 +125,9 @@ set_engine_cb (GObject *object, GAsyncRe + int index_stride; + + if (!ibus_bus_set_global_engine_async_finish (bus, res, &error)) { +- g_warning ("set engine failed: %s", error->message); ++ gchar *msg = g_strdup_printf ("set engine failed: %s", error->message); ++ g_test_incomplete (msg); ++ g_free (msg); + g_error_free (error); + return; + } +@@ -210,7 +210,7 @@ window_inserted_text_cb (GtkEntryBuffer + test = GREEN "PASS" NC; + } else { + test = RED "FAIL" NC; +- m_retval = -1; ++ g_test_fail (); + } + g_print ("%05d/%05d %s expected: %04X typed: %04X\n", + seq, +@@ -249,20 +249,39 @@ create_window () + gtk_widget_show_all (window); + } + ++static void ++test_compose (void) ++{ ++ if (!register_ibus_engine ()) { ++ g_test_fail (); ++ return; ++ } ++ ++ create_window (); ++ gtk_main (); ++ ++} ++ + int + main (int argc, char *argv[]) + { ++ const gchar *test_name; ++ gchar *test_path; ++ + ibus_init (); ++ g_test_init (&argc, &argv, NULL); + gtk_init (&argc, &argv); + + m_srcdir = argc > 1 ? 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_get_language_names_with_category ("LC_CTYPE")[0]; ++#else ++ test_name = g_getenv ("LANG"); ++#endif ++ test_path = g_build_filename ("/ibus-compose", test_name, NULL); ++ g_test_add_func (test_path, test_compose); ++ g_free (test_path); + +- if (!register_ibus_engine ()) +- return -1; +- +- create_window (); +- gtk_main (); +- +- return m_retval; ++ return g_test_run (); + } +-- +2.21.0 + +From af00f4156b5c79c526eab18c49da80affd41ebee Mon Sep 17 00:00:00 2001 +From: fujiwarat +Date: Fri, 12 Jul 2019 21:12:38 +0900 +Subject: [PATCH] src/tests: Install IBus tests into gnome-desktop-testing + +--- + configure.ac | 13 +++++++++++ + src/tests/Makefile.am | 39 ++++++++++++++++++++++++++++++- + src/tests/ibus-compose-locales.in | 23 ++++++++++++++++++ + src/tests/ibus-compose.c | 10 ++++++-- + src/tests/meta.test.in | 4 ++++ + src/tests/runtest | 4 ++-- + 6 files changed, 88 insertions(+), 5 deletions(-) + create mode 100755 src/tests/ibus-compose-locales.in + create mode 100644 src/tests/meta.test.in + +diff --git a/configure.ac b/configure.ac +index b5a87b56..f1df3ac1 100644 +--- a/configure.ac ++++ b/configure.ac +@@ -595,6 +595,18 @@ PKG_CHECK_MODULES(XTEST, + ) + AM_CONDITIONAL([ENABLE_XTEST], [test x"$enable_xtest" = x"yes"]) + ++# --enable-install-tests ++AC_ARG_ENABLE(install-tests, ++ AS_HELP_STRING([--enable-install-tests], ++ [Enable to install tests]), ++ [enable_install_tests=$enableval], ++ [enable_install_tests=no] ++) ++AM_CONDITIONAL([ENABLE_INSTALL_TESTS], [test x"$enable_install_tests" = x"yes"]) ++if test x"$enable_install_tests" = x"no"; then ++ enable_install_tests="no (disabled, use --enable-install-tests to enable)" ++fi ++ + + # --disable-emoji-dict option. + AC_ARG_ENABLE(emoji-dict, +@@ -773,5 +785,6 @@ Build options: + Enable Unicode dict $enable_unicode_dict + UCD directory $UCD_DIR + Run test cases $enable_tests ++ Install tests $enable_install_tests + ]) + +diff --git a/src/tests/Makefile.am b/src/tests/Makefile.am +index a58504a3..ff31111b 100644 +--- a/src/tests/Makefile.am ++++ b/src/tests/Makefile.am +@@ -78,7 +78,44 @@ TESTS_ENVIRONMENT = \ + + LOG_COMPILER = $(srcdir)/runtest + +-EXTRA_DIST = runtest ibus-compose.emoji ibus-compose.env ++if ENABLE_INSTALL_TESTS ++test_metas_in = meta.test.in ++test_execs = $(TESTS:ibus-compose=ibus-compose-locales) ++test_metas = $(addsuffix .test, $(test_execs)) ++test_sources_DATA = \ ++ $(test_metas) \ ++ ibus-compose.emoji \ ++ ibus-compose.env \ ++ $(NULL) ++test_sourcesdir = $(datadir)/installed-tests/ibus ++ ++test_execs_PROGRAMS = $(TESTS) ++if ENABLE_GTK3 ++test_execs_SCRIPTS = ibus-compose-locales ++endif ++test_execsdir = $(libexecdir)/installed-tests/ibus ++endif ++ ++$(test_metas): $(test_metas_in) $(test_programs) ++ f=`echo $@ | sed -e 's/\.test//'`; \ ++ TEST_EXEC=$(test_execsdir)/$$f; \ ++ sed -e "s|@TEST_EXEC[@]|$$TEST_EXEC|g" $(test_metas_in) > $@.tmp; \ ++ mv $@.tmp $@; \ ++ $(NULL) ++ ++ibus-compose-locales: ibus-compose-locales.in ++ SRCDIR=$(test_sourcesdir); \ ++ sed -e "s|@SRCDIR[@]|$$SRCDIR|g" $< > $@.tmp; \ ++ mv $@.tmp $@; \ ++ $(NULL) ++ ++EXTRA_DIST = \ ++ $(test_metas_in) \ ++ runtest \ ++ ibus-compose.emoji \ ++ ibus-compose.env \ ++ ibus-compose-locales.in \ ++ $(NULL) + + ibus_bus_SOURCES = ibus-bus.c + ibus_bus_LDADD = $(prog_ldadd) +diff --git a/src/tests/ibus-compose-locales.in b/src/tests/ibus-compose-locales.in +new file mode 100755 +index 00000000..8d2384d1 +--- /dev/null ++++ b/src/tests/ibus-compose-locales.in +@@ -0,0 +1,23 @@ ++#!/bin/sh ++ ++SRCDIR=@SRCDIR@ ++BUILDDIR=`dirname $0` ++ ++ ++export IBUS_COMPOSE_CACHE_DIR=$PWD ++ ++for var in `cat $SRCDIR/ibus-compose.env` ++do ++ IS_COMMENT=`echo "$var" | grep "^#"` ++ if [ "x$IS_COMMENT" != x ] ; then ++ continue ++ fi ++ env $var $BUILDDIR/ibus-compose $SRCDIR $@ ++ ++ CACHE_FILES=`ls *.cache` ++ if [ x"$CACHE_FILES" != x ] ; then ++ echo "Clean $CACHE_FILES" ++ rm $CACHE_FILES ++ fi ++done ++ +diff --git a/src/tests/ibus-compose.c b/src/tests/ibus-compose.c +index 09c687c2..c8d3c126 100644 +--- a/src/tests/ibus-compose.c ++++ b/src/tests/ibus-compose.c +@@ -351,6 +347,14 @@ main (int argc, char *argv[]) + + ibus_init (); + g_test_init (&argc, &argv, NULL); ++ /* FIXME: ++ * IBusIMContext opens GtkIMContextSimple as the slave and ++ * GtkIMContextSimple opens the compose table on el_GR.UTF-8, and the ++ * multiple outputs in el_GR's compose causes a warning in gtkcomposetable ++ * and the warning always causes a fatal in GTest: ++ " "GTK+ supports to output one char only: " ++ */ ++ g_log_set_always_fatal (G_LOG_LEVEL_CRITICAL); + gtk_init (&argc, &argv); + + m_srcdir = argc > 1 ? g_strdup (argv[1]) : g_strdup ("."); +diff --git a/src/tests/meta.test.in b/src/tests/meta.test.in +new file mode 100644 +index 00000000..ae2b2991 +--- /dev/null ++++ b/src/tests/meta.test.in +@@ -0,0 +1,4 @@ ++[Test] ++Type=session ++Exec=@TEST_EXEC@ --tap ++Output=TAP +diff --git a/src/tests/runtest b/src/tests/runtest +index 35ccc5a0..1fcc9283 100755 +--- a/src/tests/runtest ++++ b/src/tests/runtest +@@ -200,7 +200,7 @@ if test -f $envfile ; then + ENVS="`cat $envfile`" + fi; + if test x"$ENVS" = x ; then +- run_test_case ++ run_test_case $@ + else + LANG_backup=$LANG + i=1 +@@ -212,7 +212,7 @@ else + export $e + echo "Run `func_basename $tst` on $e" + echo "=======================" +- run_test_case ++ run_test_case $@ + echo "" + i=`expr $i + 1` + done +-- +2.21.0 + +From 2a4f9518d42b618d8111fa5f9f885757524758a0 Mon Sep 17 00:00:00 2001 +From: fujiwarat +Date: Fri, 12 Jul 2019 21:12:40 +0900 +Subject: [PATCH] src/tests: Rename test-console.sh to + ibus-desktop-testing-runner + +--- + src/tests/Makefile.am | 9 +++++++++ + .../tests/ibus-desktop-testing-runner.in | 0 + 2 files changed, 9 insertions(+) + rename test/test-console.sh => src/tests/ibus-desktop-testing-runner.in (100%) + +diff --git a/src/tests/Makefile.am b/src/tests/Makefile.am +index ff31111b..b9aad29a 100644 +--- a/src/tests/Makefile.am ++++ b/src/tests/Makefile.am +@@ -79,6 +79,7 @@ TESTS_ENVIRONMENT = \ + LOG_COMPILER = $(srcdir)/runtest + + if ENABLE_INSTALL_TESTS ++bin_SCRIPTS = ibus-desktop-testing-runner + test_metas_in = meta.test.in + test_execs = $(TESTS:ibus-compose=ibus-compose-locales) + test_metas = $(addsuffix .test, $(test_execs)) +@@ -109,12 +110,20 @@ ibus-compose-locales: ibus-compose-locales.in + mv $@.tmp $@; \ + $(NULL) + ++ ibus-desktop-testing-runner.in \ ++ibus-desktop-testing-runner: ibus-desktop-testing-runner.in ++ SRCDIR=$(test_sourcesdir); \ ++ sed -e "s|@SRCDIR[@]|$$SRCDIR|g" $< > $@.tmp; \ ++ mv $@.tmp $@; \ ++ $(NULL) ++ + EXTRA_DIST = \ + $(test_metas_in) \ + runtest \ + ibus-compose.emoji \ + ibus-compose.env \ + ibus-compose-locales.in \ ++ ibus-desktop-testing-runner.in \ + $(NULL) + + ibus_bus_SOURCES = ibus-bus.c +diff --git a/src/tests/ibus-desktop-testing-runner.in b/src/tests/ibus-desktop-testing-runner.in +new file mode 100755 +index 00000000..7fbf82cf +--- /dev/null ++++ b/src/tests/ibus-desktop-testing-runner.in +@@ -0,0 +1,255 @@ ++#!/bin/sh ++# -*- mode: C; c-basic-offset: 4; indent-tabs-mode: nil; -*- ++# vim:set noet ts=4: ++# ++# ibus-anthy - The Anthy engine for IBus ++# ++# Copyright (c) 2018-2019 Takao Fujiwara ++# 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. ++ ++# 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 ++ ++PROGNAME=`basename $0` ++VERSION=0.1 ++DISPLAY=:99.0 ++BUILDDIR="." ++SRCDIR="." ++TEST_LOG=test-suite.log ++HAVE_GRAPHICS=1 ++DESKTOP_COMMAND="gnome-session" ++PID_XORG=0 ++PID_GNOME_SESSION=0 ++TESTS="" ++GREEN='\033[0;32m' ++RED='\033[0;31m' ++NC='\033[0m' ++ ++usage() ++{ ++ echo -e \ ++"This test runs /usr/bin/ibus-daemon after install ibus\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" \ ++"-c, --no-graphics Use Xvfb instead of Xorg\n" \ ++"-d, --desktop=DESKTOP Run DESTKTOP. The default is gnome-session\n" \ ++"-t, --tests=\"TESTS...\" Run TESTS programs which is separated by space\n" \ ++"" ++} ++ ++parse_args() ++{ ++ # This is GNU getopt. "sudo port getopt" in BSD? ++ ARGS=`getopt -o hvb:s:cd:t: --long help,version,builddir:,srcdir:,no-graphics,desktop:,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;; ++ -d | --desktop ) DESKTOP_COMMAND="$2"; shift 2;; ++ -t | --tests ) TESTS="$2"; shift 2;; ++ -- ) shift; break;; ++ * ) usage; exit 1;; ++ esac ++ done ++} ++ ++init_desktop() ++{ ++ if test x$FORCE_TEST != x ; then ++ RUN_ARGS="$RUN_ARGS --force" ++ fi ++ ++ if test ! -f $HOME/.config/gnome-initial-setup-done ; then ++ 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=false ++_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 test -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 ++} ++ ++run_dbus_daemon() ++{ ++ a=`ps -ef | grep dbus-daemon | grep "\-\-system" | grep -v session | grep -v grep` ++ if test x"$a" = x ; then ++ eval `dbus-launch --sh-syntax` ++ fi ++ SUSER=`echo "$USER" | cut -c 1-7` ++ a=`ps -ef | grep dbus-daemon | grep "$SUSER" | grep -v gdm | grep session | grep -v grep` ++ if test x"$a" = x ; then ++ systemctl --user start dbus ++ export DBUS_SESSION_BUS_ADDRESS=unix:path=/run/user/$UID/bus ++ fi ++ systemctl --user status dbus | col -b ++ ps -ef | grep dbus-daemon | grep "$SUSER" | grep -v gdm | egrep 'session|system' | grep -v grep ++ systemctl --user show-environment | col -b ++} ++ ++run_desktop() ++{ ++ 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 ++ export DISPLAY=$DISPLAY ++ $DESKTOP_COMMAND & ++ PID_GNOME_SESSION=$! ++ sleep 30 ++ if test "$DESKTOP_COMMAND" != "gnome-session" ; then ++ ibus-daemon --daemonize --verbose ++ sleep 1 ++ 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 ++ log=$3 ++ subtst=${4:-''} ++ ++ if test $retval -eq 0 ; then ++ echo -e "${GREEN}PASS${NC}: $tst $subtst" ++ else ++ echo -e "${RED}FAIL${NC}: $tst $subtst" ++ echo "FAIL: $tst $subtst" >> $TEST_LOG ++ echo "======================" >> $TEST_LOG ++ echo "" >> $TEST_LOG ++ cat "$log" >> $TEST_LOG ++ echo "" >> $TEST_LOG ++ fi ++} ++ ++run_test_suite() ++{ ++ cd `dirname $0` ++ pass=0 ++ fail=0 ++ ++ export GTK_IM_MODULE=ibus ++ export IBUS_COMPOSE_CACHE_DIR=$PWD ++ if test -f $TEST_LOG ; then ++ rm $TEST_LOG ++ fi ++ 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 >&${tst}.log ++ retval=$? ++ read pass fail << EOF ++ `count_case_result $retval $pass $fail` ++EOF ++ echo_case_result $retval $tst ${tst}.log ++ else ++ LANG_backup=$LANG ++ i=1 ++ for e in $ENVS; do ++ first=`echo "$e" | cut -c1-1` ++ if test x"$first" = x"#" ; then ++ continue ++ fi ++ export $e ++ $BUILDDIR/$tst $SRCDIR >&${tst}.${i}.log ++ retval=$? ++ read pass fail << EOF ++ `count_case_result $retval $pass $fail` ++EOF ++ echo_case_result $retval $tst ${tst}.${i}.log $e ++ i=`expr $i + 1` ++ done ++ export LANG=$LANG_backup ++ fi ++ done ++ echo "" ++ echo -e "# ${GREEN}PASS${NC}: $pass" ++ echo -e "# ${RED}FAIL${NC}: $fail" ++ if test -f ${TEST_LOG} ; then ++ echo "" ++ echo -e "${RED}See ${TEST_LOG}$NC" ++ fi ++} ++ ++finit() ++{ ++ if test "$DESKTOP_COMMAND" != "gnome-session" ; then ++ ibus exit ++ fi ++ kill $PID_GNOME_SESSION $PID_XORG ++} ++ ++main() ++{ ++ parse_args $@ ++ init_desktop ++ run_dbus_daemon ++ run_desktop ++ run_test_suite ++ finit ++} ++ ++main $@ +-- +2.21.0 + +From fa081ac8ea37d2feb7c7f395ad66e7381b4cb65b Mon Sep 17 00:00:00 2001 +From: fujiwarat +Date: Fri, 12 Jul 2019 21:20:32 +0900 +Subject: [PATCH] src/tests: Use gnome-desktop-testing-runner + +--- + src/tests/Makefile.am | 4 +- + src/tests/ibus-desktop-testing-runner.in | 154 ++++++++++++++++++----- + 2 files changed, 123 insertions(+), 35 deletions(-) + +diff --git a/src/tests/Makefile.am b/src/tests/Makefile.am +index b9aad29a..913e42fb 100644 +--- a/src/tests/Makefile.am ++++ b/src/tests/Makefile.am +@@ -105,8 +105,8 @@ $(test_metas): $(test_metas_in) $(test_programs) + $(NULL) + + ibus-compose-locales: ibus-compose-locales.in +- SRCDIR=$(test_sourcesdir); \ +- sed -e "s|@SRCDIR[@]|$$SRCDIR|g" $< > $@.tmp; \ ++ INSTALLEDDIR=$(datadir)/installed-tests; \ ++ sed -e "s|@INSTALLEDDIR[@]|$$INSTALLEDDIR|g" $< > $@.tmp; \ + mv $@.tmp $@; \ + $(NULL) + +diff --git a/src/tests/ibus-desktop-testing-runner.in b/src/tests/ibus-desktop-testing-runner.in +index 9e689634..a90c1378 100755 +--- a/src/tests/ibus-desktop-testing-runner.in ++++ b/src/tests/ibus-desktop-testing-runner.in +@@ -2,7 +2,7 @@ + # -*- mode: C; c-basic-offset: 4; indent-tabs-mode: nil; -*- + # vim:set noet ts=4: + # +-# ibus-anthy - The Anthy engine for IBus ++# ibus - The Input Bus + # + # Copyright (c) 2018-2019 Takao Fujiwara + # Copyright (c) 2018 Red Hat, Inc. +@@ -33,16 +33,32 @@ VERSION=0.1 + DISPLAY=:99.0 + BUILDDIR="." + SRCDIR="." +-TEST_LOG=test-suite.log ++TEST_LOG="test-suite.log" ++RESULT_LOG="" + HAVE_GRAPHICS=1 + DESKTOP_COMMAND="gnome-session" + PID_XORG=0 + PID_GNOME_SESSION=0 ++TESTING_RUNNER="default" + TESTS="" + 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 ++} ++ + usage() + { + echo -e \ +@@ -57,13 +73,19 @@ usage() + "-c, --no-graphics Use Xvfb instead of Xorg\n" \ + "-d, --desktop=DESKTOP Run DESTKTOP. The default is gnome-session\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" \ ++"-o, --output=OUTPUT_FILE OUtput the log to OUTPUT_FILE\n" \ ++"-O, --result=RESULT_FILE OUtput the result to RESULT_FILE\n" \ + "" + } + + parse_args() + { + # This is GNU getopt. "sudo port getopt" in BSD? +- ARGS=`getopt -o hvb:s:cd:t: --long help,version,builddir:,srcdir:,no-graphics,desktop:,tests:\ ++ ARGS=`getopt -o hvb:s:cd:t:r:o:O: --long \ ++ help,version,builddir:,srcdir:,no-graphics,desktop:,tests:,runner:,output:,result:\ + -- "$@"`; + eval set -- "$ARGS" + while [ 1 ] ; do +@@ -75,6 +97,9 @@ parse_args() + -c | --no-graphics ) HAVE_GRAPHICS=0; shift;; + -d | --desktop ) DESKTOP_COMMAND="$2"; shift 2;; + -t | --tests ) TESTS="$2"; shift 2;; ++ -r | --runner ) TESTING_RUNNER="$2"; shift 2;; ++ -o | --output ) TEST_LOG="$2"; shift 2;; ++ -O | --result ) RESULT_LOG="$2"; shift 2;; + -- ) shift; break;; + * ) usage; exit 1;; + esac +@@ -83,18 +108,31 @@ parse_args() + + init_desktop() + { ++ if [ "$RESULT_LOG" != "" ] ; then ++ rm $RESULT_LOG ++ 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" ++ abrt ++ else ++ rm $TEST_LOG ++ fi + if test x$FORCE_TEST != x ; then + RUN_ARGS="$RUN_ARGS --force" + fi + + if test ! -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=false ++SystemAccount=$IS_SYSTEM_ACCOUNT + _EOF + fi + mkdir -p $HOME/.config +@@ -167,71 +205,120 @@ echo_case_result() + { + retval=$1 + tst=$2 +- log=$3 +- subtst=${4:-''} ++ subtst=${3:-''} + + if test $retval -eq 0 ; then +- echo -e "${GREEN}PASS${NC}: $tst $subtst" ++ print_log -e "${GREEN}PASS${NC}: $tst $subtst" + else +- echo -e "${RED}FAIL${NC}: $tst $subtst" +- echo "FAIL: $tst $subtst" >> $TEST_LOG +- echo "======================" >> $TEST_LOG +- echo "" >> $TEST_LOG +- cat "$log" >> $TEST_LOG +- echo "" >> $TEST_LOG ++ print_log -e "${RED}FAIL${NC}: $tst $subtst" ++ print_log "======================" ++ print_log "" + fi + } + +-run_test_suite() ++run_direct_test_cases() + { +- cd `dirname $0` + pass=0 + fail=0 +- +- export GTK_IM_MODULE=ibus +- export IBUS_COMPOSE_CACHE_DIR=$PWD +- if test -f $TEST_LOG ; then +- rm $TEST_LOG +- fi + 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 >&${tst}.log ++ $BUILDDIR/$tst $SRCDIR 2>>$TEST_LOG 1>>$TEST_LOG + retval=$? + read pass fail << EOF + `count_case_result $retval $pass $fail` + EOF +- echo_case_result $retval $tst ${tst}.log ++ echo_case_result $retval $tst ++ CACHE_FILES=`ls *.cache` ++ if [ x"$CACHE_FILES" != x ] ; then ++ print_log "Clean $CACHE_FILES" ++ rm $CACHE_FILES ++ fi + else + LANG_backup=$LANG + i=1 + for e in $ENVS; do +- first=`echo "$e" | cut -c1-1` ++ first=`echo "$e" | grep '^#'` + if test x"$first" = x"#" ; then + continue + fi + export $e +- $BUILDDIR/$tst $SRCDIR >&${tst}.${i}.log ++ $BUILDDIR/$tst $SRCDIR 2>>$TEST_LOG 1>>$TEST_LOG + retval=$? + read pass fail << EOF + `count_case_result $retval $pass $fail` + EOF +- echo_case_result $retval $tst ${tst}.${i}.log $e ++ echo_case_result $retval $tst $e ++ CACHE_FILES=`ls *.cache` ++ if [ x"$CACHE_FILES" != x ] ; then ++ print_log "Clean $CACHE_FILES" ++ rm $CACHE_FILES ++ fi + i=`expr $i + 1` + done + export LANG=$LANG_backup + 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 $tst 2>>$TEST_LOG 1>>$TEST_LOG ++ retval=$? ++ read pass fail << EOF ++ `count_case_result $retval $pass $fail` ++EOF ++ done ++ 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 "" +- echo -e "# ${GREEN}PASS${NC}: $pass" +- echo -e "# ${RED}FAIL${NC}: $fail" +- if test -f ${TEST_LOG} ; then +- echo "" +- echo -e "${RED}See ${TEST_LOG}$NC" ++ 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 "" ++ echo "See ${TEST_LOG}" + } + + finit() +@@ -240,14 +327,15 @@ finit() + ibus exit + fi + kill $PID_GNOME_SESSION $PID_XORG ++ echo "Finished $PROGNAME testing" + } + + main() + { + parse_args $@ + init_desktop +- run_dbus_daemon +- run_desktop ++ run_dbus_daemon 2>>$TEST_LOG 1>>$TEST_LOG ++ run_desktop 2>>$TEST_LOG 1>>$TEST_LOG + run_test_suite + finit + } +-- +2.21.0 + +From 85b647a1c57c206779eb0b4b15a734c1b1f29c10 Mon Sep 17 00:00:00 2001 +From: fujiwarat +Date: Wed, 24 Jul 2019 17:27:37 +0900 +Subject: [PATCH] src/tests: Fix IBus test cases for gnome-desktop-testing + +- dconf/config.c: Replaced dconf_client_write_fast() with + dconf_client_write_sync() because + dconf_client_write_fast() does not syn the data when + ibus_config_get_values() is called immediately after + ibus_config_set_value() is called. + +- ibus-compose-locales.in returns the return value of ibus-compose + +- ibus-compose: Set $NO_AT_BRIDGE to suppress a AT_SPI warning + and call g_log_set_always_fatal() because GtkIMContextSimple + does not support multiple compose outputs yet and the API can + suppress a warning. + +- ibus-config: Delete async watch testings which causes several errors + with gnome-shell testing and the testing is now deprecated and + GSettings is recommended. + +- ibus-desktop-testing-runner.in: Support --output=log:stdout to + cat the log to stdout and Use dbus-launch --exit-with-session instead of + --sh-syntax and count PASS of test cases instead of PASS of + gnome-desktop-testing and always run ibus exit and kill + gnome-shell-calendar-server + +- ibus-engine-switch.c: Set xkb:jp::jpn if gnome-shell sets xkb:us::eng + +- ibus-inputcontext.c: Use ibus_bus_get_global_engine() instead of + ibus_bus_list_active_engines() since ibus_bus_list_active_engines() + does not work with gnome-shell and the API is now deprecated. + +- ibus-keypress.c: Set $NO_AT_BRIDGE to suppress a AT_SPI warning +--- + conf/dconf/config.c | 14 +- + src/tests/Makefile.am | 19 +- + src/tests/ibus-compose-locales.in | 4 +- + src/tests/ibus-compose.c | 10 +- + src/tests/ibus-config.c | 283 ----------------------- + src/tests/ibus-desktop-testing-runner.in | 77 +++--- + src/tests/ibus-engine-switch.c | 34 ++- + src/tests/ibus-inputcontext.c | 29 +-- + src/tests/ibus-keypress.c | 4 + + 9 files changed, 126 insertions(+), 348 deletions(-) + +diff --git a/conf/dconf/config.c b/conf/dconf/config.c +index 500ea1d8..30ac137d 100644 +--- a/conf/dconf/config.c ++++ b/conf/dconf/config.c +@@ -335,7 +335,19 @@ ibus_config_dconf_set_value (IBusConfigService *config, + } + + #ifdef DCONF_0_13_4 +- retval = dconf_client_write_fast (client, gkey, value, error); ++ /* Use dconf_client_write_sync() instead of dconf_client_write_fast() ++ * because dconf_client_write_fast() does not sync the data when ++ * ibus_config_get_values() is called immediately after ++ * ibus_config_set_value() is called. ++ * We won't add a new API for the sync only since IBusConfig is ++ * now deprecated and GSettings is recommended. ++ */ ++ retval = dconf_client_write_sync (client, ++ gkey, ++ value, ++ NULL, ++ NULL, ++ error); + #else + retval = dconf_client_write (client, + gkey, +diff --git a/src/tests/Makefile.am b/src/tests/Makefile.am +index 913e42fb..2e75932c 100644 +--- a/src/tests/Makefile.am ++++ b/src/tests/Makefile.am +@@ -55,6 +55,8 @@ TESTS = \ + ibus-util \ + $(NULL) + ++CLEANFILES = ++ + if ENABLE_ENGINE + TESTS += ibus-engine-switch + endif +@@ -90,9 +92,17 @@ test_sources_DATA = \ + $(NULL) + test_sourcesdir = $(datadir)/installed-tests/ibus + ++CLEANFILES += \ ++ $(test_metas) \ ++ ibus-desktop-testing-runner \ ++ $(NULL) ++ + test_execs_PROGRAMS = $(TESTS) + if ENABLE_GTK3 + test_execs_SCRIPTS = ibus-compose-locales ++CLEANFILES += \ ++ ibus-compose-locales \ ++ $(NULL) + endif + test_execsdir = $(libexecdir)/installed-tests/ibus + endif +@@ -105,15 +115,14 @@ $(test_metas): $(test_metas_in) $(test_programs) + $(NULL) + + ibus-compose-locales: ibus-compose-locales.in +- INSTALLEDDIR=$(datadir)/installed-tests; \ +- sed -e "s|@INSTALLEDDIR[@]|$$INSTALLEDDIR|g" $< > $@.tmp; \ ++ SRCDIR=$(test_sourcesdir); \ ++ sed -e "s|@SRCDIR[@]|$$SRCDIR|g" $< > $@.tmp; \ + mv $@.tmp $@; \ + $(NULL) + +- ibus-desktop-testing-runner.in \ + ibus-desktop-testing-runner: ibus-desktop-testing-runner.in +- SRCDIR=$(test_sourcesdir); \ +- sed -e "s|@SRCDIR[@]|$$SRCDIR|g" $< > $@.tmp; \ ++ INSTALLEDDIR=$(datadir)/installed-tests; \ ++ sed -e "s|@INSTALLEDDIR[@]|$$INSTALLEDDIR|g" $< > $@.tmp; \ + mv $@.tmp $@; \ + $(NULL) + +diff --git a/src/tests/ibus-compose-locales.in b/src/tests/ibus-compose-locales.in +index 8d2384d1..fad02965 100755 +--- a/src/tests/ibus-compose-locales.in ++++ b/src/tests/ibus-compose-locales.in +@@ -6,6 +6,7 @@ BUILDDIR=`dirname $0` + + export IBUS_COMPOSE_CACHE_DIR=$PWD + ++retval=0 + for var in `cat $SRCDIR/ibus-compose.env` + do + IS_COMMENT=`echo "$var" | grep "^#"` +@@ -13,6 +14,7 @@ do + continue + fi + env $var $BUILDDIR/ibus-compose $SRCDIR $@ ++ retval=`expr $retval + $?` + + CACHE_FILES=`ls *.cache` + if [ x"$CACHE_FILES" != x ] ; then +@@ -20,4 +22,4 @@ do + rm $CACHE_FILES + fi + done +- ++exit $retval +diff --git a/src/tests/ibus-compose.c b/src/tests/ibus-compose.c +index c8d3c126..db359477 100644 +--- a/src/tests/ibus-compose.c ++++ b/src/tests/ibus-compose.c +@@ -344,20 +344,26 @@ test_compose (void) + int + main (int argc, char *argv[]) + { ++ GLogLevelFlags flags; + const gchar *test_name; + gchar *test_path; + + ibus_init (); ++ /* Avoid a warning of "AT-SPI: Could not obtain desktop path or name" ++ * with gtk_main(). ++ */ ++ g_setenv ("NO_AT_BRIDGE", "1", TRUE); + g_test_init (&argc, &argv, NULL); + /* FIXME: + * IBusIMContext opens GtkIMContextSimple as the slave and + * GtkIMContextSimple opens the compose table on el_GR.UTF-8, and the +- * multiple outputs in el_GR's compose causes a warning in gtkcomposetable ++ * multiple outputs in el_GR's compose causes a warning in gtkcomposetable + * and the warning always causes a fatal in GTest: + " "GTK+ supports to output one char only: " + */ +- g_log_set_always_fatal (G_LOG_LEVEL_CRITICAL); ++ flags = g_log_set_always_fatal (G_LOG_LEVEL_CRITICAL); + gtk_init (&argc, &argv); ++ g_log_set_always_fatal (flags); + + m_srcdir = argc > 1 ? g_strdup (argv[1]) : g_strdup ("."); + m_compose_file = g_strdup (g_getenv ("COMPOSE_FILE")); +diff --git a/src/tests/ibus-config.c b/src/tests/ibus-config.c +index c6141ab5..9b925ad9 100644 +--- a/src/tests/ibus-config.c ++++ b/src/tests/ibus-config.c +@@ -133,254 +133,6 @@ test_config_set_get (void) + g_object_unref (config); + } + +-typedef struct { +- GMainLoop *loop; +- guint timeout_id; +- gchar *section; +- gchar *name; +-} WatchData; +- +-typedef struct { +- gchar *section; +- gchar *name; +-} WatchKey; +- +-typedef struct { +- WatchKey *watched; /* watched keys (null-terminated) */ +- WatchKey *changed; /* changed keys (null-terminated) */ +- WatchKey *notified; /* notified keys (same length as +- changed, not null-terminated) */ +-} WatchTestData; +- +-static WatchKey default_watched[] = { +- { NULL } +-}; +-static WatchKey default_changed[] = { +- { "test/s1", "n1" }, +- { "test/s1", "n2" }, +- { "test/s2", "n1" }, +- { "test/s2", "n2" }, +- { NULL } +-}; +-static WatchKey default_notified[] = { +- { "test/s1", "n1" }, +- { "test/s1", "n2" }, +- { "test/s2", "n1" }, +- { "test/s2", "n2" } +-}; +-static WatchTestData default_data = { +- default_watched, +- default_changed, +- default_notified +-}; +- +-static WatchKey section_watched[] = { +- { "test/s1", NULL }, +- { NULL } +-}; +-static WatchKey section_notified[] = { +- { "test/s1", "n1" }, +- { "test/s1", "n2" }, +- { NULL, NULL }, +- { NULL, NULL }, +-}; +-static WatchTestData section_data = { +- section_watched, +- default_changed, +- section_notified +-}; +- +-static WatchKey section_multiple_watched[] = { +- { "test/s1", NULL }, +- { "test/s2", NULL }, +- { NULL } +-}; +-static WatchKey section_multiple_notified[] = { +- { "test/s1", "n1" }, +- { "test/s1", "n2" }, +- { "test/s2", "n1" }, +- { "test/s2", "n2" }, +-}; +-static WatchTestData section_multiple_data = { +- section_multiple_watched, +- default_changed, +- section_multiple_notified +-}; +- +-static WatchKey section_name_watched[] = { +- { "test/s1", "n1" }, +- { NULL } +-}; +-static WatchKey section_name_notified[] = { +- { "test/s1", "n1" }, +- { NULL, NULL }, +- { NULL, NULL }, +- { NULL, NULL }, +-}; +-static WatchTestData section_name_data = { +- section_name_watched, +- default_changed, +- section_name_notified +-}; +- +-static WatchKey section_name_multiple_watched[] = { +- { "test/s1", "n1" }, +- { "test/s2", "n2" }, +- { NULL } +-}; +-static WatchKey section_name_multiple_notified[] = { +- { "test/s1", "n1" }, +- { NULL, NULL }, +- { NULL, NULL }, +- { "test/s2", "n2" }, +-}; +-static WatchTestData section_name_multiple_data = { +- section_name_multiple_watched, +- default_changed, +- section_name_multiple_notified +-}; +- +-typedef struct { +- IBusConfig *config; +- WatchData data; +-} WatchFixture; +- +-static void +-value_changed_cb (IBusConfig *config, +- const gchar *section, +- const gchar *name, +- GVariant *value, +- gpointer user_data) +-{ +- WatchData *data = (WatchData *) user_data; +- +- data->section = g_strdup (section); +- data->name = g_strdup (name); +- +- g_main_loop_quit (data->loop); +-} +- +-static gboolean +-timeout_cb (gpointer user_data) +-{ +- WatchData *data = (WatchData *) user_data; +- g_main_loop_quit (data->loop); +- data->timeout_id = 0; +- return FALSE; +-} +- +-static void +-change_and_test (IBusConfig *config, +- const gchar *section, +- const gchar *name, +- const gchar *expected_section, +- const gchar *expected_name, +- WatchData *data) +-{ +- gboolean retval; +- GVariant *var; +- +- data->section = NULL; +- data->name = NULL; +- +- /* Unset won't notify value-changed signal. */ +- var = ibus_config_get_values (config, section); +- if (var != NULL) { +- GVariant *value = g_variant_lookup_value (var, name, +- G_VARIANT_TYPE_VARIANT); +- if (value != NULL) { +- ibus_config_unset (config, section, name); +- g_variant_unref (value); +- } +- g_variant_unref (var); +- } +- +- data->timeout_id = g_timeout_add (1, timeout_cb, data); +- g_main_loop_run (data->loop); +- if (data->timeout_id != 0) { +- g_source_remove (data->timeout_id); +- } +- +- retval = ibus_config_set_value (config, section, name, +- g_variant_new_int32 (1)); +- g_assert (retval); +- +- data->timeout_id = g_timeout_add (1, timeout_cb, data); +- g_main_loop_run (data->loop); +- if (data->timeout_id != 0) { +- g_source_remove (data->timeout_id); +- } +- +- g_assert_cmpstr (data->section, ==, expected_section); +- g_assert_cmpstr (data->name, ==, expected_name); +- +- g_free (data->section); +- g_free (data->name); +-} +- +-static void +-watch_fixture_setup (WatchFixture *fixture, gconstpointer user_data) +-{ +- fixture->config = ibus_config_new (ibus_bus_get_connection (bus), +- NULL, +- NULL); +- g_assert (fixture->config); +- +- fixture->data.loop = g_main_loop_new (NULL, FALSE); +- g_signal_connect (fixture->config, "value-changed", +- G_CALLBACK (value_changed_cb), &fixture->data); +-} +- +-static void +-watch_fixture_teardown (WatchFixture *fixture, gconstpointer user_data) +-{ +- g_main_loop_unref (fixture->data.loop); +- +- ibus_proxy_destroy (IBUS_PROXY (fixture->config)); +- g_object_unref (fixture->config); +-} +- +-static void +-test_config_watch (WatchFixture *fixture, gconstpointer user_data) +-{ +- const WatchTestData *data = user_data; +- gint i; +- +- for (i = 0; data->watched[i].section != NULL; i++) { +- ibus_config_watch (fixture->config, +- data->watched[i].section, +- data->watched[i].name); +- } +- for (i = 0; data->changed[i].section != NULL; i++) { +- change_and_test (fixture->config, +- data->changed[i].section, +- data->changed[i].name, +- data->notified[i].section, +- data->notified[i].name, +- &fixture->data); +- } +- for (i = 0; data->watched[i].section != NULL; i++) { +- ibus_config_unwatch (fixture->config, +- data->watched[i].section, +- data->watched[i].name); +- } +- if (i > 0) { +- /* Check if the above unwatch takes effect. */ +- for (i = 0; data->changed[i].section != NULL; i++) { +- change_and_test (fixture->config, +- data->changed[i].section, +- data->changed[i].name, +- NULL, +- NULL, +- &fixture->data); +- } +- } else { +- /* Since we reuse single D-Bus connection, we need to remove the +- default match rule for the next ibus_config_new() call. */ +- ibus_config_unwatch (fixture->config, NULL, NULL); +- } +-} +- + gint + main (gint argc, + gchar **argv) +@@ -390,41 +142,6 @@ main (gint argc, + g_test_init (&argc, &argv, NULL); + bus = ibus_bus_new (); + +- g_test_add ("/ibus/config-watch/default", +- WatchFixture, +- &default_data, +- watch_fixture_setup, +- test_config_watch, +- watch_fixture_teardown); +- +- g_test_add ("/ibus/config-watch/section", +- WatchFixture, +- §ion_data, +- watch_fixture_setup, +- test_config_watch, +- watch_fixture_teardown); +- +- g_test_add ("/ibus/config-watch/section-multiple", +- WatchFixture, +- §ion_multiple_data, +- watch_fixture_setup, +- test_config_watch, +- watch_fixture_teardown); +- +- g_test_add ("/ibus/config-watch/section-name", +- WatchFixture, +- §ion_name_data, +- watch_fixture_setup, +- test_config_watch, +- watch_fixture_teardown); +- +- g_test_add ("/ibus/config-watch/section-name-multiple", +- WatchFixture, +- §ion_name_multiple_data, +- watch_fixture_setup, +- test_config_watch, +- watch_fixture_teardown); +- + g_test_add_func ("/ibus/create-config-async", test_create_config_async); + g_test_add_func ("/ibus/config-set-get", test_config_set_get); + +diff --git a/src/tests/ibus-desktop-testing-runner.in b/src/tests/ibus-desktop-testing-runner.in +index a90c1378..b7a72285 100755 +--- a/src/tests/ibus-desktop-testing-runner.in ++++ b/src/tests/ibus-desktop-testing-runner.in +@@ -34,9 +34,10 @@ DISPLAY=:99.0 + BUILDDIR="." + SRCDIR="." + TEST_LOG="test-suite.log" ++TEST_LOG_STDOUT=0 + RESULT_LOG="" + HAVE_GRAPHICS=1 +-DESKTOP_COMMAND="gnome-session" ++DESKTOP_COMMAND="dbus-launch --exit-with-session gnome-session" + PID_XORG=0 + PID_GNOME_SESSION=0 + TESTING_RUNNER="default" +@@ -109,19 +110,26 @@ parse_args() + init_desktop() + { + if [ "$RESULT_LOG" != "" ] ; then +- rm $RESULT_LOG ++ if [ -f $RESULT_LOG ] ; then ++ rm $RESULT_LOG ++ fi ++ fi ++ HAS_STDOUT=`echo "$TEST_LOG" | grep ':stdout'` ++ if [ x"$HAS_STDOUT" != x ] ; 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" +- abrt +- else ++ exit -1 ++ elif [ -f $TEST_LOG ] ; then + rm $TEST_LOG + fi +- if test x$FORCE_TEST != x ; then ++ if [ x$FORCE_TEST != x ] ; then + RUN_ARGS="$RUN_ARGS --force" + fi + +- if test ! -f $HOME/.config/gnome-initial-setup-done ; then ++ if [ ! -f $HOME/.config/gnome-initial-setup-done ] ; then + IS_SYSTEM_ACCOUNT=false + if [ "$USER" = "root" ] ; then + IS_SYSTEM_ACCOUNT=true +@@ -141,7 +149,7 @@ _EOF + + # Prevent from launching a XDG dialog + XDG_LOCALE_FILE="$HOME/.config/user-dirs.locale" +- if test -f $XDG_LOCALE_FILE ; then ++ 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 +@@ -153,19 +161,8 @@ _EOF + + run_dbus_daemon() + { +- a=`ps -ef | grep dbus-daemon | grep "\-\-system" | grep -v session | grep -v grep` +- if test x"$a" = x ; then +- eval `dbus-launch --sh-syntax` +- fi +- SUSER=`echo "$USER" | cut -c 1-7` +- a=`ps -ef | grep dbus-daemon | grep "$SUSER" | grep -v gdm | grep session | grep -v grep` +- if test x"$a" = x ; then +- systemctl --user start dbus +- export DBUS_SESSION_BUS_ADDRESS=unix:path=/run/user/$UID/bus +- fi +- systemctl --user status dbus | col -b +- ps -ef | grep dbus-daemon | grep "$SUSER" | grep -v gdm | egrep 'session|system' | grep -v grep +- systemctl --user show-environment | col -b ++ # Use dbus-launch --exit-with-session later instead of --sh-syntax ++ export DBUS_SESSION_BUS_ADDRESS=unix:path=/run/user/$UID/bus + } + + run_desktop() +@@ -181,7 +178,8 @@ run_desktop() + $DESKTOP_COMMAND & + PID_GNOME_SESSION=$! + sleep 30 +- if test "$DESKTOP_COMMAND" != "gnome-session" ; then ++ HAS_GNOME=`echo $DESKTOP_COMMAND | grep gnome-session` ++ if [ x"$HAS_GNOME" = x ] ; then + ibus-daemon --daemonize --verbose + sleep 1 + fi +@@ -285,6 +283,16 @@ run_gnome_desktop_testing_runner() + `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 -o $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 + } + +@@ -311,22 +319,29 @@ EOF_RUNNER + ;; + esac + echo "" +- 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 ++ print_log -e "${GREEN}PASS${NC}: $pass" ++ print_log -e "${RED}FAIL${NC}: $fail" + echo "" +- echo "See ${TEST_LOG}" ++ if [ $TEST_LOG_STDOUT -eq 1 ] ; then ++ cat $TEST_LOG ++ else ++ echo "See $TEST_LOG" ++ fi + } + + finit() + { +- if test "$DESKTOP_COMMAND" != "gnome-session" ; then +- ibus exit +- fi ++ 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" + } + +diff --git a/src/tests/ibus-engine-switch.c b/src/tests/ibus-engine-switch.c +index 5c2bd516..a1eeba2a 100644 +--- a/src/tests/ibus-engine-switch.c ++++ b/src/tests/ibus-engine-switch.c +@@ -13,17 +13,25 @@ static const gchar *engine_names[] = { + AFTER_ENGINE + }; + ++static const gchar *engine_names2[] = { ++ AFTER_ENGINE, ++ BEFORE_ENGINE ++}; ++ + static void +-change_global_engine (void) ++change_global_engine (gboolean reverse) + { + gint i; + + for (i = 0; i < G_N_ELEMENTS (engine_names); i++) { +- ibus_bus_set_global_engine (bus, engine_names[i]); ++ const gchar *engine_name = engine_names[i]; ++ if (reverse) ++ engine_name = engine_names2[i]; ++ ibus_bus_set_global_engine (bus, engine_name); + IBusEngineDesc *engine_desc = ibus_bus_get_global_engine (bus); + g_assert_cmpstr (ibus_engine_desc_get_name (engine_desc), + ==, +- engine_names[i]); ++ engine_name); + g_object_unref (G_OBJECT (engine_desc)); + } + } +@@ -46,6 +54,7 @@ typedef struct { + gint count; + guint timeout_id; + guint idle_id; ++ gboolean reverse; + } GlobalEngineChangedData; + + static void +@@ -70,7 +79,7 @@ static gboolean + change_global_engine_cb (gpointer user_data) + { + GlobalEngineChangedData *data = (GlobalEngineChangedData *) user_data; +- change_global_engine (); ++ change_global_engine (data->reverse); + data->idle_id = 0; + return FALSE; + } +@@ -78,12 +87,25 @@ change_global_engine_cb (gpointer user_data) + static void + test_global_engine (void) + { ++ GLogLevelFlags flags; ++ IBusEngineDesc *desc; + GlobalEngineChangedData data; + guint handler_id; + + if (!ibus_bus_get_use_global_engine (bus)) + return; + ++ /* "No global engine." warning is not critical message. */ ++ flags = g_log_set_always_fatal (G_LOG_LEVEL_CRITICAL); ++ desc = ibus_bus_get_global_engine (bus); ++ g_log_set_always_fatal (flags); ++ if (desc && ++ !g_strcmp0 (BEFORE_ENGINE, ibus_engine_desc_get_name (desc))) { ++ data.reverse = TRUE; ++ } else { ++ data.reverse = FALSE; ++ } ++ + data.count = 0; + + handler_id = g_signal_connect (bus, +@@ -141,7 +163,7 @@ test_context_engine_set_by_global (void) + /* ibus_bus_set_global_engine() changes focused context engine. */ + ibus_input_context_focus_in (context); + +- change_global_engine (); ++ change_global_engine (FALSE); + + /* ibus_input_context_set_engine() does not take effect when + global engine is used. */ +@@ -170,7 +192,7 @@ test_context_engine_set_by_focus (void) + + ibus_input_context_focus_in (context); + +- change_global_engine (); ++ change_global_engine (FALSE); + + /* When focus is lost, context engine is set to "dummy". */ + ibus_input_context_focus_in (another_context); +diff --git a/src/tests/ibus-inputcontext.c b/src/tests/ibus-inputcontext.c +index fab183aa..ed04bd64 100644 +--- a/src/tests/ibus-inputcontext.c ++++ b/src/tests/ibus-inputcontext.c +@@ -37,18 +37,6 @@ fatal_handler(const gchar *log_domain, + return TRUE; + } + +-static gchar * +-get_last_engine_id (const GList *engines) +-{ +- const char *result = NULL; +- for (; engines; engines = g_list_next (engines)) { +- IBusEngineDesc *engine_desc = IBUS_ENGINE_DESC (engines->data); +- g_assert (engine_desc); +- result = ibus_engine_desc_get_name (engine_desc); +- } +- return g_strdup (result); +-} +- + static void + call_basic_ipcs (IBusInputContext *context) + { +@@ -68,18 +56,23 @@ call_basic_ipcs (IBusInputContext *context) + static void + test_input_context (void) + { +- GList *engines; +- gchar *active_engine_name = NULL; + IBusInputContext *context; ++ GLogLevelFlags flags; + IBusEngineDesc *engine_desc; ++ gchar *active_engine_name = NULL; + gchar *current_ic; + + context = ibus_bus_create_input_context (bus, "test"); + call_basic_ipcs (context); + +- engines = ibus_bus_list_active_engines (bus); +- if (engines != NULL) { +- active_engine_name = get_last_engine_id (engines); ++ /* "No global engine." warning is not critical message. */ ++ flags = g_log_set_always_fatal (G_LOG_LEVEL_CRITICAL); ++ engine_desc = ibus_bus_get_global_engine (bus); ++ g_log_set_always_fatal (flags); ++ if (engine_desc != NULL) { ++ active_engine_name = g_strdup (ibus_engine_desc_get_name(engine_desc)); ++ g_object_unref (engine_desc); ++ engine_desc = NULL; + } else { + active_engine_name = g_strdup ("dummy"); + } +@@ -111,8 +104,6 @@ test_input_context (void) + g_object_unref (context); + + g_free (active_engine_name); +- g_list_foreach (engines, (GFunc) g_object_unref, NULL); +- g_list_free (engines); + } + + static void +diff --git a/src/tests/ibus-keypress.c b/src/tests/ibus-keypress.c +index 17920226..dd1b0042 100644 +--- a/src/tests/ibus-keypress.c ++++ b/src/tests/ibus-keypress.c +@@ -288,6 +288,10 @@ int + main (int argc, char *argv[]) + { + ibus_init (); ++ /* Avoid a warning of "AT-SPI: Could not obtain desktop path or name" ++ * with gtk_main(). ++ */ ++ g_setenv ("NO_AT_BRIDGE", "1", TRUE); + g_test_init (&argc, &argv, NULL); + gtk_init (&argc, &argv); + +-- +2.21.0 + +From f4463c0433c5f48a4fb2830e8c2ae9619fbb18d1 Mon Sep 17 00:00:00 2001 +From: fujiwarat +Date: Mon, 29 Jul 2019 19:05:43 +0900 +Subject: [PATCH] src/tests: Fix a fatal error with g_warning + +I set g_log_set_always_fatal() before gtk_init() in ibus-compose for +a compose warning of GtkIMContextSimple but actually the warning is +output during gtk_main() due to GtkIMContextSimple.set_client_window() +so I moved g_log_set_always_fatal() before gtk_main() in ibus-compose.c. + +Also set IFS in ibus-compose-locales to set the delimiter to '\n' for +for-loop arguments. +--- + src/tests/ibus-compose-locales.in | 8 ++++++++ + src/tests/ibus-compose.c | 21 ++++++++++----------- + 2 files changed, 18 insertions(+), 11 deletions(-) + +diff --git a/src/tests/ibus-compose-locales.in b/src/tests/ibus-compose-locales.in +index fad02965..f650b584 100755 +--- a/src/tests/ibus-compose-locales.in ++++ b/src/tests/ibus-compose-locales.in +@@ -7,19 +7,27 @@ BUILDDIR=`dirname $0` + export IBUS_COMPOSE_CACHE_DIR=$PWD + + retval=0 ++# Let for-loop notice '\n' as a delimiter ++IFS=$'\n' + for var in `cat $SRCDIR/ibus-compose.env` + do ++ # Revert IFS to recognize env a=foo b=foo ++ IFS=' ' + IS_COMMENT=`echo "$var" | grep "^#"` + if [ "x$IS_COMMENT" != x ] ; then + continue + fi ++ echo "# Starting $var $BUILDDIR/ibus-compose $SRCDIR $@" + env $var $BUILDDIR/ibus-compose $SRCDIR $@ + 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 ++ IFS=$'\n' + done ++IFS=' ' + exit $retval +diff --git a/src/tests/ibus-compose.c b/src/tests/ibus-compose.c +index db359477..4b4c56e7 100644 +--- a/src/tests/ibus-compose.c ++++ b/src/tests/ibus-compose.c +@@ -331,20 +331,28 @@ create_window () + static void + test_compose (void) + { ++ GLogLevelFlags flags; + if (!register_ibus_engine ()) { + g_test_fail (); + return; + } + + create_window (); ++ /* FIXME: ++ * IBusIMContext opens GtkIMContextSimple as the slave and ++ * GtkIMContextSimple opens the compose table on el_GR.UTF-8, and the ++ * multiple outputs in el_GR's compose causes a warning in gtkcomposetable ++ * and the warning always causes a fatal in GTest: ++ " "GTK+ supports to output one char only: " ++ */ ++ flags = g_log_set_always_fatal (G_LOG_LEVEL_CRITICAL); + gtk_main (); +- ++ g_log_set_always_fatal (flags); + } + + int + main (int argc, char *argv[]) + { +- GLogLevelFlags flags; + const gchar *test_name; + gchar *test_path; + +@@ -354,16 +362,7 @@ main (int argc, char *argv[]) + */ + g_setenv ("NO_AT_BRIDGE", "1", TRUE); + g_test_init (&argc, &argv, NULL); +- /* FIXME: +- * IBusIMContext opens GtkIMContextSimple as the slave and +- * GtkIMContextSimple opens the compose table on el_GR.UTF-8, and the +- * multiple outputs in el_GR's compose causes a warning in gtkcomposetable +- * and the warning always causes a fatal in GTest: +- " "GTK+ supports to output one char only: " +- */ +- flags = g_log_set_always_fatal (G_LOG_LEVEL_CRITICAL); + gtk_init (&argc, &argv); +- g_log_set_always_fatal (flags); + + m_srcdir = argc > 1 ? g_strdup (argv[1]) : g_strdup ("."); + m_compose_file = g_strdup (g_getenv ("COMPOSE_FILE")); +-- +2.21.0 + +From 7dde99600777f195da614130950ecbd339439d35 Mon Sep 17 00:00:00 2001 +From: fujiwarat +Date: Wed, 31 Jul 2019 16:27:49 +0900 +Subject: [PATCH] src/tests: Fix wrong echo with direct runner in + ibus-desktop-testing-runner + +The wrong echo prevent from counting the test results in the direct +testing runner. +--- + src/tests/ibus-desktop-testing-runner.in | 33 +++++++++++++----------- + 1 file changed, 18 insertions(+), 15 deletions(-) + +diff --git a/src/tests/ibus-desktop-testing-runner.in b/src/tests/ibus-desktop-testing-runner.in +index b7a72285..3045d601 100755 +--- a/src/tests/ibus-desktop-testing-runner.in ++++ b/src/tests/ibus-desktop-testing-runner.in +@@ -153,7 +153,7 @@ _EOF + 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 "# Overriding XDG locale $XDG_LANG_ORIG with $XDG_LANG_NEW" + echo "$XDG_LANG_NEW" > $XDG_LOCALE_FILE + fi + fi +@@ -206,11 +206,9 @@ echo_case_result() + subtst=${3:-''} + + if test $retval -eq 0 ; then +- print_log -e "${GREEN}PASS${NC}: $tst $subtst" ++ echo "PASS: $tst $subtst" >>$TEST_LOG + else +- print_log -e "${RED}FAIL${NC}: $tst $subtst" +- print_log "======================" +- print_log "" ++ echo "FAIL: $tst $subtst" >>$TEST_LOG + fi + } + +@@ -232,32 +230,37 @@ EOF + echo_case_result $retval $tst + CACHE_FILES=`ls *.cache` + if [ x"$CACHE_FILES" != x ] ; then +- print_log "Clean $CACHE_FILES" ++ echo "# Clean $CACHE_FILES" >>$TEST_LOG + rm $CACHE_FILES + fi + else +- LANG_backup=$LANG + i=1 ++ # Let for-loop notice '\n' as a delimiter ++ IFS=$'\n' + for e in $ENVS; do ++ # Revert IFS to recognize env a=foo b=foo ++ IFS=' ' + first=`echo "$e" | grep '^#'` + if test x"$first" = x"#" ; then + continue + fi +- export $e +- $BUILDDIR/$tst $SRCDIR 2>>$TEST_LOG 1>>$TEST_LOG ++ 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_case_result $retval $pass $fail` + EOF + echo_case_result $retval $tst $e + CACHE_FILES=`ls *.cache` + if [ x"$CACHE_FILES" != x ] ; then +- print_log "Clean $CACHE_FILES" ++ echo "# Clean $CACHE_FILES" >>$TEST_LOG + rm $CACHE_FILES + fi + i=`expr $i + 1` ++ IFS=$'\n' + done +- export LANG=$LANG_backup ++ IFS=' ' + fi + done + echo $pass $fail +@@ -325,24 +328,24 @@ EOF_RUNNER + if [ $TEST_LOG_STDOUT -eq 1 ] ; then + cat $TEST_LOG + else +- echo "See $TEST_LOG" ++ echo "# See $TEST_LOG" + fi + } + + finit() + { +- echo "Killing left gnome-session and Xorg" ++ 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 "# Killing left gnome-shell-calendar-server" + echo "$LEFT_CALENDAR" + echo "$LEFT_CALENDAR" | awk '{print $2}' | xargs kill + fi + +- echo "Finished $PROGNAME testing" ++ echo "# Finished $PROGNAME testing" + } + + main() +-- +2.21.0 + +From 28c10d64d282fa9fbc35a7bc44a096f6137d5e46 Mon Sep 17 00:00:00 2001 +From: fujiwarat +Date: Tue, 13 Aug 2019 20:06:51 +0900 +Subject: [PATCH] src/tests: Set XDG_SESSION_TYPE in + ibus-desktop-testing-runner + +mutter 3.33.90 or later exits the session without loginctl. +Now ibus-desktop-testing-runner has XDG_SESSION_TYPE forcibly +not to exit gnome-shell. +--- + src/tests/ibus-desktop-testing-runner.in | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/src/tests/ibus-desktop-testing-runner.in b/src/tests/ibus-desktop-testing-runner.in +index 3045d601..141e9b5b 100755 +--- a/src/tests/ibus-desktop-testing-runner.in ++++ b/src/tests/ibus-desktop-testing-runner.in +@@ -157,6 +157,8 @@ _EOF + echo "$XDG_LANG_NEW" > $XDG_LOCALE_FILE + fi + fi ++ # `su` command does not run loginctl ++ export XDG_SESSION_TYPE='x11' + } + + run_dbus_daemon() +@@ -175,6 +177,7 @@ run_desktop() + PID_XORG=$! + sleep 1 + export DISPLAY=$DISPLAY ++ echo "Running $DESKTOP_COMMAND with $USER in `tty`" + $DESKTOP_COMMAND & + PID_GNOME_SESSION=$! + sleep 30 +-- +2.21.0 + +From bccf94d5ec1c5fc80d5aeac622f2ab8007d5a28a Mon Sep 17 00:00:00 2001 +From: fujiwarat +Date: Fri, 29 Nov 2019 20:28:49 +0900 +Subject: [PATCH] src/tests: RHEL codereview for ibus-desktop-testing-runner + +--- + src/tests/ibus-desktop-testing-runner.in | 16 ++++++++++------ + 1 file changed, 10 insertions(+), 6 deletions(-) + +diff --git a/src/tests/ibus-desktop-testing-runner.in b/src/tests/ibus-desktop-testing-runner.in +index 141e9b5b..72537cd4 100755 +--- a/src/tests/ibus-desktop-testing-runner.in ++++ b/src/tests/ibus-desktop-testing-runner.in +@@ -28,6 +28,10 @@ + # # /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'} ++ ++ + PROGNAME=`basename $0` + VERSION=0.1 + DISPLAY=:99.0 +@@ -54,15 +58,15 @@ print_log() + shift + fi + NO_ESCAPE=`echo $@ | sed -e 's/\\\033\\[0;3.m//g' -e 's/\\\033\\[0m//g'` +- echo $NO_ESCAPE >> $RESULT_LOG ++ $ECHO $NO_ESCAPE >> $RESULT_LOG + else +- echo $@ ++ $ECHO $@ + fi + } + + usage() + { +- echo -e \ ++ $ECHO -e \ + "This test runs /usr/bin/ibus-daemon after install ibus\n" \ + "$PROGNAME [OPTIONS…]\n" \ + "\n" \ +@@ -92,7 +96,7 @@ parse_args() + while [ 1 ] ; do + case "$1" in + -h | --help ) usage; exit 0;; +- -v | --version ) echo -e "$VERSION"; 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;; +@@ -121,7 +125,7 @@ init_desktop() + 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 ++ exit 255 + elif [ -f $TEST_LOG ] ; then + rm $TEST_LOG + fi +@@ -291,7 +295,7 @@ EOF + done + child_pass=`grep '^PASS:' $TEST_LOG | wc -l` + child_fail=`grep '^FAIL:' $TEST_LOG | wc -l` +- if [ $child_pass -ne 0 -o $child_fail -ne 0 ] ; then ++ if [ $child_pass -ne 0 ] || [ $child_fail -ne 0 ] ; then + pass=$child_pass + if [ $child_fail -ne 0 ] ; then + fail=`expr $child_fail / 2` +-- +2.21.0 + +From d50627f0b7a000ee13ea6dcc02a4162be1fa853d Mon Sep 17 00:00:00 2001 +From: fujiwarat +Date: Tue, 3 Dec 2019 21:42:49 +0900 +Subject: [PATCH] src/tests: RHEL codereview #2 for ibus-desktop-testing-runner + +--- + src/tests/ibus-compose-locales.in | 21 +++++++-------- + src/tests/ibus-desktop-testing-runner.in | 33 ++++++++++++------------ + 2 files changed, 27 insertions(+), 27 deletions(-) + +diff --git a/src/tests/ibus-compose-locales.in b/src/tests/ibus-compose-locales.in +index f650b584..b36165fe 100755 +--- a/src/tests/ibus-compose-locales.in ++++ b/src/tests/ibus-compose-locales.in +@@ -7,27 +7,26 @@ BUILDDIR=`dirname $0` + export IBUS_COMPOSE_CACHE_DIR=$PWD + + retval=0 +-# Let for-loop notice '\n' as a delimiter +-IFS=$'\n' +-for var in `cat $SRCDIR/ibus-compose.env` ++# Deleted for var in `cat *.env` because IFS=$'\n' is not supported in POSIX sh ++while read var + do +- # Revert IFS to recognize env a=foo b=foo +- IFS=' ' + IS_COMMENT=`echo "$var" | grep "^#"` + if [ "x$IS_COMMENT" != x ] ; then + continue + fi +- echo "# Starting $var $BUILDDIR/ibus-compose $SRCDIR $@" +- env $var $BUILDDIR/ibus-compose $SRCDIR $@ ++ # 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" ++ 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 +- IFS=$'\n' +-done +-IFS=' ' ++done << EOF_ENVS ++`cat $SRCDIR/ibus-compose.env` ++EOF_ENVS + exit $retval +diff --git a/src/tests/ibus-desktop-testing-runner.in b/src/tests/ibus-desktop-testing-runner.in +index 72537cd4..981941d5 100755 +--- a/src/tests/ibus-desktop-testing-runner.in ++++ b/src/tests/ibus-desktop-testing-runner.in +@@ -30,6 +30,8 @@ + + # POSIX sh has no 'echo -e' + : ${ECHO:='/usr/bin/echo'} ++# POSIX sh has $UID ++: ${UID:='`id -u`'} + + + PROGNAME=`basename $0` +@@ -57,10 +59,10 @@ print_log() + if [ x"$1" = x'-e' ] ; then + shift + fi +- NO_ESCAPE=`echo $@ | sed -e 's/\\\033\\[0;3.m//g' -e 's/\\\033\\[0m//g'` ++ NO_ESCAPE=`echo "$@" | sed -e 's/\\\033\\[0;3.m//g' -e 's/\\\033\\[0m//g'` + $ECHO $NO_ESCAPE >> $RESULT_LOG + else +- $ECHO $@ ++ $ECHO "$@" + fi + } + +@@ -231,9 +233,9 @@ run_direct_test_cases() + if test x"$ENVS" = x ; then + $BUILDDIR/$tst $SRCDIR 2>>$TEST_LOG 1>>$TEST_LOG + retval=$? +- read pass fail << EOF ++ read pass fail << EOF_COUNT + `count_case_result $retval $pass $fail` +-EOF ++EOF_COUNT + echo_case_result $retval $tst + CACHE_FILES=`ls *.cache` + if [ x"$CACHE_FILES" != x ] ; then +@@ -242,11 +244,9 @@ EOF + fi + else + i=1 +- # Let for-loop notice '\n' as a delimiter +- IFS=$'\n' +- for e in $ENVS; do +- # Revert IFS to recognize env a=foo b=foo +- IFS=' ' ++ # 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 +@@ -255,9 +255,9 @@ EOF + 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 ++ read pass fail << EOF_COUNT + `count_case_result $retval $pass $fail` +-EOF ++EOF_COUNT + echo_case_result $retval $tst $e + CACHE_FILES=`ls *.cache` + if [ x"$CACHE_FILES" != x ] ; then +@@ -265,9 +265,9 @@ EOF + rm $CACHE_FILES + fi + i=`expr $i + 1` +- IFS=$'\n' +- done +- IFS=' ' ++ done << EOF_ENVS ++ `echo "$ENVS"` ++EOF_ENVS + fi + done + echo $pass $fail +@@ -357,7 +357,7 @@ finit() + + main() + { +- parse_args $@ ++ parse_args "$@" + init_desktop + run_dbus_daemon 2>>$TEST_LOG 1>>$TEST_LOG + run_desktop 2>>$TEST_LOG 1>>$TEST_LOG +@@ -365,4 +365,5 @@ main() + finit + } + +-main $@ ++# Need to enclose $@ with double quotes not to split the array. ++main "$@" +-- +2.21.0 + diff --git a/SOURCES/ibus-1713606-hangul-with-mouse.patch b/SOURCES/ibus-1713606-hangul-with-mouse.patch new file mode 100644 index 0000000..b86145f --- /dev/null +++ b/SOURCES/ibus-1713606-hangul-with-mouse.patch @@ -0,0 +1,1120 @@ +From a40631e166137c9042a68c2d76844e7afc53d388 Mon Sep 17 00:00:00 2001 +From: fujiwarat +Date: Fri, 9 Nov 2018 14:49:44 +0900 +Subject: [PATCH] Detect mouse click to commit Hangul preedit + +If preedit text is not committed with the mouse click, preedit text +is moved to the new cursor position in Hangul typing. +Since set_cursor_location() is received before the reset() signal is +sent to ibus-daemon and commit_text() signal is received from +ibus-daemon, UpdatePreeditTextWithMode D-Bus method is newly added +and now ibus clients commit the preedit. + +BUG=https://github.com/ibus/ibus/issues/1980 +--- + bus/ibusimpl.c | 11 ++++ + bus/inputcontext.c | 108 ++++++++++++++++++++++++------- + bus/inputcontext.h | 19 +++++- + client/gtk2/ibusimcontext.c | 95 +++++++++++++++++++++++++--- + src/ibusinputcontext.c | 122 ++++++++++++++++++++++++++++++++---- + src/ibusinputcontext.h | 27 +++++++- + 6 files changed, 338 insertions(+), 44 deletions(-) + +diff --git a/bus/ibusimpl.c b/bus/ibusimpl.c +index 80f3acfb..bbbb5770 100644 +--- a/bus/ibusimpl.c ++++ b/bus/ibusimpl.c +@@ -815,6 +815,17 @@ bus_ibus_impl_set_focused_context (BusIBusImpl *ibus, + engine = bus_input_context_get_engine (ibus->focused_context); + if (engine) { + g_object_ref (engine); ++ /* _ic_focus_in() can be called before _ic_focus_out() is ++ * called under the async processes of two ibus clients. ++ * E.g. gedit is a little slower v.s. a simple GtkTextView ++ * application is the fastest when you click a Hangul ++ * preedit text between the applications. ++ * preedit will be committed with focus-out in the ibus client ++ * likes ibus-im.so ++ * so do not commit preedit here in focus-in event. ++ */ ++ bus_input_context_clear_preedit_text (ibus->focused_context, ++ FALSE); + bus_input_context_set_engine (ibus->focused_context, NULL); + bus_input_context_set_emoji_extension (ibus->focused_context, + NULL); +diff --git a/bus/inputcontext.c b/bus/inputcontext.c +index 4f98b849..1b8e7adb 100644 +--- a/bus/inputcontext.c ++++ b/bus/inputcontext.c +@@ -73,6 +73,7 @@ struct _BusInputContext { + guint preedit_cursor_pos; + gboolean preedit_visible; + guint preedit_mode; ++ gboolean client_commit_preedit; + + /* auxiliary text */ + IBusText *auxiliary_text; +@@ -212,6 +213,9 @@ static IBusPropList *props_empty = NULL; + static const gchar introspection_xml[] = + "" + " " ++ /* properties */ ++ " " ++ " \n" + /* methods */ + " " + " " +@@ -273,6 +277,12 @@ static const gchar introspection_xml[] = + " " + " " + " " ++ " " ++ " " ++ " " ++ " " ++ " " ++ " " + " " + " " + " " +@@ -297,9 +307,6 @@ static const gchar introspection_xml[] = + " " + " " + " " +- +- /* properties */ +- " " + " " + ""; + +@@ -1069,6 +1076,12 @@ _ic_reset (BusInputContext *context, + GDBusMethodInvocation *invocation) + { + if (context->engine) { ++ if (context->preedit_mode == IBUS_ENGINE_PREEDIT_COMMIT) { ++ if (context->client_commit_preedit) ++ bus_input_context_clear_preedit_text (context, FALSE); ++ else ++ bus_input_context_clear_preedit_text (context, TRUE); ++ } + bus_engine_proxy_reset (context->engine); + } + g_dbus_method_invocation_return_value (invocation, NULL); +@@ -1354,6 +1367,13 @@ _ic_set_content_type (BusInputContext *context, + } + } + ++static void ++_ic_set_client_commit_preedit (BusInputContext *context, ++ GVariant *value) ++{ ++ g_variant_get (value, "(b)", &context->client_commit_preedit); ++} ++ + static gboolean + bus_input_context_service_set_property (IBusService *service, + GDBusConnection *connection, +@@ -1379,9 +1399,14 @@ bus_input_context_service_set_property (IBusService *service, + if (!bus_input_context_service_authorized_method (service, connection)) + return FALSE; + ++ g_return_val_if_fail (BUS_IS_INPUT_CONTEXT (service), FALSE); ++ + if (g_strcmp0 (property_name, "ContentType") == 0) { +- BusInputContext *context = (BusInputContext *) service; +- _ic_set_content_type (context, value); ++ _ic_set_content_type (BUS_INPUT_CONTEXT (service), value); ++ return TRUE; ++ } ++ if (g_strcmp0 (property_name, "ClientCommitPreedit") == 0) { ++ _ic_set_client_commit_preedit (BUS_INPUT_CONTEXT (service), value); + return TRUE; + } + +@@ -1453,22 +1478,44 @@ bus_input_context_focus_in (BusInputContext *context) + + /** + * bus_input_context_clear_preedit_text: ++ * @context: A #BusInputContext ++ * @with_signal: %FALSE if the preedit is already updated in ibus clients ++ * likes ibus-im.so. Otherwise %TRUE. + * +- * Clear context->preedit_text. If the preedit mode is IBUS_ENGINE_PREEDIT_COMMIT, commit it before clearing. ++ * Clear context->preedit_text. If the preedit mode is ++ * IBUS_ENGINE_PREEDIT_COMMIT, commit it before clearing. + */ +-static void +-bus_input_context_clear_preedit_text (BusInputContext *context) ++void ++bus_input_context_clear_preedit_text (BusInputContext *context, ++ gboolean with_signal) + { ++ IBusText *preedit_text; ++ guint preedit_mode; ++ gboolean preedit_visible; ++ + g_assert (BUS_IS_INPUT_CONTEXT (context)); + +- if (context->preedit_visible && +- context->preedit_mode == IBUS_ENGINE_PREEDIT_COMMIT) { +- bus_input_context_commit_text (context, context->preedit_text); ++ if (!with_signal) { ++ g_object_unref (context->preedit_text); ++ context->preedit_mode = IBUS_ENGINE_PREEDIT_CLEAR; ++ context->preedit_text = (IBusText *) g_object_ref_sink (text_empty); ++ context->preedit_cursor_pos = 0; ++ context->preedit_visible = FALSE; ++ return; + } + +- /* always clear preedit text */ ++ /* always clear preedit text to reset the cursor position in the ++ * client application before commit the preeit text. */ ++ preedit_text = g_object_ref (context->preedit_text); ++ preedit_mode = context->preedit_mode; ++ preedit_visible = context->preedit_visible; + bus_input_context_update_preedit_text (context, + text_empty, 0, FALSE, IBUS_ENGINE_PREEDIT_CLEAR, TRUE); ++ ++ if (preedit_visible && preedit_mode == IBUS_ENGINE_PREEDIT_COMMIT) { ++ bus_input_context_commit_text (context, preedit_text); ++ } ++ g_object_unref (preedit_text); + } + + void +@@ -1479,7 +1526,10 @@ bus_input_context_focus_out (BusInputContext *context) + if (!context->has_focus) + return; + +- bus_input_context_clear_preedit_text (context); ++ if (context->client_commit_preedit) ++ bus_input_context_clear_preedit_text (context, FALSE); ++ else ++ bus_input_context_clear_preedit_text (context, TRUE); + bus_input_context_update_auxiliary_text (context, text_empty, FALSE); + bus_input_context_update_lookup_table (context, + lookup_table_empty, +@@ -2338,7 +2388,7 @@ bus_input_context_disable (BusInputContext *context) + { + g_assert (BUS_IS_INPUT_CONTEXT (context)); + +- bus_input_context_clear_preedit_text (context); ++ bus_input_context_clear_preedit_text (context, TRUE); + bus_input_context_update_auxiliary_text (context, text_empty, FALSE); + bus_input_context_update_lookup_table (context, + lookup_table_empty, +@@ -2385,7 +2435,7 @@ bus_input_context_unset_engine (BusInputContext *context) + { + g_assert (BUS_IS_INPUT_CONTEXT (context)); + +- bus_input_context_clear_preedit_text (context); ++ bus_input_context_clear_preedit_text (context, TRUE); + bus_input_context_update_auxiliary_text (context, text_empty, FALSE); + bus_input_context_update_lookup_table (context, + lookup_table_empty, +@@ -2807,14 +2857,26 @@ bus_input_context_update_preedit_text (BusInputContext *context, + } else if (PREEDIT_CONDITION) { + GVariant *variant = ibus_serializable_serialize ( + (IBusSerializable *)context->preedit_text); +- bus_input_context_emit_signal (context, +- "UpdatePreeditText", +- g_variant_new ( +- "(vub)", +- variant, +- context->preedit_cursor_pos, +- extension_visible), +- NULL); ++ if (context->client_commit_preedit) { ++ bus_input_context_emit_signal ( ++ context, ++ "UpdatePreeditTextWithMode", ++ g_variant_new ("(vubu)", ++ variant, ++ context->preedit_cursor_pos, ++ extension_visible, ++ context->preedit_mode), ++ NULL); ++ } else { ++ bus_input_context_emit_signal ( ++ context, ++ "UpdatePreeditText", ++ g_variant_new ("(vub)", ++ variant, ++ context->preedit_cursor_pos, ++ extension_visible), ++ NULL); ++ } + } else { + g_signal_emit (context, + context_signals[UPDATE_PREEDIT_TEXT], +diff --git a/bus/inputcontext.h b/bus/inputcontext.h +index a46d5c06..7105fff8 100644 +--- a/bus/inputcontext.h ++++ b/bus/inputcontext.h +@@ -2,8 +2,8 @@ + /* vim:set et sts=4: */ + /* ibus - The Input Bus + * Copyright (C) 2008-2014 Peng Huang +- * Copyright (C) 2017 Takao Fujiwara +- * Copyright (C) 2008-2014 Red Hat, Inc. ++ * Copyright (C) 2017-2018 Takao Fujiwara ++ * Copyright (C) 2008-2018 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public +@@ -377,5 +377,20 @@ void bus_input_context_update_lookup_table + void bus_input_context_panel_extension_received + (BusInputContext *context, + IBusExtensionEvent *event); ++ ++/** ++ * bus_input_context_clear_preedit_text: ++ * ++ * Clear context->preedit_text. If the preedit mode is ++ * IBUS_ENGINE_PREEDIT_COMMIT and with_signal is %TRUE, commit it before ++ * clearing. ++ * If with_signal is %FALSE, this just clears the preedit coditions ++ * and the actual preedit is handled in ibus clients. ++ */ ++void bus_input_context_clear_preedit_text ++ (BusInputContext *context, ++ gboolean ++ with_signal); ++ + G_END_DECLS + #endif +diff --git a/client/gtk2/ibusimcontext.c b/client/gtk2/ibusimcontext.c +index e4de52d9..73a0eaec 100644 +--- a/client/gtk2/ibusimcontext.c ++++ b/client/gtk2/ibusimcontext.c +@@ -2,8 +2,8 @@ + /* vim:set et sts=4: */ + /* ibus - The Input Bus + * Copyright (C) 2008-2013 Peng Huang +- * Copyright (C) 2015-2017 Takao Fujiwara +- * Copyright (C) 2008-2017 Red Hat, Inc. ++ * Copyright (C) 2015-2018 Takao Fujiwara ++ * Copyright (C) 2008-2018 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public +@@ -61,6 +61,7 @@ struct _IBusIMContext { + PangoAttrList *preedit_attrs; + gint preedit_cursor_pos; + gboolean preedit_visible; ++ guint preedit_mode; + + GdkRectangle cursor_area; + gboolean has_focus; +@@ -132,8 +133,14 @@ static void ibus_im_context_set_surrounding + gint len, + gint cursor_index); + +- + /* static methods*/ ++static void _ibus_context_update_preedit_text_cb ++ (IBusInputContext *ibuscontext, ++ IBusText *text, ++ gint cursor_pos, ++ gboolean visible, ++ guint mode, ++ IBusIMContext *ibusimcontext); + static void _create_input_context (IBusIMContext *context); + static gboolean _set_cursor_location_internal + (IBusIMContext *context); +@@ -744,6 +751,7 @@ ibus_im_context_init (GObject *obj) + ibusimcontext->preedit_attrs = NULL; + ibusimcontext->preedit_cursor_pos = 0; + ibusimcontext->preedit_visible = FALSE; ++ ibusimcontext->preedit_mode = IBUS_ENGINE_PREEDIT_CLEAR; + + // Init cursor area + ibusimcontext->cursor_area.x = -1; +@@ -854,6 +862,24 @@ ibus_im_context_finalize (GObject *obj) + G_OBJECT_CLASS(parent_class)->finalize (obj); + } + ++static void ++ibus_im_context_clear_preedit_text (IBusIMContext *ibusimcontext) ++{ ++ g_assert (ibusimcontext->ibuscontext); ++ if (ibusimcontext->preedit_visible && ++ ibusimcontext->preedit_mode == IBUS_ENGINE_PREEDIT_COMMIT) { ++ gchar *preedit_string = g_strdup (ibusimcontext->preedit_string); ++ _ibus_context_update_preedit_text_cb (ibusimcontext->ibuscontext, ++ ibus_text_new_from_string (""), ++ 0, ++ FALSE, ++ IBUS_ENGINE_PREEDIT_CLEAR, ++ ibusimcontext); ++ g_signal_emit (ibusimcontext, _signal_commit_id, 0, preedit_string); ++ g_free (preedit_string); ++ } ++} ++ + static gboolean + ibus_im_context_filter_keypress (GtkIMContext *context, + GdkEventKey *event) +@@ -1003,6 +1029,7 @@ ibus_im_context_focus_out (GtkIMContext *context) + + ibusimcontext->has_focus = FALSE; + if (ibusimcontext->ibuscontext) { ++ ibus_im_context_clear_preedit_text (ibusimcontext); + ibus_input_context_focus_out (ibusimcontext->ibuscontext); + } + +@@ -1022,6 +1049,12 @@ ibus_im_context_reset (GtkIMContext *context) + IBusIMContext *ibusimcontext = IBUS_IM_CONTEXT (context); + + if (ibusimcontext->ibuscontext) { ++ /* Commented out ibus_im_context_clear_preedit_text(). ++ * Hangul needs to receive the reset callback with button press ++ * but other IMEs should avoid to receive the reset callback ++ * so the signal would need to be customized with GtkSetting. ++ * IBus uses button-press-event instead. ++ */ + ibus_input_context_reset (ibusimcontext->ibuscontext); + } + gtk_im_context_reset (ibusimcontext->slave); +@@ -1068,21 +1101,67 @@ ibus_im_context_get_preedit_string (GtkIMContext *context, + } + + ++static gboolean ++ibus_im_context_button_press_event_cb (GtkWidget *widget, ++ GdkEventButton *event, ++ IBusIMContext *ibusimcontext) ++{ ++ if (event->button != 1) ++ return FALSE; ++ ++ if (ibusimcontext->preedit_visible && ++ ibusimcontext->preedit_mode == IBUS_ENGINE_PREEDIT_COMMIT) { ++ ibus_im_context_clear_preedit_text (ibusimcontext); ++ if (ibusimcontext->ibuscontext) ++ ibus_input_context_reset (ibusimcontext->ibuscontext); ++ } ++ return FALSE; ++} ++ + static void + ibus_im_context_set_client_window (GtkIMContext *context, GdkWindow *client) + { ++ IBusIMContext *ibusimcontext; ++#if !GTK_CHECK_VERSION (3, 93, 0) ++ GtkWidget *widget; ++#endif ++ + IDEBUG ("%s", __FUNCTION__); + +- IBusIMContext *ibusimcontext = IBUS_IM_CONTEXT (context); ++ ibusimcontext = IBUS_IM_CONTEXT (context); + + if (ibusimcontext->client_window) { ++#if !GTK_CHECK_VERSION (3, 93, 0) ++ gdk_window_get_user_data (ibusimcontext->client_window, ++ (gpointer *)&widget); ++ /* firefox needs GtkWidget instead of GtkWindow */ ++ if (GTK_IS_WIDGET (widget)) { ++ g_signal_handlers_disconnect_by_func ( ++ widget, ++ (GCallback)ibus_im_context_button_press_event_cb, ++ ibusimcontext); ++ } ++#endif + g_object_unref (ibusimcontext->client_window); + ibusimcontext->client_window = NULL; + } + +- if (client != NULL) ++ if (client != NULL) { + ibusimcontext->client_window = g_object_ref (client); ++#if !GTK_CHECK_VERSION (3, 93, 0) ++ gdk_window_get_user_data (ibusimcontext->client_window, ++ (gpointer *)&widget); + ++ /* firefox needs GtkWidget instead of GtkWindow */ ++ if (GTK_IS_WIDGET (widget)) { ++ g_signal_connect ( ++ widget, ++ "button-press-event", ++ G_CALLBACK (ibus_im_context_button_press_event_cb), ++ ibusimcontext); ++ } ++#endif ++ } + if (ibusimcontext->slave) + gtk_im_context_set_client_window (ibusimcontext->slave, client); + } +@@ -1530,6 +1609,7 @@ _ibus_context_update_preedit_text_cb (IBusInputContext *ibuscontext, + IBusText *text, + gint cursor_pos, + gboolean visible, ++ guint mode, + IBusIMContext *ibusimcontext) + { + IDEBUG ("%s", __FUNCTION__); +@@ -1586,6 +1666,7 @@ _ibus_context_update_preedit_text_cb (IBusInputContext *ibuscontext, + + flag = ibusimcontext->preedit_visible != visible; + ibusimcontext->preedit_visible = visible; ++ ibusimcontext->preedit_mode = mode; + + if (ibusimcontext->preedit_visible) { + if (flag) { +@@ -1676,7 +1757,7 @@ _create_input_context_done (IBusBus *bus, + g_error_free (error); + } + else { +- ++ ibus_input_context_set_client_commit_preedit (context, TRUE); + ibusimcontext->ibuscontext = context; + + g_signal_connect (ibusimcontext->ibuscontext, +@@ -1692,7 +1773,7 @@ _create_input_context_done (IBusBus *bus, + G_CALLBACK (_ibus_context_delete_surrounding_text_cb), + ibusimcontext); + g_signal_connect (ibusimcontext->ibuscontext, +- "update-preedit-text", ++ "update-preedit-text-with-mode", + G_CALLBACK (_ibus_context_update_preedit_text_cb), + ibusimcontext); + g_signal_connect (ibusimcontext->ibuscontext, +diff --git a/src/ibusinputcontext.c b/src/ibusinputcontext.c +index ae7048ad..a809ef08 100644 +--- a/src/ibusinputcontext.c ++++ b/src/ibusinputcontext.c +@@ -2,7 +2,8 @@ + /* vim:set et sts=4: */ + /* ibus - The Input Bus + * Copyright (C) 2008-2013 Peng Huang +- * Copyright (C) 2008-2013 Red Hat, Inc. ++ * Copyright (C) 2018 Takao Fujiwara ++ * Copyright (C) 2008-2018 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public +@@ -39,6 +40,7 @@ enum { + FORWARD_KEY_EVENT, + DELETE_SURROUNDING_TEXT, + UPDATE_PREEDIT_TEXT, ++ UPDATE_PREEDIT_TEXT_WITH_MODE, + SHOW_PREEDIT_TEXT, + HIDE_PREEDIT_TEXT, + UPDATE_AUXILIARY_TEXT, +@@ -217,6 +219,34 @@ ibus_input_context_class_init (IBusInputContextClass *class) + G_TYPE_UINT, + G_TYPE_BOOLEAN); + ++ /** ++ * IBusInputContext::update-preedit-text-with-mode: ++ * @context: An IBusInputContext. ++ * @text: Text to be updated. ++ * @cursor_pos: Cursor position. ++ * @visible: Whether the update is visible. ++ * @mode: Preedit mode. ++ * ++ * Emitted to update preedit text with the mode. ++ * ++ * (Note: The text object is floating, and it will be released after the ++ * signal. If signal handler wants to keep the object, the handler should ++ * use g_object_ref_sink() to get the ownership of the object.) ++ */ ++ context_signals[UPDATE_PREEDIT_TEXT_WITH_MODE] = ++ g_signal_new (I_("update-preedit-text-with-mode"), ++ G_TYPE_FROM_CLASS (class), ++ G_SIGNAL_RUN_LAST, ++ 0, ++ NULL, NULL, ++ _ibus_marshal_VOID__OBJECT_UINT_BOOLEAN_UINT, ++ G_TYPE_NONE, ++ 4, ++ IBUS_TYPE_TEXT, ++ G_TYPE_UINT, ++ G_TYPE_BOOLEAN, ++ G_TYPE_UINT); ++ + /** + * IBusInputContext::show-preedit-text: + * @context: An IBusInputContext. +@@ -542,6 +572,28 @@ ibus_input_context_g_signal (GDBusProxy *proxy, + g_object_unref (text); + return; + } ++ if (g_strcmp0 (signal_name, "UpdatePreeditTextWithMode") == 0) { ++ GVariant *variant = NULL; ++ gint32 cursor_pos; ++ gboolean visible; ++ guint mode = 0; ++ g_variant_get (parameters, ++ "(vubu)", &variant, &cursor_pos, &visible, &mode); ++ IBusText *text = IBUS_TEXT (ibus_serializable_deserialize (variant)); ++ g_variant_unref (variant); ++ ++ g_signal_emit (context, ++ context_signals[UPDATE_PREEDIT_TEXT_WITH_MODE], ++ 0, ++ text, ++ cursor_pos, ++ visible, ++ mode); ++ ++ if (g_object_is_floating (text)) ++ g_object_unref (text); ++ return; ++ } + + /* lookup signal in table */ + gint i; +@@ -1043,10 +1095,11 @@ ibus_input_context_set_surrounding_text (IBusInputContext *context, + guint32 cursor_pos, + guint32 anchor_pos) + { ++ IBusInputContextPrivate *priv; ++ + g_assert (IBUS_IS_INPUT_CONTEXT (context)); + g_assert (IBUS_IS_TEXT (text)); + +- IBusInputContextPrivate *priv; + priv = IBUS_INPUT_CONTEXT_GET_PRIVATE (context); + + if (cursor_pos != priv->surrounding_cursor_pos || +@@ -1090,12 +1143,15 @@ ibus_input_context_set_content_type (IBusInputContext *context, + guint purpose, + guint hints) + { ++ GVariant *cached_content_type; ++ GVariant *content_type; ++ + g_assert (IBUS_IS_INPUT_CONTEXT (context)); + +- GVariant *cached_content_type = ++ cached_content_type = + g_dbus_proxy_get_cached_property ((GDBusProxy *) context, + "ContentType"); +- GVariant *content_type = g_variant_new ("(uu)", purpose, hints); ++ content_type = g_variant_new ("(uu)", purpose, hints); + + g_variant_ref_sink (content_type); + if (cached_content_type == NULL || +@@ -1142,18 +1198,22 @@ ibus_input_context_get_engine_async_finish (IBusInputContext *context, + GAsyncResult *res, + GError **error) + { ++ GVariant *variant; ++ GVariant *engine_desc_variant; ++ IBusEngineDesc *desc; ++ + g_assert (IBUS_IS_INPUT_CONTEXT (context)); + g_assert (G_IS_ASYNC_RESULT (res)); + g_assert (error == NULL || *error == NULL); + +- GVariant *variant = g_dbus_proxy_call_finish ((GDBusProxy *) context, +- res, error); ++ variant = g_dbus_proxy_call_finish ((GDBusProxy *) context, res, error); + if (variant == NULL) { + return NULL; + } + +- GVariant *engine_desc_variant = g_variant_get_child_value (variant, 0); +- IBusEngineDesc *desc = IBUS_ENGINE_DESC (ibus_serializable_deserialize (engine_desc_variant)); ++ engine_desc_variant = g_variant_get_child_value (variant, 0); ++ desc = IBUS_ENGINE_DESC ( ++ ibus_serializable_deserialize (engine_desc_variant)); + g_variant_unref (engine_desc_variant); + g_variant_unref (variant); + +@@ -1163,9 +1223,13 @@ ibus_input_context_get_engine_async_finish (IBusInputContext *context, + IBusEngineDesc * + ibus_input_context_get_engine (IBusInputContext *context) + { +- g_assert (IBUS_IS_INPUT_CONTEXT (context)); + GVariant *result = NULL; + GError *error = NULL; ++ GVariant *engine_desc_variant; ++ IBusEngineDesc *desc; ++ ++ g_assert (IBUS_IS_INPUT_CONTEXT (context)); ++ + result = g_dbus_proxy_call_sync ((GDBusProxy *) context, + "GetEngine", /* method_name */ + NULL, /* parameters */ +@@ -1189,8 +1253,9 @@ ibus_input_context_get_engine (IBusInputContext *context) + return NULL; + } + +- GVariant *engine_desc_variant = g_variant_get_child_value (result, 0); +- IBusEngineDesc *desc = IBUS_ENGINE_DESC (ibus_serializable_deserialize (engine_desc_variant)); ++ engine_desc_variant = g_variant_get_child_value (result, 0); ++ desc = IBUS_ENGINE_DESC ( ++ ibus_serializable_deserialize (engine_desc_variant)); + g_variant_unref (engine_desc_variant); + g_variant_unref (result); + +@@ -1214,6 +1279,41 @@ ibus_input_context_set_engine (IBusInputContext *context, + ); + } + ++void ++ibus_input_context_set_client_commit_preedit (IBusInputContext *context, ++ gboolean client_commit) ++{ ++ GVariant *cached_content_type; ++ GVariant *var_client_commit; ++ ++ g_assert (IBUS_IS_INPUT_CONTEXT (context)); ++ ++ cached_content_type = ++ g_dbus_proxy_get_cached_property ((GDBusProxy *) context, ++ "ClientCommitPreedit"); ++ var_client_commit = g_variant_new ("(b)", client_commit); ++ ++ g_variant_ref_sink (var_client_commit); ++ if (cached_content_type == NULL) { ++ g_dbus_proxy_call ((GDBusProxy *) context, ++ "org.freedesktop.DBus.Properties.Set", ++ g_variant_new ("(ssv)", ++ IBUS_INTERFACE_INPUT_CONTEXT, ++ "ClientCommitPreedit", ++ var_client_commit), ++ G_DBUS_CALL_FLAGS_NONE, ++ -1, ++ NULL, /* cancellable */ ++ NULL, /* callback */ ++ NULL /* user_data */ ++ ); ++ } ++ ++ if (cached_content_type != NULL) ++ g_variant_unref (cached_content_type); ++ g_variant_unref (var_client_commit); ++} ++ + #define DEFINE_FUNC(name, Name) \ + void \ + ibus_input_context_##name (IBusInputContext *context) \ +diff --git a/src/ibusinputcontext.h b/src/ibusinputcontext.h +index a77cf92f..09992148 100644 +--- a/src/ibusinputcontext.h ++++ b/src/ibusinputcontext.h +@@ -2,7 +2,8 @@ + /* vim:set et sts=4: */ + /* ibus - The Input Bus + * Copyright (C) 2008-2013 Peng Huang +- * Copyright (C) 2008-2013 Red Hat, Inc. ++ * Copyright (C) 2018 Takao Fujiwara ++ * Copyright (C) 2008-2018 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public +@@ -498,5 +499,29 @@ void ibus_input_context_set_content_type + guint purpose, + guint hints); + ++/** ++ * ibus_input_context_set_client_commit_preedit: ++ * @context: An #IBusInputContext. ++ * @client_commit: %TRUE if your input context commits pre-edit texts ++ * with Space or Enter key events or mouse click events. %FALSE if ++ * ibus-daemon commits pre-edit texts with those events. ++ * The default is %FALSE. The behavior is decided with ++ * ibus_engine_update_preedit_text_with_mode() to commit, clear or ++ * keep the pre-edit text and this API is important in ibus-hangul. ++ * ++ * Set whether #IBusInputContext commits pre-edit texts or not. ++ * If %TRUE, 'update-preedit-text-with-mode' signal is emitted ++ * instead of 'update-preedit-text' signal. ++ * If your client receives the 'update-preedit-text-with-mode' signal, ++ * the client needs to implement commit_text() of pre-edit text when ++ * GtkIMContextClass.focus_out() is called in case an IME desires that ++ * behavior but it depends on each IME. ++ * ++ * See also ibus_engine_update_preedit_text_with_mode(). ++ */ ++void ibus_input_context_set_client_commit_preedit ( ++ IBusInputContext *context, ++ gboolean client_commit); ++ + G_END_DECLS + #endif +-- +2.21.0 + +From 7b3b8c8b0c6a41ab524e0be9474825da9cba96ac Mon Sep 17 00:00:00 2001 +From: fujiwarat +Date: Tue, 13 Nov 2018 14:27:52 +0900 +Subject: [PATCH] client/gtk2: Do not delete IBUS_CAP_SURROUNDING_TEXT + +retrieve-surrounding signal could be failed with the first typing +on firefox. It could be a bug in firefox but now IBusIMContext does not +delete IBUS_CAP_SURROUNDING_TEXT in the capabilities as a workaround +when retrieve-surrounding signal is failed. +Also added retrieve-surrounding signal after some committing text. + +BUG=https://github.com/ibus/ibus/issues/2054 +--- + client/gtk2/ibusimcontext.c | 11 ++++++++--- + 1 file changed, 8 insertions(+), 3 deletions(-) + +diff --git a/client/gtk2/ibusimcontext.c b/client/gtk2/ibusimcontext.c +index 73a0eaec..82af51a1 100644 +--- a/client/gtk2/ibusimcontext.c ++++ b/client/gtk2/ibusimcontext.c +@@ -298,6 +298,7 @@ ibus_im_context_commit_event (IBusIMContext *ibusimcontext, + IBusText *text = ibus_text_new_from_unichar (ch); + g_signal_emit (ibusimcontext, _signal_commit_id, 0, text->text); + g_object_unref (text); ++ _request_surrounding_text (ibusimcontext); + return TRUE; + } + return FALSE; +@@ -386,9 +387,12 @@ _request_surrounding_text (IBusIMContext *context) + g_signal_emit (context, _signal_retrieve_surrounding_id, 0, + &return_value); + if (!return_value) { +- context->caps &= ~IBUS_CAP_SURROUNDING_TEXT; +- ibus_input_context_set_capabilities (context->ibuscontext, +- context->caps); ++ /* #2054 firefox::IMContextWrapper::GetCurrentParagraph() could ++ * fail with the first typing on firefox but it succeeds with ++ * the second typing. ++ */ ++ g_warning ("%s has no capability of surrounding-text feature", ++ g_get_prgname ()); + } + } + } +@@ -877,6 +881,7 @@ ibus_im_context_clear_preedit_text (IBusIMContext *ibusimcontext) + ibusimcontext); + g_signal_emit (ibusimcontext, _signal_commit_id, 0, preedit_string); + g_free (preedit_string); ++ _request_surrounding_text (ibusimcontext); + } + } + +-- +2.21.0 + +From 4c40afba9c862b4f6651b1b971553e5e89e83343 Mon Sep 17 00:00:00 2001 +From: fujiwarat +Date: Thu, 6 Dec 2018 16:53:57 +0900 +Subject: [PATCH] client/gtk2: Always reset and clear preedit on mouse click + +Thinking about the reset signal again, now I think it's good to emit +the reset signal and clear the preedit on mouse click for any engines +besides Hangul because the behavior could be handled by each engine +with the reset signal. + +BUG=https://github.com/ibus/ibus/issues/1980 +--- + client/gtk2/ibusimcontext.c | 26 +++++++++++++------------- + 1 file changed, 13 insertions(+), 13 deletions(-) + +diff --git a/client/gtk2/ibusimcontext.c b/client/gtk2/ibusimcontext.c +index 82af51a1..ed7fea6e 100644 +--- a/client/gtk2/ibusimcontext.c ++++ b/client/gtk2/ibusimcontext.c +@@ -869,16 +869,19 @@ ibus_im_context_finalize (GObject *obj) + static void + ibus_im_context_clear_preedit_text (IBusIMContext *ibusimcontext) + { ++ gchar *preedit_string = NULL; + g_assert (ibusimcontext->ibuscontext); + if (ibusimcontext->preedit_visible && + ibusimcontext->preedit_mode == IBUS_ENGINE_PREEDIT_COMMIT) { +- gchar *preedit_string = g_strdup (ibusimcontext->preedit_string); +- _ibus_context_update_preedit_text_cb (ibusimcontext->ibuscontext, +- ibus_text_new_from_string (""), +- 0, +- FALSE, +- IBUS_ENGINE_PREEDIT_CLEAR, +- ibusimcontext); ++ preedit_string = g_strdup (ibusimcontext->preedit_string); ++ } ++ _ibus_context_update_preedit_text_cb (ibusimcontext->ibuscontext, ++ ibus_text_new_from_string (""), ++ 0, ++ FALSE, ++ IBUS_ENGINE_PREEDIT_CLEAR, ++ ibusimcontext); ++ if (preedit_string) { + g_signal_emit (ibusimcontext, _signal_commit_id, 0, preedit_string); + g_free (preedit_string); + _request_surrounding_text (ibusimcontext); +@@ -1114,12 +1117,9 @@ ibus_im_context_button_press_event_cb (GtkWidget *widget, + if (event->button != 1) + return FALSE; + +- if (ibusimcontext->preedit_visible && +- ibusimcontext->preedit_mode == IBUS_ENGINE_PREEDIT_COMMIT) { +- ibus_im_context_clear_preedit_text (ibusimcontext); +- if (ibusimcontext->ibuscontext) +- ibus_input_context_reset (ibusimcontext->ibuscontext); +- } ++ ibus_im_context_clear_preedit_text (ibusimcontext); ++ if (ibusimcontext->ibuscontext) ++ ibus_input_context_reset (ibusimcontext->ibuscontext); + return FALSE; + } + +-- +2.21.0 + +From c7d8771cb9fc652cb638aa7cb8e10ea6b889509e Mon Sep 17 00:00:00 2001 +From: fujiwarat +Date: Tue, 11 Dec 2018 19:16:10 +0900 +Subject: [PATCH] client/gtk2: Fix SEGV on mouse clicks when ibus-daemon not + running + +--- + client/gtk2/ibusimcontext.c | 5 +++-- + 1 file changed, 3 insertions(+), 2 deletions(-) + +diff --git a/client/gtk2/ibusimcontext.c b/client/gtk2/ibusimcontext.c +index ed7fea6e..ab7ff88a 100644 +--- a/client/gtk2/ibusimcontext.c ++++ b/client/gtk2/ibusimcontext.c +@@ -1117,9 +1117,10 @@ ibus_im_context_button_press_event_cb (GtkWidget *widget, + if (event->button != 1) + return FALSE; + +- ibus_im_context_clear_preedit_text (ibusimcontext); +- if (ibusimcontext->ibuscontext) ++ if (ibusimcontext->ibuscontext) { ++ ibus_im_context_clear_preedit_text (ibusimcontext); + ibus_input_context_reset (ibusimcontext->ibuscontext); ++ } + return FALSE; + } + +-- +2.21.0 + +From 9ae2d4658fff3d1e7262fb4fb7ca9ce1af0a27ec Mon Sep 17 00:00:00 2001 +From: fujiwarat +Date: Thu, 20 Dec 2018 16:40:31 +0900 +Subject: [PATCH] client/gtk2: Use button-press-event only with + IBUS_ENGINE_PREEDIT_COMMIT + +BUG=https://github.com/ibus/ibus/issues/1980 +--- + client/gtk2/ibusimcontext.c | 66 ++++++++++++++++++++++++------------- + 1 file changed, 43 insertions(+), 23 deletions(-) + +diff --git a/client/gtk2/ibusimcontext.c b/client/gtk2/ibusimcontext.c +index ab7ff88a..f9310867 100644 +--- a/client/gtk2/ibusimcontext.c ++++ b/client/gtk2/ibusimcontext.c +@@ -72,6 +72,8 @@ struct _IBusIMContext { + /* cancellable */ + GCancellable *cancellable; + GQueue *events_queue; ++ ++ gboolean use_button_press_event; + }; + + struct _IBusIMContextClass { +@@ -1109,6 +1111,7 @@ ibus_im_context_get_preedit_string (GtkIMContext *context, + } + + ++#if !GTK_CHECK_VERSION (3, 93, 0) + static gboolean + ibus_im_context_button_press_event_cb (GtkWidget *widget, + GdkEventButton *event, +@@ -1124,13 +1127,37 @@ ibus_im_context_button_press_event_cb (GtkWidget *widget, + return FALSE; + } + ++static void ++_connect_button_press_event (IBusIMContext *ibusimcontext, ++ gboolean do_connect) ++{ ++ GtkWidget *widget = NULL; ++ ++ g_assert (ibusimcontext->client_window); ++ gdk_window_get_user_data (ibusimcontext->client_window, ++ (gpointer *)&widget); ++ /* firefox needs GtkWidget instead of GtkWindow */ ++ if (GTK_IS_WIDGET (widget)) { ++ if (do_connect) { ++ g_signal_connect ( ++ widget, ++ "button-press-event", ++ G_CALLBACK (ibus_im_context_button_press_event_cb), ++ ibusimcontext); ++ } else { ++ g_signal_handlers_disconnect_by_func ( ++ widget, ++ G_CALLBACK (ibus_im_context_button_press_event_cb), ++ ibusimcontext); ++ } ++ } ++} ++#endif ++ + static void + ibus_im_context_set_client_window (GtkIMContext *context, GdkWindow *client) + { + IBusIMContext *ibusimcontext; +-#if !GTK_CHECK_VERSION (3, 93, 0) +- GtkWidget *widget; +-#endif + + IDEBUG ("%s", __FUNCTION__); + +@@ -1138,15 +1165,8 @@ ibus_im_context_set_client_window (GtkIMContext *context, GdkWindow *client) + + if (ibusimcontext->client_window) { + #if !GTK_CHECK_VERSION (3, 93, 0) +- gdk_window_get_user_data (ibusimcontext->client_window, +- (gpointer *)&widget); +- /* firefox needs GtkWidget instead of GtkWindow */ +- if (GTK_IS_WIDGET (widget)) { +- g_signal_handlers_disconnect_by_func ( +- widget, +- (GCallback)ibus_im_context_button_press_event_cb, +- ibusimcontext); +- } ++ if (ibusimcontext->use_button_press_event) ++ _connect_button_press_event (ibusimcontext, FALSE); + #endif + g_object_unref (ibusimcontext->client_window); + ibusimcontext->client_window = NULL; +@@ -1155,17 +1175,8 @@ ibus_im_context_set_client_window (GtkIMContext *context, GdkWindow *client) + if (client != NULL) { + ibusimcontext->client_window = g_object_ref (client); + #if !GTK_CHECK_VERSION (3, 93, 0) +- gdk_window_get_user_data (ibusimcontext->client_window, +- (gpointer *)&widget); +- +- /* firefox needs GtkWidget instead of GtkWindow */ +- if (GTK_IS_WIDGET (widget)) { +- g_signal_connect ( +- widget, +- "button-press-event", +- G_CALLBACK (ibus_im_context_button_press_event_cb), +- ibusimcontext); +- } ++ if (ibusimcontext->use_button_press_event) ++ _connect_button_press_event (ibusimcontext, TRUE); + #endif + } + if (ibusimcontext->slave) +@@ -1631,6 +1642,15 @@ _ibus_context_update_preedit_text_cb (IBusInputContext *ibuscontext, + ibusimcontext->preedit_attrs = NULL; + } + ++ if (!ibusimcontext->use_button_press_event && ++ mode == IBUS_ENGINE_PREEDIT_COMMIT) { ++#if !GTK_CHECK_VERSION (3, 93, 0) ++ if (ibusimcontext->client_window) ++ _connect_button_press_event (ibusimcontext, TRUE); ++#endif ++ ibusimcontext->use_button_press_event = TRUE; ++ } ++ + str = text->text; + ibusimcontext->preedit_string = g_strdup (str); + if (text->attrs) { +-- +2.21.0 + +From 0fd043c3b4c90855bfb4fceed4bf2f3c3635a041 Mon Sep 17 00:00:00 2001 +From: fujiwarat +Date: Tue, 8 Jan 2019 12:02:32 +0900 +Subject: [PATCH] portal: Update APIs for Hangul preedit in Flatpak + +BUG=https://github.com/ibus/ibus/issues/1980 +--- + portal/org.freedesktop.IBus.Portal.xml | 9 ++++++++- + portal/portal.c | 18 +++++++++++++++++- + 2 files changed, 25 insertions(+), 2 deletions(-) + +diff --git a/portal/org.freedesktop.IBus.Portal.xml b/portal/org.freedesktop.IBus.Portal.xml +index afce4daa..376ad424 100644 +--- a/portal/org.freedesktop.IBus.Portal.xml ++++ b/portal/org.freedesktop.IBus.Portal.xml +@@ -1,6 +1,6 @@ + +