attempt to fix stuttering when leaving win32 screen. seems to
work but will let testers make the final call. also fixed desktop synchronization by setting a variable that was mistakenly left unset. and tried to work around an apparent bug in MsgWaitForMultipleObjects() that prevented the service from closing down properly. start/pause/continue/stop sequence still doesn't shut down correctly. start/pause/stop and start/stop work fine.
This commit is contained in:
parent
82cdfb478a
commit
76cc62d133
|
@ -1,6 +1,7 @@
|
||||||
#include "CMSWindowsScreen.h"
|
#include "CMSWindowsScreen.h"
|
||||||
#include "CMSWindowsClipboard.h"
|
#include "CMSWindowsClipboard.h"
|
||||||
#include "CMSWindowsScreenSaver.h"
|
#include "CMSWindowsScreenSaver.h"
|
||||||
|
#include "CPlatform.h"
|
||||||
#include "CClipboard.h"
|
#include "CClipboard.h"
|
||||||
#include "IMSWindowsScreenEventHandler.h"
|
#include "IMSWindowsScreenEventHandler.h"
|
||||||
#include "IScreenReceiver.h"
|
#include "IScreenReceiver.h"
|
||||||
|
@ -35,6 +36,7 @@ CMSWindowsScreen::CMSWindowsScreen(IScreenReceiver* receiver,
|
||||||
m_class(NULL),
|
m_class(NULL),
|
||||||
m_icon(NULL),
|
m_icon(NULL),
|
||||||
m_cursor(NULL),
|
m_cursor(NULL),
|
||||||
|
m_is95Family(CPlatform::isWindows95Family()),
|
||||||
m_window(NULL),
|
m_window(NULL),
|
||||||
m_x(0), m_y(0),
|
m_x(0), m_y(0),
|
||||||
m_w(0), m_h(0),
|
m_w(0), m_h(0),
|
||||||
|
@ -206,7 +208,11 @@ CMSWindowsScreen::mainLoop()
|
||||||
void
|
void
|
||||||
CMSWindowsScreen::exitMainLoop()
|
CMSWindowsScreen::exitMainLoop()
|
||||||
{
|
{
|
||||||
|
// post an arbitrary message after the quit because
|
||||||
|
// MsgWaitForMultipleObjects() is broken and might not wake up if
|
||||||
|
// just WM_QUIT is in the queue.
|
||||||
PostThreadMessage(m_threadID, WM_QUIT, 0, 0);
|
PostThreadMessage(m_threadID, WM_QUIT, 0, 0);
|
||||||
|
PostThreadMessage(m_threadID, WM_APP + 1, 0, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|
|
@ -187,14 +187,7 @@ mouseHook(int code, WPARAM wParam, LPARAM lParam)
|
||||||
// relay the motion
|
// relay the motion
|
||||||
SInt32 x = (SInt32)info->pt.x;
|
SInt32 x = (SInt32)info->pt.x;
|
||||||
SInt32 y = (SInt32)info->pt.y;
|
SInt32 y = (SInt32)info->pt.y;
|
||||||
if (info->dwExtraInfo == 0x12345678) {
|
PostThreadMessage(g_threadID, SYNERGY_MSG_MOUSE_MOVE, x, y);
|
||||||
PostThreadMessage(g_threadID,
|
|
||||||
SYNERGY_MSG_POST_WARP, x, y);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
PostThreadMessage(g_threadID,
|
|
||||||
SYNERGY_MSG_MOUSE_MOVE, x, y);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,10 +19,13 @@
|
||||||
#define SYNERGY_MSG_MARK WM_APP + 0x0011 // mark id; <unused>
|
#define SYNERGY_MSG_MARK WM_APP + 0x0011 // mark id; <unused>
|
||||||
#define SYNERGY_MSG_KEY WM_APP + 0x0012 // vk code; key data
|
#define SYNERGY_MSG_KEY WM_APP + 0x0012 // vk code; key data
|
||||||
#define SYNERGY_MSG_MOUSE_BUTTON WM_APP + 0x0013 // button msg; <unused>
|
#define SYNERGY_MSG_MOUSE_BUTTON WM_APP + 0x0013 // button msg; <unused>
|
||||||
#define SYNERGY_MSG_MOUSE_MOVE WM_APP + 0x0014 // x; y
|
#define SYNERGY_MSG_MOUSE_WHEEL WM_APP + 0x0014 // delta; <unused>
|
||||||
#define SYNERGY_MSG_POST_WARP WM_APP + 0x0015 // x; y
|
#define SYNERGY_MSG_MOUSE_MOVE WM_APP + 0x0015 // x; y
|
||||||
#define SYNERGY_MSG_MOUSE_WHEEL WM_APP + 0x0016 // delta; <unused>
|
#define SYNERGY_MSG_POST_WARP WM_APP + 0x0016 // <unused>; <unused>
|
||||||
#define SYNERGY_MSG_SCREEN_SAVER WM_APP + 0x0017 // activated; <unused>
|
#define SYNERGY_MSG_PRE_WARP WM_APP + 0x0017 // x; y
|
||||||
|
#define SYNERGY_MSG_SCREEN_SAVER WM_APP + 0x0018 // activated; <unused>
|
||||||
|
#define SYNERGY_MSG_INPUT_FIRST SYNERGY_MSG_KEY
|
||||||
|
#define SYNERGY_MSG_INPUT_LAST SYNERGY_MSG_PRE_WARP
|
||||||
|
|
||||||
extern "C" {
|
extern "C" {
|
||||||
|
|
||||||
|
|
|
@ -19,8 +19,7 @@ CMSWindowsPrimaryScreen::CMSWindowsPrimaryScreen(
|
||||||
m_threadID(0),
|
m_threadID(0),
|
||||||
m_window(NULL),
|
m_window(NULL),
|
||||||
m_mark(0),
|
m_mark(0),
|
||||||
m_markReceived(0),
|
m_markReceived(0)
|
||||||
m_mouseMoveIgnore(0)
|
|
||||||
{
|
{
|
||||||
assert(m_receiver != NULL);
|
assert(m_receiver != NULL);
|
||||||
|
|
||||||
|
@ -71,9 +70,15 @@ CMSWindowsPrimaryScreen::reconfigure(UInt32 activeSides)
|
||||||
void
|
void
|
||||||
CMSWindowsPrimaryScreen::warpCursor(SInt32 x, SInt32 y)
|
CMSWindowsPrimaryScreen::warpCursor(SInt32 x, SInt32 y)
|
||||||
{
|
{
|
||||||
// set the cursor position without generating an event
|
// warp mouse
|
||||||
// FIXME -- doesn't this generate an event anyway?
|
warpCursorNoFlush(x, y);
|
||||||
SetCursorPos(x, y);
|
|
||||||
|
// remove all input events before and including warp
|
||||||
|
MSG msg;
|
||||||
|
while (PeekMessage(&msg, NULL, SYNERGY_MSG_INPUT_FIRST,
|
||||||
|
SYNERGY_MSG_INPUT_LAST, PM_REMOVE)) {
|
||||||
|
// do nothing
|
||||||
|
}
|
||||||
|
|
||||||
// save position as last position
|
// save position as last position
|
||||||
m_x = x;
|
m_x = x;
|
||||||
|
@ -165,7 +170,7 @@ CMSWindowsPrimaryScreen::onPreDispatch(const CEvent* event)
|
||||||
|
|
||||||
case SYNERGY_MSG_KEY:
|
case SYNERGY_MSG_KEY:
|
||||||
// ignore message if posted prior to last mark change
|
// ignore message if posted prior to last mark change
|
||||||
if (m_markReceived == m_mark) {
|
if (!ignore()) {
|
||||||
KeyModifierMask mask;
|
KeyModifierMask mask;
|
||||||
const KeyID key = mapKey(msg->wParam, msg->lParam, &mask);
|
const KeyID key = mapKey(msg->wParam, msg->lParam, &mask);
|
||||||
if (key != kKeyNone) {
|
if (key != kKeyNone) {
|
||||||
|
@ -201,7 +206,7 @@ CMSWindowsPrimaryScreen::onPreDispatch(const CEvent* event)
|
||||||
|
|
||||||
case SYNERGY_MSG_MOUSE_BUTTON:
|
case SYNERGY_MSG_MOUSE_BUTTON:
|
||||||
// ignore message if posted prior to last mark change
|
// ignore message if posted prior to last mark change
|
||||||
if (m_markReceived == m_mark) {
|
if (!ignore()) {
|
||||||
static const int s_vkButton[] = {
|
static const int s_vkButton[] = {
|
||||||
0, // kButtonNone
|
0, // kButtonNone
|
||||||
VK_LBUTTON, // kButtonLeft, etc.
|
VK_LBUTTON, // kButtonLeft, etc.
|
||||||
|
@ -236,53 +241,65 @@ CMSWindowsPrimaryScreen::onPreDispatch(const CEvent* event)
|
||||||
|
|
||||||
case SYNERGY_MSG_MOUSE_WHEEL:
|
case SYNERGY_MSG_MOUSE_WHEEL:
|
||||||
// ignore message if posted prior to last mark change
|
// ignore message if posted prior to last mark change
|
||||||
if (m_markReceived == m_mark) {
|
if (!ignore()) {
|
||||||
log((CLOG_ERR "event: button wheel delta=%d %d", msg->wParam, msg->lParam));
|
log((CLOG_DEBUG1 "event: button wheel delta=%d %d", msg->wParam, msg->lParam));
|
||||||
m_receiver->onMouseWheel(msg->wParam);
|
m_receiver->onMouseWheel(msg->wParam);
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
|
case SYNERGY_MSG_PRE_WARP:
|
||||||
|
{
|
||||||
|
// save position to compute delta of next motion
|
||||||
|
m_x = static_cast<SInt32>(msg->wParam);
|
||||||
|
m_y = static_cast<SInt32>(msg->lParam);
|
||||||
|
|
||||||
|
// we warped the mouse. discard events until we find the
|
||||||
|
// matching post warp event. see warpCursorNoFlush() for
|
||||||
|
// where the events are sent. we discard the matching
|
||||||
|
// post warp event and can be sure we've skipped the warp
|
||||||
|
// event.
|
||||||
|
MSG msg;
|
||||||
|
do {
|
||||||
|
GetMessage(&msg, NULL, SYNERGY_MSG_MOUSE_MOVE,
|
||||||
|
SYNERGY_MSG_POST_WARP);
|
||||||
|
} while (msg.message != SYNERGY_MSG_POST_WARP);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
case SYNERGY_MSG_POST_WARP:
|
||||||
|
log((CLOG_WARN "unmatched post warp"));
|
||||||
|
return true;
|
||||||
|
|
||||||
case SYNERGY_MSG_MOUSE_MOVE:
|
case SYNERGY_MSG_MOUSE_MOVE:
|
||||||
// ignore message if posted prior to last mark change
|
// ignore message if posted prior to last mark change
|
||||||
if (m_markReceived == m_mark) {
|
if (!ignore()) {
|
||||||
SInt32 x = static_cast<SInt32>(msg->wParam);
|
// compute motion delta (relative to the last known
|
||||||
SInt32 y = static_cast<SInt32>(msg->lParam);
|
// mouse position)
|
||||||
|
SInt32 x = static_cast<SInt32>(msg->wParam) - m_x;
|
||||||
|
SInt32 y = static_cast<SInt32>(msg->lParam) - m_y;
|
||||||
|
|
||||||
|
// save position to compute delta of next motion
|
||||||
|
m_x = static_cast<SInt32>(msg->wParam);
|
||||||
|
m_y = static_cast<SInt32>(msg->lParam);
|
||||||
|
|
||||||
if (!isActive()) {
|
if (!isActive()) {
|
||||||
m_receiver->onMouseMovePrimary(x, y);
|
// motion on primary screen
|
||||||
|
m_receiver->onMouseMovePrimary(m_x, m_y);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
// compute motion delta. this is relative to the
|
// motion on secondary screen. warp mouse back to
|
||||||
// last known mouse position.
|
// center.
|
||||||
x -= m_x;
|
if (x != 0 || y != 0) {
|
||||||
y -= m_y;
|
// back to center
|
||||||
|
warpCursorNoFlush(m_xCenter, m_yCenter);
|
||||||
|
|
||||||
// save position to compute delta of next motion
|
// send motion
|
||||||
m_x = static_cast<SInt32>(msg->wParam);
|
m_receiver->onMouseMoveSecondary(x, y);
|
||||||
m_y = static_cast<SInt32>(msg->lParam);
|
|
||||||
|
|
||||||
// ignore if the mouse didn't move or we're ignoring
|
|
||||||
// motion.
|
|
||||||
if (m_mouseMoveIgnore == 0) {
|
|
||||||
if (x != 0 || y != 0) {
|
|
||||||
// back to center
|
|
||||||
warpCursorToCenter();
|
|
||||||
|
|
||||||
// send motion
|
|
||||||
m_receiver->onMouseMoveSecondary(x, y);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
// ignored one more motion event
|
|
||||||
--m_mouseMoveIgnore;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
case SYNERGY_MSG_POST_WARP:
|
|
||||||
m_x = static_cast<SInt32>(msg->wParam);
|
|
||||||
m_y = static_cast<SInt32>(msg->lParam);
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
|
@ -414,9 +431,6 @@ CMSWindowsPrimaryScreen::onPreEnter()
|
||||||
{
|
{
|
||||||
assert(m_window != NULL);
|
assert(m_window != NULL);
|
||||||
|
|
||||||
// reset motion ignore count
|
|
||||||
m_mouseMoveIgnore = 0;
|
|
||||||
|
|
||||||
// enable ctrl+alt+del, alt+tab, etc
|
// enable ctrl+alt+del, alt+tab, etc
|
||||||
if (m_is95Family) {
|
if (m_is95Family) {
|
||||||
DWORD dummy = 0;
|
DWORD dummy = 0;
|
||||||
|
@ -450,23 +464,11 @@ CMSWindowsPrimaryScreen::onPostLeave(bool success)
|
||||||
// relay all mouse and keyboard events
|
// relay all mouse and keyboard events
|
||||||
m_setRelay(true);
|
m_setRelay(true);
|
||||||
|
|
||||||
// ignore this many mouse motion events (not including the already
|
|
||||||
// queued events). on (at least) the win2k login desktop, one
|
|
||||||
// motion event is reported using a position from before the above
|
|
||||||
// warpCursor(). i don't know why it does that and other desktops
|
|
||||||
// don't have the same problem. anyway, simply ignoring that event
|
|
||||||
// works around it.
|
|
||||||
// FIXME -- is this true now that we're using mouse_event?
|
|
||||||
m_mouseMoveIgnore = 1;
|
|
||||||
|
|
||||||
// disable ctrl+alt+del, alt+tab, etc
|
// disable ctrl+alt+del, alt+tab, etc
|
||||||
if (m_is95Family) {
|
if (m_is95Family) {
|
||||||
DWORD dummy = 0;
|
DWORD dummy = 0;
|
||||||
SystemParametersInfo(SPI_SETSCREENSAVERRUNNING, TRUE, &dummy, 0);
|
SystemParametersInfo(SPI_SETSCREENSAVERRUNNING, TRUE, &dummy, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
// discard messages until after the warp
|
|
||||||
nextMark();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -550,16 +552,21 @@ CMSWindowsPrimaryScreen::hideWindow()
|
||||||
void
|
void
|
||||||
CMSWindowsPrimaryScreen::warpCursorToCenter()
|
CMSWindowsPrimaryScreen::warpCursorToCenter()
|
||||||
{
|
{
|
||||||
// warp to center. the extra info tells the hook DLL to send
|
warpCursor(m_xCenter, m_yCenter);
|
||||||
// SYNERGY_MSG_POST_WARP instead of SYNERGY_MSG_MOUSE_MOVE.
|
}
|
||||||
SInt32 x, y, w, h;
|
|
||||||
m_screen->getShape(x, y, w, h);
|
void
|
||||||
mouse_event(MOUSEEVENTF_ABSOLUTE | MOUSEEVENTF_MOVE,
|
CMSWindowsPrimaryScreen::warpCursorNoFlush(SInt32 x, SInt32 y)
|
||||||
(DWORD)((65535.99 * (m_xCenter - x)) / (w - 1)),
|
{
|
||||||
(DWORD)((65535.99 * (m_yCenter - y)) / (h - 1)),
|
// send an event that we can recognize before the mouse warp
|
||||||
0,
|
PostThreadMessage(m_threadID, SYNERGY_MSG_PRE_WARP, x, y);
|
||||||
0x12345678);
|
|
||||||
// FIXME -- ignore mouse until we get warp notification?
|
// warp mouse. hopefully this inserts a mouse motion event
|
||||||
|
// between the previous message and the following message.
|
||||||
|
SetCursorPos(x, y);
|
||||||
|
|
||||||
|
// send an event that we can recognize after the mouse warp
|
||||||
|
PostThreadMessage(m_threadID, SYNERGY_MSG_POST_WARP, 0, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -572,6 +579,12 @@ CMSWindowsPrimaryScreen::nextMark()
|
||||||
PostThreadMessage(m_threadID, SYNERGY_MSG_MARK, m_mark, 0);
|
PostThreadMessage(m_threadID, SYNERGY_MSG_MARK, m_mark, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
CMSWindowsPrimaryScreen::ignore() const
|
||||||
|
{
|
||||||
|
return (m_mark != m_markReceived);
|
||||||
|
}
|
||||||
|
|
||||||
static const KeyID g_virtualKey[] =
|
static const KeyID g_virtualKey[] =
|
||||||
{
|
{
|
||||||
/* 0x00 */ kKeyNone, // reserved
|
/* 0x00 */ kKeyNone, // reserved
|
||||||
|
@ -984,15 +997,14 @@ CMSWindowsPrimaryScreen::mapKey(
|
||||||
// set shift state required to generate key
|
// set shift state required to generate key
|
||||||
BYTE keys[256];
|
BYTE keys[256];
|
||||||
memset(keys, 0, sizeof(keys));
|
memset(keys, 0, sizeof(keys));
|
||||||
// FIXME -- surely these masks should be different in each if expression
|
|
||||||
if (vkCode & 0x0100) {
|
if (vkCode & 0x0100) {
|
||||||
keys[VK_SHIFT] = 0x80;
|
keys[VK_SHIFT] = 0x80;
|
||||||
}
|
}
|
||||||
if (vkCode & 0x0100) {
|
if (vkCode & 0x0200) {
|
||||||
keys[VK_CONTROL] = 0x80;
|
keys[VK_CONTROL] = 0x80;
|
||||||
}
|
}
|
||||||
if (vkCode & 0x0100) {
|
if (vkCode & 0x0400) {
|
||||||
keys[VK_MENU] = 0x80;
|
keys[VK_MENU] = 0x80;
|
||||||
}
|
}
|
||||||
|
|
||||||
// strip shift state off of virtual key code
|
// strip shift state off of virtual key code
|
||||||
|
|
|
@ -56,9 +56,15 @@ protected:
|
||||||
private:
|
private:
|
||||||
void enterNoWarp();
|
void enterNoWarp();
|
||||||
|
|
||||||
|
// warp cursor without discarding queued events
|
||||||
|
void warpCursorNoFlush(SInt32 x, SInt32 y);
|
||||||
|
|
||||||
// discard posted messages
|
// discard posted messages
|
||||||
void nextMark();
|
void nextMark();
|
||||||
|
|
||||||
|
// test if event should be ignored
|
||||||
|
bool ignore() const;
|
||||||
|
|
||||||
// key and button queries
|
// key and button queries
|
||||||
KeyID mapKey(WPARAM keycode, LPARAM info,
|
KeyID mapKey(WPARAM keycode, LPARAM info,
|
||||||
KeyModifierMask* maskOut);
|
KeyModifierMask* maskOut);
|
||||||
|
@ -91,9 +97,6 @@ private:
|
||||||
// position of center pixel of screen
|
// position of center pixel of screen
|
||||||
SInt32 m_xCenter, m_yCenter;
|
SInt32 m_xCenter, m_yCenter;
|
||||||
|
|
||||||
// used to ignore mouse motion
|
|
||||||
SInt32 m_mouseMoveIgnore;
|
|
||||||
|
|
||||||
// hook library stuff
|
// hook library stuff
|
||||||
HINSTANCE m_hookLibrary;
|
HINSTANCE m_hookLibrary;
|
||||||
InitFunc m_init;
|
InitFunc m_init;
|
||||||
|
|
|
@ -155,19 +155,12 @@ CPrimaryScreen::leave()
|
||||||
// get keyboard state as we leave
|
// get keyboard state as we leave
|
||||||
updateKeys();
|
updateKeys();
|
||||||
|
|
||||||
// warp mouse to center
|
|
||||||
warpCursorToCenter();
|
|
||||||
// FIXME -- this doesn't match the win32 version. that just does
|
|
||||||
// the warp while we flush the input queue until we find the warp
|
|
||||||
// and we discard that too. would prefer to at least match our
|
|
||||||
// own warping when we receive MotionNotify; that just does the
|
|
||||||
// warp. however, the win32 version sometimes stutters when
|
|
||||||
// leaving and perhaps this is why. hmm, win32 does ignore the
|
|
||||||
// events until after the warp (via the mark).
|
|
||||||
|
|
||||||
// subclass hook
|
// subclass hook
|
||||||
onPostLeave(true);
|
onPostLeave(true);
|
||||||
|
|
||||||
|
// warp mouse to center
|
||||||
|
warpCursorToCenter();
|
||||||
|
|
||||||
// local client now active
|
// local client now active
|
||||||
m_active = true;
|
m_active = true;
|
||||||
|
|
||||||
|
|
|
@ -47,7 +47,9 @@ public:
|
||||||
// primary screen are linked to clients.
|
// primary screen are linked to clients.
|
||||||
virtual void reconfigure(UInt32 activeSides) = 0;
|
virtual void reconfigure(UInt32 activeSides) = 0;
|
||||||
|
|
||||||
// warp the cursor to the given absolute coordinates
|
// warp the cursor to the given absolute coordinates. also
|
||||||
|
// discard input events up to and including the warp before
|
||||||
|
// returning.
|
||||||
virtual void warpCursor(SInt32 x, SInt32 y) = 0;
|
virtual void warpCursor(SInt32 x, SInt32 y) = 0;
|
||||||
|
|
||||||
// set the screen's clipboard contents. this is usually called
|
// set the screen's clipboard contents. this is usually called
|
||||||
|
|
Loading…
Reference in New Issue