LibWeb: Implement the Gamepad API with SDL3

This commit is contained in:
Luke Wilde 2025-08-18 17:27:00 +01:00 committed by Andreas Kling
parent 50dcd8fc85
commit 74e0483ea5
Notes: github-actions[bot] 2025-09-01 19:11:57 +00:00
36 changed files with 1848 additions and 50 deletions

View file

@ -20,6 +20,7 @@
#include <LibWeb/HTML/HTMLImageElement.h>
#include <LibWeb/HTML/HTMLMediaElement.h>
#include <LibWeb/HTML/HTMLVideoElement.h>
#include <LibWeb/HTML/Navigator.h>
#include <LibWeb/Layout/Label.h>
#include <LibWeb/Layout/Viewport.h>
#include <LibWeb/Page/DragAndDropEventHandler.h>
@ -37,6 +38,8 @@
#include <LibWeb/UIEvents/PointerEvent.h>
#include <LibWeb/UIEvents/WheelEvent.h>
#include <SDL3/SDL_events.h>
namespace Web {
#define FIRE(expression) \
@ -1459,6 +1462,56 @@ EventResult EventHandler::handle_paste(String const& text)
return EventResult::Handled;
}
void EventHandler::handle_gamepad_connected(SDL_JoystickID sdl_joystick_id)
{
auto active_document = m_navigable->active_document();
if (active_document)
active_document->window()->navigator()->handle_gamepad_connected(sdl_joystick_id);
for (auto child_navigable : m_navigable->child_navigables())
child_navigable->event_handler().handle_gamepad_connected(sdl_joystick_id);
}
void EventHandler::handle_gamepad_updated(SDL_JoystickID sdl_joystick_id)
{
auto active_document = m_navigable->active_document();
if (active_document)
active_document->window()->navigator()->handle_gamepad_updated({}, sdl_joystick_id);
for (auto child_navigable : m_navigable->child_navigables())
child_navigable->event_handler().handle_gamepad_updated(sdl_joystick_id);
}
void EventHandler::handle_gamepad_disconnected(SDL_JoystickID sdl_joystick_id)
{
auto active_document = m_navigable->active_document();
if (active_document)
active_document->window()->navigator()->handle_gamepad_disconnected({}, sdl_joystick_id);
for (auto child_navigable : m_navigable->child_navigables())
child_navigable->event_handler().handle_gamepad_disconnected(sdl_joystick_id);
}
void EventHandler::handle_sdl_input_events()
{
SDL_Event event;
while (SDL_PollEvent(&event)) {
switch (event.type) {
case SDL_EVENT_GAMEPAD_ADDED:
handle_gamepad_connected(event.gdevice.which);
break;
case SDL_EVENT_GAMEPAD_UPDATE_COMPLETE:
handle_gamepad_updated(event.gdevice.which);
break;
case SDL_EVENT_GAMEPAD_REMOVED:
handle_gamepad_disconnected(event.gdevice.which);
break;
default:
break;
}
}
}
void EventHandler::set_mouse_event_tracking_paintable(GC::Ptr<Painting::Paintable> paintable)
{
m_mouse_event_tracking_paintable = paintable;

View file

@ -20,6 +20,8 @@
#include <LibWeb/PixelUnits.h>
#include <LibWeb/UIEvents/KeyCode.h>
#include <SDL3/SDL_joystick.h>
namespace Web {
class WEB_API EventHandler {
@ -43,6 +45,8 @@ public:
EventResult handle_paste(String const& text);
void handle_sdl_input_events();
void visit_edges(JS::Cell::Visitor& visitor) const;
Unicode::Segmenter& word_segmenter();
@ -68,6 +72,10 @@ private:
bool should_ignore_device_input_event() const;
void handle_gamepad_connected(SDL_JoystickID);
void handle_gamepad_updated(SDL_JoystickID);
void handle_gamepad_disconnected(SDL_JoystickID);
GC::Ref<HTML::Navigable> m_navigable;
bool m_in_mouse_selection { false };

View file

@ -244,6 +244,11 @@ EventResult Page::handle_keyup(UIEvents::KeyCode key, unsigned modifiers, u32 co
return focused_navigable().event_handler().handle_keyup(key, modifiers, code_point, repeat);
}
void Page::handle_sdl_input_events()
{
top_level_traversable()->event_handler().handle_sdl_input_events();
}
void Page::set_top_level_traversable(GC::Ref<HTML::TraversableNavigable> navigable)
{
VERIFY(!m_top_level_traversable); // Replacement is not allowed!

View file

@ -102,6 +102,8 @@ public:
EventResult handle_keydown(UIEvents::KeyCode, unsigned modifiers, u32 code_point, bool repeat);
EventResult handle_keyup(UIEvents::KeyCode, unsigned modifiers, u32 code_point, bool repeat);
void handle_sdl_input_events();
Gfx::Palette palette() const;
CSSPixelRect web_exposed_screen_area() const;
CSS::PreferredColorScheme preferred_color_scheme() const;