mirror of
https://github.com/kovidgoyal/kitty
synced 2026-07-19 23:14:55 +02:00
Fix cursor rendering when on first cell of multicell
This commit is contained in:
@@ -9,7 +9,8 @@ layout(std140) uniform CellRenderData {
|
|||||||
uint default_fg, highlight_fg, highlight_bg, cursor_fg, cursor_bg, url_color, url_style, inverted;
|
uint default_fg, highlight_fg, highlight_bg, cursor_fg, cursor_bg, url_color, url_style, inverted;
|
||||||
|
|
||||||
uint xnum, ynum, sprites_xnum, sprites_ynum, cursor_fg_sprite_idx, cell_height;
|
uint xnum, ynum, sprites_xnum, sprites_ynum, cursor_fg_sprite_idx, cell_height;
|
||||||
float cursor_x, cursor_y, cursor_w, cursor_opacity;
|
uint cursor_x1, cursor_x2, cursor_y1, cursor_y2;
|
||||||
|
float cursor_opacity;
|
||||||
|
|
||||||
// must have unique entries with 0 being default_bg and unset being UINT32_MAX
|
// must have unique entries with 0 being default_bg and unset being UINT32_MAX
|
||||||
uint bg_colors0, bg_colors1, bg_colors2, bg_colors3, bg_colors4, bg_colors5, bg_colors6, bg_colors7;
|
uint bg_colors0, bg_colors1, bg_colors2, bg_colors3, bg_colors4, bg_colors5, bg_colors6, bg_colors7;
|
||||||
@@ -81,6 +82,11 @@ float one_if_equal_zero_otherwise(int a, int b) {
|
|||||||
return 1.0f - clamp(abs(float(a) - float(b)), 0.0f, 1.0f);
|
return 1.0f - clamp(abs(float(a) - float(b)), 0.0f, 1.0f);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
float one_if_equal_zero_otherwise(uint a, uint b) {
|
||||||
|
return 1.0f - clamp(abs(float(a) - float(b)), 0.0f, 1.0f);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
uint resolve_color(uint c, uint defval) {
|
uint resolve_color(uint c, uint defval) {
|
||||||
// Convert a cell color to an actual color based on the color table
|
// Convert a cell color to an actual color based on the color table
|
||||||
int t = int(c & BYTE_MASK);
|
int t = int(c & BYTE_MASK);
|
||||||
@@ -144,18 +150,10 @@ vec3 choose_color(float q, vec3 a, vec3 b) {
|
|||||||
return mix(b, a, q);
|
return mix(b, a, q);
|
||||||
}
|
}
|
||||||
|
|
||||||
float are_integers_equal(float a, float b) { // return 1 if equal otherwise 0
|
float is_cursor(uint x, uint y) {
|
||||||
float delta = abs(a - b); // delta can be 0, 1 or larger
|
uint clamped_x = clamp(x, cursor_x1, cursor_x2);
|
||||||
return step(delta, 0.5); // 0 if 0.5 < delta else 1
|
uint clamped_y = clamp(y, cursor_y1, cursor_y2);
|
||||||
}
|
return one_if_equal_zero_otherwise(x, clamped_x) * one_if_equal_zero_otherwise(y, clamped_y);
|
||||||
|
|
||||||
float is_cursor(uint xi, uint y) {
|
|
||||||
float x = float(xi);
|
|
||||||
float y_equal = are_integers_equal(float(y), cursor_y);
|
|
||||||
float x1_equal = are_integers_equal(x, cursor_x);
|
|
||||||
float x2_equal = are_integers_equal(x, cursor_w);
|
|
||||||
float x_equal = step(0.5, x1_equal + x2_equal);
|
|
||||||
return step(2.0, x_equal + y_equal);
|
|
||||||
}
|
}
|
||||||
// }}}
|
// }}}
|
||||||
|
|
||||||
|
|||||||
@@ -13,7 +13,6 @@
|
|||||||
// TODO: Test handling of calt ligatures with scale see is_group_calt_ligature()
|
// TODO: Test handling of calt ligatures with scale see is_group_calt_ligature()
|
||||||
// TODO: Handle selection with multicell
|
// TODO: Handle selection with multicell
|
||||||
// TODO: URL detection with multicell
|
// TODO: URL detection with multicell
|
||||||
// TODO: Cursor rendering over multicell
|
|
||||||
// TODO: Wrapping of multicell draw commands
|
// TODO: Wrapping of multicell draw commands
|
||||||
// TODO: Handle rewrap and restitch of multiline chars
|
// TODO: Handle rewrap and restitch of multiline chars
|
||||||
// TODO: Handle rewrap when a character is too wide/tall to fit on resized screen
|
// TODO: Handle rewrap when a character is too wide/tall to fit on resized screen
|
||||||
|
|||||||
@@ -369,7 +369,9 @@ cell_update_uniform_block(ssize_t vao_idx, Screen *screen, int uniform_buffer, c
|
|||||||
GLuint default_fg, highlight_fg, highlight_bg, cursor_fg, cursor_bg, url_color, url_style, inverted;
|
GLuint default_fg, highlight_fg, highlight_bg, cursor_fg, cursor_bg, url_color, url_style, inverted;
|
||||||
|
|
||||||
GLuint xnum, ynum, sprites_xnum, sprites_ynum, cursor_fg_sprite_idx, cell_height;
|
GLuint xnum, ynum, sprites_xnum, sprites_ynum, cursor_fg_sprite_idx, cell_height;
|
||||||
GLfloat cursor_x, cursor_y, cursor_w, cursor_opacity;
|
GLuint cursor_x1, cursor_x2, cursor_y1, cursor_y2;
|
||||||
|
GLfloat cursor_opacity;
|
||||||
|
|
||||||
GLuint bg_colors0, bg_colors1, bg_colors2, bg_colors3, bg_colors4, bg_colors5, bg_colors6, bg_colors7;
|
GLuint bg_colors0, bg_colors1, bg_colors2, bg_colors3, bg_colors4, bg_colors5, bg_colors6, bg_colors7;
|
||||||
GLfloat bg_opacities0, bg_opacities1, bg_opacities2, bg_opacities3, bg_opacities4, bg_opacities5, bg_opacities6, bg_opacities7;
|
GLfloat bg_opacities0, bg_opacities1, bg_opacities2, bg_opacities3, bg_opacities4, bg_opacities5, bg_opacities6, bg_opacities7;
|
||||||
};
|
};
|
||||||
@@ -402,7 +404,8 @@ cell_update_uniform_block(ssize_t vao_idx, Screen *screen, int uniform_buffer, c
|
|||||||
enum { BLOCK_IDX = 0, BEAM_IDX = 2, UNDERLINE_IDX = 3, UNFOCUSED_IDX = 4 };
|
enum { BLOCK_IDX = 0, BEAM_IDX = 2, UNDERLINE_IDX = 3, UNFOCUSED_IDX = 4 };
|
||||||
Line *line_for_cursor = NULL;
|
Line *line_for_cursor = NULL;
|
||||||
if (cursor->opacity > 0) {
|
if (cursor->opacity > 0) {
|
||||||
rd->cursor_x = cursor->x, rd->cursor_y = cursor->y;
|
rd->cursor_x1 = cursor->x, rd->cursor_y1 = cursor->y;
|
||||||
|
rd->cursor_x2 = cursor->x, rd->cursor_y2 = cursor->y;
|
||||||
rd->cursor_opacity = cursor->opacity;
|
rd->cursor_opacity = cursor->opacity;
|
||||||
CursorShape cs = (cursor->is_focused || OPT(cursor_shape_unfocused) == NO_CURSOR_SHAPE) ? cursor->shape : OPT(cursor_shape_unfocused);
|
CursorShape cs = (cursor->is_focused || OPT(cursor_shape_unfocused) == NO_CURSOR_SHAPE) ? cursor->shape : OPT(cursor_shape_unfocused);
|
||||||
switch(cs) {
|
switch(cs) {
|
||||||
@@ -427,6 +430,24 @@ cell_update_uniform_block(ssize_t vao_idx, Screen *screen, int uniform_buffer, c
|
|||||||
}
|
}
|
||||||
if (line_for_cursor) {
|
if (line_for_cursor) {
|
||||||
colors_for_cell(line_for_cursor, cp, &cell_color_x, &cell_fg, &cell_bg, &reversed);
|
colors_for_cell(line_for_cursor, cp, &cell_color_x, &cell_fg, &cell_bg, &reversed);
|
||||||
|
const CPUCell *cursor_cell;
|
||||||
|
const bool large_cursor = ((cursor_cell = &line_for_cursor->cpu_cells[cursor->x])->is_multicell) && cursor_cell->x == 0 && cursor_cell->y == 0;
|
||||||
|
if (large_cursor) {
|
||||||
|
switch(cs) {
|
||||||
|
case CURSOR_BEAM:
|
||||||
|
rd->cursor_y2 += cursor_cell->scale - 1; break;
|
||||||
|
case CURSOR_UNDERLINE:
|
||||||
|
rd->cursor_y1 += cursor_cell->scale - 1;
|
||||||
|
rd->cursor_y2 = rd->cursor_y1;
|
||||||
|
rd->cursor_x2 += mcd_x_limit(cursor_cell) - 1;
|
||||||
|
break;
|
||||||
|
case CURSOR_BLOCK:
|
||||||
|
rd->cursor_y2 += cursor_cell->scale - 1;
|
||||||
|
rd->cursor_x2 += mcd_x_limit(cursor_cell) - 1;
|
||||||
|
break;
|
||||||
|
case CURSOR_HOLLOW: case NUM_OF_CURSOR_SHAPES: case NO_CURSOR_SHAPE: break;
|
||||||
|
};
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (IS_SPECIAL_COLOR(cursor_color)) {
|
if (IS_SPECIAL_COLOR(cursor_color)) {
|
||||||
if (line_for_cursor) pick_cursor_color(line_for_cursor, cp, cell_fg, cell_bg, cell_color_x, &rd->cursor_fg, &rd->cursor_bg, rd->default_fg, rd->bg_colors0);
|
if (line_for_cursor) pick_cursor_color(line_for_cursor, cp, cell_fg, cell_bg, cell_color_x, &rd->cursor_fg, &rd->cursor_bg, rd->default_fg, rd->bg_colors0);
|
||||||
@@ -441,15 +462,9 @@ cell_update_uniform_block(ssize_t vao_idx, Screen *screen, int uniform_buffer, c
|
|||||||
}
|
}
|
||||||
// store last rendered cursor color for trail rendering
|
// store last rendered cursor color for trail rendering
|
||||||
screen->last_rendered.cursor_bg = rd->cursor_bg;
|
screen->last_rendered.cursor_bg = rd->cursor_bg;
|
||||||
} else rd->cursor_x = screen->columns, rd->cursor_y = screen->lines;
|
} else {
|
||||||
rd->cursor_w = rd->cursor_x;
|
rd->cursor_x1 = screen->columns + 1; rd->cursor_x2 = screen->columns;
|
||||||
const CPUCell *cursor_cell;
|
rd->cursor_y1 = screen->lines + 1; rd->cursor_y2 = screen->lines;
|
||||||
if (
|
|
||||||
(rd->cursor_fg_sprite_idx == BLOCK_IDX || rd->cursor_fg_sprite_idx == UNDERLINE_IDX) &&
|
|
||||||
line_for_cursor && (cursor_cell = line_for_cursor->cpu_cells + cursor->x)->is_multicell &&
|
|
||||||
cursor_cell->x == 0
|
|
||||||
) {
|
|
||||||
rd->cursor_w = mcd_x_limit(cursor_cell);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
rd->xnum = screen->columns; rd->ynum = screen->lines;
|
rd->xnum = screen->columns; rd->ynum = screen->lines;
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
# License: GPLv3 Copyright: 2024, Kovid Goyal <kovid at kovidgoyal.net>
|
# License: GPLv3 Copyright: 2024, Kovid Goyal <kovid at kovidgoyal.net>
|
||||||
|
|
||||||
|
|
||||||
from kitty.fast_data_types import TEXT_SIZE_CODE, wcswidth, test_ch_and_idx
|
from kitty.fast_data_types import TEXT_SIZE_CODE, test_ch_and_idx, wcswidth
|
||||||
|
|
||||||
from . import BaseTest, parse_bytes
|
from . import BaseTest, parse_bytes
|
||||||
from . import draw_multicell as multicell
|
from . import draw_multicell as multicell
|
||||||
|
|||||||
Reference in New Issue
Block a user