Skip to content

Commit

Permalink
fix for libinput version 1.8 or later
Browse files Browse the repository at this point in the history
  • Loading branch information
iberianpig committed Jun 11, 2018
1 parent 867514c commit c399e7a
Show file tree
Hide file tree
Showing 6 changed files with 252 additions and 37 deletions.
36 changes: 11 additions & 25 deletions lib/fusuma.rb
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
require_relative 'fusuma/multi_logger'
require_relative 'fusuma/config.rb'
require_relative 'fusuma/device.rb'
require_relative 'fusuma/libinput_commands.rb'
require 'logger'
require 'open3'
require 'yaml'
Expand All @@ -20,7 +21,7 @@ def run(option = {})
set_trap
read_options(option)
instance = new
instance.read_libinput
instance.run
end

private
Expand All @@ -33,6 +34,7 @@ def set_trap
def print_version
puts '---------------------------------------------'
puts "Fusuma: #{Fusuma::VERSION}"
puts "libinput: #{LibinputCommands.new.version}"
puts "OS: #{`uname -rsv`}"
puts "Distribution: #{`cat /etc/issue`}"
puts "Desktop session: #{`echo $DESKTOP_SESSION`}"
Expand All @@ -53,31 +55,15 @@ def read_options(option)
end
end

def read_libinput
Open3.popen3(libinput_command) do |_i, o, _e, _w|
o.each do |line|
gesture_action = GestureAction.initialize_by(line, Device.names)
next if gesture_action.nil?
@action_stack ||= ActionStack.new
@action_stack << gesture_action
event_trigger = @action_stack.generate_event_trigger
event_trigger.send_command unless event_trigger.nil?
end
def run
LibinputCommands.new.debug_events do |line|
gesture_action = GestureAction.initialize_by(line, Device.names)
next if gesture_action.nil?
@action_stack ||= ActionStack.new
@action_stack << gesture_action
event_trigger = @action_stack.generate_event_trigger
event_trigger.send_command unless event_trigger.nil?
end
end

private

def libinput_command
return @libinput_command if @libinput_command
prefix = 'stdbuf -oL --'
command = 'libinput-debug-events'
device_option = if Device.names.size == 1
"--device /dev/input/#{Device.names.first}"
end
@libinput_command = [prefix, command, device_option].join(' ')
MultiLogger.debug(libinput_command: @libinput_command)
@libinput_command
end
end
end
12 changes: 4 additions & 8 deletions lib/fusuma/device.rb
Original file line number Diff line number Diff line change
Expand Up @@ -19,17 +19,13 @@ def names

def fetch_device_names
current_device = nil
list_devices_logs.map do |line|
devices = []
LibinputCommands.new.list_devices do |line|
current_device = extracted_input_device_from(line) || current_device
next unless natural_scroll_is_available?(line)
current_device
end.compact
end

def list_devices_logs
Open3.popen3('libinput-list-devices') do |_i, o, _e, _w|
return o.to_a
devices << current_device
end
devices.compact
end

def extracted_input_device_from(line)
Expand Down
95 changes: 95 additions & 0 deletions lib/fusuma/libinput_commands.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
module Fusuma
# libinput commands wrapper
class LibinputCommands
def initialize(*options)
@options = options
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

# @yield [line] gives a line in libinput list-devices output to the block
def list_devices
cmd = list_devices_command
MultiLogger.debug(debug_events: cmd)
Open3.popen3(cmd) do |_i, o, _e, _w|
o.each { |line| yield(line) }
end
end

# @yield [line] gives a line in libinput debug-events output to the block
def debug_events
prefix = 'stdbuf -oL --'
options = [*@options, device_option]
cmd = "#{prefix} #{debug_events_command} #{options.join(' ')}".strip
MultiLogger.debug(debug_events: cmd)
Open3.popen3(cmd) do |_i, o, _e, _w|
o.each { |line| yield(line) }
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

private

def device_option
"--device /dev/input/#{Device.names.first}" if Device.names.size == 1
end

# 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
2 changes: 1 addition & 1 deletion lib/fusuma/version.rb
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
module Fusuma
VERSION = '0.7.1'.freeze
VERSION = '0.7.2'.freeze
end
6 changes: 3 additions & 3 deletions spec/fusuma_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -10,15 +10,15 @@ module Fusuma

context 'when without option' do
it 'should not enable debug mode' do
allow_any_instance_of(Fusuma::Runner).to receive(:read_libinput)
allow_any_instance_of(Fusuma::Runner).to receive(:run)
Fusuma::Runner.run
expect(Fusuma::MultiLogger.instance).not_to be_debug_mode
end
end

