lib/glfw/0001-wayland-static-link.patch
$ cat 0001-wayland-static-link.patch
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index 1057a6f..62965ca 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -160,13 +160,19 @@ endif()
 if (GLFW_BUILD_WAYLAND)
     include(FindPkgConfig)
 
-    pkg_check_modules(Wayland REQUIRED
+    pkg_check_modules(Wayland REQUIRED IMPORTED_TARGET
         wayland-client>=0.2.7
         wayland-cursor>=0.2.7
         wayland-egl>=0.2.7
         xkbcommon>=0.5.0)
 
     target_include_directories(glfw PRIVATE ${Wayland_INCLUDE_DIRS})
+    target_link_libraries(glfw PRIVATE PkgConfig::Wayland)
+    list(APPEND glfw_PKG_DEPS
+         "wayland-client"
+         "wayland-cursor"
+         "wayland-egl"
+         "xkbcommon")
 
     if (NOT CMAKE_SYSTEM_NAME STREQUAL "Linux")
         find_package(EpollShim)
@@ -365,4 +371,3 @@ if (GLFW_INSTALL)
             ARCHIVE DESTINATION "${CMAKE_INSTALL_LIBDIR}"
             LIBRARY DESTINATION "${CMAKE_INSTALL_LIBDIR}")
 endif()
-
diff --git a/src/init.c b/src/init.c
index 532264e..3bb8c1d 100644
--- a/src/init.c
+++ b/src/init.c
@@ -64,7 +64,7 @@ static _GLFWinitconfig _glfwInitHints =
     },
     .wl =
     {
-        .libdecorMode = GLFW_WAYLAND_PREFER_LIBDECOR
+        .libdecorMode = GLFW_WAYLAND_DISABLE_LIBDECOR
     },
 };
 
@@ -525,4 +525,3 @@ GLFWAPI GLFWerrorfun glfwSetErrorCallback(GLFWerrorfun cbfun)
     _GLFW_SWAP(GLFWerrorfun, _glfwErrorCallback, cbfun);
     return cbfun;
 }
-
diff --git a/src/wl_init.c b/src/wl_init.c
index 3aff476..5415c26 100644
--- a/src/wl_init.c
+++ b/src/wl_init.c
@@ -91,6 +91,185 @@
 #include "idle-inhibit-unstable-v1-client-protocol-code.h"
 #undef types
 
