Skip to content

Conversation

@jtollet
Copy link
Contributor

@jtollet jtollet commented Jan 13, 2026

Summary

This PR fixes mouse drag tracking in libtsm for SGR (mode 1006) and PIXEL (mode 1016) modes, enabling applications like Vim to display visual selection in real-time during mouse drags.

Problem

When applications activated mouse tracking, drag operations (mouse motion with button pressed) were not working correctly:

  1. Mode 1002 (Button-event tracking) rejected ALL motion events, even drags
  2. SGR and PIXEL modes hardcoded button value to 35, ignoring actual button

This caused applications like Vim to only update selection on button release, not during the drag.

Root Causes

Issue 1: Mode 1002 filter too strict
The code was rejecting ALL MOVED events in mode 1002, but per spec mode 1002 should accept drags (motion with button pressed, button >= 32).

Issue 2: Hardcoded button value
When handling MOVED events in SGR/PIXEL modes, reply_flags was hardcoded to 35, ignoring the actual button parameter passed in.

Solution

Commit 1: Accept drags in mode 1002

  • Detect drags by checking if button >= 32 && button <= 34 (protocol encoding)
  • Allow MOVED events in mode 1002 if it's a drag
  • Mode 1003 (ANY) continues to work as before (all motion allowed)

Commit 2: Use actual button value in SGR/PIXEL modes

  • Remove reply_flags = 35; hardcode
  • Use the actual button parameter for drags (button >= 32)
  • Keep reply_flags = 35 for hover motion (button < 32, mode ANY only)

Testing

Tested with Vim under kmscon with set mouse=a ttymouse=sgr:

  • Before: Visual selection updates only on button release
  • After: Visual selection updates in real-time during drag

All unit tests pass (7/7).

Protocol Reference

Mouse tracking protocol encoding:

  • Button press/release: button = 0 (left), 1 (right), 2 (middle)
  • Motion with button (drag): button = 32 (left drag), 33 (right drag), 34 (middle drag)
  • Hover motion: button = 35 (move marker, mode ANY only)

Related

This works in conjunction with fixes in kmscon: kmscon/kmscon#214

This commit fixes two issues in libtsm mouse tracking:

1. Mode 1002 (Button-event) drag support:
   The code was rejecting ALL MOVED events in mode 1002, but per spec
   mode 1002 should accept drags (motion with button pressed, button >= 32).
   Added is_drag check to allow MOVED events with button >= 32 in mode 1002.

2. Hardcoded reply_flags in SGR mode:
   When handling MOVED events in SGR mode, reply_flags was hardcoded to 35,
   ignoring the actual button parameter. Now uses the button value passed in
   (which includes the +32 offset for drags from kmscon).

Mode behavior now:
- Mode 1000 (X10): No drags (as before)
- Mode 1002 (BTN): Clicks + drags (button pressed motion) - NOW FIXED
- Mode 1003 (ANY): Clicks + drags + hover (all motion) - works as before

This allows Vim visual selection to update in real-time during mouse drag.
The PIXEL mode (1016) had the same bug as SGR mode - hardcoded
reply_flags = 35 for MOVED events, ignoring the actual button value.

This commit applies the same fix to PIXEL mode as was done for SGR mode,
allowing drag events to work correctly in pixel coordinate mode.
@kdj0c kdj0c merged commit 41e4c25 into kmscon:main Jan 14, 2026
2 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants