Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

change: HotkeysJSを代替 #1984

Open
wants to merge 28 commits into
base: main
Choose a base branch
from

Conversation

tsym77yoshi
Copy link
Contributor

@tsym77yoshi tsym77yoshi commented Apr 7, 2024

内容

  • 動作
  1. App.vueでキー入力を受け付ける
  2. hotkeyPluginでキー入力に反応する
  3. 以前のkeyInputされたときの動作(190~200行目あたり)と同じことを行う
  4. actions内で入力されたものと一致するか検索しあれば実行する
  • 削除
    hotkeysJsの部分をコメントアウト

hotkeysJsの為に書かれた部分を消す作業はしていませんが一応動作の中心部分はこんな感じで大丈夫だと思います

関連 Issue

ref #1947 :一応解決することはできていますが保存形式に関する議論は解決していないのでrefとしました
ref #1964 :同じissueですがこちらとは衝突しません
close #20243b0ed98 です

その他

combinationToBindingKey関数を利用して一致検索しているので.code.keyどちらで保存する仕様にしても動作します。shift+"となっていても(表示は変ですが)実行できます(未実装の複合キーが困りますが)。

1. App.vueでキー入力を受け付ける
2. hotkeyPluginでキー入力に反応する
3. 以前のkeyInputされたときのif文などの判定を(190~200行目あたり)を移動
4. actions内で入力されたものと一致するか検索しあれば実行する

hotkeysJsの為に書かれた部分を消す作業はしていませんが一応動作部分はこんな感じで大丈夫だと思います
1. App.vueでキー入力を受け付ける
2. hotkeyPluginでキー入力に反応する
3. 以前のkeyInputされたときのif文などの判定を(190~200行目あたり)を移動
4. actions内で入力されたものと一致するか検索しあれば実行する

hotkeysJsの為に書かれた部分を消す作業はしていませんが一応動作部分はこんな感じで大丈夫だと思います
@Hiroshiba
Copy link
Member

Hiroshiba commented Apr 30, 2024

なるほど、すべてのキーで反応させる感じですかね!!
hotkeysjsとかは登録されているものだけコールバックが呼び出される設計だけど、その制約をなくすと素直なコードで実現できるの面白いですね。

入力のたびに処理が走りまくるので、TTSソフトとしては結構避けたほうが良い・・・かも・・・?
でもショートカットライブラリの仕様に振り回されなくて済むのはありがたい気もしますね・・・。

うーーーーーーーーーーーーーん判断ができない。
判断ができないというところで一旦コメントをお返しします。。。 🙇

もし実装する機運がある場合は、まずはコールバック内の処理がだいぶ軽いことを把握するか、軽くない場合はより軽くできるか、なんとかして不要なときにコールバックが実行されない形にするか(これはかなり難しい気がする)・・・・・・・・・・?
処理は意外と軽いのかなぁ。どうなんだろう。

@sevenc-nanashi
Copy link
Member

割と軽いと思います。そもそもhotkeys-jsも内部でこんな(keydown毎に列挙)感じになっていると思います。

コメントアウトで消すのをやめる
型を書く不要な処理を削除
filterの順番を一般的に速くなりそうな順番に
@Hiroshiba
Copy link
Member

Hiroshiba commented May 1, 2024

@sevenc-nanashi

そもそもhotkeys-jsも内部でこんな(keydown毎に列挙)感じになっていると思います。

コード読んだのですが、流石に全部にコールバックが呼ばれる形には(たしか)なっておらず、1つ以上hotkeyが登録されたものだけlistenされる形だったと記憶しています。
う〜〜ん! 処理時間が1ms以下なら絶対大丈夫かな!!! 10msくらいでも大丈夫そうだけどわからない!!

@sevenc-nanashi
Copy link
Member

1つ以上hotkeyが登録されたものだけlistenされる形だったと記憶しています

そもそも特定のキーのkeydownをlistenするのは自分が知ってる限りではできないです。
自分もコード読んでみましたが、登録されたものだけlistenするのはDOMの話かも?(hotkeys-jsは特定のDOM内に限定できる)

@Hiroshiba
Copy link
Member

@sevenc-nanashi なるほどです。そうかも。

@Hiroshiba
Copy link
Member

Hiroshiba commented May 1, 2024

2つのショートカットキーで、片方が片方を内包しているときの挙動ってどうなってそうでしょう・・・? 👀

@tsym77yoshi
Copy link
Contributor Author

==でつないでいるので含まれるものでは反応しません、例えばCtrlとSpaceが押されていれば"Ctrl Space"という文字列が返ってくるので!

@Hiroshiba
Copy link
Member

あ、あるショートカットキーを入力してるときに別のショートカットキーを通過する場合を考えてました!
けど大体のユースケースで問題にならない気がしてきました。
一応そういうショートカットキーが入力中に被りそうなユースケースとして考えられそうなのは、修飾キー単体に意味を持たせたい場合とか、文字キー2つ押しとかくらい?
どちらもしばらくは大丈夫そう感!

今のPRの方向性で難しい機能でニーズありそうなのは、修飾キー以外の2つのキー同時押しあたりくらい…?
例えば右手だけでショートカットキー入力できるようにF12と右上の方のキー同時押しに登録される方とかはいなくはなさそう。けど正直すごい少ないケースな気がする。

自前実装アリな気がしてきました!!
もう少し問題点がないか考えた方が良さそう。懸念点あればなんでもコメントいただけると!!

キーを押す関数(HotkeyManager.keyInput)があるのでそれを実行して関数の実行回数を検査

keyとcodeの両方を書いているが将来的に統一が決まったら削除する
@tsym77yoshi
Copy link
Contributor Author

  • 処理速度
    npm run electron:serveしたものに対して、keyInputの最初から最後(if (action == null)の手前)までの時間をconsole.timeEndで計測しました
    テスト内容:一度ソング・トークのどちらも開いた後、テキスト欄内・外で適当にキーを押す
    PC:
    Intel(R) Core(TM) i7-10750H CPU
    メモリ 16GB
    結果:添付画像(1msにはならなさそうでした)
    image
  • testの概要
    以前の方法が使えなくなったので変更しています。
    キーが押されたときに呼び出されるHotkeyManager.keyInput関数を使用して、testCountを増やしていき、その数が想定通りかどうかをテストしています
  • testでhotkeyManager.replace(createDummySetting("a"));"A"にしたことについて
    保存している形式が"A"になっているはずなので変更しました。また、"a"だと動かないのですが、以前"a"のように保存していたことはありますでしょうか?

@tsym77yoshi tsym77yoshi marked this pull request as ready for review May 6, 2024 13:07
@tsym77yoshi tsym77yoshi requested a review from a team as a code owner May 6, 2024 13:07
@tsym77yoshi tsym77yoshi requested review from Hiroshiba and removed request for a team May 6, 2024 13:07
@Hiroshiba
Copy link
Member

