fusuma 2.0.0 → 2.0.5

Sign up to get free protection for your applications and to get access to all the features.
Files changed (68) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +27 -22
  3. data/fusuma.gemspec +2 -4
  4. data/lib/fusuma.rb +11 -4
  5. data/lib/fusuma/config.rb +1 -1
  6. data/lib/fusuma/config/searcher.rb +1 -2
  7. data/lib/fusuma/environment.rb +1 -1
  8. data/lib/fusuma/libinput_command.rb +11 -11
  9. data/lib/fusuma/plugin/buffers/timer_buffer.rb +1 -3
  10. data/lib/fusuma/plugin/executors/command_executor.rb +10 -10
  11. data/lib/fusuma/plugin/executors/executor.rb +1 -1
  12. data/lib/fusuma/plugin/inputs/libinput_command_input.rb +9 -2
  13. data/lib/fusuma/plugin/manager.rb +3 -3
  14. data/lib/fusuma/version.rb +1 -1
  15. data/spec/helpers/config_helper.rb +20 -0
  16. data/spec/lib/config/searcher_spec.rb +179 -0
  17. data/spec/lib/config_spec.rb +104 -0
  18. data/spec/lib/custom_process_spec.rb +28 -0
  19. data/spec/lib/device_spec.rb +96 -0
  20. data/spec/lib/dummy_config.yml +31 -0
  21. data/spec/lib/fusuma_spec.rb +103 -0
  22. data/spec/lib/libinput-list-devices_iberianpig-XPS-9360.txt +181 -0
  23. data/spec/lib/libinput-list-devices_magic_trackpad.txt +51 -0
  24. data/spec/lib/libinput-list-devices_razer_razer_blade.txt +252 -0
  25. data/spec/lib/libinput-list-devices_thejinx0r.txt +361 -0
  26. data/spec/lib/libinput-list-devices_unavailable.txt +36 -0
  27. data/spec/lib/libinput_command_spec.rb +164 -0
  28. data/spec/lib/plugin/base_spec.rb +74 -0
  29. data/spec/lib/plugin/buffers/buffer_spec.rb +80 -0
  30. data/spec/lib/plugin/buffers/dummy_buffer.rb +20 -0
  31. data/spec/lib/plugin/buffers/gesture_buffer_spec.rb +172 -0
  32. data/spec/lib/plugin/detectors/detector_spec.rb +43 -0
  33. data/spec/lib/plugin/detectors/dummy_detector.rb +24 -0
  34. data/spec/lib/plugin/detectors/pinch_detector_spec.rb +119 -0
  35. data/spec/lib/plugin/detectors/rotate_detector_spec.rb +125 -0
  36. data/spec/lib/plugin/detectors/swipe_detector_spec.rb +118 -0
  37. data/spec/lib/plugin/events/event_spec.rb +30 -0
  38. data/spec/lib/plugin/events/records/gesture_record_spec.rb +22 -0
  39. data/spec/lib/plugin/events/records/record_spec.rb +31 -0
  40. data/spec/lib/plugin/events/records/text_record_spec.rb +26 -0
  41. data/spec/lib/plugin/executors/command_executor_spec.rb +57 -0
  42. data/spec/lib/plugin/executors/executor_spec.rb +164 -0
  43. data/spec/lib/plugin/filters/filter_spec.rb +92 -0
  44. data/spec/lib/plugin/filters/libinput_filter_spec.rb +120 -0
  45. data/spec/lib/plugin/inputs/input_spec.rb +70 -0
  46. data/spec/lib/plugin/inputs/libinput_command_input_spec.rb +121 -0
  47. data/spec/lib/plugin/inputs/timer_input_spec.rb +40 -0
  48. data/spec/lib/plugin/manager_spec.rb +27 -0
  49. data/spec/lib/plugin/parsers/parser_spec.rb +45 -0
  50. data/spec/spec_helper.rb +20 -0
  51. metadata +76 -35
  52. data/.github/FUNDING.yml +0 -8
  53. data/.github/ISSUE_TEMPLATE/bug_report.md +0 -32
  54. data/.github/ISSUE_TEMPLATE/feature_request.md +0 -17
  55. data/.github/pull_request_template.md +0 -9
  56. data/.github/stale.yml +0 -18
  57. data/.gitignore +0 -17
  58. data/.reek.yml +0 -96
  59. data/.rspec +0 -2
  60. data/.rubocop.yml +0 -43
  61. data/.rubocop_todo.yml +0 -55
  62. data/.solargraph.yml +0 -16
  63. data/.travis.yml +0 -9
  64. data/CHANGELOG.md +0 -456
  65. data/CODE_OF_CONDUCT.md +0 -74
  66. data/CONTRIBUTING.md +0 -72
  67. data/Gemfile +0 -23
  68. data/Rakefile +0 -15
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: c8b830de9940632862b66b2cd6dbd6cf9ead713a24d7913d31baae7baacef348
4
- data.tar.gz: e55c53522a2184c8e6197bc12c4ca203cd844f1277dafbfe02fde48ae8f0d8c6
3
+ metadata.gz: e9b2c355ba50b2c62cf23f7c8975d50485710a67b76ffe5a904f67a043c0cac4
4
+ data.tar.gz: 655c8dcbc527e11a2a8883391ec3970af2081285d54332da975ddd8015117186
5
5
  SHA512:
