diff options
Diffstat (limited to 'mozilla-1438131.patch')
-rw-r--r-- | mozilla-1438131.patch | 1558 |
1 files changed, 0 insertions, 1558 deletions
diff --git a/mozilla-1438131.patch b/mozilla-1438131.patch deleted file mode 100644 index e77186d..0000000 --- a/mozilla-1438131.patch +++ /dev/null @@ -1,1558 +0,0 @@ - -# HG changeset patch -# User Martin Stransky <stransky@redhat.com> -# Date 1522937803 -7200 -# Node ID 7e4166e13b3ec513ef3003527df601adf85f654b -# Parent bf4962739d38ac21ba6ba216fa61f572e7976354 -Bug 1438131 - Implement Drop on Wayland, r=jhorak - -This patch implements Drop operation on Wayland/Gtk+. That's because drop operations are part -of clipboard on Wayland and we use our own paste clipboard handler on Wayland (Bug 1282015). - -Wayland drop data are provided by wl_data_device_listener, it provides us drag and drop callbacks -which we route to nsDragService module. - -MozReview-Commit-ID: 9uGYPg9YF6P - -diff --git a/widget/gtk/nsClipboardWayland.cpp b/widget/gtk/nsClipboardWayland.cpp ---- a/widget/gtk/nsClipboardWayland.cpp -+++ b/widget/gtk/nsClipboardWayland.cpp -@@ -18,16 +18,17 @@ - #include "nsPrimitiveHelpers.h" - #include "nsIServiceManager.h" - #include "nsImageToPixbuf.h" - #include "nsStringStream.h" - #include "nsIObserverService.h" - #include "mozilla/Services.h" - #include "mozilla/RefPtr.h" - #include "mozilla/TimeStamp.h" -+#include "nsDragService.h" - - #include "imgIContainer.h" - - #include <gtk/gtk.h> - #include <poll.h> - #include <sys/epoll.h> - #include <stdlib.h> - #include <string.h> -@@ -41,16 +42,54 @@ - const char* - nsRetrievalContextWayland::sTextMimeTypes[TEXT_MIME_TYPES_NUM] = - { - "text/plain;charset=utf-8", - "UTF8_STRING", - "COMPOUND_TEXT" - }; - -+static inline GdkDragAction -+wl_to_gdk_actions(uint32_t dnd_actions) -+{ -+ GdkDragAction actions = GdkDragAction(0); -+ -+ if (dnd_actions & WL_DATA_DEVICE_MANAGER_DND_ACTION_COPY) -+ actions = GdkDragAction(actions|GDK_ACTION_COPY); -+ if (dnd_actions & WL_DATA_DEVICE_MANAGER_DND_ACTION_MOVE) -+ actions = GdkDragAction(actions|GDK_ACTION_MOVE); -+ -+ return actions; -+} -+ -+static inline uint32_t -+gdk_to_wl_actions(GdkDragAction action) -+{ -+ uint32_t dnd_actions = 0; -+ -+ if (action & (GDK_ACTION_COPY | GDK_ACTION_LINK | GDK_ACTION_PRIVATE)) -+ dnd_actions |= WL_DATA_DEVICE_MANAGER_DND_ACTION_COPY; -+ if (action & GDK_ACTION_MOVE) -+ dnd_actions |= WL_DATA_DEVICE_MANAGER_DND_ACTION_MOVE; -+ -+ return dnd_actions; -+} -+ -+static GtkWidget* -+get_gtk_widget_for_wl_surface(struct wl_surface *surface) -+{ -+ GdkWindow *gdkParentWindow = -+ static_cast<GdkWindow*>(wl_surface_get_user_data(surface)); -+ -+ gpointer user_data = nullptr; -+ gdk_window_get_user_data(gdkParentWindow, &user_data); -+ -+ return GTK_WIDGET(user_data); -+} -+ - void - DataOffer::AddMIMEType(const char *aMimeType) - { - GdkAtom atom = gdk_atom_intern(aMimeType, FALSE); - mTargetMIMETypes.AppendElement(atom); - } - - GdkAtom* -@@ -150,44 +189,99 @@ WaylandDataOffer::RequestDataTransfer(co - if (mWaylandDataOffer) { - wl_data_offer_receive(mWaylandDataOffer, aMimeType, fd); - return true; - } - - return false; - } - -+void -+WaylandDataOffer::DragOfferAccept(const char* aMimeType, uint32_t aTime) -+{ -+ wl_data_offer_accept(mWaylandDataOffer, aTime, aMimeType); -+} -+ -+/* We follow logic of gdk_wayland_drag_context_commit_status()/gdkdnd-wayland.c -+ * here. -+ */ -+void -+WaylandDataOffer::SetDragStatus(GdkDragAction aAction, uint32_t aTime) -+{ -+ uint32_t dnd_actions = gdk_to_wl_actions(aAction); -+ uint32_t all_actions = WL_DATA_DEVICE_MANAGER_DND_ACTION_COPY | -+ WL_DATA_DEVICE_MANAGER_DND_ACTION_MOVE; -+ -+ wl_data_offer_set_actions(mWaylandDataOffer, all_actions, dnd_actions); -+ -+ /* Workaround Wayland D&D architecture here. To get the data_device_drop() -+ signal (which routes to nsDragService::GetData() call) we need to -+ accept at least one mime type before data_device_leave(). -+ -+ Real wl_data_offer_accept() for actualy requested data mime type is -+ called from nsDragService::GetData(). -+ */ -+ if (mTargetMIMETypes[0]) { -+ wl_data_offer_accept(mWaylandDataOffer, aTime, -+ gdk_atom_name(mTargetMIMETypes[0])); -+ } -+} -+ -+void -+WaylandDataOffer::SetSelectedDragAction(uint32_t aWaylandAction) -+{ -+ mSelectedDragAction = aWaylandAction; -+} -+ -+GdkDragAction -+WaylandDataOffer::GetSelectedDragAction() -+{ -+ return wl_to_gdk_actions(mSelectedDragAction); -+} -+ - static void - data_offer_offer (void *data, - struct wl_data_offer *wl_data_offer, - const char *type) - { - auto *offer = static_cast<DataOffer*>(data); - offer->AddMIMEType(type); - } - -+/* Advertise all available drag and drop actions from source. -+ * We don't use that but follow gdk_wayland_drag_context_commit_status() -+ * from gdkdnd-wayland.c here. -+ */ - static void - data_offer_source_actions(void *data, - struct wl_data_offer *wl_data_offer, - uint32_t source_actions) - { - } - -+/* Advertise recently selected drag and drop action by compositor, based -+ * on source actions and user choice (key modifiers, etc.). -+ */ - static void - data_offer_action(void *data, - struct wl_data_offer *wl_data_offer, - uint32_t dnd_action) - { -+ auto *offer = static_cast<WaylandDataOffer*>(data); -+ offer->SetSelectedDragAction(dnd_action); - } - - /* wl_data_offer callback description: - * - * data_offer_offer - Is called for each MIME type available at wl_data_offer. -- * data_offer_source_actions - Exposes all available D&D actions. -- * data_offer_action - Expose one actually selected D&D action. -+ * data_offer_source_actions - This event indicates the actions offered by -+ * the data source. -+ * data_offer_action - This event indicates the action selected by -+ * the compositor after matching the source/destination -+ * side actions. - */ - static const struct wl_data_offer_listener data_offer_listener = { - data_offer_offer, - data_offer_source_actions, - data_offer_action - }; - - WaylandDataOffer::WaylandDataOffer(wl_data_offer* aWaylandDataOffer) -@@ -241,92 +335,203 @@ PrimaryDataOffer::PrimaryDataOffer(gtk_p - - PrimaryDataOffer::~PrimaryDataOffer(void) - { - if(mPrimaryDataOffer) { - gtk_primary_selection_offer_destroy(mPrimaryDataOffer); - } - } - -+NS_IMPL_ISUPPORTS(nsWaylandDragContext, nsISupports); -+ -+nsWaylandDragContext::nsWaylandDragContext(WaylandDataOffer* aDataOffer, -+ wl_display *aDisplay) -+ : mDataOffer(aDataOffer) -+ , mDisplay(aDisplay) -+ , mTime(0) -+ , mGtkWidget(nullptr) -+ , mX(0) -+ , mY(0) -+{ -+} -+ - void --nsRetrievalContextWayland::RegisterDataOffer(wl_data_offer *aWaylandDataOffer) -+nsWaylandDragContext::DropDataEnter(GtkWidget* aGtkWidget, uint32_t aTime, -+ nscoord aX, nscoord aY) -+{ -+ mTime = aTime; -+ mGtkWidget = aGtkWidget; -+ mX = aX; -+ mY = aY; -+} -+ -+void -+nsWaylandDragContext::DropMotion(uint32_t aTime, nscoord aX, nscoord aY) -+{ -+ mTime = aTime; -+ mX = aX; -+ mY = aY; -+} -+ -+void -+nsWaylandDragContext::GetLastDropInfo(uint32_t *aTime, nscoord *aX, nscoord *aY) -+{ -+ *aTime = mTime; -+ *aX = mX; -+ *aY = mY; -+} -+ -+void -+nsWaylandDragContext::SetDragStatus(GdkDragAction aAction) -+{ -+ mDataOffer->SetDragStatus(aAction, mTime); -+} -+ -+GdkDragAction -+nsWaylandDragContext::GetSelectedDragAction() -+{ -+ return mDataOffer->GetSelectedDragAction(); -+} -+ -+GList* -+nsWaylandDragContext::GetTargets() -+{ -+ int targetNums; -+ GdkAtom *atoms = mDataOffer->GetTargets(&targetNums); -+ -+ GList* targetList = nullptr; -+ for (int i = 0; i < targetNums; i++) { -+ targetList = g_list_append(targetList, GDK_ATOM_TO_POINTER(atoms[i])); -+ } -+ -+ return targetList; -+} -+ -+char* -+nsWaylandDragContext::GetData(const char* aMimeType, uint32_t* aContentLength) -+{ -+ mDataOffer->DragOfferAccept(aMimeType, mTime); -+ return mDataOffer->GetData(mDisplay, aMimeType, aContentLength); -+} -+ -+void -+nsRetrievalContextWayland::RegisterNewDataOffer(wl_data_offer *aWaylandDataOffer) - { - DataOffer* dataOffer = - static_cast<DataOffer*>(g_hash_table_lookup(mActiveOffers, - aWaylandDataOffer)); -+ MOZ_ASSERT(dataOffer == nullptr, -+ "Registered WaylandDataOffer already exists. Wayland protocol error?"); -+ - if (!dataOffer) { - dataOffer = new WaylandDataOffer(aWaylandDataOffer); - g_hash_table_insert(mActiveOffers, aWaylandDataOffer, dataOffer); - } - } - - void --nsRetrievalContextWayland::RegisterDataOffer( -+nsRetrievalContextWayland::RegisterNewDataOffer( - gtk_primary_selection_offer *aPrimaryDataOffer) - { - DataOffer* dataOffer = - static_cast<DataOffer*>(g_hash_table_lookup(mActiveOffers, - aPrimaryDataOffer)); -+ MOZ_ASSERT(dataOffer == nullptr, -+ "Registered PrimaryDataOffer already exists. Wayland protocol error?"); -+ - if (!dataOffer) { - dataOffer = new PrimaryDataOffer(aPrimaryDataOffer); - g_hash_table_insert(mActiveOffers, aPrimaryDataOffer, dataOffer); - } - } - - void - nsRetrievalContextWayland::SetClipboardDataOffer(wl_data_offer *aWaylandDataOffer) - { -+ // Delete existing clipboard data offer -+ mClipboardOffer = nullptr; -+ - DataOffer* dataOffer = - static_cast<DataOffer*>(g_hash_table_lookup(mActiveOffers, - aWaylandDataOffer)); - NS_ASSERTION(dataOffer, "We're missing clipboard data offer!"); - if (dataOffer) { - g_hash_table_remove(mActiveOffers, aWaylandDataOffer); - mClipboardOffer = dataOffer; - } - } - - void - nsRetrievalContextWayland::SetPrimaryDataOffer( - gtk_primary_selection_offer *aPrimaryDataOffer) - { -- if (aPrimaryDataOffer == nullptr) { -- // Release any primary offer we have. -- mPrimaryOffer = nullptr; -- } else { -+ // Release any primary offer we have. -+ mPrimaryOffer = nullptr; -+ -+ // aPrimaryDataOffer can be null which means we lost -+ // the mouse selection. -+ if (aPrimaryDataOffer) { - DataOffer* dataOffer = - static_cast<DataOffer*>(g_hash_table_lookup(mActiveOffers, - aPrimaryDataOffer)); - NS_ASSERTION(dataOffer, "We're missing primary data offer!"); - if (dataOffer) { - g_hash_table_remove(mActiveOffers, aPrimaryDataOffer); - mPrimaryOffer = dataOffer; - } - } - } - - void --nsRetrievalContextWayland::ClearDataOffers(void) -+nsRetrievalContextWayland::AddDragAndDropDataOffer(wl_data_offer *aDropDataOffer) -+{ -+ // Remove any existing D&D contexts. -+ mDragContext = nullptr; -+ -+ WaylandDataOffer* dataOffer = -+ static_cast<WaylandDataOffer*>(g_hash_table_lookup(mActiveOffers, -+ aDropDataOffer)); -+ NS_ASSERTION(dataOffer, "We're missing drag and drop data offer!"); -+ if (dataOffer) { -+ g_hash_table_remove(mActiveOffers, aDropDataOffer); -+ mDragContext = new nsWaylandDragContext(dataOffer, mDisplay); -+ } -+} -+ -+nsWaylandDragContext* -+nsRetrievalContextWayland::GetDragContext(void) -+{ -+ return mDragContext; -+} -+ -+void -+nsRetrievalContextWayland::ClearClipboardDataOffers(void) - { - if (mClipboardOffer) - mClipboardOffer = nullptr; - if (mPrimaryOffer) - mPrimaryOffer = nullptr; - } - -+void -+nsRetrievalContextWayland::ClearDragAndDropDataOffer(void) -+{ -+ mDragContext = nullptr; -+} -+ - // We have a new fresh data content. - // We should attach listeners to it and save for further use. - static void - data_device_data_offer (void *data, - struct wl_data_device *data_device, - struct wl_data_offer *offer) - { - nsRetrievalContextWayland *context = - static_cast<nsRetrievalContextWayland*>(data); -- context->RegisterDataOffer(offer); -+ context->RegisterNewDataOffer(offer); - } - - // The new fresh data content is clipboard. - static void - data_device_selection (void *data, - struct wl_data_device *wl_data_device, - struct wl_data_offer *offer) - { -@@ -336,41 +541,88 @@ data_device_selection (void - } - - // The new fresh wayland data content is drag and drop. - static void - data_device_enter (void *data, - struct wl_data_device *data_device, - uint32_t time, - struct wl_surface *surface, -- int32_t x, -- int32_t y, -+ int32_t x_fixed, -+ int32_t y_fixed, - struct wl_data_offer *offer) - { -+ nsRetrievalContextWayland *context = -+ static_cast<nsRetrievalContextWayland*>(data); -+ context->AddDragAndDropDataOffer(offer); -+ -+ nsWaylandDragContext* dragContext = context->GetDragContext(); -+ -+ GtkWidget* gtkWidget = get_gtk_widget_for_wl_surface(surface); -+ if (!gtkWidget) { -+ NS_WARNING("DragAndDrop: Unable to get GtkWidget for wl_surface!"); -+ return; -+ } -+ -+ LOGDRAG(("nsWindow data_device_enter for GtkWidget %p\n", -+ (void*)gtkWidget)); -+ -+ dragContext->DropDataEnter(gtkWidget, time, -+ wl_fixed_to_int(x_fixed), -+ wl_fixed_to_int(y_fixed)); - } - - static void - data_device_leave (void *data, - struct wl_data_device *data_device) - { -+ nsRetrievalContextWayland *context = -+ static_cast<nsRetrievalContextWayland*>(data); -+ -+ nsWaylandDragContext* dropContext = context->GetDragContext(); -+ WindowDragLeaveHandler(dropContext->GetWidget()); -+ -+ context->ClearDragAndDropDataOffer(); - } - - static void - data_device_motion (void *data, - struct wl_data_device *data_device, - uint32_t time, -- int32_t x, -- int32_t y) -+ int32_t x_fixed, -+ int32_t y_fixed) - { -+ nsRetrievalContextWayland *context = -+ static_cast<nsRetrievalContextWayland*>(data); -+ -+ nsWaylandDragContext* dropContext = context->GetDragContext(); -+ -+ nscoord x = wl_fixed_to_int(x_fixed); -+ nscoord y = wl_fixed_to_int(y_fixed); -+ dropContext->DropMotion(time, x, y); -+ -+ WindowDragMotionHandler(dropContext->GetWidget(), nullptr, -+ dropContext, x, y, time); - } - - static void - data_device_drop (void *data, - struct wl_data_device *data_device) - { -+ nsRetrievalContextWayland *context = -+ static_cast<nsRetrievalContextWayland*>(data); -+ -+ nsWaylandDragContext* dropContext = context->GetDragContext(); -+ -+ uint32_t time; -+ nscoord x, y; -+ dropContext->GetLastDropInfo(&time, &x, &y); -+ -+ WindowDragDropHandler(dropContext->GetWidget(), nullptr, dropContext, -+ x, y, time); - } - - /* wl_data_device callback description: - * - * data_device_data_offer - It's called when there's a new wl_data_offer - * available. We need to attach wl_data_offer_listener - * to it to get available MIME types. - * -@@ -400,29 +652,41 @@ static const struct wl_data_device_liste - static void - primary_selection_data_offer (void *data, - struct gtk_primary_selection_device *gtk_primary_selection_device, - struct gtk_primary_selection_offer *gtk_primary_offer) - { - // create and add listener - nsRetrievalContextWayland *context = - static_cast<nsRetrievalContextWayland*>(data); -- context->RegisterDataOffer(gtk_primary_offer); -+ context->RegisterNewDataOffer(gtk_primary_offer); - } - - static void - primary_selection_selection (void *data, - struct gtk_primary_selection_device *gtk_primary_selection_device, - struct gtk_primary_selection_offer *gtk_primary_offer) - { - nsRetrievalContextWayland *context = - static_cast<nsRetrievalContextWayland*>(data); - context->SetPrimaryDataOffer(gtk_primary_offer); - } - -+/* gtk_primary_selection_device callback description: -+ * -+ * primary_selection_data_offer - It's called when there's a new -+ * gtk_primary_selection_offer available. -+ * We need to attach gtk_primary_selection_offer_listener -+ * to it to get available MIME types. -+ * -+ * primary_selection_selection - It's called when the new gtk_primary_selection_offer -+ * is a primary selection content. It can be also called with -+ * gtk_primary_selection_offer = null which means there's no -+ * primary selection. -+ */ - static const struct - gtk_primary_selection_device_listener primary_selection_device_listener = { - primary_selection_data_offer, - primary_selection_selection, - }; - - bool - nsRetrievalContextWayland::HasSelectionSupport(void) -@@ -446,17 +710,17 @@ keyboard_handle_enter(void *data, struct - static void - keyboard_handle_leave(void *data, struct wl_keyboard *keyboard, - uint32_t serial, struct wl_surface *surface) - { - // We lost focus so our clipboard data are outdated - nsRetrievalContextWayland *context = - static_cast<nsRetrievalContextWayland*>(data); - -- context->ClearDataOffers(); -+ context->ClearClipboardDataOffers(); - } - - static void - keyboard_handle_key(void *data, struct wl_keyboard *keyboard, - uint32_t serial, uint32_t time, uint32_t key, - uint32_t state) - { - } -@@ -568,16 +832,17 @@ nsRetrievalContextWayland::nsRetrievalCo - : mInitialized(false) - , mSeat(nullptr) - , mDataDeviceManager(nullptr) - , mPrimarySelectionDataDeviceManager(nullptr) - , mKeyboard(nullptr) - , mActiveOffers(g_hash_table_new(NULL, NULL)) - , mClipboardOffer(nullptr) - , mPrimaryOffer(nullptr) -+ , mDragContext(nullptr) - , mClipboardRequestNumber(0) - , mClipboardData(nullptr) - , mClipboardDataLength(0) - { - // Available as of GTK 3.8+ - static auto sGdkWaylandDisplayGetWlDisplay = - (wl_display *(*)(GdkDisplay *)) - dlsym(RTLD_DEFAULT, "gdk_wayland_display_get_wl_display"); -@@ -611,18 +876,31 @@ nsRetrievalContextWayland::nsRetrievalCo - mSeat); - gtk_primary_selection_device_add_listener(primaryDataDevice, - &primary_selection_device_listener, this); - } - - mInitialized = true; - } - -+static gboolean -+offer_hash_remove(gpointer wl_offer, gpointer aDataOffer, gpointer user_data) -+{ -+#ifdef DEBUG -+ nsPrintfCString msg("nsRetrievalContextWayland(): leaked nsDataOffer %p\n", -+ aDataOffer); -+ NS_WARNING(msg.get()); -+#endif -+ delete static_cast<DataOffer*>(aDataOffer); -+ return true; -+} -+ - nsRetrievalContextWayland::~nsRetrievalContextWayland(void) - { -+ g_hash_table_foreach_remove(mActiveOffers, offer_hash_remove, nullptr); - g_hash_table_destroy(mActiveOffers); - } - - GdkAtom* - nsRetrievalContextWayland::GetTargets(int32_t aWhichClipboard, - int* aTargetNum) - { - if (GetSelectionAtom(aWhichClipboard) == GDK_SELECTION_CLIPBOARD) { -diff --git a/widget/gtk/nsClipboardWayland.h b/widget/gtk/nsClipboardWayland.h ---- a/widget/gtk/nsClipboardWayland.h -+++ b/widget/gtk/nsClipboardWayland.h -@@ -27,65 +27,108 @@ public: - - char* GetData(wl_display* aDisplay, const char* aMimeType, - uint32_t* aContentLength); - - virtual ~DataOffer() {}; - private: - virtual bool RequestDataTransfer(const char* aMimeType, int fd) = 0; - -+protected: - nsTArray<GdkAtom> mTargetMIMETypes; - }; - - class WaylandDataOffer : public DataOffer - { - public: - WaylandDataOffer(wl_data_offer* aWaylandDataOffer); - -+ void DragOfferAccept(const char* aMimeType, uint32_t aTime); -+ void SetDragStatus(GdkDragAction aAction, uint32_t aTime); -+ -+ GdkDragAction GetSelectedDragAction(); -+ void SetSelectedDragAction(uint32_t aWaylandAction); -+ -+ void SetSourceDragActions(uint32_t aWaylandActions); -+ -+ virtual ~WaylandDataOffer(); - private: -- virtual ~WaylandDataOffer(); - bool RequestDataTransfer(const char* aMimeType, int fd) override; - - wl_data_offer* mWaylandDataOffer; -+ uint32_t mSelectedDragAction; - }; - - class PrimaryDataOffer : public DataOffer - { - public: - PrimaryDataOffer(gtk_primary_selection_offer* aPrimaryDataOffer); -+ void SetAvailableDragActions(uint32_t aWaylandActions) {}; - -+ virtual ~PrimaryDataOffer(); - private: -- virtual ~PrimaryDataOffer(); - bool RequestDataTransfer(const char* aMimeType, int fd) override; - - gtk_primary_selection_offer* mPrimaryDataOffer; - }; - -+class nsWaylandDragContext : public nsISupports -+{ -+ NS_DECL_ISUPPORTS -+ -+public: -+ nsWaylandDragContext(WaylandDataOffer* aWaylandDataOffer, -+ wl_display *aDisplay); -+ -+ void DropDataEnter(GtkWidget* aGtkWidget, uint32_t aTime, -+ nscoord aX, nscoord aY); -+ void DropMotion(uint32_t aTime, nscoord aX, nscoord aY); -+ void GetLastDropInfo(uint32_t *aTime, nscoord *aX, nscoord *aY); -+ -+ void SetDragStatus(GdkDragAction action); -+ GdkDragAction GetSelectedDragAction(); -+ -+ GtkWidget* GetWidget() { return mGtkWidget; } -+ GList* GetTargets(); -+ char* GetData(const char* aMimeType, uint32_t* aContentLength); -+private: -+ virtual ~nsWaylandDragContext() {}; -+ -+ nsAutoPtr<WaylandDataOffer> mDataOffer; -+ wl_display* mDisplay; -+ uint32_t mTime; -+ GtkWidget* mGtkWidget; -+ nscoord mX, mY; -+}; -+ - class nsRetrievalContextWayland : public nsRetrievalContext - { - public: - nsRetrievalContextWayland(); - - virtual const char* GetClipboardData(const char* aMimeType, - int32_t aWhichClipboard, - uint32_t* aContentLength) override; - virtual const char* GetClipboardText(int32_t aWhichClipboard) override; - virtual void ReleaseClipboardData(const char* aClipboardData) override; - - virtual GdkAtom* GetTargets(int32_t aWhichClipboard, - int* aTargetNum) override; - virtual bool HasSelectionSupport(void) override; - -- void RegisterDataOffer(wl_data_offer *aWaylandDataOffer); -- void RegisterDataOffer(gtk_primary_selection_offer *aPrimaryDataOffer); -+ void RegisterNewDataOffer(wl_data_offer *aWaylandDataOffer); -+ void RegisterNewDataOffer(gtk_primary_selection_offer *aPrimaryDataOffer); - - void SetClipboardDataOffer(wl_data_offer *aWaylandDataOffer); - void SetPrimaryDataOffer(gtk_primary_selection_offer *aPrimaryDataOffer); -+ void AddDragAndDropDataOffer(wl_data_offer *aWaylandDataOffer); -+ nsWaylandDragContext* GetDragContext(); - -- void ClearDataOffers(); -+ void ClearClipboardDataOffers(); -+ void ClearDragAndDropDataOffer(); - - void ConfigureKeyboard(wl_seat_capability caps); - void TransferFastTrackClipboard(int aClipboardRequestNumber, - GtkSelectionData *aSelectionData); - - void InitDataDeviceManager(wl_registry *registry, uint32_t id, uint32_t version); - void InitPrimarySelectionDataDeviceManager(wl_registry *registry, uint32_t id); - void InitSeat(wl_registry *registry, uint32_t id, uint32_t version, void *data); -@@ -98,16 +141,17 @@ private: - wl_data_device_manager *mDataDeviceManager; - gtk_primary_selection_device_manager *mPrimarySelectionDataDeviceManager; - wl_keyboard *mKeyboard; - - // Data offers provided by Wayland data device - GHashTable* mActiveOffers; - nsAutoPtr<DataOffer> mClipboardOffer; - nsAutoPtr<DataOffer> mPrimaryOffer; -+ RefPtr<nsWaylandDragContext> mDragContext; - - int mClipboardRequestNumber; - char* mClipboardData; - uint32_t mClipboardDataLength; - - // Mime types used for text data at Gtk+, see request_text_received_func() - // at gtkclipboard.c. - #define TEXT_MIME_TYPES_NUM 3 -diff --git a/widget/gtk/nsDragService.cpp b/widget/gtk/nsDragService.cpp ---- a/widget/gtk/nsDragService.cpp -+++ b/widget/gtk/nsDragService.cpp -@@ -37,16 +37,19 @@ - #include "nsViewManager.h" - #include "nsIFrame.h" - #include "nsGtkUtils.h" - #include "nsGtkKeyUtils.h" - #include "mozilla/gfx/2D.h" - #include "gfxPlatform.h" - #include "ScreenHelperGTK.h" - #include "nsArrayUtils.h" -+#ifdef MOZ_WAYLAND -+#include "nsClipboardWayland.h" -+#endif - - using namespace mozilla; - using namespace mozilla::gfx; - - // This sets how opaque the drag image is - #define DRAG_IMAGE_ALPHA_LEVEL 0.5 - - // These values are copied from GtkDragResult (rather than using GtkDragResult -@@ -93,16 +96,20 @@ invisibleSourceDragDataGet(GtkWidget - GtkSelectionData *aSelectionData, - guint aInfo, - guint32 aTime, - gpointer aData); - - nsDragService::nsDragService() - : mScheduledTask(eDragTaskNone) - , mTaskSource(0) -+#ifdef MOZ_WAYLAND -+ , mPendingWaylandDragContext(nullptr) -+ , mTargetWaylandDragContext(nullptr) -+#endif - { - // We have to destroy the hidden widget before the event loop stops - // running. - nsCOMPtr<nsIObserverService> obsServ = - mozilla::services::GetObserverService(); - obsServ->AddObserver(this, "quit-application", false); - - // our hidden source widget -@@ -509,16 +516,19 @@ nsDragService::EndDragSession(bool aDone - } - } - - // unset our drag action - SetDragAction(DRAGDROP_ACTION_NONE); - - // We're done with the drag context. - mTargetDragContextForRemote = nullptr; -+#ifdef MOZ_WAYLAND -+ mTargetWaylandDragContextForRemote = nullptr; -+#endif - - return nsBaseDragService::EndDragSession(aDoneDrag, aKeyModifiers); - } - - // nsIDragSession - NS_IMETHODIMP - nsDragService::SetCanDrop(bool aCanDrop) - { -@@ -629,16 +639,24 @@ nsDragService::GetNumDropItems(uint32_t - if (!mTargetWidget) { - MOZ_LOG(sDragLm, LogLevel::Debug, - ("*** warning: GetNumDropItems \ - called without a valid target widget!\n")); - *aNumItems = 0; - return NS_OK; - } - -+#ifdef MOZ_WAYLAND -+ // TODO: Wayland implementation of text/uri-list. -+ if (!mTargetDragContext) { -+ *aNumItems = 1; -+ return NS_OK; -+ } -+#endif -+ - bool isList = IsTargetContextList(); - if (isList) - mSourceDataItems->GetLength(aNumItems); - else { - GdkAtom gdkFlavor = gdk_atom_intern(gTextUriListType, FALSE); - GetTargetDragData(gdkFlavor); - if (mTargetDragData) { - const char *data = reinterpret_cast<char*>(mTargetDragData); -@@ -1020,19 +1038,28 @@ nsDragService::IsDataFlavorSupported(con - } - } - } - } - return NS_OK; - } - - // check the target context vs. this flavor, one at a time -- GList *tmp; -- for (tmp = gdk_drag_context_list_targets(mTargetDragContext); -- tmp; tmp = tmp->next) { -+ GList *tmp = nullptr; -+ if (mTargetDragContext) { -+ tmp = gdk_drag_context_list_targets(mTargetDragContext); -+ } -+#ifdef MOZ_WAYLAND -+ else { -+ tmp = mTargetWaylandDragContext->GetTargets(); -+ } -+#endif -+ GList *tmp_head = tmp; -+ -+ for (; tmp; tmp = tmp->next) { - /* Bug 331198 */ - GdkAtom atom = GDK_POINTER_TO_ATOM(tmp->data); - gchar *name = nullptr; - name = gdk_atom_name(atom); - MOZ_LOG(sDragLm, LogLevel::Debug, - ("checking %s against %s\n", name, aDataFlavor)); - if (name && (strcmp(name, aDataFlavor) == 0)) { - MOZ_LOG(sDragLm, LogLevel::Debug, ("good!\n")); -@@ -1067,16 +1094,23 @@ nsDragService::IsDataFlavorSupported(con - (strcmp(aDataFlavor, kFileMime) == 0))) { - MOZ_LOG(sDragLm, LogLevel::Debug, - ("good! ( it's text plain and we're checking \ - against text/unicode or application/x-moz-file)\n")); - *_retval = true; - } - g_free(name); - } -+ -+ // mTargetWaylandDragContext->GetTargets allocates the list -+ // so we need to free it here. -+ if (!mTargetDragContext) { -+ g_list_free(tmp_head); -+ } -+ - return NS_OK; - } - - void - nsDragService::ReplyToDragMotion(GdkDragContext* aDragContext) - { - MOZ_LOG(sDragLm, LogLevel::Debug, - ("nsDragService::ReplyToDragMotion %d", mCanDrop)); -@@ -1098,16 +1132,46 @@ nsDragService::ReplyToDragMotion(GdkDrag - action = GDK_ACTION_MOVE; - break; - } - } - - gdk_drag_status(aDragContext, action, mTargetTime); - } - -+#ifdef MOZ_WAYLAND -+void -+nsDragService::ReplyToDragMotion(nsWaylandDragContext* aDragContext) -+{ -+ MOZ_LOG(sDragLm, LogLevel::Debug, -+ ("nsDragService::ReplyToDragMotion %d", mCanDrop)); -+ -+ GdkDragAction action = (GdkDragAction)0; -+ if (mCanDrop) { -+ // notify the dragger if we can drop -+ switch (mDragAction) { -+ case DRAGDROP_ACTION_COPY: -+ action = GDK_ACTION_COPY; -+ break; -+ case DRAGDROP_ACTION_LINK: -+ action = GDK_ACTION_LINK; -+ break; -+ case DRAGDROP_ACTION_NONE: -+ action = (GdkDragAction)0; -+ break; -+ default: -+ action = GDK_ACTION_MOVE; -+ break; -+ } -+ } -+ -+ aDragContext->SetDragStatus(action); -+} -+#endif -+ - void - nsDragService::TargetDataReceived(GtkWidget *aWidget, - GdkDragContext *aContext, - gint aX, - gint aY, - GtkSelectionData *aSelectionData, - guint aInfo, - guint32 aTime) -@@ -1129,16 +1193,22 @@ nsDragService::TargetDataReceived(GtkWid - } - } - - bool - nsDragService::IsTargetContextList(void) - { - bool retval = false; - -+#ifdef MOZ_WAYLAND -+ // TODO: We need a wayland implementation here. -+ if (!mTargetDragContext) -+ return retval; -+#endif -+ - // gMimeListType drags only work for drags within a single process. The - // gtk_drag_get_source_widget() function will return nullptr if the source - // of the drag is another app, so we use it to check if a gMimeListType - // drop will work or not. - if (gtk_drag_get_source_widget(mTargetDragContext) == nullptr) - return retval; - - GList *tmp; -@@ -1167,27 +1237,38 @@ void - nsDragService::GetTargetDragData(GdkAtom aFlavor) - { - MOZ_LOG(sDragLm, LogLevel::Debug, ("getting data flavor %p\n", aFlavor)); - MOZ_LOG(sDragLm, LogLevel::Debug, ("mLastWidget is %p and mLastContext is %p\n", - mTargetWidget.get(), - mTargetDragContext.get())); - // reset our target data areas - TargetResetData(); -- gtk_drag_get_data(mTargetWidget, mTargetDragContext, aFlavor, mTargetTime); -+ -+ if (mTargetDragContext) { -+ gtk_drag_get_data(mTargetWidget, mTargetDragContext, aFlavor, mTargetTime); - -- MOZ_LOG(sDragLm, LogLevel::Debug, ("about to start inner iteration.")); -- PRTime entryTime = PR_Now(); -- while (!mTargetDragDataReceived && mDoingDrag) { -- // check the number of iterations -- MOZ_LOG(sDragLm, LogLevel::Debug, ("doing iteration...\n")); -- PR_Sleep(20*PR_TicksPerSecond()/1000); /* sleep for 20 ms/iteration */ -- if (PR_Now()-entryTime > NS_DND_TIMEOUT) break; -- gtk_main_iteration(); -+ MOZ_LOG(sDragLm, LogLevel::Debug, ("about to start inner iteration.")); -+ PRTime entryTime = PR_Now(); -+ while (!mTargetDragDataReceived && mDoingDrag) { -+ // check the number of iterations -+ MOZ_LOG(sDragLm, LogLevel::Debug, ("doing iteration...\n")); -+ PR_Sleep(20*PR_TicksPerSecond()/1000); /* sleep for 20 ms/iteration */ -+ if (PR_Now()-entryTime > NS_DND_TIMEOUT) break; -+ gtk_main_iteration(); -+ } - } -+#ifdef MOZ_WAYLAND -+ else { -+ mTargetDragData = -+ mTargetWaylandDragContext->GetData(gdk_atom_name(aFlavor), -+ &mTargetDragDataLen); -+ mTargetDragDataReceived = true; -+ } -+#endif - MOZ_LOG(sDragLm, LogLevel::Debug, ("finished inner iteration\n")); - } - - void - nsDragService::TargetResetData(void) - { - mTargetDragDataReceived = false; - // make sure to free old data if we have to -@@ -1428,17 +1509,17 @@ nsDragService::SourceEndDragSession(GdkD - } - } - - if (mDataTransfer) { - mDataTransfer->SetDropEffectInt(dropEffect); - } - - // Schedule the appropriate drag end dom events. -- Schedule(eDragTaskSourceEnd, nullptr, nullptr, LayoutDeviceIntPoint(), 0); -+ Schedule(eDragTaskSourceEnd, nullptr, nullptr, nullptr, LayoutDeviceIntPoint(), 0); - } - - static void - CreateUriList(nsIArray *items, gchar **text, gint *length) - { - uint32_t i, count; - GString *uriList = g_string_new(nullptr); - -@@ -1778,64 +1859,68 @@ invisibleSourceDragEnd(GtkWidget - // - // No Gecko drag events are dispatched (during nested event loops) while other - // Gecko drag events are in flight. This helps event handlers that may not - // expect nested events, while accessing an event's dataTransfer for example. - - gboolean - nsDragService::ScheduleMotionEvent(nsWindow *aWindow, - GdkDragContext *aDragContext, -+ nsWaylandDragContext *aWaylandDragContext, - LayoutDeviceIntPoint aWindowPoint, guint aTime) - { -- if (mScheduledTask == eDragTaskMotion) { -+ if (aDragContext && mScheduledTask == eDragTaskMotion) { - // The drag source has sent another motion message before we've - // replied to the previous. That shouldn't happen with Xdnd. The - // spec for Motif drags is less clear, but we'll just update the - // scheduled task with the new position reply only to the most - // recent message. - NS_WARNING("Drag Motion message received before previous reply was sent"); - } - - // Returning TRUE means we'll reply with a status message, unless we first - // get a leave. -- return Schedule(eDragTaskMotion, aWindow, aDragContext, -+ return Schedule(eDragTaskMotion, aWindow, aDragContext, aWaylandDragContext, - aWindowPoint, aTime); - } - - void - nsDragService::ScheduleLeaveEvent() - { - // We don't know at this stage whether a drop signal will immediately - // follow. If the drop signal gets sent it will happen before we return - // to the main loop and the scheduled leave task will be replaced. -- if (!Schedule(eDragTaskLeave, nullptr, nullptr, LayoutDeviceIntPoint(), 0)) { -+ if (!Schedule(eDragTaskLeave, nullptr, nullptr, nullptr, -+ LayoutDeviceIntPoint(), 0)) { - NS_WARNING("Drag leave after drop"); - } - } - - gboolean - nsDragService::ScheduleDropEvent(nsWindow *aWindow, - GdkDragContext *aDragContext, -+ nsWaylandDragContext *aWaylandDragContext, - LayoutDeviceIntPoint aWindowPoint, guint aTime) - { - if (!Schedule(eDragTaskDrop, aWindow, -- aDragContext, aWindowPoint, aTime)) { -+ aDragContext, aWaylandDragContext, aWindowPoint, aTime)) { - NS_WARNING("Additional drag drop ignored"); - return FALSE; - } - - SetDragEndPoint(aWindowPoint + aWindow->WidgetToScreenOffset()); - - // We'll reply with gtk_drag_finish(). - return TRUE; - } - - gboolean - nsDragService::Schedule(DragTask aTask, nsWindow *aWindow, - GdkDragContext *aDragContext, -+ nsWaylandDragContext *aWaylandDragContext, - LayoutDeviceIntPoint aWindowPoint, guint aTime) - { - // If there is an existing leave or motion task scheduled, then that - // will be replaced. When the new task is run, it will dispatch - // any necessary leave or motion events. - - // If aTask is eDragTaskSourceEnd, then it will replace even a scheduled - // drop event (which could happen if the drop event has not been processed -@@ -1844,16 +1929,19 @@ nsDragService::Schedule(DragTask aTask, - // drop. - if (mScheduledTask == eDragTaskSourceEnd || - (mScheduledTask == eDragTaskDrop && aTask != eDragTaskSourceEnd)) - return FALSE; - - mScheduledTask = aTask; - mPendingWindow = aWindow; - mPendingDragContext = aDragContext; -+#ifdef MOZ_WAYLAND -+ mPendingWaylandDragContext = aWaylandDragContext; -+#endif - mPendingWindowPoint = aWindowPoint; - mPendingTime = aTime; - - if (!mTaskSource) { - // High priority is used here because the native events involved have - // already waited at default priority. Perhaps a lower than default - // priority could be used for motion tasks because there is a chance - // that a leave or drop is waiting, but managing different priorities -@@ -1919,17 +2007,24 @@ nsDragService::RunScheduledTask() - // This may be the start of a destination drag session. - StartDragSession(); - - // mTargetWidget may be nullptr if the window has been destroyed. - // (The leave event is not scheduled if a drop task is still scheduled.) - // We still reply appropriately to indicate that the drop will or didn't - // succeeed. - mTargetWidget = mTargetWindow->GetMozContainerWidget(); -- mTargetDragContext.steal(mPendingDragContext); -+ if (mTargetDragContext) { -+ mTargetDragContext.steal(mPendingDragContext); -+ } -+#ifdef MOZ_WAYLAND -+ else { -+ mTargetWaylandDragContext = mPendingWaylandDragContext.forget(); -+ } -+#endif - mTargetTime = mPendingTime; - - // http://www.whatwg.org/specs/web-apps/current-work/multipage/dnd.html#drag-and-drop-processing-model - // (as at 27 December 2010) indicates that a "drop" event should only be - // fired (at the current target element) if the current drag operation is - // not none. The current drag operation will only be set to a non-none - // value during a "dragover" event. - // -@@ -1951,44 +2046,59 @@ nsDragService::RunScheduledTask() - // protocol is used. - if (task == eDragTaskMotion || positionHasChanged) { - UpdateDragAction(); - TakeDragEventDispatchedToChildProcess(); // Clear the old value. - DispatchMotionEvents(); - if (task == eDragTaskMotion) { - if (TakeDragEventDispatchedToChildProcess()) { - mTargetDragContextForRemote = mTargetDragContext; -+#ifdef MOZ_WAYLAND -+ mTargetWaylandDragContextForRemote = mTargetWaylandDragContext; -+#endif - } else { - // Reply to tell the source whether we can drop and what - // action would be taken. -- ReplyToDragMotion(mTargetDragContext); -+ if (mTargetDragContext) { -+ ReplyToDragMotion(mTargetDragContext); -+ } -+#ifdef MOZ_WAYLAND -+ else { -+ ReplyToDragMotion(mTargetWaylandDragContext); -+ } -+#endif - } - } - } - - if (task == eDragTaskDrop) { - gboolean success = DispatchDropEvent(); - - // Perhaps we should set the del parameter to TRUE when the drag - // action is move, but we don't know whether the data was successfully - // transferred. -- gtk_drag_finish(mTargetDragContext, success, -- /* del = */ FALSE, mTargetTime); -+ if (mTargetDragContext) { -+ gtk_drag_finish(mTargetDragContext, success, -+ /* del = */ FALSE, mTargetTime); -+ } - - // This drag is over, so clear out our reference to the previous - // window. - mTargetWindow = nullptr; - // Make sure to end the drag session. If this drag started in a - // different app, we won't get a drag_end signal to end it from. - EndDragSession(true, GetCurrentModifiers()); - } - - // We're done with the drag context. - mTargetWidget = nullptr; - mTargetDragContext = nullptr; -+#ifdef MOZ_WAYLAND -+ mTargetWaylandDragContext = nullptr; -+#endif - - // If we got another drag signal while running the sheduled task, that - // must have happened while running a nested event loop. Leave the task - // source on the event loop. - if (mScheduledTask != eDragTaskNone) - return TRUE; - - // We have no task scheduled. -@@ -2008,17 +2118,26 @@ nsDragService::UpdateDragAction() - // nsContentUtils::SetDataTransferInEvent() to set the initial - // dataTransfer.dropEffect, so GdkDragContext::suggested_action would be - // more appropriate. GdkDragContext::actions should be used to set - // dataTransfer.effectAllowed, which doesn't currently happen with - // external sources. - - // default is to do nothing - int action = nsIDragService::DRAGDROP_ACTION_NONE; -- GdkDragAction gdkAction = gdk_drag_context_get_actions(mTargetDragContext); -+ GdkDragAction gdkAction = GDK_ACTION_DEFAULT; -+ if (mTargetDragContext) { -+ gdkAction = gdk_drag_context_get_actions(mTargetDragContext); -+ } -+#ifdef MOZ_WAYLAND -+ else { -+ // We got the selected D&D action from compositor on Wayland. -+ gdkAction = mTargetWaylandDragContext->GetSelectedDragAction(); -+ } -+#endif - - // set the default just in case nothing matches below - if (gdkAction & GDK_ACTION_DEFAULT) - action = nsIDragService::DRAGDROP_ACTION_MOVE; - - // first check to see if move is set - if (gdkAction & GDK_ACTION_MOVE) - action = nsIDragService::DRAGDROP_ACTION_MOVE; -@@ -2037,16 +2156,22 @@ nsDragService::UpdateDragAction() - - NS_IMETHODIMP - nsDragService::UpdateDragEffect() - { - if (mTargetDragContextForRemote) { - ReplyToDragMotion(mTargetDragContextForRemote); - mTargetDragContextForRemote = nullptr; - } -+#ifdef MOZ_WAYLAND -+ else if (mTargetWaylandDragContextForRemote) { -+ ReplyToDragMotion(mTargetWaylandDragContextForRemote); -+ mTargetWaylandDragContextForRemote = nullptr; -+ } -+#endif - return NS_OK; - } - - void - nsDragService::DispatchMotionEvents() - { - mCanDrop = false; - -diff --git a/widget/gtk/nsDragService.h b/widget/gtk/nsDragService.h ---- a/widget/gtk/nsDragService.h -+++ b/widget/gtk/nsDragService.h -@@ -9,16 +9,17 @@ - - #include "mozilla/RefPtr.h" - #include "nsBaseDragService.h" - #include "nsIObserver.h" - #include "nsAutoRef.h" - #include <gtk/gtk.h> - - class nsWindow; -+class nsWaylandDragContext; - - namespace mozilla { - namespace gfx { - class SourceSurface; - } - } - - #ifndef HAVE_NSGOBJECTREFTRAITS -@@ -93,21 +94,23 @@ public: - gint aX, - gint aY, - GtkSelectionData *aSelection_data, - guint aInfo, - guint32 aTime); - - gboolean ScheduleMotionEvent(nsWindow *aWindow, - GdkDragContext *aDragContext, -+ nsWaylandDragContext* aPendingWaylandDragContext, - mozilla::LayoutDeviceIntPoint aWindowPoint, - guint aTime); - void ScheduleLeaveEvent(); - gboolean ScheduleDropEvent(nsWindow *aWindow, - GdkDragContext *aDragContext, -+ nsWaylandDragContext* aPendingWaylandDragContext, - mozilla::LayoutDeviceIntPoint aWindowPoint, - guint aTime); - - nsWindow* GetMostRecentDestWindow() - { - return mScheduledTask == eDragTaskNone ? mTargetWindow - : mPendingWindow; - } -@@ -153,30 +156,39 @@ private: - - // mPendingWindow, mPendingWindowPoint, mPendingDragContext, and - // mPendingTime, carry information from the GTK signal that will be used - // when the scheduled task is run. mPendingWindow and mPendingDragContext - // will be nullptr if the scheduled task is eDragTaskLeave. - RefPtr<nsWindow> mPendingWindow; - mozilla::LayoutDeviceIntPoint mPendingWindowPoint; - nsCountedRef<GdkDragContext> mPendingDragContext; -+#ifdef MOZ_WAYLAND -+ RefPtr<nsWaylandDragContext> mPendingWaylandDragContext; -+#endif - guint mPendingTime; - - // mTargetWindow and mTargetWindowPoint record the position of the last - // eDragTaskMotion or eDragTaskDrop task that was run or is still running. - // mTargetWindow is cleared once the drag has completed or left. - RefPtr<nsWindow> mTargetWindow; - mozilla::LayoutDeviceIntPoint mTargetWindowPoint; - // mTargetWidget and mTargetDragContext are set only while dispatching - // motion or drop events. mTime records the corresponding timestamp. - nsCountedRef<GtkWidget> mTargetWidget; - nsCountedRef<GdkDragContext> mTargetDragContext; -+#ifdef MOZ_WAYLAND -+ RefPtr<nsWaylandDragContext> mTargetWaylandDragContext; -+#endif - // mTargetDragContextForRemote is set while waiting for a reply from - // a child process. - nsCountedRef<GdkDragContext> mTargetDragContextForRemote; -+#ifdef MOZ_WAYLAND -+ RefPtr<nsWaylandDragContext> mTargetWaylandDragContextForRemote; -+#endif - guint mTargetTime; - - // is it OK to drop on us? - bool mCanDrop; - - // have we received our drag data? - bool mTargetDragDataReceived; - // last data received and its length -@@ -207,22 +219,25 @@ private: - bool SetAlphaPixmap(SourceSurface *aPixbuf, - GdkDragContext *aContext, - int32_t aXOffset, - int32_t aYOffset, - const mozilla::LayoutDeviceIntRect &dragRect); - - gboolean Schedule(DragTask aTask, nsWindow *aWindow, - GdkDragContext *aDragContext, -+ nsWaylandDragContext* aPendingWaylandDragContext, - mozilla::LayoutDeviceIntPoint aWindowPoint, guint aTime); - - // Callback for g_idle_add_full() to run mScheduledTask. - static gboolean TaskDispatchCallback(gpointer data); - gboolean RunScheduledTask(); - void UpdateDragAction(); - void DispatchMotionEvents(); - void ReplyToDragMotion(GdkDragContext* aDragContext); -+#ifdef MOZ_WAYLAND -+ void ReplyToDragMotion(nsWaylandDragContext* aDragContext); -+#endif - gboolean DispatchDropEvent(); - static uint32_t GetCurrentModifiers(); - }; - - #endif // nsDragService_h__ -- -diff --git a/widget/gtk/nsWindow.cpp b/widget/gtk/nsWindow.cpp ---- a/widget/gtk/nsWindow.cpp -+++ b/widget/gtk/nsWindow.cpp -@@ -6081,23 +6081,23 @@ touch_event_cb(GtkWidget* aWidget, GdkEv - void - nsWindow::InitDragEvent(WidgetDragEvent &aEvent) - { - // set the keyboard modifiers - guint modifierState = KeymapWrapper::GetCurrentModifierState(); - KeymapWrapper::InitInputEvent(aEvent, modifierState); - } - --static gboolean --drag_motion_event_cb(GtkWidget *aWidget, -- GdkDragContext *aDragContext, -- gint aX, -- gint aY, -- guint aTime, -- gpointer aData) -+gboolean -+WindowDragMotionHandler(GtkWidget *aWidget, -+ GdkDragContext *aDragContext, -+ nsWaylandDragContext *aWaylandDragContext, -+ gint aX, -+ gint aY, -+ guint aTime) - { - RefPtr<nsWindow> window = get_window_for_gtk_widget(aWidget); - if (!window) - return FALSE; - - // figure out which internal widget this drag motion actually happened on - nscoord retx = 0; - nscoord rety = 0; -@@ -6112,25 +6112,34 @@ drag_motion_event_cb(GtkWidget *aWidget, - } - - LOGDRAG(("nsWindow drag-motion signal for %p\n", (void*)innerMostWindow)); - - LayoutDeviceIntPoint point = window->GdkPointToDevicePixels({ retx, rety }); - - RefPtr<nsDragService> dragService = nsDragService::GetInstance(); - return dragService-> -- ScheduleMotionEvent(innerMostWindow, aDragContext, -+ ScheduleMotionEvent(innerMostWindow, aDragContext, aWaylandDragContext, - point, aTime); - } - --static void --drag_leave_event_cb(GtkWidget *aWidget, -- GdkDragContext *aDragContext, -- guint aTime, -- gpointer aData) -+static gboolean -+drag_motion_event_cb(GtkWidget *aWidget, -+ GdkDragContext *aDragContext, -+ gint aX, -+ gint aY, -+ guint aTime, -+ gpointer aData) -+{ -+ return WindowDragMotionHandler(aWidget, aDragContext, nullptr, -+ aX, aY, aTime); -+} -+ -+void -+WindowDragLeaveHandler(GtkWidget *aWidget) - { - RefPtr<nsWindow> window = get_window_for_gtk_widget(aWidget); - if (!window) - return; - - RefPtr<nsDragService> dragService = nsDragService::GetInstance(); - - nsWindow *mostRecentDragWindow = dragService->GetMostRecentDestWindow(); -@@ -6153,24 +6162,32 @@ drag_leave_event_cb(GtkWidget *aWidget, - } - - LOGDRAG(("nsWindow drag-leave signal for %p\n", - (void*)mostRecentDragWindow)); - - dragService->ScheduleLeaveEvent(); - } - -- --static gboolean --drag_drop_event_cb(GtkWidget *aWidget, -- GdkDragContext *aDragContext, -- gint aX, -- gint aY, -- guint aTime, -- gpointer aData) -+static void -+drag_leave_event_cb(GtkWidget *aWidget, -+ GdkDragContext *aDragContext, -+ guint aTime, -+ gpointer aData) -+{ -+ WindowDragLeaveHandler(aWidget); -+} -+ -+gboolean -+WindowDragDropHandler(GtkWidget *aWidget, -+ GdkDragContext *aDragContext, -+ nsWaylandDragContext *aWaylandDragContext, -+ gint aX, -+ gint aY, -+ guint aTime) - { - RefPtr<nsWindow> window = get_window_for_gtk_widget(aWidget); - if (!window) - return FALSE; - - // figure out which internal widget this drag motion actually happened on - nscoord retx = 0; - nscoord rety = 0; -@@ -6185,20 +6202,31 @@ drag_drop_event_cb(GtkWidget *aWidget, - } - - LOGDRAG(("nsWindow drag-drop signal for %p\n", (void*)innerMostWindow)); - - LayoutDeviceIntPoint point = window->GdkPointToDevicePixels({ retx, rety }); - - RefPtr<nsDragService> dragService = nsDragService::GetInstance(); - return dragService-> -- ScheduleDropEvent(innerMostWindow, aDragContext, -+ ScheduleDropEvent(innerMostWindow, aDragContext, aWaylandDragContext, - point, aTime); - } - -+static gboolean -+drag_drop_event_cb(GtkWidget *aWidget, -+ GdkDragContext *aDragContext, -+ gint aX, -+ gint aY, -+ guint aTime, -+ gpointer aData) -+{ -+ return WindowDragDropHandler(aWidget, aDragContext, nullptr, aX, aY, aTime); -+} -+ - static void - drag_data_received_event_cb(GtkWidget *aWidget, - GdkDragContext *aDragContext, - gint aX, - gint aY, - GtkSelectionData *aSelectionData, - guint aInfo, - guint aTime, -diff --git a/widget/gtk/nsWindow.h b/widget/gtk/nsWindow.h ---- a/widget/gtk/nsWindow.h -+++ b/widget/gtk/nsWindow.h -@@ -61,16 +61,31 @@ extern mozilla::LazyLogModule gWidgetDra - - #define LOG(args) - #define LOGFOCUS(args) - #define LOGDRAG(args) - #define LOGDRAW(args) - - #endif /* MOZ_LOGGING */ - -+#ifdef MOZ_WAYLAND -+class nsWaylandDragContext; -+ -+gboolean -+WindowDragMotionHandler(GtkWidget *aWidget, GdkDragContext *aDragContext, -+ nsWaylandDragContext *aWaylandDragContext, -+ gint aX, gint aY, guint aTime); -+gboolean -+WindowDragDropHandler(GtkWidget *aWidget, GdkDragContext *aDragContext, -+ nsWaylandDragContext *aWaylandDragContext, gint aX, gint aY, -+ guint aTime); -+void -+WindowDragLeaveHandler(GtkWidget *aWidget); -+#endif -+ - class gfxPattern; - - namespace mozilla { - class TimeStamp; - class CurrentX11TimeGetter; - } - - class nsWindow final : public nsBaseWidget - |