Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 9 additions & 1 deletion src/gui/src/ServerConfig.cpp
100644 → 100755
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,8 @@ bool ServerConfig::operator==(const ServerConfig &sc) const
m_SwitchCornerSize == sc.m_SwitchCornerSize && m_SwitchCorners == sc.m_SwitchCorners &&
m_Hotkeys == sc.m_Hotkeys && m_pAppConfig == sc.m_pAppConfig &&
m_DisableLockToScreen == sc.m_DisableLockToScreen && m_ClipboardSharing == sc.m_ClipboardSharing &&
m_ClipboardSharingSize == sc.m_ClipboardSharingSize && m_pMainWindow == sc.m_pMainWindow;
m_ClipboardSharingSize == sc.m_ClipboardSharingSize && m_TouchInputLocal == sc.m_TouchInputLocal &&
m_pMainWindow == sc.m_pMainWindow;
}

void ServerConfig::save(QFile &file) const
Expand Down Expand Up @@ -127,6 +128,7 @@ void ServerConfig::commit()
settings().setValue("disableLockToScreen", disableLockToScreen());
settings().setValue("clipboardSharing", clipboardSharing());
settings().setValue("clipboardSharingSize", QVariant::fromValue(clipboardSharingSize()));
settings().setValue("touchInputLocal", touchInputLocal());

if (!getClientAddress().isEmpty()) {
settings().setValue("clientAddress", getClientAddress());
Expand Down Expand Up @@ -182,6 +184,7 @@ void ServerConfig::recall()
settings().value("clipboardSharingSize", (int)ServerConfig::defaultClipboardSharingSize()).toULongLong()
);
setClipboardSharing(settings().value("clipboardSharing", true).toBool());
setTouchInputLocal(settings().value("touchInputLocal", false).toBool());
setClientAddress(settings().value("clientAddress", "").toString());

readSettings(settings(), switchCorners(), "switchCorner", 0, static_cast<int>(NumSwitchCorners));
Expand Down Expand Up @@ -216,6 +219,9 @@ void ServerConfig::recall()
if (locked.contains("clipboardSharingSize")) {
m_ClipboardSharingSize = locked.value("clipboardSharingSize").toULongLong();
}
if (locked.contains("touchInputLocal")) {
m_TouchInputLocal = locked.value("touchInputLocal").toBool();
}
locked.endGroup();
}

Expand Down Expand Up @@ -286,6 +292,8 @@ QTextStream &operator<<(QTextStream &outStream, const ServerConfig &config)
<< "clipboardSharing = " << (config.clipboardSharing() ? "true" : "false") << Qt::endl;
outStream << "\t"
<< "clipboardSharingSize = " << config.clipboardSharingSize() << Qt::endl;
outStream << "\t"
<< "touchInputLocal = " << (config.touchInputLocal() ? "true" : "false") << Qt::endl;

