talons

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

commit 0b14aad2d4be65b524f13e87380d7c92916d42dd
parent 3c7b518b7b9e265a96a8bd437a8f3bddb6623dbc
Author: Andrej Kacian <ticho@claws-mail.org>
Date:   Sun,  5 May 2019 13:48:09 +0200

Make litehtml plugin rendering work better with GTK3 widget redraw

Unlike GTK2's "expose-event", GTK3's "draw" signal provides the
handler function with an already prepared cairo context to draw
on. This fixes flickering when scrolling HTML messages.

Unfortunately, litehtml's redraw() doesn't allow us to pass
custom arguments, so we have to store a pointer to the cairo
context as a member variable of our document container, so that
redraw() can access it.

Diffstat:
Msrc/plugins/litehtml_viewer/lh_widget.cpp | 29+++++++++++++++++++++++------
Msrc/plugins/litehtml_viewer/lh_widget.h | 3+++
2 files changed, 26 insertions(+), 6 deletions(-)

diff --git a/src/plugins/litehtml_viewer/lh_widget.cpp b/src/plugins/litehtml_viewer/lh_widget.cpp @@ -108,6 +108,8 @@ lh_widget::lh_widget() m_showing_url = FALSE; + m_cairo_context = NULL; + gtk_widget_set_events(m_drawing_area, GDK_BUTTON_RELEASE_MASK | GDK_BUTTON_PRESS_MASK @@ -255,16 +257,23 @@ void lh_widget::redraw(gboolean force_render) m_html->width(), m_html->height()); } - gdkwin = gtk_widget_get_window(m_drawing_area); - if (gdkwin == NULL) { - g_warning("lh_widget::redraw: No GdkWindow to draw on!"); - return; + /* Use provided cairo context, if any. Otherwise create our own. */ + if (m_cairo_context != NULL) { + cr = m_cairo_context; + } else { + gdkwin = gtk_widget_get_window(m_drawing_area); + if (gdkwin == NULL) { + g_warning("lh_widget::redraw: No GdkWindow to draw on!"); + return; + } + cr = gdk_cairo_create(gdkwin); } - cr = gdk_cairo_create(gdkwin); draw(cr); - cairo_destroy(cr); + /* Only destroy the used cairo context if we created it earlier. */ + if (m_cairo_context == NULL) + cairo_destroy(cr); } void lh_widget::paint_white() @@ -479,12 +488,20 @@ GdkPixbuf *lh_widget::get_local_image(const litehtml::tstring url) const return NULL; } +void lh_widget::set_cairo_context(cairo_t *cr) +{ + m_cairo_context = cr; +} + + //////////////////////////////////////////////// static gboolean draw_cb(GtkWidget *widget, cairo_t *cr, gpointer user_data) { lh_widget *w = (lh_widget *)user_data; + w->set_cairo_context(cr); w->redraw(false); + 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 @@ -69,6 +69,8 @@ class lh_widget : public container_linux void set_partinfo(MimeInfo *partinfo); GdkPixbuf *get_local_image(const litehtml::tstring url) const; + void set_cairo_context(cairo_t *cr); + litehtml::document::ptr m_html; litehtml::tstring m_clicked_url; litehtml::tstring m_base_url; @@ -86,6 +88,7 @@ class lh_widget : public container_linux litehtml::element::ptr m_over_element; gboolean m_showing_url; MimeInfo *m_partinfo; + cairo_t *m_cairo_context; litehtml::tchar_t *m_font_name; int m_font_size;