またマクロパッドを弄っている。
シフトキーが欲しくて、ボームポジションに置きたい。
ホームポジションはカーソルキー。
MT(MOD_LSFT, KC_RIGHT)だけだと、
シフト+マウスの挙動がよろしくない。
config.hに、
PERMISSVE_HOLD
を定義して、
シフト優先する。
キーボード内のキーコードと組み合わせるときは、
シフトキーとして機能する。
しかし、
マウスとの組み合わせが、
TAPPING_TERM
だけ待たないとシフトキーにならない…
100だと素早く押して離さないと単押しのカーソルにならず、
150だとシフト+スクロールホイールが、
ちょい待ちでないと発動しない。
125だとどっちも不安定。
キーボード内にホイールスクロールを入れると、
キー数が足りなくなるし、
オペレーションの動線が悪くなる。
TAPPING_TERM 0
にして、
RETRO_TAPPING
を有効にすると、
キーコード内での挙動、
「押して他に何かを押せば即シフト、
他に何も押さず離すと単押し発行してカーソル」
は実現できるが、
シフト+マウスの組み合わせだと、
「他に何かのキーコードを押した」
と認識されずに、
シフト機能後、カーソルがポロリと出る。
ううむ、
キーボード内にマウスを入れ込まないと、
思う挙動をしないのか…
5ボタンマウス買ってシフトキーをそっちに当てた方がいいのか、
悩ましい。
「押して何かを押せば、即シフト、
離したとき、他に何も押してないならカーソル」
の「何か」に他のマウスも含める方法は、
QMKには存在しない、
で合ってる?
外部のマウスから入力を検知するということは難しいと思います。
keyboard quantizereのように専用のキーボードを設計し、
それにマウスを接続し、
さらにQMKのコードを大改造すればいけなくもなさそうですが、現実的ではないですね……。
代替案として、以下のような動作なら実現できます。
押した瞬間、即時シフトキー押下
すぐに離したら(例えば0.5秒以内) シフトキー離 右キー単押
長押し(0.5秒以上)だったらシフトキー離すだけ
ダブルタップで右キー押下(オートリピート)
といった感じです。
少し煩雑ですが、以下にコードも残しておきますので、もしよければ試してみてください。
//enum custom_keycodes に自作コードSHIFT_RIGHTを登録
/*enum custom_keycodes {
* ~~~~ = SAFE_RANGE,
* ~~~~,
* ~~~~,
* SHIFT_RIGHT,
*};
*/
//process_record_user 関数の前に以下をペースト
typedef struct {
uint16_t keycode;
uint16_t time;
bool double_tapped;
} event_prev_t;
bool get_double_tap_state(void){
return event_prev.double_tapped;
}
void set_keycode_prev(uint16_t keycode, uint16_t time){
event_prev.keycode = keycode;
event_prev.time = time;
if(event_prev.double_tapped)
event_prev.double_tapped = (keycode == event_prev.keycode);
}
bool is_released_within_time( uint16_t keycode, uint16_t tapping_tarm){
return ((keycode == event_prev.keycode) && timer_elapsed(event_prev.time) < tapping_tarm );
}
bool is_double_tapped_within_time( uint16_t keycode, uint16_t tapping_tarm){
if (is_released_within_time( keycode, tapping_tarm) ){
event_prev.double_tapped = true;
}else{
event_prev.double_tapped = false;
}
return event_prev.double_tapped;
}
//process_record_user 関数の前にペースト ここまで
//process_record_user 関数 switch文内にペースト
case SHIFT_RIGHT:
if (record->event.pressed) {
if(is_double_tapped_within_time(keycode, 200)){
register_code(KC_RIGHT);
}else{
register_code(KC_LSIHFT);
}
set_keycode_prev(keycode, record->event.time);
}else{
if(get_double_tap_state()){
unregister_code(KC_RIGHT);
}else{
unregister_code(KC_LSHIFT);
if(is_released_within_time(keycode, 500)){
tap_code(KC_RIGHT);
}
}
}
return false;
break;
//process_record_user 関数 switch文内にペースト ここまで
//process_record_user 関数最後の return ture;前に以下の二行をペースト
if(record->event.pressed)
set_keycode_prev(keycode, record->event.time);
/*
* if(record->event.pressed)
* set_keycode_prev(keycode, record->event.time);
*
* return true;
*}//end of process_record_user function
*/
//process_record_user 関数の前に以下をペースト
typedef struct {
uint16_t keycode;
uint16_t time;
bool double_tapped;
} event_prev_t;
bool get_double_tap_state(void){
return event_prev.double_tapped;
}
……
の部分が正しくは
//process_record_user 関数の前に以下をペースト
typedef struct {
uint16_t keycode;
uint16_t time;
bool double_tapped;
} event_prev_t;
static event_prev_t event_prev ={ .keycode = 0, .time = 0, .double_tapped = false };
event_prev_t *recode_prev = &event_prev;
bool get_double_tap_state(void){
return event_prev.double_tapped;
}
でした。
個人で使っている自作関数ファイルから必要な部分だけ引っ張ってきたので、もしかするとまだ不具合が残っているかもしれないです。
何かあれば、このコメントへの返信やdiscordなどで気軽に相談いただければと思います。
なるほど、
予想通り自分マクロを組むしかない、
ということですね。
押しと離しでコード書くしかないんだよな…
ちなみに目的は動画編集で、
考えに集中してる時に、
TAPPING_TERMのことを考えたくないなあ、
というところから来ています。
(今薙刀式動画編集中…)
単独シフトキーを増やすほうが、いいのかなあ。
キーマップをさらに煮詰めれば行けるかも…
どっちがいいかは使ってみないと分からないのが、
難しいところですね…
>ということですね。
今はどうなってるかわかりませんが、
少なくともこのコードを組んだ
1年前くらいの時点ではその通りでした。
もっと1ファイルにまとめて、
一行書くだけといった感じで
簡潔にお渡しできればよかったのですが、
力不足ですみません。
私もペイントツールを使っているときに、
ctrl+マウスキーでイライラして組んだので
ショートカットキー煮詰めてる人あるあるな
悩みなのかもですね。
キー範囲を増やすと、
そこに指を飛ばすための思考が必要。
ModTap とかはキーボード側の制約に
付き合わされて煩わしい。
かといってマクロ自作は敷居が高すぎる。
まだまだ、自作キーボードが万人のニーズに
行き届いていない現状を残念に思います。