6
- metadata.gz: 8153cf247654a3b70f976f74b0c3d791a962185fec288286f625448e8c23c6b53e134acff8d2ebad51eebdd51fefe8539a8da11c5abbd7744b90f6f943b3316e
7
- data.tar.gz: 5065d471bfa721b9e973ac276ffb60db09ed1a5e4f967fa8dd7010856d6709b9c44ea3b9cd5fab82c2b2ae2467a0b072f14a3c779db331abbcda1b9fa479a276
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
 
@@ -330,16 +334,17 @@ Fusuma plugins are provided with the `fusuma-plugin-XXXXX` naming convention and
330
334
 
331
335
  ### Available plugins
332
336
 
333
- | Name | About |
334
- | ------------------------------------------------------------------------------ | --------------------------------------------- |
335
- | [fusuma-plugin-sendkey](https://github.com/iberianpig/fusuma-plugin-sendkey) | Emulates keyboard events |
336
- | [fusuma-plugin-wmctrl](https://github.com/iberianpig/fusuma-plugin-wmctrl) | Manages Window and Workspace |
337
- | [fusuma-plugin-keypress](https://github.com/iberianpig/fusuma-plugin-keypress) | Detects gestures while pressing multiple keys |
338
- | [fusuma-plugin-tap](https://github.com/iberianpig/fusuma-plugin-tap) | Detects Tap and Hold gestures |
337
+ | Name | Version | About |
338
+ | ---------------------------------------------------------------------------------- | --------------------------------------------------------------------- | --------------------------------------------- |
339
+ | [fusuma-plugin-sendkey](https://github.com/iberianpig/fusuma-plugin-sendkey) | ![Gem Version](https://badge.fury.io/rb/fusuma-plugin-sendkey.svg) | Emulates keyboard events |
340
+ | [fusuma-plugin-wmctrl](https://github.com/iberianpig/fusuma-plugin-wmctrl) | ![Gem Version](https://badge.fury.io/rb/fusuma-plugin-wmctrl.svg) | Manages Window and Workspace |
341
+ | [fusuma-plugin-keypress](https://github.com/iberianpig/fusuma-plugin-keypress) | ![Gem Version](https://badge.fury.io/rb/fusuma-plugin-keypress.svg) | Detects gestures while pressing multiple keys |
342
+ | [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 |
343
+ | [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 |
339
344
 
340
345
  ## Tutorial Video
341
346
 
342
- [![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")
343
348
  [Multitouch Touchpad Gestures in Linux with Fusuma](http://www.youtube.com/watch?v=bn11Iwvf29I) by [Eric Adams](https://www.youtube.com/user/igster75)
344
349
 
345
350
  ## Support
@@ -348,7 +353,7 @@ I'm a Freelance Engineer in Japan and working on these products after finishing
348
353
  Currently, my open-source contribution times is not enough.
349
354
  If you like my work and want to contribute and become a sponsor, I will be able to focus on my projects.
350
355
 
351
- - [GitHub Sponsors](https://github.com/sponsors/iberianpig) (Zero fee!)
356
+ - [GitHub Sponsors](https://github.com/sponsors/iberianpig)
352
357
  - [Patreon](https://www.patreon.com/iberianpig)
353
358
 
354
359
  ## Contributing
data/fusuma.gemspec CHANGED
@@ -15,9 +15,8 @@ Gem::Specification.new do |spec|
15
15
  spec.homepage = 'https://github.com/iberianpig/fusuma'
16
16
  spec.license = 'MIT'
17
17
 
18
- spec.files = `git ls-files -z`.split("\x0").reject do |f|
19
- f.match(%r{^(test|spec|features)/})
20
- end
18
+ spec.files = Dir['{bin,lib,exe}/**/*', 'LICENSE*', 'README*', '*.gemspec']
19
+ spec.test_files = Dir['{test,spec,features}/**/*']
21
20
  spec.bindir = 'exe'
22
21
  spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
23
22
  spec.require_paths = ['lib']
@@ -25,5 +24,4 @@ Gem::Specification.new do |spec|
25
24
 
26
25
  spec.required_ruby_version = '>= 2.5.1' # https://packages.ubuntu.com/search?keywords=ruby&searchon=names&exact=1&suite=all&section=main
27
26
  # support bionic (18.04LTS) 2.5.1
28
- spec.add_dependency 'posix-spawn'
29
27
  end
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
@@ -1,6 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'posix/spawn'
3
+ require 'open3'
4
4
 
5
5
  module Fusuma
6
6
  # Execute libinput command
@@ -33,20 +33,20 @@ module Fusuma
33
33
  def list_devices(&block)
34
34
  cmd = list_devices_command
35
35
  MultiLogger.debug(list_devices: cmd)
36
- p, i, o, e = POSIX::Spawn.popen4(cmd)
36
+ i, o, e, _w = Open3.popen3(cmd)
37
+ MultiLogger.error(e.read) if o.eof?
37
38
  i.close
39
+ e.close
38
40
  o.each(&block)
39
- ensure
40
- [i, o, e].each { |io| io.close unless io.closed? }
41
- Process.waitpid(p)
42
41
  end
43
42
 
44
- # @return [Integer, IO] return a latest line libinput debug-events
45
- def debug_events
46
- @debug_events = begin
47
- p, i, o, _e = POSIX::Spawn.popen4(debug_events_with_options)
48
- i.close
49
- [p, o]
43
+ # @return [Integer] return a latest line libinput debug-events
44
+ def debug_events(writer)
45
+ @debug_events ||= begin
46
+ pid = Process.spawn(debug_events_with_options, out: writer,
47
+ in: '/dev/null')
48
+ Process.detach(pid)
49
+ pid
50
50
  end
51
51
  end
52
52
 
@@ -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
@@ -1,6 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'posix/spawn'
4
3
  require_relative './executor'
5
4
 
6
5
  module Fusuma
@@ -15,18 +14,19 @@ module Fusuma
15
14
  end
16
15
 
17
16
  def execute(event)
18
- search_command(event).tap do |command|
19
- break unless command
17
+ command = search_command(event)
20
18
 
21
- MultiLogger.info(command: command, args: event.record.args)
19
+ MultiLogger.info(command: command, args: event.record.args)
22
20
 
23
- additional_env = event.record.args
24
- .deep_transform_keys(&:to_s)
25
- .deep_transform_values { |v| (v * args_accel(event)).to_s }
21
+ accel = args_accel(event)
22
+ additional_env = event.record.args
23
+ .deep_transform_keys(&:to_s)
24
+ .deep_transform_values { |v| (v * accel).to_s }
26
25
 
27
- pid = POSIX::Spawn.spawn(additional_env, command.to_s)
28
- Process.detach(pid)
29
- end
26
+ pid = Process.spawn(additional_env, command.to_s)
27
+ Process.detach(pid)
28
+ rescue SystemCallError => e
29
+ MultiLogger.error("#{event.record.index.keys}": e.message.to_s)
30
30
  end
31
31
 
32
32
  def executable?(event)
@@ -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
@@ -25,8 +25,9 @@ module Fusuma
25
25
  # @return [IO]
26
26
  def io
27
27
  @io ||= begin
28
- @pid, io = command.debug_events
29
- io
28
+ reader, writer = create_io
29
+ @pid = command.debug_events(writer)
30
+ reader
30
31
  end
31
32
  end
32
33
 
@@ -64,6 +65,12 @@ module Fusuma
64
65
  def list_devices_command
65
66
  config_params(:'libinput-list-devices')
66
67
  end
68
+
69
+ private
70
+
71
+ def create_io
72
+ IO.pipe
73
+ end
67
74
  end
68
75
  end
69
76
  end
@@ -27,9 +27,9 @@ module Fusuma
27
27
  gemspec_path = Dir.glob("#{match_data[1]}/#{match_data[2]}/*.gemspec").first
28
28
  raise "Not Found: #{match_data[1]}/#{match_data[2]}/*.gemspec" unless gemspec_path
29
29
 
30
- gemspec = Gem::Specification.load gemspec_path
31
- fusuma_gemspec = Gem::Specification.load File.expand_path('../../../fusuma.gemspec',
32
- __dir__)
30
+ gemspec = Gem::Specification.load(gemspec_path)
31
+ fusuma_gemspec_path = File.expand_path('../../../fusuma.gemspec', __dir__)
32
+ fusuma_gemspec = Gem::Specification.load(fusuma_gemspec_path)
33
33
  if gemspec.dependencies.find { |d| d.name == 'fusuma' }&.match?(fusuma_gemspec)
34
34
  require siblings_plugin
35
35
  else
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Fusuma
4
- VERSION = '2.0.0'
4
+ VERSION = '2.0.5'
5
5
  end
@@ -0,0 +1,20 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'tempfile'
4
+ require './lib/fusuma/config'
5
+
6
+ module Fusuma
7
+ module ConfigHelper
8
+ module_function
9
+
10
+ def load_config_yml=(string)
11
+ Config.custom_path = Tempfile.open do |temp_file|
12
+ temp_file.tap { |f| f.write(string) }
13
+ end
14
+ end
15
+
16
+ def clear_config_yml
17
+ Config.custom_path = nil
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,179 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'spec_helper'
4
+ require './lib/fusuma/config'
5
+ require './lib/fusuma/config/searcher'
6
+
7
+ # spec for Config
8
+ module Fusuma
9
+ RSpec.describe Config::Searcher do
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
29
+
30
+ example.run
31
+
32
+ ConfigHelper.clear_config_yml
33
+ end
34
+
35
+ describe '.search' do
36
+ let(:index) { nil }
37
+ let(:location) { Config.instance.keymap[0] }
38
+ let(:search) { Config::Searcher.new.search(index, location: location) }
39
+ context 'index correct order' do
40
+ let(:index) { Config::Index.new %w[pinch in command] }
41
+ it { expect(Config::Searcher.new.search(index, location: location)).to eq 'ctrl+plus' }
42
+ end
43
+
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' }
47
+ end
48
+
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
65
+ end
66
+
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
166
+ end
167
+ end
168
+
169
+ describe 'private_method: :cache' do
170
+ it 'should cache command' do
171
+ key = %w[event_type finger direction command].join(',')
172
+ value = 'shourtcut string'
173
+ searcher = Config::Searcher.new
174
+ searcher.send(:cache, key) { value }
175
+ expect(searcher.send(:cache, key)).to eq value
176
+ end
177
+ end
178
+ end
179
+ end