rkremap 0.3.0.1 → 0.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 55d8872f73bd984afd69fdf3c17e53f39de16a4f8feef40bc851b6527e57aa17
4
- data.tar.gz: 99c6a99b3fdd44e206d416eab361ca1ab4c9e4defc0d96bfa2fc0e563a5a1e4c
3
+ metadata.gz: 2052faf03d55e5ca684ee7c991fe42ecb187f2294376216e333d9aced2a45188
4
+ data.tar.gz: cc901a01fec47fcafc320ea355c5ea71dd8cc8e54c05f4f7774f02beda3ab328
5
5
  SHA512:
6
- metadata.gz: c9ad9908d2a602e2740748924e5cd83c1f6526eda164c389cde0b22d1b4462d74c7f5eba3809f2c353396500efe5a5447cb22302a0c8db9aaf4fbfa739f1c6a9
7
- data.tar.gz: 936cef85543d1089d81323ddd4f11a7b4da2afb44d6f7d7c9921132182e300e963a73ad8e51f8e80a6cf879251caad0c5235cddc0cc73a51dc315f2b5a487744
6
+ metadata.gz: dad24b3679af4213746a787811812afe8791d4964eba2ea018debffb94f7558dec29915a9be18e3aa1952a6817ea6ec823045c0ab8ae45afc9d22649f8c90374
7
+ data.tar.gz: 6dbef790e758293b32891d2aabd4cc939b3259b55b5c6d5ed297d2a96ffe9feaeb657675c98b16cd3c73480f3d6f0b35e98f12fadd0d0f41a3020cca894cf069
data/README.md CHANGED
@@ -22,8 +22,11 @@ KERNEL=="uinput", GROUP="input"
22
22
  ```
23
23
  という内容で作れば `/dev/uinput` のグループを `input` にできるっぽい。
24
24
 
25
+ `$VERBOSE` が真の場合はデバイスを検出したときと切断を検出したときにデバイス名を標準出力に出力する。
25
26
 
26
- ### `Rkremap.new`
27
+ ## Rkremap
28
+
29
+ ### Rkremap.new
27
30
 
28
31
  引数を指定しなければ自動的にキーボードデバイスの検出を試みる。
29
32
 
@@ -40,9 +43,28 @@ sudo evtest /dev/input/eventX
40
43
 
41
44
  ThinkPad 本体のキーボードは `/dev/input/event3` だった。
42
45
 
46
+ ### Rkremap#exclude
47
+
48
+ 無視するデバイス名を正規表現で指定できる。
49
+
50
+
51
+ ```ruby
52
+ rkremap.exclude = /touchpad/i
53
+ ```
54
+
55
+ ### Rkremap#mouse
56
+
57
+ 真を指定するとマウスも対象にする。
58
+
43
59
  ### Rkremap#grab
44
60
 
45
- `true` に設定するとキーイベントを奪う。キーイベントを見るだけでいいなら `false` を設定する。
61
+ `true` を設定するとキーイベントを奪う。キーイベントを見るだけでいいなら `false` を設定する。
62
+
63
+ `:keyboard` を設定するとキーボードデバイスを grab する。
64
+
65
+ `:mouse` を設定するとマウスデバイスを grab する。
66
+
67
+ 正規表現を設定するとデバイス名がマッチした場合にデバイスを grab する。
46
68
 
47
69
  ### Rkremap#x11
48
70
 
@@ -52,11 +74,49 @@ ThinkPad 本体のキーボードは `/dev/input/event3` だった。
52
74
 
53
75
  修飾キーの一覧。これらのキーは単体で押されただけでは `start` ブロックを実行しない。
54
76
 
55
- ### auto_detect
77
+ ### Rkremap#auto_detect
56
78
 
57
79
  `true` の場合はキーボードデバイスの接続を自動検知する。
58
80
  `new` 時にデバイスファイルが指定されない場合は `true` になる。
59
81
 
82
+ ### Rkremap#remap
83
+
84
+ 引数の Hash で変換するキーを指定する:
85
+ ```ruby
86
+ rk.remap(KEY_CAPSLOCK => KEY_LEFTCTRL)
87
+ ```
88
+
89
+ 変換元を配列で修飾キーを書くとその修飾キーとの組み合わせで変換する:
90
+ ```ruby
91
+ rk.remap([KEY_LEFTCTRL, KEY_A] => KEY_HOME)
92
+ ```
93
+
94
+ hold を指定すると指定秒数長押ししたときだけ変換する:
95
+ ```ruby
96
+ rk.remap(hold: 0.5, map: {
97
+ KEY_MUHENKAN => KEY_RIGHTMETA,
98
+ KEY_HENKAN => KEY_RIGHTMETA,
99
+ })
100
+ ```
101
+
102
+ 次のように書くと、A も B も C もすべて A になってしまう:
103
+ ```ruby
104
+ rk.remap(KEY_A => KEY_B)
105
+ rk.remap(KEY_B => KEY_C)
106
+ rk.remap(KEY_C => KEY_A)
107
+ ```
108
+
109
+ A を B, B を C, C を A と変換したい場合は次のように書く:
110
+ ```ruby
111
+ rk.remap(
112
+ KEY_A => KEY_B,
113
+ KEY_B => KEY_C,
114
+ KEY_C => KEY_A
115
+ )
116
+ ```
117
+
118
+ `#remap` で実現できないような複雑な処理は、後述の `#match` や `#start` で書くことができるかもしれない。
119
+
60
120
  ### Rkremap#start
