Compare commits

..

No commits in common. "c8" and "c10s" have entirely different histories.
c8 ... c10s

36 changed files with 1974 additions and 6144 deletions

1
.fmf/version Normal file
View File

@ -0,0 +1 @@
1

78
.gitignore vendored
View File

@ -1,2 +1,76 @@
SOURCES/ibus-1.5.19.tar.gz /cldr-emoji-annotation-30.0.3_2.tar.gz
SOURCES/ibus-po-1.5.19-20210706.tar.gz /ibus-gjs-3.0.2.20110823.tar.gz
/ibus-gjs-3.1.4.20110823.tar.gz
/ibus-gjs-3.0.2.20110908.tar.gz
/ibus-gjs-3.1.91.20110908.tar.gz
/ibus-gjs-3.1.91.20110913.tar.gz
/ibus-gjs-3.0.2.20110928.tar.gz
/ibus-gjs-3.2.0.20110928.tar.gz
/ibus-gjs-3.0.2.20111018.tar.gz
/ibus-gjs-3.2.0.20111018.tar.gz
/ibus-gjs-3.2.1.20111021.tar.gz
/ibus-gjs-3.0.2.20111028.tar.gz
/ibus-gjs-3.2.1.20111028.tar.gz
/ibus-gjs-3.0.2.20111104.tar.gz
/ibus-gjs-3.2.1.20111104.tar.gz
/ibus-gjs-3.0.2.20111118.tar.gz
/ibus-gjs-3.2.1.20111118.tar.gz
/ibus-gjs-3.2.1.20111128.tar.gz
/ibus-gjs-3.2.1.20111230.tar.gz
/ibus-gjs-3.3.3.20120203.tar.gz
/ibus-gjs-3.3.90.20120308.tar.gz
/ibus-gjs-3.3.90.20120317.tar.gz
/ibus-gjs-3.3.92.20120327.tar.gz
/ibus-gjs-3.4.1.20120428.tar.gz
/ibus-gjs-3.4.1.20120518.tar.gz
/ibus-gjs-3.4.1.20120815.tar.gz
/ibus-gjs-3.4.1.20130115.tar.gz
/ibus-xkb-1.5.0.tar.gz
/ibus-xkb-1.5.0.20140114.tar.gz
/ibus-po-1.5.22-20200914.tar.gz
/ibus-simple-1.5.22.20200909.xml.gz
ibus-1.3.6.tar.gz
/ibus-1.3.7.tar.gz
/ibus-1.3.8.tar.gz
/ibus-1.3.9.tar.gz
/ibus-1.4.0.tar.gz
/ibus-1.4.1.tar.gz
/ibus-1.5.1.tar.gz
/ibus-1.5.2.tar.gz
/ibus-1.5.3.tar.gz
/ibus-1.5.4.tar.gz
/ibus-1.5.5.tar.gz
/ibus-1.5.6.tar.gz
/ibus-1.5.7.tar.gz
/ibus-1.5.8.tar.gz
/ibus-1.5.9.tar.gz
/ibus-1.5.10.tar.gz
/ibus-1.5.11.tar.gz
/ibus-1.5.12.tar.gz
/ibus-1.5.13.tar.gz
/ibus-1.5.14.tar.gz
/ibus-1.5.15.tar.gz
/ibus-1.5.16.tar.gz
/ibus-1.5.17.tar.gz
/ibus-1.5.18.tar.gz
/ibus-1.5.19.tar.gz
/ibus-1.5.20.tar.gz
/ibus-1.5.21.tar.gz
/ibus-1.5.22.tar.gz
/ibus-1.5.23.tar.gz
/ibus-1.5.24.tar.gz
/ibus-1.5.25.tar.gz
/ibus-1.5.26.tar.gz
/ibus-1.5.27.tar.gz
/ibus-1.5.28.tar.gz
/ibus-1.5.29-beta1.tar.gz
/ibus-1.5.29-beta2.tar.gz
/ibus-1.5.29-rc1.tar.gz
/ibus-1.5.29-rc2.tar.gz
/ibus-1.5.30-beta1.tar.gz
/ibus-1.5.30-rc1.tar.gz
/ibus-1.5.30-rc2.tar.gz
/ibus-1.5.30-rc3.tar.gz
/ibus-1.5.30.tar.gz
/ibus-1.5.31-beta1.tar.gz
/ibus-1.5.31.tar.gz

View File

@ -1,2 +0,0 @@
fdda025d81247e40ad7acf953c2a0a606d18e965 SOURCES/ibus-1.5.19.tar.gz
236f5dc3c072d0587e107ae75084454c791bbf73 SOURCES/ibus-po-1.5.19-20210706.tar.gz

View File

