SDL: Made SDL_WINDOWEVENT_* and SDL_DISPLAYEVENT_* first class event types

From 909b513c3354d5489ac0ddfc9358135544d79789 Mon Sep 17 00:00:00 2001
From: Sam Lantinga <[EMAIL REDACTED]>
Date: Thu, 22 Dec 2022 07:20:48 -0800
Subject: [PATCH] Made SDL_WINDOWEVENT_* and SDL_DISPLAYEVENT_* first class
 event types

Fixes https://github.com/libsdl-org/SDL/issues/6772
---
 WhatsNew.txt                                |   1 +
 docs/README-migration.md                    |  10 +-
 include/SDL3/SDL_events.h                   |  47 +++--
 include/SDL3/SDL_video.h                    |  43 ----
 src/core/haiku/SDL_BApp.h                   |   2 +-
 src/core/winrt/SDL_winrtapp_direct3d.cpp    |  11 +-
 src/events/SDL_displayevents.c              |   9 +-
 src/events/SDL_displayevents_c.h            |   2 +-
 src/events/SDL_events.c                     |  82 +++-----
 src/events/SDL_windowevents.c               |  28 ++-
 src/events/SDL_windowevents_c.h             |   2 +-
 src/render/SDL_render.c                     |  16 +-
 src/render/direct3d/SDL_render_d3d.c        |   2 +-
 src/render/direct3d11/SDL_render_d3d11.c    |   2 +-
 src/render/direct3d12/SDL_render_d3d12.c    |   2 +-
 src/render/opengl/SDL_render_gl.c           |   4 +-
 src/render/opengles2/SDL_render_gles2.c     |   2 +-
 src/render/software/SDL_render_sw.c         |   2 +-
 src/test/SDL_test_common.c                  | 216 +++++++++-----------
 src/video/cocoa/SDL_cocoametalview.m        |   2 +-
 src/video/emscripten/SDL_emscriptenevents.c |   9 +-
 test/testdrawchessboard.c                   |   2 +-
 test/testgles.c                             |  29 ++-
 test/testgles2.c                            |   2 +-
 test/testgles2_sdf.c                        |  40 ++--
 test/testhittesting.c                       |   6 +-
 test/testnative.c                           |  10 +-
 test/testoverlay2.c                         |  10 +-
 test/testwm2.c                              |  52 +++--
 29 files changed, 281 insertions(+), 364 deletions(-)

diff --git a/WhatsNew.txt b/WhatsNew.txt
index 59762ecaa326..daaba20e7e6f 100644
--- a/WhatsNew.txt
+++ b/WhatsNew.txt
@@ -40,4 +40,5 @@ General:
 * Added SDL_GetTicksNS() to return the number of nanoseconds since the SDL library initialized
 * Added SDL_DelayNS() to specify a delay in nanoseconds, to the highest precision the system will support
 * The timestamp member of the SDL_Event structure is now in nanoseconds, filled in with the time the event was generated, or the time it was queued if that's not available
+* The `SDL_DISPLAYEVENT_*` and `SDL_WINDOWEVENT_*` events have been moved to top level events
 * Intrinsic headers are no longer included in the public SDL headers
diff --git a/docs/README-migration.md b/docs/README-migration.md
index 15b80f39b8d0..504140a6366f 100644
--- a/docs/README-migration.md
+++ b/docs/README-migration.md
@@ -48,13 +48,17 @@ The following headers are no longer automatically included, and will need to be
 
 ## SDL_events.h
 
-The `timestamp` member of the SDL_Event structure now represents nanoseconds, and is populated with `SDL_GetTicksNS()`
+The `timestamp` member of the `SDL_Event` structure now represents nanoseconds, and is populated with `SDL_GetTicksNS()`
 
-The `timestamp_us` member of the sensor events has been renamed `sensor_timestamp` and now represents nanoseconds. This value is filled in from the hardware, if available, and may not be synchronized with values returned from SDL_GetTicksNS().
+The `timestamp_us` member of the sensor events has been renamed `sensor_timestamp` and now represents nanoseconds. This value is filled in from the hardware, if available, and may not be synchronized with values returned from `SDL_GetTicksNS()`.
 
 You should set the `event.common.timestamp` field before passing an event to `SDL_PushEvent()`. If the timestamp is 0 it will be filled in with `SDL_GetTicksNS()`.
 
-SDL_GetEventState used to be a macro, now it's a real function, but otherwise functions identically.
+`SDL_GetEventState` used to be a macro, now it's a real function, but otherwise functions identically.
+
+The `SDL_DISPLAYEVENT_*` events have been moved to top level events, and `SDL_DISPLAYEVENT` has been removed. In general, handling this change just means checking for the individual events instead of first checking for `SDL_DISPLAYEVENT` and then checking for display events. You can compare the event >= `SDL_DISPLAYEVENT_FIRST` and <= `SDL_DISPLAYEVENT_LAST` if you need to see whether it's a display event.
+
+The `SDL_WINDOWEVENT_*` events have been moved to top level events, and `SDL_WINDOWEVENT` has been removed. In general, handling this change just means checking for the individual events instead of first checking for `SDL_WINDOWEVENT` and then checking for window events. You can compare the event >= `SDL_WINDOWEVENT_FIRST` and <= `SDL_WINDOWEVENT_LAST` if you need to see whether it's a window event.
 
 
 ## SDL_gamecontroller.h
