boolean mLocalOnly;
ClipData mData;
ClipDescription mDataDescription;
+ float mCurrentX, mCurrentY;
float mThumbOffsetX, mThumbOffsetY;
InputChannel mServerChannel, mClientChannel;
WindowState mTargetWindow;
mNotifiedWindows.clear();
mDragInProgress = true;
- DragEvent evt = DragEvent.obtain(DragEvent.ACTION_DRAG_STARTED, touchX, touchY,
- mDataDescription, null);
-
if (DEBUG_DRAG) {
- Slog.d(TAG, "broadcasting DRAG_STARTED: " + evt);
+ Slog.d(TAG, "broadcasting DRAG_STARTED at (" + touchX + ", " + touchY + ")");
}
final int N = mWindows.size();
for (int i = 0; i < N; i++) {
- // sendDragStartedLw() clones evt for local-process dispatch
- sendDragStartedLw(mWindows.get(i), evt);
+ sendDragStartedLw(mWindows.get(i), touchX, touchY, mDataDescription);
}
- evt.recycle();
}
/* helper - send a caller-provided event, presumed to be DRAG_STARTED, if the
* This method clones the 'event' parameter if it's being delivered to the same
* process, so it's safe for the caller to call recycle() on the event afterwards.
*/
- private void sendDragStartedLw(WindowState newWin, DragEvent event) {
+ private void sendDragStartedLw(WindowState newWin, float touchX, float touchY,
+ ClipDescription desc) {
if (mDragInProgress && newWin.isPotentialDragTarget()) {
+ DragEvent event = DragEvent.obtain(DragEvent.ACTION_DRAG_STARTED,
+ touchX - newWin.mFrame.left, touchY - newWin.mFrame.top,
+ desc, null);
try {
- // clone for local callees since dispatch will recycle the event
- if (Process.myPid() == newWin.mSession.mPid) {
- event = DragEvent.obtain(event);
- }
newWin.mClient.dispatchDragEvent(event);
// track each window that we've notified that the drag is starting
mNotifiedWindows.add(newWin);
} catch (RemoteException e) {
Slog.w(TAG, "Unable to drag-start window " + newWin);
+ } finally {
+ // if the callee was local, the dispatch has already recycled the event
+ if (Process.myPid() != newWin.mSession.mPid) {
+ event.recycle();
+ }
}
}
}
if (DEBUG_DRAG) {
Slog.d(TAG, "sending DRAG_STARTED to new window " + newWin);
}
- DragEvent event = DragEvent.obtain(DragEvent.ACTION_DRAG_STARTED, 0, 0,
- mDataDescription, null);
- // sendDragStartedLw() clones 'event' if the window is process-local
- sendDragStartedLw(newWin, event);
- event.recycle();
+ sendDragStartedLw(newWin, mCurrentX, mCurrentY, mDataDescription);
}
}
}
// force DRAG_EXITED_EVENT if appropriate
DragEvent evt = DragEvent.obtain(DragEvent.ACTION_DRAG_EXITED,
- 0, 0, null, null);
+ x - mTargetWindow.mFrame.left, y - mTargetWindow.mFrame.top,
+ null, null);
mTargetWindow.mClient.dispatchDragEvent(evt);
if (myPid != mTargetWindow.mSession.mPid) {
evt.recycle();
Slog.d(TAG, "sending DRAG_LOCATION to " + touchedWin);
}
DragEvent evt = DragEvent.obtain(DragEvent.ACTION_DRAG_LOCATION,
- x, y, null, null);
+ x - touchedWin.mFrame.left, y - touchedWin.mFrame.top,
+ null, null);
touchedWin.mClient.dispatchDragEvent(evt);
if (myPid != touchedWin.mSession.mPid) {
evt.recycle();
Slog.d(TAG, "sending DROP to " + touchedWin);
}
final int myPid = Process.myPid();
- DragEvent evt = DragEvent.obtain(DragEvent.ACTION_DROP, x, y, null, mData);
+ DragEvent evt = DragEvent.obtain(DragEvent.ACTION_DROP,
+ x - touchedWin.mFrame.left, y - touchedWin.mFrame.top,
+ null, mData);
try {
touchedWin.mClient.dispatchDragEvent(evt);
} catch (RemoteException e) {
// !!! TODO: extract the current touch (x, y) in screen coordinates. That
// will let us eliminate the (touchX,touchY) parameters from the API.
+ // !!! FIXME: put all this heavy stuff onto the mH looper, as well as
+ // the actual drag event dispatch stuff in the dragstate
+
mDragState.register();
mInputMonitor.updateInputWindowsLw();
mInputManager.transferTouchFocus(callingWin.mInputChannel,
mDragState.mServerChannel);
mDragState.mData = data;
+ mDragState.mCurrentX = touchX;
+ mDragState.mCurrentY = touchY;
mDragState.broadcastDragStartedLw(touchX, touchY);
// remember the thumb offsets for later
// Make the surface visible at the proper location
final Surface surface = mDragState.mSurface;
- surface.openTransaction();
+ Surface.openTransaction();
try {
surface.setPosition((int)(touchX - thumbCenterX),
(int)(touchY - thumbCenterY));
- surface.setAlpha(.5f);
+ surface.setAlpha(.7071f);
surface.setLayer(mDragState.getDragLayerLw());
surface.show();
} finally {
- surface.closeTransaction();
+ Surface.closeTransaction();
}
}