diff --git a/.clang-format b/.clang-format
index f7b785adaf26dfd81acf3ee1806151ad6bf4df21..7b8e0ef8eba7bf355127ed2077443d4c5e1fbe52 100644
--- a/.clang-format
+++ b/.clang-format
@@ -265,6 +265,7 @@ ForEachMacros:
   - SET_SLOT_PROBING_BEGIN
   - MAP_SLOT_PROBING_BEGIN
   - VECTOR_SET_SLOT_PROBING_BEGIN
+  - WL_ARRAY_FOR_EACH
 
 StatementMacros:
   - PyObject_HEAD
diff --git a/intern/ghost/intern/GHOST_WaylandUtils.h b/intern/ghost/intern/GHOST_WaylandUtils.h
new file mode 100644
index 0000000000000000000000000000000000000000..0e1e133bc4c9401a7d4c2de6ba9dcc8cb794a191
--- /dev/null
+++ b/intern/ghost/intern/GHOST_WaylandUtils.h
@@ -0,0 +1,19 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
+/** \file
+ * \ingroup GHOST
+ */
+
+#pragma once
+
+#ifdef __cplusplus
+#  undef wl_array_for_each
+/**
+ * This macro causes a warning for C++ code, define our own.
+ * See: https://gitlab.freedesktop.org/wayland/wayland/-/issues/34
+ */
+#  define WL_ARRAY_FOR_EACH(pos, array) \
+    for (pos = (decltype(pos))((array)->data); \
+         (const char *)pos < ((const char *)(array)->data + (array)->size); \
+         (pos)++)
+#endif
diff --git a/intern/ghost/intern/GHOST_WindowWayland.cpp b/intern/ghost/intern/GHOST_WindowWayland.cpp
index 394ad35082b68d9bd85d8c7ce4df56d2b5c2225f..afaa2e11aa77970fe686cfb8df5a0dca1563bc44 100644
--- a/intern/ghost/intern/GHOST_WindowWayland.cpp
+++ b/intern/ghost/intern/GHOST_WindowWayland.cpp
@@ -6,6 +6,7 @@
 
 #include "GHOST_WindowWayland.h"
 #include "GHOST_SystemWayland.h"
+#include "GHOST_WaylandUtils.h"
 #include "GHOST_WindowManager.h"
 
 #include "GHOST_Event.h"
@@ -134,12 +135,8 @@ static void xdg_toplevel_handle_configure(void *data,
   win->is_fullscreen = false;
   win->is_active = false;
 
-  /* Note that the macro 'wl_array_for_each' would typically be used to simplify this logic,
-   * however it's not compatible with C++, so perform casts instead.
-   * If this needs to be done more often we could define our own C++ compatible macro. */
-  for (enum xdg_toplevel_state *state = static_cast<xdg_toplevel_state *>(states->data);
-       reinterpret_cast<uint8_t *>(state) < (static_cast<uint8_t *>(states->data) + states->size);
-       state++) {
+  enum xdg_toplevel_state *state;
+  WL_ARRAY_FOR_EACH (state, states) {
     switch (*state) {
       case XDG_TOPLEVEL_STATE_MAXIMIZED:
         win->is_maximised = true;