context 'when run with argument "-v"' do
it 'should enable debug mode' do
allow_any_instance_of(Fusuma::Runner).to receive(:read_libinput)
allow_any_instance_of(Fusuma::Runner).to receive(:run)
Fusuma::MultiLogger.send(:new)
Fusuma::Runner.run(verbose: true)
expect(Fusuma::MultiLogger.instance).to be_debug_mode
Expand All @@ -27,7 +27,7 @@ module Fusuma

context 'when run with argument "-c path/to/config.yml"' do
it 'should assign custom_path' do
allow_any_instance_of(Fusuma::Runner).to receive(:read_libinput)
allow_any_instance_of(Fusuma::Runner).to receive(:run)
config = Fusuma::Config.instance
expect { Fusuma::Runner.run(config_path: 'path/to/config.yml') }
.to change { config.custom_path }.from(nil).to('path/to/config.yml')
Expand Down
138 changes: 138 additions & 0 deletions spec/lib/libinput_commands_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,138 @@
require 'spec_helper'
module Fusuma
describe LibinputCommands do
let(:libinput_commands) { described_class.new }
describe '#version' do
subject { libinput_commands.version }

context 'when libinput-list-device is available' do
before do
allow(libinput_commands).to receive('which')
.with('libinput') { false }
allow(libinput_commands).to receive('which')
.with('libinput-list-devices') { true }
allow_any_instance_of(Kernel).to receive(:`)
.with('libinput-list-devices --version') { "1.6.3\n" }
end

it { is_expected.to eq '1.6.3' }
it { expect(libinput_commands.new_cli_option_available?).to be false }
end

context 'when libinput is available' do
before do
allow(libinput_commands).to receive('which')
.with('libinput') { true }
allow(libinput_commands).to receive('which')
.with('libinput-list-devices') { false }
allow_any_instance_of(Kernel).to receive(:`)
.with('libinput --version') { "1.8\n" }
end

it { is_expected.to eq '1.8' }
it { expect(libinput_commands.new_cli_option_available?).to be true }
end

context 'when libinput command is not found' do
before do
allow(libinput_commands).to receive('which')
.with('libinput') { false }
allow(libinput_commands).to receive('which')
.with('libinput-list-devices') { false }
end

it 'shold print error and exit 1' do
expect(MultiLogger).to receive(:error)
expect { subject }.to raise_error(SystemExit)
end
end
end

describe '#new_cli_option_available?' do
subject { libinput_commands.new_cli_option_available? }
context 'with NEW_CLI_OPTION_VERSION' do
before do
allow(libinput_commands).to receive(:version)
.and_return(LibinputCommands::NEW_CLI_OPTION_VERSION)
end
it { is_expected.to eq true }
end
context 'without NEW_CLI_OPTION_VERSION' do
before do
allow(libinput_commands).to receive(:version)
.and_return(LibinputCommands::NEW_CLI_OPTION_VERSION - 0.1)
end
it { is_expected.to eq false }
end
end

describe 'list_devices' do
subject { libinput_commands.list_devices }
after { subject }

context 'with new cli version' do
before do
allow(libinput_commands).to receive(:new_cli_option_available?)
.and_return(true)
end

it 'call `libinput list-devices`' do
command = 'libinput list-devices'
expect(Open3).to receive(:popen3)
.with("#{command}")
end
end
context 'with old cli version' do
before do
allow(libinput_commands).to receive(:new_cli_option_available?)
.and_return(false)
end

it 'call `libinput-list-devices`' do
command = 'libinput-list-devices'
expect(Open3).to receive(:popen3)
.with("#{command}")
end
end
end

describe 'debug_events' do
subject { libinput_commands.debug_events }

before do
allow(libinput_commands).to receive(:device_option)
.and_return('--device stub_device')
end

after { subject }

context 'with new cli version' do
before do
allow(libinput_commands).to receive(:new_cli_option_available?)
.and_return(true)
end

it 'call `libinput debug-events`' do
command = 'libinput debug-events'
expect(Open3).to receive(:popen3)
.with("stdbuf -oL -- #{command} --device stub_device")
.and_return 'stub message'
end
end

context 'with old cli version' do
before do
allow(libinput_commands).to receive(:new_cli_option_available?)
.and_return(false)
end

it 'call `libinput-debug-events`' do
command = 'libinput-debug-events'
expect(Open3).to receive(:popen3)
.with("stdbuf -oL -- #{command} --device stub_device")
.and_return 'stub message'
end
end
end
end
end

0 comments on commit c399e7a

Please sign in to comment.