fusuma 2.5.0 → 3.0.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: 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