1
0
mirror of https://git.tartarus.org/simon/putty.git synced 2025-01-09 17:38:00 +00:00

Support xterm any-event mouse tracking

From https://invisible-island.net/xterm/ctlseqs/ctlseqs.html#h3-Any-event-tracking:

    Any-event mode is the same as button-event mode, except that all motion
    events are reported, even if no mouse button is down.  It is enabled by
    specifying 1003 to DECSET.

Normally the front ends only report mouse events when buttons are
pressed, so we introduce a MA_MOVE event with MBT_NOTHING set to
indicate such a mouse movement.
This commit is contained in:
Ben Jackson 2019-12-20 13:56:58 +00:00 committed by Simon Tatham
parent 854d78eef3
commit 3cfbd3df0f
5 changed files with 48 additions and 5 deletions

View File

@ -367,7 +367,7 @@ typedef enum {
} Mouse_Button;
typedef enum {
MA_NOTHING, MA_CLICK, MA_2CLK, MA_3CLK, MA_DRAG, MA_RELEASE
MA_NOTHING, MA_CLICK, MA_2CLK, MA_3CLK, MA_DRAG, MA_RELEASE, MA_MOVE
} Mouse_Action;
/* Keyboard modifiers -- keys the user is actually holding down */

View File

@ -1374,6 +1374,8 @@ static void power_on(Terminal *term, bool clear)
term->xterm_mouse = 0;
term->xterm_extended_mouse = false;
term->urxvt_extended_mouse = false;
term->raw_mouse_reported_x = 0;
term->raw_mouse_reported_y = 0;
win_set_raw_mouse_mode(term->win, false);
term->win_pointer_shape_pending = true;
term->win_pointer_shape_raw = false;
@ -3067,6 +3069,10 @@ static void toggle_mode(Terminal *term, int mode, int query, bool state)
term->xterm_mouse = state ? 2 : 0;
term_update_raw_mouse_mode(term);
break;
case 1003: /* xterm mouse any-event tracking */
term->xterm_mouse = state ? 3 : 0;
term_update_raw_mouse_mode(term);
break;
case 1006: /* xterm extended mouse */
term->xterm_extended_mouse = state;
break;
@ -7053,6 +7059,13 @@ void term_mouse(Terminal *term, Mouse_Button braw, Mouse_Button bcooked,
!(term->mouse_override && shift));
int default_seltype;
// Don't do anything if mouse movement events weren't requested;
// Note: return early to avoid doing all of this code on every mouse move
// event only to throw it away.
if (a == MA_MOVE && (!raw_mouse || term->xterm_mouse < 3)) {
return;
}
if (y < 0) {
y = 0;
if (a == MA_DRAG && !raw_mouse)
@ -7139,6 +7152,11 @@ void term_mouse(Terminal *term, Mouse_Button braw, Mouse_Button bcooked,
encstate = 0x41;
wheel = true;
break;
case MBT_NOTHING:
assert( a == MA_MOVE );
encstate = 0x03; // release; no buttons pressed
wheel = false;
break;
default:
return;
}
@ -7153,7 +7171,21 @@ void term_mouse(Terminal *term, Mouse_Button braw, Mouse_Button bcooked,
case MA_DRAG:
if (term->xterm_mouse == 1)
return;
encstate += 0x20;
encstate += 0x20; // motion indicator
break;
case MA_MOVE: // mouse move without buttons
assert( braw == MBT_NOTHING && bcooked == MBT_NOTHING );
if (term->xterm_mouse < 3)
return;
if (selpoint.x == term->raw_mouse_reported_x &&
selpoint.y == term->raw_mouse_reported_y)
return;
term->raw_mouse_reported_x = x;
term->raw_mouse_reported_y = y;
encstate += 0x20; // motion indicator
break;
case MA_RELEASE:
/* If multiple extensions are enabled, the xterm 1006 is used, so it's okay to check for only that */

View File

@ -155,6 +155,8 @@ struct terminal_tag {
bool xterm_extended_mouse;
bool urxvt_extended_mouse;
int mouse_is_down; /* used while tracking mouse buttons */
int raw_mouse_reported_x;
int raw_mouse_reported_y;
bool bracketed_paste, bracketed_paste_active;

View File

@ -502,6 +502,8 @@ static Mouse_Button translate_button(Mouse_Button button)
return MBT_PASTE;
if (button == MBT_RIGHT)
return MBT_EXTEND;
if (button == MBT_NOTHING)
return MBT_NOTHING;
return 0; /* shouldn't happen */
}
@ -2305,7 +2307,9 @@ gint motion_event(GtkWidget *widget, GdkEventMotion *event, gpointer data)
{
GtkFrontend *inst = (GtkFrontend *)data;
bool shift, ctrl, alt;
int x, y, button;
Mouse_Action action = MA_DRAG;
Mouse_Button button = MBT_NOTHING;
int x, y;
/* Remember the timestamp. */
inst->input_event_time = event->time;
@ -2325,12 +2329,12 @@ gint motion_event(GtkWidget *widget, GdkEventMotion *event, gpointer data)
else if (event->state & GDK_BUTTON3_MASK)
button = MBT_RIGHT;
else
return false; /* don't even know what button! */
action = MA_MOVE;
x = (event->x - inst->window_border) / inst->font_width;
y = (event->y - inst->window_border) / inst->font_height;
term_mouse(inst->term, button, translate_button(button), MA_DRAG,
term_mouse(inst->term, button, translate_button(button), action,
x, y, shift, ctrl, alt);
return true;

View File

@ -2729,6 +2729,11 @@ static LRESULT CALLBACK WndProc(HWND hwnd, UINT message,
TO_CHR_X(X_POS(lParam)),
TO_CHR_Y(Y_POS(lParam)), wParam & MK_SHIFT,
wParam & MK_CONTROL, is_alt_pressed());
} else {
term_mouse(wgs->term, MBT_NOTHING, MBT_NOTHING, MA_MOVE,
TO_CHR_X(X_POS(lParam)),
TO_CHR_Y(Y_POS(lParam)), false,
false, false);
}
return 0;
}