From c272582ab78d43c595eefb843126c999c09dfd4f Mon Sep 17 00:00:00 2001 From: Rick Pasetto Date: Thu, 3 Dec 2009 11:48:28 -0800 Subject: Change API to no longer include slurl argument (its a platform-agnostic policy), add some code (not working yet) to implement DND on the mac --- indra/llwindow/llwindowmacosx.cpp | 96 ++++++++++++++++++++++++++++++++++++--- 1 file changed, 89 insertions(+), 7 deletions(-) (limited to 'indra/llwindow/llwindowmacosx.cpp') diff --git a/indra/llwindow/llwindowmacosx.cpp b/indra/llwindow/llwindowmacosx.cpp index af9a30cb25..0acda8ab3a 100644 --- a/indra/llwindow/llwindowmacosx.cpp +++ b/indra/llwindow/llwindowmacosx.cpp @@ -499,8 +499,9 @@ BOOL LLWindowMacOSX::createContext(int x, int y, int width, int height, int bits // Set up window event handlers (some window-related events ONLY go to window handlers.) InstallStandardEventHandler(GetWindowEventTarget(mWindow)); - InstallWindowEventHandler (mWindow, mEventHandlerUPP, GetEventTypeCount (WindowHandlerEventList), WindowHandlerEventList, (void*)this, &mWindowHandlerRef); // add event handler - + InstallWindowEventHandler(mWindow, mEventHandlerUPP, GetEventTypeCount (WindowHandlerEventList), WindowHandlerEventList, (void*)this, &mWindowHandlerRef); // add event handler + InstallTrackingHandler( dragTrackingHandler, mWindow, (void*)this ); + InstallReceiveHandler( dragReceiveHandler, mWindow, (void*)this ); } { @@ -2172,11 +2173,8 @@ OSStatus LLWindowMacOSX::eventHandler (EventHandlerCallRef myHandler, EventRef e } else { - MASK mask = 0; - if(modifiers & shiftKey) { mask |= MASK_SHIFT; } - if(modifiers & (cmdKey | controlKey)) { mask |= MASK_CONTROL; } - if(modifiers & optionKey) { mask |= MASK_ALT; } - + MASK mask = LLWindowMacOSX::modifiersToMask(modifiers); + llassert( actualType == typeUnicodeText ); // The result is a UTF16 buffer. Pass the characters in turn to handleUnicodeChar. @@ -3377,3 +3375,87 @@ std::vector LLWindowMacOSX::getDynamicFallbackFontList() return std::vector(); } +// static +MASK LLWindowMacOSX::modifiersToMask(SInt16 modifiers) +{ + MASK mask = 0; + if(modifiers & shiftKey) { mask |= MASK_SHIFT; } + if(modifiers & (cmdKey | controlKey)) { mask |= MASK_CONTROL; } + if(modifiers & optionKey) { mask |= MASK_ALT; } + return mask; +} + +OSErr LLWindowMacOSX::dragTrackingHandler(DragTrackingMessage message, WindowRef theWindow, + void * handlerRefCon, DragRef theDrag) +{ + LLWindowMacOSX *self = (LLWindowMacOSX*)handlerRefCon; + return self->handleDragNDrop(theDrag, false); +} + +OSErr LLWindowMacOSX::dragReceiveHandler(WindowRef theWindow, void * handlerRefCon, + DragRef theDrag) +{ + LLWindowMacOSX *self = (LLWindowMacOSX*)handlerRefCon; + return self->handleDragNDrop(theDrag, true); + +} + +OSErr LLWindowMacOSX::handleDragNDrop(DragRef theDrag, bool drop) +{ + OSErr result = noErr; + + UInt16 num_items = 0; + ::CountDragItems(theDrag, &num_items); + if (1 == num_items) + { + 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); + + UInt16 numFlavors = 0; + ::CountDragItemFlavors(theDrag, theItemRef, &numFlavors); + + FlavorType theType = kScrapFlavorTypeUnicode; + std::string url; + for (UInt16 i=0; ihandleDragNDrop(this, gl_pos, mask, drop, url); + + if (LLWindowCallbacks::DND_NONE == res) + { + result = dragNotAcceptedErr; + } + } + else { + result = dragNotAcceptedErr; + } + + return result; +} + -- cgit v1.2.3 From bfe66526c83d260d3e69971d30786d1e061c2c47 Mon Sep 17 00:00:00 2001 From: Monroe Linden Date: Thu, 3 Dec 2009 17:01:58 -0800 Subject: 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. --- indra/llwindow/llwindowmacosx.cpp | 141 +++++++++++++++++++++++++------------- 1 file changed, 92 insertions(+), 49 deletions(-) (limited to 'indra/llwindow/llwindowmacosx.cpp') 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; ihandleDragNDrop(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; } -- cgit v1.2.3 From fe0b027d4d7381a532bb0f14f64ecffdeb7190b6 Mon Sep 17 00:00:00 2001 From: Monroe Linden Date: Thu, 3 Dec 2009 17:40:58 -0800 Subject: Added the LLWindowCallbacks::DragNDropAction enum, and made the mac implementation and the cross-platform window callbacks use it (instead of 'bool drop'). This will break the windows impl until someone fixes it to match. --- indra/llwindow/llwindowmacosx.cpp | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) (limited to 'indra/llwindow/llwindowmacosx.cpp') diff --git a/indra/llwindow/llwindowmacosx.cpp b/indra/llwindow/llwindowmacosx.cpp index 87296b1202..02fa9df22d 100644 --- a/indra/llwindow/llwindowmacosx.cpp +++ b/indra/llwindow/llwindowmacosx.cpp @@ -3396,12 +3396,15 @@ OSErr LLWindowMacOSX::dragTrackingHandler(DragTrackingMessage message, WindowRef switch(message) { case kDragTrackingInWindow: - result = self->handleDragNDrop(drag, false); + result = self->handleDragNDrop(drag, LLWindowCallbacks::DNDA_TRACK); break; case kDragTrackingEnterHandler: + result = self->handleDragNDrop(drag, LLWindowCallbacks::DNDA_START_TRACKING); + break; + case kDragTrackingLeaveHandler: - // TODO: We probably want to do something clever for these (at least for the LeaveHandler). + result = self->handleDragNDrop(drag, LLWindowCallbacks::DNDA_STOP_TRACKING); break; default: @@ -3415,11 +3418,11 @@ OSErr LLWindowMacOSX::dragReceiveHandler(WindowRef theWindow, void * handlerRefC DragRef drag) { LLWindowMacOSX *self = (LLWindowMacOSX*)handlerRefCon; - return self->handleDragNDrop(drag, true); + return self->handleDragNDrop(drag, LLWindowCallbacks::DNDA_DROPPED); } -OSErr LLWindowMacOSX::handleDragNDrop(DragRef drag, bool drop) +OSErr LLWindowMacOSX::handleDragNDrop(DragRef drag, LLWindowCallbacks::DragNDropAction action) { OSErr result = dragNotAcceptedErr; // overall function result OSErr err = noErr; // for local error handling @@ -3488,7 +3491,7 @@ OSErr LLWindowMacOSX::handleDragNDrop(DragRef drag, bool drop) if(!url.empty()) { LLWindowCallbacks::DragNDropResult res = - mCallbacks->handleDragNDrop(this, gl_pos, mask, drop, url); + mCallbacks->handleDragNDrop(this, gl_pos, mask, action, url); if (LLWindowCallbacks::DND_NONE != res) { -- cgit v1.2.3 From 1500e90eccf237fb50f901528c5dc9d747f6d2f0 Mon Sep 17 00:00:00 2001 From: Rick Pasetto Date: Fri, 8 Jan 2010 15:11:03 -0800 Subject: Make sure mac build honors compile-time flag that en/disables OS drag and drop. Also fixed the cmake file to properly set LL_OS_DRAGDROP_ENABLED. --- indra/llwindow/llwindowmacosx.cpp | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'indra/llwindow/llwindowmacosx.cpp') diff --git a/indra/llwindow/llwindowmacosx.cpp b/indra/llwindow/llwindowmacosx.cpp index ffc44a1e84..dc5a98756a 100644 --- a/indra/llwindow/llwindowmacosx.cpp +++ b/indra/llwindow/llwindowmacosx.cpp @@ -500,8 +500,10 @@ BOOL LLWindowMacOSX::createContext(int x, int y, int width, int height, int bits // Set up window event handlers (some window-related events ONLY go to window handlers.) InstallStandardEventHandler(GetWindowEventTarget(mWindow)); InstallWindowEventHandler(mWindow, mEventHandlerUPP, GetEventTypeCount (WindowHandlerEventList), WindowHandlerEventList, (void*)this, &mWindowHandlerRef); // add event handler +#if LL_OS_DRAGDROP_ENABLED InstallTrackingHandler( dragTrackingHandler, mWindow, (void*)this ); InstallReceiveHandler( dragReceiveHandler, mWindow, (void*)this ); +#endif // LL_OS_DRAGDROP_ENABLED } { @@ -3387,6 +3389,8 @@ MASK LLWindowMacOSX::modifiersToMask(SInt16 modifiers) return mask; } +#if LL_OS_DRAGDROP_ENABLED + OSErr LLWindowMacOSX::dragTrackingHandler(DragTrackingMessage message, WindowRef theWindow, void * handlerRefCon, DragRef drag) { @@ -3507,3 +3511,4 @@ OSErr LLWindowMacOSX::handleDragNDrop(DragRef drag, LLWindowCallbacks::DragNDrop return result; } +#endif // LL_OS_DRAGDROP_ENABLED -- cgit v1.2.3 From b06d655727c15530c1f65ccea83ab911f42e04ff Mon Sep 17 00:00:00 2001 From: Rick Pasetto Date: Mon, 11 Jan 2010 18:44:00 -0800 Subject: Add cursor-change override while dragging on the mac This changes the setCursor() call in LLWindowMacOSX to be ignored if we're currently dragging via the OS http://codereview.lindenlab.com/273045 --- indra/llwindow/llwindowmacosx.cpp | 38 ++++++++++++++++++++++++++++++++++++-- 1 file changed, 36 insertions(+), 2 deletions(-) (limited to 'indra/llwindow/llwindowmacosx.cpp') diff --git a/indra/llwindow/llwindowmacosx.cpp b/indra/llwindow/llwindowmacosx.cpp index dc5a98756a..783d1f39ca 100644 --- a/indra/llwindow/llwindowmacosx.cpp +++ b/indra/llwindow/llwindowmacosx.cpp @@ -278,6 +278,8 @@ LLWindowMacOSX::LLWindowMacOSX(LLWindowCallbacks* callbacks, mMoveEventCampartorUPP = NewEventComparatorUPP(staticMoveEventComparator); mGlobalHandlerRef = NULL; mWindowHandlerRef = NULL; + + mDragOverrideCursor = -1; // We're not clipping yet SetRect( &mOldMouseClip, 0, 0, 0, 0 ); @@ -2795,6 +2797,8 @@ void LLWindowMacOSX::setCursor(ECursorType cursor) { OSStatus result = noErr; + if (mDragOverrideCursor != -1) return; + if (cursor == UI_CURSOR_ARROW && mBusyCount > 0) { @@ -3499,10 +3503,40 @@ OSErr LLWindowMacOSX::handleDragNDrop(DragRef drag, LLWindowCallbacks::DragNDrop LLWindowCallbacks::DragNDropResult res = mCallbacks->handleDragNDrop(this, gl_pos, mask, action, url); - if (LLWindowCallbacks::DND_NONE != res) + switch (res) { + case LLWindowCallbacks::DND_NONE: // No drop allowed + if (action == LLWindowCallbacks::DNDA_TRACK) + { + mDragOverrideCursor = kThemeNotAllowedCursor; + } + else { + mDragOverrideCursor = -1; + } + break; + case LLWindowCallbacks::DND_MOVE: // Drop accepted would result in a "move" operation + mDragOverrideCursor = kThemePointingHandCursor; + result = noErr; + break; + case LLWindowCallbacks::DND_COPY: // Drop accepted would result in a "copy" operation + mDragOverrideCursor = kThemeCopyArrowCursor; + result = noErr; + break; + case LLWindowCallbacks::DND_LINK: // Drop accepted would result in a "link" operation: + mDragOverrideCursor = kThemeAliasArrowCursor; + result = noErr; + break; + default: + mDragOverrideCursor = -1; + break; + } + if (mDragOverrideCursor == -1) { - result = noErr; + SetThemeCursor(kThemeArrowCursor); + } + else { + SetThemeCursor(mDragOverrideCursor); } + } } } -- cgit v1.2.3 From df69302cd2f00dd44b5b34aeb3ba896ce7548556 Mon Sep 17 00:00:00 2001 From: Rick Pasetto Date: Tue, 12 Jan 2010 11:31:07 -0800 Subject: Add restoring of previous cursor to mac impl http://codereview.lindenlab.com/273045 --- indra/llwindow/llwindowmacosx.cpp | 20 +++++++++++++++++--- 1 file changed, 17 insertions(+), 3 deletions(-) (limited to 'indra/llwindow/llwindowmacosx.cpp') diff --git a/indra/llwindow/llwindowmacosx.cpp b/indra/llwindow/llwindowmacosx.cpp index 783d1f39ca..9ccd4c7f97 100644 --- a/indra/llwindow/llwindowmacosx.cpp +++ b/indra/llwindow/llwindowmacosx.cpp @@ -2797,8 +2797,14 @@ void LLWindowMacOSX::setCursor(ECursorType cursor) { OSStatus result = noErr; - if (mDragOverrideCursor != -1) return; - + if (mDragOverrideCursor != -1) + { + // A drag is in progress...remember the requested cursor and we'll + // restore it when it is done + mCurrentCursor = cursor; + return; + } + if (cursor == UI_CURSOR_ARROW && mBusyCount > 0) { @@ -3529,11 +3535,19 @@ OSErr LLWindowMacOSX::handleDragNDrop(DragRef drag, LLWindowCallbacks::DragNDrop mDragOverrideCursor = -1; break; } + // This overrides the cursor being set by setCursor. + // This is a bit of a hack workaround because lots of areas + // within the viewer just blindly set the cursor. if (mDragOverrideCursor == -1) { - SetThemeCursor(kThemeArrowCursor); + // Restore the cursor + ECursorType temp_cursor = mCurrentCursor; + // get around the "setting the same cursor" code in setCursor() + mCurrentCursor = UI_CURSOR_COUNT; + setCursor(temp_cursor); } else { + // Override the cursor SetThemeCursor(mDragOverrideCursor); } -- cgit v1.2.3