summaryrefslogtreecommitdiff
path: root/client
diff options
context:
space:
mode:
authorPeng Huang <shawn.p.huang@gmail.com>2011-03-01 15:34:37 -0500
committerPeng Huang <shawn.p.huang@gmail.com>2011-03-01 15:34:37 -0500
commit279ee5d5b3697b427cc22cd99a55f4e611318e25 (patch)
tree0333268e19790ad954dece59f9646d234c894ce0 /client
parent690be230c116afd52a6002d2ef92b56e28d829b1 (diff)
Optimize focus_in to avoid call some UI blocking functions.
focus_in calls some X blocking functions. It will block UI. This change delays the X blocking calls to idle callback, to avoid blocking UI. BUG=http://crbug.com/74237 TEST=Linux desktop Review URL: http://codereview.appspot.com/4254048
Diffstat (limited to 'client')
-rw-r--r--client/gtk2/ibusimcontext.c67
1 files changed, 40 insertions, 27 deletions
diff --git a/client/gtk2/ibusimcontext.c b/client/gtk2/ibusimcontext.c
index 477e7a10..a634d0e4 100644
--- a/client/gtk2/ibusimcontext.c
+++ b/client/gtk2/ibusimcontext.c
@@ -113,7 +113,7 @@ static void ibus_im_context_set_use_preedit
/* static methods*/
static void _create_input_context (IBusIMContext *context);
-static void _set_cursor_location_internal
+static gboolean _set_cursor_location_internal
(GtkIMContext *context);
static void _bus_connected_cb (IBusBus *bus,
@@ -208,8 +208,9 @@ _focus_in_cb (GtkWidget *widget,
GdkEventFocus *event,
gpointer user_data)
{
- if (_focus_im_context == NULL && _fake_context != NULL)
+ if (_focus_im_context == NULL && _fake_context != NULL) {
ibus_input_context_focus_in (_fake_context);
+ }
return FALSE;
}
@@ -218,8 +219,9 @@ _focus_out_cb (GtkWidget *widget,
GdkEventFocus *event,
gpointer user_data)
{
- if (_focus_im_context == NULL && _fake_context != NULL)
+ if (_focus_im_context == NULL && _fake_context != NULL) {
ibus_input_context_focus_out (_fake_context);
+ }
return FALSE;
}
@@ -680,18 +682,20 @@ ibus_im_context_focus_in (GtkIMContext *context)
{
IDEBUG ("%s", __FUNCTION__);
- IBusIMContext *ibusimcontext = IBUS_IM_CONTEXT (context);
+ IBusIMContext *ibusimcontext = (IBusIMContext *) context;
+ if (ibusimcontext->has_focus)
+ return;
if (_focus_im_context != NULL) {
- if (_focus_im_context != context) {
- gtk_im_context_focus_out (_focus_im_context);
- g_assert (_focus_im_context == NULL);
- }
+ g_assert (_focus_im_context != context);
+ gtk_im_context_focus_out (_focus_im_context);
+ g_assert (_focus_im_context == NULL);
}
else {
/* focus out fake context */
- if (_fake_context)
+ if (_fake_context != NULL) {
ibus_input_context_focus_out (_fake_context);
+ }
}
ibusimcontext->has_focus = TRUE;
@@ -701,27 +705,33 @@ ibus_im_context_focus_in (GtkIMContext *context)
gtk_im_context_focus_in (ibusimcontext->slave);
- _set_cursor_location_internal (context);
+ /* set_cursor_location_internal() will get origin from X server,
+ * it blocks UI. So delay it to idle callback. */
+ g_idle_add_full (G_PRIORITY_DEFAULT_IDLE,
+ (GSourceFunc) _set_cursor_location_internal,
+ g_object_ref (context),
+ (GDestroyNotify) g_object_unref);
- if (_focus_im_context != context) {
- g_object_add_weak_pointer ((GObject *) context,
- (gpointer *) &_focus_im_context);
- _focus_im_context = context;
- }
+ g_object_add_weak_pointer ((GObject *) context,
+ (gpointer *) &_focus_im_context);
+ _focus_im_context = context;
}
static void
ibus_im_context_focus_out (GtkIMContext *context)
{
IDEBUG ("%s", __FUNCTION__);
+ IBusIMContext *ibusimcontext = (IBusIMContext *) context;
- IBusIMContext *ibusimcontext = IBUS_IM_CONTEXT (context);
- if (_focus_im_context == context) {
- g_object_remove_weak_pointer ((GObject *) context,
- (gpointer *) &_focus_im_context);
- _focus_im_context = NULL;
+ if (ibusimcontext->has_focus == FALSE) {
+ return;
}
+ g_assert (context == _focus_im_context);
+ g_object_remove_weak_pointer ((GObject *) context,
+ (gpointer *) &_focus_im_context);
+ _focus_im_context = NULL;
+
ibusimcontext->has_focus = FALSE;
if (ibusimcontext->ibuscontext) {
ibus_input_context_focus_out (ibusimcontext->ibuscontext);
@@ -730,8 +740,9 @@ ibus_im_context_focus_out (GtkIMContext *context)
gtk_im_context_focus_out (ibusimcontext->slave);
/* focus in the fake ic */
- if (_fake_context)
+ if (_fake_context != NULL) {
ibus_input_context_focus_in (_fake_context);
+ }
}
static void
@@ -812,15 +823,16 @@ ibus_im_context_set_client_window (GtkIMContext *context, GdkWindow *client)
gtk_im_context_set_client_window (ibusimcontext->slave, client);
}
-static void
+static gboolean
_set_cursor_location_internal (GtkIMContext *context)
{
IBusIMContext *ibusimcontext = IBUS_IM_CONTEXT (context);
GdkRectangle area;
gint x, y;
- if(ibusimcontext->client_window == NULL || ibusimcontext->ibuscontext == NULL) {
- return;
+ if(ibusimcontext->client_window == NULL ||
+ ibusimcontext->ibuscontext == NULL) {
+ return FALSE;
}
area = ibusimcontext->cursor_area;
@@ -836,14 +848,15 @@ _set_cursor_location_internal (GtkIMContext *context)
#endif
}
- gdk_window_get_origin (ibusimcontext->client_window, &x, &y);
- area.x += x;
- area.y += y;
+ gdk_window_get_root_coords (ibusimcontext->client_window,
+ area.x, area.y,
+ &area.x, &area.y);
ibus_input_context_set_cursor_location (ibusimcontext->ibuscontext,
area.x,
area.y,
area.width,
area.height);
+ return FALSE;
}
static void