diff options
author | Daiki Ueno <ueno@gnu.org> | 2016-02-17 16:29:03 +0900 |
---|---|---|
committer | Daiki Ueno <ueno@gnu.org> | 2016-02-17 16:29:03 +0900 |
commit | b51c6200686d5494f317f8675763bad5cdd442b2 (patch) | |
tree | 9d70b7654eebfb4fe4ce07c3a14108d9a7a716f3 | |
parent | 97e28cc04b4601295b22a0aa8e9e21ed4e0758a1 (diff) | |
download | ibus-b51c6200686d5494f317f8675763bad5cdd442b2.tar.gz |
Add SetCursorLocationRelative D-Bus method
We have SetCursorLocation D-Bus method which takes the absolute
coordinates of the screen, while on Wayland the coordinates are relative
to the current input window and there is no way to calculate the
absolute coordinates. That makes it impossible for the panel to
position the lookup table correctly.
This patch adds a new D-Bus method, SetCursorLocationRelative, which
takes the relative coordinates, so that the panel
implementation (typically the same process of Wayland compositor) can
use that information. The counterpart of this changes is at:
https://bugzilla.gnome.org/show_bug.cgi?id=753476
Unlike SetCursorLocation, SetCursorLocationRelative is not delivered to
engines, since it is not very useful for the engines without knowing the
current input window (which is also not accessible from a different
process on Wayland).
Co-authored-by: Rui Matos <tiagomatos@gmail.com>
BUG=
R=takao.fujiwara1@gmail.com
Review URL: https://codereview.appspot.com/290780043 .
-rw-r--r-- | bus/inputcontext.c | 54 | ||||
-rw-r--r-- | bus/panelproxy.c | 32 | ||||
-rw-r--r-- | bus/panelproxy.h | 6 | ||||
-rw-r--r-- | client/gtk2/ibusimcontext.c | 28 | ||||
-rw-r--r-- | src/ibusinputcontext.c | 20 | ||||
-rw-r--r-- | src/ibusinputcontext.h | 16 | ||||
-rw-r--r-- | src/ibuspanelservice.c | 62 | ||||
-rw-r--r-- | src/ibuspanelservice.h | 8 |
8 files changed, 225 insertions, 1 deletions
diff --git a/bus/inputcontext.c b/bus/inputcontext.c index ea77102d..789bba26 100644 --- a/bus/inputcontext.c +++ b/bus/inputcontext.c @@ -105,6 +105,7 @@ struct _BusInputContextClass { enum { PROCESS_KEY_EVENT, SET_CURSOR_LOCATION, + SET_CURSOR_LOCATION_RELATIVE, FOCUS_IN, FOCUS_OUT, UPDATE_PREEDIT_TEXT, @@ -230,6 +231,12 @@ static const gchar introspection_xml[] = " <arg direction='in' type='i' name='w' />" " <arg direction='in' type='i' name='h' />" " </method>" + " <method name='SetCursorLocationRelative'>" + " <arg direction='in' type='i' name='x' />" + " <arg direction='in' type='i' name='y' />" + " <arg direction='in' type='i' name='w' />" + " <arg direction='in' type='i' name='h' />" + " </method>" " <method name='ProcessHandWritingEvent'>" " <arg direction='in' type='ad' name='coordinates' />" " </method>" @@ -373,6 +380,20 @@ bus_input_context_class_init (BusInputContextClass *class) G_TYPE_INT, G_TYPE_INT); + context_signals[SET_CURSOR_LOCATION_RELATIVE] = + g_signal_new (I_("set-cursor-location-relative"), + G_TYPE_FROM_CLASS (class), + G_SIGNAL_RUN_LAST, + 0, + NULL, NULL, + bus_marshal_VOID__INT_INT_INT_INT, + G_TYPE_NONE, + 4, + G_TYPE_INT, + G_TYPE_INT, + G_TYPE_INT, + G_TYPE_INT); + context_signals[FOCUS_IN] = g_signal_new (I_("focus-in"), G_TYPE_FROM_CLASS (class), @@ -846,6 +867,38 @@ _ic_set_cursor_location (BusInputContext *context, } } +/** + * _ic_set_cursor_location_relative: + * + * Implement the "SetCursorLocationRelative" method call of the + * org.freedesktop.IBus.InputContext interface. + * + * Unlike _ic_set_cursor_location, this doesn't deliver the location + * to the engine proxy, since the relative coordinates are not very + * useful for engines. + */ +static void +_ic_set_cursor_location_relative (BusInputContext *context, + GVariant *parameters, + GDBusMethodInvocation *invocation) +{ + gint x, y, w, h; + + g_dbus_method_invocation_return_value (invocation, NULL); + + g_variant_get (parameters, "(iiii)", &x, &y, &w, &h); + + if (context->capabilities & IBUS_CAP_FOCUS) { + g_signal_emit (context, + context_signals[SET_CURSOR_LOCATION_RELATIVE], + 0, + x, + y, + w, + h); + } +} + static void _ic_process_hand_writing_event (BusInputContext *context, GVariant *parameters, @@ -1127,6 +1180,7 @@ bus_input_context_service_method_call (IBusService *service, } methods [] = { { "ProcessKeyEvent", _ic_process_key_event }, { "SetCursorLocation", _ic_set_cursor_location }, + { "SetCursorLocationRelative", _ic_set_cursor_location_relative }, { "ProcessHandWritingEvent", _ic_process_hand_writing_event }, { "CancelHandWriting", _ic_cancel_hand_writing }, diff --git a/bus/panelproxy.c b/bus/panelproxy.c index 9d47b136..4ff5d89a 100644 --- a/bus/panelproxy.c +++ b/bus/panelproxy.c @@ -320,6 +320,21 @@ bus_panel_proxy_set_cursor_location (BusPanelProxy *panel, } void +bus_panel_proxy_set_cursor_location_relative (BusPanelProxy *panel, + gint x, + gint y, + gint w, + gint h) +{ + g_assert (BUS_IS_PANEL_PROXY (panel)); + g_dbus_proxy_call ((GDBusProxy *)panel, + "SetCursorLocationRelative", + g_variant_new ("(iiii)", x, y, w, h), + G_DBUS_CALL_FLAGS_NONE, + -1, NULL, NULL, NULL); +} + +void bus_panel_proxy_update_preedit_text (BusPanelProxy *panel, IBusText *text, guint cursor_pos, @@ -499,6 +514,22 @@ _context_set_cursor_location_cb (BusInputContext *context, } static void +_context_set_cursor_location_relative_cb (BusInputContext *context, + gint x, + gint y, + gint w, + gint h, + BusPanelProxy *panel) +{ + g_assert (BUS_IS_INPUT_CONTEXT (context)); + g_assert (BUS_IS_PANEL_PROXY (panel)); + + g_return_if_fail (panel->focused_context == context); + + bus_panel_proxy_set_cursor_location_relative (panel, x, y, w, h); +} + +static void _context_update_preedit_text_cb (BusInputContext *context, IBusText *text, guint cursor_pos, @@ -634,6 +665,7 @@ static const struct { GCallback callback; } input_context_signals[] = { { "set-cursor-location", G_CALLBACK (_context_set_cursor_location_cb) }, + { "set-cursor-location-relative", G_CALLBACK (_context_set_cursor_location_relative_cb) }, { "update-preedit-text", G_CALLBACK (_context_update_preedit_text_cb) }, { "show-preedit-text", G_CALLBACK (_context_show_preedit_text_cb) }, diff --git a/bus/panelproxy.h b/bus/panelproxy.h index 57cf9db3..5002f86d 100644 --- a/bus/panelproxy.h +++ b/bus/panelproxy.h @@ -70,6 +70,12 @@ void bus_panel_proxy_set_cursor_location gint32 y, gint32 w, gint32 h); +void bus_panel_proxy_set_cursor_location_relative + (BusPanelProxy *panel, + gint32 x, + gint32 y, + gint32 w, + gint32 h); void bus_panel_proxy_update_preedit_text (BusPanelProxy *panel, IBusText *text, diff --git a/client/gtk2/ibusimcontext.c b/client/gtk2/ibusimcontext.c index 5c20592d..9d927e63 100644 --- a/client/gtk2/ibusimcontext.c +++ b/client/gtk2/ibusimcontext.c @@ -30,6 +30,10 @@ #include <ibus.h> #include "ibusimcontext.h" +#ifdef GDK_WINDOWING_WAYLAND +#include <gdk/gdkwayland.h> +#endif + #if !GTK_CHECK_VERSION (2, 91, 0) # define DEPRECATED_GDK_KEYSYMS 1 #endif @@ -1011,6 +1015,30 @@ _set_cursor_location_internal (IBusIMContext *ibusimcontext) } area = ibusimcontext->cursor_area; + +#ifdef GDK_WINDOWING_WAYLAND + if (GDK_IS_WAYLAND_DISPLAY (gdk_display_get_default ())) { + gdouble px, py; + GdkWindow *parent; + GdkWindow *window = ibusimcontext->client_window; + + while ((parent = gdk_window_get_effective_parent (window)) != NULL) { + gdk_window_coords_to_parent (window, area.x, area.y, &px, &py); + area.x = px; + area.y = py; + window = parent; + } + + ibus_input_context_set_cursor_location_relative ( + ibusimcontext->ibuscontext, + area.x, + area.y, + area.width, + area.height); + return FALSE; + } +#endif + if (area.x == -1 && area.y == -1 && area.width == 0 && area.height == 0) { #if GTK_CHECK_VERSION (2, 91, 0) area.x = 0; diff --git a/src/ibusinputcontext.c b/src/ibusinputcontext.c index 908011fa..9a50acc0 100644 --- a/src/ibusinputcontext.c +++ b/src/ibusinputcontext.c @@ -944,6 +944,26 @@ ibus_input_context_set_cursor_location (IBusInputContext *context, } void +ibus_input_context_set_cursor_location_relative (IBusInputContext *context, + gint32 x, + gint32 y, + gint32 w, + gint32 h) +{ + g_assert (IBUS_IS_INPUT_CONTEXT (context)); + + g_dbus_proxy_call ((GDBusProxy *) context, + "SetCursorLocationRelative", /* method_name */ + g_variant_new ("(iiii)", x, y, w, h),/* parameters */ + G_DBUS_CALL_FLAGS_NONE, /* flags */ + -1, /* timeout */ + NULL, /* cancellable */ + NULL, /* callback */ + NULL /* user_data */ + ); +} + +void ibus_input_context_set_capabilities (IBusInputContext *context, guint32 capabilites) { diff --git a/src/ibusinputcontext.h b/src/ibusinputcontext.h index 5c6372f6..a77cf92f 100644 --- a/src/ibusinputcontext.h +++ b/src/ibusinputcontext.h @@ -317,6 +317,22 @@ void ibus_input_context_set_cursor_location gint32 w, gint32 h); /** + * ibus_input_context_set_cursor_location_relative: + * @context: An IBusInputContext. + * @x: X coordinate of the cursor. + * @y: Y coordinate of the cursor. + * @w: Width of the cursor. + * @h: Height of the cursor. + * + * Set the relative cursor location of IBus input context asynchronously. + */ +void ibus_input_context_set_cursor_location_relative + (IBusInputContext *context, + gint32 x, + gint32 y, + gint32 w, + gint32 h); +/** * ibus_input_context_set_capabilities: * @context: An IBusInputContext. * @capabilities: Capabilities flags of IBusEngine, see #IBusCapabilite diff --git a/src/ibuspanelservice.c b/src/ibuspanelservice.c index 27b76558..b95f54a9 100644 --- a/src/ibuspanelservice.c +++ b/src/ibuspanelservice.c @@ -33,6 +33,7 @@ enum { REGISTER_PROPERTIES, UPDATE_PROPERTY, SET_CURSOR_LOCATION, + SET_CURSOR_LOCATION_RELATIVE, CURSOR_UP_LOOKUP_TABLE, CURSOR_DOWN_LOOKUP_TABLE, HIDE_AUXILIARY_TEXT, @@ -118,6 +119,12 @@ static void ibus_panel_service_set_cursor_location gint y, gint w, gint h); +static void ibus_panel_service_set_cursor_location_relative + (IBusPanelService *panel, + gint x, + gint y, + gint w, + gint h); static void ibus_panel_service_update_auxiliary_text (IBusPanelService *panel, IBusText *text, @@ -189,6 +196,12 @@ static const gchar introspection_xml[] = " <arg direction='in' type='i' name='w' />" " <arg direction='in' type='i' name='h' />" " </method>" + " <method name='SetCursorLocationRelative'>" + " <arg direction='in' type='i' name='x' />" + " <arg direction='in' type='i' name='y' />" + " <arg direction='in' type='i' name='w' />" + " <arg direction='in' type='i' name='h' />" + " </method>" " <method name='Reset' />" " <method name='StartSetup' />" " <method name='StateChanged' />" @@ -251,6 +264,7 @@ ibus_panel_service_class_init (IBusPanelServiceClass *class) class->destroy_context = ibus_panel_service_destroy_context; class->register_properties = ibus_panel_service_register_properties; class->set_cursor_location = ibus_panel_service_set_cursor_location; + class->set_cursor_location_relative = ibus_panel_service_set_cursor_location_relative; class->update_lookup_table = ibus_panel_service_update_lookup_table; class->update_auxiliary_text = ibus_panel_service_update_auxiliary_text; class->update_preedit_text = ibus_panel_service_update_preedit_text; @@ -481,6 +495,35 @@ ibus_panel_service_class_init (IBusPanelServiceClass *class) G_TYPE_INT); /** + * IBusPanelService::set-cursor-location-relative: + * @panel: An #IBusPanelService + * @x: X coordinate of the cursor. + * @y: Y coordinate of the cursor. + * @w: Width of the cursor. + * @h: Height of the cursor. + * + * Emitted when the client application get the set-cursor-location-relative. + * Implement the member function set_cursor_location_relative() in + * extended class to receive this signal. + * + * <note><para>Argument @user_data is ignored in this function.</para> + * </note> + */ + panel_signals[SET_CURSOR_LOCATION_RELATIVE] = + g_signal_new (I_("set-cursor-location-relative"), + G_TYPE_FROM_CLASS (gobject_class), + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET (IBusPanelServiceClass, set_cursor_location_relative), + NULL, NULL, + _ibus_marshal_VOID__INT_INT_INT_INT, + G_TYPE_NONE, + 4, + G_TYPE_INT, + G_TYPE_INT, + G_TYPE_INT, + G_TYPE_INT); + + /** * IBusPanelService::cursor-up-lookup-table: * @panel: An #IBusPanelService * @@ -1011,6 +1054,15 @@ ibus_panel_service_service_method_call (IBusService *service, return; } + if (g_strcmp0 (method_name, "SetCursorLocationRelative") == 0) { + gint x, y, w, h; + g_variant_get (parameters, "(iiii)", &x, &y, &w, &h); + g_signal_emit (panel, panel_signals[SET_CURSOR_LOCATION_RELATIVE], + 0, x, y, w, h); + g_dbus_method_invocation_return_value (invocation, NULL); + return; + } + if (g_strcmp0 (method_name, "ContentType") == 0) { guint purpose, hints; g_variant_get (parameters, "(uu)", &purpose, &hints); @@ -1142,6 +1194,16 @@ ibus_panel_service_set_cursor_location (IBusPanelService *panel, } static void +ibus_panel_service_set_cursor_location_relative (IBusPanelService *panel, + gint x, + gint y, + gint w, + gint h) +{ + ibus_panel_service_not_implemented(panel); +} + +static void ibus_panel_service_update_auxiliary_text (IBusPanelService *panel, IBusText *text, gboolean visible) diff --git a/src/ibuspanelservice.h b/src/ibuspanelservice.h index c3f1833c..07b56296 100644 --- a/src/ibuspanelservice.h +++ b/src/ibuspanelservice.h @@ -121,10 +121,16 @@ struct _IBusPanelServiceClass { void (* set_content_type) (IBusPanelService *panel, guint purpose, guint hints); + void (* set_cursor_location_relative) + (IBusPanelService *panel, + gint x, + gint y, + gint w, + gint h); /*< private >*/ /* padding */ - gpointer pdummy[6]; // We can add 8 pointers without breaking the ABI. + gpointer pdummy[5]; // We can add 8 pointers without breaking the ABI. }; GType ibus_panel_service_get_type (void); |