rkremap 0.2.1 → 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: d204d310504030119a941b532fec985cae5747c1d1e04958baefbb112327a629
4
- data.tar.gz: c98176cf3e753eb59da16e614159a5516e9bc1701e63806ec02d3e3bd8c4d076
3
+ metadata.gz: 04a75325e18cfa14e1eeb93462af309c6d692083c5ef4a2609e6dfd53747a6c8
4
+ data.tar.gz: 1f86fc05c3098eed25b0d09bbebfc75fdad37122898ee9762376ce5241f21c60
5
5
  SHA512:
6
- metadata.gz: e04feb18bbae681fc1b5bbd2f8a95ea85b58aff976865d857fd044274214eb9f2502c34bb7ff4cb9b620f3658e55f82157b4c6b98dbe4eb5dce8ce8446ff042d
7
- data.tar.gz: 941f5b2893c031a7891151635b8cfb83d5ce410d8c0751da86a2b2699ce440a10221684dba881849bd54f4afa10f3b18cd8defe98b0a7601cfed4f5eb15bd7b6
6
+ metadata.gz: 3874c3c1a1c9b78a82faf4c3ceb40f28e1d9d5f1380a8ac3f604ffc904f2dcb4099db5b84f2f9542ae4d104ac8f242f4edd8060c8da0aa4f65e8ddc472a4cab2
7
+ data.tar.gz: f9700cd0991fb27fa03de2a402dd1bfebe0f23cc35d128b5b35ca9115608988ce2f1aeea55cd8525a3c645e1b4a465b0aa0995703e4cb0b58f73bdb7e2efda3f
data/README.md CHANGED
@@ -48,6 +48,15 @@ ThinkPad 本体のキーボードは `/dev/input/event3` だった。
48
48
 
49
49
  `true` に設定すると X のアプリ名等を取得できる。X 環境下でないなら `false` を設定する。
50
50
 
51
+ ### Rkremap#modifers
52
+
53
+ 修飾キーの一覧。これらのキーは単体で押されただけでは `start` ブロックを実行しない。
54
+
55
+ ### auto_detect
56
+
57
+ `true` の場合はキーボードデバイスの接続を自動検知する。
58
+ `new` 時にデバイスファイルが指定されない場合は `true` になる。
59
+
51
60
  ### Rkremap#start
52
61
 
53
62
  なにかキーを押されたらブロックを実行する。修飾キー単体ではブロックは実行されない。
data/example/tmtms.rb CHANGED
@@ -1,14 +1,4 @@
1
1
  # tmtms 用
2
- #
3
- # fcitx が有効な場合に /tmp/fcitx-enabled ファイルを作るスクリプトを動かしておく:
4
- # while :; do
5
- # if [ $(fcitx-remote) -eq 2 ]; then
6
- # touch /tmp/fcitx-enabled
7
- # else
8
- # rm -f /tmp/fcitx-enabled
9
- # fi
10
- # sleep 0.1
11
- # done
12
2
 
13
3
  require 'rkremap'
14
4
  include Rkremap::KeyCode
@@ -159,8 +149,8 @@ rk.start do |code, mod, app|
159
149
 
160
150
  # Ctrl は他のキーに変換
161
151
  if mod[KEY_LEFTCTRL] || mod[KEY_RIGHTCTRL]
162
- # Ctrl-K/I/O は日本語変換時はそのまま
163
- if (code == KEY_K || code == KEY_I || code ==KEY_O) && File.exist?('/tmp/fcitx-enabled')
152
+ # Ctrl+I/O はそのまま
153
+ if code == KEY_I || code ==KEY_O
164
154
  rk.key(code, mod)
165
155
  next
166
156
  end
data/lib/rkremap/evdev.rb CHANGED
@@ -8,27 +8,49 @@ class Rkremap
8
8
  EVIOCGBIT_ANY = 2147566880 # EVIOCGBIT(0, 1)
9
9
  EVIOCGBIT_EV_KEY = 2153792801 # EVIOCGBIT(EV_KEY, (KEY_MAX-1)/8+1)
10
10
  EVIOCGRAB = 1074021776
11
+ EVIOCGNAME = 2164278534 # EVIOCGNAME(256)
11
12
 
12
13
  @io2evdev = {}
13
14
  def self.io2evdev
14
15
  @io2evdev
15
16
  end
16
17
 
18
+ @device_list = {}
19
+
17
20
  # @return [Array<Evdev>]
18
- def self.devices
19
- Dir.children("/dev/input").map do |dev|
20
- dev =~ /\Aevent\d+\z/ ? Evdev.new("/dev/input/#{dev}") : nil
21
+ def self.detect
22
+ devs = []
23
+ new_devs = Dir.children("/dev/input").map do |dev|
24
+ if dev =~ /\Aevent\d+\z/
25
+ path = "/dev/input/#{dev}"
26
+ devs.push path
27
+ next if @device_list[path]
28
+ @device_list[path] = true
29
+ Evdev.new(path)
30
+ end
21
31
  end.compact
