fusuma 3.11.1 → 3.12.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 +4 -4
- data/README.md +5 -5
- data/bin/console +4 -4
- data/exe/fusuma +15 -15
- data/lib/fusuma/config/context_matcher.rb +44 -0
- data/lib/fusuma/config/index.rb +2 -0
- data/lib/fusuma/config/searcher.rb +27 -19
- data/lib/fusuma/config.rb +1 -0
- data/lib/fusuma/plugin/detectors/detector.rb +1 -0
- data/lib/fusuma/plugin/inputs/timer_input.rb +1 -0
- data/lib/fusuma/version.rb +1 -1
- metadata +3 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: d715f3ca82e4571ad3c23547a0e6d1d833327c225b40db7337b14b38fd10d024
|
|
4
|
+
data.tar.gz: 414ed1c453e221a0e01524212627c945564643af054d81c8022436929ce0964a
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 01f4fcec30760030cadc3d746d8c5c2423940493f610505d7ab6ceadb79751f845181f559b5c3924c80c8c272d773ba9ca56a9c9be5230e18e7b393b829b681d
|
|
7
|
+
data.tar.gz: 21db3821c594aca2aa3b8e881ea5288bec8e5447ed0b0e75a1a060a17fb4b0ab5cab8aa7489cc9d295fd212ec84f5dd4a489f4f45ad8439dc334459fa95b2574
|
data/README.md
CHANGED
|
@@ -9,7 +9,7 @@ Fusuma is a powerful tool designed to enable multitouch gesture recognition on L
|
|
|
9
9
|
|
|
10
10
|
## Features
|
|
11
11
|
|
|
12
|
-
- **Easy Installation**:
|
|
12
|
+
- **Easy Installation**: Easy to install via RubyGems.
|
|
13
13
|
- **Flexible Configuration**: Customize gestures and actions freely in YAML file format.
|
|
14
14
|
- **Sensitivity Settings**: Fine-tune gesture recognition with adjustable thresholds and intervals to suit your preferences and enhance precision.
|
|
15
15
|
- **Extension through Plugins**: A [plugin system](https://github.com/iberianpig/fusuma/#fusuma-plugins) allows for additional functionality as needed.
|
|
@@ -32,7 +32,7 @@ Then, You apply the change with no logout or reboot.
|
|
|
32
32
|
newgrp input
|
|
33
33
|
```
|
|
34
34
|
|
|
35
|
-
**IMPORTANT**: This makes `/dev/input/` readable, so if that's an issue for you for some reason (like for privacy- or
|
|
35
|
+
**IMPORTANT**: This makes `/dev/input/` readable, so if that's an issue for you for some reason (like for privacy- or security concerns etc. or if it causes other parts of your OS to misbehave), **consider this your heads-up.**
|
|
36
36
|
|
|
37
37
|
<details>
|
|
38
38
|
<summary>For Debian Based Distros (Ubuntu, Debian, Mint, Pop!_OS)</summary>
|
|
@@ -109,7 +109,7 @@ For sending shortcuts:
|
|
|
109
109
|
```sh
|
|
110
110
|
sudo pacman -Syu xdotool
|
|
111
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.
|
|
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. The package you would want is called `ruby-fusuma`.
|
|
113
113
|
|
|
114
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
115
|
Installing Fusuma this way means that if things do not work as intended during or after the installation, you are on your own.
|
|
@@ -428,8 +428,8 @@ Fusuma plugins are provided with the `fusuma-plugin-XXXXX` naming convention and
|
|
|
428
428
|
### Installation of Fusuma plugins
|
|
429
429
|
|
|
430
430
|
```sh
|
|
431
|
-
# install fusuma-plugin-
|
|
432
|
-
sudo gem install fusuma-plugin-XXXXX
|
|
431
|
+
# install fusuma-plugin-XXXXX
|
|
432
|
+
sudo gem install fusuma-plugin-XXXXX
|
|
433
433
|
```
|
|
434
434
|
```sh
|
|
435
435
|
# update
|
data/bin/console
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
#!/usr/bin/env ruby
|
|
2
2
|
# frozen_string_literal: true
|
|
3
3
|
|
|
4
|
-
require
|
|
5
|
-
require
|
|
4
|
+
require "bundler/setup"
|
|
5
|
+
require "fusuma"
|
|
6
6
|
|
|
7
7
|
# You can add fixtures and/or initialization code here to make experimenting
|
|
8
8
|
# with your gem easier. You can also use a different console, if you like.
|
|
@@ -10,9 +10,9 @@ require 'fusuma'
|
|
|
10
10
|
# (If you use this, don't forget to add pry to your Gemfile!)
|
|
11
11
|
|
|
12
12
|
def reload!(print = true)
|
|
13
|
-
puts
|
|
13
|
+
puts "Reloading ..." if print
|
|
14
14
|
# Main project directory.
|
|
15
|
-
root_dir = File.expand_path(
|
|
15
|
+
root_dir = File.expand_path("..", __dir__)
|
|
16
16
|
# Directories within the project that should be reloaded.
|
|
17
17
|
reload_dirs = %w[lib]
|
|
18
18
|
# Loop through and reload every file in all relevant project directories.
|
data/exe/fusuma
CHANGED
|
@@ -1,47 +1,47 @@
|
|
|
1
1
|
#!/usr/bin/env ruby
|
|
2
2
|
# frozen_string_literal: true
|
|
3
3
|
|
|
4
|
-
require
|
|
5
|
-
require_relative
|
|
4
|
+
require "optparse"
|
|
5
|
+
require_relative "../lib/fusuma"
|
|
6
6
|
|
|
7
7
|
option = {}
|
|
8
8
|
opt = OptionParser.new
|
|
9
9
|
|
|
10
|
-
opt.on(
|
|
11
|
-
|
|
10
|
+
opt.on("-c", "--config=path/to/file",
|
|
11
|
+
"Use an alternative config file") do |v|
|
|
12
12
|
option[:config_path] = v
|
|
13
13
|
end
|
|
14
14
|
|
|
15
|
-
opt.on(
|
|
16
|
-
|
|
15
|
+
opt.on("-d", "--daemon",
|
|
16
|
+
"Daemonize process") do |v|
|
|
17
17
|
option[:daemon] = v
|
|
18
18
|
end
|
|
19
19
|
|
|
20
|
-
opt.on(
|
|
21
|
-
|
|
20
|
+
opt.on("-l", "--list-devices",
|
|
21
|
+
"List available devices") do |v|
|
|
22
22
|
option[:list] = v
|
|
23
23
|
end
|
|
24
24
|
|
|
25
|
-
opt.on(
|
|
26
|
-
|
|
25
|
+
opt.on("--log=path/to/file",
|
|
26
|
+
"Print logs to file") do |v|
|
|
27
27
|
option[:log_filepath] = v
|
|
28
28
|
end
|
|
29
29
|
|
|
30
|
-
opt.on(
|
|
30
|
+
opt.on("--show-config", "Show config as YAML format which is loaded internally") do |v|
|
|
31
31
|
option[:show_config] = v
|
|
32
32
|
end
|
|
33
33
|
|
|
34
34
|
opt.on('--device="Device name"',
|
|
35
|
-
|
|
35
|
+
"Open the given device only (DEPRECATED)") do |v|
|
|
36
36
|
option[:device] = v
|
|
37
37
|
end
|
|
38
38
|
|
|
39
|
-
opt.on(
|
|
40
|
-
|
|
39
|
+
opt.on("-v", "--verbose",
|
|
40
|
+
"Show details about the results of running fusuma") do |v|
|
|
41
41
|
option[:verbose] = v
|
|
42
42
|
end
|
|
43
43
|
|
|
44
|
-
opt.on(
|
|
44
|
+
opt.on("--version", "Show fusuma version") do |v|
|
|
45
45
|
option[:version] = v
|
|
46
46
|
end
|
|
47
47
|
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Fusuma
|
|
4
|
+
class Config
|
|
5
|
+
# Matches context conditions for configuration lookup.
|
|
6
|
+
# Supports AND (multiple keys) and OR (array values) conditions.
|
|
7
|
+
class ContextMatcher
|
|
8
|
+
class << self
|
|
9
|
+
# Check if config context matches request context.
|
|
10
|
+
# @param config_context [Hash, nil] context defined in YAML config
|
|
11
|
+
# @param request_context [Hash, nil] context from runtime
|
|
12
|
+
# @return [Boolean] true if matched
|
|
13
|
+
#: (Hash[untyped, untyped]?, Hash[untyped, untyped]?) -> bool
|
|
14
|
+
def match?(config_context, request_context)
|
|
15
|
+
return true if config_context.nil? || config_context.empty?
|
|
16
|
+
return false if request_context.nil? || request_context.empty?
|
|
17
|
+
|
|
18
|
+
config_context.all? do |key, expected_value|
|
|
19
|
+
match_value?(expected_value, request_context[key])
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
private
|
|
24
|
+
|
|
25
|
+
# @param expected [Object] expected value (single or array for OR)
|
|
26
|
+
# @param actual [Object] actual value from request context
|
|
27
|
+
# @return [Boolean] true if matched
|
|
28
|
+
#: (untyped, untyped) -> bool
|
|
29
|
+
def match_value?(expected, actual)
|
|
30
|
+
case expected
|
|
31
|
+
when Array
|
|
32
|
+
if actual.is_a?(Array)
|
|
33
|
+
expected == actual # exact match when both are arrays
|
|
34
|
+
else
|
|
35
|
+
expected.include?(actual) # OR condition
|
|
36
|
+
end
|
|
37
|
+
else
|
|
38
|
+
expected == actual
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
end
|
|
44
|
+
end
|
data/lib/fusuma/config/index.rb
CHANGED
|
@@ -19,29 +19,37 @@ module Fusuma
|
|
|
19
19
|
def search(index, location:)
|
|
20
20
|
key = index.keys.first
|
|
21
21
|
return location if key.nil?
|
|
22
|
-
|
|
23
22
|
return nil if location.nil?
|
|
24
|
-
|
|
25
23
|
return nil unless location.is_a?(Hash)
|
|
26
24
|
|
|
27
|
-
next_index = Index.new(
|
|
25
|
+
next_index = Index.new(index.keys.drop(1))
|
|
28
26
|
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
27
|
+
next_location_cadidates(location, key).each do |next_location|
|
|
28
|
+
result = search(next_index, location: next_location)
|
|
29
|
+
return result if result
|
|
32
30
|
end
|
|
33
|
-
|
|
31
|
+
nil
|
|
34
32
|
end
|
|
35
33
|
|
|
36
34
|
#: (Fusuma::Config::Index, location: Array[untyped], context: Hash[untyped, untyped] | nil) -> untyped
|
|
37
35
|
def search_with_context(index, location:, context:)
|
|
38
36
|
return nil if location.nil?
|
|
39
37
|
|
|
40
|
-
|
|
38
|
+
# When context is nil or empty, search in no-context config blocks
|
|
39
|
+
if context.nil? || context == {}
|
|
40
|
+
no_context_conf = location.find { |conf| conf[:context].nil? }
|
|
41
|
+
return no_context_conf ? search(index, location: no_context_conf) : nil
|
|
42
|
+
end
|
|
41
43
|
|
|
44
|
+
# When context is specified, search only in context-having config blocks
|
|
42
45
|
value = nil
|
|
43
|
-
location.
|
|
44
|
-
|
|
46
|
+
location.each do |conf|
|
|
47
|
+
next if conf[:context].nil? # skip no-context blocks
|
|
48
|
+
|
|
49
|
+
if ContextMatcher.match?(conf[:context], context)
|
|
50
|
+
value = search(index, location: conf)
|
|
51
|
+
break if value
|
|
52
|
+
end
|
|
45
53
|
end
|
|
46
54
|
value
|
|
47
55
|
end
|
|
@@ -77,7 +85,7 @@ module Fusuma
|
|
|
77
85
|
def next_location_cadidates(location, key)
|
|
78
86
|
[
|
|
79
87
|
location[key.symbol],
|
|
80
|
-
key.skippable
|
|
88
|
+
key.skippable ? location : nil
|
|
81
89
|
].compact
|
|
82
90
|
end
|
|
83
91
|
|
|
@@ -103,12 +111,11 @@ module Fusuma
|
|
|
103
111
|
#: (Hash[untyped, untyped], ?Array[untyped]) { () -> untyped } -> Hash[untyped, untyped]?
|
|
104
112
|
def find_context(request_context, fallbacks = CONTEXT_SEARCH_ORDER, &block)
|
|
105
113
|
# Search in blocks in the following order.
|
|
106
|
-
# 1. primary context(no context)
|
|
107
|
-
# 2.
|
|
108
|
-
#
|
|
109
|
-
#
|
|
110
|
-
#
|
|
111
|
-
# partial_match_context(request_context, &block)
|
|
114
|
+
# 1. no_context: primary context (no context specified)
|
|
115
|
+
# 2. complete_match_context: config[:context] matches request_context
|
|
116
|
+
# - Supports OR condition (array values)
|
|
117
|
+
# - Supports AND condition (multiple keys)
|
|
118
|
+
# 3. partial_match_context: config[:context] partially matches request_context
|
|
112
119
|
fallbacks.find do |method|
|
|
113
120
|
result = send(method, request_context, &block)
|
|
114
121
|
return result if result
|
|
@@ -125,14 +132,15 @@ module Fusuma
|
|
|
125
132
|
{} if with_context({}, &block)
|
|
126
133
|
end
|
|
127
134
|
|
|
128
|
-
#
|
|
135
|
+
# Match config context with request context using ContextMatcher.
|
|
136
|
+
# Supports OR condition (array values) and AND condition (multiple keys).
|
|
129
137
|
# @param request_context [Hash]
|
|
130
138
|
# @return [Hash] matched context
|
|
131
139
|
# @return [NilClass] if not matched
|
|
132
140
|
#: (Hash[untyped, untyped]) { () -> untyped } -> Hash[untyped, untyped]?
|
|
133
141
|
def complete_match_context(request_context, &block)
|
|
134
142
|
Config.instance.keymap.each do |config|
|
|
135
|
-
next unless config[:context]
|
|
143
|
+
next unless ContextMatcher.match?(config[:context], request_context)
|
|
136
144
|
return config[:context] if with_context(config[:context], &block)
|
|
137
145
|
end
|
|
138
146
|
nil
|
data/lib/fusuma/config.rb
CHANGED
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
require_relative "multi_logger"
|
|
4
4
|
require_relative "config/index"
|
|
5
5
|
require_relative "config/searcher"
|
|
6
|
+
require_relative "config/context_matcher"
|
|
6
7
|
require_relative "config/yaml_duplication_checker"
|
|
7
8
|
require_relative "plugin/manager"
|
|
8
9
|
require_relative "hash_support"
|
data/lib/fusuma/version.rb
CHANGED
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: fusuma
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 3.
|
|
4
|
+
version: 3.12.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- iberianpig
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: exe
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2026-01-
|
|
11
|
+
date: 2026-01-26 00:00:00.000000000 Z
|
|
12
12
|
dependencies: []
|
|
13
13
|
description: Fusuma is multitouch gesture recognizer. This gem makes your touchpad
|
|
14
14
|
on Linux able to recognize swipes or pinchs and assign command to them. Read installation
|
|
@@ -29,6 +29,7 @@ files:
|
|
|
29
29
|
- lib/fusuma.rb
|
|
30
30
|
- lib/fusuma/config.rb
|
|
31
31
|
- lib/fusuma/config.yml
|
|
32
|
+
- lib/fusuma/config/context_matcher.rb
|
|
32
33
|
- lib/fusuma/config/index.rb
|
|
33
34
|
- lib/fusuma/config/searcher.rb
|
|
34
35
|
- lib/fusuma/config/yaml_duplication_checker.rb
|