LibWeb+LibWebView+WebContent: Add IPC to send drag-and-drop events

This adds the IPC and related hooks to allow the UI to send drag-and-
drop events from the UI process to the WebContent process.
This commit is contained in:
Timothy Flynn 2024-08-17 13:36:28 -04:00 committed by Andreas Kling
commit 948b6de3b1
Notes: github-actions[bot] 2024-08-19 11:30:20 +00:00
7 changed files with 65 additions and 8 deletions

View file

@ -76,3 +76,30 @@ ErrorOr<Web::MouseEvent> IPC::decode(Decoder& decoder)
return Web::MouseEvent { type, position, screen_position, button, buttons, modifiers, wheel_delta_x, wheel_delta_y, nullptr }; return Web::MouseEvent { type, position, screen_position, button, buttons, modifiers, wheel_delta_x, wheel_delta_y, nullptr };
} }
template<>
ErrorOr<void> IPC::encode(Encoder& encoder, Web::DragEvent const& event)
{
TRY(encoder.encode(event.type));
TRY(encoder.encode(event.position));
TRY(encoder.encode(event.screen_position));
TRY(encoder.encode(event.button));
TRY(encoder.encode(event.buttons));
TRY(encoder.encode(event.modifiers));
TRY(encoder.encode(event.files));
return {};
}
template<>
ErrorOr<Web::DragEvent> IPC::decode(Decoder& decoder)
{
auto type = TRY(decoder.decode<Web::DragEvent::Type>());
auto position = TRY(decoder.decode<Web::DevicePixelPoint>());
auto screen_position = TRY(decoder.decode<Web::DevicePixelPoint>());
auto button = TRY(decoder.decode<Web::UIEvents::MouseButton>());
auto buttons = TRY(decoder.decode<Web::UIEvents::MouseButton>());
auto modifiers = TRY(decoder.decode<Web::UIEvents::KeyModifier>());
auto files = TRY(decoder.decode<Vector<Web::HTML::SelectedFile>>());
return Web::DragEvent { type, position, screen_position, button, buttons, modifiers, move(files), nullptr };
}

View file

@ -82,7 +82,7 @@ struct DragEvent {
OwnPtr<ChromeInputData> chrome_data; OwnPtr<ChromeInputData> chrome_data;
}; };
using InputEvent = Variant<KeyEvent, MouseEvent>; using InputEvent = Variant<KeyEvent, MouseEvent, DragEvent>;
} }
@ -100,4 +100,10 @@ ErrorOr<void> encode(Encoder&, Web::MouseEvent const&);
template<> template<>
ErrorOr<Web::MouseEvent> decode(Decoder&); ErrorOr<Web::MouseEvent> decode(Decoder&);
template<>
ErrorOr<void> encode(Encoder&, Web::DragEvent const&);
template<>
ErrorOr<Web::DragEvent> decode(Decoder&);
} }

View file

