fusuma 2.0.0.pre → 2.0.0.pre2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.rubocop.yml +8 -5
- data/.rubocop_todo.yml +34 -19
- data/.solargraph.yml +16 -0
- data/.travis.yml +1 -3
- data/CHANGELOG.md +1 -1
- data/Gemfile +6 -1
- data/README.md +43 -5
- data/fusuma.gemspec +3 -2
- data/lib/fusuma.rb +87 -33
- data/lib/fusuma/config.rb +33 -40
- data/lib/fusuma/config/index.rb +34 -8
- data/lib/fusuma/config/searcher.rb +78 -4
- data/lib/fusuma/custom_process.rb +13 -0
- data/lib/fusuma/device.rb +19 -6
- data/lib/fusuma/environment.rb +3 -3
- data/lib/fusuma/hash_support.rb +40 -0
- data/lib/fusuma/libinput_command.rb +8 -8
- data/lib/fusuma/multi_logger.rb +2 -6
- data/lib/fusuma/plugin/base.rb +18 -15
- data/lib/fusuma/plugin/buffers/buffer.rb +3 -2
- data/lib/fusuma/plugin/buffers/gesture_buffer.rb +34 -25
- data/lib/fusuma/plugin/buffers/timer_buffer.rb +3 -3
- data/lib/fusuma/plugin/detectors/detector.rb +26 -5
- data/lib/fusuma/plugin/detectors/pinch_detector.rb +109 -58
- data/lib/fusuma/plugin/detectors/rotate_detector.rb +91 -50
- data/lib/fusuma/plugin/detectors/swipe_detector.rb +93 -56
- data/lib/fusuma/plugin/events/event.rb +5 -4
- data/lib/fusuma/plugin/events/records/context_record.rb +27 -0
- data/lib/fusuma/plugin/events/records/gesture_record.rb +9 -6
- data/lib/fusuma/plugin/events/records/index_record.rb +46 -14
- data/lib/fusuma/plugin/events/records/record.rb +1 -1
- data/lib/fusuma/plugin/events/records/text_record.rb +2 -1
- data/lib/fusuma/plugin/executors/command_executor.rb +20 -3
- data/lib/fusuma/plugin/executors/executor.rb +45 -3
- data/lib/fusuma/plugin/filters/filter.rb +1 -1
- data/lib/fusuma/plugin/filters/libinput_device_filter.rb +6 -7
- data/lib/fusuma/plugin/filters/libinput_timeout_filter.rb +2 -2
- data/lib/fusuma/plugin/inputs/input.rb +19 -7
- data/lib/fusuma/plugin/inputs/libinput_command_input.rb +10 -5
- data/lib/fusuma/plugin/inputs/timer_input.rb +7 -7
- data/lib/fusuma/plugin/manager.rb +10 -28
- data/lib/fusuma/plugin/parsers/libinput_gesture_parser.rb +10 -8
- data/lib/fusuma/plugin/parsers/parser.rb +8 -9
- data/lib/fusuma/string_support.rb +16 -0
- data/lib/fusuma/version.rb +1 -1
- metadata +13 -8
@@ -1,6 +1,6 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require_relative '../base
|
3
|
+
require_relative '../base'
|
4
4
|
|
5
5
|
module Fusuma
|
6
6
|
module Plugin
|
@@ -8,14 +8,56 @@ module Fusuma
|
|
8
8
|
module Executors
|
9
9
|
# Inherite this base
|
10
10
|
class Executor < Base
|
11
|
+
BASE_ONESHOT_INTERVAL = 0.3
|
12
|
+
BASE_REPEAT_INTERVAL = 0.1
|
13
|
+
|
14
|
+
# Executor parameter on config.yml
|
15
|
+
# @return [Array<Symbol>]
|
16
|
+
def execute_keys
|
17
|
+
# [name.split('Executors::').last.underscore.gsub('_executor', '').to_sym]
|
18
|
+
raise NotImplementedError, "override #{name}##{__method__}"
|
19
|
+
end
|
20
|
+
|
11
21
|
# check executable
|
12
|
-
# @param _event [Event]
|
22
|
+
# @param _event [Events::Event]
|
13
23
|
# @return [TrueClass, FalseClass]
|
14
24
|
def executable?(_event)
|
15
25
|
raise NotImplementedError, "override #{self.class.name}##{__method__}"
|
16
26
|
end
|
17
27
|
|
18
|
-
#
|
28
|
+
# @param event [Events::Event]
|
29
|
+
# @param time [Time]
|
30
|
+
# @return [TrueClass, FalseClass]
|
31
|
+
def enough_interval?(event)
|
32
|
+
# NOTE: Cache at the index that is actually used, reflecting Fallback and Skip.
|
33
|
+
# Otherwise, a wrong index will cause invalid intervals.
|
34
|
+
return true if event.record.index.with_context.keys.any? { |key| key.symbol == :end }
|
35
|
+
|
36
|
+
return false if @wait_until && event.time < @wait_until
|
37
|
+
|
38
|
+
true
|
39
|
+
end
|
40
|
+
|
41
|
+
def update_interval(event)
|
42
|
+
@wait_until = event.time + interval(event).to_f
|
43
|
+
end
|
44
|
+
|
45
|
+
def interval(event)
|
46
|
+
@interval_time ||= {}
|
47
|
+
index = event.record.index
|
48
|
+
@interval_time[index.cache_key] ||= begin
|
49
|
+
config_value =
|
50
|
+
Config.search(Config::Index.new([*index.keys, 'interval'])) ||
|
51
|
+
Config.search(Config::Index.new(['interval', Detectors::Detector.type(event.tag)]))
|
52
|
+
if event.record.trigger == :oneshot
|
53
|
+
(config_value || 1) * BASE_ONESHOT_INTERVAL
|
54
|
+
else
|
55
|
+
(config_value || 1) * BASE_REPEAT_INTERVAL
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
# execute something
|
19
61
|
# @param _event [Event]
|
20
62
|
# @return [nil]
|
21
63
|
def execute(_event)
|
@@ -1,7 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require_relative './filter
|
4
|
-
require_relative '../../device
|
3
|
+
require_relative './filter'
|
4
|
+
require_relative '../../device'
|
5
5
|
|
6
6
|
module Fusuma
|
7
7
|
module Plugin
|
@@ -25,15 +25,14 @@ module Fusuma
|
|
25
25
|
keep_device.reset
|
26
26
|
return false
|
27
27
|
end
|
28
|
-
|
29
|
-
keep_device.all.map(&:id).any? { |device_id| record.to_s =~ /^\s?#{device_id}\s/ }
|
28
|
+
keep_device.all.map(&:id).any? { |device_id| record.to_s =~ /^[\s-]?#{device_id}\s/ }
|
30
29
|
end
|
31
30
|
|
32
31
|
def keep_device
|
33
32
|
@keep_device ||= begin
|
34
|
-
|
35
|
-
|
36
|
-
|
33
|
+
from_config = Array(config_params(:keep_device_names))
|
34
|
+
KeepDevice.new(name_patterns: from_config)
|
35
|
+
end
|
37
36
|
end
|
38
37
|
|
39
38
|
def config_param_sample
|
@@ -1,7 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require_relative '../base
|
4
|
-
require_relative '../events/event
|
3
|
+
require_relative '../base'
|
4
|
+
require_relative '../events/event'
|
5
5
|
|
6
6
|
module Fusuma
|
7
7
|
module Plugin
|
@@ -12,7 +12,7 @@ module Fusuma
|
|
12
12
|
# Wait multiple inputs until it becomes readable
|
13
13
|
# and read lines with nonblock
|
14
14
|
# @param inputs [Array<Input>]
|
15
|
-
# @return Event
|
15
|
+
# @return [Event]
|
16
16
|
def self.select(inputs)
|
17
17
|
ios = IO.select(inputs.map(&:io))
|
18
18
|
io = ios&.first&.first
|
@@ -21,14 +21,26 @@ module Fusuma
|
|
21
21
|
|
22
22
|
begin
|
23
23
|
line = io.readline_nonblock("\n").chomp
|
24
|
+
rescue EOFError => e
|
25
|
+
warn "#{input.class.name}: #{e}"
|
26
|
+
warn 'Send SIGKILL to fusuma processes'
|
27
|
+
inputs.reject { |i| i == input }.each do |i|
|
28
|
+
Process.kill(:SIGKILL, i.pid)
|
29
|
+
end
|
30
|
+
exit 1
|
24
31
|
rescue StandardError => e
|
25
|
-
warn e
|
32
|
+
warn "#{input.class.name}: #{e}"
|
26
33
|
exit 1
|
27
34
|
end
|
28
35
|
|
29
36
|
input.create_event(record: line)
|
30
37
|
end
|
31
38
|
|
39
|
+
# @return [Integer]
|
40
|
+
def pid
|
41
|
+
raise NotImplementedError, "override #{self.class.name}##{__method__}"
|
42
|
+
end
|
43
|
+
|
32
44
|
# @return [IO]
|
33
45
|
def io
|
34
46
|
raise NotImplementedError, "override #{self.class.name}##{__method__}"
|
@@ -36,9 +48,9 @@ module Fusuma
|
|
36
48
|
|
37
49
|
# @return [Event]
|
38
50
|
def create_event(record: 'dummy input')
|
39
|
-
Events::Event.new(tag: tag, record: record)
|
40
|
-
|
41
|
-
|
51
|
+
e = Events::Event.new(tag: tag, record: record)
|
52
|
+
MultiLogger.debug(input_event: e)
|
53
|
+
e
|
42
54
|
end
|
43
55
|
|
44
56
|
def tag
|
@@ -1,20 +1,22 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require_relative '../../libinput_command
|
4
|
-
require_relative './input
|
3
|
+
require_relative '../../libinput_command'
|
4
|
+
require_relative './input'
|
5
5
|
|
6
6
|
module Fusuma
|
7
7
|
module Plugin
|
8
8
|
module Inputs
|
9
9
|
# libinput commands wrapper
|
10
10
|
class LibinputCommandInput < Input
|
11
|
+
attr_reader :pid
|
12
|
+
|
11
13
|
def config_param_types
|
12
14
|
{
|
13
|
-
|
15
|
+
device: [String],
|
14
16
|
'enable-dwt': [TrueClass, FalseClass],
|
15
17
|
'enable-tap': [TrueClass, FalseClass],
|
16
18
|
'show-keycodes': [TrueClass, FalseClass],
|
17
|
-
|
19
|
+
verbose: [TrueClass, FalseClass],
|
18
20
|
'libinput-debug-events': [String],
|
19
21
|
'libinput-list-devices': [String]
|
20
22
|
}
|
@@ -22,7 +24,10 @@ module Fusuma
|
|
22
24
|
|
23
25
|
# @return [IO]
|
24
26
|
def io
|
25
|
-
@io ||=
|
27
|
+
@io ||= begin
|
28
|
+
@pid, io = command.debug_events
|
29
|
+
io
|
30
|
+
end
|
26
31
|
end
|
27
32
|
|
28
33
|
# @return [LibinputCommand]
|
@@ -1,6 +1,6 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require_relative './input
|
3
|
+
require_relative './input'
|
4
4
|
|
5
5
|
module Fusuma
|
6
6
|
module Plugin
|
@@ -10,19 +10,19 @@ module Fusuma
|
|
10
10
|
DEFAULT_INTERVAL = 0.3
|
11
11
|
def config_param_types
|
12
12
|
{
|
13
|
-
|
13
|
+
interval: [Float]
|
14
14
|
}
|
15
15
|
end
|
16
16
|
|
17
|
-
attr_reader :
|
17
|
+
attr_reader :pid
|
18
18
|
|
19
19
|
def io
|
20
20
|
@io ||= begin
|
21
|
-
|
22
|
-
|
21
|
+
reader, writer = create_io
|
22
|
+
@pid = start(reader, writer)
|
23
23
|
|
24
|
-
|
25
|
-
|
24
|
+
reader
|
25
|
+
end
|
26
26
|
end
|
27
27
|
|
28
28
|
def start(reader, writer)
|
@@ -1,7 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
|
4
|
-
require_relative '../
|
3
|
+
require_relative '../multi_logger'
|
4
|
+
require_relative '../string_support'
|
5
5
|
|
6
6
|
module Fusuma
|
7
7
|
module Plugin
|
@@ -58,14 +58,14 @@ module Fusuma
|
|
58
58
|
end
|
59
59
|
|
60
60
|
def require_base_plugins
|
61
|
-
require_relative './base
|
62
|
-
require_relative './events/event
|
63
|
-
require_relative './inputs/input
|
64
|
-
require_relative './filters/filter
|
65
|
-
require_relative './parsers/parser
|
66
|
-
require_relative './buffers/buffer
|
67
|
-
require_relative './detectors/detector
|
68
|
-
require_relative './executors/executor
|
61
|
+
require_relative './base'
|
62
|
+
require_relative './events/event'
|
63
|
+
require_relative './inputs/input'
|
64
|
+
require_relative './filters/filter'
|
65
|
+
require_relative './parsers/parser'
|
66
|
+
require_relative './buffers/buffer'
|
67
|
+
require_relative './detectors/detector'
|
68
|
+
require_relative './executors/executor'
|
69
69
|
end
|
70
70
|
|
71
71
|
def plugins
|
@@ -90,21 +90,3 @@ module Fusuma
|
|
90
90
|
end
|
91
91
|
end
|
92
92
|
end
|
93
|
-
|
94
|
-
# support camerize and underscore
|
95
|
-
class String
|
96
|
-
def camerize
|
97
|
-
split('_').map do |w|
|
98
|
-
w[0].upcase!
|
99
|
-
w
|
100
|
-
end.join
|
101
|
-
end
|
102
|
-
|
103
|
-
def underscore
|
104
|
-
gsub(/([A-Z]+)([A-Z][a-z])/, '\1_\2')
|
105
|
-
.gsub(/([a-z\d])([A-Z])/, '\1_\2')
|
106
|
-
.gsub('::', '/')
|
107
|
-
.tr('-', '_')
|
108
|
-
.downcase
|
109
|
-
end
|
110
|
-
end
|
@@ -1,7 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require_relative '../events/records/record
|
4
|
-
require_relative '../events/records/gesture_record
|
3
|
+
require_relative '../events/records/record'
|
4
|
+
require_relative '../events/records/gesture_record'
|
5
5
|
|
6
6
|
module Fusuma
|
7
7
|
module Plugin
|
@@ -15,7 +15,7 @@ module Fusuma
|
|
15
15
|
def parse_record(record)
|
16
16
|
case line = record.to_s
|
17
17
|
when /GESTURE_SWIPE|GESTURE_PINCH/
|
18
|
-
gesture, status, finger,
|
18
|
+
gesture, status, finger, delta = parse_libinput(line)
|
19
19
|
else
|
20
20
|
return
|
21
21
|
end
|
@@ -23,7 +23,7 @@ module Fusuma
|
|
23
23
|
Events::Records::GestureRecord.new(status: status,
|
24
24
|
gesture: gesture,
|
25
25
|
finger: finger,
|
26
|
-
|
26
|
+
delta: delta)
|
27
27
|
end
|
28
28
|
|
29
29
|
private
|
@@ -32,8 +32,8 @@ module Fusuma
|
|
32
32
|
_device, event_name, _time, other = line.strip.split(nil, 4)
|
33
33
|
finger, other = other.split(nil, 2)
|
34
34
|
|
35
|
-
|
36
|
-
[*detect_gesture(event_name), finger,
|
35
|
+
delta = parse_delta(other)
|
36
|
+
[*detect_gesture(event_name), finger, delta]
|
37
37
|
end
|
38
38
|
|
39
39
|
def detect_gesture(event_name)
|
@@ -41,11 +41,13 @@ module Fusuma
|
|
41
41
|
[Regexp.last_match(1).downcase, Regexp.last_match(2).downcase]
|
42
42
|
end
|
43
43
|
|
44
|
-
def
|
44
|
+
def parse_delta(line)
|
45
45
|
return if line.nil?
|
46
46
|
|
47
|
-
move_x, move_y,
|
47
|
+
move_x, move_y, unaccelerated_x, unaccelerated_y, _, zoom, _, rotate =
|
48
|
+
line.tr('/|(|)', ' ').split
|
48
49
|
Events::Records::GestureRecord::Delta.new(move_x.to_f, move_y.to_f,
|
50
|
+
unaccelerated_x.to_f, unaccelerated_y.to_f,
|
49
51
|
zoom.to_f, rotate.to_f)
|
50
52
|
end
|
51
53
|
end
|
@@ -1,6 +1,6 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require_relative '../base
|
3
|
+
require_relative '../base'
|
4
4
|
|
5
5
|
module Fusuma
|
6
6
|
module Plugin
|
@@ -13,15 +13,14 @@ module Fusuma
|
|
13
13
|
# @param event [Event]
|
14
14
|
# @return [Event]
|
15
15
|
def parse(event)
|
16
|
-
event.
|
17
|
-
next if e.tag != source
|
16
|
+
return event if event.tag != source
|
18
17
|
|
19
|
-
|
20
|
-
|
18
|
+
new_record = parse_record(event.record)
|
19
|
+
return event if new_record.nil?
|
21
20
|
|
22
|
-
|
23
|
-
|
24
|
-
|
21
|
+
event.record = new_record
|
22
|
+
event.tag = tag
|
23
|
+
event
|
25
24
|
end
|
26
25
|
|
27
26
|
# Set source for tag from config.yml.
|
@@ -31,7 +30,7 @@ module Fusuma
|
|
31
30
|
end
|
32
31
|
|
33
32
|
def tag
|
34
|
-
self.class.name.split('::').last.underscore
|
33
|
+
@tag ||= self.class.name.split('::').last.underscore
|
35
34
|
end
|
36
35
|
|
37
36
|
# parse Record object
|
@@ -0,0 +1,16 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# support camerize and underscore
|
4
|
+
class String
|
5
|
+
def camelize
|
6
|
+
split('_').map(&:capitalize).join
|
7
|
+
end
|
8
|
+
|
9
|
+
def underscore
|
10
|
+
gsub(/([A-Z]+)([A-Z][a-z])/, '\1_\2')
|
11
|
+
.gsub(/([a-z\d])([A-Z])/, '\1_\2')
|
12
|
+
.gsub('::', '/')
|
13
|
+
.tr('-', '_')
|
14
|
+
.downcase
|
15
|
+
end
|
16
|
+
end
|
data/lib/fusuma/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: fusuma
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.0.0.
|
4
|
+
version: 2.0.0.pre2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- iberianpig
|
8
|
-
autorequire:
|
8
|
+
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2021-03-29 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: posix-spawn
|
@@ -44,6 +44,7 @@ files:
|
|
44
44
|
- ".rspec"
|
45
45
|
- ".rubocop.yml"
|
46
46
|
- ".rubocop_todo.yml"
|
47
|
+
- ".solargraph.yml"
|
47
48
|
- ".travis.yml"
|
48
49
|
- CHANGELOG.md
|
49
50
|
- CODE_OF_CONDUCT.md
|
@@ -62,8 +63,10 @@ files:
|
|
62
63
|
- lib/fusuma/config/index.rb
|
63
64
|
- lib/fusuma/config/searcher.rb
|
64
65
|
- lib/fusuma/config/yaml_duplication_checker.rb
|
66
|
+
- lib/fusuma/custom_process.rb
|
65
67
|
- lib/fusuma/device.rb
|
66
68
|
- lib/fusuma/environment.rb
|
69
|
+
- lib/fusuma/hash_support.rb
|
67
70
|
- lib/fusuma/libinput_command.rb
|
68
71
|
- lib/fusuma/multi_logger.rb
|
69
72
|
- lib/fusuma/plugin/base.rb
|
@@ -75,6 +78,7 @@ files:
|
|
75
78
|
- lib/fusuma/plugin/detectors/rotate_detector.rb
|
76
79
|
- lib/fusuma/plugin/detectors/swipe_detector.rb
|
77
80
|
- lib/fusuma/plugin/events/event.rb
|
81
|
+
- lib/fusuma/plugin/events/records/context_record.rb
|
78
82
|
- lib/fusuma/plugin/events/records/gesture_record.rb
|
79
83
|
- lib/fusuma/plugin/events/records/index_record.rb
|
80
84
|
- lib/fusuma/plugin/events/records/record.rb
|
@@ -90,13 +94,14 @@ files:
|
|
90
94
|
- lib/fusuma/plugin/manager.rb
|
91
95
|
- lib/fusuma/plugin/parsers/libinput_gesture_parser.rb
|
92
96
|
- lib/fusuma/plugin/parsers/parser.rb
|
97
|
+
- lib/fusuma/string_support.rb
|
93
98
|
- lib/fusuma/version.rb
|
94
99
|
homepage: https://github.com/iberianpig/fusuma
|
95
100
|
licenses:
|
96
101
|
- MIT
|
97
102
|
metadata:
|
98
103
|
yard.run: yri
|
99
|
-
post_install_message:
|
104
|
+
post_install_message:
|
100
105
|
rdoc_options: []
|
101
106
|
require_paths:
|
102
107
|
- lib
|
@@ -104,15 +109,15 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
104
109
|
requirements:
|
105
110
|
- - ">="
|
106
111
|
- !ruby/object:Gem::Version
|
107
|
-
version:
|
112
|
+
version: 2.5.1
|
108
113
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
109
114
|
requirements:
|
110
115
|
- - ">"
|
111
116
|
- !ruby/object:Gem::Version
|
112
117
|
version: 1.3.1
|
113
118
|
requirements: []
|
114
|
-
rubygems_version: 3.
|
115
|
-
signing_key:
|
119
|
+
rubygems_version: 3.2.15
|
120
|
+
signing_key:
|
116
121
|
specification_version: 4
|
117
|
-
summary: Multitouch gestures with libinput
|
122
|
+
summary: Multitouch gestures with libinput driver on X11, Linux
|
118
123
|
test_files: []
|