Bug 539862, Call TargetSetLastContext and UpdateDragStatus before dragenter is fired so drag action and window are properly set up, fixes dragging themes into addons dialog, r=karlt

This commit is contained in:
Neil Deakin 2010-02-01 10:11:09 -05:00
Родитель d3f3733d62
Коммит acbe0320e0
2 изменённых файлов: 49 добавлений и 59 удалений

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

@ -3609,6 +3609,36 @@ nsWindow::ThemeChanged()
}
}
void
nsWindow::CheckNeedDragLeaveEnter(nsWindow* aInnerMostWidget,
nsIDragService* aDragService,
GdkDragContext *aDragContext,
nscoord aX, nscoord aY)
{
// check to see if there was a drag motion window already in place
if (mLastDragMotionWindow) {
// same as the last window so no need for dragenter and dragleave events
if (mLastDragMotionWindow == aInnerMostWidget) {
UpdateDragStatus(aDragContext, aDragService);
return;
}
// send a dragleave event to the last window that got a motion event
nsRefPtr<nsWindow> kungFuDeathGrip = mLastDragMotionWindow;
mLastDragMotionWindow->OnDragLeave();
}
// Make sure that the drag service knows we're now dragging
aDragService->StartDragSession();
// update our drag status and send a dragenter event to the window
UpdateDragStatus(aDragContext, aDragService);
aInnerMostWidget->OnDragEnter(aX, aY);
// set the last window to the innerMostWidget
mLastDragMotionWindow = aInnerMostWidget;
}
gboolean
nsWindow::OnDragMotionEvent(GtkWidget *aWidget,
GdkDragContext *aDragContext,
@ -3657,30 +3687,18 @@ nsWindow::OnDragMotionEvent(GtkWidget *aWidget,
if (!innerMostWidget)
innerMostWidget = this;
// check to see if there was a drag motion window already in place
if (mLastDragMotionWindow) {
// if it wasn't this
if (mLastDragMotionWindow != innerMostWidget) {
// send a drag event to the last window that got a motion event
nsRefPtr<nsWindow> kungFuDeathGrip = mLastDragMotionWindow;
mLastDragMotionWindow->OnDragLeave();
// and enter on the new one
innerMostWidget->OnDragEnter(retx, rety);
}
}
else {
// if there was no other motion window, then we're starting a
// drag. Send an enter event to initiate the drag.
innerMostWidget->OnDragEnter(retx, rety);
}
// set the last window to the innerMostWidget
mLastDragMotionWindow = innerMostWidget;
// update the drag context
dragSessionGTK->TargetSetLastContext(aWidget, aDragContext, aTime);
// clear any drag leave timer that might be pending so that it
// doesn't get processed when we actually go out to get data.
if (mDragLeaveTimer) {
mDragLeaveTimer->Cancel();
mDragLeaveTimer = nsnull;
}
CheckNeedDragLeaveEnter(innerMostWidget, dragService, aDragContext, retx, rety);
// notify the drag service that we are starting a drag motion.
dragSessionGTK->TargetStartDragMotion();
@ -3690,9 +3708,6 @@ nsWindow::OnDragMotionEvent(GtkWidget *aWidget,
InitDragEvent(event);
// now that we have initialized the event update our drag status
UpdateDragStatus(event, aDragContext, dragService);
event.refPoint.x = retx;
event.refPoint.y = rety;
event.time = aTime;
@ -3761,28 +3776,11 @@ nsWindow::OnDragDropEvent(GtkWidget *aWidget,
&retx, &rety);
nsRefPtr<nsWindow> innerMostWidget = get_window_for_gdk_window(innerWindow);
// set this now before any of the drag enter or leave events happen
dragSessionGTK->TargetSetLastContext(aWidget, aDragContext, aTime);
if (!innerMostWidget)
innerMostWidget = this;
// check to see if there was a drag motion window already in place
if (mLastDragMotionWindow) {
// if it wasn't this
if (mLastDragMotionWindow != innerMostWidget) {
// send a drag event to the last window that got a motion event
nsRefPtr<nsWindow> kungFuDeathGrip = mLastDragMotionWindow;
mLastDragMotionWindow->OnDragLeave();
// and enter on the new one
innerMostWidget->OnDragEnter(retx, rety);
}
}
else {
// if there was no other motion window, send an enter event to
// initiate the drag session.
innerMostWidget->OnDragEnter(retx, rety);
}
// set this now before any of the drag enter or leave events happen
dragSessionGTK->TargetSetLastContext(aWidget, aDragContext, aTime);
// clear any drag leave timer that might be pending so that it
// doesn't get processed when we actually go out to get data.
@ -3791,8 +3789,7 @@ nsWindow::OnDragDropEvent(GtkWidget *aWidget,
mDragLeaveTimer = nsnull;
}
// set the last window to this
mLastDragMotionWindow = innerMostWidget;
CheckNeedDragLeaveEnter(innerMostWidget, dragService, aDragContext, retx, rety);
// What we do here is dispatch a new drag motion event to
// re-validate the drag target and then we do the drop. The events
@ -3802,9 +3799,6 @@ nsWindow::OnDragDropEvent(GtkWidget *aWidget,
InitDragEvent(event);
// now that we have initialized the event update our drag status
UpdateDragStatus(event, aDragContext, dragService);
event.refPoint.x = retx;
event.refPoint.y = rety;
event.time = aTime;
@ -3909,13 +3903,6 @@ nsWindow::OnDragEnter(nscoord aX, nscoord aY)
LOGDRAG(("nsWindow::OnDragEnter(%p)\n", (void*)this));
nsCOMPtr<nsIDragService> dragService = do_GetService(kCDragServiceCID);
if (dragService) {
// Make sure that the drag service knows we're now dragging.
dragService->StartDragSession();
}
nsDragEvent event(PR_TRUE, NS_DRAGDROP_ENTER, this);
event.refPoint.x = aX;
@ -6103,8 +6090,7 @@ nsWindow::InitDragEvent(nsDragEvent &aEvent)
// and what the source is offering.
void
nsWindow::UpdateDragStatus(nsDragEvent &aEvent,
GdkDragContext *aDragContext,
nsWindow::UpdateDragStatus(GdkDragContext *aDragContext,
nsIDragService *aDragService)
{
// default is to do nothing

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

@ -296,6 +296,11 @@ public:
void ThemeChanged(void);
void CheckNeedDragLeaveEnter(nsWindow* aInnerMostWidget,
nsIDragService* aDragService,
GdkDragContext *aDragContext,
nscoord aX, nscoord aY);
#ifdef MOZ_X11
Window mOldFocusWindow;
#endif /* MOZ_X11 */
@ -499,8 +504,7 @@ private:
// this is the last window that had a drag event happen on it.
static nsWindow *mLastDragMotionWindow;
void InitDragEvent (nsDragEvent &aEvent);
void UpdateDragStatus (nsDragEvent &aEvent,
GdkDragContext *aDragContext,
void UpdateDragStatus (GdkDragContext *aDragContext,
nsIDragService *aDragService);
// this is everything we need to be able to fire motion events