Experimental IBus support for X11 backend built on top of the IME API#10
Experimental IBus support for X11 backend built on top of the IME API#10ashie wants to merge 12 commits into
Conversation
Introduce glfwSetTextInputFocus(window, focused), internal state and a platform hook for explicit application text input focus. Track whether the application has explicitly called the API with textInputFocusExplicit, so existing applications keep legacy platform behavior until they opt into explicit text input focus. This follows the text input focus direction from the IME support discussions in #5 and #7, without changing platform behavior yet.
Map explicit text input focus to XIM input context focus with XSetICFocus and XUnsetICFocus. On focus out, reset preedit through the existing X11 helper before unsetting IC focus, preserving its conservative behavior. Native FocusIn only restores XIC focus when text input focus has not been explicitly disabled.
When explicit text input focus is inactive, keep GLFW from processing its own WM_IME_* composition, preedit, candidate and IME status paths while preserving normal key input. On Win32, gating GLFW message handling is not enough to prevent native IMM candidate UI from appearing. Temporarily associate a NULL HIMC with the window while explicit text input focus is out, then restore the saved HIMC when focus returns. Cancel and clear active preedit/candidate state as focus-out cleanup. After restoring the HIMC, reapply the preedit cursor rectangle so candidate UI uses the latest location.
When explicit text input focus is inactive, skip interpretKeyEvents and send plain event characters through GLFW text input instead. This prevents routing key events through NSTextInput composition while preserving normal key input. Applications that never call glfwSetTextInputFocus keep the previous interpretKeyEvents behavior. On focus out, discard marked text through the existing NSTextInputContext reset path. Do not use TIS input source switching for this API.
Map explicit text input focus to text-input-v3 enable/disable and text-input-v1 activate/deactivate. When text input focus is inactive, avoid auto-enabling text input on protocol enter and ignore stale text-input callbacks. Applications that never call glfwSetTextInputFocus keep the previous enter-time activation behavior. On focus out, reset local preedit state and send the available protocol reset/disable requests.
Expose glfwSetTextInputFocus in the input_text test so IME and text input focus behavior can be exercised independently. The UI starts in compatibility mode, then shows explicit Focus In or Focus Out after the toggle is used.
This adds a dynamically loaded X11 IME module ABI and an experimental glfw-ibus.so backend for feasibility testing only. The module owns D-Bus and worker-thread communication, while GLFW drains queued IME events on the main thread without modifying the event loop architecture. The prototype includes preedit and commit handling, cursor location updates for IBus SetCursorLocation, the first-candidate-window positioning workaround, GLFW_IME_DEBUG instrumentation, and documentation of the architecture and known timeout risks.
Keep XFilterEvent as the suppressor for the XIM path, but do not call it before the experimental IME module sees KeyPress events. When the module reports a key as handled, return before normal GLFW key and character processing. This gives the IME module path the same kind of duplicate-input suppression that XFilterEvent provides for the XIM path, while keeping the XIM behavior unchanged. This effectively extends the duplicate-input suppression addressed by PR glfw#1972 to the experimental IME module path.
Map glfwSetTextInputFocus to the experimental X11 IME module path. When text input focus is enabled for a focused X11 window, send FocusIn to the module so IBus resumes routing text input. When it is disabled, reset composition and send FocusOut, keeping GLFW window focus separate from the text input focus abstraction. Also gate the module KeyPress path on GLFW's text input focus state so FocusOut actually stops routing input through IBus. Applications that never opt into explicit text input focus keep the legacy behavior. Document the prototype mapping without adding a new module ABI entry.
Parse IBus UpdatePreeditText cursor position, visibility and text attributes in the experimental X11 IME module. The module now converts IBus attribute ranges into GLFW preedit block sizes, picks a focused block from highlighted attributes or the caret, and passes the caret index through to the GLFW main-thread preedit update. This keeps D-Bus and IBus details inside the module while allowing applications to draw richer preedit state. Bump the experimental module ABI because the host preedit callback now carries block metadata.
Document the current state of the experimental X11 IBus module after adding text input focus gating and richer preedit handling. The prototype now maps IBus caret and attribute ranges to GLFW preedit state, gates ProcessKeyEvent on explicit text input focus, and is close to usable for application testing while still remaining experimental.
Add two switches for game/application compatibility testing. GLFW_IME_MODE_AS_TEXT_INPUT_FOCUS makes GLFW_IME control GLFW's text input focus path by default, and also acts as the runtime override environment variable. This lets applications that already toggle GLFW_IME use the more portable text-input-focus semantics without code changes. glfwGetInputMode(GLFW_IME) keeps reporting the native IME status until text input focus has been explicitly set for the window, preserving the old query behavior for applications that never use the compatibility mode. GLFW_EMBED_IBUS_MODULE builds the IBus backend into the X11 GLFW library. The embedded backend is used when GLFW_IM_MODULE is not set, while GLFW_IM_MODULE can still override it with an external module.
New experimental build switchesI've added two more optional build switches for experiments with applications that already use GLFW with glfw#2130. These options are not intended as an upstream API proposal. They are provided to make it easier to evaluate the IBus backend with existing applications and prebuilt GLFW binaries.
|
This PR is an experiment built on top of the IME API introduced by PR #2130: Add IME support for each platform.
One motivation for this work is that the traditional X11 XIM protocol is relatively limited compared to modern IME frameworks and can make it difficult to provide functionality comparable to IME implementations available on other platforms.
While XIM remains useful as a baseline solution, as GLFW's IME support evolves, it may be desirable to investigate alternatives that can expose richer IME functionality on X11.
The goal of this experiment is therefore not to propose IBus support for GLFW itself, but to evaluate whether the abstractions introduced by PR glfw#2130 are flexible enough to support an alternative X11 IME backend without modifying the GLFW event loop.
The prototype uses:
and currently supports:
on X11.
This implementation should be viewed as a research prototype rather than an upstream proposal.
See docs/ime-ibus-prototype.md for architecture details, design rationale, limitations and future work.
Additional prerequisites
Build:
Run demo:
$ GLFW_IM_MODULE=$PWD/build/src/glfw-ibus.so ./build/tests/input_text