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

Support horizontal scroll events in mouse tracking.

Horizontal scroll events aren't generated by the traditional mouse
wheel, but they can be generated by trackpad gestures, though this
isn't always configured on.

The cross-platform and Windows parts of this patch is due to
Christopher Plewright; I added the GTK support.
This commit is contained in:
Simon Tatham 2022-11-22 18:36:23 +00:00
parent 5f2eff2fea
commit 819efc3c21
4 changed files with 59 additions and 16 deletions

View File

@ -363,7 +363,8 @@ typedef enum {
MBT_NOTHING,
MBT_LEFT, MBT_MIDDLE, MBT_RIGHT, /* `raw' button designations */
MBT_SELECT, MBT_EXTEND, MBT_PASTE, /* `cooked' button designations */
MBT_WHEEL_UP, MBT_WHEEL_DOWN /* mouse wheel */
MBT_WHEEL_UP, MBT_WHEEL_DOWN, /* vertical mouse wheel */
MBT_WHEEL_LEFT, MBT_WHEEL_RIGHT /* horizontal mouse wheel */
} Mouse_Button;
typedef enum {

View File

@ -7221,6 +7221,14 @@ void term_mouse(Terminal *term, Mouse_Button braw, Mouse_Button bcooked,
encstate = 0x41;
wheel = true;
break;
case MBT_WHEEL_LEFT:
encstate = 0x42;
wheel = true;
break;
case MBT_WHEEL_RIGHT:
encstate = 0x43;
wheel = true;
break;
case MBT_NOTHING:
assert( a == MA_MOVE );
encstate = 0x03; // release; no buttons pressed

View File

@ -169,7 +169,7 @@ struct GtkFrontend {
guint32 input_event_time; /* Timestamp of the most recent input event. */
GtkWidget *dialogs[DIALOG_SLOT_LIMIT];
#if GTK_CHECK_VERSION(3,4,0)
gdouble cumulative_scroll;
gdouble cumulative_hscroll, cumulative_vscroll;
#endif
/* Cached things out of conf that we refer to a lot */
int bold_style;
@ -2118,8 +2118,8 @@ void input_method_commit_event(GtkIMContext *imc, gchar *str, gpointer data)
#define SCROLL_INCREMENT_LINES 5
#if GTK_CHECK_VERSION(3,4,0)
gboolean scroll_internal(GtkFrontend *inst, gdouble delta, guint state,
gdouble ex, gdouble ey)
gboolean scroll_internal(GtkFrontend *inst, gdouble xdelta, gdouble ydelta,
guint state, gdouble ex, gdouble ey)
{
int x, y;
bool shift, ctrl, alt, raw_mouse_mode;
@ -2137,22 +2137,22 @@ gboolean scroll_internal(GtkFrontend *inst, gdouble delta, guint state,
!(shift && conf_get_bool(inst->conf,
CONF_mouse_override)));
inst->cumulative_scroll += delta * SCROLL_INCREMENT_LINES;
inst->cumulative_vscroll += ydelta * SCROLL_INCREMENT_LINES;
if (!raw_mouse_mode) {
int scroll_lines = (int)inst->cumulative_scroll; /* rounds toward 0 */
int scroll_lines = (int)inst->cumulative_vscroll; /* rounds toward 0 */
if (scroll_lines) {
term_scroll(inst->term, 0, scroll_lines);
inst->cumulative_scroll -= scroll_lines;
inst->cumulative_vscroll -= scroll_lines;
}
return true;
} else {
int scroll_events = (int)(inst->cumulative_scroll /
int scroll_events = (int)(inst->cumulative_vscroll /
SCROLL_INCREMENT_LINES);
if (scroll_events) {
int button;
inst->cumulative_scroll -= scroll_events * SCROLL_INCREMENT_LINES;
inst->cumulative_vscroll -= scroll_events * SCROLL_INCREMENT_LINES;
if (scroll_events > 0) {
button = MBT_WHEEL_DOWN;
@ -2166,6 +2166,35 @@ gboolean scroll_internal(GtkFrontend *inst, gdouble delta, guint state,
MA_CLICK, x, y, shift, ctrl, alt);
}
}
/*
* Now do the same for horizontal scrolling. But because we
* _only_ use that for passing through to mouse reporting, we
* don't even collect the scroll deltas while not in
* raw_mouse_mode. (Otherwise there would likely be a huge
* unexpected lurch when raw_mouse_mode was enabled!)
*/
inst->cumulative_hscroll += xdelta * SCROLL_INCREMENT_LINES;
scroll_events = (int)(inst->cumulative_hscroll /
SCROLL_INCREMENT_LINES);
if (scroll_events) {
int button;
inst->cumulative_hscroll -= scroll_events * SCROLL_INCREMENT_LINES;
if (scroll_events > 0) {
button = MBT_WHEEL_RIGHT;
} else {
button = MBT_WHEEL_LEFT;
scroll_events = -scroll_events;
}
while (scroll_events-- > 0) {
term_mouse(inst->term, button, translate_button(button),
MA_CLICK, x, y, shift, ctrl, alt);
}
}
return true;
}
}
@ -2267,7 +2296,7 @@ gboolean scroll_event(GtkWidget *widget, GdkEventScroll *event, gpointer data)
#if GTK_CHECK_VERSION(3,4,0)
gdouble dx, dy;
if (gdk_event_get_scroll_deltas((GdkEvent *)event, &dx, &dy)) {
return scroll_internal(inst, dy, event->state, event->x, event->y);
return scroll_internal(inst, dx, dy, event->state, event->x, event->y);
} else if (!gdk_event_get_scroll_direction((GdkEvent *)event, &dir)) {
return false;
}
@ -5283,7 +5312,8 @@ void new_session_window(Conf *conf, const char *geometry_string)
inst->wintitle = inst->icontitle = NULL;
inst->drawtype = DRAWTYPE_DEFAULT;
#if GTK_CHECK_VERSION(3,4,0)
inst->cumulative_scroll = 0.0;
inst->cumulative_vscroll = 0.0;
inst->cumulative_hscroll = 0.0;
#endif
inst->drawing_area_setup_needed = true;

View File

@ -74,6 +74,9 @@
#ifndef WM_MOUSEWHEEL
#define WM_MOUSEWHEEL 0x020A /* not defined in earlier SDKs */
#endif
#ifndef WM_MOUSEHWHEEL
#define WM_MOUSEHWHEEL 0x020E /* not defined in earlier SDKs */
#endif
#ifndef WHEEL_DELTA
#define WHEEL_DELTA 120
#endif
@ -3378,10 +3381,11 @@ static LRESULT CALLBACK WndProc(HWND hwnd, UINT message,
process_clipdata(wgs, (HGLOBAL)lParam, wParam);
return 0;
default:
if (message == wm_mousewheel || message == WM_MOUSEWHEEL) {
if (message == wm_mousewheel || message == WM_MOUSEWHEEL
|| message == WM_MOUSEHWHEEL) {
bool shift_pressed = false, control_pressed = false;
if (message == WM_MOUSEWHEEL) {
if (message == WM_MOUSEWHEEL || message == WM_MOUSEHWHEEL) {
wgs->wheel_accumulator += (short)HIWORD(wParam);
shift_pressed=LOWORD(wParam) & MK_SHIFT;
control_pressed=LOWORD(wParam) & MK_CONTROL;
@ -3400,10 +3404,10 @@ static LRESULT CALLBACK WndProc(HWND hwnd, UINT message,
/* reduce amount for next time */
if (wgs->wheel_accumulator > 0) {
b = MBT_WHEEL_UP;
b = message == WM_MOUSEHWHEEL ? MBT_WHEEL_RIGHT : MBT_WHEEL_UP;
wgs->wheel_accumulator -= WHEEL_DELTA;
} else if (wgs->wheel_accumulator < 0) {
b = MBT_WHEEL_DOWN;
b = message == WM_MOUSEHWHEEL ? MBT_WHEEL_LEFT : MBT_WHEEL_DOWN;
wgs->wheel_accumulator += WHEEL_DELTA;
} else
break;
@ -3423,7 +3427,7 @@ static LRESULT CALLBACK WndProc(HWND hwnd, UINT message,
TO_CHR_Y(p.y), shift_pressed,
control_pressed, is_alt_pressed());
} /* else: not sure when this can fail */
} else {
} else if (message != WM_MOUSEHWHEEL) {
/* trigger a scroll */
term_scroll(wgs->term, 0,
b == MBT_WHEEL_UP ?