class Rkremap
Constants
- CODE_KEY
- EVENT_TYPE_VALUE
- EV_KEY
- EV_SYN
- SYN_REPORT
- VERSION
Attributes
auto_detect[RW]
grab[RW]
modifiers[RW]
x11[RW]
Public Class Methods
new(devices=nil)
click to toggle source
@param devices [Array<String>, String]
# File lib/rkremap.rb, line 23 def initialize(devices=nil) if devices devices = Array(devices) @inputs = devices.map{|d| Evdev.new(d)} else @auto_detect = true @inputs = Evdev.detect.select(&:keyboard?) end raise 'Unable to detect keyboard device' if @inputs.empty? @uinput = Uinput.new @grab = false @x11 = false @modifiers = [ KEY_LEFTCTRL, KEY_RIGHTCTRL, KEY_LEFTSHIFT, KEY_RIGHTSHIFT, KEY_LEFTALT, KEY_RIGHTALT, KEY_LEFTMETA, KEY_RIGHTMETA, ] @events = [] @mutex = Mutex.new end
Public Instance Methods
detect_device_loop()
click to toggle source
# File lib/rkremap.rb, line 73 def detect_device_loop Thread.new do while true sleep 3 new_devs = Evdev.detect.select(&:keyboard?) unless new_devs.empty? new_devs.each(&:grab) if @grab @inputs += new_devs end end end end
event(code: nil, type: nil, event: nil)
click to toggle source
@param code [Integer] @param type [Symbol] :press / :release / :repeat @param ev [Rkmap::Event]
# File lib/rkremap.rb, line 106 def event(code: nil, type: nil, event: nil) value = EVENT_TYPE_VALUE[type] or raise "invalid type: #{type.inspect}" proc_event(code, value, event) end
key(code, mod={})
click to toggle source
@param code [Integer] @param mod [Hash] {MOD_KEY => true, …}
# File lib/rkremap.rb, line 113 def key(code, mod={}) mod_diff(mod).each do |mcode, state| write_event(mcode, state ? 1 : 0) end write_event(code, 1) write_event(code, 0) mod_diff(mod).each do |mcode, _| write_event(mcode, @mod_state[mcode] ? 1 : 0) end end
match(code: nil, type: nil, &block)
click to toggle source
@param code [Integer] @param type [Symbol] :press / :release / :repeat
# File lib/rkremap.rb, line 47 def match(code: nil, type: nil, &block) @events.push [{code: code, type: type}, block] end
read_event()
click to toggle source
# File lib/rkremap.rb, line 86 def read_event while true begin input = Evdev.select(@inputs, 3) next unless input return input.read_event rescue Errno::ENODEV input.close rescue nil @inputs.delete input end end end
start(&block)
click to toggle source
# File lib/rkremap.rb, line 51 def start(&block) detect_device_loop if @auto_detect @mod_state = @modifiers.map.to_h{|m| [m, false]} @winattr = WinAttr.new if @x11 @inputs.each(&:grab) if @grab while true @keys = [] time, type, code, value = read_event next if type != EV_KEY event = Event.new(time, code, value, @winattr) @events.each do |cond, b| synchronize{ b.call event } if event.match?(**cond) break if event.skipped end next if event.skipped synchronize{ proc_event(code, value, event) } @keys.each do |c, mod, app| synchronize{ block.call(c, mod, app) } if block end end end
synchronize(&block)
click to toggle source
# File lib/rkremap.rb, line 99 def synchronize(&block) @mutex.synchronize(&block) end
Private Instance Methods
mod_diff(mod)
click to toggle source
# File lib/rkremap.rb, line 135 def mod_diff(mod) mod.select{|k, v| @mod_state[k] != v} end
proc_event(code, value, event)
click to toggle source
# File lib/rkremap.rb, line 126 def proc_event(code, value, event) if @mod_state.include?(code) @mod_state[code] = value != 0 write_event(code, value) elsif value != 0 @keys.push [code, @mod_state.dup, App.new(event&.win, @winattr)] end end
write_event(code, value)
click to toggle source
@param code [Integer] @param value [Integer] 0:release / 1:press / 2:repeat
# File lib/rkremap.rb, line 141 def write_event(code, value) @uinput.write_event(EV_KEY, code, value) @uinput.write_event(EV_SYN, SYN_REPORT, 0) end