Migrate i3 rendering to cairo.

This patch migrates all decoration rendering of i3 to cairo. Using the
compile switch CAIRO_SUPPORT, rendering can be switched back to the
previous XCB behavior, just like with the previous migration to cairo
in i3bar.

This patch also fixes a bug in draw_util.c where copying one surface
to another would use incorrect coordinates if the source coordinates
are not 0, 0.

Furthermore, this patch implicitly fixes some minor issues in the
decoration rendering which would be ignored previously due to the fact
that errors would only show up in the event queue, but not cause the
rendering code path to crash. One example is zero-height pixmaps which
are not allowed. Using cairo, these would cause i3 to instantly segfault,
so this patch avoids this.

Lastly, this patch annotates other issues found but not fixed in this patch
using TODO comments, e.g., the zero-height check not working correctly
and the comment that it should probably work the same way for zero-width
pixmaps.

relates to #1278
This commit is contained in:
Ingo Bürk
2015-11-16 21:26:06 +01:00
parent d9bbfb7b35
commit b665049883
11 changed files with 276 additions and 207 deletions

View File

@ -174,7 +174,7 @@ static void draw_separator(i3_output *output, uint32_t x, struct status_block *b
uint32_t center_x = x - sep_offset;
if (config.separator_symbol == NULL) {
/* Draw a classic one pixel, vertical separator. */
draw_util_rectangle(&output->statusline_buffer, sep_fg,
draw_util_rectangle(xcb_connection, &output->statusline_buffer, sep_fg,
center_x,
logical_px(sep_voff_px),
logical_px(1),
@ -243,7 +243,7 @@ void draw_statusline(i3_output *output, uint32_t clip_left, bool use_focus_color
struct status_block *block;
color_t bar_color = (use_focus_colors ? colors.focus_bar_bg : colors.bar_bg);
draw_util_clear_surface(&output->statusline_buffer, bar_color);
draw_util_clear_surface(xcb_connection, &output->statusline_buffer, bar_color);
/* Use unsigned integer wraparound to clip off the left side.
* For example, if clip_left is 75, then x will start at the very large
@ -294,13 +294,13 @@ void draw_statusline(i3_output *output, uint32_t clip_left, bool use_focus_color
}
/* Draw the border. */
draw_util_rectangle(&output->statusline_buffer, border_color,
draw_util_rectangle(xcb_connection, &output->statusline_buffer, border_color,
x, logical_px(1),
full_render_width,
bar_height - logical_px(2));
/* Draw the background. */
draw_util_rectangle(&output->statusline_buffer, bg_color,
draw_util_rectangle(xcb_connection, &output->statusline_buffer, bg_color,
x + border_width,
logical_px(1) + border_width,
full_render_width - 2 * border_width,
@ -1709,9 +1709,9 @@ void reconfig_windows(bool redraw_bars) {
1,
(unsigned char *)&atoms[_NET_WM_WINDOW_TYPE_DOCK]);
draw_util_surface_init(&walk->bar, bar_id, walk->rect.w, bar_height);
draw_util_surface_init(&walk->buffer, buffer_id, walk->rect.w, bar_height);
draw_util_surface_init(&walk->statusline_buffer, statusline_buffer_id, walk->rect.w, bar_height);
draw_util_surface_init(xcb_connection, &walk->bar, bar_id, NULL, walk->rect.w, bar_height);
draw_util_surface_init(xcb_connection, &walk->buffer, buffer_id, NULL, walk->rect.w, bar_height);
draw_util_surface_init(xcb_connection, &walk->statusline_buffer, statusline_buffer_id, NULL, walk->rect.w, bar_height);
xcb_void_cookie_t strut_cookie = config_strut_partial(walk);
@ -1820,12 +1820,12 @@ void reconfig_windows(bool redraw_bars) {
walk->rect.w,
bar_height);
draw_util_surface_free(&(walk->bar));
draw_util_surface_free(&(walk->buffer));
draw_util_surface_free(&(walk->statusline_buffer));
draw_util_surface_init(&(walk->bar), walk->bar.id, walk->rect.w, bar_height);
draw_util_surface_init(&(walk->buffer), walk->buffer.id, walk->rect.w, bar_height);
draw_util_surface_init(&(walk->statusline_buffer), walk->statusline_buffer.id, walk->rect.w, bar_height);
draw_util_surface_free(xcb_connection, &(walk->bar));
draw_util_surface_free(xcb_connection, &(walk->buffer));
draw_util_surface_free(xcb_connection, &(walk->statusline_buffer));
draw_util_surface_init(xcb_connection, &(walk->bar), walk->bar.id, NULL, walk->rect.w, bar_height);
draw_util_surface_init(xcb_connection, &(walk->buffer), walk->buffer.id, NULL, walk->rect.w, bar_height);
draw_util_surface_init(xcb_connection, &(walk->statusline_buffer), walk->statusline_buffer.id, NULL, walk->rect.w, bar_height);
xcb_void_cookie_t map_cookie, umap_cookie;
if (redraw_bars) {
@ -1886,7 +1886,7 @@ void draw_bars(bool unhide) {
bool use_focus_colors = output_has_focus(outputs_walk);
/* First things first: clear the backbuffer */
draw_util_clear_surface(&(outputs_walk->buffer),
draw_util_clear_surface(xcb_connection, &(outputs_walk->buffer),
(use_focus_colors ? colors.focus_bar_bg : colors.bar_bg));
if (!config.disable_ws) {
@ -1917,14 +1917,14 @@ void draw_bars(bool unhide) {
}
/* Draw the border of the button. */
draw_util_rectangle(&(outputs_walk->buffer), border_color,
draw_util_rectangle(xcb_connection, &(outputs_walk->buffer), border_color,
workspace_width,
logical_px(1),
ws_walk->name_width + 2 * logical_px(ws_hoff_px) + 2 * logical_px(1),
font.height + 2 * logical_px(ws_voff_px) - 2 * logical_px(1));
/* Draw the inside of the button. */
draw_util_rectangle(&(outputs_walk->buffer), bg_color,
draw_util_rectangle(xcb_connection, &(outputs_walk->buffer), bg_color,
workspace_width + logical_px(1),
2 * logical_px(1),
ws_walk->name_width + 2 * logical_px(ws_hoff_px),
@ -1947,13 +1947,13 @@ void draw_bars(bool unhide) {
color_t fg_color = colors.binding_mode_fg;
color_t bg_color = colors.binding_mode_bg;
draw_util_rectangle(&(outputs_walk->buffer), colors.binding_mode_border,
draw_util_rectangle(xcb_connection, &(outputs_walk->buffer), colors.binding_mode_border,
workspace_width,
logical_px(1),
binding.width + 2 * logical_px(ws_hoff_px) + 2 * logical_px(1),
font.height + 2 * logical_px(ws_voff_px) - 2 * logical_px(1));
draw_util_rectangle(&(outputs_walk->buffer), bg_color,
draw_util_rectangle(xcb_connection, &(outputs_walk->buffer), bg_color,
workspace_width + logical_px(1),
2 * logical_px(1),
binding.width + 2 * logical_px(ws_hoff_px),
@ -1989,7 +1989,7 @@ void draw_bars(bool unhide) {
int x_dest = outputs_walk->rect.w - tray_width - logical_px(sb_hoff_px) - visible_statusline_width;
draw_statusline(outputs_walk, clip_left, use_focus_colors, use_short_text);
draw_util_copy_surface(&outputs_walk->statusline_buffer, &outputs_walk->buffer, 0, 0,
draw_util_copy_surface(xcb_connection, &outputs_walk->statusline_buffer, &outputs_walk->buffer, 0, 0,
x_dest, 0, visible_statusline_width, (int16_t)bar_height);
outputs_walk->statusline_width = statusline_width;
@ -2020,7 +2020,7 @@ void redraw_bars(void) {
continue;
}
draw_util_copy_surface(&(outputs_walk->buffer), &(outputs_walk->bar), 0, 0,
draw_util_copy_surface(xcb_connection, &(outputs_walk->buffer), &(outputs_walk->bar), 0, 0,
0, 0, outputs_walk->rect.w, outputs_walk->rect.h);
xcb_flush(xcb_connection);
}