Add support for reporting mouse events with pixel co-ordinates using the SGR_PIXEL_PROTOCOL introduced in xterm 359
This commit is contained in:
parent
f3447d187d
commit
9a3d99515f
@ -18,6 +18,9 @@ To update |kitty|, :doc:`follow the instructions <binary>`.
|
|||||||
- Allow the user to supply a custom Python function to draw tab bar. See
|
- Allow the user to supply a custom Python function to draw tab bar. See
|
||||||
:opt:`tab_bar_style`
|
:opt:`tab_bar_style`
|
||||||
|
|
||||||
|
- Add support for reporting mouse events with pixel co-ordinates using the
|
||||||
|
``SGR_PIXEL_PROTOCOL`` introduced in xterm 359
|
||||||
|
|
||||||
- When programs ask to read from the clipboard prompt the user to allow
|
- When programs ask to read from the clipboard prompt the user to allow
|
||||||
the request by default instead of denying by default. See
|
the request by default instead of denying by default. See
|
||||||
:opt:`clipboard_control` for details (:iss:`4022`)
|
:opt:`clipboard_control` for details (:iss:`4022`)
|
||||||
|
|||||||
@ -60,7 +60,7 @@ typedef enum { DISABLE_LIGATURES_NEVER, DISABLE_LIGATURES_CURSOR, DISABLE_LIGATU
|
|||||||
|
|
||||||
#define ERROR_PREFIX "[PARSE ERROR]"
|
#define ERROR_PREFIX "[PARSE ERROR]"
|
||||||
typedef enum MouseTrackingModes { NO_TRACKING, BUTTON_MODE, MOTION_MODE, ANY_MODE } MouseTrackingMode;
|
typedef enum MouseTrackingModes { NO_TRACKING, BUTTON_MODE, MOTION_MODE, ANY_MODE } MouseTrackingMode;
|
||||||
typedef enum MouseTrackingProtocols { NORMAL_PROTOCOL, UTF8_PROTOCOL, SGR_PROTOCOL, URXVT_PROTOCOL} MouseTrackingProtocol;
|
typedef enum MouseTrackingProtocols { NORMAL_PROTOCOL, UTF8_PROTOCOL, SGR_PROTOCOL, URXVT_PROTOCOL, SGR_PIXEL_PROTOCOL} MouseTrackingProtocol;
|
||||||
typedef enum MouseShapes { BEAM, HAND, ARROW } MouseShape;
|
typedef enum MouseShapes { BEAM, HAND, ARROW } MouseShape;
|
||||||
typedef enum { NONE, MENUBAR, WINDOW, ALL } WindowTitleIn;
|
typedef enum { NONE, MENUBAR, WINDOW, ALL } WindowTitleIn;
|
||||||
typedef enum { TILING, SCALED, MIRRORED } BackgroundImageLayout;
|
typedef enum { TILING, SCALED, MIRRORED } BackgroundImageLayout;
|
||||||
|
|||||||
@ -66,6 +66,7 @@
|
|||||||
#define MOUSE_UTF8_MODE (1005 << 5)
|
#define MOUSE_UTF8_MODE (1005 << 5)
|
||||||
#define MOUSE_SGR_MODE (1006 << 5)
|
#define MOUSE_SGR_MODE (1006 << 5)
|
||||||
#define MOUSE_URXVT_MODE (1015 << 5)
|
#define MOUSE_URXVT_MODE (1015 << 5)
|
||||||
|
#define MOUSE_SGR_PIXEL_MODE (1016 << 5)
|
||||||
|
|
||||||
// Save cursor (DECSC)
|
// Save cursor (DECSC)
|
||||||
#define SAVE_CURSOR (1048 << 5)
|
#define SAVE_CURSOR (1048 << 5)
|
||||||
|
|||||||
@ -66,7 +66,7 @@ encode_button(unsigned int button) {
|
|||||||
static char mouse_event_buf[64];
|
static char mouse_event_buf[64];
|
||||||
|
|
||||||
static int
|
static int
|
||||||
encode_mouse_event_impl(unsigned int x, unsigned int y, int mouse_tracking_protocol, int button, MouseAction action, int mods) {
|
encode_mouse_event_impl(const MousePosition *mpos, int mouse_tracking_protocol, int button, MouseAction action, int mods) {
|
||||||
unsigned int cb = 0;
|
unsigned int cb = 0;
|
||||||
if (action == MOVE) {
|
if (action == MOVE) {
|
||||||
cb = 3;
|
cb = 3;
|
||||||
@ -79,7 +79,12 @@ encode_mouse_event_impl(unsigned int x, unsigned int y, int mouse_tracking_proto
|
|||||||
if (mods & GLFW_MOD_SHIFT) cb |= SHIFT_INDICATOR;
|
if (mods & GLFW_MOD_SHIFT) cb |= SHIFT_INDICATOR;
|
||||||
if (mods & GLFW_MOD_ALT) cb |= ALT_INDICATOR;
|
if (mods & GLFW_MOD_ALT) cb |= ALT_INDICATOR;
|
||||||
if (mods & GLFW_MOD_CONTROL) cb |= CONTROL_INDICATOR;
|
if (mods & GLFW_MOD_CONTROL) cb |= CONTROL_INDICATOR;
|
||||||
|
int x = mpos->cell_x + 1, y = mpos->cell_y + 1;
|
||||||
switch(mouse_tracking_protocol) {
|
switch(mouse_tracking_protocol) {
|
||||||
|
case SGR_PIXEL_PROTOCOL:
|
||||||
|
x = (unsigned int)round(mpos->x);
|
||||||
|
y = (unsigned int)round(mpos->y);
|
||||||
|
/* fallthrough */
|
||||||
case SGR_PROTOCOL:
|
case SGR_PROTOCOL:
|
||||||
return snprintf(mouse_event_buf, sizeof(mouse_event_buf), "<%d;%d;%d%s", cb, x, y, action == RELEASE ? "m" : "M");
|
return snprintf(mouse_event_buf, sizeof(mouse_event_buf), "<%d;%d;%d%s", cb, x, y, action == RELEASE ? "m" : "M");
|
||||||
break;
|
break;
|
||||||
@ -106,9 +111,8 @@ encode_mouse_event_impl(unsigned int x, unsigned int y, int mouse_tracking_proto
|
|||||||
|
|
||||||
static int
|
static int
|
||||||
encode_mouse_event(Window *w, int button, MouseAction action, int mods) {
|
encode_mouse_event(Window *w, int button, MouseAction action, int mods) {
|
||||||
unsigned int x = w->mouse_pos.cell_x + 1, y = w->mouse_pos.cell_y + 1; // 1 based indexing
|
|
||||||
Screen *screen = w->render_data.screen;
|
Screen *screen = w->render_data.screen;
|
||||||
return encode_mouse_event_impl(x, y, screen->modes.mouse_tracking_protocol, button, action, mods);
|
return encode_mouse_event_impl(&w->mouse_pos, screen->modes.mouse_tracking_protocol, button, action, mods);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
@ -337,7 +341,7 @@ HANDLER(handle_move_event) {
|
|||||||
if (handle_in_kitty) {
|
if (handle_in_kitty) {
|
||||||
handle_mouse_movement_in_kitty(w, button, mouse_cell_changed | cell_half_changed);
|
handle_mouse_movement_in_kitty(w, button, mouse_cell_changed | cell_half_changed);
|
||||||
} else {
|
} else {
|
||||||
if (!mouse_cell_changed) return;
|
if (!mouse_cell_changed && screen->modes.mouse_tracking_protocol != SGR_PIXEL_PROTOCOL) return;
|
||||||
int sz = encode_mouse_button(w, MAX(0, button), button >=0 ? DRAG : MOVE, modifiers);
|
int sz = encode_mouse_button(w, MAX(0, button), button >=0 ? DRAG : MOVE, modifiers);
|
||||||
if (sz > 0) { mouse_event_buf[sz] = 0; write_escape_code_to_child(screen, CSI, mouse_event_buf); }
|
if (sz > 0) { mouse_event_buf[sz] = 0; write_escape_code_to_child(screen, CSI, mouse_event_buf); }
|
||||||
}
|
}
|
||||||
@ -799,7 +803,8 @@ send_mouse_event(PyObject *self UNUSED, PyObject *args) {
|
|||||||
|
|
||||||
MouseTrackingMode mode = screen->modes.mouse_tracking_mode;
|
MouseTrackingMode mode = screen->modes.mouse_tracking_mode;
|
||||||
if (mode == ANY_MODE || (mode == MOTION_MODE && action != MOVE) || (mode == BUTTON_MODE && (action == PRESS || action == RELEASE))) {
|
if (mode == ANY_MODE || (mode == MOTION_MODE && action != MOVE) || (mode == BUTTON_MODE && (action == PRESS || action == RELEASE))) {
|
||||||
int sz = encode_mouse_event_impl(x + 1, y + 1, screen->modes.mouse_tracking_protocol, button, action, mods);
|
MousePosition mpos = {.cell_x = x, .cell_y = y};
|
||||||
|
int sz = encode_mouse_event_impl(&mpos, screen->modes.mouse_tracking_protocol, button, action, mods);
|
||||||
if (sz > 0) {
|
if (sz > 0) {
|
||||||
mouse_event_buf[sz] = 0;
|
mouse_event_buf[sz] = 0;
|
||||||
write_escape_code_to_child(screen, CSI, mouse_event_buf);
|
write_escape_code_to_child(screen, CSI, mouse_event_buf);
|
||||||
@ -814,7 +819,8 @@ test_encode_mouse(PyObject *self UNUSED, PyObject *args) {
|
|||||||
unsigned int x, y;
|
unsigned int x, y;
|
||||||
int mouse_tracking_protocol, button, action, mods;
|
int mouse_tracking_protocol, button, action, mods;
|
||||||
if (!PyArg_ParseTuple(args, "IIiiii", &x, &y, &mouse_tracking_protocol, &button, &action, &mods)) return NULL;
|
if (!PyArg_ParseTuple(args, "IIiiii", &x, &y, &mouse_tracking_protocol, &button, &action, &mods)) return NULL;
|
||||||
int sz = encode_mouse_event_impl(x, y, mouse_tracking_protocol, button, action, mods);
|
MousePosition mpos = {.cell_x = x - 1, .cell_y = y - 1};
|
||||||
|
int sz = encode_mouse_event_impl(&mpos, mouse_tracking_protocol, button, action, mods);
|
||||||
return PyUnicode_FromStringAndSize(mouse_event_buf, sz);
|
return PyUnicode_FromStringAndSize(mouse_event_buf, sz);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -921,6 +921,7 @@ set_mode_from_const(Screen *self, unsigned int mode, bool val) {
|
|||||||
MOUSE_MODE(MOUSE_MOVE_TRACKING, mouse_tracking_mode, ANY_MODE)
|
MOUSE_MODE(MOUSE_MOVE_TRACKING, mouse_tracking_mode, ANY_MODE)
|
||||||
MOUSE_MODE(MOUSE_UTF8_MODE, mouse_tracking_protocol, UTF8_PROTOCOL)
|
MOUSE_MODE(MOUSE_UTF8_MODE, mouse_tracking_protocol, UTF8_PROTOCOL)
|
||||||
MOUSE_MODE(MOUSE_SGR_MODE, mouse_tracking_protocol, SGR_PROTOCOL)
|
MOUSE_MODE(MOUSE_SGR_MODE, mouse_tracking_protocol, SGR_PROTOCOL)
|
||||||
|
MOUSE_MODE(MOUSE_SGR_PIXEL_MODE, mouse_tracking_protocol, SGR_PIXEL_PROTOCOL)
|
||||||
MOUSE_MODE(MOUSE_URXVT_MODE, mouse_tracking_protocol, URXVT_PROTOCOL)
|
MOUSE_MODE(MOUSE_URXVT_MODE, mouse_tracking_protocol, URXVT_PROTOCOL)
|
||||||
|
|
||||||
case DECSCLM:
|
case DECSCLM:
|
||||||
@ -1816,6 +1817,10 @@ report_mode_status(Screen *self, unsigned int which, bool private) {
|
|||||||
ans = self->modes.mouse_tracking_mode == ANY_MODE ? 1 : 2; break;
|
ans = self->modes.mouse_tracking_mode == ANY_MODE ? 1 : 2; break;
|
||||||
case MOUSE_SGR_MODE:
|
case MOUSE_SGR_MODE:
|
||||||
ans = self->modes.mouse_tracking_protocol == SGR_PROTOCOL ? 1 : 2; break;
|
ans = self->modes.mouse_tracking_protocol == SGR_PROTOCOL ? 1 : 2; break;
|
||||||
|
case MOUSE_UTF8_MODE:
|
||||||
|
ans = self->modes.mouse_tracking_protocol == UTF8_PROTOCOL ? 1 : 2; break;
|
||||||
|
case MOUSE_SGR_PIXEL_MODE:
|
||||||
|
ans = self->modes.mouse_tracking_protocol == SGR_PIXEL_PROTOCOL ? 1 : 2; break;
|
||||||
case PENDING_UPDATE:
|
case PENDING_UPDATE:
|
||||||
ans = self->pending_mode.activated_at ? 1 : 2; break;
|
ans = self->pending_mode.activated_at ? 1 : 2; break;
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user