fixed drag drop from Mac server to Windows client

This commit is contained in:
jerry 2013-09-18 14:12:19 +00:00
parent 39734374b1
commit 4e09b06cb0
12 changed files with 101 additions and 28 deletions

View File

@ -822,5 +822,5 @@ CClient::sendFileThread(void* filename)
void void
CClient::draggingInfoSending(UInt32 fileCount, CString& fileList, size_t size) CClient::draggingInfoSending(UInt32 fileCount, CString& fileList, size_t size)
{ {
m_server->draggingInfoSending(fileCount, fileList, size); m_server->draggingInfoSending(fileCount, fileList.c_str(), size);
} }

View File

@ -947,7 +947,8 @@ CServerProxy::fileChunkSending(UInt8 mark, char* data, size_t dataSize)
} }
void void
CServerProxy::draggingInfoSending(UInt32 fileCount, CString fileList, size_t size) CServerProxy::draggingInfoSending(UInt32 fileCount, const char* data, size_t dataSize)
{ {
CProtocolUtil::writef(m_stream, kMsgDDragInfo, fileCount, &fileList); CString info(data, dataSize);
CProtocolUtil::writef(m_stream, kMsgDDragInfo, fileCount, &info);
} }

View File

@ -59,7 +59,7 @@ public:
void fileChunkSending(UInt8 mark, char* data, size_t dataSize); void fileChunkSending(UInt8 mark, char* data, size_t dataSize);
// sending dragging information to server // sending dragging information to server
void draggingInfoSending(UInt32 fileCount, CString fileList, size_t size); void draggingInfoSending(UInt32 fileCount, const char* data, size_t dataSize);
#ifdef TEST_ENV #ifdef TEST_ENV
void handleDataForTest() { handleData(CEvent(), NULL); } void handleDataForTest() { handleData(CEvent(), NULL); }

View File

@ -358,6 +358,11 @@ CMSWindowsScreen::leave()
m_isOnScreen = false; m_isOnScreen = false;
forceShowCursor(); forceShowCursor();
if (m_draggingStarted) {
fakeMouseButton(kButtonLeft, false);
m_draggingStarted = false;
}
return true; return true;
} }

View File

