From 4696bf1bc46228bf6880eac77b8dab3d9d2c7746 Mon Sep 17 00:00:00 2001 From: IoI_xD Date: Thu, 26 Mar 2026 17:48:22 -0700 Subject: [PATCH] fix wayland csd, more doublebuffering fixes --- src/backend/wayland.c | 30 ++++++++++++++++++------------ src/draw.c | 28 ++++++++++++++-------------- src/widget/button.c | 1 + src/widget/checkbox.c | 1 + src/widget/combobox.c | 1 + src/widget/entry.c | 1 + 6 files changed, 36 insertions(+), 26 deletions(-) diff --git a/src/backend/wayland.c b/src/backend/wayland.c index 1f27ed7..d3e8e02 100644 --- a/src/backend/wayland.c +++ b/src/backend/wayland.c @@ -46,7 +46,7 @@ static void buffer_destroy(struct _MwLLWaylandShmBuffer* buffer); static void region_setup(MwLL handle); static void region_invalidate(MwLL handle); - +static void update_buffer(MwLL self, struct _MwLLWaylandShmBuffer* buffer); /* Get the registered interface from r, or NULL if it doesn't currently have it. */ #define WAYLAND_GET_INTERFACE(handle, inter) shget(handle.wl_protocol_map, inter##_interface.name) @@ -65,8 +65,11 @@ static void new_protocol(void* data, struct wl_registry* registry, char* inter = malloc(strlen(interface) + 1); strcpy(inter, interface); shput(self->wayland.wl_protocol_map, inter, cb->setup(name, data)); + /* we don't care for adding this protocol, we just use it to know if the compositor will let us have transparent surfaces */ + } else if(strcmp(interface, "wp_alpha_modifier_v1") == 0) { + self->common.supports_transparency = MwTRUE; } else { - /* printf("unknown interface %s\n", interface); */ + // printf("unknown interface %s\n", interface); } WAYLAND_EVENT_OP_END(self); @@ -1075,9 +1078,9 @@ static int event_loop(MwLL handle) { if(!poll(&fd, 1, timeout.tv_nsec)) { wl_display_cancel_read(wayland->display); - wl_surface_commit(wayland->framebuffer.surface); + update_buffer(handle, &wayland->framebuffer); if(wayland->type == MWLL_WAYLAND_TOPLEVEL) - wl_surface_commit(wayland->backbuffer.surface); + update_buffer(handle, &wayland->backbuffer); return 0; } wl_display_read_events(wayland->display); @@ -1163,8 +1166,8 @@ static void xdg_surface_configure( xdg_surface_ack_configure(xdg_surface, serial); if(self->wayland.configured) { - wl_surface_commit(self->wayland.framebuffer.surface); - wl_surface_commit(self->wayland.backbuffer.surface); + update_buffer(self, &self->wayland.framebuffer); + update_buffer(self, &self->wayland.backbuffer); } self->wayland.configured = MwTRUE; @@ -1735,13 +1738,17 @@ static void widget_setup(MwLL r, MwLL parent, int x, int y, int width, int heigh if(parent != NULL) { MwLLForceRender(parent); } + + if(!r->wayland.has_decorations) { + MwLLBeginDraw(r); + MwLLEndDraw(r); + } } static MwLL MwLLCreateImpl(MwLL parent, int x, int y, int width, int height) { MwLL r; r = malloc(sizeof(*r)); memset(r, 0, sizeof(*r)); MwLLCreateCommon(r); - r->common.supports_transparency = MwTRUE; widget_setup(r, parent, x, y, width, height, MWLL_WAYLAND_UNKNOWN); @@ -1956,8 +1963,6 @@ static void MwLLBeginDrawImpl(MwLL handle) { free(px); } update_buffer(handle, &handle->wayland.backbuffer); - - wl_surface_commit(handle->wayland.backbuffer.surface); } handle->wayland.selected_cairo = handle->wayland.front_cairo; } @@ -1976,7 +1981,7 @@ static void MwLLPolygonImpl(MwLL handle, MwPoint* points, int points_count, MwLL clip(handle); - cairo_set_source_rgb(handle->wayland.front_cairo, color->common.red / 255.0, color->common.green / 255.0, color->common.blue / 255.0); + cairo_set_source_rgba(handle->wayland.front_cairo, color->common.red / 255.0, color->common.green / 255.0, color->common.blue / 255.0, 1.0); cairo_new_path(handle->wayland.front_cairo); for(i = 0; i < points_count; i++) { if(i == 0) { @@ -1999,7 +2004,7 @@ static void MwLLLineImpl(MwLL handle, MwPoint* points, MwLLColor color) { cairo_set_antialias(handle->wayland.front_cairo, CAIRO_ANTIALIAS_NONE); cairo_set_line_cap(handle->wayland.front_cairo, CAIRO_LINE_CAP_SQUARE); - cairo_set_source_rgb(handle->wayland.front_cairo, color->common.red / 255.0, color->common.green / 255.0, color->common.blue / 255.0); + cairo_set_source_rgba(handle->wayland.front_cairo, color->common.red / 255.0, color->common.green / 255.0, color->common.blue / 255.0, 1.0); cairo_new_path(handle->wayland.front_cairo); for(i = 0; i < 2; i++) { if(i == 0) { @@ -2109,6 +2114,8 @@ static void MwLLSetTitleImpl(MwLL handle, const char* title) { } if(!handle->wayland.has_decorations) { strncpy(handle->wayland.title, title, 255); + MwLLBeginDraw(handle); + MwLLEndDraw(handle); } } @@ -2178,7 +2185,6 @@ static void MwLLDrawPixmapImpl(MwLL handle, MwRect* rect, MwLLPixmap pixmap) { cairo_surface_destroy(cs); MwLLForceRender(handle); - // update_buffer(handle, &handle->wayland.framebuffer); wl_surface_damage(handle->wayland.framebuffer.surface, 0, 0, handle->wayland.ww, handle->wayland.wh); } static void MwLLSetIconImpl(MwLL handle, MwLLPixmap pixmap) { diff --git a/src/draw.c b/src/draw.c index 7bf413e..ee9475e 100644 --- a/src/draw.c +++ b/src/draw.c @@ -116,10 +116,10 @@ void MwDrawRectFading(MwWidget handle, MwRect* rect, MwLLColor color, int rounde unsigned char* data = malloc(sz); MwRect r = *rect; int roundness = MwGetInteger(handle, MwNroundness); - double h; + double div; if(roundness == MwDEFAULT) roundness = DEFAULT_ROUNDNESS; if(roundness >= MAX_ROUNDNESS) roundness = MAX_ROUNDNESS; - h = (roundness <= 10) ? 7. : 10.; + div = (roundness <= 10) ? 7. : 10.; memset(data, 0, sz); for(y = 0; y < rect->height; y++) { @@ -138,8 +138,8 @@ void MwDrawRectFading(MwWidget handle, MwRect* rect, MwLLColor color, int rounde int x = rect->x + (roundness + 1); int y = rect->y + (roundness + 1); for(i = 0; i < roundness; i++) { - double point = ((i + (M_PI * 4)) / h); - double point2 = (((i + 1) + (M_PI * 4)) / h); + double point = ((i + (M_PI * 4)) / div); + double point2 = (((i + 1) + (M_PI * 4)) / div); int x2 = x - (sin(point2) * roundness); r.x = x - (sin(point) * roundness); r.y = y + (cos(point) * roundness); @@ -153,16 +153,16 @@ void MwDrawRectFading(MwWidget handle, MwRect* rect, MwLLColor color, int rounde } } r = *rect; - r.x += roundness; - r.width -= (roundness * 2); - r.height -= 1; + r.x += roundness - 1; + r.width -= (roundness * 2) + 1; + r.height -= 2; MwLLDrawPixmap(handle->lowlevel, &r, pixmap); r = *rect; x = (rect->x + rect->width) - (roundness + 2); y = rect->y + (roundness + 1); for(i = 0; i < roundness; i++) { - double point = ((i + (M_PI * 4)) / h); - double point2 = (((i + 1) + (M_PI * 4)) / h); + double point = ((i + (M_PI * 4)) / div); + double point2 = (((i + 1) + (M_PI * 4)) / div); int x2 = x + (sin(point2) * roundness); r.x = x + (sin(point) * roundness); r.y = y + (cos(point) * roundness); @@ -207,13 +207,14 @@ void MwDrawFrame(MwWidget handle, MwRect* rect, MwLLColor color, int invert, int void MwDrawWidgetBack(MwWidget handle, MwRect* rect, MwLLColor color, int invert, int border) { MwLLColor col; + MwBool rounded = handle->lowlevel->common.supports_transparency && MwGetInteger(handle, MwNroundness) != MwDEFAULT; if(border) { - MwDrawFrame(handle, rect, color, invert, handle->lowlevel->common.supports_transparency); + MwDrawFrame(handle, rect, color, invert, rounded); } col = invert ? MwLightenColor(handle, color, -8, -8, -8) : color; if(MwGetInteger(handle, MwNmodernLook)) { - MwDrawRectFading(handle, rect, col, handle->lowlevel->common.supports_transparency); + MwDrawRectFading(handle, rect, col, rounded); } else { MwDrawRect(handle, rect, col); } @@ -318,10 +319,10 @@ void MwDrawFrameEx(MwWidget handle, MwRect* rect, MwLLColor color, int invert, i p[0].x = rect->x + roundness; p[0].y = rect->y; - p[1].x = rect->x + rect->width - border - roundness; + p[1].x = rect->x + rect->width - border - roundness - 2; p[1].y = rect->y; - p[2].x = rect->x + rect->width - border - roundness; + p[2].x = rect->x + rect->width - border - roundness - 2; p[2].y = rect->y + border; p[3].x = rect->x + border - roundness; @@ -332,7 +333,6 @@ void MwDrawFrameEx(MwWidget handle, MwRect* rect, MwLLColor color, int invert, i p[5].x = rect->x + roundness; p[5].y = rect->y + rect->height - roundness; - MwLLPolygon(handle->lowlevel, p, 6, invert ? darker : lighter); /* top right edge */ for(i = 0; i < BORDER_SMOOTHNESS; i += 2) { diff --git a/src/widget/button.c b/src/widget/button.c index dac7739..f3240b0 100644 --- a/src/widget/button.c +++ b/src/widget/button.c @@ -8,6 +8,7 @@ static int create(MwWidget handle) { MwSetInteger(handle, MwNflat, 0); MwSetInteger(handle, MwNpadding, 0); MwSetInteger(handle, MwNfillArea, 1); + MwSetInteger(handle, MwNroundness, 5); return 0; } diff --git a/src/widget/checkbox.c b/src/widget/checkbox.c index 1ccccd4..224cfec 100644 --- a/src/widget/checkbox.c +++ b/src/widget/checkbox.c @@ -4,6 +4,7 @@ static int create(MwWidget handle) { MwSetDefault(handle); MwSetInteger(handle, MwNchecked, 0); + MwSetInteger(handle, MwNroundness, 5); return 0; } diff --git a/src/widget/combobox.c b/src/widget/combobox.c index 0672ff3..9982372 100644 --- a/src/widget/combobox.c +++ b/src/widget/combobox.c @@ -14,6 +14,7 @@ static int create(MwWidget handle) { MwSetInteger(handle, MwNareaShown, 6); MwSetInteger(handle, MwNvalue, 0); + MwSetInteger(handle, MwNroundness, 5); return 0; } diff --git a/src/widget/entry.c b/src/widget/entry.c index 34a90a3..998935b 100644 --- a/src/widget/entry.c +++ b/src/widget/entry.c @@ -11,6 +11,7 @@ static int create(MwWidget handle) { MwSetDefault(handle); MwLLSetCursor(handle->lowlevel, &MwCursorText, &MwCursorTextMask); + MwSetInteger(handle, MwNroundness, 5); return 0; }