Compare commits

...

6 Commits

Author SHA1 Message Date
Sebastian Dawid
55688f4ff4
Merge fb0828d828 into 162896e5b9 2025-11-14 18:35:51 +01:00
Doug Binks
162896e5b9
Wayland: free modules at end of terminate function
- Fixes #2744
2025-11-14 16:35:47 +00:00
Sebastian Emanuel Dawid
fb0828d828 Add option to enable building the WebGPU example
The example is now not built by default. Move code to fetch pre-compiled
`wgpu_native` library to `CMake/modules/FindWebGPU.cmake`.
2025-11-14 15:18:14 +01:00
Doug Binks
936307558e X11: Clamp w,h in glfwSetWindowSize to >= 1
-  prevents BadValue error and program exit
2025-11-08 10:37:52 +00:00
Drew Weymouth
4df5129529 X11: check crtcInfo for NULL when polling monitors 2025-11-07 17:39:26 +00:00
Ivor Wanders
6de70d8252 X11: Prevent BadWindow when creating small windows
The glfwCreateWindow function ensures that the width and height are
at least greater or equal than zero, but on X11 it is invalid to
create a window with dimensions that equal zero, see [1].

This change ensures that the dimensions passed to XCreateWindow are
at least 1 by 1.

This issue was detected in [2], where a call to glfwCreateWindow
was done to request a 1x1 window, with a _glfw.x11.contentScaleX of
less than 1.0 (0.958333) this results in a request for a 0x0 window
which then causes an BadWindow error from X11.

[1]: e003f52661/specs/libX11/CH03.xml (L1333-1337)
[2]: https://github.com/WerWolv/ImHex/pull/2390
2025-11-07 17:24:35 +00:00
8 changed files with 153 additions and 102 deletions

View File

@ -0,0 +1,84 @@
set(WebGPU_FOUND True) # since we fetch the depencency it will always be found
set(URL_ARCH)
if (CMAKE_SYSTEM_PROCESSOR STREQUAL "AMD64" OR CMAKE_SYSTEM_PROCESSOR STREQUAL "x86_64")
if (CMAKE_SIZEOF_VOID_P EQUAL 8)
set(URL_ARCH "x86_64")
elseif (CMAKE_SIZEOF_VOID_P EQUAL 4)
set(URL_ARCH "i686")
endif ()
elseif (CMAKE_SYSTEM_PROCESSOR MATCHES "^(aarch64|arm64|armv8|arm)$")
set(URL_ARCH "aarch64")
else ()
message(FATAL_ERROR "Unsopported CPU architecture: ${CMAKE_SYSTEM_PROCESSOR}")
endif ()
set(URL_OS)
set(WEBGPU_LIBNAME "libwgpu_native.so")
if (CMAKE_SYSTEM_NAME STREQUAL "Windows")
set(URL_OS "windows")
set(WEBGPU_LIBNAME "wgpu_native.dll")
if (MSVC)
set(URL_ARCH "${URL_ARCH}-msvc")
else ()
set(URL_ARCH "${URL_ARCH}-gnu")
endif ()
elseif (CMAKE_SYSTEM_NAME STREQUAL "Darwin")
set(WEBGPU_LIBNAME "libwgpu_native.dylib")
set(URL_OS "macos")
elseif (CMAKE_SYSTEM_NAME STREQUAL "Linux")
set(URL_OS "linux")
else ()
message(FATAL_ERROR "Unsopported OS: ${CMAKE_SYSTEM_NAME}")
endif ()
set(WEBGPU_URL "https://github.com/gfx-rs/wgpu-native/releases/download/v24.0.3.1/wgpu-${URL_OS}-${URL_ARCH}-release.zip")
include(FetchContent)
FetchContent_Declare(webgpu_bins
URL ${WEBGPU_URL}
)
FetchContent_MakeAvailable(webgpu_bins)
add_library(WebGPU::WebGPU SHARED IMPORTED GLOBAL)
set(WEBGPU_RUNTIME_LIB "${webgpu_bins_SOURCE_DIR}/lib/${WEBGPU_LIBNAME}")
set_target_properties(WebGPU::WebGPU PROPERTIES
IMPORTED_LOCATION "${WEBGPU_RUNTIME_LIB}"
)
target_include_directories(WebGPU::WebGPU INTERFACE
"${webgpu_bins_SOURCE_DIR}/include"
"${webgpu_bins_SOURCE_DIR}/include/webgpu"
)
if (CMAKE_SYSTEM_NAME STREQUAL "Windows")
if (MSVC)
set_target_properties(WebGPU::WebGPU PROPERTIES
IMPORTED_IMPLIB ${webgpu_bins_SOURCE_DIR}/lib/${WEBGPU_LIBNAME}.lib
)
else ()
set_target_properties(WebGPU::WebGPU PROPERTIES
IMPORTED_IMPLIB ${webgpu_bins_SOURCE_DIR}/lib/lib${WEBGPU_LIBNAME}.a
)
endif ()
elseif (CMAKE_SYSTEM_NAME STREQUAL "Linux")
set_target_properties(WebGPU::WebGPU PROPERTIES IMPORTED_NO_SONAME True)
else () # macOS
if (URL_ARCH STREQUAL "aarch64")
set(URL_ARCH "x86_64")
else ()
set(URL_ARCH "aarch64")
endif ()
set(WEBGPU_URL "https://github.com/gfx-rs/wgpu-native/releases/download/v24.0.3.1/wgpu-macos-${URL_ARCH}-release.zip")
FetchContent_Declare(webgpu_other_bins
URL ${WEBGPU_URL}
)
FetchContent_MakeAvailable(webgpu_other_bins)
set(WEBGPU_RUNTIME_LIB_OTHER "${webgpu_other_bins_SOURCE_DIR}/lib/${WEBGPU_LIBNAME}")
execute_process(COMMAND lipo -create ${WEBGPU_RUNTIME_LIB} ${WEBGPU_RUNTIME_LIB_OTHER} -output ${WEBGPU_RUNTIME_LIB})
endif ()
unset(URL_ARCH)
unset(URL_OS)
unset(WEBGPU_URL)
unset(WEBGPU_RUNTIME_LIB)
unset(WEBGPU_RUNTIME_LIB_OTHER)

