Bug 1896863 [Linux] Use IsDragFlavorAvailable() instead of gdk_drag_context_list_targets() r=emilio

Differential Revision: https://phabricator.services.mozilla.com/D210441
This commit is contained in:
stransky 2024-05-16 08:39:34 +00:00
parent 95aa11043a
commit 02f1285802
2 changed files with 40 additions and 79 deletions

View file

@ -1238,53 +1238,37 @@ nsDragService::IsDataFlavorSupported(const char* aDataFlavor, bool* _retval) {
return NS_OK; return NS_OK;
} }
// check the target context vs. this flavor, one at a time GdkAtom requestedFlavor = gdk_atom_intern(aDataFlavor, FALSE);
GList* tmp = nullptr; if (IsDragFlavorAvailable(requestedFlavor)) {
if (mTargetDragContext) { LOGDRAGSERVICE(" %s is supported", aDataFlavor);
tmp = gdk_drag_context_list_targets(mTargetDragContext);
}
for (; tmp; tmp = tmp->next) {
/* Bug 331198 */
GdkAtom atom = GDK_POINTER_TO_ATOM(tmp->data);
GUniquePtr<gchar> name(gdk_atom_name(atom));
if (!name) {
continue;
}
if (strcmp(name.get(), aDataFlavor) == 0) {
*_retval = true; *_retval = true;
return NS_OK;
} }
// check for automatic text/uri-list -> text/x-moz-url mapping if (requestedFlavor == sTextUriListTypeAtom &&
else if (strcmp(name.get(), gTextUriListType) == 0 && (IsDragFlavorAvailable(sURLMimeAtom) ||
(strcmp(aDataFlavor, kURLMime) == 0 || IsDragFlavorAvailable(sFileMimeAtom))) {
strcmp(aDataFlavor, kFileMime) == 0)) {
*_retval = true; *_retval = true;
} }
// check for automatic _NETSCAPE_URL -> text/x-moz-url mapping // check for automatic _NETSCAPE_URL -> text/x-moz-url mapping
else if (strcmp(name.get(), gMozUrlType) == 0 && if (requestedFlavor == sMozUrlTypeAtom &&
(strcmp(aDataFlavor, kURLMime) == 0)) { IsDragFlavorAvailable(sURLMimeAtom)) {
*_retval = true; *_retval = true;
} }
// check for file portal // check for file portal
// If we're asked for kURLMime/kFileMime we can convert gPortalFile // If we're asked for kURLMime/kFileMime we can convert gPortalFile
// or gPortalFileTransfer to it. // or gPortalFileTransfer to it.
else if ((strcmp(name.get(), gPortalFile) == 0 || if ((requestedFlavor == sPortalFileAtom ||
strcmp(name.get(), gPortalFileTransfer) == 0) && requestedFlavor == sPortalFileTransferAtom) &&
(strcmp(aDataFlavor, kURLMime) == 0 || (IsDragFlavorAvailable(sURLMimeAtom) ||
strcmp(aDataFlavor, kFileMime) == 0)) { IsDragFlavorAvailable(sFileMimeAtom))) {
*_retval = true; *_retval = true;
} }
if (*_retval) { if (*_retval) {
LOGDRAGSERVICE(" supported, with converting %s => %s", name.get(), LOGDRAGSERVICE(" %s supported with conversion", aDataFlavor);
aDataFlavor);
} }
}
if (!*_retval) { if (!*_retval) {
LOGDRAGSERVICE(" %s is not supported", aDataFlavor); LOGDRAGSERVICE(" %s is not supported", aDataFlavor);
} }
return NS_OK; return NS_OK;
} }
@ -1359,34 +1343,16 @@ void nsDragService::SetCachedDragContext(GdkDragContext* aDragContext) {
} }
bool nsDragService::IsTargetContextList(void) { bool nsDragService::IsTargetContextList(void) {
bool retval = false;
// gMimeListType drags only work for drags within a single process. The // gMimeListType drags only work for drags within a single process. The
// gtk_drag_get_source_widget() function will return nullptr if the source // 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 // of the drag is another app, so we use it to check if a gMimeListType
// drop will work or not. // drop will work or not.
if (mTargetDragContext && if (mTargetDragContext &&
gtk_drag_get_source_widget(mTargetDragContext) == nullptr) { gtk_drag_get_source_widget(mTargetDragContext) == nullptr) {
return retval; return false;
} }
GList* tmp = nullptr; return IsDragFlavorAvailable(sMimeListTypeAtom);
if (mTargetDragContext) {
tmp = gdk_drag_context_list_targets(mTargetDragContext);
}
// walk the list of context targets and see if one of them is a list
// of items.
for (; tmp; tmp = tmp->next) {
/* Bug 331198 */
GdkAtom atom = GDK_POINTER_TO_ATOM(tmp->data);
GUniquePtr<gchar> name(gdk_atom_name(atom));
if (name && !strcmp(name.get(), gMimeListType)) {
return true;
}
}
return retval;
} }
bool nsDragService::IsDragFlavorAvailable(GdkAtom aRequestedFlavor) { bool nsDragService::IsDragFlavorAvailable(GdkAtom aRequestedFlavor) {
@ -2481,7 +2447,8 @@ static void invisibleSourceDragDataGet(GtkWidget* aWidget,
static gboolean invisibleSourceDragFailed(GtkWidget* aWidget, static gboolean invisibleSourceDragFailed(GtkWidget* aWidget,
GdkDragContext* aContext, GdkDragContext* aContext,
gint aResult, gpointer aData) { gint aResult, gpointer aData) {
#ifdef MOZ_WAYLAND nsDragService* dragService = (nsDragService*)aData;
// Wayland and X11 uses different drag results here. When drag target is // Wayland and X11 uses different drag results here. When drag target is
// missing X11 passes GDK_DRAG_CANCEL_NO_TARGET // missing X11 passes GDK_DRAG_CANCEL_NO_TARGET
// (from gdk_dnd_handle_button_event()/gdkdnd-x11.c) // (from gdk_dnd_handle_button_event()/gdkdnd-x11.c)
@ -2490,22 +2457,15 @@ static gboolean invisibleSourceDragFailed(GtkWidget* aWidget,
// GDK_DRAG_CANCEL_ERROR error code // GDK_DRAG_CANCEL_ERROR error code
// (see data_source_cancelled/gdkselection-wayland.c). // (see data_source_cancelled/gdkselection-wayland.c).
// Bug 1527976 // Bug 1527976
if (widget::GdkIsWaylandDisplay() && aResult == GTK_DRAG_RESULT_ERROR) { if (widget::GdkIsWaylandDisplay() && aResult == GTK_DRAG_RESULT_ERROR &&
for (GList* tmp = gdk_drag_context_list_targets(aContext); tmp; dragService->IsDragFlavorAvailable(nsDragService::sTabDropTypeAtom)) {
tmp = tmp->next) {
GdkAtom atom = GDK_POINTER_TO_ATOM(tmp->data);
if (atom == nsDragService::sTabDropTypeAtom) {
aResult = GTK_DRAG_RESULT_NO_TARGET; aResult = GTK_DRAG_RESULT_NO_TARGET;
LOGDRAGSERVICESTATIC("invisibleSourceDragFailed(%p): Wayland tab drop", LOGDRAGSERVICESTATIC("invisibleSourceDragFailed(%p): Wayland tab drop",
aContext); aContext);
break; } else {
}
}
}
#endif
LOGDRAGSERVICESTATIC("invisibleSourceDragFailed(%p) %s", aContext, LOGDRAGSERVICESTATIC("invisibleSourceDragFailed(%p) %s", aContext,
kGtkDragResults[aResult]); kGtkDragResults[aResult]);
nsDragService* dragService = (nsDragService*)aData; }
// End the drag session now (rather than waiting for the drag-end signal) // End the drag session now (rather than waiting for the drag-end signal)
// so that operations performed on dropEffect == none can start immediately // so that operations performed on dropEffect == none can start immediately
// rather than waiting for the drag-failed animation to finish. // rather than waiting for the drag-failed animation to finish.

View file

@ -177,6 +177,8 @@ class nsDragService final : public nsBaseDragService, public nsIObserver {
// set the drag icon during drag-begin // set the drag icon during drag-begin
void SetDragIcon(GdkDragContext* aContext); void SetDragIcon(GdkDragContext* aContext);
bool IsDragFlavorAvailable(GdkAtom aRequestedFlavor);
class AutoEventLoop { class AutoEventLoop {
RefPtr<nsDragService> mService; RefPtr<nsDragService> mService;
@ -266,7 +268,6 @@ class nsDragService final : public nsBaseDragService, public nsIObserver {
// is the current target drag context contain a list? // is the current target drag context contain a list?
bool IsTargetContextList(void); bool IsTargetContextList(void);
bool IsDragFlavorAvailable(GdkAtom aRequestedFlavor);
// this will get the native data from the last target given a // this will get the native data from the last target given a
// specific flavor // specific flavor
RefPtr<DragData> GetDragData(GdkAtom aRequestedFlavor); RefPtr<DragData> GetDragData(GdkAtom aRequestedFlavor);