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 "CMSWindowsClipboard.h"
|
||||
#include "CMSWindowsScreenSaver.h"
|
||||
#include "CPlatform.h"
|
||||
#include "CClipboard.h"
|
||||
#include "IMSWindowsScreenEventHandler.h"
|
||||
#include "IScreenReceiver.h"
|
||||
|
@ -35,6 +36,7 @@ CMSWindowsScreen::CMSWindowsScreen(IScreenReceiver* receiver,
|
|||
m_class(NULL),
|
||||
m_icon(NULL),
|
||||
m_cursor(NULL),
|
||||
m_is95Family(CPlatform::isWindows95Family()),
|
||||
m_window(NULL),
|
||||
m_x(0), m_y(0),
|
||||
m_w(0), m_h(0),
|
||||
|
@ -206,7 +208,11 @@ CMSWindowsScreen::mainLoop()
|
|||
void
|
||||
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_APP + 1, 0, 0);
|
||||
}
|
||||
|
||||
void
|
||||
|
|
|
@ -187,14 +187,7 @@ mouseHook(int code, WPARAM wParam, LPARAM lParam)
|
|||
// relay the motion
|
||||
SInt32 x = (SInt32)info->pt.x;
|
||||
SInt32 y = (SInt32)info->pt.y;
|
||||
if (info->dwExtraInfo == 0x12345678) {
|
||||
PostThreadMessage(g_threadID,
|
||||
SYNERGY_MSG_POST_WARP, x, y);
|
||||
}
|
||||
else {
|
||||
PostThreadMessage(g_threadID,
|
||||
SYNERGY_MSG_MOUSE_MOVE, x, y);
|
||||
}
|
||||
PostThreadMessage(g_threadID, SYNERGY_MSG_MOUSE_MOVE, x, y);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
|
|
@ -19,10 +19,13 @@
|
|||
#define SYNERGY_MSG_MARK WM_APP + 0x0011 // mark id; <unused>
|
||||
#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_MOVE WM_APP + 0x0014 // x; y
|
||||
#define SYNERGY_MSG_POST_WARP WM_APP + 0x0015 // x; y
|
||||
#define SYNERGY_MSG_MOUSE_WHEEL WM_APP + 0x0016 // delta; <unused>
|
||||
#define SYNERGY_MSG_SCREEN_SAVER WM_APP + 0x0017 // activated; <unused>
|
||||
#define SYNERGY_MSG_MOUSE_WHEEL WM_APP + 0x0014 // delta; <unused>
|
||||
#define SYNERGY_MSG_MOUSE_MOVE WM_APP + 0x0015 // x; y
|
||||
#define SYNERGY_MSG_POST_WARP WM_APP + 0x0016 // <unused>; <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" {
|
||||
|
||||
|
|
|
@ -19,8 +19,7 @@ CMSWindowsPrimaryScreen::CMSWindowsPrimaryScreen(
|
|||
m_threadID(0),
|
||||
m_window(NULL),
|
||||
m_mark(0),
|
||||
m_markReceived(0),
|
||||
m_mouseMoveIgnore(0)
|
||||
m_markReceived(0)
|
||||
{
|
||||
assert(m_receiver != NULL);
|
||||
|
||||
|
@ -71,9 +70,15 @@ CMSWindowsPrimaryScreen::reconfigure(UInt32 activeSides)
|
|||
void
|
||||
CMSWindowsPrimaryScreen::warpCursor(SInt32 x, SInt32 y)
|
||||
{
|
||||
// set the cursor position without generating an event
|
||||
// FIXME -- doesn't this generate an event anyway?
|
||||
SetCursorPos(x, y);
|
||||
// warp mouse
|
||||
warpCursorNoFlush(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
|
||||
m_x = x;
|
||||
|
@ -165,7 +170,7 @@ CMSWindowsPrimaryScreen::onPreDispatch(const CEvent* event)
|
|||
|
||||
case SYNERGY_MSG_KEY:
|
||||
// ignore message if posted prior to last mark change
|
||||
if (m_markReceived == m_mark) {
|
||||
if (!ignore()) {
|
||||
KeyModifierMask mask;
|
||||
const KeyID key = mapKey(msg->wParam, msg->lParam, &mask);
|
||||
if (key != kKeyNone) {
|
||||
|
@ -201,7 +206,7 @@ CMSWindowsPrimaryScreen::onPreDispatch(const CEvent* event)
|
|||
|
||||
case SYNERGY_MSG_MOUSE_BUTTON:
|
||||
// ignore message if posted prior to last mark change
|
||||
if (m_markReceived == m_mark) {
|
||||
if (!ignore()) {
|
||||
static const int s_vkButton[] = {
|
||||
0, // kButtonNone
|
||||
VK_LBUTTON, // kButtonLeft, etc.
|
||||
|
@ -236,53 +241,65 @@ CMSWindowsPrimaryScreen::onPreDispatch(const CEvent* event)
|
|||
|
||||
case SYNERGY_MSG_MOUSE_WHEEL:
|
||||
// ignore message if posted prior to last mark change
|
||||
if (m_markReceived == m_mark) {
|
||||
log((CLOG_ERR "event: button wheel delta=%d %d", msg->wParam, msg->lParam));
|
||||
if (!ignore()) {
|
||||
log((CLOG_DEBUG1 "event: button wheel delta=%d %d", msg->wParam, msg->lParam));
|
||||
m_receiver->onMouseWheel(msg->wParam);
|
||||
}
|
||||
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:
|
||||
// ignore message if posted prior to last mark change
|
||||
if (m_markReceived == m_mark) {
|
||||
SInt32 x = static_cast<SInt32>(msg->wParam);
|
||||
SInt32 y = static_cast<SInt32>(msg->lParam);
|
||||
if (!ignore()) {
|
||||
// compute motion delta (relative to the last known
|
||||
// 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()) {
|
||||
m_receiver->onMouseMovePrimary(x, y);
|
||||
// motion on primary screen
|
||||
m_receiver->onMouseMovePrimary(m_x, m_y);
|
||||
}
|
||||
else {
|
||||
// compute motion delta. this is relative to the
|
||||
// last known mouse position.
|
||||
x -= m_x;
|
||||
y -= m_y;
|
||||
// motion on secondary screen. warp mouse back to
|
||||
// center.
|
||||
if (x != 0 || y != 0) {
|
||||
// back to center
|
||||
warpCursorNoFlush(m_xCenter, m_yCenter);
|
||||
|
||||
// save position to compute delta of next motion
|
||||
m_x = static_cast<SInt32>(msg->wParam);
|
||||
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;
|
||||
// send motion
|
||||
m_receiver->onMouseMoveSecondary(x, y);
|
||||
}
|
||||
}
|
||||
}
|
||||
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;
|
||||
|
@ -414,9 +431,6 @@ CMSWindowsPrimaryScreen::onPreEnter()
|
|||
{
|
||||
assert(m_window != NULL);
|
||||
|
||||
// reset motion ignore count
|
||||
m_mouseMoveIgnore = 0;
|
||||
|
||||
// enable ctrl+alt+del, alt+tab, etc
|
||||
if (m_is95Family) {
|
||||
DWORD dummy = 0;
|
||||
|
@ -450,23 +464,11 @@ CMSWindowsPrimaryScreen::onPostLeave(bool success)
|
|||
// relay all mouse and keyboard events
|
||||
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
|
||||
if (m_is95Family) {
|
||||
DWORD dummy = 0;
|
||||
SystemParametersInfo(SPI_SETSCREENSAVERRUNNING, TRUE, &dummy, 0);
|
||||
}
|
||||
|
||||
// discard messages until after the warp
|
||||
nextMark();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -550,16 +552,21 @@ CMSWindowsPrimaryScreen::hideWindow()
|
|||
void
|
||||
CMSWindowsPrimaryScreen::warpCursorToCenter()
|
||||
{
|
||||
// warp to center. the extra info tells the hook DLL to send
|
||||
// SYNERGY_MSG_POST_WARP instead of SYNERGY_MSG_MOUSE_MOVE.
|
||||
SInt32 x, y, w, h;
|
||||
m_screen->getShape(x, y, w, h);
|
||||
mouse_event(MOUSEEVENTF_ABSOLUTE | MOUSEEVENTF_MOVE,
|
||||
(DWORD)((65535.99 * (m_xCenter - x)) / (w - 1)),
|
||||
(DWORD)((65535.99 * (m_yCenter - y)) / (h - 1)),
|
||||
0,
|
||||
0x12345678);
|
||||
// FIXME -- ignore mouse until we get warp notification?
|
||||
warpCursor(m_xCenter, m_yCenter);
|
||||
}
|
||||
|
||||
void
|
||||
CMSWindowsPrimaryScreen::warpCursorNoFlush(SInt32 x, SInt32 y)
|
||||
{
|
||||
// send an event that we can recognize before the mouse warp
|
||||
PostThreadMessage(m_threadID, SYNERGY_MSG_PRE_WARP, x, y);
|
||||
|
||||
// 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
|
||||
|
@ -572,6 +579,12 @@ CMSWindowsPrimaryScreen::nextMark()
|
|||
PostThreadMessage(m_threadID, SYNERGY_MSG_MARK, m_mark, 0);
|
||||
}
|
||||
|
||||
bool
|
||||
CMSWindowsPrimaryScreen::ignore() const
|
||||
{
|
||||
return (m_mark != m_markReceived);
|
||||
}
|
||||
|
||||
static const KeyID g_virtualKey[] =
|
||||
{
|
||||
/* 0x00 */ kKeyNone, // reserved
|
||||
|
@ -984,15 +997,14 @@ CMSWindowsPrimaryScreen::mapKey(
|
|||
// set shift state required to generate key
|
||||
BYTE keys[256];
|
||||
memset(keys, 0, sizeof(keys));
|
||||
// FIXME -- surely these masks should be different in each if expression
|
||||
if (vkCode & 0x0100) {
|
||||
keys[VK_SHIFT] = 0x80;
|
||||
keys[VK_SHIFT] = 0x80;
|
||||
}
|
||||
if (vkCode & 0x0100) {
|
||||
if (vkCode & 0x0200) {
|
||||
keys[VK_CONTROL] = 0x80;
|
||||
}
|
||||
if (vkCode & 0x0100) {
|
||||
keys[VK_MENU] = 0x80;
|
||||
if (vkCode & 0x0400) {
|
||||
keys[VK_MENU] = 0x80;
|
||||
}
|
||||
|
||||
// strip shift state off of virtual key code
|
||||
|
|
|
@ -56,9 +56,15 @@ protected:
|
|||
private:
|
||||
void enterNoWarp();
|
||||
|
||||
// warp cursor without discarding queued events
|
||||
void warpCursorNoFlush(SInt32 x, SInt32 y);
|
||||
|
||||
// discard posted messages
|
||||
void nextMark();
|
||||
|
||||
// test if event should be ignored
|
||||
bool ignore() const;
|
||||
|
||||
// key and button queries
|
||||
KeyID mapKey(WPARAM keycode, LPARAM info,
|
||||
KeyModifierMask* maskOut);
|
||||
|
@ -91,9 +97,6 @@ private:
|
|||
// position of center pixel of screen
|
||||
SInt32 m_xCenter, m_yCenter;
|
||||
|
||||
// used to ignore mouse motion
|
||||
SInt32 m_mouseMoveIgnore;
|
||||
|
||||
// hook library stuff
|
||||
HINSTANCE m_hookLibrary;
|
||||
InitFunc m_init;
|
||||
|
|
|
@ -155,19 +155,12 @@ CPrimaryScreen::leave()
|
|||
// get keyboard state as we leave
|
||||
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
|
||||
onPostLeave(true);
|
||||
|
||||
// warp mouse to center
|
||||
warpCursorToCenter();
|
||||
|
||||
// local client now active
|
||||
m_active = true;
|
||||
|
||||
|
|
|
@ -47,7 +47,9 @@ public:
|
|||
// primary screen are linked to clients.
|
||||
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;
|
||||
|
||||
// set the screen's clipboard contents. this is usually called
|
||||
|
|
Loading…
Reference in New Issue