fusuma 2.0.4 → 2.0.5

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 8f19305771a0704b1f7294b9b54653f09d7d4f6153ffbdd19a6c23a753870b09
4
- data.tar.gz: 3b6c9addcda816e7379e69bb258bd11f091ea39fbae37fc8e0ef4c9ca4b7dff7
3
+ metadata.gz: e9b2c355ba50b2c62cf23f7c8975d50485710a67b76ffe5a904f67a043c0cac4
4
+ data.tar.gz: 655c8dcbc527e11a2a8883391ec3970af2081285d54332da975ddd8015117186
5
5
  SHA512:
6
- metadata.gz: 422dc7e58b8db650754c4939ec1946456bfdfb0a8e4af33d79a20d88d84190f393952e05e1d086f711fb1ee2e6c415c4ddf6861dba8d94bf84df4f4e0585374f
7
- data.tar.gz: 02e75550adfd4a6f3e3d43b4a6326377d5182131bdd9d9f3ff3ca0abcb89888e0bca9eea8551868cc87edb0a706fb9b51ee97cc517e093566c7448729359ded2
6
+ metadata.gz: 7740116f70ca83b977820801c0c2e4b49cd358d2df040710b1a0fa4c75b10cdb9713f932afb08f543c7ec35ae52f4bd3ab141cdf064914fa0e57d19d49443abb
7
+ data.tar.gz: c53b8ec89c8aabd9c0d32674345472ca0814a559a99a14eb001a9eaea6447de7ef955bccfa5ee29cb9b9b3dfbcab5bc550afa479b26600e5b6f0a979c29dd53d
data/README.md CHANGED
@@ -3,7 +3,7 @@
3
3
  Fusuma is multitouch gesture recognizer.
4
4
  This gem makes your linux able to recognize swipes or pinchs and assign commands to them.
5
5
 
