fusuma-plugin-keypress 0.4.2 → 0.5.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: 958f90d65b6a5bfe120a5462bbfc1d21e01dbdf95d97f279e824a6ad6aafa5a3
4
- data.tar.gz: 6d8c96cb5be6b003f00c0d20bc6bf68af693857e82d9ceb87837a1b752678e0f
3
+ metadata.gz: e4dee24a10fad696ea3f6fd58e02e1c2358f522455bc9ec4aef6bc53b2004d2c
4
+ data.tar.gz: 3e0016a1d55bc7cb4096c9a77916fa1910e8a81561992255c97b17a8a67d6ddf
5
5
  SHA512:
6
- metadata.gz: 7be790c59d66696f078c89121f32f9dd61630a0debfe3584899cac8b0ed73d335b2858aca88e7d84b511dcb1cbaf9a0e36ac487300c519f2c5480ac7f16a4040
7
- data.tar.gz: 858e05f1aca03e80be587ed315e79717a5c6815336c5b1ef8e1c112603df698be6d3b720853c18f2b200137b8c9eb866907e325032c8727ee6d1ffba368bc07e
6
+ metadata.gz: 22187a3a208c1d0989eac56c565cf00124920bb141d38f3549743c473c0b42708256c73d6c7603c6776f245a46c3ae6df8f791ba4e51f9c09de47f529b8b008b
7
+ data.tar.gz: e7f937130567f31bb3b226b3cb502f98fff973aceb21a68813170fa77d0ea80e1e531c5fabf1e0c57e56c463072ed14a1f3e9f28fc5201eca69610cdfea56f5b
data/README.md CHANGED
@@ -1,4 +1,4 @@
1
- # Fusuma::Plugin::Keypress [![Gem Version](https://badge.fury.io/rb/fusuma-plugin-keypress.svg)](https://badge.fury.io/rb/fusuma-plugin-keypress) [![Build Status](https://travis-ci.com/iberianpig/fusuma-plugin-keypress.svg?branch=master)](https://travis-ci.com/iberianpig/fusuma-plugin-keypress)
1
+ # Fusuma::Plugin::Keypress [![Gem Version](https://badge.fury.io/rb/fusuma-plugin-keypress.svg)](https://badge.fury.io/rb/fusuma-plugin-keypress) [![Build Status](https://github.com/iberianpig/fusuma-plugin-keypress/actions/workflows/ubuntu.yml/badge.svg)](https://github.com/iberianpig/fusuma-plugin-keypress/actions/workflows/ubuntu.yml)
2
2
 
3
3
 
4
4
  Keyboard + Touchpad combination plugin for [Fusuma](https://github.com/iberianpig/fusuma)
@@ -33,6 +33,7 @@ plugin:
33
33
 
34
34
  ## Properties
35
35
 
36
+ ### Keypress
36
37
  Add `keypress:` property in `~/.config/fusuma/config.yml`.
37
38
 
38
39
  Keys following are available for `keypress`.
@@ -80,6 +81,29 @@ plugin:
80
81
  * Swipe up/down with four fingers while keypress LEFTMETA and LEFTALT keys to change audio volume.
81
82
  - If you want to combine a gesture with two keys, combine modifier keys with `+`
82
83
 
84
+
85
+ ## Typing Gesture
86
+
87
+ `typing:` is a trigger that fires when keys other than modifier keys are pressed. This trigger provides disable-while-typing similar to libinput and syndaemon.
88
+ If you are using a keyremapper such as xkeysnail and libinput's disable-while-typing does not work, try setting it.
89
+
90
+ It can be placed in the root of yaml and configured as a gesture.
91
+ The following is a configuration that uses xinput to turn off tapping for 0.6 seconds to avoid false touches.
92
+
93
+ ```yaml
94
+ typing: # disable while typing
95
+ command: |
96
+ touchpad_id=$(xinput | grep Touchpad | grep -oE "id=[0-9]*" | cut -d"=" -f 2)
97
+ xinput set-prop $touchpad_id "libinput Tapping Enabled" 0
98
+ file=/tmp/typing_command_break
99
+ touch "$file"
100
+ sleep 0.6
101
+ [ `find "$file" -mmin +0.01` ] && \
102
+ xinput set-prop $touchpad_id "libinput Tapping Enabled" 1
103
+ interval: 0.5
104
+ ```
105
+
106
+
83
107
  ## Contributing
84
108
 
85
109
  Bug reports and pull requests are welcome on GitHub at https://github.com/iberianpig/fusuma-plugin-keypress. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [Contributor Covenant](http://contributor-covenant.org) code of conduct.
@@ -25,4 +25,7 @@ Gem::Specification.new do |spec|
25
25
  spec.required_ruby_version = '>= 2.5.1' # https://packages.ubuntu.com/search?keywords=ruby&searchon=names&exact=1&suite=all&section=main
26
26
  # support bionic (18.04LTS) 2.5.1
27
27
  spec.add_dependency 'fusuma', '~> 2.0'
28
+ spec.metadata = {
29
+ 'rubygems_mfa_required' => 'true'
30
+ }
28
31
  end
@@ -1,13 +1,27 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require 'set'
4
+
3
5
  module Fusuma
4
6
  module Plugin
5
7
  module Detectors
6
8
  # Detect KeypressEvent from KeypressBuffer
7
9
  class KeypressDetector < Detector
8
- SOURCES = ['keypress'].freeze
10
+ SOURCES = %w[keypress].freeze
9
11
  BUFFER_TYPE = 'keypress'
10
12
 
13
+ MODIFIER_KEYS = Set.new(%w[
14
+ CAPSLOCK
15
+ LEFTALT
16
+ LEFTCTRL
17
+ LEFTMETA
18
+ LEFTSHIFT
19
+ RIGHTALT
20
+ RIGHTCTRL
21
+ RIGHTSHIFT
22
+ RIGHTMETA
23
+ ])
24
+
11
25
  # Always watch buffers and detect them.
12
26
  def watch?
13
27
  true
@@ -17,28 +31,59 @@ module Fusuma
17
31
  # @return [Event] if event is detected
18
32
  # @return [NilClass] if event is NOT detected
19
33
  def detect(buffers)
20
- buffer = buffers.find { |b| b.type == BUFFER_TYPE }
34
+ keypress_buffer = find_buffer(buffers)
21
35
 
22
- return if buffer.empty?
36
+ return if keypress_buffer.empty?
23
37
 
24
- records = buffer.events.select { |e| e.record.status == 'pressed' }.map(&:record)
38
+ codes = pressed_codes(keypress_buffer.events.map(&:record))
25
39
 
26
- index_record = Events::Records::IndexRecord.new(
27
- index: create_index(records: records),
28
- position: :surfix
29
- )
40
+ return if codes.empty?
41
+
42
+ record = if codes.any? { |code| MODIFIER_KEYS.include?(code) }
43
+ Events::Records::IndexRecord.new(index: create_index(codes: codes),
44
+ position: :surfix)
45
+ else
46
+ Events::Records::IndexRecord.new(index: create_typing_index)
47
+ end
48
+
49
+ create_event(record: record)
50
+ end
51
+
52
+ private
53
+
54
+ def find_buffer(buffers)
55
+ buffers.find { |b| b.type == BUFFER_TYPE }
56
+ end
30
57
 
31
- create_event(record: index_record)
58
+ def pressed_codes(records)
59
+ codes = []
60
+ records.each do |r|
61
+ if r.status == 'pressed'
62
+ codes << r.code
63
+ else
64
+ codes.delete_if { |code| code == r.code }
65
+ end
66
+ end
67
+ codes
32
68
  end
33
69
 
34
- # @param records [Array<Events::Records::KeypressRecord>]
70
+ # @param code [String]
35
71
  # @return [Config::Index]
36
- def create_index(records:)
37
- code = records.map(&:code).join('+')
72
+ def create_index(codes:)
38
73
  Config::Index.new(
39
74
  [
40
75
  Config::Index::Key.new('keypress', skippable: true),
41
- Config::Index::Key.new(code, skippable: true)
76
+ Config::Index::Key.new(codes.join('+'), skippable: true)
77
+ ]
78
+ )
79
+ end
80
+
81
+ # @param status [String]
82
+ # @return [Config::Index]
83
+ def create_typing_index
84
+ Config::Index.new(
85
+ [
86
+ Config::Index::Key.new('typing')
42
87
  ]
43
88
  )
44
89
  end
@@ -12,6 +12,7 @@ module Fusuma
12
12
  def initialize(status:, code:)
13
13
  @status = status
14
14
  @code = code
15
+ super()
15
16
  end
16
17
  end
17
18
  end
@@ -1,5 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require 'fusuma/device'
4
+
3
5
  module Fusuma
4
6
  module Plugin
5
7
  module Filters
@@ -7,10 +9,54 @@ module Fusuma
7
9
  class KeypressFilter < Filter
8
10
  DEFAULT_SOURCE = 'libinput_command_input'
9
11
 
12
+ def config_param_types
13
+ {
14
+ source: String,
15
+ keep_device_names: [Array, String]
16
+ }
17
+ end
18
+
19
+ # NOTE: example of line# Select keyboard devices for filtering devices pressed/released
20
+ # event4 KEYBOARD_KEY +4.81s KEY_LEFTSHIFT (42) pressed
21
+ # event4 KEYBOARD_KEY +4.90s KEY_LEFTSHIFT (42) released
22
+ # event4 KEYBOARD_KEY +7.39s KEY_CAPSLOCK (58) pressed
23
+ # event4 KEYBOARD_KEY +7.52s KEY_CAPSLOCK (58) released
24
+ # event4 KEYBOARD_KEY +8.98s KEY_LEFTCTRL (29) pressed
25
+ # event4 KEYBOARD_KEY +9.14s KEY_LEFTCTRL (29) released
26
+
10
27
  # @return [TrueClass] when keeping it
11
28
  # @return [FalseClass] when discarding it
12
29
  def keep?(record)
13
- record.to_s =~ /\sKEYBOARD_KEY\s/
30
+ keep_devices.any? do |d|
31
+ record.to_s =~ /#{d.id}\s+KEYBOARD_KEY\s/
32
+ end
33
+ end
34
+
35
+ private
36
+
37
+ # @return [Array<Fusuma::Device>]
38
+ def keep_devices
39
+ @keep_devices ||= KeepDevice.new(config_params(:keep_device_names)).select
40
+ end
41
+
42
+ # Devices to detect key presses and releases
43
+ class KeepDevice
44
+ def initialize(names)
45
+ @names = names
46
+ end
47
+
48
+ # @return [Array<Fusuma::Device>]
49
+ def select
50
+ if @names
51
+ Fusuma::Device.all.select do |d|
52
+ Array(config_params(:keep_device_names)).any? do |name|
53
+ d.name =~ name
54
+ end
55
+ end
56
+ else
57
+ Fusuma::Device.all.select { |d| d.capabilities =~ /keyboard/ }
58
+ end
59
+ end
14
60
  end
15
61
  end
16
62
  end
@@ -3,7 +3,7 @@
3
3
  module Fusuma
4
4
  module Plugin
5
5
  module Keypress
6
- VERSION = '0.4.2'
6
+ VERSION = '0.5.0'
7
7
  end
8
8
  end
9
9
  end
@@ -7,18 +7,6 @@ module Fusuma
7
7
  class KeypressParser < Parser
8
8
  DEFAULT_SOURCE = 'libinput_command_input'
9
9
 
10
- AVAILABLE_KEYS = %w[
11
- CAPSLOCK
12
- LEFTALT
13
- LEFTCTRL
14
- LEFTMETA
15
- LEFTSHIFT
16
- RIGHTALT
17
- RIGHTCTRL
18
- RIGHTSHIFT
19
- RIGHTMETA
20
- ].freeze
21
-
22
10
  # @param record [String]
23
11
  # @return [Records::Gesture, nil]
24
12
  def parse_record(record)
@@ -39,8 +27,6 @@ module Fusuma
39
27
  code = matched[2] # LEFTSHIFT
40
28
  status = matched[3] # pressed
41
29
 
42
- return unless AVAILABLE_KEYS.include?(code)
43
-
44
30
  Events::Records::KeypressRecord.new(status: status, code: code)
45
31
  end
46
32
  end
@@ -0,0 +1,131 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'spec_helper'
4
+
5
+ require 'fusuma/plugin/filters/filter'
6
+ require 'fusuma/plugin/inputs/input'
7
+
8
+ require './lib/fusuma/plugin/filters/keypress_filter'
9
+
10
+ module Fusuma
11
+ module Plugin
12
+ module Filters
13
+ RSpec.describe KeypressFilter do
14
+ describe '#keep?' do
15
+ before { @filter = KeypressFilter.new }
16
+ context 'with keyboard event' do
17
+ before do
18
+ keyboard = double(Fusuma::Device, id: 'event4')
19
+ allow(@filter).to receive(:keep_devices).and_return([keyboard])
20
+ text = " #{keyboard.id} KEYBOARD_KEY +4.81s KEY_LEFTSHIFT (42) pressed"
21
+ @event = Events::Event.new(tag: 'libinput_command_input', record: text)
22
+ # @filter = KeypressFilter.new
23
+ end
24
+ it 'should be true' do
25
+ expect(@filter.keep?(@event.record)).to eq true
26
+ end
27
+ end
28
+ context 'with multiple keyboards' do
29
+ before do
30
+ keyboard1 = double(Fusuma::Device, id: 'event1')
31
+ keyboard2 = double(Fusuma::Device, id: 'event2')
32
+ allow(@filter).to receive(:keep_devices).and_return([
33
+ keyboard1, keyboard2
34
+ ])
35
+ text1 = " #{keyboard1.id} KEYBOARD_KEY +4.81s KEY_LEFTSHIFT (42) pressed"
36
+ text2 = " #{keyboard2.id} KEYBOARD_KEY +4.81s KEY_LEFTSHIFT (42) pressed"
37
+ @event1 = Events::Event.new(tag: 'libinput_command_input', record: text1)
38
+ @event2 = Events::Event.new(tag: 'libinput_command_input', record: text2)
39
+ end
40
+ it 'should return multiple keyboards' do
41
+ expect(@filter.keep?(@event1.record)).to eq true
42
+ expect(@filter.keep?(@event2.record)).to eq true
43
+ end
44
+ end
45
+ context 'when touchpad events' do
46
+ before do
47
+ touchpad = double(Fusuma::Device, id: 'event18')
48
+ allow(@filter).to receive(:keep_devices).and_return([touchpad])
49
+ text = " #{touchpad.id} GESTURE_SWIPE_UPDATE +1.44s 4 11.23/ 1.00 (36.91/ 3.28 unaccelerated) "
50
+ # ^^^^^^^^^^^^^^^^^^^^ Shoud be KEYBOARD_KEY
51
+ @event = Events::Event.new(tag: 'libinput_command_input', record: text)
52
+ end
53
+ it 'should be false' do
54
+ expect(@filter.keep?(@event.record)).to eq false
55
+ end
56
+ end
57
+
58
+ context 'with plugins.filters.keypress_filter.source=CUSTOM_INPUT' do
59
+ it { expect(@filter.source).to eq 'libinput_command_input' }
60
+
61
+ context 'with config' do
62
+ around do |example|
63
+ @custom_source = 'CUSTOM_INPUT'
64
+
65
+ ConfigHelper.load_config_yml = <<~CONFIG
66
+ plugin:
67
+ filters:
68
+ keypress_filter:
69
+ source: #{@custom_source}
70
+ CONFIG
71
+
72
+ example.run
73
+
74
+ Config.custom_path = nil
75
+ end
76
+
77
+ it { expect(@filter.source).to eq @custom_source }
78
+ end
79
+ end
80
+ context "with config file having plugins.filters.keypress.keep_device_names='CUSTOM_KEYBOARD'" do
81
+ it { expect(@filter.source).to eq 'libinput_command_input' }
82
+
83
+ context 'with config' do
84
+ around do |example|
85
+ @name = 'CUSTOM_KEYBOARD'
86
+
87
+ ConfigHelper.load_config_yml = <<~CONFIG
88
+ plugin:
89
+ filters:
90
+ keypress_filter:
91
+ keep_device_names: #{@name}
92
+ CONFIG
93
+
94
+ example.run
95
+
96
+ Config.custom_path = nil
97
+ end
98
+
99
+ it { expect(@filter.config_params[:keep_device_names]).to eq @name }
100
+ end
101
+ end
102
+ context "with config file having plugins.filters.keypress.keep_device_names=['INTERNAL_KEYBOARD','EXTERNAL_KEYBOARD']" do
103
+ it { expect(@filter.source).to eq 'libinput_command_input' }
104
+
105
+ context 'with config' do
106
+ around do |example|
107
+ @name1 = 'INTERNAL_KEYBOARD'
108
+ @name2 = 'EXTERNAL_KEYBOARD'
109
+
110
+ ConfigHelper.load_config_yml = <<~CONFIG
111
+ plugin:
112
+ filters:
113
+ keypress_filter:
114
+ keep_device_names:
115
+ - #{@name1}
116
+ - #{@name2}
117
+ CONFIG
118
+
119
+ example.run
120
+
121
+ Config.custom_path = nil
122
+ end
123
+
124
+ it { expect(@filter.config_params(:keep_device_names)).to eq [@name1, @name2] }
125
+ end
126
+ end
127
+ end
128
+ end
129
+ end
130
+ end
131
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: fusuma-plugin-keypress
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.2
4
+ version: 0.5.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - iberianpig
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2021-10-03 00:00:00.000000000 Z
11
+ date: 2021-11-24 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: fusuma
@@ -44,13 +44,15 @@ files:
44
44
  - lib/fusuma/plugin/keypress/version.rb
45
45
  - lib/fusuma/plugin/parsers/keypress_parser.rb
46
46
  - spec/fusuma/plugin/detectors/keypress_detector_spec.rb
47
+ - spec/fusuma/plugin/filters/keypress_filter_spec.rb
47
48
  - spec/fusuma/plugin/keypress_spec.rb
48
49
  - spec/helpers/config_helper.rb
49
50
  - spec/spec_helper.rb
50
51
  homepage: https://github.com/iberianpig/fusuma-plugin-keypress
51
52
  licenses:
52
53
  - MIT
53
- metadata: {}
54
+ metadata:
55
+ rubygems_mfa_required: 'true'
54
56
  post_install_message:
55
57
  rdoc_options: []
56
58
  require_paths:
@@ -66,12 +68,13 @@ required_rubygems_version: !ruby/object:Gem::Requirement
66
68
  - !ruby/object:Gem::Version
67
69
  version: '0'
68
70
  requirements: []
69
- rubygems_version: 3.1.4
71
+ rubygems_version: 3.0.3.1
70
72
  signing_key:
71
73
  specification_version: 4
72
74
  summary: Keypress plugin for Fusuma
73
75
  test_files:
74
- - spec/fusuma/plugin/detectors/keypress_detector_spec.rb
75
- - spec/fusuma/plugin/keypress_spec.rb
76
- - spec/helpers/config_helper.rb
77
76
  - spec/spec_helper.rb
77
+ - spec/helpers/config_helper.rb
78
+ - spec/fusuma/plugin/filters/keypress_filter_spec.rb
79
+ - spec/fusuma/plugin/keypress_spec.rb
80
+ - spec/fusuma/plugin/detectors/keypress_detector_spec.rb