Skip to content

Fix SGR and PIXEL mouse modes blocked by mouse_event check#5

Merged
kdj0c merged 1 commit into
kmscon:mainfrom
jtollet:fix-sgr-mouse-mode
Dec 17, 2025
Merged

Fix SGR and PIXEL mouse modes blocked by mouse_event check#5
kdj0c merged 1 commit into
kmscon:mainfrom
jtollet:fix-sgr-mouse-mode

Conversation

@jtollet

@jtollet jtollet commented Dec 14, 2025

Copy link
Copy Markdown
Contributor

Pull Request: Fix SGR and PIXEL mouse modes blocked by mouse_event check

Summary

This PR fixes a bug where SGR (mode 1006) and PIXEL (mode 1016) mouse modes were not working in applications like less and vim due to an incorrect condition check.

The Bug

In src/tsm/tsm-vte.c, the SGR and PIXEL mode handlers check both the mouse mode AND the mouse_event flag:

} else if (vte->mouse_mode == TSM_VTE_MOUSE_MODE_SGR && vte->mouse_event) {
    // SGR handling code
}
} else if (vte->mouse_mode == TSM_VTE_MOUSE_MODE_PIXEL && vte->mouse_event) {
    // PIXEL handling code
}

Problem: When applications like less or vim activate SGR mouse mode, they don't always set vte->mouse_event first. The value remains 0, causing the condition && vte->mouse_event to evaluate to false, and the SGR/PIXEL handler never executes.

The Fix

Remove the && vte->mouse_event condition from both checks:

} else if (vte->mouse_mode == TSM_VTE_MOUSE_MODE_SGR) {
    // SGR handling code
}
} else if (vte->mouse_mode == TSM_VTE_MOUSE_MODE_PIXEL) {
    // PIXEL handling code
}

Rationale: The mouse_mode check alone is sufficient. If the mode is set to SGR or PIXEL, the handler should execute. The mouse_event flag is used internally to filter event types (press/release/motion), but shouldn't prevent the mode handler from running.

Test Cases

Before the fix:

  • Run less --mouse in kmscon → mouse wheel does NOT work
  • Run vim with :set mouse=a ttymouse=sgr → mouse wheel does NOT work (in some cases)

After the fix:

  • Run less --mouse in kmscon → mouse wheel WORKS correctly
  • Run vim with :set mouse=a ttymouse=sgr → mouse wheel WORKS correctly

Impact

This bug affects any application using libtsm that:

  1. Activates SGR or PIXEL mouse modes
  2. Doesn't explicitly set mouse_event before sending mouse events
  3. Common examples: less, vim, emacs, nano with mouse support

Related Information

  • SGR mode (1006) is the modern standard for mouse reporting in terminals
  • It's supported by all major terminal emulators (xterm, gnome-terminal, etc.)
  • This bug makes libtsm incompatible with standard terminal behavior

Compatibility

This change has no negative impact:

  • Applications that DO set mouse_event will continue to work
  • Applications that DON'T set mouse_event will now work correctly
  • No API changes
  • Purely a bug fix

The SGR (mode 1006) and PIXEL (mode 1016) mouse mode handlers
were incorrectly checking the vte->mouse_event flag, which prevented
these modes from working when mouse_event was 0.

This bug affected applications like less and vim that activate SGR
mouse mode without setting a specific mouse_event value. The condition
"&& vte->mouse_event" was preventing the mode handlers from executing
even when the mouse mode was correctly set to SGR or PIXEL.

The mouse_event flag is used to filter which types of events to report
(button press/release, motion, etc.), but it should not prevent the
mode handler from executing when the mode is active. The mode check
alone (vte->mouse_mode == TSM_VTE_MOUSE_MODE_SGR) is sufficient.

Test case:
  - Run 'less --mouse' in kmscon
  - Before fix: mouse wheel does not work
  - After fix: mouse wheel works correctly
  - Same behavior applies to vim with 'set ttymouse=sgr'
@kdj0c

kdj0c commented Dec 16, 2025

Copy link
Copy Markdown
Contributor

It looks good to me, if no other comment, I'll merge it soon.

