fix(frontends): preserve preedit lifecycle
This commit is contained in:
@@ -8,12 +8,19 @@ typedef struct Log Log;
|
||||
struct Log
|
||||
{
|
||||
GMainLoop *loop;
|
||||
int *waiting;
|
||||
IBusInputContext *a;
|
||||
IBusInputContext *clearctx;
|
||||
int legacy;
|
||||
int modern;
|
||||
int commit;
|
||||
int invalid;
|
||||
int sawpreedit;
|
||||
int sawcommit;
|
||||
int done;
|
||||
int transfer;
|
||||
int atext;
|
||||
int aclear;
|
||||
};
|
||||
|
||||
static void
|
||||
@@ -38,10 +45,25 @@ legacy(IBusInputContext *ctx, IBusText *text, guint cursor,
|
||||
a->start_index != 0 || a->end_index != 1 ||
|
||||
ibus_attr_list_get(attrs, 1) != NULL)
|
||||
log->invalid = 1;
|
||||
else
|
||||
else{
|
||||
log->sawpreedit = 1;
|
||||
if(log->transfer && ctx == log->a)
|
||||
log->atext = 1;
|
||||
}
|
||||
}
|
||||
if(log->loop != NULL && log->sawpreedit && log->sawcommit)
|
||||
if(log->transfer && log->atext && !log->aclear && s[0] == '\0'){
|
||||
if(cursor != 0 || visible)
|
||||
log->invalid = 1;
|
||||
else{
|
||||
log->clearctx = ctx;
|
||||
if(ctx == log->a)
|
||||
log->aclear = 1;
|
||||
else
|
||||
log->invalid = 1;
|
||||
}
|
||||
}
|
||||
log->done = log->sawpreedit && log->sawcommit;
|
||||
if(log->loop != NULL && log->waiting != NULL && *log->waiting)
|
||||
g_main_loop_quit(log->loop);
|
||||
}
|
||||
|
||||
@@ -80,7 +102,8 @@ commit(IBusInputContext *ctx, IBusText *text, void *arg)
|
||||
log->invalid = 1;
|
||||
else
|
||||
log->sawcommit = 1;
|
||||
if(log->loop != NULL && log->sawpreedit && log->sawcommit)
|
||||
log->done = log->sawpreedit && log->sawcommit;
|
||||
if(log->loop != NULL && log->waiting != NULL && *log->waiting)
|
||||
g_main_loop_quit(log->loop);
|
||||
}
|
||||
|
||||
@@ -92,12 +115,13 @@ timeout(void *arg)
|
||||
}
|
||||
|
||||
static int
|
||||
waitdone(Log *log)
|
||||
waitflag(Log *log, int *flag)
|
||||
{
|
||||
guint timer;
|
||||
|
||||
if(log->sawpreedit && log->sawcommit)
|
||||
if(*flag)
|
||||
return 1;
|
||||
log->waiting = flag;
|
||||
log->loop = g_main_loop_new(NULL, FALSE);
|
||||
timer = g_timeout_add_seconds(4, timeout, log->loop);
|
||||
g_main_loop_run(log->loop);
|
||||
@@ -105,14 +129,15 @@ waitdone(Log *log)
|
||||
g_source_remove(timer);
|
||||
g_main_loop_unref(log->loop);
|
||||
log->loop = NULL;
|
||||
return log->sawpreedit && log->sawcommit;
|
||||
log->waiting = NULL;
|
||||
return *flag;
|
||||
}
|
||||
|
||||
int
|
||||
main(int argc, char **argv)
|
||||
{
|
||||
IBusBus *bus;
|
||||
IBusInputContext *ctx;
|
||||
IBusInputContext *a, *b;
|
||||
Log log;
|
||||
int ok;
|
||||
|
||||
@@ -127,6 +152,7 @@ main(int argc, char **argv)
|
||||
return 1;
|
||||
}
|
||||
memset(&log, 0, sizeof log);
|
||||
b = NULL;
|
||||
ibus_init();
|
||||
bus = ibus_bus_new();
|
||||
if(bus == NULL || !ibus_bus_is_connected(bus)){
|
||||
@@ -134,36 +160,56 @@ main(int argc, char **argv)
|
||||
if(bus != NULL) g_object_unref(bus);
|
||||
return 1;
|
||||
}
|
||||
ctx = ibus_bus_create_input_context(bus, "strans-libibus-smoke");
|
||||
if(ctx == NULL){
|
||||
a = ibus_bus_create_input_context(bus, "strans-libibus-smoke-a");
|
||||
if(a == NULL){
|
||||
fprintf(stderr, "ibus_client_smoke: cannot create input context\n");
|
||||
g_object_unref(bus);
|
||||
return 1;
|
||||
}
|
||||
g_signal_connect(ctx, "update-preedit-text", G_CALLBACK(legacy), &log);
|
||||
g_signal_connect(ctx, "update-preedit-text-with-mode", G_CALLBACK(modern),
|
||||
log.a = a;
|
||||
g_signal_connect(a, "update-preedit-text", G_CALLBACK(legacy), &log);
|
||||
g_signal_connect(a, "update-preedit-text-with-mode", G_CALLBACK(modern),
|
||||
&log);
|
||||
g_signal_connect(ctx, "commit-text", G_CALLBACK(commit), &log);
|
||||
ibus_input_context_set_capabilities(ctx, IBUS_CAP_PREEDIT_TEXT);
|
||||
ibus_input_context_focus_in(ctx);
|
||||
ok = ibus_input_context_process_key_event(ctx, 'n', 0, IBUS_CONTROL_MASK) &&
|
||||
ibus_input_context_process_key_event(ctx, 'k', 0, 0) &&
|
||||
ibus_input_context_process_key_event(ctx, 'a', 0, 0) &&
|
||||
ibus_input_context_process_key_event(ctx, '0', 0, 0) &&
|
||||
waitdone(&log);
|
||||
ibus_input_context_focus_out(ctx);
|
||||
if(log.legacy == 0 || log.modern != 0 || log.commit != 1 ||
|
||||
log.invalid || !log.sawpreedit || !log.sawcommit)
|
||||
g_signal_connect(a, "commit-text", G_CALLBACK(commit), &log);
|
||||
ibus_input_context_set_capabilities(a, IBUS_CAP_PREEDIT_TEXT);
|
||||
ibus_input_context_focus_in(a);
|
||||
ok = ibus_input_context_process_key_event(a, 'n', 0, IBUS_CONTROL_MASK) &&
|
||||
ibus_input_context_process_key_event(a, 'k', 0, 0) &&
|
||||
ibus_input_context_process_key_event(a, 'a', 0, 0) &&
|
||||
ibus_input_context_process_key_event(a, '0', 0, 0) &&
|
||||
waitflag(&log, &log.done);
|
||||
b = ibus_bus_create_input_context(bus, "strans-libibus-smoke-b");
|
||||
if(b == NULL)
|
||||
ok = 0;
|
||||
g_object_unref(ctx);
|
||||
else{
|
||||
g_signal_connect(b, "update-preedit-text", G_CALLBACK(legacy), &log);
|
||||
g_signal_connect(b, "update-preedit-text-with-mode",
|
||||
G_CALLBACK(modern), &log);
|
||||
ibus_input_context_set_capabilities(b, IBUS_CAP_PREEDIT_TEXT);
|
||||
log.transfer = 1;
|
||||
ok = ok && ibus_input_context_process_key_event(a, 'k', 0, 0) &&
|
||||
waitflag(&log, &log.atext);
|
||||
ibus_input_context_focus_in(b);
|
||||
ok = ok && ibus_input_context_process_key_event(b, 'n', 0, 0) &&
|
||||
waitflag(&log, &log.aclear);
|
||||
ibus_input_context_focus_out(b);
|
||||
}
|
||||
ibus_input_context_focus_out(a);
|
||||
if(log.legacy == 0 || log.modern != 0 || log.commit != 1 ||
|
||||
log.invalid || !log.done || !log.atext || !log.aclear ||
|
||||
log.clearctx != a)
|
||||
ok = 0;
|
||||
if(b != NULL)
|
||||
g_object_unref(b);
|
||||
g_object_unref(a);
|
||||
g_object_unref(bus);
|
||||
if(!ok){
|
||||
fprintf(stderr,
|
||||
"ibus_client_smoke: legacy=%d modern=%d commit=%d invalid=%d preedit=%d committed=%d\n",
|
||||
"ibus_client_smoke: legacy=%d modern=%d commit=%d invalid=%d preedit=%d committed=%d transfer-text=%d a-clear=%d\n",
|
||||
log.legacy, log.modern, log.commit, log.invalid,
|
||||
log.sawpreedit, log.sawcommit);
|
||||
log.sawpreedit, log.sawcommit, log.atext, log.aclear);
|
||||
return 1;
|
||||
}
|
||||
printf("official libibus client preedit and commit: ok\n");
|
||||
printf("official libibus client preedit, commit, and owner clear: ok\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user