+#undef wl_display_flush
+#undef wl_display_cancel_read
+#undef wl_display_dispatch_pending
+#undef wl_display_read_events
+#undef wl_display_disconnect
+#undef wl_display_roundtrip
+#undef wl_display_get_fd
+#undef wl_display_prepare_read
+#undef wl_proxy_marshal
+#undef wl_proxy_add_listener
+#undef wl_proxy_destroy
+#undef wl_proxy_marshal_constructor
+#undef wl_proxy_marshal_constructor_versioned
+#undef wl_proxy_get_user_data
+#undef wl_proxy_set_user_data
+#undef wl_proxy_get_tag
+#undef wl_proxy_set_tag
+#undef wl_proxy_get_version
+#undef wl_proxy_marshal_flags
+#undef wl_cursor_theme_load
+#undef wl_cursor_theme_destroy
+#undef wl_cursor_theme_get_cursor
+#undef wl_cursor_image_get_buffer
+#undef wl_egl_window_create
+#undef wl_egl_window_destroy
+#undef wl_egl_window_resize
+#undef xkb_context_new
+#undef xkb_context_unref
+#undef xkb_keymap_new_from_string
+#undef xkb_keymap_unref
+#undef xkb_keymap_mod_get_index
+#undef xkb_keymap_key_repeats
+#undef xkb_keymap_key_get_syms_by_level
+#undef xkb_state_new
+#undef xkb_state_unref
+#undef xkb_state_key_get_syms
+#undef xkb_state_update_mask
+#undef xkb_state_key_get_layout
+#undef xkb_state_mod_index_is_active
+#undef xkb_compose_table_new_from_locale
+#undef xkb_compose_table_unref
+#undef xkb_compose_state_new
+#undef xkb_compose_state_unref
+#undef xkb_compose_state_feed
+#undef xkb_compose_state_get_status
+#undef xkb_compose_state_get_one_sym
+
+extern struct wl_cursor_theme* wl_cursor_theme_load(const char* name,
+                                                    int size,
+                                                    struct wl_shm* shm);
+extern void wl_cursor_theme_destroy(struct wl_cursor_theme* theme);
+extern struct wl_cursor* wl_cursor_theme_get_cursor(struct wl_cursor_theme* theme,
+                                                    const char* name);
+extern struct wl_buffer* wl_cursor_image_get_buffer(struct wl_cursor_image* image);
+
+extern struct wl_egl_window* wl_egl_window_create(struct wl_surface* surface,
+                                                  int width,
+                                                  int height);
+extern void wl_egl_window_destroy(struct wl_egl_window* egl_window);
+extern void wl_egl_window_resize(struct wl_egl_window* egl_window,
+                                 int width,
+                                 int height,
+                                 int dx,
+                                 int dy);
+
+static void loadWaylandClientFunctions(void)
+{
+    _glfw.wl.client.handle = NULL;
+    _glfw.wl.client.display_flush = wl_display_flush;
+    _glfw.wl.client.display_cancel_read = wl_display_cancel_read;
+    _glfw.wl.client.display_dispatch_pending = wl_display_dispatch_pending;
+    _glfw.wl.client.display_read_events = wl_display_read_events;
+    _glfw.wl.client.display_disconnect = wl_display_disconnect;
+    _glfw.wl.client.display_roundtrip = wl_display_roundtrip;
+    _glfw.wl.client.display_get_fd = wl_display_get_fd;
+    _glfw.wl.client.display_prepare_read = wl_display_prepare_read;
+    _glfw.wl.client.proxy_marshal = wl_proxy_marshal;
+    _glfw.wl.client.proxy_add_listener = wl_proxy_add_listener;
+    _glfw.wl.client.proxy_destroy = wl_proxy_destroy;
+    _glfw.wl.client.proxy_marshal_constructor = wl_proxy_marshal_constructor;
+    _glfw.wl.client.proxy_marshal_constructor_versioned =
+        wl_proxy_marshal_constructor_versioned;
+    _glfw.wl.client.proxy_get_user_data = wl_proxy_get_user_data;
+    _glfw.wl.client.proxy_set_user_data = wl_proxy_set_user_data;
+    _glfw.wl.client.proxy_get_tag = wl_proxy_get_tag;
+    _glfw.wl.client.proxy_set_tag = wl_proxy_set_tag;
+    _glfw.wl.client.proxy_get_version = wl_proxy_get_version;
+    _glfw.wl.client.proxy_marshal_flags = wl_proxy_marshal_flags;
+}
+
+static void loadWaylandCursorFunctions(void)
+{
+    _glfw.wl.cursor.handle = NULL;
+    _glfw.wl.cursor.theme_load = wl_cursor_theme_load;
+    _glfw.wl.cursor.theme_destroy = wl_cursor_theme_destroy;
+    _glfw.wl.cursor.theme_get_cursor = wl_cursor_theme_get_cursor;
+    _glfw.wl.cursor.image_get_buffer = wl_cursor_image_get_buffer;
+}
+
+static void loadWaylandEGLFunctions(void)
+{
+    _glfw.wl.egl.handle = NULL;
+    _glfw.wl.egl.window_create = wl_egl_window_create;
+    _glfw.wl.egl.window_destroy = wl_egl_window_destroy;
+    _glfw.wl.egl.window_resize = wl_egl_window_resize;
+}
+
+static void loadWaylandXKBFunctions(void)
+{
+    _glfw.wl.xkb.handle = NULL;
+    _glfw.wl.xkb.context_new = xkb_context_new;
+    _glfw.wl.xkb.context_unref = xkb_context_unref;
+    _glfw.wl.xkb.keymap_new_from_string = xkb_keymap_new_from_string;
+    _glfw.wl.xkb.keymap_unref = xkb_keymap_unref;
+    _glfw.wl.xkb.keymap_mod_get_index = xkb_keymap_mod_get_index;
+    _glfw.wl.xkb.keymap_key_repeats = xkb_keymap_key_repeats;
+    _glfw.wl.xkb.keymap_key_get_syms_by_level = xkb_keymap_key_get_syms_by_level;
+    _glfw.wl.xkb.state_new = xkb_state_new;
+    _glfw.wl.xkb.state_unref = xkb_state_unref;
+    _glfw.wl.xkb.state_key_get_syms = xkb_state_key_get_syms;
+    _glfw.wl.xkb.state_update_mask = xkb_state_update_mask;
+    _glfw.wl.xkb.state_key_get_layout = xkb_state_key_get_layout;
+    _glfw.wl.xkb.state_mod_index_is_active = xkb_state_mod_index_is_active;
+    _glfw.wl.xkb.compose_table_new_from_locale = xkb_compose_table_new_from_locale;
+    _glfw.wl.xkb.compose_table_unref = xkb_compose_table_unref;
+    _glfw.wl.xkb.compose_state_new = xkb_compose_state_new;
+    _glfw.wl.xkb.compose_state_unref = xkb_compose_state_unref;
+    _glfw.wl.xkb.compose_state_feed = xkb_compose_state_feed;
+    _glfw.wl.xkb.compose_state_get_status = xkb_compose_state_get_status;
+    _glfw.wl.xkb.compose_state_get_one_sym = xkb_compose_state_get_one_sym;
+}
+
+#define wl_display_flush _glfw.wl.client.display_flush
+#define wl_display_cancel_read _glfw.wl.client.display_cancel_read
+#define wl_display_dispatch_pending _glfw.wl.client.display_dispatch_pending
+#define wl_display_read_events _glfw.wl.client.display_read_events
+#define wl_display_disconnect _glfw.wl.client.display_disconnect
+#define wl_display_roundtrip _glfw.wl.client.display_roundtrip
+#define wl_display_get_fd _glfw.wl.client.display_get_fd
+#define wl_display_prepare_read _glfw.wl.client.display_prepare_read
+#define wl_proxy_marshal _glfw.wl.client.proxy_marshal
+#define wl_proxy_add_listener _glfw.wl.client.proxy_add_listener
+#define wl_proxy_destroy _glfw.wl.client.proxy_destroy
+#define wl_proxy_marshal_constructor _glfw.wl.client.proxy_marshal_constructor
+#define wl_proxy_marshal_constructor_versioned _glfw.wl.client.proxy_marshal_constructor_versioned
+#define wl_proxy_get_user_data _glfw.wl.client.proxy_get_user_data
+#define wl_proxy_set_user_data _glfw.wl.client.proxy_set_user_data
+#define wl_proxy_get_tag _glfw.wl.client.proxy_get_tag
+#define wl_proxy_set_tag _glfw.wl.client.proxy_set_tag
+#define wl_proxy_get_version _glfw.wl.client.proxy_get_version
+#define wl_proxy_marshal_flags _glfw.wl.client.proxy_marshal_flags
+#define wl_cursor_theme_load _glfw.wl.cursor.theme_load
+#define wl_cursor_theme_destroy _glfw.wl.cursor.theme_destroy
+#define wl_cursor_theme_get_cursor _glfw.wl.cursor.theme_get_cursor
+#define wl_cursor_image_get_buffer _glfw.wl.cursor.image_get_buffer
+#define wl_egl_window_create _glfw.wl.egl.window_create
+#define wl_egl_window_destroy _glfw.wl.egl.window_destroy
+#define wl_egl_window_resize _glfw.wl.egl.window_resize
+#define xkb_context_new _glfw.wl.xkb.context_new
+#define xkb_context_unref _glfw.wl.xkb.context_unref
+#define xkb_keymap_new_from_string _glfw.wl.xkb.keymap_new_from_string
+#define xkb_keymap_unref _glfw.wl.xkb.keymap_unref
+#define xkb_keymap_mod_get_index _glfw.wl.xkb.keymap_mod_get_index
+#define xkb_keymap_key_repeats _glfw.wl.xkb.keymap_key_repeats
+#define xkb_keymap_key_get_syms_by_level _glfw.wl.xkb.keymap_key_get_syms_by_level
+#define xkb_state_new _glfw.wl.xkb.state_new
+#define xkb_state_unref _glfw.wl.xkb.state_unref
+#define xkb_state_key_get_syms _glfw.wl.xkb.state_key_get_syms
+#define xkb_state_update_mask _glfw.wl.xkb.state_update_mask
+#define xkb_state_key_get_layout _glfw.wl.xkb.state_key_get_layout
+#define xkb_state_mod_index_is_active _glfw.wl.xkb.state_mod_index_is_active
+#define xkb_compose_table_new_from_locale _glfw.wl.xkb.compose_table_new_from_locale
+#define xkb_compose_table_unref _glfw.wl.xkb.compose_table_unref
+#define xkb_compose_state_new _glfw.wl.xkb.compose_state_new
+#define xkb_compose_state_unref _glfw.wl.xkb.compose_state_unref
+#define xkb_compose_state_feed _glfw.wl.xkb.compose_state_feed
+#define xkb_compose_state_get_status _glfw.wl.xkb.compose_state_get_status
+#define xkb_compose_state_get_one_sym _glfw.wl.xkb.compose_state_get_one_sym
+
 static void wmBaseHandlePing(void* userData,
                              struct xdg_wm_base* wmBase,
                              uint32_t serial)
