Fix SIGABRT by finalized IBusIMContext during _request_surrounding_text
authorfujiwarat <takao.fujiwara1@gmail.com>
Wed, 3 Oct 2012 02:48:20 +0000 (11:48 +0900)
committerfujiwarat <takao.fujiwara1@gmail.com>
Wed, 3 Oct 2012 02:48:20 +0000 (11:48 +0900)
BUG=RH#859879
TEST=Manually

Review URL: https://codereview.appspot.com/6573051

client/gtk2/ibusimcontext.c

index cb5561b0955b3243caae91b9e77c8a0cb5213ece..17da2637130fc82b89512037be44f59a04cd7b93 100644 (file)
@@ -294,14 +294,17 @@ _key_snooper_cb (GtkWidget   *widget,
     IDEBUG ("%s", __FUNCTION__);
     gboolean retval = FALSE;
 
-    IBusIMContext *ibusimcontext = (IBusIMContext *) _focus_im_context;
+    IBusIMContext *ibusimcontext = NULL;
     IBusInputContext *ibuscontext = NULL;
 
-    if (ibusimcontext != NULL &&
-        ibusimcontext->has_focus == TRUE) {
-        /* has IC with focus and use_key_snooper is true */
-        if (_use_key_snooper)
-            ibuscontext = ibusimcontext->ibuscontext;
+    if (!_use_key_snooper)
+        return;
+
+    if (_focus_im_context != NULL &&
+        ((IBusIMContext *) _focus_im_context)->has_focus == TRUE) {
+        ibusimcontext = (IBusIMContext *) _focus_im_context;
+        /* has IC with focus */
+        ibuscontext = ibusimcontext->ibuscontext;
     }
     else {
         /* If no IC has focus, and fake IC has been created, then pass key events to fake IC. */
@@ -373,6 +376,13 @@ _key_snooper_cb (GtkWidget   *widget,
     } while (0);
 
     if (ibusimcontext != NULL) {
+        /* "retrieve-surrounding" signal sometimes calls unref by
+         * gtk_im_multicontext_get_slave() because priv->context_id is not
+         * the latest than global_context_id in GtkIMMulticontext.
+         * Since _focus_im_context is gotten by the focus_in event,
+         * it would be good to call ref here.
+         */
+        g_object_ref (ibusimcontext);
         _request_surrounding_text (ibusimcontext);
         ibusimcontext->time = event->time;
     }
@@ -410,6 +420,13 @@ _key_snooper_cb (GtkWidget   *widget,
         event->state |= IBUS_IGNORED_MASK;
     }
 
+    if (ibusimcontext != NULL) {
+        /* unref ibusimcontext could call ibus_im_context_finalize here
+         * because "retrieve-surrounding" signal could call unref.
+         */
+        g_object_unref (ibusimcontext);
+    }
+
     return retval;
 }