fusuma 2.0.4 → 2.3.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +77 -51
- data/exe/fusuma +5 -0
- data/fusuma.gemspec +4 -1
- data/lib/fusuma/config/searcher.rb +1 -2
- data/lib/fusuma/config.rb +1 -1
- data/lib/fusuma/custom_process.rb +2 -0
- data/lib/fusuma/environment.rb +1 -1
- data/lib/fusuma/libinput_command.rb +1 -8
- data/lib/fusuma/multi_logger.rb +12 -1
- data/lib/fusuma/plugin/buffers/gesture_buffer.rb +6 -1
- data/lib/fusuma/plugin/buffers/timer_buffer.rb +1 -3
- data/lib/fusuma/plugin/detectors/hold_detector.rb +129 -0
- data/lib/fusuma/plugin/detectors/pinch_detector.rb +9 -2
- data/lib/fusuma/plugin/detectors/rotate_detector.rb +8 -2
- data/lib/fusuma/plugin/detectors/swipe_detector.rb +11 -3
- data/lib/fusuma/plugin/executors/executor.rb +1 -1
- data/lib/fusuma/plugin/parsers/libinput_gesture_parser.rb +9 -4
- data/lib/fusuma/version.rb +1 -1
- data/lib/fusuma.rb +12 -4
- data/spec/lib/config/searcher_spec.rb +142 -60
- data/spec/lib/config_spec.rb +0 -8
- data/spec/lib/libinput_command_spec.rb +1 -1
- data/spec/lib/plugin/buffers/gesture_buffer_spec.rb +34 -14
- data/spec/lib/plugin/detectors/detector_spec.rb +1 -1
- data/spec/lib/plugin/detectors/hold_detector_spec.rb +145 -0
- data/spec/lib/plugin/executors/executor_spec.rb +10 -6
- data/spec/lib/plugin/parsers/libinput_gesture_parser_spec.rb +76 -0
- metadata +35 -30
- data/lib/fusuma/plugin/filters/libinput_timeout_filter.rb +0 -21
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: f5d1aa62dc207e88f6b59dd13c073fe0465943f8de5ccc198475121a4fded8bb
|
4
|
+
data.tar.gz: 1a88e8369cd71286838b4ea52fcd692d15425864509b98cc2fb9f4116031039c
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 267f59ae0400d3266edf799981ee757357e7ecebb48b44f5e12769fb4a00c46f23276492f3b5769c5a6b02720ced7c7ddf4c52313173de223ef0eeb06860d505
|
7
|
+
data.tar.gz: 740b03cc4a5315b0ed70ec8f95459045dd93c13c3c8bf708f7414597fb1f710dd85d6080c9628cf3377f6e457473a5873711d3e980c1ad31987b350bf6759a12
|
data/README.md
CHANGED
@@ -1,9 +1,9 @@
|
|
1
|
-
# Fusuma [![Gem Version](https://badge.fury.io/rb/fusuma.svg)](https://badge.fury.io/rb/fusuma) [![Build Status](https://
|
1
|
+
# Fusuma [![Gem Version](https://badge.fury.io/rb/fusuma.svg)](https://badge.fury.io/rb/fusuma) [![Build Status](https://github.com/iberianpig/fusuma/actions/workflows/ubuntu.yml/badge.svg)](https://github.com/iberianpig/fusuma/actions/workflows/ubuntu.yml) [![Coverage Status](https://coveralls.io/repos/github/iberianpig/fusuma/badge.svg?branch=master)](https://coveralls.io/github/iberianpig/fusuma?branch=master)
|
2
2
|
|
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://
|
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
|
|
@@ -22,13 +22,13 @@ This gem makes your linux able to recognize swipes or pinchs and assign commands
|
|
22
22
|
**IMPORTANT**: You **MUST** be a member of the **INPUT** group to read touchpad by Fusuma.
|
23
23
|
|
24
24
|
```bash
|
25
|
-
|
25
|
+
sudo gpasswd -a $USER input
|
26
26
|
```
|
27
27
|
|
28
28
|
Then, You apply the change with no logout or reboot.
|
29
29
|
|
30
30
|
```bash
|
31
|
-
|
31
|
+
newgrp input
|
32
32
|
```
|
33
33
|
|
34
34
|
### For Debian Based Distros (Ubuntu, Debian, Mint, Pop!OS)
|
@@ -38,7 +38,7 @@ $ newgrp input
|
|
38
38
|
You need `libinput` release 1.0 or later.
|
39
39
|
|
40
40
|
```bash
|
41
|
-
|
41
|
+
sudo apt-get install libinput-tools
|
42
42
|
```
|
43
43
|
|
44
44
|
#### 2. Install Ruby
|
@@ -46,13 +46,13 @@ $ sudo apt-get install libinput-tools
|
|
46
46
|
Fusuma runs in Ruby, so you must install it first.
|
47
47
|
|
48
48
|
```bash
|
49
|
-
|
49
|
+
sudo apt-get install ruby
|
50
50
|
```
|
51
51
|
|
52
52
|
#### 3. Install Fusuma
|
53
53
|
|
54
54
|
```bash
|
55
|
-
|
55
|
+
sudo gem install fusuma
|
56
56
|
```
|
57
57
|
|
58
58
|
#### 4. Install xdotool (optional)
|
@@ -60,7 +60,7 @@ $ sudo gem install fusuma
|
|
60
60
|
For sending shortcuts:
|
61
61
|
|
62
62
|
```bash
|
63
|
-
|
63
|
+
sudo apt-get install xdotool
|
64
64
|
```
|
65
65
|
|
66
66
|
### For Arch Based Distros (Manjaro, Arch)
|
@@ -70,7 +70,7 @@ $ sudo apt-get install xdotool
|
|
70
70
|
You need `libinput` release 1.0 or later. This is most probably installed by default on Manjaro
|
71
71
|
|
72
72
|
```z-h
|
73
|
-
|
73
|
+
sudo pacman -S libinput
|
74
74
|
```
|
75
75
|
|
76
76
|
#### 2. Install Ruby
|
@@ -78,17 +78,17 @@ $ sudo pacman -S libinput
|
|
78
78
|
Fusuma runs in Ruby, so you must install it first.
|
79
79
|
|
80
80
|
```zsh
|
81
|
-
|
81
|
+
sudo pacman -S ruby
|
82
82
|
```
|
83
83
|
|
84
84
|
#### 3. Install Fusuma
|
85
85
|
|
86
|
-
**Note:** By default in Arch Linux, when running
|
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
|
|
90
90
|
```zsh
|
91
|
-
|
91
|
+
sudo gem install fusuma
|
92
92
|
```
|
93
93
|
|
94
94
|
#### 4. Install xdotool (optional)
|
@@ -96,7 +96,7 @@ $ sudo gem install fusuma
|
|
96
96
|
For sending shortcuts:
|
97
97
|
|
98
98
|
```zsh
|
99
|
-
|
99
|
+
sudo pacman -S xdotool
|
100
100
|
```
|
101
101
|
|
102
102
|
### Touchpad not working in GNOME
|
@@ -104,43 +104,56 @@ $ sudo pacman -S xdotool
|
|
104
104
|
Ensure the touchpad events are being sent to the GNOME desktop by running the following command:
|
105
105
|
|
106
106
|
```bash
|
107
|
-
|
107
|
+
gsettings set org.gnome.desktop.peripherals.touchpad send-events enabled
|
108
108
|
```
|
109
109
|
|
110
110
|
## Usage
|
111
111
|
|
112
112
|
```bash
|
113
|
-
|
113
|
+
fusuma
|
114
114
|
```
|
115
115
|
|
116
116
|
## Update
|
117
117
|
|
118
118
|
```bash
|
119
|
-
|
119
|
+
sudo gem update fusuma
|
120
120
|
```
|
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
|
128
|
-
|
129
|
-
|
128
|
+
mkdir -p ~/.config/fusuma # create config directory
|
129
|
+
nano ~/.config/fusuma/config.yml # edit config file.
|
130
130
|
```
|
131
131
|
|
132
132
|
|
133
133
|
### Available gestures
|
134
134
|
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
* `
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
135
|
+
#### swipe:
|
136
|
+
|
137
|
+
* support `3:`, `4:` fingers
|
138
|
+
* support `left:`, `right:`, `up:`, `down:` directions
|
139
|
+
* support `begin:`, `update:`, `end:` events
|
140
|
+
|
141
|
+
#### pinch:
|
142
|
+
|
143
|
+
* support `2:`, `3:`, `4:` fingers
|
144
|
+
* support `in:`, `out:` directions
|
145
|
+
* support `begin:`, `update:`, `end:` events
|
146
|
+
|
147
|
+
#### rotate:
|
148
|
+
|
149
|
+
* support `2:`, `3:`, `4:` fingers
|
150
|
+
* support `clockwise:`,`counterclockwise:` directions
|
151
|
+
* support `begin:`, `update:`, `end:` events
|
152
|
+
|
153
|
+
#### hold:
|
154
|
+
* require libinput version 1.19.0 or later
|
155
|
+
* support `1:`, `2:`, `3:`, `4:` fingers
|
156
|
+
* support `begin:`, `end:`, `cancelled:` events
|
144
157
|
|
145
158
|
### About YAML Basic Syntax
|
146
159
|
|
@@ -157,7 +170,7 @@ https://github.com/iberianpig/fusuma/wiki/Ubuntu
|
|
157
170
|
swipe:
|
158
171
|
3:
|
159
172
|
left:
|
160
|
-
command: "xdotool key alt+Right" # History forward
|
173
|
+
command: "xdotool key alt+Right" # History forward
|
161
174
|
right:
|
162
175
|
command: "xdotool key alt+Left" # History back
|
163
176
|
up:
|
@@ -178,6 +191,9 @@ pinch:
|
|
178
191
|
command: "xdotool keydown ctrl click 4 keyup ctrl" # Zoom in
|
179
192
|
out:
|
180
193
|
command: "xdotool keydown ctrl click 5 keyup ctrl" # Zoom out
|
194
|
+
hold:
|
195
|
+
4:
|
196
|
+
command: "xdotool key super" # Activity
|
181
197
|
```
|
182
198
|
|
183
199
|
### More Example of config.yml
|
@@ -191,36 +207,38 @@ The following wiki pages can be edited by everyone.
|
|
191
207
|
- [POP OS with Cinnamon](https://github.com/iberianpig/fusuma/wiki/POP-OS-with-Cinnamon)
|
192
208
|
- [PopOS Default Gnome](https://github.com/iberianpig/fusuma/wiki/PopOS-Default-Gnome)
|
193
209
|
- [Ubuntu OS to mimic Mac a little](https://github.com/iberianpig/fusuma/wiki/Ubuntu-OS-to-mimic-Mac-a-little)
|
210
|
+
- [3 fingers Drag (OS X Style)](https://github.com/iberianpig/fusuma/wiki/3-fingers-Drag-(OS-X-Style))
|
211
|
+
- [3 fingers Alt Tab Switcher(Windows Style)](https://github.com/iberianpig/fusuma/wiki/3-fingers-Alt-Tab-Switcher(Windows-Style))
|
194
212
|
|
195
213
|
If you have a nice configuration, please share `~/.config/fusuma/config.yml` with everyone.
|
196
214
|
|
197
215
|
### Threshold and Interval
|
198
216
|
|
199
|
-
if `command:` properties are blank, the swipe/pinch doesn't execute command.
|
217
|
+
if `command:` properties are blank, the swipe/pinch/hold doesn't execute command.
|
200
218
|
|
201
|
-
`threshold:` is sensitivity to swipe/pinch. Default value is 1.
|
219
|
+
`threshold:` is sensitivity to swipe/pinch/hold. Default value is 1.
|
202
220
|
If the swipe's threshold is `0.5`, shorten swipe-length by half.
|
203
221
|
|
204
|
-
`interval:` is delay between swipes/pinches. Default value is 1.
|
222
|
+
`interval:` is delay between swipes/pinches/hold. Default value is 1.
|
205
223
|
If the swipe's interval is `0.5`, shorten swipe-interval by half to recognize a next swipe.
|
206
224
|
|
207
225
|
### Example of `threshold:` / `interval:` settings
|
208
226
|
|
209
227
|
```yaml
|
210
228
|
swipe:
|
211
|
-
3:
|
212
|
-
left:
|
229
|
+
3:
|
230
|
+
left:
|
213
231
|
command: 'xdotool key alt+Right' # threshold: 0.5, interval: 0.75
|
214
232
|
threshold: 0.5
|
215
|
-
right:
|
233
|
+
right:
|
216
234
|
command: 'xdotool key alt+Left' # threshold: 0.5, interval: 0.75
|
217
235
|
threshold: 0.5
|
218
|
-
up:
|
236
|
+
up:
|
219
237
|
command: 'xdotool key super' # threshold: 1, interval: 0.75
|
220
|
-
down:
|
238
|
+
down:
|
221
239
|
command: 'xdotool key super' # threshold: 1, interval: 0.75
|
222
240
|
pinch:
|
223
|
-
2:
|
241
|
+
2:
|
224
242
|
in:
|
225
243
|
command: "xdotool keydown ctrl click 4 keyup ctrl" # threshold: 0.5, interval: 0.5
|
226
244
|
out:
|
@@ -234,11 +252,11 @@ interval:
|
|
234
252
|
pinch: 0.5
|
235
253
|
```
|
236
254
|
|
237
|
-
There are three priorities of `threshold:` and `interval:`.
|
255
|
+
There are three priorities of `threshold:` and `interval:`.
|
238
256
|
The individual `threshold:` and `interval:` settings (under "direction") have a higher priority than the global one (under "root")
|
239
257
|
|
240
258
|
1. child elements in the direction (left/right/down/up → threshold/interval)
|
241
|
-
1. root child elements (threshold/interval → swipe/pinch)
|
259
|
+
1. root child elements (threshold/interval → swipe/pinch/hold)
|
242
260
|
1. default value (= 1)
|
243
261
|
|
244
262
|
### `command:` property for assigning commands
|
@@ -280,7 +298,7 @@ swipe:
|
|
280
298
|
- `xte`
|
281
299
|
- [xte(1) - Linux man page](https://linux.die.net/man/1/xte)
|
282
300
|
- install with `sudo apt xautomation`
|
283
|
-
|
301
|
+
|
284
302
|
- [ydotool](https://github.com/ReimuNotMoe/ydotool)
|
285
303
|
- Wayland compatible
|
286
304
|
- Needs more maintainers.
|
@@ -292,8 +310,8 @@ swipe:
|
|
292
310
|
- `-d`, `--daemon` : Daemonize process
|
293
311
|
- `-l`, `--list-devices` : List available devices
|
294
312
|
- `-v`, `--verbose` : Show details about the results of running fusuma
|
295
|
-
- `--device="Device name"` : Open the given device only (DEPRECATED)
|
296
313
|
- `--version` : Show fusuma version
|
314
|
+
- `--log-file=path/to/file` : Set path of log file
|
297
315
|
|
298
316
|
### Specify touchpads by device name
|
299
317
|
Set the following options to recognize multi-touch gestures only for the specified touchpad device.
|
@@ -309,8 +327,8 @@ plugin:
|
|
309
327
|
|
310
328
|
## Autostart (gnome-session-properties)
|
311
329
|
|
312
|
-
1. Check the path where you installed fusuma with
|
313
|
-
2. Open
|
330
|
+
1. Check the path where you installed fusuma with `which fusuma`
|
331
|
+
2. Open `gnome-session-properties`
|
314
332
|
3. Add Fusuma and enter the location where the above path was checked in the command input field
|
315
333
|
4. Add the `-d` option at the end of the command input field
|
316
334
|
|
@@ -322,14 +340,10 @@ Following features are provided as plugins.
|
|
322
340
|
- Features for specific Linux distributions
|
323
341
|
- Setting different gestures per applications
|
324
342
|
|
325
|
-
###
|
343
|
+
### Available plugins
|
326
344
|
|
327
345
|
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
346
|
|
329
|
-
`$ sudo gem install fusuma-plugin-XXXXX`
|
330
|
-
|
331
|
-
### Available plugins
|
332
|
-
|
333
347
|
| Name | Version | About |
|
334
348
|
| ---------------------------------------------------------------------------------- | --------------------------------------------------------------------- | --------------------------------------------- |
|
335
349
|
| [fusuma-plugin-sendkey](https://github.com/iberianpig/fusuma-plugin-sendkey) | ![Gem Version](https://badge.fury.io/rb/fusuma-plugin-sendkey.svg) | Emulates keyboard events |
|
@@ -338,9 +352,21 @@ Fusuma plugins are provided with the `fusuma-plugin-XXXXX` naming convention and
|
|
338
352
|
| [fusuma-plugin-tap](https://github.com/iberianpig/fusuma-plugin-tap) | ![Gem Version](https://badge.fury.io/rb/fusuma-plugin-tap.svg) | Detects Tap and Hold gestures |
|
339
353
|
| [fusuma-plugin-appmatcher](https://github.com/iberianpig/fusuma-plugin-appmatcher) | ![Gem Version](https://badge.fury.io/rb/fusuma-plugin-appmatcher.svg) | Configure app-specific gestures |
|
340
354
|
|
355
|
+
|
356
|
+
### Installation of Fusuma plugins
|
357
|
+
|
358
|
+
```bash
|
359
|
+
# install fusuma-plugin-XXXX
|
360
|
+
sudo gem install fusuma-plugin-XXXXX`
|
361
|
+
```
|
362
|
+
```bash
|
363
|
+
# update
|
364
|
+
sudo gem list fusuma-plugin- | cut -d' ' -f1 | xargs --no-run-if-empty sudo gem update
|
365
|
+
```
|
366
|
+
|
341
367
|
## Tutorial Video
|
342
368
|
|
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")
|
369
|
+
[![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
370
|
[Multitouch Touchpad Gestures in Linux with Fusuma](http://www.youtube.com/watch?v=bn11Iwvf29I) by [Eric Adams](https://www.youtube.com/user/igster75)
|
345
371
|
|
346
372
|
## Support
|
@@ -349,7 +375,7 @@ I'm a Freelance Engineer in Japan and working on these products after finishing
|
|
349
375
|
Currently, my open-source contribution times is not enough.
|
350
376
|
If you like my work and want to contribute and become a sponsor, I will be able to focus on my projects.
|
351
377
|
|
352
|
-
- [GitHub Sponsors](https://github.com/sponsors/iberianpig)
|
378
|
+
- [GitHub Sponsors](https://github.com/sponsors/iberianpig)
|
353
379
|
- [Patreon](https://www.patreon.com/iberianpig)
|
354
380
|
|
355
381
|
## Contributing
|
data/exe/fusuma
CHANGED
@@ -22,6 +22,11 @@ opt.on('-l', '--list-devices',
|
|
22
22
|
option[:list] = v
|
23
23
|
end
|
24
24
|
|
25
|
+
opt.on('--log=path/to/file',
|
26
|
+
'Print logs to file') do |v|
|
27
|
+
option[:log_filepath] = v
|
28
|
+
end
|
29
|
+
|
25
30
|
opt.on('--device="Device name"',
|
26
31
|
'Open the given device only (DEPRECATED)') do |v|
|
27
32
|
option[:device] = v
|
data/fusuma.gemspec
CHANGED
@@ -20,7 +20,10 @@ Gem::Specification.new do |spec|
|
|
20
20
|
spec.bindir = 'exe'
|
21
21
|
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
22
22
|
spec.require_paths = ['lib']
|
23
|
-
spec.metadata
|
23
|
+
spec.metadata = {
|
24
|
+
'rubygems_mfa_required' => 'true',
|
25
|
+
'yard.run' => 'yri' # use "yard" to build full HTML docs.
|
26
|
+
}
|
24
27
|
|
25
28
|
spec.required_ruby_version = '>= 2.5.1' # https://packages.ubuntu.com/search?keywords=ruby&searchon=names&exact=1&suite=all§ion=main
|
26
29
|
# support bionic (18.04LTS) 2.5.1
|
@@ -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.
|
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],
|
data/lib/fusuma/config.rb
CHANGED
data/lib/fusuma/environment.rb
CHANGED
@@ -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 #{
|
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
|
@@ -13,10 +13,7 @@ module Fusuma
|
|
13
13
|
|
14
14
|
# `libinput-list-devices` and `libinput-debug-events` are deprecated,
|
15
15
|
# use `libinput list-devices` and `libinput debug-events` from 1.8.
|
16
|
-
NEW_CLI_OPTION_VERSION = 1.8
|
17
|
-
|
18
|
-
DEFAULT_WAIT_TIME = 0.3
|
19
|
-
TIMEOUT_MESSAGE = 'LIBINPUT TIMEOUT'
|
16
|
+
NEW_CLI_OPTION_VERSION = '1.8'
|
20
17
|
|
21
18
|
# @return [Boolean]
|
22
19
|
def new_cli_option_available?
|
@@ -92,10 +89,6 @@ module Fusuma
|
|
92
89
|
|
93
90
|
private
|
94
91
|
|
95
|
-
def wait_time
|
96
|
-
DEFAULT_WAIT_TIME
|
97
|
-
end
|
98
|
-
|
99
92
|
# which in ruby: Checking if program exists in $PATH from ruby
|
100
93
|
# (https://stackoverflow.com/questions/2108727/which-in-ruby-checking-if-program-exists-in-path-from-ruby)
|
101
94
|
# Cross-platform way of finding an executable in the $PATH.
|
data/lib/fusuma/multi_logger.rb
CHANGED
@@ -11,8 +11,19 @@ module Fusuma
|
|
11
11
|
attr_reader :err_logger
|
12
12
|
attr_accessor :debug_mode
|
13
13
|
|
14
|
+
class << self
|
15
|
+
attr_writer :filepath
|
16
|
+
end
|
17
|
+
|
14
18
|
def initialize
|
15
|
-
|
19
|
+
filepath = self.class.instance_variable_get('@filepath')
|
20
|
+
if filepath
|
21
|
+
logfile = File.new(filepath, 'a')
|
22
|
+
super(logfile)
|
23
|
+
$stderr = logfile
|
24
|
+
else
|
25
|
+
super($stdout)
|
26
|
+
end
|
16
27
|
@err_logger = Logger.new($stderr)
|
17
28
|
@debug_mode = false
|
18
29
|
end
|
@@ -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 =
|
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
|
@@ -0,0 +1,129 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative './detector'
|
4
|
+
|
5
|
+
module Fusuma
|
6
|
+
module Plugin
|
7
|
+
module Detectors
|
8
|
+
# Detect Hold gesture
|
9
|
+
class HoldDetector < Detector
|
10
|
+
SOURCES = %w[gesture timer].freeze
|
11
|
+
BUFFER_TYPE = 'gesture'
|
12
|
+
GESTURE_RECORD_TYPE = 'hold'
|
13
|
+
|
14
|
+
BASE_THERESHOLD = 0.7
|
15
|
+
|
16
|
+
# @param buffers [Array<Buffers::Buffer>]
|
17
|
+
# @return [Events::Event] if event is detected
|
18
|
+
# @return [Array<Events::Event>] if hold end event is detected
|
19
|
+
# @return [NilClass] if event is NOT detected
|
20
|
+
def detect(buffers)
|
21
|
+
hold_buffer = find_hold_buffer(buffers)
|
22
|
+
return if hold_buffer.empty?
|
23
|
+
|
24
|
+
hold_events = hold_buffer.events
|
25
|
+
|
26
|
+
timer_buffer = buffers.find { |b| b.type == 'timer' }
|
27
|
+
timer_events = timer_buffer.events
|
28
|
+
|
29
|
+
finger = hold_buffer.finger
|
30
|
+
holding_time = calc_holding_time(hold_events: hold_events, timer_events: timer_events)
|
31
|
+
|
32
|
+
@timeout ||= nil
|
33
|
+
status = case hold_events.last.record.status
|
34
|
+
when 'begin'
|
35
|
+
if holding_time.zero?
|
36
|
+
'begin'
|
37
|
+
else
|
38
|
+
'timer'
|
39
|
+
end
|
40
|
+
when 'cancelled'
|
41
|
+
'cancelled'
|
42
|
+
when 'end'
|
43
|
+
'end'
|
44
|
+
else
|
45
|
+
last_record = hold_events.last.record.status
|
46
|
+
raise "Unexpected Status:#{last_record.status} in #{last_record}"
|
47
|
+
end
|
48
|
+
|
49
|
+
repeat_index = create_repeat_index(finger: finger, status: status)
|
50
|
+
oneshot_index = create_oneshot_index(finger: finger)
|
51
|
+
|
52
|
+
@timeout = nil if status == 'begin'
|
53
|
+
|
54
|
+
if status == 'timer'
|
55
|
+
return if @timeout
|
56
|
+
|
57
|
+
return unless enough?(index: oneshot_index, holding_time: holding_time)
|
58
|
+
|
59
|
+
@timeout = holding_time
|
60
|
+
return create_event(record: Events::Records::IndexRecord.new(
|
61
|
+
index: oneshot_index, trigger: :oneshot
|
62
|
+
))
|
63
|
+
end
|
64
|
+
|
65
|
+
create_event(record: Events::Records::IndexRecord.new(
|
66
|
+
index: repeat_index, trigger: :repeat
|
67
|
+
))
|
68
|
+
end
|
69
|
+
|
70
|
+
# @param [Integer] finger
|
71
|
+
# @return [Config::Index]
|
72
|
+
def create_oneshot_index(finger:)
|
73
|
+
Config::Index.new(
|
74
|
+
[
|
75
|
+
Config::Index::Key.new(type),
|
76
|
+
Config::Index::Key.new(finger.to_i)
|
77
|
+
]
|
78
|
+
)
|
79
|
+
end
|
80
|
+
|
81
|
+
# @param [Integer] finger
|
82
|
+
# @return [Config::Index]
|
83
|
+
def create_repeat_index(finger:, status:)
|
84
|
+
Config::Index.new(
|
85
|
+
[
|
86
|
+
Config::Index::Key.new(type),
|
87
|
+
Config::Index::Key.new(finger.to_i),
|
88
|
+
Config::Index::Key.new(status)
|
89
|
+
]
|
90
|
+
)
|
91
|
+
end
|
92
|
+
|
93
|
+
private
|
94
|
+
|
95
|
+
# @param buffers [Array<Buffers::Buffer>]
|
96
|
+
# @return [Buffers::GestureBuffer]
|
97
|
+
def find_hold_buffer(buffers)
|
98
|
+
buffers.find { |b| b.type == BUFFER_TYPE }
|
99
|
+
.select_from_last_begin
|
100
|
+
.select_by_events { |e| e.record.gesture == GESTURE_RECORD_TYPE }
|
101
|
+
end
|
102
|
+
|
103
|
+
def calc_holding_time(hold_events:, timer_events:)
|
104
|
+
last_time = if !timer_events.empty? && (hold_events.last.time < timer_events.last.time)
|
105
|
+
timer_events.last.time
|
106
|
+
else
|
107
|
+
hold_events.last.time
|
108
|
+
end
|
109
|
+
last_time - hold_events.first.time
|
110
|
+
end
|
111
|
+
|
112
|
+
def enough?(index:, holding_time:)
|
113
|
+
holding_time > threshold(index: index)
|
114
|
+
end
|
115
|
+
|
116
|
+
def threshold(index:)
|
117
|
+
@threshold ||= {}
|
118
|
+
@threshold[index.cache_key] ||= begin
|
119
|
+
keys_specific = Config::Index.new [*index.keys, 'threshold']
|
120
|
+
keys_global = Config::Index.new ['threshold', type]
|
121
|
+
config_value = Config.search(keys_specific) ||
|
122
|
+
Config.search(keys_global) || 1
|
123
|
+
BASE_THERESHOLD * config_value
|
124
|
+
end
|
125
|
+
end
|
126
|
+
end
|
127
|
+
end
|
128
|
+
end
|
129
|
+
end
|
@@ -62,8 +62,15 @@ module Fusuma
|
|
62
62
|
if status == 'update'
|
63
63
|
return unless moved?(prev_event, event)
|
64
64
|
|
65
|
-
avg_zoom =
|
66
|
-
|
65
|
+
first_zoom, avg_zoom = if updating_events.size >= 10
|
66
|
+
[updating_events[-10].record.delta.zoom,
|
67
|
+
gesture_buffer.class.new(
|
68
|
+
updating_events[-10..-1]
|
69
|
+
).avg_attrs(:zoom)]
|
70
|
+
else
|
71
|
+
[updating_events.first.record.delta.zoom,
|
72
|
+
gesture_buffer.avg_attrs(:zoom)]
|
73
|
+
end
|
67
74
|
|
68
75
|
oneshot_quantity = Quantity.new(target: avg_zoom, base: first_zoom).to_f
|
69
76
|
oneshot_direction = Direction.new(target: avg_zoom, base: first_zoom).to_s
|
@@ -24,8 +24,14 @@ module Fusuma
|
|
24
24
|
updating_events = gesture_buffer.updating_events
|
25
25
|
return if updating_events.empty?
|
26
26
|
|
27
|
-
|
28
|
-
|
27
|
+
oneshot_angle = if updating_events.size >= 10
|
28
|
+
updating_time = 100 * (updating_events[-1].time - updating_events[-10].time)
|
29
|
+
last_10 = gesture_buffer.class.new(updating_events[-10..-1])
|
30
|
+
last_10.sum_attrs(:rotate) / updating_time
|
31
|
+
else
|
32
|
+
updating_time = 100 * (updating_events.last.time - updating_events.first.time)
|
33
|
+
gesture_buffer.sum_attrs(:rotate) / updating_time
|
34
|
+
end
|
29
35
|
|
30
36
|
return if updating_events.empty?
|
31
37
|
|