@@ -511,44 +690,17 @@ GLFWbool _glfwConnectWayland(int platformID, _GLFWplatform* platform)
         .createWindowSurface = _glfwCreateWindowSurfaceWayland
     };
 
-    void* module = _glfwPlatformLoadModule("libwayland-client.so.0");
-    if (!module)
-    {
-        if (platformID == GLFW_PLATFORM_WAYLAND)
-        {
-            _glfwInputError(GLFW_PLATFORM_ERROR,
-                            "Wayland: Failed to load libwayland-client");
-        }
-
-        return GLFW_FALSE;
-    }
-
-    PFN_wl_display_connect wl_display_connect = (PFN_wl_display_connect)
-        _glfwPlatformGetModuleSymbol(module, "wl_display_connect");
-    if (!wl_display_connect)
-    {
-        if (platformID == GLFW_PLATFORM_WAYLAND)
-        {
-            _glfwInputError(GLFW_PLATFORM_ERROR,
-                            "Wayland: Failed to load libwayland-client entry point");
-        }
-
-        _glfwPlatformFreeModule(module);
-        return GLFW_FALSE;
-    }
-
     struct wl_display* display = wl_display_connect(NULL);
     if (!display)
     {
         if (platformID == GLFW_PLATFORM_WAYLAND)
             _glfwInputError(GLFW_PLATFORM_ERROR, "Wayland: Failed to connect to display");
 
-        _glfwPlatformFreeModule(module);
         return GLFW_FALSE;
     }
 
     _glfw.wl.display = display;
