--- ./src/core/linux/SDL_evdev_capabilities.h.orig	2023-12-02 16:08:14.571510426 +0000
+++ ./src/core/linux/SDL_evdev_capabilities.h	2023-12-02 16:09:50.150137338 +0000
@@ -35,10 +35,11 @@
 #define EVDEV_LONG(x)        ((x) / BITS_PER_LONG)
 #define test_bit(bit, array) ((array[EVDEV_LONG(bit)] >> EVDEV_OFF(bit)) & 1)
 
-extern int SDL_EVDEV_GuessDeviceClass(const unsigned long bitmask_ev[NBITS(EV_MAX)],
-                                      const unsigned long bitmask_abs[NBITS(ABS_MAX)],
-                                      const unsigned long bitmask_key[NBITS(KEY_MAX)],
-                                      const unsigned long bitmask_rel[NBITS(REL_MAX)]);
+extern SDL_UDEV_deviceclass
+SDL_EVDEV_GuessDeviceClass(const unsigned long bitmask_ev[NBITS(EV_MAX)],
+                           const unsigned long bitmask_abs[NBITS(ABS_MAX)],
+                           const unsigned long bitmask_key[NBITS(KEY_MAX)],
+                           const unsigned long bitmask_rel[NBITS(REL_MAX)]);
 
 #endif /* HAVE_LINUX_INPUT_H */
 
--- ./src/core/linux/SDL_udev.c.orig	2023-12-02 16:08:14.572510412 +0000
+++ ./src/core/linux/SDL_udev.c	2023-12-02 16:09:50.151137324 +0000
@@ -47,6 +47,9 @@
 static SDL_bool SDL_UDEV_load_sym(const char *fn, void **addr);
 static int SDL_UDEV_load_syms(void);
 static SDL_bool SDL_UDEV_hotplug_update_available(void);
+static void get_caps(struct udev_device *dev, struct udev_device *pdev, const char *attr, unsigned long *bitmask, size_t bitmask_len);
+static SDL_UDEV_deviceclass guess_device_class(struct udev_device *dev);
+static SDL_UDEV_deviceclass device_class(struct udev_device *dev);
 static void device_event(SDL_UDEV_deviceevent type, struct udev_device *dev);
 
 static SDL_bool SDL_UDEV_load_sym(const char *fn, void **addr)
@@ -222,7 +225,7 @@
     _this->syms.udev_enumerate_unref(enumerate);
 }
 
-SDL_bool SDL_UDEV_GetProductInfo(const char *device_path, Uint16 *vendor, Uint16 *product, Uint16 *version)
+SDL_bool SDL_UDEV_GetProductInfo(const char *device_path, Uint16 *vendor, Uint16 *product, Uint16 *version, SDL_UDEV_deviceclass *class)
 {
     struct udev_enumerate *enumerate = NULL;
     struct udev_list_entry *devs = NULL;
@@ -250,6 +253,7 @@
 
             existing_path = _this->syms.udev_device_get_devnode(dev);
             if (existing_path && SDL_strcmp(device_path, existing_path) == 0) {
+                SDL_UDEV_deviceclass class_temp;
                 found = SDL_TRUE;
 
                 val = _this->syms.udev_device_get_property_value(dev, "ID_VENDOR_ID");
@@ -266,6 +270,11 @@
                 if (val != NULL) {
                     *version = (Uint16)SDL_strtol(val, NULL, 16);
                 }
+
+                class_temp = device_class(dev);
+                if (class_temp) {
+                  *class = class_temp;
+                }
             }
             _this->syms.udev_device_unref(dev);
         }
@@ -394,20 +403,17 @@
                                       &bitmask_rel[0]);
 }
 
