diff --git a/kitty/child-monitor.c b/kitty/child-monitor.c index b2dc780ce..6b75efd3c 100644 --- a/kitty/child-monitor.c +++ b/kitty/child-monitor.c @@ -545,7 +545,7 @@ change_menubar_title(PyObject *title UNUSED) { } static inline 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) { +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 bool needs_render = os_window->needs_render; os_window->needs_render = false; @@ -590,6 +590,14 @@ prepare_to_render_os_window(OSWindow *os_window, monotonic_t now, unsigned int * set_os_window_title_from_window(w, os_window); *active_window_bg = window_bg; } else WD.screen->cursor_render_info.is_visible = false; + if (scan_for_animated_images) { + monotonic_t min_gap; + if (scan_active_animations(WD.screen->grman, now, &min_gap, true)) needs_render = true; + if (min_gap < MONOTONIC_T_MAX) { + global_state.has_active_animated_images = true; + set_maximum_wait(min_gap); + } + } if (send_cell_data_to_gpu(WD.vao_idx, WD.gvao_idx, WD.xstart, WD.ystart, WD.dx, WD.dy, WD.screen, os_window)) needs_render = true; if (WD.screen->start_visual_bell_at != 0) needs_render = true; } @@ -662,7 +670,7 @@ no_render_frame_received_recently(OSWindow *w, monotonic_t now, monotonic_t max_ static inline void render(monotonic_t now, bool input_read) { - EVDBG("input_read: %d", input_read); + EVDBG("input_read: %d, has_active_animated_images: %d", input_read, global_state.has_active_animated_images); static monotonic_t last_render_at = MONOTONIC_T_MIN; monotonic_t time_since_last_render = last_render_at == MONOTONIC_T_MIN ? OPT(repaint_delay) : now - last_render_at; if (!input_read && time_since_last_render < OPT(repaint_delay)) { @@ -670,6 +678,9 @@ render(monotonic_t now, bool input_read) { return; } + const bool scan_for_animated_images = global_state.has_active_animated_images; + global_state.has_active_animated_images = false; + for (size_t i = 0; i < global_state.num_os_windows; i++) { OSWindow *w = global_state.os_windows + i; w->render_calls++; @@ -703,7 +714,7 @@ render(monotonic_t now, bool input_read) { bool all_windows_have_same_bg; color_type active_window_bg = 0; if (!w->fonts_data) { log_error("No fonts data found for window id: %llu", w->id); continue; } - if (prepare_to_render_os_window(w, now, &active_window_id, &active_window_bg, &num_visible_windows, &all_windows_have_same_bg)) needs_render = true; + if (prepare_to_render_os_window(w, now, &active_window_id, &active_window_bg, &num_visible_windows, &all_windows_have_same_bg, scan_for_animated_images)) needs_render = true; if (w->last_active_window_id != active_window_id || w->last_active_tab != w->active_tab || w->focused_at_last_render != w->is_focused) needs_render = true; if (w->render_calls < 3 && w->bgimage && w->bgimage->texture_id) needs_render = true; if (needs_render) render_os_window(w, now, active_window_id, active_window_bg, num_visible_windows, all_windows_have_same_bg); diff --git a/kitty/graphics.c b/kitty/graphics.c index 067115e56..73d5d6fc9 100644 --- a/kitty/graphics.c +++ b/kitty/graphics.c @@ -768,7 +768,7 @@ grman_update_layers(GraphicsManager *self, unsigned int scrolled_by, float scree } if (img->is_drawn && !was_drawn && img->animation_enabled && img->extra_framecnt) { self->has_images_needing_animation = true; - // TODO: rescan animation timeouts + global_state.has_active_animated_images = true; } } if (!self->count) return false; @@ -1004,17 +1004,18 @@ handle_animation_control_command(GraphicsManager *self, bool *is_dirty, const Gr if (img->animation_enabled) { self->has_images_needing_animation = true; if (!was_enabled) img->current_frame_shown_at = monotonic(); - // TODO: schedule animation rescan + global_state.has_active_animated_images = true; } } } bool -scan_active_animations(GraphicsManager *self, const monotonic_t now, monotonic_t *minimum_gap) { +scan_active_animations(GraphicsManager *self, const monotonic_t now, monotonic_t *minimum_gap, bool os_window_context_set) { bool dirtied = false; *minimum_gap = MONOTONIC_T_MAX; if (!self->has_images_needing_animation) return dirtied; - self->has_images_needing_animation = false; + self->has_images_needing_animation = os_window_context_set; + self->context_made_current_for_this_command = true; for (size_t i = self->image_count; i-- > 0;) { Image *img = self->images + i; if (img->animation_enabled && img->extra_framecnt && img->is_drawn) { diff --git a/kitty/graphics.h b/kitty/graphics.h index 5932a9f22..099b3b7ee 100644 --- a/kitty/graphics.h +++ b/kitty/graphics.h @@ -118,4 +118,4 @@ void grman_resize(GraphicsManager*, index_type, index_type, index_type, index_ty void grman_rescale(GraphicsManager *self, CellPixelSize fg); void gpu_data_for_centered_image(ImageRenderData *ans, unsigned int screen_width_px, unsigned int screen_height_px, unsigned int width, unsigned int height); bool png_path_to_bitmap(const char *path, uint8_t** data, unsigned int* width, unsigned int* height, size_t* sz); -bool scan_active_animations(GraphicsManager *self, const monotonic_t now, monotonic_t *minimum_gap); +bool scan_active_animations(GraphicsManager *self, const monotonic_t now, monotonic_t *minimum_gap, bool os_window_context_set); diff --git a/kitty/state.h b/kitty/state.h index 1f03a6b8a..dabbb1453 100644 --- a/kitty/state.h +++ b/kitty/state.h @@ -205,6 +205,7 @@ typedef struct { bool has_pending_resizes, has_pending_closes; bool in_sequence_mode; bool tab_bar_hidden; + bool has_active_animated_images; double font_sz_in_pts; struct { double x, y; } default_dpi; id_type active_drag_in_window;