Queue redraw after downloading image
authorJonathan Boeing <jonathan.n.boeing@gmail.com>
Sun, 25 Jul 2021 05:53:32 +0000 (22:53 -0700)
committerJonathan Boeing <jonathan.n.boeing@gmail.com>
Mon, 26 Jul 2021 22:42:49 +0000 (15:42 -0700)
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.

src/plugins/litehtml_viewer/container_linux.h
src/plugins/litehtml_viewer/container_linux_images.cpp
src/plugins/litehtml_viewer/lh_widget.cpp
src/plugins/litehtml_viewer/lh_widget.h

index f35ffeab1d36b175d8f892ee4078f540b0126513..f842025aeeed018bebfd0181edc477adb0720871 100644 (file)
@@ -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:
index 6cda9d7d26a8aa8e3a3ac9fce48ca79d95d6c042..a0d6aedb131e7d887ab936b0565e19951ada9551 100644 (file)
@@ -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);
index 81f075c3d82f65cf9aa7c205af31ae05379196cb..d49e6147cbb283d6ab591944d62420f029486f74 100644 (file)
@@ -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),
@@ -199,6 +201,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;
@@ -221,7 +229,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);
 
@@ -474,7 +482,7 @@ static gboolean expose_event_cb(GtkWidget *widget, GdkEvent *event,
                gpointer user_data)
 {
        lh_widget *w = (lh_widget *)user_data;
-       w->redraw(FALSE);
+       w->redraw();
        return FALSE;
 }
 
index 9b95ef83beb6c80d842ba961c2df276e5f19ddd0..ff45efa0320746b6500f9222d5198606f361f056 100644 (file)
@@ -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);
@@ -89,4 +91,5 @@ class lh_widget : public container_linux
 
                litehtml::tchar_t *m_font_name;
                int m_font_size;
+               std::atomic<bool> m_force_render;
 };