From d22634d6377a53fc5a37e1df29833eb7ae7b65ab Mon Sep 17 00:00:00 2001 From: IoIxD Date: Wed, 16 Sep 2026 15:15:51 -0700 Subject: [PATCH] h --- include/Mw/LowLevel/Wayland.h | 9 +++++++ src/backend/wayland/buffer.c | 5 ++-- src/backend/wayland/wayland.c | 44 +++++++++++++++++++++-------------- 3 files changed, 38 insertions(+), 20 deletions(-) diff --git a/include/Mw/LowLevel/Wayland.h b/include/Mw/LowLevel/Wayland.h index 4f09d0b..67de572 100644 --- a/include/Mw/LowLevel/Wayland.h +++ b/include/Mw/LowLevel/Wayland.h @@ -422,6 +422,15 @@ struct _MwLLWayland { int resizing; int setting_wh; + // /* True only while setup_popup()'s own synchronous roundtrip (the one + // * requesting the current xdg_positioner size) is in flight. Lets + // * popup_configure tell "this is the direct response to the resize we + // * just requested" apart from a configure that was merely delayed by + // * the compositor (e.g. because the popup wasn't shown yet) and only + // * gets dispatched later, after a newer resize is already pending - + // * which would otherwise clobber that newer, not-yet-applied size. */ + MwBool awaiting_own_popup_configure; + MwU32 mw, mh; /* Monitor width and height as advertised by wl_output.mode */ MwLL parent; diff --git a/src/backend/wayland/buffer.c b/src/backend/wayland/buffer.c index 8450851..79ce72c 100644 --- a/src/backend/wayland/buffer.c +++ b/src/backend/wayland/buffer.c @@ -126,10 +126,9 @@ void MwLLWaylandBufferUpdate(MwLL self, struct _MwLLWaylandShmBuffer* buffer) { // Yes this is needed every time, it's how we fix weston. if(self->wayland.configured) { wl_surface_attach(buffer->surface, buffer->shm_buffer, 0, 0); - // if(buffer->fifo) - // wp_fifo_v1_set_barrier(buffer->fifo); } - + if(buffer->fifo) + wp_fifo_v1_wait_barrier(buffer->fifo); wl_surface_commit(buffer->surface); } } diff --git a/src/backend/wayland/wayland.c b/src/backend/wayland/wayland.c index 5b59795..918307d 100644 --- a/src/backend/wayland/wayland.c +++ b/src/backend/wayland/wayland.c @@ -411,10 +411,13 @@ static void popup_configure(void* data, if(width < 50) width = 50; if(height < 50) height = 50; - self->wayland.x = x; - self->wayland.y = y; - self->wayland.ww = width; - self->wayland.wh = height; + self->wayland.x = x; + self->wayland.y = y; + + if(!self->wayland.setting_wh) { + self->wayland.ww = width; + self->wayland.wh = height; + } }; static void popup_done(void* data, @@ -443,10 +446,11 @@ struct xdg_popup_listener popup_listener = { static void setup_popup(MwLL r, int x, int y, MwLL parent) { char* mw_force_csd = getenv("MW_FORCE_CSD"); MwLL topmost_parent = r->wayland.parent; - r->wayland.type = MwLL_WAYLAND_POPUP; - r->wayland.x = x; - r->wayland.y = y; - r->wayland.popup = malloc(sizeof(struct _MwLLWaylandPopup)); + + r->wayland.type = MwLL_WAYLAND_POPUP; + r->wayland.x = x; + r->wayland.y = y; + r->wayland.popup = malloc(sizeof(struct _MwLLWaylandPopup)); if(parent) { MwWidget p = parent->common.user; @@ -526,11 +530,13 @@ static void setup_popup(MwLL r, int x, int y, MwLL parent) { r->wayland.popup->xdg_surface_listener.configure = xdg_surface_configure; xdg_surface_add_listener(r->wayland.popup->xdg_surface, &r->wayland.popup->xdg_surface_listener, r); + r->wayland.awaiting_own_popup_configure = MwTRUE; if(wl_display_roundtrip(r->wayland.display) == -1) { printf("roundtrip failed\n"); raise(SIGTRAP); return; } + r->wayland.awaiting_own_popup_configure = MwFALSE; MwLLWaylandFramebufferSetup(&r->wayland); } @@ -913,6 +919,8 @@ static void draw_child(MwLL handle, MwLL child) { cairo_surface_t* cs; cairo_t* selected_cairo; + draw_children(child); + wl_surface_commit(child->wayland.framebuffer.surface); cs = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, child->wayland.ww, child->wayland.wh); @@ -930,13 +938,13 @@ static void draw_child(MwLL handle, MwLL child) { cairo_destroy(c); cairo_surface_destroy(cs); - - draw_children(child); } static void draw_children(MwLL handle) { wl_surface_damage(handle->wayland.framebuffer.surface, 0, 0, handle->wayland.ww, handle->wayland.wh); + cairo_reset_clip(handle->wayland.cairo.front_cairo_back); + MwLLWaylandChildrenIterate(handle, draw_child); if(handle->wayland.configured) MwLLWaylandBufferUpdate(handle, &handle->wayland.framebuffer); @@ -944,18 +952,13 @@ static void draw_children(MwLL handle) { } static void frontbuffer_draw(MwLL handle) { - cairo_t* c = handle->wayland.cairo.frontbuffer_cairo; - cairo_surface_t* cs = handle->wayland.cairo.frontbuffer_cs; + cairo_t* c = handle->wayland.cairo.frontbuffer_cairo; cairo_set_source_surface(c, handle->wayland.cairo.front_cs_back, 0, 0); cairo_pattern_set_filter(cairo_get_source(c), CAIRO_FILTER_NEAREST); - cairo_set_operator(handle->wayland.cairo.front_cairo_back, CAIRO_OPERATOR_OVER); cairo_paint(c); - - cairo_set_source_surface(handle->wayland.cairo.front_cairo, cs, 0, 0); - cairo_paint(handle->wayland.cairo.front_cairo); } static MwLL MwLLCreateImpl(MwLL parent, int x, int y, int width, int height) { @@ -1290,6 +1293,12 @@ static void MwLLBeginDrawImpl(MwLL handle) { } static void MwLLEndDrawImpl(MwLL handle) { + MwLL root = handle; + while(root->wayland.type == MwLL_WAYLAND_SUBLEVEL && root->wayland.parent) { + root = root->wayland.parent; + } + root->wayland.do_cascading_draw = MwTRUE; + if(handle->wayland.configured) { if(handle->wayland.type == MwLL_WAYLAND_TOPLEVEL) { MwLLWaylandBufferUpdate(handle, &handle->wayland.backbuffer); @@ -1353,9 +1362,10 @@ static int MwLLPendingImpl(MwLL handle) { handle->wayland.resizing = 0; - if(handle->wayland.type != MwLL_WAYLAND_SUBLEVEL) { + if(handle->wayland.do_cascading_draw) { draw_children(handle); frontbuffer_draw(handle); + handle->wayland.do_cascading_draw = MwFALSE; } if(handle->wayland.setting_wh) {