diff --git a/include/SDL3/SDL_events.h b/include/SDL3/SDL_events.h
index d2265f9b92a3..13993f99178c 100644
--- a/include/SDL3/SDL_events.h
+++ b/include/SDL3/SDL_events.h
@@ -87,11 +87,40 @@ typedef enum
     SDL_LOCALECHANGED,  /**< The user's locale preferences have changed. */
 
     /* Display events */
-    SDL_DISPLAYEVENT   = 0x150,  /**< Display state change */
+    SDL_DISPLAYEVENT_ORIENTATION = 0x150, /**< Display orientation has changed to data1 */
+    SDL_DISPLAYEVENT_CONNECTED,           /**< Display has been added to the system */
+    SDL_DISPLAYEVENT_DISCONNECTED,        /**< Display has been removed from the system */
+    SDL_DISPLAYEVENT_MOVED,               /**< Display has changed position */
+    SDL_DISPLAYEVENT_FIRST = SDL_DISPLAYEVENT_ORIENTATION,
+    SDL_DISPLAYEVENT_LAST = SDL_DISPLAYEVENT_DISCONNECTED,
 
     /* Window events */
-    SDL_WINDOWEVENT    = 0x200, /**< Window state change */
-    SDL_SYSWMEVENT,             /**< System specific event */
+    SDL_SYSWMEVENT     = 0x201,     /**< System specific event */
+    SDL_WINDOWEVENT_SHOWN,          /**< Window has been shown */
+    SDL_WINDOWEVENT_HIDDEN,         /**< Window has been hidden */
+    SDL_WINDOWEVENT_EXPOSED,        /**< Window has been exposed and should be
+                                         redrawn */
+    SDL_WINDOWEVENT_MOVED,          /**< Window has been moved to data1, data2
+                                     */
+    SDL_WINDOWEVENT_RESIZED,        /**< Window has been resized to data1xdata2 */
+    SDL_WINDOWEVENT_SIZE_CHANGED,   /**< The window size has changed, either as
+                                         a result of an API call or through the
+                                         system or user changing the window size. */
+    SDL_WINDOWEVENT_MINIMIZED,      /**< Window has been minimized */
+    SDL_WINDOWEVENT_MAXIMIZED,      /**< Window has been maximized */
+    SDL_WINDOWEVENT_RESTORED,       /**< Window has been restored to normal size
+                                         and position */
+    SDL_WINDOWEVENT_ENTER,          /**< Window has gained mouse focus */
+    SDL_WINDOWEVENT_LEAVE,          /**< Window has lost mouse focus */
+    SDL_WINDOWEVENT_FOCUS_GAINED,   /**< Window has gained keyboard focus */
+    SDL_WINDOWEVENT_FOCUS_LOST,     /**< Window has lost keyboard focus */
+    SDL_WINDOWEVENT_CLOSE,          /**< The window manager requests that the window be closed */
+    SDL_WINDOWEVENT_TAKE_FOCUS,     /**< Window is being offered a focus (should SetWindowInputFocus() on itself or a subwindow, or ignore) */
+    SDL_WINDOWEVENT_HIT_TEST,       /**< Window had a hit test that wasn't SDL_HITTEST_NORMAL. */
+    SDL_WINDOWEVENT_ICCPROF_CHANGED,/**< The ICC profile of the window's display has changed. */
+    SDL_WINDOWEVENT_DISPLAY_CHANGED,/**< Window has been moved to display data1. */
+    SDL_WINDOWEVENT_FIRST = SDL_WINDOWEVENT_SHOWN,
+    SDL_WINDOWEVENT_LAST = SDL_WINDOWEVENT_DISPLAY_CHANGED,
 
     /* Keyboard events */
     SDL_KEYDOWN        = 0x300, /**< Key pressed */
@@ -185,13 +214,9 @@ typedef struct SDL_CommonEvent
  */
 typedef struct SDL_DisplayEvent
 {
-    Uint32 type;        /**< ::SDL_DISPLAYEVENT */
+    Uint32 type;        /**< ::SDL_DISPLAYEVENT_* */
     Uint64 timestamp;   /**< In nanoseconds, populated using SDL_GetTicksNS() */
     Uint32 display;     /**< The associated display index */
-    Uint8 event;        /**< ::SDL_DisplayEventID */
-    Uint8 padding1;
-    Uint8 padding2;
-    Uint8 padding3;
     Sint32 data1;       /**< event dependent data */
 } SDL_DisplayEvent;
 
