Fix horizontal wheel events not being reported to client programs when they grab the mouse
Fixes #2819
This commit is contained in:
parent
3a9c6088b2
commit
a89e1b5573
@ -45,6 +45,8 @@ Detailed list of changes
|
|||||||
|
|
||||||
- Allow resizing windows created in session files (:pull:`5196`)
|
- Allow resizing windows created in session files (:pull:`5196`)
|
||||||
|
|
||||||
|
- Fix horizontal wheel events not being reported to client programs when they grab the mouse (:iss:`2819`)
|
||||||
|
|
||||||
|
|
||||||
0.25.2 [2022-06-07]
|
0.25.2 [2022-06-07]
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|||||||
@ -109,17 +109,17 @@ class TermManager:
|
|||||||
|
|
||||||
|
|
||||||
class MouseButton(IntFlag):
|
class MouseButton(IntFlag):
|
||||||
NONE, LEFT, MIDDLE, RIGHT, FOURTH, FIFTH = 0, 1, 2, 4, 8, 16
|
NONE, LEFT, MIDDLE, RIGHT, FOURTH, FIFTH, SIXTH, SEVENTH = 0, 1, 2, 4, 8, 16, 32, 64
|
||||||
WHEEL_UP, WHEEL_DOWN = -1, -2
|
WHEEL_UP, WHEEL_DOWN, WHEEL_LEFT, WHEEL_RIGHT = -1, -2, -4, -8
|
||||||
|
|
||||||
|
|
||||||
bmap = {0: MouseButton.LEFT, 1: MouseButton.MIDDLE, 2: MouseButton.RIGHT}
|
bmap = MouseButton.LEFT, MouseButton.MIDDLE, MouseButton.RIGHT
|
||||||
|
ebmap = MouseButton.FOURTH, MouseButton.FIFTH, MouseButton.SIXTH, MouseButton.SEVENTH
|
||||||
|
wbmap = MouseButton.WHEEL_UP, MouseButton.WHEEL_DOWN, MouseButton.WHEEL_LEFT, MouseButton.WHEEL_RIGHT
|
||||||
SHIFT_INDICATOR = 1 << 2
|
SHIFT_INDICATOR = 1 << 2
|
||||||
ALT_INDICATOR = 1 << 3
|
ALT_INDICATOR = 1 << 3
|
||||||
CTRL_INDICATOR = 1 << 4
|
CTRL_INDICATOR = 1 << 4
|
||||||
MOTION_INDICATOR = 1 << 5
|
MOTION_INDICATOR = 1 << 5
|
||||||
SCROLL_BUTTON_INDICATOR = 1 << 6
|
|
||||||
EXTRA_BUTTON_INDICATOR = 1 << 7
|
|
||||||
|
|
||||||
|
|
||||||
class EventType(Enum):
|
class EventType(Enum):
|
||||||
@ -150,13 +150,12 @@ def decode_sgr_mouse(text: str, screen_size: ScreenSize) -> MouseEvent:
|
|||||||
typ = EventType.RELEASE if m == 'm' else (EventType.MOVE if cb & MOTION_INDICATOR else EventType.PRESS)
|
typ = EventType.RELEASE if m == 'm' else (EventType.MOVE if cb & MOTION_INDICATOR else EventType.PRESS)
|
||||||
buttons: MouseButton = MouseButton.NONE
|
buttons: MouseButton = MouseButton.NONE
|
||||||
cb3 = cb & 3
|
cb3 = cb & 3
|
||||||
if cb3 != 3:
|
if cb >= 128:
|
||||||
if cb & SCROLL_BUTTON_INDICATOR:
|
buttons |= ebmap[cb3]
|
||||||
buttons = MouseButton.WHEEL_DOWN if cb3 & 1 else MouseButton.WHEEL_UP
|
elif cb >= 64:
|
||||||
elif cb & EXTRA_BUTTON_INDICATOR:
|
buttons |= wbmap[cb3]
|
||||||
buttons |= MouseButton.FIFTH if cb3 & 1 else MouseButton.FOURTH
|
elif cb3 < 3:
|
||||||
else:
|
buttons |= bmap[cb3]
|
||||||
buttons |= bmap[cb3]
|
|
||||||
mods = 0
|
mods = 0
|
||||||
if cb & SHIFT_INDICATOR:
|
if cb & SHIFT_INDICATOR:
|
||||||
mods |= SHIFT
|
mods |= SHIFT
|
||||||
|
|||||||
105
kitty/mouse.c
105
kitty/mouse.c
@ -135,8 +135,8 @@ encode_mouse_button(Window *w, int button, MouseAction action, int mods) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
encode_mouse_scroll(Window *w, bool upwards, int mods) {
|
encode_mouse_scroll(Window *w, int button, int mods) {
|
||||||
return encode_mouse_event(w, upwards ? 4 : 5, PRESS, mods);
|
return encode_mouse_event(w, button, PRESS, mods);
|
||||||
}
|
}
|
||||||
|
|
||||||
// }}}
|
// }}}
|
||||||
@ -815,6 +815,38 @@ mouse_event(const int button, int modifiers, int action) {
|
|||||||
if (mouse_cursor_shape != old_cursor) set_mouse_cursor(mouse_cursor_shape);
|
if (mouse_cursor_shape != old_cursor) set_mouse_cursor(mouse_cursor_shape);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
scale_scroll(Screen *screen, double offset, bool is_high_resolution, double *pending_scroll_pixels, int cell_size) {
|
||||||
|
// scale the scroll by the multiplier unless the mouse is grabbed. If the mouse is grabbed only change direction.
|
||||||
|
#define SCALE_SCROLL(which) { double scale = OPT(which); if (screen->modes.mouse_tracking_mode) scale /= fabs(scale); offset *= scale; }
|
||||||
|
int s = 0;
|
||||||
|
if (is_high_resolution) {
|
||||||
|
SCALE_SCROLL(touch_scroll_multiplier);
|
||||||
|
double pixels = *pending_scroll_pixels + offset;
|
||||||
|
if (fabs(pixels) < cell_size) {
|
||||||
|
*pending_scroll_pixels = pixels;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
s = (int)round(pixels) / cell_size;
|
||||||
|
*pending_scroll_pixels = pixels - s * cell_size;
|
||||||
|
} else {
|
||||||
|
SCALE_SCROLL(wheel_scroll_multiplier);
|
||||||
|
s = (int) round(offset);
|
||||||
|
if (offset != 0) {
|
||||||
|
const int min_lines = screen->modes.mouse_tracking_mode ? 1 : OPT(wheel_scroll_min_lines);
|
||||||
|
if (min_lines > 0 && abs(s) < min_lines) s = offset > 0 ? min_lines : -min_lines;
|
||||||
|
// Always add the minimum number of lines when it is negative
|
||||||
|
else if (min_lines < 0) s = offset > 0 ? s - min_lines : s + min_lines;
|
||||||
|
// apparently on cocoa some mice generate really small yoffset values
|
||||||
|
// when scrolling slowly https://github.com/kovidgoyal/kitty/issues/1238
|
||||||
|
if (s == 0) s = offset > 0 ? 1 : -1;
|
||||||
|
}
|
||||||
|
*pending_scroll_pixels = 0;
|
||||||
|
}
|
||||||
|
return s;
|
||||||
|
#undef SCALE_SCROLL
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
scroll_event(double xoffset, double yoffset, int flags, int modifiers) {
|
scroll_event(double xoffset, double yoffset, int flags, int modifiers) {
|
||||||
debug("\x1b[36mScroll\x1b[m xoffset: %f yoffset: %f flags: %x modifiers: %s\n", xoffset, yoffset, flags, format_mods(modifiers));
|
debug("\x1b[36mScroll\x1b[m xoffset: %f yoffset: %f flags: %x modifiers: %s\n", xoffset, yoffset, flags, format_mods(modifiers));
|
||||||
@ -874,51 +906,42 @@ scroll_event(double xoffset, double yoffset, int flags, int modifiers) {
|
|||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (yoffset == 0.0) return;
|
|
||||||
|
|
||||||
int s;
|
int s;
|
||||||
bool is_high_resolution = flags & 1;
|
bool is_high_resolution = flags & 1;
|
||||||
|
|
||||||
// scale the scroll by the multiplier unless the mouse is grabbed. If the mouse is grabbed only change direction.
|
if (yoffset != 0.0) {
|
||||||
#define SCALE_SCROLL(which) { double scale = OPT(which); if (screen->modes.mouse_tracking_mode) scale /= fabs(scale); yoffset *= scale; }
|
s = scale_scroll(screen, yoffset, is_high_resolution, &screen->pending_scroll_pixels_y, global_state.callback_os_window->fonts_data->cell_height);
|
||||||
if (is_high_resolution) {
|
if (s) {
|
||||||
SCALE_SCROLL(touch_scroll_multiplier);
|
bool upwards = s > 0;
|
||||||
double pixels = screen->pending_scroll_pixels + yoffset;
|
if (screen->modes.mouse_tracking_mode) {
|
||||||
if (fabs(pixels) < global_state.callback_os_window->fonts_data->cell_height) {
|
int sz = encode_mouse_scroll(w, upwards ? 4 : 5, modifiers);
|
||||||
screen->pending_scroll_pixels = pixels;
|
if (sz > 0) {
|
||||||
return;
|
mouse_event_buf[sz] = 0;
|
||||||
}
|
for (s = abs(s); s > 0; s--) {
|
||||||
s = (int)round(pixels) / (int)global_state.callback_os_window->fonts_data->cell_height;
|
write_escape_code_to_child(screen, CSI, mouse_event_buf);
|
||||||
screen->pending_scroll_pixels = pixels - s * (int) global_state.callback_os_window->fonts_data->cell_height;
|
}
|
||||||
} else {
|
}
|
||||||
SCALE_SCROLL(wheel_scroll_multiplier);
|
} else {
|
||||||
s = (int) round(yoffset);
|
if (screen->linebuf == screen->main_linebuf) screen_history_scroll(screen, abs(s), upwards);
|
||||||
if (yoffset != 0) {
|
else fake_scroll(w, abs(s), upwards);
|
||||||
const int min_lines = screen->modes.mouse_tracking_mode ? 1 : OPT(wheel_scroll_min_lines);
|
|
||||||
if (min_lines > 0 && abs(s) < min_lines) s = yoffset > 0 ? min_lines : -min_lines;
|
|
||||||
// Always add the minimum number of lines when it is negative
|
|
||||||
else if (min_lines < 0) s = yoffset > 0 ? s - min_lines : s + min_lines;
|
|
||||||
// apparently on cocoa some mice generate really small yoffset values
|
|
||||||
// when scrolling slowly https://github.com/kovidgoyal/kitty/issues/1238
|
|
||||||
if (s == 0) s = yoffset > 0 ? 1 : -1;
|
|
||||||
}
|
|
||||||
screen->pending_scroll_pixels = 0;
|
|
||||||
}
|
|
||||||
#undef SCALE_SCROLL
|
|
||||||
if (s == 0) return;
|
|
||||||
bool upwards = s > 0;
|
|
||||||
if (screen->modes.mouse_tracking_mode) {
|
|
||||||
int sz = encode_mouse_scroll(w, upwards, modifiers);
|
|
||||||
if (sz > 0) {
|
|
||||||
mouse_event_buf[sz] = 0;
|
|
||||||
for (s = abs(s); s > 0; s--) {
|
|
||||||
write_escape_code_to_child(screen, CSI, mouse_event_buf);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
if (screen->linebuf == screen->main_linebuf) screen_history_scroll(screen, abs(s), upwards);
|
|
||||||
else fake_scroll(w, abs(s), upwards);
|
|
||||||
}
|
}
|
||||||
|
if (xoffset != 0.0) {
|
||||||
|
s = scale_scroll(screen, xoffset, is_high_resolution, &screen->pending_scroll_pixels_x, global_state.callback_os_window->fonts_data->cell_width);
|
||||||
|
if (s) {
|
||||||
|
if (screen->modes.mouse_tracking_mode) {
|
||||||
|
int sz = encode_mouse_scroll(w, s > 0 ? 6 : 7, modifiers);
|
||||||
|
if (sz > 0) {
|
||||||
|
mouse_event_buf[sz] = 0;
|
||||||
|
for (s = abs(s); s > 0; s--) {
|
||||||
|
write_escape_code_to_child(screen, CSI, mouse_event_buf);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static PyObject*
|
static PyObject*
|
||||||
|
|||||||
@ -78,7 +78,7 @@ typedef struct {
|
|||||||
PyObject_HEAD
|
PyObject_HEAD
|
||||||
|
|
||||||
unsigned int columns, lines, margin_top, margin_bottom, charset, scrolled_by;
|
unsigned int columns, lines, margin_top, margin_bottom, charset, scrolled_by;
|
||||||
double pending_scroll_pixels;
|
double pending_scroll_pixels_x, pending_scroll_pixels_y;
|
||||||
CellPixelSize cell_size;
|
CellPixelSize cell_size;
|
||||||
OverlayLine overlay_line;
|
OverlayLine overlay_line;
|
||||||
id_type window_id;
|
id_type window_id;
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user