fusuma 2.5.0 → 3.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 8c6f872a195572cd05d5cbf86ff5a55e3b7419b9ddc3a2e1b1b09bd395adde36
4
- data.tar.gz: 51c32b562df304b04a0b607b9e4404bfb7fb031fee73388a2902b56a6a94c4a5
3
+ metadata.gz: 4670e37d93cd689661c036a4d2a25361af7a283f407b3ffc98dd1d275d6ef675
4
+ data.tar.gz: 78735688ac87ab4c09ebd0f7b69000a56e5543916bd41b490df02b7130525832
5
5
  SHA512:
6
- metadata.gz: 90da79d6210fc47324fda9d3b5e4f9ed1f4e820ccead8c2dc0341d2bb69e3bd691c34db39bdb83cd94529f9e69efe478d02c1cca43f4b953bddd4b0eb46f8888
7
- data.tar.gz: adbd22a0b5a1d8213d96994e33a38c4cf2c6f667d33d16019cf1e4f90dee7d114301fee0c544e18e1e532fa7f10c5aa13c09963d5694072c63721bbc8f5ab065
6
+ metadata.gz: 998e0a7cd21c42870a7b747a0280f4aa55695bea79139f0bef3b2dbcedefc448548f4ed261b2993a67c6e9e5921fa2dcab93b595153fc9b9a04818816fdf605f
7
+ data.tar.gz: 8892cf28ab5d7bce157fbf7eca3c9458565585b223d36f9c15f7cc0b2d3d08248c643504f00bc33aac51b88e86270c59b3c886d968e1ce52f7f51a4614dcb16e
data/README.md CHANGED
@@ -1,4 +1,5 @@
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)
1
+ # Fusuma
2
+ ![Gem](https://img.shields.io/gem/v/fusuma?color=brightgreen) [![Build Status](https://github.com/iberianpig/fusuma/actions/workflows/main.yml/badge.svg)](https://github.com/iberianpig/fusuma/actions/workflows/main.yml)
2
3
 
3
4
  Fusuma is multitouch gesture recognizer.
4
5
  This gem makes your linux able to recognize swipes or pinchs and assign commands to them.
@@ -21,23 +22,28 @@ This gem makes your linux able to recognize swipes or pinchs and assign commands
21
22
 
22
23
  **IMPORTANT**: You **MUST** be a member of the **INPUT** group to read touchpad by Fusuma.
23
24
 
24
- ```bash
25
+ ```sh
25
26
  sudo gpasswd -a $USER input
26
27
  ```
27
28
 
28
29
  Then, You apply the change with no logout or reboot.
29
30
 
30
- ```bash
31
+ ```sh
31
32
  newgrp input
32
33
  ```
33
34
 
35
+ **IMPORTANT**: This makes `/dev/input/` readable, so if that's an issue for you for some reason (like for privacy- or securityconcerns etc. or if it causes other parts of your OS to misbehave), **consider this your heads-up.**
36
+
37
+ <details>
38
+ <summary>For Debian Based Distros (Ubuntu, Debian, Mint, Pop!OS)</summary>
39
+
34
40
  ### For Debian Based Distros (Ubuntu, Debian, Mint, Pop!OS)
35
41
 
36
42
  #### 1. Install libinput-tools
37
43
 
38
44
  You need `libinput` release 1.0 or later.
39
45
 
40
- ```bash
46
+ ```sh
41
47
  sudo apt-get install libinput-tools
42
48
  ```
43
49
 
@@ -45,13 +51,13 @@ sudo apt-get install libinput-tools
45
51
 
46
52
  Fusuma runs in Ruby, so you must install it first.
47
53
 
48
- ```bash
54
+ ```sh
49
55
  sudo apt-get install ruby
50
56
  ```
51
57
 
52
58
  #### 3. Install Fusuma
53
59
 
54
- ```bash
60
+ ```sh
55
61
  sudo gem install fusuma
56
62
  ```
57
63
 
@@ -59,26 +65,31 @@ sudo gem install fusuma
59
65
 
60
66
  For sending shortcuts:
61
67
 
62
- ```bash
68
+ ```sh
63
69
  sudo apt-get install xdotool
64
70
  ```
65
71
 
72
+ </details>
73
+
74
+ <details>
75
+ <summary> For Arch Based Distros (Manjaro, Arch) </summary>
76
+
66
77
  ### For Arch Based Distros (Manjaro, Arch)
67
78
 
68
79
  #### 1. Install libinput.
69
80
 
70
81
  You need `libinput` release 1.0 or later. This is most probably installed by default on Manjaro
71
82
 
72
- ```z-h
73
- sudo pacman -S libinput
83
+ ```sh
84
+ sudo pacman -Syu libinput
74
85
  ```
75
86
 
76
87
  #### 2. Install Ruby
77
88
 
78
89
  Fusuma runs in Ruby, so you must install it first.
79
90
 
80
- ```zsh
81
- sudo pacman -S ruby
91
+ ```sh
92
+ sudo pacman -Syu ruby
82
93
  ```
83
94
 
84
95
  #### 3. Install Fusuma
@@ -87,7 +98,7 @@ sudo pacman -S ruby
87
98
 
88
99
  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
100
 
90
- ```zsh
101
+ ```sh
91
102
  sudo gem install fusuma
92
103
  ```
93
104
 
@@ -95,9 +106,19 @@ sudo gem install fusuma
95
106
 
96
107
  For sending shortcuts:
97
108
 
98
- ```zsh
99
- sudo pacman -S xdotool
109
+ ```sh
110
+ sudo pacman -Syu xdotool
100
111
  ```
112
+ **For the truly lazy people:** As with pretty much anything else available as Open-Source-Software, you can install Fusuma via a package from the AUR. As off time of writing (March 2023), the package you would want is called `ruby-fusuma`.
113
+
114
+ Please keep in mind that this community-built package is NOT officially supported here and while it might do the job, it is not the intended way to install.
115
+ Installing Fusuma this way means that if things do not work as intended during or after the installation, you are on your own.
116
+ So please do not bombard the Issues-Page here on Github if Fusuma isn't working correctly after installing it via the AUR.
117
+ Fusuma's plugins as listed below here in this Readme can be installed as optional dependencies also via the AUR, namescheme being `ruby-fusuma-replacewithnameofplugin`.
118
+ </details>
119
+
120
+ <details>
121
+ <summary>For Fedora</summary>
101
122
 
102
123
  ### For Fedora
103
124
 
@@ -105,7 +126,7 @@ sudo pacman -S xdotool
105
126
 
106
127
  You need `libinput` release 1.0 or later.
107
128
 
108
- ```bash
129
+ ```sh
109
130
  sudo dnf install libinput
110
131
  ```
111
132
 
@@ -113,13 +134,13 @@ sudo dnf install libinput
113
134
 
114
135
  Fusuma runs in Ruby, so you must install it first.
115
136
 
116
- ```bash
137
+ ```sh
117
138
  sudo dnf install ruby
118
139
  ```
119
140
 
120
141
  #### 3. Install Fusuma
121
142
 
122
- ```bash
143
+ ```sh
123
144
  sudo gem install fusuma
124
145
  ```
125
146
 
@@ -127,27 +148,28 @@ sudo gem install fusuma
127
148
 
128
149
  For sending shortcuts:
129
150
 
130
- ```bash
151
+ ```sh
131
152
  sudo dnf install xdotool
132
153
  ```
154
+ </details>
133
155
 
134
156
  ### Touchpad not working in GNOME
135
157
 
136
158
  Ensure the touchpad events are being sent to the GNOME desktop by running the following command:
137
159
 
138
- ```bash
160
+ ```sh
139
161
  gsettings set org.gnome.desktop.peripherals.touchpad send-events enabled
140
162
  ```
141
163
 
142
164
  ## Usage
143
165
 
144
- ```bash
166
+ ```sh
145
167
  fusuma
146
168
  ```
147
169
 
148
170
  ## Update
149
171
 
150
- ```bash
172
+ ```sh
151
173
  sudo gem update fusuma
152
174
  ```
153
175
 
@@ -156,7 +178,7 @@ sudo gem update fusuma
156
178
  You can customize the settings for gestures to put and edit `~/.config/fusuma/config.yml`.
157
179
  **NOTE: You will need to create the `~/.config/fusuma` directory if it doesn't exist yet.**
158
180
 
159
- ```bash
181
+ ```sh
160
182
  mkdir -p ~/.config/fusuma # create config directory
161
183
  nano ~/.config/fusuma/config.yml # edit config file.
162
184
  ```
@@ -322,7 +344,6 @@ swipe:
322
344
  #### Alternatives to xdotool
323
345
 
324
346
  - [fusuma-plugin-sendkey](https://github.com/iberianpig/fusuma-plugin-sendkey)
325
-
326
347
  - Emulates keyboard events
327
348
  - Low latency
328
349
  - Wayland compatible
@@ -334,7 +355,8 @@ swipe:
334
355
  - [ydotool](https://github.com/ReimuNotMoe/ydotool)
335
356
  - Wayland compatible
336
357
  - Needs more maintainers.
337
- - Requires only replacing `xdotool` with `ydotool` in fusuma conf.
358
+
359
+
338
360
 
339
361
  ## Options
340
362
 
@@ -376,22 +398,22 @@ Following features are provided as plugins.
376
398
 
377
399
  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).
378
400
 
379
- | Name | Version | About |
380
- | ---------------------------------------------------------------------------------- | --------------------------------------------------------------------- | --------------------------------------------- |
381
- | [fusuma-plugin-sendkey](https://github.com/iberianpig/fusuma-plugin-sendkey) | ![Gem Version](https://badge.fury.io/rb/fusuma-plugin-sendkey.svg) | Emulates keyboard events |
382
- | [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 |
383
- | [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 |
384
- | [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 |
385
- | [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 |
401
+ | Name | Version | About |
402
+ | --- | --- | --- |
403
+ | [fusuma-plugin-sendkey](https://github.com/iberianpig/fusuma-plugin-sendkey) | ![Gem](https://img.shields.io/gem/v/fusuma-plugin-sendkey?color=brightgreen) | Emulates keyboard events(Wayland compatible) |
404
+ | [fusuma-plugin-wmctrl](https://github.com/iberianpig/fusuma-plugin-wmctrl) | ![Gem](https://img.shields.io/gem/v/fusuma-plugin-wmctrl?color=brightgreen) | Manages Window and Workspace |
405
+ | [fusuma-plugin-keypress](https://github.com/iberianpig/fusuma-plugin-keypress) | ![Gem](https://img.shields.io/gem/v/fusuma-plugin-keypress?color=brightgreen) | Detecting a combination of key presses and touchpad gestures |
406
+ | [fusuma-plugin-tap](https://github.com/iberianpig/fusuma-plugin-tap) | ![Gem](https://img.shields.io/gem/v/fusuma-plugin-tap?color=brightgreen) | Detects Tap gesture |
407
+ | [fusuma-plugin-appmatcher](https://github.com/iberianpig/fusuma-plugin-appmatcher) | ![Gem](https://img.shields.io/gem/v/fusuma-plugin-appmatcher?color=brightgreen) | Configure app-specific gestures |
386
408
 
387
409
 
388
410
  ### Installation of Fusuma plugins
389
411
 
390
- ```bash
412
+ ```sh
391
413
  # install fusuma-plugin-XXXX
392
414
  sudo gem install fusuma-plugin-XXXXX`
393
415
  ```
394
- ```bash
416
+ ```sh
395
417
  # update
396
418
  sudo gem list fusuma-plugin- | cut -d' ' -f1 | xargs --no-run-if-empty sudo gem update
397
419
  ```
@@ -408,7 +430,6 @@ Currently, my open-source contribution times is not enough.
408
430
  If you like my work and want to contribute and become a sponsor, I will be able to focus on my projects.
409
431
 
410
432
  - [GitHub Sponsors](https://github.com/sponsors/iberianpig)
411
- - [Patreon](https://www.patreon.com/iberianpig)
412
433
 
413
434
  ## Contributing
414
435
 
data/bin/console CHANGED
@@ -23,5 +23,5 @@ def reload!(print = true)
23
23
  true
24
24
  end
25
25
 
26
- require 'pry'
27
- Pry.start
26
+ require "irb"
27
+ IRB.start(__FILE__)
@@ -6,17 +6,19 @@ module Fusuma
6
6
  # index for config.yml
7
7
  class Index
8
8
  def initialize(keys)
9
- @keys = case keys
9
+ @count = 0
10
+ case keys
10
11
  when Array
11
- keys.map do |key|
12
- if key.is_a? Key
13
- key
14
- else
15
- Key.new(key)
16
- end
17
- end
12
+ @keys = []
13
+ @cache_key = keys.map do |key|
14
+ key = Key.new(key) if !key.is_a? Key
15
+ @keys << key
16
+ key.symbol
17
+ end.join(",")
18
18
  else
19
- [Key.new(keys)]
19
+ key = Key.new(keys)
20
+ @cache_key = key.symbol
21
+ @keys = [key]
20
22
  end
21
23
  end
22
24
 
@@ -24,36 +26,11 @@ module Fusuma
24
26
  @keys.map(&:inspect)
25
27
  end
26
28
 
27
- attr_reader :keys
28
-
29
- def cache_key
30
- case @keys
31
- when Array
32
- @keys.map(&:symbol).join(",")
33
- when Key
34
- @keys.symbol
35
- else
36
- raise "invalid keys"
37
- end
38
- end
39
-
40
- # @return [Index]
41
- def with_context
42
- keys = @keys.map do |key|
43
- next if Searcher.skip? && key.skippable
44
-
45
- if Searcher.fallback? && key.fallback
46
- key.fallback
47
- else
48
- key
49
- end
50
- end
51
- self.class.new(keys.compact)
52
- end
29
+ attr_reader :keys, :cache_key
53
30
 
54
31
  # Keys in Index
55
32
  class Key
56
- def initialize(symbol_word, skippable: false, fallback: nil)
33
+ def initialize(symbol_word, skippable: false)
57
34
  @symbol = begin
58
35
  symbol_word.to_sym
59
36
  rescue
@@ -61,21 +38,17 @@ module Fusuma
61
38
  end
62
39
 
63
40
  @skippable = skippable
64
-
65
- @fallback = begin
66
- fallback.to_sym
67
- rescue
68
- fallback
69
- end
70
41
  end
71
42
 
72
43
  def inspect
73
- skip_marker = @skippable && Searcher.skip? ? "(skip)" : ""
74
- fallback_marker = @fallback && Searcher.fallback? ? "(fallback)" : ""
75
- "#{@symbol}#{skip_marker}#{fallback_marker}"
44
+ if @skippable
45
+ "#{@symbol}(skippable)"
46
+ else
47
+ "#{@symbol}"
48
+ end
76
49
  end
77
50
 
78
- attr_reader :symbol, :skippable, :fallback
51
+ attr_reader :symbol, :skippable
79
52
  end
80
53
  end
81
54
  end
@@ -6,7 +6,7 @@ module Fusuma
6
6
  # Search config.yml
7
7
  class Searcher
8
8
  def initialize
9
- @cache = nil
9
+ @cache = {}
10
10
  end
11
11
 
12
12
  # @param index [Index]
@@ -36,10 +36,11 @@ module Fusuma
36
36
 
37
37
  return search(index, location: location[0]) if context == {}
38
38
 
39
- new_location = location.find do |conf|
40
- search(index, location: conf) if conf[:context] == context
39
+ value = nil
40
+ location.find do |conf|
41
+ value = search(index, location: conf) if conf[:context] == context
41
42
  end
42
- search(index, location: new_location)
43
+ value
43
44
  end
44
45
 
45
46
  # @param index [Index]
@@ -48,13 +49,12 @@ module Fusuma
48
49
  # @return [Hash]
49
50
  # @return [Object]
50
51
  def search_with_cache(index, location:)
51
- cache([index.cache_key, Searcher.context, Searcher.skip?, Searcher.fallback?]) do
52
+ cache([index.cache_key, Searcher.context]) do
52
53
  search_with_context(index, location: location, context: Searcher.context)
53
54
  end
54
55
  end
55
56
 
56
57
  def cache(key)
57
- @cache ||= {}
58
58
  key = key.join(",") if key.is_a? Array
59
59
  if @cache.key?(key)
60
60
  @cache[key]
@@ -71,37 +71,11 @@ module Fusuma
71
71
  def next_location_cadidates(location, key)
72
72
  [
73
73
  location[key.symbol],
74
- Searcher.skip? && key.skippable && location
74
+ key.skippable && location
75
75
  ].compact
76
76
  end
77
77
 
78
78
  class << self
79
- # @return [Hash]
80
- def conditions(&block)
81
- {
82
- nothing: -> { block.call },
83
- skip: -> { Config::Searcher.skip { block.call } }
84
- }
85
- end
86
-
87
- # Execute block with specified conditions
88
- # @param conidtion [Symbol]
89
- # @return [Object]
90
- def with_condition(condition, &block)
91
- conditions(&block)[condition].call
92
- end
93
-
94
- # Execute block with all conditions
95
- # @return [Array<Symbol, Object>]
96
- def find_condition(&block)
97
- conditions(&block).find do |c, l|
98
- result = l.call
99
- return [c, result] if result
100
-
101
- nil
102
- end
103
- end
104
-
105
79
  # Search with context from load_streamed Config
106
80
  # @param context [Hash]
107
81
  # @return [Object]
@@ -117,48 +91,27 @@ module Fusuma
117
91
  # @return [Hash]
118
92
  def find_context(request_context, &block)
119
93
  # Search in blocks in the following order.
120
- # 1. complete match config[:context] == request_context
121
- # 2. partial match config[:context] =~ request_context
122
- # 3. no context
94
+ # 1. primary context(no context)
95
+ # 2. complete match config[:context] == request_context
96
+ # 3. partial match config[:context] =~ request_context
97
+ return {} if with_context({}, &block)
98
+
123
99
  Config.instance.keymap.each do |config|
124
100
  next unless config[:context] == request_context
125
- return config[:context] if with_context(config[:context]) { block.call }
101
+ return config[:context] if with_context(config[:context], &block)
126
102
  end
127
103
  if request_context.keys.size > 1
128
104
  Config.instance.keymap.each do |config|
129
105
  next if config[:context].nil?
130
106
 
131
107
  next unless config[:context].all? { |k, v| request_context[k] == v }
132
- return config[:context] if with_context(config[:context]) { block.call }
108
+ return config[:context] if with_context(config[:context], &block)
133
109
  end
134
110
  end
135
- return {} if with_context({}) { block.call }
136
111
  end
137
112
 
138
113
  attr_reader :context
139
114
 
140
- def fallback?
141
- @fallback
142
- end
143
-
144
- def skip?
145
- @skip
146
- end
147
-
148
- # switch context for fallback
149
- def fallback(&block)
150
- @fallback = true
151
- result = block.call
152
- @fallback = false
153
- result
154
- end
155
-
156
- def skip(&block)
157
- @skip = true
158
- result = block.call
159
- @skip = false
160
- result
161
- end
162
115
  end
163
116
  end
164
117
  end
@@ -7,15 +7,47 @@ module Fusuma
7
7
  module CustomProcess
8
8
  attr_writer :proctitle
9
9
 
10
+ def child_pids
11
+ @child_pids ||= []
12
+ end
13
+
10
14
  def fork
11
- Process.fork do
15
+ pid = Process.fork do
12
16
  Process.setproctitle(proctitle)
17
+ set_trap # for child process
13
18
  yield
14
19
  end
20
+ child_pids << pid
21
+ pid
22
+ end
23
+
24
+ def shutdown
25
+ child_pids.each do |pid|
26
+ Process.kill("TERM", pid)
27
+ rescue Errno::ESRCH
28
+ # ignore
29
+ end
30
+
31
+ child_pids.each do |pid|
32
+ Process.wait(pid)
33
+ rescue Errno::ECHILD
34
+ # ignore
35
+ end
15
36
  end
16
37
 
17
38
  def proctitle
18
39
  @proctitle ||= self.class.name.underscore
19
40
  end
41
+
42
+ def set_trap
43
+ Signal.trap("INT") {
44
+ shutdown
45
+ exit
46
+ } # Trap ^C
47
+ Signal.trap("TERM") {
48
+ shutdown
49
+ exit
50
+ } # Trap `Kill `
51
+ end
20
52
  end
21
53
  end
data/lib/fusuma/device.rb CHANGED
@@ -66,6 +66,7 @@ module Fusuma
66
66
  line_parser = LineParser.new
67
67
 
68
68
  libinput_command = Plugin::Inputs::LibinputCommandInput.new.command
69
+ # note: this libinput command takes a nontrivial amout of time (~200ms)
69
70
  libinput_command.list_devices do |line|
70
71
  line_parser.push(line)
71
72
  end
@@ -32,6 +32,8 @@ module Fusuma
32
32
  def debug(msg)
33
33
  return unless debug_mode?
34
34
 
35
+ return if ignore_pattern?(msg)
36
+
35
37
  super(msg)
36
38
  end
37
39
 
@@ -47,6 +49,20 @@ module Fusuma
47
49
  debug_mode
48
50
  end
49
51
 
52
+ def ignore_pattern?(msg)
53
+ # TODO: configurable from config.yml
54
+ pattern = /timer_input/
55
+ case msg
56
+ when Hash
57
+ e = msg.values.find { |v| v.is_a? Fusuma::Plugin::Events::Event }
58
+ return unless e
59
+
60
+ e.tag.match?(pattern)
61
+ else
62
+ false
63
+ end
64
+ end
65
+
50
66
  class << self
51
67
  def info(msg)
52
68
  instance.info(msg)
@@ -8,7 +8,6 @@ module Fusuma
8
8
  module Plugin
9
9
  # Create a Plugin Class with extending this class
10
10
  class Base
11
- include CustomProcess
12
11
  # when inherited from subclass
13
12
  def self.inherited(subclass)
14
13
  super
@@ -22,6 +21,10 @@ module Fusuma
22
21
  Manager.plugins[name]
23
22
  end
24
23
 
24
+ # @abstract override `#shutdown` to implement
25
+ def shutdown
26
+ end
27
+
25
28
  # config parameter name and Type of the value of parameter
26
29
  # @return [Hash]
27
30
  def config_param_types