summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDaiki Ueno <ueno@gnu.org>2016-02-17 16:29:03 +0900
committerDaiki Ueno <ueno@gnu.org>2016-02-17 16:29:03 +0900
commitb51c6200686d5494f317f8675763bad5cdd442b2 (patch)
tree9d70b7654eebfb4fe4ce07c3a14108d9a7a716f3
parent97e28cc04b4601295b22a0aa8e9e21ed4e0758a1 (diff)
downloadibus-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.c54
-rw-r--r--bus/panelproxy.c32
-rw-r--r--bus/panelproxy.h6
-rw-r--r--client/gtk2/ibusimcontext.c28
-rw-r--r--src/ibusinputcontext.c20
-rw-r--r--src/ibusinputcontext.h16
-rw-r--r--src/ibuspanelservice.c62
-rw-r--r--src/ibuspanelservice.h8
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);