diff --git a/widget/src/gtk/nsDragService.cpp b/widget/src/gtk/nsDragService.cpp index 51b5b297d97e..24ba79b6035a 100644 --- a/widget/src/gtk/nsDragService.cpp +++ b/widget/src/gtk/nsDragService.cpp @@ -148,12 +148,21 @@ nsDragService::InvokeDragSession (nsIDOMNode *aDOMNode, // before we start our drag, give the widget code a chance to // clean up any state. nsWidget::DragStarted(); + + // save our action type + GdkDragAction action = GDK_ACTION_DEFAULT; + + if (aActionType & DRAGDROP_ACTION_COPY) + (int)action |= GDK_ACTION_COPY; + if (aActionType & DRAGDROP_ACTION_MOVE) + (int)action |= GDK_ACTION_MOVE; + if (aActionType & DRAGDROP_ACTION_LINK) + (int)action |= GDK_ACTION_LINK; + // start our drag. GdkDragContext *context = gtk_drag_begin(mHiddenWidget, sourceList, - (GdkDragAction)(GDK_ACTION_COPY | GDK_ACTION_MOVE | - GDK_ACTION_LINK), - // GDK_ACTION_DEFAULT, + action, 1, &gdk_event); // make sure to set our default icon @@ -175,6 +184,8 @@ NS_IMETHODIMP nsDragService::EndDragSession() { PR_LOG(sDragLm, PR_LOG_DEBUG, ("nsDragService::EndDragSession")); + // unset our drag action + SetDragAction(DRAGDROP_ACTION_NONE); return nsBaseDragService::EndDragSession(); } @@ -508,11 +519,28 @@ nsDragService::TargetEndDragMotion (GtkWidget *aWidget, GdkDragContext *aContext, guint aTime) { - PR_LOG(sDragLm, PR_LOG_DEBUG, ("nsDragService::TargetEndDragMotion")); - if (mCanDrop) - gdk_drag_status(aContext, GDK_ACTION_COPY, aTime); - else + PR_LOG(sDragLm, PR_LOG_DEBUG, ("nsDragService::TargetEndDragMotion %d", mCanDrop)); + + if (mCanDrop) { + GdkDragAction action; + // 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; + default: + action = GDK_ACTION_MOVE; + break; + } + gdk_drag_status(aContext, action, aTime); + } + else { gdk_drag_status(aContext, (GdkDragAction)0, aTime); + } + return NS_OK; } diff --git a/widget/src/gtk/nsWindow.cpp b/widget/src/gtk/nsWindow.cpp index 38ea5faedcad..8f0f67b8fe7b 100644 --- a/widget/src/gtk/nsWindow.cpp +++ b/widget/src/gtk/nsWindow.cpp @@ -3175,6 +3175,43 @@ nsWindow::InitDragEvent (nsMouseEvent &aEvent) aEvent.isMeta = PR_FALSE; // GTK+ doesn't support the meta key } +// This will update the drag action based on the information in the +// drag context. Gtk gets this from a combination of the key settings +// and what the source is offering. + +void +nsWindow::UpdateDragStatus(nsMouseEvent &aEvent, + GdkDragContext *aDragContext, + nsIDragService *aDragService) +{ + // default is to do nothing + int action = nsIDragService::DRAGDROP_ACTION_NONE; + + // set the default just in case nothing matches below + if (aDragContext->actions & GDK_ACTION_DEFAULT) { + action = nsIDragService::DRAGDROP_ACTION_MOVE; + } + + // first check to see if move is set + if (aDragContext->actions & GDK_ACTION_MOVE) + action = nsIDragService::DRAGDROP_ACTION_MOVE; + + // then fall to the others + else if (aDragContext->actions & GDK_ACTION_LINK) + action = nsIDragService::DRAGDROP_ACTION_LINK; + + // copy is ctrl + else if (aDragContext->actions & GDK_ACTION_COPY) + action = nsIDragService::DRAGDROP_ACTION_COPY; + + // update the drag information + nsCOMPtr session; + aDragService->GetCurrentSession(getter_AddRefs(session)); + + if (session) + session->SetDragAction(action); +} + /* static */ gint nsWindow::DragMotionSignal (GtkWidget * aWidget, @@ -3254,6 +3291,9 @@ gint nsWindow::OnDragMotionSignal (GtkWidget * aWidget, InitDragEvent(event); + // now that we have initialized the event update our drag status + UpdateDragStatus(event, aDragContext, dragService); + event.message = NS_DRAGDROP_OVER; event.eventStructType = NS_DRAGDROP_EVENT; @@ -3391,6 +3431,9 @@ nsWindow::OnDragDropSignal (GtkWidget *aWidget, InitDragEvent(event); + // now that we have initialized the event update our drag status + UpdateDragStatus(event, aDragContext, dragService); + event.message = NS_DRAGDROP_OVER; event.eventStructType = NS_DRAGDROP_EVENT; event.widget = innerMostWidget; diff --git a/widget/src/gtk/nsWindow.h b/widget/src/gtk/nsWindow.h index fd0129854121..a53ec61e61ad 100644 --- a/widget/src/gtk/nsWindow.h +++ b/widget/src/gtk/nsWindow.h @@ -22,14 +22,14 @@ #ifndef nsWindow_h__ #define nsWindow_h__ - - #include "nsISupports.h" #include "nsWidget.h" #include "nsString.h" +#include "nsIDragService.h" + #include "gtkmozarea.h" #include "gdksuperwin.h" @@ -234,6 +234,9 @@ protected: static nsWindow *mLastLeaveWindow; void InitDragEvent(nsMouseEvent &aEvent); + void UpdateDragStatus(nsMouseEvent &aEvent, + GdkDragContext *aDragContext, + nsIDragService *aDragService); // DragBegin not needed ? // always returns TRUE