/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ /* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
// GTK distinguishes between display lines (wrapped, as they appear on the // screen) and paragraphs, which are runs of text terminated by a newline. // We don't have this distinction, so we always use editor's notion of // lines, which are newline-terminated.
staticconst Command sDeleteCommands[][2] = { // backward, forward // CHARS
{Command::DeleteCharBackward, Command::DeleteCharForward}, // WORD_ENDS
{Command::DeleteWordBackward, Command::DeleteWordForward}, // WORDS
{Command::DeleteWordBackward, Command::DeleteWordForward}, // LINES
{Command::DeleteToBeginningOfLine, Command::DeleteToEndOfLine}, // LINE_ENDS
{Command::DeleteToBeginningOfLine, Command::DeleteToEndOfLine}, // PARAGRAPH_ENDS
{Command::DeleteToBeginningOfLine, Command::DeleteToEndOfLine}, // PARAGRAPHS
{Command::DeleteToBeginningOfLine, Command::DeleteToEndOfLine}, // This deletes from the end of the previous word to the beginning of the // next word, but only if the caret is not in a word. // XXX need to implement in editor
{Command::DoNothing, Command::DoNothing} // WHITESPACE
};
gHandled = true; if (uint32_t(del_type) >= std::size(sDeleteCommands)) { // unsupported deletion type return;
}
if (del_type == GTK_DELETE_WORDS) { // This works like word_ends, except we first move the caret to the // beginning/end of the current word. if (forward) {
AddCommand(Command::WordNext);
AddCommand(Command::WordPrevious);
} else {
AddCommand(Command::WordPrevious);
AddCommand(Command::WordNext);
}
} elseif (del_type == GTK_DELETE_DISPLAY_LINES ||
del_type == GTK_DELETE_PARAGRAPHS) { // This works like display_line_ends, except we first move the caret to the // beginning/end of the current line. if (forward) {
AddCommand(Command::BeginLine);
} else {
AddCommand(Command::EndLine);
}
}
// GtkTextView-only signals staticvoid select_all_cb(GtkWidget* aWidget, gboolean aSelect,
gpointer aUserData) { // We don't support "Unselect All" command. // Note that if we'd support it, `Ctrl-Shift-a` will be mapped to it and // overrides open `about:addons` shortcut. if (aSelect) {
AddCommand(Command::SelectAll);
}
g_signal_stop_emission_by_name(aWidget, "select_all"); // Although we prevent the default of `GtkTExtView` with // `g_signal_stop_emission_by_name`, but `gHandled` is used for asserting // if it does not match with the emptiness of the command array. // Therefore, we should not set it to `true` if we don't add a command.
gHandled |= aSelect;
}
// static
NativeKeyBindings* NativeKeyBindings::GetInstance(NativeKeyBindingsType aType) { switch (aType) { case NativeKeyBindingsType::SingleLineEditor: if (!sInstanceForSingleLineEditor) {
sInstanceForSingleLineEditor = new NativeKeyBindings();
sInstanceForSingleLineEditor->Init(aType);
} return sInstanceForSingleLineEditor;
default: // fallback to multiline editor case in release build
MOZ_FALLTHROUGH_ASSERT("aType is invalid or not yet implemented"); case NativeKeyBindingsType::MultiLineEditor: case NativeKeyBindingsType::RichTextEditor: if (!sInstanceForMultiLineEditor) {
sInstanceForMultiLineEditor = new NativeKeyBindings();
sInstanceForMultiLineEditor->Init(aType);
} return sInstanceForMultiLineEditor;
}
}
// It must be a DOM event dispached by chrome script. if (!aEvent.mNativeKeyEvent) { return;
}
guint keyval; if (aEvent.mCharCode) {
keyval = gdk_unicode_to_keyval(aEvent.mCharCode);
} elseif (aWritingMode.isSome() && aEvent.NeedsToRemapNavigationKey() &&
aWritingMode.ref().IsVertical()) { // TODO: Use KeyNameIndex rather than legacy keyCode.
uint32_t remappedGeckoKeyCode =
aEvent.GetRemappedKeyCode(aWritingMode.ref()); switch (remappedGeckoKeyCode) { case NS_VK_UP:
keyval = GDK_Up; break; case NS_VK_DOWN:
keyval = GDK_Down; break; case NS_VK_LEFT:
keyval = GDK_Left; break; case NS_VK_RIGHT:
keyval = GDK_Right; break; default:
MOZ_ASSERT_UNREACHABLE("Add a case for the new remapped key"); return;
}
} else {
keyval = static_cast<GdkEventKey*>(aEvent.mNativeKeyEvent)->keyval;
}
if (GetEditCommandsInternal(aEvent, aCommands, keyval)) { return;
}
for (uint32_t i = 0; i < aEvent.mAlternativeCharCodes.Length(); ++i) {
uint32_t ch = aEvent.IsShift()
? aEvent.mAlternativeCharCodes[i].mShiftedCharCode
: aEvent.mAlternativeCharCodes[i].mUnshiftedCharCode; if (ch && ch != aEvent.mCharCode) {
keyval = gdk_unicode_to_keyval(ch); if (GetEditCommandsInternal(aEvent, aCommands, keyval)) { return;
}
}
}
// If the key event does not cause any commands, and we're for single line // editor, let's check whether the key combination is for "select-all" in // GtkTextView because the signal is not supported by GtkEntry. if (aCommands.IsEmpty() && this == sInstanceForSingleLineEditor &&
StaticPrefs::ui_key_use_select_all_in_single_line_editor()) { if (NativeKeyBindings* bindingsForMultilineEditor =
GetInstance(NativeKeyBindingsType::MultiLineEditor)) {
bindingsForMultilineEditor->GetEditCommands(aEvent, aWritingMode,
aCommands); if (aCommands.Length() == 1u &&
aCommands[0u] == static_cast<CommandInt>(Command::SelectAll)) { return;
}
aCommands.Clear();
}
}
/* gtk_bindings_activate_event is preferable, but it has unresolved bug: http://bugzilla.gnome.org/show_bug.cgi?id=162726 The bug was already marked as FIXED. However, somebody reports that the bug still exists. Also gtk_bindings_activate may work with some non-shortcuts operations (todo: check it). See bug 411005 and bug 406407.
Code, which should be used after fixing GNOME bug 162726:
¤ Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.0.13Bemerkung:
(vorverarbeitet)
¤
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung ist noch experimentell.