fusuma-plugin-sendkey 0.2.0 → 0.5.1

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: 20acb25008be7032e506513fd56003563ad0a03f1b619ecd8971b6cc850ccec9
4
- data.tar.gz: 06fc628741861bc7583d7d78c129114ba758e2947ea293d87db8f30f736752c0
3
+ metadata.gz: 5594a966bf8ab22cd79d90873cf558ecf313b6d3d4ae167a4d060cee2bd76ac4
4
+ data.tar.gz: c14f1fa0b6ec8237ce5cc603d8996a8d53a77e0122382c5c4d9b9ff8e5ba1b5b
5
5
  SHA512:
6
- metadata.gz: 9dafb894307348bb7530fbc396576c82d092e8e6b1761fdd7690766e0722aaa2bae106a8e9ebf8d29c9d206854f20586e4ad402574751531fe1f8bd2f7938501
7
- data.tar.gz: a953190bc8e09ad23ae43c1b318c53b4ffbaafac71066410da779ecf32c6933c04230f4848dd9028fae5ea354957af5818be74f79b2fc95d05df8bd0853ae8a3
6
+ metadata.gz: fc0d0de02efb73f7a2d6da35672d4087971af78a2b5711be6bc05dad1e7efa0a04ccca59eb53d41538222478306413f0897eade0d6725f402f9300803ca01add
7
+ data.tar.gz: 571f948d4ab8ea8cea6b134c013ac907d19f91f57eda9ee94bdadc2d4fbff3b44123beef3690cdac6851095aaecbc898cb3c20283458bb4ccfeec571ea9cba92
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 is wayland compatible and alternative to 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,8 +11,9 @@ 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 ruby-ffi
16
+ $ sudo apt-get install libevdev-dev ruby-dev
16
17
  ```
17
18
 
18
19
  ### Install fusuma-plugin-sendkey
@@ -22,22 +23,33 @@ $ 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 Fusuma::Plugin::Sendkey::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
- Fusuma::Plugin::Sendkey::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,117 @@ 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: nil)
14
+ name_pattern ||= 'keyboard|Keyboard|KEYBOARD'
15
+ device = find_device(name_pattern: name_pattern)
16
+
17
+ if device.nil?
18
+ warn "sendkey: Keyboard: /#{name_pattern}/ is not found"
19
+ exit(1)
20
+ end
21
+
22
+ @device = Device.new(path: "/dev/input/#{device.id}")
12
23
  end
13
24
 
25
+ attr_reader :device
26
+
14
27
  # @param param [String]
15
- def type_command(param:)
28
+ def type(param:)
16
29
  return unless param.is_a?(String)
17
30
 
18
- codes = param.split('+')
19
- press_commands = codes.map { |code| press_command(code) }
20
- release_commands = codes.reverse.map { |code| release_command(code) }
31
+ keycodes = split_param(param)
21
32
 
22
- (press_commands | release_commands).join(' && ')
33
+ clear_modifiers
34
+ keycodes.each { |keycode| key_event(keycode: keycode, press: true) }
35
+ key_sync(press: true)
36
+ keycodes.reverse.map { |keycode| key_event(keycode: keycode, press: false) }
37
+ key_sync(press: false)
23
38
  end
24
39
 
25
- def press_command(code)
26
- return unless support?(code)
40
+ # @param param [String]
41
+ def valid?(param:)
42
+ return unless param.is_a?(String)
27
43
 
28
- @device.emulate(code: code, press: true)
44
+ keycodes = split_param(param)
45
+ keycodes.all? { |keycode| support?(keycode) }
29
46
  end
30
47
 
31
- def release_command(code)
32
- return unless support?(code)
48
+ def key_event(keycode:, press: true)
49
+ event = Revdev::InputEvent.new(
50
+ nil,
51
+ Revdev.const_get(:EV_KEY),
52
+ Revdev.const_get(keycode),
53
+ press ? 1 : 0
54
+ )
55
+ @device.write_event(event)
56
+ end
33
57
 
34
- @device.emulate(code: code, press: false)
58
+ def key_sync(press: true)
59
+ event = Revdev::InputEvent.new(
60
+ nil,
61
+ Revdev.const_get(:EV_SYN),
62
+ Revdev.const_get(:SYN_REPORT),
63
+ press ? 1 : 0
64
+ )
65
+ @device.write_event(event)
35
66
  end
36
67
 
37
- def support?(code)
68
+ def support?(keycode)
38
69
  @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
70
+ @supported_code[keycode] ||= if find_code(keycode: keycode)
71
+ true
72
+ else
73
+ search_candidates(keycode: keycode)
74
+ end
75
+ end
76
+
77
+ def search_candidates(keycode:)
78
+ query = keycode&.upcase&.gsub('KEY_', '')
79
+
80
+ candidates = search_codes(query: query)
81
+
82
+ warn "Did you mean? #{candidates.join(' / ')}" unless candidates.empty?
83
+ warn "sendkey: #{remove_prefix(keycode)} is unsupported."
84
+ end
85
+
86
+ def search_codes(query: nil)
87
+ Revdev.constants
88
+ .select { |c| c[/KEY_.*#{query}.*/] }
89
+ .map { |c| c.to_s.gsub('KEY_', '') }
90
+ end
91
+
92
+ def find_code(keycode: nil)
93
+ query = keycode&.upcase&.gsub('KEY_', '')
94
+
95
+ Revdev.constants.find { |c| c == "KEY_#{query}".to_sym }
96
+ end
97
+
98
+ def keycode_const(keycode)
99
+ Object.const_get "LinuxInput::#{keycode}"
100
+ end
101
+
102
+ def clear_modifiers
103
+ modifiers = %w[ CAPSLOCK LEFTALT LEFTCTRL LEFTMETA
104
+ LEFTSHIFT RIGHTALT RIGHTCTRL RIGHTSHIFT ]
105
+ modifiers.each { |code| key_event(keycode: key_prefix(code), press: false) }
106
+ end
107
+
108
+ private
109
+
110
+ def find_device(name_pattern:)
111
+ Fusuma::Device.all.find { |d| d.name.match(/#{name_pattern}/) }
112
+ end
113
+
114
+ def split_param(param)
115
+ param.split('+').map { |code| key_prefix(code) }
116
+ end
117
+
118
+ def key_prefix(code)
119
+ "KEY_#{code.upcase}"
46
120
  end
47
121
 
48
- def available_codes
49
- @device.search_codes
122
+ def remove_prefix(keycode)
123
+ keycode.gsub('KEY_', '')
50
124
  end
51
125
  end
52
126
  end
@@ -3,7 +3,7 @@
3
3
  module Fusuma
4
4
  module Plugin
5
5
  module Sendkey
6
- VERSION = '0.2.0'
6
+ VERSION = '0.5.1'
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.2.0
4
+ version: 0.5.1
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-04 00:00:00.000000000 Z
11
+ date: 2020-07-14 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
@@ -223,8 +224,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
223
224
  - !ruby/object:Gem::Version
224
225
  version: '0'
225
226
  requirements: []
226
- rubygems_version: 3.0.3
227
+ rubygems_version: 3.0.6
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: []