ちょ、何故今まで気が付かなかったのだ?
CapsLock が掛かっていると自作アプリの Ctrl+o 等が動作しない!
GNOME 標準アプリは問題なく使えるのね。
うん、GTK+ における CapsLock について調べる必要があるな。
てなわけで調べたんだけど。
CapsLock は GTK+ では Ctrl, Shift と同じ装飾キー扱いなのね。
具体的には列挙体で
1:Shift,
2:CapsLock
4:Ctrl
8:Alt
が OR 演算で key-press-event シグナルの GdkEvent に入ってくる。
On にした状態だとずっと押されていると認識するというおまけつき。
つまり CapsLock が On の状態では、えっと。
Ctrl+o は CapsLock+Ctrl+O と認識、装飾キーが 6 で O が大文字。
なるほど、動かなくて当然だ。
CapsLock 状態を別途で調べる。
On であれば装飾キー値 gdk_event_get_state から 2 を引く。
On 又は Shift を押した状態なら gdk_event_get_keyval 値を小文字化。
という流れで CapsLock を完全に無視できるようだ。
#!/usr/bin/gjs const Gtk = imports.gi.Gtk; const Gdk = imports.gi.Gdk; const Lang = imports.lang; const KeyPressWindow = new Lang.Class({ Name: 'KeyPressWindow', Extends: Gtk.ApplicationWindow, _init: function(app) { this.parent({ application: app }); this.connect("key-press-event", Lang.bind(this, function(widget, event) { /** * CapsLock */ let keymap = Gdk.Keymap.get_default(); let caps_state = keymap.get_caps_lock_state(); let caps = caps_state ? "[CapsLock]+" : ""; /** * Modifier */ let [ok, state] = event.get_state(); let mod = ""; if (ok) { if (caps_state) state -= 2; switch(state) { case 1: mod = "Shift+"; break; //case 2: // mod = "CapsLock+"; // break; case 4: mod = "Ctrl+"; break; case 5: mod = "Ctrl+Shift+"; break; case 8: mod = "Alt+"; break; case 9: mod = "Alt+Shift+"; break; case 12: mod = "Alt+Ctrl+"; break; case 13: mod = "Alt+Ctrl+Shift+"; break; } /** * Key */ let [ok, keyval] = event.get_keyval(); if (ok) { // CapsLock or Shift if (Gdk.keyval_is_upper(keyval)) keyval = Gdk.keyval_to_lower(keyval); //let key = String.fromCharCode(keyval); let key = Gdk.keyval_name(keyval); if (key != null) this.set_title(`${caps}${mod}${key}`); } } })); this.show_all(); } }); let app = new Gtk.Application(); app.connect("activate", function() { new KeyPressWindow(app); }); app.run(null);
こんな感じ。
GNOME 標準アプリがどうやって認識しているかは調べていないけど。
もっといい手段があるかも、とりあえずは様子見かな。
やっと晴れたし名駅前でスイクンでも(関係無い!