@ -1,214 +0,0 @@
From 865b204f1c06b782cf7b4a479b358e76f4b3dfee Mon Sep 17 00:00:00 2001
From: fujiwarat <takao.fujiwara1@gmail.com>
Date: Tue, 17 Jul 2018 13:39:30 +0900
Subject: [PATCH] bus: Fix SEGV in bus_panel_proxy_focus_in()
BUG=rhbz#1349148
BUG=rhbz#1385349
BUG=rhbz#1350291
BUG=rhbz#1406699
BUG=rhbz#1432252
BUG=rhbz#1601577
---
bus/dbusimpl.c | 38 ++++++++++++++++++++++++++++++++------
bus/engineproxy.c | 5 ++++-
bus/ibusimpl.c | 21 ++++++++++++++++++---
3 files changed, 54 insertions(+), 10 deletions(-)
diff --git a/bus/dbusimpl.c b/bus/dbusimpl.c
index b54ef817..e4dd8683 100644
--- a/bus/dbusimpl.c
+++ b/bus/dbusimpl.c
@@ -2,7 +2,8 @@
/* vim:set et sts=4: */
/* ibus - The Input Bus
* Copyright (C) 2008-2013 Peng Huang <shawn.p.huang@gmail.com>
- * Copyright (C) 2008-2013 Red Hat, Inc.
+ * Copyright (C) 2015-2017 Takao Fujiwara <takao.fujiwara1@gmail.com>
+ * Copyright (C) 2008-2017 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
@@ -344,6 +345,8 @@ bus_name_service_set_primary_owner (BusNameService *service,
BusConnectionOwner *owner,
BusDBusImpl *dbus)
{
+ gboolean has_old_owner = FALSE;
+
g_assert (service != NULL);
g_assert (owner != NULL);
g_assert (dbus != NULL);
@@ -351,6 +354,13 @@ bus_name_service_set_primary_owner (BusNameService *service,
BusConnectionOwner *old = service->owners != NULL ?
(BusConnectionOwner *)service->owners->data : NULL;
+ /* rhbz#1432252 If bus_connection_get_unique_name() == NULL,
+ * "Hello" method is not received yet.
+ */
+ if (old != NULL && bus_connection_get_unique_name (old->conn) != NULL) {
+ has_old_owner = TRUE;
+ }
+
if (old != NULL) {
g_signal_emit (dbus,
dbus_signals[NAME_LOST],
@@ -370,7 +380,8 @@ bus_name_service_set_primary_owner (BusNameService *service,
0,
owner->conn,
service->name,
- old != NULL ? bus_connection_get_unique_name (old->conn) : "",
+ has_old_owner ? bus_connection_get_unique_name (old->conn) :
+ "",
bus_connection_get_unique_name (owner->conn));
if (old != NULL && old->do_not_queue != 0) {
@@ -427,6 +438,7 @@ bus_name_service_remove_owner (BusNameService *service,
BusDBusImpl *dbus)
{
GSList *owners;
+ gboolean has_new_owner = FALSE;
g_assert (service != NULL);
g_assert (owner != NULL);
@@ -439,6 +451,13 @@ bus_name_service_remove_owner (BusNameService *service,
BusConnectionOwner *_new = NULL;
if (owners->next != NULL) {
_new = (BusConnectionOwner *)owners->next->data;
+ /* rhbz#1406699 If bus_connection_get_unique_name() == NULL,
+ * "Hello" method is not received yet.
+ */
+ if (_new != NULL &&
+ bus_connection_get_unique_name (_new->conn) != NULL) {
+ has_new_owner = TRUE;
+ }
}
if (dbus != NULL) {
@@ -447,7 +466,7 @@ bus_name_service_remove_owner (BusNameService *service,
0,
owner->conn,
service->name);
- if (_new != NULL) {
+ if (has_new_owner) {
g_signal_emit (dbus,
dbus_signals[NAME_ACQUIRED],
0,
@@ -460,7 +479,7 @@ bus_name_service_remove_owner (BusNameService *service,
_new != NULL ? _new->conn : NULL,
service->name,
bus_connection_get_unique_name (owner->conn),
- _new != NULL ? bus_connection_get_unique_name (_new->conn) : "");
+ has_new_owner ? bus_connection_get_unique_name (_new->conn) : "");
}
}
@@ -1464,13 +1483,20 @@ bus_dbus_impl_connection_filter_cb (GDBusConnection *dbus_connection,
gboolean incoming,
gpointer user_data)
{
+ BusDBusImpl *dbus;
+ BusConnection *connection;
+
g_assert (G_IS_DBUS_CONNECTION (dbus_connection));
g_assert (G_IS_DBUS_MESSAGE (message));
g_assert (BUS_IS_DBUS_IMPL (user_data));
- BusDBusImpl *dbus = (BusDBusImpl *) user_data;
- BusConnection *connection = bus_connection_lookup (dbus_connection);
+ if (g_dbus_connection_is_closed (dbus_connection))
+ return NULL;
+
+ dbus = (BusDBusImpl *) user_data;
+ connection = bus_connection_lookup (dbus_connection);
g_assert (connection != NULL);
+ g_assert (BUS_IS_CONNECTION (connection));
if (incoming) {
/* is incoming message */
diff --git a/bus/engineproxy.c b/bus/engineproxy.c
index 2d98995c..d661673a 100644
--- a/bus/engineproxy.c
+++ b/bus/engineproxy.c
@@ -665,6 +665,7 @@ bus_engine_proxy_new_internal (const gchar *path,
IBusEngineDesc *desc,
GDBusConnection *connection)
{
+ GError *error = NULL;
g_assert (path);
g_assert (IBUS_IS_ENGINE_DESC (desc));
g_assert (G_IS_DBUS_CONNECTION (connection));
@@ -673,7 +674,7 @@ bus_engine_proxy_new_internal (const gchar *path,
BusEngineProxy *engine =
(BusEngineProxy *) g_initable_new (BUS_TYPE_ENGINE_PROXY,
NULL,
- NULL,
+ &error,
"desc", desc,
"g-connection", connection,
"g-interface-name", IBUS_INTERFACE_ENGINE,
@@ -681,6 +682,8 @@ bus_engine_proxy_new_internal (const gchar *path,
"g-default-timeout", g_gdbus_timeout,
"g-flags", flags,
NULL);
+ /* FIXME: rhbz#1601577 */
+ g_assert_no_error (error);
const gchar *layout = ibus_engine_desc_get_layout (desc);
if (layout != NULL && layout[0] != '\0') {
engine->keymap = ibus_keymap_get (layout);
diff --git a/bus/ibusimpl.c b/bus/ibusimpl.c
index ec1caea8..9ae3751b 100644
--- a/bus/ibusimpl.c
+++ b/bus/ibusimpl.c
@@ -484,13 +484,16 @@ _dbus_name_owner_changed_cb (BusDBusImpl *dbus,
else if (!g_strcmp0 (name, IBUS_SERVICE_PANEL_EXTENSION_EMOJI))
panel_type = PANEL_TYPE_EXTENSION_EMOJI;
- if (panel_type != PANEL_TYPE_NONE) {
+ do {
+ if (panel_type == PANEL_TYPE_NONE)
+ break;
if (g_strcmp0 (new_name, "") != 0) {
/* a Panel process is started. */
BusConnection *connection;
BusInputContext *context = NULL;
BusPanelProxy **panel = (panel_type == PANEL_TYPE_PANEL) ?
&ibus->panel : &ibus->emoji_extension;
+ GDBusConnection *dbus_connection = NULL;
if (*panel != NULL) {
ibus_proxy_destroy ((IBusProxy *)(*panel));
@@ -499,9 +502,21 @@ _dbus_name_owner_changed_cb (BusDBusImpl *dbus,
g_assert (*panel == NULL);
}
- connection = bus_dbus_impl_get_connection_by_name (BUS_DEFAULT_DBUS, new_name);
+ connection = bus_dbus_impl_get_connection_by_name (BUS_DEFAULT_DBUS,
+ new_name);
g_return_if_fail (connection != NULL);
+ dbus_connection = bus_connection_get_dbus_connection (connection);
+ /* rhbz#1349148 rhbz#1385349
+ * Avoid SEGV of BUS_IS_PANEL_PROXY (ibus->panel)
+ * This function is called during destroying the connection
+ * in this case? */
+ if (dbus_connection == NULL ||
+ g_dbus_connection_is_closed (dbus_connection)) {
+ new_name = "";
+ break;
+ }
+
*panel = bus_panel_proxy_new (connection, panel_type);
if (panel_type == PANEL_TYPE_EXTENSION_EMOJI)
ibus->enable_emoji_extension = FALSE;
@@ -555,7 +570,7 @@ _dbus_name_owner_changed_cb (BusDBusImpl *dbus,
}
}
}
- }
+ } while (0);
bus_ibus_impl_component_name_owner_changed (ibus, name, old_name, new_name);
}
--
2.17.1

View File

@ -1,48 +0,0 @@
From 0f5084e07c215d74adc4eeeda40b374855cce59a Mon Sep 17 00:00:00 2001
From: fujiwarat <takao.fujiwara1@gmail.com>
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 <shawn.p.huang@gmail.com>
- * Copyright (C) 2013-2018 Takao Fujiwara <takao.fujiwara1@gmail.com>
+ * Copyright (C) 2013-2019 Takao Fujiwara <takao.fujiwara1@gmail.com>
*
* 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

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -1,179 +0,0 @@
From 3d442dbf936d197aa11ca0a71663c2bc61696151 Mon Sep 17 00:00:00 2001
From: fujiwarat <takao.fujiwara1@gmail.com>
Date: Fri, 13 Sep 2019 15:59:03 +0900
Subject: [PATCH] bus: Implement GDBusAuthObserver callback
ibus uses a GDBusServer with G_DBUS_SERVER_FLAGS_AUTHENTICATION_ALLOW_ANONYMOUS,
and doesn't set a GDBusAuthObserver, which allows anyone who can connect
to its AF_UNIX socket to authenticate and be authorized to send method calls.
It also seems to use an abstract AF_UNIX socket, which does not have
filesystem permissions, so the practical effect might be that a local
attacker can connect to another user's ibus service and make arbitrary
method calls.
BUGS=rhbz#1717958
---
bus/server.c | 89 ++++++++++++++++++++++++++++++++++++++++++----------
1 file changed, 73 insertions(+), 16 deletions(-)
diff --git a/bus/server.c b/bus/server.c
index 3a626230..2439de14 100644
--- a/bus/server.c
+++ b/bus/server.c
@@ -2,7 +2,8 @@
/* vim:set et sts=4: */
/* bus - The Input Bus
* Copyright (C) 2008-2010 Peng Huang <shawn.p.huang@gmail.com>
- * Copyright (C) 2008-2010 Red Hat, Inc.
+ * Copyright (C) 2011-2019 Takao Fujiwara <takao.fujiwara1@gmail.com>
+ * Copyright (C) 2008-2019 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
@@ -70,16 +71,63 @@ _restart_server (void)
}
/**
+ * bus_allow_mechanism_cb:
+ * @observer: A #GDBusAuthObserver.
+ * @mechanism: The name of the mechanism.
+ * @user_data: always %NULL.
+ *
+ * Check if @mechanism can be used to authenticate the other peer.
+ * Returns: %TRUE if the peer's mechanism is allowed.
+ */
+static gboolean
+bus_allow_mechanism_cb (GDBusAuthObserver *observer,
+ const gchar *mechanism,
+ G_GNUC_UNUSED gpointer user_data)
+{
+ if (g_strcmp0 (mechanism, "EXTERNAL") == 0)
+ return TRUE;
+ return FALSE;
+}
+
+/**
+ * bus_authorize_authenticated_peer_cb:
+ * @observer: A #GDBusAuthObserver.
+ * @stream: A #GIOStream.
+ * @credentials: A #GCredentials.
+ * @user_data: always %NULL.
+ *
+ * Check if a peer who has already authenticated should be authorized.
+ * Returns: %TRUE if the peer's credential is authorized.
+ */
+static gboolean
+bus_authorize_authenticated_peer_cb (GDBusAuthObserver *observer,
+ GIOStream *stream,
+ GCredentials *credentials,
+ G_GNUC_UNUSED gpointer user_data)
+{
+ gboolean authorized = FALSE;
+ if (credentials) {
+ GCredentials *own_credentials = g_credentials_new ();
+ if (g_credentials_is_same_user (credentials, own_credentials, NULL))
+ authorized = TRUE;
+ g_object_unref (own_credentials);
+ }
+ return authorized;
+}
+
+/**
* bus_new_connection_cb:
- * @user_data: always NULL.
- * @returns: TRUE when the function can handle the connection.
+ * @observer: A #GDBusAuthObserver.
+ * @dbus_connection: A #GDBusconnection.
+ * @user_data: always %NULL.
*
* Handle incoming connections.
+ * Returns: %TRUE when the function can handle the connection.
*/
static gboolean
-bus_new_connection_cb (GDBusServer *server,
- GDBusConnection *dbus_connection,
- gpointer user_data)
+bus_new_connection_cb (GDBusServer *server,
+ GDBusConnection *dbus_connection,
+ G_GNUC_UNUSED gpointer user_data)
{
BusConnection *connection = bus_connection_new (dbus_connection);
bus_dbus_impl_new_connection (dbus, connection);
@@ -94,9 +142,9 @@ bus_new_connection_cb (GDBusServer *
}
static void
-_server_connect_start_portal_cb (GObject *source_object,
- GAsyncResult *res,
- gpointer user_data)
+_server_connect_start_portal_cb (GObject *source_object,
+ GAsyncResult *res,
+ G_GNUC_UNUSED gpointer user_data)
{
GVariant *result;
GError *error = NULL;
@@ -113,9 +161,9 @@ _server_connect_start_portal_cb (GObject
}
static void
-bus_acquired_handler (GDBusConnection *connection,
- const gchar *name,
- gpointer user_data)
+bus_acquired_handler (GDBusConnection *connection,
+ const gchar *name,
+ G_GNUC_UNUSED gpointer user_data)
{
g_dbus_connection_call (connection,
IBUS_SERVICE_PORTAL,
@@ -136,22 +184,27 @@ void
bus_server_init (void)
{
GError *error = NULL;
+ GDBusServerFlags flags = G_DBUS_SERVER_FLAGS_NONE;
+ gchar *guid;
+ GDBusAuthObserver *observer;
dbus = bus_dbus_impl_get_default ();
ibus = bus_ibus_impl_get_default ();
bus_dbus_impl_register_object (dbus, (IBusService *)ibus);
/* init server */
- GDBusServerFlags flags = G_DBUS_SERVER_FLAGS_AUTHENTICATION_ALLOW_ANONYMOUS;
- gchar *guid = g_dbus_generate_guid ();
- if (!g_str_has_prefix (g_address, "unix:tmpdir=")) {
- g_error ("Your socket address does not have the format unix:tmpdir=$DIR; %s",
- g_address);
+ guid = g_dbus_generate_guid ();
+ observer = g_dbus_auth_observer_new ();
+ if (!g_str_has_prefix (g_address, "unix:tmpdir=") &&
+ !g_str_has_prefix (g_address, "unix:path=")) {
+ g_error ("Your socket address does not have the format unix:tmpdir=$DIR "
+ "or unix:path=$FILE; %s", g_address);
+
}
server = g_dbus_server_new_sync (
g_address, /* the place where the socket file lives, e.g. /tmp, abstract namespace, etc. */
flags, guid,
- NULL /* observer */,
+ observer,
NULL /* cancellable */,
&error);
if (server == NULL) {
@@ -161,7 +214,13 @@ bus_server_init (void)
}
g_free (guid);
- g_signal_connect (server, "new-connection", G_CALLBACK (bus_new_connection_cb), NULL);
+ g_signal_connect (observer, "allow-mechanism",
+ G_CALLBACK (bus_allow_mechanism_cb), NULL);
+ g_signal_connect (observer, "authorize-authenticated-peer",
+ G_CALLBACK (bus_authorize_authenticated_peer_cb), NULL);
+ g_object_unref (observer);
+ g_signal_connect (server, "new-connection",
+ G_CALLBACK (bus_new_connection_cb), NULL);
g_dbus_server_start (server);
--
2.21.0

View File

@ -1,347 +0,0 @@
From c38e925eba2b1f7af39696e2f64ec1eaea94b00b Mon Sep 17 00:00:00 2001
From: Takao Fujiwara <fujiwara@redhat.com>
Date: Thu, 30 Sep 2021 09:36:12 -0400
Subject: [PATCH] Backport IBus Unicode feature
---
configure.ac | 10 +++++++
ui/gtk3/Makefile.am | 5 +++-
ui/gtk3/emojier.vala | 37 +++++++++++++++--------
ui/gtk3/emojierapp.vala | 63 ++++++++++++++++++++++++++++-----------
ui/gtk3/panelbinding.vala | 13 ++++++--
5 files changed, 93 insertions(+), 35 deletions(-)
diff --git a/configure.ac b/configure.ac
index 46ab7a9..26bb357 100644
--- a/configure.ac
+++ b/configure.ac
@@ -237,12 +237,21 @@ if test x"$enable_gtk3" = x"yes"; then
PKG_CHECK_MODULES(GTK3, [
gtk+-3.0
])
+ PKG_CHECK_EXISTS([gdk-wayland-3.0],
+ [enable_gdk3_wayland=yes],
+ [enable_gdk3_wayland=no]
+ )
gtk3_binary_version=`$PKG_CONFIG --variable=gtk_binary_version gtk+-3.0`
GTK3_IM_MODULEDIR="$libdir"/gtk-3.0/$gtk3_binary_version/immodules
else
enable_gtk3="no (disabled, use --enable-gtk3 to enable)"
+ enable_gdk3_wayland=no
+fi
+if test x"$enable_gdk3_wayland" != x"yes"; then
+ enable_gdk3_wayland="no (disabled, need to install gdk-wayland-3.0.pc)"
fi
+AM_CONDITIONAL([ENABLE_GDK3_WAYLAND], [test x"$enable_gdk3_wayland" = x"yes"])
if test x"$enable_xim" = x"yes"; then
# Check for x11
@@ -796,6 +805,7 @@ Build options:
Build gtk3 immodule $enable_gtk3
Build XIM agent server $enable_xim
Build wayland support $enable_wayland
+ Build gdk3 wayland support $enable_gdk3_wayland
Build appindicator support $enable_appindicator
Build appindicator engine icon $enable_appindicator_engine_icon
Build python library $enable_python_library
diff --git a/ui/gtk3/Makefile.am b/ui/gtk3/Makefile.am
index aaba7a4..6ebc96c 100644
--- a/ui/gtk3/Makefile.am
+++ b/ui/gtk3/Makefile.am
@@ -78,7 +78,6 @@ AM_VALAFLAGS = \
--pkg=ibus-1.0 \
--pkg=config \
--pkg=xi \
- --pkg=gdk-wayland \
--target-glib="$(VALA_TARGET_GLIB_VERSION)" \
$(NULL)
@@ -105,6 +104,10 @@ if ENABLE_APPINDICATOR_ENGINE_ICON
AM_VALAFLAGS += --define=INDICATOR_ENGINE_ICON
endif
+if ENABLE_GDK3_WAYLAND
+AM_VALAFLAGS += --pkg=gdk-wayland --define=USE_GDK_WAYLAND
+endif
+
libexec_PROGRAMS = ibus-ui-gtk3
ibus_ui_gtk3_SOURCES = \
diff --git a/ui/gtk3/emojier.vala b/ui/gtk3/emojier.vala
index 3eac2f2..9e6e926 100644
--- a/ui/gtk3/emojier.vala
+++ b/ui/gtk3/emojier.vala
@@ -2,7 +2,7 @@
*
* ibus - The Input Bus
*
- * Copyright (c) 2017-2018 Takao Fujiwara <takao.fujiwara1@gmail.com>
+ * Copyright (c) 2017-2019 Takao Fujiwara <takao.fujiwara1@gmail.com>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -320,6 +320,7 @@ public class IBusEmojier : Gtk.ApplicationWindow {
public signal void candidate_clicked(uint index, uint button, uint state);
public signal void commit_text(string text);
+ public signal void cancel();
public IBusEmojier() {
GLib.Object(
@@ -864,7 +865,7 @@ public class IBusEmojier : Gtk.ApplicationWindow {
row.get_allocation(out alloc);
var adjustment = m_scrolled_window.get_vadjustment();
adjustment.clamp_page(alloc.y, alloc.y + alloc.height);
- return_val_if_fail(m_category_active_index >= 0, false);
+ return_if_fail(m_category_active_index >= 0);
m_lookup_table.set_cursor_pos((uint)m_category_active_index);
}
@@ -936,8 +937,13 @@ public class IBusEmojier : Gtk.ApplicationWindow {
update_unicode_blocks();
return;
} else {
- unowned GLib.SList<unowned string> emojis =
- m_category_to_emojis_dict.lookup(category);
+ // Use copy_deep() since vala 0.43.4 does not allow to assign
+ // a weak pointer to the full one in SList:
+ // emojier.vala:885.48-886.62: error: Assignment: Cannot convert
+ // from `GLib.SList<string>' to `GLib.SList<weak string>?'
+ GLib.SList<string> emojis =
+ m_category_to_emojis_dict.lookup(category).copy_deep(
+ GLib.strdup);
m_lookup_table.clear();
m_candidate_panel_mode = true;
foreach (unowned string emoji in emojis) {
@@ -1601,8 +1607,8 @@ public class IBusEmojier : Gtk.ApplicationWindow {
m_vbox.add(widget);
widget.show_all();
}
- unowned GLib.SList<unowned string>? annotations =
- data.get_annotations();
+ GLib.SList<string> annotations =
+ data.get_annotations().copy_deep(GLib.strdup);
var buff = new GLib.StringBuilder();
int i = 0;
foreach (unowned string annotation in annotations) {
@@ -1784,8 +1790,7 @@ public class IBusEmojier : Gtk.ApplicationWindow {
show_emoji_variants(emojis);
return true;
}
- if (m_input_context_path != "")
- m_result = text;
+ m_result = text;
if (need_commit_signal)
commit_text(text);
return false;
@@ -1892,6 +1897,7 @@ public class IBusEmojier : Gtk.ApplicationWindow {
// PageUp/PageDown.
remove_all_children();
}
+ cancel();
return false;
}
@@ -2055,17 +2061,20 @@ public class IBusEmojier : Gtk.ApplicationWindow {
) as IBus.EmojiData;
m_emoji_to_data_dict.insert(favorite, new_data);
} else {
- unowned GLib.SList<string> annotations = data.get_annotations();
+ GLib.SList<string> annotations =
+ data.get_annotations().copy_deep(GLib.strdup);
if (annotations.find_custom(annotation, GLib.strcmp) == null) {
annotations.append(annotation);
- data.set_annotations(annotations.copy());
+ data.set_annotations(annotations.copy_deep(GLib.strdup));
}
}
unowned GLib.SList<string> emojis =
m_annotation_to_emojis_dict.lookup(annotation);
if (emojis.find_custom(favorite, GLib.strcmp) == null) {
emojis.append(favorite);
- m_annotation_to_emojis_dict.replace(annotation, emojis.copy());
+ m_annotation_to_emojis_dict.replace(
+ annotation,
+ emojis.copy_deep(GLib.strdup));
}
}
}
@@ -2117,7 +2126,7 @@ public class IBusEmojier : Gtk.ApplicationWindow {
public string get_current_candidate() {
// If category_list mode, do not show the category name on preedit.
// If candidate_panel mode, the first space key does not show the
- // lookup table but the first candidate is avaiable on preedit.
+ // lookup table but the first candidate is available on preedit.
if (!m_candidate_panel_mode)
return "";
uint cursor = m_lookup_table.get_cursor_pos();
@@ -2139,11 +2148,13 @@ public class IBusEmojier : Gtk.ApplicationWindow {
ncandidates));
int char_count = text.text.char_count();
int start_index = -1;
+ unowned string title = text.text;
for (int i = 0; i < char_count; i++) {
- if (text.text.utf8_offset(i).has_prefix(language)) {
+ if (title.has_prefix(language)) {
start_index = i;
break;
}
+ title = title.next_char();
}
if (start_index >= 0) {
var attr = new IBus.Attribute(
diff --git a/ui/gtk3/emojierapp.vala b/ui/gtk3/emojierapp.vala
index fab99d9..7bc7b42 100644
--- a/ui/gtk3/emojierapp.vala
+++ b/ui/gtk3/emojierapp.vala
@@ -3,6 +3,7 @@
* ibus - The Input Bus
*
* Copyright (c) 2017 Peng Wu <alexepico@gmail.com>
+ * Copyright (c) 2017-2019 Takao Fujiwara <takao.fujiwara1@gmail.com>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -40,6 +41,33 @@ public class EmojiApplication : Gtk.Application {
}
+ private void save_selected_string(string? selected_string,
+ bool cancelled) {
+ if (cancelled) {
+ m_command_line.print("%s\n", _("Canceled to choose an emoji."));
+ return;
+ }
+ GLib.return_if_fail(selected_string != null);
+ Gtk.Clipboard clipboard = Gtk.Clipboard.get(Gdk.SELECTION_CLIPBOARD);
+ clipboard.set_text(selected_string, -1);
+ clipboard.store();
+
+ var emojier_favorites = m_settings_emoji.get_strv("favorites");
+ bool has_favorite = false;
+ foreach (unowned string favorite in emojier_favorites) {
+ if (favorite == selected_string) {
+ has_favorite = true;
+ break;
+ }
+ }
+ if (!has_favorite) {
+ emojier_favorites += selected_string;
+ m_settings_emoji.set_strv("favorites", emojier_favorites);
+ }
+ m_command_line.print("%s\n", _("Copied an emoji to your clipboard."));
+ }
+
+
private void show_dialog(ApplicationCommandLine command_line) {
m_command_line = command_line;
m_emojier.reset();
@@ -55,7 +83,7 @@ public class EmojiApplication : Gtk.Application {
return;
if (button == IBusEmojier.BUTTON_CLOSE_BUTTON) {
m_emojier.hide();
- m_command_line.print("%s\n", _("Canceled to choose an emoji."));
+ save_selected_string(null, true);
m_command_line = null;
return;
}
@@ -74,23 +102,7 @@ public class EmojiApplication : Gtk.Application {
}
string emoji = m_emojier.get_current_candidate();
m_emojier.hide();
- Gtk.Clipboard clipboard = Gtk.Clipboard.get(Gdk.SELECTION_CLIPBOARD);
- clipboard.set_text(emoji, -1);
- clipboard.store();
-
- var emojier_favorites = m_settings_emoji.get_strv("favorites");
- bool has_favorite = false;
- foreach (unowned string favorite in emojier_favorites) {
- if (favorite == emoji) {
- has_favorite = true;
- break;
- }
- }
- if (!has_favorite) {
- emojier_favorites += emoji;
- m_settings_emoji.set_strv("favorites", emojier_favorites);
- }
- m_command_line.print("%s\n", _("Copied an emoji to your clipboard."));
+ save_selected_string(emoji, false);
m_command_line = null;
}
@@ -202,6 +214,21 @@ public class EmojiApplication : Gtk.Application {
m_emojier.candidate_clicked.connect((i, b, s) => {
candidate_clicked_lookup_table(i, b, s);
});
+ m_emojier.cancel.connect(() => {
+ if (m_command_line == null)
+ return;
+ m_emojier.hide();
+ save_selected_string(null, true);
+ m_command_line = null;
+ });
+ m_emojier.commit_text.connect(() => {
+ if (m_command_line == null)
+ return;
+ m_emojier.hide();
+ string selected_string = m_emojier.get_selected_string();
+ save_selected_string(selected_string, false);
+ m_command_line = null;
+ });
}
activate_dialog(command_line);
diff --git a/ui/gtk3/panelbinding.vala b/ui/gtk3/panelbinding.vala
index cfedb2d..861255b 100644
--- a/ui/gtk3/panelbinding.vala
+++ b/ui/gtk3/panelbinding.vala
@@ -3,7 +3,7 @@
* ibus - The Input Bus
*
* Copyright(c) 2018 Peng Huang <shawn.p.huang@gmail.com>
- * Copyright(c) 2018 Takao Fujwiara <takao.fujiwara1@gmail.com>
+ * Copyright(c) 2018-2020 Takao Fujwiara <takao.fujiwara1@gmail.com>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -190,7 +190,7 @@ class Preedit : Gtk.Window {
public IBus.Text get_commit_text() {
string extension_text = m_extension_preedit_emoji.get_text();
- if (extension_text.length == 0)
+ if (extension_text.length == 0 && m_prefix != "u")
extension_text = m_extension_preedit_text.get_text();
return new IBus.Text.from_string(extension_text);
}
@@ -237,9 +237,14 @@ class PanelBinding : IBus.PanelService {
GLib.Object(connection : bus.get_connection(),
object_path : IBus.PATH_PANEL_EXTENSION_EMOJI);
+#if USE_GDK_WAYLAND
Type instance_type = Gdk.Display.get_default().get_type();
Type wayland_type = typeof(GdkWayland.Display);
m_is_wayland = instance_type.is_a(wayland_type);
+#else
+ m_is_wayland = false;
+ warning("Checking Wayland is disabled");
+#endif
m_bus = bus;
m_application = application;
@@ -551,8 +556,10 @@ class PanelBinding : IBus.PanelService {
private bool key_press_keyval(uint keyval) {
unichar ch = IBus.keyval_to_unicode(keyval);
+ if (m_extension_name == "unicode" && !ch.isxdigit())
+ return false;
if (ch.iscntrl())
- return false;
+ return false;
string str = ch.to_string();
m_preedit.append_text(str);
string annotation = m_preedit.get_text();
--
2.27.0

View File

@ -1,26 +0,0 @@
From 6aab10f2e5a8e10dac9b007eff19b26990461790 Mon Sep 17 00:00:00 2001
From: fujiwarat <takao.fujiwara1@gmail.com>
Date: Thu, 14 Feb 2019 17:37:39 +0900
Subject: [PATCH] ui/gtk3: Fix assert with 16 candidates
BUG=https://github.com/ibus/ibus/issues/2076
---
ui/gtk3/candidatearea.vala | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/ui/gtk3/candidatearea.vala b/ui/gtk3/candidatearea.vala
index f590cf3a..781ecd1e 100644
--- a/ui/gtk3/candidatearea.vala
+++ b/ui/gtk3/candidatearea.vala
@@ -109,7 +109,7 @@ class CandidateArea : Gtk.Box {
m_focus_candidate = focus_candidate;
m_show_cursor = show_cursor;
- assert(candidates.length < 16);
+ assert(candidates.length <= 16);
for (int i = 0 ; i < 16 ; i++) {
Gtk.Label label = m_candidates[i];
bool visible = false;
--
2.21.0

View File

@ -1,920 +0,0 @@
From 7edaefdc1d80aefdbbc2dc52526c20715759da83 Mon Sep 17 00:00:00 2001
From: fujiwarat <takao.fujiwara1@gmail.com>
Date: Wed, 22 Aug 2018 17:20:53 +0900
Subject: [PATCH] ui/gtk3: Do not clear unicode data when emoji annotation lang
is changed
---
ui/gtk3/emojier.vala | 8 ++++++--
1 file changed, 6 insertions(+), 2 deletions(-)
diff --git a/ui/gtk3/emojier.vala b/ui/gtk3/emojier.vala
index 85dcdceb..637ae049 100644
--- a/ui/gtk3/emojier.vala
+++ b/ui/gtk3/emojier.vala
@@ -440,13 +440,17 @@ public class IBusEmojier : Gtk.ApplicationWindow {
m_emoji_to_emoji_variants_dict =
new GLib.HashTable<string, GLib.SList<string>>(GLib.str_hash,
GLib.str_equal);
- m_unicode_to_data_dict =
+ if (m_unicode_to_data_dict == null) {
+ m_unicode_to_data_dict =
new GLib.HashTable<unichar, IBus.UnicodeData>(
GLib.direct_hash,
GLib.direct_equal);
- m_name_to_unicodes_dict =
+ }
+ if (m_name_to_unicodes_dict == null) {
+ m_name_to_unicodes_dict =
new GLib.HashTable<string, GLib.SList<unichar>>(GLib.str_hash,
GLib.str_equal);
+ }
}
--
2.17.1
From 28d22176aee6be97d88dd6c60fa5395c79563ec0 Mon Sep 17 00:00:00 2001
From: fujiwarat <takao.fujiwara1@gmail.com>
Date: Thu, 30 Aug 2018 12:57:33 +0900
Subject: [PATCH] ui/gtk3: Fix SEGV when type ASCII on emojier
Emojier still included Gtk.Entry, accepted key events in Wayland,
reset the lookup table and it caused SEGV because IBus.Text
is NULL in the lookup table in Emojier.get_current_candidate().
Now Gtk.Entry is deleted completely.
BUG=rhbz#1618682
---
ui/gtk3/emojier.vala | 139 +------------------------------------------
1 file changed, 1 insertion(+), 138 deletions(-)
diff --git a/ui/gtk3/emojier.vala b/ui/gtk3/emojier.vala
index 637ae049..0f455800 100644
--- a/ui/gtk3/emojier.vala
+++ b/ui/gtk3/emojier.vala
@@ -283,7 +283,6 @@ public class IBusEmojier : Gtk.ApplicationWindow {
private ThemedRGBA m_rgba;
private Gtk.Box m_vbox;
- private EEntry m_entry;
/* If emojier is emoji category list or Unicode category list,
* m_annotation is "" and preedit is also "".
* If emojier is candidate mode, m_annotation is an annotation and
@@ -367,23 +366,6 @@ public class IBusEmojier : Gtk.ApplicationWindow {
m_vbox = new Gtk.Box(Gtk.Orientation.VERTICAL, 0);
add(m_vbox);
- m_entry = new EEntry();
- m_entry.set_placeholder_text(_("Type annotation or choose emoji"));
- //m_vbox.add(m_entry);
- m_entry.changed.connect(() => {
- update_candidate_window();
- });
- m_entry.icon_release.connect((icon_pos, event) => {
- hide_candidate_panel();
- });
-
- /* Set the accessible role of the label to a status bar so it
- * will emit name changed events that can be used by screen
- * readers.
- */
- Atk.Object obj = m_entry.get_accessible();
- obj.set_role (Atk.Role.STATUSBAR);
-
// The constructor of IBus.LookupTable does not support more than
// 16 pages.
m_lookup_table = new IBus.LookupTable(1, 0, true, true);
@@ -1806,18 +1788,6 @@ public class IBusEmojier : Gtk.ApplicationWindow {
m_lookup_table.cursor_up();
else if (keyval == Gdk.Key.Right)
m_lookup_table.cursor_down();
- } else if (m_entry.get_text().length > 0) {
- int step = 0;
- if (keyval == Gdk.Key.Left)
- step = -1;
- else if (keyval == Gdk.Key.Right)
- step = 1;
- GLib.Signal.emit_by_name(
- m_entry, "move-cursor",
- Gtk.MovementStep.VISUAL_POSITIONS,
- step,
- (modifiers & Gdk.ModifierType.SHIFT_MASK) != 0
- ? true : false);
} else {
// For Gdk.Key.f and Gdk.Key.b
if (keyval == Gdk.Key.Left)
@@ -1880,20 +1850,6 @@ public class IBusEmojier : Gtk.ApplicationWindow {
}
return true;
}
- if (m_entry.get_text().length > 0) {
- int step = 0;
- if (keyval == Gdk.Key.Home)
- step = -1;
- else if (keyval == Gdk.Key.End)
- step = 1;
- GLib.Signal.emit_by_name(
- m_entry, "move-cursor",
- Gtk.MovementStep.DISPLAY_LINE_ENDS,
- step,
- (modifiers & Gdk.ModifierType.SHIFT_MASK) != 0
- ? true : false);
- return true;
- }
return category_list_cursor_move(keyval);
}
@@ -1941,28 +1897,6 @@ public class IBusEmojier : Gtk.ApplicationWindow {
}
- private void entry_enter_keyval(uint keyval) {
- unichar ch = IBus.keyval_to_unicode(keyval);
- if (ch.iscntrl())
- return;
- string str = ch.to_string();
-
- // what gtk_entry_commit_cb() do
- if (m_entry.get_selection_bounds(null, null)) {
- m_entry.delete_selection();
- } else {
- if (m_entry.get_overwrite_mode()) {
- uint text_length = m_entry.get_buffer().get_length();
- if (m_entry.cursor_position < text_length)
- m_entry.delete_from_cursor(Gtk.DeleteType.CHARS, 1);
- }
- }
- int pos = m_entry.get_position();
- m_entry.insert_text(str, -1, ref pos);
- m_entry.set_position(pos);
- }
-
-
private Gdk.Rectangle get_monitor_geometry() {
Gdk.Rectangle monitor_area = { 0, };
@@ -2245,10 +2179,7 @@ public class IBusEmojier : Gtk.ApplicationWindow {
/* Let gtk recalculate the window size. */
resize(1, 1);
- m_entry.set_text("");
-
show_category_list();
- m_entry.set_activates_default(true);
show_all();
/* Some window managers, e.g. MATE, GNOME, Plasma desktops,
@@ -2289,13 +2220,6 @@ public class IBusEmojier : Gtk.ApplicationWindow {
m_loop.run();
m_loop = null;
- // Need focus-out on Gtk.Entry to send the emoji to applications.
- Gdk.Event fevent = new Gdk.Event(Gdk.EventType.FOCUS_CHANGE);
- fevent.focus_change.in = 0;
- fevent.focus_change.window = get_window();
- m_entry.send_focus_change(fevent);
- fevent.focus_change.window = null;
-
hide();
// Make sure the switcher is hidden before returning from this function.
while (Gtk.events_pending())
@@ -2357,36 +2281,9 @@ public class IBusEmojier : Gtk.ApplicationWindow {
hide();
}
return true;
- case Gdk.Key.BackSpace:
- if (m_entry.get_text().length > 0) {
- if ((modifiers & Gdk.ModifierType.CONTROL_MASK) != 0) {
- GLib.Signal.emit_by_name(m_entry, "delete-from-cursor",
- Gtk.DeleteType.WORD_ENDS, -1);
- } else {
- GLib.Signal.emit_by_name(m_entry, "backspace");
- }
- return true;
- }
- break;
- case Gdk.Key.Delete:
- case Gdk.Key.KP_Delete:
- if (m_entry.get_text().length > 0) {
- if ((modifiers & Gdk.ModifierType.CONTROL_MASK) != 0) {
- GLib.Signal.emit_by_name(m_entry, "delete-from-cursor",
- Gtk.DeleteType.WORD_ENDS, 1);
- } else {
- GLib.Signal.emit_by_name(m_entry, "delete-from-cursor",
- Gtk.DeleteType.CHARS, 1);
- }
- return true;
- }
- break;
case Gdk.Key.space:
case Gdk.Key.KP_Space:
- if ((modifiers & Gdk.ModifierType.SHIFT_MASK) != 0) {
- if (m_entry.get_text().length > 0)
- entry_enter_keyval(keyval);
- } else if (m_candidate_panel_is_visible) {
+ if (m_candidate_panel_is_visible) {
enter_notify_disable_with_timer();
m_lookup_table.cursor_down();
show_candidate_panel();
@@ -2436,10 +2333,6 @@ public class IBusEmojier : Gtk.ApplicationWindow {
key_press_cursor_home_end(Gdk.Key.End, modifiers);
show_all();
return true;
- case Gdk.Key.Insert:
- case Gdk.Key.KP_Insert:
- GLib.Signal.emit_by_name(m_entry, "toggle-overwrite");
- return true;
}
if ((modifiers & Gdk.ModifierType.CONTROL_MASK) != 0) {
@@ -2470,27 +2363,6 @@ public class IBusEmojier : Gtk.ApplicationWindow {
key_press_cursor_home_end(Gdk.Key.End, modifiers);
show_all();
return true;
- case Gdk.Key.u:
- if (m_entry.get_text().length > 0) {
- GLib.Signal.emit_by_name(m_entry,
- "delete-from-cursor",
- Gtk.DeleteType.PARAGRAPH_ENDS,
- -1);
- return true;
- }
- break;
- case Gdk.Key.a:
- if (m_entry.get_text().length > 0) {
- m_entry.select_region(0, -1);
- return true;
- }
- break;
- case Gdk.Key.x:
- if (m_entry.get_text().length > 0) {
- GLib.Signal.emit_by_name(m_entry, "cut-clipboard");
- return true;
- }
- break;
case Gdk.Key.C:
case Gdk.Key.c:
if ((modifiers & Gdk.ModifierType.SHIFT_MASK) != 0) {
@@ -2503,19 +2375,11 @@ public class IBusEmojier : Gtk.ApplicationWindow {
clipboard.store();
return true;
}
- } else if (m_entry.get_text().length > 0) {
- GLib.Signal.emit_by_name(m_entry, "copy-clipboard");
- return true;
}
break;
- case Gdk.Key.v:
- GLib.Signal.emit_by_name(m_entry, "paste-clipboard");
- return true;
}
return false;
}
-
- entry_enter_keyval(keyval);
return true;
}
@@ -2595,7 +2459,6 @@ public class IBusEmojier : Gtk.ApplicationWindow {
uint32 timestamp = event.get_time();
present_with_time(timestamp);
- m_entry.set_activates_default(true);
}
--
2.17.1
From e6badb494e0a31b7aca3a5078a5dc5b27b83390d Mon Sep 17 00:00:00 2001
From: fujiwarat <takao.fujiwara1@gmail.com>
Date: Thu, 30 Aug 2018 12:57:46 +0900
Subject: [PATCH] ui/gtk3: Support Shift-Space to insert a Space on Emojier
preedit
Implemented Shift-Space on preedit since Shift-Space had worked on
Emojier's GtkEntry in the previous release.
---
ui/gtk3/panelbinding.vala | 27 ++++++++++++++++++++-------
1 file changed, 20 insertions(+), 7 deletions(-)
diff --git a/ui/gtk3/panelbinding.vala b/ui/gtk3/panelbinding.vala
index 981b5509..4ebff8da 100644
--- a/ui/gtk3/panelbinding.vala
+++ b/ui/gtk3/panelbinding.vala
@@ -548,6 +548,19 @@ class PanelBinding : IBus.PanelService {
}
+ private bool key_press_keyval(uint keyval) {
+ unichar ch = IBus.keyval_to_unicode(keyval);
+ if (ch.iscntrl())
+ return false;
+ string str = ch.to_string();
+ m_preedit.append_text(str);
+ string annotation = m_preedit.get_text();
+ m_emojier.set_annotation(annotation);
+ m_preedit.set_emoji("");
+ return true;
+ }
+
+
private bool key_press_enter() {
if (m_extension_name != "unicode" && is_emoji_lookup_table()) {
// Check if variats exist
@@ -899,6 +912,12 @@ class PanelBinding : IBus.PanelService {
break;
case Gdk.Key.space:
case Gdk.Key.KP_Space:
+ if ((modifiers & Gdk.ModifierType.SHIFT_MASK) != 0) {
+ if (!key_press_keyval(keyval))
+ return true;
+ show_candidate = is_emoji_lookup_table();
+ break;
+ }
show_candidate = key_press_space();
if (m_extension_name == "unicode") {
key_press_enter();
@@ -979,14 +998,8 @@ class PanelBinding : IBus.PanelService {
show_candidate = key_press_control_keyval(keyval, modifiers);
break;
}
- unichar ch = IBus.keyval_to_unicode(keyval);
- if (ch.iscntrl())
+ if (!key_press_keyval(keyval))
return true;
- string str = ch.to_string();
- m_preedit.append_text(str);
- string annotation = m_preedit.get_text();
- m_emojier.set_annotation(annotation);
- m_preedit.set_emoji("");
show_candidate = is_emoji_lookup_table();
break;
}
--
2.17.1
From 809d880337e75b7cee429292a238bf53899bef6a Mon Sep 17 00:00:00 2001
From: fujiwarat <takao.fujiwara1@gmail.com>
Date: Thu, 30 Aug 2018 12:58:57 +0900
Subject: [PATCH] ui/gtk3: Do not move Emojier popup with the active
candidate in Xorg
Probably I think it's not useful to change the popup position frequently.
The popup size is always slightly changed with the emoji annotation length.
---
ui/gtk3/emojier.vala | 10 +++++++++-
1 file changed, 9 insertions(+), 1 deletion(-)
diff --git a/ui/gtk3/emojier.vala b/ui/gtk3/emojier.vala
index 0f455800..9811fde5 100644
--- a/ui/gtk3/emojier.vala
+++ b/ui/gtk3/emojier.vala
@@ -1944,7 +1944,15 @@ public class IBusEmojier : Gtk.ApplicationWindow {
x = 0;
bool changed = false;
- if (window_right_bottom.y > monitor_bottom) {
+ // Do not up side down frequently.
+ // The first pos does not show the lookup table yet but the
+ // preedit only and the second pos shows the lookup table.
+ if (m_lookup_table.get_cursor_pos() != 1) {
+ if (m_is_up_side_down)
+ y = m_cursor_location.y - allocation.height;
+ else
+ y = cursor_right_bottom.y;
+ } else if (window_right_bottom.y > monitor_bottom) {
y = m_cursor_location.y - allocation.height;
// Do not up side down in Wayland
if (m_input_context_path == "") {
--
2.17.1
From 1c6565e205528a45e88a84ba2a328f9035875c8d Mon Sep 17 00:00:00 2001
From: fujiwarat <takao.fujiwara1@gmail.com>
Date: Fri, 14 Sep 2018 16:15:41 +0900
Subject: [PATCH] ui/gtk3: Fix SEGV when commit an emoji on Emojier in Wayland
Just pressing Space key without emoji annotations can launch Emojier
popup and the popup takes a focus in Wayland and the chosen emoji is
output when the original text application gets the focus after Emojier
popup release the focus. Emojier disabled Ctrl-Shift-e after got the focus.
But currently GNOME Wayland has a bug not to send focus-in until a
key press or mouse click happens [1] and Emojier causes a SEGV.
Now Emojier disables Ctrl-Shift-e immediately when an emoji is chosen
whether focus-in comes or not and fixes the SEGV.
[1] https://gitlab.gnome.org/GNOME/gnome-shell/issues/573
BUG=rhbz#1625187
---
ui/gtk3/emojier.vala | 63 +++++++-------------------------------
ui/gtk3/emojierapp.vala | 2 +-
ui/gtk3/panelbinding.vala | 64 ++++++++++++++++++++++++++-------------
3 files changed, 55 insertions(+), 74 deletions(-)
diff --git a/ui/gtk3/emojier.vala b/ui/gtk3/emojier.vala
index 9811fde5..e23ef889 100644
--- a/ui/gtk3/emojier.vala
+++ b/ui/gtk3/emojier.vala
@@ -21,17 +21,6 @@
*/
public class IBusEmojier : Gtk.ApplicationWindow {
- private class EEntry : Gtk.SearchEntry {
- public EEntry() {
- GLib.Object(
- name : "IBusEmojierEntry",
- margin_start : 6,
- margin_end : 6,
- margin_top : 6,
- margin_bottom : 6
- );
- }
- }
private class EListBox : Gtk.ListBox {
public EListBox() {
GLib.Object(
@@ -330,6 +319,7 @@ public class IBusEmojier : Gtk.ApplicationWindow {
private uint m_redraw_window_id;
public signal void candidate_clicked(uint index, uint button, uint state);
+ public signal void commit_text(string text);
public IBusEmojier() {
GLib.Object(
@@ -380,12 +370,6 @@ public class IBusEmojier : Gtk.ApplicationWindow {
adjust_window_position();
});
- candidate_clicked.connect((i, b, s) => {
- if (m_input_context_path != "")
- candidate_panel_select_index(i, b);
- });
-
-
if (m_annotation_to_emojis_dict == null) {
reload_emoji_dict();
}
@@ -1641,34 +1625,6 @@ public class IBusEmojier : Gtk.ApplicationWindow {
}
- private void candidate_panel_select_index(uint index,
- uint button) {
- if (button == BUTTON_CLOSE_BUTTON) {
- hide();
- if (m_candidate_panel_mode &&
- m_lookup_table.get_number_of_candidates() > 0) {
- // Call remove_all_children() instead of show_category_list()
- // so that show_category_list do not remove children with
- // PageUp/PageDown.
- remove_all_children();
- }
- m_result = "";
- return;
- }
- string text = m_lookup_table.get_candidate(index).text;
- unowned GLib.SList<string>? emojis =
- m_emoji_to_emoji_variants_dict.lookup(text);
- if (m_show_emoji_variant && emojis != null &&
- m_backward_index < 0) {
- show_emoji_variants(emojis);
- show_all();
- } else {
- m_result = text;
- hide();
- }
- }
-
-
private void candidate_panel_cursor_down() {
enter_notify_disable_with_timer();
uint ncandidates = m_lookup_table.get_number_of_candidates();
@@ -1762,7 +1718,8 @@ public class IBusEmojier : Gtk.ApplicationWindow {
}
- public bool has_variants(uint index) {
+ public bool has_variants(uint index,
+ bool need_commit_signal) {
if (index >= m_lookup_table.get_number_of_candidates())
return false;
string text = m_lookup_table.get_candidate(index).text;
@@ -1773,6 +1730,10 @@ public class IBusEmojier : Gtk.ApplicationWindow {
show_emoji_variants(emojis);
return true;
}
+ if (m_input_context_path != "")
+ m_result = text;
+ if (need_commit_signal)
+ commit_text(text);
return false;
}
@@ -1881,10 +1842,10 @@ public class IBusEmojier : Gtk.ApplicationWindow {
}
- public bool key_press_enter() {
+ public bool key_press_enter(bool need_commit_signal) {
if (m_candidate_panel_is_visible) {
uint index = m_lookup_table.get_cursor_pos();
- return has_variants(index);
+ return has_variants(index, need_commit_signal);
} else if (m_category_active_index >= 0) {
Gtk.ListBoxRow gtkrow = m_list_box.get_selected_row();
EBoxRow row = gtkrow as EBoxRow;
@@ -2282,12 +2243,10 @@ public class IBusEmojier : Gtk.ApplicationWindow {
return true;
case Gdk.Key.Return:
case Gdk.Key.KP_Enter:
- if (key_press_enter()) {
+ if (key_press_enter(true))
show_all();
- } else {
- m_result = get_current_candidate();
+ else
hide();
- }
return true;
case Gdk.Key.space:
case Gdk.Key.KP_Space:
diff --git a/ui/gtk3/emojierapp.vala b/ui/gtk3/emojierapp.vala
index 787d448f..fab99d9e 100644
--- a/ui/gtk3/emojierapp.vala
+++ b/ui/gtk3/emojierapp.vala
@@ -65,7 +65,7 @@ public class EmojiApplication : Gtk.Application {
uint ncandidates = m_emojier.get_number_of_candidates();
if (ncandidates > 0 && ncandidates >= index) {
m_emojier.set_cursor_pos(index);
- show_candidate = m_emojier.has_variants(index);
+ show_candidate = m_emojier.has_variants(index, false);
} else {
return;
}
diff --git a/ui/gtk3/panelbinding.vala b/ui/gtk3/panelbinding.vala
index 4ebff8da..01c43b0d 100644
--- a/ui/gtk3/panelbinding.vala
+++ b/ui/gtk3/panelbinding.vala
@@ -447,13 +447,19 @@ class PanelBinding : IBus.PanelService {
}
- private void commit_text_update_favorites(IBus.Text text) {
+ private void commit_text_update_favorites(IBus.Text text,
+ bool disable_extension) {
commit_text(text);
- IBus.ExtensionEvent event = new IBus.ExtensionEvent(
+
+ // If disable_extension is false, the extension event is already
+ // sent before the focus-in is received.
+ if (disable_extension) {
+ IBus.ExtensionEvent event = new IBus.ExtensionEvent(
"name", m_extension_name,
"is-enabled", false,
"is-extension", true);
- panel_extension(event);
+ panel_extension(event);
+ }
string committed_string = text.text;
string preedit_string = m_preedit.get_text();
m_preedit.hide();
@@ -482,7 +488,7 @@ class PanelBinding : IBus.PanelService {
prev_context_path != "" &&
prev_context_path == m_current_context_path) {
IBus.Text text = new IBus.Text.from_string(selected_string);
- commit_text_update_favorites(text);
+ commit_text_update_favorites(text, false);
m_emojier.reset();
return true;
}
@@ -564,13 +570,13 @@ class PanelBinding : IBus.PanelService {
private bool key_press_enter() {
if (m_extension_name != "unicode" && is_emoji_lookup_table()) {
// Check if variats exist
- if (m_emojier.key_press_enter()) {
+ if (m_emojier.key_press_enter(false)) {
convert_preedit_text();
return true;
}
}
IBus.Text text = m_preedit.get_commit_text();
- commit_text_update_favorites(text);
+ commit_text_update_favorites(text, true);
return false;
}
@@ -712,15 +718,10 @@ class PanelBinding : IBus.PanelService {
}
- private bool is_visible_wayland_lookup_table() {
- return m_wayland_lookup_table_is_visible;
- }
-
-
private void hide_emoji_lookup_table() {
if (m_emojier == null)
return;
- if (m_is_wayland)
+ if (m_wayland_lookup_table_is_visible)
hide_wayland_lookup_table();
else
m_emojier.hide();
@@ -747,7 +748,7 @@ class PanelBinding : IBus.PanelService {
private bool is_emoji_lookup_table() {
if (m_is_wayland)
- return is_visible_wayland_lookup_table();
+ return m_wayland_lookup_table_is_visible;
else
return m_emojier.get_visible();
}
@@ -788,7 +789,8 @@ class PanelBinding : IBus.PanelService {
*/
if (!input_context_path.has_suffix("InputContext_1")) {
m_real_current_context_path = m_current_context_path;
- this.emojier_focus_commit();
+ if (m_is_wayland)
+ this.emojier_focus_commit();
}
}
@@ -822,8 +824,18 @@ class PanelBinding : IBus.PanelService {
// For title handling in gnome-shell
m_application.add_window(m_emojier);
m_emojier.candidate_clicked.connect((i, b, s) => {
+ candidate_clicked_lookup_table_real(i, b, s, true);
+ });
+ m_emojier.commit_text.connect((s) => {
if (!m_is_wayland)
- candidate_clicked_lookup_table(i, b, s);
+ return;
+ // Currently emojier has a focus but the text input focus
+ // does not and commit the text later.
+ IBus.ExtensionEvent close_event = new IBus.ExtensionEvent(
+ "name", m_extension_name,
+ "is-enabled", false,
+ "is-extension", true);
+ panel_extension(close_event);
});
}
m_emojier.reset();
@@ -1041,9 +1053,10 @@ class PanelBinding : IBus.PanelService {
show_preedit_and_candidate(show_candidate);
}
- public override void candidate_clicked_lookup_table(uint index,
- uint button,
- uint state) {
+ private void candidate_clicked_lookup_table_real(uint index,
+ uint button,
+ uint state,
+ bool is_emojier) {
if (button == IBusEmojier.BUTTON_CLOSE_BUTTON) {
m_enable_extension = false;
hide_emoji_lookup_table();
@@ -1061,17 +1074,26 @@ class PanelBinding : IBus.PanelService {
uint ncandidates = m_emojier.get_number_of_candidates();
if (ncandidates > 0 && ncandidates >= index) {
m_emojier.set_cursor_pos(index);
- show_candidate = m_emojier.has_variants(index);
- m_preedit.set_emoji(m_emojier.get_current_candidate());
+ bool need_commit_signal = m_is_wayland && is_emojier;
+ show_candidate = m_emojier.has_variants(index, need_commit_signal);
+ if (!m_is_wayland)
+ m_preedit.set_emoji(m_emojier.get_current_candidate());
} else {
return;
}
if (!show_candidate) {
IBus.Text text = m_preedit.get_commit_text();
- commit_text_update_favorites(text);
hide_emoji_lookup_table();
+ if (!is_emojier || !m_is_wayland)
+ commit_text_update_favorites(text, true);
return;
}
show_preedit_and_candidate(show_candidate);
}
+
+ public override void candidate_clicked_lookup_table(uint index,
+ uint button,
+ uint state) {
+ candidate_clicked_lookup_table_real(index, button, state, false);
+ }
}
--
2.17.1
From c1b55431c076dfa3fc26a3a998bfcf729e9ba602 Mon Sep 17 00:00:00 2001
From: fujiwarat <takao.fujiwara1@gmail.com>
Date: Fri, 26 Oct 2018 18:44:35 +0900
Subject: [PATCH] src/tests: Fix make check in Fedora 29
ibus-bus and ibus-compose failed in Fedora 29.
1. In ibus-bus with runtest, ibus-daemon failed to restart in
start_exit_async() because it seems to have conflicting IO with runtest
and ibus-daemon failed to close a file descriptor in _restart_server().
The solution is to add a sleep in start_exit_async().
Also added ibus_get_address() in test_async_apis_finish() to check
if ibus-daemon finished to restart.
2. In ibus-compose, the GTK application could not get the ibus module.
The solution is to export GTK_IM_MODULE=ibus.
3. Added DISABLE_DAEMONIZE_IN_TESTS to get error messages in ibus-daemon.
% make DISABLE_DAEMONIZE_IN_TESTS=1 check
---
bus/Makefile.am | 1 +
src/tests/Makefile.am | 1 +
src/tests/ibus-bus.c | 15 ++++++++++++++-
src/tests/runtest | 24 +++++++++++++++++-------
4 files changed, 33 insertions(+), 8 deletions(-)
diff --git a/bus/Makefile.am b/bus/Makefile.am
index bdae5c92..4383a874 100644
--- a/bus/Makefile.am
+++ b/bus/Makefile.am
@@ -124,6 +124,7 @@ TESTS_ENVIRONMENT = \
srcdir=$(srcdir) \
LD_LIBRARY_PATH="$(top_builddir)/src/.libs:$(top_builddir)/src" \
DISABLE_GUI_TESTS="$(DISABLE_GUI_TESTS)" \
+ DISABLE_DAEMONIZE_IN_TESTS="$(DISABLE_DAEMONIZE_IN_TESTS)" \
$(NULL)
LOG_COMPILER = $(top_srcdir)/src/tests/runtest
diff --git a/src/tests/Makefile.am b/src/tests/Makefile.am
index c5fef3c8..e337a59b 100644
--- a/src/tests/Makefile.am
+++ b/src/tests/Makefile.am
@@ -73,6 +73,7 @@ TESTS_ENVIRONMENT = \
srcdir=$(srcdir) \
LD_LIBRARY_PATH="$(top_builddir)/src/.libs:$(top_builddir)/src" \
DISABLE_GUI_TESTS="$(DISABLE_GUI_TESTS)" \
+ DISABLE_DAEMONIZE_IN_TESTS="$(DISABLE_DAEMONIZE_IN_TESTS)" \
$(NULL)
LOG_COMPILER = $(srcdir)/runtest
diff --git a/src/tests/ibus-bus.c b/src/tests/ibus-bus.c
index 7fa1bc4a..0bf9e612 100644
--- a/src/tests/ibus-bus.c
+++ b/src/tests/ibus-bus.c
@@ -820,6 +820,14 @@ finish_exit_async (GObject *source_object,
static void
start_exit_async (void)
{
+ /* When `./runtest ibus-bus` runs, ibus-daemon sometimes failed to
+ * restart because closing a file descriptor was failed in
+ * bus/server.c:_restart_server() with a following error:
+ * "inotify read(): Bad file descriptor"
+ * Now g_usleep() is added here to write down the buffer and not to
+ * fail to restart ibus-daemon.
+ */
+ g_usleep (G_USEC_PER_SEC);
ibus_bus_exit_async (bus,
TRUE, /* restart */
-1, /* timeout */
@@ -831,6 +839,9 @@ start_exit_async (void)
static gboolean
test_async_apis_finish (gpointer user_data)
{
+ /* INFO: g_warning() causes SEGV with runtest script */
+ if (ibus_get_address () == NULL)
+ g_warning ("ibus-daemon does not restart yet from start_exit_async().");
ibus_quit ();
return FALSE;
}
@@ -906,7 +917,9 @@ call_next_async_function (void)
};
static guint index = 0;
- // Use g_timeout_add to make sure test_async_apis finishes even if async_functions is empty.
+ /* Use g_timeout_add to make sure test_async_apis finishes even if
+ * async_functions is empty.
+ */
if (index >= G_N_ELEMENTS (async_functions))
g_timeout_add (1, test_async_apis_finish, NULL);
else
diff --git a/src/tests/runtest b/src/tests/runtest
index d7f96ea3..ab39e9f2 100755
--- a/src/tests/runtest
+++ b/src/tests/runtest
@@ -22,6 +22,7 @@
: ${builddir:=.}
: ${srcdir:=.}
: ${DISABLE_GUI_TESTS:=''}
+: ${DISABLE_DAEMONIZE_IN_TESTS:=''}
BUS_REQUIRED_TESTS="
ibus-bus
@@ -162,16 +163,25 @@ run_test_case()
export GSETTINGS_SCHEMA_DIR=$PWD
# Start ibus-daemon.
- ../$top_builddir/bus/ibus-daemon \
- --daemonize \
- --cache=none \
- --panel=disable \
- --emoji-extension=disable \
- --config=default \
- --verbose;
+ DAEMON_ARGS='
+ --cache=none
+ --panel=disable
+ --emoji-extension=disable
+ --config=default
+ --verbose
+ '
+ if test x"$DISABLE_DAEMONIZE_IN_TESTS" = x ; then
+ ../$top_builddir/bus/ibus-daemon \
+ $DAEMON_ARGS --daemonize;
+ else
+ ../$top_builddir/bus/ibus-daemon \
+ $DAEMON_ARGS &
+ fi
# Wait until all necessary components are up.
sleep 1
+
+ export GTK_IM_MODULE=ibus
fi
"../$tst" ${1+"$@"}
--
2.17.1
From 3172c3b23faefe76b3b7adfc75f9be34a0fb2e02 Mon Sep 17 00:00:00 2001
From: fujiwarat <takao.fujiwara1@gmail.com>
Date: Wed, 31 Oct 2018 17:42:38 +0900
Subject: [PATCH] RHEL code reviews
---
src/ibuskeymap.c | 2 +-
src/ibuspanelservice.c | 6 +++++-
src/tests/ibus-keypress.c | 2 +-
util/IMdkit/FrameMgr.c | 1 +
4 files changed, 8 insertions(+), 3 deletions(-)
diff --git a/src/ibuskeymap.c b/src/ibuskeymap.c
index 27a56754..5abfb99a 100644
--- a/src/ibuskeymap.c
+++ b/src/ibuskeymap.c
@@ -143,7 +143,7 @@ ibus_keymap_parse_line (gchar *str,
/* Do not assign *p1 to g_ascii_isalpha() directly for the syntax check */
if (i == 0 &&
strncmp (p2, "addupper", sizeof ("addupper") - 1) == 0 &&
- (ch = *p1) && g_ascii_isalpha (ch)) {
+ (ch = *p1) && (ch >= 0) && g_ascii_isalpha (ch)) {
gchar buf[] = "a";
buf[0] = g_ascii_toupper(ch);
keymap[keycode][0] = keymap[keycode][3] = keysym;
diff --git a/src/ibuspanelservice.c b/src/ibuspanelservice.c
index 9d87e19b..984cc890 100644
--- a/src/ibuspanelservice.c
+++ b/src/ibuspanelservice.c
@@ -1615,7 +1615,11 @@ ibus_panel_service_panel_extension_register_keys (IBusPanelService *panel,
va_start (var_args, first_property_name);
do {
keys = va_arg (var_args, IBusProcessKeyEventData *);
- g_return_if_fail (keys != NULL);
+ if (keys == NULL) {
+ va_end (var_args);
+ g_warning ("Failed to va_arg for IBusProcessKeyEventData");
+ return;
+ }
g_variant_builder_init (&child, G_VARIANT_TYPE ("av"));
for (; keys; keys++) {
if (keys->keyval == 0 && keys->keycode == 0 && keys->state == 0)
diff --git a/src/tests/ibus-keypress.c b/src/tests/ibus-keypress.c
index 3486523b..17920226 100644
--- a/src/tests/ibus-keypress.c
+++ b/src/tests/ibus-keypress.c
@@ -173,7 +173,7 @@ set_engine_cb (GObject *object,
IBusBus *bus = IBUS_BUS (object);
GtkWidget *entry = GTK_WIDGET (data);
GdkDisplay *display;
- Display *xdisplay;
+ Display *xdisplay = NULL;
GError *error = NULL;
int i, j;
diff --git a/util/IMdkit/FrameMgr.c b/util/IMdkit/FrameMgr.c
index 084b8810..0e91b78e 100644
--- a/util/IMdkit/FrameMgr.c
+++ b/util/IMdkit/FrameMgr.c
@@ -1414,6 +1414,7 @@ static int FrameInstGetSize (FrameInst fi)
break;
}
/*endswitch*/
+ assert (i >= 0);
i = _FrameInstIncrement (fi->template, i);
}
/*endwhile*/
--
2.17.1

View File

@ -1,134 +0,0 @@
From 8375f391e1b9bfc048ff14fd458f689d853064ac Mon Sep 17 00:00:00 2001
From: fujiwarat <takao.fujiwara1@gmail.com>
Date: Thu, 28 Feb 2019 15:26:11 +0900
Subject: [PATCH] ui/gtk3: Do not add emojis in compose category to emoji
variants
Any emojis in compose category have variants and should be shown by default.
---
bindings/vala/IBus-1.0-custom.vala | 4 ++
ui/gtk3/emojier.vala | 74 ++++++++++++++++++++++++++----
2 files changed, 68 insertions(+), 10 deletions(-)
diff --git a/bindings/vala/IBus-1.0-custom.vala b/bindings/vala/IBus-1.0-custom.vala
index 7d34a8bd..ec46fc90 100644
--- a/bindings/vala/IBus-1.0-custom.vala
+++ b/bindings/vala/IBus-1.0-custom.vala
@@ -17,4 +17,8 @@ namespace IBus {
public class PanelService : IBus.Service {
public void panel_extension_register_keys(string first_property_name, ...);
}
+ public class EmojiData : IBus.Serializable {
+ [CCode (cname = "ibus_emoji_data_new", has_construct_function = true)]
+ public EmojiData (string first_property_name, ...);
+ }
}
diff --git a/ui/gtk3/emojier.vala b/ui/gtk3/emojier.vala
index aedeb4cb..fc15cffe 100644
--- a/ui/gtk3/emojier.vala
+++ b/ui/gtk3/emojier.vala
@@ -389,6 +389,14 @@ public class IBusEmojier : Gtk.ApplicationWindow {
}
make_emoji_dict(m_current_lang_id);
}
+ add_variants_to_component();
+
+ GLib.List<unowned string> annotations =
+ m_annotation_to_emojis_dict.get_keys();
+ foreach (unowned string annotation in annotations) {
+ if (m_emoji_max_seq_len < annotation.length)
+ m_emoji_max_seq_len = annotation.length;
+ }
update_favorite_emoji_dict();
}
@@ -430,11 +438,54 @@ public class IBusEmojier : Gtk.ApplicationWindow {
update_annotation_to_emojis_dict(data);
update_category_to_emojis_dict(data, lang);
}
- GLib.List<unowned string> annotations =
- m_annotation_to_emojis_dict.get_keys();
- foreach (unowned string annotation in annotations) {
- if (m_emoji_max_seq_len < annotation.length)
- m_emoji_max_seq_len = annotation.length;
+ }
+
+
+ private static void add_variants_to_component() {
+ string category = "Component";
+ unowned GLib.SList<string> hits =
+ m_category_to_emojis_dict.lookup(category);
+ if (hits == null) {
+ category = "component";
+ hits = m_category_to_emojis_dict.lookup(category);
+ }
+ if (hits == null)
+ return;
+ GLib.SList<IBus.EmojiData> emoji_list =
+ new GLib.SList<IBus.EmojiData>();
+ GLib.SList<string> annotations = new GLib.SList<string>();
+ annotations.append("zero");
+ IBus.EmojiData _data;
+ _data = new IBus.EmojiData("emoji", "\u200d",
+ "annotations", annotations,
+ "description",
+ "ZERO WIDTH JOINER",
+ "category", category);
+ emoji_list.append(_data);
+ annotations = null;
+ annotations.append("text");
+ annotations.append("variation");
+ annotations.append("selector");
+ _data = new IBus.EmojiData("emoji", "\ufe0e",
+ "annotations", annotations,
+ "description",
+ "VARIATION SELECTOR-15",
+ "category", category);
+ emoji_list.append(_data);
+ annotations = null;
+ annotations.append("emoji");
+ annotations.append("variation");
+ annotations.append("selector");
+ _data = new IBus.EmojiData("emoji", "\ufe0f",
+ "annotations", annotations,
+ "description",
+ "VARIATION SELECTOR-16",
+ "category", category);
+ emoji_list.append(_data);
+ foreach (IBus.EmojiData data in emoji_list) {
+ update_emoji_to_data_dict(data, "en");
+ update_annotation_to_emojis_dict(data);
+ update_category_to_emojis_dict(data, "en");
}
}
@@ -583,10 +634,12 @@ public class IBusEmojier : Gtk.ApplicationWindow {
category = EMOJI_CATEGORY_OTHERS;
if (lang == "en") {
bool has_variant = false;
- foreach (unichar ch in EMOJI_VARIANT_LIST) {
- if (emoji.index_of_char(ch) >= 0) {
- has_variant = true;
- break;
+ if (category.ascii_casecmp("component") != 0) {
+ foreach (unichar ch in EMOJI_VARIANT_LIST) {
+ if (emoji.index_of_char(ch) >= 0) {
+ has_variant = true;
+ break;
+ }
}
}
// If emoji includes variants (skin colors and items),
@@ -606,7 +659,8 @@ public class IBusEmojier : Gtk.ApplicationWindow {
if (variants.find_custom(emoji, GLib.strcmp) == null) {
if (variants == null)
variants.append(base_emoji);
- variants.append(emoji);
+ if (base_emoji != emoji)
+ variants.append(emoji);
m_emoji_to_emoji_variants_dict.replace(
base_emoji,
variants.copy_deep(GLib.strdup));
--
2.21.0

View File

@ -1,60 +0,0 @@
From 1cb5032e85d85f496e349236d1b74f17fb8db966 Mon Sep 17 00:00:00 2001
From: fujiwarat <takao.fujiwara1@gmail.com>
Date: Tue, 23 Apr 2019 15:40:45 +0900
Subject: [PATCH] configure: Move ibus-setup from configure.ac to Makefile.am
@localedir@ can be extracted to ${datarootdir}/locale and
it needs datarootdir=/usr/share in case configure.ac is used
and deleting the datarootdir line caused a regression.
All variables can be extracted in Makefile.am with sed.
---
configure.ac | 1 -
setup/Makefile.am | 13 +++++++++++--
2 files changed, 11 insertions(+), 3 deletions(-)
diff --git a/configure.ac b/configure.ac
index 9518e808..7503f3e8 100644
--- a/configure.ac
+++ b/configure.ac
@@ -724,7 +724,6 @@ ibus/interface/Makefile
ui/Makefile
ui/gtk3/Makefile
setup/Makefile
-setup/ibus-setup
bindings/Makefile
bindings/pygobject/Makefile
bindings/vala/Makefile
diff --git a/setup/Makefile.am b/setup/Makefile.am
index cb4dd8d1..34c8f136 100644
--- a/setup/Makefile.am
+++ b/setup/Makefile.am
@@ -3,8 +3,8 @@
# ibus - The Input Bus
#
# Copyright (c) 2007-2014 Peng Huang <shawn.p.huang@gmail.com>
-# Copyright (c) 2015-2017 Takao Fujiwara <takao.fujiwara1@gmail.com>
-# Copyright (c) 2007-2017 Red Hat, Inc.
+# Copyright (c) 2015-2019 Takao Fujiwara <takao.fujiwara1@gmail.com>
+# Copyright (c) 2007-2019 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
@@ -40,6 +40,15 @@ ibussetup_DATA = \
bin_SCRIPTS = ibus-setup
ibussetupdir = $(pkgdatadir)/setup
+ibus-setup: ibus-setup.in
+ $(AM_V_GEN) sed -e "s|\@datarootdir\@|$(datarootdir)|g" \
+ -e "s|\@localedir\@|$(localedir)|g" \
+ -e "s|\@libexecdir\@|$(libexecdir)|g" \
+ -e "s|\@prefix\@|$(prefix)|g" \
+ -e "s|\@PYTHON\@|$(PYTHON)|g" \
+ $< > $@.tmp && \
+ mv $@.tmp $@
+
desktop_in_files = ibus-setup.desktop.in
desktop_DATA = $(desktop_in_files:.desktop.in=.desktop)
desktopdir = $(datadir)/applications
--
2.21.0

7
gating.yaml Normal file
View File

@ -0,0 +1,7 @@
--- !Policy
product_versions:
- rhel-10
decision_context: osci_compose_gate
rules:
# this is the testcase identifier, which OSCI pipeline uses
- !PassingTestCaseRule {test_case_name: osci.brew-build.tier0.functional}

View File

@ -0,0 +1,638 @@
From 1286ce92a5ccf68b5dcf1b4a7c0884ce29d5c51b Mon Sep 17 00:00:00 2001
From: fujiwarat <takao.fujiwara1@gmail.com>
Date: Fri, 12 Jul 2024 23:30:25 +0900
Subject: [PATCH] Fix SEGV in bus_panel_proxy_focus_in()
rhbz#1350291 SEGV in BUS_IS_CONNECTION(skip_connection) in
bus_dbus_impl_dispatch_message_by_rule()
check if dbus_connection is closed in bus_dbus_impl_connection_filter_cb().
rhbz#1767976 SEGV in assert(connection != NULL) in
bus_dbus_impl_connection_filter_cb()
call bus_connection_set_filter() in bus_dbus_impl_destroy().
rhbz#2213445 SEGV in bus_panel_proxy_new()
WIP: Add a GError.
rhbz#1601577 rhbz#1797726 SEGV in ibus_engine_desc_get_layout() in
bus_engine_proxy_new_internal()
WIP: Add a GError to get the error message to check why the SEGV happened.
rhbz#1663528 SEGV in g_mutex_clear() in bus_dbus_impl_destroy()
If the mutex is not unlocked, g_mutex_clear() causes assert.
rhbz#1767691 SEGV in client/x11/main.c:_sighandler().
Do not call atexit functions in _sighandler().
rhbz#2195895 SEGV in client/x11/main.c:_xim_set_cursor_location()
check if IBusInputContext was disconnected.
rhbz#1795499 rhbz#1936777 SEGV in ibus_bus_get_bus_address() because of
no _bus->priv.
_changed_cb() should not be called after ibus_bus_destroy() is called.
rhbz#1771238 SEGV in assert(m_loop == null) in switcher.vala.
Grabbing keyboard could be failed and switcher received the keyboard
events and m_loop was not released.
rhbz#1797120 SEGV in assert(bus.is_connected()) in panel_binding_construct()
Check m_ibus in extension.vala:bus_name_acquired_cb()
rhbz#2151344 SEGV with portal_context->owner in name_owner_changed()
Maybe g_object_unref() is called but not finalized yet.
rhbz#2239633 SEGV with g_object_unref() in
ibus_portal_context_handle_destroy()
Connect "handle-destroy" signal after g_list_prepend().
BUG=rhbz#1350291
BUG=rhbz#1601577
BUG=rhbz#1663528
BUG=rhbz#1767691
BUG=rhbz#1795499
BUG=rhbz#1771238
BUG=rhbz#1767976
BUG=rhbz#1797120
BUG=rhbz#2151344
BUG=rhbz#2195895
BUG=rhbz#2239633
---
bus/dbusimpl.c | 47 ++++++++++++++++++++++++---
bus/engineproxy.c | 44 +++++++++++++++++++------
bus/panelproxy.c | 9 +++++-
client/x11/main.c | 56 ++++++++++++++++++++++++++++----
portal/portal.c | 25 ++++++++++++---
src/ibusbus.c | 6 ++++
ui/gtk3/extension.vala | 4 +++
ui/gtk3/switcher.vala | 73 +++++++++++++++++++++++++-----------------
8 files changed, 208 insertions(+), 56 deletions(-)
diff --git a/bus/dbusimpl.c b/bus/dbusimpl.c
index 110d864a..391d576a 100644
--- a/bus/dbusimpl.c
+++ b/bus/dbusimpl.c
@@ -621,6 +621,7 @@ static void
bus_dbus_impl_destroy (BusDBusImpl *dbus)
{
GList *p;
+ int i;
for (p = dbus->objects; p != NULL; p = p->next) {
IBusService *object = (IBusService *) p->data;
@@ -644,6 +645,10 @@ bus_dbus_impl_destroy (BusDBusImpl *dbus)
for (p = dbus->connections; p != NULL; p = p->next) {
BusConnection *connection = BUS_CONNECTION (p->data);
+ /* rhbz#1767976 Fix connection == NULL in
+ * bus_dbus_impl_connection_filter_cb()
+ */
+ bus_connection_set_filter (connection, NULL, NULL, NULL);
g_signal_handlers_disconnect_by_func (connection,
bus_dbus_impl_connection_destroy_cb, dbus);
ibus_object_destroy (IBUS_OBJECT (connection));
@@ -658,12 +663,39 @@ bus_dbus_impl_destroy (BusDBusImpl *dbus)
dbus->unique_names = NULL;
dbus->names = NULL;
+ for (i = 0; g_idle_remove_by_data (dbus); i++) {
+ if (i > 1000) {
+ g_warning ("Too many idle threads were generated by " \
+ "bus_dbus_impl_forward_message_idle_cb and " \
+ "bus_dbus_impl_dispatch_message_by_rule_idle_cb");
+ break;
+ }
+ }
g_list_free_full (dbus->start_service_calls,
(GDestroyNotify) bus_method_call_free);
dbus->start_service_calls = NULL;
- g_mutex_clear (&dbus->dispatch_lock);
- g_mutex_clear (&dbus->forward_lock);
+ /* rhbz#1663528 Call g_mutex_trylock() before g_mutex_clear()
+ * because if the mutex is not unlocked, g_mutex_clear() causes assert.
+ */
+#define BUS_DBUS_MUTEX_SAFE_CLEAR(mtex) { \
+ int count = 0; \
+ while (!g_mutex_trylock ((mtex))) { \
+ g_usleep (1); \
+ if (count > 60) { \
+ g_warning (#mtex " is dead lock"); \
+ break; \
+ } \
+ ++count; \
+ } \
+ g_mutex_unlock ((mtex)); \
+ g_mutex_clear ((mtex)); \
+}
+
+ BUS_DBUS_MUTEX_SAFE_CLEAR (&dbus->dispatch_lock);
+ BUS_DBUS_MUTEX_SAFE_CLEAR (&dbus->forward_lock);
+
+#undef BUS_DBUS_MUTEX_SAFE_CLEAR
/* FIXME destruct _lock and _queue members. */
IBUS_OBJECT_CLASS(bus_dbus_impl_parent_class)->destroy ((IBusObject *)dbus);
@@ -1539,13 +1571,20 @@ bus_dbus_impl_connection_filter_cb (GDBusConnection *dbus_connection,
gboolean incoming,
gpointer user_data)
{
+ BusDBusImpl *dbus;
+ BusConnection *connection;
+
g_assert (G_IS_DBUS_CONNECTION (dbus_connection));
g_assert (G_IS_DBUS_MESSAGE (message));
g_assert (BUS_IS_DBUS_IMPL (user_data));
- BusDBusImpl *dbus = (BusDBusImpl *) user_data;
- BusConnection *connection = bus_connection_lookup (dbus_connection);
+ if (g_dbus_connection_is_closed (dbus_connection))
+ return NULL;
+
+ dbus = (BusDBusImpl *) user_data;
+ connection = bus_connection_lookup (dbus_connection);
g_assert (connection != NULL);
+ g_assert (BUS_IS_CONNECTION (connection));
if (incoming) {
/* is incoming message */
diff --git a/bus/engineproxy.c b/bus/engineproxy.c
index b3e16066..ba479b59 100644
--- a/bus/engineproxy.c
+++ b/bus/engineproxy.c
@@ -696,7 +696,8 @@ bus_engine_proxy_g_signal (GDBusProxy *proxy,
static BusEngineProxy *
bus_engine_proxy_new_internal (const gchar *path,
IBusEngineDesc *desc,
- GDBusConnection *connection)
+ GDBusConnection *connection,
+ GError **error)
{
GDBusProxyFlags flags;
BusEngineProxy *engine;
@@ -706,12 +707,20 @@ bus_engine_proxy_new_internal (const gchar *path,
g_assert (path);
g_assert (IBUS_IS_ENGINE_DESC (desc));
g_assert (G_IS_DBUS_CONNECTION (connection));
+ g_assert (error && *error == NULL);
+ /* rhbz#1601577 engine == NULL if connection is closed. */
+ if (g_dbus_connection_is_closed (connection)) {
+ *error = g_error_new (G_DBUS_ERROR,
+ G_DBUS_ERROR_FAILED,
+ "Connection is closed.");
+ return NULL;
+ }
flags = G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START;
engine = (BusEngineProxy *) g_initable_new (
BUS_TYPE_ENGINE_PROXY,
NULL,
- NULL,
+ error,
"desc", desc,
"g-connection", connection,
"g-interface-name", IBUS_INTERFACE_ENGINE,
@@ -719,6 +728,12 @@ bus_engine_proxy_new_internal (const gchar *path,
"g-default-timeout", g_gdbus_timeout,
"g-flags", flags,
NULL);
+ /* FIXME: rhbz#1601577 */
+ if (!engine) {
+ /* show abrt local variable */
+ gchar *message = g_strdup ((*error)->message);
+ g_error ("%s", message);
+ }
const gchar *layout = ibus_engine_desc_get_layout (desc);
if (layout != NULL && layout[0] != '\0') {
engine->keymap = ibus_keymap_get (layout);
@@ -818,23 +833,30 @@ create_engine_ready_cb (BusFactoryProxy *factory,
GAsyncResult *res,
EngineProxyNewData *data)
{
+ GError *error = NULL;
+ gchar *path;
+ BusEngineProxy *engine;
+
g_return_if_fail (data->task != NULL);
- GError *error = NULL;
- gchar *path = bus_factory_proxy_create_engine_finish (factory,
- res,
- &error);
+ path = bus_factory_proxy_create_engine_finish (factory, res, &error);
if (path == NULL) {
g_task_return_error (data->task, error);
engine_proxy_new_data_free (data);
return;
}
- BusEngineProxy *engine =
- bus_engine_proxy_new_internal (path,
- data->desc,
- g_dbus_proxy_get_connection ((GDBusProxy *)data->factory));
+ engine = bus_engine_proxy_new_internal (
+ path,
+ data->desc,
+ g_dbus_proxy_get_connection ((GDBusProxy *)data->factory),
+ &error);
g_free (path);
+ if (!engine) {
+ g_task_return_error (data->task, error);
+ engine_proxy_new_data_free (data);
+ return;
+ }
/* FIXME: set destroy callback ? */
g_task_return_pointer (data->task, engine, NULL);
diff --git a/bus/panelproxy.c b/bus/panelproxy.c
index e6001ebf..00828fbc 100644
--- a/bus/panelproxy.c
+++ b/bus/panelproxy.c
@@ -122,6 +122,8 @@ bus_panel_proxy_new (BusConnection *connection,
const gchar *path = NULL;
GObject *obj;
BusPanelProxy *panel;
+ GError *error = NULL;
+ const gchar *message;
g_assert (BUS_IS_CONNECTION (connection));
@@ -138,7 +140,7 @@ bus_panel_proxy_new (BusConnection *connection,
obj = g_initable_new (BUS_TYPE_PANEL_PROXY,
NULL,
- NULL,
+ &error,
"g-object-path", path,
"g-interface-name", IBUS_INTERFACE_PANEL,
"g-connection", bus_connection_get_dbus_connection (connection),
@@ -146,6 +148,11 @@ bus_panel_proxy_new (BusConnection *connection,
"g-flags", G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START | G_DBUS_PROXY_FLAGS_DO_NOT_LOAD_PROPERTIES,
NULL);
+ if (error) {
+ /* TODO: rhbz#2213445 Why does this issue happen? */
+ message = error->message;
+ g_critical ("Failed to generate BusPanelProxy: %s", message);
+ }
panel = BUS_PANEL_PROXY (obj);
panel->panel_type = panel_type;
return panel;
diff --git a/client/x11/main.c b/client/x11/main.c
index b7eb5961..3075d5d0 100644
--- a/client/x11/main.c
+++ b/client/x11/main.c
@@ -45,6 +45,7 @@
#include <iconv.h>
#include <signal.h>
#include <stdlib.h>
+#include <unistd.h>
#include <getopt.h>
@@ -69,6 +70,7 @@ typedef struct _X11ICONN X11ICONN;
typedef struct _X11IC X11IC;
struct _X11IC {
IBusInputContext *context;
+ gboolean ibus_connected;
Window client_window;
Window focus_window;
gint32 input_style;
@@ -327,6 +329,18 @@ _xim_store_ic_values (X11IC *x11ic, IMChangeICStruct *call_data)
return 1;
}
+static void
+ibus_ic_connection_closed_cb (GDBusConnection *connection,
+ gboolean remote_peer_vanished,
+ GError *error,
+ X11IC *x11ic)
+{
+ /* rhbz#2195895 The moment of the IBusBus disconnection would be
+ * different from the moment of XIM_DISCONNECT.
+ */
+ x11ic->ibus_connected = FALSE;
+}
+
static int
xim_create_ic (XIMS xims, IMChangeICStruct *call_data)
@@ -334,6 +348,7 @@ xim_create_ic (XIMS xims, IMChangeICStruct *call_data)
static int base_icid = 1;
X11IC *x11ic;
guint32 capabilities = IBUS_CAP_FOCUS;
+ GDBusConnection *connection;
call_data->icid = base_icid ++;
@@ -345,8 +360,9 @@ xim_create_ic (XIMS xims, IMChangeICStruct *call_data)
x11ic->icid = call_data->icid;
x11ic->connect_id = call_data->connect_id;
- x11ic->conn = (X11ICONN *)g_hash_table_lookup (_connections,
- GINT_TO_POINTER ((gint) call_data->connect_id));
+ x11ic->conn = (X11ICONN *)g_hash_table_lookup (
+ _connections,
+ GINT_TO_POINTER ((gint) call_data->connect_id));
if (x11ic->conn == NULL) {
g_slice_free (X11IC, x11ic);
g_return_val_if_reached (0);
@@ -376,6 +392,10 @@ xim_create_ic (XIMS xims, IMChangeICStruct *call_data)
G_CALLBACK (_context_enabled_cb), x11ic);
g_signal_connect (x11ic->context, "disabled",
G_CALLBACK (_context_disabled_cb), x11ic);
+ connection = g_dbus_proxy_get_connection (G_DBUS_PROXY (x11ic->context));
+ x11ic->ibus_connected = !g_dbus_connection_is_closed (connection);
+ g_signal_connect (connection, "closed",
+ G_CALLBACK (ibus_ic_connection_closed_cb), x11ic);
if (x11ic->input_style & XIMPreeditCallbacks)
@@ -400,11 +420,19 @@ xim_destroy_ic (XIMS xims, IMChangeICStruct *call_data)
LOG (1, "XIM_DESTROY_IC ic=%d connect_id=%d",
call_data->icid, call_data->connect_id);
- x11ic = (X11IC *)g_hash_table_lookup (_x11_ic_table,
- GINT_TO_POINTER ((gint) call_data->icid));
+ x11ic = (X11IC *)g_hash_table_lookup (
+ _x11_ic_table,
+ GINT_TO_POINTER ((gint) call_data->icid));
g_return_val_if_fail (x11ic != NULL, 0);
if (x11ic->context) {
+ GDBusConnection *connection =
+ g_dbus_proxy_get_connection (G_DBUS_PROXY (x11ic->context));
+ x11ic->ibus_connected = FALSE;
+ g_signal_handlers_disconnect_by_func (
+ connection,
+ (GCallback)ibus_ic_connection_closed_cb,
+ x11ic);
ibus_proxy_destroy ((IBusProxy *)x11ic->context);
g_object_unref (x11ic->context);
x11ic->context = NULL;
@@ -412,7 +440,8 @@ xim_destroy_ic (XIMS xims, IMChangeICStruct *call_data)
g_hash_table_remove (_x11_ic_table,
GINT_TO_POINTER ((gint) call_data->icid));
- x11ic->conn->clients = g_list_remove (x11ic->conn->clients, (gconstpointer)x11ic);
+ x11ic->conn->clients = g_list_remove (x11ic->conn->clients,
+ (gconstpointer)x11ic);
g_free (x11ic->preedit_string);
x11ic->preedit_string = NULL;
@@ -439,6 +468,8 @@ xim_set_ic_focus (XIMS xims, IMChangeFocusStruct *call_data)
x11ic = (X11IC *) g_hash_table_lookup (_x11_ic_table,
GINT_TO_POINTER ((gint) call_data->icid));
g_return_val_if_fail (x11ic != NULL, 0);
+ if (!x11ic->ibus_connected)
+ return 1;
ibus_input_context_focus_in (x11ic->context);
_xim_set_cursor_location (x11ic);
@@ -458,6 +489,8 @@ xim_unset_ic_focus (XIMS xims, IMChangeFocusStruct *call_data)
x11ic = (X11IC *) g_hash_table_lookup (_x11_ic_table,
GINT_TO_POINTER ((gint) call_data->icid));
g_return_val_if_fail (x11ic != NULL, 0);
+ if (!x11ic->ibus_connected)
+ return 1;
ibus_input_context_focus_out (x11ic->context);
@@ -712,6 +745,8 @@ xim_forward_event (XIMS xims, IMForwardEventStruct *call_data)
_x11_ic_table,
GINT_TO_POINTER ((gint) call_data->icid));
g_return_val_if_fail (x11ic != NULL, 0);
+ if (!x11ic->ibus_connected)
+ return 0;
xevent = (XKeyEvent*) &(call_data->event);
@@ -870,6 +905,8 @@ _xim_set_cursor_location (X11IC *x11ic)
}
}
+ if (!x11ic->ibus_connected)
+ return;
ibus_input_context_set_cursor_location (x11ic->context,
preedit_area.x,
preedit_area.y,
@@ -950,6 +987,8 @@ xim_reset_ic (XIMS xims, IMResetICStruct *call_data)
x11ic = (X11IC *) g_hash_table_lookup (_x11_ic_table,
GINT_TO_POINTER ((gint) call_data->icid));
g_return_val_if_fail (x11ic != NULL, 0);
+ if (!x11ic->ibus_connected)
+ return 1;
ibus_input_context_reset (x11ic->context);
@@ -1309,7 +1348,12 @@ _atexit_cb ()
static void
_sighandler (int sig)
{
- exit(EXIT_FAILURE);
+ /* rhbz#1767691 _sighandler() is called with SIGTERM
+ * and exit() causes SEGV during calling atexit functions.
+ * _atexit_cb() might be broken. _exit() does not call
+ * atexit functions.
+ */
+ _exit(EXIT_FAILURE);
}
static void
diff --git a/portal/portal.c b/portal/portal.c
index 5cd38779..5110baad 100644
--- a/portal/portal.c
+++ b/portal/portal.c
@@ -92,6 +92,11 @@ static void portal_context_g_signal (GDBusProxy *proxy,
GVariant *parameters,
IBusPortalContext *portal_context);
+#define IBUS_TYPE_PORTAL_CONTEXT \
+ (ibus_portal_context_get_type ())
+#define IBUS_IS_PORTAL_CONTEXT(obj) \
+ (G_TYPE_CHECK_INSTANCE_TYPE ((obj), IBUS_TYPE_PORTAL_CONTEXT))
+
G_DEFINE_TYPE_WITH_CODE (IBusPortalContext,
ibus_portal_context,
IBUS_DBUS_TYPE_INPUT_CONTEXT_SKELETON,
@@ -492,11 +497,6 @@ ibus_portal_context_new (IBusInputContext *context,
g_strdup_printf (IBUS_PATH_INPUT_CONTEXT, portal_context->id);
portal_context->service = ibus_dbus_service_skeleton_new ();
- g_signal_connect (portal_context->service,
- "handle-destroy",
- G_CALLBACK (ibus_portal_context_handle_destroy),
- portal_context);
-
if (!g_dbus_interface_skeleton_export (
G_DBUS_INTERFACE_SKELETON (portal_context->service),
connection, portal_context->object_path,
@@ -509,8 +509,17 @@ ibus_portal_context_new (IBusInputContext *context,
return NULL;
}
+ /* rhbz#2239633 g_list_prepend() needs to be callsed before
+ * ibus_portal_context_handle_destroy() is connected
+ * for g_list_remove() in ibus_portal_context_finalize().
+ */
all_contexts = g_list_prepend (all_contexts, portal_context);
+ g_signal_connect (portal_context->service,
+ "handle-destroy",
+ G_CALLBACK (ibus_portal_context_handle_destroy),
+ portal_context);
+
return portal_context;
}
@@ -667,6 +676,12 @@ name_owner_changed (GDBusConnection *connection,
IBusPortalContext *portal_context = l->data;
next = l->next;
+ /* rhbz#2151344 portal_context might not be finalized? */
+ if (!G_LIKELY (IBUS_IS_PORTAL_CONTEXT (portal_context))) {
+ g_warn_message (G_LOG_DOMAIN, __FILE__, __LINE__, G_STRFUNC,
+ "portal_context is not IBusPortalContext");
+ continue;
+ }
if (g_strcmp0 (portal_context->owner, name) == 0) {
g_object_unref (portal_context);
}
diff --git a/src/ibusbus.c b/src/ibusbus.c
index 0e6d67f1..fcc742b6 100644
--- a/src/ibusbus.c
+++ b/src/ibusbus.c
@@ -742,6 +742,12 @@ ibus_bus_destroy (IBusObject *object)
_bus = NULL;
if (bus->priv->monitor) {
+ /* rhbz#1795499 _changed_cb() causes SEGV because of no bus->priv
+ * after ibus_bus_destroy() is called.
+ */
+ g_signal_handlers_disconnect_by_func (bus->priv->monitor,
+ (GCallback) _changed_cb, bus);
+ g_file_monitor_cancel (bus->priv->monitor);
g_object_unref (bus->priv->monitor);
bus->priv->monitor = NULL;
}
diff --git a/ui/gtk3/extension.vala b/ui/gtk3/extension.vala
index a6f2e8e6..b7a04081 100644
--- a/ui/gtk3/extension.vala
+++ b/ui/gtk3/extension.vala
@@ -73,6 +73,10 @@ class ExtensionGtk : Gtk.Application {
string signal_name,
Variant parameters) {
debug("signal_name = %s", signal_name);
+ /* rhbz#1797120 Fix assert(bus.is_connected()) in
+ * panel_binding_construct()
+ */
+ return_if_fail(m_bus.is_connected());
m_panel = new PanelBinding(m_bus, this);
m_panel.load_settings();
}
diff --git a/ui/gtk3/switcher.vala b/ui/gtk3/switcher.vala
index 26bded99..21ede7be 100644
--- a/ui/gtk3/switcher.vala
+++ b/ui/gtk3/switcher.vala
@@ -176,8 +176,8 @@ class Switcher : Gtk.Window {
IBus.EngineDesc[] engines,
int index,
string input_context_path) {
- assert (m_loop == null);
- assert (index < engines.length);
+ assert(m_loop == null);
+ assert(index < engines.length);
if (m_is_running)
return index;
@@ -236,16 +236,18 @@ class Switcher : Gtk.Window {
null,
event,
null);
- if (status != Gdk.GrabStatus.SUCCESS)
+ if (status != Gdk.GrabStatus.SUCCESS) {
warning("Grab keyboard failed! status = %d", status);
- status = seat.grab(get_window(),
- Gdk.SeatCapabilities.POINTER,
- true,
- null,
- event,
- null);
- if (status != Gdk.GrabStatus.SUCCESS)
- warning("Grab pointer failed! status = %d", status);
+ } else {
+ status = seat.grab(get_window(),
+ Gdk.SeatCapabilities.POINTER,
+ true,
+ null,
+ event,
+ null);
+ if (status != Gdk.GrabStatus.SUCCESS)
+ warning("Grab pointer failed! status = %d", status);
+ }
#else
Gdk.Device device = event.get_device();
if (device == null) {
@@ -281,30 +283,41 @@ class Switcher : Gtk.Window {
Gdk.EventMask.KEY_RELEASE_MASK,
null,
Gdk.CURRENT_TIME);
- if (status != Gdk.GrabStatus.SUCCESS)
+ if (status != Gdk.GrabStatus.SUCCESS) {
warning("Grab keyboard failed! status = %d", status);
- // Grab all pointer events
- status = pointer.grab(get_window(),
- Gdk.GrabOwnership.NONE,
- true,
- Gdk.EventMask.BUTTON_PRESS_MASK |
- Gdk.EventMask.BUTTON_RELEASE_MASK,
- null,
- Gdk.CURRENT_TIME);
- if (status != Gdk.GrabStatus.SUCCESS)
- warning("Grab pointer failed! status = %d", status);
+ } else {
+ // Grab all pointer events
+ status = pointer.grab(get_window(),
+ Gdk.GrabOwnership.NONE,
+ true,
+ Gdk.EventMask.BUTTON_PRESS_MASK |
+ Gdk.EventMask.BUTTON_RELEASE_MASK,
+ null,
+ Gdk.CURRENT_TIME);
+ if (status != Gdk.GrabStatus.SUCCESS)
+ warning("Grab pointer failed! status = %d", status);
+ }
#endif
- // Probably we can delete m_popup_delay_time in 1.6
- pointer.get_position_double(null,
- out m_mouse_init_x,
- out m_mouse_init_y);
- m_mouse_moved = false;
+ /* Fix RHBZ #1771238 assert(m_loop == null)
+ * Grabbing keyboard can be failed when the second Super-e is typed
+ * before Switcher dialog is focused. And m_loop could not be released
+ * if the failed Super-e would call m_loop.run() below and could not
+ * call key_release_event(). And m_loop == null would be false in the
+ * third Super-e.
+ */
+ if (status == Gdk.GrabStatus.SUCCESS) {
+ // Probably we can delete m_popup_delay_time in 1.6
+ pointer.get_position_double(null,
+ out m_mouse_init_x,
+ out m_mouse_init_y);
+ m_mouse_moved = false;
- m_loop = new GLib.MainLoop();
- m_loop.run();
- m_loop = null;
+ m_loop = new GLib.MainLoop();
+ m_loop.run();
+ m_loop = null;
+ }
#if VALA_0_34
seat.ungrab();
--
2.45.0

0
ibus-HEAD.patch Normal file
View File

View File

@ -6,6 +6,10 @@ PREFERENCE_PROGRAM=/usr/bin/ibus-setup
SHORT_DESC="IBus" SHORT_DESC="IBus"
GTK_IM_MODULE=ibus GTK_IM_MODULE=ibus
NOT_RUN=gnome3 NOT_RUN=gnome3
# IMSETTINGS_IGNORE_SESSION concatenate the current session name and type x11 or
# wayland. The current session name is calculated by get_destop()
# in /usr/libexec/imsettings-functions and the value is case-sensitive.
IMSETTINGS_IGNORE_SESSION=KDE-wayland
if test -f /usr/lib64/qt5/plugins/platforminputcontexts/libibusplatforminputcontextplugin.so || \ if test -f /usr/lib64/qt5/plugins/platforminputcontexts/libibusplatforminputcontextplugin.so || \
test -f /usr/lib/qt5/plugins/platforminputcontexts/libibusplatforminputcontextplugin.so || \ test -f /usr/lib/qt5/plugins/platforminputcontexts/libibusplatforminputcontextplugin.so || \

File diff suppressed because it is too large Load Diff

4
ibus.tar.gz.sum Normal file
View File

@ -0,0 +1,4 @@
cksum 3075875856 4108303 ibus-1.5.31.tar.gz
sha1sum 02c754a119a1a1f88ed8d578148e8ec609496733 ibus-1.5.31.tar.gz
sha256sum 5093994c8342551134c81f2d271575efbc459bb756cef1173c22430c8601a1e1 ibus-1.5.31.tar.gz
sha512sum adfad740002662262981ddfcc3f6eb1e898433d3bd90b07535ceef367d496d3da3e0836e59133d0063caf2d3d55d0deb6cf18ae2807fdd1ce4afab84a7725ca5 ibus-1.5.31.tar.gz

5
plans/test.fmf Normal file
View File

@ -0,0 +1,5 @@
summary: Basic smoke test
discover:
how: fmf
execute:
how: tmt

1
sources Normal file
View File

@ -0,0 +1 @@
SHA512 (ibus-1.5.31.tar.gz) = adfad740002662262981ddfcc3f6eb1e898433d3bd90b07535ceef367d496d3da3e0836e59133d0063caf2d3d55d0deb6cf18ae2807fdd1ce4afab84a7725ca5

View File

@ -0,0 +1,88 @@
summary: Install common GNOME desktop components
description:
The listed packages are installed commonly between Fedora and
RHEL GNOME desktop components.
require:
# IBus CI sets
- ibus
- ibus-desktop-testing
- dbus-x11
# https://pagure.io/fedora-comps/blob/main/f/comps-f41.xml.in
# dnf group info GNOME
# base-graphical mandatory
- mesa-dri-drivers
- mesa-vulkan-drivers
- plymouth-system-theme
# fonts default
- default-fonts-cjk-mono
- default-fonts-cjk-sans
- default-fonts-cjk-serif
- default-fonts-core-emoji
- default-fonts-core-math
- default-fonts-core-mono
- default-fonts-core-sans
- default-fonts-core-serif
- default-fonts-other-mono
- default-fonts-other-sans
- default-fonts-other-serif
# gnome-desktop mandatory
- dconf
- gdm
- gnome-connections
- gnome-control-center
- gnome-initial-setup
- gnome-session-wayland-session
- gnome-settings-daemon
- gnome-shell
- gnome-software
- gnome-text-editor
- nautilus
- polkit
- ptyxis
# gnome-desktop default
- avahi
- baobab
# Sometimes version mismatch with gnome-shell in rawhide
#- chrome-gnome-shell
- fprintd-pam
- glib-networking
- gnome-bluetooth
- gnome-browser-connector
- gnome-calculator
- gnome-characters
- gnome-classic-session
- gnome-clocks
- gnome-color-manager
- gnome-disk-utility
- gnome-font-viewer
- gnome-remote-desktop
- gnome-system-monitor
- gnome-user-docs
- gvfs-goa
- gvfs-mtp
- librsvg2
- libsane-hpaio
- loupe
- mesa-dri-drivers
- mesa-libEGL
- ModemManager
- NetworkManager-adsl
- NetworkManager-ppp
- NetworkManager-wwan
- PackageKit-command-not-found
- PackageKit-gtk3-module
- sane-backends-drivers-scanners
- snapshot
# Move systemd-oomd-defaults to Post-Installing section
- tracker
- tracker-miners
- xdg-desktop-portal
- xdg-desktop-portal-gnome
- xdg-desktop-portal-gtk
- xdg-user-dirs-gtk
# desktop-accessibility default
- at-spi2-atk
- at-spi2-core
- brltty
- orca
- speech-dispatcher

View File

@ -0,0 +1,41 @@
summary: Install Fedora specific GNOME desktop components
description:
The listed packages are available in Fedora only.
enabled: false
adjust:
when: distro == fedora
enabled: true
require:
- adobe-source-code-pro-fonts
- gnome-screenshot
- gnome-boxes
- yelp
- cheese
- eog
- evince
- evince-djvu
- gnome-backgrounds
- gnome-calendar
- gnome-contacts
- gnome-epub-thumbnailer
- gnome-logs
- gnome-maps
- gnome-photos
- gnome-themes-extra
- gnome-user-share
- gnome-weather
- gvfs-afc
- gvfs-afp
- gvfs-archive
- gvfs-fuse
- gvfs-gphoto2
- gvfs-smb
- NetworkManager-openconnect-gnome
- NetworkManager-openvpn-gnome
- NetworkManager-pptp-gnome
- NetworkManager-ssh-gnome
- NetworkManager-vpnc-gnome
- rygel
- simple-scan
- sushi
- totem

View File

@ -0,0 +1,7 @@
summary: Install RHEL specific GNOME desktop components
description:
Currently no specific packages for RHEL.
enabled: false
adjust:
when: distro != fedora
enabled: true

View File

@ -0,0 +1,6 @@
summary: Install GNOME installed-tests testing harness
description:
gnome-desktop-testing package is required by IBus CI(ibus-desktop-testing)
and it's available in Fedora only at present.
require:
- gnome-desktop-testing

View File

@ -0,0 +1,5 @@
summary: Install TMT packages
description:
The test script is calling the beakerlib script.
require:
- beakerlib

View File

@ -0,0 +1,10 @@
summary: Install ibus specific packages
description:
The listed packages are required by CI of ibus core.
require:
- ibus-tests
# ibus-compose test needs locales
- glibc-langpack-el
- glibc-langpack-fi
- glibc-langpack-ja
- glibc-langpack-pt

View File

@ -0,0 +1,3 @@
summary: gnome-desktop-testing tests
# common test for sub tests
test: env

View File

@ -0,0 +1,5 @@
summary: Run tests
description:
Run CI with ibus-desktop-testing-runner in GNOME Wayland.
duration: 15m
test: ./test.sh

View File

@ -0,0 +1,15 @@
#!/bin/bash
# vim: dict+=/usr/share/beakerlib/dictionary.vim cpt=.,w,b,u,t,i,k
. /usr/share/beakerlib/beakerlib.sh || exit 1
rlJournalStart
rlPhaseStartTest
rlRun -t "/usr/bin/ibus-desktop-testing-runner --runner gnome --no-graphics --lang ja_JP.UTF-8"
rlPhaseEnd
rlPhaseStartCleanup
rlRun "echo test-suite.log"
rlRun "cat test-suite.log"
rlRun "echo /export/home/itestuser/test-autostart.log"
rlRun "cat /export/home/itestuser/test-autostart.log"
rlPhaseEnd
rlJournalEnd

View File

@ -0,0 +1,157 @@
#!/usr/bin/python3
import argparse
import pam
import pwd
import os
import signal
import sys
import gi
gi.require_version('AccountsService', '1.0')
from gi.repository import AccountsService, GLib
def run_desktop_in_new_session(pam_environment, user, session_desktop, tty_input, tty_output):
keyfile = GLib.KeyFile()
keyfile.load_from_data_dirs(f'wayland-sessions/{session_desktop}.desktop',
GLib.KeyFileFlags.NONE)
try:
can_run_headless = keyfile.get_boolean(GLib.KEY_FILE_DESKTOP_GROUP,
'X-GDM-CanRunHeadless')
except GLib.GError:
raise Exception(f"Session {session_desktop} can't run headlessly")
if not can_run_headless:
raise Exception(f"Session {session_desktop} can't run headlessly")
executable = keyfile.get_string(GLib.KEY_FILE_DESKTOP_GROUP,
GLib.KEY_FILE_DESKTOP_KEY_TRY_EXEC)
if GLib.find_program_in_path(executable) is None:
raise Exception(f"Invalid session {session_desktop}")
command = keyfile.get_string(GLib.KEY_FILE_DESKTOP_GROUP,
GLib.KEY_FILE_DESKTOP_KEY_EXEC)
[success, args] = GLib.shell_parse_argv(command)
pam_handle = pam.pam()
for key, value in pam_environment.items():
pam_handle.putenv(f'{key}={value}')
if not pam_handle.authenticate(user, '', service='gdm-autologin', call_end=False):
raise Exception("Authentication failed")
for key, value in pam_environment.items():
pam_handle.putenv(f'{key}={value}')
if pam_handle.open_session() != pam.PAM_SUCCESS:
raise Exception("Failed to open PAM session")
session_environment = os.environ.copy()
session_environment.update(pam_handle.getenvlist())
user_info = pwd.getpwnam(user)
uid = user_info.pw_uid
gid = user_info.pw_gid
old_tty_output = os.fdopen(os.dup(2), 'w')
pid = os.fork()
if pid == 0:
try:
os.setsid()
except OSError as e:
print(f"Could not create new pid session: {e}", file=old_tty_output)
try:
os.dup2(tty_input.fileno(), 0)
os.dup2(tty_output.fileno(), 1)
os.dup2(tty_output.fileno(), 2)
except OSError as e:
print(f"Could not set up standard i/o: {e}", file=old_tty_output)
try:
os.initgroups(user, gid)
os.setgid(gid)
os.setuid(uid);
except OSError as e:
print(f"Could not become user {user} (uid={uid}): {e}", file=old_tty_output)
try:
os.execvpe(args[0], args, session_environment)
except OSError as e:
print(f"Could not run program \"{' '.join(arguments)}\": {e}", file=old_tty_output)
os._exit(1)
def signal_handler(sig, frame):
os.kill(pid, sig)
signal.signal(signal.SIGTERM, signal_handler)
try:
(_, exit_code) = os.waitpid(pid, 0);
except KeyboardInterrupt:
os.kill(pid, signal.SIGTERM)
except OSError as e:
print(f"Could not wait for program to finish: {e}", file=old_tty_output)
if os.WIFEXITED(exit_code):
exit_code = os.WEXITSTATUS(exit_code)
else:
os.kill(os.getpid(), os.WTERMSIG(exit_code))
old_tty_output.close()
if pam_handle.close_session() != pam.PAM_SUCCESS:
raise Exception("Failed to close PAM session")
pam_handle.end()
return exit_code
def wait_for_user_data(user):
main_context = GLib.MainContext.default()
while not user.is_loaded():
main_context.iteration(True)
def main():
parser = argparse.ArgumentParser(description='Run a desktop session in a PAM session as a specified user.')
parser.add_argument('--user', help='Username for which to run the session')
args = parser.parse_args()
if args.user is None:
parser.print_usage()
sys.exit(1)
try:
tty_path = '/dev/null'
tty_input = open(tty_path, 'r')
tty_output = open(tty_path, 'w')
except OSError as e:
raise Exception(f"Error opening /dev/null as tty associated with VT {vt}: {e}")
user_manager = AccountsService.UserManager().get_default()
user = user_manager.get_user(args.user)
wait_for_user_data(user)
session_desktop = user.get_session()
if not session_desktop:
session_desktop = 'gnome'
pam_environment = {}
pam_environment['XDG_SESSION_TYPE'] = 'wayland'
pam_environment['XDG_SESSION_CLASS'] = 'user'
pam_environment['XDG_SESSION_DESKTOP'] = session_desktop
try:
result = run_desktop_in_new_session(pam_environment, args.user, session_desktop, tty_input, tty_output)
except Exception as e:
raise Exception(f"Error running desktop session \"{session_desktop}\": {e}")
tty_input.close()
tty_output.close()
sys.exit(result)
if __name__ == '__main__':
main()

View File

@ -0,0 +1,6 @@
[Unit]
Description=Headless desktop session
[Service]
ExecStart=/usr/libexec/gdm-headless-login-session --user=%i
Restart=on-failure

View File

@ -0,0 +1,26 @@
/*
No overview at start-up
GNOME Shell 45+ extension
Contributors: @fthx
License: GPL v3
*/
import * as Main from 'resource:///org/gnome/shell/ui/main.js';
export default class NoOverviewExtension {
enable() {
if (!Main.layoutManager._startingUp) {
return;
}
Main.layoutManager.connectObject(
'startup-complete',
() => Main.overview.hide(),
this
);
}
disable() {
Main.layoutManager.disconnectObject(this);
}
}

View File

@ -0,0 +1,10 @@
{
"_generated": "Generated by SweetTooth, do not edit",
"description": "No overview at start-up. Nothing more.",
"name": "No overview at start-up",
"original-authors": ["fthx"],
"shell-version": ["46"],
"url": "https://github.com/fthx/no-overview",
"uuid": "no-overview@fthx",
"version": 999
}

1
tests/main.fmt Normal file
View File

@ -0,0 +1 @@
contact: Takao Fujiwara <fujiwara@redhat.com>