diff options
author | Philippe Rouquier <bonfire-app@wanadoo.fr> | 2023-01-23 21:04:51 +0900 |
---|---|---|
committer | fujiwarat <takao.fujiwara1@gmail.com> | 2023-01-23 21:04:51 +0900 |
commit | bd24be4582f67e278fc85e843d39b81629bf7d9b (patch) | |
tree | 0ec1599c95e853df7863ca0b5a59db592c3f5007 | |
parent | d190bc32fe0fe780b66100e5461326973ac7a804 (diff) | |
download | ibus-bd24be4582f67e278fc85e843d39b81629bf7d9b.tar.gz |
Add active-surrounding-text property to IBusEngine
When this property is set to TRUE, ibus daemon will update
surrounding text on every focus(in/out) event which makes
ibus_engine_get_surrounding_text() calls from an engine
code unnecessary.
This property must be set at construct time.
BUG=https://github.com/ibus/ibus/pull/2447
-rw-r--r-- | bus/engineproxy.c | 114 | ||||
-rw-r--r-- | bus/ibusimpl.c | 16 | ||||
-rw-r--r-- | bus/ibusimpl.h | 9 | ||||
-rw-r--r-- | src/ibusengine.c | 47 |
4 files changed, 167 insertions, 19 deletions
diff --git a/bus/engineproxy.c b/bus/engineproxy.c index fd1f34fb..b3e16066 100644 --- a/bus/engineproxy.c +++ b/bus/engineproxy.c @@ -60,6 +60,7 @@ struct _BusEngineProxy { /* cached properties */ IBusPropList *prop_list; gboolean has_focus_id; + gboolean has_active_surrounding_text; }; struct _BusEngineProxyClass { @@ -130,6 +131,8 @@ static void bus_engine_proxy_initable_iface_init *initable_iface); static void bus_engine_proxy_get_has_focus_id (BusEngineProxy *engine); +static void bus_engine_proxy_get_active_surrounding_text + (BusEngineProxy *engine); G_DEFINE_TYPE_WITH_CODE (BusEngineProxy, bus_engine_proxy, IBUS_TYPE_PROXY, G_IMPLEMENT_INTERFACE ( @@ -699,7 +702,6 @@ bus_engine_proxy_new_internal (const gchar *path, 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)); @@ -721,9 +723,12 @@ bus_engine_proxy_new_internal (const gchar *path, 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); + + g_return_val_if_fail (ibus, engine); + + hash_table = bus_ibus_impl_get_engine_focus_id_table (ibus); if (hash_table) { + EngineFocusCategory category; category = (EngineFocusCategory)GPOINTER_TO_INT ( g_hash_table_lookup (hash_table, ibus_engine_desc_get_name (desc))); @@ -734,6 +739,21 @@ bus_engine_proxy_new_internal (const gchar *path, else bus_engine_proxy_get_has_focus_id (engine); } + + hash_table = bus_ibus_impl_get_engine_active_surrounding_text_table (ibus); + if (hash_table) { + EngineSurroundingTextCategory category; + category = (EngineSurroundingTextCategory)GPOINTER_TO_INT ( + g_hash_table_lookup (hash_table, + ibus_engine_desc_get_name (desc))); + if (category == ENGINE_SURROUNDING_TEXT_CATEGORY_HAS_ACTIVE) + engine->has_active_surrounding_text = TRUE; + else if (category == ENGINE_SURROUNDING_TEXT_CATEGORY_NOT_ACTIVE) + engine->has_active_surrounding_text = FALSE; + else + bus_engine_proxy_get_active_surrounding_text (engine); + } + return engine; } @@ -1264,6 +1284,26 @@ bus_engine_proxy_set_content_type (BusEngineProxy *engine, } static void +bus_engine_proxy_get_engine_property (BusEngineProxy *engine, + const gchar *prop_name, + GAsyncReadyCallback callback, + GHashTable *hash_table) +{ + g_assert (BUS_IS_ENGINE_PROXY (engine)); + g_assert (hash_table); + g_dbus_proxy_call ((GDBusProxy *) engine, + "org.freedesktop.DBus.Properties.Get", + g_variant_new ("(ss)", + IBUS_INTERFACE_ENGINE, + prop_name), + G_DBUS_CALL_FLAGS_NONE, + -1, + NULL, + callback, + g_hash_table_ref (hash_table)); +} + +static void _get_has_focus_id_cb (GObject *object, GAsyncResult *res, gpointer user_data) @@ -1299,23 +1339,57 @@ 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); + bus_engine_proxy_get_engine_property ( + engine, + "FocusId", + _get_has_focus_id_cb, + bus_ibus_impl_get_engine_focus_id_table (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)); +static void +_get_active_surrounding_text_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_active_surrounding_text = g_variant_get_boolean (variant); + g_variant_unref (variant); + g_variant_unref (result); + value = GINT_TO_POINTER ( + engine->has_active_surrounding_text + ? ENGINE_SURROUNDING_TEXT_CATEGORY_HAS_ACTIVE + : ENGINE_SURROUNDING_TEXT_CATEGORY_NOT_ACTIVE); + 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_active_surrounding_text (BusEngineProxy *engine) +{ + BusIBusImpl *ibus = BUS_DEFAULT_IBUS; + g_assert (ibus); + bus_engine_proxy_get_engine_property ( + engine, + "ActiveSurroundingText", + _get_active_surrounding_text_cb, + bus_ibus_impl_get_engine_active_surrounding_text_table (ibus)); } /* a macro to generate a function to call a nullary D-Bus method. */ @@ -1348,6 +1422,8 @@ bus_engine_proxy_focus_in (BusEngineProxy *engine, if (engine->has_focus) return; engine->has_focus = TRUE; + if (engine->has_active_surrounding_text) + g_signal_emit (engine, engine_signals[REQUIRE_SURROUNDING_TEXT], 0); if (engine->has_focus_id) { g_dbus_proxy_call ((GDBusProxy *)engine, "FocusInId", @@ -1404,6 +1480,8 @@ bus_engine_proxy_enable (BusEngineProxy *engine) g_assert (BUS_IS_ENGINE_PROXY (engine)); if (!engine->enabled) { engine->enabled = TRUE; + if (engine->has_active_surrounding_text) + g_signal_emit (engine, engine_signals[REQUIRE_SURROUNDING_TEXT], 0); g_dbus_proxy_call ((GDBusProxy *)engine, "Enable", NULL, diff --git a/bus/ibusimpl.c b/bus/ibusimpl.c index 8a443545..6df86c3f 100644 --- a/bus/ibusimpl.c +++ b/bus/ibusimpl.c @@ -73,6 +73,7 @@ struct _BusIBusImpl { GHashTable *engine_table; GHashTable *engine_focus_id_table; + GHashTable *engine_active_surrounding_text_table; BusInputContext *focused_context; BusPanelProxy *panel; @@ -599,6 +600,8 @@ bus_ibus_impl_init (BusIBusImpl *ibus) 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); + ibus->engine_active_surrounding_text_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) @@ -681,6 +684,11 @@ bus_ibus_impl_destroy (BusIBusImpl *ibus) bus_ibus_impl_registry_destroy (ibus); + if (ibus->engine_active_surrounding_text_table != NULL) { + g_hash_table_destroy (ibus->engine_active_surrounding_text_table); + ibus->engine_active_surrounding_text_table = NULL; + } + IBUS_OBJECT_CLASS (bus_ibus_impl_parent_class)->destroy (IBUS_OBJECT (ibus)); } @@ -2397,3 +2405,11 @@ bus_ibus_impl_get_engine_focus_id_table (BusIBusImpl *ibus) return ibus->engine_focus_id_table; } +GHashTable * +bus_ibus_impl_get_engine_active_surrounding_text_table (BusIBusImpl *ibus) +{ + + g_assert (BUS_IS_IBUS_IMPL (ibus)); + + return ibus->engine_active_surrounding_text_table; +} diff --git a/bus/ibusimpl.h b/bus/ibusimpl.h index cbe6856d..93a854de 100644 --- a/bus/ibusimpl.h +++ b/bus/ibusimpl.h @@ -66,6 +66,13 @@ typedef enum ENGINE_FOCUS_CATEGORY_HAS_ID } EngineFocusCategory; +typedef enum +{ + ENGINE_SURROUNDING_TEXT_CATEGORY_NONE = 0, + ENGINE_SURROUNDING_TEXT_CATEGORY_NOT_ACTIVE, + ENGINE_SURROUNDING_TEXT_CATEGORY_HAS_ACTIVE +} EngineSurroundingTextCategory; + GType bus_ibus_impl_get_type (void); /** @@ -91,5 +98,7 @@ BusInputContext *bus_ibus_impl_get_focused_input_context (BusIBusImpl *ibus); GHashTable *bus_ibus_impl_get_engine_focus_id_table (BusIBusImpl *ibus); +GHashTable *bus_ibus_impl_get_engine_active_surrounding_text_table + (BusIBusImpl *ibus); G_END_DECLS #endif diff --git a/src/ibusengine.c b/src/ibusengine.c index 7c797103..cc12ac5a 100644 --- a/src/ibusengine.c +++ b/src/ibusengine.c @@ -64,6 +64,7 @@ enum { PROP_0, PROP_ENGINE_NAME, PROP_HAS_FOCUS_ID, + PROP_ACTIVE_SURROUNDING_TEXT, }; @@ -86,6 +87,7 @@ struct _IBusEnginePrivate { gboolean enable_extension; gchar *current_extension_name; gboolean has_focus_id; + gboolean has_active_surrounding_text; }; @@ -303,6 +305,7 @@ static const gchar introspection_xml[] = /* FIXME properties */ " <property name='ContentType' type='(uu)' access='write' />" " <property name='FocusId' type='(b)' access='read' />" + " <property name='ActiveSurroundingText' type='(b)' access='read' />" " </interface>" "</node>"; @@ -391,6 +394,23 @@ ibus_engine_class_init (IBusEngineClass *class) G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)); + /** + * IBusEngine:active-surrounding-text: + * + * When this property is set to %TRUE, "RequireSurroundingText" D-Bus + * signal will be called by ibus-daemon on every focus-in/out event, with + * no need for the engine to call ibus_engine_get_surrounding_text(). + * This property can only be set at construct time. + */ + g_object_class_install_property (gobject_class, + PROP_ACTIVE_SURROUNDING_TEXT, + g_param_spec_boolean ("active-surrounding-text", + "enable surrounding text update by focus event", + "Enable surrounding text update by focus event", + FALSE, + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT_ONLY)); + /* install signals */ /** * IBusEngine::process-key-event: @@ -988,6 +1008,9 @@ ibus_engine_set_property (IBusEngine *engine, case PROP_HAS_FOCUS_ID: engine->priv->has_focus_id = g_value_get_boolean (value); break; + case PROP_ACTIVE_SURROUNDING_TEXT: + engine->priv->has_active_surrounding_text = g_value_get_boolean (value); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (engine, prop_id, pspec); } @@ -1006,6 +1029,9 @@ ibus_engine_get_property (IBusEngine *engine, case PROP_HAS_FOCUS_ID: g_value_set_boolean (value, engine->priv->has_focus_id); break; + case PROP_ACTIVE_SURROUNDING_TEXT: + g_value_set_boolean (value, engine->priv->has_active_surrounding_text); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (engine, prop_id, pspec); } @@ -1446,6 +1472,24 @@ ibus_engine_service_method_call (IBusService *service, } /** + * _ibus_engine_get_active_surrounding_text: + * + * Implement the "ActiveSurroundingText" method call of the + * org.freedesktop.IBus interface. + */ +static GVariant * +_ibus_engine_get_active_surrounding_text (IBusEngine *engine, + GDBusConnection *connection, + GError **error) +{ + if (error) { + *error = NULL; + } + + return g_variant_new_boolean (engine->priv->has_active_surrounding_text); +} + +/** * _ibus_engine_has_focus_id: * * Implement the "FocusId" method call of the org.freedesktop.IBus interface. @@ -1478,7 +1522,8 @@ ibus_engine_service_get_property (IBusService *service, GDBusConnection *, GError **); } methods [] = { - { "FocusId", _ibus_engine_has_focus_id }, + { "FocusId", _ibus_engine_has_focus_id }, + { "ActiveSurroundingText", _ibus_engine_get_active_surrounding_text }, }; if (g_strcmp0 (interface_name, IBUS_INTERFACE_ENGINE) != 0) { |