Refactor window positioning and surface rendering into x.c

Move the double-buffering implementation and the x_win_call move into
x.c so we only need to call x_display_surface for each draw.

This isolates all uses of the cairo context and root surface outside of
x.c which will help to add support for other display servers.
This commit is contained in:
Nikos Tsipinakis 2018-05-06 19:55:13 +03:00
parent 72aab3daf4
commit c29b1a39fb
3 changed files with 24 additions and 27 deletions

View File

@ -1,9 +1,7 @@
#include "draw.h" #include "draw.h"
#include <X11/Xutil.h> // Temporary
#include <assert.h> #include <assert.h>
#include <cairo.h> #include <cairo.h>
#include <cairo-xlib.h> // Temporary
#include <math.h> #include <math.h>
#include <pango/pango-attributes.h> #include <pango/pango-attributes.h>
#include <pango/pango-font.h> #include <pango/pango-font.h>
@ -556,15 +554,8 @@ void draw(void)
GSList *layouts = create_layouts(win->c_ctx); GSList *layouts = create_layouts(win->c_ctx);
struct dimensions dim = calculate_dimensions(layouts); struct dimensions dim = calculate_dimensions(layouts);
int width = dim.w;
int height = dim.h;
int win_x, win_y;
cairo_surface_t *image_surface = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, width, height); cairo_surface_t *image_surface = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, dim.w, dim.h);
calc_window_pos(dim.w, dim.h, &win_x, &win_y);
x_win_move(win_x, win_y, width, height);
cairo_xlib_surface_set_size(win->root_surface, width, height);
bool first = true; bool first = true;
for (GSList *iter = layouts; iter; iter = iter->next) { for (GSList *iter = layouts; iter; iter = iter->next) {
@ -576,11 +567,8 @@ void draw(void)
first = false; first = false;
} }
cairo_set_source_surface(win->c_ctx, image_surface, 0, 0); calc_window_pos(dim.w, dim.h, &dim.x, &dim.y);
cairo_paint(win->c_ctx); x_display_surface(image_surface, win, &dim);
cairo_show_page(win->c_ctx);
XFlush(xctx.dpy);
cairo_surface_destroy(image_surface); cairo_surface_destroy(image_surface);
free_layouts(layouts); free_layouts(layouts);

View File

@ -44,28 +44,37 @@ static int x_shortcut_tear_down_error_handler(void);
static void setopacity(Window win, unsigned long opacity); static void setopacity(Window win, unsigned long opacity);
static void x_handle_click(XEvent ev); static void x_handle_click(XEvent ev);
void x_win_move(int x, int y, int width, int height) static void x_win_move(window_x11 *win, int x, int y, int width, int height)
{ {
// Previous dimensions of the window to avoid calling X11 if no change
// is needed
static struct dimensions window_dim = { 0 };
/* move and resize */ /* move and resize */
if (x != window_dim.x || y != window_dim.y) { if (x != win->dim.x || y != win->dim.y) {
XMoveWindow(xctx.dpy, win->xwin, x, y); XMoveWindow(xctx.dpy, win->xwin, x, y);
window_dim.x = x; win->dim.x = x;
window_dim.y = y; win->dim.y = y;
} }
if (width != window_dim.w || height != window_dim.h) { if (width != win->dim.w || height != win->dim.h) {
XResizeWindow(xctx.dpy, win->xwin, width, height); XResizeWindow(xctx.dpy, win->xwin, width, height);
window_dim.h = height; win->dim.h = height;
window_dim.w = width; win->dim.w = width;
} }
} }
void x_display_surface(cairo_surface_t *srf, window_x11 *win, const struct dimensions *dim)
{
x_win_move(win, dim->x, dim->y, dim->w, dim->h);
cairo_xlib_surface_set_size(win->root_surface, dim->w, dim->h);
cairo_set_source_surface(win->c_ctx, srf, 0, 0);
cairo_paint(win->c_ctx);
cairo_show_page(win->c_ctx);
XFlush(xctx.dpy);
}
static void setopacity(Window win, unsigned long opacity) static void setopacity(Window win, unsigned long opacity)
{ {
Atom _NET_WM_WINDOW_OPACITY = Atom _NET_WM_WINDOW_OPACITY =

View File

@ -58,10 +58,10 @@ extern xctx_t xctx;
/* window */ /* window */
window_x11 *x_win_create(void); window_x11 *x_win_create(void);
void x_win_move(int x, int y, int width, int height);
void x_win_hide(void); void x_win_hide(void);
void x_win_show(void); void x_win_show(void);
void x_win_destroy(window_x11 *win); void x_win_destroy(window_x11 *win);
void x_display_surface(cairo_surface_t *srf, window_x11 *win, const struct dimensions *dim);
/* shortcut */ /* shortcut */
void x_shortcut_init(keyboard_shortcut *shortcut); void x_shortcut_init(keyboard_shortcut *shortcut);