summaryrefslogtreecommitdiff
path: root/bus
diff options
context:
space:
mode:
authorDaiki Ueno <ueno@unixuser.org>2013-08-14 13:29:45 +0200
committerDaiki Ueno <ueno@unixuser.org>2013-08-14 13:29:45 +0200
commit3b3a7ceccbf75f36dee0df45589d79f7e96131f4 (patch)
tree7e230ec8fde7008482dbd30f12497da11d31bc48 /bus
parent5136dbc59fd3048445826c534fd6b5f3f8ca6b1e (diff)
Notify engines of the content-type of input context
Add a new D-Bus method SetContentType to InputContext and Engine, to notify engines of the content-type (primary purpose and hints) of input context. This is useful to implement intelligent features in engines, such as automatic input-mode switch and text prediction. The "purpose" and "hints" arguments are compatible with GtkInputPurpose and GtkInputHints: https://developer.gnome.org/gtk3/unstable/GtkEntry.html#GtkInputPurpose https://developer.gnome.org/gtk3/unstable/GtkEntry.html#GtkInputHints and the API is similar to the content_type event in the Wayland Input Method Framework: http://cgit.freedesktop.org/wayland/weston/tree/protocol/input-method.xml#n202 BUG= Review URL: https://codereview.appspot.com/11422043
Diffstat (limited to 'bus')
-rw-r--r--bus/engineproxy.c40
-rw-r--r--bus/engineproxy.h221
-rw-r--r--bus/inputcontext.c249
3 files changed, 374 insertions, 136 deletions
diff --git a/bus/engineproxy.c b/bus/engineproxy.c
index 200b89be..19c28616 100644
--- a/bus/engineproxy.c
+++ b/bus/engineproxy.c
@@ -1,8 +1,8 @@
/* -*- mode: C; c-basic-offset: 4; indent-tabs-mode: nil; -*- */
/* vim:set et sts=4: */
/* ibus - The Input Bus
- * Copyright (C) 2008-2010 Peng Huang <shawn.p.huang@gmail.com>
- * Copyright (C) 2008-2010 Red Hat, Inc.
+ * Copyright (C) 2008-2013 Peng Huang <shawn.p.huang@gmail.com>
+ * Copyright (C) 2008-2013 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
@@ -642,8 +642,7 @@ bus_engine_proxy_new_internal (const gchar *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 |
- G_DBUS_PROXY_FLAGS_DO_NOT_LOAD_PROPERTIES;
+ GDBusProxyFlags flags = G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START;
BusEngineProxy *engine =
(BusEngineProxy *) g_initable_new (BUS_TYPE_ENGINE_PROXY,
NULL,
@@ -1134,6 +1133,39 @@ void bus_engine_proxy_set_surrounding_text (BusEngineProxy *engine,
}
}
+void
+bus_engine_proxy_set_content_type (BusEngineProxy *engine,
+ guint purpose,
+ guint hints)
+{
+ g_assert (BUS_IS_ENGINE_PROXY (engine));
+
+ GVariant *cached_content_type =
+ g_dbus_proxy_get_cached_property ((GDBusProxy *) engine,
+ "ContentType");
+ GVariant *content_type = g_variant_new ("(uu)", purpose, hints);
+
+ g_variant_ref_sink (content_type);
+ if (cached_content_type == NULL ||
+ !g_variant_equal (content_type, cached_content_type)) {
+ g_dbus_proxy_call ((GDBusProxy *) engine,
+ "org.freedesktop.DBus.Properties.Set",
+ g_variant_new ("(ssv)",
+ IBUS_INTERFACE_ENGINE,
+ "ContentType",
+ content_type),
+ G_DBUS_CALL_FLAGS_NONE,
+ -1,
+ NULL,
+ NULL,
+ NULL);
+ }
+
+ if (cached_content_type != NULL)
+ g_variant_unref (cached_content_type);
+ g_variant_unref (content_type);
+}
+
/* a macro to generate a function to call a nullary D-Bus method. */
#define DEFINE_FUNCTION(Name, name) \
void \
diff --git a/bus/engineproxy.h b/bus/engineproxy.h
index 8fe025db..528e61b7 100644
--- a/bus/engineproxy.h
+++ b/bus/engineproxy.h
@@ -1,8 +1,8 @@
/* -*- mode: C; c-basic-offset: 4; indent-tabs-mode: nil; -*- */
/* vim:set et sts=4: */
/* ibus - The Input Bus
- * Copyright (C) 2008-2010 Peng Huang <shawn.p.huang@gmail.com>
- * Copyright (C) 2008-2010 Red Hat, Inc.
+ * Copyright (C) 2008-2013 Peng Huang <shawn.p.huang@gmail.com>
+ * Copyright (C) 2008-2013 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
@@ -49,7 +49,7 @@ G_BEGIN_DECLS
typedef struct _BusEngineProxy BusEngineProxy;
typedef struct _BusEngineProxyClass BusEngineProxyClass;
-GType bus_engine_proxy_get_type (void);
+GType bus_engine_proxy_get_type (void);
/**
* bus_engine_proxy_new:
@@ -59,196 +59,271 @@ GType bus_engine_proxy_get_type (void);
* @callback: a function to be called when the method invocation is done.
* @user_data: a pointer that will be passed to the callback.
*/
-void bus_engine_proxy_new (IBusEngineDesc *desc,
- gint timeout,
- GCancellable *cancellable,
- GAsyncReadyCallback callback,
- gpointer user_data);
+void bus_engine_proxy_new (IBusEngineDesc *desc,
+ gint timeout,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data);
/**
* bus_engine_proxy_new_finish:
- * @returns: On success, return an engine object. On error, return NULL.
+ * @res: A #GAsyncResult.
+ * @error: Return location for error or %NULL.
+ * @returns: On success, return an engine object. On error, return %NULL.
*
- * Get the result of bus_engine_proxy_new call. You have to call this function in the GAsyncReadyCallback function.
+ * Get the result of bus_engine_proxy_new() call. You have to call this
+ * function in the #GAsyncReadyCallback function.
*/
-BusEngineProxy *bus_engine_proxy_new_finish (GAsyncResult *res,
- GError **error);
+BusEngineProxy *bus_engine_proxy_new_finish (GAsyncResult *res,
+ GError **error);
/**
* bus_engine_proxy_get_desc:
+ * @engine: A #BusEngineProxy.
*
- * Get an IBusEngineDesc object associated with the engine.
+ * Get an #IBusEngineDesc object associated with the engine.
*/
-IBusEngineDesc *bus_engine_proxy_get_desc (BusEngineProxy *engine);
+IBusEngineDesc *bus_engine_proxy_get_desc (BusEngineProxy *engine);
/**
* bus_engine_proxy_process_key_event:
- * @callback: a function to be called when the method invocation is done.
+ * @engine: A #BusEngineProxy.
+ * @keyval: Key symbol of the key press.
+ * @keycode: KeyCode of the key press.
+ * @state: Key modifier flags.
+ * @callback: A function to be called when the method invocation is done.
+ * @user_data: Data supplied to @callback.
*
* Call "ProcessKeyEvent" method of an engine asynchronously.
*/
-void bus_engine_proxy_process_key_event (BusEngineProxy *engine,
- guint keyval,
- guint keycode,
- guint state,
- GAsyncReadyCallback callback,
- gpointer user_data);
+void bus_engine_proxy_process_key_event
+ (BusEngineProxy *engine,
+ guint keyval,
+ guint keycode,
+ guint state,
+ GAsyncReadyCallback callback,
+ gpointer user_data);
/**
* bus_engine_proxy_set_cursor_location:
+ * @engine: A #BusEngineProxy.
+ * @x: X coordinate of the cursor.
+ * @y: Y coordinate of the cursor.
+ * @w: Width of the cursor.
+ * @h: Height of the cursor.
*
- * Call "SetCursorLocation" method of an engine asynchronously. Unlike bus_engine_proxy_process_key_event, there's no way to know the
- * result of the method invocation. If the same coordinate is given twice or more, the function does nothing from the second time.
+ * Call "SetCursorLocation" method of an engine asynchronously. Unlike
+ * bus_engine_proxy_process_key_event(), there's no way to know the
+ * result of the method invocation. If the same coordinate is given
+ * twice or more, the function does nothing from the second time.
*/
-void bus_engine_proxy_set_cursor_location
- (BusEngineProxy *engine,
- gint x,
- gint y,
- gint w,
- gint h);
+void bus_engine_proxy_set_cursor_location
+ (BusEngineProxy *engine,
+ gint x,
+ gint y,
+ gint w,
+ gint h);
/**
* bus_engine_proxy_focus_in:
+ * @engine: A #BusEngineProxy.
*
- * Call "FocusIn" method of an engine asynchronously. Do nothing if the engine already has a focus.
+ * 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);
/**
* bus_engine_proxy_focus_out:
+ * @engine: A #BusEngineProxy.
*
- * Call "FocusOut" method of an engine asynchronously. Do nothing if the engine does not have a focus.
+ * 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);
/**
* bus_engine_proxy_reset:
+ * @engine: A #BusEngineProxy.
*
* Call "Reset" method of an engine asynchronously.
*/
-void bus_engine_proxy_reset (BusEngineProxy *engine);
+void bus_engine_proxy_reset (BusEngineProxy *engine);
/**
* bus_engine_proxy_set_capabilities:
+ * @engine: A #BusEngineProxy.
+ * @caps: Capabilities flags of IBusEngine, see #IBusCapabilite.
*
* Call "SetCapabilities" method of an engine asynchronously.
*/
-void bus_engine_proxy_set_capabilities (BusEngineProxy *engine,
- guint caps);
+void bus_engine_proxy_set_capabilities
+ (BusEngineProxy *engine,
+ guint caps);
/**
* bus_engine_proxy_page_up:
+ * @engine: A #BusEngineProxy.
*
* Call "PageUp" method of an engine asynchronously.
*/
-void bus_engine_proxy_page_up (BusEngineProxy *engine);
+void bus_engine_proxy_page_up (BusEngineProxy *engine);
/**
* bus_engine_proxy_page_down:
+ * @engine: A #BusEngineProxy.
*
* Call "PageDown" method of an engine asynchronously.
*/
-void bus_engine_proxy_page_down (BusEngineProxy *engine);
+void bus_engine_proxy_page_down (BusEngineProxy *engine);
/**
* bus_engine_proxy_cursor_up:
+ * @engine: A #BusEngineProxy.
*
* Call "CursorUp" method of an engine asynchronously.
*/
-void bus_engine_proxy_cursor_up (BusEngineProxy *engine);
+void bus_engine_proxy_cursor_up (BusEngineProxy *engine);
/**
* bus_engine_proxy_cursor_down:
+ * @engine: A #BusEngineProxy.
*
* Call "CursorDown" method of an engine asynchronously.
*/
-void bus_engine_proxy_cursor_down (BusEngineProxy *engine);
+void bus_engine_proxy_cursor_down (BusEngineProxy *engine);
/**
* bus_engine_proxy_candidate_clicked:
+ * @engine: A #BusEngineProxy.
+ * @index: Index of candidate be clicked.
+ * @button: Mouse button.
+ * @state: Keyboard state.
*
* Call "CandidateClicked" method of an engine asynchronously.
*/
-void bus_engine_proxy_candidate_clicked (BusEngineProxy *engine,
- guint index,
- guint button,
- guint state);
+void bus_engine_proxy_candidate_clicked
+ (BusEngineProxy *engine,
+ guint index,
+ guint button,
+ guint state);
/**
* bus_engine_proxy_enable:
+ * @engine: A #BusEngineProxy.
*
- * Call "Enable" method of an engine asynchronously. Do nothing if the engine is already enabled.
+ * Call "Enable" method of an engine asynchronously. Do nothing if the
+ * engine is already enabled.
*/
-void bus_engine_proxy_enable (BusEngineProxy *engine);
+void bus_engine_proxy_enable (BusEngineProxy *engine);
/**
* bus_engine_proxy_disable:
+ * @engine: A #BusEngineProxy.
*
- * Call "Disable" method of an engine asynchronously. Do nothing if the engine is already disabled.
+ * Call "Disable" method of an engine asynchronously. Do nothing if
+ * the engine is already disabled.
*/
-void bus_engine_proxy_disable (BusEngineProxy *engine);
+void bus_engine_proxy_disable (BusEngineProxy *engine);
/**
* bus_engine_proxy_property_activate:
+ * @engine: A #BusEngineProxy.
+ * @name: Property name.
+ * @state: Property state.
*
* Call "PropertyActivate" method of an engine asynchronously.
*/
-void bus_engine_proxy_property_activate (BusEngineProxy *engine,
- const gchar *prop_name,
- guint state);
+void bus_engine_proxy_property_activate
+ (BusEngineProxy *engine,
+ const gchar *prop_name,
+ guint state);
/**
* bus_engine_proxy_property_show:
+ * @engine: A #BusEngineProxy.
+ * @prop_name: Property name.
*
* Call "PropertyShow" method of an engine asynchronously.
*/
-void bus_engine_proxy_property_show (BusEngineProxy *engine,
- const gchar *prop_name);
+void bus_engine_proxy_property_show
+ (BusEngineProxy *engine,
+ const gchar *prop_name);
/**
* bus_engine_proxy_property_hide:
+ * @engine: A #BusEngineProxy.
+ * @prop_name: Property name.
*
* Call "PropertyHide" method of an engine asynchronously.
*/
-void bus_engine_proxy_property_hide (BusEngineProxy *engine,
- const gchar *prop_name);
+void bus_engine_proxy_property_hide
+ (BusEngineProxy *engine,
+ const gchar *prop_name);
/**
* bus_engine_proxy_is_enabled:
- * @returns: TRUE if the engine is enabled.
+ * @engine: A #BusEngineProxy.
+ * @returns: %TRUE if the engine is enabled.
*/
-gboolean bus_engine_proxy_is_enabled (BusEngineProxy *engine);
+gboolean bus_engine_proxy_is_enabled (BusEngineProxy *engine);
/**
* bus_engine_proxy_set_surrounding_text:
+ * @engine: A #BusEngineProxy.
+ * @text: The surrounding text.
+ * @cursor_pos: The cursor position on surrounding text.
+ * @anchor_pos: The anchor position on selection area.
*
* Call "SetSurroundingText" method of an engine asynchronously.
*/
-void bus_engine_proxy_set_surrounding_text
- (BusEngineProxy *engine,
- IBusText *text,
- guint cursor_pos,
- guint anchor_pos);
+void bus_engine_proxy_set_surrounding_text
+ (BusEngineProxy *engine,
+ IBusText *text,
+ guint cursor_pos,
+ guint anchor_pos);
/**
* bus_engine_proxy_process_hand_writing_event:
+ * @engine: A #BusEngineProxy.
+ * @coordinates: A #GVariant containing an array of coordinates.
*
- * Call "ProcessHandWritingEvent" method of an engine asynchronously. The type of the GVariant should be "(ad)".
- * See ibus_input_context_process_hand_writing_event for details.
+ * Call "ProcessHandWritingEvent" method of an engine
+ * asynchronously. The type of the GVariant should be "(ad)". See
+ * ibus_input_context_process_hand_writing_event() for details.
*/
-void bus_engine_proxy_process_hand_writing_event
- (BusEngineProxy *engine,
- GVariant *coordinates);
+void bus_engine_proxy_process_hand_writing_event
+ (BusEngineProxy *engine,
+ GVariant *coordinates);
/**
* bus_engine_proxy_cancel_hand_writing:
+ * @engine: A #BusEngineProxy.
+ * @n_strokes: The number of strokes to be removed. 0 means "remove all".
*
* Call "CancelHandWriting" method of an engine asynchronously.
- * See ibus_input_context_cancel_hand_writing for details.
+ * See ibus_input_context_cancel_hand_writing() for details.
+ */
+void bus_engine_proxy_cancel_hand_writing
+ (BusEngineProxy *engine,
+ guint n_strokes);
+
+/**
+ * bus_engine_proxy_set_content_type:
+ * @engine: A #BusEngineProxy.
+ * @purpose: Primary purpose of the input context, as an #IBusInputPurpose.
+ * @hints: Hints that augment @purpose, as an #IBusInputHints.
+ *
+ * Call "SetContentType" method of an engine asynchronously.
+ * See ibus_input_context_set_content_type() for details.
*/
-void bus_engine_proxy_cancel_hand_writing
- (BusEngineProxy *engine,
- guint n_strokes);
+void bus_engine_proxy_set_content_type
+ (BusEngineProxy *engine,
+ guint purpose,
+ guint hints);
/**
* bus_engine_proxy_get_properties:
+ * @engine: A #BusEngineProxy.
+ * @returns: An #IBusPropList.
*
- * Get an IBusPropList object associated with the engine.
+ * Get an #IBusPropList object associated with the engine.
*/
-IBusPropList *bus_engine_proxy_get_properties (BusEngineProxy *engine);
+IBusPropList *bus_engine_proxy_get_properties
+ (BusEngineProxy *engine);
G_END_DECLS
#endif
diff --git a/bus/inputcontext.c b/bus/inputcontext.c
index d7ada6ef..a2d1d52c 100644
--- a/bus/inputcontext.c
+++ b/bus/inputcontext.c
@@ -1,8 +1,8 @@
/* -*- mode: C; c-basic-offset: 4; indent-tabs-mode: nil; -*- */
/* vim:set et sts=4: */
/* ibus - The Input Bus
- * Copyright (C) 2008-2010 Peng Huang <shawn.p.huang@gmail.com>
- * Copyright (C) 2008-2010 Red Hat, Inc.
+ * Copyright (C) 2008-2013 Peng Huang <shawn.p.huang@gmail.com>
+ * Copyright (C) 2008-2013 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
@@ -89,6 +89,10 @@ struct _BusInputContext {
/* incompleted set engine by desc request */
SetEngineByDescData *data;
+
+ /* content-type (primary purpose and hints) */
+ guint purpose;
+ guint hints;
};
struct _BusInputContextClass {
@@ -132,69 +136,83 @@ typedef struct _BusInputContextPrivate BusInputContextPrivate;
static guint context_signals[LAST_SIGNAL] = { 0 };
/* functions prototype */
-static void bus_input_context_destroy (BusInputContext *context);
+static void bus_input_context_destroy
+ (BusInputContext *context);
static void bus_input_context_service_method_call
- (IBusService *service,
- GDBusConnection *connection,
- const gchar *sender,
- const gchar *object_path,
- const gchar *interface_name,
- const gchar *method_name,
- GVariant *parameters,
- GDBusMethodInvocation *invocation);
-static void bus_input_context_unset_engine (BusInputContext *context);
-static void bus_input_context_commit_text (BusInputContext *context,
- IBusText *text);
+ (IBusService *service,
+ GDBusConnection *connection,
+ const gchar *sender,
+ const gchar *object_path,
+ const gchar *interface_name,
+ const gchar *method_name,
+ GVariant *parameters,
+ GDBusMethodInvocation *invocation);
+static gboolean bus_input_context_service_set_property
+ (IBusService *service,
+ GDBusConnection *connection,
+ const gchar *sender,
+ const gchar *object_path,
+ const gchar *interface_name,
+ const gchar *property_name,
+ GVariant *value,
+ GError **error);
+static void bus_input_context_unset_engine
+ (BusInputContext *context);
+static void bus_input_context_commit_text
+ (BusInputContext *context,
+ IBusText *text);
static void bus_input_context_update_preedit_text
- (BusInputContext *context,
- IBusText *text,
- guint cursor_pos,
- gboolean visible,
- guint mode);
+ (BusInputContext *context,
+ IBusText *text,
+ guint cursor_pos,
+ gboolean visible,
+ guint mode);
static void bus_input_context_show_preedit_text
- (BusInputContext *context);
+ (BusInputContext *context);
static void bus_input_context_hide_preedit_text
- (BusInputContext *context);
+ (BusInputContext *context);
static void bus_input_context_update_auxiliary_text
- (BusInputContext *context,
- IBusText *text,
- gboolean visible);
+ (BusInputContext *context,
+ IBusText *text,
+ gboolean visible);
static void bus_input_context_show_auxiliary_text
- (BusInputContext *context);
+ (BusInputContext *context);
static void bus_input_context_hide_auxiliary_text
- (BusInputContext *context);
+ (BusInputContext *context);
static void bus_input_context_update_lookup_table
- (BusInputContext *context,
- IBusLookupTable *table,
- gboolean visible);
+ (BusInputContext *context,
+ IBusLookupTable *table,
+ gboolean visible);
static void bus_input_context_show_lookup_table
- (BusInputContext *context);
+ (BusInputContext *context);
static void bus_input_context_hide_lookup_table
- (BusInputContext *context);
+ (BusInputContext *context);
static void bus_input_context_page_up_lookup_table
- (BusInputContext *context);
+ (BusInputContext *context);
static void bus_input_context_page_down_lookup_table
- (BusInputContext *context);
+ (BusInputContext *context);
static void bus_input_context_cursor_up_lookup_table
- (BusInputContext *context);
+ (BusInputContext *context);
static void bus_input_context_cursor_down_lookup_table
- (BusInputContext *context);
+ (BusInputContext *context);
static void bus_input_context_register_properties
- (BusInputContext *context,
- IBusPropList *props);
+ (BusInputContext *context,
+ IBusPropList *props);
static void bus_input_context_update_property
- (BusInputContext *context,
- IBusProperty *prop);
-static void _engine_destroy_cb (BusEngineProxy *factory,
- BusInputContext *context);
+ (BusInputContext *context,
+ IBusProperty *prop);
+static void _engine_destroy_cb (BusEngineProxy *factory,
+ BusInputContext *context);
static IBusText *text_empty = NULL;
static IBusLookupTable *lookup_table_empty = NULL;
static IBusPropList *props_empty = NULL;
-/* The interfaces available in this class, which consists of a list of methods this class implements and
- * a list of signals this class may emit. Method calls to the interface that are not defined in this XML
- * will be automatically rejected by the GDBus library (see src/ibusservice.c for details.) */
+/* The interfaces available in this class, which consists of a list of
+ * methods this class implements and a list of signals this class may
+ * emit. Method calls to the interface that are not defined in this
+ * XML will be automatically rejected by the GDBus library (see
+ * src/ibusservice.c for details.) */
static const gchar introspection_xml[] =
"<node>"
" <interface name='org.freedesktop.IBus.InputContext'>"
@@ -277,6 +295,9 @@ static const gchar introspection_xml[] =
" <signal name='UpdateProperty'>"
" <arg type='v' name='prop' />"
" </signal>"
+
+ /* properties */
+ " <property name='ContentType' type='(uu)' access='write' />"
" </interface>"
"</node>";
@@ -316,7 +337,10 @@ bus_input_context_class_init (BusInputContextClass *class)
ibus_object_class->destroy = (IBusObjectDestroyFunc) bus_input_context_destroy;
/* override the parent class's implementation. */
- IBUS_SERVICE_CLASS (class)->service_method_call = bus_input_context_service_method_call;
+ IBUS_SERVICE_CLASS (class)->service_method_call =
+ bus_input_context_service_method_call;
+ IBUS_SERVICE_CLASS (class)->service_set_property =
+ bus_input_context_service_set_property;
/* register the xml so that bus_ibus_impl_service_method_call will be called on a method call defined in the xml (e.g. 'FocusIn'.) */
ibus_service_class_add_interfaces (IBUS_SERVICE_CLASS (class), introspection_xml);
@@ -607,14 +631,9 @@ bus_input_context_destroy (BusInputContext *context)
IBUS_OBJECT_CLASS (bus_input_context_parent_class)->destroy (IBUS_OBJECT (context));
}
-/**
- * bus_input_context_emit_signal:
- * @signal_name: The D-Bus signal name to emit which is in the introspection_xml.
- *
- * Emit the D-Bus signal.
- */
static gboolean
-bus_input_context_emit_signal (BusInputContext *context,
+bus_input_context_send_signal (BusInputContext *context,
+ const gchar *interface_name,
const gchar *signal_name,
GVariant *parameters,
GError **error)
@@ -623,7 +642,7 @@ bus_input_context_emit_signal (BusInputContext *context,
return TRUE;
GDBusMessage *message = g_dbus_message_new_signal (ibus_service_get_object_path ((IBusService *)context),
- "org.freedesktop.IBus.InputContext",
+ interface_name,
signal_name);
g_dbus_message_set_sender (message, "org.freedesktop.IBus");
g_dbus_message_set_destination (message, bus_connection_get_unique_name (context->connection));
@@ -639,6 +658,58 @@ bus_input_context_emit_signal (BusInputContext *context,
}
/**
+ * bus_input_context_emit_signal:
+ * @signal_name: The D-Bus signal name to emit which is in the introspection_xml.
+ *
+ * Emit the D-Bus signal.
+ */
+static gboolean
+bus_input_context_emit_signal (BusInputContext *context,
+ const gchar *signal_name,
+ GVariant *parameters,
+ GError **error)
+{
+ if (context->connection == NULL)
+ return TRUE;
+
+ return bus_input_context_send_signal (context,
+ "org.freedesktop.IBus.InputContext",
+ signal_name,
+ parameters,
+ error);
+}
+
+/**
+ * bus_input_context_property_changed:
+ * @context: a #BusInputContext
+ * @property_name: The D-Bus property name which has changed
+ * @value: The new value of the property
+ *
+ * Emit the D-Bus "PropertiesChanged" signal for a property.
+ * Returns: %TRUE on success, %FALSE on failure
+ */
+static gboolean
+bus_input_context_property_changed (BusInputContext *context,
+ const gchar *property_name,
+ GVariant *value,
+ GError **error)
+{
+ if (context->connection == NULL)
+ return TRUE;
+
+ GVariantBuilder *builder = g_variant_builder_new (G_VARIANT_TYPE_ARRAY);
+ g_variant_builder_add (builder, "{sv}", property_name, value);
+ return bus_input_context_send_signal (context,
+ "org.freedesktop.DBus.Properties",
+ "PropertiesChanged",
+ g_variant_new ("(sa{sv}as)",
+ "org.freedesktop.IBus",
+ builder,
+ NULL),
+ error);
+}
+
+/**
* _ic_process_key_event_reply_cb:
*
* A GAsyncReadyCallback function to be called when bus_engine_proxy_process_key_event() is finished.
@@ -948,11 +1019,6 @@ _ic_get_engine (BusInputContext *context,
g_variant_new ("(v)", ibus_serializable_serialize ((IBusSerializable *)desc)));
}
-/**
- * bus_input_context_service_method_call:
- *
- * Handle a D-Bus method call whose destination and interface name are both "org.freedesktop.IBus.InputContext"
- */
static void
_ic_set_surrounding_text (BusInputContext *context,
GVariant *parameters,
@@ -985,6 +1051,11 @@ _ic_set_surrounding_text (BusInputContext *context,
g_dbus_method_invocation_return_value (invocation, NULL);
}
+/**
+ * bus_input_context_service_method_call:
+ *
+ * Handle a D-Bus method call whose destination and interface name are both "org.freedesktop.IBus.InputContext"
+ */
static void
bus_input_context_service_method_call (IBusService *service,
GDBusConnection *connection,
@@ -1024,7 +1095,7 @@ bus_input_context_service_method_call (IBusService *service,
{ "PropertyActivate", _ic_property_activate },
{ "SetEngine", _ic_set_engine },
{ "GetEngine", _ic_get_engine },
- { "SetSurroundingText", _ic_set_surrounding_text},
+ { "SetSurroundingText", _ic_set_surrounding_text }
};
gint i;
@@ -1038,6 +1109,63 @@ bus_input_context_service_method_call (IBusService *service,
g_return_if_reached ();
}
+static gboolean
+bus_input_context_service_set_property (IBusService *service,
+ GDBusConnection *connection,
+ const gchar *sender,
+ const gchar *object_path,
+ const gchar *interface_name,
+ const gchar *property_name,
+ GVariant *value,
+ GError **error)
+{
+ if (g_strcmp0 (interface_name, IBUS_INTERFACE_INPUT_CONTEXT) != 0) {
+ return IBUS_SERVICE_CLASS (bus_input_context_parent_class)->
+ service_set_property (service,
+ connection,
+ sender,
+ object_path,
+ interface_name,
+ property_name,
+ value,
+ error);
+ }
+
+ if (g_strcmp0 (property_name, "ContentType") == 0) {
+ BusInputContext *context = (BusInputContext *) service;
+ guint purpose = 0;
+ guint hints = 0;
+
+ g_variant_get (value, "(uu)", &purpose, &hints);
+ if (purpose != context->purpose || hints != context->hints) {
+ GError *error;
+ gboolean retval;
+
+ context->purpose = purpose;
+ context->hints = hints;
+
+ if (context->has_focus && context->engine)
+ bus_engine_proxy_set_content_type (context->engine,
+ purpose,
+ hints);
+
+ error = NULL;
+ retval = bus_input_context_property_changed (context,
+ "ContentType",
+ value,
+ &error);
+ if (!retval) {
+ g_warning ("Failed to emit PropertiesChanged signal: %s",
+ error->message);
+ g_error_free (error);
+ }
+ }
+ return TRUE;
+ }
+
+ g_return_val_if_reached (FALSE);
+}
+
gboolean
bus_input_context_has_focus (BusInputContext *context)
{
@@ -1066,6 +1194,7 @@ bus_input_context_focus_in (BusInputContext *context)
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);
}
if (context->capabilities & IBUS_CAP_FOCUS) {
@@ -1953,6 +2082,7 @@ bus_input_context_enable (BusInputContext *context)
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
@@ -2057,6 +2187,7 @@ bus_input_context_set_engine (BusInputContext *context,
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);
}
}
g_signal_emit (context,