talons

Fork of Claws Mail https://www.claws-mail
Log | Files | Refs | README | LICENSE

commit c35aa5ff6bb8d6e4d724c6ced84d5ed1eedbbc5b
parent fb4106737755b4f8f1090832b451885b13e26fba
Author: Jonathan Boeing <jonathan.n.boeing@gmail.com>
Date:   Sat, 24 Jul 2021 22:53:32 -0700

Queue redraw after downloading image

Calling redraw directly from the g_task callback can corrupt the display
if other drawing is already in progress.  For example, scrolling the email
while it's still loading draws the message outside where the viewport should
be.  Instead, queue up a draw signal to the DrawingArea.

Diffstat:
Msrc/plugins/litehtml_viewer/container_linux.h | 2+-
Msrc/plugins/litehtml_viewer/container_linux_images.cpp | 2+-
Msrc/plugins/litehtml_viewer/lh_widget.cpp | 14+++++++++++---
Msrc/plugins/litehtml_viewer/lh_widget.h | 5++++-
4 files changed, 17 insertions(+), 6 deletions(-)

diff --git a/src/plugins/litehtml_viewer/container_linux.h b/src/plugins/litehtml_viewer/container_linux.h @@ -95,7 +95,7 @@ public: gint clear_images(gint desired_size); void add_image_to_cache(const gchar *url, GdkPixbuf *image); - virtual void redraw(gboolean force_render) = 0; + virtual void rerender() = 0; virtual GdkPixbuf *get_local_image(const litehtml::tstring url) const = 0; protected: diff --git a/src/plugins/litehtml_viewer/container_linux_images.cpp b/src/plugins/litehtml_viewer/container_linux_images.cpp @@ -82,7 +82,7 @@ static void get_image_callback(GObject *source, GAsyncResult *res, gpointer user if (pixbuf != NULL) { ctx->container->add_image_to_cache(ctx->url, pixbuf); - ctx->container->redraw(TRUE); + ctx->container->rerender(); } g_free(ctx->url); diff --git a/src/plugins/litehtml_viewer/lh_widget.cpp b/src/plugins/litehtml_viewer/lh_widget.cpp @@ -60,6 +60,8 @@ lh_widget::lh_widget() { GtkWidget *item; + m_force_render = false; + /* scrolled window */ m_scrolled_window = gtk_scrolled_window_new(NULL, NULL); gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(m_scrolled_window), @@ -197,6 +199,12 @@ void lh_widget::open_html(const gchar *contents) lh_widget_statusbar_pop(); } +void lh_widget::rerender() +{ + m_force_render = true; + gtk_widget_queue_draw(m_drawing_area); +} + void lh_widget::draw(cairo_t *cr) { double x1, x2, y1, y2; @@ -219,7 +227,7 @@ void lh_widget::draw(cairo_t *cr) m_html->draw((litehtml::uint_ptr)cr, 0, 0, &pos); } -void lh_widget::redraw(gboolean force_render) +void lh_widget::redraw() { GtkAllocation rect; gint width; @@ -237,7 +245,7 @@ void lh_widget::redraw(gboolean force_render) m_height = rect.height; /* If the available width has changed, rerender the HTML content. */ - if (m_rendered_width != width || force_render) { + if (m_rendered_width != width || std::atomic_exchange(&m_force_render, false)) { debug_print("lh_widget::redraw: width changed: %d != %d\n", m_rendered_width, width); @@ -502,7 +510,7 @@ static gboolean draw_cb(GtkWidget *widget, cairo_t *cr, { lh_widget *w = (lh_widget *)user_data; w->set_cairo_context(cr); - w->redraw(FALSE); + w->redraw(); w->set_cairo_context(NULL); return FALSE; } diff --git a/src/plugins/litehtml_viewer/lh_widget.h b/src/plugins/litehtml_viewer/lh_widget.h @@ -18,6 +18,7 @@ #include <gtk/gtk.h> #include <glib.h> #include <gio/gio.h> +#include <atomic> #include "procmime.h" @@ -54,7 +55,8 @@ class lh_widget : public container_linux void draw_text(litehtml::uint_ptr hdc, const litehtml::tchar_t* text, litehtml::uint_ptr hFont, litehtml::web_color color, const litehtml::position& pos); void draw(cairo_t *cr); - void redraw(gboolean force_render); + void rerender(); + void redraw(); void open_html(const gchar *contents); void clear(); void update_cursor(const litehtml::tchar_t* cursor); @@ -92,4 +94,5 @@ class lh_widget : public container_linux litehtml::tchar_t *m_font_name; int m_font_size; + std::atomic<bool> m_force_render; };