used a hidden drop window to get drag filename
This commit is contained in:
parent
7b8cdb6b38
commit
b85a9b628e
|
@ -0,0 +1,178 @@
|
|||
/*
|
||||
* synergy -- mouse and keyboard sharing utility
|
||||
* Copyright (C) 2014 Bolton Software Ltd.
|
||||
*
|
||||
* This package is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* found in the file COPYING that should have accompanied this file.
|
||||
*
|
||||
* This package is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "platform/MSWindowsDropTarget.h"
|
||||
|
||||
#include "base/Log.h"
|
||||
#include "common/common.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <Shlobj.h>
|
||||
|
||||
void getDropData(IDataObject *pDataObject);
|
||||
|
||||
CMSWindowsDropTarget* CMSWindowsDropTarget::s_instance = NULL;
|
||||
|
||||
CMSWindowsDropTarget::CMSWindowsDropTarget() :
|
||||
m_refCount(1),
|
||||
m_allowDrop(false)
|
||||
{
|
||||
s_instance = this;
|
||||
}
|
||||
|
||||
CMSWindowsDropTarget::~CMSWindowsDropTarget()
|
||||
{
|
||||
}
|
||||
|
||||
CMSWindowsDropTarget&
|
||||
CMSWindowsDropTarget::instance()
|
||||
{
|
||||
assert(s_instance != NULL);
|
||||
return *s_instance;
|
||||
}
|
||||
|
||||
HRESULT
|
||||
CMSWindowsDropTarget::DragEnter(IDataObject* dataObject, DWORD keyState, POINTL point, DWORD* effect)
|
||||
{
|
||||
// check if data object contain drop
|
||||
m_allowDrop = queryDataObject(dataObject);
|
||||
if (m_allowDrop) {
|
||||
getDropData(dataObject);
|
||||
}
|
||||
|
||||
*effect = DROPEFFECT_NONE;
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
HRESULT
|
||||
CMSWindowsDropTarget::DragOver(DWORD keyState, POINTL point, DWORD* effect)
|
||||
{
|
||||
*effect = DROPEFFECT_NONE;
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
HRESULT
|
||||
CMSWindowsDropTarget::DragLeave(void)
|
||||
{
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
HRESULT
|
||||
CMSWindowsDropTarget::Drop(IDataObject* dataObject, DWORD keyState, POINTL point, DWORD* effect)
|
||||
{
|
||||
*effect = DROPEFFECT_NONE;
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
bool
|
||||
CMSWindowsDropTarget::queryDataObject(IDataObject* dataObject)
|
||||
{
|
||||
// check if it supports CF_HDROP using a HGLOBAL
|
||||
FORMATETC fmtetc = { CF_HDROP, 0, DVASPECT_CONTENT, -1, TYMED_HGLOBAL };
|
||||
|
||||
return dataObject->QueryGetData(&fmtetc) == S_OK ? true : false;
|
||||
}
|
||||
|
||||
void
|
||||
CMSWindowsDropTarget::setDraggingFilename(char* const filename)
|
||||
{
|
||||
m_dragFilename = filename;
|
||||
}
|
||||
|
||||
std::string
|
||||
CMSWindowsDropTarget::getDraggingFilename()
|
||||
{
|
||||
return m_dragFilename;
|
||||
}
|
||||
|
||||
void
|
||||
CMSWindowsDropTarget::clearDraggingFilename()
|
||||
{
|
||||
m_dragFilename.clear();
|
||||
}
|
||||
|
||||
void
|
||||
getDropData(IDataObject* dataObject)
|
||||
{
|
||||
// construct a FORMATETC object
|
||||
FORMATETC fmtEtc = { CF_HDROP, 0, DVASPECT_CONTENT, -1, TYMED_HGLOBAL };
|
||||
STGMEDIUM stgMed;
|
||||
|
||||
// See if the dataobject contains any DROP stored as a HGLOBAL
|
||||
if(dataObject->QueryGetData(&fmtEtc) == S_OK) {
|
||||
if(dataObject->GetData(&fmtEtc, &stgMed) == S_OK) {
|
||||
// get data here
|
||||
PVOID data = GlobalLock(stgMed.hGlobal);
|
||||
|
||||
// data object global handler contains:
|
||||
// DROPFILESfilename1 filename2 two spaces as the end
|
||||
// TODO: get multiple filenames
|
||||
wchar_t* wcData = (wchar_t*)((LPBYTE)data + sizeof(DROPFILES));
|
||||
|
||||
// convert wchar to char
|
||||
char* filename = new char[wcslen(wcData) + 1];
|
||||
filename[wcslen(wcData)] = '\0';
|
||||
wcstombs(filename, wcData, wcslen(wcData));
|
||||
|
||||
CMSWindowsDropTarget::instance().setDraggingFilename(filename);
|
||||
|
||||
GlobalUnlock(stgMed.hGlobal);
|
||||
|
||||
// release the data using the COM API
|
||||
ReleaseStgMedium(&stgMed);
|
||||
|
||||
delete[] filename;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
HRESULT __stdcall
|
||||
CMSWindowsDropTarget::QueryInterface (REFIID iid, void ** object)
|
||||
{
|
||||
if (iid == IID_IDropTarget || iid == IID_IUnknown) {
|
||||
AddRef();
|
||||
*object = this;
|
||||
return S_OK;
|
||||
}
|
||||
else {
|
||||
*object = 0;
|
||||
return E_NOINTERFACE;
|
||||
}
|
||||
}
|
||||
|
||||
ULONG __stdcall
|
||||
CMSWindowsDropTarget::AddRef(void)
|
||||
{
|
||||
return InterlockedIncrement(&m_refCount);
|
||||
}
|
||||
|
||||
ULONG __stdcall
|
||||
CMSWindowsDropTarget::Release(void)
|
||||
{
|
||||
LONG count = InterlockedDecrement(&m_refCount);
|
||||
|
||||
if (count == 0) {
|
||||
delete this;
|
||||
return 0;
|
||||
}
|
||||
else {
|
||||
return count;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,59 @@
|
|||
/*
|
||||
* synergy -- mouse and keyboard sharing utility
|
||||
* Copyright (C) 2014 Bolton Software Ltd.
|
||||
*
|
||||
* This package is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* found in the file COPYING that should have accompanied this file.
|
||||
*
|
||||
* This package is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#include <Windows.h>
|
||||
#include <oleidl.h>
|
||||
|
||||
class CMSWindowsScreen;
|
||||
|
||||
class CMSWindowsDropTarget : public IDropTarget {
|
||||
public:
|
||||
CMSWindowsDropTarget();
|
||||
~CMSWindowsDropTarget();
|
||||
|
||||
// IUnknown implementation
|
||||
HRESULT __stdcall QueryInterface(REFIID iid, void** object);
|
||||
ULONG __stdcall AddRef(void);
|
||||
ULONG __stdcall Release(void);
|
||||
|
||||
// IDropTarget implementation
|
||||
HRESULT __stdcall DragEnter(IDataObject* dataObject, DWORD keyState, POINTL point, DWORD* effect);
|
||||
HRESULT __stdcall DragOver(DWORD keyState, POINTL point, DWORD* effect);
|
||||
HRESULT __stdcall DragLeave(void);
|
||||
HRESULT __stdcall Drop(IDataObject* dataObject, DWORD keyState, POINTL point, DWORD* effect);
|
||||
|
||||
void setDraggingFilename(char* const);
|
||||
std::string getDraggingFilename();
|
||||
void clearDraggingFilename();
|
||||
|
||||
static CMSWindowsDropTarget&
|
||||
instance();
|
||||
|
||||
private:
|
||||
bool queryDataObject(IDataObject* dataObject);
|
||||
|
||||
long m_refCount;
|
||||
bool m_allowDrop;
|
||||
std::string m_dragFilename;
|
||||
|
||||
static CMSWindowsDropTarget*
|
||||
s_instance;
|
||||
};
|
|
@ -18,6 +18,7 @@
|
|||
|
||||
#include "platform/MSWindowsScreen.h"
|
||||
|
||||
#include "platform/MSWindowsDropTarget.h"
|
||||
#include "client/Client.h"
|
||||
#include "platform/MSWindowsClipboard.h"
|
||||
#include "platform/MSWindowsDesks.h"
|
||||
|
@ -118,7 +119,9 @@ CMSWindowsScreen::CMSWindowsScreen(
|
|||
m_keyState(NULL),
|
||||
m_hasMouse(GetSystemMetrics(SM_MOUSEPRESENT) != 0),
|
||||
m_showingMouse(false),
|
||||
m_events(events)
|
||||
m_events(events),
|
||||
m_dropWindow(NULL),
|
||||
m_dropWindowSize(20)
|
||||
{
|
||||
assert(s_windowInstance != NULL);
|
||||
assert(s_screen == NULL);
|
||||
|
@ -157,6 +160,11 @@ CMSWindowsScreen::CMSWindowsScreen(
|
|||
else {
|
||||
LOG((CLOG_ERR "failed to get desktop path, no drop target available, error=%d", GetLastError()));
|
||||
}
|
||||
|
||||
OleInitialize(0);
|
||||
m_dropWindow = createDropWindow(m_class, "DropWindow");
|
||||
m_dropTarget = new CMSWindowsDropTarget();
|
||||
RegisterDragDrop(m_dropWindow, m_dropTarget);
|
||||
}
|
||||
catch (...) {
|
||||
delete m_keyState;
|
||||
|
@ -190,6 +198,11 @@ CMSWindowsScreen::~CMSWindowsScreen()
|
|||
destroyWindow(m_window);
|
||||
destroyClass(m_class);
|
||||
|
||||
RevokeDragDrop(m_dropWindow);
|
||||
m_dropTarget->Release();
|
||||
OleUninitialize();
|
||||
destroyWindow(m_dropWindow);
|
||||
|
||||
s_screen = NULL;
|
||||
}
|
||||
|
||||
|
@ -345,32 +358,33 @@ CMSWindowsScreen::leave()
|
|||
m_isOnScreen = false;
|
||||
forceShowCursor();
|
||||
|
||||
if (isDraggingStarted()) {
|
||||
CString& draggingFilename = getDraggingFilename();
|
||||
size_t size = draggingFilename.size();
|
||||
if (isDraggingStarted() && !m_isPrimary) {
|
||||
m_sendDragThread = new CThread(
|
||||
new TMethodJob<CMSWindowsScreen>(
|
||||
this,
|
||||
&CMSWindowsScreen::sendDragThread));
|
||||
}
|
||||
|
||||
if (!m_isPrimary) {
|
||||
// TODO: fake these keys properly
|
||||
fakeKeyDown(kKeyEscape, 8192, 1);
|
||||
fakeKeyUp(1);
|
||||
return true;
|
||||
}
|
||||
|
||||
fakeMouseButton(kButtonLeft, false);
|
||||
void
|
||||
CMSWindowsScreen::sendDragThread(void*)
|
||||
{
|
||||
CString& draggingFilename = getDraggingFilename();
|
||||
size_t size = draggingFilename.size();
|
||||
|
||||
if (draggingFilename.empty() == false) {
|
||||
CClientApp& app = CClientApp::instance();
|
||||
CClient* client = app.getClientPtr();
|
||||
UInt32 fileCount = 1;
|
||||
LOG((CLOG_DEBUG "send dragging info to server: %s", draggingFilename.c_str()));
|
||||
client->draggingInfoSending(fileCount, draggingFilename, size);
|
||||
LOG((CLOG_DEBUG "send dragging file to server"));
|
||||
client->sendFileToServer(draggingFilename.c_str());
|
||||
}
|
||||
}
|
||||
|
||||
m_draggingStarted = false;
|
||||
if (draggingFilename.empty() == false) {
|
||||
CClientApp& app = CClientApp::instance();
|
||||
CClient* client = app.getClientPtr();
|
||||
UInt32 fileCount = 1;
|
||||
LOG((CLOG_DEBUG "send dragging info to server: %s", draggingFilename.c_str()));
|
||||
client->draggingInfoSending(fileCount, draggingFilename, size);
|
||||
LOG((CLOG_DEBUG "send dragging file to server"));
|
||||
client->sendFileToServer(draggingFilename.c_str());
|
||||
}
|
||||
|
||||
return true;
|
||||
m_draggingStarted = false;
|
||||
}
|
||||
|
||||
bool
|
||||
|
@ -858,6 +872,29 @@ CMSWindowsScreen::createWindow(ATOM windowClass, const char* name) const
|
|||
return window;
|
||||
}
|
||||
|
||||
HWND
|
||||
CMSWindowsScreen::createDropWindow(ATOM windowClass, const char* name) const
|
||||
{
|
||||
HWND window = CreateWindowEx(
|
||||
WS_EX_TOPMOST |
|
||||
WS_EX_TRANSPARENT |
|
||||
WS_EX_ACCEPTFILES,
|
||||
reinterpret_cast<LPCTSTR>(m_class),
|
||||
name,
|
||||
WS_POPUP,
|
||||
0, 0, m_dropWindowSize, m_dropWindowSize,
|
||||
NULL, NULL,
|
||||
s_windowInstance,
|
||||
NULL);
|
||||
|
||||
if (window == NULL) {
|
||||
LOG((CLOG_ERR "failed to create drop window: %d", GetLastError()));
|
||||
throw XScreenOpenFailure();
|
||||
}
|
||||
|
||||
return window;
|
||||
}
|
||||
|
||||
void
|
||||
CMSWindowsScreen::destroyWindow(HWND hwnd) const
|
||||
{
|
||||
|
@ -1801,9 +1838,48 @@ CString&
|
|||
CMSWindowsScreen::getDraggingFilename()
|
||||
{
|
||||
if (m_draggingStarted) {
|
||||
char filename[MAX_PATH];
|
||||
m_shellEx.getDraggingFilename(filename);
|
||||
m_draggingFilename = filename;
|
||||
m_dropTarget->clearDraggingFilename();
|
||||
m_draggingFilename.clear();
|
||||
|
||||
int halfSize = m_dropWindowSize / 2;
|
||||
|
||||
SInt32 xPos = m_isPrimary ? m_xCursor : m_xCenter;
|
||||
SInt32 yPos = m_isPrimary ? m_yCursor : m_yCenter;
|
||||
xPos = (xPos - halfSize) < 0 ? 0 : xPos - halfSize;
|
||||
yPos = (yPos - halfSize) < 0 ? 0 : yPos - halfSize;
|
||||
SetWindowPos(
|
||||
m_dropWindow,
|
||||
HWND_TOPMOST,
|
||||
xPos,
|
||||
yPos,
|
||||
m_dropWindowSize,
|
||||
m_dropWindowSize,
|
||||
SWP_SHOWWINDOW);
|
||||
|
||||
// TODO: fake these keys properly
|
||||
fakeKeyDown(kKeyEscape, 8192, 1);
|
||||
fakeKeyUp(1);
|
||||
fakeMouseButton(kButtonLeft, false);
|
||||
|
||||
CString filename;
|
||||
DOUBLE timeout = ARCH->time() + .5f;
|
||||
while (ARCH->time() < timeout) {
|
||||
ARCH->sleep(.05f);
|
||||
filename = m_dropTarget->getDraggingFilename();
|
||||
if (!filename.empty()) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
ShowWindow(m_dropWindow, SW_HIDE);
|
||||
|
||||
if (!filename.empty()) {
|
||||
m_draggingFilename = filename;
|
||||
}
|
||||
|
||||
if (m_draggingFilename.empty()) {
|
||||
LOG((CLOG_DEBUG "failed to get drag file name from OLE"));
|
||||
}
|
||||
}
|
||||
|
||||
return m_draggingFilename;
|
||||
|
|
|
@ -34,6 +34,7 @@ class CMSWindowsDesks;
|
|||
class CMSWindowsKeyState;
|
||||
class CMSWindowsScreenSaver;
|
||||
class CThread;
|
||||
class CMSWindowsDropTarget;
|
||||
|
||||
//! Implementation of IPlatformScreen for Microsoft Windows
|
||||
class CMSWindowsScreen : public CPlatformScreen {
|
||||
|
@ -135,6 +136,7 @@ private:
|
|||
ATOM createDeskWindowClass(bool isPrimary) const;
|
||||
void destroyClass(ATOM windowClass) const;
|
||||
HWND createWindow(ATOM windowClass, const char* name) const;
|
||||
HWND createDropWindow(ATOM windowClass, const char* name) const;
|
||||
void destroyWindow(HWND) const;
|
||||
|
||||
// convenience function to send events
|
||||
|
@ -216,6 +218,9 @@ private: // HACK
|
|||
bool isModifierRepeat(KeyModifierMask oldState,
|
||||
KeyModifierMask state, WPARAM wParam) const;
|
||||
|
||||
// send drag info and data back to server
|
||||
void sendDragThread(void*);
|
||||
|
||||
private:
|
||||
struct CHotKeyItem {
|
||||
public:
|
||||
|
@ -325,4 +330,11 @@ private:
|
|||
IEventQueue* m_events;
|
||||
|
||||
CString m_desktopPath;
|
||||
|
||||
CMSWindowsDropTarget*
|
||||
m_dropTarget;
|
||||
HWND m_dropWindow;
|
||||
const int m_dropWindowSize;
|
||||
|
||||
CThread* m_sendDragThread;
|
||||
};
|
||||
|
|
|
@ -2102,6 +2102,11 @@ COSXScreen::getDraggingFilename()
|
|||
CString fileList(info);
|
||||
m_draggingFilename = fileList;
|
||||
}
|
||||
|
||||
// fake a escape key down and up then left mouse button up
|
||||
fakeKeyDown(kKeyEscape, 8192, 1);
|
||||
fakeKeyUp(1);
|
||||
fakeMouseButton(kButtonLeft, false);
|
||||
}
|
||||
return m_draggingFilename;
|
||||
}
|
||||
|
|
|
@ -85,7 +85,9 @@ CServer::CServer(
|
|||
m_sendFileThread(NULL),
|
||||
m_writeToDropDirThread(NULL),
|
||||
m_ignoreFileTransfer(false),
|
||||
m_enableDragDrop(enableDragDrop)
|
||||
m_enableDragDrop(enableDragDrop),
|
||||
m_getDragInfoThread(NULL),
|
||||
m_waitDragInfoThread(true)
|
||||
{
|
||||
// must have a primary client and it must have a canonical name
|
||||
assert(m_primaryClient != NULL);
|
||||
|
@ -1658,6 +1660,9 @@ CServer::onMouseDown(ButtonID id)
|
|||
|
||||
// relay
|
||||
m_active->mouseDown(id);
|
||||
|
||||
// reset this variable back to default value true
|
||||
m_waitDragInfoThread = true;
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -1759,46 +1764,76 @@ CServer::onMouseMovePrimary(SInt32 x, SInt32 y)
|
|||
|
||||
// should we switch or not?
|
||||
if (isSwitchOkay(newScreen, dir, x, y, xc, yc)) {
|
||||
if (m_enableDragDrop && m_screen->isDraggingStarted() && m_active != newScreen) {
|
||||
CString& dragFileList = m_screen->getDraggingFilename();
|
||||
size_t size = dragFileList.size() + 1;
|
||||
char* fileList = NULL;
|
||||
UInt32 fileCount = 1;
|
||||
if (dragFileList.empty() == false) {
|
||||
fileList = new char[size];
|
||||
memcpy(fileList, dragFileList.c_str(), size);
|
||||
fileList[size - 1] = '\0';
|
||||
if (m_enableDragDrop
|
||||
&& m_screen->isDraggingStarted()
|
||||
&& m_active != newScreen
|
||||
&& m_waitDragInfoThread) {
|
||||
if (m_getDragInfoThread == NULL) {
|
||||
m_getDragInfoThread = new CThread(
|
||||
new TMethodJob<CServer>(
|
||||
this,
|
||||
&CServer::getDragInfoThread));
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
if (m_getDragInfoThread == NULL) {
|
||||
// switch screen
|
||||
switchScreen(newScreen, x, y, false);
|
||||
|
||||
// send drag file info to client if there is any
|
||||
if (m_dragFileList.size() > 0) {
|
||||
sendDragInfo(newScreen);
|
||||
m_dragFileList.clear();
|
||||
}
|
||||
|
||||
// fake a escape key down and up then left mouse button up
|
||||
m_screen->keyDown(kKeyEscape, 8192, 1);
|
||||
m_screen->keyUp(kKeyEscape, 8192, 1);
|
||||
m_screen->mouseUp(kButtonLeft);
|
||||
m_waitDragInfoThread = true;
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void
|
||||
CServer::getDragInfoThread(void*)
|
||||
{
|
||||
m_dragFileList.clear();
|
||||
CString& dragFileList = m_screen->getDraggingFilename();
|
||||
if (!dragFileList.empty()) {
|
||||
m_dragFileList.push_back(dragFileList);
|
||||
}
|
||||
|
||||
#if defined(__APPLE__)
|
||||
|
||||
// on mac it seems that after faking a LMB up, system would signal back
|
||||
// to synergy a mouse up event, which doesn't happen on windows. as a
|
||||
// result, synergy would send dragging file to client twice. This variable
|
||||
// is used to ignore the first file sending.
|
||||
m_ignoreFileTransfer = true;
|
||||
// on mac it seems that after faking a LMB up, system would signal back
|
||||
// to synergy a mouse up event, which doesn't happen on windows. as a
|
||||
// result, synergy would send dragging file to client twice. This variable
|
||||
// is used to ignore the first file sending.
|
||||
m_ignoreFileTransfer = true;
|
||||
#endif
|
||||
|
||||
if (dragFileList.empty() == false) {
|
||||
LOG((CLOG_DEBUG2 "sending drag information to client"));
|
||||
LOG((CLOG_DEBUG3 "dragging file list: %s", fileList));
|
||||
LOG((CLOG_DEBUG3 "dragging file list string size: %i", size));
|
||||
newScreen->draggingInfoSending(fileCount, fileList, size);
|
||||
}
|
||||
}
|
||||
|
||||
// switch screen
|
||||
switchScreen(newScreen, x, y, false);
|
||||
m_waitDragInfoThread = false;
|
||||
m_getDragInfoThread = NULL;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
else {
|
||||
return false;
|
||||
void
|
||||
CServer::sendDragInfo(CBaseClientProxy* newScreen)
|
||||
{
|
||||
// TODO: support multiple files dragging
|
||||
CString& dragFile = m_dragFileList.at(0);
|
||||
size_t size = dragFile.size() + 1;
|
||||
char* fileList = NULL;
|
||||
UInt32 fileCount = 1;
|
||||
if (dragFile.empty() == false) {
|
||||
fileList = new char[size];
|
||||
memcpy(fileList, dragFile.c_str(), size);
|
||||
fileList[size - 1] = '\0';
|
||||
|
||||
LOG((CLOG_DEBUG2 "sending drag information to client"));
|
||||
LOG((CLOG_DEBUG3 "dragging file list: %s", fileList));
|
||||
LOG((CLOG_DEBUG3 "dragging file list string size: %i", size));
|
||||
newScreen->draggingInfoSending(fileCount, fileList, size);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -365,6 +365,12 @@ private:
|
|||
// thread function for writing file to drop directory
|
||||
void writeToDropDirThread(void*);
|
||||
|
||||
// thread function for getting drag filename
|
||||
void getDragInfoThread(void*);
|
||||
|
||||
// send drag info to new client screen
|
||||
void sendDragInfo(CBaseClientProxy* newScreen);
|
||||
|
||||
public:
|
||||
bool m_mock;
|
||||
|
||||
|
@ -472,4 +478,7 @@ private:
|
|||
CString m_dragFileExt;
|
||||
bool m_ignoreFileTransfer;
|
||||
bool m_enableDragDrop;
|
||||
|
||||
CThread* m_getDragInfoThread;
|
||||
bool m_waitDragInfoThread;
|
||||
};
|
||||
|
|
Loading…
Reference in New Issue