@@ -200,13 +225,9 @@ typedef struct SDL_DisplayEvent
  */
 typedef struct SDL_WindowEvent
 {
-    Uint32 type;        /**< ::SDL_WINDOWEVENT */
+    Uint32 type;        /**< ::SDL_WINDOWEVENT_* */
     Uint64 timestamp;   /**< In nanoseconds, populated using SDL_GetTicksNS() */
     Uint32 windowID;    /**< The associated window */
-    Uint8 event;        /**< ::SDL_WindowEventID */
-    Uint8 padding1;
-    Uint8 padding2;
-    Uint8 padding3;
     Sint32 data1;       /**< event dependent data */
     Sint32 data2;       /**< event dependent data */
 } SDL_WindowEvent;
diff --git a/include/SDL3/SDL_video.h b/include/SDL3/SDL_video.h
index 503472732baa..7444fdc6e496 100644
--- a/include/SDL3/SDL_video.h
+++ b/include/SDL3/SDL_video.h
@@ -148,49 +148,6 @@ typedef enum
 #define SDL_WINDOWPOS_ISCENTERED(X)    \
             (((X)&0xFFFF0000) == SDL_WINDOWPOS_CENTERED_MASK)
 
-/**
- *  \brief Event subtype for window events
- */
-typedef enum
-{
-    SDL_WINDOWEVENT_NONE,           /**< Never used */
-    SDL_WINDOWEVENT_SHOWN,          /**< Window has been shown */
-    SDL_WINDOWEVENT_HIDDEN,         /**< Window has been hidden */
-    SDL_WINDOWEVENT_EXPOSED,        /**< Window has been exposed and should be
-                                         redrawn */
-    SDL_WINDOWEVENT_MOVED,          /**< Window has been moved to data1, data2
-                                     */
-    SDL_WINDOWEVENT_RESIZED,        /**< Window has been resized to data1xdata2 */
-    SDL_WINDOWEVENT_SIZE_CHANGED,   /**< The window size has changed, either as
-                                         a result of an API call or through the
-                                         system or user changing the window size. */
-    SDL_WINDOWEVENT_MINIMIZED,      /**< Window has been minimized */
-    SDL_WINDOWEVENT_MAXIMIZED,      /**< Window has been maximized */
-    SDL_WINDOWEVENT_RESTORED,       /**< Window has been restored to normal size
-                                         and position */
-    SDL_WINDOWEVENT_ENTER,          /**< Window has gained mouse focus */
-    SDL_WINDOWEVENT_LEAVE,          /**< Window has lost mouse focus */
-    SDL_WINDOWEVENT_FOCUS_GAINED,   /**< Window has gained keyboard focus */
-    SDL_WINDOWEVENT_FOCUS_LOST,     /**< Window has lost keyboard focus */
-    SDL_WINDOWEVENT_CLOSE,          /**< The window manager requests that the window be closed */
-    SDL_WINDOWEVENT_TAKE_FOCUS,     /**< Window is being offered a focus (should SetWindowInputFocus() on itself or a subwindow, or ignore) */
-    SDL_WINDOWEVENT_HIT_TEST,       /**< Window had a hit test that wasn't SDL_HITTEST_NORMAL. */
-    SDL_WINDOWEVENT_ICCPROF_CHANGED,/**< The ICC profile of the window's display has changed. */
-    SDL_WINDOWEVENT_DISPLAY_CHANGED /**< Window has been moved to display data1. */
-} SDL_WindowEventID;
-
-/**
- *  \brief Event subtype for display events
- */
-typedef enum
-{
-    SDL_DISPLAYEVENT_NONE,          /**< Never used */
-    SDL_DISPLAYEVENT_ORIENTATION,   /**< Display orientation has changed to data1 */
-    SDL_DISPLAYEVENT_CONNECTED,     /**< Display has been added to the system */
-    SDL_DISPLAYEVENT_DISCONNECTED,  /**< Display has been removed from the system */
-    SDL_DISPLAYEVENT_MOVED          /**< Display has changed position */
-} SDL_DisplayEventID;
-
 /**
  *  \brief Display orientation
  */
diff --git a/src/core/haiku/SDL_BApp.h b/src/core/haiku/SDL_BApp.h
index 350d4b633601..a766411a0063 100644
--- a/src/core/haiku/SDL_BApp.h
+++ b/src/core/haiku/SDL_BApp.h
@@ -221,7 +221,7 @@ class SDL_BApp : public BApplication
 
   private:
     /* Event management */
-    void _HandleBasicWindowEvent(BMessage *msg, int32 sdlEventType)
+    void _HandleBasicWindowEvent(BMessage *msg, SDL_EventType sdlEventType)
     {
         SDL_Window *win;
         int32 winID;
diff --git a/src/core/winrt/SDL_winrtapp_direct3d.cpp b/src/core/winrt/SDL_winrtapp_direct3d.cpp
index fca112afe725..017547817fea 100644
--- a/src/core/winrt/SDL_winrtapp_direct3d.cpp
+++ b/src/core/winrt/SDL_winrtapp_direct3d.cpp
@@ -354,16 +354,11 @@ void SDL_WinRTApp::Run()
     }
 }
 
