Task #3951 - Clear filename stored in synwinxt on mouse up

- renamed some functions for file drag/drop to be more similar to existing
- improved log messages for the library loader
- removed hack that blocked .exe and .lnk files (annoying for developers)
- removed hack that always clears dragging filename (not very robust)
This commit is contained in:
Nick Bolton 2014-03-17 13:10:29 +00:00
parent ae327055c2
commit 407378fbc5
15 changed files with 95 additions and 79 deletions

View File

@ -742,7 +742,7 @@ CClient::writeToDropDirThread(void*)
{ {
LOG((CLOG_DEBUG "starting write to drop dir thread")); LOG((CLOG_DEBUG "starting write to drop dir thread"));
while (m_screen->getFakeDraggingStarted()) { while (m_screen->isFakeDraggingStarted()) {
ARCH->sleep(.1f); ARCH->sleep(.1f);
} }

View File

@ -27,7 +27,8 @@ CMSWindowsHookLibraryLoader::CMSWindowsHookLibraryLoader() :
m_setSides(NULL), m_setSides(NULL),
m_setZone(NULL), m_setZone(NULL),
m_setMode(NULL), m_setMode(NULL),
m_getDraggingFilename(NULL) m_getDraggingFilename(NULL),
m_clearDraggingFilename(NULL)
{ {
} }
@ -52,12 +53,13 @@ CMSWindowsHookLibraryLoader::openHookLibrary(const char* name)
m_setMode = (SetModeFunc)GetProcAddress(hookLibrary, "setMode"); m_setMode = (SetModeFunc)GetProcAddress(hookLibrary, "setMode");
m_init = (InitFunc)GetProcAddress(hookLibrary, "init"); m_init = (InitFunc)GetProcAddress(hookLibrary, "init");
m_cleanup = (CleanupFunc)GetProcAddress(hookLibrary, "cleanup"); m_cleanup = (CleanupFunc)GetProcAddress(hookLibrary, "cleanup");
if (m_setSides == NULL || if (m_setSides == NULL ||
m_setZone == NULL || m_setZone == NULL ||
m_setMode == NULL || m_setMode == NULL ||
m_init == NULL || m_init == NULL ||
m_cleanup == NULL) { m_cleanup == NULL) {
LOG((CLOG_ERR "invalid hook library, use a newer %s.dll", name)); LOG((CLOG_ERR "failed to load hook function, %s.dll could be out of date", name));
throw XScreenOpenFailure(); throw XScreenOpenFailure();
} }
@ -80,22 +82,24 @@ CMSWindowsHookLibraryLoader::openShellLibrary(const char* name)
GetVersionEx(&osvi); GetVersionEx(&osvi);
if (osvi.dwMajorVersion < 6) { if (osvi.dwMajorVersion < 6) {
LOG((CLOG_INFO "skipping shell library load, %s.dll not supported before vista", name)); LOG((CLOG_INFO "skipping shell extension library load, %s.dll not supported before vista", name));
return NULL; return NULL;
} }
// load the hook library // load the hook library
HINSTANCE shellLibrary = LoadLibrary(name); HINSTANCE shellLibrary = LoadLibrary(name);
if (shellLibrary == NULL) { if (shellLibrary == NULL) {
LOG((CLOG_ERR "failed to load shell library, %s.dll is missing or invalid", name)); LOG((CLOG_ERR "failed to load shell extension library, %s.dll is missing or invalid", name));
throw XScreenOpenFailure(); throw XScreenOpenFailure();
} }
// look up functions // look up functions
m_getDraggingFilename = (GetDraggingFilename)GetProcAddress(shellLibrary, "getDraggingFilename"); m_getDraggingFilename = (GetDraggingFilenameFunc)GetProcAddress(shellLibrary, "getDraggingFilename");
m_clearDraggingFilename = (ClearDraggingFilenameFunc)GetProcAddress(shellLibrary, "clearDraggingFilename");
if (m_getDraggingFilename == NULL) { if (m_getDraggingFilename == NULL ||
LOG((CLOG_ERR "invalid shell library, use a newer %s.dll", name)); m_clearDraggingFilename == NULL) {
LOG((CLOG_ERR "failed to load shell extension function, %s.dll could be out of date", name));
throw XScreenOpenFailure(); throw XScreenOpenFailure();
} }

View File

@ -41,5 +41,8 @@ public:
SetZoneFunc m_setZone; SetZoneFunc m_setZone;
SetModeFunc m_setMode; SetModeFunc m_setMode;
GetDraggingFilename m_getDraggingFilename; GetDraggingFilenameFunc
m_getDraggingFilename;
ClearDraggingFilenameFunc
m_clearDraggingFilename;
}; };

