mirror of
https://github.com/kovidgoyal/kitty
synced 2026-07-19 15:04:50 +02:00
don't draw cursor trail over the real cursor
This commit is contained in:
@@ -809,7 +809,7 @@ render_prepared_os_window(OSWindow *os_window, unsigned int active_window_id, co
|
||||
w->cursor_opacity_at_last_render = WD.screen->cursor_render_info.opacity; w->last_cursor_shape = WD.screen->cursor_render_info.shape;
|
||||
}
|
||||
}
|
||||
if (true) draw_cursor_trail(&tab->cursor_trail);
|
||||
if (true && tab->cursor_trail.needs_render) draw_cursor_trail(&tab->cursor_trail);
|
||||
if (os_window->live_resize.in_progress) draw_resizing_text(os_window);
|
||||
swap_window_buffers(os_window);
|
||||
os_window->last_active_tab = os_window->active_tab; os_window->last_num_tabs = os_window->num_tabs; os_window->last_active_window_id = active_window_id;
|
||||
|
||||
@@ -38,36 +38,37 @@ update_cursor_trail(CursorTrail *ct, Window *w, monotonic_t now) {
|
||||
static const int ci[4][2] = {{1, 0}, {1, 1}, {0, 1}, {0, 0}};
|
||||
const float dx_threshold = WD.dx / WD.screen->cell_size.width;
|
||||
const float dy_threshold = WD.dy / WD.screen->cell_size.height;
|
||||
bool needs_render_prev = ct->needs_render;
|
||||
ct->needs_render = false;
|
||||
|
||||
float cursor_edge_x[2], cursor_edge_y[2];
|
||||
if (!get_cursor_edge(&cursor_edge_x[0], &cursor_edge_x[1],
|
||||
&cursor_edge_y[0], &cursor_edge_y[1], w)) {
|
||||
return false;
|
||||
if (!get_cursor_edge(&ct->cursor_edge_x[0], &ct->cursor_edge_x[1],
|
||||
&ct->cursor_edge_y[0], &ct->cursor_edge_y[1], w)) {
|
||||
return needs_render_prev;
|
||||
}
|
||||
|
||||
// todo - make these configurable
|
||||
// the decay time for the trail to reach 1/1024 of its distance from the cursor corner
|
||||
float decay_fast = 0.10f;
|
||||
float decay_slow = 0.40f;
|
||||
float decay_slow = 0.80f;
|
||||
if (OPT(input_delay) < now - WD.screen->cursor->updated_at && ct->updated_at < now) {
|
||||
float cursor_center_x = (cursor_edge_x[0] + cursor_edge_x[1]) * 0.5f;
|
||||
float cursor_center_y = (cursor_edge_y[0] + cursor_edge_y[1]) * 0.5f;
|
||||
float cursor_diag_2 = norm(cursor_edge_x[1] - cursor_edge_x[0], cursor_edge_y[1] - cursor_edge_y[0]) * 0.5;
|
||||
float cursor_center_x = (ct->cursor_edge_x[0] + ct->cursor_edge_x[1]) * 0.5f;
|
||||
float cursor_center_y = (ct->cursor_edge_y[0] + ct->cursor_edge_y[1]) * 0.5f;
|
||||
float cursor_diag_2 = norm(ct->cursor_edge_x[1] - ct->cursor_edge_x[0], ct->cursor_edge_y[1] - ct->cursor_edge_y[0]) * 0.5;
|
||||
float dt = monotonic_t_to_s_double(now - ct->updated_at);
|
||||
|
||||
for (int i = 0; i < 4; ++i) {
|
||||
float dx = cursor_edge_x[ci[i][0]] - ct->corner_x[i];
|
||||
float dy = cursor_edge_y[ci[i][1]] - ct->corner_y[i];
|
||||
float dx = ct->cursor_edge_x[ci[i][0]] - ct->corner_x[i];
|
||||
float dy = ct->cursor_edge_y[ci[i][1]] - ct->corner_y[i];
|
||||
if (fabsf(dx) < dx_threshold && fabsf(dy) < dy_threshold) {
|
||||
ct->corner_x[i] = cursor_edge_x[ci[i][0]];
|
||||
ct->corner_y[i] = cursor_edge_y[ci[i][1]];
|
||||
ct->corner_x[i] = ct->cursor_edge_x[ci[i][0]];
|
||||
ct->corner_y[i] = ct->cursor_edge_y[ci[i][1]];
|
||||
continue;
|
||||
}
|
||||
|
||||
// Corner that is closer to the cursor moves faster.
|
||||
// It creates dynamic effect that looks like the trail is being pulled towards the cursor.
|
||||
float dot = (dx * (cursor_edge_x[ci[i][0]] - cursor_center_x) +
|
||||
dy * (cursor_edge_y[ci[i][1]] - cursor_center_y)) /
|
||||
float dot = (dx * (ct->cursor_edge_x[ci[i][0]] - cursor_center_x) +
|
||||
dy * (ct->cursor_edge_y[ci[i][1]] - cursor_center_y)) /
|
||||
cursor_diag_2 / norm(dx, dy);
|
||||
|
||||
float decay_seconds = decay_slow + (decay_fast - decay_slow) * (1.0f + dot) * 0.5f;
|
||||
@@ -79,12 +80,14 @@ update_cursor_trail(CursorTrail *ct, Window *w, monotonic_t now) {
|
||||
}
|
||||
ct->updated_at = now;
|
||||
for (int i = 0; i < 4; ++i) {
|
||||
float dx = fabsf(cursor_edge_x[ci[i][0]] - ct->corner_x[i]);
|
||||
float dy = fabsf(cursor_edge_y[ci[i][1]] - ct->corner_y[i]);
|
||||
float dx = fabsf(ct->cursor_edge_x[ci[i][0]] - ct->corner_x[i]);
|
||||
float dy = fabsf(ct->cursor_edge_y[ci[i][1]] - ct->corner_y[i]);
|
||||
if (dx_threshold <= dx || dy_threshold <= dy) {
|
||||
return true;
|
||||
ct->needs_render = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
#undef WD
|
||||
return false;
|
||||
// returning true here will cause the cells to be drawn
|
||||
return ct->needs_render || needs_render_prev;
|
||||
}
|
||||
|
||||
@@ -1147,15 +1147,15 @@ init_trail_program(void) {
|
||||
void
|
||||
draw_cursor_trail(CursorTrail *trail) {
|
||||
glEnable(GL_BLEND);
|
||||
// BLEND_PREMULT
|
||||
/*glBlendFuncSeparate(GL_ONE, GL_ONE_MINUS_SRC_ALPHA, GL_ZERO, GL_ONE);*/
|
||||
BLEND_ONTO_OPAQUE;
|
||||
|
||||
bind_program(TRAIL_PROGRAM);
|
||||
|
||||
glUniform4fv(trail_program_layout.uniforms.x_coords, 1, trail->corner_x);
|
||||
glUniform4fv(trail_program_layout.uniforms.y_coords, 1, trail->corner_y);
|
||||
|
||||
glUniform2fv(trail_program_layout.uniforms.cursor_edge_x, 1, trail->cursor_edge_x);
|
||||
glUniform2fv(trail_program_layout.uniforms.cursor_edge_y, 1, trail->cursor_edge_y);
|
||||
|
||||
// todo - get cursor color from opt
|
||||
float trail_color[4] = {1.0f, 1.0f, 1.0f, 1.0f};
|
||||
glUniform4fv(trail_program_layout.uniforms.trail_color, 1, trail_color);
|
||||
|
||||
@@ -214,8 +214,11 @@ typedef struct {
|
||||
|
||||
typedef struct {
|
||||
monotonic_t updated_at;
|
||||
bool needs_render;
|
||||
float corner_x[4];
|
||||
float corner_y[4];
|
||||
float cursor_edge_x[2];
|
||||
float cursor_edge_y[2];
|
||||
} CursorTrail;
|
||||
|
||||
typedef struct {
|
||||
|
||||
@@ -1,6 +1,14 @@
|
||||
uniform vec2 cursor_edge_x;
|
||||
uniform vec2 cursor_edge_y;
|
||||
uniform vec4 trail_color;
|
||||
out vec4 color;
|
||||
in vec2 frag_pos;
|
||||
out vec4 final_color;
|
||||
|
||||
void main() {
|
||||
color = trail_color;
|
||||
if (cursor_edge_x[0] <= frag_pos.x && frag_pos.x <= cursor_edge_x[1] &&
|
||||
cursor_edge_y[1] <= frag_pos.y && frag_pos.y <= cursor_edge_y[0]) {
|
||||
discard;
|
||||
} else {
|
||||
final_color = trail_color;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,9 @@
|
||||
uniform vec4 x_coords;
|
||||
uniform vec4 y_coords;
|
||||
|
||||
out vec2 frag_pos;
|
||||
|
||||
void main() {
|
||||
gl_Position = vec4(x_coords[gl_VertexID], y_coords[gl_VertexID], -1.0, 1.0);
|
||||
frag_pos = vec2(x_coords[gl_VertexID], y_coords[gl_VertexID]);
|
||||
gl_Position = vec4(x_coords[gl_VertexID], y_coords[gl_VertexID], 1.0, 1.0);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user