Implement new process_key_event for ibus-x11
This commit is contained in:
parent
c0c536452c
commit
82f34afdef
432
ibus-HEAD.patch
432
ibus-HEAD.patch
@ -318,3 +318,435 @@ index a4529c88..9400e9ba 100644
|
|||||||
--
|
--
|
||||||
2.37.3
|
2.37.3
|
||||||
|
|
||||||
|
From 506ac9993d5166196b7c4e9bfa9fb0f9d3792ffa Mon Sep 17 00:00:00 2001
|
||||||
|
From: fujiwarat <takao.fujiwara1@gmail.com>
|
||||||
|
Date: Thu, 10 Nov 2022 18:38:05 +0900
|
||||||
|
Subject: [PATCH] client/x11: Implement new process_key_event for ibus-x11
|
||||||
|
|
||||||
|
The new process_key_event is ported from GTK4 to X11 because
|
||||||
|
hangul maintainers wish to delete forward_key_event as much as possible
|
||||||
|
and currently we could apply forward_key_event to the sync mode only
|
||||||
|
and the new process_key_event is a new async key event process in X11
|
||||||
|
and hangul might disable forward_key_event by default.
|
||||||
|
|
||||||
|
Now the definition of IBUS_CAP_SYNC_PROCESS_KEY_V2 capability is changed
|
||||||
|
to set only if the sync mode.
|
||||||
|
|
||||||
|
Also switch a heavy GMainLoop to the light GSource.
|
||||||
|
|
||||||
|
Fixes: https://github.com/ibus/ibus/commit/c957c5f
|
||||||
|
---
|
||||||
|
client/gtk2/ibusimcontext.c | 61 ++++++++++----
|
||||||
|
client/x11/main.c | 157 +++++++++++++++++++++++++++++++-----
|
||||||
|
src/ibustypes.h | 1 +
|
||||||
|
3 files changed, 184 insertions(+), 35 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/client/gtk2/ibusimcontext.c b/client/gtk2/ibusimcontext.c
|
||||||
|
index 6e338157..1f3723e6 100644
|
||||||
|
--- a/client/gtk2/ibusimcontext.c
|
||||||
|
+++ b/client/gtk2/ibusimcontext.c
|
||||||
|
@@ -382,8 +382,9 @@ typedef struct {
|
||||||
|
} ProcessKeyEventData;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
- GMainLoop *loop;
|
||||||
|
- gboolean retval;
|
||||||
|
+ int count;
|
||||||
|
+ guint count_cb_id;
|
||||||
|
+ gboolean retval;
|
||||||
|
} ProcessKeyEventReplyData;
|
||||||
|
|
||||||
|
static void
|
||||||
|
@@ -453,7 +454,23 @@ _process_key_event_reply_done (GObject *object,
|
||||||
|
}
|
||||||
|
g_return_if_fail (data);
|
||||||
|
data->retval = retval;
|
||||||
|
- g_main_loop_quit (data->loop);
|
||||||
|
+ data->count = 0;
|
||||||
|
+ g_source_remove (data->count_cb_id);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static gboolean
|
||||||
|
+_process_key_event_count_cb (gpointer user_data)
|
||||||
|
+{
|
||||||
|
+ ProcessKeyEventReplyData *data = (ProcessKeyEventReplyData *)user_data;
|
||||||
|
+ g_return_val_if_fail (data, G_SOURCE_REMOVE);
|
||||||
|
+ if (!data->count)
|
||||||
|
+ return G_SOURCE_REMOVE;
|
||||||
|
+ /* Wait for about 10 secs. */
|
||||||
|
+ if (data->count++ == 10000) {
|
||||||
|
+ data->count = 0;
|
||||||
|
+ return G_SOURCE_REMOVE;
|
||||||
|
+ }
|
||||||
|
+ return G_SOURCE_CONTINUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
@@ -496,10 +513,10 @@ _process_key_event (IBusInputContext *context,
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 2: {
|
||||||
|
- GMainLoop *loop = g_main_loop_new (NULL, TRUE);
|
||||||
|
+ GSource *source = g_timeout_source_new (1);
|
||||||
|
ProcessKeyEventReplyData *data = NULL;
|
||||||
|
|
||||||
|
- if (loop)
|
||||||
|
+ if (source)
|
||||||
|
data = g_slice_new0 (ProcessKeyEventReplyData);
|
||||||
|
if (!data) {
|
||||||
|
g_warning ("Cannot wait for the reply of the process key event.");
|
||||||
|
@@ -507,11 +524,14 @@ _process_key_event (IBusInputContext *context,
|
||||||
|
keyval,
|
||||||
|
keycode - 8,
|
||||||
|
state);
|
||||||
|
- if (loop)
|
||||||
|
- g_main_loop_quit (loop);
|
||||||
|
+ if (source)
|
||||||
|
+ g_source_destroy (source);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
- data->loop = loop;
|
||||||
|
+ data->count = 1;
|
||||||
|
+ g_source_attach (source, NULL);
|
||||||
|
+ g_source_unref (source);
|
||||||
|
+ data->count_cb_id = g_source_get_id (source);
|
||||||
|
ibus_input_context_process_key_event_async (context,
|
||||||
|
keyval,
|
||||||
|
keycode - 8,
|
||||||
|
@@ -520,7 +540,14 @@ _process_key_event (IBusInputContext *context,
|
||||||
|
NULL,
|
||||||
|
_process_key_event_reply_done,
|
||||||
|
data);
|
||||||
|
- g_main_loop_run (loop);
|
||||||
|
+ g_source_set_callback (source, _process_key_event_count_cb, data, NULL);
|
||||||
|
+ while (data->count)
|
||||||
|
+ g_main_context_iteration (NULL, TRUE);
|
||||||
|
+ if (source->ref_count > 0) {
|
||||||
|
+ /* g_source_get_id() could causes a SEGV */
|
||||||
|
+ g_info ("Broken GSource.ref_count and maybe a timing issue in %p.",
|
||||||
|
+ source);
|
||||||
|
+ }
|
||||||
|
retval = data->retval;
|
||||||
|
g_slice_free (ProcessKeyEventReplyData, data);
|
||||||
|
break;
|
||||||
|
@@ -994,8 +1021,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;
|
||||||
|
+ if (_use_sync_mode == 1)
|
||||||
|
+ ibusimcontext->caps |= IBUS_CAP_SYNC_PROCESS_KEY_V2;
|
||||||
|
|
||||||
|
ibusimcontext->events_queue = g_queue_new ();
|
||||||
|
|
||||||
|
@@ -1338,7 +1365,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 == 1)
|
||||||
|
+ if (_use_sync_mode != 0)
|
||||||
|
ibus_im_context_clear_preedit_text (ibusimcontext);
|
||||||
|
ibus_input_context_reset (ibusimcontext->ibuscontext);
|
||||||
|
}
|
||||||
|
@@ -1453,7 +1480,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 != 1)
|
||||||
|
+ if (ibusimcontext->use_button_press_event && _use_sync_mode == 0)
|
||||||
|
_connect_button_press_event (ibusimcontext, FALSE);
|
||||||
|
#endif
|
||||||
|
g_object_unref (ibusimcontext->client_window);
|
||||||
|
@@ -1463,7 +1490,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 != 1)
|
||||||
|
+ if (!ibusimcontext->use_button_press_event && _use_sync_mode == 0)
|
||||||
|
_connect_button_press_event (ibusimcontext, TRUE);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
@@ -2085,7 +2112,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 != 1) {
|
||||||
|
+ _use_sync_mode == 0) {
|
||||||
|
if (ibusimcontext->client_window) {
|
||||||
|
_connect_button_press_event (ibusimcontext, TRUE);
|
||||||
|
}
|
||||||
|
@@ -2459,8 +2486,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;
|
||||||
|
+ if (_use_sync_mode == 1)
|
||||||
|
+ caps |= IBUS_CAP_SYNC_PROCESS_KEY_V2;
|
||||||
|
ibus_input_context_set_capabilities (_fake_context, caps);
|
||||||
|
|
||||||
|
/* focus in/out the fake context */
|
||||||
|
diff --git a/client/x11/main.c b/client/x11/main.c
|
||||||
|
index 6057cc03..905fd251 100644
|
||||||
|
--- a/client/x11/main.c
|
||||||
|
+++ b/client/x11/main.c
|
||||||
|
@@ -124,7 +124,7 @@ static gint g_debug_level = 0;
|
||||||
|
|
||||||
|
static IBusBus *_bus = NULL;
|
||||||
|
|
||||||
|
-static gboolean _use_sync_mode = TRUE;
|
||||||
|
+static char _use_sync_mode = 2;
|
||||||
|
|
||||||
|
static void
|
||||||
|
_xim_preedit_start (XIMS xims, const X11IC *x11ic)
|
||||||
|
@@ -331,6 +331,7 @@ xim_create_ic (XIMS xims, IMChangeICStruct *call_data)
|
||||||
|
{
|
||||||
|
static int base_icid = 1;
|
||||||
|
X11IC *x11ic;
|
||||||
|
+ guint32 capabilities = IBUS_CAP_FOCUS;
|
||||||
|
|
||||||
|
call_data->icid = base_icid ++;
|
||||||
|
|
||||||
|
@@ -375,12 +376,11 @@ xim_create_ic (XIMS xims, IMChangeICStruct *call_data)
|
||||||
|
G_CALLBACK (_context_disabled_cb), x11ic);
|
||||||
|
|
||||||
|
|
||||||
|
- if (x11ic->input_style & XIMPreeditCallbacks) {
|
||||||
|
- ibus_input_context_set_capabilities (x11ic->context, IBUS_CAP_FOCUS | IBUS_CAP_PREEDIT_TEXT);
|
||||||
|
- }
|
||||||
|
- else {
|
||||||
|
- ibus_input_context_set_capabilities (x11ic->context, IBUS_CAP_FOCUS);
|
||||||
|
- }
|
||||||
|
+ if (x11ic->input_style & XIMPreeditCallbacks)
|
||||||
|
+ capabilities |= IBUS_CAP_PREEDIT_TEXT;
|
||||||
|
+ if (_use_sync_mode == 1)
|
||||||
|
+ capabilities |= IBUS_CAP_SYNC_PROCESS_KEY_V2;
|
||||||
|
+ ibus_input_context_set_capabilities (x11ic->context, capabilities);
|
||||||
|
|
||||||
|
g_hash_table_insert (_x11_ic_table,
|
||||||
|
GINT_TO_POINTER (x11ic->icid), (gpointer)x11ic);
|
||||||
|
@@ -461,6 +461,13 @@ xim_unset_ic_focus (XIMS xims, IMChangeFocusStruct *call_data)
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
+typedef struct {
|
||||||
|
+ IMForwardEventStruct *pfe;
|
||||||
|
+ int count;
|
||||||
|
+ guint count_cb_id;
|
||||||
|
+ gboolean retval;
|
||||||
|
+} ProcessKeyEventReplyData;
|
||||||
|
+
|
||||||
|
static void
|
||||||
|
_process_key_event_done (GObject *object,
|
||||||
|
GAsyncResult *res,
|
||||||
|
@@ -493,6 +500,43 @@ _process_key_event_done (GObject *object,
|
||||||
|
g_slice_free (IMForwardEventStruct, pfe);
|
||||||
|
}
|
||||||
|
|
||||||
|
+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;
|
||||||
|
+ data->count = 0;
|
||||||
|
+ g_source_remove (data->count_cb_id);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static gboolean
|
||||||
|
+_process_key_event_count_cb (gpointer user_data)
|
||||||
|
+{
|
||||||
|
+ ProcessKeyEventReplyData *data = (ProcessKeyEventReplyData *)user_data;
|
||||||
|
+ g_return_val_if_fail (data, G_SOURCE_REMOVE);
|
||||||
|
+ if (!data->count)
|
||||||
|
+ return G_SOURCE_REMOVE;
|
||||||
|
+ /* Wait for about 10 secs. */
|
||||||
|
+ if (data->count++ == 10000) {
|
||||||
|
+ data->count = 0;
|
||||||
|
+ return G_SOURCE_REMOVE;
|
||||||
|
+ }
|
||||||
|
+ return G_SOURCE_CONTINUE;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
static int
|
||||||
|
xim_forward_event (XIMS xims, IMForwardEventStruct *call_data)
|
||||||
|
{
|
||||||
|
@@ -520,14 +564,15 @@ xim_forward_event (XIMS xims, IMForwardEventStruct *call_data)
|
||||||
|
event.state |= IBUS_RELEASE_MASK;
|
||||||
|
}
|
||||||
|
|
||||||
|
- if (_use_sync_mode) {
|
||||||
|
+ switch (_use_sync_mode) {
|
||||||
|
+ case 1: {
|
||||||
|
retval = ibus_input_context_process_key_event (
|
||||||
|
x11ic->context,
|
||||||
|
event.keyval,
|
||||||
|
event.hardware_keycode - 8,
|
||||||
|
event.state);
|
||||||
|
if (retval) {
|
||||||
|
- if (! x11ic->has_preedit_area) {
|
||||||
|
+ if (!x11ic->has_preedit_area) {
|
||||||
|
_xim_set_cursor_location (x11ic);
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
@@ -546,8 +591,80 @@ xim_forward_event (XIMS xims, IMForwardEventStruct *call_data)
|
||||||
|
IMForwardEvent (_xims, (XPointer) &fe);
|
||||||
|
|
||||||
|
retval = 1;
|
||||||
|
+ break;
|
||||||
|
}
|
||||||
|
- else {
|
||||||
|
+ case 2: {
|
||||||
|
+ GSource *source = g_timeout_source_new (1);
|
||||||
|
+ ProcessKeyEventReplyData *data = NULL;
|
||||||
|
+ IMForwardEventStruct fe;
|
||||||
|
+
|
||||||
|
+ if (source)
|
||||||
|
+ 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 (
|
||||||
|
+ x11ic->context,
|
||||||
|
+ event.keyval,
|
||||||
|
+ event.hardware_keycode - 8,
|
||||||
|
+ event.state);
|
||||||
|
+ if (source)
|
||||||
|
+ g_source_destroy (source);
|
||||||
|
+ } else {
|
||||||
|
+ CARD16 connect_id = x11ic->connect_id;
|
||||||
|
+ data->count = 1;
|
||||||
|
+ g_source_attach (source, NULL);
|
||||||
|
+ g_source_unref (source);
|
||||||
|
+ data->count_cb_id = g_source_get_id (source);
|
||||||
|
+ ibus_input_context_process_key_event_async (
|
||||||
|
+ x11ic->context,
|
||||||
|
+ event.keyval,
|
||||||
|
+ event.hardware_keycode - 8,
|
||||||
|
+ event.state,
|
||||||
|
+ -1,
|
||||||
|
+ NULL,
|
||||||
|
+ _process_key_event_reply_done,
|
||||||
|
+ data);
|
||||||
|
+ g_source_set_callback (source, _process_key_event_count_cb,
|
||||||
|
+ data, NULL);
|
||||||
|
+ while (data->count)
|
||||||
|
+ g_main_context_iteration (NULL, TRUE);
|
||||||
|
+ if (source->ref_count > 0) {
|
||||||
|
+ /* g_source_get_id() could causes a SEGV */
|
||||||
|
+ g_info ("Broken GSource.ref_count and maybe a timing "
|
||||||
|
+ "issue in %p.", source);
|
||||||
|
+ }
|
||||||
|
+ retval = data->retval;
|
||||||
|
+ g_slice_free (ProcessKeyEventReplyData, data);
|
||||||
|
+
|
||||||
|
+ if (g_hash_table_lookup (_connections,
|
||||||
|
+ GINT_TO_POINTER ((gint)connect_id))
|
||||||
|
+ == NULL) {
|
||||||
|
+ return 1;
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ if (retval) {
|
||||||
|
+ if (! x11ic->has_preedit_area) {
|
||||||
|
+ _xim_set_cursor_location (x11ic);
|
||||||
|
+ }
|
||||||
|
+ return 1;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ memset (&fe, 0, sizeof (fe));
|
||||||
|
+
|
||||||
|
+ fe.major_code = XIM_FORWARD_EVENT;
|
||||||
|
+ fe.icid = x11ic->icid;
|
||||||
|
+ fe.connect_id = x11ic->connect_id;
|
||||||
|
+ fe.sync_bit = 0;
|
||||||
|
+ fe.serial_number = 0L;
|
||||||
|
+ fe.event = call_data->event;
|
||||||
|
+
|
||||||
|
+ IMForwardEvent (_xims, (XPointer) &fe);
|
||||||
|
+
|
||||||
|
+ retval = 1;
|
||||||
|
+ break;
|
||||||
|
+ }
|
||||||
|
+ default: {
|
||||||
|
IMForwardEventStruct *pfe;
|
||||||
|
|
||||||
|
pfe = g_slice_new0 (IMForwardEventStruct);
|
||||||
|
@@ -569,6 +686,7 @@ xim_forward_event (XIMS xims, IMForwardEventStruct *call_data)
|
||||||
|
pfe);
|
||||||
|
retval = 1;
|
||||||
|
}
|
||||||
|
+ }
|
||||||
|
return retval;
|
||||||
|
}
|
||||||
|
|
||||||
|
@@ -1026,23 +1144,26 @@ _context_disabled_cb (IBusInputContext *context,
|
||||||
|
_xim_preedit_end (_xims, x11ic);
|
||||||
|
}
|
||||||
|
|
||||||
|
-static gboolean
|
||||||
|
-_get_boolean_env(const gchar *name,
|
||||||
|
- gboolean defval)
|
||||||
|
+static char
|
||||||
|
+_get_char_env (const gchar *name,
|
||||||
|
+ char 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 0;
|
||||||
|
+ } else if (!g_strcmp0 (value, "2")) {
|
||||||
|
+ return 2;
|
||||||
|
+ }
|
||||||
|
|
||||||
|
- return TRUE;
|
||||||
|
+ return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
@@ -1059,7 +1180,7 @@ _init_ibus (void)
|
||||||
|
G_CALLBACK (_bus_disconnected_cb), NULL);
|
||||||
|
|
||||||
|
/* https://github.com/ibus/ibus/issues/1713 */
|
||||||
|
- _use_sync_mode = _get_boolean_env ("IBUS_ENABLE_SYNC_MODE", TRUE);
|
||||||
|
+ _use_sync_mode = _get_char_env ("IBUS_ENABLE_SYNC_MODE", 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
diff --git a/src/ibustypes.h b/src/ibustypes.h
|
||||||
|
index a8eee319..ba2a0010 100644
|
||||||
|
--- a/src/ibustypes.h
|
||||||
|
+++ b/src/ibustypes.h
|
||||||
|
@@ -124,6 +124,7 @@ typedef enum {
|
||||||
|
IBUS_CAP_SURROUNDING_TEXT = 1 << 5,
|
||||||
|
IBUS_CAP_OSK = 1 << 6,
|
||||||
|
IBUS_CAP_SYNC_PROCESS_KEY = 1 << 7,
|
||||||
|
+ IBUS_CAP_SYNC_PROCESS_KEY_V2 = IBUS_CAP_SYNC_PROCESS_KEY,
|
||||||
|
} IBusCapabilite;
|
||||||
|
|
||||||
|
/**
|
||||||
|
--
|
||||||
|
2.37.3
|
||||||
|
|
||||||
|
@ -39,7 +39,7 @@
|
|||||||
|
|
||||||
Name: ibus
|
Name: ibus
|
||||||
Version: 1.5.27
|
Version: 1.5.27
|
||||||
Release: 5%{?dist}
|
Release: 6%{?dist}
|
||||||
Summary: Intelligent Input Bus for Linux OS
|
Summary: Intelligent Input Bus for Linux OS
|
||||||
License: LGPL-2.0-or-later
|
License: LGPL-2.0-or-later
|
||||||
URL: https://github.com/ibus/%name/wiki
|
URL: https://github.com/ibus/%name/wiki
|
||||||
@ -523,6 +523,9 @@ dconf update || :
|
|||||||
%{_datadir}/installed-tests/ibus
|
%{_datadir}/installed-tests/ibus
|
||||||
|
|
||||||
%changelog
|
%changelog
|
||||||
|
* Thu Nov 24 2022 Takao Fujiwara <tfujiwar@redhat.com> - 1.5.27-6
|
||||||
|
- Implement new process_key_event for ibus-x11
|
||||||
|
|
||||||
* Wed Nov 16 2022 Takao Fujiwara <tfujiwar@redhat.com> - 1.5.27-5
|
* Wed Nov 16 2022 Takao Fujiwara <tfujiwar@redhat.com> - 1.5.27-5
|
||||||
- Migrate license tag to SPDX
|
- Migrate license tag to SPDX
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user