fusuma 0.2.0 → 0.2.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.rubocop.yml +7 -0
- data/fusuma.gemspec +1 -0
- data/lib/fusuma/action_stack.rb +21 -38
- data/lib/fusuma/config.rb +77 -0
- data/lib/fusuma/config.yml +13 -9
- data/lib/fusuma/gesture_info.rb +25 -0
- data/lib/fusuma/pinch.rb +26 -0
- data/lib/fusuma/swipe.rb +26 -0
- data/lib/fusuma/version.rb +1 -1
- data/lib/fusuma.rb +5 -31
- metadata +21 -3
- data/config.yml +0 -24
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 46afda55ad48083da6e0d94a17a9ec3b1a009b4b
|
4
|
+
data.tar.gz: 475fabc77f03056b25f9b718c26875bc75871380
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 87b72d664ca8e7891f02265030fe261f7576b7de85ef55aad28f81809d06eaf29a4d016359375b1dae05847f4c13d86a752254fe65b7da9492e09b0b7ed9fa4e
|
7
|
+
data.tar.gz: fa163ef797185c55af24204466f8bb48f80d01fcbf1571973b3e7e51c495982186df767b7114280cdba4b7cadb8061b1c7259e8d79b64213eaccddd6dfbb971b
|
data/.rubocop.yml
ADDED
data/fusuma.gemspec
CHANGED
data/lib/fusuma/action_stack.rb
CHANGED
@@ -5,7 +5,6 @@ module Fusuma
|
|
5
5
|
super(*args)
|
6
6
|
end
|
7
7
|
|
8
|
-
# return { finger:, direction:, action: } or nil
|
9
8
|
def gesture_info
|
10
9
|
return unless enough_actions? && enough_time_passed?
|
11
10
|
action_type = detect_action_type
|
@@ -25,8 +24,6 @@ module Fusuma
|
|
25
24
|
|
26
25
|
private
|
27
26
|
|
28
|
-
GestureInfo = Struct.new(:finger, :direction, :action_type)
|
29
|
-
|
30
27
|
def elapsed_time
|
31
28
|
return 0 if length.zero?
|
32
29
|
last.time - first.time
|
@@ -35,39 +32,38 @@ module Fusuma
|
|
35
32
|
def detect_direction(action_type)
|
36
33
|
case action_type
|
37
34
|
when 'swipe'
|
38
|
-
|
35
|
+
detect_swipe
|
39
36
|
when 'pinch'
|
40
|
-
|
37
|
+
detect_pinch
|
41
38
|
end
|
42
39
|
end
|
43
40
|
|
44
|
-
def
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
return move[:x] > 0 ? 'right' : 'left' if move[:x].abs > move[:y].abs
|
49
|
-
move[:y] > 0 ? 'down' : 'up'
|
41
|
+
def detect_swipe
|
42
|
+
swipe = avg_swipe
|
43
|
+
return unless swipe.enough_distance?
|
44
|
+
swipe.direction
|
50
45
|
end
|
51
46
|
|
52
|
-
def
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
return unless enough_diameter?(diameter)
|
57
|
-
return 'in' if diameter > 1
|
58
|
-
'out'
|
47
|
+
def detect_pinch
|
48
|
+
pinch = avg_pinch
|
49
|
+
return unless pinch.enough_diameter?
|
50
|
+
pinch.direction
|
59
51
|
end
|
60
52
|
|
61
53
|
def detect_finger
|
62
54
|
last.finger
|
63
55
|
end
|
64
56
|
|
65
|
-
|
57
|
+
def avg_swipe
|
58
|
+
move_x = avg_attrs(:move_x)
|
59
|
+
move_y = avg_attrs(:move_y)
|
60
|
+
Swipe.new(move_x, move_y)
|
61
|
+
end
|
66
62
|
|
67
|
-
def
|
68
|
-
|
69
|
-
|
70
|
-
|
63
|
+
def avg_pinch
|
64
|
+
diameter = avg_attrs(:zoom)
|
65
|
+
delta_diameter = diameter - first.zoom
|
66
|
+
Pinch.new(delta_diameter)
|
71
67
|
end
|
72
68
|
|
73
69
|
def sum_attrs(attr)
|
@@ -89,21 +85,8 @@ module Fusuma
|
|
89
85
|
last.action
|
90
86
|
end
|
91
87
|
|
92
|
-
def enough_distance?(move)
|
93
|
-
(move[:x].abs > 20) || (move[:y].abs > 20)
|
94
|
-
end
|
95
|
-
|
96
|
-
def enough_diameter?(avg_diameter)
|
97
|
-
delta_diameter = if avg_diameter > 1
|
98
|
-
avg_diameter - first.zoom
|
99
|
-
else
|
100
|
-
first.zoom - avg_diameter
|
101
|
-
end
|
102
|
-
delta_diameter > 0.3
|
103
|
-
end
|
104
|
-
|
105
88
|
def enough_actions?
|
106
|
-
(length > 1) && (elapsed_time > 0.
|
89
|
+
(length > 1) && (elapsed_time > 0.05)
|
107
90
|
end
|
108
91
|
|
109
92
|
def enough_time_passed?
|
@@ -111,7 +94,7 @@ module Fusuma
|
|
111
94
|
end
|
112
95
|
|
113
96
|
def last_triggerd_time
|
114
|
-
@last_triggered_time
|
97
|
+
@last_triggered_time ||= 0
|
115
98
|
end
|
116
99
|
|
117
100
|
def detect_action_type
|
@@ -0,0 +1,77 @@
|
|
1
|
+
# module as namespace
|
2
|
+
module Fusuma
|
3
|
+
require 'singleton'
|
4
|
+
# read keymap from yaml file
|
5
|
+
class Config
|
6
|
+
include Singleton
|
7
|
+
|
8
|
+
class << self
|
9
|
+
def shortcut(gesture_info)
|
10
|
+
instance.shortcut(gesture_info)
|
11
|
+
end
|
12
|
+
|
13
|
+
def threshold(action_type)
|
14
|
+
instance.threshold(action_type)
|
15
|
+
end
|
16
|
+
|
17
|
+
def reload
|
18
|
+
instance.reload
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
def initialize
|
23
|
+
reload
|
24
|
+
end
|
25
|
+
attr_accessor :keymap
|
26
|
+
|
27
|
+
def reload
|
28
|
+
@cache = nil
|
29
|
+
@keymap = YAML.load_file(file_path)
|
30
|
+
self
|
31
|
+
end
|
32
|
+
|
33
|
+
def shortcut(gesture_info)
|
34
|
+
seek_index = [*action_index(gesture_info), 'shortcut']
|
35
|
+
cache(seek_index) { search_config(keymap, seek_index) }
|
36
|
+
end
|
37
|
+
|
38
|
+
def threshold(action_type)
|
39
|
+
seek_index = ['threshold', action_type]
|
40
|
+
cache(seek_index) { search_config(keymap, seek_index) } || 1
|
41
|
+
end
|
42
|
+
|
43
|
+
private
|
44
|
+
|
45
|
+
def search_config(keymap_node, seek_index)
|
46
|
+
if seek_index == []
|
47
|
+
return nil if keymap_node.is_a? Hash
|
48
|
+
return keymap_node
|
49
|
+
end
|
50
|
+
key = seek_index[0]
|
51
|
+
child_node = keymap_node[key]
|
52
|
+
next_index = seek_index[1..-1]
|
53
|
+
return search_config(child_node, next_index) if child_node
|
54
|
+
search_config(keymap_node, next_index)
|
55
|
+
end
|
56
|
+
|
57
|
+
def file_path
|
58
|
+
filename = 'fusuma/config.yml'
|
59
|
+
original_path = File.expand_path "~/.config/#{filename}"
|
60
|
+
default_path = File.expand_path "../../#{filename}", __FILE__
|
61
|
+
File.exist?(original_path) ? original_path : default_path
|
62
|
+
end
|
63
|
+
|
64
|
+
def action_index(gesture_info)
|
65
|
+
action_type = gesture_info.action_type
|
66
|
+
finger = gesture_info.finger
|
67
|
+
direction = gesture_info.direction
|
68
|
+
[action_type, finger, direction]
|
69
|
+
end
|
70
|
+
|
71
|
+
def cache(key)
|
72
|
+
@cache ||= {}
|
73
|
+
key = key.join(',') if key.is_a? Array
|
74
|
+
@cache[key] ||= block_given? ? yield : nil
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
data/lib/fusuma/config.yml
CHANGED
@@ -1,24 +1,28 @@
|
|
1
1
|
swipe:
|
2
|
-
3:
|
3
|
-
left:
|
2
|
+
3:
|
3
|
+
left:
|
4
4
|
shortcut: 'alt+Left'
|
5
|
-
right:
|
5
|
+
right:
|
6
6
|
shortcut: 'alt+Right'
|
7
|
-
up:
|
7
|
+
up:
|
8
8
|
shortcut: 'ctrl+t'
|
9
|
-
down:
|
9
|
+
down:
|
10
10
|
shortcut: 'ctrl+w'
|
11
11
|
4:
|
12
|
-
left:
|
12
|
+
left:
|
13
13
|
shortcut: 'super+Left'
|
14
|
-
right:
|
14
|
+
right:
|
15
15
|
shortcut: 'super+Right'
|
16
|
-
up:
|
16
|
+
up:
|
17
17
|
shortcut: 'super+a'
|
18
|
-
down:
|
18
|
+
down:
|
19
19
|
shortcut: 'super+s'
|
20
20
|
pinch:
|
21
21
|
in:
|
22
22
|
shortcut: 'ctrl+plus'
|
23
23
|
out:
|
24
24
|
shortcut: 'ctrl+minus'
|
25
|
+
|
26
|
+
threshold:
|
27
|
+
swipe: 1
|
28
|
+
pinch: 1
|
@@ -0,0 +1,25 @@
|
|
1
|
+
module Fusuma
|
2
|
+
# manage actions
|
3
|
+
class GestureInfo
|
4
|
+
def initialize(finger, direction, action_type)
|
5
|
+
@finger = finger.to_i
|
6
|
+
@direction = direction
|
7
|
+
@action_type = action_type
|
8
|
+
end
|
9
|
+
attr_reader :finger, :direction, :action_type
|
10
|
+
|
11
|
+
def trigger_keyevent
|
12
|
+
exec_xdotool(shortcut)
|
13
|
+
end
|
14
|
+
|
15
|
+
private
|
16
|
+
|
17
|
+
def exec_xdotool(keys)
|
18
|
+
`xdotool key #{keys}` unless keys.nil?
|
19
|
+
end
|
20
|
+
|
21
|
+
def shortcut
|
22
|
+
Config.shortcut(self)
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
data/lib/fusuma/pinch.rb
ADDED
@@ -0,0 +1,26 @@
|
|
1
|
+
module Fusuma
|
2
|
+
# manage actions
|
3
|
+
class Pinch
|
4
|
+
BASE_THERESHOLD = 0.3
|
5
|
+
|
6
|
+
def initialize(diameter)
|
7
|
+
@diameter = diameter.to_f
|
8
|
+
end
|
9
|
+
|
10
|
+
attr_reader :diameter
|
11
|
+
|
12
|
+
def direction
|
13
|
+
return 'in' if diameter > 0
|
14
|
+
'out'
|
15
|
+
end
|
16
|
+
|
17
|
+
def enough_diameter?
|
18
|
+
MultiLogger.debug(diameter: diameter)
|
19
|
+
diameter.abs > threshold
|
20
|
+
end
|
21
|
+
|
22
|
+
def threshold
|
23
|
+
@threshold ||= BASE_THERESHOLD * Config.threshold('pinch')
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
data/lib/fusuma/swipe.rb
ADDED
@@ -0,0 +1,26 @@
|
|
1
|
+
module Fusuma
|
2
|
+
# manage actions
|
3
|
+
class Swipe
|
4
|
+
BASE_THERESHOLD = 20
|
5
|
+
|
6
|
+
def initialize(x, y)
|
7
|
+
@x = x
|
8
|
+
@y = y
|
9
|
+
end
|
10
|
+
attr_reader :x, :y
|
11
|
+
|
12
|
+
def direction
|
13
|
+
return x > 0 ? 'right' : 'left' if x.abs > y.abs
|
14
|
+
y > 0 ? 'down' : 'up'
|
15
|
+
end
|
16
|
+
|
17
|
+
def enough_distance?
|
18
|
+
MultiLogger.debug(x: x, y: y)
|
19
|
+
(x.abs > threshold) || (y.abs > threshold)
|
20
|
+
end
|
21
|
+
|
22
|
+
def threshold
|
23
|
+
@threshold ||= BASE_THERESHOLD * Config.threshold('swipe')
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
data/lib/fusuma/version.rb
CHANGED
data/lib/fusuma.rb
CHANGED
@@ -1,7 +1,11 @@
|
|
1
1
|
require_relative 'fusuma/version'
|
2
2
|
require_relative 'fusuma/action_stack'
|
3
3
|
require_relative 'fusuma/gesture_action'
|
4
|
+
require_relative 'fusuma/gesture_info'
|
5
|
+
require_relative 'fusuma/swipe.rb'
|
6
|
+
require_relative 'fusuma/pinch.rb'
|
4
7
|
require_relative 'fusuma/multi_logger'
|
8
|
+
require_relative 'fusuma/config.rb'
|
5
9
|
require 'logger'
|
6
10
|
require 'open3'
|
7
11
|
require 'yaml'
|
@@ -34,7 +38,7 @@ module Fusuma
|
|
34
38
|
@action_stack ||= ActionStack.new
|
35
39
|
@action_stack.push gesture_action
|
36
40
|
gesture_info = @action_stack.gesture_info
|
37
|
-
trigger_keyevent
|
41
|
+
gesture_info.trigger_keyevent unless gesture_info.nil?
|
38
42
|
end
|
39
43
|
end
|
40
44
|
end
|
@@ -71,35 +75,5 @@ module Fusuma
|
|
71
75
|
return false if line =~ %r{n/a}
|
72
76
|
true
|
73
77
|
end
|
74
|
-
|
75
|
-
def trigger_keyevent(gesture_info)
|
76
|
-
case gesture_info.action_type
|
77
|
-
when 'swipe'
|
78
|
-
swipe(gesture_info.finger, gesture_info.direction)
|
79
|
-
when 'pinch'
|
80
|
-
pinch(gesture_info.direction)
|
81
|
-
end
|
82
|
-
end
|
83
|
-
|
84
|
-
def swipe(finger, direction)
|
85
|
-
shortcut = event_map['swipe'][finger.to_i][direction]['shortcut']
|
86
|
-
`xdotool key #{shortcut}` unless shortcut.nil?
|
87
|
-
end
|
88
|
-
|
89
|
-
def pinch(direction)
|
90
|
-
shortcut = event_map['pinch'][direction]['shortcut']
|
91
|
-
`xdotool key #{shortcut}` unless shortcut.nil?
|
92
|
-
end
|
93
|
-
|
94
|
-
def event_map
|
95
|
-
@event_map ||= YAML.load_file(config_file)
|
96
|
-
end
|
97
|
-
|
98
|
-
def config_file
|
99
|
-
filename = 'fusuma/config.yml'
|
100
|
-
original_path = File.expand_path "~/.config/#{filename}"
|
101
|
-
default_path = File.expand_path "../#{filename}", __FILE__
|
102
|
-
File.exist?(original_path) ? original_path : default_path
|
103
|
-
end
|
104
78
|
end
|
105
79
|
end
|
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: 0.2.
|
4
|
+
version: 0.2.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- iberianpig
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2016-12-
|
11
|
+
date: 2016-12-31 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -66,6 +66,20 @@ dependencies:
|
|
66
66
|
- - ">="
|
67
67
|
- !ruby/object:Gem::Version
|
68
68
|
version: '0'
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: rubocop
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - ">="
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '0'
|
76
|
+
type: :development
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - ">="
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '0'
|
69
83
|
description: Fusuma is multitouch gesture recognizer. This gem makes your linux PC
|
70
84
|
able to recognize swipes or pinchs and assign shortcuts to them. Read installation
|
71
85
|
on Github(https://github.com/iberianpig/fusuma#installation).
|
@@ -78,6 +92,7 @@ extra_rdoc_files: []
|
|
78
92
|
files:
|
79
93
|
- ".gitignore"
|
80
94
|
- ".rspec"
|
95
|
+
- ".rubocop.yml"
|
81
96
|
- ".travis.yml"
|
82
97
|
- CODE_OF_CONDUCT.md
|
83
98
|
- Gemfile
|
@@ -87,14 +102,17 @@ files:
|
|
87
102
|
- Rakefile
|
88
103
|
- bin/console
|
89
104
|
- bin/setup
|
90
|
-
- config.yml
|
91
105
|
- exe/fusuma
|
92
106
|
- fusuma.gemspec
|
93
107
|
- lib/fusuma.rb
|
94
108
|
- lib/fusuma/action_stack.rb
|
109
|
+
- lib/fusuma/config.rb
|
95
110
|
- lib/fusuma/config.yml
|
96
111
|
- lib/fusuma/gesture_action.rb
|
112
|
+
- lib/fusuma/gesture_info.rb
|
97
113
|
- lib/fusuma/multi_logger.rb
|
114
|
+
- lib/fusuma/pinch.rb
|
115
|
+
- lib/fusuma/swipe.rb
|
98
116
|
- lib/fusuma/version.rb
|
99
117
|
homepage: https://github.com/iberianpig/fusuma
|
100
118
|
licenses:
|
data/config.yml
DELETED
@@ -1,24 +0,0 @@
|
|
1
|
-
swipe:
|
2
|
-
3:
|
3
|
-
left:
|
4
|
-
shortcut: 'alt+Right'
|
5
|
-
right:
|
6
|
-
shortcut: 'alt+Left'
|
7
|
-
up:
|
8
|
-
shortcut: 'ctrl+t'
|
9
|
-
down:
|
10
|
-
shortcut: 'ctrl+w'
|
11
|
-
4:
|
12
|
-
left:
|
13
|
-
shortcut: 'super+Right'
|
14
|
-
right:
|
15
|
-
shortcut: 'super+Left'
|
16
|
-
up:
|
17
|
-
shortcut: 'super+a'
|
18
|
-
down:
|
19
|
-
shortcut: 'super+s'
|
20
|
-
pinch:
|
21
|
-
in:
|
22
|
-
shortcut: 'ctrl+plus'
|
23
|
-
out:
|
24
|
-
shortcut: 'ctrl+minus'
|