diff --git a/Libraries/LibGUI/Application.cpp b/Libraries/LibGUI/Application.cpp index 8aaae7026e..fbd0c7260d 100644 --- a/Libraries/LibGUI/Application.cpp +++ b/Libraries/LibGUI/Application.cpp @@ -261,7 +261,7 @@ void Application::set_pending_drop_widget(Widget* widget) m_pending_drop_widget->update(); } -void Application::set_drag_hovered_widget_impl(Widget* widget, const Gfx::IntPoint& position, const String& mime_type) +void Application::set_drag_hovered_widget_impl(Widget* widget, const Gfx::IntPoint& position, Vector mime_types) { if (widget == m_drag_hovered_widget) return; @@ -275,7 +275,7 @@ void Application::set_drag_hovered_widget_impl(Widget* widget, const Gfx::IntPoi m_drag_hovered_widget = widget; if (m_drag_hovered_widget) { - DragEvent enter_event(Event::DragEnter, position, mime_type); + DragEvent enter_event(Event::DragEnter, position, move(mime_types)); enter_event.ignore(); m_drag_hovered_widget->dispatch_event(enter_event, m_drag_hovered_widget->window()); if (enter_event.is_accepted()) diff --git a/Libraries/LibGUI/Application.h b/Libraries/LibGUI/Application.h index ea073c17e8..4114ef631d 100644 --- a/Libraries/LibGUI/Application.h +++ b/Libraries/LibGUI/Application.h @@ -90,9 +90,9 @@ public: Widget* pending_drop_widget() { return m_pending_drop_widget.ptr(); } const Widget* pending_drop_widget() const { return m_pending_drop_widget.ptr(); } - void set_drag_hovered_widget(Badge, Widget* widget, const Gfx::IntPoint& position = {}, const String& mime_type = {}) + void set_drag_hovered_widget(Badge, Widget* widget, const Gfx::IntPoint& position = {}, Vector mime_types = {}) { - set_drag_hovered_widget_impl(widget, position, mime_type); + set_drag_hovered_widget_impl(widget, position, move(mime_types)); } void notify_drag_cancelled(Badge); @@ -102,7 +102,7 @@ private: void tooltip_show_timer_did_fire(); void tooltip_hide_timer_did_fire(); - void set_drag_hovered_widget_impl(Widget*, const Gfx::IntPoint& = {}, const String& = {}); + void set_drag_hovered_widget_impl(Widget*, const Gfx::IntPoint& = {}, Vector = {}); void set_pending_drop_widget(Widget*); OwnPtr m_event_loop; diff --git a/Libraries/LibGUI/Event.h b/Libraries/LibGUI/Event.h index 17ae0c65ed..ce60f00e12 100644 --- a/Libraries/LibGUI/Event.h +++ b/Libraries/LibGUI/Event.h @@ -347,19 +347,19 @@ private: class DragEvent final : public Event { public: - DragEvent(Type type, const Gfx::IntPoint& position, const String& data_type) + DragEvent(Type type, const Gfx::IntPoint& position, Vector mime_types) : Event(type) , m_position(position) - , m_data_type(data_type) + , m_mime_types(move(mime_types)) { } const Gfx::IntPoint& position() const { return m_position; } - const String& data_type() const { return m_data_type; } + const Vector& mime_types() const { return m_mime_types; } private: Gfx::IntPoint m_position; - String m_data_type; + Vector m_mime_types; }; class DropEvent final : public Event { diff --git a/Libraries/LibGUI/FileSystemModel.cpp b/Libraries/LibGUI/FileSystemModel.cpp index 69b0fcb168..f5ed18c637 100644 --- a/Libraries/LibGUI/FileSystemModel.cpp +++ b/Libraries/LibGUI/FileSystemModel.cpp @@ -589,11 +589,11 @@ String FileSystemModel::column_name(int column) const ASSERT_NOT_REACHED(); } -bool FileSystemModel::accepts_drag(const ModelIndex& index, const StringView& data_type) +bool FileSystemModel::accepts_drag(const ModelIndex& index, const Vector& mime_types) { if (!index.is_valid()) return false; - if (data_type != "text/uri-list") + if (!mime_types.contains_slow("text/uri-list")) return false; auto& node = this->node(index); return node.is_directory(); diff --git a/Libraries/LibGUI/FileSystemModel.h b/Libraries/LibGUI/FileSystemModel.h index 203ae3cd98..f2c0ea4e7b 100644 --- a/Libraries/LibGUI/FileSystemModel.h +++ b/Libraries/LibGUI/FileSystemModel.h @@ -147,7 +147,7 @@ public: virtual ModelIndex parent_index(const ModelIndex&) const override; virtual ModelIndex index(int row, int column = 0, const ModelIndex& parent = ModelIndex()) const override; virtual StringView drag_data_type() const override { return "text/uri-list"; } - virtual bool accepts_drag(const ModelIndex&, const StringView& data_type) override; + virtual bool accepts_drag(const ModelIndex&, const Vector& mime_types) override; virtual bool is_column_sortable(int column_index) const override { return column_index != Column::Icon; } virtual bool is_editable(const ModelIndex&) const override; virtual bool is_searchable() const override { return true; } diff --git a/Libraries/LibGUI/IconView.cpp b/Libraries/LibGUI/IconView.cpp index 340df616fb..51c3801c0f 100644 --- a/Libraries/LibGUI/IconView.cpp +++ b/Libraries/LibGUI/IconView.cpp @@ -270,10 +270,7 @@ void IconView::drag_move_event(DragEvent& event) auto index = index_at_event_position(event.position()); ModelIndex new_drop_candidate_index; if (index.is_valid()) { - bool acceptable = model()->accepts_drag(index, event.data_type()); -#ifdef DRAGDROP_DEBUG - dbg() << "Drag of type '" << event.data_type() << "' moving over " << index << ", acceptable: " << acceptable; -#endif + bool acceptable = model()->accepts_drag(index, event.mime_types()); if (acceptable) new_drop_candidate_index = index; } diff --git a/Libraries/LibGUI/Model.cpp b/Libraries/LibGUI/Model.cpp index 6f8b833f7d..a1e4180a9b 100644 --- a/Libraries/LibGUI/Model.cpp +++ b/Libraries/LibGUI/Model.cpp @@ -71,7 +71,7 @@ ModelIndex Model::index(int row, int column, const ModelIndex&) const return create_index(row, column); } -bool Model::accepts_drag(const ModelIndex&, const StringView&) +bool Model::accepts_drag(const ModelIndex&, const Vector&) { return false; } diff --git a/Libraries/LibGUI/Model.h b/Libraries/LibGUI/Model.h index de6defbb25..5402edcb31 100644 --- a/Libraries/LibGUI/Model.h +++ b/Libraries/LibGUI/Model.h @@ -82,7 +82,7 @@ public: virtual bool is_searchable() const { return false; } virtual void set_data(const ModelIndex&, const Variant&) { } virtual int tree_column() const { return 0; } - virtual bool accepts_drag(const ModelIndex&, const StringView& data_type); + virtual bool accepts_drag(const ModelIndex&, const Vector& mime_types); virtual Vector matches(const StringView&, unsigned = MatchesFlag::AllMatching, const ModelIndex& = ModelIndex()) { return {}; } virtual bool is_column_sortable([[maybe_unused]] int column_index) const { return true; } diff --git a/Libraries/LibGUI/Widget.cpp b/Libraries/LibGUI/Widget.cpp index 273d048f4a..04e8249e69 100644 --- a/Libraries/LibGUI/Widget.cpp +++ b/Libraries/LibGUI/Widget.cpp @@ -510,7 +510,9 @@ void Widget::drag_move_event(DragEvent&) void Widget::drag_enter_event(DragEvent& event) { - dbgln("{} {:p} DRAG ENTER @ {}, {}", class_name(), this, event.position(), event.data_type()); + StringBuilder builder; + builder.join(',', event.mime_types()); + dbgln("{} {:p} DRAG ENTER @ {}, {}", class_name(), this, event.position(), builder.string_view()); } void Widget::drag_leave_event(Event&) diff --git a/Libraries/LibGUI/Window.cpp b/Libraries/LibGUI/Window.cpp index 0094175c84..ac4aa36001 100644 --- a/Libraries/LibGUI/Window.cpp +++ b/Libraries/LibGUI/Window.cpp @@ -446,14 +446,14 @@ void Window::handle_drag_move_event(DragEvent& event) auto result = m_main_widget->hit_test(event.position()); ASSERT(result.widget); - Application::the()->set_drag_hovered_widget({}, result.widget, result.local_position, event.data_type()); + Application::the()->set_drag_hovered_widget({}, result.widget, result.local_position, event.mime_types()); // NOTE: Setting the drag hovered widget may have executed arbitrary code, so re-check that the widget is still there. if (!result.widget) return; if (result.widget->has_pending_drop()) { - DragEvent drag_move_event(static_cast(event.type()), result.local_position, event.data_type()); + DragEvent drag_move_event(static_cast(event.type()), result.local_position, event.mime_types()); result.widget->dispatch_event(drag_move_event, this); } } diff --git a/Libraries/LibGUI/WindowServerConnection.cpp b/Libraries/LibGUI/WindowServerConnection.cpp index bbd49d702c..8250f134af 100644 --- a/Libraries/LibGUI/WindowServerConnection.cpp +++ b/Libraries/LibGUI/WindowServerConnection.cpp @@ -246,7 +246,7 @@ void WindowServerConnection::handle(const Messages::WindowClient::MouseMove& mes { if (auto* window = Window::from_window_id(message.window_id())) { if (message.is_drag()) - Core::EventLoop::current().post_event(*window, make(Event::DragMove, message.mouse_position(), message.drag_data_type())); + Core::EventLoop::current().post_event(*window, make(Event::DragMove, message.mouse_position(), message.mime_types())); else Core::EventLoop::current().post_event(*window, make(Event::MouseMove, message.mouse_position(), message.buttons(), to_gmousebutton(message.button()), message.modifiers(), message.wheel_delta())); } diff --git a/Services/WindowServer/Event.h b/Services/WindowServer/Event.h index 3e9adf8830..e82df2d4c9 100644 --- a/Services/WindowServer/Event.h +++ b/Services/WindowServer/Event.h @@ -126,7 +126,13 @@ public: unsigned modifiers() const { return m_modifiers; } int wheel_delta() const { return m_wheel_delta; } bool is_drag() const { return m_drag; } - const String& drag_data_type() const { return m_drag_data_type; } + + Vector mime_types() const + { + if (!m_mime_data) + return {}; + return m_mime_data->formats(); + } void set_drag(bool b) { m_drag = b; } void set_mime_data(const Core::MimeData& mime_data) { m_mime_data = mime_data; } @@ -140,7 +146,6 @@ private: unsigned m_modifiers { 0 }; int m_wheel_delta { 0 }; bool m_drag { false }; - String m_drag_data_type; RefPtr m_mime_data; }; diff --git a/Services/WindowServer/Screen.cpp b/Services/WindowServer/Screen.cpp index f929586c50..2d68c4890e 100644 --- a/Services/WindowServer/Screen.cpp +++ b/Services/WindowServer/Screen.cpp @@ -162,6 +162,8 @@ void Screen::on_receive_mouse_data(const MousePacket& packet) post_mousedown_or_mouseup_if_needed(MouseButton::Forward); if (m_cursor_location != prev_location) { auto message = make(Event::MouseMove, m_cursor_location, buttons, MouseButton::None, m_modifiers); + if (WindowManager::the().dnd_client()) + message->set_mime_data(WindowManager::the().dnd_mime_data()); Core::EventLoop::current().post_event(WindowManager::the(), move(message)); } diff --git a/Services/WindowServer/Window.cpp b/Services/WindowServer/Window.cpp index b79684e79e..1d0497c1c6 100644 --- a/Services/WindowServer/Window.cpp +++ b/Services/WindowServer/Window.cpp @@ -182,7 +182,7 @@ void Window::handle_mouse_event(const MouseEvent& event) switch (event.type()) { case Event::MouseMove: - m_client->post_message(Messages::WindowClient::MouseMove(m_window_id, event.position(), (u32)event.button(), event.buttons(), event.modifiers(), event.wheel_delta(), event.is_drag(), event.drag_data_type())); + m_client->post_message(Messages::WindowClient::MouseMove(m_window_id, event.position(), (u32)event.button(), event.buttons(), event.modifiers(), event.wheel_delta(), event.is_drag(), event.mime_types())); break; case Event::MouseDown: m_client->post_message(Messages::WindowClient::MouseDown(m_window_id, event.position(), (u32)event.button(), event.buttons(), event.modifiers(), event.wheel_delta())); diff --git a/Services/WindowServer/WindowClient.ipc b/Services/WindowServer/WindowClient.ipc index a1ce1413a3..c6ac17b022 100644 --- a/Services/WindowServer/WindowClient.ipc +++ b/Services/WindowServer/WindowClient.ipc @@ -1,7 +1,7 @@ endpoint WindowClient = 4 { Paint(i32 window_id, Gfx::IntSize window_size, Vector rects) =| - MouseMove(i32 window_id, Gfx::IntPoint mouse_position, u32 button, u32 buttons, u32 modifiers, i32 wheel_delta, bool is_drag, String drag_data_type) =| + MouseMove(i32 window_id, Gfx::IntPoint mouse_position, u32 button, u32 buttons, u32 modifiers, i32 wheel_delta, bool is_drag, Vector mime_types) =| MouseDown(i32 window_id, Gfx::IntPoint mouse_position, u32 button, u32 buttons, u32 modifiers, i32 wheel_delta) =| MouseDoubleClick(i32 window_id, Gfx::IntPoint mouse_position, u32 button, u32 buttons, u32 modifiers, i32 wheel_delta) =| MouseUp(i32 window_id, Gfx::IntPoint mouse_position, u32 button, u32 buttons, u32 modifiers, i32 wheel_delta) =|