View File

@ -282,10 +282,12 @@ video tutorials.
- Corentin Wallez
- Torsten Walluhn
- Patrick Walton
- Ivor Wanders
- Jim Wang
- Xo Wang
- Andre Weissflog
- Jay Weisskopf
- Drew Weymouth
- Frank Wille
- Andy Williams
- Joel Winarske

View File

@ -144,7 +144,13 @@ information on what to include when reporting a bug.
a modal to a fallback decoration
- [Wayland] Bugfix: The cursor position was not updated when clicking through
from a modal to the content area
- [Wayland] Bugfix: free modules at end of terminate function to resolve
potential segmentation fault (#2744)
- [X11] Bugfix: Running without a WM could trigger an assert (#2593,#2601,#2631)
- [X11] Bugfix: Occasional crash when an idle display awakes (#2766)
- [X11] Bugfix: Prevent BadWindow when creating small windows with a content scale
less than 1 (#2754)
- [X11] Bugfix: Clamp width and height to >= 1 to prevent BadValue error and app exit
- [Null] Added Vulkan 'window' surface creation via `VK_EXT_headless_surface`
- [Null] Added EGL context creation on Mesa via `EGL_MESA_platform_surfaceless`
- [EGL] Allowed native access on Wayland with `GLFW_CONTEXT_CREATION_API` set to

View File

@ -25,81 +25,9 @@ set(GETOPT "${GLFW_SOURCE_DIR}/deps/getopt.h"
set(TINYCTHREAD "${GLFW_SOURCE_DIR}/deps/tinycthread.h"
"${GLFW_SOURCE_DIR}/deps/tinycthread.c")
set(URL_ARCH)
if (CMAKE_SYSTEM_PROCESSOR STREQUAL "AMD64" OR CMAKE_SYSTEM_PROCESSOR STREQUAL "x86_64")
if (CMAKE_SIZEOF_VOID_P EQUAL 8)
set(URL_ARCH "x86_64")
elseif (CMAKE_SIZEOF_VOID_P EQUAL 4)
set(URL_ARCH "i686")
endif ()
elseif (CMAKE_SYSTEM_PROCESSOR MATCHES "^(aarch64|arm64|armv8|arm)$")
set(URL_ARCH "aarch64")
else ()
message(FATAL_ERROR "Unsopported CPU architecture: ${CMAKE_SYSTEM_PROCESSOR}")
endif ()
set(URL_OS)
set(WEBGPU_LIBNAME "libwgpu_native.so")
if (CMAKE_SYSTEM_NAME STREQUAL "Windows")
set(URL_OS "windows")
set(WEBGPU_LIBNAME "wgpu_native.dll")
if (MSVC)
set(URL_ARCH "${URL_ARCH}-msvc")
else ()
set(URL_ARCH "${URL_ARCH}-gnu")
endif ()
elseif (CMAKE_SYSTEM_NAME STREQUAL "Darwin")
set(WEBGPU_LIBNAME "libwgpu_native.dylib")
set(URL_OS "macos")
elseif (CMAKE_SYSTEM_NAME STREQUAL "Linux")
set(URL_OS "linux")
else ()
message(FATAL_ERROR "Unsopported OS: ${CMAKE_SYSTEM_NAME}")
endif ()
set(WEBGPU_URL "https://github.com/gfx-rs/wgpu-native/releases/download/v24.0.3.1/wgpu-${URL_OS}-${URL_ARCH}-release.zip")
include(FetchContent)
FetchContent_Declare(webgpu_bins
URL ${WEBGPU_URL}
)
FetchContent_MakeAvailable(webgpu_bins)
add_library(webgpu SHARED IMPORTED GLOBAL)
set(WEBGPU_RUNTIME_LIB "${webgpu_bins_SOURCE_DIR}/lib/${WEBGPU_LIBNAME}")
set_target_properties(webgpu PROPERTIES
IMPORTED_LOCATION "${WEBGPU_RUNTIME_LIB}"
)
target_include_directories(webgpu INTERFACE
"${webgpu_bins_SOURCE_DIR}/include"
"${webgpu_bins_SOURCE_DIR}/include/webgpu"
)
if (CMAKE_SYSTEM_NAME STREQUAL "Windows")
if (MSVC)
set_target_properties(webgpu PROPERTIES
IMPORTED_IMPLIB ${webgpu_bins_SOURCE_DIR}/lib/${WEBGPU_LIBNAME}.lib
)
else ()
set_target_properties(webgpu PROPERTIES
IMPORTED_IMPLIB ${webgpu_bins_SOURCE_DIR}/lib/lib${WEBGPU_LIBNAME}.a
)
endif ()
elseif (CMAKE_SYSTEM_NAME STREQUAL "Linux")
set_target_properties(webgpu PROPERTIES IMPORTED_NO_SONAME True)
else () # macOS
if (URL_ARCH STREQUAL "aarch64")
set(URL_ARCH "x86_64")
else ()
set(URL_ARCH "aarch64")
endif ()
set(WEBGPU_URL "https://github.com/gfx-rs/wgpu-native/releases/download/v24.0.3.1/wgpu-macos-${URL_ARCH}-release.zip")
FetchContent_Declare(webgpu_other_bins
URL ${WEBGPU_URL}
)
FetchContent_MakeAvailable(webgpu_other_bins)
set(WEBGPU_RUNTIME_LIB_OTHER "${webgpu_other_bins_SOURCE_DIR}/lib/${WEBGPU_LIBNAME}")
execute_process(COMMAND lipo -create ${WEBGPU_RUNTIME_LIB} ${WEBGPU_RUNTIME_LIB_OTHER} -output ${WEBGPU_RUNTIME_LIB})
option(BUILD_WEBGPU_EXAMPLE "Build WebGPU example" False)
if (BUILD_WEBGPU_EXAMPLE)
find_package(WebGPU)
endif ()
add_executable(boing WIN32 MACOSX_BUNDLE boing.c ${ICON} ${GLAD_GL})
@ -111,7 +39,9 @@ add_executable(sharing WIN32 MACOSX_BUNDLE sharing.c ${ICON} ${GLAD_GL})
add_executable(splitview WIN32 MACOSX_BUNDLE splitview.c ${ICON} ${GLAD_GL})
add_executable(triangle-opengl WIN32 MACOSX_BUNDLE triangle-opengl.c ${ICON} ${GLAD_GL})
add_executable(triangle-opengles WIN32 MACOSX_BUNDLE triangle-opengles.c ${ICON} ${GLAD_GLES2})
add_executable(triangle-webgpu WIN32 MACOSX_BUNDLE triangle-webgpu.c ${ICON})
if (BUILD_WEBGPU_EXAMPLE AND WebGPU_FOUND)
add_executable(triangle-webgpu WIN32 MACOSX_BUNDLE triangle-webgpu.c ${ICON})
endif ()
add_executable(wave WIN32 MACOSX_BUNDLE wave.c ${ICON} ${GLAD_GL})
add_executable(windows WIN32 MACOSX_BUNDLE windows.c ${ICON} ${GLAD_GL})
@ -120,10 +50,15 @@ if (RT_LIBRARY)
target_link_libraries(particles "${RT_LIBRARY}")
endif()
target_link_libraries(triangle-webgpu webgpu)
if (BUILD_WEBGPU_EXAMPLE AND WebGPU_FOUND)
target_link_libraries(triangle-webgpu WebGPU::WebGPU)
endif ()
set(GUI_ONLY_BINARIES boing gears heightmap particles sharing splitview
triangle-opengl triangle-opengles triangle-webgpu wave windows)
triangle-opengl triangle-opengles wave windows)
if (BUILD_WEBGPU_EXAMPLE AND WebGPU_FOUND)
list(APPEND GUI_ONLY_BINARIES triangle-webgpu)
endif ()
set(CONSOLE_BINARIES offscreen)
set_target_properties(${GUI_ONLY_BINARIES} ${CONSOLE_BINARIES} PROPERTIES
@ -148,7 +83,9 @@ if (APPLE)
set_target_properties(sharing PROPERTIES MACOSX_BUNDLE_BUNDLE_NAME "Sharing")
set_target_properties(triangle-opengl PROPERTIES MACOSX_BUNDLE_BUNDLE_NAME "OpenGL Triangle")
set_target_properties(triangle-opengles PROPERTIES MACOSX_BUNDLE_BUNDLE_NAME "OpenGL ES Triangle")
set_target_properties(triangle-webgpu PROPERTIES MACOSX_BUNDLE_BUNDLE_NAME "WebGPU Triangle")
if (BUILD_WEBGPU_EXAMPLE AND WebGPU_FOUND)
set_target_properties(triangle-webgpu PROPERTIES MACOSX_BUNDLE_BUNDLE_NAME "WebGPU Triangle")
endif ()
set_target_properties(splitview PROPERTIES MACOSX_BUNDLE_BUNDLE_NAME "SplitView")
set_target_properties(wave PROPERTIES MACOSX_BUNDLE_BUNDLE_NAME "Wave")
set_target_properties(windows PROPERTIES MACOSX_BUNDLE_BUNDLE_NAME "Windows")

View File

@ -555,7 +555,8 @@ void _glfwTerminateEGL(void)
_glfw.egl.display = EGL_NO_DISPLAY;
}
if (_glfw.egl.handle)
// Free modules only after all wayland termination functions are called
if (_glfw.egl.handle && _glfw.platform.platformID != GLFW_PLATFORM_WAYLAND)
{
_glfwPlatformFreeModule(_glfw.egl.handle);
_glfw.egl.handle = NULL;

View File

@ -908,18 +908,6 @@ void _glfwTerminateWayland(void)
libdecor_unref(_glfw.wl.libdecor.context);
}
if (_glfw.wl.libdecor.handle)
{
_glfwPlatformFreeModule(_glfw.wl.libdecor.handle);
_glfw.wl.libdecor.handle = NULL;
}
if (_glfw.wl.egl.handle)
{
_glfwPlatformFreeModule(_glfw.wl.egl.handle);
_glfw.wl.egl.handle = NULL;
}
if (_glfw.wl.xkb.composeState)
xkb_compose_state_unref(_glfw.wl.xkb.composeState);
if (_glfw.wl.xkb.keymap)
@ -928,21 +916,11 @@ void _glfwTerminateWayland(void)
xkb_state_unref(_glfw.wl.xkb.state);
if (_glfw.wl.xkb.context)
xkb_context_unref(_glfw.wl.xkb.context);
if (_glfw.wl.xkb.handle)
{
_glfwPlatformFreeModule(_glfw.wl.xkb.handle);
_glfw.wl.xkb.handle = NULL;
}
if (_glfw.wl.cursorTheme)
wl_cursor_theme_destroy(_glfw.wl.cursorTheme);
if (_glfw.wl.cursorThemeHiDPI)
wl_cursor_theme_destroy(_glfw.wl.cursorThemeHiDPI);
if (_glfw.wl.cursor.handle)
{
_glfwPlatformFreeModule(_glfw.wl.cursor.handle);
_glfw.wl.cursor.handle = NULL;
}
for (unsigned int i = 0; i < _glfw.wl.offerCount; i++)
wl_data_offer_destroy(_glfw.wl.offers[i].offer);
@ -1002,6 +980,36 @@ void _glfwTerminateWayland(void)
if (_glfw.wl.cursorTimerfd >= 0)
close(_glfw.wl.cursorTimerfd);
// Free modules only after all wayland termination functions are called
if (_glfw.egl.handle)
{
_glfwPlatformFreeModule(_glfw.egl.handle);
_glfw.egl.handle = NULL;
}
if (_glfw.wl.libdecor.handle)
{
_glfwPlatformFreeModule(_glfw.wl.libdecor.handle);
_glfw.wl.libdecor.handle = NULL;
}
if (_glfw.wl.egl.handle)
{
_glfwPlatformFreeModule(_glfw.wl.egl.handle);
_glfw.wl.egl.handle = NULL;
}
if (_glfw.wl.xkb.handle)
{
_glfwPlatformFreeModule(_glfw.wl.xkb.handle);
_glfw.wl.xkb.handle = NULL;
}
if (_glfw.wl.cursor.handle)
{
_glfwPlatformFreeModule(_glfw.wl.cursor.handle);
_glfw.wl.cursor.handle = NULL;
}
_glfw_free(_glfw.wl.clipboardString);
}

View File

@ -151,6 +151,11 @@ void _glfwPollMonitorsX11(void)
}
XRRCrtcInfo* ci = XRRGetCrtcInfo(_glfw.x11.display, sr, oi->crtc);
if (!ci) {
XRRFreeOutputInfo(oi);
continue;
}
if (ci->rotation == RR_Rotate_90 || ci->rotation == RR_Rotate_270)
{
widthMM = oi->mm_height;

View File

@ -576,6 +576,10 @@ static GLFWbool createNativeWindow(_GLFWwindow* window,
height *= _glfw.x11.contentScaleY;
}
// The dimensions must be nonzero, or a BadValue error results.
width = _glfw_max(1, width);
height = _glfw_max(1, height);
int xpos = 0, ypos = 0;
if (wndconfig->xpos != GLFW_ANY_POSITION && wndconfig->ypos != GLFW_ANY_POSITION)
@ -2203,6 +2207,10 @@ void _glfwGetWindowSizeX11(_GLFWwindow* window, int* width, int* height)
void _glfwSetWindowSizeX11(_GLFWwindow* window, int width, int height)
{
// The dimensions must be nonzero, or a BadValue error results.
width = _glfw_max(1, width);
height = _glfw_max(1, height);
if (window->monitor)
{
if (window->monitor->window == window)