-    _glfw.wl.client.handle = module;
+    _glfw.wl.client.handle = NULL;
 
     *platform = wayland;
     return GLFW_TRUE;
@@ -562,44 +714,7 @@ int _glfwInitWayland(void)
 
     _glfw.wl.tag = glfwGetVersionString();
 
-    _glfw.wl.client.display_flush = (PFN_wl_display_flush)
-        _glfwPlatformGetModuleSymbol(_glfw.wl.client.handle, "wl_display_flush");
-    _glfw.wl.client.display_cancel_read = (PFN_wl_display_cancel_read)
-        _glfwPlatformGetModuleSymbol(_glfw.wl.client.handle, "wl_display_cancel_read");
-    _glfw.wl.client.display_dispatch_pending = (PFN_wl_display_dispatch_pending)
-        _glfwPlatformGetModuleSymbol(_glfw.wl.client.handle, "wl_display_dispatch_pending");
-    _glfw.wl.client.display_read_events = (PFN_wl_display_read_events)
-        _glfwPlatformGetModuleSymbol(_glfw.wl.client.handle, "wl_display_read_events");
-    _glfw.wl.client.display_disconnect = (PFN_wl_display_disconnect)
-        _glfwPlatformGetModuleSymbol(_glfw.wl.client.handle, "wl_display_disconnect");
-    _glfw.wl.client.display_roundtrip = (PFN_wl_display_roundtrip)
-        _glfwPlatformGetModuleSymbol(_glfw.wl.client.handle, "wl_display_roundtrip");
-    _glfw.wl.client.display_get_fd = (PFN_wl_display_get_fd)
-        _glfwPlatformGetModuleSymbol(_glfw.wl.client.handle, "wl_display_get_fd");
-    _glfw.wl.client.display_prepare_read = (PFN_wl_display_prepare_read)
-        _glfwPlatformGetModuleSymbol(_glfw.wl.client.handle, "wl_display_prepare_read");
-    _glfw.wl.client.proxy_marshal = (PFN_wl_proxy_marshal)
-        _glfwPlatformGetModuleSymbol(_glfw.wl.client.handle, "wl_proxy_marshal");
-    _glfw.wl.client.proxy_add_listener = (PFN_wl_proxy_add_listener)
-        _glfwPlatformGetModuleSymbol(_glfw.wl.client.handle, "wl_proxy_add_listener");
-    _glfw.wl.client.proxy_destroy = (PFN_wl_proxy_destroy)
-        _glfwPlatformGetModuleSymbol(_glfw.wl.client.handle, "wl_proxy_destroy");
-    _glfw.wl.client.proxy_marshal_constructor = (PFN_wl_proxy_marshal_constructor)
-        _glfwPlatformGetModuleSymbol(_glfw.wl.client.handle, "wl_proxy_marshal_constructor");
-    _glfw.wl.client.proxy_marshal_constructor_versioned = (PFN_wl_proxy_marshal_constructor_versioned)
-        _glfwPlatformGetModuleSymbol(_glfw.wl.client.handle, "wl_proxy_marshal_constructor_versioned");
-    _glfw.wl.client.proxy_get_user_data = (PFN_wl_proxy_get_user_data)
-        _glfwPlatformGetModuleSymbol(_glfw.wl.client.handle, "wl_proxy_get_user_data");
-    _glfw.wl.client.proxy_set_user_data = (PFN_wl_proxy_set_user_data)
-        _glfwPlatformGetModuleSymbol(_glfw.wl.client.handle, "wl_proxy_set_user_data");
-    _glfw.wl.client.proxy_get_tag = (PFN_wl_proxy_get_tag)
-        _glfwPlatformGetModuleSymbol(_glfw.wl.client.handle, "wl_proxy_get_tag");
-    _glfw.wl.client.proxy_set_tag = (PFN_wl_proxy_set_tag)
-        _glfwPlatformGetModuleSymbol(_glfw.wl.client.handle, "wl_proxy_set_tag");
-    _glfw.wl.client.proxy_get_version = (PFN_wl_proxy_get_version)
-        _glfwPlatformGetModuleSymbol(_glfw.wl.client.handle, "wl_proxy_get_version");
-    _glfw.wl.client.proxy_marshal_flags = (PFN_wl_proxy_marshal_flags)
-        _glfwPlatformGetModuleSymbol(_glfw.wl.client.handle, "wl_proxy_marshal_flags");
+    loadWaylandClientFunctions();
 
     if (!_glfw.wl.client.display_flush ||
         !_glfw.wl.client.display_cancel_read ||
@@ -620,90 +735,13 @@ int _glfwInitWayland(void)
         !_glfw.wl.client.proxy_set_tag)
     {
         _glfwInputError(GLFW_PLATFORM_ERROR,
-                        "Wayland: Failed to load libwayland-client entry point");
-        return GLFW_FALSE;
-    }
-
-    _glfw.wl.cursor.handle = _glfwPlatformLoadModule("libwayland-cursor.so.0");
-    if (!_glfw.wl.cursor.handle)
-    {
-        _glfwInputError(GLFW_PLATFORM_ERROR,
-                        "Wayland: Failed to load libwayland-cursor");
+                        "Wayland: Failed to resolve required linked libwayland-client entry points");
         return GLFW_FALSE;
     }
 