-static void device_event(SDL_UDEV_deviceevent type, struct udev_device *dev)
+static SDL_UDEV_deviceclass device_class(struct udev_device *dev)
 {
     const char *subsystem;
     const char *val = NULL;
     SDL_UDEV_deviceclass devclass = 0;
-    const char *path;
-    SDL_UDEV_CallbackList *item;
 
-    path = _this->syms.udev_device_get_devnode(dev);
-    if (path == NULL) {
-        return;
+    subsystem = _this->syms.udev_device_get_subsystem(dev);
+    if (!subsystem) {
+        return 0;
     }
 
-    subsystem = _this->syms.udev_device_get_subsystem(dev);
     if (SDL_strcmp(subsystem, "sound") == 0) {
         devclass = SDL_UDEV_DEVICE_SOUND;
     } else if (SDL_strcmp(subsystem, "input") == 0) {
@@ -455,18 +461,33 @@
                     devclass = SDL_UDEV_DEVICE_MOUSE;
                 } else if (SDL_strcmp(val, "kbd") == 0) {
                     devclass = SDL_UDEV_DEVICE_KEYBOARD;
-                } else {
-                    return;
                 }
             } else {
                 /* We could be linked with libudev on a system that doesn't have udev running */
                 devclass = guess_device_class(dev);
             }
         }
-    } else {
+    }
+
+    return devclass;
+}
+
+static void device_event(SDL_UDEV_deviceevent type, struct udev_device *dev)
+{
+    int devclass = 0;
+    const char *path;
+    SDL_UDEV_CallbackList *item;
+
+    path = _this->syms.udev_device_get_devnode(dev);
+    if (!path) {
         return;
     }
 
+    devclass = device_class(dev);
+    if (!devclass) {
+         return;
+     }
+
     /* Process callbacks */
     for (item = _this->first; item != NULL; item = item->next) {
         item->callback(type, devclass, path);
--- ./src/core/linux/SDL_udev.h.orig	2023-12-02 16:08:14.572510412 +0000
+++ ./src/core/linux/SDL_udev.h	2023-12-02 16:09:50.151137324 +0000
@@ -119,7 +119,7 @@
 extern int SDL_UDEV_LoadLibrary(void);
 extern void SDL_UDEV_Poll(void);
 extern void SDL_UDEV_Scan(void);
-extern SDL_bool SDL_UDEV_GetProductInfo(const char *device_path, Uint16 *vendor, Uint16 *product, Uint16 *version);
+extern SDL_bool SDL_UDEV_GetProductInfo(const char *device_path, Uint16 *vendor, Uint16 *product, Uint16 *version, SDL_UDEV_deviceclass *class);
 extern int SDL_UDEV_AddCallback(SDL_UDEV_Callback cb);
 extern void SDL_UDEV_DelCallback(SDL_UDEV_Callback cb);
 extern const SDL_UDEV_Symbols *SDL_UDEV_GetUdevSyms(void);
--- ./src/joystick/linux/SDL_sysjoystick.c.orig	2023-10-01 19:12:03.000000000 +0000
+++ ./src/joystick/linux/SDL_sysjoystick.c	2023-12-02 16:09:50.151137324 +0000
@@ -234,18 +234,20 @@
     struct input_id inpid;
     char *name;
     char product_string[128];
+    SDL_UDEV_deviceclass class = 0;
 
-    if (ioctl(fd, JSIOCGNAME(sizeof(product_string)), product_string) >= 0) {
-        SDL_zero(inpid);
+    SDL_zero(inpid);
 #if SDL_USE_LIBUDEV
-        SDL_UDEV_GetProductInfo(path, &inpid.vendor, &inpid.product, &inpid.version);
+    SDL_UDEV_GetProductInfo(path, &inpid.vendor, &inpid.product, &inpid.version, &class);
 #endif
-    } else {
+    if (ioctl(fd, JSIOCGNAME(sizeof(product_string)), product_string) <= 0) {
         /* When udev is enabled we only get joystick devices here, so there's no need to test them */
-        if (enumeration_method != ENUMERATION_LIBUDEV && !GuessIsJoystick(fd)) {
+        if ( enumeration_method != ENUMERATION_LIBUDEV &&
+             !(class & SDL_UDEV_DEVICE_JOYSTICK) && !GuessIsJoystick(fd) ) {
             return 0;
         }
 
+        /* The old code never used udev on the ev branch, so we still let ev overwrite any udev info */
         if (ioctl(fd, EVIOCGID, &inpid) < 0) {
             return 0;
         }
