wayland: actual subsurface type for the one widget that needs it (vulkan)
All checks were successful
pyrite-dev/milsko/pipeline/head This commit looks good

This commit is contained in:
IoIxD 2026-09-21 17:22:15 -07:00
commit c2f8fb3f82
6 changed files with 100 additions and 13 deletions

View file

@ -467,7 +467,7 @@ if(MW_BUILD_VULKAN)
)
endif()
check_include_files(vulkan/VULKAN.h HAS_VK_HEADER)
check_include_files(vulkan/vulkan.h HAS_VK_HEADER)
if(HAS_VK_HEADER)
target_compile_definitions(
Mw

View file

@ -257,8 +257,8 @@ void vulkan_setup(MwWidget handle) {
swapchainCreateInfo.imageExtent = (VkExtent2D){.width = ow, .height = oh},
swapchainCreateInfo.imageArrayLayers = 1,
swapchainCreateInfo.imageUsage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT |
VK_IMAGE_USAGE_TRANSFER_DST_BIT |
VK_IMAGE_USAGE_SAMPLED_BIT;
VK_IMAGE_USAGE_TRANSFER_DST_BIT |
VK_IMAGE_USAGE_SAMPLED_BIT;
// th is how we specify no transformation.
swapchainCreateInfo.preTransform = VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR;
swapchainCreateInfo.compositeAlpha = VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR;

View file

@ -257,6 +257,14 @@ struct _MwLLWaylandLayerSurface {
struct zwlr_layer_surface_v1* surface;
};
struct _MwLLWaylandSubsurface {
MwLL parent;
struct xdg_surface* xdg_surface;
struct wl_subsurface* subsurface;
struct wl_subcompositor* subcompositor;
};
/* Shared set of anything needed for a shm buffer. */
struct _MwLLWaylandShmBuffer {
struct wl_shm* shm;
@ -283,6 +291,7 @@ enum _MwLLWaylandType {
MwLL_WAYLAND_SUBLEVEL,
MwLL_WAYLAND_POPUP,
MwLL_WAYLAND_LAYER_SURFACE,
MwLL_WAYLAND_SUBSURFACE,
};
typedef struct wl_clipboard_device_context {
@ -315,6 +324,8 @@ struct _MwLLWayland {
struct _MwLLWaylandPopup* popup;
/* Pointer for data that's only loaded if the widget is a layer surface */
struct _MwLLWaylandLayerSurface* layer_surface;
/* Pointer for data that's only loaded if the widget is a subsurface */
struct _MwLLWaylandSubsurface* subsurface;
};
enum _MwLLWaylandType type;

View file

@ -1350,6 +1350,8 @@ static wayland_protocol_t* wl_subcompositor_setup(MwU32 name, struct _MwLLWaylan
(void)version;
if(wayland->type == MwLL_WAYLAND_TOPLEVEL) {
wayland->toplevel->scompositor = wl_registry_bind(wayland->registry, name, &wl_subcompositor_interface, 1);
} else if(wayland->type == MwLL_WAYLAND_SUBSURFACE) {
wayland->subsurface->subcompositor = wl_registry_bind(wayland->registry, name, &wl_subcompositor_interface, 1);
}
return NULL;
@ -1360,6 +1362,9 @@ static void wl_subcompositor_interface_destroy(struct _MwLLWayland* wayland, way
if(wayland->type == MwLL_WAYLAND_TOPLEVEL) {
wl_subcompositor_destroy(wayland->toplevel->scompositor);
}
if(wayland->type == MwLL_WAYLAND_SUBSURFACE) {
wl_subcompositor_destroy(wayland->subsurface->subcompositor);
}
}
/* xdg_wm_base setup function */
@ -1500,19 +1505,11 @@ void MwLLWaylandSetupCallbacks(struct _MwLLWayland* wayland) {
WL_INTERFACE(zwp_relative_pointer_manager_v1);
WL_INTERFACE(xdg_wm_base);
WL_INTERFACE(zwlr_layer_shell_v1); /* Only used for layer surface, but we use it always if it's turned into a tool window */
WL_INTERFACE(wl_subcompositor);
if(wayland->type == MwLL_WAYLAND_TOPLEVEL) {
WL_INTERFACE(zxdg_decoration_manager_v1);
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) {
WL_INTERFACE(wl_subcompositor);
WL_INTERFACE(wl_seat);
} else {
WL_INTERFACE(wl_subcompositor);
}
#undef WL_INTERFACE
}

View file

@ -366,6 +366,8 @@ static void setup_sublevel(MwLL parent, MwLL r, int x, int y) {
r->wayland.sublevel->xdg_surface = parent->wayland.toplevel->xdg_surface;
} else if(parent->wayland.type == MwLL_WAYLAND_SUBLEVEL) {
r->wayland.sublevel->xdg_surface = parent->wayland.sublevel->xdg_surface;
} else if(parent->wayland.type == MwLL_WAYLAND_SUBSURFACE) {
r->wayland.sublevel->xdg_surface = parent->wayland.subsurface->xdg_surface;
} else if(parent->wayland.type == MwLL_WAYLAND_POPUP) {
r->wayland.sublevel->xdg_surface = parent->wayland.popup->xdg_surface;
}
@ -396,6 +398,66 @@ static void destroy_sublevel(MwLL r) {
r->wayland.configured = MwFALSE;
}
/* Subsurface setup function */
static void setup_subsurface(MwLL parent, MwLL r, int x, int y) {
struct wl_compositor* compositor = parent->wayland.compositor;
struct wl_surface* parent_surface = parent->wayland.framebuffer.surface;
r->wayland.subsurface = malloc(sizeof(struct _MwLLWaylandSubsurface));
r->wayland.subsurface->parent = parent;
r->wayland.type = MwLL_WAYLAND_SUBSURFACE;
r->wayland.display = parent->wayland.display;
MwLLWaylandSetupCallbacks(&r->wayland);
r->wayland.registry = wl_display_get_registry(parent->wayland.display);
r->wayland.display = parent->wayland.display;
if(parent->wayland.type == MwLL_WAYLAND_TOPLEVEL) {
r->wayland.subsurface->xdg_surface = parent->wayland.toplevel->xdg_surface;
} else {
r->wayland.subsurface->xdg_surface = parent->wayland.subsurface->xdg_surface;
}
wl_registry_add_listener(r->wayland.registry, &r->wayland.registry_listener, r);
if(wl_display_roundtrip(r->wayland.display) == -1) {
printf("roundtrip failed: %d\n", wl_display_get_error(r->wayland.display));
raise(SIGTRAP);
return;
}
r->wayland.framebuffer.surface = wl_compositor_create_surface(compositor);
r->wayland.subsurface->subsurface = wl_subcompositor_get_subsurface(r->wayland.subsurface->subcompositor, r->wayland.framebuffer.surface, parent_surface);
wl_subsurface_set_desync(r->wayland.subsurface->subsurface);
wl_subsurface_set_position(r->wayland.subsurface->subsurface, x, y);
if(parent) {
wl_subsurface_place_above(r->wayland.subsurface->subsurface, parent->wayland.framebuffer.surface);
}
r->wayland.xkb_keymap = parent->wayland.xkb_keymap;
r->wayland.xkb_state = parent->wayland.xkb_state;
r->wayland.configured = MwTRUE;
MwLLWaylandFramebufferSetup(&r->wayland);
MwLLWaylandBackbufferSetup(&r->wayland);
}
/* Subsurface setup function */
static void destroy_subsurface(MwLL r) {
MwLLWaylandBackbufferDestroy(&r->wayland);
MwLLWaylandFramebufferDestroy(&r->wayland);
free(r->wayland.sublevel);
r->wayland.configured = MwFALSE;
}
static void popup_configure(void* data,
struct xdg_popup* xdg_popup,
int32_t x,
@ -830,6 +892,7 @@ static void widget_setup(MwLL r, MwLL parent, int x, int y, int width, int heigh
r->wayland.parent = parent;
r->wayland.valid = MwTRUE;
printf("type %d\n", ty);
if(ty == MwLL_WAYLAND_UNKNOWN) {
if(parent == NULL) {
setup_toplevel(r, x, y);
@ -862,6 +925,9 @@ static void widget_setup(MwLL r, MwLL parent, int x, int y, int width, int heigh
case MwLL_WAYLAND_LAYER_SURFACE:
setup_layer_surface(r, x, y, width, height);
break;
case MwLL_WAYLAND_SUBSURFACE:
setup_subsurface(parent, r, x, y);
break;
}
}
@ -1086,6 +1152,9 @@ static void MwLLSetXYImpl(MwLL handle, int x, int y) {
break;
case MwLL_WAYLAND_UNKNOWN:
break;
case MwLL_WAYLAND_SUBSURFACE:
wl_subsurface_set_position(handle->wayland.subsurface->subsurface, x, y);
break;
}
MwLLWaylandRegionSetup(handle);

View file

@ -351,13 +351,22 @@ static int vulkan_surface_setup(MwWidget handle, vulkan_t* o) {
if(handle->lowlevel->common.type == MwLLBackendWayland) {
LOAD_VK_FUNCTION(vkCreateWaylandSurfaceKHR);
VkWaylandSurfaceCreateInfoKHR createInfo = {
VkWaylandSurfaceCreateInfoKHR createInfo;
/* transition to a subsurface */
MwLLBeginStateChange(handle->lowlevel);
handle->lowlevel->wayland.changing = MwTRUE;
handle->lowlevel->wayland.type_to_be = MwLL_WAYLAND_SUBSURFACE;
MwLLEndStateChange(handle->lowlevel);
createInfo = (VkWaylandSurfaceCreateInfoKHR){
.sType = VK_STRUCTURE_TYPE_WAYLAND_SURFACE_CREATE_INFO_KHR,
.pNext = NULL,
.flags = 0,
.display = handle->lowlevel->wayland.display,
.surface = handle->lowlevel->wayland.framebuffer.surface,
};
VK_CMD(_vkCreateWaylandSurfaceKHR(o->vkInstance, &createInfo, NULL, &o->vkSurface));
}
#endif
@ -609,6 +618,7 @@ void MwVulkanConfigure(MwVulkanConfig* cfg) {
}
int MwVulkanSupported(void) {
printf("[vulkan support not copmiled]\n");
return 0;
}
#endif