-    _glfw.wl.cursor.theme_load = (PFN_wl_cursor_theme_load)
-        _glfwPlatformGetModuleSymbol(_glfw.wl.cursor.handle, "wl_cursor_theme_load");
-    _glfw.wl.cursor.theme_destroy = (PFN_wl_cursor_theme_destroy)
-        _glfwPlatformGetModuleSymbol(_glfw.wl.cursor.handle, "wl_cursor_theme_destroy");
-    _glfw.wl.cursor.theme_get_cursor = (PFN_wl_cursor_theme_get_cursor)
-        _glfwPlatformGetModuleSymbol(_glfw.wl.cursor.handle, "wl_cursor_theme_get_cursor");
-    _glfw.wl.cursor.image_get_buffer = (PFN_wl_cursor_image_get_buffer)
-        _glfwPlatformGetModuleSymbol(_glfw.wl.cursor.handle, "wl_cursor_image_get_buffer");
-
-    _glfw.wl.egl.handle = _glfwPlatformLoadModule("libwayland-egl.so.1");
-    if (!_glfw.wl.egl.handle)
-    {
-        _glfwInputError(GLFW_PLATFORM_ERROR,
-                        "Wayland: Failed to load libwayland-egl");
-        return GLFW_FALSE;
-    }
-
-    _glfw.wl.egl.window_create = (PFN_wl_egl_window_create)
-        _glfwPlatformGetModuleSymbol(_glfw.wl.egl.handle, "wl_egl_window_create");
-    _glfw.wl.egl.window_destroy = (PFN_wl_egl_window_destroy)
-        _glfwPlatformGetModuleSymbol(_glfw.wl.egl.handle, "wl_egl_window_destroy");
-    _glfw.wl.egl.window_resize = (PFN_wl_egl_window_resize)
-        _glfwPlatformGetModuleSymbol(_glfw.wl.egl.handle, "wl_egl_window_resize");
-
-    _glfw.wl.xkb.handle = _glfwPlatformLoadModule("libxkbcommon.so.0");
-    if (!_glfw.wl.xkb.handle)
-    {
-        _glfwInputError(GLFW_PLATFORM_ERROR,
-                        "Wayland: Failed to load libxkbcommon");
-        return GLFW_FALSE;
-    }
-
-    _glfw.wl.xkb.context_new = (PFN_xkb_context_new)
-        _glfwPlatformGetModuleSymbol(_glfw.wl.xkb.handle, "xkb_context_new");
-    _glfw.wl.xkb.context_unref = (PFN_xkb_context_unref)
-        _glfwPlatformGetModuleSymbol(_glfw.wl.xkb.handle, "xkb_context_unref");
-    _glfw.wl.xkb.keymap_new_from_string = (PFN_xkb_keymap_new_from_string)
-        _glfwPlatformGetModuleSymbol(_glfw.wl.xkb.handle, "xkb_keymap_new_from_string");
-    _glfw.wl.xkb.keymap_unref = (PFN_xkb_keymap_unref)
-        _glfwPlatformGetModuleSymbol(_glfw.wl.xkb.handle, "xkb_keymap_unref");
-    _glfw.wl.xkb.keymap_mod_get_index = (PFN_xkb_keymap_mod_get_index)
-        _glfwPlatformGetModuleSymbol(_glfw.wl.xkb.handle, "xkb_keymap_mod_get_index");
-    _glfw.wl.xkb.keymap_key_repeats = (PFN_xkb_keymap_key_repeats)
-        _glfwPlatformGetModuleSymbol(_glfw.wl.xkb.handle, "xkb_keymap_key_repeats");
-    _glfw.wl.xkb.keymap_key_get_syms_by_level = (PFN_xkb_keymap_key_get_syms_by_level)
-        _glfwPlatformGetModuleSymbol(_glfw.wl.xkb.handle, "xkb_keymap_key_get_syms_by_level");
-    _glfw.wl.xkb.state_new = (PFN_xkb_state_new)
-        _glfwPlatformGetModuleSymbol(_glfw.wl.xkb.handle, "xkb_state_new");
-    _glfw.wl.xkb.state_unref = (PFN_xkb_state_unref)
-        _glfwPlatformGetModuleSymbol(_glfw.wl.xkb.handle, "xkb_state_unref");
-    _glfw.wl.xkb.state_key_get_syms = (PFN_xkb_state_key_get_syms)
-        _glfwPlatformGetModuleSymbol(_glfw.wl.xkb.handle, "xkb_state_key_get_syms");
-    _glfw.wl.xkb.state_update_mask = (PFN_xkb_state_update_mask)
-        _glfwPlatformGetModuleSymbol(_glfw.wl.xkb.handle, "xkb_state_update_mask");
-    _glfw.wl.xkb.state_key_get_layout = (PFN_xkb_state_key_get_layout)
-        _glfwPlatformGetModuleSymbol(_glfw.wl.xkb.handle, "xkb_state_key_get_layout");
-    _glfw.wl.xkb.state_mod_index_is_active = (PFN_xkb_state_mod_index_is_active)
-        _glfwPlatformGetModuleSymbol(_glfw.wl.xkb.handle, "xkb_state_mod_index_is_active");
-    _glfw.wl.xkb.compose_table_new_from_locale = (PFN_xkb_compose_table_new_from_locale)
-        _glfwPlatformGetModuleSymbol(_glfw.wl.xkb.handle, "xkb_compose_table_new_from_locale");
-    _glfw.wl.xkb.compose_table_unref = (PFN_xkb_compose_table_unref)
-        _glfwPlatformGetModuleSymbol(_glfw.wl.xkb.handle, "xkb_compose_table_unref");
-    _glfw.wl.xkb.compose_state_new = (PFN_xkb_compose_state_new)
-        _glfwPlatformGetModuleSymbol(_glfw.wl.xkb.handle, "xkb_compose_state_new");
-    _glfw.wl.xkb.compose_state_unref = (PFN_xkb_compose_state_unref)
-        _glfwPlatformGetModuleSymbol(_glfw.wl.xkb.handle, "xkb_compose_state_unref");
-    _glfw.wl.xkb.compose_state_feed = (PFN_xkb_compose_state_feed)
-        _glfwPlatformGetModuleSymbol(_glfw.wl.xkb.handle, "xkb_compose_state_feed");
-    _glfw.wl.xkb.compose_state_get_status = (PFN_xkb_compose_state_get_status)
-        _glfwPlatformGetModuleSymbol(_glfw.wl.xkb.handle, "xkb_compose_state_get_status");
-    _glfw.wl.xkb.compose_state_get_one_sym = (PFN_xkb_compose_state_get_one_sym)
-        _glfwPlatformGetModuleSymbol(_glfw.wl.xkb.handle, "xkb_compose_state_get_one_sym");
+    loadWaylandCursorFunctions();
+    loadWaylandEGLFunctions();
+    loadWaylandXKBFunctions();
 
     if (!_glfw.wl.xkb.context_new ||
         !_glfw.wl.xkb.context_unref ||
@@ -727,12 +765,11 @@ int _glfwInitWayland(void)
         !_glfw.wl.xkb.compose_state_get_one_sym)
     {
         _glfwInputError(GLFW_PLATFORM_ERROR,
-                        "Wayland: Failed to load all entry points from libxkbcommon");
+                        "Wayland: Failed to resolve required linked libxkbcommon entry points");
         return GLFW_FALSE;
     }
 
