4564 lines
167 KiB
Diff
4564 lines
167 KiB
Diff
From 17648f0522910480b6c5dd4f5356ca1f6c160bf5 Mon Sep 17 00:00:00 2001
|
|
From: Carlos Garnacho <carlosg@gnome.org>
|
|
Date: Tue, 29 Mar 2022 22:48:19 +0200
|
|
Subject: [PATCH] src: Fix refcounting issues
|
|
|
|
Commit 5a455b1ead attempted to fix both GLib warnings around
|
|
floating references and other presumed refcounting issues. However
|
|
it missed 2 kinds of bugs:
|
|
|
|
- The places that take an IBusText created from a static string
|
|
were made to avoid freeing it afterwards, but the staticness refers
|
|
to the string content, not the object itself.
|
|
- The places that are documented to emit signals on floating object
|
|
references used to do the following after signal emission:
|
|
|
|
if (g_object_is_floating (object))
|
|
g_object_unref (object)
|
|
|
|
And did possibly trigger GLib warnings were changed to:
|
|
|
|
if (g_object_is_floating (object))
|
|
g_object_sink_ref (object);
|
|
g_object_unref (object);
|
|
|
|
Which fixes the GLib warning for floating references, but do
|
|
unintendedly steal one reference away for non floating references.
|
|
|
|
This commit is essentially a revert of commit 5a455b1ead, but
|
|
addressing both things differently:
|
|
|
|
- All label/tooltip/symbol IBusText properties in IBusProperty do
|
|
now always sink the reference of the stored object.
|
|
|
|
- All places documented as maybe using objects with a floating reference
|
|
on signals changed to doing:
|
|
|
|
if (g_object_is_floating (object)) {
|
|
g_object_ref_sink (object);
|
|
g_object_unref (object);
|
|
}
|
|
|
|
So the floating reference is owned and unreferenced without warnings,
|
|
but already owned references are left unchanged.
|
|
|
|
This addresses the possible GLib warnings, fixes the possible double
|
|
unrefs happening on IBusText used in signals, and fixes the missing
|
|
unrefs on IBusText objects created from static strings.
|
|
|
|
BUG=https://github.com/ibus/ibus/issues/2393
|
|
BUG=https://github.com/ibus/ibus/issues/2387
|
|
---
|
|
src/ibusinputcontext.c | 35 +++++++++++++++++++++--------------
|
|
src/ibusproperty.c | 32 +++++++++++++++++---------------
|
|
2 files changed, 38 insertions(+), 29 deletions(-)
|
|
|
|
diff --git a/src/ibusinputcontext.c b/src/ibusinputcontext.c
|
|
index 4b27551b..7981de38 100644
|
|
--- a/src/ibusinputcontext.c
|
|
+++ b/src/ibusinputcontext.c
|
|
@@ -549,9 +549,10 @@ ibus_input_context_g_signal (GDBusProxy *proxy,
|
|
g_variant_unref (variant);
|
|
g_signal_emit (context, context_signals[COMMIT_TEXT], 0, text);
|
|
|
|
- if (g_object_is_floating (text))
|
|
+ if (g_object_is_floating (text)) {
|
|
g_object_ref_sink (text);
|
|
- g_object_unref (text);
|
|
+ g_object_unref (text);
|
|
+ }
|
|
return;
|
|
}
|
|
if (g_strcmp0 (signal_name, "UpdatePreeditText") == 0) {
|
|
@@ -569,9 +570,10 @@ ibus_input_context_g_signal (GDBusProxy *proxy,
|
|
cursor_pos,
|
|
visible);
|
|
|
|
- if (g_object_is_floating (text))
|
|
+ if (g_object_is_floating (text)) {
|
|
g_object_ref_sink (text);
|
|
- g_object_unref (text);
|
|
+ g_object_unref (text);
|
|
+ }
|
|
return;
|
|
}
|
|
if (g_strcmp0 (signal_name, "UpdatePreeditTextWithMode") == 0) {
|
|
@@ -592,9 +594,10 @@ ibus_input_context_g_signal (GDBusProxy *proxy,
|
|
visible,
|
|
mode);
|
|
|
|
- if (g_object_is_floating (text))
|
|
+ if (g_object_is_floating (text)) {
|
|
g_object_ref_sink (text);
|
|
- g_object_unref (text);
|
|
+ g_object_unref (text);
|
|
+ }
|
|
return;
|
|
}
|
|
|
|
@@ -621,9 +624,10 @@ ibus_input_context_g_signal (GDBusProxy *proxy,
|
|
0,
|
|
text,
|
|
visible);
|
|
- if (g_object_is_floating (text))
|
|
+ if (g_object_is_floating (text)) {
|
|
g_object_ref_sink (text);
|
|
- g_object_unref (text);
|
|
+ g_object_unref (text);
|
|
+ }
|
|
return;
|
|
}
|
|
|
|
@@ -640,9 +644,10 @@ ibus_input_context_g_signal (GDBusProxy *proxy,
|
|
0,
|
|
table,
|
|
visible);
|
|
- if (g_object_is_floating (table))
|
|
+ if (g_object_is_floating (table)) {
|
|
g_object_ref_sink (table);
|
|
- g_object_unref (table);
|
|
+ g_object_unref (table);
|
|
+ }
|
|
return;
|
|
|
|
}
|
|
@@ -659,9 +664,10 @@ ibus_input_context_g_signal (GDBusProxy *proxy,
|
|
0,
|
|
prop_list);
|
|
|
|
- if (g_object_is_floating (prop_list))
|
|
+ if (g_object_is_floating (prop_list)) {
|
|
g_object_ref_sink (prop_list);
|
|
- g_object_unref (prop_list);
|
|
+ g_object_unref (prop_list);
|
|
+ }
|
|
return;
|
|
}
|
|
|
|
@@ -673,9 +679,10 @@ ibus_input_context_g_signal (GDBusProxy *proxy,
|
|
|
|
g_signal_emit (context, context_signals[UPDATE_PROPERTY], 0, prop);
|
|
|
|
- if (g_object_is_floating (prop))
|
|
+ if (g_object_is_floating (prop)) {
|
|
g_object_ref_sink (prop);
|
|
- g_object_unref (prop);
|
|
+ g_object_unref (prop);
|
|
+ }
|
|
return;
|
|
}
|
|
|
|
diff --git a/src/ibusproperty.c b/src/ibusproperty.c
|
|
index 6d4ed088..cd8a0e2a 100644
|
|
--- a/src/ibusproperty.c
|
|
+++ b/src/ibusproperty.c
|
|
@@ -336,20 +336,17 @@ ibus_property_destroy (IBusProperty *prop)
|
|
prop->priv->icon = NULL;
|
|
|
|
if (prop->priv->label) {
|
|
- if (!ibus_text_get_is_static (prop->priv->label))
|
|
- g_object_unref (prop->priv->label);
|
|
+ g_object_unref (prop->priv->label);
|
|
prop->priv->label = NULL;
|
|
}
|
|
|
|
if (prop->priv->symbol) {
|
|
- if (!ibus_text_get_is_static (prop->priv->symbol))
|
|
- g_object_unref (prop->priv->symbol);
|
|
+ g_object_unref (prop->priv->symbol);
|
|
prop->priv->symbol = NULL;
|
|
}
|
|
|
|
if (prop->priv->tooltip) {
|
|
- if (!ibus_text_get_is_static (prop->priv->tooltip))
|
|
- g_object_unref (prop->priv->tooltip);
|
|
+ g_object_unref (prop->priv->tooltip);
|
|
prop->priv->tooltip = NULL;
|
|
}
|
|
|
|
@@ -404,7 +401,7 @@ ibus_property_deserialize (IBusProperty *prop,
|
|
g_variant_get_child (variant, retval++, "u", &prop->priv->type);
|
|
|
|
GVariant *subvar = g_variant_get_child_value (variant, retval++);
|
|
- if (prop->priv->label && !ibus_text_get_is_static (prop->priv->label)) {
|
|
+ if (prop->priv->label) {
|
|
g_object_unref (prop->priv->label);
|
|
}
|
|
prop->priv->label = IBUS_TEXT (ibus_serializable_deserialize (subvar));
|
|
@@ -414,7 +411,7 @@ ibus_property_deserialize (IBusProperty *prop,
|
|
ibus_g_variant_get_child_string (variant, retval++, &prop->priv->icon);
|
|
|
|
subvar = g_variant_get_child_value (variant, retval++);
|
|
- if (prop->priv->tooltip && !ibus_text_get_is_static (prop->priv->tooltip)) {
|
|
+ if (prop->priv->tooltip) {
|
|
g_object_unref (prop->priv->tooltip);
|
|
}
|
|
prop->priv->tooltip = IBUS_TEXT (ibus_serializable_deserialize (subvar));
|
|
@@ -435,7 +432,7 @@ ibus_property_deserialize (IBusProperty *prop,
|
|
|
|
/* Keep the serialized order for the compatibility when add new members. */
|
|
subvar = g_variant_get_child_value (variant, retval++);
|
|
- if (prop->priv->symbol && !ibus_text_get_is_static (prop->priv->symbol)) {
|
|
+ if (prop->priv->symbol) {
|
|
g_object_unref (prop->priv->symbol);
|
|
}
|
|
prop->priv->symbol = IBUS_TEXT (ibus_serializable_deserialize (subvar));
|
|
@@ -567,7 +564,7 @@ ibus_property_set_label (IBusProperty *prop,
|
|
g_assert (IBUS_IS_PROPERTY (prop));
|
|
g_return_if_fail (label == NULL || IBUS_IS_TEXT (label));
|
|
|
|
- if (prop->priv->label && !ibus_text_get_is_static (prop->priv->label)) {
|
|
+ if (prop->priv->label) {
|
|
g_object_unref (prop->priv->label);
|
|
}
|
|
|
|
@@ -575,8 +572,10 @@ ibus_property_set_label (IBusProperty *prop,
|
|
prop->priv->label = ibus_text_new_from_static_string ("");
|
|
}
|
|
else {
|
|
- prop->priv->label = g_object_ref_sink (label);
|
|
+ prop->priv->label = label;
|
|
}
|
|
+
|
|
+ g_object_ref_sink (prop->priv->label);
|
|
}
|
|
|
|
void
|
|
@@ -586,7 +585,7 @@ ibus_property_set_symbol (IBusProperty *prop,
|
|
g_assert (IBUS_IS_PROPERTY (prop));
|
|
g_return_if_fail (symbol == NULL || IBUS_IS_TEXT (symbol));
|
|
|
|
- if (prop->priv->symbol && !ibus_text_get_is_static (prop->priv->symbol)) {
|
|
+ if (prop->priv->symbol) {
|
|
g_object_unref (prop->priv->symbol);
|
|
}
|
|
|
|
@@ -594,8 +593,10 @@ ibus_property_set_symbol (IBusProperty *prop,
|
|
prop->priv->symbol = ibus_text_new_from_static_string ("");
|
|
}
|
|
else {
|
|
- prop->priv->symbol = g_object_ref_sink (symbol);
|
|
+ prop->priv->symbol = symbol;
|
|
}
|
|
+
|
|
+ g_object_ref_sink (prop->priv->symbol);
|
|
}
|
|
|
|
void
|
|
@@ -615,7 +616,7 @@ ibus_property_set_tooltip (IBusProperty *prop,
|
|
g_assert (IBUS_IS_PROPERTY (prop));
|
|
g_assert (tooltip == NULL || IBUS_IS_TEXT (tooltip));
|
|
|
|
- if (prop->priv->tooltip && !ibus_text_get_is_static (prop->priv->tooltip)) {
|
|
+ if (prop->priv->tooltip) {
|
|
g_object_unref (prop->priv->tooltip);
|
|
}
|
|
|
|
@@ -624,8 +625,9 @@ ibus_property_set_tooltip (IBusProperty *prop,
|
|
}
|
|
else {
|
|
prop->priv->tooltip = tooltip;
|
|
- g_object_ref_sink (prop->priv->tooltip);
|
|
}
|
|
+
|
|
+ g_object_ref_sink (prop->priv->tooltip);
|
|
}
|
|
|
|
void
|
|
--
|
|
2.34.1
|
|
|
|
From 1b5b9548ad418765717ce1fbdc70b3f3eaae67fc Mon Sep 17 00:00:00 2001
|
|
From: fujiwarat <takao.fujiwara1@gmail.com>
|
|
Date: Mon, 14 Mar 2022 14:25:10 +0900
|
|
Subject: [PATCH] client/gtk2: Revert CCedilla change for pt-BR
|
|
|
|
gtk_im_context_simple_add_table() is deprecated in GTK4.
|
|
I decide to delete gtk_im_context_simple_add_table() here because
|
|
the change 03c9e591430c62354bbf26ef7bd4a2e6acfb7c8f is no longer needed
|
|
because IBusEngineSimple has implemented to load pt_br compose key
|
|
by locale
|
|
|
|
BUG=chromium-os:11421
|
|
BUG=http://codereview.appspot.com/3989060
|
|
---
|
|
client/gtk2/ibusimcontext.c | 33 +--------------------------------
|
|
1 file changed, 1 insertion(+), 32 deletions(-)
|
|
|
|
diff --git a/client/gtk2/ibusimcontext.c b/client/gtk2/ibusimcontext.c
|
|
index a5e5e792..e314ae98 100644
|
|
--- a/client/gtk2/ibusimcontext.c
|
|
+++ b/client/gtk2/ibusimcontext.c
|
|
@@ -2,7 +2,7 @@
|
|
/* vim:set et sts=4: */
|
|
/* ibus - The Input Bus
|
|
* Copyright (C) 2008-2013 Peng Huang <shawn.p.huang@gmail.com>
|
|
- * Copyright (C) 2015-2021 Takao Fujiwara <takao.fujiwara1@gmail.com>
|
|
+ * Copyright (C) 2015-2022 Takao Fujiwara <takao.fujiwara1@gmail.com>
|
|
* Copyright (C) 2008-2021 Red Hat, Inc.
|
|
*
|
|
* This library is free software; you can redistribute it and/or
|
|
@@ -874,33 +874,6 @@ ibus_im_context_class_fini (IBusIMContextClass *class)
|
|
g_bus_unwatch_name (_daemon_name_watch_id);
|
|
}
|
|
|
|
-/* Copied from gtk+2.0-2.20.1/modules/input/imcedilla.c to fix crosbug.com/11421.
|
|
- * Overwrite the original Gtk+'s compose table in gtk+-2.x.y/gtk/gtkimcontextsimple.c. */
|
|
-
|
|
-/* The difference between this and the default input method is the handling
|
|
- * of C+acute - this method produces C WITH CEDILLA rather than C WITH ACUTE.
|
|
- * For languages that use CCedilla and not acute, this is the preferred mapping,
|
|
- * and is particularly important for pt_BR, where the us-intl keyboard is
|
|
- * used extensively.
|
|
- */
|
|
-static guint16 cedilla_compose_seqs[] = {
|
|
-#ifdef DEPRECATED_GDK_KEYSYMS
|
|
- GDK_dead_acute, GDK_C, 0, 0, 0, 0x00C7, /* LATIN_CAPITAL_LETTER_C_WITH_CEDILLA */
|
|
- GDK_dead_acute, GDK_c, 0, 0, 0, 0x00E7, /* LATIN_SMALL_LETTER_C_WITH_CEDILLA */
|
|
- GDK_Multi_key, GDK_apostrophe, GDK_C, 0, 0, 0x00C7, /* LATIN_CAPITAL_LETTER_C_WITH_CEDILLA */
|
|
- GDK_Multi_key, GDK_apostrophe, GDK_c, 0, 0, 0x00E7, /* LATIN_SMALL_LETTER_C_WITH_CEDILLA */
|
|
- GDK_Multi_key, GDK_C, GDK_apostrophe, 0, 0, 0x00C7, /* LATIN_CAPITAL_LETTER_C_WITH_CEDILLA */
|
|
- GDK_Multi_key, GDK_c, GDK_apostrophe, 0, 0, 0x00E7, /* LATIN_SMALL_LETTER_C_WITH_CEDILLA */
|
|
-#else
|
|
- GDK_KEY_dead_acute, GDK_KEY_C, 0, 0, 0, 0x00C7, /* LATIN_CAPITAL_LETTER_C_WITH_CEDILLA */
|
|
- GDK_KEY_dead_acute, GDK_KEY_c, 0, 0, 0, 0x00E7, /* LATIN_SMALL_LETTER_C_WITH_CEDILLA */
|
|
- GDK_KEY_Multi_key, GDK_KEY_apostrophe, GDK_KEY_C, 0, 0, 0x00C7, /* LATIN_CAPITAL_LETTER_C_WITH_CEDILLA */
|
|
- GDK_KEY_Multi_key, GDK_KEY_apostrophe, GDK_KEY_c, 0, 0, 0x00E7, /* LATIN_SMALL_LETTER_C_WITH_CEDILLA */
|
|
- GDK_KEY_Multi_key, GDK_KEY_C, GDK_KEY_apostrophe, 0, 0, 0x00C7, /* LATIN_CAPITAL_LETTER_C_WITH_CEDILLA */
|
|
- GDK_KEY_Multi_key, GDK_KEY_c, GDK_KEY_apostrophe, 0, 0, 0x00E7, /* LATIN_SMALL_LETTER_C_WITH_CEDILLA */
|
|
-#endif
|
|
-};
|
|
-
|
|
static void
|
|
ibus_im_context_init (GObject *obj)
|
|
{
|
|
@@ -936,10 +909,6 @@ ibus_im_context_init (GObject *obj)
|
|
|
|
// Create slave im context
|
|
ibusimcontext->slave = gtk_im_context_simple_new ();
|
|
- gtk_im_context_simple_add_table (GTK_IM_CONTEXT_SIMPLE (ibusimcontext->slave),
|
|
- cedilla_compose_seqs,
|
|
- 4,
|
|
- G_N_ELEMENTS (cedilla_compose_seqs) / (4 + 2));
|
|
|
|
g_signal_connect (ibusimcontext->slave,
|
|
"commit",
|
|
--
|
|
2.34.1
|
|
|
|
From 37900574934bb01cc31860ae3ae2f668e4360838 Mon Sep 17 00:00:00 2001
|
|
From: fujiwarat <takao.fujiwara1@gmail.com>
|
|
Date: Mon, 28 Mar 2022 23:18:58 +0900
|
|
Subject: [PATCH] src/tests: Run ibus-daemon from CI even if GNOME desktop
|
|
|
|
gnome-shell no longer launch ibus-daemon with IBus systemd file.
|
|
This is a workaround to call ibus-daemon after GNOME fails to
|
|
launch ibus-daemon
|
|
|
|
BUG=https://gitlab.gnome.org/GNOME/gdm/-/issues/777
|
|
---
|
|
src/tests/ibus-desktop-testing-runner.in | 38 +++++++++++++++++++++---
|
|
1 file changed, 34 insertions(+), 4 deletions(-)
|
|
|
|
diff --git a/src/tests/ibus-desktop-testing-runner.in b/src/tests/ibus-desktop-testing-runner.in
|
|
index 48528326..6b208345 100755
|
|
--- a/src/tests/ibus-desktop-testing-runner.in
|
|
+++ b/src/tests/ibus-desktop-testing-runner.in
|
|
@@ -55,6 +55,7 @@ GREEN='\033[0;32m'
|
|
RED='\033[0;31m'
|
|
NC='\033[0m'
|
|
|
|
+
|
|
print_log()
|
|
{
|
|
if [ x"$RESULT_LOG" != x ] ; then
|
|
@@ -69,6 +70,7 @@ print_log()
|
|
fi
|
|
}
|
|
|
|
+
|
|
usage()
|
|
{
|
|
$ECHO -e \
|
|
@@ -95,6 +97,7 @@ usage()
|
|
""
|
|
}
|
|
|
|
+
|
|
parse_args()
|
|
{
|
|
# This is GNU getopt. "sudo port getopt" in BSD?
|
|
@@ -129,6 +132,7 @@ parse_args()
|
|
fi
|
|
}
|
|
|
|
+
|
|
init_desktop()
|
|
{
|
|
if [ "$RESULT_LOG" != "" ] ; then
|
|
@@ -207,6 +211,7 @@ _EOF
|
|
#export XDG_SEAT=seat0
|
|
}
|
|
|
|
+
|
|
run_dbus_daemon()
|
|
{
|
|
# Use dbus-launch --exit-with-session later instead of --sh-syntax
|
|
@@ -216,6 +221,7 @@ run_dbus_daemon()
|
|
export DBUS_SESSION_BUS_ADDRESS="unix:path=/run/user/$UID/bus"
|
|
}
|
|
|
|
+
|
|
init_gnome()
|
|
{
|
|
# gsettings set command needs dconf-service with the same $DISPLAY
|
|
@@ -258,6 +264,7 @@ init_gnome()
|
|
fi
|
|
}
|
|
|
|
+
|
|
run_desktop()
|
|
{
|
|
echo "$DESKTOP_COMMAND" | grep gnome-session > /dev/null
|
|
@@ -278,12 +285,28 @@ run_desktop()
|
|
$DESKTOP_COMMAND &
|
|
PID_GNOME_SESSION=$!
|
|
sleep 30
|
|
- if [ $HAS_GNOME -ne 0 ] ; then
|
|
- ibus-daemon --daemonize --verbose
|
|
- sleep 3
|
|
- fi
|
|
+
|
|
+ # gnome-shell 42 checks if org.freedesktop.IBus.session.GNOME.service
|
|
+ # systemd file is available with org.freedesktop.systemd1.Manager.GetUnit
|
|
+ # D-Bus method, which is provided by IBus 1.5.26, and if the file
|
|
+ # is available, gnome-shell no longer launch ibus-daemon
|
|
+ # because gnome-shell assumes gnome-session would launch ibus-daemon
|
|
+ # with org.freedesktop.systemd1.Manager.StartUnit D-Bus method.
|
|
+ # But actually gnome-session failed to launch ibus-daemon
|
|
+ # because the IBus systemd file depends on gnome-session.target
|
|
+ # but this CI launches gnome-session directly.
|
|
+ #
|
|
+ # So ibus-dameon is now always called here after gnome-shell fails to
|
|
+ # launch ibus-daemon.
|
|
+ # It may be better this CI launches GDM autologin to run gnome-session
|
|
+ # with gnome-session.target systemd file.
|
|
+ # But `systemctl start gdm` terminates the parent script forcibly
|
|
+ # and the script cannot get the CI result.
|
|
+ ibus-daemon --daemonize --verbose
|
|
+ sleep 3
|
|
}
|
|
|
|
+
|
|
count_case_result()
|
|
{
|
|
retval=$1
|
|
@@ -298,6 +321,7 @@ count_case_result()
|
|
echo $pass $fail
|
|
}
|
|
|
|
+
|
|
echo_case_result()
|
|
{
|
|
retval=$1
|
|
@@ -311,6 +335,7 @@ echo_case_result()
|
|
fi
|
|
}
|
|
|
|
+
|
|
run_direct_test_cases()
|
|
{
|
|
pass=0
|
|
@@ -363,6 +388,7 @@ EOF_ENVS
|
|
echo $pass $fail
|
|
}
|
|
|
|
+
|
|
run_gnome_desktop_testing_runner()
|
|
{
|
|
pass=0
|
|
@@ -397,6 +423,7 @@ EOF
|
|
echo $pass $fail
|
|
}
|
|
|
|
+
|
|
run_test_suite()
|
|
{
|
|
pass=0
|
|
@@ -435,6 +462,7 @@ EOF_RUNNER
|
|
fi
|
|
}
|
|
|
|
+
|
|
finit()
|
|
{
|
|
echo "# Killing left gnome-session and Xorg"
|
|
@@ -451,6 +479,7 @@ finit()
|
|
echo "# Finished $PROGNAME testing"
|
|
}
|
|
|
|
+
|
|
main()
|
|
{
|
|
parse_args "$@"
|
|
@@ -470,5 +499,6 @@ main()
|
|
finit
|
|
}
|
|
|
|
+
|
|
# Need to enclose $@ with double quotes not to split the array.
|
|
main "$@"
|
|
--
|
|
2.34.1
|
|
|
|
From b024ea8fcee6fe1a20570a6f80cc4f9f8f420706 Mon Sep 17 00:00:00 2001
|
|
From: fujiwarat <takao.fujiwara1@gmail.com>
|
|
Date: Wed, 20 Apr 2022 19:36:10 +0900
|
|
Subject: [PATCH] ui/gtk3: Disable XKB engines in Plasma Wayland
|
|
|
|
Currently ibus-ui-gtk3 runs the setxkbmap command internally to set
|
|
the XKB keymaps from XKB engines but setxkbmap does not work in Wayland
|
|
session.
|
|
The IBus XKB engines are disabled at the moment in Plamsa Wayland
|
|
and ibus-ui-gtk3 asks users to use systemsettings5.
|
|
|
|
Will use libinput and libxkbcommon later but it would be better
|
|
to implement IBus in Plamsa Wayland compositor.
|
|
|
|
BUG=rhbz#2076596
|
|
---
|
|
configure.ac | 16 ++++++++++
|
|
ui/gtk3/Makefile.am | 17 ++++++++++-
|
|
ui/gtk3/panel.vala | 74 +++++++++++++++++++++++++++++++++++++++++----
|
|
3 files changed, 100 insertions(+), 7 deletions(-)
|
|
|
|
diff --git a/configure.ac b/configure.ac
|
|
index a3cdb2da..79b9c11a 100644
|
|
--- a/configure.ac
|
|
+++ b/configure.ac
|
|
@@ -636,6 +636,21 @@ if test x"$enable_engine" = x"yes"; then
|
|
enable_engine="yes (enabled, use --disable-engine to disable)"
|
|
fi
|
|
|
|
+# --disable-libnotify
|
|
+AC_ARG_ENABLE(libnotify,
|
|
+ AS_HELP_STRING([--disable-libnotify],
|
|
+ [Disable to link libnotify]),
|
|
+ [enable_libnotify=$enableval],
|
|
+ [enable_libnotify=yes]
|
|
+)
|
|
+AM_CONDITIONAL([ENABLE_LIBNOTIFY], [test x"$enable_libnotify" = x"yes"])
|
|
+if test x"$enable_libnotify" = x"yes"; then
|
|
+ PKG_CHECK_MODULES(LIBNOTIFY, [
|
|
+ libnotify >= 0.7
|
|
+ ])
|
|
+ enable_libnotify="yes (enabled, use --disable-libnotify to disable)"
|
|
+fi
|
|
+
|
|
PKG_CHECK_MODULES(XTEST,
|
|
[x11 xtst],
|
|
[enable_xtest=yes],
|
|
@@ -871,6 +886,7 @@ Build options:
|
|
No snooper regexes "$NO_SNOOPER_APPS"
|
|
Panel icon "$IBUS_ICON_KEYBOARD"
|
|
Enable surrounding-text $enable_surrounding_text
|
|
+ Enable libnotify $enable_libnotify
|
|
Enable Emoji dict $enable_emoji_dict
|
|
Unicode Emoji directory $UNICODE_EMOJI_DIR
|
|
CLDR annotation directory $EMOJI_ANNOTATION_DIR
|
|
diff --git a/ui/gtk3/Makefile.am b/ui/gtk3/Makefile.am
|
|
index ab379328..2a9cabde 100644
|
|
--- a/ui/gtk3/Makefile.am
|
|
+++ b/ui/gtk3/Makefile.am
|
|
@@ -3,7 +3,7 @@
|
|
# ibus - The Input Bus
|
|
#
|
|
# Copyright (c) 2007-2015 Peng Huang <shawn.p.huang@gmail.com>
|
|
-# Copyright (c) 2015-2020 Takao Fujwiara <takao.fujiwara1@gmail.com>
|
|
+# Copyright (c) 2015-2022 Takao Fujwiara <takao.fujiwara1@gmail.com>
|
|
# Copyright (c) 2007-2020 Red Hat, Inc.
|
|
#
|
|
# This library is free software; you can redistribute it and/or
|
|
@@ -81,6 +81,21 @@ AM_VALAFLAGS = \
|
|
--target-glib="$(VALA_TARGET_GLIB_VERSION)" \
|
|
$(NULL)
|
|
|
|
+if ENABLE_LIBNOTIFY
|
|
+AM_CFLAGS += \
|
|
+ @LIBNOTIFY_CFLAGS@ \
|
|
+ $(NULL)
|
|
+
|
|
+AM_LDADD += \
|
|
+ @LIBNOTIFY_LIBS@ \
|
|
+ $(NULL)
|
|
+
|
|
+AM_VALAFLAGS += \
|
|
+ --pkg=libnotify \
|
|
+ -D ENABLE_LIBNOTIFY \
|
|
+ $(NULL)
|
|
+endif
|
|
+
|
|
if ENABLE_APPINDICATOR
|
|
AM_VALAFLAGS += --define=INDICATOR
|
|
endif
|
|
diff --git a/ui/gtk3/panel.vala b/ui/gtk3/panel.vala
|
|
index 07ce6524..bd70d7d2 100644
|
|
--- a/ui/gtk3/panel.vala
|
|
+++ b/ui/gtk3/panel.vala
|
|
@@ -73,6 +73,7 @@ class Panel : IBus.PanelService {
|
|
private string m_icon_prop_key = "";
|
|
private int m_property_icon_delay_time = 500;
|
|
private uint m_property_icon_delay_time_id;
|
|
+ private bool m_is_wayland;
|
|
#if INDICATOR
|
|
private bool m_is_kde = is_kde();
|
|
#else
|
|
@@ -93,6 +94,18 @@ class Panel : IBus.PanelService {
|
|
|
|
m_bus = bus;
|
|
|
|
+#if USE_GDK_WAYLAND
|
|
+ Gdk.set_allowed_backends("*");
|
|
+ var display = Gdk.DisplayManager.get().open_display(null);
|
|
+ Type instance_type = display.get_type();
|
|
+ Type wayland_type = typeof(GdkWayland.Display);
|
|
+ m_is_wayland = instance_type.is_a(wayland_type);
|
|
+ Gdk.set_allowed_backends("x11");
|
|
+#else
|
|
+ m_is_wayland = false;
|
|
+ warning("Checking Wayland is disabled");
|
|
+#endif
|
|
+
|
|
init_settings();
|
|
|
|
// init ui
|
|
@@ -553,6 +566,11 @@ class Panel : IBus.PanelService {
|
|
GLib.List<IBus.EngineDesc> im_engines =
|
|
get_engines_from_locale(engines);
|
|
|
|
+ if (m_is_wayland) {
|
|
+ if (xkb_engines.length() > 0)
|
|
+ xkb_engines = new GLib.List<IBus.EngineDesc>();
|
|
+ }
|
|
+
|
|
string[] names = {};
|
|
foreach (unowned IBus.EngineDesc engine in xkb_engines)
|
|
names += engine.get_name();
|
|
@@ -728,6 +746,32 @@ class Panel : IBus.PanelService {
|
|
inited_engines_order = false;
|
|
}
|
|
|
|
+ private void update_version_1_5_26() {
|
|
+#if ENABLE_LIBNOTIFY
|
|
+ if (!Notify.is_initted()) {
|
|
+ Notify.init ("ibus");
|
|
+ }
|
|
+
|
|
+ var notification = new Notify.Notification(
|
|
+ _("IBus Attention"),
|
|
+ _("Layout changes do not work in Plasma Wayland. " +
|
|
+ "Please use systemsettings5."),
|
|
+ "ibus");
|
|
+ notification.set_timeout(30 * 1000);
|
|
+ notification.set_category("hotkey");
|
|
+
|
|
+ try {
|
|
+ notification.show();
|
|
+ } catch (GLib.Error e){
|
|
+ warning (_("Layout changes do not work in Plasma Wayland. " +
|
|
+ "Please use systemsettings5."));
|
|
+ }
|
|
+#else
|
|
+ warning (_("Layout changes do not work in Plasma Wayland. " +
|
|
+ "Please use systemsettings5."));
|
|
+#endif
|
|
+ }
|
|
+
|
|
private void set_version() {
|
|
string prev_version = m_settings_general.get_string("version");
|
|
string current_version = null;
|
|
@@ -735,6 +779,9 @@ class Panel : IBus.PanelService {
|
|
if (compare_versions(prev_version, "1.5.8") < 0)
|
|
update_version_1_5_8();
|
|
|
|
+ if (compare_versions(prev_version, "1.5.26") < 0)
|
|
+ update_version_1_5_26();
|
|
+
|
|
current_version = "%d.%d.%d".printf(IBus.MAJOR_VERSION,
|
|
IBus.MINOR_VERSION,
|
|
IBus.MICRO_VERSION);
|
|
@@ -856,7 +903,7 @@ class Panel : IBus.PanelService {
|
|
m_icon_prop_key = "";
|
|
|
|
// set xkb layout
|
|
- if (!m_use_system_keyboard_layout)
|
|
+ if (!m_use_system_keyboard_layout && !m_is_wayland)
|
|
m_xkblayout.set_layout(engine);
|
|
|
|
set_language_from_engine(engine);
|
|
@@ -960,17 +1007,25 @@ class Panel : IBus.PanelService {
|
|
string[]? order_names) {
|
|
string[]? engine_names = unowned_engine_names;
|
|
|
|
- if (engine_names == null || engine_names.length == 0)
|
|
- engine_names = {"xkb:us::eng"};
|
|
+ if (engine_names == null || engine_names.length == 0) {
|
|
+ if (m_is_wayland)
|
|
+ engine_names = {};
|
|
+ else
|
|
+ engine_names = {"xkb:us::eng"};
|
|
+ }
|
|
|
|
string[] names = {};
|
|
|
|
foreach (var name in order_names) {
|
|
+ if (m_is_wayland && name.has_prefix("xkb:"))
|
|
+ continue;
|
|
if (name in engine_names)
|
|
names += name;
|
|
}
|
|
|
|
foreach (var name in engine_names) {
|
|
+ if (m_is_wayland && name.has_prefix("xkb:"))
|
|
+ continue;
|
|
if (name in names)
|
|
continue;
|
|
names += name;
|
|
@@ -1011,9 +1066,14 @@ class Panel : IBus.PanelService {
|
|
}
|
|
|
|
if (m_engines.length == 0) {
|
|
- m_engines = engines;
|
|
- switch_engine(0, true);
|
|
- run_preload_engines(engines, 1);
|
|
+ if (engines.length > 0) {
|
|
+ m_engines = engines;
|
|
+ switch_engine(0, true);
|
|
+ run_preload_engines(engines, 1);
|
|
+ } else {
|
|
+ m_candidate_panel.set_language(new Pango.AttrLanguage(
|
|
+ Pango.Language.from_string(null)));
|
|
+ }
|
|
} else {
|
|
var current_engine = m_engines[0];
|
|
m_engines = engines;
|
|
@@ -1478,6 +1538,8 @@ class Panel : IBus.PanelService {
|
|
/* Do not change the order of m_engines during running switcher. */
|
|
if (m_switcher.is_running())
|
|
return;
|
|
+ if (m_engines.length == 0)
|
|
+ return;
|
|
|
|
if (m_icon_type == IconType.INDICATOR) {
|
|
// Wait for the callback of the session bus.
|
|
--
|
|
2.34.1
|
|
|
|
From bca7bf0f97230806a26f53c798050408108cfb3d Mon Sep 17 00:00:00 2001
|
|
From: Mike FABIAN <mfabian@redhat.com>
|
|
Date: Wed, 25 May 2022 23:07:24 +0900
|
|
Subject: [PATCH] data/dconf: Update xkb-latin-layouts in gschema
|
|
|
|
Add more keyboard layouts which cannot produce ASCII to
|
|
data/dconf/org.freedesktop.ibus.gschema.xml
|
|
Remove "mal" and "mkd", there are no such layouts.
|
|
|
|
BUG=https://github.com/ibus/ibus/issues/2404
|
|
---
|
|
data/dconf/org.freedesktop.ibus.gschema.xml | 47 ++++++++++++++++++++-
|
|
1 file changed, 46 insertions(+), 1 deletion(-)
|
|
|
|
diff --git a/data/dconf/org.freedesktop.ibus.gschema.xml b/data/dconf/org.freedesktop.ibus.gschema.xml
|
|
index 516f7520..8b181d76 100644
|
|
--- a/data/dconf/org.freedesktop.ibus.gschema.xml
|
|
+++ b/data/dconf/org.freedesktop.ibus.gschema.xml
|
|
@@ -28,7 +28,52 @@
|
|
<description>The saved version number will be used to check the difference between the version of the previous installed ibus and one of the current ibus.</description>
|
|
</key>
|
|
<key name="xkb-latin-layouts" type="as">
|
|
- <default>[ 'ara', 'bg', 'cz', 'dev', 'gr', 'gur', 'in', 'jp(kana)', 'mal', 'mkd', 'ru', 'ua' ]</default>
|
|
+ <default>
|
|
+ [ 'af', 'af(fa-olpc)', 'af(ps-olpc)', 'af(ps)', 'af(uz)',
|
|
+ 'af(uz-olpc)', 'am', 'am(eastern)', 'am(eastern-alt)',
|
|
+ 'am(phonetic)', 'am(phonetic-alt)', 'am(western)', 'ara',
|
|
+ 'ara(azerty)', 'ara(azerty_digits)', 'ara(buckwalter)',
|
|
+ 'ara(digits)', 'ara(qwerty)', 'ara(qwerty_digits)',
|
|
+ 'az(cyrillic)', 'bd', 'bd(probhat)', 'bg', 'bg(bas_phonetic)',
|
|
+ 'bg(phonetic)', 'brai', 'brai(left_hand)', 'brai(right_hand)',
|
|
+ 'bt', 'by', 'by(legacy)', 'ca(ike)', 'ca(multi-2gr)',
|
|
+ 'cn(tib)', 'cn(tib_asciinum)', 'cn(ug)', 'cz', 'cz(ucw)',
|
|
+ 'de(ru)', 'dev', 'et', 'fr(geo)', 'ge', 'ge(os)', 'gr',
|
|
+ 'gr(extended)', 'gr(nodeadkeys)', 'gr(polytonic)',
|
|
+ 'gr(simple)', 'gur', 'il', 'il(biblical)', 'il(lyx)',
|
|
+ 'il(phonetic)', 'in', 'in(ben)', 'in(ben_baishakhi)',
|
|
+ 'in(ben_bornona)', 'in(ben_gitanjali)', 'in(ben_inscript)',
|
|
+ 'in(ben_probhat)', 'in(bolnagri)', 'in(deva)', 'in(guj)',
|
|
+ 'in(guru)', 'in(hin-kagapa)', 'in(hin-wx)', 'in(jhelum)',
|
|
+ 'in(kan)', 'in(kan-kagapa)', 'in(mal)', 'in(mal_enhanced)',
|
|
+ 'in(mal_lalitha)', 'in(mar-kagapa)', 'in(ori)',
|
|
+ 'in(san-kagapa)', 'in(tam)', 'in(tam_tamilnet)',
|
|
+ 'in(tam_tamilnet_TAB)', 'in(tam_tamilnet_TSCII)',
|
|
+ 'in(tam_tamilnet_with_tam_nums)', 'in(tel)', 'in(tel-kagapa)',
|
|
+ 'in(urd-phonetic)', 'in(urd-phonetic3)', 'in(urd-winkeys)',
|
|
+ 'iq', 'ir', 'ir(pes_keypad)', 'jp(kana)', 'jp(mac)', 'kg',
|
|
+ 'kg(phonetic)', 'kh', 'kz', 'kz(kazrus)', 'kz(ruskaz)', 'la',
|
|
+ 'la(stea)', 'lk', 'lk(tam_TAB)', 'lk(tam_unicode)', 'ma',
|
|
+ 'ma(tifinagh)', 'ma(tifinagh-alt)',
|
|
+ 'ma(tifinagh-alt-phonetic)', 'ma(tifinagh-extended)',
|
|
+ 'ma(tifinagh-extended-phonetic)', 'ma(tifinagh-phonetic)',
|
|
+ 'me(cyrillic)', 'me(cyrillicalternatequotes)',
|
|
+ 'me(cyrillicyz)', 'mk', 'mk(nodeadkeys)', 'mm', 'mn', 'mv',
|
|
+ 'np', 'ph(capewell-dvorak-bay)', 'ph(capewell-qwerf2k6-bay)',
|
|
+ 'ph(colemak-bay)', 'ph(dvorak-bay)', 'ph(qwerty-bay)', 'pk',
|
|
+ 'pk(ara)', 'pk(snd)', 'pk(urd-crulp)', 'pk(urd-nla)',
|
|
+ 'pl(ru_phonetic_dvorak)', 'rs', 'rs(alternatequotes)',
|
|
+ 'rs(rue)', 'rs(yz)', 'ru', 'ru(bak)', 'ru(chm)', 'ru(cv)',
|
|
+ 'ru(dos)', 'ru(kom)', 'ru(legacy)', 'ru(mac)',
|
|
+ 'ru(os_legacy)', 'ru(os_winkeys)', 'ru(phonetic)',
|
|
+ 'ru(phonetic_winkeys)', 'ru(sah)', 'ru(srp)', 'ru(tt)',
|
|
+ 'ru(typewriter)', 'ru(typewriter-legacy)', 'ru(udm)',
|
|
+ 'ru(xal)', 'se(rus)', 'se(rus_nodeadkeys)', 'se(swl)', 'sy',
|
|
+ 'sy(syc)', 'sy(syc_phonetic)', 'th', 'th(pat)', 'th(tis)',
|
|
+ 'tj', 'tj(legacy)', 'tz', 'ua', 'ua(homophonic)',
|
|
+ 'ua(legacy)', 'ua(phonetic)', 'ua(rstu)', 'ua(rstu_ru)',
|
|
+ 'ua(typewriter)', 'ua(winkeys)', 'us(chr)', 'us(rus)', 'uz' ]
|
|
+ </default>
|
|
<summary>Latin layouts which have no ASCII</summary>
|
|
<description>US layout is appended to the Latin layouts. variant can be omitted.</description>
|
|
</key>
|
|
--
|
|
2.35.3
|
|
|
|
From 16df64edadc21f50906e5442b73425b9256fbf65 Mon Sep 17 00:00:00 2001
|
|
From: fujiwarat <takao.fujiwara1@gmail.com>
|
|
Date: Wed, 25 May 2022 23:07:33 +0900
|
|
Subject: [PATCH] src/tests: Add xkb-latin-layouts case
|
|
|
|
BUG=https://github.com/ibus/ibus/issues/2404
|
|
---
|
|
src/tests/Makefile.am | 26 ++++++--
|
|
src/tests/runtest | 1 +
|
|
src/tests/xkb-latin-layouts | 130 ++++++++++++++++++++++++++++++++++++
|
|
3 files changed, 150 insertions(+), 8 deletions(-)
|
|
create mode 100755 src/tests/xkb-latin-layouts
|
|
|
|
diff --git a/src/tests/Makefile.am b/src/tests/Makefile.am
|
|
index f932f18f..ca5285bd 100644
|
|
--- a/src/tests/Makefile.am
|
|
+++ b/src/tests/Makefile.am
|
|
@@ -41,8 +41,9 @@ prog_ldadd =\
|
|
$(top_builddir)/src/libibus-@IBUS_API_VERSION@.la \
|
|
$(NULL)
|
|
|
|
-noinst_PROGRAMS = $(TESTS)
|
|
-TESTS = \
|
|
+noinst_PROGRAMS = $(TESTS_C)
|
|
+noinst_SCRIPTS = $(TESTS_SCRIPT)
|
|
+TESTS_C = \
|
|
ibus-bus \
|
|
ibus-config \
|
|
ibus-configservice \
|
|
@@ -56,16 +57,25 @@ TESTS = \
|
|
ibus-util \
|
|
$(NULL)
|
|
|
|
+TESTS_SCRIPT = \
|
|
+ xkb-latin-layouts \
|
|
+ $(NULL)
|
|
+
|
|
+TESTS = \
|
|
+ $(TESTS_C) \
|
|
+ $(TESTS_SCRIPT) \
|
|
+ $(NULL)
|
|
+
|
|
CLEANFILES =
|
|
|
|
if ENABLE_ENGINE
|
|
-TESTS += ibus-engine-switch
|
|
+TESTS_C += ibus-engine-switch
|
|
endif
|
|
|
|
if ENABLE_GTK3
|
|
-TESTS += ibus-compose
|
|
+TESTS_C += ibus-compose
|
|
if ENABLE_XTEST
|
|
-TESTS += ibus-keypress
|
|
+TESTS_C += ibus-keypress
|
|
endif
|
|
endif
|
|
|
|
@@ -99,9 +109,10 @@ CLEANFILES += \
|
|
org.freedesktop.IBus.Desktop.Testing.desktop \
|
|
$(NULL)
|
|
|
|
-test_execs_PROGRAMS = $(TESTS)
|
|
+test_execs_PROGRAMS = $(TESTS_C)
|
|
+test_execs_SCRIPTS = $(TESTS_SCRIPT)
|
|
if ENABLE_GTK3
|
|
-test_execs_SCRIPTS = ibus-compose-locales
|
|
+test_execs_SCRIPTS += ibus-compose-locales
|
|
CLEANFILES += \
|
|
ibus-compose-locales \
|
|
$(NULL)
|
|
@@ -138,6 +149,7 @@ ibus-desktop-testing-runner: ibus-desktop-testing-runner.in
|
|
|
|
EXTRA_DIST = \
|
|
$(test_metas_in) \
|
|
+ $(TESTS_SCRIPT) \
|
|
runtest \
|
|
ibus-compose.emoji \
|
|
ibus-compose.env \
|
|
diff --git a/src/tests/runtest b/src/tests/runtest
|
|
index a6e4194b..a229140a 100755
|
|
--- a/src/tests/runtest
|
|
+++ b/src/tests/runtest
|
|
@@ -35,6 +35,7 @@ ibus-engine-switch
|
|
ibus-compose
|
|
ibus-keypress
|
|
test-stress
|
|
+xkb-latin-layouts
|
|
"
|
|
IBUS_SCHEMA_FILE='org.freedesktop.ibus.gschema.xml'
|
|
GTK_QUERY_MODULE=gtk-query-immodules-3.0-32
|
|
diff --git a/src/tests/xkb-latin-layouts b/src/tests/xkb-latin-layouts
|
|
new file mode 100755
|
|
index 00000000..f8dced6b
|
|
--- /dev/null
|
|
+++ b/src/tests/xkb-latin-layouts
|
|
@@ -0,0 +1,130 @@
|
|
+#!/bin/bash
|
|
+
|
|
+PROGNAME=`basename $0`
|
|
+VERSION=0.1
|
|
+# POSIX sh has no 'echo -e'
|
|
+: ${ECHO:='/usr/bin/echo'}
|
|
+TMPDIR=
|
|
+INSTALLED_SCHEMAS_DIR=
|
|
+
|
|
+
|
|
+usage()
|
|
+{
|
|
+ $ECHO -e \
|
|
+"This test runs setxkbmap command for gsettings xkb-latin-layouts value\n" \
|
|
+"$PROGNAME [OPTIONS…]\n" \
|
|
+"\n" \
|
|
+"OPTIONS:\n" \
|
|
+"-h, --help This help\n" \
|
|
+"-v, --version Show version\n" \
|
|
+"-D, --schemasdir=DIR Load the latest schema file in DIR\n" \
|
|
+""
|
|
+}
|
|
+
|
|
+
|
|
+parse_args()
|
|
+{
|
|
+ # This is GNU getopt. "sudo port getopt" in BSD?
|
|
+ ARGS=`getopt -o hD:Tv --long \
|
|
+ help,schemasdir:,tap,version\
|
|
+ -- "$@"`;
|
|
+ eval set -- "$ARGS"
|
|
+ while [ 1 ] ; do
|
|
+ case "$1" in
|
|
+ -h | --help ) usage; exit 0;;
|
|
+ -D | --schemasdir ) INSTALLED_SCHEMAS_DIR="$2"; shift 2;;
|
|
+ -T | --tap ) shift;; # ignore the option
|
|
+ -v | --version ) $ECHO -e "$VERSION"; exit 0;;
|
|
+ -- ) shift; break;;
|
|
+ * ) shift;;
|
|
+ esac
|
|
+ done
|
|
+}
|
|
+
|
|
+
|
|
+init()
|
|
+{
|
|
+ set -e
|
|
+
|
|
+ # gnome-continuous doesn't have a machine-id set, which
|
|
+ # breaks dbus-launch. There's dbus-run-session which is
|
|
+ # better, but not everyone has it yet.
|
|
+ export DBUS_FATAL_WARNINGS=0
|
|
+ export TMPDIR=$(mktemp -d --tmpdir="$PWD")
|
|
+ export XDG_CONFIG_HOME="$TMPDIR/config"
|
|
+ export XDG_CACHE_HOME="$TMPDIR/cache"
|
|
+ export GSETTINGS_SCHEMA_DIR="$TMPDIR/schemas"
|
|
+ mkdir -p $XDG_CONFIG_HOME $XDG_CACHE_HOME $GSETTINGS_SCHEMA_DIR
|
|
+
|
|
+ eval `dbus-launch --sh-syntax`
|
|
+
|
|
+ trap 'rm -rf $TMPDIR; kill $DBUS_SESSION_BUS_PID; setxkbmap -layout us' ERR
|
|
+
|
|
+ # in case that schema is not installed on the system
|
|
+ glib-compile-schemas --targetdir "$GSETTINGS_SCHEMA_DIR" "$INSTALLED_SCHEMAS_DIR"
|
|
+}
|
|
+
|
|
+
|
|
+finit()
|
|
+{
|
|
+ # dbus-launch and gsettings run /usr/lib*/gvfsd-fuse $TMPDIR/cache/gvfs -f
|
|
+ # via systemd since gvfs 1.45.90 in Fedora 33
|
|
+ # and rm $TMPDIR could be failed until umount would be called.
|
|
+ if [ -d $TMPDIR/cache/gvfs ] ; then
|
|
+ umount $TMPDIR/cache/gvfs
|
|
+ fi
|
|
+ rm -rf $TMPDIR
|
|
+
|
|
+ kill $DBUS_SESSION_BUS_PID
|
|
+ exit 0
|
|
+}
|
|
+
|
|
+
|
|
+test_xkb_keymaps()
|
|
+{
|
|
+ # Loop over top level schemas since "gsettings list-recursively" only
|
|
+ # looks for direct children.
|
|
+ xkb_latin_layouts=`gsettings get org.freedesktop.ibus.general xkb-latin-layouts`
|
|
+ while read keymap ; do
|
|
+ eval keymap="$keymap"
|
|
+ HAS_VARIANT=$($ECHO "$keymap" | grep '(' 2> /dev/null) ||:
|
|
+ if [ "x$HAS_VARIANT" != "x" ] ; then
|
|
+ layout=$($ECHO "$keymap" | sed -e 's/\([^(]*\)([^)]*)/\1/')
|
|
+ variant=$($ECHO "$keymap" | sed -e 's/[^(]*(\([^)]*\))/\1/')
|
|
+ $ECHO setxkbmap -layout $layout -variant $variant
|
|
+ setxkbmap -layout $layout -variant $variant
|
|
+ else
|
|
+ layout="$keymap"
|
|
+ $ECHO setxkbmap -layout $layout
|
|
+ setxkbmap -layout $layout
|
|
+ fi
|
|
+ if [ $? -ne 0 ] ; then
|
|
+ $ECHO "Error in layout $layout variant $variant"
|
|
+ setxkbmap -layout us
|
|
+ exit 1
|
|
+ fi
|
|
+ done << EOF_READ_XKB
|
|
+ `$ECHO $xkb_latin_layouts | sed -e 's/^\[//' -e 's/\]$//' | tr "," "\n"`
|
|
+EOF_READ_XKB
|
|
+
|
|
+ setxkbmap -layout us
|
|
+}
|
|
+
|
|
+
|
|
+main()
|
|
+{
|
|
+ parse_args "$@"
|
|
+
|
|
+ if [ x"$INSTALLED_SCHEMAS_DIR" != x ] ; then
|
|
+ init
|
|
+ fi
|
|
+
|
|
+ test_xkb_keymaps
|
|
+
|
|
+ if [ x"$INSTALLED_SCHEMAS_DIR" != x ] ; then
|
|
+ finit
|
|
+ fi
|
|
+}
|
|
+
|
|
+
|
|
+main "$@"
|
|
--
|
|
2.35.3
|
|
|
|
From 233a3f4d4d3dc6782e74db5bf4e7c28fae729bc9 Mon Sep 17 00:00:00 2001
|
|
From: Hollow Man <hollowman@opensuse.org>
|
|
Date: Wed, 26 Jan 2022 09:35:11 +0800
|
|
Subject: [PATCH 1/3] Add functionality to change IBus panel themes with
|
|
available GTK themes
|
|
|
|
To allow IBus to have their own control of themes.
|
|
|
|
https://gitlab.gnome.org/GNOME/gnome-tweaks/-/blob/b9badc47b92dd73f8cedbd2efc66cbaf3ea25773/gtweak/tweaks/tweak_group_appearance.py#L69
|
|
|
|
BUG=https://github.com/ibus/ibus/pull/2327
|
|
|
|
Signed-off-by: Hollow Man <hollowman@opensuse.org>
|
|
---
|
|
data/dconf/org.freedesktop.ibus.gschema.xml | 20 +++
|
|
setup/main.py | 137 ++++++++++++++++++++
|
|
setup/setup.ui | 97 +++++++++++++-
|
|
ui/gtk3/bindingcommon.vala | 46 +++++++
|
|
ui/gtk3/panel.vala | 18 +++
|
|
ui/gtk3/panelbinding.vala | 18 +++
|
|
6 files changed, 335 insertions(+), 1 deletion(-)
|
|
|
|
diff --git a/data/dconf/org.freedesktop.ibus.gschema.xml b/data/dconf/org.freedesktop.ibus.gschema.xml
|
|
index 8b181d76..051f21a5 100644
|
|
--- a/data/dconf/org.freedesktop.ibus.gschema.xml
|
|
+++ b/data/dconf/org.freedesktop.ibus.gschema.xml
|
|
@@ -210,6 +210,26 @@
|
|
<summary>Custom font</summary>
|
|
<description>Custom font name for language panel</description>
|
|
</key>
|
|
+ <key name="use-custom-theme" type="b">
|
|
+ <default>false</default>
|
|
+ <summary>Use custom theme</summary>
|
|
+ <description>Use custom theme name for language panel</description>
|
|
+ </key>
|
|
+ <key name="custom-theme" type="s">
|
|
+ <default>'Adwaita'</default>
|
|
+ <summary>Custom theme</summary>
|
|
+ <description>Custom theme name for language panel</description>
|
|
+ </key>
|
|
+ <key name="use-custom-icon" type="b">
|
|
+ <default>false</default>
|
|
+ <summary>Use custom icon</summary>
|
|
+ <description>Use custom icon name for language panel</description>
|
|
+ </key>
|
|
+ <key name="custom-icon" type="s">
|
|
+ <default>'Adwaita'</default>
|
|
+ <summary>Custom icon</summary>
|
|
+ <description>Custom icon name for language panel</description>
|
|
+ </key>
|
|
<key name="use-glyph-from-engine-lang" type="b">
|
|
<default>true</default>
|
|
<summary>Choose glyphs with input method's language on candidate window</summary>
|
|
diff --git a/setup/main.py b/setup/main.py
|
|
index 1b9056a6..71896693 100644
|
|
--- a/setup/main.py
|
|
+++ b/setup/main.py
|
|
@@ -29,6 +29,7 @@ import os
|
|
import signal
|
|
import sys
|
|
import time
|
|
+import glob
|
|
|
|
from gi import require_version as gi_require_version
|
|
gi_require_version('GLib', '2.0')
|
|
@@ -196,6 +197,79 @@ class Setup(object):
|
|
'sensitive',
|
|
Gio.SettingsBindFlags.GET)
|
|
|
|
+ # custom theme
|
|
+ self.__model_custom_theme = self.__builder.get_object(
|
|
+ "model_custom_theme")
|
|
+ self.__combobox_custom_theme = self.__builder.get_object(
|
|
+ "combobox_custom_theme")
|
|
+ self.__checkbutton_custom_theme = self.__builder.get_object(
|
|
+ "checkbutton_custom_theme")
|
|
+
|
|
+ def update_combobox_custom_theme(settings, key):
|
|
+ theme_name_list = self.__init_available_gtk_themes()
|
|
+ self.__model_custom_theme.clear()
|
|
+ for name in theme_name_list:
|
|
+ self.__model_custom_theme.append([name])
|
|
+ current_theme = self.__settings_panel.get_string(key)
|
|
+ try:
|
|
+ current_theme_number = theme_name_list.index(current_theme)
|
|
+ except ValueError:
|
|
+ self.__settings_panel.reset(key)
|
|
+ current_theme = self.__settings_panel.get_string(key)
|
|
+ current_theme_number = theme_name_list.index(current_theme)
|
|
+ self.__combobox_custom_theme.set_active(current_theme_number)
|
|
+
|
|
+ update_combobox_custom_theme(None, 'custom-theme')
|
|
+ self.__settings_panel.bind('use-custom-theme',
|
|
+ self.__checkbutton_custom_theme,
|
|
+ 'active',
|
|
+ Gio.SettingsBindFlags.DEFAULT)
|
|
+ self.__settings_panel.connect('changed::custom-theme',
|
|
+ update_combobox_custom_theme)
|
|
+ self.__settings_panel.bind('use-custom-theme',
|
|
+ self.__combobox_custom_theme,
|
|
+ 'sensitive',
|
|
+ Gio.SettingsBindFlags.DEFAULT)
|
|
+ self.__combobox_custom_theme.connect("changed",
|
|
+ self.__on_combobox_custom_theme_changed)
|
|
+
|
|
+
|
|
+ # custom icon
|
|
+ self.__model_custom_icon = self.__builder.get_object(
|
|
+ "model_custom_icon")
|
|
+ self.__combobox_custom_icon = self.__builder.get_object(
|
|
+ "combobox_custom_icon")
|
|
+ self.__checkbutton_custom_icon = self.__builder.get_object(
|
|
+ "checkbutton_custom_icon")
|
|
+
|
|
+ def update_combobox_custom_icon(settings, key):
|
|
+ icon_name_list = self.__init_available_gtk_icons()
|
|
+ self.__model_custom_icon.clear()
|
|
+ for name in icon_name_list:
|
|
+ self.__model_custom_icon.append([name])
|
|
+ current_icon = self.__settings_panel.get_string(key)
|
|
+ try:
|
|
+ current_icon_number = icon_name_list.index(current_icon)
|
|
+ except ValueError:
|
|
+ self.__settings_panel.reset(key)
|
|
+ current_icon = self.__settings_panel.get_string(key)
|
|
+ current_icon_number = icon_name_list.index(current_icon)
|
|
+ self.__combobox_custom_icon.set_active(current_icon_number)
|
|
+
|
|
+ update_combobox_custom_icon(None, 'custom-icon')
|
|
+ self.__settings_panel.bind('use-custom-icon',
|
|
+ self.__checkbutton_custom_icon,
|
|
+ 'active',
|
|
+ Gio.SettingsBindFlags.DEFAULT)
|
|
+ self.__settings_panel.connect('changed::custom-icon',
|
|
+ update_combobox_custom_icon)
|
|
+ self.__settings_panel.bind('use-custom-icon',
|
|
+ self.__combobox_custom_icon,
|
|
+ 'sensitive',
|
|
+ Gio.SettingsBindFlags.DEFAULT)
|
|
+ self.__combobox_custom_icon.connect("changed",
|
|
+ self.__on_combobox_custom_icon_changed)
|
|
+
|
|
# show icon on system tray
|
|
self.__checkbutton_show_icon_on_systray = self.__builder.get_object(
|
|
"checkbutton_show_icon_on_systray")
|
|
@@ -588,6 +662,69 @@ class Setup(object):
|
|
_("Use shortcut with shift to switch to the previous input method")
|
|
entry.set_tooltip_text(tooltip)
|
|
|
|
+ def __init_available_gtk_themes(self):
|
|
+ path_list = []
|
|
+ path_list.append(os.path.join(GLib.get_home_dir(), ".themes"))
|
|
+ path_list.append(os.path.join(GLib.get_user_data_dir(), "themes"))
|
|
+ path_list.extend(list(map(lambda x: os.path.join(
|
|
+ x, "themes"), GLib.get_system_data_dirs())))
|
|
+ theme_name_list = []
|
|
+ gtk_theme_path = []
|
|
+ for path in path_list:
|
|
+ gtk_theme_path.extend(glob.glob(path + "/*/gtk-*/gtk.css"))
|
|
+ gtk_theme_path.extend(glob.glob(path + "/*/gtk-*/gtk-dark.css"))
|
|
+ for path in gtk_theme_path:
|
|
+ filename = os.path.basename(path)
|
|
+ appendix = ""
|
|
+ if filename == "gtk-dark.css":
|
|
+ appendix = ":dark"
|
|
+ theme_name_list.append(os.path.basename(
|
|
+ os.path.dirname(os.path.dirname(path))) + appendix)
|
|
+
|
|
+ theme_name_list.extend([
|
|
+ 'Adwaita', 'Adwaita:dark',
|
|
+ 'HighContrast', 'HighContrastInverse'
|
|
+ ])
|
|
+ theme_name_list = list(set(theme_name_list))
|
|
+ theme_name_list.sort()
|
|
+
|
|
+ return theme_name_list
|
|
+
|
|
+ def __on_combobox_custom_theme_changed(self, combobox):
|
|
+ tree_iter = self.__combobox_custom_theme.get_active_iter()
|
|
+ if tree_iter is not None:
|
|
+ model = self.__combobox_custom_theme.get_model()
|
|
+ theme_name = model[tree_iter][0]
|
|
+ self.__settings_panel.set_string('custom-theme', theme_name)
|
|
+
|
|
+ def __init_available_gtk_icons(self):
|
|
+ path_list = []
|
|
+ path_list.append(os.path.join(GLib.get_home_dir(), ".icons"))
|
|
+ path_list.append(os.path.join(GLib.get_user_data_dir(), "icons"))
|
|
+ path_list.extend(list(map(lambda x: os.path.join(
|
|
+ x, "icons"), GLib.get_system_data_dirs())))
|
|
+ icon_name_list = []
|
|
+ gtk_icon_path = []
|
|
+ for path in path_list:
|
|
+ gtk_icon_path.extend(glob.glob(path + "/*/index.theme"))
|
|
+ for path in gtk_icon_path:
|
|
+ dir = os.path.dirname(path)
|
|
+ if not os.path.exists(os.path.join(dir, "cursors")):
|
|
+ icon_name_list.append(os.path.basename(dir))
|
|
+
|
|
+ icon_name_list.extend(["Adwaita"])
|
|
+ icon_name_list = list(set(icon_name_list))
|
|
+ icon_name_list.sort()
|
|
+
|
|
+ return icon_name_list
|
|
+
|
|
+ def __on_combobox_custom_icon_changed(self, combobox):
|
|
+ tree_iter = self.__combobox_custom_icon.get_active_iter()
|
|
+ if tree_iter is not None:
|
|
+ model = self.__combobox_custom_icon.get_model()
|
|
+ icon_name = model[tree_iter][0]
|
|
+ self.__settings_panel.set_string('custom-icon', icon_name)
|
|
+
|
|
def __item_started_column_toggled_cb(self, cell, path_str, model):
|
|
|
|
# get toggled iter
|
|
diff --git a/setup/setup.ui b/setup/setup.ui
|
|
index a15b9083..5a9804f9 100644
|
|
--- a/setup/setup.ui
|
|
+++ b/setup/setup.ui
|
|
@@ -55,6 +55,18 @@
|
|
</row>
|
|
</data>
|
|
</object>
|
|
+ <object class="GtkListStore" id="model_custom_theme">
|
|
+ <columns>
|
|
+ <!-- column-name gchararray -->
|
|
+ <column type="gchararray"/>
|
|
+ </columns>
|
|
+ </object>
|
|
+ <object class="GtkListStore" id="model_custom_icon">
|
|
+ <columns>
|
|
+ <!-- column-name gchararray -->
|
|
+ <column type="gchararray"/>
|
|
+ </columns>
|
|
+ </object>
|
|
<object class="GtkAdjustment" id="adjustment_emoji_partial_match">
|
|
<property name="value">3.0</property>
|
|
<property name="lower">1.0</property>
|
|
@@ -1318,13 +1330,96 @@
|
|
<property name="position">0</property>
|
|
</packing>
|
|
</child>
|
|
+ <child>
|
|
+ <object class="GtkGrid" id="table3">
|
|
+ <property name="visible">True</property>
|
|
+ <property name="can_focus">False</property>
|
|
+ <property name="column_spacing">12</property>
|
|
+ <property name="row_spacing">6</property>
|
|
+ <child>
|
|
+ <object class="GtkCheckButton" id="checkbutton_custom_theme">
|
|
+ <property name="label" translatable="yes">Use custom theme:</property>
|
|
+ <property name="use_action_appearance">False</property>
|
|
+ <property name="visible">True</property>
|
|
+ <property name="can_focus">True</property>
|
|
+ <property name="receives_default">False</property>
|
|
+ <property name="use_action_appearance">False</property>
|
|
+ <property name="use_underline">True</property>
|
|
+ <property name="halign">start</property>
|
|
+ <property name="draw_indicator">True</property>
|
|
+ <property name="hexpand">True</property>
|
|
+ </object>
|
|
+ <packing>
|
|
+ <property name="left_attach">0</property>
|
|
+ <property name="top_attach">0</property>
|
|
+ </packing>
|
|
+ </child>
|
|
+ <child>
|
|
+ <object class="GtkComboBox" id="combobox_custom_theme">
|
|
+ <property name="visible">True</property>
|
|
+ <property name="can_focus">False</property>
|
|
+ <property name="model">model_custom_theme</property>
|
|
+ <property name="hexpand">True</property>
|
|
+ <child>
|
|
+ <object class="GtkCellRendererText" id="renderer4"/>
|
|
+ <attributes>
|
|
+ <attribute name="text">0</attribute>
|
|
+ </attributes>
|
|
+ </child>
|
|
+ </object>
|
|
+ <packing>
|
|
+ <property name="left_attach">1</property>
|
|
+ <property name="top_attach">0</property>
|
|
+ </packing>
|
|
+ </child>
|
|
+ <child>
|
|
+ <object class="GtkCheckButton" id="checkbutton_custom_icon">
|
|
+ <property name="label" translatable="yes">Use custom icon:</property>
|
|
+ <property name="use_action_appearance">False</property>
|
|
+ <property name="visible">True</property>
|
|
+ <property name="can_focus">True</property>
|
|
+ <property name="receives_default">False</property>
|
|
+ <property name="use_action_appearance">False</property>
|
|
+ <property name="use_underline">True</property>
|
|
+ <property name="halign">start</property>
|
|
+ <property name="draw_indicator">True</property>
|
|
+ </object>
|
|
+ <packing>
|
|
+ <property name="left_attach">0</property>
|
|
+ <property name="top_attach">1</property>
|
|
+ </packing>
|
|
+ </child>
|
|
+ <child>
|
|
+ <object class="GtkComboBox" id="combobox_custom_icon">
|
|
+ <property name="visible">True</property>
|
|
+ <property name="can_focus">False</property>
|
|
+ <property name="model">model_custom_icon</property>
|
|
+ <child>
|
|
+ <object class="GtkCellRendererText" id="renderer5"/>
|
|
+ <attributes>
|
|
+ <attribute name="text">0</attribute>
|
|
+ </attributes>
|
|
+ </child>
|
|
+ </object>
|
|
+ <packing>
|
|
+ <property name="left_attach">1</property>
|
|
+ <property name="top_attach">1</property>
|
|
+ </packing>
|
|
+ </child>
|
|
+ </object>
|
|
+ <packing>
|
|
+ <property name="expand">False</property>
|
|
+ <property name="fill">False</property>
|
|
+ <property name="position">1</property>
|
|
+ </packing>
|
|
+ </child>
|
|
</object>
|
|
</child>
|
|
<child type="label">
|
|
<object class="GtkLabel" id="label20">
|
|
<property name="visible">True</property>
|
|
<property name="can_focus">False</property>
|
|
- <property name="label" translatable="yes"><b>Fonts</b></property>
|
|
+ <property name="label" translatable="yes"><b>Font and Theme</b></property>
|
|
<property name="use_markup">True</property>
|
|
</object>
|
|
</child>
|
|
diff --git a/ui/gtk3/bindingcommon.vala b/ui/gtk3/bindingcommon.vala
|
|
index 150d4c39..e825167b 100644
|
|
--- a/ui/gtk3/bindingcommon.vala
|
|
+++ b/ui/gtk3/bindingcommon.vala
|
|
@@ -212,4 +212,50 @@ class BindingCommon {
|
|
css_provider,
|
|
Gtk.STYLE_PROVIDER_PRIORITY_APPLICATION);
|
|
}
|
|
+
|
|
+ public static void
|
|
+ set_custom_theme(GLib.Settings? settings_panel) {
|
|
+ if (settings_panel == null)
|
|
+ return;
|
|
+
|
|
+ bool use_custom_theme = settings_panel.get_boolean("use-custom-theme");
|
|
+ string custom_theme = settings_panel.get_string("custom-theme");
|
|
+
|
|
+ Gtk.Settings gtk_settings = Gtk.Settings.get_default();
|
|
+
|
|
+ if (use_custom_theme == false)
|
|
+ custom_theme = "";
|
|
+
|
|
+ if (custom_theme == null || custom_theme == "") {
|
|
+ gtk_settings.reset_property("gtk-theme-name");
|
|
+ gtk_settings.reset_property("gtk-application-prefer-dark-theme");
|
|
+ } else {
|
|
+ string[] custom_theme_splitted = custom_theme.split(":");
|
|
+ gtk_settings.gtk_theme_name = custom_theme_splitted[0];
|
|
+ if (custom_theme_splitted.length == 2 &&
|
|
+ custom_theme_splitted[1] == "dark")
|
|
+ gtk_settings.gtk_application_prefer_dark_theme = true;
|
|
+ else
|
|
+ gtk_settings.gtk_application_prefer_dark_theme = false;
|
|
+ }
|
|
+ }
|
|
+
|
|
+ public static void
|
|
+ set_custom_icon(GLib.Settings? settings_panel) {
|
|
+ if (settings_panel == null)
|
|
+ return;
|
|
+
|
|
+ bool use_custom_icon = settings_panel.get_boolean("use-custom-icon");
|
|
+ string custom_icon = settings_panel.get_string("custom-icon");
|
|
+
|
|
+ Gtk.Settings gtk_settings = Gtk.Settings.get_default();
|
|
+
|
|
+ if (use_custom_icon == false)
|
|
+ custom_icon = "";
|
|
+
|
|
+ if (custom_icon == null || custom_icon == "")
|
|
+ gtk_settings.reset_property("gtk-icon-theme-name");
|
|
+ else
|
|
+ gtk_settings.gtk_icon_theme_name = custom_icon;
|
|
+ }
|
|
}
|
|
diff --git a/ui/gtk3/panel.vala b/ui/gtk3/panel.vala
|
|
index 61bfa1b6..101c2b3d 100644
|
|
--- a/ui/gtk3/panel.vala
|
|
+++ b/ui/gtk3/panel.vala
|
|
@@ -211,6 +211,22 @@ class Panel : IBus.PanelService {
|
|
ref m_css_provider);
|
|
});
|
|
|
|
+ m_settings_panel.changed["custom-theme"].connect((key) => {
|
|
+ BindingCommon.set_custom_theme(m_settings_panel);
|
|
+ });
|
|
+
|
|
+ m_settings_panel.changed["use-custom-theme"].connect((key) => {
|
|
+ BindingCommon.set_custom_theme(m_settings_panel);
|
|
+ });
|
|
+
|
|
+ m_settings_panel.changed["custom-icon"].connect((key) => {
|
|
+ BindingCommon.set_custom_icon(m_settings_panel);
|
|
+ });
|
|
+
|
|
+ m_settings_panel.changed["use-custom-icon"].connect((key) => {
|
|
+ BindingCommon.set_custom_icon(m_settings_panel);
|
|
+ });
|
|
+
|
|
m_settings_panel.changed["use-glyph-from-engine-lang"].connect((key) =>
|
|
{
|
|
m_use_engine_lang = m_settings_panel.get_boolean(
|
|
@@ -816,6 +832,8 @@ class Panel : IBus.PanelService {
|
|
BindingCommon.set_custom_font(m_settings_panel,
|
|
null,
|
|
ref m_css_provider);
|
|
+ BindingCommon.set_custom_theme(m_settings_panel);
|
|
+ BindingCommon.set_custom_icon(m_settings_panel);
|
|
set_show_icon_on_systray();
|
|
set_lookup_table_orientation();
|
|
set_show_property_panel();
|
|
diff --git a/ui/gtk3/panelbinding.vala b/ui/gtk3/panelbinding.vala
|
|
index e63d93f2..3c516afd 100644
|
|
--- a/ui/gtk3/panelbinding.vala
|
|
+++ b/ui/gtk3/panelbinding.vala
|
|
@@ -270,6 +270,22 @@ class PanelBinding : IBus.PanelService {
|
|
ref m_css_provider);
|
|
});
|
|
|
|
+ m_settings_panel.changed["custom-theme"].connect((key) => {
|
|
+ BindingCommon.set_custom_theme(m_settings_panel);
|
|
+ });
|
|
+
|
|
+ m_settings_panel.changed["use-custom-theme"].connect((key) => {
|
|
+ BindingCommon.set_custom_theme(m_settings_panel);
|
|
+ });
|
|
+
|
|
+ m_settings_panel.changed["custom-icon"].connect((key) => {
|
|
+ BindingCommon.set_custom_icon(m_settings_panel);
|
|
+ });
|
|
+
|
|
+ m_settings_panel.changed["use-custom-icon"].connect((key) => {
|
|
+ BindingCommon.set_custom_icon(m_settings_panel);
|
|
+ });
|
|
+
|
|
m_settings_emoji.changed["unicode-hotkey"].connect((key) => {
|
|
set_emoji_hotkey();
|
|
});
|
|
@@ -422,6 +438,8 @@ class PanelBinding : IBus.PanelService {
|
|
BindingCommon.set_custom_font(m_settings_panel,
|
|
m_settings_emoji,
|
|
ref m_css_provider);
|
|
+ BindingCommon.set_custom_theme(m_settings_panel);
|
|
+ BindingCommon.set_custom_icon(m_settings_panel);
|
|
set_emoji_favorites();
|
|
if (m_load_emoji_at_startup && !m_loaded_emoji)
|
|
set_emoji_lang();
|
|
--
|
|
2.35.3
|
|
|
|
From addab9fdc7f98c172b6fcb1e24faa133368bdaf3 Mon Sep 17 00:00:00 2001
|
|
From: Hollow Man <hollowman@opensuse.org>
|
|
Date: Wed, 26 Jan 2022 10:03:04 +0800
|
|
Subject: [PATCH 2/3] Revert support for choosing GTK themes dark variant
|
|
|
|
So that the theme list won't get too messy
|
|
|
|
BUG=https://github.com/ibus/ibus/pull/2327
|
|
|
|
Signed-off-by: Hollow Man <hollowman@opensuse.org>
|
|
---
|
|
setup/main.py | 10 ++--------
|
|
ui/gtk3/bindingcommon.vala | 14 +++-----------
|
|
2 files changed, 5 insertions(+), 19 deletions(-)
|
|
|
|
diff --git a/setup/main.py b/setup/main.py
|
|
index 71896693..d0e05666 100644
|
|
--- a/setup/main.py
|
|
+++ b/setup/main.py
|
|
@@ -672,18 +672,12 @@ class Setup(object):
|
|
gtk_theme_path = []
|
|
for path in path_list:
|
|
gtk_theme_path.extend(glob.glob(path + "/*/gtk-*/gtk.css"))
|
|
- gtk_theme_path.extend(glob.glob(path + "/*/gtk-*/gtk-dark.css"))
|
|
for path in gtk_theme_path:
|
|
- filename = os.path.basename(path)
|
|
- appendix = ""
|
|
- if filename == "gtk-dark.css":
|
|
- appendix = ":dark"
|
|
theme_name_list.append(os.path.basename(
|
|
- os.path.dirname(os.path.dirname(path))) + appendix)
|
|
+ os.path.dirname(os.path.dirname(path))))
|
|
|
|
theme_name_list.extend([
|
|
- 'Adwaita', 'Adwaita:dark',
|
|
- 'HighContrast', 'HighContrastInverse'
|
|
+ 'Adwaita', 'HighContrast', 'HighContrastInverse'
|
|
])
|
|
theme_name_list = list(set(theme_name_list))
|
|
theme_name_list.sort()
|
|
diff --git a/ui/gtk3/bindingcommon.vala b/ui/gtk3/bindingcommon.vala
|
|
index e825167b..4ecb7159 100644
|
|
--- a/ui/gtk3/bindingcommon.vala
|
|
+++ b/ui/gtk3/bindingcommon.vala
|
|
@@ -226,18 +226,10 @@ class BindingCommon {
|
|
if (use_custom_theme == false)
|
|
custom_theme = "";
|
|
|
|
- if (custom_theme == null || custom_theme == "") {
|
|
+ if (custom_theme == null || custom_theme == "")
|
|
gtk_settings.reset_property("gtk-theme-name");
|
|
- gtk_settings.reset_property("gtk-application-prefer-dark-theme");
|
|
- } else {
|
|
- string[] custom_theme_splitted = custom_theme.split(":");
|
|
- gtk_settings.gtk_theme_name = custom_theme_splitted[0];
|
|
- if (custom_theme_splitted.length == 2 &&
|
|
- custom_theme_splitted[1] == "dark")
|
|
- gtk_settings.gtk_application_prefer_dark_theme = true;
|
|
- else
|
|
- gtk_settings.gtk_application_prefer_dark_theme = false;
|
|
- }
|
|
+ else
|
|
+ gtk_settings.gtk_theme_name = custom_theme;
|
|
}
|
|
|
|
public static void
|
|
--
|
|
2.35.3
|
|
|
|
From ff99828cb60915318ed0f40998a1a23d5dea42c7 Mon Sep 17 00:00:00 2001
|
|
From: Hollow Man <hollowman@opensuse.org>
|
|
Date: Wed, 26 Jan 2022 11:19:40 +0800
|
|
Subject: [PATCH 3/3] Add tooltip text for use custom icon and theme
|
|
|
|
BUG=https://github.com/ibus/ibus/pull/2327
|
|
|
|
Signed-off-by: Hollow Man <hollowman@opensuse.org>
|
|
---
|
|
setup/setup.ui | 2 ++
|
|
1 file changed, 2 insertions(+)
|
|
|
|
diff --git a/setup/setup.ui b/setup/setup.ui
|
|
index 5a9804f9..6ded2061 100644
|
|
--- a/setup/setup.ui
|
|
+++ b/setup/setup.ui
|
|
@@ -1339,6 +1339,7 @@
|
|
<child>
|
|
<object class="GtkCheckButton" id="checkbutton_custom_theme">
|
|
<property name="label" translatable="yes">Use custom theme:</property>
|
|
+ <property name="tooltip_text" translatable="yes">Choose a theme of the candidate window</property>
|
|
<property name="use_action_appearance">False</property>
|
|
<property name="visible">True</property>
|
|
<property name="can_focus">True</property>
|
|
@@ -1375,6 +1376,7 @@
|
|
<child>
|
|
<object class="GtkCheckButton" id="checkbutton_custom_icon">
|
|
<property name="label" translatable="yes">Use custom icon:</property>
|
|
+ <property name="tooltip_text" translatable="yes">Choose a theme of the arrow buttons on the candidate window</property>
|
|
<property name="use_action_appearance">False</property>
|
|
<property name="visible">True</property>
|
|
<property name="can_focus">True</property>
|
|
--
|
|
2.35.3
|
|
|
|
From 9ad063746ec3d919217ae18acce2d4768bcfca05 Mon Sep 17 00:00:00 2001
|
|
From: fujiwarat <takao.fujiwara1@gmail.com>
|
|
Date: Mon, 20 Jun 2022 21:01:31 +0900
|
|
Subject: [PATCH] ui/gtk3: Hide XKB engine but enable it in Plasma Wayland
|
|
|
|
IBus just cannot defer key events to the secondary input methods
|
|
to switch XKB keymaps in Plasma Wayland because IBus has to handle the
|
|
compose keys before defer the key events.
|
|
|
|
Also update the POT file.
|
|
|
|
BUG=rhbz#2088656
|
|
---
|
|
data/dconf/org.freedesktop.ibus.gschema.xml | 4 +-
|
|
ui/gtk3/panel.vala | 50 ++-
|
|
3 files changed, 248 insertions(+), 180 deletions(-)
|
|
|
|
diff --git a/data/dconf/org.freedesktop.ibus.gschema.xml b/data/dconf/org.freedesktop.ibus.gschema.xml
|
|
index 051f21a5..0ece2b4f 100644
|
|
--- a/data/dconf/org.freedesktop.ibus.gschema.xml
|
|
+++ b/data/dconf/org.freedesktop.ibus.gschema.xml
|
|
@@ -223,12 +223,12 @@
|
|
<key name="use-custom-icon" type="b">
|
|
<default>false</default>
|
|
<summary>Use custom icon</summary>
|
|
- <description>Use custom icon name for language panel</description>
|
|
+ <description>Use custom icon name for arrow buttons on candidate window</description>
|
|
</key>
|
|
<key name="custom-icon" type="s">
|
|
<default>'Adwaita'</default>
|
|
<summary>Custom icon</summary>
|
|
- <description>Custom icon name for language panel</description>
|
|
+ <description>Custom icon name for arrow buttons on candidate window</description>
|
|
</key>
|
|
<key name="use-glyph-from-engine-lang" type="b">
|
|
<default>true</default>
|
|
diff --git a/ui/gtk3/panel.vala b/ui/gtk3/panel.vala
|
|
index 101c2b3d..452b14c8 100644
|
|
--- a/ui/gtk3/panel.vala
|
|
+++ b/ui/gtk3/panel.vala
|
|
@@ -41,6 +41,7 @@ class Panel : IBus.PanelService {
|
|
private Gtk.Menu m_ime_menu;
|
|
private Gtk.Menu m_sys_menu;
|
|
private IBus.EngineDesc[] m_engines = {};
|
|
+ private IBus.EngineDesc m_en_engine;
|
|
private GLib.HashTable<string, IBus.EngineDesc> m_engine_contexts =
|
|
new GLib.HashTable<string, IBus.EngineDesc>(GLib.str_hash,
|
|
GLib.str_equal);
|
|
@@ -928,13 +929,20 @@ class Panel : IBus.PanelService {
|
|
}
|
|
|
|
private void switch_engine(int i, bool force = false) {
|
|
- GLib.assert(i >= 0 && i < m_engines.length);
|
|
+ if (m_is_wayland)
|
|
+ GLib.assert(i >= 0 && i <= m_engines.length);
|
|
+ else
|
|
+ GLib.assert(i >= 0 && i < m_engines.length);
|
|
|
|
// Do not need switch
|
|
if (i == 0 && !force)
|
|
return;
|
|
|
|
- IBus.EngineDesc engine = m_engines[i];
|
|
+ IBus.EngineDesc engine;
|
|
+ if (m_is_wayland && m_engines.length == 0)
|
|
+ engine = m_en_engine;
|
|
+ else
|
|
+ engine = m_engines[i];
|
|
|
|
set_engine(engine);
|
|
}
|
|
@@ -1024,17 +1032,15 @@ class Panel : IBus.PanelService {
|
|
string[]? order_names) {
|
|
string[]? engine_names = unowned_engine_names;
|
|
|
|
- if (engine_names == null || engine_names.length == 0) {
|
|
- if (m_is_wayland)
|
|
- engine_names = {};
|
|
- else
|
|
- engine_names = {"xkb:us::eng"};
|
|
- }
|
|
+ if (engine_names == null || engine_names.length == 0)
|
|
+ engine_names = {"xkb:us::eng"};
|
|
|
|
string[] names = {};
|
|
|
|
foreach (var name in order_names) {
|
|
if (m_is_wayland && name.has_prefix("xkb:"))
|
|
+ name = "xkb:us::eng";
|
|
+ if (name in names)
|
|
continue;
|
|
if (name in engine_names)
|
|
names += name;
|
|
@@ -1042,7 +1048,7 @@ class Panel : IBus.PanelService {
|
|
|
|
foreach (var name in engine_names) {
|
|
if (m_is_wayland && name.has_prefix("xkb:"))
|
|
- continue;
|
|
+ name = "xkb:us::eng";
|
|
if (name in names)
|
|
continue;
|
|
names += name;
|
|
@@ -1083,14 +1089,20 @@ class Panel : IBus.PanelService {
|
|
}
|
|
|
|
if (m_engines.length == 0) {
|
|
- if (engines.length > 0) {
|
|
- m_engines = engines;
|
|
- switch_engine(0, true);
|
|
- run_preload_engines(engines, 1);
|
|
- } else {
|
|
- m_candidate_panel.set_language(new Pango.AttrLanguage(
|
|
- Pango.Language.from_string(null)));
|
|
+ m_engines = engines;
|
|
+ // Do not show engines in panel icon and suggest systemsettings5
|
|
+ // in Plasma Wayland in case all engines are XKB.
|
|
+ if (m_is_wayland && m_engines.length == 1 &&
|
|
+ m_engines[0].get_name() == "xkb:us::eng") {
|
|
+ m_engines = {};
|
|
+ if (m_en_engine == null) {
|
|
+ m_en_engine =
|
|
+ m_bus.get_engines_by_names({"xkb:us::eng"})[0];
|
|
+ }
|
|
}
|
|
+ switch_engine(0, true);
|
|
+ if (m_engines.length > 0)
|
|
+ run_preload_engines(m_engines, 1);
|
|
} else {
|
|
var current_engine = m_engines[0];
|
|
m_engines = engines;
|
|
@@ -1307,6 +1319,10 @@ class Panel : IBus.PanelService {
|
|
var longname = engine.get_longname();
|
|
var textdomain = engine.get_textdomain();
|
|
var transname = GLib.dgettext(textdomain, longname);
|
|
+ if (m_is_wayland && engine.get_name().has_prefix("xkb:")) {
|
|
+ language = _("Other");
|
|
+ transname = _("No input method");
|
|
+ }
|
|
var item = new Gtk.MenuItem.with_label(
|
|
"%s - %s".printf (IBus.get_language_name(language), transname));
|
|
// Make a copy of engine to workaround a bug in vala.
|
|
@@ -1584,7 +1600,7 @@ class Panel : IBus.PanelService {
|
|
|
|
if (engine != null) {
|
|
var name = engine.get_name();
|
|
- if (name.length >= 4 && name[0:4] == "xkb:")
|
|
+ if (!m_is_wayland && name.length >= 4 && name[0:4] == "xkb:")
|
|
language = m_switcher.get_xkb_language(engine);
|
|
}
|
|
|
|
--
|
|
2.35.3
|
|
|
|
From b94f0c1cea5d0e423fef3bcc13b23f212f04c930 Mon Sep 17 00:00:00 2001
|
|
From: fujiwarat <takao.fujiwara1@gmail.com>
|
|
Date: Thu, 7 Jul 2022 08:13:57 +0900
|
|
Subject: [PATCH] src: Add IBUS_CAP_OSK to IBusCapabilite
|
|
|
|
Some IMEs' behavior is different between the on-screen keyboard and
|
|
the direct physical keyboard and this flag is useful for the IMEs.
|
|
|
|
Also fix src/ibusaccelgroup.c for gtkdoc-mkhtml.
|
|
If the API comment of IBusCapabilite is updated, XML & HTML files
|
|
are rebuilt and gtk-doc-1.33.2 no longer accepts HTML tags in
|
|
the comments.
|
|
---
|
|
src/ibusaccelgroup.c | 14 +++++++-------
|
|
src/ibustypes.h | 2 ++
|
|
2 files changed, 9 insertions(+), 7 deletions(-)
|
|
|
|
diff --git a/src/ibusaccelgroup.c b/src/ibusaccelgroup.c
|
|
index ef2d3976..aec1c7e4 100644
|
|
--- a/src/ibusaccelgroup.c
|
|
+++ b/src/ibusaccelgroup.c
|
|
@@ -267,14 +267,14 @@ is_keycode (const gchar *string)
|
|
* modifier mask, %NULL
|
|
*
|
|
* Parses a string representing an accelerator. The format looks like
|
|
- * “<Control>a” or “<Shift><Alt>F1” or “<Release>z” (the last one is
|
|
- * for key release).
|
|
+ * “<Control>a” or “<Shift><Alt>F1” or “<Release%gt;z”
|
|
+ * (the last one is for key release).
|
|
*
|
|
* The parser is fairly liberal and allows lower or upper case, and also
|
|
- * abbreviations such as “<Ctl>” and “<Ctrl>”. Key names are parsed using
|
|
- * gdk_keyval_from_name(). For character keys the name is not the symbol,
|
|
- * but the lowercase name, e.g. one would use “<Ctrl>minus” instead of
|
|
- * “<Ctrl>-”.
|
|
+ * abbreviations such as “<Ctl>” and “<Ctrl>”. Key names are
|
|
+ * parsed using gdk_keyval_from_name(). For character keys the name is not the
|
|
+ * symbol, but the lowercase name, e.g. one would use “<Ctrl>minus”
|
|
+ * instead of “<Ctrl>-”.
|
|
*
|
|
* If the parse fails, @accelerator_key and @accelerator_mods will
|
|
* be set to 0 (zero).
|
|
@@ -403,7 +403,7 @@ out:
|
|
*
|
|
* Converts an accelerator keyval and modifier mask into a string
|
|
* parseable by gtk_accelerator_parse(). For example, if you pass in
|
|
- * #IBUS_KEY_q and #IBUS_CONTROL_MASK, this function returns “<Control>q”.
|
|
+ * #IBUS_KEY_q and #IBUS_CONTROL_MASK, this function returns “<Control>q”.
|
|
*
|
|
* If you need to display accelerators in the user interface,
|
|
* see gtk_accelerator_get_label().
|
|
diff --git a/src/ibustypes.h b/src/ibustypes.h
|
|
index 990659ac..60bcb92b 100644
|
|
--- a/src/ibustypes.h
|
|
+++ b/src/ibustypes.h
|
|
@@ -108,6 +108,7 @@ typedef enum
|
|
* @IBUS_CAP_PROPERTY: UI is capable to have property.
|
|
* @IBUS_CAP_SURROUNDING_TEXT: Client can provide surround text,
|
|
* or IME can handle surround text.
|
|
+ * @IBUS_CAP_OSK: UI is owned by on-screen keyboard.
|
|
*
|
|
* Capability flags of UI.
|
|
*/
|
|
@@ -118,6 +119,7 @@ typedef enum {
|
|
IBUS_CAP_FOCUS = 1 << 3,
|
|
IBUS_CAP_PROPERTY = 1 << 4,
|
|
IBUS_CAP_SURROUNDING_TEXT = 1 << 5,
|
|
+ IBUS_CAP_OSK = 1 << 6,
|
|
} IBusCapabilite;
|
|
|
|
/**
|
|
--
|
|
2.35.3
|
|
|
|
From 4e48e7237d73d20f0426265dbb6b692b14891932 Mon Sep 17 00:00:00 2001
|
|
From: fujiwarat <takao.fujiwara1@gmail.com>
|
|
Date: Thu, 7 Jul 2022 08:21:24 +0900
|
|
Subject: [PATCH] tools: Enable ibus restart in GNOME desktop
|
|
|
|
If ibus-daemon is called via systemd, IBus restart API cannot restart
|
|
ibus-daemon but just terminates it.
|
|
Now ibus restart command checks the systemd avaiability and restart
|
|
ibus-daemon via systemd.
|
|
ibus start command is also added to launch ibus-daemon with systemd.
|
|
|
|
BUG=https://github.com/ibus/ibus/issues/2407
|
|
---
|
|
tools/Makefile.am | 3 +-
|
|
tools/ibus.1.in | 30 +++++-
|
|
tools/main.vala | 261 ++++++++++++++++++++++++++++++++++++++++++++--
|
|
3 files changed, 330 insertions(+), 44 deletions(-)
|
|
|
|
diff --git a/tools/Makefile.am b/tools/Makefile.am
|
|
index 5c18d3d6..e380a9aa 100644
|
|
--- a/tools/Makefile.am
|
|
+++ b/tools/Makefile.am
|
|
@@ -3,7 +3,7 @@
|
|
# ibus - The Input Bus
|
|
#
|
|
# Copyright (c) 2007-2013 Peng Huang <shawn.p.huang@gmail.com>
|
|
-# Copyright (c) 2015-2017 Takao Fujiwara <takao.fujiwara1@gmail.com>
|
|
+# Copyright (c) 2015-2022 Takao Fujiwara <takao.fujiwara1@gmail.com>
|
|
# Copyright (c) 2007-2017 Red Hat, Inc.
|
|
#
|
|
# This library is free software; you can redistribute it and/or
|
|
@@ -57,6 +57,7 @@ AM_LDADD = \
|
|
AM_VALAFLAGS = \
|
|
--vapidir=$(top_builddir)/bindings/vala \
|
|
--vapidir=$(top_srcdir)/bindings/vala \
|
|
+ --pkg=gio-2.0 \
|
|
--pkg=ibus-1.0 \
|
|
--pkg=posix \
|
|
--pkg=config \
|
|
diff --git a/tools/ibus.1.in b/tools/ibus.1.in
|
|
index 525d972e..fe1b7157 100644
|
|
--- a/tools/ibus.1.in
|
|
+++ b/tools/ibus.1.in
|
|
@@ -3,7 +3,7 @@
|
|
.\" Copyright (C) Takao Fujiwara <takao.fujiwara1@gmail.com>, 2013-2017.
|
|
.\" Copyright (c) Peng Huang <shawn.p.huang@gmail.com>, 2013.
|
|
.\"
|
|
-.TH "IBUS" 1 "May 2017" "@VERSION@" "User Commands"
|
|
+.TH "IBUS" 1 "Jul 2022" "@VERSION@" "User Commands"
|
|
.SH NAME
|
|
.B ibus
|
|
\- command line utility for ibus
|
|
@@ -45,13 +45,33 @@ Exit ibus-daemon.
|
|
\fBlist-engine\fR
|
|
Show ibus engines list.
|
|
.TP
|
|
-\fBrestart\fR
|
|
-Restart ibus-daemon.
|
|
+\fBrestart\fR [\fB\-\-type=TYPE|\-\-verbose|\-\-help\fR]
|
|
+Restart ibus-daemon. This command tries to restart ibus-daemon via systemd
|
|
+firstly and directly secondary by default. If
|
|
+.B \-\-type=systemd
|
|
+is given, It tries to restart via systemd only. If
|
|
+.B \-\-type=direct
|
|
+is given, It tries to restart with an IBus API only. GNOME desktop runs
|
|
+ibus-daemon via systemd and other desktops run ibus-daemon directly.
|
|
+.TP
|
|
+\fBstart\fR [\fB\-\-type=TYPE|\-\-verbose|\-\-help\fR]
|
|
+Start ibus-daemon. This command tries to start ibus-daemon via systemd
|
|
+firstly and directly secondary by default. If
|
|
+.B \-\-type=systemd
|
|
+is given, It tries to start as a background process via systemd only. If
|
|
+.B \-\-type=direct
|
|
+is given, It tries to start directly only as a foreground process and other
|
|
+option arguments of ibus command are sent to ibus-daemon. E.g.
|
|
+ibus start
|
|
+.B \-\-type=direct
|
|
+.B \-\-xim
|
|
+&
|
|
+GNOME desktop runs ibus-daemon via systemd and other desktops run ibus-daemon directly.
|
|
.TP
|
|
\fBversion\fR
|
|
Show the ibus version.
|
|
.TP
|
|
-\fBread\-cache\fR [\fB\-\-system|\-\-file=FILE\fR]
|
|
+\fBread\-cache\fR [\fB\-\-system|\-\-file=FILE|\-\-help\fR]
|
|
Show the content of the user registry cache if
|
|
.B \-\-system
|
|
is not given.
|
|
@@ -64,7 +84,7 @@ if
|
|
.B \-\-file=FILE
|
|
is given.
|
|
.TP
|
|
-\fBwrite\-cache\fR [\fB\-\-system|\-\-file=FILE\fR]
|
|
+\fBwrite\-cache\fR [\fB\-\-system|\-\-file=FILE|\-\-help\fR]
|
|
Save the user registry cache if
|
|
.B \-\-system
|
|
is not given.
|
|
diff --git a/tools/main.vala b/tools/main.vala
|
|
index 26e7fd88..407eaf74 100644
|
|
--- a/tools/main.vala
|
|
+++ b/tools/main.vala
|
|
@@ -3,7 +3,7 @@
|
|
* ibus - The Input Bus
|
|
*
|
|
* Copyright(c) 2013 Peng Huang <shawn.p.huang@gmail.com>
|
|
- * Copyright(c) 2015-2020 Takao Fujiwara <takao.fujiwara1@gmail.com>
|
|
+ * Copyright(c) 2015-2022 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
|
|
@@ -27,17 +27,23 @@ private const string IBUS_SCHEMAS_GENERAL_HOTKEY =
|
|
private const string IBUS_SCHEMAS_PANEL = "org.freedesktop.ibus.panel";
|
|
private const string IBUS_SCHEMAS_PANEL_EMOJI =
|
|
"org.freedesktop.ibus.panel.emoji";
|
|
+private const string SYSTEMD_SESSION_GNOME_FILE =
|
|
+ "org.freedesktop.IBus.session.GNOME.service";
|
|
|
|
bool name_only = false;
|
|
/* system() exists as a public API. */
|
|
bool is_system = false;
|
|
string cache_file = null;
|
|
string engine_id = null;
|
|
+bool verbose = false;
|
|
+string daemon_type = null;
|
|
+string systemd_service_file = null;
|
|
|
|
class EngineList {
|
|
public IBus.EngineDesc[] data = {};
|
|
}
|
|
|
|
+
|
|
IBus.Bus? get_bus() {
|
|
var bus = new IBus.Bus();
|
|
if (!bus.is_connected ())
|
|
@@ -45,6 +51,131 @@ IBus.Bus? get_bus() {
|
|
return bus;
|
|
}
|
|
|
|
+
|
|
+GLib.DBusConnection? get_session_bus(bool verbose) {
|
|
+ try {
|
|
+ return GLib.Bus.get_sync (GLib.BusType.SESSION, null);
|
|
+ } catch (GLib.IOError e) {
|
|
+ if (verbose)
|
|
+ stderr.printf("%s\n", e.message);
|
|
+ }
|
|
+ return null;
|
|
+}
|
|
+
|
|
+string?
|
|
+get_ibus_systemd_object_path(GLib.DBusConnection connection,
|
|
+ bool verbose) {
|
|
+ string object_path = null;
|
|
+ assert(systemd_service_file != null);
|
|
+ try {
|
|
+ var variant = connection.call_sync (
|
|
+ "org.freedesktop.systemd1",
|
|
+ "/org/freedesktop/systemd1",
|
|
+ "org.freedesktop.systemd1.Manager",
|
|
+ "GetUnit",
|
|
+ new GLib.Variant("(s)", systemd_service_file),
|
|
+ new GLib.VariantType("(o)"),
|
|
+ GLib.DBusCallFlags.NONE,
|
|
+ -1,
|
|
+ null);
|
|
+ variant.get("(o)", ref object_path);
|
|
+ if (verbose) {
|
|
+ stderr.printf("Succeed to get an object path \"%s\" for IBus " +
|
|
+ "systemd service file \"%s\".\n",
|
|
+ object_path, systemd_service_file);
|
|
+ }
|
|
+ return object_path;
|
|
+ } catch (GLib.Error e) {
|
|
+ if (verbose) {
|
|
+ stderr.printf("IBus systemd service file \"%s\" is not installed " +
|
|
+ "in your system: %s\n",
|
|
+ systemd_service_file, e.message);
|
|
+ }
|
|
+ }
|
|
+ return null;
|
|
+}
|
|
+
|
|
+
|
|
+bool
|
|
+is_running_daemon_via_systemd(GLib.DBusConnection connection,
|
|
+ string object_path,
|
|
+ bool verbose) {
|
|
+ string? state = null;
|
|
+ try {
|
|
+ while (true) {
|
|
+ var variant = connection.call_sync (
|
|
+ "org.freedesktop.systemd1",
|
|
+ object_path,
|
|
+ "org.freedesktop.DBus.Properties",
|
|
+ "Get",
|
|
+ new GLib.Variant("(ss)",
|
|
+ "org.freedesktop.systemd1.Unit",
|
|
+ "ActiveState"),
|
|
+ new GLib.VariantType("(v)"),
|
|
+ GLib.DBusCallFlags.NONE,
|
|
+ -1,
|
|
+ null);
|
|
+ GLib.Variant child = null;
|
|
+ variant.get("(v)", ref child);
|
|
+ state = child.dup_string();
|
|
+ if (verbose) {
|
|
+ stderr.printf("systemd state is \"%s\" for an object " +
|
|
+ "path \"%s\".\n", state, object_path);
|
|
+ }
|
|
+ if (state != "activating")
|
|
+ break;
|
|
+ Posix.sleep(1);
|
|
+ }
|
|
+ } catch (GLib.Error e) {
|
|
+ if (verbose)
|
|
+ stderr.printf("%s\n", e.message);
|
|
+ return false;
|
|
+ }
|
|
+ if (state == "active")
|
|
+ return true;
|
|
+ return false;
|
|
+}
|
|
+
|
|
+
|
|
+bool
|
|
+start_daemon_via_systemd(GLib.DBusConnection connection,
|
|
+ bool restart,
|
|
+ bool verbose) {
|
|
+ string object_path = null;
|
|
+ string method = "StartUnit";
|
|
+ assert(systemd_service_file != null);
|
|
+ if (restart)
|
|
+ method = "RestartUnit";
|
|
+ try {
|
|
+ var variant = connection.call_sync (
|
|
+ "org.freedesktop.systemd1",
|
|
+ "/org/freedesktop/systemd1",
|
|
+ "org.freedesktop.systemd1.Manager",
|
|
+ method,
|
|
+ new GLib.Variant("(ss)", systemd_service_file, "fail"),
|
|
+ new GLib.VariantType("(o)"),
|
|
+ GLib.DBusCallFlags.NONE,
|
|
+ -1,
|
|
+ null);
|
|
+ variant.get("(o)", ref object_path);
|
|
+ if (verbose) {
|
|
+ stderr.printf("Succeed to restart IBus daemon via IBus systemd " +
|
|
+ "service file \"%s\": \"%s\"\n",
|
|
+ systemd_service_file, object_path);
|
|
+ }
|
|
+ return true;
|
|
+ } catch (GLib.Error e) {
|
|
+ if (verbose) {
|
|
+ stderr.printf("Failed to %s IBus daemon via IBus systemd " +
|
|
+ "service file \"%s\": %s\n",
|
|
+ restart ? "restart" : "start",
|
|
+ systemd_service_file, e.message);
|
|
+ }
|
|
+ }
|
|
+ return false;
|
|
+}
|
|
+
|
|
+
|
|
int list_engine(string[] argv) {
|
|
const OptionEntry[] options = {
|
|
{ "name-only", 0, 0, OptionArg.NONE, out name_only,
|
|
@@ -99,6 +230,7 @@ int list_engine(string[] argv) {
|
|
return Posix.EXIT_SUCCESS;
|
|
}
|
|
|
|
+
|
|
private int exec_setxkbmap(IBus.EngineDesc engine) {
|
|
string layout = engine.get_layout();
|
|
string variant = engine.get_layout_variant();
|
|
@@ -149,6 +281,7 @@ private int exec_setxkbmap(IBus.EngineDesc engine) {
|
|
return Posix.EXIT_SUCCESS;
|
|
}
|
|
|
|
+
|
|
int get_set_engine(string[] argv) {
|
|
var bus = get_bus();
|
|
string engine = null;
|
|
@@ -182,20 +315,121 @@ int get_set_engine(string[] argv) {
|
|
return Posix.EXIT_SUCCESS;
|
|
}
|
|
|
|
+
|
|
int message_watch(string[] argv) {
|
|
return Posix.EXIT_SUCCESS;
|
|
}
|
|
|
|
-int restart_daemon(string[] argv) {
|
|
- var bus = get_bus();
|
|
- if (bus == null) {
|
|
- stderr.printf(_("Can't connect to IBus.\n"));
|
|
+
|
|
+int start_daemon_real(string[] argv,
|
|
+ bool restart) {
|
|
+ const OptionEntry[] options = {
|
|
+ { "type", 0, 0, OptionArg.STRING, out daemon_type,
|
|
+ N_("Start or restart daemon with \"direct\" or \"systemd\" TYPE."),
|
|
+ "TYPE" },
|
|
+ { "service-file", 0, 0, OptionArg.STRING, out systemd_service_file,
|
|
+ N_("Start or restart daemon with SYSTEMD_SERVICE file."),
|
|
+ "SYSTEMD_SERVICE" },
|
|
+ { "verbose", 0, 0, OptionArg.NONE, out verbose,
|
|
+ N_("Show debug messages."), null },
|
|
+ { null }
|
|
+ };
|
|
+
|
|
+ var option = new OptionContext();
|
|
+ option.add_main_entries(options, Config.GETTEXT_PACKAGE);
|
|
+ option.set_ignore_unknown_options(true);
|
|
+
|
|
+ try {
|
|
+ option.parse(ref argv);
|
|
+ } catch (OptionError e) {
|
|
+ stderr.printf("%s\n", e.message);
|
|
+ return Posix.EXIT_FAILURE;
|
|
+ }
|
|
+ if (daemon_type != null && daemon_type != "direct" &&
|
|
+ daemon_type != "systemd") {
|
|
+ stderr.printf("type argument must be \"direct\" or \"systemd\"\n");
|
|
+ return Posix.EXIT_FAILURE;
|
|
+ }
|
|
+ if (systemd_service_file == null)
|
|
+ systemd_service_file = SYSTEMD_SESSION_GNOME_FILE;
|
|
+
|
|
+ do {
|
|
+ if (daemon_type == "direct")
|
|
+ break;
|
|
+ GLib.DBusConnection? connection = get_session_bus(verbose);
|
|
+ if (connection == null)
|
|
+ break;
|
|
+ string? object_path = null;
|
|
+ if (restart) {
|
|
+ object_path = get_ibus_systemd_object_path(connection, verbose);
|
|
+ if (object_path == null)
|
|
+ break;
|
|
+ if (!is_running_daemon_via_systemd(connection,
|
|
+ object_path,
|
|
+ verbose)) {
|
|
+ break;
|
|
+ }
|
|
+ }
|
|
+ if (!start_daemon_via_systemd(connection, restart, verbose))
|
|
+ break;
|
|
+ // Do not check the systemd state in case of restart because
|
|
+ // the systemd file validation is already done and also stopping
|
|
+ // daemon and starting daemon take time and the state could be
|
|
+ // "inactive" with the time lag.
|
|
+ if (restart)
|
|
+ return Posix.EXIT_SUCCESS;
|
|
+ object_path = get_ibus_systemd_object_path(connection, verbose);
|
|
+ if (object_path == null)
|
|
+ break;
|
|
+ if (!is_running_daemon_via_systemd(connection, object_path, verbose))
|
|
+ break;
|
|
+ return Posix.EXIT_SUCCESS;
|
|
+ } while (false);
|
|
+
|
|
+ if (daemon_type == "systemd")
|
|
return Posix.EXIT_FAILURE;
|
|
+ if (restart) {
|
|
+ var bus = get_bus();
|
|
+ if (bus == null) {
|
|
+ stderr.printf(_("Can't connect to IBus.\n"));
|
|
+ return Posix.EXIT_FAILURE;
|
|
+ }
|
|
+ bus.exit(true);
|
|
+ if (verbose) {
|
|
+ stderr.printf("Succeed to restart ibus-daemon with an IBus API " +
|
|
+ "directly.\n");
|
|
+ }
|
|
+ } else {
|
|
+ string startarg = "ibus-daemon";
|
|
+ argv[0] = startarg;
|
|
+ var paths = GLib.Environment.get_variable("PATH").split(":");
|
|
+ foreach (unowned string path in paths) {
|
|
+ var full_path = "%s/%s".printf(path, startarg);
|
|
+ if (GLib.FileUtils.test(full_path, GLib.FileTest.IS_EXECUTABLE)) {
|
|
+ startarg = full_path;
|
|
+ break;
|
|
+ }
|
|
+ }
|
|
+ // When ibus-daemon is launched by GLib.Process.spawn_async(),
|
|
+ // the parent process will be systemd
|
|
+ if (verbose) {
|
|
+ stderr.printf("Running \"%s\" directly as a foreground " +
|
|
+ "process.\n", startarg);
|
|
+ }
|
|
+ Posix.execv(startarg, argv);
|
|
}
|
|
- bus.exit(true);
|
|
return Posix.EXIT_SUCCESS;
|
|
}
|
|
|
|
+
|
|
+int restart_daemon(string[] argv) {
|
|
+ return start_daemon_real(argv, true);
|
|
+}
|
|
+
|
|
+int start_daemon(string[] argv) {
|
|
+ return start_daemon_real(argv, false);
|
|
+}
|
|
+
|
|
int exit_daemon(string[] argv) {
|
|
var bus = get_bus();
|
|
if (bus == null) {
|
|
@@ -206,11 +440,13 @@ int exit_daemon(string[] argv) {
|
|
return Posix.EXIT_SUCCESS;
|
|
}
|
|
|
|
+
|
|
int print_version(string[] argv) {
|
|
print("IBus %s\n", Config.PACKAGE_VERSION);
|
|
return Posix.EXIT_SUCCESS;
|
|
}
|
|
|
|
+
|
|
int read_cache (string[] argv) {
|
|
const OptionEntry[] options = {
|
|
{ "system", 0, 0, OptionArg.NONE, out is_system,
|
|
@@ -251,6 +487,7 @@ int read_cache (string[] argv) {
|
|
return Posix.EXIT_SUCCESS;
|
|
}
|
|
|
|
+
|
|
int write_cache (string[] argv) {
|
|
const OptionEntry[] options = {
|
|
{ "system", 0, 0, OptionArg.NONE, out is_system,
|
|
@@ -283,12 +520,14 @@ int write_cache (string[] argv) {
|
|
Posix.EXIT_SUCCESS : Posix.EXIT_FAILURE;
|
|
}
|
|
|
|
+
|
|
int print_address(string[] argv) {
|
|
string address = IBus.get_address();
|
|
print("%s\n", address != null ? address : "(null)");
|
|
return Posix.EXIT_SUCCESS;
|
|
}
|
|
|
|
+
|
|
private int read_config_options(string[] argv) {
|
|
const OptionEntry[] options = {
|
|
{ "engine-id", 0, 0, OptionArg.STRING, out engine_id,
|
|
@@ -309,6 +548,7 @@ private int read_config_options(string[] argv) {
|
|
return Posix.EXIT_SUCCESS;
|
|
}
|
|
|
|
+
|
|
private GLib.SList<string> get_ibus_schemas() {
|
|
string[] ids = {};
|
|
if (engine_id != null) {
|
|
@@ -342,6 +582,7 @@ private GLib.SList<string> get_ibus_schemas() {
|
|
return ibus_schemas;
|
|
}
|
|
|
|
+
|
|
int read_config(string[] argv) {
|
|
if (read_config_options(argv) == Posix.EXIT_FAILURE)
|
|
return Posix.EXIT_FAILURE;
|
|
@@ -370,6 +611,7 @@ int read_config(string[] argv) {
|
|
return Posix.EXIT_SUCCESS;
|
|
}
|
|
|
|
+
|
|
int reset_config(string[] argv) {
|
|
if (read_config_options(argv) == Posix.EXIT_FAILURE)
|
|
return Posix.EXIT_FAILURE;
|
|
@@ -401,6 +643,7 @@ int reset_config(string[] argv) {
|
|
return Posix.EXIT_SUCCESS;
|
|
}
|
|
|
|
+
|
|
#if EMOJI_DICT
|
|
int emoji_dialog(string[] argv) {
|
|
string cmd = Config.LIBEXECDIR + "/ibus-ui-emojier";
|
|
@@ -427,11 +670,13 @@ int emoji_dialog(string[] argv) {
|
|
}
|
|
#endif
|
|
|
|
+
|
|
int print_help(string[] argv) {
|
|
print_usage(stdout);
|
|
return Posix.EXIT_SUCCESS;
|
|
}
|
|
|
|
+
|
|
delegate int EntryFunc(string[] argv);
|
|
|
|
struct CommandEntry {
|
|
@@ -440,12 +685,14 @@ struct CommandEntry {
|
|
unowned EntryFunc entry;
|
|
}
|
|
|
|
+
|
|
const CommandEntry commands[] = {
|
|
{ "engine", N_("Set or get engine"), get_set_engine },
|
|
{ "exit", N_("Exit ibus-daemon"), exit_daemon },
|
|
{ "list-engine", N_("Show available engines"), list_engine },
|
|
{ "watch", N_("(Not implemented)"), message_watch },
|
|
{ "restart", N_("Restart ibus-daemon"), restart_daemon },
|
|
+ { "start", N_("Start ibus-daemon"), start_daemon },
|
|
{ "version", N_("Show version"), print_version },
|
|
{ "read-cache", N_("Show the content of registry cache"), read_cache },
|
|
{ "write-cache", N_("Create registry cache"), write_cache },
|
|
@@ -460,6 +707,7 @@ const CommandEntry commands[] = {
|
|
|
|
static string program_name;
|
|
|
|
+
|
|
void print_usage(FileStream stream) {
|
|
stream.printf(_("Usage: %s COMMAND [OPTION...]\n\n"), program_name);
|
|
stream.printf(_("Commands:\n"));
|
|
@@ -470,6 +718,7 @@ void print_usage(FileStream stream) {
|
|
}
|
|
}
|
|
|
|
+
|
|
public int main(string[] argv) {
|
|
GLib.Intl.setlocale(GLib.LocaleCategory.ALL, "");
|
|
GLib.Intl.bindtextdomain(Config.GETTEXT_PACKAGE, Config.LOCALEDIR);
|
|
--
|
|
2.35.3
|
|
|
|
From 5b441fabc9d766e694b992e0e2f28924d00a7402 Mon Sep 17 00:00:00 2001
|
|
From: fujiwarat <takao.fujiwara1@gmail.com>
|
|
Date: Thu, 7 Jul 2022 08:22:26 +0900
|
|
Subject: [PATCH] tools: Add ibus im-module command
|
|
|
|
ibus im-module command can retrive gtk-im-module value from an
|
|
instance of GtkIMMultiContext.
|
|
The GTK version can be specified by --type option and the default
|
|
is --type=gtk3 and GTK3 im-ibus.so is dlopened.
|
|
---
|
|
client/gtk2/ibusim.c | 20 ++++++
|
|
client/gtk4/ibusim.c | 20 ++++++
|
|
tools/IBusIMModule-1.0.metadata | 1 +
|
|
tools/Makefile.am | 116 ++++++++++++++++++++++++++------
|
|
tools/ibus.1.in | 10 +++
|
|
tools/ibusimmodule.c | 87 ++++++++++++++++++++++++
|
|
tools/ibusimmodule.h | 36 ++++++++++
|
|
tools/main.vala | 11 +++
|
|
8 files changed, 308 insertions(+), 40 deletions(-)
|
|
create mode 100644 tools/IBusIMModule-1.0.metadata
|
|
create mode 100644 tools/ibusimmodule.c
|
|
create mode 100644 tools/ibusimmodule.h
|
|
|
|
diff --git a/client/gtk2/ibusim.c b/client/gtk2/ibusim.c
|
|
index 55609ce7..e196d536 100644
|
|
--- a/client/gtk2/ibusim.c
|
|
+++ b/client/gtk2/ibusim.c
|
|
@@ -77,3 +77,23 @@ im_module_list (const GtkIMContextInfo ***contexts,
|
|
*n_contexts = G_N_ELEMENTS (info_list);
|
|
}
|
|
|
|
+G_MODULE_EXPORT const char *
|
|
+im_get_context_id (int *argc,
|
|
+ char ***argv)
|
|
+{
|
|
+ GtkIMContext *context;
|
|
+ char *preedit_string = NULL;
|
|
+ PangoAttrList *preedit_attrs = NULL;
|
|
+ const char *context_id;
|
|
+
|
|
+ gtk_init (argc, argv);
|
|
+ context = gtk_im_multicontext_new ();
|
|
+ gtk_im_context_get_preedit_string (context,
|
|
+ &preedit_string,
|
|
+ &preedit_attrs,
|
|
+ 0);
|
|
+ context_id = gtk_im_multicontext_get_context_id (
|
|
+ GTK_IM_MULTICONTEXT (context));
|
|
+ return context_id;
|
|
+}
|
|
+
|
|
diff --git a/client/gtk4/ibusim.c b/client/gtk4/ibusim.c
|
|
index 5ecf9778..562bdf2d 100644
|
|
--- a/client/gtk4/ibusim.c
|
|
+++ b/client/gtk4/ibusim.c
|
|
@@ -50,3 +50,23 @@ g_io_im_ibus_unload (GTypeModule *type_module)
|
|
g_type_module_unuse (type_module);
|
|
}
|
|
|
|
+G_MODULE_EXPORT const char *
|
|
+im_get_context_id (int *argc,
|
|
+ char ***argv)
|
|
+{
|
|
+ GtkIMContext *context;
|
|
+ char *preedit_string = NULL;
|
|
+ PangoAttrList *preedit_attrs = NULL;
|
|
+ const char *context_id;
|
|
+
|
|
+ gtk_init ();
|
|
+ context = gtk_im_multicontext_new ();
|
|
+ gtk_im_context_get_preedit_string (context,
|
|
+ &preedit_string,
|
|
+ &preedit_attrs,
|
|
+ 0);
|
|
+ context_id = gtk_im_multicontext_get_context_id (
|
|
+ GTK_IM_MULTICONTEXT (context));
|
|
+ return context_id;
|
|
+}
|
|
+
|
|
diff --git a/tools/IBusIMModule-1.0.metadata b/tools/IBusIMModule-1.0.metadata
|
|
new file mode 100644
|
|
index 00000000..14adc9ee
|
|
--- /dev/null
|
|
+++ b/tools/IBusIMModule-1.0.metadata
|
|
@@ -0,0 +1 @@
|
|
+IBusIMModule cheader_filename="ibusimmodule.h" name="IBusIMModule"
|
|
diff --git a/tools/Makefile.am b/tools/Makefile.am
|
|
index e380a9aa..a9262ee0 100644
|
|
--- a/tools/Makefile.am
|
|
+++ b/tools/Makefile.am
|
|
@@ -24,9 +24,19 @@
|
|
NULL =
|
|
|
|
libibus = $(top_builddir)/src/libibus-@IBUS_API_VERSION@.la
|
|
+libibusimmodule = libibusimmodule.la
|
|
+ibusimmodule_gir = IBusIMModule-1.0.gir
|
|
+ibus_immodule_vapi = ibus-immodule-1.0.vapi
|
|
libibus_emoji_dialog = \
|
|
$(top_builddir)/ui/gtk3/libibus-emoji-dialog-@IBUS_API_VERSION@.la
|
|
|
|
+noinst_LTLIBRARIES = $(libibusimmodule)
|
|
+noinst_DATA =
|
|
+INTROSPECTION_GIRS =
|
|
+MAINTAINERCLEANFILES =
|
|
+DISTCLEANFILES =
|
|
+VAPIGEN_VAPIS =
|
|
+
|
|
# force include config.h before gi18n.h.
|
|
AM_CPPFLAGS = \
|
|
-I$(top_srcdir)/src \
|
|
@@ -47,22 +57,26 @@ AM_CFLAGS = \
|
|
$(NULL)
|
|
|
|
AM_LDADD = \
|
|
- @GOBJECT2_LIBS@ \
|
|
- @GLIB2_LIBS@ \
|
|
- @GIO2_LIBS@ \
|
|
- @GTHREAD2_LIBS@ \
|
|
- $(libibus) \
|
|
- $(NULL)
|
|
+ @GOBJECT2_LIBS@ \
|
|
+ @GLIB2_LIBS@ \
|
|
+ @GIO2_LIBS@ \
|
|
+ @GTHREAD2_LIBS@ \
|
|
+ $(libibus) \
|
|
+ $(libibusimmodule) \
|
|
+ $(NULL)
|
|
|
|
AM_VALAFLAGS = \
|
|
- --vapidir=$(top_builddir)/bindings/vala \
|
|
- --vapidir=$(top_srcdir)/bindings/vala \
|
|
- --pkg=gio-2.0 \
|
|
- --pkg=ibus-1.0 \
|
|
- --pkg=posix \
|
|
- --pkg=config \
|
|
- --target-glib="$(VALA_TARGET_GLIB_VERSION)" \
|
|
- $(NULL)
|
|
+ --vapidir=$(top_builddir)/bindings/vala \
|
|
+ --vapidir=$(top_srcdir)/bindings/vala \
|
|
+ --vapidir=$(builddir) \
|
|
+ --vapidir=$(srcdir) \
|
|
+ --pkg=gio-2.0 \
|
|
+ --pkg=ibus-1.0 \
|
|
+ --pkg=ibus-immodule-1.0 \
|
|
+ --pkg=posix \
|
|
+ --pkg=config \
|
|
+ --target-glib="$(VALA_TARGET_GLIB_VERSION)" \
|
|
+ $(NULL)
|
|
|
|
bin_PROGRAMS = ibus
|
|
|
|
@@ -79,9 +93,27 @@ bash_completion_DATA= \
|
|
$(NULL)
|
|
bash_completiondir=@datadir@/bash-completion/completions
|
|
|
|
+libibusimmodule_la_SOURCES = \
|
|
+ ibusimmodule.c \
|
|
+ ibusimmodule.h \
|
|
+ $(NULL)
|
|
+libibusimmodule_la_CFLAGS = \
|
|
+ @GLIB2_CFLAGS@ \
|
|
+ -DGTK2_IM_MODULEDIR=\"$(GTK2_IM_MODULEDIR)\" \
|
|
+ -DGTK3_IM_MODULEDIR=\"$(GTK3_IM_MODULEDIR)\" \
|
|
+ -DGTK4_IM_MODULEDIR=\"$(GTK4_IM_MODULEDIR)\" \
|
|
+ $(NULL)
|
|
+libibusimmodule_la_LIBADD = \
|
|
+ @GLIB2_LIBS@ \
|
|
+ $(NULL)
|
|
+libibusimmodule_la_LDFLAGS = \
|
|
+ -no-undefined \
|
|
+ -export-symbols-regex "ibus_.*" \
|
|
+ $(NULL)
|
|
+
|
|
man_one_in_files = ibus.1.in
|
|
man_one_files = $(man_one_in_files:.1.in=.1)
|
|
-man_one_DATA =$(man_one_files:.1=.1.gz)
|
|
+man_one_DATA =$(man_one_files:.1=.1.gz)
|
|
man_onedir = $(mandir)/man1
|
|
%.1: %.1.in
|
|
$(AM_V_GEN) sed \
|
|
@@ -91,14 +123,17 @@ man_onedir = $(mandir)/man1
|
|
$(AM_V_GEN) gzip -c $< > $@.tmp && mv $@.tmp $@
|
|
|
|
EXTRA_DIST = \
|
|
- $(man_one_in_files) \
|
|
- ibus.bash \
|
|
- $(NULL)
|
|
+ $(ibus_immodule_vapi) \
|
|
+ $(ibusimmodule_gir) \
|
|
+ $(man_one_in_files) \
|
|
+ ibus.bash \
|
|
+ IBusIMModule-1.0.metadata \
|
|
+ $(NULL)
|
|
|
|
CLEANFILES = \
|
|
- $(man_one_DATA) \
|
|
- $(man_one_files) \
|
|
- $(NULL)
|
|
+ $(man_one_DATA) \
|
|
+ $(man_one_files) \
|
|
+ $(NULL)
|
|
|
|
if ENABLE_EMOJI_DICT
|
|
if ENABLE_UI
|
|
@@ -108,4 +143,43 @@ AM_VALAFLAGS += \
|
|
endif
|
|
endif
|
|
|
|
+if HAVE_INTROSPECTION
|
|
+BUILT_SOURCES = $(INTROSPECTION_GIRS) $(VAPIGEN_VAPIS)
|
|
+
|
|
+-include $(INTROSPECTION_MAKEFILE)
|
|
+INTROSPECTION_SCANNER_ARGS =
|
|
+INTROSPECTION_COMPILER_ARGS = \
|
|
+ --includedir=$(srcdir) \
|
|
+ --includedir=. \
|
|
+ $(NULL)
|
|
+
|
|
+IBusIMModule-1.0.gir: $(libibusimmodule) Makefile
|
|
+IBusIMModule_1_0_gir_SCANNERFLAGS = \
|
|
+ --pkg=glib-2.0 \
|
|
+ $(IBUS_GIR_SCANNERFLAGS) \
|
|
+ $(NULL)
|
|
+IBusIMModule_1_0_gir_INCLUDES = GLib-2.0
|
|
+IBusIMModule_1_0_gir_LIBS = $(libibusimmodule)
|
|
+IBusIMModule_1_0_gir_FILES = ibusimmodule.h
|
|
+IBusIMModule_1_0_gir_CFLAGS = \
|
|
+ -I$(srcdir) \
|
|
+ -I$(builddir) \
|
|
+ $(NULL)
|
|
+
|
|
+INTROSPECTION_GIRS += $(ibusimmodule_gir)
|
|
+noinst_DATA += $(ibusimmodule_gir)
|
|
+MAINTAINERCLEANFILES += $(ibusimmodule_gir)
|
|
+DISTCLEANFILES += $(ibusimmodule_gir)
|
|
+
|
|
+-include $(VAPIGEN_MAKEFILE)
|
|
+ibus-immodule-1.0.vapi: $(ibusimmodule_gir) IBusIMModule-1.0.metadata
|
|
+ibus_immodule_1_0_vapi_DEPS = glib-2.0
|
|
+ibus_immodule_1_0_vapi_METADATADIRS = $(srcdir)
|
|
+ibus_immodule_1_0_vapi_FILES = IBusIMModule-1.0.gir
|
|
+VAPIGEN_VAPIS += $(ibus_immodule_vapi)
|
|
+noinst_DATA += $(ibus_immodule_vapi)
|
|
+MAINTAINERCLEANFILES += $(ibus_immodule_vapi)
|
|
+DISTCLEANFILES += $(ibus_immodule_vapi)
|
|
+endif
|
|
+
|
|
-include $(top_srcdir)/git.mk
|
|
diff --git a/tools/ibus.1.in b/tools/ibus.1.in
|
|
index fe1b7157..84ef5fff 100644
|
|
--- a/tools/ibus.1.in
|
|
+++ b/tools/ibus.1.in
|
|
@@ -128,6 +128,16 @@ option enables to match annotations with a partial string. These settings
|
|
are available with
|
|
.B ibus\-setup (1)
|
|
utility.
|
|
+.TP
|
|
+\fBim-module\fR [\fB\-\-type=TYPE|\-\-help\fR]
|
|
+Show an internal im-module value in a virtual GTK application. If IBus is
|
|
+installed and configured properly, the output is "ibus". This sub-command
|
|
+is useful for some users who build IBus from the source codes and check
|
|
+the configurations. Currently the sub-command supports GTK applications only
|
|
+and the default is GTK3. If you wish to check a GTK4 application, you can
|
|
+specify
|
|
+.B \-\-type=gtk4
|
|
+option and you can choose one of "gtk2", "gtk3" and "gtk4".
|
|
|
|
.SH BUGS
|
|
If you find a bug, please report it at https://github.com/ibus/ibus/issues
|
|
diff --git a/tools/ibusimmodule.c b/tools/ibusimmodule.c
|
|
new file mode 100644
|
|
index 00000000..20ccc748
|
|
--- /dev/null
|
|
+++ b/tools/ibusimmodule.c
|
|
@@ -0,0 +1,87 @@
|
|
+#include <glib.h>
|
|
+#include <glib/gi18n-lib.h>
|
|
+#include <dlfcn.h>
|
|
+
|
|
+#ifndef DEFAULT_IM_MODULE_TYPE
|
|
+#define DEFAULT_IM_MODULE_TYPE "gtk3"
|
|
+#endif
|
|
+
|
|
+#define OPTION_TYPE_MESSAGE \
|
|
+ N_("Type im-module TYPE = \"gtk2\", \"gtk3\", \"gtk4\". Default is " \
|
|
+ "\"gtk3\".")
|
|
+
|
|
+typedef const char * (* IBusIMGetContextIdFunc) (int *argc, char ***argv);
|
|
+
|
|
+static char *im_module_type;
|
|
+
|
|
+
|
|
+char *
|
|
+ibus_im_module_get_id (int argc, char *argv[])
|
|
+{
|
|
+ static const GOptionEntry options[3] = {
|
|
+ { "type", (char)0, (int)0, G_OPTION_ARG_STRING, &im_module_type,
|
|
+ OPTION_TYPE_MESSAGE,
|
|
+ "TYPE"},
|
|
+ { NULL }
|
|
+ };
|
|
+ GOptionContext *option;
|
|
+ GError *error = NULL;
|
|
+ void *module;
|
|
+ char *im_context_id;
|
|
+ IBusIMGetContextIdFunc im_get_context_id;
|
|
+
|
|
+ if (!(option = g_option_context_new (NULL))) {
|
|
+ g_critical ("malloc GOptionContext is failed.");
|
|
+ return NULL;
|
|
+ }
|
|
+ g_option_context_add_main_entries (option, options, GETTEXT_PACKAGE);
|
|
+ g_option_context_parse (option, &argc, &argv, &error);
|
|
+ if (error) {
|
|
+ g_critical ("%s", error->message);
|
|
+ g_clear_error (&error);
|
|
+ return NULL;
|
|
+ }
|
|
+ g_option_context_free (option);
|
|
+ if (!im_module_type)
|
|
+ im_module_type = g_strdup (DEFAULT_IM_MODULE_TYPE);
|
|
+
|
|
+ if (G_LIKELY (!g_strcmp0 (im_module_type, "gtk3"))) {
|
|
+ module = dlopen (GTK3_IM_MODULEDIR "/im-ibus.so",
|
|
+ RTLD_LAZY);
|
|
+ } else if (!g_strcmp0 (im_module_type, "gtk4")) {
|
|
+ const char *module_path_env = g_getenv ("GTK_PATH");
|
|
+ char *module_path;
|
|
+ if (module_path_env) {
|
|
+ module_path = g_build_filename (module_path_env,
|
|
+ GTK4_IM_MODULEDIR "/libim-ibus.so",
|
|
+ NULL);
|
|
+ } else {
|
|
+ module_path = g_strdup (GTK4_IM_MODULEDIR "/libim-ibus.so");
|
|
+ }
|
|
+ module = dlopen (module_path, RTLD_LAZY);
|
|
+ g_free (module_path);
|
|
+ } else if (!g_strcmp0 (im_module_type, "gtk2")) {
|
|
+ module = dlopen (GTK2_IM_MODULEDIR "/im-ibus.so",
|
|
+ RTLD_LAZY);
|
|
+ } else {
|
|
+ module = dlopen (im_module_type, RTLD_LAZY);
|
|
+ }
|
|
+ if (!module) {
|
|
+ g_warning ("Not found module: %s", dlerror ());
|
|
+ return NULL;
|
|
+ }
|
|
+
|
|
+ im_get_context_id = dlsym (module, "im_get_context_id");
|
|
+ if (!im_get_context_id) {
|
|
+ g_warning ("Not found im_get_context_id: %s", dlerror ());
|
|
+ dlclose (module);
|
|
+ return NULL;
|
|
+ }
|
|
+
|
|
+ im_context_id = strdup (im_get_context_id (&argc, &argv));
|
|
+ dlclose (module);
|
|
+ return im_context_id;
|
|
+}
|
|
+
|
|
+#undef DEFAULT_IM_MODULE_TYPE
|
|
+
|
|
diff --git a/tools/ibusimmodule.h b/tools/ibusimmodule.h
|
|
new file mode 100644
|
|
index 00000000..e762a747
|
|
--- /dev/null
|
|
+++ b/tools/ibusimmodule.h
|
|
@@ -0,0 +1,36 @@
|
|
+/* -*- mode: C; c-basic-offset: 4; indent-tabs-mode: nil; -*- */
|
|
+/* vim:set et sts=4: */
|
|
+/* ibus - The Input Bus
|
|
+ * Copyright (C) 2022 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
|
|
+ * License as published by the Free Software Foundation; either
|
|
+ * version 2.1 of the License, or (at your option) any later version.
|
|
+ *
|
|
+ * This library is distributed in the hope that it will be useful,
|
|
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
+ * Lesser General Public License for more details.
|
|
+ *
|
|
+ * You should have received a copy of the GNU Lesser General Public
|
|
+ * License along with this library; if not, write to the Free Software
|
|
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
|
|
+ * USA
|
|
+ */
|
|
+
|
|
+#ifndef __IBUS_IM_MODULE_CONTEXT_H_
|
|
+#define __IBUS_IM_MODULE_CONTEXT_H_
|
|
+
|
|
+/**
|
|
+ * ibus_im_module_get_id:
|
|
+ * @argc: The length of argv
|
|
+ * @argv: (array length=argc) (element-type utf8): argv from main()
|
|
+ *
|
|
+ * Retrieve im-module value from GTK instance.
|
|
+ *
|
|
+ * Returns: (nullable): im-module value.
|
|
+ */
|
|
+char * ibus_im_module_get_id (int argc, char *argv[]);
|
|
+
|
|
+#endif
|
|
diff --git a/tools/main.vala b/tools/main.vala
|
|
index 407eaf74..1fed2440 100644
|
|
--- a/tools/main.vala
|
|
+++ b/tools/main.vala
|
|
@@ -671,6 +671,15 @@ int emoji_dialog(string[] argv) {
|
|
#endif
|
|
|
|
|
|
+int read_im_module(string[] argv) {
|
|
+ string? im_module = IBusIMModule.im_module_get_id(argv);
|
|
+ if (im_module == null)
|
|
+ return Posix.EXIT_FAILURE;
|
|
+ print("%s\n".printf(im_module));
|
|
+ return Posix.EXIT_SUCCESS;
|
|
+}
|
|
+
|
|
+
|
|
int print_help(string[] argv) {
|
|
print_usage(stdout);
|
|
return Posix.EXIT_SUCCESS;
|
|
@@ -702,6 +711,8 @@ const CommandEntry commands[] = {
|
|
#if EMOJI_DICT
|
|
{ "emoji", N_("Save emoji on dialog to clipboard"), emoji_dialog },
|
|
#endif
|
|
+ { "im-module", N_("Retrieve im-module value from GTK instance"),
|
|
+ read_im_module },
|
|
{ "help", N_("Show this information"), print_help }
|
|
};
|
|
|
|
--
|
|
2.35.3
|
|
|
|
From 7e42b437c901bb56ca2f776aad5fe65d0d8c246a Mon Sep 17 00:00:00 2001
|
|
From: fujiwarat <takao.fujiwara1@gmail.com>
|
|
Date: Thu, 7 Jul 2022 08:22:42 +0900
|
|
Subject: [PATCH] client/gtk2: Implement new process_key_event for GTK4
|
|
|
|
---
|
|
client/gtk2/ibusimcontext.c | 147 ++++++++++++++++++++++++++++++------
|
|
src/ibustypes.h | 4 +
|
|
2 files changed, 127 insertions(+), 24 deletions(-)
|
|
|
|
diff --git a/client/gtk2/ibusimcontext.c b/client/gtk2/ibusimcontext.c
|
|
index c7f23293..bc14df00 100644
|
|
--- a/client/gtk2/ibusimcontext.c
|
|
+++ b/client/gtk2/ibusimcontext.c
|
|
@@ -111,13 +111,13 @@ static guint _signal_delete_surrounding_id = 0;
|
|
static guint _signal_retrieve_surrounding_id = 0;
|
|
|
|
#if GTK_CHECK_VERSION (3, 98, 4)
|
|
-static gboolean _use_sync_mode = TRUE;
|
|
+static char _use_sync_mode = 2;
|
|
#else
|
|
static const gchar *_no_snooper_apps = NO_SNOOPER_APPS;
|
|
static gboolean _use_key_snooper = ENABLE_SNOOPER;
|
|
static guint _key_snooper_id = 0;
|
|
|
|
-static gboolean _use_sync_mode = FALSE;
|
|
+static char _use_sync_mode = 0;
|
|
#endif
|
|
|
|
static const gchar *_discard_password_apps = "";
|
|
@@ -375,12 +375,15 @@ ibus_im_context_commit_event (IBusIMContext *ibusimcontext,
|
|
return FALSE;
|
|
}
|
|
|
|
-struct _ProcessKeyEventData {
|
|
+typedef struct {
|
|
GdkEvent *event;
|
|
IBusIMContext *ibusimcontext;
|
|
-};
|
|
+} ProcessKeyEventData;
|
|
|
|
-typedef struct _ProcessKeyEventData ProcessKeyEventData;
|
|
+typedef struct {
|
|
+ GMainLoop *loop;
|
|
+ gboolean retval;
|
|
+} ProcessKeyEventReplyData;
|
|
|
|
static void
|
|
_process_key_event_done (GObject *object,
|
|
@@ -395,12 +398,12 @@ _process_key_event_done (GObject *object,
|
|
IBusIMContext *ibusimcontext = data->ibusimcontext;
|
|
#endif
|
|
GError *error = NULL;
|
|
+ gboolean retval;
|
|
|
|
g_slice_free (ProcessKeyEventData, data);
|
|
- gboolean retval = ibus_input_context_process_key_event_async_finish (
|
|
- context,
|
|
- res,
|
|
- &error);
|
|
+ retval = ibus_input_context_process_key_event_async_finish (context,
|
|
+ res,
|
|
+ &error);
|
|
|
|
if (error != NULL) {
|
|
g_warning ("Process Key Event failed: %s.", error->message);
|
|
@@ -431,6 +434,27 @@ _process_key_event_done (GObject *object,
|
|
#endif
|
|
}
|
|
|
|
+static void
|
|
+_process_key_event_reply_done (GObject *object,
|
|
+ GAsyncResult *res,
|
|
+ gpointer user_data)
|
|
+{
|
|
+ IBusInputContext *context = (IBusInputContext *)object;
|
|
+ ProcessKeyEventReplyData *data = (ProcessKeyEventReplyData *)user_data;
|
|
+ GError *error = NULL;
|
|
+ gboolean retval = ibus_input_context_process_key_event_async_finish (
|
|
+ context,
|
|
+ res,
|
|
+ &error);
|
|
+ if (error != NULL) {
|
|
+ g_warning ("Process Key Event failed: %s.", error->message);
|
|
+ g_error_free (error);
|
|
+ }
|
|
+ g_return_if_fail (data);
|
|
+ data->retval = retval;
|
|
+ g_main_loop_quit (data->loop);
|
|
+}
|
|
+
|
|
static gboolean
|
|
_process_key_event (IBusInputContext *context,
|
|
#if GTK_CHECK_VERSION (3, 98, 4)
|
|
@@ -462,13 +486,45 @@ _process_key_event (IBusInputContext *context,
|
|
#endif
|
|
keycode = hardware_keycode;
|
|
|
|
- if (_use_sync_mode) {
|
|
+ switch (_use_sync_mode) {
|
|
+ case 1: {
|
|
retval = ibus_input_context_process_key_event (context,
|
|
+ keyval,
|
|
+ keycode - 8,
|
|
+ state);
|
|
+ break;
|
|
+ }
|
|
+ case 2: {
|
|
+ GMainLoop *loop = g_main_loop_new (NULL, TRUE);
|
|
+ ProcessKeyEventReplyData *data = NULL;
|
|
+
|
|
+ if (loop)
|
|
+ data = g_slice_new0 (ProcessKeyEventReplyData);
|
|
+ if (!data) {
|
|
+ g_warning ("Cannot wait for the reply of the process key event.");
|
|
+ retval = ibus_input_context_process_key_event (context,
|
|
+ keyval,
|
|
+ keycode - 8,
|
|
+ state);
|
|
+ if (loop)
|
|
+ g_main_loop_quit (loop);
|
|
+ break;
|
|
+ }
|
|
+ data->loop = loop;
|
|
+ ibus_input_context_process_key_event_async (context,
|
|
keyval,
|
|
keycode - 8,
|
|
- state);
|
|
+ state,
|
|
+ -1,
|
|
+ NULL,
|
|
+ _process_key_event_reply_done,
|
|
+ data);
|
|
+ g_main_loop_run (loop);
|
|
+ retval = data->retval;
|
|
+ g_slice_free (ProcessKeyEventReplyData, data);
|
|
+ break;
|
|
}
|
|
- else {
|
|
+ default: {
|
|
ProcessKeyEventData *data = g_slice_new0 (ProcessKeyEventData);
|
|
#if GTK_CHECK_VERSION (3, 98, 4)
|
|
data->event = gdk_event_ref (event);
|
|
@@ -487,6 +543,7 @@ _process_key_event (IBusInputContext *context,
|
|
|
|
retval = TRUE;
|
|
}
|
|
+ }
|
|
|
|
/* GTK4 does not provide gtk_key_snooper_install() and also
|
|
* GtkIMContextClass->filter_keypress() cannot send the updated
|
|
@@ -676,24 +733,47 @@ _key_snooper_cb (GtkWidget *widget,
|
|
#endif
|
|
|
|
static gboolean
|
|
-_get_boolean_env(const gchar *name,
|
|
- gboolean defval)
|
|
+_get_boolean_env (const gchar *name,
|
|
+ gboolean defval)
|
|
{
|
|
const gchar *value = g_getenv (name);
|
|
|
|
if (value == NULL)
|
|
- return defval;
|
|
+ return defval;
|
|
|
|
if (g_strcmp0 (value, "") == 0 ||
|
|
g_strcmp0 (value, "0") == 0 ||
|
|
g_strcmp0 (value, "false") == 0 ||
|
|
g_strcmp0 (value, "False") == 0 ||
|
|
- g_strcmp0 (value, "FALSE") == 0)
|
|
- return FALSE;
|
|
+ g_strcmp0 (value, "FALSE") == 0) {
|
|
+ return FALSE;
|
|
+ }
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
+static char
|
|
+_get_char_env (const gchar *name,
|
|
+ char defval)
|
|
+{
|
|
+ const gchar *value = g_getenv (name);
|
|
+
|
|
+ if (value == NULL)
|
|
+ return defval;
|
|
+
|
|
+ if (g_strcmp0 (value, "") == 0 ||
|
|
+ g_strcmp0 (value, "0") == 0 ||
|
|
+ g_strcmp0 (value, "false") == 0 ||
|
|
+ g_strcmp0 (value, "False") == 0 ||
|
|
+ g_strcmp0 (value, "FALSE") == 0) {
|
|
+ return 0;
|
|
+ } else if (!g_strcmp0 (value, "2")) {
|
|
+ return 2;
|
|
+ }
|
|
+
|
|
+ return 1;
|
|
+}
|
|
+
|
|
static void
|
|
daemon_name_appeared (GDBusConnection *connection,
|
|
const gchar *name,
|
|
@@ -777,11 +857,11 @@ ibus_im_context_class_init (IBusIMContextClass *class)
|
|
g_assert (_signal_retrieve_surrounding_id != 0);
|
|
|
|
#if GTK_CHECK_VERSION (3, 98, 4)
|
|
- _use_sync_mode = _get_boolean_env ("IBUS_ENABLE_SYNC_MODE", TRUE);
|
|
+ _use_sync_mode = _get_char_env ("IBUS_ENABLE_SYNC_MODE", 2);
|
|
#else
|
|
_use_key_snooper = !_get_boolean_env ("IBUS_DISABLE_SNOOPER",
|
|
!(ENABLE_SNOOPER));
|
|
- _use_sync_mode = _get_boolean_env ("IBUS_ENABLE_SYNC_MODE", FALSE);
|
|
+ _use_sync_mode = (char)_get_char_env ("IBUS_ENABLE_SYNC_MODE", 0);
|
|
#endif
|
|
_use_discard_password = _get_boolean_env ("IBUS_DISCARD_PASSWORD", FALSE);
|
|
|
|
@@ -904,6 +984,8 @@ ibus_im_context_init (GObject *obj)
|
|
#else
|
|
ibusimcontext->caps = IBUS_CAP_PREEDIT_TEXT | IBUS_CAP_FOCUS;
|
|
#endif
|
|
+ if (_use_sync_mode != 1)
|
|
+ ibusimcontext->caps |= IBUS_CAP_SYNC_PROCESS_KEY;
|
|
|
|
ibusimcontext->events_queue = g_queue_new ();
|
|
|
|
@@ -1246,7 +1328,7 @@ ibus_im_context_reset (GtkIMContext *context)
|
|
* IBus uses button-press-event instead until GTK is fixed.
|
|
* https://gitlab.gnome.org/GNOME/gtk/issues/1534
|
|
*/
|
|
- if (_use_sync_mode)
|
|
+ if (_use_sync_mode == 1)
|
|
ibus_im_context_clear_preedit_text (ibusimcontext);
|
|
ibus_input_context_reset (ibusimcontext->ibuscontext);
|
|
}
|
|
@@ -1361,7 +1443,7 @@ ibus_im_context_set_client_window (GtkIMContext *context,
|
|
|
|
if (ibusimcontext->client_window) {
|
|
#if !GTK_CHECK_VERSION (3, 98, 4)
|
|
- if (ibusimcontext->use_button_press_event && !_use_sync_mode)
|
|
+ if (ibusimcontext->use_button_press_event && _use_sync_mode != 1)
|
|
_connect_button_press_event (ibusimcontext, FALSE);
|
|
#endif
|
|
g_object_unref (ibusimcontext->client_window);
|
|
@@ -1371,7 +1453,7 @@ ibus_im_context_set_client_window (GtkIMContext *context,
|
|
if (client != NULL) {
|
|
ibusimcontext->client_window = g_object_ref (client);
|
|
#if !GTK_CHECK_VERSION (3, 98, 4)
|
|
- if (!ibusimcontext->use_button_press_event && !_use_sync_mode)
|
|
+ if (!ibusimcontext->use_button_press_event && _use_sync_mode != 1)
|
|
_connect_button_press_event (ibusimcontext, TRUE);
|
|
#endif
|
|
}
|
|
@@ -1993,7 +2075,7 @@ _ibus_context_update_preedit_text_cb (IBusInputContext *ibuscontext,
|
|
#if !GTK_CHECK_VERSION (3, 98, 4)
|
|
if (!ibusimcontext->use_button_press_event &&
|
|
mode == IBUS_ENGINE_PREEDIT_COMMIT &&
|
|
- !_use_sync_mode) {
|
|
+ _use_sync_mode != 1) {
|
|
if (ibusimcontext->client_window) {
|
|
_connect_button_press_event (ibusimcontext, TRUE);
|
|
}
|
|
@@ -2200,6 +2282,8 @@ _create_input_context_done (IBusBus *bus,
|
|
static void
|
|
_create_input_context (IBusIMContext *ibusimcontext)
|
|
{
|
|
+ gchar *prgname = g_strdup (g_get_prgname());
|
|
+ gchar *client_name;
|
|
IDEBUG ("%s", __FUNCTION__);
|
|
|
|
g_assert (ibusimcontext->ibuscontext == NULL);
|
|
@@ -2208,11 +2292,24 @@ _create_input_context (IBusIMContext *ibusimcontext)
|
|
|
|
ibusimcontext->cancellable = g_cancellable_new ();
|
|
|
|
+ if (!prgname)
|
|
+ prgname = g_strdup_printf ("(%d)", getpid ());
|
|
+ client_name = g_strdup_printf ("%s:%s",
|
|
+#if GTK_CHECK_VERSION (3, 98, 4)
|
|
+ "gtk4-im",
|
|
+#elif GTK_CHECK_VERSION (2, 91, 0)
|
|
+ "gtk3-im",
|
|
+#else
|
|
+ "gtk-im",
|
|
+#endif
|
|
+ prgname);
|
|
+ g_free (prgname);
|
|
ibus_bus_create_input_context_async (_bus,
|
|
- "gtk-im", -1,
|
|
+ client_name, -1,
|
|
ibusimcontext->cancellable,
|
|
(GAsyncReadyCallback)_create_input_context_done,
|
|
g_object_ref (ibusimcontext));
|
|
+ g_free (client_name);
|
|
}
|
|
|
|
/* Callback functions for slave context */
|
|
@@ -2329,6 +2426,8 @@ _create_fake_input_context_done (IBusBus *bus,
|
|
NULL);
|
|
|
|
guint32 caps = IBUS_CAP_PREEDIT_TEXT | IBUS_CAP_FOCUS | IBUS_CAP_SURROUNDING_TEXT;
|
|
+ if (_use_sync_mode != 1)
|
|
+ caps |= IBUS_CAP_SYNC_PROCESS_KEY;
|
|
ibus_input_context_set_capabilities (_fake_context, caps);
|
|
|
|
/* focus in/out the fake context */
|
|
diff --git a/src/ibustypes.h b/src/ibustypes.h
|
|
index 60bcb92b..a8eee319 100644
|
|
--- a/src/ibustypes.h
|
|
+++ b/src/ibustypes.h
|
|
@@ -109,6 +109,9 @@ typedef enum
|
|
* @IBUS_CAP_SURROUNDING_TEXT: Client can provide surround text,
|
|
* or IME can handle surround text.
|
|
* @IBUS_CAP_OSK: UI is owned by on-screen keyboard.
|
|
+ * @IBUS_CAP_SYNC_PROCESS_KEY: Asynchronous process key events are not
|
|
+ * supported and the ibus_engine_forward_key_event() should not be
|
|
+ * used for the return value of #IBusEngine::process_key_event().
|
|
*
|
|
* Capability flags of UI.
|
|
*/
|
|
@@ -120,6 +123,7 @@ typedef enum {
|
|
IBUS_CAP_PROPERTY = 1 << 4,
|
|
IBUS_CAP_SURROUNDING_TEXT = 1 << 5,
|
|
IBUS_CAP_OSK = 1 << 6,
|
|
+ IBUS_CAP_SYNC_PROCESS_KEY = 1 << 7,
|
|
} IBusCapabilite;
|
|
|
|
/**
|
|
--
|
|
2.35.3
|
|
|
|
From b14cab3753c6510a0a48eec673aa6eac89c793a1 Mon Sep 17 00:00:00 2001
|
|
From: fujiwarat <takao.fujiwara1@gmail.com>
|
|
Date: Thu, 7 Jul 2022 08:22:45 +0900
|
|
Subject: [PATCH] src/ibusengine: Add focus_in_id()/focus_out_id() class
|
|
methods
|
|
|
|
IBusEngine constructor now has a 'has-focus-id' property and if it's %TRUE,
|
|
IBusEngine::focus_in_id()/focus_out_id() are called instaed of
|
|
IBusEngine::focus_in()/focus_out() and the class method has an object_path
|
|
argument for the unique input context ID and a client argument for
|
|
the client application type likes ibus-gtk, ibus-gtk4, xim.
|
|
---
|
|
bus/engineproxy.c | 304 +++++++++++++++++++++++++++++-----------
|
|
bus/engineproxy.h | 12 +-
|
|
bus/ibusimpl.c | 13 ++
|
|
bus/ibusimpl.h | 13 +-
|
|
bus/inputcontext.c | 50 +++++--
|
|
src/ibusengine.c | 217 ++++++++++++++++++++++++++--
|
|
src/ibusengine.h | 10 +-
|
|
src/ibusmarshalers.list | 1 +
|
|
8 files changed, 505 insertions(+), 115 deletions(-)
|
|
|
|
diff --git a/bus/engineproxy.c b/bus/engineproxy.c
|
|
index 2d98995c..fd1f34fb 100644
|
|
--- a/bus/engineproxy.c
|
|
+++ b/bus/engineproxy.c
|
|
@@ -2,7 +2,7 @@
|
|
/* vim:set et sts=4: */
|
|
/* ibus - The Input Bus
|
|
* Copyright (C) 2008-2013 Peng Huang <shawn.p.huang@gmail.com>
|
|
- * Copyright (C) 2015-2018 Takao Fujiwara <takao.fujiwara1@gmail.com>
|
|
+ * Copyright (C) 2015-2022 Takao Fujiwara <takao.fujiwara1@gmail.com>
|
|
* Copyright (C) 2008-2016 Red Hat, Inc.
|
|
*
|
|
* This library is free software; you can redistribute it and/or
|
|
@@ -59,6 +59,7 @@ struct _BusEngineProxy {
|
|
|
|
/* cached properties */
|
|
IBusPropList *prop_list;
|
|
+ gboolean has_focus_id;
|
|
};
|
|
|
|
struct _BusEngineProxyClass {
|
|
@@ -105,30 +106,35 @@ static IBusText *text_empty = NULL;
|
|
static IBusPropList *prop_list_empty = NULL;
|
|
|
|
/* functions prototype */
|
|
-static void bus_engine_proxy_set_property (BusEngineProxy *engine,
|
|
- guint prop_id,
|
|
- const GValue *value,
|
|
- GParamSpec *pspec);
|
|
-static void bus_engine_proxy_get_property (BusEngineProxy *engine,
|
|
- guint prop_id,
|
|
- GValue *value,
|
|
- GParamSpec *pspec);
|
|
+static void bus_engine_proxy_set_property (BusEngineProxy *engine,
|
|
+ guint prop_id,
|
|
+ const GValue *value,
|
|
+ GParamSpec *pspec);
|
|
+static void bus_engine_proxy_get_property (BusEngineProxy *engine,
|
|
+ guint prop_id,
|
|
+ GValue *value,
|
|
+ GParamSpec *pspec);
|
|
static void bus_engine_proxy_real_register_properties
|
|
- (BusEngineProxy *engine,
|
|
- IBusPropList *prop_list);
|
|
+ (BusEngineProxy *engine,
|
|
+ IBusPropList *prop_list);
|
|
static void bus_engine_proxy_real_update_property
|
|
- (BusEngineProxy *engine,
|
|
- IBusProperty *prop);
|
|
-static void bus_engine_proxy_real_destroy (IBusProxy *proxy);
|
|
-static void bus_engine_proxy_g_signal (GDBusProxy *proxy,
|
|
- const gchar *sender_name,
|
|
- const gchar *signal_name,
|
|
- GVariant *parameters);
|
|
+ (BusEngineProxy *engine,
|
|
+ IBusProperty *prop);
|
|
+static void bus_engine_proxy_real_destroy (IBusProxy *proxy);
|
|
+static void bus_engine_proxy_g_signal (GDBusProxy *proxy,
|
|
+ const gchar *sender_name,
|
|
+ const gchar *signal_name,
|
|
+ GVariant *parameters);
|
|
static void bus_engine_proxy_initable_iface_init
|
|
- (GInitableIface *initable_iface);
|
|
+ (GInitableIface
|
|
+ *initable_iface);
|
|
+static void bus_engine_proxy_get_has_focus_id
|
|
+ (BusEngineProxy *engine);
|
|
|
|
G_DEFINE_TYPE_WITH_CODE (BusEngineProxy, bus_engine_proxy, IBUS_TYPE_PROXY,
|
|
- G_IMPLEMENT_INTERFACE (G_TYPE_INITABLE, bus_engine_proxy_initable_iface_init)
|
|
+ G_IMPLEMENT_INTERFACE (
|
|
+ G_TYPE_INITABLE,
|
|
+ bus_engine_proxy_initable_iface_init)
|
|
);
|
|
|
|
static GInitableIface *parent_initable_iface = NULL;
|
|
@@ -138,8 +144,10 @@ bus_engine_proxy_class_init (BusEngineProxyClass *class)
|
|
{
|
|
GObjectClass *gobject_class = G_OBJECT_CLASS (class);
|
|
|
|
- gobject_class->set_property = (GObjectSetPropertyFunc)bus_engine_proxy_set_property;
|
|
- gobject_class->get_property = (GObjectGetPropertyFunc)bus_engine_proxy_get_property;
|
|
+ gobject_class->set_property =
|
|
+ (GObjectSetPropertyFunc)bus_engine_proxy_set_property;
|
|
+ gobject_class->get_property =
|
|
+ (GObjectGetPropertyFunc)bus_engine_proxy_get_property;
|
|
|
|
class->register_properties = bus_engine_proxy_real_register_properties;
|
|
class->update_property = bus_engine_proxy_real_update_property;
|
|
@@ -147,8 +155,9 @@ bus_engine_proxy_class_init (BusEngineProxyClass *class)
|
|
IBUS_PROXY_CLASS (class)->destroy = bus_engine_proxy_real_destroy;
|
|
G_DBUS_PROXY_CLASS (class)->g_signal = bus_engine_proxy_g_signal;
|
|
|
|
- parent_initable_iface =
|
|
- (GInitableIface *)g_type_interface_peek (bus_engine_proxy_parent_class, G_TYPE_INITABLE);
|
|
+ parent_initable_iface = (GInitableIface *)g_type_interface_peek (
|
|
+ bus_engine_proxy_parent_class,
|
|
+ G_TYPE_INITABLE);
|
|
|
|
/* install properties */
|
|
g_object_class_install_property (gobject_class,
|
|
@@ -164,7 +173,9 @@ bus_engine_proxy_class_init (BusEngineProxyClass *class)
|
|
G_PARAM_STATIC_NICK
|
|
));
|
|
|
|
- /* install glib signals that will be sent when corresponding D-Bus signals are sent from an engine process. */
|
|
+ /* install glib signals that will be sent when corresponding D-Bus signals
|
|
+ * are sent from an engine process.
|
|
+ */
|
|
engine_signals[COMMIT_TEXT] =
|
|
g_signal_new (I_("commit-text"),
|
|
G_TYPE_FROM_CLASS (class),
|
|
@@ -473,7 +484,8 @@ bus_engine_proxy_real_destroy (IBusProxy *proxy)
|
|
engine->prop_list = NULL;
|
|
}
|
|
|
|
- IBUS_PROXY_CLASS (bus_engine_proxy_parent_class)->destroy ((IBusProxy *)engine);
|
|
+ IBUS_PROXY_CLASS (bus_engine_proxy_parent_class)->destroy (
|
|
+ (IBusProxy *)engine);
|
|
}
|
|
|
|
static void
|
|
@@ -486,7 +498,8 @@ _g_object_unref_if_floating (gpointer instance)
|
|
/**
|
|
* bus_engine_proxy_g_signal:
|
|
*
|
|
- * Handle all D-Bus signals from the engine process. This function emits corresponding glib signal for the D-Bus signal.
|
|
+ * Handle all D-Bus signals from the engine process. This function emits
|
|
+ * corresponding glib signal for the D-Bus signal.
|
|
*/
|
|
static void
|
|
bus_engine_proxy_g_signal (GDBusProxy *proxy,
|
|
@@ -522,7 +535,9 @@ bus_engine_proxy_g_signal (GDBusProxy *proxy,
|
|
}
|
|
}
|
|
|
|
- /* Handle D-Bus signals with parameters. Deserialize them and emit a glib signal. */
|
|
+ /* Handle D-Bus signals with parameters. Deserialize them and emit a glib
|
|
+ * signal.
|
|
+ */
|
|
if (g_strcmp0 (signal_name, "CommitText") == 0) {
|
|
GVariant *arg0 = NULL;
|
|
g_variant_get (parameters, "(v)", &arg0);
|
|
@@ -568,7 +583,8 @@ bus_engine_proxy_g_signal (GDBusProxy *proxy,
|
|
gboolean visible = FALSE;
|
|
guint mode = 0;
|
|
|
|
- g_variant_get (parameters, "(vubu)", &arg0, &cursor_pos, &visible, &mode);
|
|
+ g_variant_get (parameters, "(vubu)",
|
|
+ &arg0, &cursor_pos, &visible, &mode);
|
|
g_return_if_fail (arg0 != NULL);
|
|
|
|
IBusText *text = IBUS_TEXT (ibus_serializable_deserialize (arg0));
|
|
@@ -594,7 +610,11 @@ bus_engine_proxy_g_signal (GDBusProxy *proxy,
|
|
g_variant_unref (arg0);
|
|
g_return_if_fail (text != NULL);
|
|
|
|
- g_signal_emit (engine, engine_signals[UPDATE_AUXILIARY_TEXT], 0, text, visible);
|
|
+ g_signal_emit (engine,
|
|
+ engine_signals[UPDATE_AUXILIARY_TEXT],
|
|
+ 0,
|
|
+ text,
|
|
+ visible);
|
|
_g_object_unref_if_floating (text);
|
|
return;
|
|
}
|
|
@@ -606,11 +626,16 @@ bus_engine_proxy_g_signal (GDBusProxy *proxy,
|
|
g_variant_get (parameters, "(vb)", &arg0, &visible);
|
|
g_return_if_fail (arg0 != NULL);
|
|
|
|
- IBusLookupTable *table = IBUS_LOOKUP_TABLE (ibus_serializable_deserialize (arg0));
|
|
+ IBusLookupTable *table =
|
|
+ IBUS_LOOKUP_TABLE (ibus_serializable_deserialize (arg0));
|
|
g_variant_unref (arg0);
|
|
g_return_if_fail (table != NULL);
|
|
|
|
- g_signal_emit (engine, engine_signals[UPDATE_LOOKUP_TABLE], 0, table, visible);
|
|
+ g_signal_emit (engine,
|
|
+ engine_signals[UPDATE_LOOKUP_TABLE],
|
|
+ 0,
|
|
+ table,
|
|
+ visible);
|
|
_g_object_unref_if_floating (table);
|
|
return;
|
|
}
|
|
@@ -620,11 +645,15 @@ bus_engine_proxy_g_signal (GDBusProxy *proxy,
|
|
g_variant_get (parameters, "(v)", &arg0);
|
|
g_return_if_fail (arg0 != NULL);
|
|
|
|
- IBusPropList *prop_list = IBUS_PROP_LIST (ibus_serializable_deserialize (arg0));
|
|
+ IBusPropList *prop_list =
|
|
+ IBUS_PROP_LIST (ibus_serializable_deserialize (arg0));
|
|
g_variant_unref (arg0);
|
|
g_return_if_fail (prop_list != NULL);
|
|
|
|
- g_signal_emit (engine, engine_signals[REGISTER_PROPERTIES], 0, prop_list);
|
|
+ g_signal_emit (engine,
|
|
+ engine_signals[REGISTER_PROPERTIES],
|
|
+ 0,
|
|
+ prop_list);
|
|
_g_object_unref_if_floating (prop_list);
|
|
return;
|
|
}
|
|
@@ -634,7 +663,8 @@ bus_engine_proxy_g_signal (GDBusProxy *proxy,
|
|
g_variant_get (parameters, "(v)", &arg0);
|
|
g_return_if_fail (arg0 != NULL);
|
|
|
|
- IBusProperty *prop = IBUS_PROPERTY (ibus_serializable_deserialize (arg0));
|
|
+ IBusProperty *prop =
|
|
+ IBUS_PROPERTY (ibus_serializable_deserialize (arg0));
|
|
g_variant_unref (arg0);
|
|
g_return_if_fail (prop != NULL);
|
|
|
|
@@ -665,26 +695,45 @@ bus_engine_proxy_new_internal (const gchar *path,
|
|
IBusEngineDesc *desc,
|
|
GDBusConnection *connection)
|
|
{
|
|
+ GDBusProxyFlags flags;
|
|
+ BusEngineProxy *engine;
|
|
+ BusIBusImpl *ibus = BUS_DEFAULT_IBUS;
|
|
+ GHashTable *hash_table = NULL;
|
|
+ EngineFocusCategory category = ENGINE_FOCUS_CATEGORY_NONE;
|
|
+
|
|
g_assert (path);
|
|
g_assert (IBUS_IS_ENGINE_DESC (desc));
|
|
g_assert (G_IS_DBUS_CONNECTION (connection));
|
|
|
|
- GDBusProxyFlags flags = G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START;
|
|
- BusEngineProxy *engine =
|
|
- (BusEngineProxy *) g_initable_new (BUS_TYPE_ENGINE_PROXY,
|
|
- NULL,
|
|
- NULL,
|
|
- "desc", desc,
|
|
- "g-connection", connection,
|
|
- "g-interface-name", IBUS_INTERFACE_ENGINE,
|
|
- "g-object-path", path,
|
|
- "g-default-timeout", g_gdbus_timeout,
|
|
- "g-flags", flags,
|
|
- NULL);
|
|
+ flags = G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START;
|
|
+ engine = (BusEngineProxy *) g_initable_new (
|
|
+ BUS_TYPE_ENGINE_PROXY,
|
|
+ NULL,
|
|
+ NULL,
|
|
+ "desc", desc,
|
|
+ "g-connection", connection,
|
|
+ "g-interface-name", IBUS_INTERFACE_ENGINE,
|
|
+ "g-object-path", path,
|
|
+ "g-default-timeout", g_gdbus_timeout,
|
|
+ "g-flags", flags,
|
|
+ NULL);
|
|
const gchar *layout = ibus_engine_desc_get_layout (desc);
|
|
if (layout != NULL && layout[0] != '\0') {
|
|
engine->keymap = ibus_keymap_get (layout);
|
|
}
|
|
+ if (ibus)
|
|
+ hash_table = bus_ibus_impl_get_engine_focus_id_table (ibus);
|
|
+ if (hash_table) {
|
|
+ category = (EngineFocusCategory)GPOINTER_TO_INT (
|
|
+ g_hash_table_lookup (hash_table,
|
|
+ ibus_engine_desc_get_name (desc)));
|
|
+ if (category == ENGINE_FOCUS_CATEGORY_HAS_ID)
|
|
+ engine->has_focus_id = TRUE;
|
|
+ else if (category == ENGINE_FOCUS_CATEGORY_NO_ID)
|
|
+ engine->has_focus_id = FALSE;
|
|
+ else
|
|
+ bus_engine_proxy_get_has_focus_id (engine);
|
|
+ }
|
|
return engine;
|
|
}
|
|
|
|
@@ -740,7 +789,8 @@ engine_proxy_new_data_free (EngineProxyNewData *data)
|
|
/**
|
|
* create_engine_ready_cb:
|
|
*
|
|
- * A callback function to be called when bus_factory_proxy_create_engine finishes.
|
|
+ * A callback function to be called when bus_factory_proxy_create_engine
|
|
+ * finishes.
|
|
* Create an BusEngineProxy object and call the GAsyncReadyCallback.
|
|
*/
|
|
static void
|
|
@@ -775,8 +825,10 @@ create_engine_ready_cb (BusFactoryProxy *factory,
|
|
/**
|
|
* notify_factory_cb:
|
|
*
|
|
- * A callback function to be called when bus_component_start() emits "notify::factory" signal within 5 seconds.
|
|
- * Call bus_factory_proxy_create_engine to create the engine proxy asynchronously.
|
|
+ * A callback function to be called when bus_component_start() emits
|
|
+ * "notify::factory" signal within 5 seconds.
|
|
+ * Call bus_factory_proxy_create_engine to create the engine proxy
|
|
+ * asynchronously.
|
|
*/
|
|
static void
|
|
notify_factory_cb (BusComponent *component,
|
|
@@ -798,22 +850,25 @@ notify_factory_cb (BusComponent *component,
|
|
data->handler_id = 0;
|
|
}
|
|
|
|
- /* We *have to* disconnect the cancelled_cb here, since g_dbus_proxy_call
|
|
- * calls create_engine_ready_cb even if the proxy call is cancelled, and
|
|
- * in this case, create_engine_ready_cb itself will return error using
|
|
- * g_task_return_error(). */
|
|
+ /* We *have to* disconnect the cancelled_cb here, since
|
|
+ * g_dbus_proxy_call calls create_engine_ready_cb even if the proxy
|
|
+ * call is cancelled, and in this case, create_engine_ready_cb itself
|
|
+ * will return error using g_task_return_error().
|
|
+ */
|
|
if (data->cancellable && data->cancelled_handler_id != 0) {
|
|
- g_cancellable_disconnect (data->cancellable, data->cancelled_handler_id);
|
|
+ g_cancellable_disconnect (data->cancellable,
|
|
+ data->cancelled_handler_id);
|
|
data->cancelled_handler_id = 0;
|
|
}
|
|
|
|
/* Create engine from factory. */
|
|
- bus_factory_proxy_create_engine (data->factory,
|
|
- data->desc,
|
|
- data->timeout,
|
|
- data->cancellable,
|
|
- (GAsyncReadyCallback) create_engine_ready_cb,
|
|
- data);
|
|
+ bus_factory_proxy_create_engine (
|
|
+ data->factory,
|
|
+ data->desc,
|
|
+ data->timeout,
|
|
+ data->cancellable,
|
|
+ (GAsyncReadyCallback) create_engine_ready_cb,
|
|
+ data);
|
|
}
|
|
/* If factory is NULL, we will continue wait for
|
|
* factory notify signal or timeout */
|
|
@@ -822,7 +877,8 @@ notify_factory_cb (BusComponent *component,
|
|
/**
|
|
* timeout_cb:
|
|
*
|
|
- * A callback function to be called when bus_component_start() does not emit "notify::factory" signal within 5 seconds.
|
|
+ * A callback function to be called when bus_component_start() does not emit
|
|
+ * "notify::factory" signal within 5 seconds.
|
|
* Call the GAsyncReadyCallback and stop the 5 sec timer.
|
|
*/
|
|
static gboolean
|
|
@@ -927,16 +983,18 @@ bus_engine_proxy_new (IBusEngineDesc *desc,
|
|
/* The factory is ready. We'll create the engine proxy directly. */
|
|
g_object_ref (data->factory);
|
|
|
|
- /* We don't have to connect to cancelled_cb here, since g_dbus_proxy_call
|
|
- * calls create_engine_ready_cb even if the proxy call is cancelled, and
|
|
- * in this case, create_engine_ready_cb itself can return error using
|
|
- * g_task_return_error(). */
|
|
- bus_factory_proxy_create_engine (data->factory,
|
|
- data->desc,
|
|
- timeout,
|
|
- cancellable,
|
|
- (GAsyncReadyCallback) create_engine_ready_cb,
|
|
- data);
|
|
+ /* We don't have to connect to cancelled_cb here, since
|
|
+ * g_dbus_proxy_call calls create_engine_ready_cb even if the proxy
|
|
+ * call is cancelled, and in this case, create_engine_ready_cb itself
|
|
+ * can return error using g_task_return_error().
|
|
+ */
|
|
+ bus_factory_proxy_create_engine (
|
|
+ data->factory,
|
|
+ data->desc,
|
|
+ timeout,
|
|
+ cancellable,
|
|
+ (GAsyncReadyCallback) create_engine_ready_cb,
|
|
+ data);
|
|
}
|
|
}
|
|
|
|
@@ -978,8 +1036,11 @@ bus_engine_proxy_process_key_event (BusEngineProxy *engine,
|
|
{
|
|
g_assert (BUS_IS_ENGINE_PROXY (engine));
|
|
|
|
- if (keycode != 0 && bus_ibus_impl_is_use_sys_layout (BUS_DEFAULT_IBUS) == FALSE) {
|
|
- /* Since use_sys_layout is false, we don't rely on XKB. Try to convert keyval from keycode by using our own mapping. */
|
|
+ if (keycode != 0 &&
|
|
+ bus_ibus_impl_is_use_sys_layout (BUS_DEFAULT_IBUS) == FALSE) {
|
|
+ /* Since use_sys_layout is false, we don't rely on XKB. Try to convert
|
|
+ * keyval from keycode by using our own mapping.
|
|
+ */
|
|
IBusKeymap *keymap = engine->keymap;
|
|
if (keymap == NULL)
|
|
keymap = BUS_DEFAULT_KEYMAP;
|
|
@@ -1142,7 +1203,8 @@ void bus_engine_proxy_set_surrounding_text (BusEngineProxy *engine,
|
|
g_strcmp0 (text->text, engine->surrounding_text->text) != 0 ||
|
|
cursor_pos != engine->surrounding_cursor_pos ||
|
|
anchor_pos != engine->selection_anchor_pos) {
|
|
- GVariant *variant = ibus_serializable_serialize ((IBusSerializable *)text);
|
|
+ GVariant *variant =
|
|
+ ibus_serializable_serialize ((IBusSerializable *)text);
|
|
if (engine->surrounding_text)
|
|
g_object_unref (engine->surrounding_text);
|
|
engine->surrounding_text = (IBusText *) g_object_ref_sink (text);
|
|
@@ -1201,6 +1263,61 @@ bus_engine_proxy_set_content_type (BusEngineProxy *engine,
|
|
g_variant_unref (content_type);
|
|
}
|
|
|
|
+static void
|
|
+_get_has_focus_id_cb (GObject *object,
|
|
+ GAsyncResult *res,
|
|
+ gpointer user_data)
|
|
+{
|
|
+ GHashTable *hash_table = (GHashTable*)user_data;
|
|
+ BusEngineProxy *engine;
|
|
+ GError *error = NULL;
|
|
+ GVariant *result;
|
|
+
|
|
+ g_return_if_fail (BUS_IS_ENGINE_PROXY (object));
|
|
+ engine = BUS_ENGINE_PROXY (object);
|
|
+ result = g_dbus_proxy_call_finish (G_DBUS_PROXY (object), res, &error);
|
|
+
|
|
+ if (result != NULL) {
|
|
+ GVariant *variant = NULL;
|
|
+ gpointer value;
|
|
+ g_variant_get (result, "(v)", &variant);
|
|
+ engine->has_focus_id = g_variant_get_boolean (variant);
|
|
+ g_variant_unref (variant);
|
|
+ g_variant_unref (result);
|
|
+ value = GINT_TO_POINTER (engine->has_focus_id
|
|
+ ? ENGINE_FOCUS_CATEGORY_HAS_ID
|
|
+ : ENGINE_FOCUS_CATEGORY_NO_ID);
|
|
+ g_hash_table_replace (
|
|
+ hash_table,
|
|
+ (gpointer)ibus_engine_desc_get_name (engine->desc),
|
|
+ value);
|
|
+ }
|
|
+ g_hash_table_unref (hash_table);
|
|
+}
|
|
+
|
|
+static void
|
|
+bus_engine_proxy_get_has_focus_id (BusEngineProxy *engine)
|
|
+{
|
|
+ BusIBusImpl *ibus = BUS_DEFAULT_IBUS;
|
|
+ GHashTable *hash_table;
|
|
+
|
|
+ g_assert (BUS_IS_ENGINE_PROXY (engine));
|
|
+ g_assert (ibus);
|
|
+
|
|
+ hash_table = bus_ibus_impl_get_engine_focus_id_table (ibus);
|
|
+ g_assert (hash_table);
|
|
+ g_dbus_proxy_call ((GDBusProxy *) engine,
|
|
+ "org.freedesktop.DBus.Properties.Get",
|
|
+ g_variant_new ("(ss)",
|
|
+ IBUS_INTERFACE_ENGINE,
|
|
+ "FocusId"),
|
|
+ G_DBUS_CALL_FLAGS_NONE,
|
|
+ -1,
|
|
+ NULL,
|
|
+ _get_has_focus_id_cb,
|
|
+ g_hash_table_ref (hash_table));
|
|
+}
|
|
+
|
|
/* a macro to generate a function to call a nullary D-Bus method. */
|
|
#define DEFINE_FUNCTION(Name, name) \
|
|
void \
|
|
@@ -1223,11 +1340,24 @@ DEFINE_FUNCTION (CursorDown, cursor_down)
|
|
#undef DEFINE_FUNCTION
|
|
|
|
void
|
|
-bus_engine_proxy_focus_in (BusEngineProxy *engine)
|
|
+bus_engine_proxy_focus_in (BusEngineProxy *engine,
|
|
+ const gchar *object_path,
|
|
+ const gchar *client)
|
|
{
|
|
g_assert (BUS_IS_ENGINE_PROXY (engine));
|
|
- if (!engine->has_focus) {
|
|
- engine->has_focus = TRUE;
|
|
+ if (engine->has_focus)
|
|
+ return;
|
|
+ engine->has_focus = TRUE;
|
|
+ if (engine->has_focus_id) {
|
|
+ g_dbus_proxy_call ((GDBusProxy *)engine,
|
|
+ "FocusInId",
|
|
+ g_variant_new ("(ss)", object_path, client),
|
|
+ G_DBUS_CALL_FLAGS_NONE,
|
|
+ -1,
|
|
+ NULL,
|
|
+ NULL,
|
|
+ NULL);
|
|
+ } else {
|
|
g_dbus_proxy_call ((GDBusProxy *)engine,
|
|
"FocusIn",
|
|
NULL,
|
|
@@ -1240,11 +1370,23 @@ bus_engine_proxy_focus_in (BusEngineProxy *engine)
|
|
}
|
|
|
|
void
|
|
-bus_engine_proxy_focus_out (BusEngineProxy *engine)
|
|
+bus_engine_proxy_focus_out (BusEngineProxy *engine,
|
|
+ const gchar *object_path)
|
|
{
|
|
g_assert (BUS_IS_ENGINE_PROXY (engine));
|
|
- if (engine->has_focus) {
|
|
- engine->has_focus = FALSE;
|
|
+ if (!engine->has_focus)
|
|
+ return;
|
|
+ engine->has_focus = FALSE;
|
|
+ if (engine->has_focus_id) {
|
|
+ g_dbus_proxy_call ((GDBusProxy *)engine,
|
|
+ "FocusOutId",
|
|
+ g_variant_new ("(s)", object_path),
|
|
+ G_DBUS_CALL_FLAGS_NONE,
|
|
+ -1,
|
|
+ NULL,
|
|
+ NULL,
|
|
+ NULL);
|
|
+ } else {
|
|
g_dbus_proxy_call ((GDBusProxy *)engine,
|
|
"FocusOut",
|
|
NULL,
|
|
diff --git a/bus/engineproxy.h b/bus/engineproxy.h
|
|
index a3006b47..957b7851 100644
|
|
--- a/bus/engineproxy.h
|
|
+++ b/bus/engineproxy.h
|
|
@@ -2,7 +2,7 @@
|
|
/* vim:set et sts=4: */
|
|
/* ibus - The Input Bus
|
|
* Copyright (C) 2008-2013 Peng Huang <shawn.p.huang@gmail.com>
|
|
- * Copyright (C) 2018 Takao Fujiwara <takao.fujiwara@gmail.com>
|
|
+ * Copyright (C) 2018-2022 Takao Fujiwara <takao.fujiwara@gmail.com>
|
|
* Copyright (C) 2008-2018 Red Hat, Inc.
|
|
*
|
|
* This library is free software; you can redistribute it and/or
|
|
@@ -126,20 +126,26 @@ void bus_engine_proxy_set_cursor_location
|
|
/**
|
|
* bus_engine_proxy_focus_in:
|
|
* @engine: A #BusEngineProxy.
|
|
+ * @object_path: An object path.
|
|
+ * @client: A client name.
|
|
*
|
|
* Call "FocusIn" method of an engine asynchronously. Do nothing if
|
|
* the engine already has a focus.
|
|
*/
|
|
-void bus_engine_proxy_focus_in (BusEngineProxy *engine);
|
|
+void bus_engine_proxy_focus_in (BusEngineProxy *engine,
|
|
+ const gchar *object_path,
|
|
+ const gchar *client);
|
|
|
|
/**
|
|
* bus_engine_proxy_focus_out:
|
|
* @engine: A #BusEngineProxy.
|
|
+ * @object_path: An object path.
|
|
*
|
|
* Call "FocusOut" method of an engine asynchronously. Do nothing if
|
|
* the engine does not have a focus.
|
|
*/
|
|
-void bus_engine_proxy_focus_out (BusEngineProxy *engine);
|
|
+void bus_engine_proxy_focus_out (BusEngineProxy *engine,
|
|
+ const gchar *object_path);
|
|
|
|
/**
|
|
* bus_engine_proxy_reset:
|
|
diff --git a/bus/ibusimpl.c b/bus/ibusimpl.c
|
|
index 49a138fe..8a443545 100644
|
|
--- a/bus/ibusimpl.c
|
|
+++ b/bus/ibusimpl.c
|
|
@@ -72,6 +72,8 @@ struct _BusIBusImpl {
|
|
* IBusEngineDesc object. */
|
|
GHashTable *engine_table;
|
|
|
|
+ GHashTable *engine_focus_id_table;
|
|
+
|
|
BusInputContext *focused_context;
|
|
BusPanelProxy *panel;
|
|
BusPanelProxy *emoji_extension;
|
|
@@ -596,6 +598,7 @@ bus_ibus_impl_init (BusIBusImpl *ibus)
|
|
ibus->use_global_engine = TRUE;
|
|
ibus->global_engine_name = NULL;
|
|
ibus->global_previous_engine_name = NULL;
|
|
+ ibus->engine_focus_id_table = g_hash_table_new (g_str_hash, g_str_equal);
|
|
|
|
/* focus the fake_context, if use_global_engine is enabled. */
|
|
if (ibus->use_global_engine)
|
|
@@ -2384,3 +2387,13 @@ bus_ibus_impl_get_focused_input_context (BusIBusImpl *ibus)
|
|
|
|
return ibus->focused_context;
|
|
}
|
|
+
|
|
+GHashTable *
|
|
+bus_ibus_impl_get_engine_focus_id_table (BusIBusImpl *ibus)
|
|
+{
|
|
+
|
|
+ g_assert (BUS_IS_IBUS_IMPL (ibus));
|
|
+
|
|
+ return ibus->engine_focus_id_table;
|
|
+}
|
|
+
|
|
diff --git a/bus/ibusimpl.h b/bus/ibusimpl.h
|
|
index 0bb18daf..cbe6856d 100644
|
|
--- a/bus/ibusimpl.h
|
|
+++ b/bus/ibusimpl.h
|
|
@@ -2,7 +2,8 @@
|
|
/* vim:set et sts=4: */
|
|
/* bus - The Input Bus
|
|
* Copyright (C) 2008-2013 Peng Huang <shawn.p.huang@gmail.com>
|
|
- * Copyright (C) 2008-2013 Red Hat, Inc.
|
|
+ * Copyright (C) 2022 Takao Fujiwara <takao.fujiwara1@gmail.com>
|
|
+ * Copyright (C) 2008-2022 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
|
|
@@ -58,6 +59,13 @@ G_BEGIN_DECLS
|
|
typedef struct _BusIBusImpl BusIBusImpl;
|
|
typedef struct _BusIBusImplClass BusIBusImplClass;
|
|
|
|
+typedef enum
|
|
+{
|
|
+ ENGINE_FOCUS_CATEGORY_NONE = 0,
|
|
+ ENGINE_FOCUS_CATEGORY_NO_ID,
|
|
+ ENGINE_FOCUS_CATEGORY_HAS_ID
|
|
+} EngineFocusCategory;
|
|
+
|
|
GType bus_ibus_impl_get_type (void);
|
|
|
|
/**
|
|
@@ -81,6 +89,7 @@ gboolean bus_ibus_impl_is_embed_preedit_text
|
|
(BusIBusImpl *ibus);
|
|
BusInputContext *bus_ibus_impl_get_focused_input_context
|
|
(BusIBusImpl *ibus);
|
|
-
|
|
+GHashTable *bus_ibus_impl_get_engine_focus_id_table
|
|
+ (BusIBusImpl *ibus);
|
|
G_END_DECLS
|
|
#endif
|
|
diff --git a/bus/inputcontext.c b/bus/inputcontext.c
|
|
index 8d84fd05..72041ecb 100644
|
|
--- a/bus/inputcontext.c
|
|
+++ b/bus/inputcontext.c
|
|
@@ -846,7 +846,8 @@ _ic_process_key_event_reply_cb (GObject *source,
|
|
/**
|
|
* _ic_process_key_event:
|
|
*
|
|
- * Implement the "ProcessKeyEvent" method call of the org.freedesktop.IBus.InputContext interface.
|
|
+ * Implement the "ProcessKeyEvent" method call of the
|
|
+ * org.freedesktop.IBus.InputContext interface.
|
|
*/
|
|
static void
|
|
_ic_process_key_event (BusInputContext *context,
|
|
@@ -860,11 +861,13 @@ _ic_process_key_event (BusInputContext *context,
|
|
g_variant_get (parameters, "(uuu)", &keyval, &keycode, &modifiers);
|
|
if (G_UNLIKELY (!context->has_focus)) {
|
|
/* workaround: set focus if context does not have focus */
|
|
- BusInputContext *focused_context = bus_ibus_impl_get_focused_input_context (BUS_DEFAULT_IBUS);
|
|
+ BusInputContext *focused_context =
|
|
+ bus_ibus_impl_get_focused_input_context (BUS_DEFAULT_IBUS);
|
|
if (focused_context == NULL ||
|
|
focused_context->fake == TRUE ||
|
|
context->fake == FALSE) {
|
|
- /* grab focus, if context is a real IC or current focused IC is fake */
|
|
+ /* grab focus, if context is a real IC or current focused IC is
|
|
+ * fake */
|
|
bus_input_context_focus_in (context);
|
|
}
|
|
}
|
|
@@ -914,7 +917,8 @@ _ic_process_key_event (BusInputContext *context,
|
|
data);
|
|
}
|
|
else {
|
|
- g_dbus_method_invocation_return_value (invocation, g_variant_new ("(b)", FALSE));
|
|
+ g_dbus_method_invocation_return_value (invocation,
|
|
+ g_variant_new ("(b)", FALSE));
|
|
}
|
|
}
|
|
|
|
@@ -1438,7 +1442,9 @@ bus_input_context_focus_in (BusInputContext *context)
|
|
context->prev_modifiers = 0;
|
|
|
|
if (context->engine) {
|
|
- bus_engine_proxy_focus_in (context->engine);
|
|
+ const gchar *path =
|
|
+ ibus_service_get_object_path ((IBusService *)context);
|
|
+ bus_engine_proxy_focus_in (context->engine, path, context->client);
|
|
bus_engine_proxy_enable (context->engine);
|
|
bus_engine_proxy_set_capabilities (context->engine, context->capabilities);
|
|
bus_engine_proxy_set_cursor_location (context->engine, context->x, context->y, context->w, context->h);
|
|
@@ -1538,7 +1544,9 @@ bus_input_context_focus_out (BusInputContext *context)
|
|
bus_input_context_register_properties (context, props_empty);
|
|
|
|
if (context->engine) {
|
|
- bus_engine_proxy_focus_out (context->engine);
|
|
+ const gchar *path =
|
|
+ ibus_service_get_object_path ((IBusService *)context);
|
|
+ bus_engine_proxy_focus_out (context->engine, path);
|
|
}
|
|
|
|
context->has_focus = FALSE;
|
|
@@ -2376,11 +2384,19 @@ bus_input_context_enable (BusInputContext *context)
|
|
if (context->engine == NULL)
|
|
return;
|
|
|
|
- bus_engine_proxy_focus_in (context->engine);
|
|
- bus_engine_proxy_enable (context->engine);
|
|
- bus_engine_proxy_set_capabilities (context->engine, context->capabilities);
|
|
- bus_engine_proxy_set_cursor_location (context->engine, context->x, context->y, context->w, context->h);
|
|
- bus_engine_proxy_set_content_type (context->engine, context->purpose, context->hints);
|
|
+ {
|
|
+ const gchar *path =
|
|
+ ibus_service_get_object_path ((IBusService *)context);
|
|
+ bus_engine_proxy_focus_in (context->engine, path, context->client);
|
|
+ bus_engine_proxy_enable (context->engine);
|
|
+ bus_engine_proxy_set_capabilities (context->engine,
|
|
+ context->capabilities);
|
|
+ bus_engine_proxy_set_cursor_location (context->engine,
|
|
+ context->x, context->y,
|
|
+ context->w, context->h);
|
|
+ bus_engine_proxy_set_content_type (context->engine,
|
|
+ context->purpose, context->hints);
|
|
+ }
|
|
}
|
|
|
|
void
|
|
@@ -2397,7 +2413,9 @@ bus_input_context_disable (BusInputContext *context)
|
|
bus_input_context_register_properties (context, props_empty);
|
|
|
|
if (context->engine) {
|
|
- bus_engine_proxy_focus_out (context->engine);
|
|
+ const gchar *path =
|
|
+ ibus_service_get_object_path ((IBusService *)context);
|
|
+ bus_engine_proxy_focus_out (context->engine, path);
|
|
bus_engine_proxy_disable (context->engine);
|
|
}
|
|
}
|
|
@@ -2445,6 +2463,8 @@ bus_input_context_unset_engine (BusInputContext *context)
|
|
|
|
if (context->engine) {
|
|
gint i;
|
|
+ const gchar *path =
|
|
+ ibus_service_get_object_path ((IBusService *)context);
|
|
/* uninstall signal handlers for the engine. */
|
|
for (i = 0; i < G_N_ELEMENTS(engine_signals); i++) {
|
|
g_signal_handlers_disconnect_by_func (context->engine,
|
|
@@ -2453,7 +2473,7 @@ bus_input_context_unset_engine (BusInputContext *context)
|
|
/* focus out engine so that the next call of
|
|
bus_engine_proxy_focus_in() will take effect and trigger
|
|
RegisterProperties. */
|
|
- bus_engine_proxy_focus_out (context->engine);
|
|
+ bus_engine_proxy_focus_out (context->engine, path);
|
|
g_object_unref (context->engine);
|
|
context->engine = NULL;
|
|
}
|
|
@@ -2488,7 +2508,9 @@ bus_input_context_set_engine (BusInputContext *context,
|
|
context);
|
|
}
|
|
if (context->has_focus) {
|
|
- bus_engine_proxy_focus_in (context->engine);
|
|
+ const gchar *path =
|
|
+ ibus_service_get_object_path ((IBusService *)context);
|
|
+ bus_engine_proxy_focus_in (context->engine, path, context->client);
|
|
bus_engine_proxy_enable (context->engine);
|
|
bus_engine_proxy_set_capabilities (context->engine, context->capabilities);
|
|
bus_engine_proxy_set_cursor_location (context->engine, context->x, context->y, context->w, context->h);
|
|
diff --git a/src/ibusengine.c b/src/ibusengine.c
|
|
index 7e844838..7c797103 100644
|
|
--- a/src/ibusengine.c
|
|
+++ b/src/ibusengine.c
|
|
@@ -2,7 +2,7 @@
|
|
/* vim:set et sts=4: */
|
|
/* ibus - The Input Bus
|
|
* Copyright (C) 2008-2013 Peng Huang <shawn.p.huang@gmail.com>
|
|
- * Copyright (C) 2018-2021 Takao Fujiwara <takao.fujiwara1@gmail.com>
|
|
+ * Copyright (C) 2018-2022 Takao Fujiwara <takao.fujiwara1@gmail.com>
|
|
* Copyright (C) 2008-2021 Red Hat, Inc.
|
|
*
|
|
* This library is free software; you can redistribute it and/or
|
|
@@ -37,7 +37,9 @@
|
|
enum {
|
|
PROCESS_KEY_EVENT,
|
|
FOCUS_IN,
|
|
+ FOCUS_IN_ID,
|
|
FOCUS_OUT,
|
|
+ FOCUS_OUT_ID,
|
|
RESET,
|
|
ENABLE,
|
|
DISABLE,
|
|
@@ -61,6 +63,7 @@ enum {
|
|
enum {
|
|
PROP_0,
|
|
PROP_ENGINE_NAME,
|
|
+ PROP_HAS_FOCUS_ID,
|
|
};
|
|
|
|
|
|
@@ -82,6 +85,7 @@ struct _IBusEnginePrivate {
|
|
GHashTable *extension_keybindings;
|
|
gboolean enable_extension;
|
|
gchar *current_extension_name;
|
|
+ gboolean has_focus_id;
|
|
};
|
|
|
|
|
|
@@ -104,7 +108,8 @@ static void ibus_engine_service_method_call
|
|
GDBusConnection *connection,
|
|
const gchar *sender,
|
|
const gchar *object_path,
|
|
- const gchar *interface_name,
|
|
+ const gchar
|
|
+ *interface_name,
|
|
const gchar *method_name,
|
|
GVariant *parameters,
|
|
GDBusMethodInvocation
|
|
@@ -132,7 +137,12 @@ static gboolean ibus_engine_process_key_event
|
|
guint keycode,
|
|
guint state);
|
|
static void ibus_engine_focus_in (IBusEngine *engine);
|
|
+static void ibus_engine_focus_in_id (IBusEngine *engine,
|
|
+ const gchar *object_path,
|
|
+ const gchar *client);
|
|
static void ibus_engine_focus_out (IBusEngine *engine);
|
|
+static void ibus_engine_focus_out_id (IBusEngine *engine,
|
|
+ const gchar *object_path);
|
|
static void ibus_engine_reset (IBusEngine *engine);
|
|
static void ibus_engine_enable (IBusEngine *engine);
|
|
static void ibus_engine_disable (IBusEngine *engine);
|
|
@@ -170,7 +180,8 @@ static void ibus_engine_set_surrounding_text
|
|
static void ibus_engine_process_hand_writing_event
|
|
(IBusEngine *engine,
|
|
const gdouble *coordinates,
|
|
- guint coordinates_len);
|
|
+ guint
|
|
+ coordinates_len);
|
|
static void ibus_engine_cancel_hand_writing
|
|
(IBusEngine *engine,
|
|
guint n_strokes);
|
|
@@ -230,7 +241,15 @@ static const gchar introspection_xml[] =
|
|
" <arg direction='in' type='u' name='state' />"
|
|
" </method>"
|
|
" <method name='FocusIn' />"
|
|
+ " <method name='FocusInId'>"
|
|
+ " <arg direction='in' type='s' name='object_path' />"
|
|
+ " <arg direction='in' type='s' name='client' />"
|
|
+ " </method>"
|
|
+ " <method name='FocusIn' />"
|
|
" <method name='FocusOut' />"
|
|
+ " <method name='FocusOutId'>"
|
|
+ " <arg direction='in' type='s' name='object_path' />"
|
|
+ " </method>"
|
|
" <method name='Reset' />"
|
|
" <method name='Enable' />"
|
|
" <method name='Disable' />"
|
|
@@ -283,6 +302,7 @@ static const gchar introspection_xml[] =
|
|
" </signal>"
|
|
/* FIXME properties */
|
|
" <property name='ContentType' type='(uu)' access='write' />"
|
|
+ " <property name='FocusId' type='(b)' access='read' />"
|
|
" </interface>"
|
|
"</node>";
|
|
|
|
@@ -324,7 +344,9 @@ ibus_engine_class_init (IBusEngineClass *class)
|
|
|
|
class->process_key_event = ibus_engine_process_key_event;
|
|
class->focus_in = ibus_engine_focus_in;
|
|
+ class->focus_in_id = ibus_engine_focus_in_id;
|
|
class->focus_out = ibus_engine_focus_out;
|
|
+ class->focus_out_id = ibus_engine_focus_out_id;
|
|
class->reset = ibus_engine_reset;
|
|
class->enable = ibus_engine_enable;
|
|
class->disable = ibus_engine_disable;
|
|
@@ -360,6 +382,15 @@ ibus_engine_class_init (IBusEngineClass *class)
|
|
G_PARAM_CONSTRUCT_ONLY |
|
|
G_PARAM_STATIC_STRINGS));
|
|
|
|
+ g_object_class_install_property (gobject_class,
|
|
+ PROP_HAS_FOCUS_ID,
|
|
+ g_param_spec_boolean ("has-focus-id",
|
|
+ "has focus id",
|
|
+ "Has focus ID",
|
|
+ FALSE,
|
|
+ G_PARAM_READWRITE |
|
|
+ G_PARAM_CONSTRUCT_ONLY));
|
|
+
|
|
/* install signals */
|
|
/**
|
|
* IBusEngine::process-key-event:
|
|
@@ -378,7 +409,8 @@ ibus_engine_class_init (IBusEngineClass *class)
|
|
* Returns: %TRUE for successfully process the key; %FALSE otherwise.
|
|
* See also: ibus_input_context_process_key_event().
|
|
*
|
|
- * <note><para>Argument @user_data is ignored in this function.</para></note>
|
|
+ * <note><para>Argument @user_data is ignored in this function.</para>
|
|
+ * </note>
|
|
*/
|
|
engine_signals[PROCESS_KEY_EVENT] =
|
|
g_signal_new (I_("process-key-event"),
|
|
@@ -402,7 +434,8 @@ ibus_engine_class_init (IBusEngineClass *class)
|
|
* in extended class to receive this signal.
|
|
*
|
|
* See also: ibus_input_context_focus_in()
|
|
- * <note><para>Argument @user_data is ignored in this function.</para></note>
|
|
+ * <note><para>Argument @user_data is ignored in this function.</para>
|
|
+ * </note>
|
|
*/
|
|
engine_signals[FOCUS_IN] =
|
|
g_signal_new (I_("focus-in"),
|
|
@@ -414,6 +447,58 @@ ibus_engine_class_init (IBusEngineClass *class)
|
|
G_TYPE_NONE,
|
|
0);
|
|
|
|
+ /**
|
|
+ * IBusEngine::focus-in-id:
|
|
+ * @engine: An IBusEngine.
|
|
+ * @object_path: An object path.
|
|
+ * @client: An client name.
|
|
+ *
|
|
+ * Emitted when the client application get the focus.
|
|
+ * Implement the member function IBusEngineClass::focus_in
|
|
+ * in extended class to receive this signal.
|
|
+ * @object_path is a unique id by input context.
|
|
+ * @client indicates a client type:
|
|
+ * 'fake': focus is on desktop background or other programs where no
|
|
+ * input is possible
|
|
+ * 'xim': old X11 programs like xterm, emacs, ...
|
|
+ * GTK3 programs in a Gnome Xorg session when GTK_IM_MODULE
|
|
+ * is unset also use xim
|
|
+ * 'gtk-im:<client-name>': Gtk2 input module is used
|
|
+ * 'gtk3-im:<client-name>': Gtk3 input module is used
|
|
+ * 'gtk4-im:<client-name>': Gtk4 input module is used
|
|
+ * In case of the Gtk input modules, the name of the
|
|
+ * client is also shown after the “:”, for example
|
|
+ * like 'gtk3-im:firefox', 'gtk4-im:gnome-text-editor', …
|
|
+ * 'gnome-shell': Entries handled by gnome-shell
|
|
+ * (like the command line dialog opened with Alt+F2
|
|
+ * or the search field when pressing the Super key.)
|
|
+ * When GTK_IM_MODULE is unset in a Gnome Wayland session
|
|
+ * all programs which would show 'gtk3-im' or 'gtk4-im'
|
|
+ * with GTK_IM_MODULE=ibus then show 'gnome-shell'
|
|
+ * instead.
|
|
+ * 'Qt': Qt4 programs like keepassx-2.0.3 …
|
|
+ * 'QIBusInputContext': Qt5 programs like keepassxc-2.7.1, anki-2.1.15
|
|
+ * telegram-desktop-3.7.3,
|
|
+ *
|
|
+ * You need to set #IBusEngine::has-focus-id property to %TRUE when you
|
|
+ * construct an #IBusEngine to use this class method.
|
|
+ *
|
|
+ * See also: ibus_input_context_focus_in()
|
|
+ * <note><para>Argument @user_data is ignored in this function.</para>
|
|
+ * </note>
|
|
+ */
|
|
+ engine_signals[FOCUS_IN_ID] =
|
|
+ g_signal_new (I_("focus-in-id"),
|
|
+ G_TYPE_FROM_CLASS (gobject_class),
|
|
+ G_SIGNAL_RUN_LAST,
|
|
+ G_STRUCT_OFFSET (IBusEngineClass, focus_in_id),
|
|
+ NULL, NULL,
|
|
+ _ibus_marshal_VOID__STRING_STRING,
|
|
+ G_TYPE_NONE,
|
|
+ 2,
|
|
+ G_TYPE_STRING,
|
|
+ G_TYPE_STRING);
|
|
+
|
|
/**
|
|
* IBusEngine::focus-out:
|
|
* @engine: An IBusEngine.
|
|
@@ -423,7 +508,8 @@ ibus_engine_class_init (IBusEngineClass *class)
|
|
* in extended class to receive this signal.
|
|
*
|
|
* See also: ibus_input_context_focus_out()
|
|
- * <note><para>Argument @user_data is ignored in this function.</para></note>
|
|
+ * <note><para>Argument @user_data is ignored in this function.</para>
|
|
+ * </note>
|
|
*/
|
|
engine_signals[FOCUS_OUT] =
|
|
g_signal_new (I_("focus-out"),
|
|
@@ -435,6 +521,33 @@ ibus_engine_class_init (IBusEngineClass *class)
|
|
G_TYPE_NONE,
|
|
0);
|
|
|
|
+ /**
|
|
+ * IBusEngine::focus-out-id:
|
|
+ * @engine: An IBusEngine.
|
|
+ * @object_path: An object path.
|
|
+ *
|
|
+ * Emitted when the client application lost the focus.
|
|
+ * Implement the member function IBusEngineClass::focus_out
|
|
+ * in extended class to receive this signal.
|
|
+ * @object_path is a unique id by input context.
|
|
+ * You need to set #IBusEngine::has-focus-id property to %TRUE when you
|
|
+ * construct an #IBusEngine to use this class method.
|
|
+ *
|
|
+ * See also: ibus_input_context_focus_out()
|
|
+ * <note><para>Argument @user_data is ignored in this function.</para>
|
|
+ * </note>
|
|
+ */
|
|
+ engine_signals[FOCUS_OUT_ID] =
|
|
+ g_signal_new (I_("focus-out-id"),
|
|
+ G_TYPE_FROM_CLASS (gobject_class),
|
|
+ G_SIGNAL_RUN_LAST,
|
|
+ G_STRUCT_OFFSET (IBusEngineClass, focus_out_id),
|
|
+ NULL, NULL,
|
|
+ _ibus_marshal_VOID__STRING,
|
|
+ G_TYPE_NONE,
|
|
+ 1,
|
|
+ G_TYPE_STRING);
|
|
+
|
|
/**
|
|
* IBusEngine::reset:
|
|
* @engine: An IBusEngine.
|
|
@@ -872,6 +985,9 @@ ibus_engine_set_property (IBusEngine *engine,
|
|
case PROP_ENGINE_NAME:
|
|
engine->priv->engine_name = g_value_dup_string (value);
|
|
break;
|
|
+ case PROP_HAS_FOCUS_ID:
|
|
+ engine->priv->has_focus_id = g_value_get_boolean (value);
|
|
+ break;
|
|
default:
|
|
G_OBJECT_WARN_INVALID_PROPERTY_ID (engine, prop_id, pspec);
|
|
}
|
|
@@ -887,7 +1003,9 @@ ibus_engine_get_property (IBusEngine *engine,
|
|
case PROP_ENGINE_NAME:
|
|
g_value_set_string (value, engine->priv->engine_name);
|
|
break;
|
|
-
|
|
+ case PROP_HAS_FOCUS_ID:
|
|
+ g_value_set_boolean (value, engine->priv->has_focus_id);
|
|
+ break;
|
|
default:
|
|
G_OBJECT_WARN_INVALID_PROPERTY_ID (engine, prop_id, pspec);
|
|
}
|
|
@@ -1176,6 +1294,30 @@ ibus_engine_service_method_call (IBusService *service,
|
|
}
|
|
}
|
|
|
|
+ if (g_strcmp0 (method_name, "FocusInId") == 0) {
|
|
+ gchar *object_path = NULL;
|
|
+ gchar *client = NULL;
|
|
+ g_variant_get (parameters, "(&s&s)", &object_path, &client);
|
|
+ g_signal_emit (engine,
|
|
+ engine_signals[FOCUS_IN_ID],
|
|
+ 0,
|
|
+ object_path,
|
|
+ client);
|
|
+ g_dbus_method_invocation_return_value (invocation, NULL);
|
|
+ return;
|
|
+ }
|
|
+
|
|
+ if (g_strcmp0 (method_name, "FocusOutId") == 0) {
|
|
+ gchar *object_path = NULL;
|
|
+ g_variant_get (parameters, "(&s)", &object_path);
|
|
+ g_signal_emit (engine,
|
|
+ engine_signals[FOCUS_OUT_ID],
|
|
+ 0,
|
|
+ object_path);
|
|
+ g_dbus_method_invocation_return_value (invocation, NULL);
|
|
+ return;
|
|
+ }
|
|
+
|
|
if (g_strcmp0 (method_name, "CandidateClicked") == 0) {
|
|
guint index, button, state;
|
|
g_variant_get (parameters, "(uuu)", &index, &button, &state);
|
|
@@ -1303,6 +1445,23 @@ ibus_engine_service_method_call (IBusService *service,
|
|
g_return_if_reached ();
|
|
}
|
|
|
|
+/**
|
|
+ * _ibus_engine_has_focus_id:
|
|
+ *
|
|
+ * Implement the "FocusId" method call of the org.freedesktop.IBus interface.
|
|
+ */
|
|
+static GVariant *
|
|
+_ibus_engine_has_focus_id (IBusEngine *engine,
|
|
+ GDBusConnection *connection,
|
|
+ GError **error)
|
|
+{
|
|
+ if (error) {
|
|
+ *error = NULL;
|
|
+ }
|
|
+
|
|
+ return g_variant_new_boolean (engine->priv->has_focus_id);
|
|
+}
|
|
+
|
|
static GVariant *
|
|
ibus_engine_service_get_property (IBusService *service,
|
|
GDBusConnection *connection,
|
|
@@ -1312,7 +1471,18 @@ ibus_engine_service_get_property (IBusService *service,
|
|
const gchar *property_name,
|
|
GError **error)
|
|
{
|
|
- return IBUS_SERVICE_CLASS (ibus_engine_parent_class)->
|
|
+ int i;
|
|
+ static const struct {
|
|
+ const gchar *method_name;
|
|
+ GVariant * (* method_callback) (IBusEngine *,
|
|
+ GDBusConnection *,
|
|
+ GError **);
|
|
+ } methods [] = {
|
|
+ { "FocusId", _ibus_engine_has_focus_id },
|
|
+ };
|
|
+
|
|
+ if (g_strcmp0 (interface_name, IBUS_INTERFACE_ENGINE) != 0) {
|
|
+ return IBUS_SERVICE_CLASS (ibus_engine_parent_class)->
|
|
service_get_property (service,
|
|
connection,
|
|
sender,
|
|
@@ -1320,6 +1490,19 @@ ibus_engine_service_get_property (IBusService *service,
|
|
interface_name,
|
|
property_name,
|
|
error);
|
|
+ }
|
|
+
|
|
+ for (i = 0; i < G_N_ELEMENTS (methods); i++) {
|
|
+ if (g_strcmp0 (methods[i].method_name, property_name) == 0) {
|
|
+ return methods[i].method_callback ((IBusEngine *) service,
|
|
+ connection,
|
|
+ error);
|
|
+ }
|
|
+ }
|
|
+
|
|
+ g_warning ("service_get_property received an unknown property: %s",
|
|
+ property_name ? property_name : "(null)");
|
|
+ return NULL;
|
|
}
|
|
|
|
static gboolean
|
|
@@ -1386,31 +1569,39 @@ ibus_engine_process_key_event (IBusEngine *engine,
|
|
static void
|
|
ibus_engine_focus_in (IBusEngine *engine)
|
|
{
|
|
- // g_debug ("focus-in");
|
|
+}
|
|
+
|
|
+static void
|
|
+ibus_engine_focus_in_id (IBusEngine *engine,
|
|
+ const gchar *object_path,
|
|
+ const gchar *client)
|
|
+{
|
|
}
|
|
|
|
static void
|
|
ibus_engine_focus_out (IBusEngine *engine)
|
|
{
|
|
- // g_debug ("focus-out");
|
|
+}
|
|
+
|
|
+static void
|
|
+ibus_engine_focus_out_id (IBusEngine *engine,
|
|
+ const gchar *object_path)
|
|
+{
|
|
}
|
|
|
|
static void
|
|
ibus_engine_reset (IBusEngine *engine)
|
|
{
|
|
- // g_debug ("reset");
|
|
}
|
|
|
|
static void
|
|
ibus_engine_enable (IBusEngine *engine)
|
|
{
|
|
- // g_debug ("enable");
|
|
}
|
|
|
|
static void
|
|
ibus_engine_disable (IBusEngine *engine)
|
|
{
|
|
- // g_debug ("disable");
|
|
}
|
|
|
|
static void
|
|
diff --git a/src/ibusengine.h b/src/ibusengine.h
|
|
index 43eaa554..6af0e856 100644
|
|
--- a/src/ibusengine.h
|
|
+++ b/src/ibusengine.h
|
|
@@ -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) 2012-2022 Takao Fujiwara <takao.fujiwara1@gmail.com>
|
|
+ * Copyright (C) 2008-2022 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
|
|
@@ -153,10 +154,15 @@ struct _IBusEngineClass {
|
|
(IBusEngine *engine,
|
|
guint purpose,
|
|
guint hints);
|
|
+ void (* focus_in_id) (IBusEngine *engine,
|
|
+ const gchar *object_path,
|
|
+ const gchar *client);
|
|
+ void (* focus_out_id) (IBusEngine *engine,
|
|
+ const gchar *object_path);
|
|
|
|
/*< private >*/
|
|
/* padding */
|
|
- gpointer pdummy[4];
|
|
+ gpointer pdummy[2];
|
|
};
|
|
|
|
GType ibus_engine_get_type (void);
|
|
diff --git a/src/ibusmarshalers.list b/src/ibusmarshalers.list
|
|
index aa9ea82a..7489f842 100644
|
|
--- a/src/ibusmarshalers.list
|
|
+++ b/src/ibusmarshalers.list
|
|
@@ -19,6 +19,7 @@ VOID:OBJECT,UINT,UINT
|
|
VOID:OBJECT,BOOLEAN
|
|
VOID:BOXED,BOOLEAN
|
|
VOID:BOXED
|
|
+VOID:STRING,STRING
|
|
VOID:STRING,STRING,VARIANT
|
|
VOID:STRING,STRING,STRING
|
|
VOID:UINT
|
|
--
|
|
2.35.3
|
|
|
|
From 59c13597918db98ec8120ccdac09f1e2dc576e1b Mon Sep 17 00:00:00 2001
|
|
From: fujiwarat <takao.fujiwara1@gmail.com>
|
|
Date: Thu, 7 Jul 2022 08:22:48 +0900
|
|
Subject: [PATCH] src/tests: Unset G_MESSAGES_DEBUG for gsettings in
|
|
xkb-latin-layouts
|
|
|
|
gsettings cannot get the key value when G_MESSAGES_DEBUG is enabled.
|
|
Add denylist.txt to engine/Makefile.am
|
|
---
|
|
engine/Makefile.am | 3 ++-
|
|
src/tests/xkb-latin-layouts | 7 +++++++
|
|
2 files changed, 9 insertions(+), 1 deletion(-)
|
|
|
|
diff --git a/engine/Makefile.am b/engine/Makefile.am
|
|
index 03867f52..7256fbc8 100644
|
|
--- a/engine/Makefile.am
|
|
+++ b/engine/Makefile.am
|
|
@@ -4,7 +4,7 @@
|
|
#
|
|
# Copyright (c) 2010-2016, Google Inc. All rights reserved.
|
|
# Copyright (c) 2007-2016 Peng Huang <shawn.p.huang@gmail.com>
|
|
-# Copyright (c) 2013-2020 Takao Fujiwara <takao.fujiwara1@gmail.com>
|
|
+# Copyright (c) 2013-2021 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
|
|
@@ -88,6 +88,7 @@ CLEANFILES = \
|
|
$(NULL)
|
|
|
|
EXTRA_DIST = \
|
|
+ denylist.txt \
|
|
gensimple.py \
|
|
iso639converter.py \
|
|
simple.xml.in \
|
|
diff --git a/src/tests/xkb-latin-layouts b/src/tests/xkb-latin-layouts
|
|
index f8dced6b..92464234 100755
|
|
--- a/src/tests/xkb-latin-layouts
|
|
+++ b/src/tests/xkb-latin-layouts
|
|
@@ -82,9 +82,16 @@ finit()
|
|
|
|
test_xkb_keymaps()
|
|
{
|
|
+ # G_MESSAGES_DEBUG=all or G_MESSAGES_DEBUG=GLib-GIO-DEBUG would append
|
|
+ # debug messages to gsettings output and could not get the result correctly.
|
|
+ backup_G_MESSAGES_DEBUG="$G_MESSAGES_DEBUG"
|
|
+ unset G_MESSAGES_DEBUG
|
|
# Loop over top level schemas since "gsettings list-recursively" only
|
|
# looks for direct children.
|
|
xkb_latin_layouts=`gsettings get org.freedesktop.ibus.general xkb-latin-layouts`
|
|
+ if [ x"$backup_G_MESSAGES_DEBUG" != x ] ; then
|
|
+ export G_MESSAGES_DEBUG=$backup_G_MESSAGES_DEBUG
|
|
+ fi
|
|
while read keymap ; do
|
|
eval keymap="$keymap"
|
|
HAS_VARIANT=$($ECHO "$keymap" | grep '(' 2> /dev/null) ||:
|
|
--
|
|
2.35.3
|
|
|
|
From d47dbfada41aa4fb5df9f7cffe873786fc4849cc Mon Sep 17 00:00:00 2001
|
|
From: fujiwarat <takao.fujiwara1@gmail.com>
|
|
Date: Mon, 25 Jul 2022 17:22:21 +0900
|
|
Subject: [PATCH] client/x11: Enhance Xutf8TextListToTextProperty
|
|
|
|
XCompoundTextStyle depends on the current locale and some locales fail
|
|
to to get the compound text style.
|
|
If Xutf8TextListToTextProperty() fails, now ibus-x11 tries to get
|
|
the compound text style with UTF-8 encoding.
|
|
|
|
BUG=https://github.com/ibus/ibus/issues/2422
|
|
---
|
|
client/x11/main.c | 41 ++++++++++++++++++++++++++++++++++-------
|
|
1 file changed, 34 insertions(+), 7 deletions(-)
|
|
|
|
diff --git a/client/x11/main.c b/client/x11/main.c
|
|
index fe30c1d6..6057cc03 100644
|
|
--- a/client/x11/main.c
|
|
+++ b/client/x11/main.c
|
|
@@ -2,7 +2,7 @@
|
|
/* vim:set et sts=4: */
|
|
/* ibus
|
|
* Copyright (C) 2007-2015 Peng Huang <shawn.p.huang@gmail.com>
|
|
- * Copyright (C) 2015-2021 Takao Fujiwara <takao.fujiwara1@gmail.com>
|
|
+ * Copyright (C) 2015-2022 Takao Fujiwara <takao.fujiwara1@gmail.com>
|
|
* Copyright (C) 2007-2015 Red Hat, Inc.
|
|
*
|
|
* main.c:
|
|
@@ -48,6 +48,8 @@
|
|
|
|
#include <getopt.h>
|
|
|
|
+#define ESC_SEQUENCE_ISO10646_1 "\033%G"
|
|
+
|
|
#define LOG(level, fmt_args...) \
|
|
if (g_debug_level >= (level)) { \
|
|
g_debug (fmt_args); \
|
|
@@ -254,9 +256,17 @@ _xim_preedit_callback_draw (XIMS xims, X11IC *x11ic, const gchar *preedit_string
|
|
text.feedback = feedback;
|
|
|
|
if (len > 0) {
|
|
- Xutf8TextListToTextProperty (GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()),
|
|
- (char **)&preedit_string,
|
|
- 1, XCompoundTextStyle, &tp);
|
|
+ int ret = Xutf8TextListToTextProperty (
|
|
+ GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()),
|
|
+ (char **)&preedit_string,
|
|
+ 1, XCompoundTextStyle, &tp);
|
|
+ if (ret == EXIT_FAILURE) {
|
|
+ XFree (tp.value);
|
|
+ tp.value = (unsigned char *)g_strdup_printf (
|
|
+ "%s%s",
|
|
+ ESC_SEQUENCE_ISO10646_1,
|
|
+ preedit_string);
|
|
+ }
|
|
text.encoding_is_wchar = 0;
|
|
text.length = strlen ((char*)tp.value);
|
|
text.string.multi_byte = (char*)tp.value;
|
|
@@ -883,9 +893,26 @@ _context_commit_text_cb (IBusInputContext *context,
|
|
|
|
XTextProperty tp;
|
|
IMCommitStruct cms = {0};
|
|
-
|
|
- Xutf8TextListToTextProperty (GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()),
|
|
- (gchar **)&(text->text), 1, XCompoundTextStyle, &tp);
|
|
+ int ret;
|
|
+
|
|
+ ret = Xutf8TextListToTextProperty (
|
|
+ GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()),
|
|
+ (gchar **)&(text->text), 1, XCompoundTextStyle, &tp);
|
|
+ /* XCompoundTextStyle uses the encoding escaped sequence + encoded chars
|
|
+ * matched to the specified multibyte characters: text->text, and
|
|
+ * libX11.so sorts the encoding sets by locale.
|
|
+ * If an encoded string fails to be matched, ibus-x11 specifies the
|
|
+ * ISO10641-1 encoding and that escaped sequence is "\033%G":
|
|
+ * https://gitlab.freedesktop.org/xorg/lib/libx11/-/blob/master/src/xlibi18n/lcCT.c
|
|
+ * , and the encoding is UTF-8 with utf8_wctomb():
|
|
+ * https://gitlab.freedesktop.org/xorg/lib/libx11/-/blob/master/src/xlibi18n/lcUniConv/utf8.h
|
|
+ */
|
|
+ if (ret == EXIT_FAILURE) {
|
|
+ XFree (tp.value);
|
|
+ tp.value = (unsigned char *)g_strdup_printf ("%s%s",
|
|
+ ESC_SEQUENCE_ISO10646_1,
|
|
+ text->text);
|
|
+ }
|
|
|
|
cms.major_code = XIM_COMMIT;
|
|
cms.icid = x11ic->icid;
|
|
--
|
|
2.35.3
|
|
|
|
From 53d8a826a62f2b43d7361f719fb72e26da8732f8 Mon Sep 17 00:00:00 2001
|
|
From: fujiwarat <takao.fujiwara1@gmail.com>
|
|
Date: Fri, 12 Aug 2022 11:41:16 +0900
|
|
Subject: [PATCH] data/dconf: Revert Emoji shoftcut key to Super-space
|
|
|
|
IBus provides the D-Bus method to override IBus emoji UI and i think
|
|
Super-period is better than Ctrl-period for the emoji shortcut key to
|
|
compare MS-Window, Macintosh. IBus emoji UI connects to the input method
|
|
and provides the language emoji annotations.
|
|
|
|
Seems moving GTK Cotrol-period to gnome-shell Suer-period is difficult
|
|
at present.
|
|
|
|
BUG=https://github.com/ibus/ibus/issues/2390
|
|
BUG=https://gitlab.gnome.org/GNOME/gnome-shell/-/issues/5728
|
|
---
|
|
data/dconf/org.freedesktop.ibus.gschema.xml | 2 +-
|
|
1 file changed, 1 insertion(+), 1 deletion(-)
|
|
|
|
diff --git a/data/dconf/org.freedesktop.ibus.gschema.xml b/data/dconf/org.freedesktop.ibus.gschema.xml
|
|
index 0ece2b4f..4d3b7ae2 100644
|
|
--- a/data/dconf/org.freedesktop.ibus.gschema.xml
|
|
+++ b/data/dconf/org.freedesktop.ibus.gschema.xml
|
|
@@ -248,7 +248,7 @@
|
|
<description>The shortcut keys for turning Unicode typing on or off</description>
|
|
</key>
|
|
<key name="hotkey" type="as">
|
|
- <default>[ '<Control>period', '<Control>semicolon' ]</default>
|
|
+ <default>[ '<Super>period' ]</default>
|
|
<summary>Emoji shortcut keys for gtk_accelerator_parse</summary>
|
|
<description>The shortcut keys for turning emoji typing on or off</description>
|
|
</key>
|
|
--
|
|
2.37.1
|
|
|