@kdj0c kdj0c merged commit b0df3c6 into kmscon:main Dec 17, 2025
2 checks passed
kdj0c pushed a commit to kdj0c/libtsm that referenced this pull request Mar 31, 2026
This is a tentative to fix the following crash:

 #0  0x00007f0a572da874 in calc_line_len (line=0x231) at ../libtsm/src/tsm/tsm-selection.c:188
 kmscon#1  copy_line (line=0x231, buf=buf@entry=0x5614ec13aa7b "", start=0, len=256) at ../libtsm/src/tsm/tsm-selection.c:207
 kmscon#2  0x00007f0a572dad65 in copy_lines (con=0x5614eb42c730, start=<optimized out>, end=<optimized out>, buf=0x5614ec139160 "iled on output DP-2\n00:13:24.870 [wlr] [backend/drm/atomic.c:83] connector DP-2: Atomic commit failed: Device or resource busy\n00:13:24.870 [sway/desktop/output.c:307] Page-flip failed on output DP-2\n"..., pos=6427) at ../libtsm/src/tsm/tsm-selection.c:459
 kmscon#3  tsm_screen_selection_copy (con=0x5614eb42c730, out=out@entry=0x5614eb3f2618) at ../libtsm/src/tsm/tsm-selection.c:520
 kmscon#4  0x00005614bb685484 in copy_selection (term=<optimized out>) at ../kmscon/src/kmscon_terminal.c:608
 kmscon#5  handle_pointer_button (term=0x5614eb3f24f0, ev=0x7ffc8c54e730) at ../kmscon/src/kmscon_terminal.c:666
 kmscon#6  pointer_event (input=<optimized out>, ev=0x7ffc8c54e730, data=0x5614eb3f24f0) at ../kmscon/src/kmscon_terminal.c:711
 kmscon#7  0x00005614bb688ce6 in shl_hook_call (hook=0x5614eb3f0290, parent=0x5614eb3f0220, arg=0x7ffc8c54e730) at ../kmscon/src/shl_hook.h:216
 kmscon#8  shl_hook_call (hook=0x5614eb3f0290, parent=0x5614eb3f0220, arg=0x7ffc8c54e730) at ../kmscon/src/shl_hook.h:200
 kmscon#9  pointer_dev_send_button (button=button@entry=0 '\000', pressed=<optimized out>, dbl_click=<optimized out>, dev=0x5614eb7d9270) at ../kmscon/src/uterm_input_pointer.c:60
 kmscon#10 0x00005614bb68fa67 in pointer_dev_button (dev=<optimized out>, code=272, value=0) at ../kmscon/src/uterm_input_pointer.c:188
 kmscon#11 notify_event (dev=<optimized out>, type=<optimized out>, code=272, value=0) at ../kmscon/src/uterm_input.c:61
 kmscon#12 input_data_dev (data=<optimized out>, mask=<optimized out>, fd=<optimized out>) at ../kmscon/src/uterm_input.c:104
 kmscon#13 0x00005614bb68be80 in ev_eloop_dispatch (loop=loop@entry=0x5614eb3ed830, timeout=timeout@entry=-1) at ../kmscon/src/eloop.c:830
 kmscon#14 0x00005614bb68c53b in ev_eloop_run (loop=0x5614eb3ed830, timeout=-1) at ../kmscon/src/eloop.c:884
 kmscon#15 0x00005614bb67b8d6 in main (argc=<optimized out>, argv=<optimized out>) at ../kmscon/src/kmscon_main.c:616

Signed-off-by: Jocelyn Falempe <jfalempe@redhat.com>
kdj0c pushed a commit to kdj0c/libtsm that referenced this pull request Mar 31, 2026
This is a tentative to fix the following crash:

 #0  0x00007f0a572da874 in calc_line_len (line=0x231) at ../libtsm/src/tsm/tsm-selection.c:188
 kmscon#1  copy_line (line=0x231, buf=buf@entry=0x5614ec13aa7b "", start=0, len=256) at ../libtsm/src/tsm/tsm-selection.c:207
 kmscon#2  0x00007f0a572dad65 in copy_lines (con=0x5614eb42c730, start=<optimized out>, end=<optimized out>, buf=0x5614ec139160 "iled on output DP-2\n00:13:24.870 [wlr] [backend/drm/atomic.c:83] connector DP-2: Atomic commit failed: Device or resource busy\n00:13:24.870 [sway/desktop/output.c:307] Page-flip failed on output DP-2\n"..., pos=6427) at ../libtsm/src/tsm/tsm-selection.c:459
 kmscon#3  tsm_screen_selection_copy (con=0x5614eb42c730, out=out@entry=0x5614eb3f2618) at ../libtsm/src/tsm/tsm-selection.c:520
 kmscon#4  0x00005614bb685484 in copy_selection (term=<optimized out>) at ../kmscon/src/kmscon_terminal.c:608
 kmscon#5  handle_pointer_button (term=0x5614eb3f24f0, ev=0x7ffc8c54e730) at ../kmscon/src/kmscon_terminal.c:666
 kmscon#6  pointer_event (input=<optimized out>, ev=0x7ffc8c54e730, data=0x5614eb3f24f0) at ../kmscon/src/kmscon_terminal.c:711
 kmscon#7  0x00005614bb688ce6 in shl_hook_call (hook=0x5614eb3f0290, parent=0x5614eb3f0220, arg=0x7ffc8c54e730) at ../kmscon/src/shl_hook.h:216
 kmscon#8  shl_hook_call (hook=0x5614eb3f0290, parent=0x5614eb3f0220, arg=0x7ffc8c54e730) at ../kmscon/src/shl_hook.h:200
 kmscon#9  pointer_dev_send_button (button=button@entry=0 '\000', pressed=<optimized out>, dbl_click=<optimized out>, dev=0x5614eb7d9270) at ../kmscon/src/uterm_input_pointer.c:60
 kmscon#10 0x00005614bb68fa67 in pointer_dev_button (dev=<optimized out>, code=272, value=0) at ../kmscon/src/uterm_input_pointer.c:188
 kmscon#11 notify_event (dev=<optimized out>, type=<optimized out>, code=272, value=0) at ../kmscon/src/uterm_input.c:61
 kmscon#12 input_data_dev (data=<optimized out>, mask=<optimized out>, fd=<optimized out>) at ../kmscon/src/uterm_input.c:104
 kmscon#13 0x00005614bb68be80 in ev_eloop_dispatch (loop=loop@entry=0x5614eb3ed830, timeout=timeout@entry=-1) at ../kmscon/src/eloop.c:830
 kmscon#14 0x00005614bb68c53b in ev_eloop_run (loop=0x5614eb3ed830, timeout=-1) at ../kmscon/src/eloop.c:884
 kmscon#15 0x00005614bb67b8d6 in main (argc=<optimized out>, argv=<optimized out>) at ../kmscon/src/kmscon_main.c:616

Signed-off-by: Jocelyn Falempe <jfalempe@redhat.com>
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