fusuma-plugin-sendkey 0.1.1 → 0.5.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: 3087cd15e356a48d1f8fd2398daed7f6153d4e9c005db98ffad34627b357bc65
4
- data.tar.gz: 0dd9da2ff1ef200d76691f9a3e72fe8efff68cea8e6eef1c448387df6154daf1
3
+ metadata.gz: e1f133065105c5e8bcdc9dd04873d6245cb3b6357a1a9f45a437cd0150b5a959
4
+ data.tar.gz: c6f759e41f007688902c837f1fedc65e00d70ee3a41bb8bc9baf28de48e3c8ed
5
5
  SHA512:
6
- metadata.gz: 830a41f20bfa018ceff548a8c660012947657fbd18b8e369a1033fb4f4d0e2f665ade047eeafa9d3ba3ade8ba5079a1c1044cc6401b4222da20847bced619a7b
7
- data.tar.gz: 9f8ae60d5377799ed80844ba3a218049c1a736cf7ed0e733dea347067a30fc548f6aa5c82b2311858e2474f8ad0d1df8a3e8739730d9e301664a784d2a073b26
6
+ metadata.gz: 6390589b886bc137bed6e4bbd4cab68b890d7660fbf09462aa471557c8c7533cff11f73cec2f25ce3875489ef3abd44e82999af2f400dbe619470f29e4d2e17b
7
+ data.tar.gz: 4f80040d29ff16b5184e2f2f51485e39e178a029da0aec8e2c647da9428bd08ab54f5814c49194eeccdfac012091e4235392768d02de71191fff8af3b9bf4f4f
data/.gitignore CHANGED
@@ -10,3 +10,4 @@
10
10
 
11
11
  # rspec failure tracking
12
12
  .rspec_status
13
+ .ruby-version
@@ -11,3 +11,10 @@ Metrics/LineLength:
11
11
  Max: 100
12
12
  Exclude:
13
13
  - "fusuma-plugin-*.gemspec"
14
+
15
+ Style/HashEachMethods:
16
+ Enabled: true
17
+ Style/HashTransformKeys:
18
+ Enabled: true
19
+ Style/HashTransformValues:
20
+ Enabled: true
@@ -6,4 +6,4 @@ rvm:
6
6
  - 2.6.1
7
7
  before_install:
8
8
  - gem install bundler -v 2.0.1
9
- - sudo apt-get -y install evemu-tools libevdev-dev
9
+ - sudo apt-get -y install libevdev-dev
@@ -0,0 +1,21 @@
1
+ # Changelog
2
+
3
+ ## [Unreleased](https://github.com/iberianpig/fusuma-plugin-keypress/tree/HEAD)
4
+
5
+ [Full Changelog](https://github.com/iberianpig/fusuma-plugin-keypress/compare/v0.1.1...HEAD)
6
+
7
+ **Closed issues:**
8
+
9
+ - Trigger a command multiple times while keeping the key pressed [\#1](https://github.com/iberianpig/fusuma-plugin-keypress/issues/1)
10
+
11
+ ## [v0.1.1](https://github.com/iberianpig/fusuma-plugin-keypress/tree/v0.1.1) (2020-02-18)
12
+
13
+ [Full Changelog](https://github.com/iberianpig/fusuma-plugin-keypress/compare/v0.1.0...v0.1.1)
14
+
15
+ ## [v0.1.0](https://github.com/iberianpig/fusuma-plugin-keypress/tree/v0.1.0) (2019-11-12)
16
+
17
+ [Full Changelog](https://github.com/iberianpig/fusuma-plugin-keypress/compare/fb8d8ccfc3828e487607706335f670ae5392f08d...v0.1.0)
18
+
19
+
20
+
21
+ \* *This Changelog was automatically generated by [github_changelog_generator](https://github.com/github-changelog-generator/github-changelog-generator)*
data/README.md CHANGED
@@ -1,9 +1,9 @@
1
1
  # Fusuma::Plugin::Sendkey [![Gem Version](https://badge.fury.io/rb/fusuma-plugin-sendkey.svg)](https://badge.fury.io/rb/fusuma-plugin-sendkey) [![Build Status](https://travis-ci.com/iberianpig/fusuma-plugin-sendkey.svg?branch=master)](https://travis-ci.com/iberianpig/fusuma-plugin-sendkey)
2
2
 
3
- [Fusuma](https://github.com/iberianpig/fusuma) plugin that sending virtual keyboard events
3
+ [Fusuma](https://github.com/iberianpig/fusuma) plugin to send keyboard events
4
4
 
5
- * Emulate keyboard events with evemu-event
6
- * This plugin replaces xdotool
5
+ * Low-latency key event emulation with evdev
6
+ * Alternative to xdotool available for X11 and Wayland
7
7
 
8
8
  ## Installation
9
9
 
@@ -11,33 +11,45 @@ Run the following code in your terminal.
11
11
 
12
12
  ### Install dependencies
13
13
 
14
+ **NOTE: If you have installed ruby by apt, you must install ruby-dev.**
14
15
  ```sh
15
- $ sudo apt-get install evemu-tools libevdev-dev
16
+ $ sudo apt-get install libevdev-dev ruby-dev
16
17
  ```
17
18
 
18
19
  ### Install fusuma-plugin-sendkey
19
20
 
20
21
  ```sh
21
- $ gem install fusuma-plugin-sendkey
22
+ $ sudo gem install fusuma-plugin-sendkey
22
23
  ```
23
24
 
24
25
 
25
- ## List avaiable keys
26
+ ## List available keys
26
27
 
27
28
  ```sh
28
29
  $ fusuma-sendkey -l
29
30
  ```
31
+ If you want to look up a specific key, like the next song or the previous song, the `grep -i` refinement search is useful.
32
+
33
+ ```sh
34
+ $ fusuma-sendkey -l | grep -i song
35
+ NEXTSONG
36
+ PREVIOUSSONG
37
+ ```
30
38
 
31
39
  ## Run fusuma-sendkey on Terminal
32
40
 
33
- * `fusuma-sendkey` can emulate keyboard inputs as a command
34
- * Combine keys for pressing the same time with `+`
41
+ * `fusuma-sendkey` command is available on your terminal
42
+ * `fusuma-sendkey` supports modifier keys and multiple key presses.
43
+ Combine keys for pressing the same time with `+`
35
44
 
36
45
 
37
46
  ```sh
38
- $ fusuma-sendkey LEFTCTRL+T
47
+ $ fusuma-sendkey LEFTCTRL+T # press ctrl key + t key
39
48
  ```
40
49
 
50
+ Some of the keys found with `fusuma-sendkey -l` may actually be invalid keys.
51
+ So test it once with `fusuma-sendkey <KEYCODE>` and then add it to config.yml.
52
+
41
53
 
42
54
  ## Add sendkey properties to config.yml
43
55
 
@@ -58,6 +70,26 @@ swipe:
58
70
  sendkey: "LEFTCTRL+W" # close tab
59
71
  ```
60
72
 
73
+
74
+ ### Specify keyboard by device name
75
+
76
+ If you got following error message, try to set your keyboard name to `plugin.executors.sendkey_executor.device_name` on config.yml
77
+
78
+ ```shell
79
+ $ fusuma-sendkey -l
80
+ sendkey: Keyboard: /keyboard|Keyboard|KEYBOARD/ is not found
81
+ ```
82
+
83
+ Set the following options to recognize keyboard only for the specified keyboard device.
84
+ Open `~/.config/fusuma/config.yml` and add the following code at the bottom.
85
+
86
+ ```yaml
87
+ plugin:
88
+ executors:
89
+ sendkey_executor:
90
+ device_name: 'YOUR KEYBOARD NAME'
91
+ ```
92
+
61
93
  ## Contributing
62
94
 
63
95
  Bug reports and pull requests are welcome on GitHub at https://github.com/iberianpig/fusuma-plugin-sendkey. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [Contributor Covenant](http://contributor-covenant.org) code of conduct.
data/Rakefile CHANGED
@@ -1,6 +1,15 @@
1
- require "bundler/gem_tasks"
2
- require "rspec/core/rake_task"
1
+ # frozen_string_literal: true
2
+
3
+ require 'bundler/gem_tasks'
4
+ require 'rspec/core/rake_task'
3
5
 
4
6
  RSpec::Core::RakeTask.new(:spec)
5
7
 
6
- task :default => :spec
8
+ task default: :spec
9
+
10
+ require 'github_changelog_generator/task'
11
+
12
+ GitHubChangelogGenerator::RakeTask.new :changelog do |config|
13
+ config.user = 'iberianpig'
14
+ config.project = 'fusuma-plugin-keypress'
15
+ end
@@ -1,14 +1,12 @@
1
1
  #!/usr/bin/env ruby
2
2
 
3
3
  require "bundler/setup"
4
+ require 'fusuma/plugin/executors/executor'
4
5
  require "fusuma/plugin/sendkey"
5
6
 
6
7
  # You can add fixtures and/or initialization code here to make experimenting
7
8
  # with your gem easier. You can also use a different console, if you like.
8
9
 
9
10
  # (If you use this, don't forget to add pry to your Gemfile!)
10
- # require "pry"
11
- # Pry.start
12
-
13
- require "irb"
14
- IRB.start(__FILE__)
11
+ require "pry"
12
+ Pry.start
@@ -3,6 +3,7 @@
3
3
 
4
4
  require 'optparse'
5
5
  require_relative '../lib/fusuma/plugin/sendkey/keyboard.rb'
6
+ require_relative '../lib/fusuma/plugin/sendkey/version.rb'
6
7
 
7
8
  option = {}
8
9
  opt = OptionParser.new
@@ -19,7 +20,7 @@ end
19
20
  opt.parse!(ARGV)
20
21
 
21
22
  if option[:list]
22
- puts Keyboard.new.available_codes
23
+ puts Fusuma::Plugin::Sendkey::Keyboard.new(name_pattern: nil).search_codes
23
24
  return
24
25
  end
25
26
 
@@ -36,6 +37,5 @@ if param.nil?
36
37
  exit 1
37
38
  end
38
39
 
39
- Keyboard.new.type_command(param: param).tap do |command|
40
- exec(command)
41
- end
40
+ keyboard = Fusuma::Plugin::Sendkey::Keyboard.new
41
+ keyboard.valid?(param: param) && keyboard.type(param: param)
@@ -10,8 +10,8 @@ Gem::Specification.new do |spec|
10
10
  spec.authors = ['iberianpig']
11
11
  spec.email = ['yhkyky@gmail.com']
12
12
 
13
- spec.summary = 'Fusuma plugin that sending virtual keyboard events'
14
- spec.description = 'Fusuma::Plugin::Sendkey emulate keyboard events with evemu-event'
13
+ spec.summary = 'Fusuma plugin to send keyboard events'
14
+ spec.description = 'Fusuma::Plugin::Sendkey emulate keyboard events with evdev'
15
15
  spec.homepage = 'https://github.com/iberianpig/fusuma-plugin-sendkey'
16
16
  spec.license = 'MIT'
17
17
 
@@ -24,8 +24,8 @@ Gem::Specification.new do |spec|
24
24
  spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
25
25
  spec.require_paths = ['lib']
26
26
 
27
- spec.add_dependency 'evdev'
28
- spec.add_dependency 'fusuma', '~> 1.5.0'
27
+ spec.add_dependency 'fusuma', '~> 1.7'
28
+ spec.add_dependency 'revdev'
29
29
 
30
30
  spec.add_development_dependency 'bundler'
31
31
  spec.add_development_dependency 'github_changelog_generator', '~> 1.14'
@@ -9,7 +9,7 @@ module Fusuma
9
9
  class SendkeyExecutor < Executor
10
10
  def config_param_types
11
11
  {
12
- 'device_path': String
12
+ 'device_name': String
13
13
  }
14
14
  end
15
15
 
@@ -17,12 +17,10 @@ module Fusuma
17
17
  # @param event [Event]
18
18
  # @return [nil]
19
19
  def execute(event)
20
- return if search_command(event).nil?
21
-
22
20
  MultiLogger.info(sendkey: search_param(event))
23
21
  pid = fork do
24
22
  Process.daemon(true)
25
- exec(search_command(event))
23
+ keyboard.type(param: search_param(event))
26
24
  end
27
25
 
28
26
  Process.detach(pid)
@@ -34,22 +32,18 @@ module Fusuma
34
32
  def executable?(event)
35
33
  event.tag.end_with?('_detector') &&
36
34
  event.record.type == :index &&
37
- search_command(event)
35
+ keyboard.valid?(param: search_param(event))
38
36
  end
39
37
 
40
- # @param event [Event]
41
- # @return [String]
42
- # @return [NilClass]
43
- def search_command(event)
38
+ private
39
+
40
+ def keyboard
44
41
  @keyboard ||= begin
45
- device = Sendkey::Device.new(path: config_params(:device_path))
46
- Sendkey::Keyboard.new(device: device)
42
+ name_pattren = config_params(:device_name)
43
+ Sendkey::Keyboard.new(name_pattern: name_pattren)
47
44
  end
48
- @keyboard.type_command(param: search_param(event))
49
45
  end
50
46
 
51
- private
52
-
53
47
  def search_param(event)
54
48
  index = Config::Index.new([*event.record.index.keys, :sendkey])
55
49
  Config.search(index)
@@ -1,62 +1,22 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'evdev'
4
-
5
3
  module Fusuma
6
4
  module Plugin
7
5
  module Sendkey
8
6
  # handle Evdev device
9
7
  class Device
10
- attr_reader :device_id
11
- def initialize(path: nil)
12
- return if path && (@evdev = Evdev.new(path))
13
-
14
- (0..99).lazy.find do |i|
15
- begin
16
- evdev = Evdev.new("/dev/input/event#{i}")
17
- @evdev = evdev if evdev.supports_event?(convert_keycode('LEFTALT'))
18
- rescue Errno::ENOENT # No such file or directory
19
- false
20
- # TODO: rescue Errno::EACCES
21
- end
22
- end
8
+ def initialize(path:)
9
+ @evdev = Revdev::EventDevice.new(path)
23
10
  end
24
11
 
25
12
  def path
26
- raise 'Keyboard is not found' if @evdev.nil?
13
+ raise 'Device path is not found' if @evdev.nil?
27
14
 
28
15
  @path ||= @evdev.file.path
29
16
  end
30
17
 
31
- def support?(code)
32
- keycode = convert_keycode(code)
33
- @evdev.supports_event?(keycode)
34
- rescue NameError
35
- candidates = search_codes(code: code)
36
-
37
- warn "Did you mean? #{candidates.join(' / ')}" unless candidates.empty?
38
-
39
- false
40
- end
41
-
42
- def search_codes(code: nil)
43
- query = code&.upcase
44
- LinuxInput.constants
45
- .select { |c| c[/KEY_.*#{query}.*/] }
46
- .select { |c| @evdev.supports_event?(c) }
47
- .map { |c| c.to_s.gsub('KEY_', '') }
48
- end
49
-
50
- def emulate(code:, press: true)
51
- keycode = convert_keycode(code)
52
- v = press ? 1 : 0
53
- "evemu-event #{path} --type EV_KEY --code #{keycode} --value #{v} --sync"
54
- end
55
-
56
- private
57
-
58
- def convert_keycode(code)
59
- "KEY_#{code.upcase}"
18
+ def write_event(event)
19
+ @evdev.write_input_event(event)
60
20
  end
61
21
  end
62
22
  end
@@ -1,5 +1,8 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require 'revdev'
4
+ require 'fusuma/device'
5
+
3
6
  require_relative './device.rb'
4
7
 
5
8
  module Fusuma
@@ -7,46 +10,116 @@ module Fusuma
7
10
  module Sendkey
8
11
  # Emulate Keyboard
9
12
  class Keyboard
10
- def initialize(device: nil)
11
- @device = device || Device.new
13
+ def initialize(name_pattern: 'keyboard|Keyboard|KEYBOARD')
14
+ device = find_device(name_pattern: name_pattern)
15
+
16
+ if device.nil?
17
+ warn "sendkey: Keyboard: /#{name_pattern}/ is not found"
18
+ exit(1)
19
+ end
20
+
21
+ @device = Device.new(path: "/dev/input/#{device.id}")
12
22
  end
13
23
 
24
+ attr_reader :device
25
+
14
26
  # @param param [String]
15
- def type_command(param:)
27
+ def type(param:)
16
28
  return unless param.is_a?(String)
17
29
 
18
- codes = param.split('+')
19
- press_commands = codes.map { |code| press_command(code) }
20
- release_commands = codes.reverse.map { |code| release_command(code) }
30
+ keycodes = split_param(param)
21
31
 
22
- (press_commands | release_commands).join(' && ')
32
+ clear_modifiers
33
+ keycodes.each { |keycode| key_event(keycode: keycode, press: true) }
34
+ key_sync(press: true)
35
+ keycodes.reverse.map { |keycode| key_event(keycode: keycode, press: false) }
36
+ key_sync(press: false)
23
37
  end
24
38
 
25
- def press_command(code)
26
- return unless support?(code)
39
+ # @param param [String]
40
+ def valid?(param:)
41
+ return unless param.is_a?(String)
27
42
 
28
- @device.emulate(code: code, press: true)
43
+ keycodes = split_param(param)
44
+ keycodes.all? { |keycode| support?(keycode) }
29
45
  end
30
46
 
31
- def release_command(code)
32
- return unless support?(code)
47
+ def key_event(keycode:, press: true)
48
+ event = Revdev::InputEvent.new(
49
+ nil,
50
+ Revdev.const_get(:EV_KEY),
51
+ Revdev.const_get(keycode),
52
+ press ? 1 : 0
53
+ )
54
+ @device.write_event(event)
55
+ end
33
56
 
34
- @device.emulate(code: code, press: false)
57
+ def key_sync(press: true)
58
+ event = Revdev::InputEvent.new(
59
+ nil,
60
+ Revdev.const_get(:EV_SYN),
61
+ Revdev.const_get(:SYN_REPORT),
62
+ press ? 1 : 0
63
+ )
64
+ @device.write_event(event)
35
65
  end
36
66
 
37
- def support?(code)
67
+ def support?(keycode)
38
68
  @supported_code ||= {}
39
- @supported_code[code] ||= if @device.support?(code)
40
- true
41
- else
42
- warn "sendkey: #{code} is unsupported."
43
- warn 'Please check your config.yml.'
44
- exit 1
45
- end
69
+ @supported_code[keycode] ||= if find_code(keycode: keycode)
70
+ true
71
+ else
72
+ search_candidates(keycode: keycode)
73
+ end
74
+ end
75
+
76
+ def search_candidates(keycode:)
77
+ query = keycode&.upcase&.gsub('KEY_', '')
78
+
79
+ candidates = search_codes(query: query)
80
+
81
+ warn "Did you mean? #{candidates.join(' / ')}" unless candidates.empty?
82
+ warn "sendkey: #{remove_prefix(keycode)} is unsupported."
83
+ end
84
+
85
+ def search_codes(query: nil)
86
+ Revdev.constants
87
+ .select { |c| c[/KEY_.*#{query}.*/] }
88
+ .map { |c| c.to_s.gsub('KEY_', '') }
89
+ end
90
+
91
+ def find_code(keycode: nil)
92
+ query = keycode&.upcase&.gsub('KEY_', '')
93
+
94
+ Revdev.constants.find { |c| c == "KEY_#{query}".to_sym }
95
+ end
96
+
97
+ def keycode_const(keycode)
98
+ Object.const_get "LinuxInput::#{keycode}"
99
+ end
100
+
101
+ def clear_modifiers
102
+ modifiers = %w[ CAPSLOCK LEFTALT LEFTCTRL LEFTMETA
103
+ LEFTSHIFT RIGHTALT RIGHTCTRL RIGHTSHIFT ]
104
+ modifiers.each { |code| key_event(keycode: key_prefix(code), press: false) }
105
+ end
106
+
107
+ private
108
+
109
+ def find_device(name_pattern:)
110
+ Fusuma::Device.all.find { |d| d.name.match(/#{name_pattern}/) }
111
+ end
112
+
113
+ def split_param(param)
114
+ param.split('+').map { |code| key_prefix(code) }
115
+ end
116
+
117
+ def key_prefix(code)
118
+ "KEY_#{code.upcase}"
46
119
  end
47
120
 
48
- def available_codes
49
- @device.search_codes
121
+ def remove_prefix(keycode)
122
+ keycode.gsub('KEY_', '')
50
123
  end
51
124
  end
52
125
  end
@@ -3,7 +3,7 @@
3
3
  module Fusuma
4
4
  module Plugin
5
5
  module Sendkey
6
- VERSION = '0.1.1'
6
+ VERSION = '0.5.0'
7
7
  end
8
8
  end
9
9
  end
metadata CHANGED
@@ -1,43 +1,43 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: fusuma-plugin-sendkey
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.1
4
+ version: 0.5.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - iberianpig
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2020-03-03 00:00:00.000000000 Z
11
+ date: 2020-07-13 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
- name: evdev
14
+ name: fusuma
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
- - - ">="
17
+ - - "~>"
18
18
  - !ruby/object:Gem::Version
19
- version: '0'
19
+ version: '1.7'
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
- - - ">="
24
+ - - "~>"
25
25
  - !ruby/object:Gem::Version
26
- version: '0'
26
+ version: '1.7'
27
27
  - !ruby/object:Gem::Dependency
28
- name: fusuma
28
+ name: revdev
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
- - - "~>"
31
+ - - ">="
32
32
  - !ruby/object:Gem::Version
33
- version: 1.5.0
33
+ version: '0'
34
34
  type: :runtime
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
- - - "~>"
38
+ - - ">="
39
39
  - !ruby/object:Gem::Version
40
- version: 1.5.0
40
+ version: '0'
41
41
  - !ruby/object:Gem::Dependency
42
42
  name: bundler
43
43
  requirement: !ruby/object:Gem::Requirement
@@ -178,7 +178,7 @@ dependencies:
178
178
  - - ">="
179
179
  - !ruby/object:Gem::Version
180
180
  version: '0'
181
- description: Fusuma::Plugin::Sendkey emulate keyboard events with evemu-event
181
+ description: Fusuma::Plugin::Sendkey emulate keyboard events with evdev
182
182
  email:
183
183
  - yhkyky@gmail.com
184
184
  executables:
@@ -190,6 +190,7 @@ files:
190
190
  - ".rspec"
191
191
  - ".rubocop.yml"
192
192
  - ".travis.yml"
193
+ - CHANGELOG.md
193
194
  - CODE_OF_CONDUCT.md
194
195
  - Gemfile
195
196
  - LICENSE.txt
@@ -226,5 +227,5 @@ requirements: []
226
227
  rubygems_version: 3.0.3
227
228
  signing_key:
228
229
  specification_version: 4
229
- summary: Fusuma plugin that sending virtual keyboard events
230
+ summary: Fusuma plugin to send keyboard events
230
231
  test_files: []