@ -137,6 +137,12 @@ void ViewImplementation::enqueue_input_event(Web::InputEvent event)
}, },
[this](Web::MouseEvent const& event) { [this](Web::MouseEvent const& event) {
client().async_mouse_event(m_client_state.page_index, event.clone_without_chrome_data()); client().async_mouse_event(m_client_state.page_index, event.clone_without_chrome_data());
},
[this](Web::DragEvent& event) {
auto cloned_event = event.clone_without_chrome_data();
cloned_event.files = move(event.files);
client().async_drag_event(m_client_state.page_index, move(cloned_event));
}); });
} }
@ -144,14 +150,21 @@ void ViewImplementation::did_finish_handling_input_event(Badge<WebContentClient>
{ {
auto event = m_pending_input_events.dequeue(); auto event = m_pending_input_events.dequeue();
if (!event_was_accepted && event.has<Web::KeyEvent>()) { if (event_was_accepted)
auto const& key_event = event.get<Web::KeyEvent>(); return;
// Here we handle events that were not consumed or cancelled by the WebContent. Propagate the event back // Here we handle events that were not consumed or cancelled by the WebContent. Propagate the event back
// to the concrete view implementation. // to the concrete view implementation.
if (on_finish_handling_key_event) event.visit(
on_finish_handling_key_event(key_event); [this](Web::KeyEvent const& event) {
} if (on_finish_handling_key_event)
on_finish_handling_key_event(event);
},
[this](Web::DragEvent const& event) {
if (on_finish_handling_drag_event)
on_finish_handling_drag_event(event);
},
[](auto const&) {});
} }
void ViewImplementation::set_preferred_color_scheme(Web::CSS::PreferredColorScheme color_scheme) void ViewImplementation::set_preferred_color_scheme(Web::CSS::PreferredColorScheme color_scheme)

View file

@ -203,6 +203,7 @@ public:
Function<void(Web::HTML::FileFilter const& accepted_file_types, Web::HTML::AllowMultipleFiles)> on_request_file_picker; Function<void(Web::HTML::FileFilter const& accepted_file_types, Web::HTML::AllowMultipleFiles)> on_request_file_picker;
Function<void(Gfx::IntPoint content_position, i32 minimum_width, Vector<Web::HTML::SelectItem> items)> on_request_select_dropdown; Function<void(Gfx::IntPoint content_position, i32 minimum_width, Vector<Web::HTML::SelectItem> items)> on_request_select_dropdown;
Function<void(Web::KeyEvent const&)> on_finish_handling_key_event; Function<void(Web::KeyEvent const&)> on_finish_handling_key_event;
Function<void(Web::DragEvent const&)> on_finish_handling_drag_event;
Function<void()> on_text_test_finish; Function<void()> on_text_test_finish;
Function<void(size_t current_match_index, Optional<size_t> const& total_match_count)> on_find_in_page; Function<void(size_t current_match_index, Optional<size_t> const& total_match_count)> on_find_in_page;
Function<void(Gfx::Color)> on_theme_color_change; Function<void(Gfx::Color)> on_theme_color_change;

View file

@ -207,6 +207,9 @@ void ConnectionFromClient::process_next_input_event()
return page->page().handle_doubleclick(event.position, event.screen_position, event.button, event.buttons, event.modifiers); return page->page().handle_doubleclick(event.position, event.screen_position, event.button, event.buttons, event.modifiers);
} }
VERIFY_NOT_REACHED(); VERIFY_NOT_REACHED();
},
[&](Web::DragEvent& event) {
return page->page().handle_drag_and_drop_event(event.type, event.position, event.screen_position, event.button, event.buttons, event.modifiers, move(event.files));
}); });
// We have to notify the client about coalesced events, so we do that by saying none of them were handled by the web page-> // We have to notify the client about coalesced events, so we do that by saying none of them were handled by the web page->
@ -257,6 +260,11 @@ void ConnectionFromClient::mouse_event(u64 page_id, Web::MouseEvent const& event
enqueue_input_event({ page_id, move(const_cast<Web::MouseEvent&>(event)), 0 }); enqueue_input_event({ page_id, move(const_cast<Web::MouseEvent&>(event)), 0 });
} }
void ConnectionFromClient::drag_event(u64 page_id, Web::DragEvent const& event)
{
enqueue_input_event({ page_id, move(const_cast<Web::DragEvent&>(event)), 0 });
}
void ConnectionFromClient::enqueue_input_event(QueuedInputEvent event) void ConnectionFromClient::enqueue_input_event(QueuedInputEvent event)
{ {
m_input_event_queue.enqueue(move(event)); m_input_event_queue.enqueue(move(event));

View file

@ -67,6 +67,7 @@ private:
virtual void set_viewport_size(u64 page_id, Web::DevicePixelSize const) override; virtual void set_viewport_size(u64 page_id, Web::DevicePixelSize const) override;
virtual void key_event(u64 page_id, Web::KeyEvent const&) 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 mouse_event(u64 page_id, Web::MouseEvent const&) override;
virtual void drag_event(u64 page_id, Web::DragEvent const&) override;
virtual void ready_to_paint(u64 page_id) override; virtual void ready_to_paint(u64 page_id) override;
virtual void debug_request(u64 page_id, ByteString const&, ByteString const&) override; virtual void debug_request(u64 page_id, ByteString const&, ByteString const&) override;
virtual void get_source(u64 page_id) override; virtual void get_source(u64 page_id) override;

View file

@ -35,6 +35,7 @@ endpoint WebContentServer
key_event(u64 page_id, Web::KeyEvent event) =| key_event(u64 page_id, Web::KeyEvent event) =|
mouse_event(u64 page_id, Web::MouseEvent event) =| mouse_event(u64 page_id, Web::MouseEvent event) =|
drag_event(u64 page_id, Web::DragEvent event) =|
debug_request(u64 page_id, ByteString request, ByteString argument) =| debug_request(u64 page_id, ByteString request, ByteString argument) =|
get_source(u64 page_id) =| get_source(u64 page_id) =|