if (!config.getClientAddress().isEmpty()) {
outStream << "\t"
Expand Down
9 changes: 9 additions & 0 deletions src/gui/src/ServerConfig.h
100644 → 100755
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,10 @@ class ServerConfig : public ScreenConfig, public deskflow::gui::IServerConfig
{
return m_ClipboardSharingSize;
}
bool touchInputLocal() const
{
return m_TouchInputLocal;
}
static size_t defaultClipboardSharingSize();

//
Expand Down Expand Up @@ -224,6 +228,10 @@ class ServerConfig : public ScreenConfig, public deskflow::gui::IServerConfig
{
m_ClipboardSharing = on;
}
void setTouchInputLocal(bool on)
{
m_TouchInputLocal = on;
}
void setConfigFile(const QString &configFile);
void setUseExternalConfig(bool useExternalConfig);
size_t setClipboardSharingSize(size_t size);
Expand Down Expand Up @@ -253,6 +261,7 @@ class ServerConfig : public ScreenConfig, public deskflow::gui::IServerConfig
int m_SwitchCornerSize = 0;
bool m_DisableLockToScreen = false;
bool m_ClipboardSharing = true;
bool m_TouchInputLocal = false;
QString m_ClientAddress = "";
QList<bool> m_SwitchCorners;
HotkeyList m_Hotkeys;
Expand Down
13 changes: 13 additions & 0 deletions src/gui/src/ServerConfigDialog.cpp
100644 → 100755
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,7 @@ ServerConfigDialog::ServerConfigDialog(QWidget *parent, ServerConfig &config, Ap
int clipboardSharingSizeM = static_cast<int>(serverConfig().clipboardSharingSize() / 1024);
m_pSpinBoxClipboardSizeLimit->setValue(clipboardSharingSizeM);
m_pSpinBoxClipboardSizeLimit->setEnabled(serverConfig().clipboardSharing());
m_pCheckBoxTouchInputLocal->setChecked(serverConfig().touchInputLocal());

foreach (const Hotkey &hotkey, serverConfig().hotkeys())
m_pListHotkeys->addItem(hotkey.text());
Expand Down Expand Up @@ -105,6 +106,10 @@ ServerConfigDialog::ServerConfigDialog(QWidget *parent, ServerConfig &config, Ap
qDebug() << "locking clipboard size setting";
m_pSpinBoxClipboardSizeLimit->setEnabled(false);
}
if (locked.contains("touchInputLocal")) {
qDebug() << "locking touch input local setting";
m_pCheckBoxTouchInputLocal->setEnabled(false);
}
locked.endGroup();

onChange();
Expand Down Expand Up @@ -142,6 +147,10 @@ ServerConfigDialog::ServerConfigDialog(QWidget *parent, ServerConfig &config, Ap
serverConfig().setDisableLockToScreen(v);
onChange();
});
connect(m_pCheckBoxTouchInputLocal, &QCheckBox::stateChanged, this, [this](const int &v) {
serverConfig().setTouchInputLocal(v);
onChange();
});
connect(m_pCheckBoxCornerTopLeft, &QCheckBox::stateChanged, this, [this](const int &v) {
serverConfig().setSwitchCorner(static_cast<int>(TopLeft), v);
onChange();
Expand Down Expand Up @@ -192,6 +201,10 @@ ServerConfigDialog::ServerConfigDialog(QWidget *parent, ServerConfig &config, Ap
serverConfig().setDisableLockToScreen(v == Qt::Checked);
onChange();
});
connect(m_pCheckBoxTouchInputLocal, &QCheckBox::checkStateChanged, this, [this](const Qt::CheckState &v) {
serverConfig().setTouchInputLocal(v == Qt::Checked);
onChange();
});
connect(m_pCheckBoxCornerTopLeft, &QCheckBox::checkStateChanged, this, [this](const Qt::CheckState &v) {
serverConfig().setSwitchCorner(static_cast<int>(TopLeft), v == Qt::Checked);
onChange();
Expand Down
10 changes: 10 additions & 0 deletions src/gui/src/ServerConfigDialogBase.ui
100644 → 100755
Original file line number Diff line number Diff line change
Expand Up @@ -567,6 +567,16 @@
</item>
</layout>
</item>
<item>
<widget class="QCheckBox" name="m_pCheckBoxTouchInputLocal">
<property name="text">
<string>Keep touch input on this computer</string>
</property>
<property name="toolTip">
<string>When enabled, touch screen input stays on this computer even when the cursor moves to another screen</string>
</property>
</widget>
</item>
<item>
<spacer name="verticalSpacer_3">
<property name="orientation">
Expand Down
1 change: 1 addition & 0 deletions src/lib/deskflow/option_types.h
100644 → 100755
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,7 @@ static const OptionID kOptionWin32KeepForeground = OPTION_CODE("_KFW");
static const OptionID kOptionDisableLockToScreen = OPTION_CODE("DLTS");
static const OptionID kOptionClipboardSharing = OPTION_CODE("CLPS");
static const OptionID kOptionClipboardSharingSize = OPTION_CODE("CLSZ");
static const OptionID kOptionTouchInputLocal = OPTION_CODE("TILC");
//@}

//! @name Screen switch corner enumeration
Expand Down
24 changes: 24 additions & 0 deletions src/lib/platform/MSWindowsHook.cpp
100644 → 100755
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,12 @@ static BYTE g_keyState[256] = {0};
static DWORD g_hookThread = 0;
static bool g_fakeServerInput = false;
static BOOL g_isPrimary = TRUE;
static bool g_touchInputLocal = false;
static bool g_isOnScreen = true;

// Touch input signature in dwExtraInfo (bit 7 set indicates touch/pen)
#define TOUCH_SIGNATURE_MASK 0xFFFFFF00
#define TOUCH_SIGNATURE 0xFF515700

MSWindowsHook::MSWindowsHook()
{
Expand Down Expand Up @@ -148,6 +154,17 @@ void MSWindowsHook::setMode(EHookMode mode)
g_mode = mode;
}

void MSWindowsHook::setTouchInputLocal(bool enable)
{
g_touchInputLocal = enable;
LOG((CLOG_DEBUG "hook: touchInputLocal = %s", enable ? "true" : "false"));
}

void MSWindowsHook::setIsOnScreen(bool onScreen)
{
g_isOnScreen = onScreen;
}

static void keyboardGetState(BYTE keys[256], DWORD vkCode, bool kf_up)
{
// we have to use GetAsyncKeyState() rather than GetKeyState() because
Expand Down Expand Up @@ -585,6 +602,13 @@ static LRESULT CALLBACK mouseLLHook(int code, WPARAM wParam, LPARAM lParam)
return CallNextHookEx(g_mouseLL, code, wParam, lParam);
}

// touch gestures don't translate well to remote clients, so optionally keep them local
bool const mouseFromTouchInput = (info->dwExtraInfo & TOUCH_SIGNATURE_MASK) == TOUCH_SIGNATURE;
if (g_touchInputLocal && !g_isOnScreen && mouseFromTouchInput) {
LOG((CLOG_DEBUG1 "touch-generated mouse event, keeping input on server"));
return CallNextHookEx(g_mouseLL, code, wParam, lParam);
}

SInt32 x = static_cast<SInt32>(info->pt.x);
SInt32 y = static_cast<SInt32>(info->pt.y);
SInt32 w = static_cast<SInt16>(HIWORD(info->mouseData));
Expand Down
6 changes: 6 additions & 0 deletions src/lib/platform/MSWindowsHook.h
100644 → 100755
Original file line number Diff line number Diff line change
Expand Up @@ -49,4 +49,10 @@ class MSWindowsHook
static int installScreenSaver();

static int uninstallScreenSaver();

//! Set whether touch input should stay on this computer
void setTouchInputLocal(bool enable);

//! Set whether cursor is currently on this screen
void setIsOnScreen(bool onScreen);
};
47 changes: 46 additions & 1 deletion src/lib/platform/MSWindowsScreen.cpp
100644 → 100755
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
#include "deskflow/Clipboard.h"
#include "deskflow/KeyMap.h"
#include "deskflow/XScreen.h"
#include "deskflow/option_types.h"
#include "mt/Thread.h"
#include "platform/MSWindowsClipboard.h"
#include "platform/MSWindowsDesks.h"
Expand Down Expand Up @@ -83,6 +84,23 @@
#define PBT_APMRESUMEAUTOMATIC 0x0012
#endif

// WM_POINTER stuff (Windows 8+)
#if !defined(WM_POINTERDOWN)
#define WM_POINTERDOWN 0x0246
#define WM_POINTERUP 0x0247
#define WM_POINTERUPDATE 0x0245
#define WM_POINTERENTER 0x0249
#define WM_POINTERLEAVE 0x024A
#define GET_POINTERID_WPARAM(wParam) (LOWORD(wParam))
#endif

#if !defined(PT_POINTER)
#define PT_POINTER 1
#define PT_TOUCH 2
#define PT_PEN 3
#define PT_MOUSE 4
#endif

//
// MSWindowsScreen
//
Expand Down Expand Up @@ -124,7 +142,9 @@ MSWindowsScreen::MSWindowsScreen(
m_hasMouse(GetSystemMetrics(SM_MOUSEPRESENT) != 0),
m_events(events),
m_dropWindow(NULL),
m_dropWindowSize(20)
m_dropWindowSize(20),
m_touchInputLocal(false),
m_lastInputWasTouch(false)
{
LOG_DEBUG("settting up %s screen", m_isPrimary ? "primary" : "secondary");

Expand Down Expand Up @@ -313,6 +333,7 @@ void MSWindowsScreen::enter()

// now on screen
m_isOnScreen = true;
m_hook.setIsOnScreen(true);
setupMouseKeys();
}

Expand Down Expand Up @@ -369,6 +390,7 @@ void MSWindowsScreen::leave()

// now off screen
m_isOnScreen = false;
m_hook.setIsOnScreen(false);

if (isDraggingStarted() && !m_isPrimary) {
m_sendDragThread = new Thread(new TMethodJob<MSWindowsScreen>(this, &MSWindowsScreen::sendDragThread));
Expand Down Expand Up @@ -475,6 +497,16 @@ void MSWindowsScreen::resetOptions()

void MSWindowsScreen::setOptions(const OptionsList &options)
{
// Handle touch input local option
for (UInt32 i = 0, n = (UInt32)options.size(); i < n; i += 2) {
if (options[i] == kOptionTouchInputLocal) {
m_touchInputLocal = (options[i + 1] != 0);
LOG((CLOG_DEBUG1 "touchInputLocal = %s", m_touchInputLocal ? "true" : "false"));
// Update the hook so it can block touch-generated mouse events
m_hook.setTouchInputLocal(m_touchInputLocal);
}
}

m_desks->setOptions(options);
}

Expand Down Expand Up @@ -1043,6 +1075,19 @@ bool MSWindowsScreen::onEvent(HWND, UINT msg, WPARAM wParam, LPARAM lParam, LRES
case WM_DISPLAYCHANGE:
return onDisplayChange();

// Handle pointer input (touch/pen) - Windows 8+
// This allows us to detect touch vs mouse input and optionally keep touch local
case WM_POINTERDOWN:
case WM_POINTERUP:
case WM_POINTERUPDATE:
if (m_isPrimary && m_touchInputLocal) {
// Touch input was consumed (kept local)
*result = 0;
return true;
}
// Fall through to let DefWindowProc convert to mouse messages
return false;

/* On windows 10 we don't receive WM_POWERBROADCAST after sleep.
We receive only WM_TIMECHANGE hence this message is used to resume.*/
case WM_TIMECHANGE:
Expand Down
4 changes: 4 additions & 0 deletions src/lib/platform/MSWindowsScreen.h
100644 → 100755
Original file line number Diff line number Diff line change
Expand Up @@ -343,6 +343,10 @@ class MSWindowsScreen : public PlatformScreen

MSWindowsHook m_hook;

// Touch input local policy - when true, touch stays on primary screen
bool m_touchInputLocal;
bool m_lastInputWasTouch;

static MSWindowsScreen *s_screen;

IEventQueue *m_events;
Expand Down
7 changes: 6 additions & 1 deletion src/lib/server/Config.cpp
100644 → 100755
Original file line number Diff line number Diff line change
Expand Up @@ -699,6 +699,8 @@ void Config::readSectionOptions(ConfigReadContext &s)
addOption("", kOptionClipboardSharing, s.parseBoolean(value));
} else if (name == "clipboardSharingSize") {
addOption("", kOptionClipboardSharingSize, s.parseInt(value));
} else if (name == "touchInputLocal") {
addOption("", kOptionTouchInputLocal, s.parseBoolean(value));
} else if (name == "clientAddress") {
m_ClientAddress = value;
} else {
Expand Down Expand Up @@ -1268,6 +1270,9 @@ const char *Config::getOptionName(OptionID id)
if (id == kOptionClipboardSharingSize) {
return "clipboardSharingSize";
}
if (id == kOptionTouchInputLocal) {
return "touchInputLocal";
}
return NULL;
}

Expand All @@ -1277,7 +1282,7 @@ String Config::getOptionValue(OptionID id, OptionValue value)
id == kOptionScreenSwitchNeedsShift || id == kOptionScreenSwitchNeedsControl ||
id == kOptionScreenSwitchNeedsAlt || id == kOptionXTestXineramaUnaware || id == kOptionRelativeMouseMoves ||
id == kOptionWin32KeepForeground || id == kOptionScreenPreserveFocus || id == kOptionClipboardSharing ||
id == kOptionClipboardSharingSize) {
id == kOptionClipboardSharingSize || id == kOptionTouchInputLocal) {
return (value != 0) ? "true" : "false";
}
if (id == kOptionModifierMapForShift || id == kOptionModifierMapForControl || id == kOptionModifierMapForAlt ||
Expand Down
Loading