Skip to content

Commit

Permalink
feat: support libinput 1.27.0 or later
Browse files Browse the repository at this point in the history
- Add `libinput_1_27_0_or_later?` method to `LibinputCommand`
- Add `parse_line_1_27_0_or_later` method to `LibinputGestureParser`
  • Loading branch information
iberianpig committed Nov 24, 2024
1 parent 7f077f8 commit d8062dd
Show file tree
Hide file tree
Showing 3 changed files with 151 additions and 26 deletions.
5 changes: 5 additions & 0 deletions lib/fusuma/libinput_command.rb
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,11 @@ def new_cli_option_available?
Gem::Version.new(version) >= Gem::Version.new(NEW_CLI_OPTION_VERSION)
end

# @return [Boolean]
def libinput_1_27_0_or_later?
Gem::Version.new(version) >= Gem::Version.new("1.27.0")
end

# @return [String]
def version
# version_command prints "1.6.3\n"
Expand Down
31 changes: 31 additions & 0 deletions lib/fusuma/plugin/parsers/libinput_gesture_parser.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

require_relative "../events/records/record"
require_relative "../events/records/gesture_record"
require_relative "../../libinput_command"

module Fusuma
module Plugin
Expand Down Expand Up @@ -29,6 +30,20 @@ def parse_record(record)
private

def parse_libinput(line)
if libinput_1_27_0_or_later?
parse_line_1_27_0_or_later(line)
else
parse_line(line)
end
end

def libinput_1_27_0_or_later?
return @libinput_1_27_0_or_later if defined?(@libinput_1_27_0_or_later)

@libinput_1_27_0_or_later = Inputs::LibinputCommandInput.new.command.libinput_1_27_0_or_later?
end

def parse_line(line)
_device, event_name, _time, other = line.strip.split(nil, 4)
finger, other = other.split(nil, 2)

Expand All @@ -39,6 +54,22 @@ def parse_libinput(line)
[gesture, status, finger, delta]
end

def parse_line_1_27_0_or_later(line)
_device, event_name, other = line.strip.split(nil, 3)

if other[0] != "+"
_seq, other = other.split(nil, 2)
end

_time, finger, other = other.split(nil, 3)

gesture, status = *detect_gesture(event_name)

status = "cancelled" if gesture == "hold" && status == "end" && other == "cancelled"
delta = parse_delta(other)
[gesture, status, finger, delta]
end

def detect_gesture(event_name)
event_name =~ /GESTURE_(SWIPE|PINCH|HOLD)_(BEGIN|UPDATE|END)/
gesture = Regexp.last_match(1).downcase
Expand Down
141 changes: 115 additions & 26 deletions spec/fusuma/plugin/parsers/libinput_gesture_parser_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

require "spec_helper"
require "./lib/fusuma/plugin/parsers/parser"
require "./lib/fusuma/plugin/events/event"
require "./lib/fusuma/plugin/inputs/input"

module Fusuma
module Plugin
Expand Down Expand Up @@ -36,39 +36,128 @@ module Parsers
it { expect(parser.parse(event)).to eq event }
end

context "with libinput_command_input event" do
let(:event) { Events::Event.new(tag: "libinput_command_input", record: record) }
context "with libinput version 1.27.0 or later" do
before do
allow_any_instance_of(LibinputCommand).to receive(:libinput_1_27_0_or_later?).and_return(true)
end

context "with swipe gestures" do
# event10 GESTURE_SWIPE_BEGIN +0.728s 3
# event10 GESTURE_SWIPE_UPDATE +0.948s 3 0.23/ 0.00 ( 0.29/ 0.00 unaccelerated)
# event10 GESTURE_SWIPE_END +0.989s 3
let(:record) { "event10 GESTURE_SWIPE_BEGIN +0.728s 3" }
it { expect(parser.parse(event).record).to be_a Events::Records::GestureRecord }
it { expect(parser.parse(event).record.status).to eq "begin" }
before do
@debug_events = <<~EVENTS
event4 GESTURE_SWIPE_BEGIN +19.410s 3
event4 GESTURE_SWIPE_UPDATE +19.410s 3 19.02/ 1.00 ( 4.17/ 0.22 unaccelerated)
event4 GESTURE_SWIPE_UPDATE 2 +19.417s 3 21.24/ 0.00 ( 4.61/ 0.00 unaccelerated)
event4 GESTURE_SWIPE_UPDATE 3 +19.424s 3 6.36/-0.22 ( 6.36/-0.22 unaccelerated)
event4 GESTURE_SWIPE_END +19.614s 3
EVENTS
.split("\n")
end

let(:event) {
-> {
record = @debug_events.shift
Events::Event.new(tag: "libinput_command_input", record: record)
}
}

it "has a gesture record" do
expect(parser.parse(event.call).record).to be_a Events::Records::GestureRecord
end

it "has a gesture record that it has a status" do
expect(parser.parse(event.call).record.status).to eq "begin"
expect(parser.parse(event.call).record.status).to eq "update"
expect(parser.parse(event.call).record.status).to eq "update"
expect(parser.parse(event.call).record.status).to eq "update"
expect(parser.parse(event.call).record.status).to eq "end"
end

it "has a gesture record that it has finger num" do
expect(parser.parse(event.call).record.finger).to eq 3
expect(parser.parse(event.call).record.finger).to eq 3
expect(parser.parse(event.call).record.finger).to eq 3
expect(parser.parse(event.call).record.finger).to eq 3
expect(parser.parse(event.call).record.finger).to eq 3
end
end
end

context "with hold gestures" do
# -event10 GESTURE_HOLD_BEGIN +2.125s 3
# event10 GESTURE_HOLD_END +3.274s 3
# event10 GESTURE_HOLD_BEGIN +5.573s 4
# event10 GESTURE_HOLD_END +6.462s 4 cancelled
context "with begin" do
let(:record) { "-event10 GESTURE_HOLD_BEGIN +2.125s 3" }
it { expect(parser.parse(event).record).to be_a Events::Records::GestureRecord }
it { expect(parser.parse(event).record.status).to eq "begin" }
context "with libinput version 1.26.0 or earlier" do
before do
allow_any_instance_of(LibinputCommand).to receive(:libinput_1_27_0_or_later?).and_return(false)
end

context "with swipe gestures" do
before do
@debug_events = <<~EVENTS
event10 GESTURE_SWIPE_BEGIN +0.728s 3
event10 GESTURE_SWIPE_UPDATE +0.948s 3 0.23/ 0.00 ( 0.29/ 0.00 unaccelerated)
event10 GESTURE_SWIPE_END +0.989s 3
EVENTS
.split("\n")
end
context "with end" do
let(:record) { " event10 GESTURE_HOLD_END +3.274s 3" }
it { expect(parser.parse(event).record).to be_a Events::Records::GestureRecord }
it { expect(parser.parse(event).record.status).to eq "end" }

let(:event) {
-> {
record = @debug_events.shift
Events::Event.new(tag: "libinput_command_input", record: record)
}
}

it "has a gesture record" do
expect(parser.parse(event.call).record).to be_a Events::Records::GestureRecord
end

it "has a gesture record that it has a status" do
expect(parser.parse(event.call).record.status).to eq "begin"
expect(parser.parse(event.call).record.status).to eq "update"
expect(parser.parse(event.call).record.status).to eq "end"
end
context "with end(cancelled)" do
let(:record) { " event10 GESTURE_HOLD_END +6.462s 4 cancelled" }
it { expect(parser.parse(event).record).to be_a Events::Records::GestureRecord }
it { expect(parser.parse(event).record.status).to eq "cancelled" }

it "has a gesture record that it has finger num" do
expect(parser.parse(event.call).record.finger).to eq 3
expect(parser.parse(event.call).record.finger).to eq 3
expect(parser.parse(event.call).record.finger).to eq 3
end
end
end

context "with hold gestures" do
before do
@debug_events = <<~EVENTS
-event10 GESTURE_HOLD_BEGIN +2.125s 3
event10 GESTURE_HOLD_END +3.274s 3
event10 GESTURE_HOLD_BEGIN +5.573s 4
event10 GESTURE_HOLD_END +6.462s 4 cancelled
EVENTS
.split("\n")
end

let(:event) {
-> {
record = @debug_events.shift
Events::Event.new(tag: "libinput_command_input", record: record)
}
}

it "has a gesture record" do
expect(parser.parse(event.call).record).to be_a Events::Records::GestureRecord
end

it "has a gesture record that it has a status" do
expect(parser.parse(event.call).record.status).to eq "begin"
expect(parser.parse(event.call).record.status).to eq "end"
expect(parser.parse(event.call).record.status).to eq "begin"
expect(parser.parse(event.call).record.status).to eq "cancelled"
end

it "has a gesture record that it has finger num" do
expect(parser.parse(event.call).record.finger).to eq 3
expect(parser.parse(event.call).record.finger).to eq 3
expect(parser.parse(event.call).record.finger).to eq 4
expect(parser.parse(event.call).record.finger).to eq 4
end
end
end
end
end
Expand Down

0 comments on commit d8062dd

Please sign in to comment.