fusuma 1.9.0 → 2.0.0.pre
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/pull_request_template.md +9 -0
- data/.rubocop.yml +24 -0
- data/CHANGELOG.md +65 -2
- data/CONTRIBUTING.md +72 -0
- data/Gemfile +12 -0
- data/README.md +140 -70
- data/bin/console +15 -0
- data/fusuma.gemspec +1 -11
- data/lib/fusuma.rb +15 -7
- data/lib/fusuma/config.rb +40 -34
- data/lib/fusuma/config/index.rb +9 -2
- data/lib/fusuma/config/searcher.rb +90 -0
- data/lib/fusuma/config/yaml_duplication_checker.rb +42 -0
- data/lib/fusuma/device.rb +3 -1
- data/lib/fusuma/environment.rb +2 -1
- data/lib/fusuma/libinput_command.rb +37 -17
- data/lib/fusuma/plugin/buffers/timer_buffer.rb +46 -0
- data/lib/fusuma/plugin/events/records/gesture_record.rb +4 -1
- data/lib/fusuma/plugin/executors/command_executor.rb +2 -4
- data/lib/fusuma/plugin/filters/libinput_timeout_filter.rb +21 -0
- data/lib/fusuma/plugin/inputs/input.rb +46 -3
- data/lib/fusuma/plugin/inputs/libinput_command_input.rb +27 -5
- data/lib/fusuma/plugin/inputs/timer_input.rb +63 -0
- data/lib/fusuma/version.rb +1 -1
- metadata +17 -150
@@ -0,0 +1,46 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative './buffer.rb'
|
4
|
+
|
5
|
+
module Fusuma
|
6
|
+
module Plugin
|
7
|
+
module Buffers
|
8
|
+
# manage events and generate command
|
9
|
+
class TimerBuffer < Buffer
|
10
|
+
DEFAULT_SOURCE = 'timer_input'
|
11
|
+
DEFAULT_SECONDS_TO_KEEP = 60
|
12
|
+
|
13
|
+
def config_param_types
|
14
|
+
{
|
15
|
+
'source': [String],
|
16
|
+
'seconds_to_keep': [Float, Integer]
|
17
|
+
}
|
18
|
+
end
|
19
|
+
|
20
|
+
# @param event [Event]
|
21
|
+
# @return [Buffer, NilClass]
|
22
|
+
def buffer(event)
|
23
|
+
return if event&.tag != source
|
24
|
+
|
25
|
+
@events.push(event)
|
26
|
+
self
|
27
|
+
end
|
28
|
+
|
29
|
+
def clear_expired(current_time: Time.now)
|
30
|
+
@seconds_to_keep ||= (config_params(:seconds_to_keep) || DEFAULT_SECONDS_TO_KEEP)
|
31
|
+
@events.each do |e|
|
32
|
+
break if current_time - e.time < @seconds_to_keep
|
33
|
+
|
34
|
+
MultiLogger.debug("#{self.class.name}##{__method__}")
|
35
|
+
|
36
|
+
@events.delete(e)
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
def empty?
|
41
|
+
@events.empty?
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
@@ -14,10 +14,13 @@ module Fusuma
|
|
14
14
|
Delta = Struct.new(:move_x, :move_y, :zoom, :rotate)
|
15
15
|
|
16
16
|
# @param status [String]
|
17
|
+
# @param gesture [String]
|
18
|
+
# @param finger [String, Integer]
|
19
|
+
# @param direction [Delta, NilClass]
|
17
20
|
def initialize(status:, gesture:, finger:, direction:)
|
18
21
|
@status = status
|
19
22
|
@gesture = gesture
|
20
|
-
@finger = finger
|
23
|
+
@finger = finger.to_i
|
21
24
|
@direction = direction
|
22
25
|
end
|
23
26
|
end
|
@@ -1,5 +1,6 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
require 'posix/spawn'
|
3
4
|
require_relative './executor.rb'
|
4
5
|
|
5
6
|
module Fusuma
|
@@ -12,11 +13,8 @@ module Fusuma
|
|
12
13
|
break unless command
|
13
14
|
|
14
15
|
MultiLogger.info(command: command)
|
15
|
-
pid = fork do
|
16
|
-
Process.daemon(true)
|
17
|
-
exec(command.to_s)
|
18
|
-
end
|
19
16
|
|
17
|
+
pid = POSIX::Spawn.spawn(command.to_s)
|
20
18
|
Process.detach(pid)
|
21
19
|
end
|
22
20
|
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative './filter.rb'
|
4
|
+
require_relative '../../libinput_command.rb'
|
5
|
+
|
6
|
+
module Fusuma
|
7
|
+
module Plugin
|
8
|
+
module Filters
|
9
|
+
# Filter device log
|
10
|
+
class LibinputTimeoutFilter < Filter
|
11
|
+
DEFAULT_SOURCE = 'libinput_command_input'
|
12
|
+
|
13
|
+
# @return [TrueClass] when keeping it
|
14
|
+
# @return [FalseClass] when discarding it
|
15
|
+
def keep?(record)
|
16
|
+
record.to_s == LibinputCommand::TIMEOUT_MESSAGE
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -5,15 +5,37 @@ require_relative '../events/event.rb'
|
|
5
5
|
|
6
6
|
module Fusuma
|
7
7
|
module Plugin
|
8
|
-
# input class
|
9
8
|
module Inputs
|
10
9
|
# Inherite this base
|
10
|
+
# @abstract Subclass and override {#io} to implement
|
11
11
|
class Input < Base
|
12
|
-
|
12
|
+
# Wait multiple inputs until it becomes readable
|
13
|
+
# and read lines with nonblock
|
14
|
+
# @param inputs [Array<Input>]
|
15
|
+
# @return Event
|
16
|
+
def self.select(inputs)
|
17
|
+
ios = IO.select(inputs.map(&:io))
|
18
|
+
io = ios&.first&.first
|
19
|
+
|
20
|
+
input = inputs.find { |i| i.io == io }
|
21
|
+
|
22
|
+
begin
|
23
|
+
line = io.readline_nonblock("\n").chomp
|
24
|
+
rescue StandardError => e
|
25
|
+
warn e
|
26
|
+
exit 1
|
27
|
+
end
|
28
|
+
|
29
|
+
input.create_event(record: line)
|
30
|
+
end
|
31
|
+
|
32
|
+
# @return [IO]
|
33
|
+
def io
|
13
34
|
raise NotImplementedError, "override #{self.class.name}##{__method__}"
|
14
35
|
end
|
15
36
|
|
16
|
-
|
37
|
+
# @return [Event]
|
38
|
+
def create_event(record: 'dummy input')
|
17
39
|
Events::Event.new(tag: tag, record: record).tap do |e|
|
18
40
|
MultiLogger.debug(input_event: e)
|
19
41
|
end
|
@@ -26,3 +48,24 @@ module Fusuma
|
|
26
48
|
end
|
27
49
|
end
|
28
50
|
end
|
51
|
+
|
52
|
+
# ref: https://github.com/Homebrew/brew/blob/6b2dbbc96f7d8aa12f9b8c9c60107c9cc58befc4/Library/Homebrew/extend/io.rb
|
53
|
+
class IO
|
54
|
+
def readline_nonblock(sep = $INPUT_RECORD_SEPARATOR)
|
55
|
+
line = +''
|
56
|
+
buffer = +''
|
57
|
+
|
58
|
+
loop do
|
59
|
+
break if buffer == sep
|
60
|
+
|
61
|
+
read_nonblock(1, buffer)
|
62
|
+
line.concat(buffer)
|
63
|
+
end
|
64
|
+
|
65
|
+
line.freeze
|
66
|
+
rescue IO::WaitReadable, EOFError => e
|
67
|
+
raise e if line.empty?
|
68
|
+
|
69
|
+
line.freeze
|
70
|
+
end
|
71
|
+
end
|
@@ -1,5 +1,6 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
require_relative '../../libinput_command.rb'
|
3
4
|
require_relative './input.rb'
|
4
5
|
|
5
6
|
module Fusuma
|
@@ -13,16 +14,29 @@ module Fusuma
|
|
13
14
|
'enable-dwt': [TrueClass, FalseClass],
|
14
15
|
'enable-tap': [TrueClass, FalseClass],
|
15
16
|
'show-keycodes': [TrueClass, FalseClass],
|
16
|
-
'verbose': [TrueClass, FalseClass]
|
17
|
+
'verbose': [TrueClass, FalseClass],
|
18
|
+
'libinput-debug-events': [String],
|
19
|
+
'libinput-list-devices': [String]
|
17
20
|
}
|
18
21
|
end
|
19
22
|
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
end
|
23
|
+
# @return [IO]
|
24
|
+
def io
|
25
|
+
@io ||= command.debug_events
|
24
26
|
end
|
25
27
|
|
28
|
+
# @return [LibinputCommand]
|
29
|
+
def command
|
30
|
+
@command ||= LibinputCommand.new(
|
31
|
+
libinput_options: libinput_options,
|
32
|
+
commands: {
|
33
|
+
debug_events_command: debug_events_command,
|
34
|
+
list_devices_command: list_devices_command
|
35
|
+
}
|
36
|
+
)
|
37
|
+
end
|
38
|
+
|
39
|
+
# @return [Array]
|
26
40
|
def libinput_options
|
27
41
|
device = ("--device='#{config_params(:device)}'" if config_params(:device))
|
28
42
|
enable_tap = '--enable-tap' if config_params(:'enable-tap')
|
@@ -37,6 +51,14 @@ module Fusuma
|
|
37
51
|
verbose
|
38
52
|
].compact
|
39
53
|
end
|
54
|
+
|
55
|
+
def debug_events_command
|
56
|
+
config_params(:'libinput-debug-events')
|
57
|
+
end
|
58
|
+
|
59
|
+
def list_devices_command
|
60
|
+
config_params(:'libinput-list-devices')
|
61
|
+
end
|
40
62
|
end
|
41
63
|
end
|
42
64
|
end
|
@@ -0,0 +1,63 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative './input.rb'
|
4
|
+
|
5
|
+
module Fusuma
|
6
|
+
module Plugin
|
7
|
+
module Inputs
|
8
|
+
# libinput commands wrapper
|
9
|
+
class TimerInput < Input
|
10
|
+
DEFAULT_INTERVAL = 0.3
|
11
|
+
def config_param_types
|
12
|
+
{
|
13
|
+
'interval': [Float]
|
14
|
+
}
|
15
|
+
end
|
16
|
+
|
17
|
+
attr_reader :writer
|
18
|
+
|
19
|
+
def io
|
20
|
+
@io ||= begin
|
21
|
+
reader, writer = create_io
|
22
|
+
@pid = start(reader, writer)
|
23
|
+
|
24
|
+
reader
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
def start(reader, writer)
|
29
|
+
pid = fork do
|
30
|
+
timer_loop(reader, writer)
|
31
|
+
end
|
32
|
+
Process.detach(pid)
|
33
|
+
writer.close
|
34
|
+
pid
|
35
|
+
end
|
36
|
+
|
37
|
+
def timer_loop(reader, writer)
|
38
|
+
reader.close
|
39
|
+
begin
|
40
|
+
loop do
|
41
|
+
sleep interval
|
42
|
+
writer.puts 'timer'
|
43
|
+
end
|
44
|
+
rescue Errno::EPIPE
|
45
|
+
exit 0
|
46
|
+
rescue StandardError => e
|
47
|
+
MultiLogger.error e
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
private
|
52
|
+
|
53
|
+
def create_io
|
54
|
+
IO.pipe
|
55
|
+
end
|
56
|
+
|
57
|
+
def interval
|
58
|
+
config_params(:interval) || DEFAULT_INTERVAL
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
data/lib/fusuma/version.rb
CHANGED
metadata
CHANGED
@@ -1,163 +1,23 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: fusuma
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version:
|
4
|
+
version: 2.0.0.pre
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- iberianpig
|
8
|
-
autorequire:
|
8
|
+
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2020-
|
11
|
+
date: 2020-11-07 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
|
-
name:
|
14
|
+
name: posix-spawn
|
15
15
|
requirement: !ruby/object:Gem::Requirement
|
16
16
|
requirements:
|
17
17
|
- - ">="
|
18
18
|
- !ruby/object:Gem::Version
|
19
19
|
version: '0'
|
20
|
-
type: :
|
21
|
-
prerelease: false
|
22
|
-
version_requirements: !ruby/object:Gem::Requirement
|
23
|
-
requirements:
|
24
|
-
- - ">="
|
25
|
-
- !ruby/object:Gem::Version
|
26
|
-
version: '0'
|
27
|
-
- !ruby/object:Gem::Dependency
|
28
|
-
name: coveralls
|
29
|
-
requirement: !ruby/object:Gem::Requirement
|
30
|
-
requirements:
|
31
|
-
- - ">="
|
32
|
-
- !ruby/object:Gem::Version
|
33
|
-
version: '0'
|
34
|
-
type: :development
|
35
|
-
prerelease: false
|
36
|
-
version_requirements: !ruby/object:Gem::Requirement
|
37
|
-
requirements:
|
38
|
-
- - ">="
|
39
|
-
- !ruby/object:Gem::Version
|
40
|
-
version: '0'
|
41
|
-
- !ruby/object:Gem::Dependency
|
42
|
-
name: github_changelog_generator
|
43
|
-
requirement: !ruby/object:Gem::Requirement
|
44
|
-
requirements:
|
45
|
-
- - "~>"
|
46
|
-
- !ruby/object:Gem::Version
|
47
|
-
version: '1.14'
|
48
|
-
type: :development
|
49
|
-
prerelease: false
|
50
|
-
version_requirements: !ruby/object:Gem::Requirement
|
51
|
-
requirements:
|
52
|
-
- - "~>"
|
53
|
-
- !ruby/object:Gem::Version
|
54
|
-
version: '1.14'
|
55
|
-
- !ruby/object:Gem::Dependency
|
56
|
-
name: pry-byebug
|
57
|
-
requirement: !ruby/object:Gem::Requirement
|
58
|
-
requirements:
|
59
|
-
- - "~>"
|
60
|
-
- !ruby/object:Gem::Version
|
61
|
-
version: '3.4'
|
62
|
-
type: :development
|
63
|
-
prerelease: false
|
64
|
-
version_requirements: !ruby/object:Gem::Requirement
|
65
|
-
requirements:
|
66
|
-
- - "~>"
|
67
|
-
- !ruby/object:Gem::Version
|
68
|
-
version: '3.4'
|
69
|
-
- !ruby/object:Gem::Dependency
|
70
|
-
name: pry-doc
|
71
|
-
requirement: !ruby/object:Gem::Requirement
|
72
|
-
requirements:
|
73
|
-
- - ">="
|
74
|
-
- !ruby/object:Gem::Version
|
75
|
-
version: '0'
|
76
|
-
type: :development
|
77
|
-
prerelease: false
|
78
|
-
version_requirements: !ruby/object:Gem::Requirement
|
79
|
-
requirements:
|
80
|
-
- - ">="
|
81
|
-
- !ruby/object:Gem::Version
|
82
|
-
version: '0'
|
83
|
-
- !ruby/object:Gem::Dependency
|
84
|
-
name: pry-inline
|
85
|
-
requirement: !ruby/object:Gem::Requirement
|
86
|
-
requirements:
|
87
|
-
- - ">="
|
88
|
-
- !ruby/object:Gem::Version
|
89
|
-
version: '0'
|
90
|
-
type: :development
|
91
|
-
prerelease: false
|
92
|
-
version_requirements: !ruby/object:Gem::Requirement
|
93
|
-
requirements:
|
94
|
-
- - ">="
|
95
|
-
- !ruby/object:Gem::Version
|
96
|
-
version: '0'
|
97
|
-
- !ruby/object:Gem::Dependency
|
98
|
-
name: rake
|
99
|
-
requirement: !ruby/object:Gem::Requirement
|
100
|
-
requirements:
|
101
|
-
- - "~>"
|
102
|
-
- !ruby/object:Gem::Version
|
103
|
-
version: '13.0'
|
104
|
-
type: :development
|
105
|
-
prerelease: false
|
106
|
-
version_requirements: !ruby/object:Gem::Requirement
|
107
|
-
requirements:
|
108
|
-
- - "~>"
|
109
|
-
- !ruby/object:Gem::Version
|
110
|
-
version: '13.0'
|
111
|
-
- !ruby/object:Gem::Dependency
|
112
|
-
name: reek
|
113
|
-
requirement: !ruby/object:Gem::Requirement
|
114
|
-
requirements:
|
115
|
-
- - ">="
|
116
|
-
- !ruby/object:Gem::Version
|
117
|
-
version: '0'
|
118
|
-
type: :development
|
119
|
-
prerelease: false
|
120
|
-
version_requirements: !ruby/object:Gem::Requirement
|
121
|
-
requirements:
|
122
|
-
- - ">="
|
123
|
-
- !ruby/object:Gem::Version
|
124
|
-
version: '0'
|
125
|
-
- !ruby/object:Gem::Dependency
|
126
|
-
name: rspec
|
127
|
-
requirement: !ruby/object:Gem::Requirement
|
128
|
-
requirements:
|
129
|
-
- - "~>"
|
130
|
-
- !ruby/object:Gem::Version
|
131
|
-
version: '3.0'
|
132
|
-
type: :development
|
133
|
-
prerelease: false
|
134
|
-
version_requirements: !ruby/object:Gem::Requirement
|
135
|
-
requirements:
|
136
|
-
- - "~>"
|
137
|
-
- !ruby/object:Gem::Version
|
138
|
-
version: '3.0'
|
139
|
-
- !ruby/object:Gem::Dependency
|
140
|
-
name: rubocop
|
141
|
-
requirement: !ruby/object:Gem::Requirement
|
142
|
-
requirements:
|
143
|
-
- - ">="
|
144
|
-
- !ruby/object:Gem::Version
|
145
|
-
version: '0'
|
146
|
-
type: :development
|
147
|
-
prerelease: false
|
148
|
-
version_requirements: !ruby/object:Gem::Requirement
|
149
|
-
requirements:
|
150
|
-
- - ">="
|
151
|
-
- !ruby/object:Gem::Version
|
152
|
-
version: '0'
|
153
|
-
- !ruby/object:Gem::Dependency
|
154
|
-
name: yard
|
155
|
-
requirement: !ruby/object:Gem::Requirement
|
156
|
-
requirements:
|
157
|
-
- - ">="
|
158
|
-
- !ruby/object:Gem::Version
|
159
|
-
version: '0'
|
160
|
-
type: :development
|
20
|
+
type: :runtime
|
161
21
|
prerelease: false
|
162
22
|
version_requirements: !ruby/object:Gem::Requirement
|
163
23
|
requirements:
|
@@ -177,6 +37,7 @@ files:
|
|
177
37
|
- ".github/FUNDING.yml"
|
178
38
|
- ".github/ISSUE_TEMPLATE/bug_report.md"
|
179
39
|
- ".github/ISSUE_TEMPLATE/feature_request.md"
|
40
|
+
- ".github/pull_request_template.md"
|
180
41
|
- ".github/stale.yml"
|
181
42
|
- ".gitignore"
|
182
43
|
- ".reek.yml"
|
@@ -186,6 +47,7 @@ files:
|
|
186
47
|
- ".travis.yml"
|
187
48
|
- CHANGELOG.md
|
188
49
|
- CODE_OF_CONDUCT.md
|
50
|
+
- CONTRIBUTING.md
|
189
51
|
- Gemfile
|
190
52
|
- LICENSE
|
191
53
|
- README.md
|
@@ -198,6 +60,8 @@ files:
|
|
198
60
|
- lib/fusuma/config.rb
|
199
61
|
- lib/fusuma/config.yml
|
200
62
|
- lib/fusuma/config/index.rb
|
63
|
+
- lib/fusuma/config/searcher.rb
|
64
|
+
- lib/fusuma/config/yaml_duplication_checker.rb
|
201
65
|
- lib/fusuma/device.rb
|
202
66
|
- lib/fusuma/environment.rb
|
203
67
|
- lib/fusuma/libinput_command.rb
|
@@ -205,6 +69,7 @@ files:
|
|
205
69
|
- lib/fusuma/plugin/base.rb
|
206
70
|
- lib/fusuma/plugin/buffers/buffer.rb
|
207
71
|
- lib/fusuma/plugin/buffers/gesture_buffer.rb
|
72
|
+
- lib/fusuma/plugin/buffers/timer_buffer.rb
|
208
73
|
- lib/fusuma/plugin/detectors/detector.rb
|
209
74
|
- lib/fusuma/plugin/detectors/pinch_detector.rb
|
210
75
|
- lib/fusuma/plugin/detectors/rotate_detector.rb
|
@@ -218,8 +83,10 @@ files:
|
|
218
83
|
- lib/fusuma/plugin/executors/executor.rb
|
219
84
|
- lib/fusuma/plugin/filters/filter.rb
|
220
85
|
- lib/fusuma/plugin/filters/libinput_device_filter.rb
|
86
|
+
- lib/fusuma/plugin/filters/libinput_timeout_filter.rb
|
221
87
|
- lib/fusuma/plugin/inputs/input.rb
|
222
88
|
- lib/fusuma/plugin/inputs/libinput_command_input.rb
|
89
|
+
- lib/fusuma/plugin/inputs/timer_input.rb
|
223
90
|
- lib/fusuma/plugin/manager.rb
|
224
91
|
- lib/fusuma/plugin/parsers/libinput_gesture_parser.rb
|
225
92
|
- lib/fusuma/plugin/parsers/parser.rb
|
@@ -229,7 +96,7 @@ licenses:
|
|
229
96
|
- MIT
|
230
97
|
metadata:
|
231
98
|
yard.run: yri
|
232
|
-
post_install_message:
|
99
|
+
post_install_message:
|
233
100
|
rdoc_options: []
|
234
101
|
require_paths:
|
235
102
|
- lib
|
@@ -240,12 +107,12 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
240
107
|
version: '2.3'
|
241
108
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
242
109
|
requirements:
|
243
|
-
- - "
|
110
|
+
- - ">"
|
244
111
|
- !ruby/object:Gem::Version
|
245
|
-
version:
|
112
|
+
version: 1.3.1
|
246
113
|
requirements: []
|
247
|
-
rubygems_version: 3.
|
248
|
-
signing_key:
|
114
|
+
rubygems_version: 3.1.4
|
115
|
+
signing_key:
|
249
116
|
specification_version: 4
|
250
117
|
summary: Multitouch gestures with libinput dirver on X11, Linux
|
251
118
|
test_files: []
|