fusuma 3.5.0 → 3.6.1
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/README.md +9 -9
- data/lib/fusuma/config/yaml_duplication_checker.rb +1 -8
- data/lib/fusuma/config.rb +3 -1
- data/lib/fusuma/device.rb +1 -1
- data/lib/fusuma/libinput_command.rb +2 -6
- data/lib/fusuma/multi_logger.rb +21 -18
- data/lib/fusuma/plugin/buffers/gesture_buffer.rb +1 -1
- data/lib/fusuma/plugin/detectors/detector.rb +1 -1
- data/lib/fusuma/plugin/detectors/hold_detector.rb +3 -3
- data/lib/fusuma/plugin/detectors/pinch_detector.rb +2 -2
- data/lib/fusuma/plugin/detectors/rotate_detector.rb +2 -2
- data/lib/fusuma/plugin/detectors/swipe_detector.rb +2 -2
- data/lib/fusuma/plugin/events/event.rb +2 -2
- data/lib/fusuma/plugin/events/records/gesture_record.rb +1 -1
- data/lib/fusuma/plugin/events/records/index_record.rb +2 -2
- data/lib/fusuma/plugin/inputs/input.rb +1 -6
- data/lib/fusuma/plugin/inputs/libinput_command_input.rb +1 -3
- data/lib/fusuma/plugin/inputs/timer_input.rb +2 -3
- data/lib/fusuma/version.rb +1 -1
- data/lib/fusuma.rb +8 -7
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: f8ebe6dea94f392eb2972323029d8f32ab58735020f0f5af4e70a52f3d80eb13
|
4
|
+
data.tar.gz: 12e77d944ef40cd9daf3c05d8f9b2de2538dd031ef0095395904f9fb4dacc238
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: ccc8856c22dfe28666edf5163913250058b3859925b1eae7e38187663dcdb99c27b24690620a0518192c7342da664683f4821d9b691e1929d1c3472d5e208699
|
7
|
+
data.tar.gz: c88048e832b387171cc3ef49f015564f8b1bfc19058eaa8e9bf54e4b79a90199c0652df7c4936b3a01eea363cb26718fbb6fc839700ef10d7c407835010a2642
|
data/README.md
CHANGED
@@ -11,10 +11,10 @@ This gem makes your linux able to recognize swipes or pinchs and assign commands
|
|
11
11
|
## Features
|
12
12
|
|
13
13
|
- Easy installation with RubyGems
|
14
|
-
-
|
15
|
-
- Sensitivity
|
16
|
-
- Automatic
|
17
|
-
-
|
14
|
+
- Define gestures and actions in YAML format
|
15
|
+
- Sensitivity settings (threshold, interval) for gesture recognition
|
16
|
+
- Automatic addition of external touchpads
|
17
|
+
- Feature extension via a [plugin system](https://github.com/iberianpig/fusuma/#fusuma-plugins)
|
18
18
|
|
19
19
|
## Installation
|
20
20
|
|
@@ -35,9 +35,9 @@ newgrp input
|
|
35
35
|
**IMPORTANT**: This makes `/dev/input/` readable, so if that's an issue for you for some reason (like for privacy- or securityconcerns etc. or if it causes other parts of your OS to misbehave), **consider this your heads-up.**
|
36
36
|
|
37
37
|
<details>
|
38
|
-
<summary>For Debian Based Distros (Ubuntu, Debian, Mint, Pop!
|
38
|
+
<summary>For Debian Based Distros (Ubuntu, Debian, Mint, Pop!_OS)</summary>
|
39
39
|
|
40
|
-
### For Debian Based Distros (Ubuntu, Debian, Mint, Pop!
|
40
|
+
### For Debian Based Distros (Ubuntu, Debian, Mint, Pop!_OS)
|
41
41
|
|
42
42
|
#### 1. Install libinput-tools
|
43
43
|
|
@@ -258,8 +258,8 @@ The following wiki pages can be edited by everyone.
|
|
258
258
|
- [elementary OS](https://github.com/iberianpig/fusuma/wiki/elementary-OS)
|
259
259
|
- [i3](https://github.com/iberianpig/fusuma/wiki/i3)
|
260
260
|
- [KDE to mimic MacOS](https://github.com/iberianpig/fusuma/wiki/KDE-to-mimic-MacOS)
|
261
|
-
- [
|
262
|
-
- [
|
261
|
+
- [Pop!_OS with Cinnamon](https://github.com/iberianpig/fusuma/wiki/POP-OS-with-Cinnamon)
|
262
|
+
- [Pop!_OS Default Gnome](https://github.com/iberianpig/fusuma/wiki/PopOS-Default-Gnome)
|
263
263
|
- [Ubuntu OS to mimic Mac a little](https://github.com/iberianpig/fusuma/wiki/Ubuntu-OS-to-mimic-Mac-a-little)
|
264
264
|
- [3 fingers Drag (OS X Style)](https://github.com/iberianpig/fusuma/wiki/3-fingers-Drag-(OS-X-Style))
|
265
265
|
- [3 fingers Alt Tab Switcher(Windows Style)](https://github.com/iberianpig/fusuma/wiki/3-fingers-Alt-Tab-Switcher(Windows-Style))
|
@@ -420,7 +420,7 @@ sudo gem list fusuma-plugin- | cut -d' ' -f1 | xargs --no-run-if-empty sudo gem
|
|
420
420
|
|
421
421
|
## Tutorial Video
|
422
422
|
|
423
|
-
[](http://www.youtube.com/watch?v=bn11Iwvf29I "Multitouch Touchpad Gestures in Linux with Fusuma")
|
423
|
+
[](http://www.youtube.com/watch?v=bn11Iwvf29I "Multitouch Touchpad Gestures in Linux with Fusuma")
|
424
424
|
[Multitouch Touchpad Gestures in Linux with Fusuma](http://www.youtube.com/watch?v=bn11Iwvf29I) by [Eric Adams](https://www.youtube.com/user/igster75)
|
425
425
|
|
426
426
|
## Support
|
@@ -6,14 +6,7 @@ module Fusuma
|
|
6
6
|
# Find duplicated keys from YAML.
|
7
7
|
module YAMLDuplicationChecker
|
8
8
|
def self.check(yaml_string, filename, &on_duplicated)
|
9
|
-
|
10
|
-
tree = if Gem::Version.new(Psych::VERSION) >= Gem::Version.new("3.1.0")
|
11
|
-
# Specify filename to display helpful message when it raises
|
12
|
-
# an error.
|
13
|
-
YAML.parse(yaml_string, filename: filename)
|
14
|
-
else
|
15
|
-
YAML.parse(yaml_string, filename)
|
16
|
-
end
|
9
|
+
tree = YAML.parse(yaml_string, filename: filename)
|
17
10
|
return unless tree
|
18
11
|
|
19
12
|
traverse(tree, &on_duplicated)
|
data/lib/fusuma/config.rb
CHANGED
@@ -100,10 +100,12 @@ module Fusuma
|
|
100
100
|
|
101
101
|
yamls = YAML.load_stream(File.read(path)).compact
|
102
102
|
yamls.map do |yaml|
|
103
|
-
raise InvalidFileError, "
|
103
|
+
raise InvalidFileError, "Invalid config.yml: #{path}" unless yaml.is_a? Hash
|
104
104
|
|
105
105
|
yaml.deep_symbolize_keys
|
106
106
|
end
|
107
|
+
rescue Psych::SyntaxError => e
|
108
|
+
raise InvalidFileError, "Invalid syntax: #{path} #{e.message}"
|
107
109
|
end
|
108
110
|
|
109
111
|
# @param index [Index]
|
data/lib/fusuma/device.rb
CHANGED
@@ -66,7 +66,7 @@ module Fusuma
|
|
66
66
|
line_parser = LineParser.new
|
67
67
|
|
68
68
|
libinput_command = Plugin::Inputs::LibinputCommandInput.new.command
|
69
|
-
# note: this libinput command takes a nontrivial
|
69
|
+
# note: this libinput command takes a nontrivial amount of time (~200ms)
|
70
70
|
libinput_command.list_devices do |line|
|
71
71
|
line_parser.push(line)
|
72
72
|
end
|
@@ -22,7 +22,7 @@ module Fusuma
|
|
22
22
|
|
23
23
|
# @return [String]
|
24
24
|
def version
|
25
|
-
#
|
25
|
+
# version_command prints "1.6.3\n"
|
26
26
|
@version ||= `#{version_command}`.strip
|
27
27
|
end
|
28
28
|
|
@@ -39,11 +39,7 @@ module Fusuma
|
|
39
39
|
|
40
40
|
# @return [Integer] return a latest line libinput debug-events
|
41
41
|
def debug_events(writer)
|
42
|
-
|
43
|
-
t = Open3.pipeline_start([debug_events_with_options], ["grep -v POINTER_ --line-buffered"],
|
44
|
-
out: writer, in: "/dev/null")
|
45
|
-
t[0].pid
|
46
|
-
end
|
42
|
+
Open3.pipeline_start([debug_events_with_options], ["grep -v POINTER_ --line-buffered"], out: writer, in: "/dev/null")
|
47
43
|
end
|
48
44
|
|
49
45
|
# @return [String] command
|
data/lib/fusuma/multi_logger.rb
CHANGED
@@ -13,6 +13,22 @@ module Fusuma
|
|
13
13
|
|
14
14
|
class << self
|
15
15
|
attr_writer :filepath
|
16
|
+
|
17
|
+
def info(msg)
|
18
|
+
instance.info(msg)
|
19
|
+
end
|
20
|
+
|
21
|
+
def debug(msg)
|
22
|
+
instance.debug(msg)
|
23
|
+
end
|
24
|
+
|
25
|
+
def warn(msg)
|
26
|
+
instance.warn(msg)
|
27
|
+
end
|
28
|
+
|
29
|
+
def error(msg)
|
30
|
+
instance.error(msg)
|
31
|
+
end
|
16
32
|
end
|
17
33
|
|
18
34
|
def initialize
|
@@ -49,8 +65,11 @@ module Fusuma
|
|
49
65
|
debug_mode
|
50
66
|
end
|
51
67
|
|
68
|
+
private
|
69
|
+
|
52
70
|
def ignore_pattern?(msg)
|
53
71
|
# TODO: configurable from config.yml
|
72
|
+
# pattern = /timer_input|remap_touchpad_input|thumbsense context|libinput_command_input/
|
54
73
|
pattern = /timer_input/
|
55
74
|
case msg
|
56
75
|
when Hash
|
@@ -58,27 +77,11 @@ module Fusuma
|
|
58
77
|
return unless e
|
59
78
|
|
60
79
|
e.tag.match?(pattern)
|
80
|
+
when String
|
81
|
+
msg.match?(pattern)
|
61
82
|
else
|
62
83
|
false
|
63
84
|
end
|
64
85
|
end
|
65
|
-
|
66
|
-
class << self
|
67
|
-
def info(msg)
|
68
|
-
instance.info(msg)
|
69
|
-
end
|
70
|
-
|
71
|
-
def debug(msg)
|
72
|
-
instance.debug(msg)
|
73
|
-
end
|
74
|
-
|
75
|
-
def warn(msg)
|
76
|
-
instance.warn(msg)
|
77
|
-
end
|
78
|
-
|
79
|
-
def error(msg)
|
80
|
-
instance.error(msg)
|
81
|
-
end
|
82
|
-
end
|
83
86
|
end
|
84
87
|
end
|
@@ -12,10 +12,10 @@ module Fusuma
|
|
12
12
|
BUFFER_TYPE = "gesture"
|
13
13
|
GESTURE_RECORD_TYPE = "hold"
|
14
14
|
|
15
|
-
|
15
|
+
BASE_THRESHOLD = 0.7
|
16
16
|
|
17
17
|
def initialize(*args)
|
18
|
-
super
|
18
|
+
super
|
19
19
|
@timer = Inputs::TimerInput.instance
|
20
20
|
end
|
21
21
|
|
@@ -134,7 +134,7 @@ module Fusuma
|
|
134
134
|
keys_global = Config::Index.new ["threshold", type]
|
135
135
|
config_value = Config.search(keys_specific) ||
|
136
136
|
Config.search(keys_global) || 1
|
137
|
-
|
137
|
+
BASE_THRESHOLD * config_value
|
138
138
|
end
|
139
139
|
end
|
140
140
|
end
|
@@ -11,7 +11,7 @@ module Fusuma
|
|
11
11
|
GESTURE_RECORD_TYPE = "pinch"
|
12
12
|
|
13
13
|
FINGERS = [2, 3, 4].freeze
|
14
|
-
|
14
|
+
BASE_THRESHOLD = 1.3
|
15
15
|
|
16
16
|
# @param buffers [Array<Buffer>]
|
17
17
|
# @return [Events::Event] if event is detected
|
@@ -141,7 +141,7 @@ module Fusuma
|
|
141
141
|
keys_global = Config::Index.new ["threshold", type]
|
142
142
|
config_value = Config.search(keys_specific) ||
|
143
143
|
Config.search(keys_global) || 1
|
144
|
-
|
144
|
+
BASE_THRESHOLD * config_value
|
145
145
|
end
|
146
146
|
end
|
147
147
|
|
@@ -11,7 +11,7 @@ module Fusuma
|
|
11
11
|
GESTURE_RECORD_TYPE = "pinch"
|
12
12
|
|
13
13
|
FINGERS = [2, 3, 4].freeze
|
14
|
-
|
14
|
+
BASE_THRESHOLD = 0.5
|
15
15
|
|
16
16
|
# @param buffers [Array<Buffer>]
|
17
17
|
# @return [Events::Event] if event is detected
|
@@ -126,7 +126,7 @@ module Fusuma
|
|
126
126
|
keys_global = Config::Index.new ["threshold", type]
|
127
127
|
config_value = Config.search(keys_specific) ||
|
128
128
|
Config.search(keys_global) || 1
|
129
|
-
|
129
|
+
BASE_THRESHOLD * config_value
|
130
130
|
end
|
131
131
|
end
|
132
132
|
|
@@ -11,7 +11,7 @@ module Fusuma
|
|
11
11
|
GESTURE_RECORD_TYPE = "swipe"
|
12
12
|
|
13
13
|
FINGERS = [3, 4].freeze
|
14
|
-
|
14
|
+
BASE_THRESHOLD = 25
|
15
15
|
|
16
16
|
# @param buffers [Array<Buffers::Buffer>]
|
17
17
|
# @return [Events::Event] if event is detected
|
@@ -124,7 +124,7 @@ module Fusuma
|
|
124
124
|
keys_global = Config::Index.new ["threshold", type]
|
125
125
|
config_value = Config.search(keys_specific) ||
|
126
126
|
Config.search(keys_global) || 1
|
127
|
-
|
127
|
+
BASE_THRESHOLD * config_value
|
128
128
|
end
|
129
129
|
end
|
130
130
|
|
@@ -26,12 +26,12 @@ module Fusuma
|
|
26
26
|
Records::TextRecord.new(record)
|
27
27
|
else
|
28
28
|
raise ArgumentError,
|
29
|
-
"@record should be String or Record"
|
29
|
+
"@record should be String or Record: #{record.class}, #{record}"
|
30
30
|
end
|
31
31
|
end
|
32
32
|
|
33
33
|
def inspect
|
34
|
-
"
|
34
|
+
"tag: #{tag}, record: #{record}"
|
35
35
|
end
|
36
36
|
end
|
37
37
|
end
|
@@ -36,7 +36,7 @@ module Fusuma
|
|
36
36
|
# @return [NilClass] when merge is not succeeded
|
37
37
|
def merge(records:, index: @index)
|
38
38
|
# FIXME: cache
|
39
|
-
raise "position is NOT body: #{self}" unless
|
39
|
+
raise "position is NOT body: #{self}" unless mergeable?
|
40
40
|
|
41
41
|
if records.empty?
|
42
42
|
if Config.instance.find_execute_key(index)
|
@@ -76,7 +76,7 @@ module Fusuma
|
|
76
76
|
end
|
77
77
|
end
|
78
78
|
|
79
|
-
def
|
79
|
+
def mergeable?
|
80
80
|
@position == :body
|
81
81
|
end
|
82
82
|
end
|
@@ -10,7 +10,7 @@ module Fusuma
|
|
10
10
|
# @abstract Subclass and override {#io} to implement
|
11
11
|
class Input < Base
|
12
12
|
def initialize(*args)
|
13
|
-
super
|
13
|
+
super
|
14
14
|
@tag = self.class.name.split("Inputs::").last.underscore
|
15
15
|
end
|
16
16
|
|
@@ -43,11 +43,6 @@ module Fusuma
|
|
43
43
|
exit 1
|
44
44
|
end
|
45
45
|
|
46
|
-
# @return [Integer]
|
47
|
-
def pid
|
48
|
-
raise NotImplementedError, "override #{self.class.name}##{__method__}"
|
49
|
-
end
|
50
|
-
|
51
46
|
# @return [IO]
|
52
47
|
def io
|
53
48
|
raise NotImplementedError, "override #{self.class.name}##{__method__}"
|
@@ -8,8 +8,6 @@ module Fusuma
|
|
8
8
|
module Inputs
|
9
9
|
# libinput commands wrapper
|
10
10
|
class LibinputCommandInput < Input
|
11
|
-
attr_reader :pid
|
12
|
-
|
13
11
|
def config_param_types
|
14
12
|
{
|
15
13
|
device: [String],
|
@@ -27,7 +25,7 @@ module Fusuma
|
|
27
25
|
def io
|
28
26
|
@io ||= begin
|
29
27
|
reader, writer = create_io
|
30
|
-
|
28
|
+
command.debug_events(writer)
|
31
29
|
reader
|
32
30
|
end
|
33
31
|
end
|
@@ -23,12 +23,12 @@ module Fusuma
|
|
23
23
|
@early_wake_queue = Queue.new
|
24
24
|
end
|
25
25
|
|
26
|
-
attr_reader :
|
26
|
+
attr_reader :interval
|
27
27
|
|
28
28
|
def io
|
29
29
|
@io ||= begin
|
30
30
|
reader, writer = create_io
|
31
|
-
|
31
|
+
start(reader, writer)
|
32
32
|
|
33
33
|
reader
|
34
34
|
end
|
@@ -38,7 +38,6 @@ module Fusuma
|
|
38
38
|
Thread.new do
|
39
39
|
timer_loop(writer)
|
40
40
|
end
|
41
|
-
nil
|
42
41
|
end
|
43
42
|
|
44
43
|
def timer_loop(writer)
|
data/lib/fusuma/version.rb
CHANGED
data/lib/fusuma.rb
CHANGED
@@ -15,14 +15,13 @@ module Fusuma
|
|
15
15
|
def run(option = {})
|
16
16
|
read_options(option)
|
17
17
|
instance = new
|
18
|
+
instance.initialize_plugins
|
18
19
|
instance.set_trap
|
19
20
|
## NOTE: Uncomment following line to measure performance
|
20
21
|
# instance.run_with_lineprof
|
21
22
|
instance.run
|
22
|
-
|
23
|
-
|
24
|
-
MultiLogger.error(e)
|
25
|
-
instance.send(:shutdown)
|
23
|
+
ensure
|
24
|
+
instance&.send(:shutdown)
|
26
25
|
end
|
27
26
|
|
28
27
|
private
|
@@ -59,7 +58,9 @@ module Fusuma
|
|
59
58
|
end
|
60
59
|
end
|
61
60
|
|
62
|
-
def initialize
|
61
|
+
def initialize; end
|
62
|
+
|
63
|
+
def initialize_plugins
|
63
64
|
@inputs = Plugin::Inputs::Input.plugins.map do |cls|
|
64
65
|
cls.ancestors.include?(Singleton) ? cls.instance : cls.new
|
65
66
|
end
|
@@ -147,7 +148,7 @@ module Fusuma
|
|
147
148
|
# @return [NilClass] when event is NOT given
|
148
149
|
def merge(events)
|
149
150
|
index_events, context_events = events.partition { |event| event.record.type == :index }
|
150
|
-
main_events, modifiers = index_events.partition { |event| event.record.
|
151
|
+
main_events, modifiers = index_events.partition { |event| event.record.mergeable? }
|
151
152
|
request_context = context_events.each_with_object({}) do |e, results|
|
152
153
|
results[e.record.name] = e.record.value
|
153
154
|
end
|
@@ -206,7 +207,7 @@ module Fusuma
|
|
206
207
|
private
|
207
208
|
|
208
209
|
def shutdown
|
209
|
-
[@inputs, @filters, @parsers, @buffers, @detectors, @executors].flatten.each do |plugin|
|
210
|
+
[@inputs, @filters, @parsers, @buffers, @detectors, @executors].flatten.compact.each do |plugin|
|
210
211
|
plugin.shutdown
|
211
212
|
end
|
212
213
|
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: 3.
|
4
|
+
version: 3.6.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- iberianpig
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2024-
|
11
|
+
date: 2024-08-19 00:00:00.000000000 Z
|
12
12
|
dependencies: []
|
13
13
|
description: Fusuma is multitouch gesture recognizer. This gem makes your touchpad
|
14
14
|
on Linux able to recognize swipes or pinchs and assign command to them. Read installation
|