6
- ![fusuma_image](https://i.gyazo.com/757fef526310b9d68f68e80eb1e4540f.png)
6
+ ![fusuma_image](https://repository-images.githubusercontent.com/69813387/60879a00-166c-11ea-9875-3bf0818c62ec)
7
7
 
8
8
  襖(Fusuma) means sliding door used to partition off rooms in a Japanese house.
9
9
 
@@ -83,7 +83,7 @@ $ sudo pacman -S ruby
83
83
 
84
84
  #### 3. Install Fusuma
85
85
 
86
- **Note:** By default in Arch Linux, when running ```gem```, gems are installed per-user (into ```~/.gem/ruby/```), instead of system-wide (into ```/usr/lib/ruby/gems/```). This is considered the best way to manage gems on Arch, because otherwise they might interfere with gems installed by Pacman. (From Arch Wiki)
86
+ **Note:** By default in Arch Linux, when running `gem`, gems are installed per-user (into `~/.gem/ruby/`), instead of system-wide (into `/usr/lib/ruby/gems/`). This is considered the best way to manage gems on Arch, because otherwise they might interfere with gems installed by Pacman. (From Arch Wiki)
87
87
 
88
88
  To install gems system-wide, see any of the methods listed on [Arch Wiki](https://wiki.archlinux.org/index.php/ruby#Installing_gems_system-wide)
89
89
 
@@ -121,7 +121,7 @@ $ sudo gem update fusuma
121
121
 
122
122
  ## Customize Gesture Mapping
123
123
 
124
- You can customize the settings for gestures to put and edit `~/.config/fusuma/config.yml`.
124
+ You can customize the settings for gestures to put and edit `~/.config/fusuma/config.yml`.
125
125
  **NOTE: You will need to create the `~/.config/fusuma` directory if it doesn't exist yet.**
126
126
 
127
127
  ```bash
@@ -135,12 +135,15 @@ $ nano ~/.config/fusuma/config.yml # edit config file.
135
135
  * `swipe:`
136
136
  * support `3:`, `4:` fingers
137
137
  * support `left:`, `right:`, `up:`, `down:` directions
138
+ * support `begin:`, `update:`, `end:` events
138
139
  * `pinch:`
139
140
  * support `2:`, `3:`, `4:` fingers
140
141
  * support `in:`, `out:` directions
142
+ * support `begin:`, `update:`, `end:` events
141
143
  * `rotate:`
142
144
  * support `2:`, `3:`, `4:` fingers
143
145
  * support `clockwise:`,`counterclockwise:` directions
146
+ * support `begin:`, `update:`, `end:` events
144
147
 
145
148
  ### About YAML Basic Syntax
146
149
 
@@ -157,7 +160,7 @@ https://github.com/iberianpig/fusuma/wiki/Ubuntu
157
160
  swipe:
158
161
  3:
159
162
  left:
160
- command: "xdotool key alt+Right" # History forward
163
+ command: "xdotool key alt+Right" # History forward
161
164
  right:
162
165
  command: "xdotool key alt+Left" # History back
163
166
  up:
@@ -191,6 +194,8 @@ The following wiki pages can be edited by everyone.
191
194
  - [POP OS with Cinnamon](https://github.com/iberianpig/fusuma/wiki/POP-OS-with-Cinnamon)
192
195
  - [PopOS Default Gnome](https://github.com/iberianpig/fusuma/wiki/PopOS-Default-Gnome)
193
196
  - [Ubuntu OS to mimic Mac a little](https://github.com/iberianpig/fusuma/wiki/Ubuntu-OS-to-mimic-Mac-a-little)
197
+ - [3 fingers Drag (OS X Style)](https://github.com/iberianpig/fusuma/wiki/3-fingers-Drag-(OS-X-Style))
198
+ - [3 fingers Alt Tab Switcher(Windows Style)](https://github.com/iberianpig/fusuma/wiki/3-fingers-Alt-Tab-Switcher(Windows-Style))
194
199
 
195
200
  If you have a nice configuration, please share `~/.config/fusuma/config.yml` with everyone.
196
201
 
@@ -208,19 +213,19 @@ If the swipe's interval is `0.5`, shorten swipe-interval by half to recognize a
208
213
 
209
214
  ```yaml
210
215
  swipe:
211
- 3:
212
- left:
216
+ 3:
217
+ left:
213
218
  command: 'xdotool key alt+Right' # threshold: 0.5, interval: 0.75
214
219
  threshold: 0.5
215
- right:
220
+ right:
216
221
  command: 'xdotool key alt+Left' # threshold: 0.5, interval: 0.75
217
222
  threshold: 0.5
218
- up:
223
+ up:
219
224
  command: 'xdotool key super' # threshold: 1, interval: 0.75
220
- down:
225
+ down:
221
226
  command: 'xdotool key super' # threshold: 1, interval: 0.75
222
227
  pinch:
223
- 2:
228
+ 2:
224
229
  in:
225
230
  command: "xdotool keydown ctrl click 4 keyup ctrl" # threshold: 0.5, interval: 0.5
226
231
  out:
@@ -234,7 +239,7 @@ interval:
234
239
  pinch: 0.5
235
240
  ```
236
241
 
237
- There are three priorities of `threshold:` and `interval:`.
242
+ There are three priorities of `threshold:` and `interval:`.
238
243
  The individual `threshold:` and `interval:` settings (under "direction") have a higher priority than the global one (under "root")
239
244
 
240
245
  1. child elements in the direction (left/right/down/up → threshold/interval)
@@ -280,7 +285,7 @@ swipe:
280
285
  - `xte`
281
286
  - [xte(1) - Linux man page](https://linux.die.net/man/1/xte)
282
287
  - install with `sudo apt xautomation`
283
-
288
+
284
289
  - [ydotool](https://github.com/ReimuNotMoe/ydotool)
285
290
  - Wayland compatible
286
291
  - Needs more maintainers.
@@ -292,7 +297,6 @@ swipe:
292
297
  - `-d`, `--daemon` : Daemonize process
293
298
  - `-l`, `--list-devices` : List available devices
294
299
  - `-v`, `--verbose` : Show details about the results of running fusuma
295
- - `--device="Device name"` : Open the given device only (DEPRECATED)
296
300
  - `--version` : Show fusuma version
297
301
 
298
302
  ### Specify touchpads by device name
@@ -322,7 +326,7 @@ Following features are provided as plugins.
322
326
  - Features for specific Linux distributions
323
327
  - Setting different gestures per applications
324
328
 
325
- ### Installation of fusuma plugins
329
+ ### Installation of Fusuma plugins
326
330
 
327
331
  Fusuma plugins are provided with the `fusuma-plugin-XXXXX` naming convention and hosted on [RubyGems](https://rubygems.org/search?utf8=%E2%9C%93&query=fusuma-plugins).
328
332
 
@@ -340,7 +344,7 @@ Fusuma plugins are provided with the `fusuma-plugin-XXXXX` naming convention and
340
344
 
341
345
  ## Tutorial Video
342
346
 
343
- [![Multitouch Touchpad Gestures in Linux with Fusuma](http://img.youtube.com/vi/bn11Iwvf29I/0.jpg)](http://www.youtube.com/watch?v=bn11Iwvf29I "Multitouch Touchpad Gestures in Linux with Fusuma")
347
+ [![Multitouch Touchpad Gestures in Linux with Fusuma](http://img.youtube.com/vi/bn11Iwvf29I/0.jpg)](http://www.youtube.com/watch?v=bn11Iwvf29I "Multitouch Touchpad Gestures in Linux with Fusuma")
344
348
  [Multitouch Touchpad Gestures in Linux with Fusuma](http://www.youtube.com/watch?v=bn11Iwvf29I) by [Eric Adams](https://www.youtube.com/user/igster75)
345
349
 
346
350
  ## Support
@@ -349,7 +353,7 @@ I'm a Freelance Engineer in Japan and working on these products after finishing
349
353
  Currently, my open-source contribution times is not enough.
350
354
  If you like my work and want to contribute and become a sponsor, I will be able to focus on my projects.
351
355
 
352
- - [GitHub Sponsors](https://github.com/sponsors/iberianpig) (Zero fee!)
356
+ - [GitHub Sponsors](https://github.com/sponsors/iberianpig)
353
357
  - [Patreon](https://www.patreon.com/iberianpig)
354
358
 
355
359
  ## Contributing
data/lib/fusuma.rb CHANGED
@@ -142,19 +142,26 @@ module Fusuma
142
142
  end
143
143
  main_events.sort_by! { |e| e.record.trigger_priority }
144
144
 
145
- condition = nil
145
+ matched_condition = nil
146
146
  matched_context = nil
147
147
  event = main_events.find do |main_event|
148
148
  matched_context = Config::Searcher.find_context(request_context) do
149
- condition, index_record = Config::Searcher.find_condition do
149
+ matched_condition, modified_record = Config::Searcher.find_condition do
150
150
  main_event.record.merge(records: modifiers.map(&:record))
151
151
  end
152
- main_event if index_record
152
+ if matched_condition && modified_record
153
+ main_event.record = modified_record
154
+ else
155
+ matched_condition, = Config::Searcher.find_condition do
156
+ Config.search(main_event.record.index) &&
157
+ Config.find_execute_key(main_event.record.index)
158
+ end
159
+ end
153
160
  end
154
161
  end
155
162
  return if event.nil?
156
163
 
157
- [condition, matched_context, event]
164
+ [matched_condition, matched_context, event]
158
165
  end
159
166
 
160
167
  # @param event [Plugin::Events::Event]
data/lib/fusuma/config.rb CHANGED
@@ -84,7 +84,7 @@ module Fusuma
84
84
  end.flatten
85
85
 
86
86
  execute_params = search(index)
87
- return if execute_params.nil?
87
+ return if execute_params.nil? || !execute_params.is_a?(Hash)
88
88
 
89
89
  @execute_keys.find { |k| execute_params.keys.include?(k) }
90
90
  end
@@ -67,8 +67,7 @@ module Fusuma
67
67
 
68
68
  # next locations' candidates sorted by priority
69
69
  # 1. look up location with key
70
- # 2. fallback to other key
71
- # 3. skip the key and go to child location
70
+ # 2. skip the key and go to child location
72
71
  def next_location_cadidates(location, key)
73
72
  [
74
73
  location[key.symbol],
@@ -20,7 +20,7 @@ module Fusuma
20
20
  libinput_command = Plugin::Inputs::LibinputCommandInput.new.command
21
21
  MultiLogger.info "Fusuma: #{VERSION}"
22
22
  MultiLogger.info "libinput: #{libinput_command.version}"
23
- MultiLogger.info "ruby #{ RUBY_VERSION }p#{ RUBY_PATCHLEVEL }"
23
+ MultiLogger.info "ruby #{RUBY_VERSION}p#{RUBY_PATCHLEVEL}"
24
24
  MultiLogger.info "OS: #{`uname -rsv`}".strip
25
25
  MultiLogger.info "Distribution: #{`cat /etc/issue`}".strip
26
26
  MultiLogger.info "Desktop session: #{`echo $DESKTOP_SESSION $XDG_SESSION_TYPE`}".strip
@@ -8,7 +8,7 @@ module Fusuma
8
8
  # manage events and generate command
9
9
  class TimerBuffer < Buffer
10
10
  DEFAULT_SOURCE = 'timer_input'
11
- DEFAULT_SECONDS_TO_KEEP = 60
11
+ DEFAULT_SECONDS_TO_KEEP = 3
12
12
 
13
13
  def config_param_types
14
14
  {
@@ -31,8 +31,6 @@ module Fusuma
31
31
  @events.each do |e|
32
32
  break if current_time - e.time < @seconds_to_keep
33
33
 
34
- MultiLogger.debug("#{self.class.name}##{__method__}")
35
-
36
34
  @events.delete(e)
37
35
  end
38
36
  end
@@ -15,7 +15,7 @@ module Fusuma
15
15
  # @return [Array<Symbol>]
16
16
  def execute_keys
17
17
  # [name.split('Executors::').last.underscore.gsub('_executor', '').to_sym]
18
- raise NotImplementedError, "override #{name}##{__method__}"
18
+ raise NotImplementedError, "override #{self.class.name}##{__method__}"
19
19
  end
20
20
 
21
21
  # check executable
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Fusuma
4
- VERSION = '2.0.4'
4
+ VERSION = '2.0.5'
5
5
  end
@@ -7,80 +7,162 @@ require './lib/fusuma/config/searcher'
7
7
  # spec for Config
8
8
  module Fusuma
9
9
  RSpec.describe Config::Searcher do
10
- let(:keymap) do
11
- {
12
- 'swipe' => {
13
- 3 => {
14
- 'left' => { 'command' => 'alt+Left' },
15
- 'right' => { 'command' => 'alt+Right' }
16
- },
17
- 4 => {
18
- 'left' => { 'command' => 'super+Left' },
19
- 'right' => { 'command' => 'super+Right' }
20
- }
21
- },
22
- 'pinch' => {
23
- 'in' => { 'command' => 'ctrl+plus' },
24
- 'out' => { 'command' => 'ctrl+minus' }
25
- }
26
- }
27
- end
10
+ around do |example|
11
+ ConfigHelper.load_config_yml = <<~CONFIG
12
+ swipe:
13
+ 3:
14
+ left:
15
+ command: 'alt+Left'
16
+ right:
17
+ command: 'alt+Right'
18
+ 4:
19
+ left:
20
+ command: 'super+Left'
21
+ right:
22
+ command: 'super+Right'
23
+ pinch:
24
+ in:
25
+ command: 'ctrl+plus'
26
+ out:
27
+ command: 'ctrl+minus'
28
+ CONFIG
28
29
 
29
- let(:keymap_without_finger) do
30
- {
31
- 'swipe' => {
32
- 'left' => { 'command' => 'alt+Left' }
33
- }
34
- }
35
- end
30
+ example.run
36
31
 
37
- describe '.custom_path=' do
38
- before { Singleton.__init__(Config) }
39
- it 'should reload keymap file' do
40
- keymap = Config.instance.keymap
41
- Config.custom_path = './spec/lib/dummy_config.yml'
42
- custom_keymap = Config.instance.keymap
43
- expect(keymap).not_to eq custom_keymap
44
- end
32
+ ConfigHelper.clear_config_yml
45
33
  end
46
34
 
47
35
  describe '.search' do
48
36
  let(:index) { nil }
49
- subject { Config::Searcher.new.search(index, location: keymap.deep_symbolize_keys) }
37
+ let(:location) { Config.instance.keymap[0] }
38
+ let(:search) { Config::Searcher.new.search(index, location: location) }
50
39
  context 'index correct order' do
51
40
  let(:index) { Config::Index.new %w[pinch in command] }
52
- it { is_expected.to eq 'ctrl+plus' }
41
+ it { expect(Config::Searcher.new.search(index, location: location)).to eq 'ctrl+plus' }
53
42
  end
54
43
 
55
- context 'index include skippable key' do
56
- let(:index) do
57
- Config::Index.new [
58
- Config::Index::Key.new('pinch'),
59
- Config::Index::Key.new(2, skippable: true),
60
- Config::Index::Key.new('out'),
61
- Config::Index::Key.new('command')
62
- ]
63
- end
64
- it { expect(Config::Searcher.skip { subject }).to eq 'ctrl+minus' }
44
+ context 'index incorrect order' do
45
+ let(:index) { Config::Index.new %w[in pinch 2 command] }
46
+ it { expect(Config::Searcher.new.search(index, location: location)).not_to eq 'ctrl+plus' }
65
47
  end
66
48
 
67
- context 'index include skippable key at first' do
68
- let(:index) do
69
- Config::Index.new [
70
- Config::Index::Key.new(:hoge, skippable: true),
71
- Config::Index::Key.new(:fuga, skippable: true),
72
- Config::Index::Key.new('pinch'),
73
- Config::Index::Key.new('in'),
74
- Config::Index::Key.new(:piyo, skippable: true),
75
- Config::Index::Key.new('command')
76
- ]
49
+ context 'with Skip condtions' do
50
+ context 'when index includes skippable key' do
51
+ let(:index) do
52
+ Config::Index.new [
53
+ Config::Index::Key.new('pinch'),
54
+ Config::Index::Key.new(2, skippable: true),
55
+ Config::Index::Key.new('out'),
56
+ Config::Index::Key.new('command')
57
+ ]
58
+ end
59
+ it 'detects ctrl+minus with skip' do
60
+ condition, value = Config::Searcher.find_condition do
61
+ Config::Searcher.new.search(index, location: location)
62
+ end
63
+ expect([condition, value]).to eq([:skip, 'ctrl+minus'])
64
+ end
77
65
  end
78
- it { expect(Config::Searcher.skip { subject }).to eq 'ctrl+plus' }
79
- end
80
66
 
81
- context 'index incorrect order' do
82
- let(:index) { Config::Index.new %w[in pinch 2 command] }
83
- it { is_expected.not_to eq 'ctrl+plus' }
67
+ context 'when index includes skippable key at first' do
68
+ let(:index) do
69
+ Config::Index.new [
70
+ Config::Index::Key.new(:hoge, skippable: true),
71
+ Config::Index::Key.new(:fuga, skippable: true),
72
+ Config::Index::Key.new('pinch'),
73
+ Config::Index::Key.new('in'),
74
+ Config::Index::Key.new(:piyo, skippable: true),
75
+ Config::Index::Key.new('command')
76
+ ]
77
+ end
78
+ it 'detects ctrl+plus with skip' do
79
+ condition, value = Config::Searcher.find_condition do
80
+ Config::Searcher.new.search(index, location: location)
81
+ end
82
+ expect([condition, value]).to eq([:skip, 'ctrl+plus'])
83
+ end
84
+ end
85
+
86
+ context 'with begin/update/end' do
87
+ around do |example|
88
+ ConfigHelper.load_config_yml = <<~CONFIG
89
+ swipe:
90
+ 3:
91
+ begin:
92
+ command: 'echo begin'
93
+ update:
94
+ command: 'echo update'
95
+ end:
96
+ command: 'echo end'
97
+ keypress:
98
+ LEFTCTRL:
99
+ command: 'echo end+ctrl'
100
+ CONFIG
101
+
102
+ example.run
103
+
104
+ ConfigHelper.clear_config_yml
105
+ end
106
+
107
+ context 'without keypress' do
108
+ let(:index) do
109
+ Config::Index.new [
110
+ Config::Index::Key.new(:swipe),
111
+ Config::Index::Key.new(3),
112
+ Config::Index::Key.new('left', skippable: true),
113
+ Config::Index::Key.new('end'),
114
+ Config::Index::Key.new('command')
115
+ ]
116
+ end
117
+
118
+ it 'detects with skip' do
119
+ condition, value = Config::Searcher.find_condition do
120
+ Config::Searcher.new.search(index, location: location)
121
+ end
122
+ expect([condition, value]).to eq([:skip, 'echo end'])
123
+ end
124
+ end
125
+ context 'with keypress' do
126
+ context 'with valid key existing in config.yml' do
127
+ let(:index) do
128
+ Config::Index.new [
129
+ Config::Index::Key.new(:swipe),
130
+ Config::Index::Key.new(3),
131
+ Config::Index::Key.new('left', skippable: true),
132
+ Config::Index::Key.new('end'),
133
+ Config::Index::Key.new('keypress', skippable: true),
134
+ Config::Index::Key.new('LEFTCTRL', skippable: true),
135
+ Config::Index::Key.new('command')
136
+ ]
137
+ end
138
+ it 'detects end+ctrl with skip' do
139
+ condition, value = Config::Searcher.find_condition do
140
+ Config::Searcher.new.search(index, location: location)
141
+ end
142
+ expect([condition, value]).to eq([:skip, 'echo end+ctrl'])
143
+ end
144
+ end
145
+ context 'with non-existing key not existing in config.yml' do
146
+ let(:index) do
147
+ Config::Index.new [
148
+ Config::Index::Key.new(:swipe),
149
+ Config::Index::Key.new(3),
150
+ Config::Index::Key.new('up', skippable: true),
151
+ Config::Index::Key.new('end'),
152
+ Config::Index::Key.new('keypress', skippable: true),
153
+ Config::Index::Key.new('LEFTSHIFT', skippable: true), # Invalid key
154
+ Config::Index::Key.new('command')
155
+ ]
156
+ end
157
+ it 'detects end with skip (fallback to no keypress)' do
158
+ condition, value = Config::Searcher.find_condition do
159
+ Config::Searcher.new.search(index, location: location)
160
+ end
161
+ expect([condition, value]).to eq([:skip, 'echo end'])
162
+ end
163
+ end
164
+ end
165
+ end
84
166
  end
85
167
  end
86
168
 
@@ -25,14 +25,6 @@ module Fusuma
25
25
  }
26
26
  end
27
27
 
28
- let(:keymap_without_finger) do
29
- {
30
- 'swipe' => {
31
- 'left' => { 'command' => 'alt+Left' }
32
- }
33
- }
34
- end
35
-
36
28
  describe '.custom_path=' do
37
29
  before { Singleton.__init__(Config) }
38
30
  it 'should reload keymap file' do
@@ -27,7 +27,7 @@ module Fusuma
27
27
 
28
28
  example.run
29
29
 
30
- Config.custom_path = nil
30
+ ConfigHelper.clear_config_yml
31
31
  end
32
32
 
33
33
  describe '#detect' do
@@ -13,20 +13,24 @@ module Fusuma
13
13
  RSpec.describe Executor do
14
14
  before { @executor = Executor.new }
15
15
 
16
+ describe '#execute_key' do
17
+ it { expect { @executor.execute_keys }.to raise_error(NotImplementedError) }
18
+ end
19
+
16
20
  describe '#execute' do
17
- it do
18
- expect { @executor.execute('dummy') }.to raise_error(NotImplementedError)
19
- end
21
+ it { expect { @executor.execute('dummy') }.to raise_error(NotImplementedError) }
20
22
  end
21
23
 
22
24
  describe '#executable?' do
23
- it do
24
- expect { @executor.executable?('dummy') }.to raise_error(NotImplementedError)
25
- end
25
+ it { expect { @executor.executable?('dummy') }.to raise_error(NotImplementedError) }
26
26
  end
27
27
  end
28
28
 
29
29
  class DummyExecutor < Executor
30
+ def execute_keys
31
+ [:dummy]
32
+ end
33
+
30
34
  def execute(event)
31
35
  index = Config::Index.new([*event.record.index.keys, :dummy])
32
36
  content = Config.search(index)
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.4
4
+ version: 2.0.5
5
5
  platform: ruby
6
6
  authors:
7
7
  - iberianpig
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2021-04-24 00:00:00.000000000 Z
11
+ date: 2021-05-21 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