-static bool IsSDLWindowEventPending(SDL_WindowEventID windowEventID)
+static bool IsSDLWindowEventPending(SDL_EventType windowEventID)
 {
     SDL_Event events[128];
-    const int count = SDL_PeepEvents(events, sizeof(events) / sizeof(SDL_Event), SDL_PEEKEVENT, SDL_WINDOWEVENT, SDL_WINDOWEVENT);
-    for (int i = 0; i < count; ++i) {
-        if (events[i].window.event == windowEventID) {
-            return true;
-        }
-    }
-    return false;
+    const int count = SDL_PeepEvents(events, sizeof(events) / sizeof(SDL_Event), SDL_PEEKEVENT, windowEventID, windowEventID);
+    return (count > 0);
 }
 
 bool SDL_WinRTApp::ShouldWaitForAppResumeEvents()
diff --git a/src/events/SDL_displayevents.c b/src/events/SDL_displayevents.c
index 8073656d9d0d..f687906e2a05 100644
--- a/src/events/SDL_displayevents.c
+++ b/src/events/SDL_displayevents.c
@@ -24,7 +24,7 @@
 
 #include "SDL_events_c.h"
 
-int SDL_SendDisplayEvent(SDL_VideoDisplay *display, Uint8 displayevent, int data1)
+int SDL_SendDisplayEvent(SDL_VideoDisplay *display, SDL_EventType displayevent, int data1)
 {
     int posted;
 
@@ -38,15 +38,16 @@ int SDL_SendDisplayEvent(SDL_VideoDisplay *display, Uint8 displayevent, int data
         }
         display->orientation = (SDL_DisplayOrientation)data1;
         break;
+    default:
+        break;
     }
 
     /* Post the event, if desired */
     posted = 0;