-    if (_glfw.hints.init.wl.libdecorMode == GLFW_WAYLAND_PREFER_LIBDECOR)
-        _glfw.wl.libdecor.handle = _glfwPlatformLoadModule("libdecor-0.so.0");
+    _glfw.wl.libdecor.handle = NULL;
 
     if (_glfw.wl.libdecor.handle)
     {
@@ -1000,4 +1037,3 @@ void _glfwTerminateWayland(void)
 }
 
 #endif // _GLFW_WAYLAND
-
diff --git a/src/wl_window.c b/src/wl_window.c
index 5b491ff..771e7e7 100644
--- a/src/wl_window.c
+++ b/src/wl_window.c
@@ -1680,35 +1680,35 @@ static void keyboardHandleKeymap(void* userData,
         return;
     }
 
-    // Look up the preferred locale, falling back to "C" as default.
+    // locale no
     locale = getenv("LC_ALL");
     if (!locale)
         locale = getenv("LC_CTYPE");
     if (!locale)
         locale = getenv("LANG");
-    if (!locale)
-        locale = "C";
-
-    composeTable =
-        xkb_compose_table_new_from_locale(_glfw.wl.xkb.context, locale,
-                                          XKB_COMPOSE_COMPILE_NO_FLAGS);
-    if (composeTable)
-    {
-        composeState =
-            xkb_compose_state_new(composeTable, XKB_COMPOSE_STATE_NO_FLAGS);
-        xkb_compose_table_unref(composeTable);
-        if (composeState)
-            _glfw.wl.xkb.composeState = composeState;
-        else
-            _glfwInputError(GLFW_PLATFORM_ERROR,
-                            "Wayland: Failed to create XKB compose state");
-    }
-    else
-    {
-        _glfwInputError(GLFW_PLATFORM_ERROR,
-                        "Wayland: Failed to create XKB compose table");
+    composeTable = NULL;
+    composeState = NULL;
+
+    if (locale &&
+        locale[0] != '\0' &&
+        strcmp(locale, "C") != 0 &&
+        strcmp(locale, "POSIX") != 0)
+    {
+        composeTable =
+            xkb_compose_table_new_from_locale(_glfw.wl.xkb.context, locale,
+                                              XKB_COMPOSE_COMPILE_NO_FLAGS);
+        if (composeTable)
+        {
+            composeState =
+                xkb_compose_state_new(composeTable, XKB_COMPOSE_STATE_NO_FLAGS);
+            xkb_compose_table_unref(composeTable);
+        }
     }
 
+    if (_glfw.wl.xkb.composeState)
+        xkb_compose_state_unref(_glfw.wl.xkb.composeState);
+    _glfw.wl.xkb.composeState = composeState;
+
     xkb_keymap_unref(_glfw.wl.xkb.keymap);
     xkb_state_unref(_glfw.wl.xkb.state);
     _glfw.wl.xkb.keymap = keymap;
@@ -3305,4 +3305,3 @@ GLFWAPI struct wl_surface* glfwGetWaylandWindow(GLFWwindow* handle)
 }
 
 #endif // _GLFW_WAYLAND
-