This will cause the space bar to insert spaces if you aren't selecting a character.  It is based on a patch written for ArchLinux: http://aur.archlinux.org/packages.php?ID=20567

BUG=chromium-os:1253
TEST=Set the input method to chewing, and try typing a space while not selecting a candidate.  Ensure that a space is output.

Review URL: http://codereview.chromium.org/1733014
diff --git a/src/IBusChewingEngine-def.c b/src/IBusChewingEngine-def.c
index 7f22364..c0c17ea 100644
--- a/src/IBusChewingEngine-def.c
+++ b/src/IBusChewingEngine-def.c
@@ -105,7 +105,7 @@
     IBusChewingEngine *engine=(IBusChewingEngine *) ctx->userData;
     ibus_chewing_engine_set_selKeys_string(engine,g_value_get_string(value));
     if (!engine->table){
-	engine->table=g_object_ref_sink(ibus_lookup_table_new(strlen(g_value_get_string(value)),0,FALSE,TRUE));
+	engine->table=g_object_ref_sink(ibus_lookup_table_new(strlen(g_value_get_string(value)),0,TRUE,TRUE));
     }
     ibus_chewing_engine_set_lookup_table_label(engine,g_value_get_string(value));
 #endif
@@ -218,7 +218,7 @@
 	ibus_lookup_table_clear(engine->table);
 	engine->table->page_size=g_value_get_int(value);
     }else{
-	engine->table=g_object_ref_sink(ibus_lookup_table_new(g_value_get_int(value),0,FALSE,TRUE));
+	engine->table=g_object_ref_sink(ibus_lookup_table_new(g_value_get_int(value),0,TRUE,TRUE));
     }
 #endif
 }
diff --git a/src/IBusChewingEngine-keys.c b/src/IBusChewingEngine-keys.c
index e9d5235..98d4e1b 100644
--- a/src/IBusChewingEngine-keys.c
+++ b/src/IBusChewingEngine-keys.c
@@ -41,13 +41,19 @@
 		    chewing_handle_Enter(self->context);
 		    break;
 		case IBUS_Escape:
+		    if (self->inputMode==CHEWING_INPUT_MODE_BYPASS)
+			return FALSE;
 		    chewing_handle_Esc(self->context);
 		    break;
 		case IBUS_BackSpace:
+		    if (self->inputMode==CHEWING_INPUT_MODE_BYPASS)
+			return FALSE;
 		    chewing_handle_Backspace(self->context);
 		    break;
 		case IBUS_Delete:
 		case IBUS_KP_Delete:
+		    if (self->inputMode==CHEWING_INPUT_MODE_BYPASS)
+			return FALSE;
 		    chewing_handle_Del(self->context);
 		    break;
 		case IBUS_space:
@@ -56,7 +62,8 @@
 		     * Fix for space in Temporary mode.
 		     */
 		    chewing_handle_Space(self->context);
-		    if (self->inputMode==CHEWING_INPUT_MODE_SELECTING_DONE)
+		    if (self->inputMode==CHEWING_INPUT_MODE_SELECTING_DONE ||
+			    self->inputMode==CHEWING_INPUT_MODE_BYPASS )
 			ibus_chewing_engine_set_status_flag(self,ENGINE_STATUS_NEED_COMMIT);
 		    break;
 		case IBUS_Page_Up:
@@ -113,6 +120,12 @@
 		    chewing_handle_Tab(self->context);
 		    break;
 		case IBUS_Caps_Lock:
+		    /* When Chi->Eng with incomplete character */
+		    if (chewing_get_ChiEngMode(self->context) && !chewing_zuin_Check(self->context)){
+			/* chewing_zuin_Check==0 means incomplete character */
+			/* Send a space to finish the character */
+			chewing_handle_Space(self->context);
+		    }
 		    chewing_handle_Capslock(self->context);
 		    self_refresh_property(self,"chewing_chieng_prop");
 		    break;
@@ -146,8 +159,17 @@
 		chewing_handle_ShiftRight(self->context);
 		break;
 	    case IBUS_Up:
-		return FALSE;
+	    case IBUS_KP_Up:
 	    case IBUS_Down:
+	    case IBUS_KP_Down:
+	    case IBUS_Page_Up:
+	    case IBUS_KP_Page_Up:
+	    case IBUS_Page_Down:
+	    case IBUS_KP_Page_Down:
+	    case IBUS_Home:
+	    case IBUS_End:
+		if (self->_priv->statusFlags & ENGINE_STATUS_NEED_COMMIT)
+		    self_force_commit(self);
 		return FALSE;
 	    case IBUS_space:
 	    case IBUS_KP_Space:
@@ -176,4 +198,3 @@
     }
     return self_update(self);
 }
