require_relative 'fusuma/version' require_relative 'fusuma/action_stack' require_relative 'fusuma/gesture_action' require 'logger' require 'open3' require 'yaml' # this is top level module module Fusuma class << self def run read_libinput end private def read_libinput Open3.popen3(libinput_command) do |_i, o, _e, _w| o.each do |line| gesture_action = GestureAction.initialize_by_libinput(line, device_name) next if gesture_action.nil? @action_stack ||= ActionStack.new @action_stack.push gesture_action gesture_info = @action_stack.gesture_info trigger_keyevent(gesture_info) unless gesture_info.nil? end end end def libinput_command @libinput_command ||= "stdbuf -oL -- libinput-debug-events --device \ /dev/input/#{device_name}" end def device_name return @device_name unless @device_name.nil? Open3.popen3('libinput-list-devices') do |_i, o, _e, _w| o.each do |line| extracted_input_device_from(line) next unless touch_is_available?(line) return @device_name end end end def extracted_input_device_from(line) return unless line =~ /^Kernel: / @device_name = line.match(/event[0-9]/).to_s end def touch_is_available?(line) return false unless line =~ /^Tap-to-click: / return false if line =~ %r{n/a} true end def trigger_keyevent(gesture_info) case gesture_info.action when 'swipe' swipe(gesture_info.finger, gesture_info.direction.move) when 'pinch' pinch(gesture_info.direction.pinch) end end def swipe(finger, direction) shortcut = event_map['swipe'][finger.to_i][direction]['shortcut'] `xdotool key #{shortcut}` end def pinch(zoom) shortcut = event_map['pinch'][zoom]['shortcut'] `xdotool key #{shortcut}` end def event_map @event_map ||= YAML.load_file(config_file) end def config_file filename = 'fusuma/config.yml' original_path = File.expand_path "~/.config/#{filename}" default_path = File.expand_path "../#{filename}", __FILE__ File.exist?(original_path) ? original_path : default_path end end end