mirror of
https://github.com/SerenityOS/serenity.git
synced 2025-01-22 09:21:57 -05:00
LibGUI+WindowServer+Applications: Carry more data across drag events
To support drag-and-drop for LibWeb, the drag events need the full mime data from WindowServer, not just the list of stringified mime types. We only provided the full data in the drop events. This patch provides the Core::MimeData type, as well as other mouse-event information needed for LibWeb (what buttons / modifiers are pressed). To do this, we add a specific WindowServer IPC to inform the Application of the event. We previously tagged mouse-move events with some drag data and formed the drag event client-side. That extra data is removed in favor of this new IPC.
This commit is contained in:
parent
b499279162
commit
81e469c911
37 changed files with 116 additions and 130 deletions
|
@ -131,8 +131,7 @@ private:
|
|||
|
||||
void GLContextWidget::drag_enter_event(GUI::DragEvent& event)
|
||||
{
|
||||
auto const& mime_types = event.mime_types();
|
||||
if (mime_types.contains_slow("text/uri-list"sv))
|
||||
if (event.mime_data().has_urls())
|
||||
event.accept();
|
||||
}
|
||||
|
||||
|
|
|
@ -992,8 +992,7 @@ void MainWidget::update_preview()
|
|||
|
||||
void MainWidget::drag_enter_event(GUI::DragEvent& event)
|
||||
{
|
||||
auto const& mime_types = event.mime_types();
|
||||
if (mime_types.contains_slow("text/uri-list"sv))
|
||||
if (event.mime_data().has_urls())
|
||||
event.accept();
|
||||
}
|
||||
|
||||
|
|
|
@ -833,8 +833,7 @@ void HexEditorWidget::set_value_inspector_visible(bool visible)
|
|||
|
||||
void HexEditorWidget::drag_enter_event(GUI::DragEvent& event)
|
||||
{
|
||||
auto const& mime_types = event.mime_types();
|
||||
if (mime_types.contains_slow("text/uri-list"sv))
|
||||
if (event.mime_data().has_urls())
|
||||
event.accept();
|
||||
}
|
||||
|
||||
|
|
|
@ -283,8 +283,7 @@ ErrorOr<void> ViewWidget::try_open_file(String const& path, Core::File& file)
|
|||
|
||||
void ViewWidget::drag_enter_event(GUI::DragEvent& event)
|
||||
{
|
||||
auto const& mime_types = event.mime_types();
|
||||
if (mime_types.contains_slow("text/uri-list"sv))
|
||||
if (event.mime_data().has_urls())
|
||||
event.accept();
|
||||
}
|
||||
|
||||
|
|
|
@ -523,8 +523,7 @@ PDF::PDFErrorOr<void> PDFViewerWidget::try_open_file(StringView path, NonnullOwn
|
|||
|
||||
void PDFViewerWidget::drag_enter_event(GUI::DragEvent& event)
|
||||
{
|
||||
auto const& mime_types = event.mime_types();
|
||||
if (mime_types.contains_slow("text/uri-list"sv))
|
||||
if (event.mime_data().has_urls())
|
||||
event.accept();
|
||||
}
|
||||
|
||||
|
|
|
@ -1492,8 +1492,7 @@ ImageEditor& MainWidget::create_new_editor(NonnullRefPtr<Image> image)
|
|||
|
||||
void MainWidget::drag_enter_event(GUI::DragEvent& event)
|
||||
{
|
||||
auto const& mime_types = event.mime_types();
|
||||
if (mime_types.contains_slow("text/uri-list"sv))
|
||||
if (event.mime_data().has_urls())
|
||||
event.accept();
|
||||
}
|
||||
|
||||
|
|
|
@ -205,8 +205,7 @@ void PresenterWidget::second_paint_event(GUI::PaintEvent& event)
|
|||
|
||||
void PresenterWidget::drag_enter_event(GUI::DragEvent& event)
|
||||
{
|
||||
auto const& mime_types = event.mime_types();
|
||||
if (mime_types.contains_slow("text/uri-list"sv))
|
||||
if (event.mime_data().has_urls())
|
||||
event.accept();
|
||||
}
|
||||
|
||||
|
|
|
@ -147,8 +147,7 @@ void SoundPlayerWidget::set_nonlinear_volume_slider(bool nonlinear)
|
|||
|
||||
void SoundPlayerWidget::drag_enter_event(GUI::DragEvent& event)
|
||||
{
|
||||
auto const& mime_types = event.mime_types();
|
||||
if (mime_types.contains_slow("text/uri-list"sv))
|
||||
if (event.mime_data().has_urls())
|
||||
event.accept();
|
||||
}
|
||||
|
||||
|
|
|
@ -835,8 +835,7 @@ bool MainWidget::request_close()
|
|||
|
||||
void MainWidget::drag_enter_event(GUI::DragEvent& event)
|
||||
{
|
||||
auto const& mime_types = event.mime_types();
|
||||
if (mime_types.contains_slow("text/uri-list"sv))
|
||||
if (event.mime_data().has_urls())
|
||||
event.accept();
|
||||
}
|
||||
|
||||
|
|
|
@ -682,8 +682,7 @@ ErrorOr<void> MainWidget::load_from_file(ByteString const& filename, NonnullOwnP
|
|||
|
||||
void MainWidget::drag_enter_event(GUI::DragEvent& event)
|
||||
{
|
||||
auto const& mime_types = event.mime_types();
|
||||
if (mime_types.contains_slow("text/uri-list"sv))
|
||||
if (event.mime_data().has_urls())
|
||||
event.accept();
|
||||
}
|
||||
|
||||
|
|
|
@ -320,8 +320,7 @@ GUI::Window::CloseRequestDecision MainWidget::request_close()
|
|||
|
||||
void MainWidget::drag_enter_event(GUI::DragEvent& event)
|
||||
{
|
||||
auto const& mime_types = event.mime_types();
|
||||
if (mime_types.contains_slow("text/uri-list"sv))
|
||||
if (event.mime_data().has_urls())
|
||||
event.accept();
|
||||
}
|
||||
|
||||
|
|
|
@ -346,8 +346,7 @@ void Editor::mousedown_event(GUI::MouseEvent& event)
|
|||
|
||||
void Editor::drag_enter_event(GUI::DragEvent& event)
|
||||
{
|
||||
auto const& mime_types = event.mime_types();
|
||||
if (mime_types.contains_slow("text/uri-list"sv))
|
||||
if (event.mime_data().has_urls())
|
||||
event.accept();
|
||||
}
|
||||
|
||||
|
|
|
@ -463,8 +463,7 @@ void MainWidget::update_editor_actions(ScriptEditor* editor)
|
|||
|
||||
void MainWidget::drag_enter_event(GUI::DragEvent& event)
|
||||
{
|
||||
auto const& mime_types = event.mime_types();
|
||||
if (mime_types.contains_slow("text/uri-list"sv))
|
||||
if (event.mime_data().has_urls())
|
||||
event.accept();
|
||||
}
|
||||
|
||||
|
|
|
@ -791,7 +791,7 @@ void AbstractView::drag_enter_event(DragEvent& event)
|
|||
// We might be able to reduce event traffic by communicating the set of drag-accepting
|
||||
// rects in this widget to the windowing system somehow.
|
||||
event.accept();
|
||||
dbgln_if(DRAG_DEBUG, "accepting drag of {}", event.mime_types());
|
||||
dbgln_if(DRAG_DEBUG, "accepting drag of {}", event.mime_data().formats());
|
||||
}
|
||||
|
||||
void AbstractView::drag_move_event(DragEvent& event)
|
||||
|
@ -801,7 +801,7 @@ void AbstractView::drag_move_event(DragEvent& event)
|
|||
|
||||
auto index = index_at_event_position(event.position());
|
||||
ModelIndex new_drop_candidate_index;
|
||||
bool acceptable = model()->accepts_drag(index, event.mime_types());
|
||||
bool acceptable = model()->accepts_drag(index, event.mime_data());
|
||||
|
||||
if (acceptable && index.is_valid())
|
||||
new_drop_candidate_index = index;
|
||||
|
|
|
@ -283,7 +283,7 @@ void Application::set_pending_drop_widget(Widget* widget)
|
|||
m_pending_drop_widget->update();
|
||||
}
|
||||
|
||||
void Application::set_drag_hovered_widget_impl(Widget* widget, Gfx::IntPoint position, Vector<String> mime_types)
|
||||
void Application::set_drag_hovered_widget_impl(Widget* widget, Gfx::IntPoint position, Optional<DragEvent const&> drag_event)
|
||||
{
|
||||
if (widget == m_drag_hovered_widget)
|
||||
return;
|
||||
|
@ -296,8 +296,8 @@ void Application::set_drag_hovered_widget_impl(Widget* widget, Gfx::IntPoint pos
|
|||
set_pending_drop_widget(nullptr);
|
||||
m_drag_hovered_widget = widget;
|
||||
|
||||
if (m_drag_hovered_widget) {
|
||||
DragEvent enter_event(Event::DragEnter, position, move(mime_types));
|
||||
if (m_drag_hovered_widget && drag_event.has_value()) {
|
||||
DragEvent enter_event(Event::DragEnter, position, drag_event->button(), drag_event->buttons(), drag_event->modifiers(), drag_event->text(), drag_event->mime_data());
|
||||
enter_event.ignore();
|
||||
m_drag_hovered_widget->dispatch_event(enter_event, m_drag_hovered_widget->window());
|
||||
if (enter_event.is_accepted())
|
||||
|
|
|
@ -78,9 +78,9 @@ public:
|
|||
Widget* pending_drop_widget() { return m_pending_drop_widget.ptr(); }
|
||||
Widget const* pending_drop_widget() const { return m_pending_drop_widget.ptr(); }
|
||||
|
||||
void set_drag_hovered_widget(Badge<Window>, Widget* widget, Gfx::IntPoint position = {}, Vector<String> mime_types = {})
|
||||
void set_drag_hovered_widget(Badge<Window>, Widget* widget, Gfx::IntPoint position = {}, Optional<DragEvent const&> drag_event = {})
|
||||
{
|
||||
set_drag_hovered_widget_impl(widget, position, move(mime_types));
|
||||
set_drag_hovered_widget_impl(widget, position, move(drag_event));
|
||||
}
|
||||
void notify_drag_cancelled(Badge<ConnectionToWindowServer>);
|
||||
|
||||
|
@ -106,7 +106,7 @@ private:
|
|||
void request_tooltip_show();
|
||||
void tooltip_hide_timer_did_fire();
|
||||
|
||||
void set_drag_hovered_widget_impl(Widget*, Gfx::IntPoint = {}, Vector<String> = {});
|
||||
void set_drag_hovered_widget_impl(Widget*, Gfx::IntPoint = {}, Optional<DragEvent const&> = {});
|
||||
void set_pending_drop_widget(Widget*);
|
||||
|
||||
OwnPtr<Core::EventLoop> m_event_loop;
|
||||
|
|
|
@ -259,14 +259,10 @@ void ConnectionToWindowServer::mouse_up(i32 window_id, Gfx::IntPoint mouse_posit
|
|||
Core::EventLoop::current().post_event(*window, make<MouseEvent>(Event::MouseUp, mouse_position, buttons, to_mouse_button(button), modifiers, wheel_delta_x, wheel_delta_y, wheel_raw_delta_x, wheel_raw_delta_y));
|
||||
}
|
||||
|
||||
void ConnectionToWindowServer::mouse_move(i32 window_id, Gfx::IntPoint mouse_position, u32 button, u32 buttons, u32 modifiers, i32 wheel_delta_x, i32 wheel_delta_y, i32 wheel_raw_delta_x, i32 wheel_raw_delta_y, bool is_drag, Vector<String> const& mime_types)
|
||||
void ConnectionToWindowServer::mouse_move(i32 window_id, Gfx::IntPoint mouse_position, u32 button, u32 buttons, u32 modifiers, i32 wheel_delta_x, i32 wheel_delta_y, i32 wheel_raw_delta_x, i32 wheel_raw_delta_y)
|
||||
{
|
||||
if (auto* window = Window::from_window_id(window_id)) {
|
||||
if (is_drag)
|
||||
Core::EventLoop::current().post_event(*window, make<DragEvent>(Event::DragMove, mouse_position, mime_types));
|
||||
else
|
||||
Core::EventLoop::current().post_event(*window, make<MouseEvent>(Event::MouseMove, mouse_position, buttons, to_mouse_button(button), modifiers, wheel_delta_x, wheel_delta_y, wheel_raw_delta_x, wheel_raw_delta_y));
|
||||
}
|
||||
if (auto* window = Window::from_window_id(window_id))
|
||||
Core::EventLoop::current().post_event(*window, make<MouseEvent>(Event::MouseMove, mouse_position, buttons, to_mouse_button(button), modifiers, wheel_delta_x, wheel_delta_y, wheel_raw_delta_x, wheel_raw_delta_y));
|
||||
}
|
||||
|
||||
void ConnectionToWindowServer::mouse_double_click(i32 window_id, Gfx::IntPoint mouse_position, u32 button, u32 buttons, u32 modifiers, i32 wheel_delta_x, i32 wheel_delta_y, i32 wheel_raw_delta_x, i32 wheel_raw_delta_y)
|
||||
|
@ -349,12 +345,16 @@ void ConnectionToWindowServer::applet_area_rect_changed(Gfx::IntRect const& rect
|
|||
});
|
||||
}
|
||||
|
||||
void ConnectionToWindowServer::drag_dropped(i32 window_id, Gfx::IntPoint mouse_position, ByteString const& text, HashMap<String, ByteBuffer> const& mime_data)
|
||||
void ConnectionToWindowServer::drag_moved(i32 window_id, Gfx::IntPoint mouse_position, u32 button, u32 buttons, u32 modifiers, ByteString const& text, HashMap<String, ByteBuffer> const& mime_data)
|
||||
{
|
||||
if (auto* window = Window::from_window_id(window_id)) {
|
||||
auto mime_data_obj = Core::MimeData::construct(mime_data);
|
||||
Core::EventLoop::current().post_event(*window, make<DropEvent>(mouse_position, text, mime_data_obj));
|
||||
}
|
||||
if (auto* window = Window::from_window_id(window_id))
|
||||
Core::EventLoop::current().post_event(*window, make<DragEvent>(Event::Type::DragMove, mouse_position, to_mouse_button(button), buttons, modifiers, text, Core::MimeData::construct(mime_data)));
|
||||
}
|
||||
|
||||
void ConnectionToWindowServer::drag_dropped(i32 window_id, Gfx::IntPoint mouse_position, u32 button, u32 buttons, u32 modifiers, ByteString const& text, HashMap<String, ByteBuffer> const& mime_data)
|
||||
{
|
||||
if (auto* window = Window::from_window_id(window_id))
|
||||
Core::EventLoop::current().post_event(*window, make<DropEvent>(Event::Type::Drop, mouse_position, to_mouse_button(button), buttons, modifiers, text, Core::MimeData::construct(mime_data)));
|
||||
}
|
||||
|
||||
void ConnectionToWindowServer::drag_accepted()
|
||||
|
|
|
@ -26,7 +26,7 @@ private:
|
|||
|
||||
virtual void fast_greet(Vector<Gfx::IntRect> const&, u32, u32, u32, Core::AnonymousBuffer const&, ByteString const&, ByteString const&, ByteString const&, Vector<bool> const&, i32) override;
|
||||
virtual void paint(i32, Gfx::IntSize, Vector<Gfx::IntRect> const&) override;
|
||||
virtual void mouse_move(i32, Gfx::IntPoint, u32, u32, u32, i32, i32, i32, i32, bool, Vector<String> const&) override;
|
||||
virtual void mouse_move(i32, Gfx::IntPoint, u32, u32, u32, i32, i32, i32, i32) override;
|
||||
virtual void mouse_down(i32, Gfx::IntPoint, u32, u32, u32, i32, i32, i32, i32) override;
|
||||
virtual void mouse_double_click(i32, Gfx::IntPoint, u32, u32, u32, i32, i32, i32, i32) override;
|
||||
virtual void mouse_up(i32, Gfx::IntPoint, u32, u32, u32, i32, i32, i32, i32) override;
|
||||
|
@ -48,7 +48,8 @@ private:
|
|||
virtual void menu_visibility_did_change(i32, bool) override;
|
||||
virtual void screen_rects_changed(Vector<Gfx::IntRect> const&, u32, u32, u32) override;
|
||||
virtual void applet_area_rect_changed(Gfx::IntRect const&) override;
|
||||
virtual void drag_dropped(i32, Gfx::IntPoint, ByteString const&, HashMap<String, ByteBuffer> const&) override;
|
||||
virtual void drag_moved(i32, Gfx::IntPoint, u32 button, u32 buttons, u32 modifiers, ByteString const&, HashMap<String, ByteBuffer> const&) override;
|
||||
virtual void drag_dropped(i32, Gfx::IntPoint, u32 button, u32 buttons, u32 modifiers, ByteString const&, HashMap<String, ByteBuffer> const&) override;
|
||||
virtual void drag_accepted() override;
|
||||
virtual void drag_cancelled() override;
|
||||
virtual void update_system_theme(Core::AnonymousBuffer const&) override;
|
||||
|
|
|
@ -12,9 +12,12 @@
|
|||
|
||||
namespace GUI {
|
||||
|
||||
DropEvent::DropEvent(Gfx::IntPoint position, ByteString const& text, NonnullRefPtr<Core::MimeData const> mime_data)
|
||||
: Event(Event::Drop)
|
||||
DropEvent::DropEvent(Type type, Gfx::IntPoint position, MouseButton button, u32 buttons, u32 modifiers, ByteString const& text, NonnullRefPtr<Core::MimeData const> mime_data)
|
||||
: Event(type)
|
||||
, m_position(position)
|
||||
, m_button(button)
|
||||
, m_buttons(buttons)
|
||||
, m_modifiers(modifiers)
|
||||
, m_text(text)
|
||||
, m_mime_data(move(mime_data))
|
||||
{
|
||||
|
@ -22,6 +25,13 @@ DropEvent::DropEvent(Gfx::IntPoint position, ByteString const& text, NonnullRefP
|
|||
|
||||
DropEvent::~DropEvent() = default;
|
||||
|
||||
DragEvent::DragEvent(Type type, Gfx::IntPoint position, MouseButton button, u32 buttons, u32 modifiers, ByteString const& text, NonnullRefPtr<Core::MimeData const> mime_data)
|
||||
: DropEvent(type, position, button, buttons, modifiers, text, move(mime_data))
|
||||
{
|
||||
}
|
||||
|
||||
DragEvent::~DragEvent() = default;
|
||||
|
||||
ByteString KeyEvent::to_byte_string() const
|
||||
{
|
||||
Vector<ByteString, 8> parts;
|
||||
|
|
|
@ -482,39 +482,33 @@ private:
|
|||
int m_wheel_raw_delta_y { 0 };
|
||||
};
|
||||
|
||||
class DragEvent final : public Event {
|
||||
class DropEvent : public Event {
|
||||
public:
|
||||
DragEvent(Type type, Gfx::IntPoint position, Vector<String> mime_types)
|
||||
: Event(type)
|
||||
, m_position(position)
|
||||
, m_mime_types(move(mime_types))
|
||||
{
|
||||
}
|
||||
|
||||
Gfx::IntPoint position() const { return m_position; }
|
||||
Vector<String> const& mime_types() const { return m_mime_types; }
|
||||
|
||||
private:
|
||||
Gfx::IntPoint m_position;
|
||||
Vector<String> m_mime_types;
|
||||
};
|
||||
|
||||
class DropEvent final : public Event {
|
||||
public:
|
||||
DropEvent(Gfx::IntPoint, ByteString const& text, NonnullRefPtr<Core::MimeData const> mime_data);
|
||||
|
||||
DropEvent(Type type, Gfx::IntPoint, MouseButton button, u32 buttons, u32 modifiers, ByteString const& text, NonnullRefPtr<Core::MimeData const> mime_data);
|
||||
~DropEvent();
|
||||
|
||||
Gfx::IntPoint position() const { return m_position; }
|
||||
MouseButton button() const { return m_button; }
|
||||
unsigned buttons() const { return m_buttons; }
|
||||
unsigned modifiers() const { return m_modifiers; }
|
||||
ByteString const& text() const { return m_text; }
|
||||
Core::MimeData const& mime_data() const { return m_mime_data; }
|
||||
|
||||
private:
|
||||
Gfx::IntPoint m_position;
|
||||
MouseButton m_button { MouseButton::None };
|
||||
unsigned m_buttons { 0 };
|
||||
unsigned m_modifiers { 0 };
|
||||
ByteString m_text;
|
||||
NonnullRefPtr<Core::MimeData const> m_mime_data;
|
||||
};
|
||||
|
||||
class DragEvent final : public DropEvent {
|
||||
public:
|
||||
DragEvent(Type type, Gfx::IntPoint, MouseButton button, u32 buttons, u32 modifiers, ByteString const& text, NonnullRefPtr<Core::MimeData const> mime_data);
|
||||
~DragEvent();
|
||||
};
|
||||
|
||||
class ThemeChangeEvent final : public Event {
|
||||
public:
|
||||
ThemeChangeEvent()
|
||||
|
|
|
@ -855,9 +855,9 @@ ErrorOr<String> FileSystemModel::column_name(int column) const
|
|||
VERIFY_NOT_REACHED();
|
||||
}
|
||||
|
||||
bool FileSystemModel::accepts_drag(ModelIndex const& index, Vector<String> const& mime_types) const
|
||||
bool FileSystemModel::accepts_drag(ModelIndex const& index, Core::MimeData const& mime_data) const
|
||||
{
|
||||
if (!mime_types.contains_slow("text/uri-list"sv))
|
||||
if (!mime_data.has_urls())
|
||||
return false;
|
||||
|
||||
if (!index.is_valid())
|
||||
|
|
|
@ -133,7 +133,7 @@ public:
|
|||
virtual ModelIndex parent_index(ModelIndex const&) const override;
|
||||
virtual ModelIndex index(int row, int column = 0, ModelIndex const& parent = ModelIndex()) const override;
|
||||
virtual StringView drag_data_type() const override { return "text/uri-list"sv; }
|
||||
virtual bool accepts_drag(ModelIndex const&, Vector<String> const& mime_types) const override;
|
||||
virtual bool accepts_drag(ModelIndex const&, Core::MimeData const&) const override;
|
||||
virtual bool is_column_sortable(int column_index) const override { return column_index != Column::Icon; }
|
||||
virtual bool is_editable(ModelIndex const&) const override;
|
||||
virtual bool is_searchable() const override { return true; }
|
||||
|
|
|
@ -63,7 +63,7 @@ ModelIndex Model::index(int row, int column, ModelIndex const&) const
|
|||
return create_index(row, column);
|
||||
}
|
||||
|
||||
bool Model::accepts_drag(ModelIndex const&, Vector<String> const&) const
|
||||
bool Model::accepts_drag(ModelIndex const&, Core::MimeData const&) const
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -81,7 +81,7 @@ public:
|
|||
virtual bool is_searchable() const { return false; }
|
||||
virtual void set_data(ModelIndex const&, Variant const&) { }
|
||||
virtual int tree_column() const { return 0; }
|
||||
virtual bool accepts_drag(ModelIndex const&, Vector<String> const& mime_types) const;
|
||||
virtual bool accepts_drag(ModelIndex const&, Core::MimeData const&) const;
|
||||
virtual Vector<ModelIndex> matches(StringView, unsigned = MatchesFlag::AllMatching, ModelIndex const& = ModelIndex()) { return {}; }
|
||||
|
||||
virtual bool is_column_sortable([[maybe_unused]] int column_index) const { return true; }
|
||||
|
|
|
@ -69,7 +69,7 @@ PathBreadcrumbbar::PathBreadcrumbbar(NonnullRefPtr<GUI::TextBox> location_text_b
|
|||
};
|
||||
|
||||
m_breadcrumbbar->on_segment_drag_enter = [&](size_t, GUI::DragEvent& event) {
|
||||
if (event.mime_types().contains_slow("text/uri-list"sv))
|
||||
if (event.mime_data().has_urls())
|
||||
event.accept();
|
||||
};
|
||||
|
||||
|
|
|
@ -49,9 +49,9 @@ void SortingProxyModel::model_did_update(unsigned flags)
|
|||
update_sort(flags);
|
||||
}
|
||||
|
||||
bool SortingProxyModel::accepts_drag(ModelIndex const& proxy_index, Vector<String> const& mime_types) const
|
||||
bool SortingProxyModel::accepts_drag(ModelIndex const& proxy_index, Core::MimeData const& mime_data) const
|
||||
{
|
||||
return source().accepts_drag(map_to_source(proxy_index), mime_types);
|
||||
return source().accepts_drag(map_to_source(proxy_index), mime_data);
|
||||
}
|
||||
|
||||
int SortingProxyModel::row_count(ModelIndex const& proxy_index) const
|
||||
|
|
|
@ -34,7 +34,7 @@ public:
|
|||
virtual bool is_searchable() const override;
|
||||
virtual void set_data(ModelIndex const&, Variant const&) override;
|
||||
virtual Vector<ModelIndex> matches(StringView, unsigned = MatchesFlag::AllMatching, ModelIndex const& = ModelIndex()) override;
|
||||
virtual bool accepts_drag(ModelIndex const&, Vector<String> const& mime_types) const override;
|
||||
virtual bool accepts_drag(ModelIndex const&, Core::MimeData const&) const override;
|
||||
|
||||
virtual bool is_column_sortable(int column_index) const override;
|
||||
|
||||
|
|
|
@ -11,6 +11,7 @@
|
|||
#include <AK/JsonObject.h>
|
||||
#include <AK/NonnullRefPtr.h>
|
||||
#include <AK/RefPtr.h>
|
||||
#include <LibCore/MimeData.h>
|
||||
#include <LibGUI/Action.h>
|
||||
#include <LibGUI/Application.h>
|
||||
#include <LibGUI/BoxLayout.h>
|
||||
|
@ -532,9 +533,7 @@ void Widget::drag_move_event(DragEvent&)
|
|||
|
||||
void Widget::drag_enter_event(DragEvent& event)
|
||||
{
|
||||
StringBuilder builder;
|
||||
builder.join(',', event.mime_types());
|
||||
dbgln_if(DRAG_DEBUG, "{} {:p} DRAG ENTER @ {}, {}", class_name(), this, event.position(), builder.string_view());
|
||||
dbgln_if(DRAG_DEBUG, "{} {:p} DRAG ENTER @ {}, {}", class_name(), this, event.position(), event.mime_data().formats());
|
||||
}
|
||||
|
||||
void Widget::drag_leave_event(Event&)
|
||||
|
|
|
@ -432,7 +432,7 @@ void Window::handle_drop_event(DropEvent& event)
|
|||
if (!m_main_widget)
|
||||
return;
|
||||
auto result = m_main_widget->hit_test(event.position());
|
||||
auto local_event = make<DropEvent>(result.local_position, event.text(), event.mime_data());
|
||||
auto local_event = make<DropEvent>(Event::Type::Drop, result.local_position, event.button(), event.buttons(), event.modifiers(), event.text(), event.mime_data());
|
||||
VERIFY(result.widget);
|
||||
result.widget->dispatch_event(*local_event, this);
|
||||
|
||||
|
@ -766,14 +766,14 @@ void Window::handle_drag_move_event(DragEvent& event)
|
|||
auto result = m_main_widget->hit_test(event.position());
|
||||
VERIFY(result.widget);
|
||||
|
||||
Application::the()->set_drag_hovered_widget({}, result.widget, result.local_position, event.mime_types());
|
||||
Application::the()->set_drag_hovered_widget({}, result.widget, result.local_position, event);
|
||||
|
||||
// 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>(event.type()), result.local_position, event.mime_types());
|
||||
DragEvent drag_move_event(static_cast<Event::Type>(event.type()), result.local_position, event.button(), event.buttons(), event.modifiers(), event.text(), event.mime_data());
|
||||
result.widget->dispatch_event(drag_move_event, this);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1199,8 +1199,7 @@ void TerminalWidget::context_menu_event(GUI::ContextMenuEvent& event)
|
|||
|
||||
void TerminalWidget::drag_enter_event(GUI::DragEvent& event)
|
||||
{
|
||||
auto const& mime_types = event.mime_types();
|
||||
if (mime_types.contains_slow("text/plain"sv) || mime_types.contains_slow("text/uri-list"sv))
|
||||
if (event.mime_data().has_text() || event.mime_data().has_urls())
|
||||
event.accept();
|
||||
}
|
||||
|
||||
|
|
|
@ -152,8 +152,7 @@ void QuickLaunchWidget::config_string_did_change(StringView domain, StringView g
|
|||
|
||||
void QuickLaunchWidget::drag_enter_event(GUI::DragEvent& event)
|
||||
{
|
||||
auto const& mime_types = event.mime_types();
|
||||
if (mime_types.contains_slow("text/uri-list"sv))
|
||||
if (event.mime_data().has_urls())
|
||||
event.accept();
|
||||
}
|
||||
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
*/
|
||||
|
||||
#include <AK/Badge.h>
|
||||
#include <LibCore/MimeData.h>
|
||||
#include <LibGfx/Bitmap.h>
|
||||
#include <LibGfx/StandardCursor.h>
|
||||
#include <LibGfx/SystemTheme.h>
|
||||
|
|
|
@ -9,7 +9,6 @@
|
|||
#include <AK/ByteString.h>
|
||||
#include <Kernel/API/KeyCode.h>
|
||||
#include <LibCore/Event.h>
|
||||
#include <LibCore/MimeData.h>
|
||||
#include <LibGfx/Rect.h>
|
||||
#include <WindowServer/Cursor.h>
|
||||
#include <WindowServer/WindowType.h>
|
||||
|
@ -115,17 +114,6 @@ public:
|
|||
int wheel_delta_y() const { return m_wheel_delta_y; }
|
||||
int wheel_raw_delta_x() const { return m_wheel_raw_delta_x; }
|
||||
int wheel_raw_delta_y() const { return m_wheel_raw_delta_y; }
|
||||
bool is_drag() const { return m_drag; }
|
||||
|
||||
Vector<String> 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(Core::MimeData const& mime_data) { m_mime_data = mime_data; }
|
||||
|
||||
MouseEvent translated(Gfx::IntPoint delta) const
|
||||
{
|
||||
|
@ -143,8 +131,6 @@ private:
|
|||
int m_wheel_delta_y { 0 };
|
||||
int m_wheel_raw_delta_x { 0 };
|
||||
int m_wheel_raw_delta_y { 0 };
|
||||
bool m_drag { false };
|
||||
RefPtr<Core::MimeData const> m_mime_data;
|
||||
};
|
||||
|
||||
class ResizeEvent final : public Event {
|
||||
|
|
|
@ -438,10 +438,9 @@ void ScreenInput::on_receive_mouse_data(MousePacket const& packet)
|
|||
post_mousedown_or_mouseup_if_needed(MouseButton::Middle);
|
||||
post_mousedown_or_mouseup_if_needed(MouseButton::Backward);
|
||||
post_mousedown_or_mouseup_if_needed(MouseButton::Forward);
|
||||
|
||||
if (m_cursor_location != prev_location) {
|
||||
auto message = make<MouseEvent>(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));
|
||||
}
|
||||
|
||||
|
|
|
@ -209,7 +209,7 @@ void Window::handle_mouse_event(MouseEvent const& event)
|
|||
|
||||
switch (event.type()) {
|
||||
case Event::MouseMove:
|
||||
m_client->async_mouse_move(m_window_id, event.position(), (u32)event.button(), event.buttons(), event.modifiers(), event.wheel_delta_x(), event.wheel_delta_y(), event.wheel_raw_delta_x(), event.wheel_raw_delta_y(), event.is_drag(), event.mime_types());
|
||||
m_client->async_mouse_move(m_window_id, event.position(), (u32)event.button(), event.buttons(), event.modifiers(), event.wheel_delta_x(), event.wheel_delta_y(), event.wheel_raw_delta_x(), event.wheel_raw_delta_y());
|
||||
break;
|
||||
case Event::MouseDown:
|
||||
m_client->async_mouse_down(m_window_id, event.position(), (u32)event.button(), event.buttons(), event.modifiers(), event.wheel_delta_x(), event.wheel_delta_y(), event.wheel_raw_delta_x(), event.wheel_raw_delta_y());
|
||||
|
|
|
@ -6,7 +6,7 @@ endpoint WindowClient
|
|||
fast_greet(Vector<Gfx::IntRect> screen_rects, u32 main_screen_index, u32 workspace_rows, u32 workspace_columns, Core::AnonymousBuffer theme_buffer, ByteString default_font_query, ByteString fixed_width_font_query, ByteString window_title_font_query, Vector<bool> effects, i32 client_id) =|
|
||||
|
||||
paint(i32 window_id, Gfx::IntSize window_size, Vector<Gfx::IntRect> rects) =|
|
||||
mouse_move(i32 window_id, Gfx::IntPoint mouse_position, u32 button, u32 buttons, u32 modifiers, i32 wheel_delta_x, i32 wheel_delta_y, i32 wheel_raw_delta_x, i32 wheel_raw_delta_y, bool is_drag, Vector<String> mime_types) =|
|
||||
mouse_move(i32 window_id, Gfx::IntPoint mouse_position, u32 button, u32 buttons, u32 modifiers, i32 wheel_delta_x, i32 wheel_delta_y, i32 wheel_raw_delta_x, i32 wheel_raw_delta_y) =|
|
||||
mouse_down(i32 window_id, Gfx::IntPoint mouse_position, u32 button, u32 buttons, u32 modifiers, i32 wheel_delta_x, i32 wheel_delta_y, i32 wheel_raw_delta_x, i32 wheel_raw_delta_y) =|
|
||||
mouse_double_click(i32 window_id, Gfx::IntPoint mouse_position, u32 button, u32 buttons, u32 modifiers, i32 wheel_delta_x, i32 wheel_delta_y, i32 wheel_raw_delta_x, i32 wheel_raw_delta_y) =|
|
||||
mouse_up(i32 window_id, Gfx::IntPoint mouse_position, u32 button, u32 buttons, u32 modifiers, i32 wheel_delta_x, i32 wheel_delta_y, i32 wheel_raw_delta_x, i32 wheel_raw_delta_y) =|
|
||||
|
@ -36,7 +36,8 @@ endpoint WindowClient
|
|||
drag_accepted() =|
|
||||
drag_cancelled() =|
|
||||
|
||||
drag_dropped(i32 window_id, Gfx::IntPoint mouse_position, [UTF8] ByteString text, HashMap<String, ByteBuffer> mime_data) =|
|
||||
drag_moved(i32 window_id, Gfx::IntPoint mouse_position, u32 button, u32 buttons, u32 modifiers, [UTF8] ByteString text, HashMap<String, ByteBuffer> mime_data) =|
|
||||
drag_dropped(i32 window_id, Gfx::IntPoint mouse_position, u32 button, u32 buttons, u32 modifiers, [UTF8] ByteString text, HashMap<String, ByteBuffer> mime_data) =|
|
||||
|
||||
update_system_theme(Core::AnonymousBuffer theme_buffer) =|
|
||||
update_system_fonts(ByteString default_font_query, ByteString fixed_width_font_query, ByteString window_title_font_query) =|
|
||||
|
|
|
@ -1110,38 +1110,48 @@ bool WindowManager::process_ongoing_drag(MouseEvent& event)
|
|||
if (!m_dnd_client)
|
||||
return false;
|
||||
|
||||
auto send_dnd_event = [&](auto callback) {
|
||||
auto* window = hovered_window();
|
||||
if (!window || !window->client())
|
||||
return false;
|
||||
|
||||
auto translated_event = event.translated(-window->position());
|
||||
auto mime_data = m_dnd_mime_data->all_data().clone();
|
||||
|
||||
// If the mime data is so large that it causes memory troubles, we should silently drop the drag'n'drop request entirely.
|
||||
if (mime_data.is_error()) {
|
||||
dbgln("Drag and drop mimetype data nearly caused OOM and was dropped: {}", mime_data.release_error());
|
||||
return false;
|
||||
}
|
||||
|
||||
callback(*window, translated_event.position(), mime_data.release_value());
|
||||
return true;
|
||||
};
|
||||
|
||||
if (event.type() == Event::MouseMove) {
|
||||
m_dnd_overlay->cursor_moved();
|
||||
|
||||
// We didn't let go of the drag yet, see if we should send some drag move events..
|
||||
if (auto* window = hovered_window()) {
|
||||
event.set_drag(true);
|
||||
event.set_mime_data(*m_dnd_mime_data);
|
||||
deliver_mouse_event(*window, event);
|
||||
} else {
|
||||
auto event_sent = send_dnd_event([&](auto& window, auto event_position, auto mime_data) {
|
||||
window.client()->async_drag_moved(window.window_id(), event_position, event.button(), event.buttons(), event.modifiers(), m_dnd_text, move(mime_data));
|
||||
});
|
||||
|
||||
if (!event_sent)
|
||||
set_accepts_drag(false);
|
||||
}
|
||||
}
|
||||
|
||||
if (!(event.type() == Event::MouseUp && event.button() == MouseButton::Primary))
|
||||
return true;
|
||||
if (event.type() == Event::MouseUp && event.button() == MouseButton::Primary) {
|
||||
auto event_sent = send_dnd_event([&](auto& window, auto event_position, auto mime_data) {
|
||||
m_dnd_client->async_drag_accepted();
|
||||
window.client()->async_drag_dropped(window.window_id(), event_position, event.button(), event.buttons(), event.modifiers(), m_dnd_text, move(mime_data));
|
||||
});
|
||||
|
||||
if (auto* window = hovered_window()) {
|
||||
m_dnd_client->async_drag_accepted();
|
||||
if (window->client()) {
|
||||
auto translated_event = event.translated(-window->position());
|
||||
auto copied_mime_data_or_error = m_dnd_mime_data->all_data().clone();
|
||||
// If the mime data is so large that it causes memory troubles, we should silently drop the drag'n'drop request entirely.
|
||||
if (copied_mime_data_or_error.is_error())
|
||||
dbgln("Drag and drop mimetype data nearly caused OOM and was dropped: {}", copied_mime_data_or_error.release_error());
|
||||
else
|
||||
window->client()->async_drag_dropped(window->window_id(), translated_event.position(), m_dnd_text, copied_mime_data_or_error.release_value());
|
||||
}
|
||||
} else {
|
||||
m_dnd_client->async_drag_cancelled();
|
||||
if (!event_sent)
|
||||
m_dnd_client->async_drag_cancelled();
|
||||
|
||||
end_dnd_drag();
|
||||
}
|
||||
|
||||
end_dnd_drag();
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue