Skip to content
Merged
Show file tree
Hide file tree
Changes from 6 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions server/internal/desktop/manager.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ type DesktopManagerCtx struct {
func New(config *config.Desktop) *DesktopManagerCtx {
var input xinput.Driver
if config.UseInputDriver {
log.Info().Str("socket", config.InputSocket).Msg("using xinput driver for scroll")
input = xinput.NewDriver(config.InputSocket)
} else {
input = xinput.NewDummy()
Expand Down
10 changes: 10 additions & 0 deletions server/internal/desktop/xorg.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,16 @@ func (manager *DesktopManagerCtx) GetCursorPosition() (int, int) {
}

func (manager *DesktopManagerCtx) Scroll(deltaX, deltaY int, controlKey bool) {
// Try xinput driver first (XI2.1 smooth scrolling via xf86-input-neko)
if err := manager.input.Scroll(int32(deltaX), int32(deltaY)); err == nil {
if controlKey {
xorg.SetKeyboardModifier(xorg.KbdModControl, true)
defer xorg.SetKeyboardModifier(xorg.KbdModControl, false)
}
return
Comment thread
cursor[bot] marked this conversation as resolved.
Outdated
}

// XTest fallback — handles controlKey atomically under a single X11 lock
xorg.Scroll(deltaX, deltaY, controlKey)
}

Expand Down
42 changes: 31 additions & 11 deletions server/internal/webrtc/legacyhandler.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ package webrtc
import (
"bytes"
"encoding/binary"
"strconv"

"github.com/m1k1o/neko/server/pkg/types"

Expand Down Expand Up @@ -35,6 +34,13 @@ type PayloadScroll struct {
Y int16
}

type PayloadScrollWithCtrl struct {
PayloadHeader
DeltaX int16
DeltaY int16
ControlKey uint8
}

type PayloadKey struct {
PayloadHeader
Key uint64 // TODO: uint32
Expand Down Expand Up @@ -72,18 +78,32 @@ func (manager *WebRTCManagerCtx) handleLegacy(

manager.desktop.Move(int(payload.X), int(payload.Y))
case OP_SCROLL:
payload := &PayloadScroll{}
if err := binary.Read(buffer, binary.LittleEndian, payload); err != nil {
return err
}
if header.Length == 5 {
payload := &PayloadScrollWithCtrl{}
if err := binary.Read(buffer, binary.LittleEndian, payload); err != nil {
return err
}

logger.Trace().
Int16("deltaX", payload.DeltaX).
Int16("deltaY", payload.DeltaY).
Bool("controlKey", payload.ControlKey != 0).
Msg("scroll")

manager.desktop.Scroll(int(payload.DeltaX), int(payload.DeltaY), payload.ControlKey != 0)
} else {
payload := &PayloadScroll{}
if err := binary.Read(buffer, binary.LittleEndian, payload); err != nil {
return err
}

logger.
Trace().
Str("x", strconv.Itoa(int(payload.X))).
Str("y", strconv.Itoa(int(payload.Y))).
Msg("scroll")
logger.Trace().
Int16("x", payload.X).
Int16("y", payload.Y).
Msg("scroll")

manager.desktop.Scroll(int(payload.X), int(payload.Y), false)
manager.desktop.Scroll(int(payload.X), int(payload.Y), false)
}
case OP_KEY_DOWN:
payload := &PayloadKey{}
if err := binary.Read(buffer, binary.LittleEndian, payload); err != nil {
Expand Down
1 change: 0 additions & 1 deletion server/internal/webrtc/manager.go
Original file line number Diff line number Diff line change
Expand Up @@ -478,7 +478,6 @@ func (manager *WebRTCManagerCtx) CreatePeer(session types.Session) (*webrtc.Sess
//

if viper.GetBool("legacy") {
// handle legacy data channel
dc.OnMessage(func(message webrtc.DataChannelMessage) {
if err := manager.handleLegacy(logger, message.Data, session); err != nil {
logger.Err(err).Msg("data handle failed")
Expand Down
11 changes: 10 additions & 1 deletion server/pkg/xinput/dummy.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@
package xinput

import "time"
import (
"errors"
"time"
)

var errNotConnected = errors.New("xinput driver not connected")

type dummy struct{}

Expand Down Expand Up @@ -29,3 +34,7 @@ func (d *dummy) TouchUpdate(touchId uint32, x, y int, pressure uint8) error {
func (d *dummy) TouchEnd(touchId uint32, x, y int, pressure uint8) error {
return nil
}

func (d *dummy) Scroll(deltaX, deltaY int32) error {
return errNotConnected
}
Comment thread
cursor[bot] marked this conversation as resolved.
4 changes: 4 additions & 0 deletions server/pkg/xinput/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ const (
XI_TouchBegin = 18
XI_TouchUpdate = 19
XI_TouchEnd = 20
NEKO_SCROLL = 0x80
)

type Message struct {
Expand Down Expand Up @@ -58,4 +59,7 @@ type Driver interface {
TouchBegin(touchId uint32, x, y int, pressure uint8) error
TouchUpdate(touchId uint32, x, y int, pressure uint8) error
TouchEnd(touchId uint32, x, y int, pressure uint8) error
// scroll via XI2 scroll valuators in the xf86-input-neko driver.
// deltaX/deltaY are in scroll units (120 = one notch).
Scroll(deltaX, deltaY int32) error
}
13 changes: 13 additions & 0 deletions server/pkg/xinput/xinput.go
Original file line number Diff line number Diff line change
Expand Up @@ -120,3 +120,16 @@ func (d *driver) TouchEnd(touchId uint32, x, y int, pressure uint8) error {
_, err := d.conn.Write(msg.Pack())
return err
}

func (d *driver) Scroll(deltaX, deltaY int32) error {
d.mu.Lock()
defer d.mu.Unlock()

msg := Message{
_type: NEKO_SCROLL,
x: deltaX,
y: deltaY,
}
_, err := d.conn.Write(msg.Pack())
return err
}
8 changes: 4 additions & 4 deletions server/pkg/xorg/xorg.c
Original file line number Diff line number Diff line change
Expand Up @@ -35,16 +35,16 @@ void XScroll(int deltaX, int deltaY) {

int ydir;
if (deltaY > 0) {
ydir = 4; // button 4 is up
Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this is needed for scrolling direction

ydir = 5; // positive = scroll down = button 5
} else {
ydir = 5; // button 5 is down
ydir = 4; // negative = scroll up = button 4
}

int xdir;
if (deltaX > 0) {
xdir = 6; // button 6 is right
xdir = 7; // positive = scroll right = button 7
} else {
xdir = 7; // button 7 is left
xdir = 6; // negative = scroll left = button 6
}

for (int i = 0; i < abs(deltaY); i++) {
Expand Down
Loading