mirror of
https://github.com/RGBCube/serenity
synced 2025-07-27 19:47:34 +00:00
LibWebView+WebContent: Use Web::InputEvent for WebContent input IPC
Now that all input events are handled by LibWebView, replace the IPCs which send the fields of Web::KeyEvent / Web::MouseEvent individually with one IPC per event type (key or mouse). We can also replace the ad-hoc queued input structure with a smaller struct that simply holds the tranferred Web::KeyEvent / Web::MouseEvent. In the future, we can also adapt Web::EventHandler to use these structs.
This commit is contained in:
parent
2c31ef11bc
commit
baf359354b
8 changed files with 164 additions and 228 deletions
|
@ -227,185 +227,84 @@ void ConnectionFromClient::process_next_input_event()
|
|||
return;
|
||||
|
||||
auto event = m_input_event_queue.dequeue();
|
||||
event.visit(
|
||||
[&](QueuedMouseEvent const& event) {
|
||||
auto maybe_page = page(event.page_id);
|
||||
if (!maybe_page.has_value()) {
|
||||
dbgln("ConnectionFromClient::process_next_input_event: No page with ID {}", event.page_id);
|
||||
return;
|
||||
}
|
||||
auto& page = maybe_page.release_value();
|
||||
|
||||
auto maybe_page = page(event.page_id);
|
||||
if (!maybe_page.has_value()) {
|
||||
dbgln("ConnectionFromClient::process_next_input_event: No page with ID {}", event.page_id);
|
||||
return;
|
||||
}
|
||||
auto& page = maybe_page->page();
|
||||
|
||||
auto handled = event.event.visit(
|
||||
[&](Web::KeyEvent const& event) {
|
||||
switch (event.type) {
|
||||
case QueuedMouseEvent::Type::MouseDown:
|
||||
report_finished_handling_input_event(event.page_id, page.page().handle_mousedown(event.position, event.screen_position, event.button, event.buttons, event.modifiers));
|
||||
break;
|
||||
case QueuedMouseEvent::Type::MouseUp:
|
||||
report_finished_handling_input_event(event.page_id, page.page().handle_mouseup(event.position, event.screen_position, event.button, event.buttons, event.modifiers));
|
||||
break;
|
||||
case QueuedMouseEvent::Type::MouseMove:
|
||||
// NOTE: We have to notify the client about coalesced MouseMoves,
|
||||
// so we do that by saying none of them were handled by the web page.
|
||||
for (size_t i = 0; i < event.coalesced_event_count; ++i) {
|
||||
report_finished_handling_input_event(event.page_id, false);
|
||||
}
|
||||
report_finished_handling_input_event(event.page_id, page.page().handle_mousemove(event.position, event.screen_position, event.buttons, event.modifiers));
|
||||
break;
|
||||
case QueuedMouseEvent::Type::DoubleClick:
|
||||
report_finished_handling_input_event(event.page_id, page.page().handle_doubleclick(event.position, event.screen_position, event.button, event.buttons, event.modifiers));
|
||||
break;
|
||||
case QueuedMouseEvent::Type::MouseWheel:
|
||||
for (size_t i = 0; i < event.coalesced_event_count; ++i) {
|
||||
report_finished_handling_input_event(event.page_id, false);
|
||||
}
|
||||
report_finished_handling_input_event(event.page_id, page.page().handle_mousewheel(event.position, event.screen_position, event.button, event.buttons, event.modifiers, event.wheel_delta_x, event.wheel_delta_y));
|
||||
break;
|
||||
case Web::KeyEvent::Type::KeyDown:
|
||||
return page.handle_keydown(event.key, event.modifiers, event.code_point);
|
||||
case Web::KeyEvent::Type::KeyUp:
|
||||
return page.handle_keyup(event.key, event.modifiers, event.code_point);
|
||||
}
|
||||
VERIFY_NOT_REACHED();
|
||||
},
|
||||
[&](QueuedKeyboardEvent const& event) {
|
||||
auto maybe_page = page(event.page_id);
|
||||
if (!maybe_page.has_value()) {
|
||||
dbgln("ConnectionFromClient::process_next_input_event: No page with ID {}", event.page_id);
|
||||
return;
|
||||
}
|
||||
auto& page = maybe_page.release_value();
|
||||
|
||||
[&](Web::MouseEvent const& event) {
|
||||
switch (event.type) {
|
||||
case QueuedKeyboardEvent::Type::KeyDown:
|
||||
report_finished_handling_input_event(event.page_id, page.page().handle_keydown((KeyCode)event.key, event.modifiers, event.code_point));
|
||||
break;
|
||||
case QueuedKeyboardEvent::Type::KeyUp:
|
||||
report_finished_handling_input_event(event.page_id, page.page().handle_keyup((KeyCode)event.key, event.modifiers, event.code_point));
|
||||
break;
|
||||
case Web::MouseEvent::Type::MouseDown:
|
||||
return page.handle_mousedown(event.position, event.screen_position, event.button, event.buttons, event.modifiers);
|
||||
case Web::MouseEvent::Type::MouseUp:
|
||||
return page.handle_mouseup(event.position, event.screen_position, event.button, event.buttons, event.modifiers);
|
||||
case Web::MouseEvent::Type::MouseMove:
|
||||
return page.handle_mousemove(event.position, event.screen_position, event.buttons, event.modifiers);
|
||||
case Web::MouseEvent::Type::MouseWheel:
|
||||
return page.handle_mousewheel(event.position, event.screen_position, event.button, event.buttons, event.modifiers, event.wheel_delta_x, event.wheel_delta_y);
|
||||
case Web::MouseEvent::Type::DoubleClick:
|
||||
return page.handle_doubleclick(event.position, event.screen_position, event.button, event.buttons, event.modifiers);
|
||||
}
|
||||
VERIFY_NOT_REACHED();
|
||||
});
|
||||
|
||||
// We have to notify the client about coalesced events, so we do that by saying none of them were handled by the web page.
|
||||
for (size_t i = 0; i < event.coalesced_event_count; ++i)
|
||||
report_finished_handling_input_event(event.page_id, false);
|
||||
report_finished_handling_input_event(event.page_id, handled);
|
||||
|
||||
if (!m_input_event_queue.is_empty())
|
||||
m_input_event_queue_timer->start();
|
||||
}
|
||||
|
||||
void ConnectionFromClient::mouse_down(u64 page_id, Web::DevicePixelPoint position, Web::DevicePixelPoint screen_position, u32 button, u32 buttons, u32 modifiers)
|
||||
void ConnectionFromClient::key_event(u64 page_id, Web::KeyEvent const& event)
|
||||
{
|
||||
enqueue_input_event(
|
||||
QueuedMouseEvent {
|
||||
.type = QueuedMouseEvent::Type::MouseDown,
|
||||
.position = position,
|
||||
.screen_position = screen_position,
|
||||
.button = button,
|
||||
.buttons = buttons,
|
||||
.modifiers = modifiers,
|
||||
.page_id = page_id,
|
||||
});
|
||||
enqueue_input_event({ page_id, move(const_cast<Web::KeyEvent&>(event)), 0 });
|
||||
}
|
||||
|
||||
void ConnectionFromClient::mouse_move(u64 page_id, Web::DevicePixelPoint position, Web::DevicePixelPoint screen_position, [[maybe_unused]] u32 button, u32 buttons, u32 modifiers)
|
||||
void ConnectionFromClient::mouse_event(u64 page_id, Web::MouseEvent const& event)
|
||||
{
|
||||
auto event = QueuedMouseEvent {
|
||||
.type = QueuedMouseEvent::Type::MouseMove,
|
||||
.position = position,
|
||||
.screen_position = screen_position,
|
||||
.button = button,
|
||||
.buttons = buttons,
|
||||
.modifiers = modifiers,
|
||||
.page_id = page_id,
|
||||
// OPTIMIZATION: Coalesce consecutive unprocessed mouse move and wheel events.
|
||||
auto should_coalesce = [&]() {
|
||||
if (m_input_event_queue.is_empty())
|
||||
return false;
|
||||
|
||||
if (event.type != Web::MouseEvent::Type::MouseMove && event.type != Web::MouseEvent::Type::MouseWheel)
|
||||
return false;
|
||||
|
||||
if (m_input_event_queue.tail().page_id != page_id)
|
||||
return false;
|
||||
|
||||
if (auto* mouse_event = m_input_event_queue.tail().event.get_pointer<Web::MouseEvent>())
|
||||
return mouse_event->type == event.type;
|
||||
|
||||
return false;
|
||||
};
|
||||
|
||||
// OPTIMIZATION: Coalesce with previous unprocessed event iff the previous event is also a MouseMove event.
|
||||
if (!m_input_event_queue.is_empty()
|
||||
&& m_input_event_queue.tail().has<QueuedMouseEvent>()
|
||||
&& m_input_event_queue.tail().get<QueuedMouseEvent>().type == QueuedMouseEvent::Type::MouseMove
|
||||
&& m_input_event_queue.tail().get<QueuedMouseEvent>().page_id == page_id) {
|
||||
event.coalesced_event_count = m_input_event_queue.tail().get<QueuedMouseEvent>().coalesced_event_count + 1;
|
||||
m_input_event_queue.tail() = event;
|
||||
if (should_coalesce()) {
|
||||
m_input_event_queue.tail().event = move(const_cast<Web::MouseEvent&>(event));
|
||||
++m_input_event_queue.tail().coalesced_event_count;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
enqueue_input_event(move(event));
|
||||
enqueue_input_event({ page_id, move(const_cast<Web::MouseEvent&>(event)), 0 });
|
||||
}
|
||||
|
||||
void ConnectionFromClient::mouse_up(u64 page_id, Web::DevicePixelPoint position, Web::DevicePixelPoint screen_position, u32 button, u32 buttons, u32 modifiers)
|
||||
{
|
||||
enqueue_input_event(
|
||||
QueuedMouseEvent {
|
||||
.type = QueuedMouseEvent::Type::MouseUp,
|
||||
.position = position,
|
||||
.screen_position = screen_position,
|
||||
.button = button,
|
||||
.buttons = buttons,
|
||||
.modifiers = modifiers,
|
||||
.page_id = page_id,
|
||||
});
|
||||
}
|
||||
|
||||
void ConnectionFromClient::mouse_wheel(u64 page_id, Web::DevicePixelPoint position, Web::DevicePixelPoint screen_position, u32 button, u32 buttons, u32 modifiers, Web::DevicePixels wheel_delta_x, Web::DevicePixels wheel_delta_y)
|
||||
{
|
||||
auto event = QueuedMouseEvent {
|
||||
.type = QueuedMouseEvent::Type::MouseWheel,
|
||||
.position = position,
|
||||
.screen_position = screen_position,
|
||||
.button = button,
|
||||
.buttons = buttons,
|
||||
.modifiers = modifiers,
|
||||
.wheel_delta_x = wheel_delta_x,
|
||||
.wheel_delta_y = wheel_delta_y,
|
||||
.page_id = page_id,
|
||||
};
|
||||
|
||||
// OPTIMIZATION: Coalesce with previous unprocessed event if the previous event is also a MouseWheel event.
|
||||
if (!m_input_event_queue.is_empty()
|
||||
&& m_input_event_queue.tail().has<QueuedMouseEvent>()
|
||||
&& m_input_event_queue.tail().get<QueuedMouseEvent>().type == QueuedMouseEvent::Type::MouseWheel
|
||||
&& m_input_event_queue.tail().get<QueuedMouseEvent>().page_id == page_id) {
|
||||
auto const& last_event = m_input_event_queue.tail().get<QueuedMouseEvent>();
|
||||
event.coalesced_event_count = last_event.coalesced_event_count + 1;
|
||||
event.wheel_delta_x += last_event.wheel_delta_x;
|
||||
event.wheel_delta_y += last_event.wheel_delta_y;
|
||||
m_input_event_queue.tail() = event;
|
||||
return;
|
||||
}
|
||||
|
||||
enqueue_input_event(move(event));
|
||||
}
|
||||
|
||||
void ConnectionFromClient::doubleclick(u64 page_id, Web::DevicePixelPoint position, Web::DevicePixelPoint screen_position, u32 button, u32 buttons, u32 modifiers)
|
||||
{
|
||||
enqueue_input_event(
|
||||
QueuedMouseEvent {
|
||||
.type = QueuedMouseEvent::Type::DoubleClick,
|
||||
.position = position,
|
||||
.screen_position = screen_position,
|
||||
.button = button,
|
||||
.buttons = buttons,
|
||||
.modifiers = modifiers,
|
||||
.page_id = page_id,
|
||||
});
|
||||
}
|
||||
|
||||
void ConnectionFromClient::key_down(u64 page_id, i32 key, u32 modifiers, u32 code_point)
|
||||
{
|
||||
enqueue_input_event(
|
||||
QueuedKeyboardEvent {
|
||||
.type = QueuedKeyboardEvent::Type::KeyDown,
|
||||
.key = key,
|
||||
.modifiers = modifiers,
|
||||
.code_point = code_point,
|
||||
.page_id = page_id,
|
||||
});
|
||||
}
|
||||
|
||||
void ConnectionFromClient::key_up(u64 page_id, i32 key, u32 modifiers, u32 code_point)
|
||||
{
|
||||
enqueue_input_event(
|
||||
QueuedKeyboardEvent {
|
||||
.type = QueuedKeyboardEvent::Type::KeyUp,
|
||||
.key = key,
|
||||
.modifiers = modifiers,
|
||||
.code_point = code_point,
|
||||
.page_id = page_id,
|
||||
});
|
||||
}
|
||||
|
||||
void ConnectionFromClient::enqueue_input_event(Variant<QueuedMouseEvent, QueuedKeyboardEvent> event)
|
||||
void ConnectionFromClient::enqueue_input_event(QueuedInputEvent event)
|
||||
{
|
||||
m_input_event_queue.enqueue(move(event));
|
||||
m_input_event_queue_timer->start();
|
||||
|
|
|
@ -16,6 +16,7 @@
|
|||
#include <LibWeb/CSS/PreferredColorScheme.h>
|
||||
#include <LibWeb/Forward.h>
|
||||
#include <LibWeb/Loader/FileRequest.h>
|
||||
#include <LibWeb/Page/InputEvent.h>
|
||||
#include <LibWeb/Platform/Timer.h>
|
||||
#include <LibWebView/Forward.h>
|
||||
#include <WebContent/Forward.h>
|
||||
|
@ -56,13 +57,8 @@ private:
|
|||
virtual void load_url(u64 page_id, URL const&) override;
|
||||
virtual void load_html(u64 page_id, ByteString const&) override;
|
||||
virtual void set_viewport_rect(u64 page_id, Web::DevicePixelRect const&) override;
|
||||
virtual void mouse_down(u64 page_id, Web::DevicePixelPoint, Web::DevicePixelPoint, u32, u32, u32) override;
|
||||
virtual void mouse_move(u64 page_id, Web::DevicePixelPoint, Web::DevicePixelPoint, u32, u32, u32) override;
|
||||
virtual void mouse_up(u64 page_id, Web::DevicePixelPoint, Web::DevicePixelPoint, u32, u32, u32) override;
|
||||
virtual void mouse_wheel(u64 page_id, Web::DevicePixelPoint, Web::DevicePixelPoint, u32, u32, u32, Web::DevicePixels, Web::DevicePixels) override;
|
||||
virtual void doubleclick(u64 page_id, Web::DevicePixelPoint, Web::DevicePixelPoint, u32, u32, u32) override;
|
||||
virtual void key_down(u64 page_id, i32, u32, u32) override;
|
||||
virtual void key_up(u64 page_id, i32, u32, u32) override;
|
||||
virtual void key_event(u64 page_id, Web::KeyEvent const&) override;
|
||||
virtual void mouse_event(u64 page_id, Web::MouseEvent const&) override;
|
||||
virtual void add_backing_store(u64 page_id, i32 front_bitmap_id, Gfx::ShareableBitmap const& front_bitmap, i32 back_bitmap_id, Gfx::ShareableBitmap const& back_bitmap) override;
|
||||
virtual void ready_to_paint(u64 page_id) override;
|
||||
virtual void debug_request(u64 page_id, ByteString const&, ByteString const&) override;
|
||||
|
@ -136,42 +132,16 @@ private:
|
|||
HashMap<int, Web::FileRequest> m_requested_files {};
|
||||
int last_id { 0 };
|
||||
|
||||
struct QueuedMouseEvent {
|
||||
enum class Type {
|
||||
MouseMove,
|
||||
MouseDown,
|
||||
MouseUp,
|
||||
MouseWheel,
|
||||
DoubleClick,
|
||||
};
|
||||
Type type {};
|
||||
Web::DevicePixelPoint position {};
|
||||
Web::DevicePixelPoint screen_position {};
|
||||
u32 button {};
|
||||
u32 buttons {};
|
||||
u32 modifiers {};
|
||||
Web::DevicePixels wheel_delta_x {};
|
||||
Web::DevicePixels wheel_delta_y {};
|
||||
struct QueuedInputEvent {
|
||||
u64 page_id { 0 };
|
||||
Web::InputEvent event;
|
||||
size_t coalesced_event_count { 0 };
|
||||
u64 page_id { 0 };
|
||||
};
|
||||
|
||||
struct QueuedKeyboardEvent {
|
||||
enum class Type {
|
||||
KeyDown,
|
||||
KeyUp,
|
||||
};
|
||||
Type type {};
|
||||
i32 key {};
|
||||
u32 modifiers {};
|
||||
u32 code_point {};
|
||||
u64 page_id { 0 };
|
||||
};
|
||||
|
||||
void enqueue_input_event(Variant<QueuedMouseEvent, QueuedKeyboardEvent>);
|
||||
void enqueue_input_event(QueuedInputEvent);
|
||||
void process_next_input_event();
|
||||
|
||||
Queue<Variant<QueuedMouseEvent, QueuedKeyboardEvent>> m_input_event_queue;
|
||||
Queue<QueuedInputEvent> m_input_event_queue;
|
||||
|
||||
RefPtr<Web::Platform::Timer> m_input_event_queue_timer;
|
||||
};
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
#include <LibWeb/CSS/Selector.h>
|
||||
#include <LibWeb/HTML/ColorPickerUpdateState.h>
|
||||
#include <LibWeb/HTML/SelectedFile.h>
|
||||
#include <LibWeb/Page/InputEvent.h>
|
||||
#include <LibWeb/WebDriver/ExecuteScript.h>
|
||||
#include <LibWebView/Attribute.h>
|
||||
|
||||
|
@ -29,14 +30,8 @@ endpoint WebContentServer
|
|||
|
||||
set_viewport_rect(u64 page_id, Web::DevicePixelRect rect) =|
|
||||
|
||||
mouse_down(u64 page_id, Web::DevicePixelPoint position, Web::DevicePixelPoint screen_position, u32 button, u32 buttons, u32 modifiers) =|
|
||||
mouse_move(u64 page_id, Web::DevicePixelPoint position, Web::DevicePixelPoint screen_position, u32 button, u32 buttons, u32 modifiers) =|
|
||||
mouse_up(u64 page_id, Web::DevicePixelPoint position, Web::DevicePixelPoint screen_position, u32 button, u32 buttons, u32 modifiers) =|
|
||||
mouse_wheel(u64 page_id, Web::DevicePixelPoint position, Web::DevicePixelPoint screen_position, u32 button, u32 buttons, u32 modifiers, Web::DevicePixels wheel_delta_x, Web::DevicePixels wheel_delta_y) =|
|
||||
doubleclick(u64 page_id, Web::DevicePixelPoint position, Web::DevicePixelPoint screen_position, u32 button, u32 buttons, u32 modifiers) =|
|
||||
|
||||
key_down(u64 page_id, i32 key, u32 modifiers, u32 code_point) =|
|
||||
key_up(u64 page_id, i32 key, u32 modifiers, u32 code_point) =|
|
||||
key_event(u64 page_id, Web::KeyEvent event) =|
|
||||
mouse_event(u64 page_id, Web::MouseEvent event) =|
|
||||
|
||||
debug_request(u64 page_id, ByteString request, ByteString argument) =|
|
||||
get_source(u64 page_id) =|
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue