diff --git a/uppsrc/CtrlCore/CocoApp.mm b/uppsrc/CtrlCore/CocoApp.mm index a59ca0ed9..465aa8a33 100644 --- a/uppsrc/CtrlCore/CocoApp.mm +++ b/uppsrc/CtrlCore/CocoApp.mm @@ -341,17 +341,6 @@ void MMCtrl::SyncRect(CocoView *view) MakeScreenRect([win screen], [win contentRectForFrameRect: [win frame]])); } -void AppendClipboardText(const String& s) -{ - CFRef cs = CFStringCreateWithCString(NULL, (const char *)~s.ToString(), kCFStringEncodingUTF8); - [[NSPasteboard generalPasteboard] setString:(NSString *)~cs forType:NSPasteboardTypeString]; -} - -void AppendClipboardUnicodeText(const WString& s) -{ - AppendClipboardText(s.ToString()); -} - ViewDraw::ViewDraw(Ctrl *ctrl) { EnterGuiMutex(); diff --git a/uppsrc/CtrlCore/CocoClip.mm b/uppsrc/CtrlCore/CocoClip.mm index 5f037eb6b..485fd5881 100644 --- a/uppsrc/CtrlCore/CocoClip.mm +++ b/uppsrc/CtrlCore/CocoClip.mm @@ -210,6 +210,19 @@ WString ReadClipboardUnicodeText() return ReadClipboardText().ToWString(); } +void AppendClipboardText(const String& s) +{ + AppendClipboard("text", s); + // TODO Remove: +// CFRef cs = CFStringCreateWithCString(NULL, (const char *)~s.ToString(), kCFStringEncodingUTF8); + // [[NSPasteboard generalPasteboard] setString:(NSString *)~cs forType:NSPasteboardTypeString]; +} + +void AppendClipboardUnicodeText(const WString& s) +{ + AppendClipboardText(s.ToString()); +} + const char *ClipFmtsText() { return "text"; @@ -379,7 +392,7 @@ Ctrl * Ctrl::GetDragAndDropSource() } - (void)draggedImage:(NSImage *)anImage endedAt:(NSPoint)aPoint operation:(NSDragOperation)operation -{ // TODO: Looks like between apps, it is always move (?!) +{ result = operation; } @@ -387,6 +400,8 @@ Ctrl * Ctrl::GetDragAndDropSource() namespace Upp { +bool Ctrl::local_dnd_copy; + int Ctrl::DoDragAndDrop(const char *fmts, const Image& sample, dword actions, const VectorMap& data) { @@ -423,14 +438,19 @@ int Ctrl::DoDragAndDrop(const char *fmts, const Image& sample, dword actions, src->actions |= NSDragOperationCopy; if(actions & DND_MOVE) src->actions |= NSDragOperationMove; + + NSPoint p = [sCurrentMouseEvent__ locationInWindow]; + p.y -= size.height; + + local_dnd_copy = false; // macos does not have ability to change action in performDragOperation [nswindow dragImage:nsimg - at:[sCurrentMouseEvent__ locationInWindow] - offset:NSMakeSize(0, 0) - event:sCurrentMouseEvent__ - pasteboard:Pasteboard(true) - source:src - slideBack:YES]; + at:p + offset:NSMakeSize(0, 0) + event:sCurrentMouseEvent__ + pasteboard:Pasteboard(true) + source:src + slideBack:YES]; ClipboardOwner(true)->source = NULL; @@ -438,6 +458,9 @@ int Ctrl::DoDragAndDrop(const char *fmts, const Image& sample, dword actions, CGImageRelease(cgimg); + if(local_dnd_copy) // action was local and changed to copy in DragAndDrop + return DND_COPY; + return decode(src->result, NSDragOperationCopy, DND_COPY, NSDragOperationMove, DND_MOVE, DND_NONE); diff --git a/uppsrc/CtrlCore/CocoCtrl.h b/uppsrc/CtrlCore/CocoCtrl.h index b71d60267..598f0990f 100644 --- a/uppsrc/CtrlCore/CocoCtrl.h +++ b/uppsrc/CtrlCore/CocoCtrl.h @@ -9,6 +9,7 @@ private: static int WndCaretTime; static bool WndCaretVisible; + static bool local_dnd_copy; static void AnimateCaret(); friend void CocoInit(int argc, const char **argv, const char **envptr); diff --git a/uppsrc/CtrlCore/CocoImage.mm b/uppsrc/CtrlCore/CocoImage.mm index 671244178..10b132512 100644 --- a/uppsrc/CtrlCore/CocoImage.mm +++ b/uppsrc/CtrlCore/CocoImage.mm @@ -169,6 +169,9 @@ NSCursor *GetNSCursor(int kind) void Ctrl::SetMouseCursor(const Image& img) { + if(GetDragAndDropSource()) + return; + int64 h = img.GetAuxData(); if(h) { [GetNSCursor(h) set]; @@ -205,7 +208,7 @@ void ImageDraw::Init(int cx, int cy) { ib.Create(cx, cy); - static CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB(); // TODO: This is probably wrong... + static CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB(); SystemDraw::Init(CGBitmapContextCreateWithData(~ib, cx, cy, 8, cx * sizeof(RGBA), colorSpace, kCGImageAlphaPremultipliedFirst, diff --git a/uppsrc/CtrlCore/CocoProc.mm b/uppsrc/CtrlCore/CocoProc.mm index 79f0fd880..45460d84a 100644 --- a/uppsrc/CtrlCore/CocoProc.mm +++ b/uppsrc/CtrlCore/CocoProc.mm @@ -61,6 +61,32 @@ bool Ctrl::ReleaseWndCapture() } struct MMImp { + static bool KeyFlags(Upp::Ctrl *ctrl, NSEvent *e) { + bool alt = GetAlt(); + bool ctl = GetCtrl(); + bool sht = GetShift(); + bool opt = GetOption(); + Flags(e); + if(!ctrl->IsEnabled()) + return false; + + if(alt != GetAlt()) + ctrl->DispatchKey(K_ALT_KEY|(alt * K_KEYUP), 1); + if(ctl != GetCtrl()) + ctrl->DispatchKey(K_CTRL_KEY|(ctl * K_KEYUP), 1); + if(sht != GetShift()) + ctrl->DispatchKey(K_SHIFT_KEY|(sht * K_KEYUP), 1); + if(opt != GetOption()) + ctrl->DispatchKey(K_OPTION_KEY|(opt * K_KEYUP), 1); + + return true; + } + + static void Flags(NSEvent *e) + { + coco_flags = [e modifierFlags]; + } + static bool MouseEvent(CocoView *view, NSEvent *e, int event, double zd = 0) { sCurrentMouseEvent__ = e; @@ -72,6 +98,7 @@ struct MMImp { Rect r = view->ctrl->GetRect(); Upp::Point p(DPI(np.x), DPI(np.y)); coco_mouse_pos = p + r.TopLeft(); + Flags(e); if(view->ctrl->IsEnabled() && (view->ctrl->HasWndCapture() || r.Contains(coco_mouse_pos))) view->ctrl->DispatchMouse(event, p, 120 * sgn(zd)); sCurrentMouseEvent__ = NULL; @@ -100,11 +127,6 @@ struct MMImp { return b; } - static void Flags(NSEvent *e) - { - coco_flags = [e modifierFlags]; - } - static void Paint(Upp::Ctrl *ctrl, Upp::SystemDraw& w, const Rect& r) { ctrl->fullrefresh = false; @@ -142,27 +164,6 @@ struct MMImp { return true; } - static bool KeyFlags(Upp::Ctrl *ctrl, NSEvent *e) { - bool alt = GetAlt(); - bool ctl = GetCtrl(); - bool sht = GetShift(); - bool opt = GetOption(); - Flags(e); - if(!ctrl->IsEnabled()) - return false; - - if(alt != GetAlt()) - ctrl->DispatchKey(K_ALT_KEY|(alt * K_KEYUP), 1); - if(ctl != GetCtrl()) - ctrl->DispatchKey(K_CTRL_KEY|(ctl * K_KEYUP), 1); - if(sht != GetShift()) - ctrl->DispatchKey(K_SHIFT_KEY|(sht * K_KEYUP), 1); - if(opt != GetOption()) - ctrl->DispatchKey(K_OPTION_KEY|(opt * K_KEYUP), 1); - - return true; - } - static void BecomeKey(Upp::Ctrl *ctrl) { LLOG("Become key " << Upp::Name(ctrl)); @@ -192,9 +193,12 @@ struct MMImp { clip.paste = paste; clip.accepted = false; clip.allowed = DND_MOVE|DND_COPY; // TODO: Use draggingSourceOperationMask + clip.action = info.draggingSourceOperationMask & NSDragOperationMove ? DND_MOVE + : DND_COPY; NSPoint np = [nsview convertPoint:[info draggingLocation] fromView:nil]; - ctrl->DnD(Upp::Point(DPI(np.x), DPI(np.y)) + ctrl->GetScreenView().TopLeft(), clip); - // TODO: Resolve allowed actions + ctrl->DnD(Upp::Point(DPI(np.x), DPI(np.y)) + ctrl->GetScreenRect().TopLeft(), clip); + if(paste && clip.IsAccepted() && clip.GetAction() == DND_COPY) + Ctrl::local_dnd_copy = true; return clip.IsAccepted() ? clip.GetAction() == DND_MOVE ? NSDragOperationMove : NSDragOperationCopy : NSDragOperationNone; @@ -279,6 +283,7 @@ struct MMImp { } - (void)cursorUpdate:(NSEvent *)event { + Upp::MMImp::Flags(event); Upp::MMImp::DoCursorShape(); } @@ -323,17 +328,17 @@ struct MMImp { - (void)draggingEnded:(id )sender { - return Upp::MMImp::DnDLeave(ctrl); + Upp::MMImp::DnDLeave(ctrl); } - (void)draggingExited:(id )sender { - return Upp::MMImp::DnDLeave(ctrl); + Upp::MMImp::DnDLeave(ctrl); } - (BOOL)performDragOperation:(id )sender { - return Upp::MMImp::DnD(ctrl, sender, true); + return Upp::MMImp::DnD(ctrl, sender, true) != NSDragOperationNone; } @end diff --git a/uppsrc/CtrlCore/CtrlClip.cpp b/uppsrc/CtrlCore/CtrlClip.cpp index c79b7a410..7d26d7f3c 100644 --- a/uppsrc/CtrlCore/CtrlClip.cpp +++ b/uppsrc/CtrlCore/CtrlClip.cpp @@ -215,7 +215,7 @@ void Ctrl::DnDRepeat() UPP::KillTimeCallback(&dndpos); } - void Ctrl::DnD(Point p, PasteClip& clip) +void Ctrl::DnD(Point p, PasteClip& clip) { GuiLock __; UPP::KillTimeCallback(&dndpos); diff --git a/uppsrc/CtrlCore/cocotodo.txt b/uppsrc/CtrlCore/cocotodo.txt index 477daeb40..90990edfa 100644 --- a/uppsrc/CtrlCore/cocotodo.txt +++ b/uppsrc/CtrlCore/cocotodo.txt @@ -2,6 +2,7 @@ sooner: - fix modifier keys (read before each event) - Ctrl key gets stuck + - initial focus in uword - icondes - rightclick on image in the list, then move mouse over color ramp - weird focus issue happens