Merge branch 'cursor_trail' of https://github.com/jinhwanlazy/kitty
This commit is contained in:
commit
65f0571b2c
4 changed files with 58 additions and 34 deletions
|
|
@ -1,50 +1,59 @@
|
|||
#include "state.h"
|
||||
#include "float.h"
|
||||
|
||||
inline static float
|
||||
norm(float x, float y) {
|
||||
return sqrtf(x * x + y * y);
|
||||
}
|
||||
|
||||
inline static bool
|
||||
get_cursor_edge(float *left, float *right, float *top, float *bottom, Window *w) {
|
||||
static void
|
||||
update_cursor_trail_target(CursorTrail *ct, Window *w) {
|
||||
#define EDGE(axis, index) ct->cursor_edge_##axis[index]
|
||||
#define WD w->render_data
|
||||
*left = WD.xstart + WD.screen->cursor_render_info.x * WD.dx;
|
||||
*bottom = WD.ystart - (WD.screen->cursor_render_info.y + 1) * WD.dy;
|
||||
float left = FLT_MAX, right = FLT_MAX, top = FLT_MAX, bottom = FLT_MAX;
|
||||
switch (WD.screen->cursor_render_info.shape) {
|
||||
case CURSOR_BLOCK:
|
||||
case CURSOR_HOLLOW:
|
||||
*right = *left + WD.dx;
|
||||
*top = *bottom + WD.dy;
|
||||
return true;
|
||||
case CURSOR_BEAM:
|
||||
*right = *left + WD.dx / WD.screen->cell_size.width * OPT(cursor_beam_thickness);
|
||||
*top = *bottom + WD.dy;
|
||||
return true;
|
||||
case CURSOR_UNDERLINE:
|
||||
*right = *left + WD.dx;
|
||||
*top = *bottom + WD.dy / WD.screen->cell_size.height * OPT(cursor_underline_thickness);
|
||||
return true;
|
||||
left = WD.xstart + WD.screen->cursor_render_info.x * WD.dx;
|
||||
bottom = WD.ystart - (WD.screen->cursor_render_info.y + 1) * WD.dy;
|
||||
default:
|
||||
return false;
|
||||
break;
|
||||
}
|
||||
switch (WD.screen->cursor_render_info.shape) {
|
||||
case CURSOR_BLOCK:
|
||||
case CURSOR_HOLLOW:
|
||||
right = left + WD.dx;
|
||||
top = bottom + WD.dy;
|
||||
break;
|
||||
case CURSOR_BEAM:
|
||||
right = left + WD.dx / WD.screen->cell_size.width * OPT(cursor_beam_thickness);
|
||||
top = bottom + WD.dy;
|
||||
break;
|
||||
case CURSOR_UNDERLINE:
|
||||
right = left + WD.dx;
|
||||
top = bottom + WD.dy / WD.screen->cell_size.height * OPT(cursor_underline_thickness);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
if (left != FLT_MAX) {
|
||||
EDGE(x, 0) = left;
|
||||
EDGE(x, 1) = right;
|
||||
EDGE(y, 0) = top;
|
||||
EDGE(y, 1) = bottom;
|
||||
ct->screen = WD.screen;
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
update_cursor_trail(CursorTrail *ct, Window *w, monotonic_t now, OSWindow *os_window) {
|
||||
static bool
|
||||
update_cursor_trail_corners(CursorTrail *ct, Window *w, monotonic_t now, OSWindow *os_window) {
|
||||
// the trail corners move towards the cursor corner at a speed proportional to their distance from the cursor corner.
|
||||
// equivalent to exponential ease out animation.
|
||||
|
||||
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;
|
||||
|
||||
#define EDGE(axis, index) ct->cursor_edge_##axis[index]
|
||||
|
||||
if (!WD.screen->paused_rendering.expires_at && !get_cursor_edge(&EDGE(x, 0), &EDGE(x, 1), &EDGE(y, 0), &EDGE(y, 1), w)) {
|
||||
return needs_render_prev;
|
||||
}
|
||||
|
||||
// the decay time for the trail to reach 1/1024 of its distance from the cursor corner
|
||||
float decay_fast = OPT(cursor_trail_decay_fast);
|
||||
|
|
@ -55,7 +64,8 @@ update_cursor_trail(CursorTrail *ct, Window *w, monotonic_t now, OSWindow *os_wi
|
|||
ct->corner_x[i] = EDGE(x, ci[i][0]);
|
||||
ct->corner_y[i] = EDGE(y, ci[i][1]);
|
||||
}
|
||||
} else if (OPT(cursor_trail) < now - WD.screen->cursor->position_changed_by_client_at && ct->updated_at < now) {
|
||||
}
|
||||
else if (ct->updated_at < now) {
|
||||
float cursor_center_x = (EDGE(x, 0) + EDGE(x, 1)) * 0.5f;
|
||||
float cursor_center_y = (EDGE(y, 0) + EDGE(y, 1)) * 0.5f;
|
||||
float cursor_diag_2 = norm(EDGE(x, 1) - EDGE(x, 0), EDGE(y, 1) - EDGE(y, 0)) * 0.5f;
|
||||
|
|
@ -83,24 +93,34 @@ update_cursor_trail(CursorTrail *ct, Window *w, monotonic_t now, OSWindow *os_wi
|
|||
ct->corner_y[i] += dy * step;
|
||||
}
|
||||
}
|
||||
|
||||
ct->updated_at = now;
|
||||
for (int i = 0; i < 4; ++i) {
|
||||
float dx = fabsf(EDGE(x, ci[i][0]) - ct->corner_x[i]);
|
||||
float dy = fabsf(EDGE(y, ci[i][1]) - ct->corner_y[i]);
|
||||
if (dx_threshold <= dx || dy_threshold <= dy) {
|
||||
ct->needs_render = true;
|
||||
break;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
if (ct->needs_render) {
|
||||
ColorProfile *cp = WD.screen->color_profile;
|
||||
ct->color = colorprofile_to_color(cp, cp->overridden.cursor_color, cp->configured.cursor_color).rgb;
|
||||
bool
|
||||
update_cursor_trail(CursorTrail *ct, Window *w, monotonic_t now, OSWindow *os_window) {
|
||||
if (!WD.screen->paused_rendering.expires_at && OPT(cursor_trail) < now - WD.screen->cursor->position_changed_by_client_at) {
|
||||
update_cursor_trail_target(ct, w);
|
||||
}
|
||||
|
||||
bool needs_render_prev = ct->needs_render;
|
||||
ct->needs_render = false;
|
||||
|
||||
if (update_cursor_trail_corners(ct, w, now, os_window)) {
|
||||
ct->needs_render = true;
|
||||
}
|
||||
|
||||
#undef EDGE
|
||||
// returning true here will cause the cells to be drawn
|
||||
return ct->needs_render || needs_render_prev;
|
||||
}
|
||||
|
||||
#undef WD
|
||||
#undef EDGE
|
||||
|
|
|
|||
|
|
@ -97,6 +97,7 @@ typedef struct {
|
|||
struct {
|
||||
unsigned int cursor_x, cursor_y, scrolled_by;
|
||||
index_type lines, columns;
|
||||
color_type cursor_bg;
|
||||
} last_rendered;
|
||||
bool is_dirty, scroll_changed, reload_all_gpu_data;
|
||||
Cursor *cursor;
|
||||
|
|
|
|||
|
|
@ -385,6 +385,9 @@ cell_update_uniform_block(ssize_t vao_idx, Screen *screen, int uniform_buffer, c
|
|||
#undef COLOR
|
||||
rd->url_color = OPT(url_color); rd->url_style = OPT(url_style);
|
||||
|
||||
// store last rendered cursor color for trail rendering
|
||||
screen->last_rendered.cursor_bg = rd->cursor_bg;
|
||||
|
||||
unmap_vao_buffer(vao_idx, uniform_buffer); rd = NULL;
|
||||
}
|
||||
|
||||
|
|
@ -1154,7 +1157,7 @@ draw_cursor_trail(CursorTrail *trail) {
|
|||
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);
|
||||
|
||||
color_vec3(trail_program_layout.uniforms.trail_color, trail->color);
|
||||
color_vec3(trail_program_layout.uniforms.trail_color, trail->screen->last_rendered.cursor_bg);
|
||||
|
||||
glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
|
||||
|
||||
|
|
|
|||
|
|
@ -218,7 +218,7 @@ typedef struct {
|
|||
typedef struct {
|
||||
bool needs_render;
|
||||
monotonic_t updated_at;
|
||||
color_type color;
|
||||
Screen* screen;
|
||||
float corner_x[4];
|
||||
float corner_y[4];
|
||||
float cursor_edge_x[2];
|
||||
|
|
|
|||
Loading…
Reference in a new issue