Implement text commit from the IME system

This commit is contained in:
Kovid Goyal
2018-07-11 12:21:31 +05:30
parent d27e7ead49
commit 56063b283e
5 changed files with 46 additions and 3 deletions

4
glfw/glfw3.h vendored
View File

@@ -1399,7 +1399,9 @@ typedef void (* GLFWscrollfun)(GLFWwindow*,double,double);
* @param[in] mods Bit field describing which [modifier keys](@ref mods) were
* held down.
* @param[in] text UTF-8 encoded text generated by this key event or empty string.
* @param[in] reserved Reserved for future use.
* @param[in] Used for Input Method events. Zero for normal key events.
* A value of 1 means the pre-edit text for the input event has been changed.
* A value of 2 means the text should be committed.
*
* @note On X11/Wayland if a modifier other than the modifiers GLFW reports
* (ctrl/shift/alt/super) is used, GLFW will report the shifted key rather

9
glfw/ibus_glfw.c vendored
View File

@@ -103,6 +103,13 @@ get_ibus_text_from_message(DBusMessage *msg) {
return text;
}
static inline void
send_text(const char *text, int state) {
_GLFWwindow *w = _glfwFocusedWindow();
if (w && w->callbacks.keyboard) {
w->callbacks.keyboard((GLFWwindow*) w, GLFW_KEY_UNKNOWN, 0, GLFW_PRESS, 0, text, state);
}
}
// Connection handling {{{
@@ -117,9 +124,11 @@ message_handler(DBusConnection *conn, DBusMessage *msg, void *user_data) {
case 0:
text = get_ibus_text_from_message(msg);
debug("IBUS: CommitText: '%s'\n", text ? text : "(nil)");
send_text(text, 2);
break;
case 1:
text = get_ibus_text_from_message(msg);
send_text(text, 1);
debug("IBUS: UpdatePreeditText: '%s'\n", text ? text : "(nil)");
break;
case 2:

4
glfw/internal.h vendored
View File

@@ -59,6 +59,7 @@
#define _GLFW_MESSAGE_SIZE 1024
typedef int GLFWbool;
typedef unsigned long long GLFWid;
typedef struct _GLFWerror _GLFWerror;
typedef struct _GLFWinitconfig _GLFWinitconfig;
@@ -377,6 +378,7 @@ struct _GLFWwindow
GLFWbool focusOnShow;
GLFWbool shouldClose;
void* userPointer;
GLFWid id;
GLFWvidmode videoMode;
_GLFWmonitor* monitor;
_GLFWcursor* cursor;
@@ -525,6 +527,7 @@ struct _GLFWlibrary
_GLFWerror* errorListHead;
_GLFWcursor* cursorListHead;
_GLFWwindow* windowListHead;
GLFWid focusedWindowId;
_GLFWmonitor** monitors;
int monitorCount;
@@ -702,6 +705,7 @@ void _glfwPlatformUnlockMutex(_GLFWmutex* mutex);
//////////////////////////////////////////////////////////////////////////
void _glfwInputWindowFocus(_GLFWwindow* window, GLFWbool focused);
_GLFWwindow* _glfwFocusedWindow();
void _glfwInputWindowPos(_GLFWwindow* window, int xpos, int ypos);
void _glfwInputWindowSize(_GLFWwindow* window, int width, int height);
void _glfwInputFramebufferSize(_GLFWwindow* window, int width, int height);

15
glfw/window.c vendored
View File

@@ -48,6 +48,7 @@ void _glfwInputWindowFocus(_GLFWwindow* window, GLFWbool focused)
if (!focused)
{
int key, button;
_glfw.focusedWindowId = 0;
for (key = 0; key <= GLFW_KEY_LAST; key++)
{
@@ -63,7 +64,19 @@ void _glfwInputWindowFocus(_GLFWwindow* window, GLFWbool focused)
if (window->mouseButtons[button] == GLFW_PRESS)
_glfwInputMouseClick(window, button, GLFW_RELEASE, 0);
}
} else
_glfw.focusedWindowId = window->id;
}
_GLFWwindow* _glfwFocusedWindow() {
if (_glfw.focusedWindowId) {
_GLFWwindow *w = _glfw.windowListHead;
while (w) {
if (w->id == _glfw.focusedWindowId) return w;
w = w->next;
}
}
return NULL;
}
// Notifies shared code that a window has moved
@@ -185,8 +198,10 @@ GLFWAPI GLFWwindow* glfwCreateWindow(int width, int height,
if (!_glfwIsValidContextConfig(&ctxconfig))
return NULL;
static GLFWid windowIdCounter = 0;
window = calloc(1, sizeof(_GLFWwindow));
window->next = _glfw.windowListHead;
window->id = ++windowIdCounter;
_glfw.windowListHead = window;
window->videoMode.width = width;

View File

@@ -114,9 +114,23 @@ check_if_special(int key, int mods, int scancode) {
}
void
on_key_input(int key, int scancode, int action, int mods, const char* text, int state UNUSED) {
on_key_input(int key, int scancode, int action, int mods, const char* text, int state) {
Window *w = active_window();
if (!w) return;
Screen *screen = w->render_data.screen;
switch(state) {
case 1: // update pre-edit text
return;
case 2: // commit text
if (text && *text) {
schedule_write_to_child(w->id, text, strlen(text));
}
return;
case 0:
break;
default:
return;
}
if (global_state.in_sequence_mode) {
if (
action != GLFW_RELEASE &&
@@ -124,7 +138,6 @@ on_key_input(int key, int scancode, int action, int mods, const char* text, int
) call_boss(process_sequence, "iiii", key, scancode, action, mods);
return;
}
Screen *screen = w->render_data.screen;
bool has_text = text && !is_ascii_control_char(text[0]);
if (action == GLFW_PRESS || action == GLFW_REPEAT) {
if (check_if_special(key, mods, scancode)) {