mirror of
https://github.com/SerenityOS/serenity.git
synced 2026-11-07 04:29:30 -10:00
LibWebView: Implement drag-and-drop for OutOfProcessWebView
Almost the entirety of drag-and-drop operations are handled within LibWeb. This patch just hooks up the UI-side operations to trigger the events. A FIXME is left here to open files in the browser that were not accepted by the web page.
This commit is contained in:
1 parent
c3b1d533f6
commit
4a52145f8e
2 files changed
+91
No files matched your search
@@ -60,6 +60,10 @@ OutOfProcessWebView::OutOfProcessWebView()
|
||||
finish_handling_key_event(event);
|
||||
};
|
||||
|
||||
on_finish_handling_drag_event = [this](auto const& event) {
|
||||
finish_handling_drag_event(event);
|
||||
};
|
||||
|
||||
on_request_worker_agent = []() {
|
||||
auto worker_client = MUST(Web::HTML::WebWorkerClient::try_create());
|
||||
return worker_client->dup_socket();
|
||||
@@ -282,6 +286,35 @@ void OutOfProcessWebView::hide_event(GUI::HideEvent&)
|
||||
set_system_visibility_state(false);
|
||||
}
|
||||
|
||||
void OutOfProcessWebView::drag_enter_event(GUI::DragEvent& event)
|
||||
{
|
||||
if (!event.mime_data().has_urls())
|
||||
return;
|
||||
|
||||
enqueue_native_event(Web::DragEvent::Type::DragStart, event);
|
||||
event.accept();
|
||||
}
|
||||
|
||||
void OutOfProcessWebView::drag_move_event(GUI::DragEvent& event)
|
||||
{
|
||||
enqueue_native_event(Web::DragEvent::Type::DragMove, event);
|
||||
event.accept();
|
||||
}
|
||||
|
||||
void OutOfProcessWebView::drag_leave_event(GUI::Event&)
|
||||
{
|
||||
Web::DragEvent event {};
|
||||
event.type = Web::DragEvent::Type::DragEnd;
|
||||
|
||||
enqueue_input_event(move(event));
|
||||
}
|
||||
|
||||
void OutOfProcessWebView::drop_event(GUI::DropEvent& event)
|
||||
{
|
||||
enqueue_native_event(Web::DragEvent::Type::Drop, event);
|
||||
event.accept();
|
||||
}
|
||||
|
||||
static constexpr Web::UIEvents::MouseButton web_button_from_gui_button(GUI::MouseButton button)
|
||||
{
|
||||
switch (button) {
|
||||
@@ -342,6 +375,56 @@ void OutOfProcessWebView::enqueue_native_event(Web::MouseEvent::Type type, GUI::
|
||||
enqueue_input_event(Web::MouseEvent { type, position, screen_position, button, buttons, modifiers, wheel_delta_x, wheel_delta_y, nullptr });
|
||||
}
|
||||
|
||||
struct DragData : Web::ChromeInputData {
|
||||
explicit DragData(GUI::DropEvent const& event)
|
||||
: event(make<GUI::DropEvent>(event))
|
||||
{
|
||||
}
|
||||
|
||||
NonnullOwnPtr<GUI::DropEvent> event;
|
||||
};
|
||||
|
||||
void OutOfProcessWebView::enqueue_native_event(Web::DragEvent::Type type, GUI::DropEvent const& event)
|
||||
{
|
||||
auto position = to_content_position(event.position()).to_type<Web::DevicePixels>();
|
||||
auto screen_position = (event.position() + (window()->position() + relative_position())).to_type<Web::DevicePixels>();
|
||||
|
||||
auto button = web_button_from_gui_button(event.button());
|
||||
auto buttons = web_buttons_from_gui_buttons(event.buttons());
|
||||
auto modifiers = web_modifiers_from_gui_modifiers(event.modifiers());
|
||||
|
||||
Vector<Web::HTML::SelectedFile> files;
|
||||
OwnPtr<DragData> chrome_data;
|
||||
|
||||
if (type == Web::DragEvent::Type::DragStart) {
|
||||
VERIFY(event.mime_data().has_urls());
|
||||
|
||||
for (auto const& url : event.mime_data().urls()) {
|
||||
auto file_path = URL::percent_decode(url.serialize_path());
|
||||
|
||||
if (auto file = Web::HTML::SelectedFile::from_file_path(file_path); file.is_error())
|
||||
warnln("Unable to open file {} for drag-and-drop: {}", file_path, file.error());
|
||||
else
|
||||
files.append(file.release_value());
|
||||
}
|
||||
} else if (type == Web::DragEvent::Type::Drop) {
|
||||
chrome_data = make<DragData>(event);
|
||||
} else {
|
||||
VERIFY(type == Web::DragEvent::Type::DragMove);
|
||||
}
|
||||
|
||||
enqueue_input_event(Web::DragEvent { type, position, screen_position, button, buttons, modifiers, move(files), move(chrome_data) });
|
||||
}
|
||||
|
||||
void OutOfProcessWebView::finish_handling_drag_event(Web::DragEvent const& event)
|
||||
{
|
||||
if (event.type != Web::DragEvent::Type::Drop)
|
||||
return;
|
||||
|
||||
// FIXME: Implement opening the event URLs in the Browser.
|
||||
[[maybe_unused]] auto const& chrome_data = verify_cast<DragData>(*event.chrome_data);
|
||||
}
|
||||
|
||||
struct KeyData : Web::ChromeInputData {
|
||||
explicit KeyData(GUI::KeyEvent const& event)
|
||||
: event(make<GUI::KeyEvent>(event))
|
||||
|
||||
@@ -71,6 +71,10 @@ private:
|
||||
virtual void focusout_event(GUI::FocusEvent&) override;
|
||||
virtual void show_event(GUI::ShowEvent&) override;
|
||||
virtual void hide_event(GUI::HideEvent&) override;
|
||||
virtual void drag_enter_event(GUI::DragEvent&) override;
|
||||
virtual void drag_move_event(GUI::DragEvent&) override;
|
||||
virtual void drag_leave_event(GUI::Event&) override;
|
||||
virtual void drop_event(GUI::DropEvent&) override;
|
||||
|
||||
// ^WebView::ViewImplementation
|
||||
virtual void initialize_client(CreateNewClient) override;
|
||||
@@ -81,6 +85,10 @@ private:
|
||||
virtual Gfx::IntPoint to_widget_position(Gfx::IntPoint content_position) const override;
|
||||
|
||||
void enqueue_native_event(Web::MouseEvent::Type, GUI::MouseEvent const& event);
|
||||
|
||||
void enqueue_native_event(Web::DragEvent::Type, GUI::DropEvent const& event);
|
||||
void finish_handling_drag_event(Web::DragEvent const&);
|
||||
|
||||
void enqueue_native_event(Web::KeyEvent::Type, GUI::KeyEvent const& event);
|
||||
void finish_handling_key_event(Web::KeyEvent const&);
|
||||
|
||||
|
||||
Reference in new issue
Block a user