diff --git a/CHANGELOG.md b/CHANGELOG.md index 16a16f40..1eb4f719 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -44,7 +44,8 @@ applications and force selection instead. * _irc://_ and _ircs://_ to the default set of protocols recognized when auto-detecting URLs. - +* [SGR-Pixels (1016) mouse extended coordinates](https://invisible-island.net/xterm/ctlseqs/ctlseqs.html#h3-Extended-coordinates) is now supported + (https://codeberg.org/dnkl/foot/issues/762). ### Changed @@ -83,6 +84,7 @@ ### Security ### Contributors +* [lamonte](https://codeberg.org/lamonte) ## 1.10.3 diff --git a/csi.c b/csi.c index e05d95e2..e76e0786 100644 --- a/csi.c +++ b/csi.c @@ -456,6 +456,13 @@ decset_decrst(struct terminal *term, unsigned param, bool enable) term->mouse_reporting = MOUSE_NORMAL; break; + case 1016: + if (enable) + term->mouse_reporting = MOUSE_SGR_PIXELS; + else if (term->mouse_reporting == MOUSE_SGR_PIXELS) + term->mouse_reporting = MOUSE_NORMAL; + break; + case 1034: /* smm */ LOG_DBG("%s 8-bit meta mode", enable ? "enabling" : "disabling"); @@ -609,6 +616,7 @@ decrqm(const struct terminal *term, unsigned param, bool *enabled) case 1006: *enabled = term->mouse_reporting == MOUSE_SGR; return true; case 1007: *enabled = term->alt_scrolling; return true; case 1015: *enabled = term->mouse_reporting == MOUSE_URXVT; return true; + case 1016: *enabled = term->mouse_reporting == MOUSE_SGR_PIXELS; return true; case 1034: *enabled = term->meta.eight_bit; return true; case 1035: *enabled = term->num_lock_modifier; return true; case 1036: *enabled = term->meta.esc_prefix; return true; @@ -652,6 +660,7 @@ xtsave(struct terminal *term, unsigned param) case 1006: term->xtsave.mouse_sgr = term->mouse_reporting == MOUSE_SGR; break; case 1007: term->xtsave.alt_scrolling = term->alt_scrolling; break; case 1015: term->xtsave.mouse_urxvt = term->mouse_reporting == MOUSE_URXVT; break; + case 1016: term->xtsave.mouse_sgr_pixels = term->mouse_reporting == MOUSE_SGR_PIXELS; break; case 1034: term->xtsave.meta_eight_bit = term->meta.eight_bit; break; case 1035: term->xtsave.num_lock_modifier = term->num_lock_modifier; break; case 1036: term->xtsave.meta_esc_prefix = term->meta.esc_prefix; break; @@ -694,6 +703,7 @@ xtrestore(struct terminal *term, unsigned param) case 1006: enable = term->xtsave.mouse_sgr; break; case 1007: enable = term->xtsave.alt_scrolling; break; case 1015: enable = term->xtsave.mouse_urxvt; break; + case 1016: enable = term->xtsave.mouse_sgr_pixels; break; case 1034: enable = term->xtsave.meta_eight_bit; break; case 1035: enable = term->xtsave.num_lock_modifier; break; case 1036: enable = term->xtsave.meta_esc_prefix; break; diff --git a/input.c b/input.c index abfc1390..ab177bf8 100644 --- a/input.c +++ b/input.c @@ -2095,7 +2095,8 @@ wl_pointer_motion(void *data, struct wl_pointer *wl_pointer, /* Send mouse event to client application */ if (!term_mouse_grabbed(term, seat) && - cursor_is_on_new_cell && + (cursor_is_on_new_cell || + term->mouse_reporting == MOUSE_SGR_PIXELS) && ((button == 0 && cursor_is_on_grid) || (button != 0 && send_to_client))) { @@ -2105,6 +2106,8 @@ wl_pointer_motion(void *data, struct wl_pointer *wl_pointer, term_mouse_motion( term, button, seat->mouse.row, seat->mouse.col, + seat->mouse.y - term->margins.top, + seat->mouse.x - term->margins.left, seat->kbd.shift, seat->kbd.alt, seat->kbd.ctrl); } break; @@ -2480,6 +2483,8 @@ wl_pointer_button(void *data, struct wl_pointer *wl_pointer, { term_mouse_down( term, button, seat->mouse.row, seat->mouse.col, + seat->mouse.y - term->margins.top, + seat->mouse.x - term->margins.left, seat->kbd.shift, seat->kbd.alt, seat->kbd.ctrl); } break; @@ -2491,6 +2496,8 @@ wl_pointer_button(void *data, struct wl_pointer *wl_pointer, if (send_to_client && !term_mouse_grabbed(term, seat)) { term_mouse_up( term, button, seat->mouse.row, seat->mouse.col, + seat->mouse.y - term->margins.top, + seat->mouse.x - term->margins.left, seat->kbd.shift, seat->kbd.alt, seat->kbd.ctrl); } break; @@ -2566,11 +2573,15 @@ mouse_scroll(struct seat *seat, int amount, enum wl_pointer_axis axis) for (int i = 0; i < amount; i++) { term_mouse_down( term, button, seat->mouse.row, seat->mouse.col, + seat->mouse.y - term->margins.top, + seat->mouse.x - term->margins.left, seat->kbd.shift, seat->kbd.alt, seat->kbd.ctrl); } term_mouse_up( term, button, seat->mouse.row, seat->mouse.col, + seat->mouse.y - term->margins.top, + seat->mouse.x - term->margins.left, seat->kbd.shift, seat->kbd.alt, seat->kbd.ctrl); } } diff --git a/terminal.c b/terminal.c index 4e0412a7..797bc84d 100644 --- a/terminal.c +++ b/terminal.c @@ -2786,7 +2786,7 @@ encode_xbutton(int xbutton) static void report_mouse_click(struct terminal *term, int encoded_button, int row, int col, - bool release) + int row_pixels, int col_pixels, bool release) { char response[128]; @@ -2807,6 +2807,11 @@ report_mouse_click(struct terminal *term, int encoded_button, int row, int col, encoded_button, col + 1, row + 1, release ? 'm' : 'M'); break; + case MOUSE_SGR_PIXELS: + snprintf(response, sizeof(response), "\033[<%d;%d;%d%c", + encoded_button, col_pixels + 1, row_pixels + 1, release ? 'm' : 'M'); + break; + case MOUSE_URXVT: snprintf(response, sizeof(response), "\033[%d;%d;%dM", 32 + (release ? 3 : encoded_button), col + 1, row + 1); @@ -2821,9 +2826,9 @@ report_mouse_click(struct terminal *term, int encoded_button, int row, int col, } static void -report_mouse_motion(struct terminal *term, int encoded_button, int row, int col) +report_mouse_motion(struct terminal *term, int encoded_button, int row, int col, int row_pixels, int col_pixels) { - report_mouse_click(term, encoded_button, row, col, false); + report_mouse_click(term, encoded_button, row, col, row_pixels, col_pixels, false); } bool @@ -2846,6 +2851,7 @@ term_mouse_grabbed(const struct terminal *term, const struct seat *seat) void term_mouse_down(struct terminal *term, int button, int row, int col, + int row_pixels, int col_pixels, bool _shift, bool _alt, bool _ctrl) { /* Map libevent button event code to X button number */ @@ -2872,7 +2878,7 @@ term_mouse_down(struct terminal *term, int button, int row, int col, case MOUSE_CLICK: case MOUSE_DRAG: case MOUSE_MOTION: - report_mouse_click(term, encoded, row, col, false); + report_mouse_click(term, encoded, row, col, row_pixels, col_pixels, false); break; case MOUSE_X10: @@ -2884,6 +2890,7 @@ term_mouse_down(struct terminal *term, int button, int row, int col, void term_mouse_up(struct terminal *term, int button, int row, int col, + int row_pixels, int col_pixels, bool _shift, bool _alt, bool _ctrl) { /* Map libevent button event code to X button number */ @@ -2914,7 +2921,7 @@ term_mouse_up(struct terminal *term, int button, int row, int col, case MOUSE_CLICK: case MOUSE_DRAG: case MOUSE_MOTION: - report_mouse_click(term, encoded, row, col, true); + report_mouse_click(term, encoded, row, col, row_pixels, col_pixels, true); break; case MOUSE_X10: @@ -2926,6 +2933,7 @@ term_mouse_up(struct terminal *term, int button, int row, int col, void term_mouse_motion(struct terminal *term, int button, int row, int col, + int row_pixels, int col_pixels, bool _shift, bool _alt, bool _ctrl) { int encoded = 0; @@ -2961,7 +2969,7 @@ term_mouse_motion(struct terminal *term, int button, int row, int col, /* FALLTHROUGH */ case MOUSE_MOTION: - report_mouse_motion(term, encoded, row, col); + report_mouse_motion(term, encoded, row, col, row_pixels, col_pixels); break; case MOUSE_X10: diff --git a/terminal.h b/terminal.h index eaedf231..3d29c4ae 100644 --- a/terminal.h +++ b/terminal.h @@ -246,6 +246,7 @@ enum mouse_reporting { MOUSE_UTF8, /* ?1005h */ MOUSE_SGR, /* ?1006h */ MOUSE_URXVT, /* ?1015h */ + MOUSE_SGR_PIXELS, /* ?1016h */ }; enum cursor_style { CURSOR_BLOCK, CURSOR_UNDERLINE, CURSOR_BEAM }; @@ -416,6 +417,7 @@ struct terminal { //bool mouse_utf8:1; bool mouse_sgr:1; bool mouse_urxvt:1; + bool mouse_sgr_pixels:1; bool meta_eight_bit:1; bool meta_esc_prefix:1; bool num_lock_modifier:1; @@ -752,12 +754,15 @@ void term_kbd_focus_in(struct terminal *term); void term_kbd_focus_out(struct terminal *term); void term_mouse_down( struct terminal *term, int button, int row, int col, + int row_pixels, int col_pixels, bool shift, bool alt, bool ctrl); void term_mouse_up( struct terminal *term, int button, int row, int col, + int row_pixels, int col_pixels, bool shift, bool alt, bool ctrl); void term_mouse_motion( struct terminal *term, int button, int row, int col, + int row_pixels, int col_pixels, bool shift, bool alt, bool ctrl); bool term_mouse_grabbed(const struct terminal *term, const struct seat *seat); void term_xcursor_update(struct terminal *term);