From 8e705b19e47645092a15b85b4bd7793aa097f3d6 Mon Sep 17 00:00:00 2001 From: Dmitry Mozgin Date: Tue, 3 Mar 2026 11:11:41 +0300 Subject: [PATCH 1/5] Update LibraryConfigurations.cmake (#5617) Typo in find_dependency --- cmake/LibraryConfigurations.cmake | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmake/LibraryConfigurations.cmake b/cmake/LibraryConfigurations.cmake index 5ccd74485..2fe05827a 100644 --- a/cmake/LibraryConfigurations.cmake +++ b/cmake/LibraryConfigurations.cmake @@ -143,7 +143,7 @@ elseif ("${PLATFORM}" MATCHES "SDL") message(STATUS "Found SDL2 via find_package()") set(PLATFORM_CPP "PLATFORM_DESKTOP_SDL") set(LIBS_PUBLIC SDL2::SDL2) - set(RAYLIB_DEPENDENCIES "${RAYLIB_DEPENDENCIES}\nfind_dependency(SDL3 REQUIRED)") + set(RAYLIB_DEPENDENCIES "${RAYLIB_DEPENDENCIES}\nfind_dependency(SDL2 REQUIRED)") add_compile_definitions(USING_SDL2_PACKAGE) endif() endif() From 9ae34d2c4bdaa8735b4527fde26d3bec78a80499 Mon Sep 17 00:00:00 2001 From: Ray Date: Tue, 3 Mar 2026 11:13:33 +0100 Subject: [PATCH 2/5] Update ROADMAP.md --- ROADMAP.md | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/ROADMAP.md b/ROADMAP.md index a49cdbfd7..b9392fa66 100644 --- a/ROADMAP.md +++ b/ROADMAP.md @@ -16,10 +16,9 @@ _Current version of raylib is complete and functional but there is always room f **raylib 5.x** - [ ] `rcore`: Support additional platforms: iOS, consoles? - [x] `rcore_web`: Avoid GLFW dependency, functionality can be directly implemented using emscripten SDK - - [ ] `rlgl`: Review GLSL shaders naming conventions for consistency + - [x] `rlgl`: Review GLSL shaders naming conventions for consistency - [ ] `textures`: Improve compressed textures support, loading and saving - - [ ] `rmodels`: Improve 3d objects loading, specially animations (obj, gltf) - - [ ] `raudio`: Implement miniaudio high-level provided features + - [x] `rmodels`: Improve 3d objects loading, specially animations (obj, gltf) - [x] `examples`: Review all examples, add more and better code explanations - [x] Software renderer backend? Maybe using `Image` provided API From b68dbaa8af5c5d7b783f09c3b54daafdd77231b9 Mon Sep 17 00:00:00 2001 From: Thomas Anderson <5776225+CrackedPixel@users.noreply.github.com> Date: Tue, 3 Mar 2026 11:55:50 -0600 Subject: [PATCH 3/5] [tools/rexm] Update nextCatIndex (#5616) * removed +1 offset * update from PR feedback --- tools/rexm/rexm.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/rexm/rexm.c b/tools/rexm/rexm.c index 30ef6411f..011102ce1 100644 --- a/tools/rexm/rexm.c +++ b/tools/rexm/rexm.c @@ -1040,7 +1040,7 @@ int main(int argc, char *argv[]) // Find position to add new example on list, just before the following category // Category order: core, shapes, textures, text, models, shaders, audio int exListNextCatIndex = -1; - if (nextCatIndex != -1) exListNextCatIndex = TextFindIndex(exList, exCategories[nextCatIndex]); + if (nextCatIndex != -1) exListNextCatIndex = TextFindIndex(exList, TextFormat("\n%s", exCategories[nextCatIndex])) + 1; else exListNextCatIndex = exListLen; // EOF strncpy(exListUpdated, exList, exListNextCatIndex); From 37a852a7aeb96df84c89f1bc3bb0ad7bada828e2 Mon Sep 17 00:00:00 2001 From: Maicon Santana Date: Tue, 3 Mar 2026 17:57:34 +0000 Subject: [PATCH 4/5] [web] Add clipboard image implementation for web (#5614) * Add clipboard image implementation for web * Making sure that are not malloc empty string or image --- src/platforms/rcore_web.c | 101 +++++++++++++++++++++----- src/platforms/rcore_web_emscripten.c | 103 +++++++++++++++++++++------ 2 files changed, 164 insertions(+), 40 deletions(-) diff --git a/src/platforms/rcore_web.c b/src/platforms/rcore_web.c index 5fd91eff6..6b9c55534 100644 --- a/src/platforms/rcore_web.c +++ b/src/platforms/rcore_web.c @@ -801,35 +801,98 @@ void SetClipboardText(const char *text) else EM_ASM({ navigator.clipboard.writeText(UTF8ToString($0)); }, text); } +// Async EM_JS to be able to await clickboard read asynchronous function +EM_ASYNC_JS(void, RequestClipboardData, (void), { + if (navigator.clipboard && window.isSecureContext) { + let items = await navigator.clipboard.read(); + for (const item of items) { + + // Check if this item contains plain text or image + if (item.types.includes("text/plain")) { + const blob = await item.getType("text/plain"); + const text = await blob.text(); + window._lastClipboardString = text; + } + else if (item.types.find(t => t.startsWith("image/"))) { + const blob = await item.getType(item.types.find(t => t.startsWith("image/"))); + const bitmap = await createImageBitmap(blob); + + const canvas = document.createElement('canvas'); + canvas.width = bitmap.width; + canvas.height = bitmap.height; + const ctx = canvas.getContext('2d'); + ctx.drawImage(bitmap, 0, 0); + + const imgData = ctx.getImageData(0, 0, canvas.width, canvas.height).data; + + // Store image and data for the Fetch function + window._lastImgWidth = canvas.width; + window._lastImgHeight = canvas.height; + window._lastImgData = imgData; + } + } + } else { + console.warn("Clipboard read() requires HTTPS/Localhost"); + } +}); + +// Returns the string created by RequestClipboardData from JS memory to Emscripten C memory +EM_JS(char*, GetLastPastedText, (void), { + var str = window._lastClipboardString || ""; + var length = lengthBytesUTF8(str) + 1; + if (length > 1) { + var ptr = _malloc(length); + stringToUTF8(str, ptr, length); + return ptr; + } + return 0; +}); + +// Returns the image created by RequestClipboardData from JS memory to Emscripten C memory +EM_JS(unsigned char*, GetLastPastedImage, (int* width, int* height), { + if (window._lastImgData) { + const data = window._lastImgData; + if (data.length > 0) { + const ptr = _malloc(data.length); + HEAPU8.set(data, ptr); + + // Set the width and height via the pointers passed from C + // HEAP32 handles the 4-byte integers + if (width) setValue(width, window._lastImgWidth, 'i32'); + if (height) setValue(height, window._lastImgHeight, 'i32'); + + // Clear the JS buffer so we don't fetch the same image twice + window._lastImgData = null; + + return ptr; + } + } + return 0; +}); + // Get clipboard text content // NOTE: returned string is allocated and freed by GLFW const char *GetClipboardText(void) { -/* - // Accessing clipboard data from browser is tricky due to security reasons - // The method to use is navigator.clipboard.readText() but this is an asynchronous method - // that will return at some moment after the function is called with the required data - emscripten_run_script_string("navigator.clipboard.readText() \ - .then(text => { document.getElementById('clipboard').innerText = text; console.log('Pasted content: ', text); }) \ - .catch(err => { console.error('Failed to read clipboard contents: ', err); });" - ); - - // The main issue is getting that data, one approach could be using ASYNCIFY and wait - // for the data but it requires adding Asyncify emscripten library on compilation - - // Another approach could be just copy the data in a HTML text field and try to retrieve it - // later on if available... and clean it for future accesses -*/ - return NULL; + RequestClipboardData(); + return GetLastPastedText(); } // Get clipboard image Image GetClipboardImage(void) { Image image = { 0 }; - - TRACELOG(LOG_WARNING, "GetClipboardImage() not implemented on target platform"); - + int w = 0, h = 0; + RequestClipboardData(); + unsigned char* data = GetLastPastedImage(&w, &h); + if (data != NULL) { + image.data = data; + image.width = w; + image.height = h; + image.mipmaps = 1; + image.format = PIXELFORMAT_UNCOMPRESSED_R8G8B8A8; + } + return image; } diff --git a/src/platforms/rcore_web_emscripten.c b/src/platforms/rcore_web_emscripten.c index 995881233..dcee45865 100644 --- a/src/platforms/rcore_web_emscripten.c +++ b/src/platforms/rcore_web_emscripten.c @@ -779,37 +779,98 @@ void SetClipboardText(const char *text) else EM_ASM({ navigator.clipboard.writeText(UTF8ToString($0)); }, text); } +// Async EM_JS to be able to await clickboard read asynchronous function +EM_ASYNC_JS(void, RequestClipboardData, (void), { + if (navigator.clipboard && window.isSecureContext) { + let items = await navigator.clipboard.read(); + for (const item of items) { + + // Check if this item contains plain text or image + if (item.types.includes("text/plain")) { + const blob = await item.getType("text/plain"); + const text = await blob.text(); + window._lastClipboardString = text; + } + else if (item.types.find(t => t.startsWith("image/"))) { + const blob = await item.getType(item.types.find(t => t.startsWith("image/"))); + const bitmap = await createImageBitmap(blob); + + const canvas = document.createElement('canvas'); + canvas.width = bitmap.width; + canvas.height = bitmap.height; + const ctx = canvas.getContext('2d'); + ctx.drawImage(bitmap, 0, 0); + + const imgData = ctx.getImageData(0, 0, canvas.width, canvas.height).data; + + // Store image and data for the Fetch function + window._lastImgWidth = canvas.width; + window._lastImgHeight = canvas.height; + window._lastImgData = imgData; + } + } + } else { + console.warn("Clipboard read() requires HTTPS/Localhost"); + } +}); + +// Returns the string created by RequestClipboardData from JS memory to Emscripten C memory +EM_JS(char*, GetLastPastedText, (void), { + var str = window._lastClipboardString || ""; + var length = lengthBytesUTF8(str) + 1; + if (length > 1) { + var ptr = _malloc(length); + stringToUTF8(str, ptr, length); + return ptr; + } + return 0; +}); + +// Returns the image created by RequestClipboardData from JS memory to Emscripten C memory +EM_JS(unsigned char*, GetLastPastedImage, (int* width, int* height), { + if (window._lastImgData) { + const data = window._lastImgData; + if (data.length > 0) { + const ptr = _malloc(data.length); + HEAPU8.set(data, ptr); + + // Set the width and height via the pointers passed from C + // HEAP32 handles the 4-byte integers + if (width) setValue(width, window._lastImgWidth, 'i32'); + if (height) setValue(height, window._lastImgHeight, 'i32'); + + // Clear the JS buffer so we don't fetch the same image twice + window._lastImgData = null; + + return ptr; + } + } + return 0; +}); + // Get clipboard text content // NOTE: returned string is allocated and freed by GLFW const char *GetClipboardText(void) { -/* - // Accessing clipboard data from browser is tricky due to security reasons - // The method to use is navigator.clipboard.readText() but this is an asynchronous method - // that will return at some moment after the function is called with the required data - emscripten_run_script_string("navigator.clipboard.readText() \ - .then(text => { document.getElementById('clipboard').innerText = text; console.log('Pasted content: ', text); }) \ - .catch(err => { console.error('Failed to read clipboard contents: ', err); });" - ); - - // The main issue is getting that data, one approach could be using ASYNCIFY and wait - // for the data but it requires adding Asyncify emscripten library on compilation - - // Another approach could be just copy the data in a HTML text field and try to retrieve it - // later on if available... and clean it for future accesses -*/ - return NULL; + RequestClipboardData(); + return GetLastPastedText(); } // Get clipboard image Image GetClipboardImage(void) { Image image = { 0 }; - - // NOTE: In theory, the new navigator.clipboard.read() can be used to return arbitrary data from clipboard (2024) - // REF: https://developer.mozilla.org/en-US/docs/Web/API/Clipboard/read - TRACELOG(LOG_WARNING, "GetClipboardImage() not implemented on target platform"); - + int w = 0, h = 0; + RequestClipboardData(); + unsigned char* data = GetLastPastedImage(&w, &h); + if (data != NULL) { + image.data = data; + image.width = w; + image.height = h; + image.mipmaps = 1; + image.format = PIXELFORMAT_UNCOMPRESSED_R8G8B8A8; + } + return image; } From 70a1a57a12845d2dd57d22a656a6aa5a61900bd7 Mon Sep 17 00:00:00 2001 From: Dmitry Mozgin Date: Tue, 3 Mar 2026 21:04:06 +0300 Subject: [PATCH 5/5] Remove unnecessary define from raylib_opengl_interop.c (#5618) --- examples/others/raylib_opengl_interop.c | 1 - 1 file changed, 1 deletion(-) diff --git a/examples/others/raylib_opengl_interop.c b/examples/others/raylib_opengl_interop.c index 935eb87f8..540a623ab 100644 --- a/examples/others/raylib_opengl_interop.c +++ b/examples/others/raylib_opengl_interop.c @@ -30,7 +30,6 @@ #if defined(PLATFORM_DESKTOP) || defined(PLATFORM_DESKTOP_SDL) #if defined(GRAPHICS_API_OPENGL_ES2) - #define GLAD_GLES2_IMPLEMENTATION #include "glad_gles2.h" // Required for: OpenGL functionality #define glGenVertexArrays glGenVertexArraysOES #define glBindVertexArray glBindVertexArrayOES