This commit is contained in:
IoIxD 2026-09-16 12:35:47 -07:00
commit 4b393e78ef
8 changed files with 79 additions and 64 deletions

View file

@ -261,6 +261,7 @@ if(MW_USE_WAYLAND)
scan_wayland_protocol("unstable" "primary-selection" "-unstable-v1")
scan_wayland_protocol("unstable" "pointer-constraints" "-unstable-v1")
scan_wayland_protocol("unstable" "relative-pointer" "-unstable-v1")
scan_wayland_protocol("staging" "fifo" "-v1")
scan_wayland_protocol_from_file("wlr-layer-shell" "wlr-layer-shell-unstable-v1.xml")
target_sources(

View file

@ -196,6 +196,9 @@ struct _MwLLCairo {
/* The cairo to actually use for draw operations. Typically is front_cairo, but wayland's MwLLBeginDraw can change this to the back_cairo so it can be used to draw window decorations. */
cairo_t* selected_cairo;
cairo_surface_t* frontbuffer_cs;
cairo_t* frontbuffer_cairo;
int x;
int y;
int width;

View file

@ -207,6 +207,7 @@ MwInline int wayland_load_funcs() {
#include "Wayland/relative-pointer-client-protocol.h"
#include "Wayland/xdg-toplevel-icon-client-protocol.h"
#include "Wayland/wlr-layer-shell-client-protocol.h"
#include "Wayland/fifo-client-protocol.h"
#endif
typedef struct wayland_protocol {
@ -265,6 +266,7 @@ struct _MwLLWaylandShmBuffer {
struct wl_buffer* shm_buffer_back;
struct wl_surface* surface;
struct wl_output* output;
struct wp_fifo_v1* fifo;
MwU8* buf;
MwU8* buf_back;
@ -440,14 +442,7 @@ struct _MwLLWayland {
MwLLPixmap icon_pixmap;
pthread_mutex_t eventsMutex;
int cancelEvent;
int numCallbacksRunning;
uint32_t last_time;
MwBool moving;
MwU64 time_test;
MwI64 keyboard_rate;
MwI32 keyboard_delay;

View file

@ -66,6 +66,7 @@ if (grep(/^wayland$/, @backends)) {
scan_wayland_protocol("unstable", "primary-selection", "-unstable-v1");
scan_wayland_protocol("unstable", "pointer-constraints", "-unstable-v1");
scan_wayland_protocol("unstable", "relative-pointer", "-unstable-v1");
scan_wayland_protocol("staging", "fifo", "-v1");
scan_wayland_protocol_from_file("wlr-layer-shell",
"wlr-layer-shell-unstable-v1.xml");

View file

@ -113,13 +113,16 @@ void MwLLCairoDrawPixmap(struct _MwLLCairo handle, MwRect* rect, MwLLPixmap pixm
void MwLLCairoFrontSetup(struct _MwLLCairo* cairo, MwU8* data, MwU32 width, MwU32 height) {
if(data) {
cairo->front_cs = cairo_image_surface_create_for_data(data, CAIRO_FORMAT_ARGB32, width, height, width * 4);
cairo->front_cs = cairo_image_surface_create_for_data(data, CAIRO_FORMAT_ARGB32, width, height, width * 4);
cairo->frontbuffer_cs = cairo_image_surface_create_for_data(data, CAIRO_FORMAT_ARGB32, width, height, width * 4);
} else {
cairo->front_cs = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, width, height);
cairo->front_cs = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, width, height);
cairo->frontbuffer_cs = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, width, height);
}
cairo->front_cs_back = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, width, height);
cairo->front_cairo_back = cairo_create(cairo->front_cs_back);
cairo->front_cairo = cairo_create(cairo->front_cs);
cairo->front_cs_back = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, width, height);
cairo->front_cairo_back = cairo_create(cairo->front_cs_back);
cairo->front_cairo = cairo_create(cairo->front_cs);
cairo->frontbuffer_cairo = cairo_create(cairo->frontbuffer_cs);
}
void MwLLCairoBackSetup(struct _MwLLCairo* cairo, MwU8* data, MwU32 width, MwU32 height) {
@ -135,6 +138,8 @@ void MwLLCairoFrontDestroy(struct _MwLLCairo* cairo) {
cairo_destroy(cairo->front_cairo);
cairo_destroy(cairo->front_cairo_back);
cairo_surface_destroy(cairo->front_cs);
cairo_surface_destroy(cairo->frontbuffer_cs);
cairo_destroy(cairo->frontbuffer_cairo);
};
void MwLLCairoBackDestroy(struct _MwLLCairo* cairo) {
cairo_destroy(cairo->back_cairo);
@ -214,8 +219,8 @@ static void MwLLFreeColorImpl(MwLLColor color) {}
static MwBool lmao = MwFALSE;
static int MwLLPendingImpl(MwLL handle) {
lmao = !lmao;
return lmao;
lmao = !lmao;
return lmao;
}
static void MwLLNextEventImpl(MwLL handle) {
MwLLDispatch(handle, draw, NULL);
@ -259,10 +264,10 @@ static void MwLLRaiseImpl(MwLL handle) {}
static void MwLLClipImpl(MwLL handle, MwRect* rect) {}
static void MwLLSetupDragAndDropImpl(MwLL handle) {}
static int MwLLCairoCallInitImpl(void) {
if(cairo_load_funcs() != 0) {
return 1;
}
return 0;
if(cairo_load_funcs() != 0) {
return 1;
}
return 0;
}
#include "call.c"
CALL(Cairo);

View file

@ -10,6 +10,9 @@ void MwLLWaylandFramebufferSetup(struct _MwLLWayland* wayland) {
memset(wayland->framebuffer.buf_back, 0, wayland->framebuffer.buf_size);
if(wayland->configured)
wl_surface_attach(wayland->framebuffer.surface, wayland->framebuffer.shm_buffer, 0, 0);
// if(wayland->framebuffer.fifo)
// wp_fifo_v1_set_barrier(wayland->framebuffer.fifo);
wl_surface_commit(wayland->framebuffer.surface);
MwLLWaylandHangUntilConfigured((MwLL)wayland);
@ -38,6 +41,8 @@ void MwLLWaylandBackbufferSetup(struct _MwLLWayland* wayland) {
memset(wayland->backbuffer.buf_back, 255, wayland->backbuffer.buf_size);
if(wayland->configured)
wl_surface_attach(wayland->backbuffer.surface, wayland->backbuffer.shm_buffer, 0, 0);
// if(wayland->framebuffer.fifo)
// wp_fifo_v1_set_barrier(wayland->framebuffer.fifo);
wl_surface_commit(wayland->backbuffer.surface);
MwLLWaylandHangUntilConfigured((MwLL)wayland);
MwLLWaylandBufferUpdate((MwLL)wayland, &wayland->backbuffer);
@ -113,3 +118,22 @@ void MwLLWaylandBufferDestroy(struct _MwLLWaylandShmBuffer* buffer) {
close(buffer->fd_back);
buffer->setup = MwFALSE;
}
void MwLLWaylandBufferUpdate(MwLL self, struct _MwLLWaylandShmBuffer* buffer) {
if(self->wayland.configured) {
memcpy(buffer->buf, buffer->buf_back, buffer->buf_size);
if(buffer->surface) {
if(self->wayland.framebuffer.fifo) {
// wp_fifo_v1_wait_barrier(self->wayland.framebuffer.fifo);
}
// 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);
}
wl_surface_commit(buffer->surface);
}
}
}

View file

@ -749,6 +749,7 @@ static void pointer_motion(void* data, struct wl_pointer* wl_pointer, MwU32 time
if(self->wayland.backbuffer.surface) {
wl_pointer_set_cursor(self->wayland.pointer, self->wayland.pointer_serial, self->wayland.cursor.surface, 0, 0);
}
WAYLAND_EVENT_OP_END(self);
};
@ -1511,6 +1512,21 @@ static void zwlr_layer_shell_v1_interface_destroy(struct _MwLLWayland* wayland,
free(data);
}
static wayland_protocol_t* wp_fifo_manager_v1_setup(MwU32 name, struct _MwLLWayland* wayland, MwU32 version) {
wayland_protocol_t* proto = malloc(sizeof(wayland_protocol_t));
proto->context = wl_registry_bind(wayland->registry, name, &wp_fifo_manager_v1_interface, version);
proto->listener = NULL;
return proto;
}
static void wp_fifo_manager_v1_interface_destroy(struct _MwLLWayland* wayland, wayland_protocol_t* data) {
(void)wayland;
free(data);
}
/* Function for setting up the callbacks/structs that will be registered upon the relevant interfaces being found. */
void MwLLWaylandSetupCallbacks(struct _MwLLWayland* wayland) {
/* Convience macro for adding the interface functions to the setup map */
@ -1553,6 +1569,7 @@ void MwLLWaylandSetupCallbacks(struct _MwLLWayland* wayland) {
WL_INTERFACE(xdg_toplevel_icon_manager_v1);
WL_INTERFACE(wl_subcompositor);
WL_INTERFACE(wl_seat);
WL_INTERFACE(wp_fifo_manager_v1);
} else if(wayland->type == MwLL_WAYLAND_POPUP) {
WL_INTERFACE(wl_seat);
} else if(wayland->type == MwLL_WAYLAND_LAYER_SURFACE) {

View file

@ -218,19 +218,6 @@ static void xdg_surface_configure(
self->wayland.configured = MwTRUE;
}
void MwLLWaylandBufferUpdate(MwLL self, struct _MwLLWaylandShmBuffer* buffer) {
if(self->wayland.configured) {
memcpy(buffer->buf, buffer->buf_back, buffer->buf_size);
if(buffer->surface) {
// 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);
wl_surface_commit(buffer->surface);
}
}
}
/* Toplevel setup function */
static void setup_toplevel(MwLL r, int x, int y) {
char* mw_force_csd = getenv("MW_FORCE_CSD");
@ -278,6 +265,10 @@ static void setup_toplevel(MwLL r, int x, int y) {
r->wayland.toplevel->ssurface = wl_subcompositor_get_subsurface(r->wayland.toplevel->scompositor, r->wayland.framebuffer.surface, r->wayland.backbuffer.surface);
wl_subsurface_set_desync(r->wayland.toplevel->ssurface);
if(WAYLAND_GET_INTERFACE(r->wayland, wp_fifo_manager_v1) != NULL) {
r->wayland.framebuffer.fifo = wp_fifo_manager_v1_get_fifo(WAYLAND_GET_INTERFACE(r->wayland, wp_fifo_manager_v1)->context, r->wayland.framebuffer.surface);
}
r->wayland.toplevel->xdg_surface =
xdg_wm_base_get_xdg_surface(WAYLAND_GET_INTERFACE(r->wayland, xdg_wm_base)->context, r->wayland.backbuffer.surface);
r->wayland.toplevel->xdg_top_level = xdg_surface_get_toplevel(r->wayland.toplevel->xdg_surface);
@ -921,13 +912,6 @@ static void draw_child(MwLL handle, MwLL child) {
cairo_t* c;
cairo_surface_t* cs;
cairo_t* selected_cairo;
MwLL topmost_parent = handle;
if(topmost_parent->wayland.type != MwLL_WAYLAND_POPUP) {
while(topmost_parent->wayland.parent) {
topmost_parent = topmost_parent->wayland.parent;
}
}
wl_surface_commit(child->wayland.framebuffer.surface);
@ -941,8 +925,6 @@ static void draw_child(MwLL handle, MwLL child) {
cairo_paint(c);
// printf("%d %d\n", child->wayland.x, child->wayland.y);
cairo_set_source_surface(handle->wayland.cairo.front_cairo_back, cs, child->wayland.x, child->wayland.y);
cairo_paint(handle->wayland.cairo.front_cairo_back);
@ -962,11 +944,8 @@ static void draw_children(MwLL handle) {
}
static void frontbuffer_draw(MwLL handle) {
cairo_t* c;
cairo_surface_t* cs;
cs = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, handle->wayland.ww, handle->wayland.wh);
c = cairo_create(cs);
cairo_t* c = handle->wayland.cairo.frontbuffer_cairo;
cairo_surface_t* cs = handle->wayland.cairo.frontbuffer_cs;
cairo_set_source_surface(c, handle->wayland.cairo.front_cs_back, 0, 0);
cairo_pattern_set_filter(cairo_get_source(c), CAIRO_FILTER_NEAREST);
@ -977,16 +956,13 @@ static void frontbuffer_draw(MwLL handle) {
cairo_set_source_surface(handle->wayland.cairo.front_cairo, cs, 0, 0);
cairo_paint(handle->wayland.cairo.front_cairo);
cairo_destroy(c);
cairo_surface_destroy(cs);
}
static MwLL MwLLCreateImpl(MwLL parent, int x, int y, int width, int height) {
MwLL r;
r = malloc(sizeof(*r));
memset(r, 0, sizeof(*r));
pthread_mutex_init(&r->wayland.eventsMutex, NULL);
// pthread_mutex_init(&r->wayland.eventsMutex, NULL);
MwLLCreateCommon(r);
r->wayland.is_toplevel = parent == NULL;
@ -1015,8 +991,6 @@ static void MwLLDestroyImpl(MwLL handle) {
MwLLWaylandFlush(handle);
handle->wayland.cancelEvent = MwTRUE;
MwLLDestroyCommon(handle);
tv.tv_sec = 0;
@ -1050,7 +1024,7 @@ static void MwLLDestroyImpl(MwLL handle) {
printf("widget invalid\n");
}
pthread_mutex_destroy(&handle->wayland.eventsMutex);
// pthread_mutex_destroy(&handle->wayland.eventsMutex);
free(handle);
}
@ -1320,11 +1294,8 @@ static void MwLLEndDrawImpl(MwLL handle) {
if(handle->wayland.type == MwLL_WAYLAND_TOPLEVEL) {
MwLLWaylandBufferUpdate(handle, &handle->wayland.backbuffer);
}
MwLLWaylandBufferUpdate(handle, &handle->wayland.framebuffer);
if(handle->wayland.type != MwLL_WAYLAND_SUBLEVEL) {
handle->wayland.do_cascading_draw = 1;
}
MwLLWaylandBufferUpdate(handle, &handle->wayland.framebuffer);
}
}
@ -1382,16 +1353,16 @@ static int MwLLPendingImpl(MwLL handle) {
handle->wayland.resizing = 0;
if(handle->wayland.type != MwLL_WAYLAND_SUBLEVEL) {
draw_children(handle);
frontbuffer_draw(handle);
}
if(handle->wayland.setting_wh) {
actually_set_wh(handle);
handle->wayland.setting_wh = 0;
}
if(handle->wayland.do_cascading_draw) {
draw_children(handle);
frontbuffer_draw(handle);
}
handle->wayland.end_time = MwTimeGetTick();
if(handle->wayland.holding_key) {
@ -1449,7 +1420,6 @@ static int MwLLPendingImpl(MwLL handle) {
}
static void MwLLNextEventImpl(MwLL handle) {
if(!MwWaylandVulkan) {
if(handle->wayland.did_event_loop_early) {
handle->wayland.did_event_loop_early = MwFALSE;
@ -1469,7 +1439,6 @@ static void MwLLNextEventImpl(MwLL handle) {
}
static void MwLLSetTitleImpl(MwLL handle, const char* title) {
if(handle->wayland.type == MwLL_WAYLAND_TOPLEVEL) {
xdg_toplevel_set_title(handle->wayland.toplevel->xdg_top_level, title);
}