bool InputMethodController::confirmCompositionOrInsertText(const String& text, ConfirmCompositionBehavior confirmBehavior) { if (!hasComposition()) { if (!text.length()) return false; editor().insertText(text, 0); return true; } if (text.length()) { confirmComposition(text); return true; } if (confirmBehavior != KeepSelection) return confirmComposition(); SelectionOffsetsScope selectionOffsetsScope(this); return confirmComposition(); }
bool GtkInputMethodFilter::filterKeyEvent(GdkEventKey* event) { if (!canEdit() || !m_enabled) return sendSimpleKeyEvent(event); m_preeditChanged = false; m_filteringKeyEvent = true; unsigned int lastFilteredKeyPressCodeWithNoResults = m_lastFilteredKeyPressCodeWithNoResults; m_lastFilteredKeyPressCodeWithNoResults = GDK_KEY_VoidSymbol; bool filtered = gtk_im_context_filter_keypress(m_context.get(), event); m_filteringKeyEvent = false; bool justSentFakeKeyUp = m_justSentFakeKeyUp; m_justSentFakeKeyUp = false; if (justSentFakeKeyUp && event->type == GDK_KEY_RELEASE) return true; // Simple input methods work such that even normal keystrokes fire the // commit signal. We detect those situations and treat them as normal // key events, supplying the commit string as the key character. if (filtered && !m_composingTextCurrently && !m_preeditChanged && m_confirmedComposition.length() == 1) { bool result = sendSimpleKeyEvent(event, m_confirmedComposition); m_confirmedComposition = String(); return result; } if (filtered && event->type == GDK_KEY_PRESS) { if (!m_preeditChanged && m_confirmedComposition.isNull()) { m_composingTextCurrently = true; m_lastFilteredKeyPressCodeWithNoResults = event->keyval; return true; } bool result = sendKeyEventWithCompositionResults(event); if (!m_confirmedComposition.isEmpty()) { m_composingTextCurrently = false; m_confirmedComposition = String(); } return result; } // If we previously filtered a key press event and it yielded no results. Suppress // the corresponding key release event to avoid confusing the web content. if (event->type == GDK_KEY_RELEASE && lastFilteredKeyPressCodeWithNoResults == event->keyval) return true; // At this point a keystroke was either: // 1. Unfiltered // 2. A filtered keyup event. As the IME code in EditorClient.h doesn't // ever look at keyup events, we send any composition results before // the key event. // Both might have composition results or not. // // It's important to send the composition results before the event // because some IM modules operate that way. For example (taken from // the Chromium source), the latin-post input method gives this sequence // when you press 'a' and then backspace: // 1. keydown 'a' (filtered) // 2. preedit changed to "a" // 3. keyup 'a' (unfiltered) // 4. keydown Backspace (unfiltered) // 5. commit "a" // 6. preedit end if (!m_confirmedComposition.isEmpty()) confirmComposition(); if (m_preeditChanged) updatePreedit(); return sendSimpleKeyEvent(event); }
bool InputMethodController::confirmComposition() { return confirmComposition(plainText(compositionEphemeralRange())); }
bool InputMethodController::confirmComposition() { return confirmComposition(composingText()); }