lib/fusuma/plugin/sendkey/keyboard.rb in fusuma-plugin-sendkey-0.6.4 vs lib/fusuma/plugin/sendkey/keyboard.rb in fusuma-plugin-sendkey-0.7.1
- old
+ new
@@ -1,11 +1,11 @@
# frozen_string_literal: true
-require 'revdev'
-require 'fusuma/device'
+require "revdev"
+require "fusuma/device"
-require_relative './device'
+require_relative "./device"
module Fusuma
module Plugin
module Sendkey
# Emulate Keyboard
@@ -27,118 +27,124 @@
def self.find_device(name_pattern:)
Fusuma::Device.all.find { |d| d.name.match(/#{name_pattern}/) }
end
def initialize(name_pattern: nil)
- name_pattern ||= 'keyboard|Keyboard|KEYBOARD'
+ name_pattern ||= "keyboard|Keyboard|KEYBOARD"
device = Keyboard.find_device(name_pattern: name_pattern)
if device.nil?
warn "sendkey: Keyboard: /#{name_pattern}/ is not found"
exit(1)
end
@device = Device.new(path: "/dev/input/#{device.id}")
end
- attr_reader :device
-
# @param param [String]
# @param keep [String]
- def type(param:)
+ def type(param:, keep: "")
return unless param.is_a?(String)
- keycodes = split_param(param)
- clear_modifiers(MODIFIER_KEY_CODES - keycodes)
- keycodes.each { |keycode| key_event(keycode: keycode, press: true) && wait }
- key_sync(press: true)
- keycodes.reverse.each { |keycode| key_event(keycode: keycode, press: false) && wait }
- key_sync(press: false)
+ param_keycodes = param_to_keycodes(param)
+ keep_keycodes = param_to_keycodes(keep)
+
+ type_keycodes = param_keycodes - keep_keycodes
+ # release other modifier keys before sending key
+ clear_modifiers(MODIFIER_KEY_CODES - param_keycodes)
+ type_keycodes.each { |keycode| keydown(keycode) && key_sync }
+ type_keycodes.reverse_each { |keycode| keyup(keycode) && key_sync }
end
+ def keydown(keycode)
+ send_event(code: keycode, press: true)
+ end
+
+ def keyup(keycode)
+ send_event(code: keycode, press: false)
+ end
+
# @param param [String]
def valid?(param:)
return unless param.is_a?(String)
- keycodes = split_param(param)
+ keycodes = param_to_keycodes(param)
keycodes.all? { |keycode| support?(keycode) }
end
- def key_event(keycode:, press: true)
+ def send_event(code:, press: true)
event = Revdev::InputEvent.new(
nil,
Revdev.const_get(:EV_KEY),
- Revdev.const_get(keycode),
+ Revdev.const_get(code),
press ? 1 : 0
)
@device.write_event(event)
end
- def key_sync(press: true)
+ def key_sync
event = Revdev::InputEvent.new(
nil,
Revdev.const_get(:EV_SYN),
Revdev.const_get(:SYN_REPORT),
- press ? 1 : 0
+ 0
)
@device.write_event(event)
+ sleep(INTERVAL)
end
def support?(keycode)
@supported_code ||= {}
- @supported_code[keycode] ||= if find_code(keycode: keycode)
- true
- else
- search_candidates(keycode: keycode)
- end
+ @supported_code[keycode] ||= find_code(keycode: keycode)
end
- def search_candidates(keycode:)
- query = keycode&.upcase&.gsub('KEY_', '')
+ def warn_undefined_codes(keycode:)
+ query = keycode&.upcase&.gsub("KEY_", "")
candidates = search_codes(query: query)
- warn "Did you mean? #{candidates.join(' / ')}" unless candidates.empty?
+ warn "Did you mean? #{candidates.join(" / ")}" unless candidates.empty?
warn "sendkey: #{remove_prefix(keycode)} is unsupported."
end
def search_codes(query: nil)
Revdev.constants
- .select { |c| c[/KEY_.*#{query}.*/] }
- .map { |c| c.to_s.gsub('KEY_', '') }
+ .select { |c| c[/KEY_.*#{query}.*/] }
+ .map { |c| c.to_s.gsub("KEY_", "") }
end
def find_code(keycode: nil)
- query = keycode&.upcase&.gsub('KEY_', '')
+ query = keycode&.upcase&.gsub("KEY_", "")
- Revdev.constants.find { |c| c == "KEY_#{query}".to_sym }
+ result = Revdev.constants.find { |c| c == "KEY_#{query}".to_sym }
+
+ warn_undefined_codes(keycode: keycode) unless result
+ result
end
def keycode_const(keycode)
Object.const_get "LinuxInput::#{keycode}"
end
# @param [Array<String>] keycodes to be released
def clear_modifiers(keycodes)
- keycodes.each { |code| key_event(keycode: code, press: false) }
+ keycodes.each { |code| send_event(code: code, press: false) }
end
- private
-
- def split_param(param)
- param.split('+').map { |code| key_prefix(code) }
+ # @param [String]
+ # @return [Array<String>]
+ def param_to_keycodes(param)
+ param.split("+").map { |keyname| add_key_prefix(keyname) }
end
- def key_prefix(code)
+ private
+
+ def add_key_prefix(code)
"KEY_#{code.upcase}"
end
def remove_prefix(keycode)
- keycode.gsub('KEY_', '')
- end
-
- def wait
- sleep(INTERVAL)
+ keycode.gsub("KEY_", "")
end
end
end
end
end