Fixes to input method handling

The goal of this patch is to make "self-insert <string>" act as a
sequence of individual self-insert calls. Once it is done, the
insertion of the commit string in GuiWorkArea can use that, which
fixes the issues described in bug 11183.

1/ in InsetMathNest, SELF_INSERT is rewritten to be a proper loop of
   interpretChar, instead of inserting the string as characters. This
   solves the issue of interpreting ^ properly.

2/ the text version does not need to be changed (the loop is rewritten
   using a range, though).

3/ Then {{{GuiWorkArea::inputMethodEvent}}} is changed to invoke
   directly self-insert. This removes the update issues.

Fixes bug 11183.

(cherry picked from commit ad5548cfe3)
This commit is contained in:
Jean-Marc Lasgouttes 2018-07-05 14:01:56 +02:00
parent ae8c0b2976
commit 014227cc40
5 changed files with 44 additions and 42 deletions

View File

@ -1912,13 +1912,10 @@ void Text::dispatch(Cursor & cur, FuncRequest & cmd)
if (lyxrc.auto_region_delete && cur.selection())
cutSelection(cur, false, false);
cur.clearSelection();
docstring::const_iterator cit = cmd.argument().begin();
docstring::const_iterator const end = cmd.argument().end();
for (; cit != end; ++cit)
bv->translateAndInsert(*cit, this, cur);
for (char_type c : cmd.argument())
bv->translateAndInsert(c, this, cur);
cur.resetAnchor();
moveCursor(cur, false);

View File

@ -1290,12 +1290,13 @@ void GuiWorkArea::inputMethodEvent(QInputMethodEvent * e)
// insert the processed text in the document (handles undo)
if (!e->commitString().isEmpty()) {
d->buffer_view_->cursor().beginUndoGroup();
d->buffer_view_->cursor().insert(qstring_to_ucs4(e->commitString()));
FuncRequest cmd(LFUN_SELF_INSERT,
qstring_to_ucs4(e->commitString()),
FuncRequest::KEYBOARD);
dispatch(cmd);
// FIXME: this is supposed to remove traces from preedit
// string. Can we avoid calling it explicitely?
d->buffer_view_->updateMetrics();
d->buffer_view_->cursor().endUndoGroup();
d->updateCaretGeometry();
viewport()->update();
}
// Hide the caret during the test transformation.

View File

@ -854,40 +854,41 @@ void InsetMathNest::doDispatch(Cursor & cur, FuncRequest & cmd)
break;
case LFUN_SELF_INSERT:
if (cmd.argument().size() != 1) {
cur.recordUndoSelection();
docstring const arg = cmd.argument();
if (!interpretString(cur, arg))
cur.insert(arg);
// special case first for big delimiters
if (cmd.argument().size() != 1 && interpretString(cur, cmd.argument()))
break;
}
// Don't record undo steps if we are in macro mode and thus
// cmd.argument is the next character of the macro name.
// Otherwise we'll get an invalid cursor if we undo after
// the macro was finished and the macro is a known command,
// e.g. sqrt. Cursor::macroModeClose replaces in this case
// the InsetMathUnknown with name "frac" by an empty
// InsetMathFrac -> a pos value > 0 is invalid.
// A side effect is that an undo before the macro is finished
// undoes the complete macro, not only the last character.
// At the time we hit '\' we are not in macro mode, still.
if (!cur.inMacroMode())
cur.recordUndoSelection();
// spacial handling of space. If we insert an inset
// via macro mode, we want to put the cursor inside it
// if relevant. Think typing "\frac<space>".
if (cmd.argument()[0] == ' '
&& cur.inMacroMode() && cur.macroName() != "\\"
&& cur.macroModeClose() && cur.pos() > 0) {
MathAtom const atom = cur.prevAtom();
if (atom->asNestInset() && atom->isActive()) {
cur.posBackward();
cur.pushBackward(*cur.nextInset());
for (char_type c : cmd.argument()) {
// Don't record undo steps if we are in macro mode and thus
// cmd.argument is the next character of the macro name.
// Otherwise we'll get an invalid cursor if we undo after
// the macro was finished and the macro is a known command,
// e.g. sqrt. Cursor::macroModeClose replaces in this case
// the InsetMathUnknown with name "frac" by an empty
// InsetMathFrac -> a pos value > 0 is invalid.
// A side effect is that an undo before the macro is finished
// undoes the complete macro, not only the last character.
// At the time we hit '\' we are not in macro mode, still.
if (!cur.inMacroMode())
cur.recordUndoSelection();
// special handling of space. If we insert an inset
// via macro mode, we want to put the cursor inside it
// if relevant. Think typing "\frac<space>".
if (c == ' '
&& cur.inMacroMode() && cur.macroName() != "\\"
&& cur.macroModeClose() && cur.pos() > 0) {
MathAtom const atom = cur.prevAtom();
if (atom->asNestInset() && atom->isActive()) {
cur.posBackward();
cur.pushBackward(*cur.nextInset());
}
} else if (!interpretChar(cur, c)) {
cmd = FuncRequest(LFUN_FINISHED_FORWARD);
cur.undispatched();
// FIXME: can we avoid skipping the end of the string?
break;
}
} else if (!interpretChar(cur, cmd.argument()[0])) {
cmd = FuncRequest(LFUN_FINISHED_FORWARD);
cur.undispatched();
}
break;
@ -1890,6 +1891,7 @@ bool InsetMathNest::interpretString(Cursor & cur, docstring const & str)
prev = prev.substr(1);
latexkeys const * l = in_word_set(prev);
if (l && l->inset == "big") {
cur.recordUndoSelection();
cur.cell()[cur.pos() - 1] =
MathAtom(new InsetMathBig(prev, str));
return true;

View File

@ -166,7 +166,7 @@ protected:
public:
/// interpret \p str and insert the result at the current position of
/// \p cur if it is something known. Return whether \p cur was
/// inserted.
/// inserted. Handles undo.
virtual bool interpretString(Cursor & cur, docstring const & str);
private:

View File

@ -88,6 +88,8 @@ What's new
- Fix display of percent sign with numbers in RTL (bug 4057).
- Fix issues with dead key accents (bug 11183).
* INTERNALS