diff --git a/kitty/child-monitor.c b/kitty/child-monitor.c index 3113ba52e..bde96ccad 100644 --- a/kitty/child-monitor.c +++ b/kitty/child-monitor.c @@ -705,63 +705,6 @@ change_menubar_title(PyObject *title UNUSED) { #endif } -inline static float -norm(float x, float y) { - return sqrtf(x * x + y * y); -} - -static bool -update_cursor_trail(CursorTrail *ct, Window *w, monotonic_t now) { -#define WD w->render_data - // 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}}; - float cursor_edge_x[2], cursor_edge_y[2]; - cursor_edge_x[0] = WD.xstart + WD.screen->cursor_render_info.x * WD.dx; - cursor_edge_x[1] = cursor_edge_x[0] + WD.dx; - cursor_edge_y[0] = WD.ystart - WD.screen->cursor_render_info.y * WD.dy; - cursor_edge_y[1] = cursor_edge_y[0] - WD.dy; - - // 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; - - 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 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 dist = norm(dx, dy); - if (dist == 0) { - continue; - } - float dot = (dx * (cursor_edge_x[ci[i][0]] - cursor_center_x) + - dy * (cursor_edge_y[ci[i][1]] - cursor_center_y)) / - cursor_diag_2 / dist; - - float decay_seconds = decay_slow + (decay_fast - decay_slow) * (1.0f + dot) * 0.5f; - float step = 1.0f - 1.0f / exp2f(10.0f * dt / decay_seconds); - - ct->corner_x[i] += dx * step; - ct->corner_y[i] += dy * step; - } - } - ct->updated_at = now; - 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]; - if (dx * dx + dy * dy >= 1e-6) { - return true; - } - } - return false; -} - static bool prepare_to_render_os_window(OSWindow *os_window, monotonic_t now, unsigned int *active_window_id, color_type *active_window_bg, unsigned int *num_visible_windows, bool *all_windows_have_same_bg, bool scan_for_animated_images) { #define TD os_window->tab_bar_render_data @@ -785,6 +728,7 @@ prepare_to_render_os_window(OSWindow *os_window, monotonic_t now, unsigned int * color_type first_window_bg = 0; for (unsigned int i = 0; i < tab->num_windows; i++) { Window *w = tab->windows + i; +#define WD w->render_data if (w->visible && WD.screen) { screen_check_pause_rendering(WD.screen, now); *num_visible_windows += 1; @@ -865,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_trail(&tab->cursor_trail); + if (true) 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; diff --git a/kitty/cursor_trail.c b/kitty/cursor_trail.c new file mode 100644 index 000000000..97d1587e5 --- /dev/null +++ b/kitty/cursor_trail.c @@ -0,0 +1,58 @@ +#include "state.h" + +inline static float +norm(float x, float y) { + return sqrtf(x * x + y * y); +} + +bool +update_cursor_trail(CursorTrail *ct, Window *w, monotonic_t now) { +#define WD w->render_data + // 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}}; + float cursor_edge_x[2], cursor_edge_y[2]; + cursor_edge_x[0] = WD.xstart + WD.screen->cursor_render_info.x * WD.dx; + cursor_edge_x[1] = cursor_edge_x[0] + WD.dx; + cursor_edge_y[0] = WD.ystart - WD.screen->cursor_render_info.y * WD.dy; + cursor_edge_y[1] = cursor_edge_y[0] - WD.dy; + + // 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; + + 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 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 dist = norm(dx, dy); + if (dist == 0) { + continue; + } + float dot = (dx * (cursor_edge_x[ci[i][0]] - cursor_center_x) + + dy * (cursor_edge_y[ci[i][1]] - cursor_center_y)) / + cursor_diag_2 / dist; + + float decay_seconds = decay_slow + (decay_fast - decay_slow) * (1.0f + dot) * 0.5f; + float step = 1.0f - 1.0f / exp2f(10.0f * dt / decay_seconds); + + ct->corner_x[i] += dx * step; + ct->corner_y[i] += dy * step; + } + } + ct->updated_at = now; + 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]; + if (dx * dx + dy * dy >= 1e-6) { + return true; + } + } + return false; +} diff --git a/kitty/shaders.c b/kitty/shaders.c index 25fb2f20d..3af977352 100644 --- a/kitty/shaders.c +++ b/kitty/shaders.c @@ -1145,7 +1145,7 @@ init_trail_program(void) { } void -draw_trail(CursorTrail *trail) { +draw_cursor_trail(CursorTrail *trail) { glEnable(GL_BLEND); // BLEND_PREMULT /*glBlendFuncSeparate(GL_ONE, GL_ONE_MINUS_SRC_ALPHA, GL_ZERO, GL_ONE);*/ diff --git a/kitty/state.h b/kitty/state.h index 02afa7d40..0f46dfa1e 100644 --- a/kitty/state.h +++ b/kitty/state.h @@ -359,7 +359,8 @@ ssize_t create_border_vao(void); bool send_cell_data_to_gpu(ssize_t, float, float, float, float, Screen *, OSWindow *); void draw_cells(ssize_t, const WindowRenderData*, OSWindow *, bool, bool, bool, Window*); void draw_centered_alpha_mask(OSWindow *w, size_t screen_width, size_t screen_height, size_t width, size_t height, uint8_t *canvas, float); -void draw_trail(CursorTrail *trail); +void draw_cursor_trail(CursorTrail *trail); +bool update_cursor_trail(CursorTrail *ct, Window *w, monotonic_t now); void update_surface_size(int, int, uint32_t); void free_texture(uint32_t*); void free_framebuffer(uint32_t*);