32
+ (@device_list.keys - devs).each do |path|
33
+ @device_list.delete path
34
+ end
35
+ new_devs
36
+ end
37
+
38
+ def self.remove_device(evdev)
39
+ @io2evdev.delete evdev.io
40
+ @device_list.delete evdev.path
22
41
  end
23
42
 
24
43
  # @param inputs [Array<Evdev>]
44
+ # @param timeout [Numeric]
25
45
  # @return [Evdev]
26
- def self.select(inputs)
27
- h = inputs.map{|ev| [ev.io, ev]}.to_h
28
- r, = IO.select(inputs.map(&:io), nil, nil, nil)
29
- @io2evdev[r[0]]
46
+ def self.select(inputs, timeout)
47
+ r, = IO.select(inputs.map(&:io), nil, nil, timeout)
48
+ r && @io2evdev[r[0]]
30
49
  end
31
50
 
51
+ # @return [String]
52
+ attr_reader :path
53
+
32
54
  # @param path [String]
33
55
  def initialize(path)
34
56
  @path = path
@@ -37,6 +59,10 @@ class Rkremap
37
59
  @uinput = nil
38
60
  end
39
61
 
62
+ def eql?(other)
63
+ other.is_a?(Evdev) && self.path == other.path
64
+ end
65
+
40
66
  # @return [IO]
41
67
  def io
42
68
  return @io if @io
@@ -47,6 +73,7 @@ class Rkremap
47
73
 
48
74
  def close
49
75
  @io&.close
76
+ self.class.remove_device(self)
50
77
  end
51
78
 
52
79
  # @param key [Integer]
@@ -63,6 +90,9 @@ class Rkremap
63
90
  # @return [Boolean]
64
91
  def keyboard?
65
92
  buf = ' '
93
+ io.ioctl(EVIOCGNAME, buf)
94
+ return false if buf =~ /\Arkremap\0*\z/
95
+
66
96
  io.ioctl(EVIOCGBIT_ANY, buf)
67
97
  return false if buf.unpack1('C')[EV_KEY] == 0
68
98
  capable?(KeyCode::KEY_0) && capable?(KeyCode::KEY_9) &&
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  class Rkremap
4
- VERSION = "0.2.1"
4
+ VERSION = "0.3.0"
5
5
  end
data/lib/rkremap.rb CHANGED
@@ -17,11 +17,17 @@ class Rkremap
17
17
  attr_accessor :grab
18
18
  attr_accessor :modifiers
19
19
  attr_accessor :x11
20
+ attr_accessor :auto_detect
20
21
 
21
22
  # @param devices [Array<String>, String]
22
23
  def initialize(devices=nil)
23
- devices = Array(devices) if devices.is_a? String
24
- @inputs = devices ? devices.map{|d| Evdev.new(d)} : Evdev.devices.select(&:keyboard?)
24
+ if devices
25
+ devices = Array(devices)
26
+ @inputs = devices.map{|d| Evdev.new(d)}
27
+ else
28
+ @auto_detect = true
29
+ @inputs = Evdev.detect.select(&:keyboard?)
30
+ end
25
31
  raise 'Unable to detect keyboard device' if @inputs.empty?
26
32
  @uinput = Uinput.new
27
33
  @grab = false
@@ -43,13 +49,13 @@ class Rkremap
43
49
  end
44
50
 
45
51
  def start(&block)
46
- @mod_state = @modifiers.map{|m| [m, false]}.to_h
52
+ detect_device_loop if @auto_detect
53
+ @mod_state = @modifiers.map.to_h{|m| [m, false]}
47
54
  @winattr = WinAttr.new if @x11
48
55
  @inputs.each(&:grab) if @grab
49
56
  while true
50
57
  @keys = []
51
- input = Evdev.select(@inputs)
52
- time, type, code, value = input.read_event
58
+ time, type, code, value = read_event
53
59
  next if type != EV_KEY
54
60
  event = Event.new(time, code, value, @winattr)
55
61
  @events.each do |cond, b|
@@ -64,6 +70,32 @@ class Rkremap
64
70
  end
65
71
  end
66
72
 
73
+ def detect_device_loop
74
+ Thread.new do
75
+ while true
76
+ sleep 3
77
+ new_devs = Evdev.detect.select(&:keyboard?)
78
+ unless new_devs.empty?
79
+ new_devs.each(&:grab) if @grab
80
+ @inputs += new_devs
81
+ end
82
+ end
83
+ end
84
+ end
85
+
86
+ def read_event
87
+ while true
88
+ begin
89
+ input = Evdev.select(@inputs, 3)
90
+ next unless input
91
+ return input.read_event
92
+ rescue Errno::ENODEV
93
+ input.close rescue nil
94
+ @inputs.delete input
95
+ end
96
+ end
97
+ end
98
+
67
99
  def synchronize(&block)
68
100
  @mutex.synchronize(&block)
69
101
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rkremap
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.1
4
+ version: 0.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - TOMITA Masahiro
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2022-01-29 00:00:00.000000000 Z
11
+ date: 2022-03-05 00:00:00.000000000 Z
12
12
  dependencies: []
13
13
  description: key remapper
14
14
  email: