class Fusuma::Plugin::Sendkey::Keyboard

Emulate Keyboard

Constants

MODIFIER_KEY_CODES

Attributes

device[R]

Public Class Methods

find_device(name_pattern:) click to toggle source
# File lib/fusuma/plugin/sendkey/keyboard.rb, line 25
def self.find_device(name_pattern:)
  Fusuma::Device.all.find { |d| d.name.match(/#{name_pattern}/) }
end
new(name_pattern: nil) click to toggle source
# File lib/fusuma/plugin/sendkey/keyboard.rb, line 29
def initialize(name_pattern: nil)
  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

Public Instance Methods

clear_modifiers(keycodes) click to toggle source

@param [Array<String>] keycodes to be released

# File lib/fusuma/plugin/sendkey/keyboard.rb, line 119
def clear_modifiers(keycodes)
  keycodes.each { |code| key_event(keycode: code, press: false) }
end
find_code(keycode: nil) click to toggle source
# File lib/fusuma/plugin/sendkey/keyboard.rb, line 108
def find_code(keycode: nil)
  query = keycode&.upcase&.gsub('KEY_', '')

  Revdev.constants.find { |c| c == "KEY_#{query}".to_sym }
end
key_event(keycode:, press: true) click to toggle source
# File lib/fusuma/plugin/sendkey/keyboard.rb, line 64
def key_event(keycode:, press: true)
  event = Revdev::InputEvent.new(
    nil,
    Revdev.const_get(:EV_KEY),
    Revdev.const_get(keycode),
    press ? 1 : 0
  )
  @device.write_event(event)
end
key_sync(press: true) click to toggle source
# File lib/fusuma/plugin/sendkey/keyboard.rb, line 74
def key_sync(press: true)
  event = Revdev::InputEvent.new(
    nil,
    Revdev.const_get(:EV_SYN),
    Revdev.const_get(:SYN_REPORT),
    press ? 1 : 0
  )
  @device.write_event(event)
end
keycode_const(keycode) click to toggle source
# File lib/fusuma/plugin/sendkey/keyboard.rb, line 114
def keycode_const(keycode)
  Object.const_get "LinuxInput::#{keycode}"
end
search_candidates(keycode:) click to toggle source
# File lib/fusuma/plugin/sendkey/keyboard.rb, line 93
def search_candidates(keycode:)
  query = keycode&.upcase&.gsub('KEY_', '')

  candidates = search_codes(query: query)

  warn "Did you mean? #{candidates.join(' / ')}" unless candidates.empty?
  warn "sendkey: #{remove_prefix(keycode)} is unsupported."
end
search_codes(query: nil) click to toggle source
# File lib/fusuma/plugin/sendkey/keyboard.rb, line 102
def search_codes(query: nil)
  Revdev.constants
        .select { |c| c[/KEY_.*#{query}.*/] }
        .map { |c| c.to_s.gsub('KEY_', '') }
end
support?(keycode) click to toggle source
# File lib/fusuma/plugin/sendkey/keyboard.rb, line 84
def support?(keycode)
  @supported_code ||= {}
  @supported_code[keycode] ||= if find_code(keycode: keycode)
                                 true
                               else
                                 search_candidates(keycode: keycode)
                               end
end
type(param:) click to toggle source

@param param [String] @param keep [String]

# File lib/fusuma/plugin/sendkey/keyboard.rb, line 45
def type(param:)
  return unless param.is_a?(String)

  param_keycodes = split_param(param)
  clear_modifiers(MODIFIER_KEY_CODES - param_keycodes)
  param_keycodes.each { |keycode| key_event(keycode: keycode, press: true) }
  key_sync(press: true)
  param_keycodes.reverse.each { |keycode| key_event(keycode: keycode, press: false) }
  key_sync(press: false)
end
valid?(param:) click to toggle source

@param param [String]

# File lib/fusuma/plugin/sendkey/keyboard.rb, line 57
def valid?(param:)
  return unless param.is_a?(String)

  keycodes = split_param(param)
  keycodes.all? { |keycode| support?(keycode) }
end

Private Instance Methods

key_prefix(code) click to toggle source
# File lib/fusuma/plugin/sendkey/keyboard.rb, line 129
def key_prefix(code)
  "KEY_#{code.upcase}"
end
remove_prefix(keycode) click to toggle source
# File lib/fusuma/plugin/sendkey/keyboard.rb, line 133
def remove_prefix(keycode)
  keycode.gsub('KEY_', '')
end
split_param(param) click to toggle source
# File lib/fusuma/plugin/sendkey/keyboard.rb, line 125
def split_param(param)
  param.split('+').map { |code| key_prefix(code) }
end