diff options
author | Monroe Linden <monroe@lindenlab.com> | 2009-12-03 17:01:58 -0800 |
---|---|---|
committer | Monroe Linden <monroe@lindenlab.com> | 2009-12-03 17:01:58 -0800 |
commit | bfe66526c83d260d3e69971d30786d1e061c2c47 (patch) | |
tree | 00d603b56dd5152c622cf51286e153bcbf953051 /indra/llwindow | |
parent | ff53d4ff9b497f4f0f30035d7e02e6df290db6a4 (diff) |
Rewrote LLWindowMacOSX::handleDragNDrop() to use pasteboard manager instead of old, busted scrap manager to extract the data. Also fixed a mouse coordinate issue that caused drag tracking to be off.
Diffstat (limited to 'indra/llwindow')
-rw-r--r-- | indra/llwindow/llwindowmacosx.cpp | 141 | ||||
-rw-r--r-- | indra/llwindow/llwindowmacosx.h | 3 |
2 files changed, 92 insertions, 52 deletions
diff --git a/indra/llwindow/llwindowmacosx.cpp b/indra/llwindow/llwindowmacosx.cpp index 0acda8ab3a..87296b1202 100644 --- a/indra/llwindow/llwindowmacosx.cpp +++ b/indra/llwindow/llwindowmacosx.cpp @@ -3386,75 +3386,118 @@ MASK LLWindowMacOSX::modifiersToMask(SInt16 modifiers) } OSErr LLWindowMacOSX::dragTrackingHandler(DragTrackingMessage message, WindowRef theWindow, - void * handlerRefCon, DragRef theDrag) + void * handlerRefCon, DragRef drag) { + OSErr result = noErr; LLWindowMacOSX *self = (LLWindowMacOSX*)handlerRefCon; - return self->handleDragNDrop(theDrag, false); + + lldebugs << "drag tracking handler, message = " << message << llendl; + + switch(message) + { + case kDragTrackingInWindow: + result = self->handleDragNDrop(drag, false); + break; + + case kDragTrackingEnterHandler: + case kDragTrackingLeaveHandler: + // TODO: We probably want to do something clever for these (at least for the LeaveHandler). + break; + + default: + break; + } + + return result; } OSErr LLWindowMacOSX::dragReceiveHandler(WindowRef theWindow, void * handlerRefCon, - DragRef theDrag) + DragRef drag) { LLWindowMacOSX *self = (LLWindowMacOSX*)handlerRefCon; - return self->handleDragNDrop(theDrag, true); + return self->handleDragNDrop(drag, true); } -OSErr LLWindowMacOSX::handleDragNDrop(DragRef theDrag, bool drop) +OSErr LLWindowMacOSX::handleDragNDrop(DragRef drag, bool drop) { - OSErr result = noErr; + OSErr result = dragNotAcceptedErr; // overall function result + OSErr err = noErr; // for local error handling + + // Get the mouse position and modifiers of this drag. + SInt16 modifiers, mouseDownModifiers, mouseUpModifiers; + ::GetDragModifiers(drag, &modifiers, &mouseDownModifiers, &mouseUpModifiers); + MASK mask = LLWindowMacOSX::modifiersToMask(modifiers); + + Point mouse_point; + // This will return the mouse point in global screen coords + ::GetDragMouse(drag, &mouse_point, NULL); + LLCoordScreen screen_coords(mouse_point.h, mouse_point.v); + LLCoordGL gl_pos; + convertCoords(screen_coords, &gl_pos); - UInt16 num_items = 0; - ::CountDragItems(theDrag, &num_items); - if (1 == num_items) + // Look at the pasteboard and try to extract an URL from it + PasteboardRef pasteboard; + if(GetDragPasteboard(drag, &pasteboard) == noErr) { - SInt16 modifiers, mouseDownModifiers, mouseUpModifiers; - ::GetDragModifiers(theDrag, &modifiers, &mouseDownModifiers, &mouseUpModifiers); - MASK mask = LLWindowMacOSX::modifiersToMask(modifiers); - - Point mouse_point; - // This will return the mouse point in global screen coords - ::GetDragMouse(theDrag, &mouse_point, NULL); - LLCoordScreen screen_coords(mouse_point.v, mouse_point.h); - LLCoordGL gl_pos; - convertCoords(screen_coords, &gl_pos); - - DragItemRef theItemRef; - ::GetDragItemReferenceNumber(theDrag, 0, &theItemRef); + ItemCount num_items = 0; + // Treat an error here as an item count of 0 + (void)PasteboardGetItemCount(pasteboard, &num_items); - UInt16 numFlavors = 0; - ::CountDragItemFlavors(theDrag, theItemRef, &numFlavors); - - FlavorType theType = kScrapFlavorTypeUnicode; - std::string url; - for (UInt16 i=0; i<numFlavors; i++) + // Only deal with single-item drags. + if(num_items == 1) { - ::GetFlavorType(theDrag, theItemRef, i, &theType); + PasteboardItemID item_id = NULL; + CFArrayRef flavors = NULL; + CFDataRef data = NULL; - printf("Drag Flavor: '%lu'", theType); - fflush(stdout); - } - - Size size = 1024; - ::GetFlavorDataSize(theDrag, theItemRef, theType, &size); - - ::GetFlavorData(theDrag, theItemRef, theType, mDragData, &size, 0); - url = mDragData; + err = PasteboardGetItemIdentifier(pasteboard, 1, &item_id); // Yes, this really is 1-based. + + // Try to extract an URL from the pasteboard + if(err == noErr) + { + err = PasteboardCopyItemFlavors( pasteboard, item_id, &flavors); + } + + if(err == noErr) + { + if(CFArrayContainsValue(flavors, CFRangeMake(0, CFArrayGetCount(flavors)), kUTTypeURL)) + { + // This is an URL. + err = PasteboardCopyItemFlavorData(pasteboard, item_id, kUTTypeURL, &data); + } + else if(CFArrayContainsValue(flavors, CFRangeMake(0, CFArrayGetCount(flavors)), kUTTypeUTF8PlainText)) + { + // This is a string that might be an URL. + err = PasteboardCopyItemFlavorData(pasteboard, item_id, kUTTypeUTF8PlainText, &data); + } - printf("Drag Flavor: '%lu' - Drag data : %s", theType, url.c_str()); - fflush(stdout); + } - LLWindowCallbacks::DragNDropResult res = - mCallbacks->handleDragNDrop(this, gl_pos, mask, drop, url); - - if (LLWindowCallbacks::DND_NONE == res) - { - result = dragNotAcceptedErr; + if(flavors != NULL) + { + CFRelease(flavors); + } + + if(data != NULL) + { + std::string url; + url.assign((char*)CFDataGetBytePtr(data), CFDataGetLength(data)); + CFRelease(data); + + if(!url.empty()) + { + LLWindowCallbacks::DragNDropResult res = + mCallbacks->handleDragNDrop(this, gl_pos, mask, drop, url); + + if (LLWindowCallbacks::DND_NONE != res) + { + result = noErr; + } + } + } } } - else { - result = dragNotAcceptedErr; - } return result; } diff --git a/indra/llwindow/llwindowmacosx.h b/indra/llwindow/llwindowmacosx.h index 24e44417f5..23e33a6e07 100644 --- a/indra/llwindow/llwindowmacosx.h +++ b/indra/llwindow/llwindowmacosx.h @@ -209,9 +209,6 @@ protected: LangCode mTSMLangCode; LLPreeditor* mPreeditor; - // Storage for drag data - char mDragData[1024]; - static BOOL sUseMultGL; friend class LLWindowManager; |