Bug 1767460 [Wayland] Send D&D status back to compositor in D&D move handler r=emilio

This is an update to Bug 1730203. We need to answer to D&D inside of D&D move handler due to specific Gtk architecture.
In fix for Bug 1730203 we send the reply but we failed to update D&D status so the reply may be outdated.
In this patch we:

- Set correct D&D state and send reply to D&D motion event
- Move above code to nsDragService (nsDragService::Schedule()) so UpdateDragAction()/ReplyToDragMotion() can be private again.
- Update UpdateDragAction()/ReplyToDragMotion() to use correct GdkDragContext.
- At UpdateDragAction() call gdk_drag_context_get_selected_action() for valid GdkDragContext only.

Depends on D154415

Differential Revision: https://phabricator.services.mozilla.com/D154416
This commit is contained in:
Martin Stransky 2022-08-15 19:29:58 +00:00
Родитель 6b622391b0
Коммит 7179bc70ae
3 изменённых файлов: 30 добавлений и 26 удалений

Просмотреть файл

@ -1057,6 +1057,8 @@ void nsDragService::ReplyToDragMotion(GdkDragContext* aDragContext) {
action = GDK_ACTION_MOVE;
break;
}
} else {
LOGDRAGSERVICE(" mCanDrop is false, disable drop");
}
gdk_drag_status(aDragContext, action, mTargetTime);
}
@ -2208,6 +2210,14 @@ gboolean nsDragService::Schedule(DragTask aTask, nsWindow* aWindow,
mTaskSource = g_timeout_add_full(G_PRIORITY_HIGH, 0, TaskDispatchCallback,
this, nullptr);
}
// We need to reply to drag_motion event on Wayland immediately,
// see Bug 1730203.
if (widget::GdkIsWaylandDisplay() && mScheduledTask == eDragTaskMotion) {
UpdateDragAction(aDragContext);
ReplyToDragMotion(aDragContext);
}
return TRUE;
}
@ -2366,33 +2376,32 @@ gboolean nsDragService::RunScheduledTask() {
// drag context. Gtk gets this from a combination of the key settings
// and what the source is offering.
void nsDragService::UpdateDragAction() {
void nsDragService::UpdateDragAction(GdkDragContext* aDragContext) {
// This doesn't look right. dragSession.dragAction is used by
// 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.
LOGDRAGSERVICE("nsDragService::UpdateDragAction(%p)",
mTargetDragContext.get());
LOGDRAGSERVICE("nsDragService::UpdateDragAction(%p)", aDragContext);
// default is to do nothing
int action = nsIDragService::DRAGDROP_ACTION_NONE;
GdkDragAction gdkAction = GDK_ACTION_DEFAULT;
if (mTargetDragContext) {
gdkAction = gdk_drag_context_get_actions(mTargetDragContext);
if (aDragContext) {
gdkAction = gdk_drag_context_get_actions(aDragContext);
LOGDRAGSERVICE(" gdk_drag_context_get_actions() returns %x", gdkAction);
}
// Under wayland the selected action specifies the currently applied drag
// modifier
if (widget::GdkIsWaylandDisplay()) {
GdkDragAction gdkActionSelected =
gdk_drag_context_get_selected_action(mTargetDragContext);
LOGDRAGSERVICE(" gdk_drag_context_get_selected_action() returns %x",
gdkActionSelected);
if (gdkActionSelected) {
gdkAction = gdkActionSelected;
// Under wayland the selected action specifies the currently applied drag
// modifier
if (widget::GdkIsWaylandDisplay()) {
GdkDragAction gdkActionSelected =
gdk_drag_context_get_selected_action(aDragContext);
LOGDRAGSERVICE(" gdk_drag_context_get_selected_action() returns %x",
gdkActionSelected);
if (gdkActionSelected) {
gdkAction = gdkActionSelected;
}
}
}
@ -2419,6 +2428,8 @@ void nsDragService::UpdateDragAction() {
SetDragAction(action);
}
void nsDragService::UpdateDragAction() { UpdateDragAction(mTargetDragContext); }
NS_IMETHODIMP
nsDragService::UpdateDragEffect() {
LOGDRAGSERVICE("nsDragService::UpdateDragEffect() from e10s child process");

Просмотреть файл

@ -99,11 +99,6 @@ class nsDragService final : public nsBaseDragService, public nsIObserver {
// set the drag icon during drag-begin
void SetDragIcon(GdkDragContext* aContext);
// Reply to drag_motion event according to recent DragService state.
// We need that on Wayland to reply immediately as it's requested
// there (see Bug 1730203).
void ReplyToDragMotion();
void EventLoopEnter() { mEventLoopDepth++; };
void EventLoopLeave() { mEventLoopDepth--; };
int GetLoopDepth() { return mEventLoopDepth; };
@ -214,9 +209,12 @@ class nsDragService final : public nsBaseDragService, public nsIObserver {
// Callback for g_idle_add_full() to run mScheduledTask.
MOZ_CAN_RUN_SCRIPT static gboolean TaskDispatchCallback(gpointer data);
MOZ_CAN_RUN_SCRIPT gboolean RunScheduledTask();
void UpdateDragAction();
MOZ_CAN_RUN_SCRIPT void DispatchMotionEvents();
void ReplyToDragMotion(GdkDragContext* aDragContext);
void ReplyToDragMotion();
void UpdateDragAction(GdkDragContext* aDragContext);
void UpdateDragAction();
#ifdef MOZ_LOGGING
const char* GetDragServiceTaskName(nsDragService::DragTask aTask);
#endif

Просмотреть файл

@ -8192,11 +8192,6 @@ gboolean WindowDragMotionHandler(GtkWidget* aWidget,
aTime)) {
return FALSE;
}
// We need to reply to drag_motion event on Wayland immediately,
// see Bug 1730203.
if (GdkIsWaylandDisplay()) {
dragService->ReplyToDragMotion();
}
return TRUE;
}