[HID] Redesigned support for Portals

- Added hotplug support on Windows
- Added support for XamInputNonControllerGetRawEx & XamInputNonControllerSetRawEx
This commit is contained in:
Gliniak
2026-03-13 22:31:24 +01:00
committed by Radosław Gliński
parent 3b8debcf5b
commit d37c22aad0
24 changed files with 427 additions and 340 deletions

View File

@@ -490,6 +490,13 @@ void Window::OnMonitorUpdate(MonitorUpdateEvent& e) {
}
}
void Window::OnUsbDeviceChanged(
bool is_arrival, WindowDestructionReceiver& destruction_receiver) {
SendEventToListeners(
[is_arrival](auto listener) { listener->OnUsbDeviceChanged(is_arrival); },
destruction_receiver);
}
bool Window::OnActualSizeUpdate(
uint32_t new_physical_width, uint32_t new_physical_height,
WindowDestructionReceiver& destruction_receiver) {

View File

@@ -553,6 +553,8 @@ class Window {
void OnDpiChanged(UISetupEvent& e,
WindowDestructionReceiver& destruction_receiver);
void OnMonitorUpdate(MonitorUpdateEvent& e);
void OnUsbDeviceChanged(bool is_arrival,
WindowDestructionReceiver& destruction_receiver);
// For calling when the platform changes something in the non-maximized,
// non-fullscreen size of the window.
void OnDesiredLogicalSizeUpdate(uint32_t new_desired_logical_width,

View File

@@ -34,6 +34,7 @@ class WindowListener {
virtual void OnLostFocus(UISetupEvent& e) {}
virtual void OnFileDrop(FileDropEvent& e) {}
virtual void OnUsbDeviceChanged(bool is_arrival) {}
};
class WindowInputListener {

View File

@@ -19,6 +19,7 @@
#include "xenia/ui/virtual_key.h"
#include "xenia/ui/windowed_app_context_win.h"
#include <Dbt.h>
#include <ShellScalingApi.h>
#include <dwmapi.h>
@@ -48,6 +49,10 @@ Win32Window::~Win32Window() {
DeleteTimerQueueTimer(nullptr, cursor_auto_hide_timer_, nullptr);
cursor_auto_hide_timer_ = nullptr;
}
if (usb_device_notify_) {
UnregisterDeviceNotification(usb_device_notify_);
usb_device_notify_ = nullptr;
}
if (hwnd_) {
// Set hwnd_ to null to ignore events from now on since this Win32Window is
// entering an indeterminate state.
@@ -203,6 +208,14 @@ bool Win32Window::OpenImpl() {
// Enable file dragging from external sources
DragAcceptFiles(hwnd_, true);
// Register USB listener
DEV_BROADCAST_DEVICEINTERFACE filter = {};
filter.dbcc_size = sizeof(filter);
filter.dbcc_devicetype = DBT_DEVTYP_DEVICEINTERFACE;
usb_device_notify_ = RegisterDeviceNotificationW(
hwnd_, &filter,
DEVICE_NOTIFY_WINDOW_HANDLE | DEVICE_NOTIFY_ALL_INTERFACE_CLASSES);
// Apply the initial state from the Window that the window shouldn't be
// visibly transitioned to.
@@ -1084,7 +1097,16 @@ LRESULT Win32Window::WndProc(HWND hWnd, UINT message, WPARAM wParam,
MonitorUpdateEvent update_event{this, true};
OnMonitorUpdate(update_event);
} break;
case WM_DEVICECHANGE: {
if (wParam == DBT_DEVICEARRIVAL || wParam == DBT_DEVICEREMOVECOMPLETE) {
bool is_arrival = (wParam == DBT_DEVICEARRIVAL);
WindowDestructionReceiver destruction_receiver(this);
OnUsbDeviceChanged(is_arrival, destruction_receiver);
if (destruction_receiver.IsWindowDestroyedOrClosed()) {
break;
}
}
} break;
case WM_DPICHANGED: {
// Note that for some reason, WM_DPICHANGED is not sent when the window is
// borderless fullscreen with per-monitor DPI awareness v1.

View File

@@ -151,6 +151,8 @@ class Win32Window : public Window {
// Whether the cursor has been hidden after the expiration of the timer, and
// hasn't been revealed yet.
bool cursor_currently_auto_hidden_ = false;
HDEVNOTIFY usb_device_notify_ = nullptr;
};
class Win32MenuItem : public MenuItem {