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:
parent
72aab3daf4
commit
c29b1a39fb
18
src/draw.c
18
src/draw.c
@ -1,9 +1,7 @@
|
||||
#include "draw.h"
|
||||
|
||||
#include <X11/Xutil.h> // Temporary
|
||||
#include <assert.h>
|
||||
#include <cairo.h>
|
||||
#include <cairo-xlib.h> // Temporary
|
||||
#include <math.h>
|
||||
#include <pango/pango-attributes.h>
|
||||
#include <pango/pango-font.h>
|
||||
@ -556,15 +554,8 @@ void draw(void)
|
||||
GSList *layouts = create_layouts(win->c_ctx);
|
||||
|
||||
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);
|
||||
|
||||
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);
|
||||
cairo_surface_t *image_surface = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, dim.w, dim.h);
|
||||
|
||||
bool first = true;
|
||||
for (GSList *iter = layouts; iter; iter = iter->next) {
|
||||
@ -576,11 +567,8 @@ void draw(void)
|
||||
first = false;
|
||||
}
|
||||
|
||||
cairo_set_source_surface(win->c_ctx, image_surface, 0, 0);
|
||||
cairo_paint(win->c_ctx);
|
||||
cairo_show_page(win->c_ctx);
|
||||
|
||||
XFlush(xctx.dpy);
|
||||
calc_window_pos(dim.w, dim.h, &dim.x, &dim.y);
|
||||
x_display_surface(image_surface, win, &dim);
|
||||
|
||||
cairo_surface_destroy(image_surface);
|
||||
free_layouts(layouts);
|
||||
|
31
src/x11/x.c
31
src/x11/x.c
@ -44,28 +44,37 @@ static int x_shortcut_tear_down_error_handler(void);
|
||||
static void setopacity(Window win, unsigned long opacity);
|
||||
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 */
|
||||
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);
|
||||
|
||||
window_dim.x = x;
|
||||
window_dim.y = y;
|
||||
win->dim.x = x;
|
||||
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);
|
||||
|
||||
window_dim.h = height;
|
||||
window_dim.w = width;
|
||||
win->dim.h = height;
|
||||
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)
|
||||
{
|
||||
Atom _NET_WM_WINDOW_OPACITY =
|
||||
|
@ -58,10 +58,10 @@ extern xctx_t xctx;
|
||||
|
||||
/* window */
|
||||
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_show(void);
|
||||
void x_win_destroy(window_x11 *win);
|
||||
void x_display_surface(cairo_surface_t *srf, window_x11 *win, const struct dimensions *dim);
|
||||
|
||||
/* shortcut */
|
||||
void x_shortcut_init(keyboard_shortcut *shortcut);
|
||||
|
Loading…
x
Reference in New Issue
Block a user