-
diff --git a/src/IBusChewingEngine.gob b/src/IBusChewingEngine.gob
index 850b8bc..2248deb 100644
--- a/src/IBusChewingEngine.gob
+++ b/src/IBusChewingEngine.gob
@@ -108,6 +108,7 @@
     FOCUS_IN=			0x4,
     SHOW_CANDIDATE=		0x8,
     NEED_COMMIT=		0x10,
+    FORCE_COMMIT=		0x20,
 } Engine:Status;
 
 %h{
@@ -439,7 +440,7 @@
 
     private void update_lookup_table(self){
 	if (!self->table){
-	    self->table=ibus_lookup_table_new(1,0,FALSE,TRUE);
+	    self->table=ibus_lookup_table_new(1,0,TRUE,TRUE);
 	    g_object_ref_sink(self->table);
 	}
 	ibus_lookup_table_clear(self->table);
@@ -520,7 +521,6 @@
 	    case CHEWING_INPUT_STYLE_IN_APPLICATION:
 		if (chewing_aux_Length(self->context)>0){
 		    gchar *aux_string=chewing_aux_String(self->context);
-		    iText=ibus_text_new_from_string (aux_string);
 		    iText=g_object_ref_sink(ibus_text_new_from_string (aux_string));
 		    ibus_engine_update_auxiliary_text(IBUS_ENGINE(self),iText,TRUE);
 		    g_object_unref (iText);
@@ -555,6 +555,7 @@
 	self_determine_input_mode(self);
 	gint chiSymbolCursor;
 	glong zhuyin_item_written;
+	self_commit(self);
 	gchar *preeditBuf=self_make_preedit_string(self, &zhuyin_item_written);
 	IBusText *iText=self_decorate_preedit(self, preeditBuf, &chiSymbolCursor, zhuyin_item_written);
 	if (g_object_is_floating(iText)){
@@ -577,7 +578,7 @@
 	    free(phoneSeq);
 	}
 	self_update_lookup_table(self);
-	self_commit(self);
+	//self_commit(self);
 	gboolean ret=TRUE;
 
 	if (chewing_keystroke_CheckAbsorb(self->context)){
@@ -792,7 +793,7 @@
     protected gboolean commit(self){
 	gint commit=chewing_commit_Check(self->context);
 	G_DEBUG_MSG(2,"[I2] commit() %s statusFlags=%x", (commit) ? "TRUE": "FALSE", self->_priv->statusFlags);
-	if (commit && (self->_priv->statusFlags & ENGINE_STATUS_NEED_COMMIT)){
+	if ((self->_priv->statusFlags & ENGINE_STATUS_NEED_COMMIT) && commit){
 	    IBusText *iText=NULL;
 
 	    gchar *commit_string=chewing_commit_String(self->context);
@@ -801,7 +802,19 @@
 	    ibus_engine_commit_text(IBUS_ENGINE(self),iText);
 	    g_free(commit_string);
 	    g_object_unref(iText);
-	    ibus_chewing_engine_clear_status_flag(self, ENGINE_STATUS_NEED_COMMIT);
+	    if (!chewing_buffer_Check(self->context)){
+		/* Buffer is clean */
+		ibus_chewing_engine_clear_status_flag(self, ENGINE_STATUS_NEED_COMMIT | ENGINE_STATUS_FORCE_COMMIT );
+	    }else if (self->_priv->statusFlags & ENGINE_STATUS_FORCE_COMMIT){
+		/* Flush the buffer  */
+		chewing_handle_Enter(self->context);
+		commit_string=chewing_commit_String(self->context);
+		iText=g_object_ref_sink(ibus_text_new_from_string(commit_string));
+		ibus_engine_commit_text(IBUS_ENGINE(self),iText);
+		g_free(commit_string);
+		g_object_unref(iText);
+		ibus_chewing_engine_clear_status_flag(self, ENGINE_STATUS_FORCE_COMMIT );
+	    }
 	}
 	return commit;
     }
@@ -820,7 +833,7 @@
 		}
 		chewing_handle_Enter(self->context);
 	    }
-	    ibus_chewing_engine_set_status_flag(self, ENGINE_STATUS_NEED_COMMIT);
+	    ibus_chewing_engine_set_status_flag(self, ENGINE_STATUS_NEED_COMMIT | ENGINE_STATUS_FORCE_COMMIT);
 	    self_update(self);
 	}
     }
@@ -832,6 +845,10 @@
     reset(IBus:Engine *engine){
 	G_DEBUG_MSG(1,"[I1] reset");
 	Self *self=SELF(engine);
+	if (self->_priv->statusFlags & ENGINE_STATUS_NEED_COMMIT){
+	    /* Force commit non-empty preedit buffer */
+	    self_force_commit(self);
+	}
 	ibus_lookup_table_clear(self->table);
 	/* Save KBType type, becaue chewing_Reset() will reset it to default.
 	 */