View File

@ -369,7 +369,7 @@ CMSWindowsScreen::leave()
m_isOnScreen = false; m_isOnScreen = false;
forceShowCursor(); forceShowCursor();
if (getDraggingStarted()) { if (isDraggingStarted()) {
CString& draggingFilename = getDraggingFilename(); CString& draggingFilename = getDraggingFilename();
size_t size = draggingFilename.size(); size_t size = draggingFilename.size();
@ -1907,16 +1907,21 @@ CString&
CMSWindowsScreen::getDraggingFilename() CMSWindowsScreen::getDraggingFilename()
{ {
if (m_draggingStarted) { if (m_draggingStarted) {
// temporarily log out dragging filename char filename[MAX_PATH];
char dir[MAX_PATH]; m_hookLibraryLoader.m_getDraggingFilename(filename);
m_hookLibraryLoader.m_getDraggingFilename(dir); m_draggingFilename = filename;
m_draggingFilename.clear();
m_draggingFilename.append(dir);
} }
return m_draggingFilename; return m_draggingFilename;
} }
void
CMSWindowsScreen::clearDraggingFilename()
{
LOG((CLOG_DEBUG "clearing stored dragging file name"));
m_hookLibraryLoader.m_clearDraggingFilename();
}
const CString& const CString&
CMSWindowsScreen::getDropTarget() const CMSWindowsScreen::getDropTarget() const
{ {

View File

@ -116,6 +116,7 @@ public:
virtual bool isPrimary() const; virtual bool isPrimary() const;
virtual void fakeDraggingFiles(CString str); virtual void fakeDraggingFiles(CString str);
virtual CString& getDraggingFilename(); virtual CString& getDraggingFilename();
virtual void clearDraggingFilename();
virtual const CString& virtual const CString&
getDropTarget() const; getDropTarget() const;

View File

@ -904,7 +904,7 @@ COSXScreen::leave()
{ {
hideCursor(); hideCursor();
if (getDraggingStarted()) { if (isDraggingStarted()) {
CString& fileList = getDraggingFilename(); CString& fileList = getDraggingFilename();
size_t size = fileList.size(); size_t size = fileList.size();

View File

@ -1674,13 +1674,17 @@ CServer::onMouseUp(ButtonID id)
return; return;
} }
if (m_enableDragDrop && !m_screen->isOnScreen()) { if (m_enableDragDrop) {
if (!m_screen->isOnScreen()) {
CString& file = m_screen->getDraggingFilename(); CString& file = m_screen->getDraggingFilename();
if (!file.empty()) { if (!file.empty()) {
LOG((CLOG_DEBUG "send file to client: %s", file.c_str()));
sendFileToClient(file.c_str()); sendFileToClient(file.c_str());
} }
} }
// always clear dragging filename
m_screen->clearDraggingFilename();
}
} }
bool bool
@ -1755,7 +1759,7 @@ CServer::onMouseMovePrimary(SInt32 x, SInt32 y)
// should we switch or not? // should we switch or not?
if (isSwitchOkay(newScreen, dir, x, y, xc, yc)) { if (isSwitchOkay(newScreen, dir, x, y, xc, yc)) {
if (m_enableDragDrop && m_screen->getDraggingStarted() && m_active != newScreen) { if (m_enableDragDrop && m_screen->isDraggingStarted() && m_active != newScreen) {
CString& dragFileList = m_screen->getDraggingFilename(); CString& dragFileList = m_screen->getDraggingFilename();
size_t size = dragFileList.size() + 1; size_t size = dragFileList.size() + 1;
char* fileList = NULL; char* fileList = NULL;
@ -1996,7 +2000,7 @@ CServer::writeToDropDirThread(void*)
{ {
LOG((CLOG_DEBUG "starting write to drop dir thread")); LOG((CLOG_DEBUG "starting write to drop dir thread"));
while (m_screen->getFakeDraggingStarted()) { while (m_screen->isFakeDraggingStarted()) {
ARCH->sleep(.1f); ARCH->sleep(.1f);
} }
@ -2331,14 +2335,15 @@ CServer::sendFileToClient(const char* filename)
} }
void void
CServer::sendFileThread(void* filename) CServer::sendFileThread(void* data)
{ {
try { try {
char* name = reinterpret_cast<char*>(filename); char* filename = reinterpret_cast<char*>(data);
CFileChunker::sendFileChunks(name, m_events, this); LOG((CLOG_DEBUG "sending file to client, filename=%s", filename));
CFileChunker::sendFileChunks(filename, m_events, this);
} }
catch (std::runtime_error error) { catch (std::runtime_error error) {
LOG((CLOG_ERR "failed sending file chunks: %s", error.what())); LOG((CLOG_ERR "failed sending file chunks, error: %s", error.what()));
} }
m_sendFileThread = NULL; m_sendFileThread = NULL;

View File

@ -188,8 +188,9 @@ public:
virtual void pollPressedKeys(KeyButtonSet& pressedKeys) const = 0; virtual void pollPressedKeys(KeyButtonSet& pressedKeys) const = 0;
virtual CString& getDraggingFilename() = 0; virtual CString& getDraggingFilename() = 0;
virtual bool getDraggingStarted() = 0; virtual void clearDraggingFilename() = 0;
virtual bool getFakeDraggingStarted() = 0; virtual bool isDraggingStarted() = 0;
virtual bool isFakeDraggingStarted() = 0;
virtual void fakeDraggingFiles(CString str) = 0; virtual void fakeDraggingFiles(CString str) = 0;
virtual const CString& virtual const CString&

View File

@ -114,7 +114,7 @@ CPlatformScreen::pollPressedKeys(KeyButtonSet& pressedKeys) const
} }
bool bool
CPlatformScreen::getDraggingStarted() CPlatformScreen::isDraggingStarted()
{ {
if (CApp::instance().argsBase().m_enableDragDrop) { if (CApp::instance().argsBase().m_enableDragDrop) {
return m_draggingStarted; return m_draggingStarted;

View File

@ -77,9 +77,10 @@ public:
virtual void pollPressedKeys(KeyButtonSet& pressedKeys) const; virtual void pollPressedKeys(KeyButtonSet& pressedKeys) const;
virtual void setDraggingStarted(bool started) { m_draggingStarted = started; } virtual void setDraggingStarted(bool started) { m_draggingStarted = started; }
virtual bool getDraggingStarted(); virtual bool isDraggingStarted();
virtual bool getFakeDraggingStarted() { return m_fakeDraggingStarted; } virtual bool isFakeDraggingStarted() { return m_fakeDraggingStarted; }
virtual CString& getDraggingFilename() { return m_draggingFilename; } virtual CString& getDraggingFilename() { return m_draggingFilename; }
virtual void clearDraggingFilename() { }
// IPlatformScreen overrides // IPlatformScreen overrides
virtual void enable() = 0; virtual void enable() = 0;

View File

@ -417,15 +417,15 @@ CScreen::pollActiveModifiers() const
} }
bool bool
CScreen::getDraggingStarted() const CScreen::isDraggingStarted() const
{ {
return m_screen->getDraggingStarted(); return m_screen->isDraggingStarted();
} }
bool bool
CScreen::getFakeDraggingStarted() const CScreen::isFakeDraggingStarted() const
{ {
return m_screen->getFakeDraggingStarted(); return m_screen->isFakeDraggingStarted();
} }
void void
@ -452,6 +452,12 @@ CScreen::getDraggingFilename() const
return m_screen->getDraggingFilename(); return m_screen->getDraggingFilename();
} }
void
CScreen::clearDraggingFilename()
{
m_screen->clearDraggingFilename();
}
const CString& const CString&
CScreen::getDropTarget() const CScreen::getDropTarget() const
{ {

View File

@ -273,20 +273,19 @@ public:
*/ */
KeyModifierMask pollActiveModifiers() const; KeyModifierMask pollActiveModifiers() const;
//! Check if a local dragging has started. //! Test if file is dragged on primary screen
bool isDraggingStarted() const;
bool getDraggingStarted() const; //! Test if file is dragged on secondary screen
bool isFakeDraggingStarted() const;
//! Check if a fake dragging has started.
bool getFakeDraggingStarted() const;
//! Get dragging file's directory.
//! Get the filename of the file being dragged
CString& getDraggingFilename() const; CString& getDraggingFilename() const;
//! Get drop target directory. //! Clear the filename of the file that was dragged
void clearDraggingFilename();
//! Get the drop target directory
const CString& getDropTarget() const; const CString& getDropTarget() const;
//@} //@}

View File

@ -309,24 +309,17 @@ getFileExt(const char* filenameCStr)
void void
setDraggingFilename(const char* filename) setDraggingFilename(const char* filename)
{ {
log("> setDraggingFilename, filename=%s", filename); log("> setDraggingFilename, filename='%s'", filename);
// HACK: only handle files that are not .exe or .lnk
// dragging anything, including a selection marquee, from a program
// (e.g. explorer.exe) will cause this function to be called with the
// path of that program. currently we don't know how to test for this
// situation, so just ignore exe and lnk files.
std::string ext = getFileExt(filename);
if ((ext != "exe") && (ext != "lnk")) {
memcpy(g_draggingFilename, filename, MAX_PATH); memcpy(g_draggingFilename, filename, MAX_PATH);
} log("< setDraggingFilename, g_draggingFilename='%s'", g_draggingFilename);
else {
log(
"ignoring filename=%s, ext=%s",
filename, ext.c_str());
} }
log("< setDraggingFilename, g_draggingFilename=%s", g_draggingFilename); void
clearDraggingFilename()
{
log("> clearDraggingFilename");
g_draggingFilename[0] = NULL;
log("< clearDraggingFilename, g_draggingFilename='%s'", g_draggingFilename);
} }
void void
@ -334,10 +327,5 @@ getDraggingFilename(char* filename)
{ {
log("> getDraggingFilename"); log("> getDraggingFilename");
memcpy(filename, g_draggingFilename, MAX_PATH); memcpy(filename, g_draggingFilename, MAX_PATH);
log("< getDraggingFilename, filename='%s'", filename);
// mark string as empty once used, so we can't accidentally copy
// the same file more than once unless the user does this on purpose.
g_draggingFilename[0] = NULL;
log("< getDraggingFilename, filename=%s", filename);
} }

View File

@ -5,3 +5,4 @@ EXPORTS
DllRegisterServer PRIVATE DllRegisterServer PRIVATE
DllUnregisterServer PRIVATE DllUnregisterServer PRIVATE
getDraggingFilename getDraggingFilename
clearDraggingFilename

View File

@ -25,6 +25,8 @@
#define CSYNERGYSHELLEXE_API __declspec(dllimport) #define CSYNERGYSHELLEXE_API __declspec(dllimport)
#endif #endif
typedef void (*GetDraggingFilename)(CHAR*); typedef void (*GetDraggingFilenameFunc)(char*);
typedef void (*ClearDraggingFilenameFunc)();
CSYNERGYSHELLEXE_API void getDraggingFilename(char*); CSYNERGYSHELLEXE_API void getDraggingFilename(char* filename);
CSYNERGYSHELLEXE_API void clearDraggingFilename();