[digesting_libdecor] move buffer fields directly into border_component

main
Allen Webster 2026-02-28 14:27:42 -08:00
parent 5568053e96
commit abac463a70
2 changed files with 77 additions and 104 deletions

View File

@ -1,12 +1,12 @@
#if 0 #if 0
libdecor_path="/home/mr4th/mr4th/libdecor" libdecor_path="/home/mr4th/mr4th/libdecor"
root_path="$PWD"
gtk_flags="$(pkg-config --cflags --libs gtk+-3.0)" gtk_flags="$(pkg-config --cflags --libs gtk+-3.0)"
dbus_flags="$(pkg-config --cflags --libs dbus-1)" dbus_flags="$(pkg-config --cflags --libs dbus-1)"
#echo "gtk_flags: $gtk_flags" my_flags="-Iwayland -I$libdecor_path/src -I$libdecor_path/src/plugins -I$libdecor_path/build"
#echo "dbus_flags: $dbus_flags" my_flags+=" -lwayland-client -lwayland-cursor -lwayland-egl -lEGL -lm"
root_path="$PWD"
mkdir -p build mkdir -p build
clang -o build/demo -g $root_path/digesting_libdecor.c $gtk_flags $dbus_flags -Iwayland -I$libdecor_path/src -I$libdecor_path/src/plugins -I$libdecor_path/build -lwayland-client -lwayland-cursor -lwayland-egl -lEGL -lm clang -o build/demo -g $root_path/digesting_libdecor.c $gtk_flags $dbus_flags $my_flags
exit 0 exit 0
#endif #endif
@ -645,7 +645,7 @@ xdg_toplevel_configure_bounds(void *user_data, struct xdg_toplevel *xdg_toplevel
int32_t inner_h = h; int32_t inner_h = h;
if (ctx.visible && if (ctx.visible &&
ctx.decoration_mode == ZXDG_TOPLEVEL_DECORATION_V1_MODE_CLIENT_SIDE){ ctx.decoration_mode == ZXDG_TOPLEVEL_DECORATION_V1_MODE_CLIENT_SIDE){
Bounds2D border_size = border_size_from_window_state(0); Sides2D border_size = border_size_from_window_state(0);
inner_w -= border_size.x[0] + border_size.x[1]; inner_w -= border_size.x[0] + border_size.x[1];
inner_h -= border_size.y[0] + border_size.y[1]; inner_h -= border_size.y[0] + border_size.y[1];
} }
@ -891,11 +891,9 @@ int main(){
{ {
static const int size = 128; static const int size = 128;
static const int boundary = 32; static const int boundary = 32;
cairo_t *cr; cairo_surface_t *shadow_blur =
cairo_surface_t *shadow_blur; cairo_image_surface_create(CAIRO_FORMAT_ARGB32, size, size);
cairo_t *cr = cairo_create(shadow_blur);
shadow_blur = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, size, size);
cr = cairo_create(shadow_blur);
cairo_set_operator(cr, CAIRO_OPERATOR_OVER); cairo_set_operator(cr, CAIRO_OPERATOR_OVER);
cairo_set_source_rgba(cr, 0, 0, 0, 1); cairo_set_source_rgba(cr, 0, 0, 0, 1);
cairo_rectangle(cr, boundary, boundary, size - 2*boundary, size - 2*boundary); cairo_rectangle(cr, boundary, boundary, size - 2*boundary, size - 2*boundary);
@ -1136,7 +1134,7 @@ frame_get_window_size_for(struct libdecor_state *state, int *window_width, int *
*window_width = state->content_width; *window_width = state->content_width;
*window_height = state->content_height; *window_height = state->content_height;
if (ctx.visible && ctx.decoration_mode == ZXDG_TOPLEVEL_DECORATION_V1_MODE_CLIENT_SIDE){ if (ctx.visible && ctx.decoration_mode == ZXDG_TOPLEVEL_DECORATION_V1_MODE_CLIENT_SIDE){
Bounds2D border_size = border_size_from_window_state(ctx.frame_window_state); Sides2D border_size = border_size_from_window_state(ctx.frame_window_state);
*window_width += border_size.x[0] + border_size.x[1]; *window_width += border_size.x[0] + border_size.x[1];
*window_height += border_size.y[0] + border_size.y[1]; *window_height += border_size.y[0] + border_size.y[1];
} }
@ -1149,7 +1147,7 @@ frame_set_window_geometry(int32_t w, int32_t h){
extent.w = h; extent.w = h;
if (ctx.visible && ctx.decoration_mode == ZXDG_TOPLEVEL_DECORATION_V1_MODE_CLIENT_SIDE){ if (ctx.visible && ctx.decoration_mode == ZXDG_TOPLEVEL_DECORATION_V1_MODE_CLIENT_SIDE){
Bounds2D border_size = border_size_from_window_state(ctx.frame_window_state); Sides2D border_size = border_size_from_window_state(ctx.frame_window_state);
extent.x = -border_size.x[0]; extent.x = -border_size.x[0];
extent.y = -border_size.y[0]; extent.y = -border_size.y[0];
extent.w = w + border_size.x[0] + border_size.x[1]; extent.w = w + border_size.x[0] + border_size.x[1];
@ -1175,7 +1173,7 @@ libdecor_configuration_get_content_size(struct libdecor_configuration *configura
ctx.decoration_mode == ZXDG_TOPLEVEL_DECORATION_V1_MODE_CLIENT_SIDE){ ctx.decoration_mode == ZXDG_TOPLEVEL_DECORATION_V1_MODE_CLIENT_SIDE){
ctx.frame_window_state = configuration->window_state; ctx.frame_window_state = configuration->window_state;
if (configuration->has_window_state){ if (configuration->has_window_state){
Bounds2D border_size = border_size_from_window_state(configuration->window_state); Sides2D border_size = border_size_from_window_state(configuration->window_state);
*width -= border_size.x[0] + border_size.x[1]; *width -= border_size.x[0] + border_size.x[1];
*height -= border_size.y[0] + border_size.y[1]; *height -= border_size.y[0] + border_size.y[1];
} }
@ -1831,25 +1829,6 @@ toggle_maximized(void){
} }
} }
static void
buffer_release(void *user_data, struct wl_buffer *wl_buffer){
struct buffer *buffer = user_data;
buffer->in_use = false;
}
const struct wl_buffer_listener buffer_listener = {
buffer_release
};
static void
buffer_free(struct buffer *buffer){
if (buffer->wl_buffer != 0){
wl_buffer_destroy(buffer->wl_buffer);
munmap(buffer->data, buffer->data_size);
}
memset(buffer, 0, sizeof *buffer);
}
static void static void
free_border_component(struct border_component *border_component){ free_border_component(struct border_component *border_component){
if (border_component->wl_surface) { if (border_component->wl_surface) {
@ -1858,10 +1837,18 @@ free_border_component(struct border_component *border_component){
wl_surface_destroy(border_component->wl_surface); wl_surface_destroy(border_component->wl_surface);
border_component->wl_surface = NULL; border_component->wl_surface = NULL;
} }
if (border_component->buffer) {
buffer_free(border_component->buffer); if (border_component->wl_buffer != 0){
border_component->buffer = NULL; wl_buffer_destroy(border_component->wl_buffer);
} }
if (border_component->data != 0){
munmap(border_component->data, border_component->data_size);
}
border_component->wl_buffer = 0;
border_component->data = 0;
border_component->data_size = 0;
border_component->width = 0;
border_component->height = 0;
} }
static void static void
@ -2131,7 +2118,10 @@ draw_header_button(cairo_t *cr, cairo_surface_t *surface,
} }
static void static void
set_component_input_region(enum component_slot slot){ draw_border_component(enum component_slot slot){
if (slot < COMPONENT_SLOT_COUNT &&
ctx.component_slot[slot].wl_surface != 0){
Extent2D extent = extent2d_from_component_slot(slot);
if (slot == COMPONENT_SLOT_SHADOW && ctx.shadow_showing){ if (slot == COMPONENT_SLOT_SHADOW && ctx.shadow_showing){
struct wl_region *input_region; struct wl_region *input_region;
Extent2D extent = extent2d_from_component_slot(COMPONENT_SLOT_SHADOW); Extent2D extent = extent2d_from_component_slot(COMPONENT_SLOT_SHADOW);
@ -2141,31 +2131,24 @@ set_component_input_region(enum component_slot slot){
wl_surface_set_input_region(ctx.component_slot[slot].wl_surface, input_region); wl_surface_set_input_region(ctx.component_slot[slot].wl_surface, input_region);
wl_region_destroy(input_region); wl_region_destroy(input_region);
} }
}
static void struct border_component *component = &ctx.component_slot[slot];
draw_border_component(enum component_slot slot){
struct buffer *buffer = 0;
if (slot < COMPONENT_SLOT_COUNT && {
ctx.component_slot[slot].wl_surface != 0){ if (component->wl_buffer != 0){
Extent2D extent = extent2d_from_component_slot(slot); wl_buffer_destroy(component->wl_buffer);
set_component_input_region(slot);
struct buffer *old_buffer = ctx.component_slot[slot].buffer;
if (old_buffer != 0){
if (!old_buffer->in_use &&
old_buffer->width == extent.w &&
old_buffer->height == extent.h){
buffer = old_buffer;
} }
else{ if (component->data != 0){
buffer_free(old_buffer); munmap(component->data, component->data_size);
ctx.component_slot[slot].buffer = 0;
} }
component->wl_buffer = 0;
component->data = 0;
component->data_size = 0;
component->width = 0;
component->height = 0;
} }
if (buffer == 0){ {
int width = extent.w; int width = extent.w;
int height = extent.h; int height = extent.h;
int stride = 4*width; int stride = 4*width;
@ -2175,31 +2158,29 @@ draw_border_component(enum component_slot slot){
if (fd >= 0){ if (fd >= 0){
void *data = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); void *data = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
if (data != MAP_FAILED){ if (data != MAP_FAILED){
enum wl_shm_format buf_fmt = (ctx.component_slot[slot].opaque ? enum wl_shm_format fmt = (ctx.component_slot[slot].opaque ?
WL_SHM_FORMAT_XRGB8888 : WL_SHM_FORMAT_XRGB8888 :
WL_SHM_FORMAT_ARGB8888); WL_SHM_FORMAT_ARGB8888);
struct wl_shm_pool *pool = wl_shm_create_pool(ctx.wl_shm, fd, size); struct wl_shm_pool *pool = wl_shm_create_pool(ctx.wl_shm, fd, size);
buffer = calloc(1, sizeof *buffer); struct wl_buffer *wl_buffer = wl_shm_pool_create_buffer(pool, 0, width, height, stride, fmt);
buffer->wl_buffer = wl_shm_pool_create_buffer(pool, 0, width, height, stride, buf_fmt);
wl_buffer_add_listener(buffer->wl_buffer, &buffer_listener, buffer);
wl_shm_pool_destroy(pool); wl_shm_pool_destroy(pool);
buffer->data = data; component->wl_buffer = wl_buffer;
buffer->data_size = size; component->data = data;
buffer->width = width; component->data_size = size;
buffer->height = height; component->width = width;
component->height = height;
} }
close(fd); close(fd);
} }
} }
memset(buffer->data, 0, buffer->data_size); memset(component->data, 0, component->data_size);
{ {
int stride = cairo_format_stride_for_width(CAIRO_FORMAT_ARGB32, buffer->width); int stride = cairo_format_stride_for_width(CAIRO_FORMAT_ARGB32, component->width);
cairo_surface_t *surface = cairo_image_surface_create_for_data(buffer->data, CAIRO_FORMAT_ARGB32, buffer->width, buffer->height, stride); cairo_surface_t *surface = cairo_image_surface_create_for_data(component->data, CAIRO_FORMAT_ARGB32, component->width, component->height, stride);
cairo_t *cr = cairo_create(surface); cairo_t *cr = cairo_create(surface);
cairo_surface_set_device_scale(surface, 1, 1); cairo_surface_set_device_scale(surface, 1, 1);
@ -2209,7 +2190,7 @@ draw_border_component(enum component_slot slot){
case COMPONENT_SLOT_SHADOW: { case COMPONENT_SLOT_SHADOW: {
render_shadow(cr, ctx.shadow_blur, render_shadow(cr, ctx.shadow_blur,
-(int)SHADOW_MARGIN/2, -(int)SHADOW_MARGIN/2, -(int)SHADOW_MARGIN/2, -(int)SHADOW_MARGIN/2,
buffer->width + SHADOW_MARGIN, buffer->height + SHADOW_MARGIN, component->width + SHADOW_MARGIN, component->height + SHADOW_MARGIN,
64, 64); 64, 64);
cairo_set_operator(cr, CAIRO_OPERATOR_CLEAR); cairo_set_operator(cr, CAIRO_OPERATOR_CLEAR);
cairo_rectangle(cr, -extent.x, -extent.y, ctx.frame_content_width, ctx.frame_content_height); cairo_rectangle(cr, -extent.x, -extent.y, ctx.frame_content_width, ctx.frame_content_height);
@ -2276,14 +2257,11 @@ draw_border_component(enum component_slot slot){
struct wl_surface *component_surface = ctx.component_slot[slot].wl_surface; struct wl_surface *component_surface = ctx.component_slot[slot].wl_surface;
struct wl_subsurface *component_subsurface = ctx.component_slot[slot].wl_subsurface; struct wl_subsurface *component_subsurface = ctx.component_slot[slot].wl_subsurface;
wl_surface_attach(component_surface, buffer->wl_buffer, 0, 0); wl_surface_attach(component_surface, component->wl_buffer, 0, 0);
wl_surface_set_buffer_scale(component_surface, 1); wl_surface_set_buffer_scale(component_surface, 1);
buffer->in_use = true;
wl_surface_commit(component_surface); wl_surface_commit(component_surface);
wl_surface_damage_buffer(component_surface, 0, 0, extent.w, extent.h); wl_surface_damage_buffer(component_surface, 0, 0, extent.w, extent.h);
wl_subsurface_set_position(component_subsurface, extent.x, extent.y); wl_subsurface_set_position(component_subsurface, extent.x, extent.y);
ctx.component_slot[slot].buffer = buffer;
} }
} }
@ -2425,9 +2403,9 @@ libdecor_plugin_gtk_frame_commit(void){
} }
} }
static Bounds2D static Sides2D
border_size_from_window_state(enum libdecor_window_state window_state){ border_size_from_window_state(enum libdecor_window_state window_state){
Bounds2D border_size = {0}; Sides2D border_size = {0};
switch (decoration_type_from_window_state(window_state)) { switch (decoration_type_from_window_state(window_state)) {
case DECORATION_TYPE_NONE: break; case DECORATION_TYPE_NONE: break;
@ -2456,10 +2434,10 @@ edge_from_pos(int x, int y){
}; };
enum libdecor_resize_edge result = 0; enum libdecor_resize_edge result = 0;
struct buffer *buffer = ctx.component_slot[COMPONENT_SLOT_SHADOW].buffer; struct border_component *component = &ctx.component_slot[COMPONENT_SLOT_SHADOW];
if (buffer != 0){ if (component->data != 0){
int w = buffer->width; int w = component->width;
int h = buffer->height; int h = component->height;
int top = (y < 2*SHADOW_MARGIN); int top = (y < 2*SHADOW_MARGIN);
int bottom = (!top && y > (h - 2*SHADOW_MARGIN)); int bottom = (!top && y > (h - 2*SHADOW_MARGIN));

View File

@ -59,10 +59,10 @@ typedef struct Extent2D{
int h; int h;
} Extent2D; } Extent2D;
typedef struct Bounds2D{ typedef struct Sides2D{
int x[2]; int x[2];
int y[2]; int y[2];
} Bounds2D; } Sides2D;
// libdecor.h // libdecor.h
@ -163,22 +163,18 @@ enum component_slot {
COMPONENT_SLOT_COUNT COMPONENT_SLOT_COUNT
}; };
struct buffer { struct border_component {
struct wl_surface *wl_surface;
struct wl_subsurface *wl_subsurface;
bool opaque;
struct wl_buffer *wl_buffer; struct wl_buffer *wl_buffer;
bool in_use;
void *data; void *data;
size_t data_size; size_t data_size;
int width; int width;
int height; int height;
}; };
struct border_component {
struct wl_surface *wl_surface;
struct wl_subsurface *wl_subsurface;
struct buffer *buffer;
bool opaque;
};
// #include "libdecor.c" // #include "libdecor.c"
struct libdecor_state { struct libdecor_state {
@ -291,12 +287,11 @@ static const char *libdecor_gtk_proxy_tag = "libdecor-gtk";
static void libdecor_plugin_gtk_frame_free(void); static void libdecor_plugin_gtk_frame_free(void);
static void libdecor_plugin_gtk_frame_commit(void); static void libdecor_plugin_gtk_frame_commit(void);
static Bounds2D border_size_from_window_state(enum libdecor_window_state window_state); static Sides2D border_size_from_window_state(enum libdecor_window_state window_state);
static struct wl_cursor* wl_cursor_from_pos(int x, int y); static struct wl_cursor* wl_cursor_from_pos(int x, int y);
static void draw_decoration(void); static void draw_decoration(void);
static void draw_header_button(cairo_t *cr, cairo_surface_t *surface, enum header_element button_type); static void draw_header_button(cairo_t *cr, cairo_surface_t *surface, enum header_element button_type);
static void buffer_free(struct buffer *buffer);
static void draw_border_component(enum component_slot slot); static void draw_border_component(enum component_slot slot);
static bool own_proxy(void *proxy); static bool own_proxy(void *proxy);
@ -357,7 +352,7 @@ typedef struct Ctx{
//struct libdecor_frame_private; //struct libdecor_frame_private;
char *title; char *title;
Bounds2D size_bounds; Sides2D size_bounds;
struct xdg_toplevel *parent; struct xdg_toplevel *parent;
struct libdecor_configuration *pending_configuration; struct libdecor_configuration *pending_configuration;