61
121
 
62
122
  なにかキーを押されたらブロックを実行する。修飾キー単体ではブロックは実行されない。
@@ -65,13 +125,27 @@ ThinkPad 本体のキーボードは `/dev/input/event3` だった。
65
125
 
66
126
  ### Rkremap#match
67
127
 
68
- キーイベントが引数に適合するとブロックを実行する。ブロック引数は Event オブジェクト。
69
- `Event#skip` するとこのイベントはスキップされる。
128
+ キーイベントが引数に適合するとブロックを実行する。ブロック引数は `Rkremap::Event` オブジェクト。
129
+ `Rkremap::Event#skip` するとこのイベントはスキップされる。
130
+
131
+ 複数回指定した場合は記述順に実行される。
70
132
 
71
133
  ### Rkremap#key
72
134
 
73
135
  キーを押したことにする。引数はキーコード(`Integer`)と修飾キー(`Hash`)。
74
136
 
137
+ 修飾キーのハッシュのキーはキーコード(`KEY_LEFTCTRL` 等)、値は `true`, または `false`。
138
+
139
+ ```ruby
140
+ {
141
+ KEY_LEFTSHIFT => false,
142
+ KEY_LEFTCTRL => true,
143
+ }
144
+ ```
145
+
146
+ と指定すると、左シフトは離した状態、左Ctrlは押した状態、それ以外の修飾キーはそのまま。
147
+ `#key()` 処理後は処理前の修飾キーの状態に戻る。
148
+
75
149
  ### Rkremap#event
76
150
 
77
151
  キーイベントを発生させる。`code` 引数はキーコード(`Integer`)。`type` 引数はイベントタイプ(`Symbol`)で `:press`, `:release`。
@@ -84,6 +158,34 @@ ThinkPad 本体のキーボードは `/dev/input/event3` だった。
84
158
 
85
159
  コードからキー名のシンボルに変換するための Hash。
86
160
 
161
+ ## Rkremap::Event
162
+
163
+ ### Rkremap::Event#code
164
+
165
+ キーコード。`Rkremap::KeyCode::KEY_*` に該当。
166
+
167
+ ### Rkremap::Event#type
168
+
169
+ イベントタイプ。 `:press`, `:release`, `:repeat` のいずれか。
170
+
171
+ ### Rkremap::Event#app
172
+
173
+ `Rkremap::App`。イベントが発生したアプリケーション。
174
+
175
+ ### Rkremap::Event#skip
176
+
177
+ このイベントをこれ以降処理しない。
178
+
179
+ ## Rkremap::App
180
+
181
+ ### Rkremap::App#class_name
182
+
183
+ アプリケーションのクラス名。
184
+
185
+ ### Rkremap::App#title
186
+
187
+ アプリケーションのタイトル。
188
+
87
189
  ## 参考
