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
parent 4bb9168712
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 };
}
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;
};
using InputEvent = Variant<KeyEvent, MouseEvent>;
using InputEvent = Variant<KeyEvent, MouseEvent, DragEvent>;
}
@ -100,4 +100,10 @@ ErrorOr<void> encode(Encoder&, Web::MouseEvent const&);
template<>
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) {
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();
if (!event_was_accepted && event.has<Web::KeyEvent>()) {
auto const& key_event = event.get<Web::KeyEvent>();
if (event_was_accepted)
return;
// Here we handle events that were not consumed or cancelled by the WebContent. Propagate the event back
// to the concrete view implementation.
if (on_finish_handling_key_event)
on_finish_handling_key_event(key_event);
}
// Here we handle events that were not consumed or cancelled by the WebContent. Propagate the event back
// to the concrete view implementation.
event.visit(
[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)

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(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::DragEvent const&)> on_finish_handling_drag_event;
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(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);
}
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->
@ -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 });
}
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)
{
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 key_event(u64 page_id, Web::KeyEvent 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 debug_request(u64 page_id, ByteString const&, ByteString const&) 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) =|
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) =|
get_source(u64 page_id) =|