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.
Files changed (47) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +8 -5
  3. data/.rubocop_todo.yml +34 -19
  4. data/.solargraph.yml +16 -0
  5. data/.travis.yml +1 -3
  6. data/CHANGELOG.md +1 -1
  7. data/Gemfile +6 -1
  8. data/README.md +43 -5
  9. data/fusuma.gemspec +3 -2
  10. data/lib/fusuma.rb +87 -33
  11. data/lib/fusuma/config.rb +33 -40
  12. data/lib/fusuma/config/index.rb +34 -8
  13. data/lib/fusuma/config/searcher.rb +78 -4
  14. data/lib/fusuma/custom_process.rb +13 -0
  15. data/lib/fusuma/device.rb +19 -6
  16. data/lib/fusuma/environment.rb +3 -3
  17. data/lib/fusuma/hash_support.rb +40 -0
  18. data/lib/fusuma/libinput_command.rb +8 -8
  19. data/lib/fusuma/multi_logger.rb +2 -6
  20. data/lib/fusuma/plugin/base.rb +18 -15
  21. data/lib/fusuma/plugin/buffers/buffer.rb +3 -2
  22. data/lib/fusuma/plugin/buffers/gesture_buffer.rb +34 -25
  23. data/lib/fusuma/plugin/buffers/timer_buffer.rb +3 -3
  24. data/lib/fusuma/plugin/detectors/detector.rb +26 -5
  25. data/lib/fusuma/plugin/detectors/pinch_detector.rb +109 -58
  26. data/lib/fusuma/plugin/detectors/rotate_detector.rb +91 -50
  27. data/lib/fusuma/plugin/detectors/swipe_detector.rb +93 -56
  28. data/lib/fusuma/plugin/events/event.rb +5 -4
  29. data/lib/fusuma/plugin/events/records/context_record.rb +27 -0
  30. data/lib/fusuma/plugin/events/records/gesture_record.rb +9 -6
  31. data/lib/fusuma/plugin/events/records/index_record.rb +46 -14
  32. data/lib/fusuma/plugin/events/records/record.rb +1 -1
  33. data/lib/fusuma/plugin/events/records/text_record.rb +2 -1
  34. data/lib/fusuma/plugin/executors/command_executor.rb +20 -3
  35. data/lib/fusuma/plugin/executors/executor.rb +45 -3
  36. data/lib/fusuma/plugin/filters/filter.rb +1 -1
  37. data/lib/fusuma/plugin/filters/libinput_device_filter.rb +6 -7
  38. data/lib/fusuma/plugin/filters/libinput_timeout_filter.rb +2 -2
  39. data/lib/fusuma/plugin/inputs/input.rb +19 -7
  40. data/lib/fusuma/plugin/inputs/libinput_command_input.rb +10 -5
  41. data/lib/fusuma/plugin/inputs/timer_input.rb +7 -7
  42. data/lib/fusuma/plugin/manager.rb +10 -28
  43. data/lib/fusuma/plugin/parsers/libinput_gesture_parser.rb +10 -8
  44. data/lib/fusuma/plugin/parsers/parser.rb +8 -9
  45. data/lib/fusuma/string_support.rb +16 -0
  46. data/lib/fusuma/version.rb +1 -1
  47. metadata +13 -8
@@ -1,6 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require_relative '../base.rb'
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
- # execute somthing
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,6 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require_relative '../base.rb'
3
+ require_relative '../base'
4
4
 
5
5
  module Fusuma
6
6
  module Plugin
@@ -1,7 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require_relative './filter.rb'
4
- require_relative '../../device.rb'
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
- from_config = Array(config_params(:keep_device_names))
35
- KeepDevice.new(name_patterns: from_config)
36
- end
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 './filter.rb'
4
- require_relative '../../libinput_command.rb'
3
+ require_relative './filter'
4
+ require_relative '../../libinput_command'
5
5
 
6
6
  module Fusuma
7
7
  module Plugin
@@ -1,7 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require_relative '../base.rb'
4
- require_relative '../events/event.rb'
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).tap do |e|
40
- MultiLogger.debug(input_event: e)
41
- end
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.rb'
4
- require_relative './input.rb'
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
- 'device': [String],
15
+ device: [String],
14
16
  'enable-dwt': [TrueClass, FalseClass],
15
17
  'enable-tap': [TrueClass, FalseClass],
16
18
  'show-keycodes': [TrueClass, FalseClass],
17
- 'verbose': [TrueClass, FalseClass],
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 ||= command.debug_events
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.rb'
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
- 'interval': [Float]
13
+ interval: [Float]
14
14
  }
15
15
  end
16
16
 
17
- attr_reader :writer
17
+ attr_reader :pid
18
18
 
19
19
  def io
20
20
  @io ||= begin
21
- reader, writer = create_io
22
- @pid = start(reader, writer)
21
+ reader, writer = create_io
22
+ @pid = start(reader, writer)
23
23
 
24
- reader
25
- end
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
- require 'pathname'
4
- require_relative '../multi_logger.rb'
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.rb'
62
- require_relative './events/event.rb'
63
- require_relative './inputs/input.rb'
64
- require_relative './filters/filter.rb'
65
- require_relative './parsers/parser.rb'
66
- require_relative './buffers/buffer.rb'
67
- require_relative './detectors/detector.rb'
68
- require_relative './executors/executor.rb'
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.rb'
4
- require_relative '../events/records/gesture_record.rb'
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, direction = parse_libinput(line)
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
- direction: direction)
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
- direction = parse_direction(other)
36
- [*detect_gesture(event_name), finger, direction]
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 parse_direction(line)
44
+ def parse_delta(line)
45
45
  return if line.nil?
46
46
 
47
- move_x, move_y, _, _, _, zoom, _, rotate = line.tr('/|(|)', ' ').split
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.rb'
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.tap do |e|
17
- next if e.tag != source
16
+ return event if event.tag != source
18
17
 
19
- new_record = parse_record(e.record)
20
- next unless new_record
18
+ new_record = parse_record(event.record)
19
+ return event if new_record.nil?
21
20
 
22
- e.record = new_record
23
- e.tag = tag
24
- end
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
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Fusuma
4
- VERSION = '2.0.0.pre'
4
+ VERSION = '2.0.0.pre2'
5
5
  end
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.pre
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: 2020-11-07 00:00:00.000000000 Z
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: '2.3'
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.1.4
115
- signing_key:
119
+ rubygems_version: 3.2.15
120
+ signing_key:
116
121
  specification_version: 4
117
- summary: Multitouch gestures with libinput dirver on X11, Linux
122
+ summary: Multitouch gestures with libinput driver on X11, Linux
118
123
  test_files: []