計測ありがとうございます!!問題なさそうですね・・・!!
あ、より正確な実測をするにはdocument.addEventListener("keydown", (e) => {hotkeyManager.keyInputを実行する前と後で計測するとやりやすいかもです!

issueの方での懸念事項洗い出しが完了したらプルリクエストをレビューさせていただこうと思います!!

以前"a"のように保存していたことはありますでしょうか?

分からないのですが、多分ないと思います・・・!
昔のコードあさってもupperCase()されていそうでした。

event.key.length > 1 ? event.key : event.key.toUpperCase();

ここからblameを使って遡って行って、ずっとそうだったら問題ないと思います!!

src/components/App.vue Outdated Show resolved Hide resolved
@@ -33,7 +33,8 @@ export const useHotkeyManager = () => {
return { hotkeyManager, registerHotkeyWithCleanup };
};

type Editor = "talk" | "song";
// FIXME: EditorType型内の要素数が増えてきたら型定義をより一般な形に変更
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

このFIXMEがいつになっても解決されないかもしれないですね!
(要素数が増えない可能性がありそう)

意図を明確にするか、なくても良いかも?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Dialogや簡単編集モードのようなEditorを追加する時のことを想定していました(4つのeditorでさえ15個になってしまうので…)
しかし、それらの中でも使わない組み合わせが大半なので型定義を将来的にも変える必要は別になさそうな気がしました
HotkeyAction内のeditoreditor = EditorType | EditorType[];にして、登録時に展開するというのも考えたのですがこれはあまりよくないですかね?)

Copy link
Member

@Hiroshiba Hiroshiba May 29, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

あ、なるほどです!!たしかに増えてくるとどうにかしていかないとですね。
まあパターンはそんなに増えないかもなので、一旦コメントはなくても良いかもと思いました!

editorのとこの型を変えるの良いと思います!!
EditorType | EditorType[]とするのもまあアリですが、関数を使う側の手間はあまり変わらないのでシンプルにeditors: EditorType[]が良いかもです・・・!
でも結構今のPRも要素盛り盛りなので、一旦マージ目指せると嬉しいです!!

Comment on lines 269 to 273
// MetaキーはCommandキーとして扱う
// NOTE: hotkeys-jsにはWinキーが無く、Commandキーとして扱われている
// NOTE: Metaキーは以前採用していたmousetrapがそうだった名残り
// NOTE: hotkeys-jsでは方向キーのarrowプレフィックスが不要
const bindingKey = combination
.toLowerCase()
.split(" ")
.map((key) => (key === "meta" ? "command" : key))
.map((key) => key.replace("arrow", ""))
.join("+");
return bindingKey as BindingKey;
// 順番が違うものも一致させるために並べ替え
return combination.split(" ").sort().join(" ") as BindingKey;
};
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ここコメントと処理が不一致かもです!

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

.sort()で並べ替える処理をしています!

Copy link
Member

@Hiroshiba Hiroshiba left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

とても良さそうに思いました!!!
実装ありがとうございます!!

テスト周りに関してもコメントしました!
ちょっと気になったのですが、既存のテストは「ショートカットキーが実行されるか」ではなく「ショートカットキーを登録できるか」のテストが主なように見えました。

「登録されたか」と「実行できるか」のテストを分けてあげるとクールかもですね!
今のままだと前者のテストができませんが、HotkeyManagerにbindされている物のリストを返すメソッドを生やしてあげれば可能になると思います。

もしご興味あれば・・・!(そのままでも、あるいは後で実装でももちろん大丈夫です!)

@tsym77yoshi
Copy link
Contributor Author

レビューありがとうございます!

コメント-commit対応一覧 > 一応addとremoveを対にしておけると嬉しそうです!

78734f1

このFIXMEがいつになっても解決されないかもしれないですね!

c5c0e89
にてコメントを削除しました

あ、初期値は結構ミスの元になるんですよね。

7bd034a
0a82b96
(テスト内でonEditorChangedを追加し忘れていて、それを後の方で書いてしまいました)

消し忘れかも?

9f62b17

talk&songというリテラル型に対して&が含まれているかという情報を使っているので、意図しないバグが混入しやすくなってるかなと!

c5c0e89

// もし必要になった時の為に残している

cfc1433

ここコメントと処理が不一致かもです!

このテスト良いですね!
testCountだとなにかわからないので、calledCountとかにすると良いかも?
あるいはvitestのspy関数を使えば、この変数自体をなくすこともできたりします。

0a82b96

もしかしたら意図がわかりづらいかも・・・?
なにかメモを残すとかどうでしょう。

317c672
008cd8a
後者の方でやり方を変更したので73行目の方ではコメントは追加しませんでした

testCountがスコープの大きな変数になってしまっていてちょっと危ないですね・・・!

0a82b96

vi.fn()にしました

ちょっと気になったのですが、既存のテストは「ショートカットキーが実行されるか」ではなく「ショートカットキーを登録できるか」のテストが主なように見えました。

008cd8a

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
3 participants