mozc本体のコメントに将来的にそういった機能をつけるような事が書かれていて、その時コンフリクトする事が予想される。
■クライアント側
以下のように定義し、ViewManager.javaでタイマーでコマンドが実行されるようにする。
ViewManager.java
private final int keycodeKaomojiToggleCommit;
keycodeKaomojiToggleCommit = res.getInteger(R.integer.key_kaomoji_toggle_commit);
とりあえず定義だけ上述のようにする。タイマー部分はよきに計らってやる。
KeycodeConverter.java
public static final ProtoCommands.KeyEvent KAOMOJI_TOGGLE_COMMIT =
ProtoCommands.KeyEvent.newBuilder().setSpecialKey(SpecialKey.KAOMOJI_TOGGLE_COMMIT).build();
keycode.xml
<integer name="key_kaomoji_toggle_commit">-10025</integer>
ProtoCommands.java
サーバー側をビルドすると生成される。
■サーバー側
composer/composer.cc
実装しようとしている機能はカーソルを右に動かす動作と非常に似ている。そしてカーソルを動かす処理はこのファイルの以下のメソッドである。
void Composer::MoveCursorRight() {
if (position_ < composition_->GetLength()) {
++position_;
}
UpdateInputMode();
typing_corrector_.Invalidate();
}
そこでpositionを移動させない関数を追加する。引き数で条件分岐してもいいのだが右に移動させる機能とトグルをコミットさせる機能は本質的に別物であるので別にする。コンフリクトすると面倒なだけでもある。
void Composer::KaomojiToggleCommit() {
UpdateInputMode();
typing_corrector_.Invalidate();
}
composer/composer.h
void KaomojiToggleCommit();
次に上述を呼び出す処理を実装する。
session/session.h
bool KaomojiToggleCommit(mozc::commands::Command *command);
session/session.cc
bool Session::KaomojiToggleCommit(commands::Command *command) {
if (context_->GetRequest().crossing_edge_behavior() == commands::Request::COMMIT_WITHOUT_CONSUMING && context_->composer().GetLength() == context_->composer().GetCursor()) {
Commit(command);
// Do not consume.
command->mutable_output()->set_consumed(false);
return true;
}
command->mutable_output()->set_consumed(true);
if (CommitIfPassword(command)) {
return true;
}
context_->mutable_composer()->KaomojiToggleCommit();
if (Suggest(command->input())) {
Output(command);
return true;
}
OutputComposition(command);
return true;
}
コピペで申し訳ない限りである。このメソッドは同ファイルの以下の部分から呼び出される。
case keymap::CompositionState::MOVE_CURSOR_RIGHT:
return MoveCursorRight(command);
case keymap::CompositionState::KAOMOJI_TOGGLE_COMMIT:
return KaomojiToggleCommit(command);
case keymap::CompositionState::MOVE_CURSOR_TO_BEGINNING:
return MoveCursorToBeginning(command);
定義したメソッドがクライアントからのコマンドで呼び出されるようにする。
■CompositionState
以下のようにCompositionStateで実行されるコマンドの定義と登録をする。
session/internal/keymap_interface.h
MOVE_CURSOR_RIGHT,
KAOMOJI_TOGGLE_COMMIT,
MOVE_CURSOR_TO_BEGINNING,
session/internal/keymap.cc
以下のようにして、コマンド名KaomojiToggleCommitで、CompositionState::KAOMOJI_TOGGLE_COMMITが実行されるようになる。
RegisterCompositionCommand("KaomojiToggleCommit", CompositionState::KAOMOJI_TOGGLE_COMMIT);
data/keymap/mobile.tsv
以下のようにして、KaomojiToggleCommitキーでKaomojiToggleCommitコマンドが実行される。
Composition Right MoveCursorRight
Composition KaomojiToggleCommit KaomojiToggleCommit
Composition Space Convert
一番左の列はstatusなのだがIME全体で入力の状態というものが存在するという事を理解しておく必要がある。
■Specialキーの追加とKeyEvent
強引ではあるがトグルをコミットさせる(実際には視認できない)KaomojiToggleCommitキーを追加する。
session/commands.proto
下のように記述して定義する。ビルドした時にKAOMOJI_TOGGLE_COMMITが追加されたProtoCommands.javaが生成され、クライアント側からSpecialKeyのKAOMOJI_TOGGLE_COMMITを叩ける。
COMMA = 70; // Numpad [,]
KAOMOJI_TOGGLE_COMMIT = 71;
NUM_SPECIALKEYS = 72;
data/usage_stats/stats.def
追加したSpecialKeyなどがusage stats用のリストに存在せず、Debugビルドするとトグルがコミットされた時に落ちるので、以下のように追加する。
Performed_Composition_KaomojiToggleCommit
# Virtual Key for software keyboard
KAOMOJI_TOGGLE_COMMIT
この定義により、今回のキーとコマンドがusage_stats_list.hに追加される。
commands.protoから、commands.pb.hとcommands.pb.ccが生成されるが、キー操作がフックされるために以下の2ファイルの書き換えが必要となる。
session/random_keyevents_generator.cc
commands.pb.hがincludeされ以下のようにkSpecialKeysの配列ができる。
commands::KeyEvent::RIGHT,
commands::KeyEvent::KAOMOJI_TOGGLE_COMMIT,
commands::KeyEvent::UP,
session/key_parser.cc
keycode_map_["right"] = KeyEvent::RIGHT;
keycode_map_["kaomojitogglecommit"] = KeyEvent::KAOMOJI_TOGGLE_COMMIT;
keycode_map_["enter"] = KeyEvent::ENTER;
SessionCommandの追加
都合によりSpecialKeyを追加したが本来ならばSessionCommandの追加で特に問題はない。
data/usage_stats/stats.def
SendCommand_KaomojiToggleCommit
session/commands.proto
以下のようにしてSessionCommandを追加できる。
KAOMOJI_TOGGLE_COMMIT = 24;
// Number of commands.
// When new command is added, the command should use below number
// and NUM_OF_COMMANDS should be incremented.
NUM_OF_COMMANDS = 25;
session/session.cc
以下のようにしてSessionCommandをフックする。
case commands::SessionCommand::KAOMOJI_TOGGLE_COMMIT:
result = KaomojiToggleCommit(command);
break;
上述のようにするとSessionExecutorから以下のように呼び出せる。
public void toggleCommit(int candidateId, EvaluationCallback callback) {
Input.Builder inputBuilder = Input.newBuilder()
.setType(CommandType.SEND_COMMAND)
.setCommand(SessionCommand.newBuilder()
.setType(SessionCommand.CommandType.KAOMOJI_TOGGLE_COMMIT)
.setId(candidateId));
evaluateAsynchronously(inputBuilder, null, callback);
}
■ダウンロード
みんなの顔文字キーボード