Skip to content

Commit

Permalink
Use separate pixmaps for each edge of a container (i3#3479)
Browse files Browse the repository at this point in the history
  • Loading branch information
buchankn committed Feb 18, 2023
1 parent a5da4d5 commit 8c3b982
Show file tree
Hide file tree
Showing 5 changed files with 418 additions and 75 deletions.
2 changes: 1 addition & 1 deletion include/data.h
Original file line number Diff line number Diff line change
Expand Up @@ -660,7 +660,7 @@ struct Con {

/* The surface used for the frame window. */
surface_t frame;
surface_t frame_buffer;
sparse_surface_t frame_buffer;
bool pixmap_recreated;

enum {
Expand Down
68 changes: 68 additions & 0 deletions include/libi3.h
Original file line number Diff line number Diff line change
Expand Up @@ -582,15 +582,64 @@ typedef struct surface_t {
/* The cairo object representing the drawable. In general,
* this is what one should use for any drawing operation. */
cairo_t *cr;

/* Indicates if the surface is initialized */
bool initialized;
} surface_t;

/* Enum used to indicate the top, bottom, left, or right side of a
* sparse surface */
typedef enum {
SPARSE_SURFACE_TOP = 0,
SPARSE_SURFACE_BOTTOM = 1,
SPARSE_SURFACE_LEFT = 2,
SPARSE_SURFACE_RIGHT = 3,
SPARSE_SURFACE_SIDE_COUNT = 4
} sparse_surface_side;

/* A wrapper grouping an XCB drawable and both a graphics context
* and the corresponding cairo objects representing it. This is
* similar to a surface_t, except that it contains four drawable
* rectangles, one for each side of the window which allows us to
* create a 'sparse' pixmap, and save memory by not allocating space
* for the window contents that we don't draw to. */
typedef struct sparse_surface_t {
/* The drawables which are being represented. */
surface_t side_surface[SPARSE_SURFACE_SIDE_COUNT];

/* x and y offset of each drawable rectangle */
int x_offset[SPARSE_SURFACE_SIDE_COUNT];
int y_offset[SPARSE_SURFACE_SIDE_COUNT];

/* Width and height of the entire sparse surface group */
int width;
int height;
} sparse_surface_t;

/**
* Checks if sparse surface has been initialized (eg, if any of the
* sparse surface sides are initialized).
*
*/
bool sparse_surface_initialized(sparse_surface_t *sparse_surface);

/**
* Initialize the surface to represent the given drawable.
*
*/
void draw_util_surface_init(xcb_connection_t *conn, surface_t *surface, xcb_drawable_t drawable,
xcb_visualtype_t *visual, int width, int height);

/**
* Initialize the sparse surface to represent the given drawables.
*
*/
void draw_util_sparse_surface_create_and_init(xcb_connection_t *conn, sparse_surface_t *sparse_surface,
xcb_drawable_t frame_id,
uint16_t win_depth,
xcb_visualtype_t *visual, int width, int height,
int top_height, int bottom_height, int left_width, int right_width);

/**
* Resize the surface to the given size.
*
Expand All @@ -603,6 +652,12 @@ void draw_util_surface_set_size(surface_t *surface, int width, int height);
*/
void draw_util_surface_free(xcb_connection_t *conn, surface_t *surface);

/**
* Destroys the sparse surface.
*
*/
void draw_util_sparse_surface_free(xcb_connection_t *conn, sparse_surface_t *sparse_surface, bool clear_id);

/**
* Parses the given color in hex format to an internal color representation.
* Note that the input must begin with a hash sign, e.g., "#3fbc59".
Expand Down Expand Up @@ -637,13 +692,26 @@ void draw_util_rectangle(surface_t *surface, color_t color, double x, double y,
*/
void draw_util_clear_surface(surface_t *surface, color_t color);

/**
* Clears a sparse surface with the given color.
*
*/
void draw_util_sparse_clear_surface(sparse_surface_t *sparse_surface, color_t color);

/**
* Copies a surface onto another surface.
*
*/
void draw_util_copy_surface(surface_t *src, surface_t *dest, double src_x, double src_y,
double dest_x, double dest_y, double width, double height);

/**
* Copies a sparse surface onto another non-sparse surface.
*
*/
void draw_util_sparse_copy_surface(sparse_surface_t *src_sparse, surface_t *dest, double src_x, double src_y,
double dest_x, double dest_y, double width, double height);

/**
* Puts the given socket file descriptor into non-blocking mode or dies if
* setting O_NONBLOCK failed. Non-blocking sockets are a good idea for our
Expand Down

0 comments on commit 8c3b982

Please sign in to comment.