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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 8f19305771a0704b1f7294b9b54653f09d7d4f6153ffbdd19a6c23a753870b09
4
- data.tar.gz: 3b6c9addcda816e7379e69bb258bd11f091ea39fbae37fc8e0ef4c9ca4b7dff7
3
+ metadata.gz: f5d1aa62dc207e88f6b59dd13c073fe0465943f8de5ccc198475121a4fded8bb
4
+ data.tar.gz: 1a88e8369cd71286838b4ea52fcd692d15425864509b98cc2fb9f4116031039c
5
5
  SHA512:
6
- metadata.gz: 422dc7e58b8db650754c4939ec1946456bfdfb0a8e4af33d79a20d88d84190f393952e05e1d086f711fb1ee2e6c415c4ddf6861dba8d94bf84df4f4e0585374f
7
- data.tar.gz: 02e75550adfd4a6f3e3d43b4a6326377d5182131bdd9d9f3ff3ca0abcb89888e0bca9eea8551868cc87edb0a706fb9b51ee97cc517e093566c7448729359ded2
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://travis-ci.com/iberianpig/fusuma.svg?branch=master)](https://travis-ci.com/iberianpig/fusuma) [![Coverage Status](https://coveralls.io/repos/github/iberianpig/fusuma/badge.svg?branch=master)](https://coveralls.io/github/iberianpig/fusuma?branch=master) [![Inline docs](http://inch-ci.org/github/iberianpig/fusuma.svg?branch=master)](http://inch-ci.org/github/iberianpig/fusuma)
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://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
 
@@ -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
- $ sudo gpasswd -a $USER input
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
- $ newgrp input
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
- $ sudo apt-get install libinput-tools
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
- $ sudo apt-get install ruby
49
+ sudo apt-get install ruby
50
50
  ```
51
51
 
52
52
  #### 3. Install Fusuma
53
53
 
54
54
  ```bash
55
- $ sudo gem install fusuma
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
- $ sudo apt-get install xdotool
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
- $ sudo pacman -S libinput
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
- $ sudo pacman -S ruby
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 ```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
 
90
90
  ```zsh
91
- $ sudo gem install fusuma
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
- $ sudo pacman -S xdotool
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
- $ gsettings set org.gnome.desktop.peripherals.touchpad send-events enabled
107
+ gsettings set org.gnome.desktop.peripherals.touchpad send-events enabled
108
108
  ```
109
109
 
110
110
  ## Usage
111
111
 
112
112
  ```bash
113
- $ fusuma
113
+ fusuma
114
114
  ```
115
115
 
116
116
  ## Update
117
117
 
118
118
  ```bash
119
- $ sudo gem update fusuma
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
- $ mkdir -p ~/.config/fusuma # create config directory
129
- $ nano ~/.config/fusuma/config.yml # edit config file.
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
- * `swipe:`
136
- * support `3:`, `4:` fingers
137
- * support `left:`, `right:`, `up:`, `down:` directions
138
- * `pinch:`
139
- * support `2:`, `3:`, `4:` fingers
140
- * support `in:`, `out:` directions
141
- * `rotate:`
142
- * support `2:`, `3:`, `4:` fingers
143
- * support `clockwise:`,`counterclockwise:` directions
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 `$ which fusuma`
313
- 2. Open `$ gnome-session-properties`
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
- ### Installation of fusuma plugins
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) (Zero fee!)
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['yard.run'] = 'yri' # use "yard" to build full HTML docs.
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&section=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. 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],
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
@@ -1,5 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require 'fusuma/string_support'
4
+
3
5
  module Fusuma
4
6
  # Rename process
5
7
  module CustomProcess
@@ -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
@@ -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.
@@ -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
- super($stdout)
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
@@ -46,7 +46,12 @@ module Fusuma
46
46
  def ended?
47
47
  return false if empty?
48
48
 
49
- @events.last.record.status == 'end'
49
+ case @events.last.record.status
50
+ when 'end', 'cancelled'
51
+ true
52
+ else
53
+ false
54
+ end
50
55
  end
51
56
 
52
57
  # @param attr [Symbol]
@@ -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
@@ -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 = gesture_buffer.avg_attrs(:zoom)
66
- first_zoom = updating_events.first.record.delta.zoom
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
- updating_time = 100 * (updating_events.last.time - updating_events.first.time)
28
- oneshot_angle = gesture_buffer.sum_attrs(:rotate) / updating_time
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