@ -24,6 +24,7 @@
extern "C" { extern "C" {
#endif #endif
void runCocoaApp(); void runCocoaApp();
void stopCocoaLoop();
void fakeDragging(const char* str, int length, int cursorX, int cursorY); void fakeDragging(const char* str, int length, int cursorX, int cursorY);
CFStringRef getCocoaDropTarget(); CFStringRef getCocoaDropTarget();

View File

@ -22,6 +22,7 @@
NSWindow* g_dragWindow = NULL; NSWindow* g_dragWindow = NULL;
COSXDragView* g_dragView = NULL; COSXDragView* g_dragView = NULL;
NSApplication* g_app = NULL;
void void
runCocoaApp() runCocoaApp()
@ -33,7 +34,8 @@ runCocoaApp()
NSApplication* app = [[NSApplication alloc] init]; NSApplication* app = [[NSApplication alloc] init];
g_app = app;
NSWindow* window = [[NSWindow alloc] NSWindow* window = [[NSWindow alloc]
initWithContentRect: NSMakeRect(0, 0, 100, 4) initWithContentRect: NSMakeRect(0, 0, 100, 4)
styleMask: NSBorderlessWindowMask styleMask: NSBorderlessWindowMask
@ -56,6 +58,12 @@ runCocoaApp()
[pool release]; [pool release];
} }
void
stopCocoaLoop()
{
[g_app stop: g_dragWindow];
}
void void
fakeDragging(const char* str, int length, int cursorX, int cursorY) fakeDragging(const char* str, int length, int cursorX, int cursorY)
{ {

View File

@ -37,6 +37,7 @@
#include "CClientApp.h" #include "CClientApp.h"
#include "CServerApp.h" #include "CServerApp.h"
#include "CClient.h" #include "CClient.h"
#include "CServer.h"
#include <math.h> #include <math.h>
@ -101,7 +102,6 @@ COSXScreen::COSXScreen(IEventQueue* events, bool isPrimary, bool autoShowHideCur
m_eventTapRLSR(nullptr), m_eventTapRLSR(nullptr),
m_eventTapPort(nullptr), m_eventTapPort(nullptr),
m_pmRootPort(0), m_pmRootPort(0),
m_draggingStarted(false),
m_fakeDraggingStarted(false), m_fakeDraggingStarted(false),
m_getDropTargetThread(NULL) m_getDropTargetThread(NULL)
{ {
@ -318,6 +318,10 @@ COSXScreen::getJumpZoneSize() const
bool bool
COSXScreen::isAnyMouseButtonDown(UInt32& buttonID) const COSXScreen::isAnyMouseButtonDown(UInt32& buttonID) const
{ {
if (m_buttonState.test(0)) {
buttonID = kButtonLeft;
}
return (GetCurrentButtonState() != 0); return (GetCurrentButtonState() != 0);
} }
@ -908,24 +912,36 @@ COSXScreen::leave()
{ {
hideCursor(); hideCursor();
if (m_draggingStarted && !m_isPrimary) { if (m_draggingStarted) {
// fake ctrl key up
fakeKeyUp(29);
// fake esc key down and up
fakeKeyDown(kKeyEscape, 8192, 1);
fakeKeyUp(1);
CFStringRef dragInfo = getDraggedFileURL(); CFStringRef dragInfo = getDraggedFileURL();
char* dragInfoCStr = CFStringRefToUTF8String(dragInfo); char* dragInfoCStr = CFStringRefToUTF8String(dragInfo);
LOG((CLOG_DEBUG "drag info: %s", dragInfoCStr)); LOG((CLOG_DEBUG "drag info: %s", dragInfoCStr));
CFRelease(dragInfo); CFRelease(dragInfo);
CString fileList(dragInfoCStr); CString fileList(dragInfoCStr);
size_t size = fileList.size(); size_t size = fileList.size();
CClientApp& app = CClientApp::instance();
CClient* client = app.getClientPtr(); // fake esc key down and up
UInt32 fileCount = 1; fakeKeyDown(kKeyEscape, 8192, 1);
client->draggingInfoSending(fileCount, fileList, size); fakeKeyUp(1);
LOG((CLOG_DEBUG "send dragging file to server"));
client->sendFileToServer(dragInfoCStr); fakeMouseButton(kButtonLeft, false);
if (m_isPrimary) {
CServerApp& app = CServerApp::instance();
CServer* server = app.getServerPtr();
LOG((CLOG_DEBUG "send dragging file to client"));
server->sendFileToClient(dragInfoCStr);
}
else {
// fake ctrl key up
fakeKeyUp(29);
CClientApp& app = CClientApp::instance();
CClient* client = app.getClientPtr();
UInt32 fileCount = 1;
client->draggingInfoSending(fileCount, fileList, size);
LOG((CLOG_DEBUG "send dragging file to server"));
client->sendFileToServer(dragInfoCStr);
}
m_draggingStarted = false; m_draggingStarted = false;
} }
@ -1149,6 +1165,9 @@ COSXScreen::onMouseMove(SInt32 mx, SInt32 my)
// motion on primary screen // motion on primary screen
sendEvent(m_events->forIPrimaryScreen().motionOnPrimary(), sendEvent(m_events->forIPrimaryScreen().motionOnPrimary(),
CMotionInfo::alloc(m_xCursor, m_yCursor)); CMotionInfo::alloc(m_xCursor, m_yCursor));
if (m_buttonState.test(0)) {
m_draggingStarted = true;
}
} }
else { else {
// motion on secondary screen. warp mouse back to // motion on secondary screen. warp mouse back to
@ -1212,6 +1231,18 @@ COSXScreen::onMouseButton(bool pressed, UInt16 macButton)
} }
} }
} }
if (macButton == kButtonLeft) {
MouseButtonState state = pressed ? kMouseButtonDown : kMouseButtonUp;
m_buttonState.set(kButtonLeft - 1, state);
if (pressed) {
m_draggingFileDir.clear();
LOG((CLOG_DEBUG2 "dragging file directory is cleared"));
}
else {
m_draggingStarted = false;
}
}
return true; return true;
} }
@ -1951,13 +1982,7 @@ COSXScreen::handleCGInputEvent(CGEventTapProxy proxy,
case kCGEventOtherMouseUp: case kCGEventOtherMouseUp:
screen->onMouseButton(false, CGEventGetIntegerValueField(event, kCGMouseEventButtonNumber) + 1); screen->onMouseButton(false, CGEventGetIntegerValueField(event, kCGMouseEventButtonNumber) + 1);
break; break;
case kCGEventLeftMouseDragged: { case kCGEventLeftMouseDragged:
CFStringRef dragInfo = getDraggedFileURL();
char* info = CFStringRefToUTF8String(dragInfo);
LOG((CLOG_DEBUG "drag info: %s", info));
CFRelease(dragInfo);
break;
}
case kCGEventRightMouseDragged: case kCGEventRightMouseDragged:
case kCGEventOtherMouseDragged: case kCGEventOtherMouseDragged:
case kCGEventMouseMoved: case kCGEventMouseMoved:
@ -2075,3 +2100,17 @@ COSXScreen::fakeDraggingFiles(CString str)
{ {
m_fakeDraggingStarted = true; m_fakeDraggingStarted = true;
} }
CString&
COSXScreen::getDraggingFileDir()
{
if (m_draggingStarted) {
CFStringRef dragInfo = getDraggedFileURL();
char* info = CFStringRefToUTF8String(dragInfo);
LOG((CLOG_DEBUG "drag info: %s", info));
CFRelease(dragInfo);
CString fileList(info);
m_draggingFileDir = fileList;
}
return m_draggingFileDir;
}

View File

@ -98,6 +98,7 @@ public:
virtual void setSequenceNumber(UInt32); virtual void setSequenceNumber(UInt32);
virtual bool isPrimary() const; virtual bool isPrimary() const;
virtual void fakeDraggingFiles(CString str); virtual void fakeDraggingFiles(CString str);
virtual CString& getDraggingFileDir();
const CString& getDropTarget() const { return m_dropTarget; } const CString& getDropTarget() const { return m_dropTarget; }
@ -344,7 +345,6 @@ private:
IEventQueue* m_events; IEventQueue* m_events;
bool m_draggingStarted;
bool m_fakeDraggingStarted; bool m_fakeDraggingStarted;
CThread* m_getDropTargetThread; CThread* m_getDropTargetThread;
CString m_dropTarget; CString m_dropTarget;

View File

@ -1752,7 +1752,7 @@ CServer::onMouseMovePrimary(SInt32 x, SInt32 y)
LOG((CLOG_DEBUG3 "dragging file list: %s", fileList)); LOG((CLOG_DEBUG3 "dragging file list: %s", fileList));
LOG((CLOG_DEBUG3 "dragging file list string size: %i", size)); LOG((CLOG_DEBUG3 "dragging file list string size: %i", size));
newScreen->draggingInfoSending(fileCount, fileList, size); newScreen->draggingInfoSending(fileCount, fileList, size);
m_screen->setDraggingStarted(false); //m_screen->setDraggingStarted(false);
} }
// switch screen // switch screen
@ -2307,3 +2307,9 @@ CServer::dragInfoReceived(UInt32 fileNum, CString content)
LOG((CLOG_DEBUG2 "dragging file %i name: %s", i + 1, m_dragFileList.at(i).c_str())); LOG((CLOG_DEBUG2 "dragging file %i name: %s", i + 1, m_dragFileList.at(i).c_str()));
} }
} }
void
CServer::draggingInfoSending(UInt32 fileCount, CString& fileList, size_t size)
{
m_active->draggingInfoSending(fileCount, fileList.c_str(), size);
}

