diff --git a/kitty/char_grid.py b/kitty/char_grid.py index a69b2c9ee..f2281a058 100644 --- a/kitty/char_grid.py +++ b/kitty/char_grid.py @@ -301,7 +301,8 @@ class CharGrid: alpha = self.opts.cursor_opacity if alpha < 1.0 and shape == CURSOR_BLOCK: glEnable(GL_BLEND) - right = left + (width(1.5) if shape == CURSOR_BEAM else sg.dx) + mult = self.screen.current_char_width() + right = left + (width(1.5) if shape == CURSOR_BEAM else sg.dx * mult) bottom = top - sg.dy if shape == CURSOR_UNDERLINE: top = bottom + width(vert=False) diff --git a/kitty/data-types.h b/kitty/data-types.h index 6c0015a89..4465602d4 100644 --- a/kitty/data-types.h +++ b/kitty/data-types.h @@ -319,6 +319,7 @@ void linebuf_insert_lines(LineBuf *self, unsigned int num, unsigned int y, unsig void linebuf_delete_lines(LineBuf *self, index_type num, index_type y, index_type bottom); void linebuf_set_attribute(LineBuf *, unsigned int , unsigned int ); void linebuf_rewrap(LineBuf *self, LineBuf *other, int *cursor_y_out, HistoryBuf *); +unsigned int linebuf_char_width_at(LineBuf *self, index_type x, index_type y); bool historybuf_resize(HistoryBuf *self, index_type lines); void historybuf_add_line(HistoryBuf *self, const Line *line); void historybuf_rewrap(HistoryBuf *self, HistoryBuf *other); diff --git a/kitty/line-buf.c b/kitty/line-buf.c index 4f9150350..84e6e751c 100644 --- a/kitty/line-buf.c +++ b/kitty/line-buf.c @@ -113,6 +113,11 @@ line(LineBuf *self, PyObject *y) { return (PyObject*)self->line; } +unsigned int linebuf_char_width_at(LineBuf *self, index_type x, index_type y) { + char_type *chars = self->chars + self->line_map[y] * self->xnum; + return (chars[x] >> ATTRS_SHIFT) & WIDTH_MASK; +} + void linebuf_set_attribute(LineBuf *self, unsigned int shift, unsigned int val) { char_type mask; for (index_type y = 0; y < self->ynum; y++) { diff --git a/kitty/screen.c b/kitty/screen.c index 5f2bafe7a..a76df4ff8 100644 --- a/kitty/screen.c +++ b/kitty/screen.c @@ -1040,6 +1040,15 @@ static PyObject* is_dirty(Screen *self) { return ans; } +static PyObject* current_char_width(Screen *self) { +#define current_char_width_doc "The width of the character under the cursor" + unsigned long ans = 1; + if (self->cursor->x < self->columns - 1 && self->cursor->y < self->lines) { + ans = linebuf_char_width_at(self->linebuf, self->cursor->x, self->cursor->y); + } + return PyLong_FromUnsignedLong(ans); +} + #define COUNT_WRAP(name) \ static PyObject* name(Screen *self, PyObject *args) { \ unsigned int count = 1; \ @@ -1071,6 +1080,7 @@ static PyMethodDef methods[] = { METHOD(cursor_back, METH_VARARGS) METHOD(erase_in_line, METH_VARARGS) METHOD(erase_in_display, METH_VARARGS) + METHOD(current_char_width, METH_NOARGS) MND(insert_lines, METH_VARARGS) MND(delete_lines, METH_VARARGS) MND(insert_characters, METH_VARARGS)