fusuma 1.11.1 → 2.0.0.pre
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.rubocop.yml +3 -0
- data/Gemfile +12 -0
- data/README.md +6 -2
- data/fusuma.gemspec +1 -11
- data/lib/fusuma.rb +14 -5
- data/lib/fusuma/config.rb +7 -28
- data/lib/fusuma/config/index.rb +9 -2
- data/lib/fusuma/config/searcher.rb +90 -0
- data/lib/fusuma/device.rb +3 -1
- data/lib/fusuma/environment.rb +2 -1
- data/lib/fusuma/libinput_command.rb +16 -20
- data/lib/fusuma/plugin/buffers/timer_buffer.rb +46 -0
- data/lib/fusuma/plugin/executors/command_executor.rb +2 -4
- data/lib/fusuma/plugin/inputs/input.rb +46 -3
- data/lib/fusuma/plugin/inputs/libinput_command_input.rb +10 -5
- data/lib/fusuma/plugin/inputs/timer_input.rb +63 -0
- data/lib/fusuma/version.rb +1 -1
- metadata +13 -150
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: bd6d9f73a5476aed954644b4d5f7caa9627779139bc84e301fa2ae67fbb1d71f
|
4
|
+
data.tar.gz: e893683da4aa5f235481ec32bf45a6a2386bc6b64989f36617b6806c538602b3
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 55b7d3393e283bc459b865d293839d6aa2286db4ece74b14d9b50c05726f4d5bfb32609b79541ad816b0ebdebb687b948f03f53fdd1e4d070bf470af56360c84
|
7
|
+
data.tar.gz: f9d5b36287ccd132687497f8f527fc1ef90b0dc818feccf2f9cc6db0b76371a30832467df2d8aa0fca8ee3c5804551da8470b34784c185da73dc08ae507034de
|
data/.rubocop.yml
CHANGED
data/Gemfile
CHANGED
@@ -4,3 +4,15 @@ source 'https://rubygems.org'
|
|
4
4
|
|
5
5
|
# Specify your gem's dependencies in fusuma.gemspec
|
6
6
|
gemspec
|
7
|
+
|
8
|
+
gem 'bundler'
|
9
|
+
gem 'coveralls'
|
10
|
+
gem 'github_changelog_generator', '~> 1.14'
|
11
|
+
gem 'pry-byebug', '~> 3.4'
|
12
|
+
gem 'pry-doc'
|
13
|
+
gem 'pry-inline'
|
14
|
+
gem 'rake', '~> 13.0'
|
15
|
+
gem 'reek'
|
16
|
+
gem 'rspec', '~> 3.0'
|
17
|
+
gem 'rubocop', '0.81'
|
18
|
+
gem 'yard'
|
data/README.md
CHANGED
@@ -25,7 +25,11 @@ This gem makes your linux able to recognize swipes or pinchs and assign commands
|
|
25
25
|
$ sudo gpasswd -a $USER input
|
26
26
|
```
|
27
27
|
|
28
|
-
Then, You
|
28
|
+
Then, You apply the change with no logout or reboot.
|
29
|
+
|
30
|
+
```bash
|
31
|
+
$ newgrp input
|
32
|
+
```
|
29
33
|
|
30
34
|
### 2. Install libinput-tools
|
31
35
|
|
@@ -242,7 +246,7 @@ swipe:
|
|
242
246
|
- [ydotool](https://github.com/ReimuNotMoe/ydotool)
|
243
247
|
- Wayland compatible
|
244
248
|
- Needs more maintainers.
|
245
|
-
- Requires only replacing `xdotool` with `ydotool` in
|
249
|
+
- Requires only replacing `xdotool` with `ydotool` in fusuma conf.
|
246
250
|
|
247
251
|
## Options
|
248
252
|
|
data/fusuma.gemspec
CHANGED
@@ -24,15 +24,5 @@ Gem::Specification.new do |spec|
|
|
24
24
|
spec.metadata['yard.run'] = 'yri' # use "yard" to build full HTML docs.
|
25
25
|
|
26
26
|
spec.required_ruby_version = '>= 2.3' # https://packages.ubuntu.com/search?keywords=ruby&searchon=names&exact=1&suite=all§ion=main
|
27
|
-
spec.
|
28
|
-
spec.add_development_dependency 'coveralls'
|
29
|
-
spec.add_development_dependency 'github_changelog_generator', '~> 1.14'
|
30
|
-
spec.add_development_dependency 'pry-byebug', '~> 3.4'
|
31
|
-
spec.add_development_dependency 'pry-doc'
|
32
|
-
spec.add_development_dependency 'pry-inline'
|
33
|
-
spec.add_development_dependency 'rake', '~> 13.0'
|
34
|
-
spec.add_development_dependency 'reek'
|
35
|
-
spec.add_development_dependency 'rspec', '~> 3.0'
|
36
|
-
spec.add_development_dependency 'rubocop'
|
37
|
-
spec.add_development_dependency 'yard'
|
27
|
+
spec.add_dependency 'posix-spawn'
|
38
28
|
end
|
data/lib/fusuma.rb
CHANGED
@@ -62,8 +62,9 @@ module Fusuma
|
|
62
62
|
end
|
63
63
|
|
64
64
|
def run
|
65
|
-
|
66
|
-
|
65
|
+
loop do
|
66
|
+
event = input
|
67
|
+
event || next
|
67
68
|
clear_expired_events
|
68
69
|
filtered = filter(event) || next
|
69
70
|
parsed = parse(filtered) || next
|
@@ -74,6 +75,10 @@ module Fusuma
|
|
74
75
|
end
|
75
76
|
end
|
76
77
|
|
78
|
+
def input
|
79
|
+
Plugin::Inputs::Input.select(@inputs)
|
80
|
+
end
|
81
|
+
|
77
82
|
def filter(event)
|
78
83
|
event if @filters.any? { |f| f.filter(event) }
|
79
84
|
end
|
@@ -110,11 +115,15 @@ module Fusuma
|
|
110
115
|
def execute(event)
|
111
116
|
return unless event
|
112
117
|
|
113
|
-
|
114
|
-
e.executable?(event)
|
118
|
+
l = lambda do
|
119
|
+
executor = @executors.find { |e| e.executable?(event) }
|
120
|
+
executor&.execute(event)
|
115
121
|
end
|
116
122
|
|
117
|
-
|
123
|
+
l.call ||
|
124
|
+
Config::Searcher.skip { l.call } ||
|
125
|
+
Config::Searcher.fallback { l.call } ||
|
126
|
+
Config::Searcher.skip { Config::Searcher.fallback { l.call } }
|
118
127
|
end
|
119
128
|
|
120
129
|
def clear_expired_events
|
data/lib/fusuma/config.rb
CHANGED
@@ -2,6 +2,7 @@
|
|
2
2
|
|
3
3
|
require_relative './multi_logger.rb'
|
4
4
|
require_relative './config/index.rb'
|
5
|
+
require_relative './config/searcher.rb'
|
5
6
|
require_relative './config/yaml_duplication_checker.rb'
|
6
7
|
require 'singleton'
|
7
8
|
require 'yaml'
|
@@ -27,10 +28,11 @@ module Fusuma
|
|
27
28
|
|
28
29
|
attr_reader :keymap
|
29
30
|
attr_reader :custom_path
|
31
|
+
attr_reader :searcher
|
30
32
|
|
31
33
|
def initialize
|
34
|
+
@searcher = Searcher.new
|
32
35
|
@custom_path = nil
|
33
|
-
@cache = nil
|
34
36
|
@keymap = nil
|
35
37
|
end
|
36
38
|
|
@@ -40,7 +42,7 @@ module Fusuma
|
|
40
42
|
end
|
41
43
|
|
42
44
|
def reload
|
43
|
-
@
|
45
|
+
@searcher = Searcher.new
|
44
46
|
path = find_filepath
|
45
47
|
MultiLogger.info "reload config: #{path}"
|
46
48
|
@keymap = validate(path)
|
@@ -68,22 +70,9 @@ module Fusuma
|
|
68
70
|
end
|
69
71
|
|
70
72
|
# @param index [Index]
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
if location.is_a?(Hash)
|
75
|
-
begin
|
76
|
-
if key.skippable
|
77
|
-
location.fetch(key.symbol, location)
|
78
|
-
else
|
79
|
-
location.fetch(key.symbol, nil)
|
80
|
-
end
|
81
|
-
end
|
82
|
-
else
|
83
|
-
location
|
84
|
-
end
|
85
|
-
end
|
86
|
-
end
|
73
|
+
# @param location [Hash]
|
74
|
+
def search(index, location: keymap)
|
75
|
+
@searcher.search_with_cache(index, location: location)
|
87
76
|
end
|
88
77
|
|
89
78
|
private
|
@@ -113,16 +102,6 @@ module Fusuma
|
|
113
102
|
def expand_default_path(filename)
|
114
103
|
File.expand_path "../../#{filename}", __FILE__
|
115
104
|
end
|
116
|
-
|
117
|
-
def cache(key)
|
118
|
-
@cache ||= {}
|
119
|
-
key = key.join(',') if key.is_a? Array
|
120
|
-
if @cache.key?(key)
|
121
|
-
@cache[key]
|
122
|
-
else
|
123
|
-
@cache[key] = block_given? ? yield : nil
|
124
|
-
end
|
125
|
-
end
|
126
105
|
end
|
127
106
|
end
|
128
107
|
|
data/lib/fusuma/config/index.rb
CHANGED
@@ -34,15 +34,22 @@ module Fusuma
|
|
34
34
|
|
35
35
|
# Keys in Index
|
36
36
|
class Key
|
37
|
-
def initialize(symbol_word, skippable: false)
|
37
|
+
def initialize(symbol_word, skippable: false, fallback: nil)
|
38
38
|
@symbol = begin
|
39
39
|
symbol_word.to_sym
|
40
40
|
rescue StandardError
|
41
41
|
symbol_word
|
42
42
|
end
|
43
|
+
|
43
44
|
@skippable = skippable
|
45
|
+
|
46
|
+
@fallback = begin
|
47
|
+
fallback.to_sym
|
48
|
+
rescue StandardError
|
49
|
+
fallback
|
50
|
+
end
|
44
51
|
end
|
45
|
-
attr_reader :symbol, :skippable
|
52
|
+
attr_reader :symbol, :skippable, :fallback
|
46
53
|
end
|
47
54
|
end
|
48
55
|
end
|
@@ -0,0 +1,90 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# Index for searching value from config.yml
|
4
|
+
module Fusuma
|
5
|
+
class Config
|
6
|
+
# Search config.yml
|
7
|
+
class Searcher
|
8
|
+
def initialize
|
9
|
+
@cache
|
10
|
+
end
|
11
|
+
|
12
|
+
# @param index [Index]
|
13
|
+
# @param location [Hash]
|
14
|
+
# @return [NilClass]
|
15
|
+
# @return [Hash]
|
16
|
+
# @return [Object]
|
17
|
+
def search(index, location:)
|
18
|
+
key = index.keys.first
|
19
|
+
return location if key.nil?
|
20
|
+
|
21
|
+
return nil if location.nil?
|
22
|
+
|
23
|
+
return nil unless location.is_a?(Hash)
|
24
|
+
|
25
|
+
next_index = Index.new(index.keys[1..-1])
|
26
|
+
|
27
|
+
value = nil
|
28
|
+
next_location_cadidates(location, key).find do |next_location|
|
29
|
+
value = search(next_index, location: next_location)
|
30
|
+
end
|
31
|
+
value
|
32
|
+
end
|
33
|
+
|
34
|
+
def search_with_cache(index, location:)
|
35
|
+
cache([index.cache_key, Searcher.skip?, Searcher.fallback?]) do
|
36
|
+
search(index, location: location)
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
def cache(key)
|
41
|
+
@cache ||= {}
|
42
|
+
key = key.join(',') if key.is_a? Array
|
43
|
+
if @cache.key?(key)
|
44
|
+
@cache[key]
|
45
|
+
else
|
46
|
+
@cache[key] = block_given? ? yield : nil
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
private
|
51
|
+
|
52
|
+
# next locations' candidates sorted by priority
|
53
|
+
# 1. look up location with key
|
54
|
+
# 2. fallback to other key
|
55
|
+
# 3. skip the key and go to child location
|
56
|
+
def next_location_cadidates(location, key)
|
57
|
+
[
|
58
|
+
location[key.symbol],
|
59
|
+
Searcher.fallback? && key.fallback && location[key.fallback],
|
60
|
+
Searcher.skip? && key.skippable && location
|
61
|
+
].compact
|
62
|
+
end
|
63
|
+
|
64
|
+
class << self
|
65
|
+
def fallback?
|
66
|
+
@fallback
|
67
|
+
end
|
68
|
+
|
69
|
+
def skip?
|
70
|
+
@skip
|
71
|
+
end
|
72
|
+
|
73
|
+
# switch context for fallback
|
74
|
+
def fallback(&block)
|
75
|
+
@fallback = true
|
76
|
+
result = block.call
|
77
|
+
@fallback = false
|
78
|
+
result
|
79
|
+
end
|
80
|
+
|
81
|
+
def skip(&block)
|
82
|
+
@skip = true
|
83
|
+
result = block.call
|
84
|
+
@skip = false
|
85
|
+
result
|
86
|
+
end
|
87
|
+
end
|
88
|
+
end
|
89
|
+
end
|
90
|
+
end
|
data/lib/fusuma/device.rb
CHANGED
@@ -59,7 +59,9 @@ module Fusuma
|
|
59
59
|
# @return [Array]
|
60
60
|
def fetch_devices
|
61
61
|
line_parser = LineParser.new
|
62
|
-
|
62
|
+
|
63
|
+
libinput_command = Plugin::Inputs::LibinputCommandInput.new.command
|
64
|
+
libinput_command.list_devices do |line|
|
63
65
|
line_parser.push(line)
|
64
66
|
end
|
65
67
|
line_parser.generate_devices
|
data/lib/fusuma/environment.rb
CHANGED
@@ -17,8 +17,9 @@ module Fusuma
|
|
17
17
|
end
|
18
18
|
|
19
19
|
def print_version
|
20
|
+
libinput_command = Plugin::Inputs::LibinputCommandInput.new.command
|
20
21
|
MultiLogger.info "Fusuma: #{VERSION}"
|
21
|
-
MultiLogger.info "libinput: #{
|
22
|
+
MultiLogger.info "libinput: #{libinput_command.version}"
|
22
23
|
MultiLogger.info "OS: #{`uname -rsv`}".strip
|
23
24
|
MultiLogger.info "Distribution: #{`cat /etc/issue`}".strip
|
24
25
|
MultiLogger.info "Desktop session: #{`echo $DESKTOP_SESSION $XDG_SESSION_TYPE`}".strip
|
@@ -1,7 +1,6 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require '
|
4
|
-
require 'timeout'
|
3
|
+
require 'posix/spawn'
|
5
4
|
|
6
5
|
module Fusuma
|
7
6
|
# Execute libinput command
|
@@ -34,32 +33,29 @@ module Fusuma
|
|
34
33
|
def list_devices
|
35
34
|
cmd = list_devices_command
|
36
35
|
MultiLogger.debug(list_devices: cmd)
|
37
|
-
|
38
|
-
|
39
|
-
|
36
|
+
p, i, o, e = POSIX::Spawn.popen4(cmd)
|
37
|
+
i.close
|
38
|
+
o.each { |line| yield(line) }
|
39
|
+
ensure
|
40
|
+
[i, o, e].each { |io| io.close unless io.closed? }
|
41
|
+
Process.waitpid(p)
|
40
42
|
end
|
41
43
|
|
42
|
-
# @
|
44
|
+
# @return [String] return a latest line libinput debug-events
|
43
45
|
def debug_events
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
o.readline.chomp
|
50
|
-
end
|
51
|
-
rescue Timeout::Error
|
52
|
-
TIMEOUT_MESSAGE
|
53
|
-
end
|
54
|
-
yield(line)
|
55
|
-
end
|
56
|
-
end
|
46
|
+
@debug_events ||= begin
|
47
|
+
_p, i, o, _e = POSIX::Spawn.popen4(debug_events_with_options)
|
48
|
+
i.close
|
49
|
+
o
|
50
|
+
end
|
57
51
|
end
|
58
52
|
|
59
53
|
# @return [String] command
|
60
54
|
# @raise [SystemExit]
|
61
55
|
def version_command
|
62
|
-
if
|
56
|
+
if @debug_events_command && @list_devices_command
|
57
|
+
"#{@list_devices_command} --version"
|
58
|
+
elsif which('libinput')
|
63
59
|
'libinput --version'
|
64
60
|
elsif which('libinput-list-devices')
|
65
61
|
'libinput-list-devices --version'
|
@@ -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
|
@@ -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
|
@@ -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
|
@@ -20,18 +20,23 @@ module Fusuma
|
|
20
20
|
}
|
21
21
|
end
|
22
22
|
|
23
|
-
|
24
|
-
|
23
|
+
# @return [IO]
|
24
|
+
def io
|
25
|
+
@io ||= command.debug_events
|
26
|
+
end
|
27
|
+
|
28
|
+
# @return [LibinputCommand]
|
29
|
+
def command
|
30
|
+
@command ||= LibinputCommand.new(
|
25
31
|
libinput_options: libinput_options,
|
26
32
|
commands: {
|
27
33
|
debug_events_command: debug_events_command,
|
28
34
|
list_devices_command: list_devices_command
|
29
35
|
}
|
30
|
-
)
|
31
|
-
yield event(record: line)
|
32
|
-
end
|
36
|
+
)
|
33
37
|
end
|
34
38
|
|
39
|
+
# @return [Array]
|
35
40
|
def libinput_options
|
36
41
|
device = ("--device='#{config_params(:device)}'" if config_params(:device))
|
37
42
|
enable_tap = '--enable-tap' if config_params(:'enable-tap')
|
@@ -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-07
|
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:
|
@@ -200,6 +60,7 @@ files:
|
|
200
60
|
- lib/fusuma/config.rb
|
201
61
|
- lib/fusuma/config.yml
|
202
62
|
- lib/fusuma/config/index.rb
|
63
|
+
- lib/fusuma/config/searcher.rb
|
203
64
|
- lib/fusuma/config/yaml_duplication_checker.rb
|
204
65
|
- lib/fusuma/device.rb
|
205
66
|
- lib/fusuma/environment.rb
|
@@ -208,6 +69,7 @@ files:
|
|
208
69
|
- lib/fusuma/plugin/base.rb
|
209
70
|
- lib/fusuma/plugin/buffers/buffer.rb
|
210
71
|
- lib/fusuma/plugin/buffers/gesture_buffer.rb
|
72
|
+
- lib/fusuma/plugin/buffers/timer_buffer.rb
|
211
73
|
- lib/fusuma/plugin/detectors/detector.rb
|
212
74
|
- lib/fusuma/plugin/detectors/pinch_detector.rb
|
213
75
|
- lib/fusuma/plugin/detectors/rotate_detector.rb
|
@@ -224,6 +86,7 @@ files:
|
|
224
86
|
- lib/fusuma/plugin/filters/libinput_timeout_filter.rb
|
225
87
|
- lib/fusuma/plugin/inputs/input.rb
|
226
88
|
- lib/fusuma/plugin/inputs/libinput_command_input.rb
|
89
|
+
- lib/fusuma/plugin/inputs/timer_input.rb
|
227
90
|
- lib/fusuma/plugin/manager.rb
|
228
91
|
- lib/fusuma/plugin/parsers/libinput_gesture_parser.rb
|
229
92
|
- lib/fusuma/plugin/parsers/parser.rb
|
@@ -233,7 +96,7 @@ licenses:
|
|
233
96
|
- MIT
|
234
97
|
metadata:
|
235
98
|
yard.run: yri
|
236
|
-
post_install_message:
|
99
|
+
post_install_message:
|
237
100
|
rdoc_options: []
|
238
101
|
require_paths:
|
239
102
|
- lib
|
@@ -244,12 +107,12 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
244
107
|
version: '2.3'
|
245
108
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
246
109
|
requirements:
|
247
|
-
- - "
|
110
|
+
- - ">"
|
248
111
|
- !ruby/object:Gem::Version
|
249
|
-
version:
|
112
|
+
version: 1.3.1
|
250
113
|
requirements: []
|
251
|
-
rubygems_version: 3.
|
252
|
-
signing_key:
|
114
|
+
rubygems_version: 3.1.4
|
115
|
+
signing_key:
|
253
116
|
specification_version: 4
|
254
117
|
summary: Multitouch gestures with libinput dirver on X11, Linux
|
255
118
|
test_files: []
|