View File

@ -158,6 +158,9 @@ public:
//! Received dragging information from client //! Received dragging information from client
void dragInfoReceived(UInt32 fileNum, CString content); void dragInfoReceived(UInt32 fileNum, CString content);
//! Send dragging file information to client
void draggingInfoSending(UInt32 fileCount, CString& fileList, size_t size);
//@} //@}
//! @name accessors //! @name accessors
//@{ //@{

View File

@ -45,6 +45,10 @@
#include <ApplicationServices/ApplicationServices.h> #include <ApplicationServices/ApplicationServices.h>
#endif #endif
#if defined(__APPLE__)
#include "COSXDragSimulator.h"
#endif
CApp* CApp::s_instance = nullptr; CApp* CApp::s_instance = nullptr;
CApp::CApp(IEventQueue* events, CreateTaskBarReceiverFunc createTaskBarReceiver, CArgsBase* args) : CApp::CApp(IEventQueue* events, CreateTaskBarReceiverFunc createTaskBarReceiver, CArgsBase* args) :
@ -393,4 +397,10 @@ CApp::runEventsLoop(void*)
{ {
m_events->cacheCurrentEventQueueRef(); m_events->cacheCurrentEventQueueRef();
m_events->loop(); m_events->loop();
#if defined(MAC_OS_X_VERSION_10_7)
stopCocoaLoop();
#endif
} }

View File

@ -376,7 +376,7 @@ CScreen::isLockedToScreen() const
LOG((CLOG_DEBUG "locked by mouse buttonID: %d", buttonID)); LOG((CLOG_DEBUG "locked by mouse buttonID: %d", buttonID));
if (buttonID == kButtonLeft) { if (buttonID == kButtonLeft) {
// TODO: fake esc key down and up // TODO: fake esc key down and up
m_screen->fakeMouseButton(buttonID, false); //m_screen->fakeMouseButton(buttonID, false);
} }
return (buttonID == kButtonLeft) ? false : true; return (buttonID == kButtonLeft) ? false : true;