diff --git a/glfw/dbus_glfw.c b/glfw/dbus_glfw.c index 7610917cd..50eda8491 100644 --- a/glfw/dbus_glfw.c +++ b/glfw/dbus_glfw.c @@ -219,7 +219,7 @@ method_reply_received(DBusPendingCall *pending, void *user_data) { } static GLFWbool -call_method(DBusConnection *conn, const char *node, const char *path, const char *interface, const char *method, dbus_pending_callback callback, void *user_data, va_list ap) { +call_method(DBusConnection *conn, const char *node, const char *path, const char *interface, const char *method, int timeout, dbus_pending_callback callback, void *user_data, va_list ap) { if (!conn) return GLFW_FALSE; DBusMessage *msg = dbus_message_new_method_call(node, path, interface, method); if (!msg) return GLFW_FALSE; @@ -233,7 +233,7 @@ call_method(DBusConnection *conn, const char *node, const char *path, const char if ((firstarg == DBUS_TYPE_INVALID) || dbus_message_append_args_valist(msg, firstarg, ap)) { if (callback) { DBusPendingCall *pending = NULL; - if (dbus_connection_send_with_reply(conn, msg, &pending, DBUS_TIMEOUT_USE_DEFAULT)) { + if (dbus_connection_send_with_reply(conn, msg, &pending, timeout)) { dbus_pending_call_set_notify(pending, method_reply_received, res, free); retval = GLFW_TRUE; } else { @@ -255,11 +255,11 @@ call_method(DBusConnection *conn, const char *node, const char *path, const char } GLFWbool -glfw_dbus_call_method_with_reply(DBusConnection *conn, const char *node, const char *path, const char *interface, const char *method, dbus_pending_callback callback, void* user_data, ...) { +glfw_dbus_call_method_with_reply(DBusConnection *conn, const char *node, const char *path, const char *interface, const char *method, int timeout, dbus_pending_callback callback, void* user_data, ...) { GLFWbool retval; va_list ap; va_start(ap, user_data); - retval = call_method(conn, node, path, interface, method, callback, user_data, ap); + retval = call_method(conn, node, path, interface, method, timeout, callback, user_data, ap); va_end(ap); return retval; } @@ -269,7 +269,7 @@ glfw_dbus_call_method_no_reply(DBusConnection *conn, const char *node, const cha GLFWbool retval; va_list ap; va_start(ap, method); - retval = call_method(conn, node, path, interface, method, NULL, NULL, ap); + retval = call_method(conn, node, path, interface, method, DBUS_TIMEOUT_USE_DEFAULT, NULL, NULL, ap); va_end(ap); return retval; } diff --git a/glfw/dbus_glfw.h b/glfw/dbus_glfw.h index 15fd67d2d..3cd0fb41b 100644 --- a/glfw/dbus_glfw.h +++ b/glfw/dbus_glfw.h @@ -44,7 +44,7 @@ void glfw_dbus_close_connection(DBusConnection *conn); GLFWbool glfw_dbus_call_method_no_reply(DBusConnection *conn, const char *node, const char *path, const char *interface, const char *method, ...); GLFWbool -glfw_dbus_call_method_with_reply(DBusConnection *conn, const char *node, const char *path, const char *interface, const char *method, dbus_pending_callback callback, void *user_data, ...); +glfw_dbus_call_method_with_reply(DBusConnection *conn, const char *node, const char *path, const char *interface, const char *method, int timeout_ms, dbus_pending_callback callback, void *user_data, ...); void glfw_dbus_dispatch(DBusConnection *); GLFWbool glfw_dbus_get_args(DBusMessage *msg, const char *failmsg, ...); int glfw_dbus_match_signal(DBusMessage *msg, const char *interface, ...); diff --git a/glfw/ibus_glfw.c b/glfw/ibus_glfw.c index 50564ae49..d42dc55e1 100644 --- a/glfw/ibus_glfw.c +++ b/glfw/ibus_glfw.c @@ -266,7 +266,7 @@ setup_connection(_GLFWIBUSData *ibus) { if (!ibus->conn) return GLFW_FALSE; free((void*)ibus->input_ctx_path); ibus->input_ctx_path = NULL; if (!glfw_dbus_call_method_with_reply( - ibus->conn, IBUS_SERVICE, IBUS_PATH, IBUS_INTERFACE, "CreateInputContext", input_context_created, ibus, + ibus->conn, IBUS_SERVICE, IBUS_PATH, IBUS_INTERFACE, "CreateInputContext", DBUS_TIMEOUT_USE_DEFAULT, input_context_created, ibus, DBUS_TYPE_STRING, &client_name, DBUS_TYPE_INVALID)) { return GLFW_FALSE; } @@ -393,13 +393,15 @@ key_event_processed(DBusMessage *msg, const char* errmsg, void *data) { uint32_t handled = 0; KeyEvent *ev = (KeyEvent*)data; GLFWbool is_release = ev->action == GLFW_RELEASE; + GLFWbool failed = GLFW_FALSE; if (errmsg) { _glfwInputError(GLFW_PLATFORM_ERROR, "IBUS: Failed to process key with error: %s", errmsg); + failed = GLFW_TRUE; } else { glfw_dbus_get_args(msg, "Failed to get IBUS handled key from reply", DBUS_TYPE_BOOLEAN, &handled, DBUS_TYPE_INVALID); debug("IBUS processed scancode: 0x%x release: %d handled: %u\n", ev->keycode, is_release, handled); } - glfw_xkb_key_from_ime(ev, handled ? GLFW_TRUE : GLFW_FALSE); + glfw_xkb_key_from_ime(ev, handled ? GLFW_TRUE : GLFW_FALSE, failed); free(ev); } @@ -412,7 +414,7 @@ ibus_process_key(const KeyEvent *ev_, _GLFWIBUSData *ibus) { uint32_t state = ibus_key_state(ev->glfw_modifiers, ev->action); if (!glfw_dbus_call_method_with_reply( ibus->conn, IBUS_SERVICE, ibus->input_ctx_path, IBUS_INPUT_INTERFACE, "ProcessKeyEvent", - key_event_processed, ev, + 3000, key_event_processed, ev, DBUS_TYPE_UINT32, &ev->ibus_sym, DBUS_TYPE_UINT32, &ev->ibus_keycode, DBUS_TYPE_UINT32, &state, DBUS_TYPE_INVALID)) { free(ev); diff --git a/glfw/xkb_glfw.c b/glfw/xkb_glfw.c index 91b4d6096..79aa1ddaa 100644 --- a/glfw/xkb_glfw.c +++ b/glfw/xkb_glfw.c @@ -413,8 +413,12 @@ glfw_xkb_update_ime_state(_GLFWwindow *w, _GLFWXKBData *xkb, int which, int a, i } void -glfw_xkb_key_from_ime(KeyEvent *ev, GLFWbool handled_by_ime) { +glfw_xkb_key_from_ime(KeyEvent *ev, GLFWbool handled_by_ime, GLFWbool failed) { _GLFWwindow *window = _glfwWindowForId(ev->window_id); + if (failed && window && window->callbacks.keyboard) { + // notify application to remove any existing pre-edit text + window->callbacks.keyboard((GLFWwindow*) window, GLFW_KEY_UNKNOWN, 0, GLFW_PRESS, 0, "", 1); + } static xkb_keycode_t last_handled_press_keycode = 0; // We filter out release events that correspond to the last press event // handled by the IME system. This wont fix the case of multiple key diff --git a/glfw/xkb_glfw.h b/glfw/xkb_glfw.h index 993ceecd9..422642767 100644 --- a/glfw/xkb_glfw.h +++ b/glfw/xkb_glfw.h @@ -93,4 +93,4 @@ xkb_keysym_t glfw_xkb_sym_for_key(int key); void glfw_xkb_handle_key_event(_GLFWwindow *window, _GLFWXKBData *xkb, xkb_keycode_t scancode, int action); int glfw_xkb_keysym_from_name(const char *name, GLFWbool case_sensitive); void glfw_xkb_update_ime_state(_GLFWwindow *w, _GLFWXKBData *xkb, int which, int a, int b, int c, int d); -void glfw_xkb_key_from_ime(KeyEvent *ev, GLFWbool handled_by_ime); +void glfw_xkb_key_from_ime(KeyEvent *ev, GLFWbool handled_by_ime, GLFWbool failed);