# frozen_string_literal: true require_relative './input.rb' require 'open3' module Fusuma module Plugin module Inputs # libinput commands wrapper class LibinputCommandInput < Input def config_param_types { 'device': [String], 'enable-dwt': [TrueClass, FalseClass], 'enable-tap': [TrueClass, FalseClass], 'show-keycodes': [TrueClass, FalseClass], 'verbose': [TrueClass, FalseClass] } end def run debug_events do |line| yield event(record: line) end end # `libinput-list-devices` and `libinput-debug-events` are deprecated, # use `libinput list-devices` and `libinput debug-events` from 1.8. NEW_CLI_OPTION_VERSION = 1.8 # @return [Boolean] def new_cli_option_available? Gem::Version.new(version) >= Gem::Version.new(NEW_CLI_OPTION_VERSION) end # @return [String] def version # versiom_command prints "1.6.3\n" @version ||= `#{version_command}`.strip end # @yieldparam [String] gives a line in libinput list-devices output to the block def list_devices cmd = list_devices_command MultiLogger.debug(list_devices: cmd) Open3.popen3(cmd) do |_i, o, _e, _w| o.each { |line| yield(line) } end end # @yieldparam [String] gives a line in libinput debug-events output to the block def debug_events prefix = 'stdbuf -oL --' options = [*libinput_options] cmd = "#{prefix} #{debug_events_command} #{options.join(' ')}".strip MultiLogger.debug(debug_events: cmd) Open3.popen3(cmd) do |_i, o, _e, _w| o.each do |line| yield(line.chomp) end end end # @return [String] command # @raise [SystemExit] def version_command if which('libinput') 'libinput --version' elsif which('libinput-list-devices') 'libinput-list-devices --version' else MultiLogger.error 'install libinput-tools' exit 1 end end def list_devices_command if new_cli_option_available? 'libinput list-devices' else 'libinput-list-devices' end end def debug_events_command if new_cli_option_available? 'libinput debug-events' else 'libinput-debug-events' end end def libinput_options device = ("--device='#{config_params(:device)}'" if config_params(:device)) enable_tap = '--enable-tap' if config_params(:'enable-tap') enable_dwt = '--enable-dwt' if config_params(:'enable-dwt') show_keycodes = '--show-keycodes' if config_params(:'show-keycodes') verbose = '--verbose' if config_params(:verbose) [ device, enable_dwt, enable_tap, show_keycodes, verbose ].compact end private # which in ruby: Checking if program exists in $PATH from ruby # (https://stackoverflow.com/questions/2108727/which-in-ruby-checking-if-program-exists-in-path-from-ruby) # Cross-platform way of finding an executable in the $PATH. # # which('ruby') #=> /usr/bin/ruby # @return [String, nil] def which(command) exts = ENV['PATHEXT'] ? ENV['PATHEXT'].split(';') : [''] ENV['PATH'].split(File::PATH_SEPARATOR).each do |path| exts.each do |ext| exe = File.join(path, "#{command}#{ext}") return exe if File.executable?(exe) && !File.directory?(exe) end end nil end end end end end