add support for "pixel-perfect" scrolling

This commit is contained in:
Unrud 2018-07-31 20:19:10 +02:00
parent 209eaf960d
commit c1509ac8fa
6 changed files with 57 additions and 19 deletions

File diff suppressed because one or more lines are too long

View file

@ -51,6 +51,9 @@ func processCommand(plugin Plugin, command string) error {
if len(command) == 0 {
return errors.New("empty command")
}
if command == "sf" {
return plugin.PointerScrollFinish()
}
if command[0] == 't' {
text := command[1:]
if !utf8.ValidString(text) {

View file

@ -42,5 +42,6 @@ type Plugin interface {
KeyboardText(text string) error
PointerButton(button uint, press bool) error
PointerMove(deltaX, deltaY int) error
PointerScroll(stepsHorizontal, stepsVertical int) error
PointerScroll(deltaHorizontal, deltaVertical int) error
PointerScrollFinish() error
}

View file

@ -44,7 +44,7 @@ const (
mouseeventfWheel uint32 = 0x800
mouseeventfHwheel uint32 = 0x1000
wheelDelta int = 120
scrollMult int = 6
)
type mouseInput struct {
@ -146,20 +146,20 @@ func (p *windowsPlugin) PointerMove(deltaX, deltaY int) error {
return nil
}
func (p *windowsPlugin) PointerScroll(stepsHorizontal, stepsVertical int) error {
func (p *windowsPlugin) PointerScroll(deltaHorizontal, deltaVertical int) error {
inputs := make([]mouseInput, 0, 2)
if stepsHorizontal != 0 {
if deltaHorizontal != 0 {
inputs = append(inputs, mouseInput{
typ: inputMouse,
dwFlags: mouseeventfHwheel,
mouseData: uint32(stepsHorizontal * wheelDelta),
mouseData: uint32(deltaHorizontal * scrollMult),
})
}
if stepsVertical != 0 {
if deltaVertical != 0 {
inputs = append(inputs, mouseInput{
typ: inputMouse,
dwFlags: mouseeventfWheel,
mouseData: uint32(stepsVertical * wheelDelta),
mouseData: uint32(deltaVertical * scrollMult),
})
}
if len(inputs) == 0 {
@ -172,3 +172,7 @@ func (p *windowsPlugin) PointerScroll(stepsHorizontal, stepsVertical int) error
}
return nil
}
func (p *windowsPlugin) PointerScrollFinish() error {
return nil
}

View file

@ -35,11 +35,15 @@ import (
"unsafe"
)
const typingDelay time.Duration = 100 * time.Millisecond
const (
typingDelay time.Duration = 100 * time.Millisecond
scrollDiv int = 20
)
type x11Plugin struct {
display *C.Display
lock sync.Mutex
scrollHorizontal, scrollVertical int
}
func InitX11Plugin() (Plugin, error) {
@ -157,7 +161,13 @@ func (p *x11Plugin) PointerMove(deltaX, deltaY int) error {
return nil
}
func (p *x11Plugin) PointerScroll(stepsHorizontal, stepsVertical int) error {
func (p *x11Plugin) PointerScroll(deltaHorizontal, deltaVertical int) error {
p.lock.Lock()
stepsHorizontal := (p.scrollHorizontal + deltaHorizontal) / scrollDiv
stepsVertical := (p.scrollVertical + deltaVertical) / scrollDiv
p.scrollHorizontal = (p.scrollHorizontal + deltaHorizontal) % scrollDiv
p.scrollVertical = (p.scrollVertical + deltaVertical) % scrollDiv
p.lock.Unlock()
var buttonHorizontal uint = 7
if stepsHorizontal < 0 {
buttonHorizontal = 6
@ -186,3 +196,11 @@ func (p *x11Plugin) PointerScroll(stepsHorizontal, stepsVertical int) error {
}
return nil
}
func (p *x11Plugin) PointerScrollFinish() error {
p.lock.Lock()
defer p.lock.Unlock()
p.scrollHorizontal = 0
p.scrollVertical = 0
return nil
}

View file

@ -20,8 +20,6 @@
// [1 Touch, 2 Touches, 3 Touches]
const TOUCH_MOVE_THRESHOLD = [10, 15, 15];
const TOUCH_TIMEOUT = 250;
const MOVE_MULT = 1;
const SCROLL_MULT = 0.05;
// [[px/s, mult], ...]
const POINTER_ACCELERATION = [[0, 0], [87, 1], [173, 1], [553, 2]];
@ -40,6 +38,7 @@ var scrollXSum = 0;
var scrollYSum = 0;
var dragging = false;
var draggingTimeout = null;
var scrolling = false;
function fullscreenEnabled() {
return (document.fullscreenEnabled ||
@ -153,6 +152,7 @@ function updateMoveAndScroll() {
if (Math.abs(scrollX) >= 1 || Math.abs(scrollY) >= 1) {
scrollXSum -= scrollX;
scrollYSum -= scrollY;
scrolling = true;
ws.send("s" + scrollX + ";" + scrollY);
}
}
@ -183,6 +183,10 @@ function handleStart(evt) {
draggingTimeout = null;
dragging = true;
}
if (scrolling) {
ws.send("sf");
scrolling = false;
}
}
}
@ -196,6 +200,10 @@ function handleEnd(evt) {
ongoingTouches.splice(idx, 1);
touchReleasedCount++;
touchLastEnd = evt.timeStamp;
if (scrolling) {
ws.send("sf");
scrolling = false;
}
}
if (touchReleasedCount > TOUCH_MOVE_THRESHOLD.length) {
touchMoved = true;
@ -234,6 +242,10 @@ function handleCancel(evt) {
touchReleasedCount++;
touchLastEnd = evt.timeStamp;
touchMoved = true;
if (scrolling) {
ws.send("sf");
scrolling = false;
}
}
}
@ -261,11 +273,11 @@ function handleMove(evt) {
}
if (touchMoved && evt.timeStamp - touchLastEnd >= TOUCH_TIMEOUT) {
if (ongoingTouches.length == 1 || dragging) {
moveXSum += sumX * MOVE_MULT;
moveYSum += sumY * MOVE_MULT;
moveXSum += sumX;
moveYSum += sumY;
} else if (ongoingTouches.length == 2) {
scrollXSum -= sumX * SCROLL_MULT;
scrollYSum -= sumY * SCROLL_MULT;
scrollXSum -= sumX;
scrollYSum -= sumY;
}
updateMoveAndScroll();
}