fusuma 0.11.1 → 1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.github/FUNDING.yml +8 -0
- data/.gitignore +6 -0
- data/.reek.yml +93 -45
- data/.rubocop.yml +2 -0
- data/.rubocop_todo.yml +16 -75
- data/Gemfile +2 -0
- data/README.md +12 -5
- data/Rakefile +2 -1
- data/bin/console +1 -1
- data/exe/fusuma +1 -0
- data/fusuma.gemspec +9 -2
- data/lib/fusuma.rb +88 -31
- data/lib/fusuma/config.rb +65 -66
- data/lib/fusuma/config/index.rb +49 -0
- data/lib/fusuma/device.rb +58 -37
- data/lib/fusuma/multi_logger.rb +3 -0
- data/lib/fusuma/plugin/base.rb +56 -0
- data/lib/fusuma/plugin/buffers/buffer.rb +41 -0
- data/lib/fusuma/plugin/buffers/gesture_buffer.rb +70 -0
- data/lib/fusuma/plugin/detectors/detector.rb +41 -0
- data/lib/fusuma/plugin/detectors/pinch_detector.rb +141 -0
- data/lib/fusuma/plugin/detectors/rotate_detector.rb +135 -0
- data/lib/fusuma/plugin/detectors/swipe_detector.rb +145 -0
- data/lib/fusuma/plugin/events/event.rb +38 -0
- data/lib/fusuma/plugin/events/records/gesture_record.rb +31 -0
- data/lib/fusuma/plugin/events/records/index_record.rb +53 -0
- data/lib/fusuma/plugin/events/records/record.rb +20 -0
- data/lib/fusuma/plugin/events/records/text_record.rb +28 -0
- data/lib/fusuma/plugin/executors/command_executor.rb +39 -0
- data/lib/fusuma/plugin/executors/executor.rb +27 -0
- data/lib/fusuma/plugin/filters/filter.rb +40 -0
- data/lib/fusuma/plugin/filters/libinput_device_filter.rb +42 -0
- data/lib/fusuma/plugin/inputs/input.rb +28 -0
- data/lib/fusuma/plugin/inputs/libinput_command_input.rb +133 -0
- data/lib/fusuma/plugin/manager.rb +118 -0
- data/lib/fusuma/plugin/parsers/libinput_gesture_parser.rb +54 -0
- data/lib/fusuma/plugin/parsers/parser.rb +46 -0
- data/lib/fusuma/version.rb +3 -1
- metadata +74 -14
- data/lib/fusuma/command_executor.rb +0 -43
- data/lib/fusuma/event_stack.rb +0 -87
- data/lib/fusuma/gesture_event.rb +0 -50
- data/lib/fusuma/libinput_commands.rb +0 -98
- data/lib/fusuma/pinch.rb +0 -58
- data/lib/fusuma/swipe.rb +0 -59
data/lib/fusuma/gesture_event.rb
DELETED
@@ -1,50 +0,0 @@
|
|
1
|
-
module Fusuma
|
2
|
-
# pinch or swipe or rotate event
|
3
|
-
class GestureEvent
|
4
|
-
def initialize(time, event, finger, directions)
|
5
|
-
@time = time.to_f
|
6
|
-
@event = event
|
7
|
-
@finger = finger
|
8
|
-
@move_x = directions[:move][:x].to_f
|
9
|
-
@move_y = directions[:move][:y].to_f
|
10
|
-
@zoom = directions[:zoom].to_f
|
11
|
-
end
|
12
|
-
attr_reader :time, :event, :finger,
|
13
|
-
:move_x, :move_y, :zoom
|
14
|
-
|
15
|
-
class << self
|
16
|
-
def initialize_by(line, device_names)
|
17
|
-
return if device_names.none? do |device_name|
|
18
|
-
line =~ /^\s?#{device_name}/
|
19
|
-
end
|
20
|
-
return if line =~ /_BEGIN/
|
21
|
-
return unless line =~ /GESTURE_SWIPE|GESTURE_PINCH/
|
22
|
-
time, event, finger, directions = gesture_event_arguments(line)
|
23
|
-
MultiLogger.debug(time: time, event: event,
|
24
|
-
finger: finger, directions: directions)
|
25
|
-
new(time, event, finger, directions)
|
26
|
-
end
|
27
|
-
|
28
|
-
private
|
29
|
-
|
30
|
-
def gesture_event_arguments(libinput_line)
|
31
|
-
event, time, finger, other = parse_libinput(libinput_line)
|
32
|
-
move_x, move_y, zoom = parse_finger_directions(other)
|
33
|
-
directions = { move: { x: move_x, y: move_y }, zoom: zoom }
|
34
|
-
[time, event, finger, directions]
|
35
|
-
end
|
36
|
-
|
37
|
-
def parse_libinput(line)
|
38
|
-
_device, event, time, other = line.strip.split(nil, 4)
|
39
|
-
finger, other = other.split(nil, 2)
|
40
|
-
[event, time, finger, other]
|
41
|
-
end
|
42
|
-
|
43
|
-
def parse_finger_directions(line)
|
44
|
-
return [] unless line
|
45
|
-
move_x, move_y, _, _, _, zoom = line.tr('/|(|)', ' ').split
|
46
|
-
[move_x, move_y, zoom]
|
47
|
-
end
|
48
|
-
end
|
49
|
-
end
|
50
|
-
end
|
@@ -1,98 +0,0 @@
|
|
1
|
-
module Fusuma
|
2
|
-
# libinput commands wrapper
|
3
|
-
class LibinputCommands
|
4
|
-
def initialize(*options)
|
5
|
-
@options = options
|
6
|
-
end
|
7
|
-
|
8
|
-
# `libinput-list-devices` and `libinput-debug-events` are deprecated,
|
9
|
-
# use `libinput list-devices` and `libinput debug-events` from 1.8.
|
10
|
-
NEW_CLI_OPTION_VERSION = 1.8
|
11
|
-
|
12
|
-
# @return [Boolean]
|
13
|
-
def new_cli_option_available?
|
14
|
-
Gem::Version.new(version) >= Gem::Version.new(NEW_CLI_OPTION_VERSION)
|
15
|
-
end
|
16
|
-
|
17
|
-
# @return [String]
|
18
|
-
def version
|
19
|
-
# versiom_command prints "1.6.3\n"
|
20
|
-
@version ||= `#{version_command}`.strip
|
21
|
-
end
|
22
|
-
|
23
|
-
# @yield [line] gives a line in libinput list-devices output to the block
|
24
|
-
def list_devices
|
25
|
-
cmd = list_devices_command
|
26
|
-
MultiLogger.debug(debug_events: cmd)
|
27
|
-
Open3.popen3(cmd) do |_i, o, _e, _w|
|
28
|
-
o.each { |line| yield(line) }
|
29
|
-
end
|
30
|
-
end
|
31
|
-
|
32
|
-
# @yield [line] gives a line in libinput debug-events output to the block
|
33
|
-
def debug_events
|
34
|
-
prefix = 'stdbuf -oL --'
|
35
|
-
options = [*@options, device_option]
|
36
|
-
cmd = "#{prefix} #{debug_events_command} #{options.join(' ')}".strip
|
37
|
-
MultiLogger.debug(debug_events: cmd)
|
38
|
-
Open3.popen3(cmd) do |_i, o, _e, _w|
|
39
|
-
o.each { |line| yield(line) }
|
40
|
-
end
|
41
|
-
end
|
42
|
-
|
43
|
-
# @return [String] command
|
44
|
-
# @raise [SystemExit]
|
45
|
-
def version_command
|
46
|
-
if which('libinput')
|
47
|
-
'libinput --version'
|
48
|
-
elsif which('libinput-list-devices')
|
49
|
-
'libinput-list-devices --version'
|
50
|
-
else
|
51
|
-
MultiLogger.error 'install libinput-tools'
|
52
|
-
exit 1
|
53
|
-
end
|
54
|
-
end
|
55
|
-
|
56
|
-
def list_devices_command
|
57
|
-
if new_cli_option_available?
|
58
|
-
'libinput list-devices'
|
59
|
-
else
|
60
|
-
'libinput-list-devices'
|
61
|
-
end
|
62
|
-
end
|
63
|
-
|
64
|
-
def debug_events_command
|
65
|
-
if new_cli_option_available?
|
66
|
-
'libinput debug-events'
|
67
|
-
else
|
68
|
-
'libinput-debug-events'
|
69
|
-
end
|
70
|
-
end
|
71
|
-
|
72
|
-
private
|
73
|
-
|
74
|
-
# use device option only if libinput detect only 1 device
|
75
|
-
# @return [String]
|
76
|
-
def device_option
|
77
|
-
return unless Device.available.size == 1
|
78
|
-
"--device /dev/input/#{Device.available.first.id}"
|
79
|
-
end
|
80
|
-
|
81
|
-
# which in ruby: Checking if program exists in $PATH from ruby
|
82
|
-
# (https://stackoverflow.com/questions/2108727/which-in-ruby-checking-if-program-exists-in-path-from-ruby)
|
83
|
-
# Cross-platform way of finding an executable in the $PATH.
|
84
|
-
#
|
85
|
-
# which('ruby') #=> /usr/bin/ruby
|
86
|
-
# @return [String, nil]
|
87
|
-
def which(command)
|
88
|
-
exts = ENV['PATHEXT'] ? ENV['PATHEXT'].split(';') : ['']
|
89
|
-
ENV['PATH'].split(File::PATH_SEPARATOR).each do |path|
|
90
|
-
exts.each do |ext|
|
91
|
-
exe = File.join(path, "#{command}#{ext}")
|
92
|
-
return exe if File.executable?(exe) && !File.directory?(exe)
|
93
|
-
end
|
94
|
-
end
|
95
|
-
nil
|
96
|
-
end
|
97
|
-
end
|
98
|
-
end
|
data/lib/fusuma/pinch.rb
DELETED
@@ -1,58 +0,0 @@
|
|
1
|
-
module Fusuma
|
2
|
-
# vector data
|
3
|
-
class Pinch
|
4
|
-
TYPE = 'pinch'.freeze
|
5
|
-
|
6
|
-
BASE_THERESHOLD = 0.3
|
7
|
-
BASE_INTERVAL = 0.05
|
8
|
-
|
9
|
-
def initialize(diameter)
|
10
|
-
@diameter = diameter.to_f
|
11
|
-
end
|
12
|
-
|
13
|
-
attr_reader :diameter
|
14
|
-
|
15
|
-
def direction
|
16
|
-
return 'in' if diameter > 0
|
17
|
-
'out'
|
18
|
-
end
|
19
|
-
|
20
|
-
def enough?(trigger)
|
21
|
-
MultiLogger.debug(diameter: diameter)
|
22
|
-
enough_diameter?(trigger) && enough_interval?(trigger) &&
|
23
|
-
self.class.touch_last_time
|
24
|
-
end
|
25
|
-
|
26
|
-
private
|
27
|
-
|
28
|
-
def enough_diameter?(trigger)
|
29
|
-
diameter.abs > threshold(trigger)
|
30
|
-
end
|
31
|
-
|
32
|
-
def enough_interval?(trigger)
|
33
|
-
return true if first_time?
|
34
|
-
return true if (Time.now - self.class.last_time) > interval_time(trigger)
|
35
|
-
false
|
36
|
-
end
|
37
|
-
|
38
|
-
def first_time?
|
39
|
-
!self.class.last_time
|
40
|
-
end
|
41
|
-
|
42
|
-
def threshold(trigger)
|
43
|
-
@threshold ||= BASE_THERESHOLD * Config.threshold(trigger)
|
44
|
-
end
|
45
|
-
|
46
|
-
def interval_time(trigger)
|
47
|
-
@interval_time ||= BASE_INTERVAL * Config.interval(trigger)
|
48
|
-
end
|
49
|
-
|
50
|
-
class << self
|
51
|
-
attr_reader :last_time
|
52
|
-
|
53
|
-
def touch_last_time
|
54
|
-
@last_time = Time.now
|
55
|
-
end
|
56
|
-
end
|
57
|
-
end
|
58
|
-
end
|
data/lib/fusuma/swipe.rb
DELETED
@@ -1,59 +0,0 @@
|
|
1
|
-
module Fusuma
|
2
|
-
# vector data
|
3
|
-
class Swipe
|
4
|
-
TYPE = 'swipe'.freeze
|
5
|
-
|
6
|
-
BASE_THERESHOLD = 20
|
7
|
-
BASE_INTERVAL = 0.5
|
8
|
-
|
9
|
-
def initialize(move_x, move_y)
|
10
|
-
@x = move_x
|
11
|
-
@y = move_y
|
12
|
-
end
|
13
|
-
attr_reader :x, :y
|
14
|
-
|
15
|
-
def direction
|
16
|
-
return x > 0 ? 'right' : 'left' if x.abs > y.abs
|
17
|
-
y > 0 ? 'down' : 'up'
|
18
|
-
end
|
19
|
-
|
20
|
-
def enough?(trigger)
|
21
|
-
MultiLogger.debug(x: x, y: y)
|
22
|
-
enough_distance?(trigger) && enough_interval?(trigger) &&
|
23
|
-
self.class.touch_last_time
|
24
|
-
end
|
25
|
-
|
26
|
-
private
|
27
|
-
|
28
|
-
def enough_distance?(trigger)
|
29
|
-
threshold = threshold(trigger)
|
30
|
-
(x.abs > threshold) || (y.abs > threshold)
|
31
|
-
end
|
32
|
-
|
33
|
-
def enough_interval?(trigger)
|
34
|
-
return true if first_time?
|
35
|
-
return true if (Time.now - self.class.last_time) > interval_time(trigger)
|
36
|
-
false
|
37
|
-
end
|
38
|
-
|
39
|
-
def first_time?
|
40
|
-
!self.class.last_time
|
41
|
-
end
|
42
|
-
|
43
|
-
def threshold(trigger)
|
44
|
-
@threshold ||= BASE_THERESHOLD * Config.threshold(trigger)
|
45
|
-
end
|
46
|
-
|
47
|
-
def interval_time(trigger)
|
48
|
-
@interval_time ||= BASE_INTERVAL * Config.interval(trigger)
|
49
|
-
end
|
50
|
-
|
51
|
-
class << self
|
52
|
-
attr_reader :last_time
|
53
|
-
|
54
|
-
def touch_last_time
|
55
|
-
@last_time = Time.now
|
56
|
-
end
|
57
|
-
end
|
58
|
-
end
|
59
|
-
end
|