88
190
 
89
191
  * [mooz/xkeysnail: Yet another keyboard remapping tool for X environment](https://github.com/mooz/xkeysnail)
@@ -1,57 +1,25 @@
1
- # 変換/無変換キーを0.5秒以上押してるとALTキーとして扱う。
2
- # 0.5秒以内でも変換/無変換キーを押しながら他のキーを押すとALTキーとして扱う。
1
+ # 変換/無変換キーを0.5秒以上押してるとSUPERキーとして扱う。
2
+ # 0.5秒以内でも変換/無変換キーを押しながら他のキーを押すとSUPERキーとして扱う。
3
3
 
4
4
  require 'rkremap'
5
- require 'tmtms_timer' # gem install tmtms_timer
6
5
 
7
6
  include Rkremap::KeyCode
8
7
 
9
- rk = Rkremap.new
8
+ rk = Rkremap.new(*ARGV, mouse: true)
10
9
  rk.grab = true
11
10
 
12
- timer = Tmtms::Timer.new
13
- jobs = {
14
- KEY_HENKAN => nil,
15
- KEY_MUHENKAN => nil,
16
- }
17
-
18
- henkan_map = {
11
+ # HENKAN, MUHENKAN を 0.5秒以上押したら SUPER とする
12
+ rk.remap(hold: 0.5, map: {
19
13
  KEY_HENKAN => KEY_RIGHTMETA,
20
14
  KEY_MUHENKAN => KEY_RIGHTMETA, # LEFTMETA だとデスクトップ環境のメニューが開いたりするため
21
- }
15
+ })
22
16
 
23
- rk.match(code: [KEY_HENKAN, KEY_MUHENKAN]) do |event|
24
- if event.type == :press
25
- job = timer.set(0.5) do
26
- rk.synchronize do
27
- rk.event(code: henkan_map[event.code], type: :press)
28
- end
29
- end
30
- jobs[event.code] = job
31
- elsif event.type == :release
32
- if jobs[event.code]&.cancel
33
- rk.key(event.code)
34
- else
35
- rk.event(code: henkan_map[event.code], type: :release)
36
- end
37
- end
17
+ # マウスボタンイベントはそのまま
18
+ rk.match(device: :mouse) do |event|
19
+ rk.event(code: event.code, type: event.type)
38
20
  event.skip
39
21
  end
40
22
 
41
- rk.match(type: :press) do
42
- [KEY_HENKAN, KEY_MUHENKAN].each do |code|
43
- if jobs[code]&.cancel
44
- rk.event(code: henkan_map[code], type: :press)
45
- end
46
- end
47
- end
48
-
49
- def code2key(code)
50
- Rkremap::CODE_KEY[code].to_s.sub(/\AKEY_/, '')
51
- end
52
-
53
23
  rk.start do |code, mod|
54
- key = (mod.select{|_, v| v}.keys + [code]).map{|c| code2key(c)}.join('-')
55
- puts key
56
24
  rk.key(code, mod)
57
25
  end
data/example/keylogger.rb CHANGED
@@ -6,9 +6,9 @@ def code2key(code)
6
6
  Rkremap::CODE_KEY[code].to_s.sub(/\AKEY_/, '')
7
7
  end
8
8
 
9
- rk = Rkremap.new
9
+ rk = Rkremap.new(*ARGV)
10
10
  rk.grab = false
11
- rk.x11 = true
11
+ rk.x11 = true if ENV['DISPLAY']
12
12
  rk.start do |code, mod, app|
13
13
  key = (mod.select{|_, v| v}.keys + [code]).map{|c| code2key(c)}.join('-')
14
14
  key << " at #{app.title} [#{app.class_name}]" if rk.x11
@@ -36,45 +36,82 @@ mod_disable_all = {}.merge(mod_disable_ctrl, mod_disable_shift, mod_disable_alt,
36
36
  rk = Rkremap.new
37
37
  rk.grab = true
38
38
  rk.x11 = true
39
- rk.start do |code, mod, app|
40
- # Emacs や端末等ではそのまま
41
- if app.class_name == 'Emacs' || app.class_name =~ /terminal/i || app.class_name == 'VirtualBox Machine'
39
+
40
+ # Emacs や VirtualBox ではそのまま
41
+ rk.match(app: /Emacs|VirtualBox Machine/) do |event|
42
+ rk.event(code: event.code, type: event.type)
43
+ event.skip
44
+ end
45
+
46
+ # 端末
47
+ rk.match(app: /terminal/i) do |event, mod|
48
+ # Super+Ctrl はそのまま
49
+ if (mod[KEY_LEFTMETA] || mod[KEY_RIGHTMETA]) && (mod[KEY_LEFTCTRL] || mod[KEY_RIGHTCTRL])
50
+ rk.event(code: event.code, type: event.type)
51
+ # Super+0/Minus は Ctrl+0/Minus に変換
52
+ elsif (mod[KEY_LEFTMETA] || mod[KEY_RIGHTMETA]) && Rkremap::CODE_KEY[event.code] =~ /\AKEY_(0|MINUS)\z/
53
+ rk.with_modifier(mod_disable_all.merge(KEY_LEFTCTRL => true)) do
54
+ rk.event(code: event.code, type: event.type)
55
+ end
56
+ # Super+KEY は Ctrl+Shift+KEY に変換
57
+ elsif (mod[KEY_LEFTMETA] || mod[KEY_RIGHTMETA]) && Rkremap::CODE_KEY[event.code] =~ /\AKEY_([A-Z]|EQUAL)\z/
58
+ rk.with_modifier(mod_disable_meta.merge(KEY_LEFTCTRL => true, KEY_LEFTSHIFT => true)) do
59
+ rk.event(code: event.code, type: event.type)
60
+ end
61
+ # それ以外はそのまま
62
+ else # rubocop:disable Lint/DuplicateBranch
63
+ rk.event(code: event.code, type: event.type)
64
+ end
65
+ event.skip
66
+ end
67
+
68
+ # その他のウィンドウ
69
+ rk.start do |code, mod|
70
+ # Super + Ctrl + 何か はそのまま
71
+ if (mod[KEY_LEFTMETA] || mod[KEY_RIGHTMETA]) && (mod[KEY_LEFTCTRL] || mod[KEY_RIGHTCTRL])
42
72
  rk.key(code, mod)
43
73
  next
44
74
  end
45
75
 
46
- # SUPER+[A-Z]/Enter を Ctrl+[A-Z]/Enter に変換
47
- if (mod[KEY_LEFTMETA] || mod[KEY_RIGHTMETA]) && (Rkremap::CODE_KEY[code] =~ /\AKEY_[A-Z]\z/ || code == KEY_ENTER)
48
- mod.merge!(mod_disable_meta, {KEY_LEFTCTRL => true})
49
- mod[KEY_LEFTCTRL] = true
50
- rk.key(code, mod)
76
+ # Super+[A-Z]/Minus/Equal/Enter を Ctrl+[A-Z]/Minus/Equal/Enter に変換
77
+ if (mod[KEY_LEFTMETA] || mod[KEY_RIGHTMETA]) && (Rkremap::CODE_KEY[code] =~ /\AKEY_([0-9A-Z]|MINUS|EQUAL|ENTER)\z/)
78
+ rk.key(code, mod.merge(mod_disable_meta, KEY_LEFTCTRL => true))
51
79
  next
52
80
  end
53
81
 
54
82
  # Alt + F, B は Ctrl + →, ← に変換
55
83
  if (mod[KEY_LEFTALT] || mod[KEY_RIGHTALT]) && (code == KEY_F || code == KEY_B)
56
- rk.key(code == KEY_F ? KEY_RIGHT : KEY_LEFT, mod.merge(mod_disable_alt, {KEY_LEFTCTRL => true}))
84
+ rk.key(code == KEY_F ? KEY_RIGHT : KEY_LEFT, mod.merge(mod_disable_alt, KEY_LEFTCTRL => true))
57
85
  next
58
86
  end
59
87
 
60
88
  # Ctrl は他のキーに変換
61
89
  if mod[KEY_LEFTCTRL] || mod[KEY_RIGHTCTRL]
90
+ # Ctrl+I/O はそのまま
91
+ if code == KEY_I || code == KEY_O
92
+ rk.key(code, mod)
93
+ next
94
+ end
95
+
62
96
  # Ctrl+K は行末まで削除
63
97
  if code == KEY_K
64
- rk.key(KEY_END, mod_disable_all.merge({KEY_LEFTSHIFT => true}))
65
- rk.key(KEY_X, mod_disable_all.merge({KEY_LEFTCTRL => true}))
98
+ rk.key(KEY_END, mod_disable_all.merge(KEY_LEFTSHIFT => true)) # SHIFT+END
99
+ rk.key(KEY_X, mod_disable_all.merge(KEY_LEFTCTRL => true)) # Ctrl+X
66
100
  next
67
101
  end
102
+
68
103
  # 単純な変換
69
104
  if ctrl_map[code]
70
- rk.key(ctrl_map[code], mod_disable_ctrl)
105
+ rk.key(ctrl_map[code], mod.merge(mod_disable_ctrl))
71
106
  next
72
107
  end
108
+
73
109
  # その他の Ctrl+[A-Z] は無視
74
110
  if Rkremap::CODE_KEY[code] =~ /\AKEY_[A-Z]\z/
75
111
  next
76
112
  end
77
113
  end
78
114
 
115
+ # それ以外はそのまま
79
116
  rk.key(code, mod)
80
117
  end
data/example/tmtms.rb CHANGED
@@ -1,67 +1,42 @@
1
1
  # tmtms 用
2
2
 
3
3
  require 'rkremap'
4
- require 'tmtms_timer' # gem install tmtms_timer
5
4
 
6
5
  include Rkremap::KeyCode
7
6
 
8
- rk = Rkremap.new
7
+ rk = Rkremap.new(*ARGV, mouse: true, exclude: /\AELAN0676/i)
9
8
  rk.grab = true
10
9
  rk.x11 = true
11
10
 
12
- timer = Tmtms::Timer.new
13
- jobs = {
14
- KEY_HENKAN => nil,
15
- KEY_MUHENKAN => nil,
16
- }
17
- henkan_map = {
11
+ # rkremap がシステムに認識されたら中ボタンスクロールを有効にする
12
+ sleep 0.1 until system "xinput | grep -q rkremap"
13
+ system "xinput set-prop pointer:rkremap 'libinput Scroll Method Enabled' 0 0 1"
14
+
15
+ # HENKAN, MUHENKAN を 0.5秒以上押したら SUPER とする
16
+ rk.remap(hold: 0.5, map: {
18
17
  KEY_HENKAN => KEY_RIGHTMETA,
19
18
  KEY_MUHENKAN => KEY_RIGHTMETA, # LEFTMETA だとデスクトップ環境のメニューが開いたりするため
20
- }
19
+ })
21
20
 
22
- rk.match(code: [KEY_HENKAN, KEY_MUHENKAN]) do |event|
23
- if event.type == :press
24
- job = timer.set(0.5) do
25
- rk.synchronize do
26
- rk.event(code: henkan_map[event.code], type: :press)
27
- end
28
- end
29
- jobs[event.code] = job
30
- elsif event.type == :release
31
- if jobs[event.code]&.cancel
32
- rk.key(event.code)
33
- else
34
- rk.event(code: henkan_map[event.code], type: :release)
35
- end
36
- end
21
+ # マウスボタンイベントはそのまま
22
+ rk.match(device: :mouse) do |event|
23
+ rk.event(code: event.code, type: event.type)
37
24
  event.skip
38
25
  end
39
26
 
40
- rk.match(type: :press) do
41
- [KEY_HENKAN, KEY_MUHENKAN].each do |code|
42
- if jobs[code]&.cancel
43
- rk.event(code: henkan_map[code], type: :press)
44
- end
45
- end
46
- end
47
-
48
27
  # CAPSLOCK は CTRL に変換
49
- rk.match(code: KEY_CAPSLOCK) do |event|
50
- rk.event(code: KEY_LEFTCTRL, type: event.type)
51
- event.skip
52
- end
28
+ rk.remap(KEY_CAPSLOCK => KEY_LEFTCTRL)
29
+
30
+ # JISキーボードを英語配列にしたときに一部キーを変える
31
+ rk.remap(
32
+ KEY_YEN => KEY_BACKSLASH,
33
+ KEY_BACKSLASH => KEY_GRAVE,
34
+ KEY_GRAVE => KEY_ESC,
35
+ [KEY_LEFTSHIFT, KEY_RO] => [KEY_LEFTSHIFT, KEY_MINUS],
36
+ [KEY_RIGHTSHIFT, KEY_RO] => [KEY_LEFTSHIFT, KEY_MINUS],
37
+ KEY_RO => KEY_BACKSLASH,
38
+ )
53
39
 
54
- ctrl_map = {
55
- KEY_A => KEY_HOME,
56
- KEY_E => KEY_END,
57
- KEY_B => KEY_LEFT,
58
- KEY_F => KEY_RIGHT,
59
- KEY_N => KEY_DOWN,
60
- KEY_P => KEY_UP,
61
- KEY_D => KEY_DELETE,
62
- KEY_H => KEY_BACKSPACE,
63
- KEY_I => KEY_TAB,
64
- }
65
40
  mod_disable_ctrl = {
66
41
  KEY_LEFTCTRL => false,
67
42
  KEY_RIGHTCTRL => false,
@@ -80,36 +55,63 @@ mod_disable_meta = {
80
55
  }
81
56
  mod_disable_all = {}.merge(mod_disable_ctrl, mod_disable_shift, mod_disable_alt, mod_disable_meta)
82
57
 
83
- key_map = {
84
- KEY_YEN => KEY_BACKSLASH,
85
- KEY_BACKSLASH => KEY_GRAVE,
86
- KEY_GRAVE => KEY_ESC,
87
- }
58
+ # Emacs や VirtualBox ではそのまま
59
+ rk.match(app: /Emacs|VirtualBox Machine/) do |event|
60
+ rk.event(code: event.code, type: event.type)
61
+ event.skip
62
+ end
88
63
 
89
- rk.start do |code, mod, app|
90
- # JISキーボードを英語配列にしたときに一部キーを変える
91
- code = key_map[code] || code
92
- if code == KEY_RO
93
- code = mod[KEY_LEFTSHIFT] || mod[KEY_RIGHTSHIFT] ? KEY_MINUS : KEY_BACKSLASH
64
+ # 端末
65
+ rk.match(app: /terminal/i) do |event, mod|
66
+ # Super+Ctrl はそのまま
67
+ if (mod[KEY_LEFTMETA] || mod[KEY_RIGHTMETA]) && (mod[KEY_LEFTCTRL] || mod[KEY_RIGHTCTRL])
68
+ rk.event(code: event.code, type: event.type)
69
+ # Super+0/Minus は Ctrl+0/Minus に変換
70
+ elsif (mod[KEY_LEFTMETA] || mod[KEY_RIGHTMETA]) && Rkremap::CODE_KEY[event.code] =~ /\AKEY_(0|MINUS)\z/
71
+ rk.with_modifier(mod_disable_all.merge(KEY_LEFTCTRL => true)) do
72
+ rk.event(code: event.code, type: event.type)
73
+ end
74
+ # Super+KEY は Ctrl+Shift+KEY に変換
75
+ elsif (mod[KEY_LEFTMETA] || mod[KEY_RIGHTMETA]) && Rkremap::CODE_KEY[event.code] =~ /\AKEY_([A-Z]|EQUAL)\z/
76
+ rk.with_modifier(mod_disable_meta.merge(KEY_LEFTCTRL => true, KEY_LEFTSHIFT => true)) do
77
+ rk.event(code: event.code, type: event.type)
78
+ end
79
+ # それ以外はそのまま
80
+ else # rubocop:disable Lint/DuplicateBranch
81
+ rk.event(code: event.code, type: event.type)
94
82
  end
83
+ event.skip
84
+ end
85
+
86
+ # その他のウィンドウ
87
+ ctrl_map = {
88
+ KEY_A => KEY_HOME,
89
+ KEY_E => KEY_END,
90
+ KEY_B => KEY_LEFT,
91
+ KEY_F => KEY_RIGHT,
92
+ KEY_N => KEY_DOWN,
93
+ KEY_P => KEY_UP,
94
+ KEY_D => KEY_DELETE,
95
+ KEY_H => KEY_BACKSPACE,
96
+ KEY_I => KEY_TAB,
97
+ }
95
98
 
96
- # Emacs や端末等ではそのまま
97
- if app.class_name == 'Emacs' || app.class_name =~ /terminal/i || app.class_name == 'VirtualBox Machine'
99
+ rk.start do |code, mod|
100
+ # Super + Ctrl + 何か はそのまま
101
+ if (mod[KEY_LEFTMETA] || mod[KEY_RIGHTMETA]) && (mod[KEY_LEFTCTRL] || mod[KEY_RIGHTCTRL])
98
102
  rk.key(code, mod)
99
103
  next
100
104
  end
101
105
 
102
- # SUPER+[A-Z]/Enter を Ctrl+[A-Z]/Enter に変換
103
- if (mod[KEY_LEFTMETA] || mod[KEY_RIGHTMETA]) && (Rkremap::CODE_KEY[code] =~ /\AKEY_[A-Z]\z/ || code == KEY_ENTER)
104
- mod.merge!(mod_disable_meta, {KEY_LEFTCTRL => true})
105
- mod[KEY_LEFTCTRL] = true
106
- rk.key(code, mod)
106
+ # Super+[A-Z]/Minus/Equal/Enter を Ctrl+[A-Z]/Minus/Equal/Enter に変換
107
+ if (mod[KEY_LEFTMETA] || mod[KEY_RIGHTMETA]) && (Rkremap::CODE_KEY[code] =~ /\AKEY_([0-9A-Z]|MINUS|EQUAL|ENTER)\z/)
108
+ rk.key(code, mod.merge(mod_disable_meta, KEY_LEFTCTRL => true))
107
109
  next
108
110
  end
109
111
 
110
112
  # Alt + F, B は Ctrl + →, ← に変換
111
113
  if (mod[KEY_LEFTALT] || mod[KEY_RIGHTALT]) && (code == KEY_F || code == KEY_B)
112
- rk.key(code == KEY_F ? KEY_RIGHT : KEY_LEFT, mod.merge(mod_disable_alt, {KEY_LEFTCTRL => true}))
114
+ rk.key(code == KEY_F ? KEY_RIGHT : KEY_LEFT, mod.merge(mod_disable_alt, KEY_LEFTCTRL => true))
113
115
  next
114
116
  end
115
117
 
@@ -120,22 +122,26 @@ rk.start do |code, mod, app|
120
122
  rk.key(code, mod)
121
123
  next
122
124
  end
125
+
123
126
  # Ctrl+K は行末まで削除
124
127
  if code == KEY_K
125
- rk.key(KEY_END, mod_disable_all.merge({KEY_LEFTSHIFT => true}))
126
- rk.key(KEY_X, mod_disable_all.merge({KEY_LEFTCTRL => true}))
128
+ rk.key(KEY_END, mod_disable_all.merge(KEY_LEFTSHIFT => true)) # SHIFT+END
129
+ rk.key(KEY_X, mod_disable_all.merge(KEY_LEFTCTRL => true)) # Ctrl+X
127
130
  next
128
131
  end
132
+
129
133
  # 単純な変換
130
134
  if ctrl_map[code]
131
- rk.key(ctrl_map[code], mod_disable_ctrl)
135
+ rk.key(ctrl_map[code], mod.merge(mod_disable_ctrl))
132
136
  next
133
137
  end
138
+
134
139
  # その他の Ctrl+[A-Z] は無視
135
140
  if Rkremap::CODE_KEY[code] =~ /\AKEY_[A-Z]\z/
136
141
  next
137
142
  end
138
143
  end
139
144
 
145
+ # それ以外はそのまま
140
146
  rk.key(code, mod)
141
147
  end