Backed out 4 changesets (bug 1825722) for causing reftest failures CLOSED TREE
[gecko.git] / editor / docs / IMEHandlingGuide.rst
blob10f2d3b58ed7bf2b26d56273d2b013627c867488
1 ==================
2 IME handling guide
3 ==================
5 This document explains how Gecko handles IME.
7 Introduction
8 ============
10 IME is an abbreviation of Input Method Editor. This is a technical term from
11 Windows but these days, this is used on other platforms as well.
13 IME is a helper application of a user's text input. It handles native key
14 events before or after focused application (depending on the platform) and
15 creates a composition string (a.k.a. preedit string), suggests a list of what
16 the user attempts to input, commits composition string as a selected item off
17 the list and commits composition string without any conversion. IME is used by
18 Chinese, Japanese, Korean and Taiwan users for inputting Chinese characters
19 because the number of them is beyond thousands and cannot be input from the
20 keyboard directly. However, especially on mobile devices nowadays, IME is also
21 used for inputting Latin languages like autocomplete. Additionally, IME may be
22 used for handwriting systems or speech input systems on some platforms.
24 If IME is available on focused elements, we call that state "enabled". If IME
25 is not fully available(i.e., user cannot enable IME), we call this state
26 "disabled".
28 If IME is enabled but users use direct input mode (e.g., for inputting Latin
29 characters), we call it "IME is closed". Otherwise, we call it "IME is open".
30 (FYI: "open" is also called "active" or "turned on". "closed" is also called
31 "inactive" or "turned off")
33 So, this document is useful when you're try to fix a bug for text input in
34 Gecko.
37 Composition string and clauses
38 ==============================
40 Typical Japanese IME can input two or more words into a composition string.
41 When a user converts from Hiragana characters to Chinese characters the
42 composition string, Japanese IME separates the composition string into multiple
43 clauses. For example, if a user types "watasinonamaehanakanodesu", it's
44 converted to Hiragana characters, "わたしのなまえはなかのです", automatically (In
45 the following screenshots, the composition string has a wavy underline and the
46 only one clause is called "raw input clause").
48 .. image:: inputting_composition_string.png
49    :alt: Screenshot of raw composition string which is inputting Roman
50          character mode of MS-IME (Japanese)
52 .. image:: raw_composition_string.png
53    :alt: Screenshot of raw composition string whose all characters are Hiragana
54          character (MS-IME, Japanese)
56 When a user presses ``Convert`` key, Japanese IME separates the composition
57 string as "わたしの" (my), "なまえは" (name is) and "なかのです" (Nakano). Then,
58 converts each clause with Chinese characters: "私の", "名前は" and "中野です" (In
59 the following screenshot each clause is underlined and not connected
60 adjacently. These clauses are called "converted clause").
62 .. image:: converted_composition_string.png
63    :alt: Screenshot of converted composition string (MS-IME, Japanese)
65 If one or more clauses were not converted as expected, the user can choose one
66 of the clauses with Arrow keys and look for the expected result form the list
67 in the drop down menu (In the following screenshot, the clause with the thicker
68 underline is called "selected clause").
70 .. image:: candidatewindow.png
71    :alt: Screenshot of candidate window of MS-IME (Japanese) which converts the
72          selected clause
74 Basically, composition string and each clause style is rendered by Gecko. And
75 the drop down menu is created by IME.
77 Each clause is represented with selection in the editor. From chrome script,
78 you can check it with ``nsISelectionController``. In native code, you can
79 access it with either ``nsISelectionController`` or ``mozilla::SelectionType``
80 (the latter is recommended because of type safer). And editor sets these IME
81 selections from ``mozilla::TextRangeType`` which are sent by
82 ``mozilla::WidgetCompositionEvent`` as ``mozilla::TextRangeArray``. The
83 following table explains the mapping between them.
85 .. table:: Selection types of each clause of composition string or caret
87    +------------------------------------------------------------+---------------------------------------+-------------------------+-------------------------+
88    |                                                            |`nsISelectionController`_              |`mozilla::SelectionType`_|`mozilla::TextRangeType`_|
89    +============================================================+=======================================+=========================+=========================+
90    |Caret                                                       |``SELECTION_NORMAL``                   |``eNormal``              |``eCaret``               |
91    +------------------------------------------------------------+---------------------------------------+-------------------------+-------------------------+
92    |Raw text typed by the user                                  |``SELECTION_IME_RAW_INPUT``            |``eIMERawClause``        |``eRawClause``           |
93    +------------------------------------------------------------+---------------------------------------+-------------------------+-------------------------+
94    |Selected clause of raw text typed by the user               |``SELECTION_IME_SELECTEDRAWTEXT``      |``eIMESelectedRawClause``|``eSelectedRawClause``   |
95    +------------------------------------------------------------+---------------------------------------+-------------------------+-------------------------+
96    |Converted clause by IME                                     |``SELECTION_IME_CONVERTEDTEXT``        |``eIMEConvertedClause``  |``eConvertedClause``     |
97    +------------------------------------------------------------+---------------------------------------+-------------------------+-------------------------+
98    |Selected clause by the user or IME and also converted by IME|``SELECTION_IME_SELECTEDCONVERTEDTEXT``|``eIMESelectedClause``   |``eSelectedClause``      |
99    +------------------------------------------------------------+---------------------------------------+-------------------------+-------------------------+
101 Note that typically, "Selected clause of raw text typed by the user" isn't used
102 because when composition string is already separated to multiple clauses, that
103 means that the composition string has already been converted by IME at least
104 once.
106 .. _nsISelectionController: https://searchfox.org/mozilla-central/source/dom/base/nsISelectionController.idl
107 .. _mozilla::SelectionType: https://searchfox.org/mozilla-central/source/dom/base/nsISelectionController.idl
108 .. _mozilla::TextRangeType: https://searchfox.org/mozilla-central/source/widget/TextRange.h
110 Modules handling IME composition
111 ================================
113 widget
114 ------
116 Each widget handles native IME events and dispatches ``WidgetCompositionEvent``
117 with ``mozilla::widget::TextEventDispatcher`` to represent the behavior of IME
118 in the focused editor.
120 This is the only module that depends on the users platform. See also
121 `Native IME handlers`_ section for the detail of each platform's
122 implementation.
124 .. note::
126    Android widget still does not use ``TextEventDispatcher`` to dispatch
127    ``WidgetCompositionEvents``, see
128    `bug 1137567 <https://bugzilla.mozilla.org/show_bug.cgi?id=1137567>`__.
130 mozilla::widget::TextEventDispatcher
131 ------------------------------------
133 This class is used by native IME handler(s) on each platform. This capsules the
134 logic to dispatch ``WidgetCompositionEvent`` and ``WidgetKeyboardEvent`` for
135 making the behavior on each platform exactly same. For example, if
136 ``WidgetKeyboardEvent`` should be dispatched when there is a composition is
137 managed by this class in XP level. First of use, native IME handlers get the
138 rights to use ``TextEventDispatcher`` with a call of
139 ``BeginNativeInputTransaction()``. Then, ``StartComposition()``,
140 ``SetPendingComposition()``, ``FlushPendingComposition()``,
141 ``CommitComposition()``, etc. are available if
142 ``BeginNativeInputTransaction()`` return true. These methods automatically
143 manage composition state and dispatch ``WidgetCompositionEvent`` properly.
145 This is also used by ``mozilla::TextInputProcessor`` which can emulates (or
146 implements) IME with chrome script. So, native IME handlers using this class
147 means that the dispatching part is also tested by automated tests.
149 mozilla::WidgetCompositionEvent
150 -------------------------------
152 Internally, ``WidgetCompositionEvent`` represents native IME behavior. Its
153 message is one of following values:
155 eCompositionStart
156 ^^^^^^^^^^^^^^^^^
158 This is dispatched at starting a composition. This represents a DOM
159 ``compositionstart`` event. The mData value is a selected string at dispatching
160 the DOM event and it's automatically set by ``TextComposition``.
162 eCompositionUpdate
163 ^^^^^^^^^^^^^^^^^^
165 This is dispatched by ``TextComposition`` when an ``eCompositionChange`` will
166 change the composition string. This represents a DOM ``compositionupdate``
167 event.
169 eCompositionEnd
170 ^^^^^^^^^^^^^^^
172 This is dispatched by ``TextComposition`` when an ``eCompositionCommitAsIs`` or
173 ``eCompositionCommit`` event is dispatched. This represents a DOM
174 ``compositionend`` event.
176 eCompositionChange
177 ^^^^^^^^^^^^^^^^^^
179 This is used internally only. This is dispatched at modifying a composition
180 string, committing a composition, changing caret position and/or changing
181 ranges of clauses. This represents a DOM text event which is not in any
182 standards. ``mRanges`` should not be empty only with this message.
184 eCompositionCommitAsIs
185 ^^^^^^^^^^^^^^^^^^^^^^
187 This is used internally only. This is dispatched when a composition is
188 committed with the string. The ``mData`` value should be always be an empty
189 string. This causes a DOM text event without clause information and a DOM
190 ``compositionend`` event.
192 eCompositionCommit
193 ^^^^^^^^^^^^^^^^^^
195 This is used internally only. This is dispatched when a composition is
196 committed with specific string. The ``mData`` value is the commit string. This
197 causes a DOM text event without clause information and a DOM ``compositionend``
198 event.
200 .. table:: Table of event messages
202    +--------------------------+-------------------------------------------+-------------------------------+-----------------------+----------------------+
203    |                          |meaning of mData                           |who sets ``mData``?            |``mRanges``            |representing DOM event|
204    +==========================+===========================================+===============================+=======================+======================+
205    |``eCompositionStart``     |selected string before starting composition|``TextComposition``            |``nullptr``            |``compositionstart``  |
206    +--------------------------+-------------------------------------------+-------------------------------+-----------------------+----------------------+
207    |``eCompositionUpdate``    |new composition string                     |``TextComposition``            |``nullptr``            |``compositionupdate`` |
208    +--------------------------+-------------------------------------------+-------------------------------+-----------------------+----------------------+
209    |``eCompositionEnd``       |commit string                              |``TextComposition``            |``nullptr``            |``compositionend``    |
210    +--------------------------+-------------------------------------------+-------------------------------+-----------------------+----------------------+
211    |``eCompositionChange``    |new composition string                     |widget (or ``TextComposition``)|must not be ``nullptr``|``text``              |
212    +--------------------------+-------------------------------------------+-------------------------------+-----------------------+----------------------+
213    |``eCompositionCommitAsIs``|N/A (must be empty)                        |nobody                         |``nullptr``            |None                  |
214    +--------------------------+-------------------------------------------+-------------------------------+-----------------------+----------------------+
215    |``eCompositionCommit``    |commit string                              |widget (or ``TextComposition``)|``nullptr``            |None                  |
216    +--------------------------+-------------------------------------------+-------------------------------+-----------------------+----------------------+
218 PresShell
219 ---------
221 ``PresShell`` receives the widget events and decides an event target from
222 focused document and element. Then, it sends the events and the event target to
223 ``IMEStateManager``.
225 mozilla::IMEStateManager
226 ------------------------
228 ``IMEStateManager`` looks for a ``TextComposition`` instance whose native IME
229 context is same as the widget' which dispatches the widget event. If there is
230 no proper ``TextComposition`` instance, it creates the instance. And it sends
231 the event to the ``TextComposition`` instance.
233 Note that all instances of ``TextComposition`` are managed by
234 ``IMEStateManager``. When an instance is created, it's registered to the list.
235 When composition completely ends, it's unregistered from the list (and released
236 automatically).
238 mozilla::TextComposition
239 ------------------------
241 ``TextComposition`` manages a composition and dispatches DOM
242 ``compositionupdate`` events.
244 When this receives an ``eCompositionChange``, ``eCompositionCommit`` or
245 ``eCompositionCommitAsIs`` event, it dispatches the event to the stored node
246 which was the event target of ``eCompositionStart`` event. Therefore, this
247 class guarantees that all composition events for a composition are fired on
248 same element.
250 When this receives ``eCompositionChange`` or ``eCompositionCommit``, this
251 checks if new composition string (or committing string) is different from the
252 last data stored by the ``TextComposition``. If the composition event is
253 changing the composition string, the ``TextComposition`` instance dispatches
254 ``WidgetCompositionEvent`` with ``eCompositionUpdate`` into the DOM tree
255 directly and modifies the last data. The ``eCompositionUpdate`` event will
256 cause a DOM ``compositionupdate`` event.
258 When this receives ``eCompositionCommitAsIs`` or ``eCompositionCommit``, this
259 dispatches an ``eCompositionEnd`` event which will cause a DOM
260 ``compositionend`` event after dispatching ``eCompositionUpdate`` event and/or
261 ``eCompositionChange`` event if necessary.
263 One of the other important jobs of this is, when a focused editor handles a
264 dispatched ``eCompositionChange`` event, this modifies the stored composition
265 string and its clause information. The editor refers the stored information for
266 creating or modifying a text node representing a composition string.
268 And before dispatching ``eComposition*`` events, this class removes ASCII
269 control characters from dispatching composition event's data in the default
270 settings. Although, this can be disabled with
271 ``"dom.compositionevent.allow_control_characters"`` pref.
273 Finally, this class guarantees that requesting to commit or cancel current
274 composition to IME is perefored synchronously. See
275 `Forcibly committing composition`_ section for the detail.
277 editor/libeditor
278 ----------------
280 `mozilla::EditorEventListener <https://searchfox.org/mozilla-central/source/editor/libeditor/EditorEventListener.cpp>`__
281 listens for trusted DOM ``compositionstart``, ``text`` and ``compositionend``
282 events and notifies
283 `mozilla::EditorBase <https://searchfox.org/mozilla-central/source/editor/libeditor/EditorBase.cpp>`__
285 `mozilla::TextEditor <https://searchfox.org/mozilla-central/source/editor/libeditor/TextEditor.cpp>`__
286 of the events.
288 When ``EditorBase`` receives an ``eCompositionStart``
289 (DOM ``"compositionstart"``) event, it looks for a proper ``TextComposition``
290 instance and stores it.
292 When ``TextEditor`` receives an ``eCompositionChange`` (DOM ``"text"``) event,
293 it creates or modifies a text node which includes the composition string and
294 `mozilla::CompositionTransaction <https://searchfox.org/mozilla-central/source/editor/libeditor/CompositionTransaction.cpp>`__
295 (it was called ``IMETextTxn``) sets IME selections for representing the clauses
296 of the composition string.
298 When ``EditorBase`` receives an ``eCompositionEnd`` (DOM ``"compositionend"``)
299 event, it releases the stored ``TextComposition`` instance.
301 nsTextFrame
302 -----------
303 ``nsTextFrame`` paints IME selections.
305 mozilla::IMEContentObserver
306 ---------------------------
308 ``IMEContentObserver`` observes various changes of a focused editor. When a
309 corresponding element of a ``TextEditor`` or ``HTMLEditor`` instance gets
310 focus, an instance is created by ``IMEStateManager``, then, starts to observe
311 and notifies ``widget`` of IME getting focus. When the editor loses focus, it
312 notifies ``widget`` of IME losing focus and stops observing everything.
313 Finally, it's destroyed by ``IMEStateManager``.
315 This class observes selection changes (caret position changes), text changes of
316 a focused editor and layout changes (by reflow or scroll) of everything in the
317 document. It depends on the result of ``nsIWidget::GetIMEUpdatePreference()``
318 what is observed.
320 When this notifies ``widget`` of something, it needs to be safe to run
321 script because notifying something may cause dispatching one or more DOM events
322 and/or new reflow. Therefore, ``IMEContentObserver`` only stores which
323 notification should be sent to ``widget``. Then,
324 ``mozilla::IMEContentObserver::IMENotificationSender`` tries to send the
325 pending notifications when it might become safe to do that. Currently, it's
326 tried:
328 * after a native event is dispatched from ``PresShell::HandleEventInternal()``
329 * when new focused editor receives DOM ``focus`` event
330 * when next refresh driver tick
332 .. note::
334    The 3rd timing may not be safe actually, but it causes a lot of oranges of
335    automated tests.
337 See also `Notifications to IME`_ section for the detail of sending
338 notifications.
340 Currently, ``WidgetQueryContentEvent`` is handled via ``IMEContentObserver``
341 because if it has a cache of selection, it can set reply of
342 ``eQuerySelectedText`` event only with the cache. That is much faster than
343 using ``ContentEventHandler``.
345 e10s support
346 ============
348 Even when a remote process has focus, native IME handler in chrome process does
349 its job. So, there is process boundary between native IME handler and focused
350 editor. Unfortunately, it's not allowed to use synchronous communication from
351 chrome process to a remote process. This means that chrome process (and also
352 native IME and our native IME handler) cannot query the focused editor contents
353 directly. For fixing this issue, we have ``ContentCache`` classes around
354 process boundary.
356 mozilla::ContentCache
357 ---------------------
358 This is a base class of ``ContentCacheInChild`` and ``ContentCacheInParent``
359 and IPC-aware. This has common members of them including all cache data:
361 ``mText``
362     Whole text in focused editor. This may be too big but IME may request all
363     text in the editor.
365     If we can separate editor contents per paragraph, moving selection between
366     paragraphs generates pseudo focus move, we can reduce this size and runtime
367     cost of ``ContentEventHandler``. However, we've not had a plan to do that
368     yet. Note that Microsoft Word uses this hack.
370 ``mCompositionStart``
371     Offset of composition string in ``mText``. When there is no composition,
372     this is ``UINT32_MAX``.
374 ``mSelection::mAnchor``, ``mSelection::mFocus``
375     Offset of selection anchor and focus in ``mText``.
377 ``mSelection::mWritingMode``
378     Writing mode at selection start.
380 ``mSelection::mAnchorCharRect``, ``mSelection::mFocusCharRect``
381     Next character rectangle of ``mSelection::mAnchor`` and
382     ``mSelection::mFocus``. If corresponding offset is end of the editor
383     contents, its rectangle should be a caret rectangle.
385     These rectangles shouldn't be empty rect.
387 ``mSelection::mRect``
388     Unified character rectangle in selection range. When the selection is
389     collapsed, this should be caret rect.
391 ``mFirstRect``
392     First character rect of ``mText``. When ``mText`` is empty string, this
393     should be caret rect.
395 ``mCaret::mOffset``
396     Always same as selection start offset even when selection isn't collapsed.
398 ``mCaret::mRect``
399     Caret rect at ``mCaret::mOffset``. If caret isn't actually exists, it's
400     computed with a character rect at the offset.
402 ``mTextRectArray::mStart``
403     If there is composition, ``mStart`` is same as ``mCompositionStart``.
404     Otherwise, ``UINT32_MAX``.
406 ``mTextRectArray::mRects``
407     Each character rectangle of composition string.
409 ``mEditorRect``
410     The rect of editor element.
412 mozilla::ContentCacheInChild
413 ----------------------------
415 This exists only in remote processes. This is created as a member of
416 `PuppetWidget <https://searchfox.org/mozilla-central/source/widget/PuppetWidget.cpp>`__.
417 When ``PuppetWidget`` receives notifications to IME from ``IMEContentObserver``
418 in the remote process, it makes this class modify its cached content. Then,
419 this class do that with ``WidgetQueryContentEvents``. Finally, ``PuppetWidget``
420 sends the notification and ``ContentCacheInParent`` instance as
421 ``ContentCache`` to its parent process.
423 mozilla::ContentCacheInParent
424 -----------------------------
426 This exists as a member of ``TabParent``. When ``TabParent`` receives
427 notification from corresponding remote process, it assigns
428 ``ContentCacheInParent`` new ``ContentCache`` and post the notification to
429 ``ContentCacheInParent``. If all sent ``WidgetCompositionEvents`` and
430 ``WidgetSelectionEvents`` are already handled in the remote process,
431 ``ContentCacheInParent`` sending the notifications to widget.
433 And also this handles ``WidgetQueryContentEvents`` with its cache. Supported
434 event messages of them are:
436 * ``eQuerySelectedText`` (only with ``SelectionType::eNormal``)
437 * ``eQueryTextContent``
438 * ``eQueryTextRect``
439 * ``eQueryCaretRect``
440 * ``eQueryEditorRect``
442 Additionally, this does not support query content events with XP line breakers
443 but this must not be any problem since native IME handlers query contents with
444 native line breakers.
446 ``ContentCacheInParent`` also manages sent ``WidgetCompositionEvents`` and
447 ``WidgetSelectionEvents``. After these events are handled in the remote
448 process, ``TabParent`` receives it with a call of
449 ``RecvOnEventNeedingAckHandled()``. Then, it calls
450 ``ContentCacheInParent::OnEventNeedingAckHandled()``. Finally,
451 ``ContentCacheInParent`` flushes pending notifications.
453 How do mozilla::TextComposition and mozilla::IMEStateManager work in e10s mode?
454 -------------------------------------------------------------------------------
455 In remote process, they work as non-e10s mode. On the other hand, they work
456 specially in parent process.
458 When ``IMEStateManager`` in parent process receives ``eCompositionStart``, it
459 creates ``TextComposition`` instance normally. However, if the event target has
460 remote contents, ``TextComposition::DispatchCompositionEvent()`` directly sends
461 the event to the remote process instead of dispatching the event into the
462 target DOM tree in the process.
464 That means that even in a parent process, anybody can retrieve
465 ``TextComposition`` instance, but it just does nothing in parent process.
467 ``IMEStateManager`` works more complicated because ``IMEStateManager`` in each
468 process need to negotiate about owner ship of managing input context.
470 When a remote process gets focus, temporarily, ``IMEStateManager`` in parent
471 process disables IME in the widget. After that, ``IMEStateManager`` in the
472 remote process will set proper input context for the focused editor. At this
473 time, ``IMEStateManager`` in the parent process does nothing. Therefore,
474 ``IMEContentObserver`` is never created while a remote process has focus.
476 When a remote process loses focus, ``IMEStateManager`` in parent process
477 notifies ``IMEStateManager`` in the remote process of
478 "Stop IME state management". When ``IMEStateManager::StopIMEStateManagement()``
479 is called in the remote process by this, the ``IMEStateManager`` forgets all
480 focus information (i.e., that indicates nobody has focus).
482 When ``IMEStateManager`` in parent process is notified of pseudo focus move
483 from or to menubar while a remote process has focus, it notifies the remote
484 process of "Menu keyboard listener installed". Then, ``TabChild`` calls
485 ``IMEStateManager::OnInstalledMenuKeyboardListener()`` in the remote process.
487 Style of each clause
488 --------------------
490 The style of each IME selection is managed by
491 `LookAndFeel <https://searchfox.org/mozilla-central/source/widget/LookAndFeel.h>`__
492 class per platform. Therefore, it can be overridden by prefs.
494 Background color, foreground color (text color) and underline color can be
495 specified with following prefs. The values must be string of "#rrggbb" format.
497 * ``ui.IMERawInputBackground``
498 * ``ui.IMERawInputForeground``
499 * ``ui.IMERawInputUnderline``
500 * ``ui.IMESelectedRawTextBackground``
501 * ``ui.IMESelectedRawTextForeground``
502 * ``ui.IMESelectedRawTextUnderline``
503 * ``ui.IMEConvertedTextBackground``
504 * ``ui.IMEConvertedTextForeground``
505 * ``ui.IMEConvertedTextUnderline``
506 * ``ui.IMESelectedConvertedTextBackground``
507 * ``ui.IMESelectedConvertedTextForeground``
508 * ``ui.IMESelectedConvertedTextUnderline``
510 Underline style can be specified with the following prefs. The values are
511 integer,  0: none, 1: dotted, 2: dashed, 3: solid, 4: double, 5: wavy (The
512 values same as ``mozilla::StyleTextDecorationStyle`` defined in
513 `nsStyleConsts.h <https://searchfox.org/mozilla-central/source/layout/style/nsStyleConsts.h>`__).
515 * ``ui.IMERawInputUnderlineStyle``
516 * ``ui.IMESelectedRawTextUnderlineStyle``
517 * ``ui.IMEConvertedTextUnderlineStyle``
518 * ``ui.IMESelectedConvertedTextUnderlineStyle``
520 Underline width can be specified with ``"ui.IMEUnderlineRelativeSize"`` pref.
521 This affects all types of clauses. The value should be 100 or 200. 100 means
522 normal width, 200 means double width.
524 On some platforms, IME may support its own style for each clause. Currently,
525 this feature is supported in TSF mode of Windows and on Linux. The style
526 information is stored in ``TextRangeStyle`` which is defined in
527 `TextRange.h <https://searchfox.org/mozilla-central/source/widget/TextRange.h>`__.
528 It's a member of ``TextRange``. ``TextRange`` is stored in ``mRanges`` of
529 ``WidgetCompositionEvent`` only when its message is ``eCompositionChange``.
531 Lifetime of composition string
532 ==============================
534 When native IME notifies Gecko of starting a composition, a widget dispatches
535 ``WidgetCompositionEvent`` with ``eCompositionStart`` which will cause a DOM
536 ``compositionstart`` event.
538 When native IME notifies Gecko of a composition string change, a caret position
539 change and/or a change of length of clauses, a widget dispatches
540 ``WidgetCompositionEvent`` with ``eCompositionChange`` event. It will cause a
541 DOM ``compositionupdate`` event when composition string is changing. That is
542 dispatched by ``TextComposition`` automatically. After that when the widget and
543 ``PresShell`` of the focused editor have not been destroyed yet, the
544 ``eCompositionChange`` will cause a DOM text event which is not in any web
545 standards.
547 When native IME notifies Gecko of the ending of a composition, a widget
548 dispatches ``WidgetCompositionEvent`` with ``eCompositionCommitAsIs`` or
549 ``eCompositionCommit``. If the committing string is different from the last set
550 of data (i.e., if the event message is ``eCompositionCommit``),
551 ``TextComposition`` dispatches a DOM ``compositionupdate`` event. After that,
552 when the widget and ``PresShell`` of the focused editor have not been destroyed
553 yet, an ``eCompositionChange`` event dispatched by ``TextComposition``, that
554 causes a DOM text event. Finally, if the widget and PresShell of the focused
555 editor has not been destroyed yet too, ``TextComposition`` dispatches an
556 ``eCompositionEnd`` event which will cause a DOM compositionend event.
558 Limitation of handling composition
559 ==================================
561 Currently, ``EditorBase`` touches undo stack at receiving every
562 ``WidgetCompositionEvent``. Therefore, ``EditorBase`` requests to commit
563 composition when the following cases occur:
565 * The editor loses focus
566 * The caret is moved by mouse or Javascript
567 * Value of the editor is changed by Javascript
568 * Node of the editor is removed from DOM tree
569 * Somethings object is modified in an HTML editor, e.g., resizing an image
570 * Composition string is moved to a different position which is specified by
571   native IME (e.g., only a part of composition is committed)
573 In the future, we should fix this limitation. If we make ``EditorBase`` not
574 touch undo stack until composition is committed, some of the cases must be
575 fixed.
577 Notifications to IME
578 ====================
580 XP part of Gecko uses ``nsIWidget::NotifyIME()`` for notifying ``widget`` of
581 something useful to handle IME. Note that some of them are notified only when
582 ``nsIWidget::GetIMEUpdatePreference()`` returns flags which request the
583 notifications.
585 ``NOTIFY_IME_OF_TEXT_CHANGE``, ``NOTIFY_IME_OF_SELECTION_CHANGE``,
586 ``NOTIFY_IME_OF_POSITION_CHANGE`` and
587 ``NOTIFY_IME_OF_COMPOSITION_EVENT_HANDLED`` are always sent by following order:
589 1. ``NOTIFY_IME_OF_TEXT_CHANGE``
590 2. ``NOTIFY_IME_OF_SELECTION_CHANGE``
591 3. ``NOTIFY_IME_OF_POSITION_CHANGE``
592 4. ``NOTIFY_IME_OF_COMPOSITION_EVENT_HANDLED``
594 If sending one of above notifications causes higher priority notification, the
595 sender should abort to send remaining notifications and restart from high
596 priority notification again.
598 Additionally, all notifications except ``NOTIFY_IME_OF_BLUR`` should be sent
599 only when it's safe to run script since the notification may cause querying
600 content and/or dispatching composition events.
602 NOTIFY_IME_OF_FOCUS
603 -------------------
605 When an editable editor gets focus and ``IMEContentObserver`` starts to observe
606 it, this is sent to widget. This must be called after the previous
607 ``IMEContentObserver`` notified widget of ``NOTIFY_IME_OF_BLUR``.
609 Note that even if there are pending notifications, they are canceled when
610 ``NOTIFY_IME_OF_FOCUS`` is sent since querying content with following
611 notifications immediately after getting focus does not make sense. The result
612 is always same as the result of querying contents at receiving this
613 notification.
615 NOTIFY_IME_OF_BLUR
616 ------------------
618 When an ``IMEContentObserver`` instance ends observing the focused editor, this
619 is sent to ``widget`` synchronously because assumed that this notification
620 causes neither query content events nor composition events.
622 If ``widget`` wants notifications even while all windows are inactive,
623 ``IMEContentObserver`` doesn't end observing the focused editor. I.e., in this
624 case, ``NOTIFY_IME_OF_FOCUS`` and ``NOTIFY_IME_OF_BLUR`` are not sent to
625 ``widget`` when a window which has a composition is being activated or
626 inactivated.
628 When ``widget`` wants notifications during inactive, ``widget`` includes
629 ``NOTIFY_DURING_DEACTIVE`` to the result of
630 ``nsIWidget::GetIMEUpdatePreference()``.
632 If this notification is tried to sent before sending ``NOTIFY_IME_OF_FOCUS``,
633 all pending notifications and ``NOTIFY_IME_OF_BLUR`` itself are canceled.
635 NOTIFY_IME_OF_TEXT_CHANGE
636 -------------------------
638 When text of focused editor is changed, this is sent to ``widget`` with a range
639 of the change. But this is sent only when result of
640 ``nsIWidget::GetIMEUpdatePreference()`` includes ``NOTIFY_TEXT_CHANGE``.
642 If two or more text changes occurred after previous
643 ``NOTIFY_IME_OF_TEXT_CHANGE`` or ``NOTIFY_IME_OF_FOCUS``, the ranges of all
644 changes are merged. E.g., if first change is from ``1`` to ``5`` and second
645 change is from ``5`` to ``10``, the notified range is from ``1`` to ``10``.
647 If all merged text changes were caused by composition,
648 ``IMENotification::mTextChangeData::mCausedOnlyByComposition`` is set to true.
649 This is useful if native IME handler wants to ignore all text changes which are
650 expected by native IME.
652 If at least one text change of the merged text changes was caused by current
653 composition,
654 ``IMENotification::mTextChangeData::mIncludingChangesDuringComposition`` is set
655 to true. This is useful if native IME handler wants to ignore delayed text
656 change notifications.
658 If at least one text change of the merged text changes was caused when there
659 was no composition,
660 ``IMENotification::mTextChangeData::mIncludingChangesWithoutComposition`` is
661 set to true.
663 NOTIFY_IME_OF_SELECTION_CHANGE
664 ------------------------------
666 When selection (or caret position) is changed in focused editor, widget is
667 notified of this.
669 If the last selection change was occurred by a composition event event
670 handling, ``IMENotification::mSelectionChangeData::mCausedByComposition`` is
671 set to true. This is useful if native IME handler wants to ignore the last
672 selection change which is expected by native IME.
674 If the last selection change was occurred by an ``eSetSelection`` event,
675 ``IMENotification::mSelectionChangeData::mCausedBySelectionEvent`` is set to
676 true. This is useful if native IME handler wants to ignore the last selection
677 change which was requested by native IME.
679 If the last selection is occurred during a composition,
680 ``IMENotification::mSelectionChangeData::mOccurredDuringComposition`` is set to
681 true. This is useful if native IME handler wants to ignore the last selection
682 change which occurred by web application's ``compositionstart`` or
683 ``compositionupdate`` event handler before inserting composition string.
685 NOTIFY_IME_OF_POSITION_CHANGE
686 -----------------------------
688 When reflow or scroll occurs in the document, this is sent to widget, but this
689 is sent only when result of ``nsIWidget::GetIMEUpdatePreference()`` includes
690 ``NOTIFY_POSITION_CHANGE``.
692 This might be useful to update a candidate window position or something.
694 NOTIFY_IME_OF_COMPOSITION_EVENT_HANDLED
695 ---------------------------------------
697 After ``TextComposition`` handles ``eCompositionStart``,
698 ``eCompositionChange``, ``eComposiitionCommit`` or ``eCompositionCommitAsIs``,
699 this notification is sent to widget. This might be useful to update a candidate
700 window position or something.
702 NOTIFY_IME_OF_MOUSE_BUTTON_EVENT
703 --------------------------------
705 When a ``mousedown`` event or a ``mouseup`` event is fired on a character in a
706 focused editor, this is sent to widget. But this is sent only when result of
707 ``nsIWidget::GetIMEUpdatePreference()`` includes
708 ``NOTIFY_MOUSE_BUTTON_EVENT_ON_CHAR``. This is sent with various information.
709 See ``IMENotification::mMouseButtonEventData`` in
710 `IMEData.h <https://searchfox.org/mozilla-central/source/widget/IMEData.h>`__
711 for the detail.
713 If native IME supports mouse button event handling, ``widget`` should notify
714 IME of mouse button events with this. If IME consumes an event, ``widget``
715 should return ``NS_SUCCESS_EVENT_CONSUMED`` from ``nsIWidget::NotifyIME()``.
716 Then, ``EditorBase`` doesn't handle the mouse event.
718 Note that if a ``mousedown`` event or a ``mouseup`` event is consumed by a web
719 application (before a focused editor handles it), this notification is not sent
720 to ``widget``. This means that web applications can handle mouse button events
721 before IME.
723 Requests to IME
724 ===============
726 XP part of Gecko can request IME to commit or cancel composition. This must be
727 requested via ``IMEStateManager::NotifyIME()``. Then, ``IMEStateManager`` looks
728 for a proper ``TextComposition`` instance. If it's found,
729 ``TextComposition::RequestToCommit()`` for calling ``nsIWidget::NotifyIME()``
730 and handles some extra jobs.
732 widget should call the proper native API if it's available. Even if commit or
733 canceling composition does not occur synchronously, widget doesn't need to
734 emulate it since ``TextComposition`` will emulate it automatically. In other
735 words, widget should only request to commit or cancel composition to IME.
737 REQUEST_TO_COMMIT_COMPOSITION
738 -----------------------------
740 A request to commit current composition to IME. See also following
741 "`Forcibly committing composition`_" section for additional information.
743 REQUEST_TO_CANCEL_COMPOSITION
744 -----------------------------
746 A request to cancel current composition to IME. In other words, a request to
747 commit current composition with an empty string.
749 Forcibly committing composition
750 ===============================
752 When ``TextComposition::RequestToCommit()`` calls ``nsIWidget::NotifyIME()``,
753 it guarantees synchronous commit or canceling composition.
755 In order to put it into practice, we need to handle the following four
756 scenarios:
758 The composition is committed with non-empty string synchronously
759 ----------------------------------------------------------------
761 This is the most usual case. In this case, ``TextComposition`` handles
762 ``WidgetCompositionEvent`` instances during a request normally. However, in a
763 remote process in e10s mode, this case never occurs since requests to native
764 IME is handled asynchronously.
766 The composition is not committed synchronously but later
767 --------------------------------------------------------
769 This is the only case in a remote process in e10s mode or occurs on Linux even
770 in non-e10s mode if the native IME is iBus. The callers of
771 ``NotifyIME(REQUEST_TO_COMMIT_COMPOSITION)`` may expect that composition string
772 is committed immediately for their next job. For such a case,
773 ``TextComposition::RequestToCommit()`` synthesizes DOM composition events and a
774 DOM text event for emulating to commit composition synchronously. Additionally,
775 ``TextComposition`` ignores committing events which are dispatched by widget
776 when the widget receives native IME events.
778 In this case, using the last composition string as commit string.
780 However, if the last composition string is only an ideographic space (fullwidth
781 space), the composition string may be a placeholder of some old Chinese IME on
782 Windows.
784 .. image:: ChangJie.png
785    :alt: aScreenshot of ChangJie (Traditional Chinese IME) which puts an
786          ideographic space into composition string for placeholder
788 In this case, although, we should not commit the placeholder character because
789 it's not a character which the user wanted to input but we commit it as is. The
790 reason is, inputting an ideographic space causes a composition. Therefore, we
791 cannot distinguish if committing composition is unexpected. If the user uses
792 such old Chinese IME, ``"intl.ime.remove_placeholder_character_at_commit"``
793 pref may be useful but we don't support them anymore in default settings
794 (except if somebody will find a good way to fix this issue).
796 The composition is committed synchronously but with empty string
797 ----------------------------------------------------------------
799 This case may occur on Linux or with some IME on other platforms. If a web
800 application implements autocomplete, committing with different strings
801 especially an empty string it might cause confusion.
803 In this case, TextComposition overwrites the commit string of
804 ``eCompositionChange`` event dispatched by widget. However, if the last
805 composition string is only an ideographic space, it shouldn't be committed. See
806 the previous case.
808 Note that this case doesn't work as expected when composition is in a remote
809 process in e10s mode.
811 The composition is not committed
812 --------------------------------
814 On Linux, there is no API to request commit or canceling composition forcibly.
815 Instead, Gecko uses ``gtk_im_context_reset()`` API for this purpose because
816 most IME cancel composition with it. But there are some IMEs which do nothing
817 when Gecko calls it.
819 If this occurs, Gecko should restart composition with a DOM
820 ``compositionstart`` event , a DOM ``compositionupdate`` event and a DOM
821 ``text`` event at caret position.
823 .. note::
825    This issue hasn't been supported yet.
827 IME state management
828 ====================
830 IME is a text input system. It means that except when a user wants to input
831 some text, IME shouldn't be available. For example, pressing the space key to
832 attempt scrolling a page may be consumed and prevented by IME. Additionally,
833 password editors need to request special behavior with IME.
835 For solving this issue, Gecko sets the proper IME state at DOM focus change.
837 First, when a DOM node gets focus, nsFocusManager notifies ``IMEStateManager``
838 of the new focused node (calls ``IMEStateManager::OnChangeFocus()``).
839 ``IMEStateManager`` asks desired IME state by calling
840 ``nsIContent::GetDesiredIMEState()`` of the node. If the node owns
841 ``TextEditor`` instance, it asks for the desired IME state from the editor and
842 returns the result.
844 Next, ``IMEStateManager`` initializes ``InputContext`` (defined in
845 `IMEData.h <https://searchfox.org/mozilla-central/source/widget/IMEData.h>`__)
846 with the desired IME state and node information. Then, it calls
847 ``nsIWidget::SetInputContext()`` with the ``InputContext``.
849 Finally, widget stores the InputContext and enables or disables IME if the
850 platform has such an API.
852 InputContext
853 ------------
855 InputContext is a struct. Its ``mIMEState``, ``mHTMLInputType``,
856 ``mHTMLInputInputMode`` and ``mActionHint`` are set at
857 ``nsIWidget::SetInputContext()`` called.
859 mIMEState
860 ^^^^^^^^^
861 IME state has two abilities. One is enabled state:
863 ENABLED
864 """""""
866 This means IME is fully available. E.g., when an editable element such as
867 ``<input type="text">``, ``<textarea>`` or ``<foo contenteditable>`` has focus.
869 DISABLED
870 """"""""
872 This means IME is not available. E.g., when a non-editable element has focus or
873 no element has focus, the desired IME state is ``DISABLED``.
875 PASSWORD
876 """"""""
878 This means IME state should be the same as the state when a native password
879 field has focus. This state is set only when
880 ``<input type="password"> (ime-mode: auto;)``,
881 ``<input type="text" style="ime-mode: disabled;">`` or
882 ``<textarea style="ime-mode: disabled;">``.
884 The other is IME open state:
886 DONT_CHANGE_OPEN_STATE
887 """"""""""""""""""""""
889 The open state of IME shouldn't be changed. I.e., Gecko should keep the last
890 IME open state.
892 OPEN
893 """"
894 Open IME. This is specified only when ime-mode of the new focused element is
895 ``active``.
897 CLOSE
898 """""
899 Close IME. This is specified only when ime-mode of the new focused element is
900 ``inactive``.
902 .. note::
904    E.g., on Linux, applications cannot manage IME open state. On such
905    platforms, this is ignored.
907 .. note::
909    IME open state should be changed only when ``nsIWidget::SetInputContext()``
910    is called at DOM focus change because changing IME open state while an
911    editor has focus makes users confused. The reason why
912    ``nsIWidget::SetInputContext()`` is called is stored in
913    ``InputContextAction::mCause``.
915 How does Gecko disable IME in IMM mode on Windows
916 """""""""""""""""""""""""""""""""""""""""""""""""
918 Every window on Windows is associated an ``IMContext``. When Gecko disables
919 IME,
920 `mozilla::widget::IMEHandler <https://searchfox.org/mozilla-central/source/widget/windows/WinIMEHandler.cpp>`__::SetInputContext()
921 disassociates the context from the window.
923 How does Gecko disable IME in TSF mode on Windows
924 """""""""""""""""""""""""""""""""""""""""""""""""
926 `mozilla::widget::TSFTextStore <https://searchfox.org/mozilla-central/source/widget/windows/TSFTextStore.cpp>`__
927 sets focus to a dummy context which disables the keyboard.
929 How does Gecko disable IME on Mac
930 """""""""""""""""""""""""""""""""
932 `mozilla::widget::TextInputHandler <https://searchfox.org/mozilla-central/source/widget/cocoa/TextInputHandler.mm>`__::HandleKeyDownEvent()
933 doesn't call focused view's interpretKeyEvents. This prevents native key events
934 to be passed to IME.
936 How does Gecko disable IME on GTK
937 """""""""""""""""""""""""""""""""
939 `mozilla::widget::IMContextWrapper <https://searchfox.org/mozilla-central/source/widget/gtk/IMContextWrapper.cpp>`__
940 sets focus to a dummy context which doesn't have IME composition.
942 How does Gecko disable IME on Android
943 """""""""""""""""""""""""""""""""""""
947 mHTMLInputType
948 ^^^^^^^^^^^^^^
950 The value is a string representing the focused editor.
952 ``"text"``, ``"password"``, ``"number"``, etc.
953     When an ``<input>`` element gets focus, the value is the type of the input
954     element.
956 ``"textarea"``
957     When a ``<textarea>`` element gets focus, the value is ``"textarea"``.
959 ``""``
960     When an HTML editor (an element whose ``contenteditable`` attribute is
961     ``true`` or document whose ``designMode`` is ``"on"``) gets focus, the
962     value is empty. And also, when the other elements get focus.
964 mHTMLInputMode
965 ^^^^^^^^^^^^^^
967 The value is ``inputmode`` attribute value of the focused editor.
969 mActionHint
970 ^^^^^^^^^^^
972 The value is ``enterkeyhint`` attribute value of the focused editor when
973 ``"dom.forms.enterkeyhint"`` pref is true. This is useful for deciding the
974 caption for the submit button in virtual keyboard. E.g., the value could be
975 ``"Go"``, ``"Next"`` or ``"Search"``.
977 Native IME handlers
978 ===================
980 Following classes handles IME on each platform:
982 Windows
983 -------
985 `mozilla::widget::IMEHandler`__
986 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
988 This class manages input method context of each window and makes ``IMMHandler``
989 or ``TSFTextStore`` work with active IME and focused editor. This class has
990 only static members, i.e., never created its instance.
992 __ https://searchfox.org/mozilla-central/source/widget/windows/WinIMEHandler.cpp
994 `mozilla::widget::IMMHandler`__
995 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
997 This class is used when TSF mode is disabled by pref (``"intl.tsf.enabled"``
998 since 108, formerly named ``"intl.tsf.enable"``) or active IME is for IMM
999 (i.e., not TIP for TSF).
1001 This class handles ``WM_IME_*`` messages and uses ``Imm*()`` API. This is a
1002 singleton class since Gecko supports only on IM context in a process.
1003 Typically, a process creates windows with default IM context. Therefore, this
1004 design is enough (ideally, an instance should be created per IM context,
1005 though). The singleton instance is created when it becomes necessary.
1007 __ https://searchfox.org/mozilla-central/source/widget/windows/IMMHandler.cpp
1009 `mozilla::widget::TSFTextStore`__
1010 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
1012 This class handles IME events in TSF mode and when TIP (IME implemented with
1013 TSF) is active. This instances are created when an editable element gets focus
1014 and released when it loses focus.
1016 ``TSFTextStore`` implements some COM interfaces which is necessary to work with
1017 TIP. And similarly, there is a singleton class, ``TSFStaticSink``, to observe
1018 active TIP changes.
1020 TSF is the most complicated IME API on all platforms, therefore, design of this
1021 class is also very complicated.
1023 FIrst, TSF/TIP requests to lock the editor content for querying or modifying
1024 the content or selection. However, web standards don't have such mechanism.
1025 Therefore, when it's requested, ``TSFTextStore`` caches current content and
1026 selection with ``WidgetQueryContentEvent``. Then, it uses the cache to reply to
1027 query requests, and modifies the cache as they requested. At this time,
1028 ``TSFTextStore`` saves the requests of modification into the queue called
1029 ``PendingAction``. Finally, after unlocking the contents, it flushes the
1030 pending actions with dispatches ``WidgetCompositionEvent``s via
1031 ``TextEventDispatcher``.
1033 Then, ``IMEContentObserver`` will notify some changes caused by the dispatched
1034 ``WidgetCompositionEvents`` (they are notified synchronously in chrome or
1035 non-e10s mode, but asynchronously from a remote process in e10s mode). At this
1036 time, ``TSFTextStore`` may receive notifications which indicates web
1037 application changes the content differently from cache in ``TSFTextStore``.
1038 However, ``TSFTextStore`` ignores such fact temporarily until the composition
1039 is finished completely. The reason is that, notifying unexpected text or
1040 selection changes to TSF and/or TIP during composition may behave them odd.
1042 When a composition is committed and it receives
1043 ``NOTIFY_IME_OF_COMPOSITION_EVENT_HANDLED``, ``TSFTextStore`` clears the cache
1044 of contents and notifying TSF of merged text changes and the last selection
1045 change if they are not caused by composition. By this step, TSF and TIP may
1046 sync its internal cache with actual contents.
1048 Note that if new composition is started before
1049 ``NOTIFY_IME_OF_COMPOSITION_EVENT_HANDLED`` notification, ``TSFTextStore``
1050 handles the a composition with cached contents which may be different from
1051 actual contents. So, e.g., reconversion around caret may not work as unexpected
1052 in such case, but we don't have a good solution for this issue.
1054 On the other hand, ``TSFTextStore`` cannot cache character rectangles since if
1055 there are a lot of characters, caching the rectangles require a lot of CPU cost
1056 (to compute each rect) and memory. Therefore, ``TSFTextStore`` will use
1057 insertion point relative query for them
1058 `bug 1286157 <https://bugzilla.mozilla.org/show_bug.cgi?id=1286157>`__. Then,
1059 it can retrieve expected character's rect even if the cache of ``TSFTextStore``
1060 is different from the actual contents because TIP typically needs caret
1061 position's character rect (for a popup to indicate current input mode or next
1062 word suggestion list) or first character rect of the target clause of current
1063 composition (for a candidate list window of conversion).
1065 __ https://searchfox.org/mozilla-central/source/widget/windows/TSFTextStore.cpp
1070 Both IME and key events are handled in
1071 `TextInputHandler.mm <https://searchfox.org/mozilla-central/source/widget/cocoa/TextInputHandler.mm>`__.
1073 ``mozilla::widget::TextInputHandlerBase`` is the most base class.
1074 ``mozilla::widget::IMEInputHandler`` inherits ``TextInputHandlerBase`` and
1075 handles IME related events. ``mozilla::widget::TextInputHandler`` inherits
1076 ``TextInputHandlerBase`` and implements ``NSTextInput`` protocol of Cocoa. Its
1077 instance is created per
1078 `nsChildView <https://searchfox.org/mozilla-central/source/widget/cocoa/nsChildView.mm>`__
1079 instance.
1084 `mozilla::widget::IMContextWrapper <https://searchfox.org/mozilla-central/source/widget/gtk/IMContextWrapper.cpp>`__
1085 handles IME. The instance is created per top level window.
1087 Android
1088 -------
1090 `org.mozilla.geckoview.GeckoEditable <https://searchfox.org/mozilla-central/source/mobile/android/geckoview/src/main/java/org/mozilla/geckoview/GeckoEditable.java>`__ handles native IME events and `mozilla::widget::GeckoEditableSupport <https://searchfox.org/mozilla-central/source/widget/android/GeckoEditableSupport.cpp>`__
1091 dispatches ``Widget*Event``.