From b51c6200686d5494f317f8675763bad5cdd442b2 Mon Sep 17 00:00:00 2001 From: Daiki Ueno Date: Wed, 17 Feb 2016 16:29:03 +0900 Subject: 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 BUG= R=takao.fujiwara1@gmail.com Review URL: https://codereview.appspot.com/290780043 . --- bus/inputcontext.c | 54 +++++++++++++++++++++++++++++++++++++++ bus/panelproxy.c | 32 +++++++++++++++++++++++ bus/panelproxy.h | 6 +++++ client/gtk2/ibusimcontext.c | 28 ++++++++++++++++++++ src/ibusinputcontext.c | 20 +++++++++++++++ src/ibusinputcontext.h | 16 ++++++++++++ src/ibuspanelservice.c | 62 +++++++++++++++++++++++++++++++++++++++++++++ src/ibuspanelservice.h | 8 +++++- 8 files changed, 225 insertions(+), 1 deletion(-) 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[] = " " " " " " + " " + " " + " " + " " + " " + " " " " " " " " @@ -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 @@ -319,6 +319,21 @@ bus_panel_proxy_set_cursor_location (BusPanelProxy *panel, -1, NULL, NULL, NULL); } +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, @@ -498,6 +513,22 @@ _context_set_cursor_location_cb (BusInputContext *context, bus_panel_proxy_set_cursor_location (panel, x, y, w, h); } +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, @@ -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 #include "ibusimcontext.h" +#ifdef GDK_WINDOWING_WAYLAND +#include +#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 @@ -943,6 +943,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 @@ -316,6 +316,22 @@ void ibus_input_context_set_cursor_location gint32 y, 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. 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[] = " " " " " " + " " + " " + " " + " " + " " + " " " " " " " " @@ -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; @@ -480,6 +494,35 @@ ibus_panel_service_class_init (IBusPanelServiceClass *class) G_TYPE_INT, 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. + * + * Argument @user_data is ignored in this function. + * + */ + 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); @@ -1141,6 +1193,16 @@ ibus_panel_service_set_cursor_location (IBusPanelService *panel, ibus_panel_service_not_implemented(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, 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); -- cgit v1.2.1