-    if (SDL_GetEventState(SDL_DISPLAYEVENT) == SDL_ENABLE) {
+    if (SDL_GetEventState(displayevent) == SDL_ENABLE) {
         SDL_Event event;
-        event.type = SDL_DISPLAYEVENT;
+        event.type = displayevent;
         event.common.timestamp = 0;
-        event.display.event = displayevent;
         event.display.display = SDL_GetIndexOfDisplay(display);
         event.display.data1 = data1;
         posted = (SDL_PushEvent(&event) > 0);
diff --git a/src/events/SDL_displayevents_c.h b/src/events/SDL_displayevents_c.h
index 4e085b640fc3..34ceb2858f20 100644
--- a/src/events/SDL_displayevents_c.h
+++ b/src/events/SDL_displayevents_c.h
@@ -23,7 +23,7 @@
 #ifndef SDL_displayevents_c_h_
 #define SDL_displayevents_c_h_
 
-extern int SDL_SendDisplayEvent(SDL_VideoDisplay *display, Uint8 displayevent, int data1);
+extern int SDL_SendDisplayEvent(SDL_VideoDisplay *display, SDL_EventType displayevent, int data1);
 
 #endif /* SDL_displayevents_c_h_ */
 
diff --git a/src/events/SDL_events.c b/src/events/SDL_events.c
index 46efed66e192..0a47ab0b27b0 100644
--- a/src/events/SDL_events.c
+++ b/src/events/SDL_events.c
@@ -230,69 +230,43 @@ static void SDL_LogEvent(const SDL_Event *event)
         SDL_EVENT_CASE(SDL_RENDER_DEVICE_RESET)
         break;
 
-        SDL_EVENT_CASE(SDL_DISPLAYEVENT)
-        {
-            char name2[64];
-            switch (event->display.event) {
-            case SDL_DISPLAYEVENT_NONE:
-                SDL_strlcpy(name2, "SDL_DISPLAYEVENT_NONE (THIS IS PROBABLY A BUG!)", sizeof(name2));
-                break;
 #define SDL_DISPLAYEVENT_CASE(x)               \
     case x:                                    \
-        SDL_strlcpy(name2, #x, sizeof(name2)); \
+        SDL_strlcpy(name, #x, sizeof(name));   \
+        (void)SDL_snprintf(details, sizeof(details), " (timestamp=%u display=%u event=%s data1=%d)", \
+                           (uint)event->display.timestamp, (uint)event->display.display, name, (int)event->display.data1); \
         break
-                SDL_DISPLAYEVENT_CASE(SDL_DISPLAYEVENT_ORIENTATION);
-                SDL_DISPLAYEVENT_CASE(SDL_DISPLAYEVENT_CONNECTED);
-                SDL_DISPLAYEVENT_CASE(SDL_DISPLAYEVENT_DISCONNECTED);
-                SDL_DISPLAYEVENT_CASE(SDL_DISPLAYEVENT_MOVED);
+        SDL_DISPLAYEVENT_CASE(SDL_DISPLAYEVENT_ORIENTATION);
+        SDL_DISPLAYEVENT_CASE(SDL_DISPLAYEVENT_CONNECTED);
+        SDL_DISPLAYEVENT_CASE(SDL_DISPLAYEVENT_DISCONNECTED);
+        SDL_DISPLAYEVENT_CASE(SDL_DISPLAYEVENT_MOVED);
 #undef SDL_DISPLAYEVENT_CASE
-            default:
-                SDL_strlcpy(name2, "UNKNOWN (bug? fixme?)", sizeof(name2));
-                break;
-            }
-            (void)SDL_snprintf(details, sizeof(details), " (timestamp=%u display=%u event=%s data1=%d)",
-                               (uint)event->display.timestamp, (uint)event->display.display, name2, (int)event->display.data1);
-            break;
-        }
 
-        SDL_EVENT_CASE(SDL_WINDOWEVENT)
-        {
-            char name2[64];
-            switch (event->window.event) {
-            case SDL_WINDOWEVENT_NONE:
-                SDL_strlcpy(name2, "SDL_WINDOWEVENT_NONE (THIS IS PROBABLY A BUG!)", sizeof(name2));
-                break;
 #define SDL_WINDOWEVENT_CASE(x)                \
     case x:                                    \
-        SDL_strlcpy(name2, #x, sizeof(name2)); \
+        SDL_strlcpy(name, #x, sizeof(name)); \
+        (void)SDL_snprintf(details, sizeof(details), " (timestamp=%u windowid=%u event=%s data1=%d data2=%d)", \
+                           (uint)event->window.timestamp, (uint)event->window.windowID, name, (int)event->window.data1, (int)event->window.data2); \
         break
-                SDL_WINDOWEVENT_CASE(SDL_WINDOWEVENT_SHOWN);
-                SDL_WINDOWEVENT_CASE(SDL_WINDOWEVENT_HIDDEN);
-                SDL_WINDOWEVENT_CASE(SDL_WINDOWEVENT_EXPOSED);
-                SDL_WINDOWEVENT_CASE(SDL_WINDOWEVENT_MOVED);
-                SDL_WINDOWEVENT_CASE(SDL_WINDOWEVENT_RESIZED);
-                SDL_WINDOWEVENT_CASE(SDL_WINDOWEVENT_SIZE_CHANGED);
-                SDL_WINDOWEVENT_CASE(SDL_WINDOWEVENT_MINIMIZED);
-                SDL_WINDOWEVENT_CASE(SDL_WINDOWEVENT_MAXIMIZED);
-                SDL_WINDOWEVENT_CASE(SDL_WINDOWEVENT_RESTORED);
-                SDL_WINDOWEVENT_CASE(SDL_WINDOWEVENT_ENTER);
-                SDL_WINDOWEVENT_CASE(SDL_WINDOWEVENT_LEAVE);
-                SDL_WINDOWEVENT_CASE(SDL_WINDOWEVENT_FOCUS_GAINED);
-                SDL_WINDOWEVENT_CASE(SDL_WINDOWEVENT_FOCUS_LOST);
-                SDL_WINDOWEVENT_CASE(SDL_WINDOWEVENT_CLOSE);
-                SDL_WINDOWEVENT_CASE(SDL_WINDOWEVENT_TAKE_FOCUS);
-                SDL_WINDOWEVENT_CASE(SDL_WINDOWEVENT_HIT_TEST);
-                SDL_WINDOWEVENT_CASE(SDL_WINDOWEVENT_ICCPROF_CHANGED);
-                SDL_WINDOWEVENT_CASE(SDL_WINDOWEVENT_DISPLAY_CHANGED);
+        SDL_WINDOWEVENT_CASE(SDL_WINDOWEVENT_SHOWN);
+        SDL_WINDOWEVENT_CASE(SDL_WINDOWEVENT_HIDDEN);
+        SDL_WINDOWEVENT_CASE(SDL_WINDOWEVENT_EXPOSED);
+        SDL_WINDOWEVENT_CASE(SDL_WINDOWEVENT_MOVED);
+        SDL_WINDOWEVENT_CASE(SDL_WINDOWEVENT_RESIZED);
+        SDL_WINDOWEVENT_CASE(SDL_WINDOWEVENT_SIZE_CHANGED);
+        SDL_WINDOWEVENT_CASE(SDL_WINDOWEVENT_MINIMIZED);
+        SDL_WINDOWEVENT_CASE(SDL_WINDOWEVENT_MAXIMIZED);
+        SDL_WINDOWEVENT_CASE(SDL_WINDOWEVENT_RESTORED);
+        SDL_WINDOWEVENT_CASE(SDL_WINDOWEVENT_ENTER);
+        SDL_WINDOWEVENT_CASE(SDL_WINDOWEVENT_LEAVE);
+        SDL_WINDOWEVENT_CASE(SDL_WINDOWEVENT_FOCUS_GAINED);
+        SDL_WINDOWEVENT_CASE(SDL_WINDOWEVENT_FOCUS_LOST);
+        SDL_WINDOWEVENT_CASE(SDL_WINDOWEVENT_CLOSE);
+        SDL_WINDOWEVENT_CASE(SDL_WINDOWEVENT_TAKE_FOCUS);
+        SDL_WINDOWEVENT_CASE(SDL_WINDOWEVENT_HIT_TEST);
+        SDL_WINDOWEVENT_CASE(SDL_WINDOWEVENT_ICCPROF_CHANGED);
+        SDL_WINDOWEVENT_CASE(SDL_WINDOWEVENT_DISPLAY_CHANGED);
 #undef SDL_WINDOWEVENT_CASE
-            default:
-                SDL_strlcpy(name2, "UNKNOWN (bug? fixme?)", sizeof(name2));
-                break;
-            }
-            (void)SDL_snprintf(details, sizeof(details), " (timestamp=%u windowid=%u event=%s data1=%d data2=%d)",
-                               (uint)event->window.timestamp, (uint)event->window.windowID, name2, (int)event->window.data1, (int)event->window.data2);
-            break;
-        }
 
         SDL_EVENT_CASE(SDL_SYSWMEVENT)
         /* !!! FIXME: we don't delve further at the moment. */
diff --git a/src/events/SDL_windowevents.c b/src/events/SDL_windowevents.c
index b3a8076e31e9..cf60d3444da6 100644
--- a/src/events/SDL_windowevents.c
+++ b/src/events/SDL_windowevents.c
@@ -36,12 +36,11 @@ static int SDLCALL RemovePendingSizeChangedAndResizedEvents(void *_userdata, SDL
     RemovePendingSizeChangedAndResizedEvents_Data *userdata = (RemovePendingSizeChangedAndResizedEvents_Data *)_userdata;
     const SDL_Event *new_event = userdata->new_event;
 
-    if (event->type == SDL_WINDOWEVENT &&
-        (event->window.event == SDL_WINDOWEVENT_SIZE_CHANGED ||
-         event->window.event == SDL_WINDOWEVENT_RESIZED) &&
+    if ((event->type == SDL_WINDOWEVENT_SIZE_CHANGED ||
+         event->type == SDL_WINDOWEVENT_RESIZED) &&
         event->window.windowID == new_event->window.windowID) {
 
-        if (event->window.event == SDL_WINDOWEVENT_RESIZED) {
+        if (event->type == SDL_WINDOWEVENT_RESIZED) {
             userdata->saw_resized = SDL_TRUE;
         }
 
@@ -55,8 +54,7 @@ static int SDLCALL RemovePendingMoveEvents(void *userdata, SDL_Event *event)
 {
     SDL_Event *new_event = (SDL_Event *)userdata;
 
-    if (event->type == SDL_WINDOWEVENT &&
-        event->window.event == SDL_WINDOWEVENT_MOVED &&
+    if (event->type == SDL_WINDOWEVENT_MOVED &&
         event->window.windowID == new_event->window.windowID) {
         /* We're about to post a new move event, drop the old one */
         return 0;
@@ -68,8 +66,7 @@ static int SDLCALL RemovePendingExposedEvents(void *userdata, SDL_Event *event)
 {
     SDL_Event *new_event = (SDL_Event *)userdata;
 
-    if (event->type == SDL_WINDOWEVENT &&
-        event->window.event == SDL_WINDOWEVENT_EXPOSED &&
+    if (event->type == SDL_WINDOWEVENT_EXPOSED &&
         event->window.windowID == new_event->window.windowID) {
         /* We're about to post a new exposed event, drop the old one */
         return 0;
@@ -77,8 +74,8 @@ static int SDLCALL RemovePendingExposedEvents(void *userdata, SDL_Event *event)
     return 1;
 }
 
-int SDL_SendWindowEvent(SDL_Window *window, Uint8 windowevent, int data1,
-                        int data2)
+int SDL_SendWindowEvent(SDL_Window *window, SDL_EventType windowevent,
+                        int data1, int data2)
 {
     int posted;
 
@@ -180,15 +177,16 @@ int SDL_SendWindowEvent(SDL_Window *window, Uint8 windowevent, int data1,
         window->flags &= ~SDL_WINDOW_INPUT_FOCUS;
         SDL_OnWindowFocusLost(window);
         break;
+    default:
+        break;
     }
 
     /* Post the event, if desired */
     posted = 0;
-    if (SDL_GetEventState(SDL_WINDOWEVENT) == SDL_ENABLE) {
+    if (SDL_GetEventState(windowevent) == SDL_ENABLE) {
         SDL_Event event;
-        event.type = SDL_WINDOWEVENT;
+        event.type = windowevent;
         event.common.timestamp = 0;
-        event.window.event = windowevent;
         event.window.data1 = data1;
         event.window.data2 = data2;
         event.window.windowID = window->id;
@@ -201,11 +199,11 @@ int SDL_SendWindowEvent(SDL_Window *window, Uint8 windowevent, int data1,
             userdata.saw_resized = SDL_FALSE;
             SDL_FilterEvents(RemovePendingSizeChangedAndResizedEvents, &userdata);
             if (userdata.saw_resized) { /* if there was a pending resize, make sure one at the new dimensions remains. */
-                event.window.event = SDL_WINDOWEVENT_RESIZED;
+                event.type = SDL_WINDOWEVENT_RESIZED;
                 if (SDL_PushEvent(&event) <= 0) {
                     return 0; /* oh well. */
                 }
-                event.window.event = SDL_WINDOWEVENT_SIZE_CHANGED; /* then push the actual event next. */
+                event.type = SDL_WINDOWEVENT_SIZE_CHANGED; /* then push the actual event next. */
             }
         }
         if (windowevent == SDL_WINDOWEVENT_MOVED) {
diff --git a/src/events/SDL_windowevents_c.h b/src/events/SDL_windowevents_c.h
index 89982a1f193f..6f7febf12dd1 100644
--- a/src/events/SDL_windowevents_c.h
+++ b/src/events/SDL_windowevents_c.h
@@ -23,7 +23,7 @@
 #ifndef SDL_windowevents_c_h_
 #define SDL_windowevents_c_h_
 
-extern int SDL_SendWindowEvent(SDL_Window *window, Uint8 windowevent,
+extern int SDL_SendWindowEvent(SDL_Window *window, SDL_EventType windowevent,
                                int data1, int data2);
 
 #endif /* SDL_windowevents_c_h_ */
diff --git a/src/render/SDL_render.c b/src/render/SDL_render.c
index e1b0ee2cd8ce..33eaaca8b9fa 100644
--- a/src/render/SDL_render.c
+++ b/src/render/SDL_render.c
@@ -671,7 +671,7 @@ static int SDLCALL SDL_RendererEventWatch(void *userdata, SDL_Event *event)
 {
     SDL_Renderer *renderer = (SDL_Renderer *)userdata;
 
-    if (event->type == SDL_WINDOWEVENT) {
+    if (event->type >= SDL_WINDOWEVENT_FIRST && event->type <= SDL_WINDOWEVENT_LAST) {
         SDL_Window *window = SDL_GetWindowFromID(event->window.windowID);
         if (window == renderer->window) {
             if (renderer->WindowEvent) {
@@ -682,8 +682,8 @@ static int SDLCALL SDL_RendererEventWatch(void *userdata, SDL_Event *event)
              * window display changes as well! If the new display has a new DPI,
              * we need to update the viewport for the new window/drawable ratio.
              */
-            if (event->window.event == SDL_WINDOWEVENT_SIZE_CHANGED ||
-                event->window.event == SDL_WINDOWEVENT_DISPLAY_CHANGED) {
+            if (event->type == SDL_WINDOWEVENT_SIZE_CHANGED ||
+                event->type == SDL_WINDOWEVENT_DISPLAY_CHANGED) {
                 /* Make sure we're operating on the default render target */
                 SDL_Texture *saved_target = SDL_GetRenderTarget(renderer);
                 if (saved_target) {
@@ -736,16 +736,16 @@ static int SDLCALL SDL_RendererEventWatch(void *userdata, SDL_Event *event)
                 if (saved_target) {
                     SDL_SetRenderTarget(renderer, saved_target);
                 }
-            } else if (event->window.event == SDL_WINDOWEVENT_HIDDEN) {
+            } else if (event->type == SDL_WINDOWEVENT_HIDDEN) {
                 renderer->hidden = SDL_TRUE;
-            } else if (event->window.event == SDL_WINDOWEVENT_SHOWN) {
+            } else if (event->type == SDL_WINDOWEVENT_SHOWN) {
                 if (!(SDL_GetWindowFlags(window) & SDL_WINDOW_MINIMIZED)) {
                     renderer->hidden = SDL_FALSE;
                 }
-            } else if (event->window.event == SDL_WINDOWEVENT_MINIMIZED) {
+            } else if (event->type == SDL_WINDOWEVENT_MINIMIZED) {
                 renderer->hidden = SDL_TRUE;
-            } else if (event->window.event == SDL_WINDOWEVENT_RESTORED ||
-                       event->window.event == SDL_WINDOWEVENT_MAXIMIZED) {
+            } else if (event->type == SDL_WINDOWEVENT_RESTORED ||
+                       event->type == SDL_WINDOWEVENT_MAXIMIZED) {
                 if (!(SDL_GetWindowFlags(window) & SDL_WINDOW_HIDDEN)) {
                     renderer->hidden = SDL_FALSE;
                 }
diff --git a/src/render/direct3d/SDL_render_d3d.c b/src/render/direct3d/SDL_render_d3d.c
index a64de3888248..0efa5c6f7f89 100644
--- a/src/render/direct3d/SDL_render_d3d.c
+++ b/src/render/direct3d/SDL_render_d3d.c
@@ -332,7 +332,7 @@ static void D3D_WindowEvent(SDL_Renderer *renderer, const SDL_WindowEvent *event
 {
     D3D_RenderData *data = (D3D_RenderData *)renderer->driverdata;
 
-    if (event->event == SDL_WINDOWEVENT_SIZE_CHANGED) {
+    if (event->type == SDL_WINDOWEVENT_SIZE_CHANGED) {
         data->updateSize = SDL_TRUE;
     }
 }
diff --git a/src/render/direct3d11/SDL_render_d3d11.c b/src/render/direct3d11/SDL_render_d3d11.c
index d24cad58bf13..288efcee783b 100644
--- a/src/render/direct3d11/SDL_render_d3d11.c
+++ b/src/render/direct3d11/SDL_render_d3d11.c
@@ -1029,7 +1029,7 @@ void D3D11_Trim(SDL_Renderer *renderer)
 
 static void D3D11_WindowEvent(SDL_Renderer *renderer, const SDL_WindowEvent *event)
 {
-    if (event->event == SDL_WINDOWEVENT_SIZE_CHANGED) {
+    if (event->type == SDL_WINDOWEVENT_SIZE_CHANGED) {
         D3D11_UpdateForWindowSizeChange(renderer);
     }
 }
diff --git a/src/render/direct3d12/SDL_render_d3d12.c b/src/render/direct3d12/SDL_render_d3d12.c
index 2db435e53dde..ffd1c56207c5 100644
--- a/src/render/direct3d12/SDL_render_d3d12.c
+++ b/src/render/direct3d12/SDL_render_d3d12.c
@@ -1377,7 +1377,7 @@ static HRESULT D3D12_UpdateForWindowSizeChange(SDL_Renderer *renderer)
 
 static void D3D12_WindowEvent(SDL_Renderer *renderer, const SDL_WindowEvent *event)
 {
-    if (event->event == SDL_WINDOWEVENT_SIZE_CHANGED) {
+    if (event->type == SDL_WINDOWEVENT_SIZE_CHANGED) {
         D3D12_UpdateForWindowSizeChange(renderer);
     }
 }
diff --git a/src/render/opengl/SDL_render_gl.c b/src/render/opengl/SDL_render_gl.c
index f79cd082631b..5060f1dcba15 100644
--- a/src/render/opengl/SDL_render_gl.c
+++ b/src/render/opengl/SDL_render_gl.c
@@ -324,8 +324,8 @@ static void GL_WindowEvent(SDL_Renderer *renderer, const SDL_WindowEvent *event)
      * changed behind our backs. x/y changes might seem weird but viewport
      * resets have been observed on macOS at minimum!
      */
-    if (event->event == SDL_WINDOWEVENT_SIZE_CHANGED ||
-        event->event == SDL_WINDOWEVENT_MOVED) {
+    if (event->type == SDL_WINDOWEVENT_SIZE_CHANGED ||
+        event->type == SDL_WINDOWEVENT_MOVED) {
         GL_RenderData *data = (GL_RenderData *)renderer->driverdata;
         data->drawstate.viewport_dirty = SDL_TRUE;
     }
diff --git a/src/render/opengles2/SDL_render_gles2.c b/src/render/opengles2/SDL_render_gles2.c
index 499ba8be48a8..ef5bfebe2a1a 100644
--- a/src/render/opengles2/SDL_render_gles2.c
+++ b/src/render/opengles2/SDL_render_gles2.c
@@ -303,7 +303,7 @@ static void GLES2_WindowEvent(SDL_Renderer *renderer, const SDL_WindowEvent *eve
 {
     GLES2_RenderData *data = (GLES2_RenderData *)renderer->driverdata;
 
-    if (event->event == SDL_WINDOWEVENT_MINIMIZED) {
+    if (event->type == SDL_WINDOWEVENT_MINIMIZED) {
         /* According to Apple documentation, we need to finish drawing NOW! */
         data->glFinish();
     }
diff --git a/src/render/software/SDL_render_sw.c b/src/render/software/SDL_render_sw.c
index bba5a814dbd8..641131047af8 100644
--- a/src/render/software/SDL_render_sw.c
+++ b/src/render/software/SDL_render_sw.c
@@ -69,7 +69,7 @@ static void SW_WindowEvent(SDL_Renderer *renderer, const SDL_WindowEvent *event)
 {
     SW_RenderData *data = (SW_RenderData *)renderer->driverdata;
 
-    if (event->event == SDL_WINDOWEVENT_SIZE_CHANGED) {
+    if (event->type == SDL_WINDOWEVENT_SIZE_CHANGED) {
         data->surface = NULL;
         data->window = NULL;
     }
diff --git a/src/test/SDL_test_common.c b/src/test/SDL_test_common.c
index 50cf8545b39e..ed80650cc36b 100644
--- a/src/test/SDL_test_common.c
+++ b/src/test/SDL_test_common.c
@@ -1432,97 +1432,81 @@ static const char *ControllerButtonName(const SDL_GameControllerButton button)
 static void SDLTest_PrintEvent(SDL_Event *event)
 {
     switch (event->type) {
-    case SDL_DISPLAYEVENT:
-        switch (event->display.event) {
-        case SDL_DISPLAYEVEN

(Patch may be truncated, please check the link at the top of this post.)