commit 6472e759fd35f87a1cbf4f0fde9bd527c6bff164
parent 9305c08ace90a7f0cdb5e92f645ed047e2c939d1
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:
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),
@@ -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;
}
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);
@@ -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;
};