Skip to content

Commit

Permalink
Improve error handling when creating cairo image surfaces
Browse files Browse the repository at this point in the history
Stop showing the perpetual and harmless cairo introspection error

Should give us more info for errors like #241, and default to drawing a
black background on the content drawing area
  • Loading branch information
Cimbali committed Mar 9, 2023
1 parent 5806049 commit 401a655
Show file tree
Hide file tree
Showing 3 changed files with 36 additions and 5 deletions.
18 changes: 15 additions & 3 deletions pympress/scribble.py
Original file line number Diff line number Diff line change
Expand Up @@ -404,14 +404,26 @@ def reset_scribble_cache(self):
window = self.c_da.get_window()

if window is None:
return ValueError('Cannot initialize scribble acche without drawing area window')
return ValueError('Cannot initialize scribble cache without drawing area window')

scale = window.get_scale_factor()
ww, wh = self.c_da.get_allocated_width() * scale, self.c_da.get_allocated_height() * scale
try:
self.scribble_cache = window.create_similar_image_surface(cairo.Format.ARGB32, ww, wh, scale)
except ValueError:
logger.exception('Error creating highlight cache')
except ValueError as e:
if e.args == ('invalid enum value: 5',):
# Just try again as this error seems to always happen at the first call but not later on
# This is the gi introspection of cairo not accepting the value Format.RGB30 (???)
try:
self.scribble_cache = window.create_similar_image_surface(cairo.Format.ARGB32, ww, wh, scale)
except ValueError:
return
else:
logger.exception('Error creating highlight cache')
except cairo.Error:
logger.warning('Failed creating an ARGB32 surface sized {}x{} scale {} for highlight cache'
.format(ww, wh, scale), exc_info=True)
return
self.next_render = 0


Expand Down
10 changes: 9 additions & 1 deletion pympress/surfacecache.py
Original file line number Diff line number Diff line change
Expand Up @@ -254,7 +254,13 @@ def _create_surface(self, widget, fmt, width, height):
"""
window = widget.get_window()
scale = window.get_scale_factor()
return window.create_similar_image_surface(fmt, width * scale, height * scale, scale)
try:
return window.create_similar_image_surface(fmt, width * scale, height * scale, scale)
except cairo.Error:
logger.warning('Failed creating a {} cache surface sized {}x{} scale {} for widget {}'
.format(fmt, width * scale, height * scale, scale, widget.get_name()), exc_info=True)
# Warn here but handle error at the call site
raise


def prerender(self, page_nb):
Expand Down Expand Up @@ -306,6 +312,8 @@ def renderer(self, widget_name, page_nb):
except AttributeError:
logger.warning('Widget {} was not mapped when rendering'.format(widget_name), exc_info = True)
return GLib.SOURCE_REMOVE
except cairo.Error:
return GLib.SOURCE_REMOVE

context = cairo.Context(surface)
page.render_cairo(context, ww, wh, wtype)
Expand Down
13 changes: 12 additions & 1 deletion pympress/ui.py
Original file line number Diff line number Diff line change
Expand Up @@ -1288,7 +1288,18 @@ def on_draw(self, widget, cairo_context):
return

# Cache miss: render the page, and save it to the cache
pb = window.create_similar_image_surface(cairo.Format.RGB24, ww * scale, wh * scale, scale)
try:
pb = window.create_similar_image_surface(cairo.Format.RGB24, ww * scale, wh * scale, scale)
except cairo.Error:
logger.warning('Failed creating an RGB24 surface sized {}x{} scale {} for widget {}'
.format(ww * scale, wh * scale, scale, name), exc_info=True)
if widget is self.c_da:
cairo_context.save()
cairo_context.set_source_rgb(0, 0, 0)
cairo_context.fill()
cairo_context.paint()
cairo_context.restore()
return

cairo_prerender = cairo.Context(pb)
cairo_prerender.transform(zoom_matrix)
Expand Down

0 comments on commit 401a655

Please sign in to comment.