We return early from drawing functions if the surface to draw to is not
initialized properly. There is no immediate need to do so, at least no
crashes have been observed, but it mirrors the previous behavior a bit
more closely. Furthermore, i3 should not crash due to not being able to
make some rendering call, so this provides some stability.
relates to #1278
/* Forward declarations */
static void draw_util_set_source_color(xcb_connection_t *conn, surface_t *surface, color_t color);
/* Forward declarations */
static void draw_util_set_source_color(xcb_connection_t *conn, surface_t *surface, color_t color);
+#define RETURN_UNLESS_SURFACE_INITIALIZED(surface) \
+ do { \
+ if ((surface)->id == XCB_NONE) { \
+ ELOG("Surface %p is not initialized, skipping drawing.\n", surface); \
+ return; \
+ } \
+ } while (0)
+
/*
* Initialize the surface to represent the given drawable.
*
/*
* Initialize the surface to represent the given drawable.
*
*
*/
static void draw_util_set_source_color(xcb_connection_t *conn, surface_t *surface, color_t color) {
*
*/
static void draw_util_set_source_color(xcb_connection_t *conn, surface_t *surface, color_t color) {
+ RETURN_UNLESS_SURFACE_INITIALIZED(surface);
+
#ifdef CAIRO_SUPPORT
cairo_set_source_rgb(surface->cr, color.red, color.green, color.blue);
#else
#ifdef CAIRO_SUPPORT
cairo_set_source_rgb(surface->cr, color.red, color.green, color.blue);
#else
*
*/
void draw_util_text(i3String *text, surface_t *surface, color_t fg_color, color_t bg_color, int x, int y, int max_width) {
*
*/
void draw_util_text(i3String *text, surface_t *surface, color_t fg_color, color_t bg_color, int x, int y, int max_width) {
+ RETURN_UNLESS_SURFACE_INITIALIZED(surface);
+
#ifdef CAIRO_SUPPORT
/* Flush any changes before we draw the text as this might use XCB directly. */
CAIRO_SURFACE_FLUSH(surface->surface);
#ifdef CAIRO_SUPPORT
/* Flush any changes before we draw the text as this might use XCB directly. */
CAIRO_SURFACE_FLUSH(surface->surface);
*
*/
void draw_util_rectangle(xcb_connection_t *conn, surface_t *surface, color_t color, double x, double y, double w, double h) {
*
*/
void draw_util_rectangle(xcb_connection_t *conn, surface_t *surface, color_t color, double x, double y, double w, double h) {
+ RETURN_UNLESS_SURFACE_INITIALIZED(surface);
+
#ifdef CAIRO_SUPPORT
cairo_save(surface->cr);
#ifdef CAIRO_SUPPORT
cairo_save(surface->cr);
*
*/
void draw_util_clear_surface(xcb_connection_t *conn, surface_t *surface, color_t color) {
*
*/
void draw_util_clear_surface(xcb_connection_t *conn, surface_t *surface, color_t color) {
+ RETURN_UNLESS_SURFACE_INITIALIZED(surface);
+
#ifdef CAIRO_SUPPORT
cairo_save(surface->cr);
#ifdef CAIRO_SUPPORT
cairo_save(surface->cr);
*/
void draw_util_copy_surface(xcb_connection_t *conn, surface_t *src, surface_t *dest, double src_x, double src_y,
double dest_x, double dest_y, double width, double height) {
*/
void draw_util_copy_surface(xcb_connection_t *conn, surface_t *src, surface_t *dest, double src_x, double src_y,
double dest_x, double dest_y, double width, double height) {
+ RETURN_UNLESS_SURFACE_INITIALIZED(src);
+ RETURN_UNLESS_SURFACE_INITIALIZED(dest);
+
#ifdef CAIRO_SUPPORT
cairo_save(dest->cr);
#ifdef CAIRO_SUPPORT
cairo_save(dest->cr);
if (p->border_style != BS_NORMAL)
goto copy_pixmaps;
if (p->border_style != BS_NORMAL)
goto copy_pixmaps;
- /* If the parent hasn't been set up yet, skip the decoratin rendering
+ /* If the parent hasn't been set up yet, skip the decoration rendering
* for now. */
if (parent->frame_buffer.id == XCB_NONE)
goto copy_pixmaps;
* for now. */
if (parent->frame_buffer.id == XCB_NONE)
goto copy_pixmaps;